Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Monitoring voice while recording it

  1. #1
    Junior Member
    Join Date
    Oct 2017
    Posts
    17

    Monitoring voice while recording it

    Hi everyone,

    I’m in the last phase of a project: a stand-alone old rotary phone that acts as a direct voice message answer machine when you lift the line. I use the Teensy 3.6 with the Audio Shield. All messages are recorded on an MicroSD card.

    It work very well, but to get some improvements and realism, it would be great that the user could hear his voice while leaving his message. Without this, it looks that he’s not “live” and maybe his message wasn’t recorded. This audio feedback (not a Larsen, but a witness) is very important, based on some users comments I had with my proto.

    I thought it was a special mixer configurations, or maybe just a “physical” thing to do with the electronics on the board.

    What do you think?

    Thanks for your help.

  2. #2
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    Just want to add that I will post my code! I’m just presently on my cellphone and can’t access to the files on my computer.

    I also have photos of the project, but the forum interface give me errors when I try to upload them.

  3. #3
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    Ok, here's my code, as you can see, it's a blend of multiple codes I found, thanks to generous predecessor coders:
    Code:
    //===============================================================
    //------------------- VoxPHONE PROTO - 018 ----------------------
    //---------------------- 2018 - 02 - 07 -------------------------
    //===============================================================
    
    #include <Bounce.h>
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SD_t3.h>
    #include <SerialFlash.h>
    #include <Time.h>
    #include <TimeLib.h>
    
    // write wav
    unsigned long ChunkSize = 0L;
    unsigned long Subchunk1Size = 16;
    unsigned int AudioFormat = 1;
    unsigned int numChannels = 1;
    unsigned long sampleRate = 44100;
    unsigned int bitsPerSample = 16;
    unsigned long byteRate = sampleRate * numChannels * (bitsPerSample / 8); // samplerate x channels x (bitspersample / 8)
    unsigned int blockAlign = numChannels * bitsPerSample / 8;
    unsigned long Subchunk2Size = 0L;
    unsigned long recByteSaved = 0L;
    unsigned long NumSamples = 0L;
    byte byte1, byte2, byte3, byte4;
    
    // Audio input on Teensy
    const int myInput = AUDIO_INPUT_MIC;
    
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav           playSdWav1;     //xy=235,318
    AudioSynthWaveform       waveform1;      //xy=233,360
    AudioInputI2S            i2s2;           //xy=188,136
    AudioOutputI2S           i2s1;           //xy=658,347
    AudioRecordQueue         queue1;         //xy=411,93
    AudioAnalyzePeak         peak1;          //xy=413,178
    AudioConnection          patchCord1(i2s2, 0, queue1, 0);
    AudioConnection          patchCord2(i2s2, 0, peak1, 0);
    AudioConnection          patchCord3(waveform1, 0, i2s1, 0);
    AudioConnection          patchCord4(waveform1, 0, i2s1, 1);
    AudioConnection          patchCord5(playSdWav1, 0, i2s1, 0);
    AudioConnection          patchCord6(playSdWav1, 1, i2s1, 1);
    AudioControlSGTL5000     audioShield;     //xy=103,62
    // GUItool: end automatically generated code
    
    ///const int HOME_MSG = "HOME/ACCU.WAV";
    
    // Use these with the Teensy 3.5 & 3.6 SD card
    #define SDCARD_CS_PIN    BUILTIN_SDCARD
    #define SDCARD_MOSI_PIN  11  // not actually used
    #define SDCARD_SCK_PIN   13  // not actually used
    
    #define    b1Pin       0
    //#define    b1ON        digitalWrite(b1Pin,HIGH)
    //#define    b1OFF       digitalWrite(b1Pin,LOW)
    #define    b2Pin       1
    //#define    b2ON        digitalWrite(b2Pin,HIGH)
    //#define    b2OFF       digitalWrite(b2Pin,LOW)
    #define    vPin        2
    #define    vLedON      digitalWrite(vPin,HIGH)
    #define    vLedOFF     digitalWrite(vPin,LOW)
    #define    rPin        3
    #define    rLedON      digitalWrite(rPin,HIGH)
    #define    rLedOFF     digitalWrite(rPin,LOW)
    #define    aPin        4
    #define    aLedON      digitalWrite(aPin,HIGH)
    #define    aLedOFF     digitalWrite(aPin,LOW)
    
    // Bounce objects to easily and reliably read the buttons
    Bounce lineUpButton = Bounce(b1Pin, 12);
    Bounce lineDownButton = Bounce(b2Pin, 12);
    
    // Variables globales
    int mode = 0;  // 0=Stby, 1=homeMsg, 2=beep1, 3=recording, 4=beep2, 5=stopAll
    int line; // 0=Down, 1=Up
    
    // Timers
    elapsedMillis recTime;
    elapsedMillis UpTime;
    elapsedMillis AlertTime;
    
    // The file where data is recorded
    File frec;
    
    
    //===============================================================
    //===============================================================
    //===============================================================
    
    void setup() {
      Serial.begin(9600);
      AudioMemory(60);
      pinMode(b1Pin, INPUT_PULLUP);
      pinMode(b2Pin, INPUT_PULLUP);
      pinMode(vPin, OUTPUT);
      pinMode(rPin, OUTPUT);
      pinMode(aPin, OUTPUT);
      audioShield.enable();
      audioShield.inputSelect(myInput);
      audioShield.micGain(10);  //0-63
      audioShield.volume(0.6);
      waveform1.begin(WAVEFORM_SINE);
      aLedON;
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        while (1) {
          Serial.println("Unable to access the SD card");
          rLedON;
          vLedOFF;
          delay(500);
          rLedOFF;
          vLedON;
          delay(500);
        }
      }
      vLedON;
      Serial.println("Bienvenue dans VoxPHONE");
      delay(500);
      Serial.println("VoxPHONE en Stand by");
      delay(1000);
    }
    
    void loop() {
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        line = 0;
        Serial.println("La ligne est fermee");
        //Serial.println(line);
        stopAll();
      }
      lineUpButton.update();
      if (lineUpButton.fallingEdge()) {
        line = 1;
        Serial.println("La ligne est ouverte");
        //Serial.println(line);
        vLedOFF;
        rLedON;
        if (mode == 0) startHomeMsg();
      }
      if (line == 1) {
        if (mode == 1) continueHomeMsg();
        if (mode == 2) playBeepOne();
        if (mode == 3) recordUser();
        if (mode == 4) continueRecordUser();
        if (mode == 5) playBeepTwo();
        if (mode == 6) alert();
        if (mode == 8) alertLoop();
      }
      //  // read the knob position (analog input A1 ou 15) =========================== VOLUME GLOBAL
      //  int knob = analogRead(15);
      //  float vol = (float)knob / 1280.0;
      //  audioShield.volume(vol);
    }
    
    
    
    
    
    //===============================================================
    //===============================================================
    //===============================================================
    
    void alert() { //================================================================ ALERT!
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        waveform1.amplitude(0);
        stopAll();
      } else {
        if (UpTime >= 5000) {
          Serial.println("Veuillez raccrocher");
          mode = 8;
          //      Serial.print("Mode = ");
          //      Serial.println(mode);
          waveform1.frequency(1320);
          waveform1.amplitude(0.1);
          delay(1000);
          AlertTime = 0;
        }
      }
    }
    
    void alertLoop() {
      if (AlertTime >= 15000) {
        waveform1.amplitude(0);
        rLedON;
        vLedON;
        line = 0;
        Serial.println("S.V.P. Veuillez raccrocher...");
      } else {
        waveform1.frequency(1000);
        waveform1.amplitude(0.1);
        rLedOFF;
        vLedON;
        delay(100);
        waveform1.amplitude(0);
        rLedON;
        vLedOFF;
        delay(100);
      }
    }
    
    
    
    void startHomeMsg() { //===================================================== HOME MSG
      delay(1000);
      Serial.println("Message d\'accueil");
      playSdWav1.play("HOME/ACCU.WAV");
      mode = 1;
      //  Serial.print("Mode = ");
      //  Serial.println(mode);
      delay(10); // wait for library to parse WAV info
    }
    
    void continueHomeMsg() {
      if (playSdWav1.isPlaying() == 0) {
        playSdWav1.stop();
        //Serial.println("Fin du message d\'accueil");
        mode = 2;
        //    Serial.print("Mode = ");
        //    Serial.println(mode);
      }
    }
    
    void stopHomeMsg() {
      //Serial.println("Arret du message d\'accueil");
      if (mode == 1) playSdWav1.stop();
    }
    
    
    void playBeepOne() { //===================================================== BEEP 1
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        stopAll();
      } else {
        //Serial.println("Beep 1");
        waveform1.frequency(880);
        waveform1.amplitude(0.1);
        delay(1000);
        waveform1.amplitude(0);
        mode = 3;
        //    Serial.print("Mode = ");
        //    Serial.println(mode);
      }
    }
    
    
    void recordUser() { //===================================================== RECORD
      Serial.println("Enregistrement du message");
      if (SD.exists("RECORD.WAV")) {
        SD.remove("RECORD.WAV");
      }
      frec = SD.open("RECORD.WAV", FILE_WRITE);
      if (frec) {
        queue1.begin();
        recTime = 0;
        mode = 4;
        //    Serial.print("Mode = ");
        //    Serial.println(mode);
        recByteSaved = 0L;
      }
    }
    
    void continueRecordUser() {
      if (recTime  >= 5000) {
        stopRecording();
      } else {
        if (queue1.available() >= 2) {
          byte buffer[512];
          memcpy(buffer, queue1.readBuffer(), 256);
          queue1.freeBuffer();
          memcpy(buffer + 256, queue1.readBuffer(), 256);
          queue1.freeBuffer();
          // write all 512 bytes to the SD card
          frec.write(buffer, 512);
          recByteSaved += 512;
        }
      }
    }
    
    
    void stopRecording() {
      Serial.println("Fin de l\'enregistrement");
      queue1.end();
      if (mode == 4) {
        while (queue1.available() > 0) {
          frec.write((byte*)queue1.readBuffer(), 256);
          queue1.freeBuffer();
          recByteSaved += 256;
        }
        writeOutHeader();
        frec.close();
      }
      mode = 5;
      //  Serial.print("Mode = ");
      //  Serial.println(mode);
    }
    
    void playBeepTwo() { //===================================================== BEEP 2
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        stopAll();
      } else {
        //Serial.println("Beep 2");
        waveform1.frequency(880);
        waveform1.amplitude(0.1);
        delay(1000);
        waveform1.frequency(440);
        delay(125);
        waveform1.frequency(220);
        delay(500);
        waveform1.amplitude(0);
        mode = 6;
        //    Serial.print("Mode = ");
        //    Serial.println(mode);
        UpTime = 0;
      }
    }
    
    void stopAll() { //===================================================== STOP-ALL
      if (mode == 1) playSdWav1.stop();
      if ((mode == 3) | (mode == 4)) stopRecording();
      if ((mode == 2) | (mode == 5)) waveform1.amplitude(0);
      rLedOFF;
      vLedON;
      mode = 0;
      //  Serial.print("Mode = ");
      //  Serial.println(mode);
      //  Serial.println("All reset");
      Serial.println("VoxPHONE en Stand by");
    }
    
    
    
    
    //===================================================== RAW TO WAV
    
    void writeOutHeader() { // update WAV header with final filesize/datasize
      //  NumSamples = (recByteSaved*8)/bitsPerSample/numChannels;
      //  Subchunk2Size = NumSamples*numChannels*bitsPerSample/8; // number of samples x number of channels x number of bytes per sample
      Subchunk2Size = recByteSaved;
      ChunkSize = Subchunk2Size + 36;
      frec.seek(0);
      frec.write("RIFF");
      byte1 = ChunkSize & 0xff;
      byte2 = (ChunkSize >> 8) & 0xff;
      byte3 = (ChunkSize >> 16) & 0xff;
      byte4 = (ChunkSize >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      frec.write("WAVE");
      frec.write("fmt ");
      byte1 = Subchunk1Size & 0xff;
      byte2 = (Subchunk1Size >> 8) & 0xff;
      byte3 = (Subchunk1Size >> 16) & 0xff;
      byte4 = (Subchunk1Size >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      byte1 = AudioFormat & 0xff;
      byte2 = (AudioFormat >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      byte1 = numChannels & 0xff;
      byte2 = (numChannels >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      byte1 = sampleRate & 0xff;
      byte2 = (sampleRate >> 8) & 0xff;
      byte3 = (sampleRate >> 16) & 0xff;
      byte4 = (sampleRate >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      byte1 = byteRate & 0xff;
      byte2 = (byteRate >> 8) & 0xff;
      byte3 = (byteRate >> 16) & 0xff;
      byte4 = (byteRate >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      byte1 = blockAlign & 0xff;
      byte2 = (blockAlign >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      byte1 = bitsPerSample & 0xff;
      byte2 = (bitsPerSample >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      frec.write("data");
      byte1 = Subchunk2Size & 0xff;
      byte2 = (Subchunk2Size >> 8) & 0xff;
      byte3 = (Subchunk2Size >> 16) & 0xff;
      byte4 = (Subchunk2Size >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      frec.close();
    //  Serial.println("header written");
    //  Serial.print("Subchunk2: ");
    //  Serial.println(Subchunk2Size);
    }
    
    
    //=====================================================
    //===================== TODOS =========================
    //=====================================================
    /*
    
      - Indexer les fichiers enregistres
    
      √ - Traduire en WAV les enregistrements RAW
    
      - Bouton On/Off ext
    
      - Bouton reset ext
    
      - Potentiometre de volume ext
    
    */

  4. #4
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    And here's some photos...
    Click image for larger version. 

Name:	IMG_4862.JPG 
Views:	47 
Size:	155.6 KB 
ID:	12870

    Click image for larger version. 

Name:	IMG_4864.jpg 
Views:	39 
Size:	79.0 KB 
ID:	12873

    Click image for larger version. 

Name:	IMG_4866.JPG 
Views:	38 
Size:	67.2 KB 
ID:	12872

  5. #5
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    So to return to my question, I'd like the user to hear his voice in the phone speaker when he leave his message. It already can record the voice from the phone mic, no problem.

    I thought I could maybe inspire my code with Synth examples where if you want to record your play, you should hear it at the same time. Not sure where to find that kind of example though.

    But in my case, it is audio input from the phone mic.

    Any ideas?

  6. #6
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,138
    I would do it in analog with a headphone amplifier chip to avoid any latency. Otherwise you should be able to pass the input to the output.

    BUT you have to have a mixer to combine with any playback as you're not supposed to use more than one signal at on input in the audio design tool.

    (Play from 12:45 of the audio tutorial video to hear Paul tell you this!)

    It looks like you didn't use a mixer for your two existing sources in your code. Surprised that works.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,306
    Wow, that's a really nice looking build.

    Would it be ok with you if we showed this on the website, when you've got it finished?

  8. #8
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    Thanks Oddson, it worked perfectly! I also added a if term to open and close the Mixer volume when line is open or close.

    It give now avery realistic feeling!!

  9. #9
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    Oh! Sure Paul, I’d be honored.

    I have photos for pretty all steps and tonight we will mount the phone to its cabin which is have a funny ‘70 design.

    My code changed also, so I’ll post the latest version here too.

    Thanks again!!

  10. #10
    Junior Member
    Join Date
    Oct 2017
    Posts
    17
    Hi Paul,

    Here's the latest version of the code and other photos including when it was installed yesterday. It still not finished though, many amelioration to do, but public had started to try the proto and they loved the concept..

    Thanks for your interest

    Code:
    //===============================================================
    //------------------- VoxPHONE PROTO - 021 ----------------------
    //---------------------- 2018 - 02 - 09 -------------------------
    //--------------------- NICOLAS__LETARTE ------------------------
    //===============================================================
    
    #include <Bounce.h>
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SD_t3.h>
    #include <SerialFlash.h>
    //#include <Time.h>
    //#include <TimeLib.h>
    
    // write wav
    unsigned long ChunkSize = 0L;
    unsigned long Subchunk1Size = 16;
    unsigned int AudioFormat = 1;
    unsigned int numChannels = 1;
    unsigned long sampleRate = 44100;
    unsigned int bitsPerSample = 16;
    unsigned long byteRate = sampleRate * numChannels * (bitsPerSample / 8); // samplerate x channels x (bitspersample / 8)
    unsigned int blockAlign = numChannels * bitsPerSample / 8;
    unsigned long Subchunk2Size = 0L;
    unsigned long recByteSaved = 0L;
    unsigned long NumSamples = 0L;
    byte byte1, byte2, byte3, byte4;
    
    // Audio input on Teensy
    const int myInput = AUDIO_INPUT_MIC;
    
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s2;           //xy=188,136
    AudioSynthWaveform       waveform1;      //xy=233,360
    AudioPlaySdWav           playSdWav1;     //xy=235,318
    AudioMixer4              mixer1;         //xy=398,343
    AudioRecordQueue         queue1;         //xy=411,93
    AudioAnalyzePeak         peak1;          //xy=413,178
    AudioOutputI2S           i2s1;           //xy=658,347
    AudioConnection          patchCord1(i2s2, 0, queue1, 0);
    AudioConnection          patchCord2(i2s2, 0, peak1, 0);
    AudioConnection          patchCord6(i2s2, 0, mixer1, 1);
    AudioConnection          patchCord3(waveform1, 0, mixer1, 2);
    AudioConnection          patchCord4(waveform1, 0, mixer1, 3);
    AudioConnection          patchCord5(playSdWav1, 0, mixer1, 0);
    //AudioConnection          patchCord6(playSdWav1, 1, mixer1, 1);
    AudioConnection          patchCord7(mixer1, 0, i2s1, 0);
    AudioConnection          patchCord8(mixer1, 0, i2s1, 1);
    AudioControlSGTL5000     audioShield;     //xy=103,62
    // GUItool: end automatically generated code
    
    ///const int HOME_MSG = "HOME/ACCU.WAV";
    
    // Use these with the Teensy 3.5 & 3.6 SD card
    #define SDCARD_CS_PIN    BUILTIN_SDCARD
    #define SDCARD_MOSI_PIN  11  // not actually used
    #define SDCARD_SCK_PIN   13  // not actually used
    
    #define    b1Pin       0
    //#define    b1ON        digitalWrite(b1Pin,HIGH)
    //#define    b1OFF       digitalWrite(b1Pin,LOW)
    #define    b2Pin       1
    //#define    b2ON        digitalWrite(b2Pin,HIGH)
    //#define    b2OFF       digitalWrite(b2Pin,LOW)
    #define    vPin        2
    #define    vLedON      digitalWrite(vPin,HIGH)
    #define    vLedOFF     digitalWrite(vPin,LOW)
    #define    rPin        3
    #define    rLedON      digitalWrite(rPin,HIGH)
    #define    rLedOFF     digitalWrite(rPin,LOW)
    #define    aPin        4
    #define    aLedON      digitalWrite(aPin,HIGH)
    #define    aLedOFF     digitalWrite(aPin,LOW)
    
    // Bounce objects to easily and reliably read the buttons
    Bounce lineUpButton = Bounce(b1Pin, 12);
    Bounce lineDownButton = Bounce(b2Pin, 12);
    
    // Variables globales
    int mode = 0;  // 0=Stby, 1=homeMsg, 2=beep1, 3=recording, 4=beep2, 5=stopAll
    int line; // 0=Down, 1=Up
    
    // Timers
    elapsedMillis recTime;
    elapsedMillis UpTime;
    elapsedMillis AlertTime;
    
    // The file where data is recorded
    File frec;
    
    
    //===============================================================
    //===============================================================
    //===============================================================
    
    void setup() {
      Serial.begin(9600);
      AudioMemory(60);
      pinMode(b1Pin, INPUT_PULLUP);
      pinMode(b2Pin, INPUT_PULLUP);
      pinMode(vPin, OUTPUT);
      pinMode(rPin, OUTPUT);
      pinMode(aPin, OUTPUT);
      audioShield.enable();
      audioShield.inputSelect(myInput);
      audioShield.micGain(10);  //0-63
      audioShield.volume(0.6);
      mixer1.gain(0, 0.9); // Accueil
      mixer1.gain(1, 0.4); // Micro
      mixer1.gain(2, 0.4); // Synth L
      //  mixer1.gain(3, 0.4); // Synth R
      waveform1.begin(WAVEFORM_SINE);
      aLedON;
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        while (1) {
          Serial.println("Impossible d\'acceder à la carte SD");
          rLedON;
          vLedOFF;
          delay(500);
          rLedOFF;
          vLedON;
          delay(500);
        }
      }
      vLedON;
      Serial.println("Bienvenue dans VoxPHONE");
      delay(500);
      Serial.println("VoxPHONE en Stand by");
      delay(1000);
    }
    
    void loop() {
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        line = 0;
        audioShield.volume(0);
        Serial.println("La ligne est fermee");
        if (mode > 0) stopAll();
      }
      lineUpButton.update();
      if (lineUpButton.fallingEdge()) {
        line = 1;
        audioShield.volume(0.6);
        Serial.println("La ligne est ouverte");
        vLedOFF;
        rLedON;
        if (mode == 0) startHomeMsg();
      }
      if (line == 1) {
        if (mode == 1) continueHomeMsg();
        if (mode == 2) playBeepOne();
        if (mode == 3) recordUser();
        if (mode == 4) continueRecordUser();
        if (mode == 5) playBeepTwo();
        if (mode == 6) alert();
        if (mode == 8) alertLoop();
      }
      //  // read the knob position (analog input A1 ou 15) =========================== VOLUME GLOBAL
      //  int knob = analogRead(15);
      //  float vol = (float)knob / 1280.0;
      //  audioShield.volume(vol);
    }
    
    
    
    
    
    //=======================================================================================
    //=======================================================================================
    //=======================================================================================
    
    void alert() { //================================================================ ALERT!
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        waveform1.amplitude(0);
        stopAll();
      } else {
        if (UpTime >= 10000) {
          Serial.println("Veuillez raccrocher");
          mode = 8;
          waveform1.frequency(1320);
          waveform1.amplitude(0.1);
          delay(1000);
          AlertTime = 0;
        }
      }
    }
    
    void alertLoop() {
      if (AlertTime >= 15000) {
        waveform1.amplitude(0);
        rLedON;
        vLedON;
        line = 0;
        Serial.println("S.V.P. Veuillez raccrocher...");
      } else {
        waveform1.frequency(1000);
        waveform1.amplitude(0.1);
        rLedOFF;
        vLedON;
        delay(100);
        waveform1.amplitude(0);
        rLedON;
        vLedOFF;
        delay(100);
      }
    }
    
    
    void startHomeMsg() { //===================================================== HOME MSG
      delay(1000);
      Serial.println("Message d\'accueil");
      playSdWav1.play("HOME/ACCU.WAV");
      mode = 1;
      delay(10); // wait for library to parse WAV info
    }
    
    void continueHomeMsg() {
      if (playSdWav1.isPlaying() == 0) {
        playSdWav1.stop();
        mode = 2;
      }
    }
    
    void stopHomeMsg() {
      if (mode == 1) playSdWav1.stop();
    }
    
    
    void playBeepOne() { //===================================================== BEEP 1
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        stopAll();
      } else {
        waveform1.frequency(880);
        waveform1.amplitude(0.1);
        delay(1000);
        waveform1.amplitude(0);
        mode = 3;
      }
    }
    
    
    void recordUser() { //===================================================== RECORD
      Serial.println("Enregistrement du message");
      String fileName = String();
      unsigned int filenumber = 1;
      while (!filenumber == 0) {
        fileName = "VP_";
        fileName += filenumber;
        fileName += ".WAV";
        char charFileName[fileName.length() + 1];
        fileName.toCharArray(charFileName, sizeof(charFileName));
        if (SD.exists(charFileName)) {
          filenumber++;
        }
        else {
          //File dataFile = SD.open(charFileName, FILE_WRITE);
          frec = SD.open(charFileName, FILE_WRITE);
          filenumber = 0;
        }
        //Serial.println("Nouveau fichier audio créé");
      }
      if (frec) {
        queue1.begin();
        recTime = 0;
        mode = 4;
        recByteSaved = 0L;
      }
    }
    
    void continueRecordUser() {
      if (recTime  >= 90000) { // 90000 ou 1:30
        stopRecording();
      } else {
        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;
          // write all 512 bytes to the SD card
          frec.write(buffer, 512);
          //Serial.print("SD write, us=");
          //Serial.println(usec);
          recByteSaved += 512;
        }
      }
    }
    
    void stopRecording() {
      Serial.println("Fin de l\'enregistrement");
      queue1.end();
      if (mode == 4) {
        while (queue1.available() > 0) {
          frec.write((byte*)queue1.readBuffer(), 256);
          queue1.freeBuffer();
          recByteSaved += 256;
        }
        writeOutHeader();
        frec.close();
      }
      mode = 5;
    }
    
    
    void playBeepTwo() { //===================================================== BEEP 2
      lineDownButton.update();
      if (lineDownButton.fallingEdge()) {
        stopAll();
      } else {
        waveform1.frequency(880);
        waveform1.amplitude(0.1);
        delay(1000);
        waveform1.frequency(440);
        delay(125);
        waveform1.frequency(220);
        delay(500);
        waveform1.amplitude(0);
        mode = 6;
        UpTime = 0;
      }
    }
    
    
    void stopAll() { //====================================================================================== STOP-ALL
      if (mode == 1) playSdWav1.stop();
      if ((mode == 3) | (mode == 4)) stopRecording();
      if ((mode == 2) | (mode == 5)) waveform1.amplitude(0);
      rLedOFF;
      vLedON;
      mode = 0;
      Serial.println("VoxPHONE en Stand by");
    }
    
    
    void writeOutHeader() { //============================================== RAW TO WAV
      Subchunk2Size = recByteSaved;
      ChunkSize = Subchunk2Size + 36;
      frec.seek(0);
      frec.write("RIFF");
      byte1 = ChunkSize & 0xff;
      byte2 = (ChunkSize >> 8) & 0xff;
      byte3 = (ChunkSize >> 16) & 0xff;
      byte4 = (ChunkSize >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      frec.write("WAVE");
      frec.write("fmt ");
      byte1 = Subchunk1Size & 0xff;
      byte2 = (Subchunk1Size >> 8) & 0xff;
      byte3 = (Subchunk1Size >> 16) & 0xff;
      byte4 = (Subchunk1Size >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      byte1 = AudioFormat & 0xff;
      byte2 = (AudioFormat >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      byte1 = numChannels & 0xff;
      byte2 = (numChannels >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      byte1 = sampleRate & 0xff;
      byte2 = (sampleRate >> 8) & 0xff;
      byte3 = (sampleRate >> 16) & 0xff;
      byte4 = (sampleRate >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      byte1 = byteRate & 0xff;
      byte2 = (byteRate >> 8) & 0xff;
      byte3 = (byteRate >> 16) & 0xff;
      byte4 = (byteRate >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      byte1 = blockAlign & 0xff;
      byte2 = (blockAlign >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      byte1 = bitsPerSample & 0xff;
      byte2 = (bitsPerSample >> 8) & 0xff;
      frec.write(byte1);  frec.write(byte2);
      frec.write("data");
      byte1 = Subchunk2Size & 0xff;
      byte2 = (Subchunk2Size >> 8) & 0xff;
      byte3 = (Subchunk2Size >> 16) & 0xff;
      byte4 = (Subchunk2Size >> 24) & 0xff;
      frec.write(byte1);  frec.write(byte2);  frec.write(byte3);  frec.write(byte4);
      frec.close();
      //  Serial.println("header written");
      //  Serial.print("Subchunk2: ");
      //  Serial.println(Subchunk2Size);
    }
    
    
    //=====================================================
    //===================== TODOS =========================
    //=====================================================
    /*
    
      √- Indexer les fichiers enregistres
    
      √ - Traduire en WAV les enregistrements RAW
    
      √- Connecteurs électriques slims + rallonger le fil
    
      - Bouton On/Off ext
    
      √- Bouton reset ext
    
      - Potentiometre de volume ext
    
      - LED différent lorsqu'un utilisateur enregistre son message
    
      - Pouvoir enregistrer le message d'accueil à même le VoxPhone
    
      - Pouvoir toujours détecter la présence de la carte SD !!!!!
    
      - Port Micro USB F 
    
    */
    Click image for larger version. 

Name:	IMG_4859.JPG 
Views:	32 
Size:	122.3 KB 
ID:	12897

    Click image for larger version. 

Name:	IMG_4860.JPG 
Views:	30 
Size:	140.0 KB 
ID:	12898

    Click image for larger version. 

Name:	IMG_4920.JPG 
Views:	32 
Size:	130.0 KB 
ID:	12900

    Click image for larger version. 

Name:	IMG_4950.JPG 
Views:	34 
Size:	173.7 KB 
ID:	12903

    Click image for larger version. 

Name:	IMG_4951.jpg 
Views:	35 
Size:	230.4 KB 
ID:	12905

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •