Play .RAW file starting from a certain position.

Status
Not open for further replies.

gilFuser

Member
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?

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
 
This works for me for creating filenames at runtime:
Code:
        int filenr = 55;
	String name = "raw/" + String(filenr) + ".raw";
	const char *filename = name.c_str();
        frec = SD.open(filename, FILE_WRITE);
 
Status
Not open for further replies.
Back
Top