
Originally Posted by
defragster
From quoted linked post:
Hi all,
please let me know if I'd better start a new post instead of writing here...
I went on with my tests, and wish to share the (even partial) result:
- copying .raw audio files from SD to Flash chip: works fine
- creating an example for playing a .raw audio file from LittleFS: ok works fine
- comparing the read-time reading audio files, using traditional SerialFlash solution and LittleFS file system.
This is the sketch using LittleFS, main code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>
#include "play_serialflash_raw_LittleFS.h"
AudioPlaySerialflashRaw_LittleFS playFlash;
AudioOutputI2S audio_out;
AudioConnection patchCord1(playFlash, 0, audio_out, 0);
AudioConnection patchCord2(playFlash, 0, audio_out, 1);
AudioControlSGTL5000 board;
void setup()
{
board.enable();
board.volume(0.2);
AudioMemory(5);
}
void loop()
{
playFlash.play("41.raw");
delay(10000);
}
AudioPlaySerialflashRaw_LittleFS.h
Code:
#ifndef play_serialflash_raw_LittleFS_h_
#define play_serialflash_raw_LittleFS_h_
#include "Arduino.h"
#include <AudioStream.h>
#include "LittleFS.h"
class AudioPlaySerialflashRaw_LittleFS : public AudioStream
{
public:
AudioPlaySerialflashRaw_LittleFS(void) : AudioStream(0, NULL)
{
begin();
}
void begin(void);
bool play(const char *filename);
void stop(void);
bool isPlaying(void) { return playing; }
uint32_t positionMillis(void);
uint32_t lengthMillis(void);
virtual void update(void);
private:
LittleFS_SPIFlash myfs; // ha i metodi di LittleFS che ha i metodi di FS
File rawfile; // SerialFlashFile rawfile;
uint32_t file_size;
volatile uint32_t file_offset;
volatile bool playing;
};
#endif
AudioPlaySerialflashRaw_LittleFS.cpp
Code:
#include <Arduino.h>
#include "play_serialflash_raw_LittleFS.h"
#include "spi_interrupt.h"
void AudioPlaySerialflashRaw_LittleFS::begin(void)
{
playing = false;
file_offset = 0;
file_size = 0;
}
bool AudioPlaySerialflashRaw_LittleFS::play(const char *filename)
{
stop();
AudioStartUsingSPI();
// rawfile = SerialFlash.open(filename);
// if (!rawfile)
if(!myfs.begin(6))
{
Serial.println("unable to access Flash");
AudioStopUsingSPI();
return false;
}
rawfile = myfs.open(filename);
if(!rawfile)
{
Serial.println("unable to access file");
AudioStopUsingSPI();
return false;
}
file_size = rawfile.size();
file_offset = 0;
//Serial.println("able to open file");
playing = true;
return true;
}
void AudioPlaySerialflashRaw_LittleFS::stop(void)
{
__disable_irq();
if (playing)
{
playing = false;
__enable_irq();
rawfile.close();
AudioStopUsingSPI();
}
else
{
__enable_irq();
}
}
void AudioPlaySerialflashRaw_LittleFS::update(void)
{
unsigned int i, n;
audio_block_t *block;
unsigned long T0;
int time_lap;
// only update if we're playing
if (!playing)
return;
// allocate the audio blocks to transmit
block = allocate();
if (block == NULL) return;
if (rawfile.available())
{
T0 = micros();
n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES*2);
time_lap=micros()-T0;
file_offset += n;
for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++)
{
block->data[i] = 0;
}
transmit(block);
Serial.println(time_lap);
}
else
{
rawfile.close();
AudioStopUsingSPI();
playing = false;
}
release(block);
}
#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592
uint32_t AudioPlaySerialflashRaw_LittleFS::positionMillis(void)
{
return ((uint64_t)file_offset * B2M) >> 32;
}
uint32_t AudioPlaySerialflashRaw_LittleFS::lengthMillis(void)
{
return ((uint64_t)file_size * B2M) >> 32;
}
where this part of code allows to measure the reading performance:
Code:
time_lap=micros()-T0;
file_offset += n;
for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++)
{
block->data[i] = 0;
}
transmit(block);
Serial.println(time_lap);
Now, using a T4.1@600MHz, and AUDIO_BLOCK_SAMPLES = 128, if I compare the reading performance of the previous code, with a similar example which uses AudioPlaySerialflashRaw:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>
AudioPlaySerialflashRaw playFlash;
AudioOutputI2S audio_out;
AudioConnection patchCord1(playFlash, 0, audio_out, 0);
AudioConnection patchCord2(playFlash, 0, audio_out, 1);
AudioControlSGTL5000 board;
void setup()
{
board.enable();
board.volume(0.2);
AudioMemory(5);
SerialFlash.begin(6);
}
void loop()
{
playFlash.play("41.raw");
delay(10000);
}
the update() time in microseconds is:
AudioPlaySerialflashRaw example:
Code:
50
50
50
50
50
50
50
50
50
50
50
...
... and so on
AudioPlaySerialflashRaw_LittleFS example:
Code:
77
78
696
78
77
78
77
78
77
78
77
78
77
78
77
78
77
78
773
78
77
78
77
78
77
78
77
78
78
78
78
78
78
78
696
78
78
78
This report shows that with LittleFS the reading time is 55% higher for 15 cycles, and after that (should be after 4KB of data) the next cycle is 10 times longer; for my application, where audio polyphony is up to 16, this slow reading time (maybe due to some "jumps" among sectors??) is incompatible