Hi there,
I'm trying to build a device that can record short sound snippets and play them back on command. I'm using a Teensy 3.6, and put together the following code to try and test the core functionality:
REC_PIN_0 and TRIG_PIN_0 are both connected to mechanical switches that control recording and playback (respectively). INPUT_PIN is connected to the audio in.
The problem I'm running into is that this sketch runs fine when I'm just pressing the record button (REC_PIN_0), but freezes whenever I press the play button (TRIG_PIN_0). Pressing the record button prints all the expected comments to the Arduino IDE's serial monitor, and creates the expected .raw file. Pressing the play button satisfies the condition for the if statement in updateTrigIns(), but the Teensy does not print 'Sample Triggered' to the serial monitor, and after pressing the play button nothing happens if I try pressing the record button.
After some troubleshooting, I've found out that if I comment out the line from playSample() that says 'samplePlayer.play(SAMPLE_NAME)' the sketch runs fine. Both 'Sample Triggered' and 'Playing sample' show up on the serial monitor, so that's telling me that I have the button wired up correctly and don't have any issues with the control flow of this sketch.
However, I'm not sure what I should be trying now. I'm pretty sure I remember seeing somewhere that AudioInputAnalog records 12bit data, while AudioPlaySdRaw expects 16bit data. I also seem to remember seeing a function related to AudioInputAnalog that lets you change the resolution of 16bit, but the only thing I've been able to find this time around is analogReadResolution(), which isn't specific to AudioInputAnalog.
Am I on the right track in thinking there's some incapatibility between the sort of file AudioInputAnalog creates and the sort of file AudioPlaySdRaw is meant to play? Or is there something else I should be looking into? Any thoughts you can share would be a huge help.
Thanks!
I'm trying to build a device that can record short sound snippets and play them back on command. I'm using a Teensy 3.6, and put together the following code to try and test the core functionality:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Bounce.h>
#include <SerialFlash.h>
#define REC_PIN_0 7
#define INPUT_PIN A1
#define TRIG_PIN_0 8
#define SAMPLE_NAME "TstAudIO.raw"
#define SDCARD_CS_PIN BUILTIN_SDCARD
AudioInputAnalog input(INPUT_PIN);
AudioRecordQueue recQueue;
AudioPlaySdRaw samplePlayer;
AudioOutputAnalogStereo outputs;
AudioConnection in2Rec(input, 0, recQueue, 0);
AudioConnection samp2Outs(samplePlayer, 0, outputs, 0);
Bounce recButton = Bounce(REC_PIN_0, 10);
Bounce trigIn = Bounce(TRIG_PIN_0, 10);
void setup() {
//Audio Setup
AudioMemory(80);
//Serial Setup
Serial.begin(9600);
while (!Serial) {}
//Trig/Rec Setup
pinMode(REC_PIN_0, INPUT_PULLUP);
pinMode(TRIG_PIN_0, INPUT_PULLUP);
//SD Setup
while (!(SD.begin(SDCARD_CS_PIN))) {
Serial.println("Unable to access the SD card");
delay(500);
}
analogReadResolution(16);
Serial.println("setup() complete");
Serial.println("Version with 16bit res");
}
void loop() {
updateRecButtons();
updateTrigIns();
}
void updateRecButtons() {
recButton.update();
if (recButton.fallingEdge()) {
Serial.println("Record Botton Pressed");
record();
}
}
void updateTrigIns() {
trigIn.update();
if (trigIn.fallingEdge()) {
Serial.println("Sample Triggered");
playSample();
}
}
void record() {
Serial.println("Entering record()");
//Setup file to record into
if(SD.exists(SAMPLE_NAME)) {
SD.remove(SAMPLE_NAME);
Serial.print("Deleting ");
Serial.println(SAMPLE_NAME);
}
File file = SD.open(SAMPLE_NAME, FILE_WRITE);
if(!file) {
Serial.println("Error: File Not Found");
while (digitalRead(REC_PIN_0) == LOW) {}
return;
}
//Start Recording
Serial.println("Starting to Record");
recQueue.begin();
while (!recButton.risingEdge()) {
recButton.update();
if (recQueue.available() >= 2) {
byte buffer[512];
memcpy(buffer, recQueue.readBuffer(), 256);
recQueue.freeBuffer();
memcpy(buffer+256, recQueue.readBuffer(), 256);
recQueue.freeBuffer();
file.write(buffer, 512);
}
}
//Finish Recording
Serial.println("Record Button Released");
recQueue.end();
while (recQueue.available() >= 2) {
file.write((byte*)recQueue.readBuffer(), 256);
recQueue.freeBuffer();
}
file.close();
Serial.println("Exiting record()");
}
void playSample() {
if (!SD.exists(SAMPLE_NAME)) {
Serial.print("File ");
Serial.print(SAMPLE_NAME);
Serial.println(" not found");
} else {
Serial.println("Playing sample");
samplePlayer.stop();
samplePlayer.play(SAMPLE_NAME);
}
}
REC_PIN_0 and TRIG_PIN_0 are both connected to mechanical switches that control recording and playback (respectively). INPUT_PIN is connected to the audio in.
The problem I'm running into is that this sketch runs fine when I'm just pressing the record button (REC_PIN_0), but freezes whenever I press the play button (TRIG_PIN_0). Pressing the record button prints all the expected comments to the Arduino IDE's serial monitor, and creates the expected .raw file. Pressing the play button satisfies the condition for the if statement in updateTrigIns(), but the Teensy does not print 'Sample Triggered' to the serial monitor, and after pressing the play button nothing happens if I try pressing the record button.
After some troubleshooting, I've found out that if I comment out the line from playSample() that says 'samplePlayer.play(SAMPLE_NAME)' the sketch runs fine. Both 'Sample Triggered' and 'Playing sample' show up on the serial monitor, so that's telling me that I have the button wired up correctly and don't have any issues with the control flow of this sketch.
However, I'm not sure what I should be trying now. I'm pretty sure I remember seeing somewhere that AudioInputAnalog records 12bit data, while AudioPlaySdRaw expects 16bit data. I also seem to remember seeing a function related to AudioInputAnalog that lets you change the resolution of 16bit, but the only thing I've been able to find this time around is analogReadResolution(), which isn't specific to AudioInputAnalog.
Am I on the right track in thinking there's some incapatibility between the sort of file AudioInputAnalog creates and the sort of file AudioPlaySdRaw is meant to play? Or is there something else I should be looking into? Any thoughts you can share would be a huge help.
Thanks!