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

Thread: Multiple WAV files on SD card not working.

  1. #1
    Junior Member
    Join Date
    Jul 2021
    Posts
    14

    Multiple WAV files on SD card not working.

    Hello-
    I cobbled together this code on another thread and it basically does what I want. It works with 4 or 5 files, but i thought I could just add my own files...as many as I like...20 wav files...nothing very long or big in size. And it doesn't really work. It plays a couple of files but only sometimes. I also had a real hard time with SD cards. I had three and only one would work. Formatted to FAT32. These were SanDisk Ultra 32G. It wasn't until I switched to a Pioneer 16G that I got it to work. Is it something with the SD cards? the formatting? the WAV files? or is it the code?

    I thought I could just change the filenames and the wavnum and I could run a bunch of files....it only seems to work with the original 4 or 5 files.

    thanks, steve

    Code:
      #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Bounce.h>
    
    // create audio component objects
    AudioPlaySdWav           playWav1;           // SD card wav file player
    AudioInputI2S            audioInput;         // audio shield input, mic or line-in selectable
    AudioMixer4              mixer1;             // mixers to combine wav file and audio shield inputs
    AudioMixer4              mixer2;
    
    // Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
    AudioOutputI2S           audioOutput;
    //AudioOutputSPDIF       audioOutput;
    //AudioOutputAnalog      audioOutput;
    
    // wire up the interfaces between audio components with patch cords
    // mixer inputs
    AudioConnection          patchCord1(playWav1, 0, mixer1, 0);          // left  channels into mixer 1
    AudioConnection          patchCord2(audioInput, 0, mixer1, 1);
    
    AudioConnection          patchCord3(playWav1, 1, mixer2, 0);          // right channels into mixer 2
    AudioConnection          patchCord4(audioInput, 1, mixer2, 1);
    
    // mixer outputs
    AudioConnection          patchCord5(mixer1, 0, audioOutput, 0);
    AudioConnection          patchCord6(mixer2, 0, audioOutput, 1);
    
    // object to allow control of the SGTL5000 audio shield settings
    AudioControlSGTL5000     audioShield;
    
    // buttons and potentiometers
    #define pot0             A1
    #define pot1             A2
    #define pot2             A3
    #define button0          0
    #define button1          1
    #define button2          2
    //#define button3          27
    
    // attach button debouncers to input buttons
    Bounce db_button0 = Bounce(button0, 30);
    Bounce db_button1 = Bounce(button1, 30);
    Bounce db_button2 = Bounce(button2, 30);
    //Bounce db_button3 = Bounce(button3, 30);
    
    // choose mic or line input for audio shield input path
    const int inputChSelect = AUDIO_INPUT_MIC;
    //const int inputChSelect = AUDIO_INPUT_LINEIN;
    
    // audio shield volume
    int masterVolume        = 0;
    
    // uncomment one set of SD card SPI pins to use
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN     10
    #define SDCARD_MOSI_PIN   7
    #define SDCARD_SCK_PIN    14
    
    
    
    // wav filenames on SD card for playback
    char *wavFiles[]       = {"CM.000.WAV", "SDTEST1.WAV", "SDTEST2.WAV", "SDTEST3.WAV", "SDTEST4.WAV"};
    byte wavNum            = 0;      // current wav file index playing from array list
    bool wavIsPlaying      = false;  // track if a wav file is currently playing or not
    
    void setup() {
      Serial.begin(9600);
      Serial.println("SD Player Demo\n");
    
      // buttons are inputs with pullups
      pinMode(button0, INPUT_PULLUP);
      pinMode(button1, INPUT_PULLUP);
      pinMode(button2, INPUT_PULLUP);
      //pinMode(button3, INPUT_PULLUP);
    
      // 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.
      Serial.print("init audio shield...");
      audioShield.enable();
      audioShield.inputSelect(inputChSelect);  // select mic or line-in for audio shield input source
      audioShield.volume(0.5);
      Serial.println("done.");
    
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.5);
      mixer1.gain(2, 0);
      mixer1.gain(3, 0);
    
      mixer2.gain(0, 0.5);
      mixer2.gain(1, 0.5);
      mixer2.gain(2, 0);
      mixer2.gain(3, 0);
    
      Serial.print("init SD card...");
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        // stop here, but print a message
        Serial.println("Unable to access the SD card.  Program halted.");
        while (1);
      }
      Serial.println("done.");
      Serial.println("Waiting for control input...");
    
      // reset audio resource usage stats.
      // useful if tracking max usage in main program
      AudioProcessorUsageMaxReset();
      AudioMemoryUsageMaxReset();
    }
    
    void playFile(const char *filename)
    {
      Serial.print("Start playing file: ");
      Serial.println(filename);
    
      // start playing the file.
      // sketch continues to run while the file plays.
      playWav1.play(filename);
    
      // A brief delay for the library to read WAV header info
      delay(5);
    }
    
    
    void loop() {
    
      // auto select next wav file if current file finishes playing
      // and if playback is enabled
      if ((!(playWav1.isPlaying())) && (wavIsPlaying)) {
        wavNum++;
        if (wavNum > 4) {
          wavNum = 0;
        }
        playFile(wavFiles[wavNum]);
      }
    
      // read volume control pot and set audio shield volume if required
      int vol = analogRead(pot0);
      if (vol != masterVolume) {
        masterVolume = vol;
        audioShield.volume((float)vol / 1023);  // audio shield headphone out volume (optional)
        mixer1.gain(0, (float)vol / 1023);      // software mixer input channel volume
        mixer1.gain(1, (float)vol / 1023);
        mixer2.gain(0, (float)vol / 1023);
        mixer2.gain(1, (float)vol / 1023);
      }
    
      // update the button debounce status so falling edges
      // can be detected and processed
      db_button0.update();
      db_button1.update();
      db_button2.update();
      //db_button3.update();
    
      // button 0 pressed - toggle playback start/stop for current wav file
      if (db_button0.fallingEdge()) {
        if (playWav1.isPlaying()) {
          playWav1.stop();
          wavIsPlaying = false;
          Serial.println("Playback stopped\n");
        }
        else {
          playFile(wavFiles[wavNum]);
          wavIsPlaying = true;
          Serial.println("Playback started");
        }
        //Serial.print("Audio memory usage max: ");
        //Serial.println(AudioMemoryUsageMax());
      }
    
      // button 1 pressed - skip track forward
      if (db_button1.fallingEdge()) {
        Serial.println("Skip track forward");
        if (wavNum == 4)
          wavNum = 0;
        else
          wavNum++;
        playFile(wavFiles[wavNum]);
        wavIsPlaying = true;
      }
    
      // button 2 pressed - skip track backward
      if (db_button2.fallingEdge()) {
        Serial.println("Skip track backward");
        if (wavNum == 0)
          wavNum = 4;
        else
          wavNum--;
        playFile(wavFiles[wavNum]);
        wavIsPlaying = true;
      }
    
    }

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,368
    Is "CM.000.WAV" actually a valid 8.3 filename?

  3. #3
    Junior Member
    Join Date
    Jul 2021
    Posts
    14
    No it's not. I didn't even know what that was. I had to look it up. I just thought they had to be all caps. That file did work sometimes. Is there something wrong with the code that I can't seem to play more than 5 files?

  4. #4
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    954
    possibly five tracks has been hard coded into the code? you have several places where button count is reset to zero or four if it crosses those thresholds in the incremental loops. I suggest changing the hard code "4" into a variable that you set to agree with the number of files to be played.
    see your code here:
    Code:
     if (wavNum > 4) {
          wavNum = 0;
    and here:
    Code:
     if (db_button1.fallingEdge()) {
        Serial.println("Skip track forward");
        if (wavNum == 4)

  5. #5
    Junior Member
    Join Date
    Jul 2021
    Posts
    14
    ok, thanks I set a variable for fileNum (number of files) instead of the hard code. It seems to work if everything is just right with twenty files. I made numbers saying one, two, three, etc. so I could tell what was playing. I couldn't really tell before if everything was playing. These are short length tho, so I need to put my other longer files back and try again.

  6. #6
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    954
    Glad it's working. Also, just a reminder, that zerois counted as the first file in your loop, so 20 files would count 0 to 19 as your loops are written starting from zero.

    You can also write code that counts the number of files on the sd card, so in theory, in setup, you could scan the sd card, count the files, and then set your fileNum with that.

Posting Permissions

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