positionhigh
Well-known member
Hi there,
after getting no usable multi-channel audio with LittleFS from soldered on FlashChip or from SD Card i changed to the older SerialFlash.h and put the optional memory chip from the teensy-on-board to the audio board. This does now work for around 50 -60 seconds but then crashes because of a memory leak.
I am using a modified VariablePlayback Library "https://github.com/newdigate/teensy-variable-playback" to play Samples at different pitches. I modified it so that all calls to the SD Card go to their counterparts of the SerialFlashLibrary. It does works, but as said, only for a short time.
Most probably i created this memory leak myself because i am not an very advanced developer - but i am not sure about if the problem is me, the variableplayback or the serialflash library or a combination.
Playing the samples from PROGMEM works perfectly and does not create a memory leak. But since i can not change the sample content without flashing the program, i would like to play the samples from the SerialFlash Chip on the Audio Board.
I suspect my problem is somewhere in this file where i replaced the "File _file" commands from the SD Library with "SerialFlashFile _file" with the commands of the serialflash Library.
As said, it does work for around a minute but then crashes because of no more free RAM - it is consuming more RAM with every sample it is playing.
This problem haunts me for half of an year now and i tried everything i can think of - but so far no progress.
I would be very glad if someone more experienced would have a look what is going wrong.
My complete code is on
https://codeberg.org/positionhigh/MicroDexed-touch
which is a continuation (or hopefully in the future could be the base for a next generation) of
https://codeberg.org/dcoredump/MicroDexed
On that version, in the past, we made everything sample related in PROGMEM only, so this particular problem does not exist there.
Many thanks in advance.
after getting no usable multi-channel audio with LittleFS from soldered on FlashChip or from SD Card i changed to the older SerialFlash.h and put the optional memory chip from the teensy-on-board to the audio board. This does now work for around 50 -60 seconds but then crashes because of a memory leak.
I am using a modified VariablePlayback Library "https://github.com/newdigate/teensy-variable-playback" to play Samples at different pitches. I modified it so that all calls to the SD Card go to their counterparts of the SerialFlashLibrary. It does works, but as said, only for a short time.
Most probably i created this memory leak myself because i am not an very advanced developer - but i am not sure about if the problem is me, the variableplayback or the serialflash library or a combination.
Playing the samples from PROGMEM works perfectly and does not create a memory leak. But since i can not change the sample content without flashing the program, i would like to play the samples from the SerialFlash Chip on the Audio Board.
Code:
#include <Arduino.h>
#include <SerialFlash.h>
#include <vector>
namespace newdigate {
struct indexedbuffer {
uint32_t index;
int16_t buffer_size;
int16_t *buffer;
};
constexpr bool isPowerOf2(size_t value){
return !(value == 0) && !(value & (value - 1));
}
template<size_t BUFFER_SIZE, size_t MAX_NUM_BUFFERS> // BUFFER_SIZE needs to be a power of two
class IndexableFile {
public:
static_assert(isPowerOf2(BUFFER_SIZE), "BUFFER_SIZE must be a power of 2");
static constexpr size_t element_size = sizeof(int16_t);
size_t buffer_to_index_shift;
IndexableFile(const char *filename) :
_buffers(),
buffer_to_index_shift(log2(BUFFER_SIZE)) {
_filename = new char[strlen(filename)+1] {0};
memcpy(_filename, filename, strlen(filename));
_file = SerialFlash.open(_filename);
}
int16_t &operator[](int i) {
int32_t indexFor_i = i >> buffer_to_index_shift;
indexedbuffer *match = find_with_index(indexFor_i);
if (match == nullptr) {
if (_buffers.size() > MAX_NUM_BUFFERS - 1) {
indexedbuffer *first = _buffers[0];
_buffers.erase(_buffers.begin());
delete [] first->buffer;
delete first;
}
indexedbuffer *next = new indexedbuffer();
next->index = indexFor_i;
next->buffer = new int16_t[BUFFER_SIZE];
size_t basePos = indexFor_i << buffer_to_index_shift;
size_t seekPos = basePos * element_size;
_file.seek(seekPos);
int16_t bytesRead = _file.read(next->buffer, BUFFER_SIZE * element_size);
#ifndef TEENSYDUINO
if (!_file.available()){
_file.close();
__disable_irq();
_file = SerialFlash.open(_filename);
__enable_irq();
}
#endif
next->buffer_size = bytesRead;
_buffers.push_back(next);
match = next;
}
return match->buffer[i % BUFFER_SIZE];
}
void close() {
if (_file)
_file.close();
if (_filename)
delete [] _filename;
_filename = nullptr;
}
private:
SerialFlashFile _file;
char *_filename;
std::vector<indexedbuffer*> _buffers;
indexedbuffer* find_with_index(uint32_t i) {
for (auto && x : _buffers){
if (x->index == i) {
return x;
}
}
return nullptr;
}
};
}
I suspect my problem is somewhere in this file where i replaced the "File _file" commands from the SD Library with "SerialFlashFile _file" with the commands of the serialflash Library.
As said, it does work for around a minute but then crashes because of no more free RAM - it is consuming more RAM with every sample it is playing.
This problem haunts me for half of an year now and i tried everything i can think of - but so far no progress.
I would be very glad if someone more experienced would have a look what is going wrong.
My complete code is on
https://codeberg.org/positionhigh/MicroDexed-touch
which is a continuation (or hopefully in the future could be the base for a next generation) of
https://codeberg.org/dcoredump/MicroDexed
On that version, in the past, we made everything sample related in PROGMEM only, so this particular problem does not exist there.
Many thanks in advance.
Last edited: