cleanup up LibMemoryManagement.*

pull/1/head
Steve Lascos 7 years ago
parent 9fd96aa5e3
commit 7cf4b57bc6
  1. 14
      src/AudioEffectAnalogDelay.cpp
  2. 6
      src/BAAudioControlWM8731.h
  3. 2
      src/BASpiMemory.h
  4. 49
      src/LibBasicFunctions.cpp
  5. 151
      src/LibMemoryManagement.cpp
  6. 189
      src/LibMemoryManagement.h

@ -71,7 +71,7 @@ void AudioEffectAnalogDelay::update(void)
m_callCount++;
Serial.println(String("AudioEffectAnalgDelay::update: ") + m_callCount);
m_memory->getSlot()->printStatus();
//m_memory->getSlot()->printStatus();
audio_block_t *blockToRelease = m_memory->addBlock(inputAudioBlock);
// if (inputAudioBlock) {
@ -113,7 +113,7 @@ void AudioEffectAnalogDelay::update(void)
if (!blockToOutput) continue; // skip this channel due to failure
// copy over data
m_memory->getSamples(blockToOutput, m_channelOffsets[channel]);
//m_memory->read16(blockToOutput->data, 0, m_channelOffsets[channel], AUDIO_BLOCK_SAMPLES);
transmit(blockToOutput);
release(blockToOutput);
}
@ -126,6 +126,8 @@ bool AudioEffectAnalogDelay::delay(unsigned channel, float milliseconds)
size_t delaySamples = calcAudioSamples(milliseconds);
if (!m_memory) { Serial.println("delay(): m_memory is not valid"); }
if (!m_externalMemory) {
// internal memory
QueuePosition queuePosition = calcQueuePosition(milliseconds);
@ -134,10 +136,11 @@ bool AudioEffectAnalogDelay::delay(unsigned channel, float milliseconds)
// external memory
Serial.println(String("CONFIG: delay:") + delaySamples);
ExtMemSlot *slot = m_memory->getSlot();
if (!slot) { Serial.println("ERROR: slot ptr is not valid"); }
if (!slot->isEnabled()) {
slot->enable();
} else {
Serial.println("ERROR: slot ptr is not valid");
Serial.println("WEIRD: slot was not enabled");
}
}
@ -151,12 +154,15 @@ bool AudioEffectAnalogDelay::delay(unsigned channel, size_t delaySamples)
if (channel > MAX_DELAY_CHANNELS-1) // channel id too high
return false;
if (!m_memory) { Serial.println("delay(): m_memory is not valid"); }
if (!m_externalMemory) {
// internal memory
QueuePosition queuePosition = calcQueuePosition(delaySamples);
Serial.println(String("CONFIG: delay:") + delaySamples + String(" queue position ") + queuePosition.index + String(":") + queuePosition.offset);
} else {
// external memory
Serial.println(String("CONFIG: delay:") + delaySamples);
ExtMemSlot *slot = m_memory->getSlot();
if (!slot->isEnabled()) {
slot->enable();

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef __INC_BAAUDIOCONTROLWM8731_H
#define __INC_BAAUDIOCONTROLWM8731_H
#ifndef __BAAUDIOCONTROLWM8731_H
#define __BAAUDIOCONTROLWM8731_H
namespace BAGuitar {
@ -128,4 +128,4 @@ private:
} /* namespace BAGuitar */
#endif /* __INC_BAAUDIOCONTROLWM8731_H */
#endif /* __BAAUDIOCONTROLWM8731_H */

@ -59,7 +59,7 @@ public:
void write16(size_t address, uint16_t data);
void write16(size_t address, uint16_t *data, size_t numWords);
void zero16(size_t address, size_t numBytes);
void zero16(size_t address, size_t numWords);
/// read a single 8-bit data word from the specified address
/// @param address the address in the SPI RAM to read from

@ -50,9 +50,10 @@ AudioDelay::AudioDelay(float maxDelayTimeMs)
}
AudioDelay::AudioDelay(ExtMemSlot *slot)
: m_slot(slot)
//: m_slot(slot)
{
m_type = MemType::MEM_EXTERNAL;
m_slot = slot;
}
AudioDelay::~AudioDelay()
@ -77,15 +78,24 @@ audio_block_t* AudioDelay::addBlock(audio_block_t *block)
return blockToRelease;
} else {
// EXTERNAL memory
if (!m_slot) { Serial.println("addBlock(): m_slot is not valid"); }
//m_slot->writeAdvance16(block->data, AUDIO_BLOCK_SAMPLES);
if (block) {
// Audio is stored in reverse in block so we need to write it backwards to external memory
// to maintain temporal coherency.
// int16_t *srcPtr = block->data + AUDIO_BLOCK_SAMPLES - 1;
// for (int i=0; i<AUDIO_BLOCK_SAMPLES; i++) {
// m_slot->writeAdvance16(*srcPtr);
// srcPtr--;
// }
int16_t *srcPtr = block->data;
for (int i=0; i<AUDIO_BLOCK_SAMPLES; i++) {
m_slot->writeAdvance16(*srcPtr);
srcPtr++;
}
// Audio is stored in reverse in block so we need to write it backwards to external memory
// to maintain temporal coherency.
int16_t *srcPtr = block->data + AUDIO_BLOCK_SAMPLES - 1;
for (int i=0; i<AUDIO_BLOCK_SAMPLES; i++) {
m_slot->writeAdvance16(*srcPtr);
srcPtr--;
}
return block;
@ -140,25 +150,36 @@ bool AudioDelay::getSamples(audio_block_t *dest, size_t offset, size_t numSample
} else {
// EXTERNAL Memory
if (numSamples <= m_slot->size() ) {
int currentPosition = (int)m_slot->getWritePosition() - (int)AUDIO_BLOCK_SAMPLES;
if (numSamples*sizeof(int16_t) <= m_slot->size() ) {
int currentPositionBytes = (int)m_slot->getWritePosition() - (int)(AUDIO_BLOCK_SAMPLES*sizeof(int16_t));
size_t offsetBytes = offset * sizeof(int16_t);
if ((int)offset <= currentPosition) {
m_slot->setReadPosition(currentPosition - offset);
if ((int)offsetBytes <= currentPositionBytes) {
m_slot->setReadPosition(currentPositionBytes - offsetBytes);
} else {
// It's going to wrap around to the end of the slot
int readPosition = (int)m_slot->size() + currentPosition - offset;
int readPosition = (int)m_slot->size() + currentPositionBytes - offsetBytes;
m_slot->setReadPosition((size_t)readPosition);
}
m_slot->printStatus();
// write the data to the destination block in reverse
int16_t *destPtr = dest->data + AUDIO_BLOCK_SAMPLES-1;
// int16_t *destPtr = dest->data + AUDIO_BLOCK_SAMPLES-1;
// for (int i=0; i<AUDIO_BLOCK_SAMPLES; i++) {
// *destPtr = m_slot->readAdvance16();
// destPtr--;
// }
int16_t *destPtr = dest->data;
for (int i=0; i<AUDIO_BLOCK_SAMPLES; i++) {
*destPtr = m_slot->readAdvance16();
destPtr++;
}
return true;
} else {
// numSampmles is > than total slot size
Serial.println("getSamples(): ERROR numSamples > total slot size");
return false;
}
}

@ -1,9 +1,26 @@
/*
* LibMemoryManagement.cpp
*
* Created on: Jan 19, 2018
* Author: slascos
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstring>
#include <new>
#include "Audio.h"
#include "LibMemoryManagement.h"
namespace BAGuitar {
@ -19,12 +36,21 @@ bool ExtMemSlot::clear()
return true;
}
bool ExtMemSlot::write16(size_t offset, int16_t *dataPtr, size_t dataSize)
bool ExtMemSlot::setWritePosition(size_t offsetBytes)
{
if (m_start + offsetBytes <= m_end) {
m_currentWrPosition = m_start + offsetBytes;
return true;
} else { return false; }
}
bool ExtMemSlot::write16(size_t offsetBytes, int16_t *dest, size_t numWords)
{
if (!m_valid) { return false; }
size_t writeStart = m_start + offset;
if ((writeStart + dataSize-1) <= m_end) {
m_spi->write16(writeStart, reinterpret_cast<uint16_t*>(dataPtr), dataSize); // cast audio data to uint
size_t writeStart = m_start + offsetBytes; // 2x because int16 is two bytes per data
size_t numBytes = sizeof(int16_t)*numWords;
if ((writeStart + numBytes-1) <= m_end) {
m_spi->write16(writeStart, reinterpret_cast<uint16_t*>(dest), numWords); // cast audio data to uint
return true;
} else {
// this would go past the end of the memory slot, do not perform the write
@ -32,12 +58,23 @@ bool ExtMemSlot::write16(size_t offset, int16_t *dataPtr, size_t dataSize)
}
}
bool ExtMemSlot::zero16(size_t offset, size_t dataSize)
bool ExtMemSlot::setReadPosition(size_t offsetBytes)
{
if (m_start + offsetBytes <= m_end) {
m_currentRdPosition = m_start + offsetBytes;
return true;
} else {
return false;
}
}
bool ExtMemSlot::zero16(size_t offsetBytes, size_t numWords)
{
if (!m_valid) { return false; }
size_t writeStart = m_start + offset;
if ((writeStart + dataSize-1) <= m_end) {
m_spi->zero16(writeStart, dataSize); // cast audio data to uint
size_t writeStart = m_start + offsetBytes;
size_t numBytes = sizeof(int16_t)*numWords;
if ((writeStart + numBytes-1) <= m_end) {
m_spi->zero16(writeStart, numWords); // cast audio data to uint
return true;
} else {
// this would go past the end of the memory slot, do not perform the write
@ -45,16 +82,17 @@ bool ExtMemSlot::zero16(size_t offset, size_t dataSize)
}
}
bool ExtMemSlot::read16(int16_t *dest, size_t srcOffset, size_t numData)
bool ExtMemSlot::read16(int16_t *dest, size_t offsetBytes, size_t numWords)
{
if (!dest) return false; // invalid destination
size_t readOffset = m_start + srcOffset;
size_t readOffset = m_start + offsetBytes;
size_t numBytes = sizeof(int16_t)*numWords;
if ((readOffset + (numData*sizeof(int16_t))-1) <= m_end) {
m_spi->read16(readOffset, reinterpret_cast<uint16_t*>(dest), numData);
if ((readOffset + numBytes-1) <= m_end) {
m_spi->read16(readOffset, reinterpret_cast<uint16_t*>(dest), numWords);
return true;
} else {
// this would go past the end of the memory slot, do not perform the write
// this would go past the end of the memory slot, do not perform the read
return false;
}
}
@ -62,8 +100,8 @@ bool ExtMemSlot::read16(int16_t *dest, size_t srcOffset, size_t numData)
uint16_t ExtMemSlot::readAdvance16()
{
uint16_t val = m_spi->read16(m_currentRdPosition);
if (m_currentRdPosition < m_end) {
m_currentRdPosition++;
if (m_currentRdPosition < m_end-1) {
m_currentRdPosition +=2; // position is in bytes and we read two
} else {
m_currentRdPosition = m_start;
}
@ -71,70 +109,65 @@ uint16_t ExtMemSlot::readAdvance16()
}
//void ExtMemSlot::read16FromPast(int16_t *dest, size_t currentOffset, size_t numData)
//{
// size_t readStart;
// if (m_currentPosition - currentOffset >= m_start) {
// readStart = m_currentPosition - currentOffset;
// } else {
// // this offset will wrap the memory slot
// size_t numBytesToStart = m_currentPosition;
// readStart = m_end - (currentOffset - numBytesToStart);
// }
// m_spi->read16(readStart, reinterpret_cast<uint16_t*>(dest), numData);
//}
bool ExtMemSlot::writeAdvance16(int16_t *dataPtr, size_t dataSize)
bool ExtMemSlot::writeAdvance16(int16_t *src, size_t numWords)
{
if (!m_valid) { return false; }
if (m_currentWrPosition + dataSize-1 <= m_end) {
size_t numBytes = sizeof(int16_t)*numWords;
if (m_currentWrPosition + numBytes-1 <= m_end) {
// entire block fits in memory slot without wrapping
m_spi->write16(m_currentWrPosition, reinterpret_cast<uint16_t*>(dataPtr), dataSize); // cast audio data to uint.
m_currentWrPosition += dataSize;
m_spi->write16(m_currentWrPosition, reinterpret_cast<uint16_t*>(src), numWords); // cast audio data to uint.
m_currentWrPosition += numBytes;
} else {
// this write will wrap the memory slot
size_t numBytes = m_end - m_currentWrPosition + 1;
m_spi->write16(m_currentWrPosition, reinterpret_cast<uint16_t*>(dataPtr), numBytes);
size_t remainingBytes = dataSize - numBytes; // calculate the remaining bytes
m_spi->write16(m_start, reinterpret_cast<uint16_t*>(dataPtr + numBytes), remainingBytes); // write remaining bytes are start
m_currentWrPosition = m_start + remainingBytes;
size_t wrBytes = m_end - m_currentWrPosition + 1;
size_t wrDataNum = wrBytes >> 1; // divide by two to get the number of data
m_spi->write16(m_currentWrPosition, reinterpret_cast<uint16_t*>(src), wrDataNum);
size_t remainingData = numWords - wrDataNum;
m_spi->write16(m_start, reinterpret_cast<uint16_t*>(src + wrDataNum), remainingData); // write remaining bytes are start
m_currentWrPosition = m_start + (remainingData*sizeof(int16_t));
}
return true;
}
bool ExtMemSlot::writeAdvance16(int16_t data)
bool ExtMemSlot::zeroAdvance16(size_t numWords)
{
if (!m_valid) { return false; }
size_t numBytes = 2*numWords;
if (m_currentWrPosition + numBytes-1 <= m_end) {
// entire block fits in memory slot without wrapping
m_spi->zero16(m_currentWrPosition, numWords); // cast audio data to uint.
m_currentWrPosition += numBytes;
m_spi->write16(m_currentWrPosition, static_cast<uint16_t>(data));
if (m_currentWrPosition < m_end) {
m_currentWrPosition++;
} else {
m_currentWrPosition = m_start;
// this write will wrap the memory slot
size_t wrBytes = m_end - m_currentWrPosition + 1;
size_t wrDataNum = wrBytes >> 1;
m_spi->zero16(m_currentWrPosition, wrDataNum);
size_t remainingWords = numWords - wrDataNum; // calculate the remaining bytes
m_spi->zero16(m_start, remainingWords); // write remaining bytes are start
m_currentWrPosition = m_start + remainingWords*sizeof(int16_t);
}
return true;
}
bool ExtMemSlot::zeroAdvance16(size_t dataSize)
bool ExtMemSlot::writeAdvance16(int16_t data)
{
if (!m_valid) { return false; }
if (m_currentWrPosition + dataSize-1 <= m_end) {
// entire block fits in memory slot without wrapping
m_spi->zero16(m_currentWrPosition, dataSize); // cast audio data to uint.
m_currentWrPosition += dataSize;
m_spi->write16(m_currentWrPosition, static_cast<uint16_t>(data));
if (m_currentWrPosition < m_end-1) {
m_currentWrPosition+=2; // wrote two bytes
} else {
// this write will wrap the memory slot
size_t numBytes = m_end - m_currentWrPosition + 1;
m_spi->zero16(m_currentWrPosition, numBytes);
size_t remainingBytes = dataSize - numBytes; // calculate the remaining bytes
m_spi->zero16(m_start, remainingBytes); // write remaining bytes are start
m_currentWrPosition = m_start + remainingBytes;
m_currentWrPosition = m_start;
}
return true;
}
bool ExtMemSlot::enable() const
{
if (m_spi) {
@ -158,6 +191,7 @@ void ExtMemSlot::printStatus(void) const
{
Serial.println(String("valid:") + m_valid + String(" m_start:") + m_start + \
String(" m_end:") + m_end + String(" m_currentWrPosition: ") + m_currentWrPosition + \
String(" m_currentRdPosition: ") + m_currentRdPosition + \
String(" m_size:") + m_size);
}
@ -178,11 +212,6 @@ ExternalSramManager::ExternalSramManager(unsigned numMemories)
m_memConfig[i].nextAvailable = 0;
m_memConfig[i].m_spi = nullptr;
// if (i < numMemories) {
// m_memConfig[i].m_spi = new BAGuitar::BASpiMemory(static_cast<BAGuitar::SpiDeviceId>(i));
// } else {
// m_memConfig[i].m_spi = nullptr;
// }
}
m_configured = true;
}
@ -204,7 +233,7 @@ bool ExternalSramManager::requestMemory(ExtMemSlot *slot, float delayMillisecond
{
// convert the time to numer of samples
size_t delayLengthInt = (size_t)((delayMilliseconds*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f);
return requestMemory(slot, delayLengthInt, mem);
return requestMemory(slot, delayLengthInt * sizeof(int16_t), mem);
}
bool ExternalSramManager::requestMemory(ExtMemSlot *slot, size_t sizeBytes, BAGuitar::MemSelect mem)

@ -1,87 +1,196 @@
/*
* ExtMemoryManagement.h
/**************************************************************************//**
* @file
* @author Steve Lascos
* @company Blackaddr Audio
*
* Created on: Dec 23, 2017
* Author: slascos
*/
* LibMemoryManagment is a class for providing access to external SPI based
* SRAM with the optional convience of breaking it up into 'slots' which are smaller
* memory entities.
* @details This class treats an external memory as a pool from which the user requests
* a block. When using that block, the user need not be concerned with where the pool
* it came from, they only deal with offsets from the start of their memory block. Ie.
* Your particular slot of memory appears to you to start at 0 and end at whatever size
* was requested.
*
* @copyright This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef SRC_LIBMEMORYMANAGEMENT_H_
#define SRC_LIBMEMORYMANAGEMENT_H_
#ifndef __LIBMEMORYMANAGEMENT_H
#define __LIBMEMORYMANAGEMENT_H
#include <cstddef>
//#include "Audio.h"
#include "BAHardware.h"
#include "BASpiMemory.h"
//#include "LibBasicFunctions.h"
namespace BAGuitar {
/**************************************************************************//**
* MemConfig contains the configuration information associated with a particular
* SPI interface.
*****************************************************************************/
struct MemConfig {
size_t size;
size_t totalAvailable;
size_t nextAvailable;
BASpiMemory *m_spi = nullptr;
size_t size; ///< the total size of the external SPI memory
size_t totalAvailable; ///< the number of bytes available (remaining)
size_t nextAvailable; ///< the starting point for the next available slot
BASpiMemory *m_spi = nullptr; ///< handle to the SPI interface
};
class ExternalSramManager; // forward declare so ExtMemSlot can setup friendship
class ExternalSramManager; // forward declare so ExtMemSlot can declared friendship with it
/**************************************************************************//**
* ExtMemSlot provides a convenient interface to a particular slot of an
* external memory.
* @details the memory can be access randomly, as a single word, as a block of
* data, or as circular queue.
*****************************************************************************/
class ExtMemSlot {
public:
/// clear the entire contents of the slot by writing zeros
/// @returns true on success
bool clear();
bool setWritePosition(size_t offset) { m_currentWrPosition = m_start + offset; return true;} // TODO add range check
/// set a new write position (in bytes) for circular operation
/// @param offsetBytes moves the write pointer to the specified offset from the slot start
/// @returns true on success, else false if offset is beyond slot boundaries.
bool setWritePosition(size_t offsetBytes);
/// returns the currently set write pointer pointer
/// @returns the write position value
size_t getWritePosition() const { return m_currentWrPosition-m_start; }
bool setReadPosition(size_t offset) { m_currentRdPosition = m_start + offset; return true;} // TODO add range check
size_t getReadPosition() const { return m_currentRdPosition-m_start; }
/// set a new read position (in bytes) for circular operation
/// @param offsetBytes moves the read pointer to the specified offset from the slot start
/// @returns true on success, else false if offset is beyond slot boundaries.
bool setReadPosition(size_t offsetBytes);
bool write16(size_t offset, int16_t *dataPtr, size_t numData);
bool zero16(size_t offset, size_t numData);
bool read16(int16_t *dest, size_t srcOffset, size_t numData);
/// returns the currently set read pointer pointer
/// @returns the read position value
size_t getReadPosition() const { return m_currentRdPosition-m_start; }
/// Write a block of 16-bit data to the memory at the specified offset
/// @param offsetBytes offset in bytes from start of slot
/// @param dataPtr pointer to start of block of 16-bit data
/// @param numWords number of 16-bit words to transfer
/// @returns true on success, else false on error
bool write16(size_t offsetBytes, int16_t *dest, size_t numWords);
/// Write a block of zeros (16-bit) to the memory at the specified offset
/// @param offsetBytes offset in bytes from start of slot
/// @param numWords number of 16-bit words to transfer
/// @returns true on success, else false on error
bool zero16(size_t offsetBytes, size_t numWords);
/// Read a block of 16-bit data from the memory at the specified location
/// @param dest pointer to destination for the read data
/// @param offsetBytes offset in bytes from start of slot
/// @param numWords number of 16-bit words to transfer
/// @returns true on success, else false on error
bool read16(int16_t *dest, size_t offsetBytes, size_t numWords);
/// Read the next in memory during circular operation
/// @returns the next 16-bit data word in memory
uint16_t readAdvance16();
bool writeAdvance16(int16_t *dataPtr, size_t numData);
/// Write a block of 16-bit data from the specified location in circular operation
/// @param src pointer to the start of the block of data to write to memory
/// @param numWords number of 16-bit words to transfer
/// @returns true on success, else false on error
bool writeAdvance16(int16_t *src, size_t numWords);
/// Write a single 16-bit data to the next location in circular operation
/// @param data the 16-bit word to transfer
/// @returns true on success, else false on error
bool writeAdvance16(int16_t data); // write just one data
bool zeroAdvance16(size_t numData);
//void read16FromPast(int16_t *dest, size_t Offset, size_t numData);
/// Write a block of 16-bit data zeros in circular operation
/// @param numWords number of 16-bit words to transfer
/// @returns true on success, else false on error
bool zeroAdvance16(size_t numWords);
/// Get the size of the memory slot
/// @returns size of the slot in bytes
size_t size() const { return m_size; }
/// Ensures the underlying SPI interface is enabled
/// @returns true on success, false on error
bool enable() const;
/// Checks whether underlying SPI interface is enabled
/// @returns true if enabled, false if not enabled
bool isEnabled() const;
/// DEBUG USE: prints out the slot member variables
void printStatus(void) const;
private:
friend ExternalSramManager;
bool m_valid = false;
size_t m_start = 0;
size_t m_end = 0;
size_t m_currentWrPosition = 0;
size_t m_currentRdPosition = 0;
size_t m_size = 0;
SpiDeviceId m_spiId;
BASpiMemory *m_spi = nullptr;
friend ExternalSramManager; ///< gives the manager access to the private variables
bool m_valid = false; ///< After a slot is successfully configured by the manager it becomes valid
size_t m_start = 0; ///< the external memory address in bytes where this slot starts
size_t m_end = 0; ///< the external memory address in bytes where this slot ends (inclusive)
size_t m_currentWrPosition = 0; ///< current write pointer for circular operation
size_t m_currentRdPosition = 0; ///< current read pointer for circular operation
size_t m_size = 0; ///< size of this slot in bytes
SpiDeviceId m_spiId; ///< the SPI Device ID
BASpiMemory *m_spi = nullptr; ///< pointer to an instance of the BASpiMemory interface class
};
/**************************************************************************//**
* ExternalSramManager provides a class to handle dividing an external SPI RAM
* into independent slots for general use.
* @details the class does not support deallocated memory because this would cause
* fragmentation.
*****************************************************************************/
class ExternalSramManager final {
public:
ExternalSramManager() = delete;
ExternalSramManager(unsigned numMemories);
/// The manager is constructed by specifying how many external memories to handle allocations for
/// @param numMemories the number of external memories
ExternalSramManager(unsigned numMemories = 1);
virtual ~ExternalSramManager();
size_t availableMemory(BAGuitar::MemSelect mem);
/// Query the amount of available (unallocated) memory
/// @details note that currently, memory cannot be allocated.
/// @param mem specifies which memory to query, default is memory 0
/// @returns the available memory in bytes
size_t availableMemory(BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0);
/// Request memory be allocated for the provided slot
/// @param slot a pointer to the global slot object to which memory will be allocated
/// @param delayMilliseconds request the amount of memory based on required time for audio samples, rather than number of bytes.
/// @param mem specify which external memory to allocate from
/// @returns true on success, otherwise false on error
bool requestMemory(ExtMemSlot *slot, float delayMilliseconds, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0);
bool requestMemory(ExtMemSlot *slot, size_t sizeBytes, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0);
/// Request memory be allocated for the provided slot
/// @param slot a pointer to the global slot object to which memory will be allocated
/// @param sizeBytes request the amount of memory in bytes to request
/// @param mem specify which external memory to allocate from
/// @returns true on success, otherwise false on error
bool requestMemory(ExtMemSlot *slot, size_t sizeBytes, BAGuitar::MemSelect mem = BAGuitar::MemSelect::MEM0);
private:
static bool m_configured;
static MemConfig m_memConfig[BAGuitar::NUM_MEM_SLOTS];
static bool m_configured; ///< there should only be one instance of ExternalSramManager in the whole project
static MemConfig m_memConfig[BAGuitar::NUM_MEM_SLOTS]; ///< store the configuration information for each external memory
};
}
#endif /* SRC_LIBMEMORYMANAGEMENT_H_ */
#endif /* __LIBMEMORYMANAGEMENT_H */

Loading…
Cancel
Save