Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 15 1 2 3 11 ... LastLast
Results 1 to 25 of 358

Thread: Play RAW from Serial Flash

  1. #1
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774

    Play RAW from Serial Flash

    Hi,

    https://github.com/FrankBoesing/Teen...romSerialFlash
    EDIT: Please take look at play_serialflash.h for some configuration-options

    In the utility-folder you will find a zipfile which contains a tool "wav2trw.exe", similar to wav2sketch, which converts wavefiles to raw-format with additional 4 byte header.
    The default is to convert to u-law format, this need only 50% space.
    If you want 16-Bit CD-Quality, add the parameter "-16" (call with "wav2trw -16") or double-click the batchfile
    (Edit: The old name was wav2raw)

    You can upload the files with this Sketch:https://github.com/FrankBoesing/Ardu...sd2serialflash

    There's a little thing that can be optimized for samplingrates < 44kHz: The Buffer should be allocated dynamically, not fixed size. But I accept pullrequests... :-) This should be easy.
    Edit: Done

    Paul, if you want, you can take it for Teensyduino121.
    Maybe one of the other users can do some tests..

    My little testsketch ( I have no buttons!) :
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    //#include <Bounce.h>
    #include <play_serialflash.h>
    
    //ULAW:
    const unsigned int AudioSampleSnare = 0x16900;				//82583__kevoy__snare-drum-4.raw
    const unsigned int AudioSampleTomtom =  0x2A000;			//86334__zgump__tom-0104.raw
    const unsigned int AudioSampleHihat = 0xFAB00;			//102790__mhc__acoustic-open-hihat2.raw
    const unsigned int AudioSampleKick =  0x106D00;			//171104__dwsd__kick-gettinglaid.raw
    const unsigned int AudioSampleGong = 0x33500;			//86773__juskiddink__gong.raw
    const unsigned int AudioSampleCashregister = 0x0;	//201159__kiddpark__cash-register.raw
    
    /*
    16 Bit RAW
    const unsigned int AudioSampleSnare = 0xF8A00;				//82583__kevoy__snare-drum-4.raw
    const unsigned int AudioSampleTomtom = 0;			//86334__zgump__tom-0104.raw
    const unsigned int AudioSampleHihat = 0xD0B00;			//102790__mhc__acoustic-open-hihat2.raw
    const unsigned int AudioSampleKick =  0xDCD00;			//171104__dwsd__kick-gettinglaid.raw
    const unsigned int AudioSampleGong = 0x9500;			//86773__juskiddink__gong.raw
    const unsigned int AudioSampleCashregister = 0xE2100;	//201159__kiddpark__cash-register.raw
    */
    
    // Create the Audio components.  These should be created in the
    // order data flows, inputs/sources -> processing -> outputs
    //
    AudioPlaySerialFlash    sound0;
    AudioPlaySerialFlash    sound1;  // six memory players, so we can play
    AudioPlaySerialFlash    sound2;  // all six sounds simultaneously
    AudioPlaySerialFlash    sound3;
    AudioPlaySerialFlash    sound4;
    AudioPlaySerialFlash    sound5;
    AudioMixer4        mix1;    // two 4-channel mixers are needed in
    AudioMixer4        mix2;    // tandem to combine 6 audio sources
    AudioOutputI2S     headphones;
    AudioOutputAnalog  dac;     // play to both I2S audio board and on-chip DAC
    
    // Create Audio connections between the components
    //
    AudioConnection c1(sound0, 0, mix1, 0);
    AudioConnection c2(sound1, 0, mix1, 1);
    AudioConnection c3(sound2, 0, mix1, 2);
    AudioConnection c4(sound3, 0, mix1, 3);
    AudioConnection c5(mix1, 0, mix2, 0);   // output of mix1 into 1st input on mix2
    AudioConnection c6(sound4, 0, mix2, 1);
    AudioConnection c7(sound5, 0, mix2, 2);
    AudioConnection c8(mix2, 0, headphones, 0);
    AudioConnection c9(mix2, 0, headphones, 1);
    AudioConnection c10(mix2, 0, dac, 0);
    
    // Create an object to control the audio shield.
    // 
    AudioControlSGTL5000 audioShield;
    /*
    // Bounce objects to read six pushbuttons (pins 0-5)
    //
    Bounce button0 = Bounce(0, 5);
    Bounce button1 = Bounce(1, 5);  // 5 ms debounce time
    Bounce button2 = Bounce(2, 5);
    Bounce button3 = Bounce(3, 5);
    Bounce button4 = Bounce(4, 5);
    Bounce button5 = Bounce(5, 5);
    */
    
    void setup() {
    /*
      // Configure the pushbutton pins for pullups.
      // Each button should connect from the pin to GND.
      pinMode(0, INPUT_PULLUP);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      pinMode(4, INPUT_PULLUP);
      pinMode(5, INPUT_PULLUP);
    */
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(10);
    
      // turn on the output
      audioShield.enable();
      audioShield.volume(0.5);
    
      // by default the Teensy 3.1 DAC uses 3.3Vp-p output
      // if your 3.3V power has noise, switching to the
      // internal 1.2V reference can give you a clean signal
      //dac.analogReference(INTERNAL);
    
      // reduce the gain on mixer channels, so more than 1
      // sound can play simultaneously without clipping
      mix1.gain(0, 0.4);
      mix1.gain(1, 0.4);
      mix1.gain(2, 0.4);
      mix1.gain(3, 0.4);
      mix2.gain(1, 0.4);
      mix2.gain(2, 0.4);
    }
    /*
    void loop() {
      // Update all the button objects
      button0.update();
      button1.update();
      button2.update();
      button3.update();
      button4.update();
      button5.update();
    
      // When the buttons are pressed, just start a sound playing.
      // The audio library will play each sound through the mixers
      // so any combination can play simultaneously.
      //
      if (button0.fallingEdge()) {
        sound0.play(AudioSampleSnare);
      }
      if (button1.fallingEdge()) {
        sound1.play(AudioSampleTomtom);
      }
      if (button2.fallingEdge()) {
        sound2.play(AudioSampleHihat);
      }
      if (button3.fallingEdge()) {
        sound3.play(AudioSampleKick);
      }
      if (button4.fallingEdge()) {
        sound4.play(AudioSampleGong);
      }
      if (button5.fallingEdge()) {
        sound5.play(AudioSampleCashregister);
      }
    
    }
    */
    void loop() {
    	sound4.play(AudioSampleGong);
    	delay(500);
    	sound0.play(AudioSampleSnare);
    	delay(200);
    	sound1.play(AudioSampleTomtom);
    	delay(100);
    	sound2.play(AudioSampleHihat);
    	delay(100);
    	sound3.play(AudioSampleKick);
    	delay(100);
    	
    	sound5.play(AudioSampleCashregister);
    	delay(8000);
    
    }
    regards,
    Frank
    Last edited by Frank B; 02-06-2015 at 09:28 PM.

  2. #2
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    neat!

    thanks for doing this!

    i only gave it a quick try, but it's working for me. definitely faster than SDraw/SDwav. here's a drum sample from teensy vs a 808 bass drum, triggered from the same pulse. the teensy is lagging just about 5 ms behind:

    Click image for larger version. 

Name:	Screen Shot 2014-12-30 at 23.45.44.jpg 
Views:	202 
Size:	40.7 KB 
ID:	3212




    edit: for the sake of completeness, here's SD_wav (playing 16 bit stereo) vs Flash_Raw vs a 808 (each): (ie, from top to bottom: Serial Flash, 808, 808, SD Wav)

    Click image for larger version. 

Name:	Screen Shot 2014-12-31 at 11.41.58.png 
Views:	171 
Size:	66.6 KB 
ID:	3229


    as you can see, the latency for Serial Flash is slightly better (~5 ms vs ~6 ms), presumably reflecting the 500-1500us until AudioPlaySdWav :: play returns.

    that's not really significant and pretty good in either case; looks as if improvements to latency will mostly come from interfacing with the API **




    **
    the code i used is fairly simplistic, basically:


    Code:
    void loop() {
    	
            if (LCLK) {
            sound0.play(0x0);
            LCLK = false; 
    	}

    where volatile uint8_t LCLK is set by an external interrupt. the trigger-pulse goes into a NPN transistor, which is attached to a gpio and pulls it low when it saturates.
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	Screen Shot 2014-12-31 at 11.27.19.jpg 
Views:	149 
Size:	56.1 KB 
ID:	3228  
    Last edited by mxxx; 12-31-2014 at 10:44 AM.

  3. #3
    Senior Member Pensive's Avatar
    Join Date
    Aug 2014
    Location
    Basingstoke, UK
    Posts
    552
    Awesome. Upgrading my project to flash as soon as possible!

    I'll redo my polyphony test first, this should give a good idea of cpu usage improvements.

    It also frees up the SDCard to either record the session or to play back sampled tracks like vocals

  4. #4
    Senior Member Pensive's Avatar
    Join Date
    Aug 2014
    Location
    Basingstoke, UK
    Posts
    552
    Forgot to mention on windows, audacity can save as a raw file if you prefer a gui.

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by Pensive View Post
    Forgot to mention on windows, audacity can save as a raw file if you prefer a gui.
    Hi, i just saw that there's a bug with 16BIT PCM. I'll look a this the next days..

    Audacity: Yes, but i choosed Pauls format, which has 4 Bytes (Format + Length) before the data.

  6. #6
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Hi,
    bugs are fixed, and there's a new wav2raw.exe Should work ok now ;-)
    Uses now SPI-Transactions, and the buffer is removed.

    Edit: Best speed should be at 120MHz, because of fastest SPI.
    Edit @mxxx: I think the 5 ms are because of update() which is at 2.9ms intervalls + the unknown time between these updates when the triggering occurs.
    Last edited by Frank B; 01-02-2015 at 01:48 PM.

  7. #7
    Junior Member
    Join Date
    Oct 2014
    Posts
    14
    This is really nice Frank, Danke.

    I wonder if it is possible to use a different chip of that family with more capacity, shouldnt be a problem if i understood the specs correctly.

    W25Q128FV W25Q256FV maybe?

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,691
    Frank, nice work on the SPI flash playing!

    I would like to ask you to consider a couple changes. Hopefully these aren't too much trouble?

    The main thing I'd like to request is reserving the first 4096 bytes of the flash for a simple allocation table. The details can be worked out later. At this early stage, the main concern is writing tools that avoid writing to the first 4k. Whatever format gets defined, we'll use 0xFF to mean unused.

    The other minor edit you might consider is calling AudioStartUsingSPI() and AudioStopUsingSPI(). These are implemented in spi_interrupt.h in the audio library. You can see example usage in play_sd_raw.cpp.


    Edit: I started a new thread to discuss the flash allocation table format.
    Last edited by PaulStoffregen; 01-07-2015 at 01:06 PM.

  9. #9
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by PaulStoffregen View Post
    The other minor edit you might consider is calling AudioStartUsingSPI() and AudioStopUsingSPI(). These are implemented in spi_interrupt.h in the audio library. You can see example usage in play_sd_raw.cpp.
    No problem. In the codecs, i use it..It looks like that i have forgotten it this time.. :-)
    For the 4096 reserved bytes: there's nothing to change in the player (ok, for the "FAT" later, mybe). And for the little sketch which loads the files into the spiflash, i can add a #define - switch.
    For the codecs (yes, they all can play from flash too), it's the same.

  10. #10
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by Relampago View Post
    This is really nice Frank, Danke.

    I wonder if it is possible to use a different chip of that family with more capacity, shouldnt be a problem if i understood the specs correctly.

    W25Q128FV W25Q256FV maybe?
    I don't know.
    But if the specs are the same, it should work!

  11. #11
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by Frank B View Post
    No problem. In the codecs, i use it..It looks like that i have forgotten it this time.. :-)
    Just updated.

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,691
    Does anyone make a larger chip in SOIC-8 package?

    The Winbond datasheet mentions only WSON-8, SOIC-16, and TFBGA-24.

  13. #13
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    Quote Originally Posted by PaulStoffregen View Post
    Does anyone make a larger chip in SOIC-8 package?

    The Winbond datasheet mentions only WSON-8, SOIC-16, and TFBGA-24.
    i can't be sure of course but everything above 128Mbit seems to be SOIC-16 (including W25Q256FV above).
    mouser for example now carries those: S25FL127S (Spansion), which seem to be pin compatible to the Winbond one. same thing though: 128Mb = SOIC-8; 256Mb/512Mb/1Gb = SOIC-16.

  14. #14
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    PJRC coud sell a shield with some of SOIC-16...
    Or a SD- shield with a "co-processor" (ARM) with SDIO.. maybe this makes more sense

  15. #15
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,691
    I ordered a couple of the Spansion S25FL127S part, for testing. At the moment, I believe I only have the Winbond ones.

    Maybe a future board could have the larger 16 pin footprint. Or maybe someone like Onehorse will make an add-on board and sell it via Tindie?

    Odds are good for larger sizes to eventually become available in SOIC-8 package. But as they move to smaller transistors for small dies, even larger ones are likely to appear on the market in those other packages.

  16. #16
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    I would buy such shields (ok, if shipping to germany is not too expensive, which is often a problem (from US) :-( )

  17. #17
    Junior Member
    Join Date
    Oct 2014
    Posts
    14
    I would buy such a board as well.

    Currently I have hard times to find someone selling those chips in Germany, @Frank where do you have it from, Digikey?

    I think the WSON8 chips can be soldered as well, at least i managed it some ages ago :-)

  18. #18
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    for the time being, 16MB isn't so bad, i'd say. at least for wavetables, that means considerable more space and then there's still the SD card (which, given the output is stereo, will probably be sufficient for many purposes. polyphony is nice, of course, but often you'd really need/want individual outputs per voice (well, in my view)).

    Or a SD- shield with a "co-processor" (ARM) with SDIO.. maybe this makes more sense
    how fast is SDIO? .. or what is it for? wouldn't some parallel SRAM / FSMC combination (and teensy 3++, assuming it has enough pins) make more sense?

    Currently I have hard times to find someone selling those chips in Germany
    yep, those are difficult to get around here. i got mine from alibaba (and shipped to Germany in < 2 weeks (see Frank's post below))
    Last edited by mxxx; 01-07-2015 at 09:14 PM.

  19. #19
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by Relampago View Post
    I would buy such a board as well.
    Currently I have hard times to find someone selling those chips in Germany, @Frank where do you have it from, Digikey?
    Ebay.. from china. Shipping took >6 weeks...

  20. #20
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by mxxx View Post
    how fast is SDIO? .. or what is it for? wouldn't some parallel SRAM / FSMC combination (and teensy 3++, assuming it has enough pins) make more sense?
    I not really sure if "SDIO" is the correct name. SD-Cards have two interfaces: SPI and 4-Bit parallel. The second allows the maximum speed (several MB/s).

    Im Mikrocontroller.net -forum gibts einen Thread dazu, die haben herausgefunden wie man diesen Modus in Software benutzen kann. Auf einem AVR. Vermutlich schafft man mit ARM ( und DMA?) mehr Speed... müsste mal jemand ausprobieren(Zaunpfahl). Aber ich habe zu viel mit anderen Projekten zu tun...
    Last edited by Frank B; 01-07-2015 at 09:24 PM.

  21. #21
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    Quote Originally Posted by Frank B View Post
    I not really sure if "SDIO" is the correct name. SD-Cards have two interfaces: SPI and 4-Bit parallel. The second allows the maximum speed (several MB/s).
    ah, that thing. verstehe. bzw, i see. looks like trouble in an open source/DIY context though. (also Hold/IO3 is tied to 3v3 on the audio adapter)

  22. #22
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    Quote Originally Posted by mxxx View Post
    ah, that thing. verstehe. bzw, i see. looks like trouble in an open source/DIY context though. (also Hold/IO3 is tied to 3v3 on the audio adapter)
    Maybe not with concentrating on reading only.. (no CRC-code?)
    Hmm..i think i have to buy another teensy (my existing are soldered & all pins used...)
    Just out of curiosity how fast reading could be. In Assembler.
    Last edited by Frank B; 01-09-2015 at 08:58 AM.

  23. #23
    Senior Member Pensive's Avatar
    Join Date
    Aug 2014
    Location
    Basingstoke, UK
    Posts
    552
    Quote Originally Posted by Frank B View Post
    Hi,
    Edit: Best speed should be at 120MHz, because of fastest SPI.
    That's handy - my teensy crashes after a while if i try 144Mhz 120Mhz is my sweet spot for performance and stability.

    Re: RAW, I'm using 44khz, 16bit mono RAW files exported straight from Audacity with no header, and it seems to be working "fine", I assume I'm losing a couple of bytes off the front, but it seems to be defaulting to playing correctly.

  24. #24
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    @Pensive: Luck...

    The header is:
    - 3 Byte Length Information (24 Bit)
    - 1 Byte Format Information:
    0x01: u-law encoded, 44100 Hz
    0x02: u-law encoded, 22050 Hz
    0x03: u-law encoded, 11025 Hz
    0x81: 16 Bit PCM, 44100 Hz
    0x82: 16 Bit PCM, 22050 Hz
    0x83: 16 Bit PCM, 11025 Hz
    All Mono.
    This is the same as Pauls format (used by wav2sketch), and his invention.
    Wav2raw (as wav2sketch) converts stereo to mono.
    Last edited by Frank B; 01-10-2015 at 09:47 PM.

  25. #25
    Senior Member Pensive's Avatar
    Join Date
    Aug 2014
    Location
    Basingstoke, UK
    Posts
    552
    That's pretty lucky, I have 16 of these samples which all play pretty well! It explains why a couple seem to cut off. None of them overshoot though.

    Better use wav2raw

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •