Hi everybody. Long time no talk here.
I'm making an object like a very simple recorder with two buttons with LEDs inside. It is aimed for children. If they press the green button they listen an instruction saying to press the other button while singing a song or telling a story or whatever else and after releasing the button they will listen what they just recorded.
The problem is that I would like to have all recordings recorded at the SD Card for later use, but if I let them being add at the end of the previous one each children will have to listen to all recordings to listen to yours.
The "recording" example prevents that simply deleting the existing file and making a new one.
It's also currently not possible to rename the files or dynamically create file names with the SD library (I'm using a Teensy 3.2 with the Audio Shield b.t.w.).
Looking at the Audio System Tool at AudioPlaySdRaw I can find this:
positionMillis();
While playing, return the current time offset, in milliseconds. When not playing, the return from this function is undefined.
lengthMillis();
Return the total length of the current sound clip, in milliseconds. When not playing, the return from this function is undefined.
And now, finally comes the the question: is it possible to use these methods to start at the end of the file before the newest recordings storing one or the other number and using it to play from that point?
Kind regards,
Gil
I'm making an object like a very simple recorder with two buttons with LEDs inside. It is aimed for children. If they press the green button they listen an instruction saying to press the other button while singing a song or telling a story or whatever else and after releasing the button they will listen what they just recorded.
The problem is that I would like to have all recordings recorded at the SD Card for later use, but if I let them being add at the end of the previous one each children will have to listen to all recordings to listen to yours.
The "recording" example prevents that simply deleting the existing file and making a new one.
It's also currently not possible to rename the files or dynamically create file names with the SD library (I'm using a Teensy 3.2 with the Audio Shield b.t.w.).
Looking at the Audio System Tool at AudioPlaySdRaw I can find this:
positionMillis();
While playing, return the current time offset, in milliseconds. When not playing, the return from this function is undefined.
lengthMillis();
Return the total length of the current sound clip, in milliseconds. When not playing, the return from this function is undefined.
And now, finally comes the the question: is it possible to use these methods to start at the end of the file before the newest recordings storing one or the other number and using it to play from that point?
Code:
// based on examples: play wav, do more while playing, recorder
// instrucao: pin 0
// gravar: pin 1
#define BUTTON_PIN_1 0
#define BUTTON_PIN_2 1
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce2.h>
AudioInputI2S audioIn;
AudioOutputI2S audioOut;
// AudioAnalyzePeak peak1;
AudioRecordQueue record1;
AudioPlaySdWav playWav1;
AudioPlaySdRaw playRaw1;
AudioConnection patchCord1(audioIn, 0, audioOut, 0);
AudioConnection patchCord2(audioIn, 1, audioOut, 1);
AudioConnection patchCord3(audioIn, 0, record1, 0);
AudioConnection patchCord4(playWav1, 0, audioOut, 0);
AudioConnection patchCord5(playWav1, 1, audioOut, 1);
AudioConnection patchCord6(playRaw1, 0, audioOut, 0);
AudioConnection patchCord7(playRaw1, 0, audioOut, 1);
AudioControlSGTL5000 sgtl5000_1;
Bounce buttonInstru = Bounce();
Bounce buttonRecord = Bounce(); // 8 = 8 ms debounce time
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
const byte recLedPin2 = 2;
const byte recLedPin3 = 3;
const byte instrLedPin4 = 4;
const byte instrLedPin5 = 5;
File frec;
//character array to store changing filename
char fname[11];
unsigned int i = 0;
void setup() {
Serial.begin(9600);
pinMode( BUTTON_PIN_1, INPUT_PULLUP );
buttonInstru.attach( BUTTON_PIN_1 );
buttonInstru.interval(5);
pinMode( BUTTON_PIN_2, INPUT_PULLUP );
buttonRecord.attach( BUTTON_PIN_2 );
buttonRecord.interval(5);
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
AudioMemory(60);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
sgtl5000_1.volume(0.6);
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);
}
}
sprintf(fname,"%d.RAW", (i++) % 999999 );
Serial.println(fname);
delay(1000);
}
byte modo = 0;
// 0 = antes_de_instruir, 1 = instruindo, 2 = preparado_para_gravar, 3 = gravando, 4 = tocando a gravacao.
elapsedMillis blinkTime;
byte ledState = LOW; // ledState used to set the LED
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long interv = 1000; // interval at which to blink (milliseconds)
void loop() {
unsigned long currentMillis = millis();
buttonInstru.update();
buttonRecord.update();
if ( buttonInstru.fallingEdge() ) {
if ( (modo == 0) || ( modo == 2 ) ) {
Serial.println("instru");
modo = 1;
}
}
if (modo == 0) {
digitalWrite(recLedPin2, LOW);
digitalWrite(recLedPin3, LOW);
if (currentMillis - previousMillis > interv) {
previousMillis = currentMillis;
ledState = !ledState;
digitalWrite(instrLedPin4, ledState);
digitalWrite(instrLedPin5, ledState);
}
}
if (modo == 1) {
ledState = HIGH;
digitalWrite(instrLedPin4, ledState);
digitalWrite(instrLedPin5, ledState);
if (playWav1.isPlaying() == false) {
playWav1.play("INSTRUCA.WAV");
delay(5); // wait for library to parse WAV info
}
modo = 2;
}
if (modo == 2) {
if (!playWav1.isPlaying()) {
digitalWrite(instrLedPin4, LOW);
digitalWrite(instrLedPin5, LOW);
if (currentMillis - previousMillis > interv) {
previousMillis = currentMillis;
ledState = !ledState;
digitalWrite(recLedPin2, ledState);
digitalWrite(recLedPin3, ledState);
}
}
}
if (buttonRecord.fallingEdge()) {
if ( modo == 0 || modo == 2 ) {
modo = 3;
if (SD.exists("RECORD.RAW")) {
//sprintf(fname,"%d.RAW", (i++) % 999999 );
SD.remove("RECORD.RAW");
}
frec = SD.open("RECORD.RAW", FILE_WRITE);
if (frec) {
record1.begin();
}
}
}
if (modo == 3) {
ledState = HIGH;
digitalWrite(recLedPin2, ledState);
digitalWrite(recLedPin3, ledState);
if (record1.available() >= 2) {
byte buffer[512];
memcpy(buffer, record1.readBuffer(), 256);
record1.freeBuffer();
memcpy(buffer+256, record1.readBuffer(), 256);
record1.freeBuffer();
// elapsedMicros usec = 0;
frec.write(buffer, 512);
}
}
if (buttonRecord.risingEdge()) {
if (modo == 3) {
modo = 4;
Serial.println("gravou");
record1.end();
while (record1.available() > 0) {
frec.write((byte*)record1.readBuffer(), 256);
record1.freeBuffer();
}
frec.close();
playRaw1.play("RECORD.RAW");
delay(5);
modo = 4;
}
}
if (modo == 4) {
if ( playRaw1.isPlaying() ) {
if ( blinkTime > 1000) {
ledState = !ledState;
digitalWrite(2, ledState);
digitalWrite(3, !ledState);
digitalWrite(4, ledState);
digitalWrite(5, !ledState);
}
} else {
modo = 0;
//sprintf(fname,"%8ld.RAW", random(1,10000000) );
}
}
}
// 0 = tudo tranquilo, 1 = instruindo, 2 = preparado_para_gravar, 3 = gravando, 4 = tocando
Kind regards,
Gil