Playing audio with TMRpcm

Hello,

A friend and I are working on a voice recorder using and Arduino uno. The main components are an SD card for storing audio, a microphone for recording and a speaker for playing the recorded audio. We can't quite get the recording to work, but we want to focus on that after we have made sure the audio can actually be played, which isn't the case. We are putting 8-bit unsigned wav files on the (type 4) 4 SD card with a laptop and then we try to play the audio on the Arduino. Occasionally the audio plays, but the pitch is too high. At other times no audio plays at all. We have tried a lot of things and honestly we just can't figure out how we can get the speaker to play the audio properly. At first we thought the audio files were too large, since songs didn't work, but then it couldn't play some short sounds either, so it must be something else. Does anyone have an idea on what we're doing wrong?

Some details: We are using an Arduino uno and we use the TMRpcm library for playing/recording audio. The audio files are unsigned, 8 bit wav files. (which are the only ones that have worked so far) I currently don't have the Arduino with me so if an image is necessary I'll have to add it at a later time.

For the library: In the 'pcmConfig.h' file of TMRpcm we have changed to buffer size to 128 and we have uncommented HANDLE_TAGS, DISABLE_SPEAKER_TWO, STEREO_OR_16BIT and BLOCK_COUNT is set to 10000UL

Here is the code we are using:

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

const int SD_pin = 6;  //example uses hardware SS pin 53 on Mega2560
//Sd2Card card;

TMRpcm audio;   // create an object for use in this sketch

//recoring & playing
int rec_pin = A0;
boolean can_press_1 = true;
boolean can_press_2 = true;
int button_1 = 2;
int button_2 = 7;
boolean _recording = false;
boolean _playing = false;


void setup() {
 
 Serial.begin(9600);
 while (!Serial) {
   // wait for serial port to connect. Needed for native USB port only
 }
 Serial.println("Serial connected");

 //Set the SD card
 if (!SD.begin(SD_pin)) {
   Serial.println("SD not OK");
   return;
 }else{
   Serial.println("SD OK"); 
 }
 audio.CSPin = SD_pin;

 //recording & playing
 audio.setVolume(7); //volume
 audio.quality(1);
 audio.speakerPin = 9; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc
 pinMode(10,OUTPUT);  //Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45
 pinMode(rec_pin, INPUT);
 pinMode(button_1, INPUT);
 pinMode(button_2, INPUT);
}
void loop() {

   //button 1 (record)
   if (digitalRead(button_1)) {
    if (can_press_1) {
      can_press_1 = false;
      //if button 1 pressed:
      Serial.println("pressed button 1");

      if (_playing) { //stop playing
        _playing = false;
        audio.stopPlayback();
        Serial.println("stopped playback");
      }
      if (!_recording) { //start or stop recording
        _recording = true;
        audio.startRecording("audio.wav",16000,rec_pin);
        Serial.println("started recording");
      } else {
        _recording = false;
        audio.stopRecording("audio.wav");
        Serial.println("stopped recording");
      }
    }
   } else {
    can_press_1 = true;
   }

   //button 2 (play)
   if (digitalRead(button_2)) {
    if (can_press_2) {
      can_press_2 = false;
      //if button 2 pressed:
      Serial.println("pressed button 2");

      if (_recording) { //stop recording
        _recording = false;
        audio.stopRecording("audio.wav");
        Serial.println("stopped recording");
      }
      if (!_playing) { //start or stop playing
        _playing = true;
        audio.play("audio.wav");
        Serial.println("started playing");
      } else {
        _playing = false;
        audio.stopPlayback();
        Serial.println("stopped playing");
      }
    }
   } else {
    can_press_2 = true;
   }
}

I've never used TMRpcm…

Occasionally the audio plays, but the pitch is too high.

Make sure the sample rate meets the TMRpcm requirements (8kHz?).

A sample rate mismatch* will play-back at the wrong speed (with a corresponding pitch error). Also, make sure the mono-stereo is "correct".

A mono-file played-back as stereo would play at double-speed because it's reading twice as many samples (and it expects twice as many samples in the file).

On a computer, iPhone, or iPod, etc., the software/operating system reads the file header and it automatically adjusts to the correct playback sample rate, bit depth, and number of channels, and/or it re-samples as-required by the hardware and everything "just works". TMRpcm is not that "smart" and the Arduino is probably not fast enough for real-time resampling.

Ah I see, thanks for the response! I won't be able to work on the Arduino for a couple of days but when I do I'll be sure to try it out.

I've recently worked with TMRpcm for a project only requiring to play audio files. I also had some audio-problems. Sometimes the "quality" doesn't work as it should be.

Try to disable your audio.quality(1) and set your volume a little bit down to 2. It might be better. I had lots of trouble with setting the volume. As I've re-written the code I set the volume to 2. Worked for me.

Tell us when you've tried a bit more.

Thanks for the reply. I've remove 'audio.quality(1)' and I've lowered the volume. Our main problem is not the pitch though, we can work with that. The fact that most audio files don't play is the real issue.

So far there's only one audio file that we can get to work, which is 16 kHz, as the TMRpcm manual said. We thought the problem has to do with our pcmConfig.h file, but then why would one file be able to play?

If anyone has had this problem before or knows what we could try, we'd love to hear it.

Did you try to sample all other music to 16khz too?