Wav playback does not work. Do you see what is wrong in my code?

Status
Not open for further replies.

nubie

Active member
All is wired ok. 100%.
WAV are ok too. 100%

If I run SD Card Test from examples:

Code:
// SD Card Test
//
// Check if the SD card on the Audio Shield is working,
// and perform some simple speed measurements to gauge
// its ability to play 1, 2, 3 and 4 WAV files at a time.
//
// Requires the audio shield:
//   http://www.pjrc.com/store/teensy3_audio.html
//
// 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 <SD.h>
#include <SPI.h>

// 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() {
  Sd2Card card;
  SdVolume volume;
  File f1, f2, f3, f4;
  char buffer[512];
  boolean status;
  unsigned long usec, usecMax;
  elapsedMicros usecTotal, usecSingle;
  int i, type;
  float size;

  // wait for the Arduino Serial Monitor to open
  while (!Serial) ;
  delay(50);

  // Configure SPI
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);

  Serial.begin(9600);
  Serial.println("SD Card Test");
  Serial.println("------------");

  // First, detect the card
  status = card.init(SPI_FULL_SPEED, SDCARD_CS_PIN);
  if (status) {
    Serial.println("SD card is connected :-)");
  } else {
    Serial.println("SD card is not connected or unusable :-(");
    return;
  }

  type = card.type();
  if (type == SD_CARD_TYPE_SD1 || type == SD_CARD_TYPE_SD2) {
    Serial.println("Card type is SD");
  } else if (type == SD_CARD_TYPE_SDHC) {
    Serial.println("Card type is SDHC");
  } else {
    Serial.println("Card is an unknown type (maybe SDXC?)");
  }

  // Then look at the file system and print its capacity
  status = volume.init(card);
  if (!status) {
    Serial.println("Unable to access the filesystem on this card. :-(");
    return;
  }

  size = volume.blocksPerCluster() * volume.clusterCount();
  size = size * (512.0 / 1e6); // convert blocks to millions of bytes
  Serial.print("File system space is ");
  Serial.print(size);
  Serial.println(" Mbytes.");

  // Now open the SD card normally
  status = SD.begin(SDCARD_CS_PIN);
  if (status) {
    Serial.println("SD library is able to access the filesystem");
  } else {
    Serial.println("SD library can not access the filesystem!");
    Serial.println("Please report this problem, with the make & model of your SD card.");
    Serial.println("  http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports");
  }


  // Open the 4 sample files.  Hopefully they're on the card
  f1 = SD.open("SDTEST1.WAV");
  f2 = SD.open("SDTEST2.WAV");
  f3 = SD.open("SDTEST3.WAV");
  f4 = SD.open("SDTEST4.WAV");

  // Speed test reading a single file
  if (f1) {
    Serial.println();
    Serial.println("Reading SDTEST1.WAV:");
    if (f1.size() >= 514048) {
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(1, 1000, usecTotal, usecMax);
    } else {
      Serial.println("SDTEST1.WAV is too small for speed testing");
    }
  } else {
    Serial.println("Unable to find SDTEST1.WAV on this card");
    return;
  }

  // Speed test reading two files
  if (f2) {
    Serial.println();
    Serial.println("Reading SDTEST1.WAV & SDTEST2.WAV:");
    if (f2.size() >= 514048) {
      f1.seek(0);
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        f2.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(2, 1000, usecTotal, usecMax);

      Serial.println();
      Serial.println("Reading SDTEST1.WAV & SDTEST2.WAV staggered:");
      f1.seek(0);
      f2.seek(0);
      f1.read(buffer, 512);
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        f2.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(2, 1000, usecTotal, usecMax);
    } else {
      Serial.println("SDTEST2.WAV is too small for speed testing");
    }
  } else {
    Serial.println("Unable to find SDTEST2.WAV on this card");
    return;
  }


  // Speed test reading three files
  if (f3) {
    Serial.println();
    Serial.println("Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV:");
    if (f3.size() >= 514048) {
      f1.seek(0);
      f2.seek(0);
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        f2.read(buffer, 512);
        f3.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(3, 1000, usecTotal, usecMax);

      Serial.println();
      Serial.println("Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV staggered:");
      f1.seek(0);
      f2.seek(0);
      f3.seek(0);
      f1.read(buffer, 512);
      f1.read(buffer, 512);
      f2.read(buffer, 512);
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        f2.read(buffer, 512);
        f3.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(3, 1000, usecTotal, usecMax);
    } else {
      Serial.println("SDTEST3.WAV is too small for speed testing");
    }
  } else {
    Serial.println("Unable to find SDTEST3.WAV on this card");
    return;
  }


  // Speed test reading four files
  if (f4) {
    Serial.println();
    Serial.println("Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV, SDTEST4.WAV:");
    if (f4.size() >= 514048) {
      f1.seek(0);
      f2.seek(0);
      f3.seek(0);
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        f2.read(buffer, 512);
        f3.read(buffer, 512);
        f4.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(4, 1000, usecTotal, usecMax);

      Serial.println();
      Serial.println("Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV, SDTEST4.WAV staggered:");
      f1.seek(0);
      f2.seek(0);
      f3.seek(0);
      f4.seek(0);
      f1.read(buffer, 512);
      f1.read(buffer, 512);
      f1.read(buffer, 512);
      f2.read(buffer, 512);
      f2.read(buffer, 512);
      f3.read(buffer, 512);
      usecMax = 0;
      usecTotal = 0;
      for (i=0; i < 1000; i++) {
        usecSingle = 0;
        f1.read(buffer, 512);
        f2.read(buffer, 512);
        f3.read(buffer, 512);
        f4.read(buffer, 512);
        usec = usecSingle;
        if (usec > usecMax) usecMax = usec;
      }
      reportSpeed(4, 1000, usecTotal, usecMax);
    } else {
      Serial.println("SDTEST4.WAV is too small for speed testing");
    }
  } else {
    Serial.println("Unable to find SDTEST4.WAV on this card");
    return;
  }

}


unsigned long maximum(unsigned long a, unsigned long b,
  unsigned long c, unsigned long d)
{
  if (b > a) a = b;
  if (c > a) a = c;
  if (d > a) a = d;
  return a;
}


void reportSpeed(unsigned int numFiles, unsigned long blockCount, unsigned long usecTotal, unsigned long usecMax)
{
  float bytesPerSecond = (float)(blockCount * 512 * numFiles) / usecTotal;
  Serial.print("  Overall speed = ");
  Serial.print(bytesPerSecond);
  Serial.println(" Mbyte/sec");
  Serial.print("  Worst block time = ");
  Serial.print((float)usecMax / 1000.0);
  Serial.println(" ms");
  Serial.print("    ");
  Serial.print( (float)usecMax / 29.01333);
  Serial.println("% of audio frame time");
}


void loop(void) {
  // do nothing after the test
}

Then all is fine on the serial monitor:

Code:
SD Card Test
------------
SD card is connected :-)
Card type is SDHC
File system space is 15923.15 Mbytes.
SD library is able to access the filesystem

Reading SDTEST1.WAV:
  Overall speed = 1.24 Mbyte/sec
  Worst block time = 0.79 ms
    27.26% of audio frame time

Reading SDTEST1.WAV & SDTEST2.WAV:
  Overall speed = 1.22 Mbyte/sec
  Worst block time = 0.87 ms
    30.06% of audio frame time

Reading SDTEST1.WAV & SDTEST2.WAV staggered:
  Overall speed = 1.22 Mbyte/sec
  Worst block time = 0.87 ms
    30.06% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV:
  Overall speed = 1.22 Mbyte/sec
  Worst block time = 1.30 ms
    44.84% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV staggered:
  Overall speed = 1.22 Mbyte/sec
  Worst block time = 1.30 ms
    44.77% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV, SDTEST4.WAV:
  Overall speed = 1.23 Mbyte/sec
  Worst block time = 1.72 ms
    59.11% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV, SDTEST4.WAV staggered:
  Overall speed = 1.23 Mbyte/sec
  Worst block time = 1.72 ms
    59.15% of audio frame time

Now I don't want only to open it, but I want to play the WAV file.
This is the code I'm compiling:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav         playWav;
AudioMixer4            mixer;
AudioOutputAnalog      dac;   // A14 on Teensy
AudioConnection        patchCord1(playWav, 0, mixer, 0);
AudioConnection        patchCord2(mixer, 0, dac, 0);

#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

#define SELECT_POT A8 
float SELECT_POT_VALUE;

void setup() {
  Serial.begin(9600);
  
  AudioMemory(25);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }

  mixer.gain(0, 1.0);
}

void playFile(const char *filename)
{
//  Serial.print("Playing file: ");
//  Serial.println(filename);

  playWav.play(filename);

  delay(5);

  // Simply wait for the file to finish playing.
  while (playWav.isPlaying()) { 
   Serial.print("playWav.isPlaying");
   SELECT_POT_VALUE = analogRead(SELECT_POT);
   mixer.gain(0, SELECT_POT_VALUE/1023);
  }
}

void loop() {
  playFile("SDTEST1.WAV");  // filenames are always uppercase 8.3 format
  delay(500);
}

I can't hear the SDTEST1.WAV file. I know the file is ok and the Teensy/hardware too (it works great with Radio music code).It's something in the code which is not.

This line does not seem to work:
Code:
while (playWav.isPlaying())
Cause this does not output anything in the serial monitor window:
Code:
Serial.print("playWav.isPlaying");

So the WAV file is not playing.
 
First of all, what Teensy are you using? And if you are using the audio shield, what audio revision are you using? The code you are using looks correct for a Teensy 3.2 using an Audio shield revisions A, B, or C If you were using a Teensy 3.5 or 3.6, you would need. It would not be correct if you were using a Teensy 4.0 or the forthcoming 4.1.

Second, your code uses A8 as a potentiometer to control the volume. If you are using the audio shield on a Teensy 3.x, note that A8 is used to send audio data from the Teensy to the audio shield. Even if you aren't using the audio shield, except as a SD card reader, I would imagine A8 would interfere with it being used for a potentiometer. I would suggest moving the potentiometer to A7, A6, A3, A2, or A0, as those pins are not used by the audio shield. You could use A1, which are the 3 pins setup to be a potentiometer on the audio shield.

Obviously you would need to amplify the sound from the DAC (pin A14 on the Teensy 3.2, pin A21 on the Teensy 3.5/3.6, and Teensy 4.0/4.1 do not have a DAC pin). But since you said the radio sketch works, I assume it is setup properly.
 
Please forgive me Michael. I forgot to mention.
I am using the Teensy 3.2, without audio shield. Audio to DAC (A14/DAC), then to opAmp circuit working fine. Pot wiring is fine too (with or without mixer, pot etc, same results, no audio). Indeed setup is fine.
 
When I write setup is fine, I mean it is used for another project, where reading SD Card, playing WAV etc work fine with a more complex code using SDPlayPCM.cpp, SDPlayPCM.h, WavHeaderReader etc etc.
Same pins, DAC, connections etc.

This is why I was asking if someone sees something wrong with this short code, which is simply trying to play a WAV file.
Or if someone can test and tell me if it works, using Teensy 3.2, DAC out (amplified) and pins as specified in code. And
a WAV file named SDTEST1.WAV present on a SD Card.

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav         playWav;
AudioMixer4            mixer;
AudioOutputAnalog      dac;   // A14 on Teensy
AudioConnection        patchCord1(playWav, 0, mixer, 0);
AudioConnection        patchCord2(mixer, 0, dac, 0);

#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

#define SELECT_POT A8 
float SELECT_POT_VALUE;

void setup() {
  Serial.begin(9600);
  
  AudioMemory(25);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }

  mixer.gain(0, 1.0);
}

void playFile(const char *filename)
{
//  Serial.print("Playing file: ");
//  Serial.println(filename);

  playWav.play(filename);

  delay(5);

  // Simply wait for the file to finish playing.
  while (playWav.isPlaying()) { 
   Serial.print("playWav.isPlaying");
   SELECT_POT_VALUE = analogRead(SELECT_POT);
   mixer.gain(0, SELECT_POT_VALUE/1023);
  }
}

void loop() {
  playFile("SDTEST1.WAV");  // filenames are always uppercase 8.3 format
  delay(500);
}
 
Okay. The code is fine.
I changed the WAV files on the SD Card and it works.
I had no doubt they were fine cause the play on my other project playing WAV files with a Teensy, but I was wrong.

I don't know how to edit the title to mention my issue is solved.

Code works fine.
 
I found out why the WAV files were playing in my other project while they can't here (though using exactly setup/hardware, Teensy).
In my other project I can play 24bit WAV samples, here I can only 16bit.

As mentionned the other project is more complex (using more code SDPlayPCM.cpp, SDPlayPCM.h, WavHeaderReader etc etc) than the one in this thread I made for test/learning purposes. The more complex one never uses the function play() for instance.

Noe I need to find out how to play 24bit in this simplified test project...
 
Status
Not open for further replies.
Back
Top