Hi,
I am working on a project that will require recording audio (from on-board or external mic) to the Tympan SD card, and I am getting an error when I try to play back a file using the SDWavPlayer.ino example.
Here’s an example of the error output to serial port
12:53:24.743 → SDWavPlayer: setup():…
12:53:24.743 → Sample Rate (Hz): 44100.00
12:53:24.743 → Audio Block Size (samples): 128
12:53:26.026 → Setup complete.
12:53:27.013 → Starting audio player: AUDIO001.WAV
12:53:27.769 → AudioSDPlayer_F32: readBuffer_16bit_to_f32: insufficient data in RAM buffer.
12:53:27.836 → AudioSDPlayer_F32: readBuffer_16bit_to_f32: insufficient data in RAM buffer.
12:53:27.901 → AudioSDPlayer_F32: readBuffer_16bit_to_f32: insufficient data in RAM buffer.
In this case, I had recorded from on-board mics some test audio to the SD card, file named AUDIO001.WAV.
I made sure to remove any SD libraries from my Arduino libraries folder so that it only uses the Teensy SD library.
I have tested the WAV file playback with the Teensy example Audio > SDWavPlayer.ino as mentioned in this post, and it does play back nicely. Here’s the code I’m using from Teensy that works. If you want to replicate it, it also works well with the Teensy supplied SDTESTx.WAV files.
// Simple WAV file player example
//
// Three types of output may be used, by configuring the code below.
//
// 1: Digital I2S - Normally used with the audio shield:
// http://www.pjrc.com/store/teensy3_audio.html
//
// 2: Digital S/PDIF - Connect pin 22 to a S/PDIF transmitter
// https://www.oshpark.com/shared_projects/KcDBKHta
//
// 3: Analog DAC - Connect the DAC pin to an amplified speaker
// http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// To configure the output type, first uncomment one of the three
// output objects. If not using the audio shield, comment out
// the sgtl5000_1 lines in setup(), so it does not wait forever
// trying to configure the SGTL5000 codec chip.
//
// The SD card may connect to different pins, depending on the
// hardware you are using. Uncomment or configure the SD card
// pins to match your hardware.
//
// 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 <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
AudioPlaySdWav playWav1;
// Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
AudioOutputI2S audioOutput;
//AudioOutputSPDIF audioOutput;
//AudioOutputAnalog audioOutput;
//On Teensy LC, use this for the Teensy Audio Shield:
//AudioOutputI2Sslave audioOutput;
AudioConnection patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection patchCord2(playWav1, 1, audioOutput, 1);
AudioControlSGTL5000 sgtl5000_1;
// Use these with the Teensy Audio Shield
// #define SDCARD_CS_PIN 10
// #define SDCARD_MOSI_PIN 7 // Teensy 4 ignores this, uses pin 11
// #define SDCARD_SCK_PIN 14 // Teensy 4 ignores this, uses pin 13
// Use these with the Teensy 3.5 & 3.6 & 4.1 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() {
Serial.begin(9600);
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);
// Comment these out if not using the audio adaptor board.
// This may wait forever if the SDA & SCL pins lack
// pullup resistors
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
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 playFile(const char *filename)
{
Serial.print("Playing file: ");
Serial.println(filename);
// Start playing the file. This sketch continues to
// run while the file plays.
playWav1.play(filename);
// A brief delay for the library read WAV info
delay(25);
// Simply wait for the file to finish playing.
while (playWav1.isPlaying()) {
// uncomment these lines if you audio shield
// has the optional volume pot soldered
//float vol = analogRead(15);
//vol = vol / 1024;
// sgtl5000_1.volume(vol);
}
}
void loop() {
playFile("AUDIO001.WAV"); // filenames are always uppercase 8.3 format
delay(500);
// playFile("SDTEST2.WAV");
// delay(500);
// playFile("SDTEST3.WAV");
// delay(500);
// playFile("SDTEST4.WAV");
// delay(1500);
}
This is the Tympan library example code that I’m using that is flagging the RAM error. It also produces the RAM error with the SDTESTx.WAV files from Teensy.
/*
* SDWavPlayer
*
* Created: Chip Audette, OpenAudio, Dec 2019
* Based On: WaveFilePlayer from Paul Stoffregen, PJRC, Teensy
*
* Play back a WAV file through the Typman.
*
* For access to WAV files, please visit https://www.pjrc.com/teensy/td_libs_AudioDataFiles.html.
*
*/
#include <Tympan_Library.h>
//set the sample rate and block size
const float sample_rate_Hz = (int)(44100); //choose sample rate ONLY from options in the table in AudioOutputI2S_F32
const int audio_block_samples = 128; //do not make bigger than AUDIO_BLOCK_SAMPLES from AudioStream.h (which is 128) Must be 128 for SD recording.
AudioSettings_F32 audio_settings(sample_rate_Hz, audio_block_samples);
//create audio objects
Tympan myTympan(TympanRev::F, audio_settings); //do TympanRev::D or E or F
AudioSDPlayer_F32 audioSDPlayer(audio_settings); //this is in the Tympan_Library
AudioOutputI2S_F32 audioOutput(audio_settings);
//create audio connections
AudioConnection_F32 patchCord1(audioSDPlayer, 0, audioOutput, 0);
AudioConnection_F32 patchCord2(audioSDPlayer, 1, audioOutput, 1);
void setup() {
myTympan.beginBothSerial(); delay(1200);
myTympan.print("SDWavPlayer"); myTympan.println(": setup():...");
myTympan.print("Sample Rate (Hz): "); myTympan.println(audio_settings.sample_rate_Hz);
myTympan.print("Audio Block Size (samples): "); myTympan.println(audio_settings.audio_block_samples);
// Audio connections require memory to work.
AudioMemory_F32(20, audio_settings);
// Start the Tympan
myTympan.enable();
myTympan.volume(0.5); //any value 0 to 1.0??
//prepare SD player
//if (audioSDPlayer.isSdCardPresent()) { THIS LOOKS LIKE IT'S DEPRECIATED
audioSDPlayer.begin();
//} else {
// Serial.println("WARNING: SD card is not present in your Tympan.");
//}
//finish setup
delay(1000); //stall a second
Serial.println("Setup complete.");
}
unsigned long end_millis = 0;
String filename = "AUDIO001.WAV"; //this file needs to be on your SD card!
void loop() {
//start the SD player if it is not playing
if (!audioSDPlayer.isPlaying()) { //wait until previous play is done
// if (audioSDPlayer.isSdCardPresent()) {
//start playing audio
delay(1000); // break between plays
myTympan.print("Starting audio player: ");
myTympan.println(filename);
if(!audioSDPlayer.play(filename)){
Serial.println("WARNING: File cannot be opened.");
}
// } else {
// Serial.println("WARNING: SD card is not present in your Tympan.");
// delay(1000);
// }
}
//do other things here, if desired...like, maybe check the volume knob?
//stall, just to be nice?
delay(5);
}