Play RAW from Serial Flash

Status
Not open for further replies.
Frank,

Oh ok. That helps a lot! I have never used it and dont have any flash chips yet. So havent tested yet.

Thank you!
 
Frank,

Where do I find the required "flash_spi.h" file?
https://forum.pjrc.com/threads/27409-Play-RAW-from-Serial-Flash?p=61996&viewfull=1#post61996

3 Minutes ago I updated the flashingtool. The output is as follows:
Code:
W25Q128FV Serial Flasher
Initializing SD card...done.

201159~1.RAW                    182271 Bytes
82583_~1.RAW                    158463 Bytes
86334_~1.RAW                    75775 Bytes
86773_~1.RAW                    1622527 Bytes
102790~1.RAW                    99327 Bytes
171104~1.RAW                    43007 Bytes
P2.RAW                  207103 Bytes
                        7 File(s), 2388473 Bytes
Flash Status: 0x0, ID:0xEF,0x40,0x18,0x0  is ok.
File(s) fit(s) in serial flash, 14388743 Bytes remaining.

Check flash content: Verify.
1. Verifying "201159~1.RAW" at position: 0x0000000...ok.
2. Verifying "82583_~1.RAW" at position: 0x002C800...ok.
3. Verifying "86334_~1.RAW" at position: 0x0053300...ok.
4. Verifying "86773_~1.RAW" at position: 0x0065B00...ok.
5. Verifying "102790~1.RAW" at position: 0x01F1D00...ok.
6. Verifying "171104~1.RAW" at position: 0x020A100...ok.
7. Verifying "P2.RAW" at position: 0x0214900...ok.
Flash content ok. Nothing to do.
Ready.
Copy'n paste:

const int SPIFlash[7] = {
                0x0000000,  //"201159~1.RAW"
                0x002C800,  //"82583_~1.RAW"
                0x0053300,  //"86334_~1.RAW"
                0x0065B00,  //"86773_~1.RAW"
                0x01F1D00,  //"102790~1.RAW"
                0x020A100,  //"171104~1.RAW"
                0x0214900}; //"P2.RAW"

const char SPIFlashFilename[7][13] = {
                "201159~1.RAW",
                "82583_~1.RAW",
                "86334_~1.RAW",
                "86773_~1.RAW",
                "102790~1.RAW",
                "171104~1.RAW",
                "P2.RAW"};

So you can copy&paste...
 
Last edited:
I dont care how they are stored. I just need to know which ones are what so I can apply my code to finding them based on user selection.


Most of your questions will be answered by experimentation or reading the thread. :)
SPI-FLASH is attached to this very thread earlier on.

When you "upload" the samples to the FLASH-ROM, the upload process provides a memory position the sample is stored at. You can store this in a variable array if you like.

BUT

This memory position and your uploaded samples will persist even after power is cycled. Your variables will not.

It is also a slow process loading the samples into the flash, not something you want to do every time you boot up.

SO

until now we had to note this address down and hard code it into the software as a const _After_ first uploading it. Thereafter we could use the samples without copying them from the SD card everytime.

In addition, Frank has delivered an update which now means this code can be copied and pasted from the serial output of the flashing tool eg:

Code:
const int SPIFlash[7] = {
                0x0000000,  //"201159~1.RAW"
                0x002C800,  //"82583_~1.RAW"
                0x0053300,  //"86334_~1.RAW"
                0x0065B00,  //"86773_~1.RAW"
                0x01F1D00,  //"102790~1.RAW"
                0x020A100,  //"171104~1.RAW"
                0x0214900}; //"P2.RAW"

const char SPIFlashFilename[7][13] = {
                "201159~1.RAW",
                "82583_~1.RAW",
                "86334_~1.RAW",
                "86773_~1.RAW",
                "102790~1.RAW",
                "171104~1.RAW",
                "P2.RAW"};

Ultimately the SPI flash will be afforded a filesystem preventing the need for this temporary workaround. But until then, this is how you do it.
 
i was just thinking it shouldn't be too difficult (even for me) to re-write the flash-tool to basically put that information at 0x00 and leave it at that. ie total filecount, position and filename. (personally, i'm ok with 8.3 names, so that would consume about fnct * 12 bytes [4 adr + 8 name] + 2 bytes [fcnt]; after that, the audio data starts).

as long as you don't allow for mix formats, that'll be ok for scenarios where you want to update the flash without having to rewrite the program. (my own scenario basically is this: update the flash from sd card: push button X when powering up the teensy. if pushed, run the flash-tool. write above information into the flash so the program can generate a list with valid addresses and corresponding names for the/a display).
 
Yes, there's an ongoing discussion in this thread:https://forum.pjrc.com/threads/27465-SPI-Flash-Allocation-Table
It's indeed not vry complex, but we want a general solution, because the SPIFlash can be used for more than audio.
From my point of view (and if one uses it only for audio (mp3 works too) ), these consts (and perhaps a lookup-mechanism that translates a filename to address) are sufficiant.
But i'm open for other ideas! Perhaps we can realize it... Plus: It's open source..

Yes, long filenames: I'm not familar with these arduino-libs - my interests are "low-level" stuff on register-level or things that are missing for teensy or arduino (like aac/mp3/flac).
So.. the simple truth is: i dont know how to add it :) And i don't want to read tons of documentation (is there any ? :) ) for this "high-level" stuff. If somebody knows how to add long-filename-support: Can you help ? :)
 
Last edited:
Thanks for the info guys!

Curious, how long do you think it would take to flash one file about 100 - 200kb?

What if the the files stay on the SD card that the user selects from via a menu or whatever, and once selected, and only that file is pulled from the SD card and placed in flash.

We then only read from the flash when playing the audio so its quicker. Using the SD card as storage and a means for selecting the sample we want.
 
Well more than a second will be too long I think.

So saving my variables with the file location to flash wont be stored permanently?

Such as..

const unsigned int AudioSampleSnare = 0xF8A00;

Are you saying the value of AudioSampleSnare would change every time the device powers up?
 
That is not a variable it is a constant.

The flash rom sample offset will not change unless you wipe the flashrom and re upload it
 
Well more than a second will be too long I think.

how so? i don't think you're supposed to write to the flash when something time-critical is going on.

So saving my variables with the file location to flash wont be stored permanently?

flash storage is permanent. that'll be ok as long as your program is simple enough and/or you only have a fixed set of files and that's ok. if, however, for some reason the content of the flash is to be updated every now and then (say, you want a different drum kit), presently the user program has no way of knowing, as was pointed out above.


i just rewrote the flash tool a little bit so now it saves the address at 0x0+, so they can be extracted later. currently the file names are still messed up, but the addresses bit is working. it's not a big deal, but if it helps anyone, i can post it later...the output looks like so:


W25Q128FV Serial Flasher
Initializing SD card...done.

XX.RAW 8703 bytes
XXX.RAW 4607 bytes
XXXX.RAW 46335 bytes
XXXXX.RAW 72191 bytes
4 file(s): 131836 bytes
Pages consumed for file info: 1 page(s)
--> total: 132092 bytes

Flash Status: 0x0, ID:0xEF,0x40,0x18,0x0 is ok.
File(s) fit(s) in serial flash, 16645124 Bytes remaining.

Check flash content:
Verify.
Files on flash ? --> file #: no match

Erasing chip....
done.
-- > Flashing file # 1 : "XX.RAW" at file_position: 0x0000100 ...
-- > Flashing file # 2 : "XXX.RAW" at file_position: 0x0002300 ...
-- > Flashing file # 3 : "XXXX.RAW" at file_position: 0x0003500 ...
-- > Flashing file # 4 : "XXXXX.RAW" at file_position: 0x000EA00 ...

File info (1 page(s)):

-- > Flashing info page # 1 (of 1) at file_position: 0x0000000 ...

done.

Extract file info:
-- > found 4 file(s): ok
-- > file_adr[0] = 0x0000100 ......
-- > file_adr[1] = 0x0002300 ......
-- > file_adr[2] = 0x0003500 ......
-- > file_adr[3] = 0x000EA00 ......

done.
Ready.
 
Awesome!

The reason a second would be too long when selecting a sample to use, is that the user will be wanting to hear the sample selection right away. They wont hear anything if the file hasnt been written to the flash quick enough. So I think the hard coding route will be just fine. Right now Im only using like 150 samples. So that wont be too bad to put into constants.
 
Because then Id have to setup WAV and Flash player objects instead of just flash player objects. I want to keep the audio playing fast as possible.
 
You only need one wav player object to preview samples, you can send any wav file to the same wav player object.

By wav player object I mean playWav from SDCard. You should preview samples straight off the SDCard.
 
fwiw, here's a variation on the flash tool:

https://github.com/mxmxmx/eurotrash/blob/master/soft/flash_pseudo_sys/flash_pseudo_sys.ino

it's very simple, basically it writes the addresses and (part of) the filenames* to 0x0 and reads it out again:

byte 0/1 : file count
remainders: 12-byte packets: adr + filename [4 bytes / 8 bytes]

i haven't really tested what happens if you flash more than 21 files or so, in which case that'll be two pages for the file information, but i guess it should be fine.

Code:
Flash Status: 0x0, ID:0xEF,0x40,0x18,0x0  is ok.
File(s) fit(s) in serial flash, 16368395 Bytes remaining.

Check flash content: 
Verify.
Files on flash ? --> # 11 file(s): ok 
1. Verifying "XX.RAW" at file_position: 0x0000100...ok.
2. Verifying "XXX.RAW" at file_position: 0x0011B00...ok.
3. Verifying "XXXX.RAW" at file_position: 0x0012D00...ok.
4. Verifying "XXXXX.RAW" at file_position: 0x001E200...ok.
5. Verifying "XXXXXX.RAW" at file_position: 0x002FC00...ok.
6. Verifying "Z.RAW" at file_position: 0x0030E00...ok.
7. Verifying "ZZZ.RAW" at file_position: 0x0042800...ok.
8. Verifying "ZZZZ.RAW" at file_position: 0x004DD00...ok.
9. Verifying "X.RAW" at file_position: 0x004EF00...ok.
10. Verifying "ZZ.RAW" at file_position: 0x0051100...ok.
11. Verifying "XXXXXXXX.RAW" at file_position: 0x0052300...ok.

Extracting file info:
-- > found 11 file(s): ok 
xx       -- > file_adr[0] = 0x0000100 ......
xxx      -- > file_adr[1] = 0x0011B00 ......
xxxx     -- > file_adr[2] = 0x0012D00 ......
xxxxx    -- > file_adr[3] = 0x001E200 ......
xxxxxx   -- > file_adr[4] = 0x002FC00 ......
z        -- > file_adr[5] = 0x0030E00 ......
zzz      -- > file_adr[6] = 0x0042800 ......
zzzz     -- > file_adr[7] = 0x004DD00 ......
x        -- > file_adr[8] = 0x004EF00 ......
zz       -- > file_adr[9] = 0x0051100 ......
xxxxxxxx -- > file_adr[10] = 0x0052300 ......

done.
Ready.

(* i just need the filename for a display, so this is why i get rid of the extension and fill everything up with blank space)
 
With filextensions, this could be used for more fileformats :)

there's a #define, MAX_LEN which gives the max. length of the filename. i haven't tried, but changing that to something larger (it's 0x8 now), and leaving out the line where it says pseudo_file_sys[slot] = makenice(tmp[j], _EXT); should then include the file-extension.
 
fwiw, here's a variation on the flash tool:

Thank you!! I will be implementing this and FIFO playback mods just as soon as a I've got to the bottom of some random crashing teensy issues. Won't even let me implement a bounce without hanging, and a fully working metro setup suddenly started freezing the CPU.

There is always a reason, but it might take me some time to find it......

Hang on....surely i'm not out of RAM......i'll have a look. I'm only querying the audio library at the moment. sorry, brain dump.......
 
i haven't really tested what happens if you flash more than 21 files or so, in which case that'll be two pages for the file information, but i guess it should be fine.

ok, i just ran a further few tests using more files and indeed there was an uint8_t, where there should have been a uint16_t ... but should be working now. here's a/the output from extract(); --


Code:
Flash Status: 0x0, ID:0xEF,0x40,0x18,0x0  is ok.

Check flash content: 

Extracting file info:
-- > found 26 file(s): ok 
xx       -- > file_adr[0] = 0x0000200 ......
xxx      -- > file_adr[1] = 0x0011C00 ......
xxxx     -- > file_adr[2] = 0x0012E00 ......
xxxxx    -- > file_adr[3] = 0x001E300 ......
xxxxxx   -- > file_adr[4] = 0x002FD00 ......
ooo      -- > file_adr[5] = 0x0030F00 ......
oooo     -- > file_adr[6] = 0x0033100 ......
oo       -- > file_adr[7] = 0x0034300 ......
x        -- > file_adr[8] = 0x0045D00 ......
o        -- > file_adr[9] = 0x0047F00 ......
ooooo    -- > file_adr[10] = 0x0059900 ......
oooooo   -- > file_adr[11] = 0x006B300 ......
xxxxxxxx -- > file_adr[12] = 0x006C500 ......
oooooooo -- > file_adr[13] = 0x007DF00 ......
zz       -- > file_adr[14] = 0x008F900 ......
zzz      -- > file_adr[15] = 0x00A1300 ......
zzzzz    -- > file_adr[16] = 0x00AC800 ......
yyyyy    -- > file_adr[17] = 0x00ADA00 ......
zzzz     -- > file_adr[18] = 0x00BF400 ......
y        -- > file_adr[19] = 0x00C1600 ......
yyy      -- > file_adr[20] = 0x00D3000 ......
yyyy     -- > file_adr[21] = 0x00D4200 ......
qqq      -- > file_adr[22] = 0x00E5C00 ......
qqqq     -- > file_adr[23] = 0x00E7E00 ......
usw      -- > file_adr[24] = 0x00E9000 ......
www      -- > file_adr[25] = 0x00EA200 ......

done.
 
I read this thread with interest because I too want to be able to play sounds as fast as possible after one another......
What are you trying to achieve that PlaySDwav library wont do.....
Since Pauls fix of PlaySDwav last week I am able to play wav files direct from SD completely tight together, no gaps and repeat them as quickly as I want.
I can play durations down to 8 or 9 ms tight after one another no gaps and I have to Zoom in on a recording of the waveform to actually see it because the sounds are so short I can hardly hear them. What more would one achieve by playing from Serial Flash.??
 
The access is faster, you can play more files parallel (polyphonic). I' did not test how many, but according to Pensive at minimum 8 (@120MHz, 16 BIT 44kHz) for the variant without SPIFifo.
 
The access is faster, you can play more files parallel (polyphonic). I' did not test how many, but according to Pensive at minimum 8 (@120MHz, 16 BIT 44kHz) for the variant without SPIFifo.

Yes, on my little setup my polyphony from the SPI flash was just short of double that from the SDcard. so a 90% improvement in polyphony moving from SDcard to SPI-flash. Not least the resolution of other issues I was experiencing related to the SD library saturating my CPU time with all the delicacy of Thor's mallet.
 
Status
Not open for further replies.
Back
Top