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

Thread: WavFilePlayer Clicks, pops and crunchy noises - solved but WHY?!

  1. #1

    WavFilePlayer Clicks, pops and crunchy noises - solved but WHY?!

    After 3 or 4 brutal days of trying, failing and trying some more I started back again at the WavFilePlayer example and built it up into a test sketch to try and work out why I was getting clicks and pops when loading more than 2 wav files at the same time. I was sure this wasn't the case when I started out.

    The problem is that if you use folders to put your wavs in the loading performance becomes terrible. This code will happily load and play 8 stereo wavs at 48k on the T4: (impressive!!)

    Code:
    playSdWav1.play("3BAB1.wav");
      playSdWav2.play("3BAB2.wav");
      playSdWav3.play("3BAB3.wav");
      playSdWav4.play("3BAB4.wav");
      playSdWav5.play("3BAD.wav");
      playSdWav6.play("3BAA.wav");
      playSdWav7.play("3BAS.wav");
      playSdWav8.play("3BAB2.wav");
    but this code clicks, pops and sounds terrible on the first couple of wavs

    Code:
    playSdWav1.play("BA/3BAB1.wav");
      playSdWav2.play("BA/3BAB2.wav");
      playSdWav3.play("BA/3BAB3.wav");
      playSdWav4.play("BA/3BAB4.wav");
      playSdWav5.play("BA/3BAD.wav");
      playSdWav6.play("BA/3BAA.wav");
      playSdWav7.play("BA/3BAS.wav");
      playSdWav8.play("BA/3BAB2.wav");
    Why is this? and what can I do to solve the problem? I am using SDIO, T4, SD.h on the latest Teensyduino

    edit, full sketch here:

    Code:
    // Simple WAV file player example
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav           playSdWav1;     //xy=265,249
    AudioPlaySdWav           playSdWav2;     //xy=271,336
    AudioPlaySdWav           playSdWav3;     //xy=287,412
    AudioPlaySdWav           playSdWav4;     //xy=295,473
    AudioPlaySdWav           playSdWav5;     //xy=310,689
    AudioPlaySdWav           playSdWav6;     //xy=318,772
    AudioPlaySdWav           playSdWav7;     //xy=321,852
    AudioPlaySdWav           playSdWav8;     //xy=332,959
    AudioMixer4              mixer2;         //xy=581,360
    AudioMixer4              mixer4;         //xy=584,597
    AudioMixer4              mixer3;         //xy=586,476
    AudioMixer4              mixer1;         //xy=590,254
    AudioMixer4              mixer6;         //xy=697,845
    AudioMixer4              mixer5;         //xy=703,736
    AudioOutputI2S           i2s1;           //xy=851,287
    AudioConnection          patchCord1(playSdWav1, 0, mixer1, 0);
    AudioConnection          patchCord2(playSdWav1, 1, mixer2, 0);
    AudioConnection          patchCord3(playSdWav2, 0, mixer3, 2);
    AudioConnection          patchCord4(playSdWav2, 1, mixer4, 2);
    AudioConnection          patchCord5(playSdWav3, 0, mixer3, 0);
    AudioConnection          patchCord6(playSdWav3, 1, mixer4, 0);
    AudioConnection          patchCord7(playSdWav4, 0, mixer3, 1);
    AudioConnection          patchCord8(playSdWav4, 1, mixer4, 1);
    AudioConnection          patchCord9(playSdWav5, 0, mixer3, 3);
    AudioConnection          patchCord10(playSdWav5, 1, mixer4, 3);
    AudioConnection          patchCord11(playSdWav6, 0, mixer5, 0);
    AudioConnection          patchCord12(playSdWav6, 1, mixer6, 0);
    AudioConnection          patchCord13(playSdWav7, 0, mixer5, 1);
    AudioConnection          patchCord14(playSdWav7, 1, mixer6, 1);
    AudioConnection          patchCord15(playSdWav8, 0, mixer5, 2);
    AudioConnection          patchCord16(playSdWav8, 1, mixer6, 3);
    AudioConnection          patchCord17(mixer2, 0, i2s1, 1);
    AudioConnection          patchCord18(mixer1, 0, i2s1, 0);
    // GUItool: end automatically generated code
    
    
    
    
    // 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
    int inByte = 0;
    byte  newDATAin = 1;
    
    
    void setup() {
      Serial.begin(115200);
    
      mixer1.gain(1, 0.2);
      mixer1.gain(2, 0.2);
      mixer1.gain(3, 0.2);
      mixer1.gain(4, 0.2);
    
      mixer2.gain(1, 0.2);
      mixer2.gain(2, 0.2);
      mixer2.gain(3, 0.2);
      mixer2.gain(4, 0.2);
    
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(150);
    
    
      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 loop() {
      
    
      // Simply wait for the file to finish playing.
      //while (playSdWav1.isPlaying()) {
    
         switch (Serial.read()) {
          
       case 's': {
        //Serial.println("s");
       playSdWav1.stop();
       playSdWav2.stop();
       playSdWav3.stop();
       playSdWav4.stop();
       playSdWav5.stop();
       playSdWav6.stop();
       playSdWav7.stop();
       playSdWav8.stop();
       }
            break;
    
            case 't': {
      playSdWav1.play("3BAB1.wav");
      playSdWav2.play("3BAB2.wav");
      playSdWav3.play("3BAB3.wav");
      playSdWav4.play("3BAB4.wav");
      playSdWav5.play("3BAD.wav");
      playSdWav6.play("3BAA.wav");
      playSdWav7.play("3BAS.wav");
      playSdWav8.play("3BAB2.wav");
      
      delay(5);
            }
          break;
    
                  case 'u': {
      playSdWav1.play("BA/3BAB1.wav");
      playSdWav2.play("BA/3BAB2.wav");
      playSdWav3.play("BA/3BAB3.wav");
      playSdWav4.play("BA/3BAB4.wav");
      playSdWav5.play("BA/3BAD.wav");
      playSdWav6.play("BA/3BAA.wav");
      playSdWav7.play("BA/3BAS.wav");
      playSdWav8.play("BA/3BAB2.wav");
      
      delay(5);
            }
          break;
       
    }
    
    
    
    }
    only the first wav player is attached to the output for this test to avoid everything playing at once and sounding crazy

  2. #2
    since writing the above post I have noticed some files load better than others, even if they are the same length file name and same size file :/ I managed to get the Sdfat.h beta to compile with the audio library and although in SDIO mode it doesn't pop or click everything hangs for a moment or two after you start the wavs playing. There must be a setting I can adjust somewhere to get rid of these pops and clicks? A

  3. #3
    Senior Member
    Join Date
    Dec 2014
    Posts
    304
    One theory:
    The code in the SD library has no caching. It will scan your entire root directory to find the "BA" directory, each time you open something. Then it will scan the "BA" directory it finds, to find each file. It does this by reading the disk, over and over again.
    You may be able to split the code into "find and open the file" versus "read the data to play it back" such that the slow scanning happens before any audio needs to be played.
    The throughput to the flash, and latency of reading sectors, is limited, and when you hit too many requests at once, it takes too long.
    Unfortunately, AudopPlaySdWav doesn't have some way of "pre-loading" without starting playing, and if you pre-load all the files in the middle of loop(), you'll have the same problem anyway.

    So, you will get the best performance if the only thing on your card is the eight files, and they are all in the root directory. Anything beyond that, will cause worse performance, and when the "worse performance" hits the necessary per-block time for the audio output, you will get glitching.

  4. #4
    Thanks for the reply! That makes a lot of sense. A friend of mine pointed out that I can probably solve this problem by using AudioRecordQueue and AudioPlayQueue to create a buffer! Looking forward to giving it a go in the morning.

Posting Permissions

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