Hi, I have just got a Teensy 4.0 using the Teensy Audio Adapter board (https://www.pjrc.com/store/teensy3_audio.html). So I have put together some code, which allows me to record audio directly from a microphone, connected to the Audio Adapter board. Which works! However, it only seems to record 3 seconds before just stopping. There is no interrupt to the stop recording pin and that seems to be handled fine when I send a low signal to the pin. I have attached the source code and the output from the serial monitor for the SD write speed and interrupt serial notification. Interesting to see that the SD write speed becomes extermely fast, presumably around the time the audio stops recording. Any advice on how to increase the duration of the audio recording please? Thanks in advance.
Output:
Record Button Press
startRecording
SD write, us=196
SD write, us=195
SD write, us=195
SD write, us=195
SD write, us=195
Continues writing "SD write, us=195" for a while.... Then presents:
SD write, us=0
SD write, us=1
SD write, us=0
SD write, us=0
SD write, us=1
SD write, us=0
SD write, us=0
SD write, us=1
SD write, us=0
SD write, us=0
SD write, us=1
SD write, us=0
Stop Button Press
stopRecording
Code:
#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioPlaySdWav playSdWav1;
AudioInputI2S i2s2; //xy=105,63
AudioAnalyzePeak peak1; //xy=278,108
AudioRecordQueue queue1; //xy=281,63
AudioPlaySdRaw playRaw1; //xy=302,157
AudioOutputI2S i2s1; //xy=470,120
AudioConnection patchCord1(i2s2, 0, queue1, 0);
AudioConnection patchCord2(i2s2, 0, peak1, 0);
AudioConnection patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection patchCord4(playRaw1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=265,212
// GUItool: end automatically generated code
Bounce buttonRecord = Bounce(0, 8);
Bounce buttonStop = Bounce(1, 8); // 8 = 8 ms debounce time
Bounce buttonPlay = Bounce(2, 8);
const int myInput = AUDIO_INPUT_MIC;
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
int mode = 0; // 0=stopped, 1=recording, 2=playing
char filename[15];
File frec;
void setup() {
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
// uses this memory to buffer incoming audio.
AudioMemory(60);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(myInput);
sgtl5000_1.volume(0.5);
sgtl5000_1.micGain(60);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
// stop here if no SD card, but print a message
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
}
void loop() {
// First, read the buttons
buttonRecord.update();
buttonStop.update();
buttonPlay.update();
// Respond to button presses
if (buttonRecord.fallingEdge()) {
Serial.println("Record Button Press");
if (mode == 2) stopPlaying();
if (mode == 0) startRecording();
}
if (buttonStop.fallingEdge()) {
Serial.println("Stop Button Press");
if (mode == 1) stopRecording();
if (mode == 2) stopPlaying();
}
if (buttonPlay.fallingEdge()) {
Serial.println("Play Button Press");
if (mode == 1) stopRecording();
if (mode == 0) startPlaying();
}
// If we're playing or recording, carry on...
if (mode == 1) {
continueRecording();
}
if (mode == 2) {
continuePlaying();
}
// when using a microphone, continuously adjust gain
if (myInput == AUDIO_INPUT_MIC) adjustMicLevel();
}
void startRecording() {
Serial.println("startRecording");
for (uint8_t i=0; i<9999; i++) {
// Format the counter as a five-digit number with leading zeroes, followed by file extension
snprintf(filename, 11, " %05d.RAW", i);
// Create if does not exist, do not open existing, write, sync after write
if (!SD.exists(filename)) {
break;
}
}
frec = SD.open(filename, FILE_WRITE);
if (frec) {
queue1.begin();
mode = 1;
}
}
void continueRecording() {
if (queue1.available() >= 2) {
byte buffer[512];
memcpy(buffer, queue1.readBuffer(), 256);
queue1.freeBuffer();
memcpy(buffer+256, queue1.readBuffer(), 256);
queue1.freeBuffer();
elapsedMicros usec = 0;
frec.write(buffer, 512);
Serial.print("SD write, us=");
Serial.println(usec);
}
}
void stopRecording() {
Serial.println("stopRecording");
queue1.end();
if (mode == 1) {
while (queue1.available() > 0) {
frec.write((byte*)queue1.readBuffer(), 256);
queue1.freeBuffer();
}
frec.close();
}
mode = 0;
}
void startPlaying() {
Serial.println("startPlaying");
playRaw1.play("RECORD.RAW");
mode = 2;
}
void continuePlaying() {
if (!playRaw1.isPlaying()) {
playRaw1.stop();
mode = 0;
}
}
void stopPlaying() {
Serial.println("stopPlaying");
if (mode == 2) playRaw1.stop();
mode = 0;
}
void adjustMicLevel() {
// TODO: read the peak1 object and adjust sgtl5000_1.micGain()
// if anyone gets this working, please submit a github pull request :-)
}
Output:
Record Button Press
startRecording
SD write, us=196
SD write, us=195
SD write, us=195
SD write, us=195
SD write, us=195
Continues writing "SD write, us=195" for a while.... Then presents:
SD write, us=0
SD write, us=1
SD write, us=0
SD write, us=0
SD write, us=1
SD write, us=0
SD write, us=0
SD write, us=1
SD write, us=0
SD write, us=0
SD write, us=1
SD write, us=0
Stop Button Press
stopRecording