Audio Library problem when repeating a file (Arduino Due, DAC)

Hi All,

I have had this problem for a while now and just picked up this project again. Help is appreciated.

I am trying to play a wav file from an SD card. I have a Due with an audio amp and speaker connected to DAC0.

I can play it once but after multiple times the sound gets quite distorted. It is as if the playback frequency halves.

The test.wav file is about 15 seconds long.

It seems to be linked to the length of the delay() in between repeating playing the file.

  • If delay is 50 it played for half an hour no fault
  • If delay is 60 it played 4 times ok, 5th was not ok.
  • If delay is 70 it played 2 times ok, 3rd was not ok
  • If delay is 100 it played once ok, 2nd was not ok

The code below is the simplest code example I can create that has the problem. I'm hoping someone can try to recreate the issue or has the same problem and solved it.

It is the Simple Audio Player example from the Audio reference library. It has the following modification:

  • My SD card is on pin 53
  • The volume is set to 50
  • the while(true) loop at the end is removed so it repeats infinitely
  • I have put a delay in at the end between the repeats
  • My test.wav file is mono, so the sample frequency is halved. This sets the buffer size.
/*
  Simple Audio Player

 Demonstrates the use of the Audio library for the Arduino Due

 Hardware required :
 * Arduino shield with a SD card on CS4
 * A sound file named "test.wav" in the root directory of the SD card
 * An audio amplifier to connect to the DAC0 and ground
 * A speaker to connect to the audio amplifier

 Original by Massimo Banzi September 20, 2012
 Modified by Scott Fitzgerald October 19, 2012

 This example code is in the public domain

 http://www.arduino.cc/en/Tutorial/SimpleAudioPlayer

*/

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

void setup()
{
  // debug output at 9600 baud
  Serial.begin(9600);

  // setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(53)) {
    Serial.println(" failed!");
    return;
  }
  Serial.println(" done.");
  // hi-speed SPI transfers
  SPI.setClockDivider(4);

  // 44100Khz mono => 44100 sample rate
  // 100 mSec of prebuffering.
  Audio.begin(44100, 100);
}

void loop()
{
  int count = 0;

  // open wave file from sdcard
  File myFile = SD.open("test.wav");
  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S = 1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while (myFile.available()) {
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 50;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();

  Serial.println("End of file. Thank you for listening!");
  //while (true) ;
  delay(50);
}

BTW I found some others that seem to be describing the same issue as mine but without a resolution yet. They might give some more clues.

http://forum.arduino.cc/index.php?topic=247058.0
http://forum.arduino.cc/index.php?topic=280021.0
http://forum.arduino.cc/index.php?topic=312557.0

Thanks for your help.

I would open an issue in GitHub

It seems this issue is well-known. Has anyone found a solution yet?

I opened an issue in the github repo for the arduino Audio library: Distorted audio when repeatedly playing a file with a delay · Issue #1 · arduino-libraries/Audio · GitHub

Any luck? I'm having the same problem. I just made a post in /Audio but after reading this I'm not sure anyone will respond.

Okay I seem to have worked it out.

Include a Audio.end(); on the line below file.close(); in every instance of of file opening. Also remove the Audio.begin(); from setup and put that on the line following file.open("*.WAV").

// open wave file from sdcard
  File myFile = SD.open("test.wav");
  Audio.begin(44100, 100);

  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S = 1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while (myFile.available()) {
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 50;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();
  
  Audio.end();

Just make sure to Audio.begin and Audio.end before and after each file.

I just want to say that this worked for me. Belatedly, thanks very much! ;D