Memory used up by repeatedly playing short .wav files from SD

I am trying to make a drum kit with my UNO board. I have two buttons and when I push one it plays a crash cymbal and when I push the other a snare is played. It is actually almost working!

I am using the TMRpcm.h library and have enabled multi mode in the pcmConfig.h file. This allows me to play two drum sounds at once which is good enough for me. The sound output comes from pins 9 and 10 and each one goes to the left or right input of a 3.5mm audio jack. The .wav files are converted to 8 bit unsigned 8khz mono as suggested in the TMRpcm documentation.

The problem is that whenever I play a file out to pin 9 it allocates a chunk of SRAM from the UNO about 50 bytes… I think… I added a chunk of code that at the bottom that supposedly tells me how much SRAM is remaining and it starts at about 780 and goes down every time a sound plays from pin 9. When this number reaches about 300 the program crashes.

The really weird thing is that this doesn’t happen when .wav files are played from pin 10. I tried many different files playing from each pin and always had the same result so I am convinced it is not the files. I tried turning multi mode off which means all files are played on pin 9 and had the same problem.

I tried to attach my .wav files but I think that file type is not allowed.

If anyone can help me understand why this is happening and fix it that would be great. Alternatively if anyone can suggest a work around to just get this thing to stop crashing that would also be good.

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

#define SD_ChipSelectPin 4

TMRpcm tmrpcm;

//bool isPlaying1 = tmrpcm.isPlaying(0);
//bool isPlaying2 = tmrpcm.isPlaying(1);
bool button1;
bool button2;

void setup(){
  tmrpcm.speakerPin = 9;
  pinMode(10, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  tmrpcm.setVolume(5);
  Serial.begin(9600);
  
  
  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD fail");
    return;
  }
}

void loop(){ 
  
  //isPlaying1 = tmrpcm.isPlaying(0);
  //isPlaying2 = tmrpcm.isPlaying(1);
  button1 = digitalRead(2);
  button2 = digitalRead(7);
  
  if (button1 == LOW)
  {
    tmrpcm.play("Crash2.wav");
    Serial.println("Crash");
    delay(50);
  }

  if (button2 == LOW)
  {
    tmrpcm.play("Snare1.wav", 1);
    Serial.println("Snare");
    delay(50);
  }

Serial.println(freeRam());
}

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Pin 10 is a hardware SPI pin, perhaps that's related? On the Uno you'd normally use it as chip select for the SD card, but you've chosen pin 4 for that for some reason?

Thanks for the reply Mark,

TMRpcm.h defines pin 10 as the second output pin when playing multiple .wav files at a time. I believe that is why pin 4 is used as the chip select pin, but to be honest I just did it that way based on a youtube tutorial.

The documentation for the library is here Home · TMRh20/TMRpcm Wiki · GitHub

The problem has to be in one of the libraries, right?

So I tried using the SDfat library instead of SD library and it works now. WOOT!

No idea what the problem was... I am such a hack!

Probably not freeing memory on closing each file? But why that depends on pin number? Who knows