Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 18 of 18

Thread: Staying awake while playing a WAV file

  1. #1
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26

    Staying awake while playing a WAV file

    I'm struggling with the interaction of the Audio and Snooze libraries. Most applications seem to want the processor to perform other tasks while Audio is playing a WAV file. But those other tasks include going to sleep, which of course stops play.

    After studying the examples, I thought the ability of Audio to play while doing something else lay in the lines:
    Code:
      while (playWav1.isPlaying()) {
        }    // Wait for the file to finish playing.
    So I figured that this was a control issue. I tried moving my play routine (including the above lines) into a function, thinking that control would not pass back to the main loop (containing the sleep command) until the function was complete. That didn't work, the processor still went to sleep mid-sentence, as it were. So I assume the multi-tasking ability is somehow built into the Audio library?

    All I want to do is to play the file from beginning to end, then go to sleep until woken by an alarm or timer. Is there a way to do this, please?

  2. #2
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Forgive me for bumping this, but having tried all kinds of workarounds, I am really stuck.

  3. #3
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,456
    I do not know well the snooze library, but there is for sure a way to keep it awake with a command which you'd insert between
    Code:
    while (playWav1.isPlaying()) {
    and
    Code:
    }    // Wait for the file to finish playing.

  4. #4
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    961
    That should work, how much more does it play after that?

  5. #5
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Thanks, both, for looking at this.

    What kind of command would you insert?

    The options I can see are a counter or a timer. I need to play the whole file, and file length is variable depending which file it is. I can implement the timer option by adding in a list of file lengths (durations) but for future flexibility I'd rather the playing/stopping was automatic irrespective of the file provided. The counter would presumably use millis() in a set of loops?

  6. #6
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    961
    I would just use one file and you can use elapsedMillis for the timing.

  7. #7
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Thanks all for those suggestions.

    I had thought that an empty
    Code:
    while(1){}
    loop would hold up the code indefinitely - and come to think of it, I've used it like that when de-bugging. But anyway, I've now tried inserting time-wasting commands to occupy the processor. In doing so, I've discovered that
    Code:
    playWav1.isPlaying()
    returns 0, and never 1. Similarly,
    Code:
    playWav1.positionMillis()
    always returns 0.

    So it begins to look as though my difficulty in staying awake may have nothing to do with Snooze. The code I've used, only very slightly adapted from the WavFilePlayer example Paul Stoffregen provides, and with no Snooze features, is below. It plays the file for as long as the delay() function in the main loop allows. Without the delay function it doesn't play. I'd be really grateful if anyone can spot where the mistake lies.

    Code:
    // Simple WAV file player example
    //
    // Three types of output may be used, by configuring the code below.
    //
    //   1: Digital I2S - Normally used with the audio shield:
    //         http://www.pjrc.com/store/teensy3_audio.html
    //
    //   2: Digital S/PDIF - Connect pin 22 to a S/PDIF transmitter
    //         https://www.oshpark.com/shared_projects/KcDBKHta
    //
    //   3: Analog DAC - Connect the DAC pin to an amplified speaker
    //         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
    //
    // To configure the output type, first uncomment one of the three
    // output objects.  If not using the audio shield, comment out
    // the sgtl5000_1 lines in setup(), so it does not wait forever
    // trying to configure the SGTL5000 codec chip.
    //
    // The SD card may connect to different pins, depending on the
    // hardware you are using.  Uncomment or configure the SD card
    // pins to match your hardware.
    //
    // Data files to put on your SD card can be downloaded here:
    //   http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
    //
    // This example code is in the public domain.
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    AudioPlaySdWav           playWav1;
    // Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
    AudioOutputI2S           audioOutput;
    //AudioOutputSPDIF       audioOutput;
    //AudioOutputAnalog      audioOutput;
    AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
    AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);
    AudioControlSGTL5000     sgtl5000_1;
    
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN    10
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    
    // Use these with the Teensy 3.5 & 3.6 SD card
    //#define SDCARD_CS_PIN    BUILTIN_SDCARD
    //#define SDCARD_MOSI_PIN  11  // not actually used
    //#define SDCARD_SCK_PIN   13  // not actually used
    
    // Use these for the SD+Wiz820 or other adaptors
    //#define SDCARD_CS_PIN    4
    //#define SDCARD_MOSI_PIN  11
    //#define SDCARD_SCK_PIN   13
    
    void setup() {
      Serial.begin(9600);
    
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(8);
    
      // Comment these out if not using the audio adaptor board.
      // This may wait forever if the SDA & SCL pins lack
      // pullup resistors
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
    
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        // stop here, but print a message repetitively
        while (1) {
          Serial.println("Unable to access the SD card");
          delay(500);
        }
      }
    }
    
    void playFile(const char *filename)
    {
      // Start playing the file.  This sketch continues to
      // run while the file plays.
      playWav1.play(filename);
    
      // A brief delay for the library to read WAV info
      delay(5);
    
      int temp=playWav1.isPlaying();
      Serial.print("playWav1.isPlaying = ");
      Serial.println(temp);
      Serial.print("Playing, now at ");
      Serial.println(playWav1.positionMillis());
    
      temp=playWav1.isPlaying();
      Serial.print("playWav1.isPlaying = ");
      Serial.println(temp);
      // Simply wait for the file to finish playing.
      while (playWav1.isPlaying() == 1) {
      }
    
    }
    
    
    void loop() {
      playFile("SDTEST1.WAV");  // filenames are always uppercase 8.3 format
      delay(5000000);
    }

  8. #8
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,084
    works for me
    I played your sketch successfully with and without the delay(5000000); So i'm not sure why it's not working for you. I tested on T3.5 using 1.8.8/1.47-beta2 with audio shield and using uSD on shield. Sketch prints
    Code:
    playWav1.isPlaying = 1
    Playing, now at 5
    playWav1.isPlaying = 1
    then prints it again when the WAV file finishes .... SDTEST1.WAV take about 95 seconds to play. (lengthMillis 95128)

    what Teensy are you using? version of IDE and of Teensyduino?

    maybe your WAV file is corrupted?? SD lib's listfiles shows
    Code:
    SDTEST1.WAV		16787550
    SDTEST2.WAV		16425698
    SDTEST3.WAV		13617358
    SDTEST4.WAV		17173152
    https://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
    Last edited by manitou; 05-22-2019 at 07:42 PM.

  9. #9
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Quote Originally Posted by manitou View Post
    works for me
    I played your sketch successfully with and without the delay(5000000); So i'm not sure why it's not working for you. I tested on T3.5 using 1.8.8/1.46-beta2 with audio shield and using uSD on shield. Sketch prints
    Code:
    playWav1.isPlaying = 1
    Playing, now at 5
    playWav1.isPlaying = 1
    then prints it again when the WAV file finishes .... SDTEST1.WAV take about 95 seconds to play.

    what Teensy are you using? version of IDE and of Teensyduino?

    maybe your WAV file is corrupted??
    Thanks so much for trying this. It's great but puzzling that the same code works for you.

    I'm using a Teensy 3.2, Arduino IDE 1.8.9. Not sure which version of Teensyduino - how do I tell? I installed it on 24 April, installer file dated 23/4/2019.

    I suppose it is possible that the WAV filed is corrupted, although it plays OK with that long delay, as do other files on the SD card, including my own WAV files.

    I noticed that Paul Stoffregen has at least partially re-written the SD library (here), though I'm not clear why. Should I be using that version?
    Last edited by snusmumriken; 05-22-2019 at 08:02 PM.

  10. #10
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,084
    I just ran it with no delay() on T3.2 with 1.8.9/1.47-beta2. you can find the Teensyduino version by clicking on Help in the teensyloader window and then click on About.

    maybe a solder problem? can you provide a photo of your Teensy and shield?

  11. #11
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,084
    Quote Originally Posted by snusmumriken View Post

    I noticed that Paul Stoffregen has at least partially re-written the SD library (here), though I'm not clear why. Should I be using that version?
    That should be the SD lib installed with Teensyduino. make sure you don't have a local copy of an older SD lib or audio lib....

  12. #12
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Quote Originally Posted by manitou View Post
    I just ran it with no delay() on T3.2 with 1.8.9/1.47-beta2. you can find the Teensyduino version by clicking on Help in the teensyloader window and then click on About.

    maybe a solder problem? can you provide a photo of your Teensy and shield?
    Many thanks. I'll do both those things, but it will have to be tomorrow (London time) as I've left the Teensy in my bag at work (lunchtime hobbyist!). I do have photos of the Teensy and audio shield together, but I have since mounted the whole assembly on Veroboard with a 5V supply from battery via a voltage regulator , and an amp. As the batteries are physically disconnected when the Teensy is connected via USB, those components are unpowered, so I'm not sure how the output from that code would be affected.

  13. #13
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Quote Originally Posted by manitou View Post
    That should be the SD lib installed with Teensyduino. make sure you don't have a local copy of an older SD lib or audio lib....
    OK, that might be an issue. I'll investigate. Thanks.

  14. #14
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,084
    There also a chance the uSD card is misbehaving. Do you have another uSD card that you can try?

  15. #15
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26

    Smile Possibly solved, fingers crossed

    I am running the Arduino IDE as a portable installation from a pen drive. There is an SD library in F:\Arduino portable IDE\hardware\teensy\avr\libraries. There is another SD library in F:\Arduino portable IDE\libraries. Is this likely to cause a problem? Doesn't Teensyduino look by default in its own library folder? I do use Arduino Uno and Nano, so I am reluctant to delete/disable the other copy if it might cause other problems with those boards.

    In any case, today I tried the code posted above with a freshly formatted SD card, and it played the SDTEST1.WAV file with and without the delay(500000). The only fault was that the Serial output was
    Code:
    playWav1.isPlaying = 1
    Playing, now at 5
    playWav1.isPlaying = 1
    playWav1.isPlaying = 1
    Playing, now at 5
    playWav1.isPlaying = 1
    playWav1.isPlaying = 1
    Playing, now at 5
    etc
    I moved the Serial.print commands inside the while() loop, and playWav1.positionMillis() then now updated correctly.

    So I've then gone back to the first SD card, and deleted everything except the .WAV files. The .WAV files now play without that delay(500000). However, the Serial output still shows that the playWav1 parameters are not updating:
    Code:
    playWav1.isPlaying = 0
    Playing, now at 0
    playWav1.isPlaying = 0
    playWav1.isPlaying = 0
    Playing, now at 0
    playWav1.isPlaying = 0
    playWav1.isPlaying = 0
    Playing, now at 0
    playWav1.isPlaying = 0
    etc
    I've then re-formatted the first SD card, and copied my .WAV files onto it. The code plays these and now the serial output shows the parameters are updating correctly. https://forum.pjrc.com/images/smilies/smile.png

    So the problem was either corrupted WAV files or a mis-behaving SD card. I'm left wondering about two things:

    1) Those files I deleted from the faulty card. They were .CSV files written to the card by an extended version of the code which also logged the RTC time at which the .WAV files were played. That file-writing code is tried and tested by me over several years of use in the field with Arduino Unos. File names are the correct 8.3 format. The first 8 characters are numeric (actually the date + file number, e.g. 19052301.CSV), but that has not caused any issue previously. Files were opened, written to, and closed again before the command to play the .WAV file. Is it conceivable that problems are caused just by just frequently writing to the same SD card that the audio files are on?

    2) In developing the extended code with Snooze functions in it, I have had to reboot the Teensy many times. I guess this could easily have corrupted the .WAV files? I will now prepare several SD cards from scratch and replace them when I run into problems.

    Anyway, I think I'm on the road again, at least until I hit the next problem. Many thanks to all for your tips.

  16. #16
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Apologies for re-opening this thread, but after some stops and starts, I have to conclude that I am basically stuck on the same problem.

    I have certain WAV files that play nicely on my device (Teensy 3.2 + audio shield - see earlier posts for details). These include the SDTEST#.WAV example files. I have others that play on my PC, but will not (ever) play on the Teensy even when newly copied onto a freshly formatted microSD card. An example is available here. I'd be really grateful if someone else would try playing this file! It should sound like a rodent squealing. The file plays fine off the SD card through my PC, but not on the Teensy.

    In my code, sound files are played after an interval determined by a Snooze alarm function. My code is writing an event log to the SD card, recording (just before) the start and (just after) the end of every 'play' event. The log file is closed immediately after writing to it. This record-to-log function is not in itself a problem: it does not interfere with the "successful" sound files. So I'm certain I can rule that out.

    What I have noticed is that the "unsuccessful" files sometimes start to play, but cut out within a couple of seconds. At this point the Arduino IDE tells me that the Teensy board is missing, which suggests that it has gone to sleep. It should not go to sleep until after the WAV file has finished playing and the log file has recorded the end of the play event. With these 'bad' files, the log file records the end of play within milliseconds of starting (whereas with successful files it is several minutes later, as it should be, depending on the length of the recording).

    Please can anyone suggest what might be wrong with certain of my WAV files that makes the device think they have ended almost as soon as they have begun? Can it be something to do with sampling rate? And if so, is it possible to adjust this?

  17. #17
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,084
    maybe your non-playing WAV files are not formatted correctly. here are parameters for Paul's WAV files
    SDTEST1.WAV: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz

    view properties with audacity or your favorite audio tool. you may need to reformat your PC WAV files to match Teensy audio required encoding. audacity can do such conversions

  18. #18
    Member
    Join Date
    Apr 2019
    Location
    UK
    Posts
    26
    Quote Originally Posted by manitou View Post
    maybe your non-playing WAV files are not formatted correctly. here are parameters for Paul's WAV files
    SDTEST1.WAV: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz

    view properties with audacity or your favorite audio tool. you may need to reformat your PC WAV files to match Teensy audio required encoding. audacity can do such conversions
    Yes, that's done the trick. The 'bad' files were on a much higher sampling rate. Not used Audacity before!

    Very many thanks for your help.

Posting Permissions

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