Forum Rule: Always post complete source code & details to reproduce any issue!
Page 6 of 6 FirstFirst ... 4 5 6
Results 126 to 149 of 149

Thread: Teensy 4.0 - based Audio Guestbook

  1. #126
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,976
    Quote Originally Posted by mjs513 View Post
    I believe that @KurtE mentioned here: https://forum.pjrc.com/threads/68139...l=1#post293743, that MACs don't natively support MTP. He had to download the free version of something called OpenMTP. I personally dont use MACs so cant be of much further help but maybe someone else will jump in.
    I do have a MAC, but I don't use it very much. It is about a 10-year-old notebook.

    As @mjs513 mentioned, I have experimented some with OpenMTP. Also have played iwth Android File Transfer:
    https://www.android.com/filetransfer/

    But I am no expert in this. I primarily used Windows. Secondarily use Ubuntu and when I need to have the MAC to try things out on.

  2. #127
    Junior Member
    Join Date
    Sep 2022
    Posts
    2
    Quote Originally Posted by KurtE View Post
    I do have a MAC, but I don't use it very much. It is about a 10-year-old notebook.

    As @mjs513 mentioned, I have experimented some with OpenMTP. Also have played iwth Android File Transfer:
    https://www.android.com/filetransfer/

    But I am no expert in this. I primarily used Windows. Secondarily use Ubuntu and when I need to have the MAC to try things out on.
    Thanks, @KurtE and @mjs513 , I will give this a try! I figured mac was the main issue. I have a couple of old Surface Pros I can pull out if needed!

  3. #128
    Junior Member
    Join Date
    Jul 2022
    Posts
    13

    Missing parts to record

    I have used the codes and the phone is now recording, however, while recording the wav files, small parts are failing to record at a regular interval.. for example, while recoding counting number (1-30) - 13 & 26 missing... any suggestion to fix this?



    Code:
    /**
     * Audio Guestbook, Copyright (c) 2022 Playful Technologyhttps://forum.pjrc.com/images/smilies/smile.png
     * 
     * Tested using a Teensy 4.0 with Teensy Audio Shield, although should work 
     * with minor modifications on other similar hardware
     * 
     * When handset is lifted, a pre-recorded greeting message is played, followed by a tone.
     * Then, recording starts, and continues until the handset is replaced.
     * Playback button allows all messages currently saved on SD card through earpiece 
     * 
     * follow the detailed instructions here:
     * https://github.com/DD4WH/audio-guestbook/blob/main/README.md
     * 
     * 
     *   the sketch only works with the latest Teensyduino 1.57 version, so please update your Arduino IDE AND your Teensyduino to Arduino version 1.8.19 and the latest Teensyduino version 1.57
     *   download the following library, unzip it and put it into your local Arduino folder (on my computer, the local Arduino folder is: "C:/Users/DD4WH/Documents/Arduino/libraries/"): https://github.com/KurtE/MTP_Teensy
     *   compile with option: "Serial + MTP Disk (Experimental)"" and with option "CPU speed: 150MHz" (this can save about 70% of battery power)
     *
     * Modifications by Frank DD4WH, August 2022
     * - now uses a Teensy 4.1 with built-in SD card (faster via SDIO), if you want to use a Teensy 4.0, uncomment in the USER CONFIGURATION below
     * - Files are saved on SD card as 44.1kHz, 16-bit mono WAV audio files 
     * - if you plug in the telephones´ USB cable into your computer, the telephone is mounted as a drive and you can acess the recordings 
     * - if there is no "greeting.wav" message on the SD card, the telephone automatically plays an invitation to record this message and then you can record the greeting message 
     * - if you want to record the greeting message again, just delete it from the telephone and lift the handheld again to record the greeting message  
     * --> if your handheld contact switch opens on lifting, simply uncomment in the USER CONFIGURATION below, everything else is done by the software
     * 
     * GNU GPL v3.0 license
     * 
     */
    
    #include <Bounce.h>
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <TimeLib.h>
    #include <MTP_Teensy.h>  // this library has to be downloaded separately (https://github.com/KurtE/MTP_Teensy)
    // unzip the downloaded file and its content into your local Arduino folder (on my computer, the local Arduino folder is: "C:/Users/DD4WH/Documents/Arduino/libraries/")
    
    /***************************************************************************************************************************************************/
    /**USER CONFIGURATION ******************************************************************************************************************************/
    /**COMMENT / UNCOMMENT ACCORDING TO YOUR HARDWARE **************************************************************************************************/
    /***************************************************************************************************************************************************/
    
    // comment this out, if your handheld OPENS the contact on lift
    // use a digital voltmeter to find out
    #define HANDHELD_CLOSES_ON_LIFT
    
    // comment this out, if you want to record your greeting message with an external recorder
    // leave as-is if you want to have the telephone automatically switch to recording the greeting message, in case there is no "greeting.wav" on the SD card 
    #define AUTO_GREETING_MESSAGE
    
    // comment out, if you use a Teensy 4.0 (and thus the SD card slot on the audio board)
    // if you leave this as-is, you have to use the built-in SD card slot on the Teensy 4.1, NOT the SD card slot on the audio board 
    //#define TEENSY_41
    
    /***************************************************************************************************************************************************/
    /**END OF USER CONFIGURATION ***********************************************************************************************************************/
    /***************************************************************************************************************************************************/
    /***************************************************************************************************************************************************/
    
    // Define pins used by Teensy Audio Shield
    #ifdef TEENSY_41
    #define SDCARD_CS_PIN    BUILTIN_SDCARD
    #else
    #define SDCARD_CS_PIN    10
    #endif
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    // And those used for inputs
    // You can choose the pins you use here:
    //#define HOOK_PIN 40
    //#define PLAYBACK_BUTTON_PIN 41
    #define HOOK_PIN 0              // this is the default
    #define PLAYBACK_BUTTON_PIN 1   // this is the default
    
    
    // GLOBALS
    // Audio initialisation code can be generated using the GUI interface at https://www.pjrc.com/teensy/gui/
    // Inputs
    AudioSynthWaveform          waveform1; // To create the "beep" sfx
    AudioInputI2S               i2s2; // I2S input from microphone on audio shield
    AudioPlaySdWav              playWav1; // Play 44.1kHz 16-bit PCM greeting WAV file
    AudioRecordQueue            queue1; // Creating an audio buffer in memory before saving to SD
    AudioMixer4                 mixer; // Allows merging several inputs to same output
    AudioOutputI2S              i2s1; // I2S interface to Speaker/Line Out on Audio shield
    AudioConnection patchCord1(waveform1, 0, mixer, 0); // wave to mixer 
    AudioConnection patchCord3(playWav1, 0, mixer, 1); // wav file playback mixer
    AudioConnection patchCord4(mixer, 0, i2s1, 0); // mixer output to speaker (L)
    AudioConnection patchCord6(mixer, 0, i2s1, 1); // mixer output to speaker (R)
    AudioConnection patchCord5(i2s2, 0, queue1, 0); // mic input to queue (L)
    AudioControlSGTL5000      sgtl5000_1;
    
    // Filename to save audio recording on SD card
    char filename[15];
    // The file object itself
    File frec;
    
    // Use long 40ms debounce time on both switches
    Bounce buttonRecord = Bounce(HOOK_PIN, 40);
    Bounce buttonPlay = Bounce(PLAYBACK_BUTTON_PIN, 40);
    
    // Keep track of current state of the device
    enum Mode {Initialising, Ready, Prompting, Recording, Playing, Recording_Greeting};
    Mode mode = Mode::Initialising;
    
    float beep_volume = 0.04f; // not too loud :-)
    
    // variables for writing to WAV file
    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;
    
    
    void setup() {
    
      Serial.begin(9600);
      while (!Serial && millis() < 5000) {
        // wait for serial port to connect.
      }
      Serial.println("Serial set up correctly");
      print_mode();
      // Configure the input pins
      pinMode(HOOK_PIN, INPUT_PULLUP);
      pinMode(PLAYBACK_BUTTON_PIN, INPUT_PULLUP);
    
      // Audio connections require memory, and the record queue
      // uses this memory to buffer incoming audio.
      AudioMemory(60);
    
      // Enable the audio shield, select input, and enable output
      sgtl5000_1.enable();
      // Define which input on the audio shield to use (AUDIO_INPUT_LINEIN / AUDIO_INPUT_MIC)
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.adcHighPassFilterDisable(); //
      sgtl5000_1.volume(0.85);
    
      mixer.gain(0, 1.0f);
      mixer.gain(1, 1.0f);
    
      // Play a beep to indicate system is online
      waveform1.begin(beep_volume, 440, WAVEFORM_SINE);
      wait(1000);
      waveform1.amplitude(0);
      delay(1000);
    
      // Initialize the SD card
    #ifndef TEENSY_41   // assumes that you are using the SD card slot of the AUDIO BOARD
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
    #endif  
      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);
        }
      }
        else Serial.println("SD card correctly initialized");
    
      // mandatory to begin the MTP session.
        MTP.begin();
    
      // Add SD Card
        MTP.addFilesystem(SD, "Gruenkohls Audio guestbook"); // choose a nice name for the SD card volume to appear in your file explorer
        Serial.println("Added SD card via MTP");
        
        // Value in dB
    //  sgtl5000_1.micGain(15);
      sgtl5000_1.micGain(8); // much lower gain is required for the AOM5024 electret capsule
    
      // Synchronise the Time object used in the program code with the RTC time provider.
      // See https://github.com/PaulStoffregen/Time
      setSyncProvider(getTeensy3Time);
      
      // Define a callback that will assign the correct datetime for any file system operations
      // (i.e. saving a new audio recording onto the SD card)
      FsDateTime::setCallback(dateTime);
    
      mode = Mode::Ready; print_mode();
    }
    
    void loop() { //1
      // First, read the buttons
      buttonRecord.update();
      buttonPlay.update();
    
      switch(mode)
      { //2
        case Mode::Ready:
          // Falling edge occurs when the handset is lifted --> 611 telephone
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if (buttonRecord.fallingEdge()) 
    #else
          if (buttonRecord.risingEdge()) 
    #endif
          {
            Serial.println("Handset lifted");
            mode = Mode::Prompting; print_mode();
          } //3
          else if(buttonPlay.fallingEdge()) 
          { //4
            //playAllRecordings();
            playLastRecording();
          } //4
          break;
    
        case Mode::Prompting:
          // Wait a second for users to put the handset to their ear
          wait(1000);
    
    #if defined(AUTO_GREETING_MESSAGE)
    
        if (!SD.exists("greeting.wav")) 
        { //5
          mode = Mode::Recording_Greeting;
          break;
        } //5
    #endif
         
          // Play the greeting inviting them to record their message
          playWav1.play("greeting.wav");    
          // Wait until the  message has finished playing
    //      while (playWav1.isPlaying()) {
          while (!playWav1.isStopped()) 
          { //6
            // Check whether the handset is replaced
            buttonRecord.update();
            buttonPlay.update();
            // Handset is replaced
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if (buttonRecord.risingEdge()) 
    #else
          if (buttonRecord.fallingEdge())
    #endif
            {
              playWav1.stop();
              mode = Mode::Ready; print_mode();
              return;
            } //7
            if(buttonPlay.fallingEdge()) 
            { //8
              playWav1.stop();
              //playAllRecordings();
              playLastRecording();
              return;
            } //8
            
          }  // 
          
          // Debug message
          Serial.println("Starting Recording");
          // Play the tone sound effect
          waveform1.begin(beep_volume, 440, WAVEFORM_SINE);
          wait(1250);
          waveform1.amplitude(0);
          // Start the recording function
          startRecording();
          break;
    
        case Mode::Recording:
          // Handset is replaced
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if (buttonRecord.risingEdge()) 
    #else
          if (buttonRecord.fallingEdge())
    #endif
          { //9  
          // Debug log
            Serial.println("Stopping Recording");
            // Stop recording
            stopRecording();
            // Play audio tone to confirm recording has ended
            end_Beep();
          } //9
          else 
          { //10
            continueRecording();
          } // 10
          break;
    
        case Mode::Playing: // to make compiler happy
          break;  
    
        case Mode::Initialising: // to make compiler happy
          break;  
    
        case Mode::Recording_Greeting: // to make compiler happy
          startRecordingGreeting();
          mode = Mode::Recording;
          break;  
          } // 2 end switch   
      MTP.loop();  //This is mandatory to be placed in the loop code.
    } // 1 end loop
    
    void startRecordingGreeting() {
        if (SD.exists("greeting.wav")) {
          return;
        }
        // play message "Please record Greeting message now !" 
        playWav1.play("invitation_greeting.wav");
        while (!playWav1.isStopped()) { // this works for playWav
          buttonPlay.update();
          buttonRecord.update();
          // Button is pressed again
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if(buttonPlay.fallingEdge() || buttonRecord.risingEdge())  
    #else
          if(buttonPlay.fallingEdge() || buttonRecord.fallingEdge())  
    #endif
          { 
            playWav1.stop();
            mode = Mode::Ready; print_mode();
            return;
          }   
        }
        // play beep
        two_tone_Beep();
      frec = SD.open("greeting.wav", FILE_WRITE);
      Serial.println("Opened Greeting file !");
      if(frec) {
        Serial.print("Recording to greeting.wav");
        queue1.begin();
        mode = Mode::Recording; print_mode();
        recByteSaved = 0L;
      }
      else {
        Serial.println("Couldn't open file to record!");
      }
    }
    
    void startRecording() {
      // Find the first available file number
    //  for (uint8_t i=0; i<9999; i++) { // BUGFIX uint8_t overflows if it reaches 255  
      for (uint16_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.wav", 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);
      Serial.println("Opened file !");
      if(frec) {
        Serial.print("Recording to ");
        Serial.println(filename);
        queue1.begin();
        mode = Mode::Recording; print_mode();
        recByteSaved = 0L;
      }
      else {
        Serial.println("Couldn't open file to record!");
      }
    }
    
    void continueRecording() {
      // Check if there is data in the queue
      if (queue1.available() >= 2) {
        byte buffer[512];
        // Fetch 2 blocks from the audio library and copy
        // into a 512 byte buffer.  The Arduino SD library
        // is most efficient when full 512 byte sector size
        // writes are used.
        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() {
      // Stop adding any new data to the queue
      queue1.end();
      // Flush all existing remaining data from the queue
      while (queue1.available() > 0) {
        // Save to open file
        frec.write((byte*)queue1.readBuffer(), 256);
        queue1.freeBuffer();
        recByteSaved += 256;
      }
      writeOutHeader();
      // Close the file
      frec.close();
      Serial.println("Closed file");
      mode = Mode::Ready; print_mode();
    }
    
    
    void playAllRecordings() {
      // Recording files are saved in the root directory
      File dir = SD.open("/");
      
      while (true) {
        File entry =  dir.openNextFile();
        if (strstr(entry.name(), "greeting"))
        {
           entry =  dir.openNextFile();
        }
        if (!entry) {
          // no more files
          entry.close();
          end_Beep();
          break;
        }
        //int8_t len = strlen(entry.name()) - 4;
    //    if (strstr(strlwr(entry.name() + (len - 4)), ".raw")) {
    //    if (strstr(strlwr(entry.name() + (len - 4)), ".wav")) {
        // the lines above throw a warning, so I replace them with this (which is also easier to read):
        if (strstr(entry.name(), ".wav") || strstr(entry.name(), ".WAV")) {
          Serial.print("Now playing ");
          Serial.println(entry.name());
          // Play a short beep before each message
          waveform1.amplitude(beep_volume);
          wait(750);
          waveform1.amplitude(0);
          // Play the file
          playWav1.play(entry.name());
          mode = Mode::Playing; print_mode();
        }
        entry.close();
    
    //    while (playWav1.isPlaying()) { // strangely enough, this works for playRaw, but it does not work properly for playWav
        while (!playWav1.isStopped()) { // this works for playWav
          buttonPlay.update();
          buttonRecord.update();
          // Button is pressed again
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if(buttonPlay.fallingEdge() || buttonRecord.risingEdge())  
    #else
          if(buttonPlay.fallingEdge() || buttonRecord.fallingEdge())  
    #endif
          { 
            playWav1.stop();
            mode = Mode::Ready; print_mode();
            return;
          }   
        }
      }
      // All files have been played
      mode = Mode::Ready; print_mode();
    }
    
    void playLastRecording() { // 1
      // Find the first available file number
      uint16_t idx = 0; 
      for (uint16_t i=0; i<9999; i++) { // 2
        // Format the counter as a five-digit number with leading zeroes, followed by file extension
        snprintf(filename, 11, " %05d.wav", i);
        // check, if file with index i exists
        if (!SD.exists(filename)) { // 3
         idx = i - 1;
         break;
          } // 3
      } // 2
          // now play file with index idx == last recorded file
          snprintf(filename, 11, " %05d.wav", idx);
          Serial.println(filename);
          playWav1.play(filename);
          mode = Mode::Playing; print_mode();
          while (!playWav1.isStopped()) 
          { // 5 // this works for playWav
              buttonPlay.update();
              buttonRecord.update();
              // Button is pressed again
        #if defined(HANDHELD_CLOSES_ON_LIFT)
              if(buttonPlay.fallingEdge() || buttonRecord.risingEdge())  
        #else
              if(buttonPlay.fallingEdge() || buttonRecord.fallingEdge()) 
        #endif
              {
                playWav1.stop();
                mode = Mode::Ready; print_mode();
                return;
              }   //4
          } // 5 end while
          // file has been played
      mode = Mode::Ready; print_mode();  
      end_Beep();
    } // 1 end playLastRecording
    
    
    // Retrieve the current time from Teensy built-in RTC
    time_t getTeensy3Time(){
      return Teensy3Clock.get();
    }
    
    // Callback to assign timestamps for file system operations
    void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) {
    
      // Return date using FS_DATE macro to format fields.
      *date = FS_DATE(year(), month(), day());
    
      // Return time using FS_TIME macro to format fields.
      *time = FS_TIME(hour(), minute(), second());
    
      // Return low time bits in units of 10 ms.
      *ms10 = second() & 1 ? 100 : 0;
    }
    
    // Non-blocking delay, which pauses execution of main program logic,
    // but while still listening for input 
    void wait(unsigned int milliseconds) {
      elapsedMillis msec=0;
    
      while (msec <= milliseconds) {
        buttonRecord.update();
        buttonPlay.update();
        if (buttonRecord.fallingEdge()) Serial.println("Button (pin 0) Press");
        if (buttonPlay.fallingEdge()) Serial.println("Button (pin 1) Press");
        if (buttonRecord.risingEdge()) Serial.println("Button (pin 0) Release");
        if (buttonPlay.risingEdge()) Serial.println("Button (pin 1) Release");
      }
    }
    
    
    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); 
    }
    
    void end_Beep(void) {
            waveform1.frequency(523.25);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
    }
    
    void two_tone_Beep(void) {
            waveform1.frequency(523.25);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            waveform1.frequency(375.0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            waveform1.frequency(523.25);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            waveform1.frequency(375.0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
    }
    
    void print_mode(void) { // only for debugging
      Serial.print("Mode switched to: ");
      // Initialising, Ready, Prompting, Recording, Playing
      if(mode == Mode::Ready)           Serial.println(" Ready");
      else if(mode == Mode::Prompting)  Serial.println(" Prompting");
      else if(mode == Mode::Recording)  Serial.println(" Recording");
      else if(mode == Mode::Playing)    Serial.println(" Playing");
      else if(mode == Mode::Initialising)  Serial.println(" Initialising");
      else if(mode == Mode::Recording_Greeting)  Serial.println(" Recording Greeting");
      else Serial.println(" Undefined");
    }

  4. #129
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    697
    Quote Originally Posted by UjjalD View Post
    while recording the wav files, small parts are failing to record at a regular interval.. for example, while recoding counting number (1-30) - 13 & 26 missing...
    Could you explain in detail what that means? What is "small parts", what is "recoding counting number" ? I do not understand what is going right and what is going wrong in your setup.

  5. #130
    I'm having some issues with getting the code to compile each time it throws more errors my way. It used to tell me multiple libraries were found for SD.h but I finally solved that issue I could really use some help because I am stuck on this. Below are the errors it is giving me any help is appreciated also I am using the correct versions of TD and Arduino I have checked multiple times.









    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:37:0: warning: "FILE_READ" redefined
    #define FILE_READ 0
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:23:0: note: this is the location of the previous definition
    #define FILE_READ O_READ
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:38:0: warning: "FILE_WRITE" redefined
    #define FILE_WRITE 1
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:24:0: note: this is the location of the previous definition
    #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:75:10: error: reference to 'File' is ambiguous
    virtual File openNextFile(uint8_t mode=0) = 0;
    ^
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:47:7: note: candidates are: class File
    class File;
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h: In member function 'File File:penNextFile(uint8_t)':
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:213:19: error: 'class FileImpl' has no member named 'openNextFile'
    return (f) ? f->openNextFile(mode) : *this;
    ^
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h: At global scope:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:273:10: error: reference to 'File' is ambiguous
    virtual File open(const char *filename, uint8_t mode = FILE_READ) = 0;
    ^
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:287:2: error: reference to 'File' is ambiguous
    File open(const String &filepath, uint8_t mode = FILE_READ) {
    ^
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45:0,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:178:2: error: reference to 'File' is ambiguous
    File open(uint32_t store, const char *filename, uint32_t mode) {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45:0,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:287:2: error: reference to 'File' is ambiguous
    File index_;
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45:0,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:288:2: error: reference to 'File' is ambiguous
    File file_;
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45:0,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:289:2: error: reference to 'File' is ambiguous
    File child_;
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    In file included from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:0:
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h: In member function 'uint32_t MTP_class::addFilesystem(SDLib::SDClass&, const char*)':
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:78:55: error: no matching function for call to 'MTP_class::addFilesystem(SDLib::SDClass&, const char*&, mtp_fstype_t)'
    return addFilesystem(disk, diskname, MTP_FSTYPE_SD);
    ^
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:76:12: note: candidate: uint32_t MTP_class::addFilesystem(SDLib::SDClass&, const char*)
    uint32_t addFilesystem(SDClass &disk, const char *diskname) {
    ^
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:76:12: note: candidate expects 2 arguments, 3 provided
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:82:12: note: candidate: uint32_t MTP_class::addFilesystem(FS&, const char*, mtp_fstype_t)
    uint32_t addFilesystem(FS &disk, const char *diskname, mtp_fstype_t fstype = MTP_FSTYPE_UNKNOWN);
    ^
    C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:82:12: note: no known conversion for argument 1 from 'SDLib::SDClass' to 'FS&'
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: At global scope:
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:97:1: error: reference to 'File' is ambiguous
    File frec;
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void setup()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:64:26: error: 'BUILTIN_SDCARD' was not declared in this scope
    #define SDCARD_CS_PIN BUILTIN_SDCARD
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:161:18: note: in expansion of macro 'SDCARD_CS_PIN'
    if (!(SD.begin(SDCARD_CS_PIN)))
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:188:3: error: 'FsDateTime' has not been declared
    FsDateTime::setCallback(dateTime);
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void startRecordingGreeting()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:329:3: error: 'frec' was not declared in this scope
    frec = SD.open("greeting.wav", FILE_WRITE);
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void startRecording()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:353:3: error: 'frec' was not declared in this scope
    frec = SD.open(filename, FILE_WRITE);
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void continueRecording()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:380:5: error: 'frec' was not declared in this scope
    frec.write(buffer, 512);
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void stopRecording()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:391:5: error: 'frec' was not declared in this scope
    frec.write((byte*)queue1.readBuffer(), 256);
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:397:3: error: 'frec' was not declared in this scope
    frec.close();
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void playAllRecordings()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:405:3: error: reference to 'File' is ambiguous
    File dir = SD.open("/");
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:408:5: error: reference to 'File' is ambiguous
    File entry = dir.openNextFile();
    ^
    In file included from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Storage.h:35:0,
    from C:\Users\Jonah\OneDrive\Documents\Arduino\librarie s\MTP_Teensy-main\src/MTP_Teensy.h:45,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note: candidates are: class File
    class File final : public Stream {
    ^
    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32:0,
    from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
    from C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
    C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: class SDLib::File
    class File : public Stream {
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:409:16: error: 'entry' was not declared in this scope
    if (strstr(entry.name(), "greeting"))
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:411:17: error: 'dir' was not declared in this scope
    entry = dir.openNextFile();
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:413:10: error: 'entry' was not declared in this scope
    if (!entry) {
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:423:16: error: 'entry' was not declared in this scope
    if (strstr(entry.name(), ".wav") || strstr(entry.name(), ".WAV")) {
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:434:5: error: 'entry' was not declared in this scope
    entry.close();
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void dateTime(uint16_t*, uint16_t*, uint8_t*)':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:505:41: error: 'FS_DATE' was not declared in this scope
    *date = FS_DATE(year(), month(), day());
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:508:45: error: 'FS_TIME' was not declared in this scope
    *time = FS_TIME(hour(), minute(), second());
    ^
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void writeOutHeader()':
    C:\Users\Jonah\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:536:3: error: 'frec' was not declared in this scope
    frec.seek(0);
    ^
    Error compiling for board Teensy 4.1.

  6. #131
    Quote Originally Posted by DD4WH View Post
    In my github, I stated very clearly, that the code only works with T4.0 and T4.1
    I now have a Teensy 4.1. I have now compiled your unaltered code found on your Github and it compiles with no errors. I can see that the errors I was getting stopped immediately after I stopped targeting a Teensy LC board and instead started targeting Teensy 4.0 and 4.1. I have now loaded the code onto the Teensy SD card (using the SD card slot on the Teensy rather than the audio shield). However, nothing happens when I pick up the receiver. I have no idea what I'm supposed to hear. Is there some kind of robot voice that's supposed to prompt me to record a greeting? I hear no such prompt when I pick up my receiver. I also hear nothing when I move a file named "greeting.wav" from my computer onto the SD card. Am I supposed to power the phone separately? It's a digital phone we bought on Amazon. It's the "Rotary Phone, MCHEETA Retro Rotary Dial Phone, 80s Vintage Old Telephone for Landline, Corded Landline Phones for Home(Yellow)."

  7. #132
    Junior Member
    Join Date
    Jul 2022
    Posts
    13
    Quote Originally Posted by DD4WH View Post
    Could you explain in detail what that means? What is "small parts", what is "recoding counting number" ? I do not understand what is going right and what is going wrong in your setup.
    00015.zip

    @DD4WH Thanks for your response, If you can manage to hear the attached WAV file (Zip), you will find what I mean. Your help to fix this will be highly appreciated.

  8. #133
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    697
    Quote Originally Posted by UjjalD View Post
    hear the attached WAV file (Zip), you will find what I mean.
    That is pretty normal behaviour! By using the standard Teensy audio lib modules, it is not possible to record audio without such glitches. A better SD card might help, but in most cases you have got to live with that.

  9. #134
    Senior Member
    Join Date
    Sep 2021
    Posts
    111
    A fast card really helps. You just can't use the alle the labels on the card to know it is fast or not.
    There are some threads here where you can find a fast card. Don't trust benchmarks on PCs.

  10. #135
    Long story short, I improved the connections between phone and Teensy/Audio shield. I am now getting a "beep" tone after I pick up the handset. After I put it down and then pick it up, I hear no beep. I do hear the beep again if I power cycle the Teensy and then pick up the handset. It doesn't appear to be playing the greeting wav file I moved to the SD card, and it doesn't appear to be prompting a new recording or recording anything new. I'm using Teensy 4.1.

  11. #136
    Also, on the Arduino IDE 1.8.19, I have either the ability to compile with Serial or with MTP Disk (Experimental) but not both. Is there a config file I need to change to fix this?

  12. #137
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    467
    Quote Originally Posted by FoxdieTestPatient View Post
    Also, on the Arduino IDE 1.8.19, I have either the ability to compile with Serial or with MTP Disk (Experimental) but not both. Is there a config file I need to change to fix this?
    TD 1.57 or later is required for "Serial + MTP Disk".

    Mark J Culross
    KD5RXT

  13. #138
    I'm using the Teensyduino 1.57 Beta #1 for Windows found here: https://forum.pjrc.com/threads/70196

  14. #139
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    467
    Quote Originally Posted by FoxdieTestPatient View Post
    I'm using the Teensyduino 1.57 Beta #1 for Windows found here: https://forum.pjrc.com/threads/70196
    The <release notes> for the formal TD 1.57 list the following: "Add Serial+MTP USB Type". Don't know specifically when / which beta version of TD 1.57bX included this capability, so best to get the formal TD 1.57 release & be sure !!

    Mark J Culross
    KD5RXT

  15. #140
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,279
    Quote Originally Posted by FoxdieTestPatient View Post
    I'm using the Teensyduino 1.57 Beta #1 for Windows found here: https://forum.pjrc.com/threads/70196
    You need at least Teensyduino 1.57 Beta #3, which was the revision that added the Serial + MTP build option:


    But it would be better to just install 1.57 final.

  16. #141
    I've installed the 1.57 TD final. I'm still only getting a beep when I lift the handset after a fresh power cycle. When I press the pushbutton for message playback, I get 4 beeps that sound identical to each other and different from the other beep that plays after I pick up the handset.

  17. #142
    Junior Member
    Join Date
    Jul 2022
    Posts
    13
    Quote Originally Posted by DD4WH View Post
    That is pretty normal behaviour! By using the standard Teensy audio lib modules, it is not possible to record audio without such glitches. A better SD card might help, but in most cases you have got to live with that.
    Thanks, can you please suggest the SD card would perform better?
    Further, you mentioned standard Teensy audio lib modules will not perform better, is there any other alternative?

  18. #143
    OK, so the phone *is* playing back my greeting, and then recording a message, but only when I physically unplug and then reconnect Pin 0 on the Teensy 4.1. The phone then doesn't immediately stop recording when I hang up the handset. I'm now noticing that after the first 2 recordings, subsequent recordings appear to be corrupted.

  19. #144
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    697
    Quote Originally Posted by FoxdieTestPatient View Post
    OK, so the phone *is* playing back my greeting, and then recording a message, but only when I physically unplug and then reconnect Pin 0 on the Teensy 4.1. The phone then doesn't immediately stop recording when I hang up the handset. I'm now noticing that after the first 2 recordings, subsequent recordings appear to be corrupted.
    It may help to read the instructions from my github:
    https://github.com/DD4WH/audio-guestbook
    Also make sure you understand whether your handset switch opens or closes on lifting the handset (and adjust the software switches accordingly).
    And ensure that your handset switch hardware is working properly and 100% reliably.
    Corrupted recordings are most probably caused by your SD card. Use a good SD card. Search for Bill Greiman SD card test, he had a thread here on the forum where SD cards were compared.

  20. #145
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    697
    Quote Originally Posted by UjjalD View Post
    Further, you mentioned standard Teensy audio lib modules will not perform better, is there any other alternative?
    Yes, the microSoundRecorder sketch by WMXZ does allow to record audio without glitches on the T3.6. Search for it on github. You would have to merge the two sketches together, adapt them to the Teensy 4.0/4.1 and put a whole lot of effort and know-how into that in order to produce a working audio guest book.

  21. #146
    Quote Originally Posted by DD4WH View Post
    It may help to read the instructions from my github:
    https://github.com/DD4WH/audio-guestbook
    Also make sure you understand whether your handset switch opens or closes on lifting the handset (and adjust the software switches accordingly).
    And ensure that your handset switch hardware is working properly and 100% reliably.
    Corrupted recordings are most probably caused by your SD card. Use a good SD card. Search for Bill Greiman SD card test, he had a thread here on the forum where SD cards were compared.
    I got it working as of last night. I found that I had misidentified the pins (there were 4 of them because it was a ribbon cable with 4 pins) that trigger when I press/depress the hook switch, and I also didn't press the Teensy 4.1 and the Audio Shield together enough, so they weren't making a strong enough connection. After soldering wires to the correct pins on the phone's circuit board, I was getting the correct behavior out of GPIO Pin 0, and thus the recording started. This also seemed to fix the issue with the SD card, because the hook switch controls were completely divorced from the actual Teensy until I made that discovery last night.

    So long story short, my problem was that I mistakenly bought a Teensy LC and didn't correctly follow the sequence in the tutorial vid where you're supposed to ID the hook switch, because I'm inexperienced with multimeter and didn't know what I was looking for.

    I think it might help future users to pay special attention to the hook switch for digital phones, and triple check any soldering connections you make to a PCB, because I had to re-solder all of the connections from the wires I had going to the Teensy to my phone's board. To any newbie reading this, you will want wire strippers and you may need a soldering iron [I](as well as flux, solder, a solder sucker, and solder wick).

  22. #147
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    697
    Congratulations!!! Very good.

    Thanks a lot for your detailed feedback and recommendations, which will help builders to check their builds and make them work :-).

    Have fun with the Teensy! Frank DD4WH

  23. #148
    Junior Member
    Join Date
    Sep 2022
    Posts
    1
    So did a few upgrades to the code to be able to use it with a more modern phone (https://a.co/d/8yH8w7j) and to have it have an LED status light when recording (on pin 2 for T4). Also now have a time recording limit.

    Issue that I'm still having is that the phone doesn't always seem to catch pickups or hangups. It also doesn't seem to like my externally recorded greeting.wav Here's the code for anyone wanting to update or play with it, thanks to @dd4wh for the work on it from the getgo!

    Code:
    /**
     * Audio Guestbook, Copyright (c) 2022 Playful Technology
     * 
     * Tested using a Teensy 4.0 with Teensy Audio Shield, although should work 
     * with minor modifications on other similar hardware
     * 
     * When handset is lifted, a pre-recorded greeting message is played, followed by a tone.
     * Then, recording starts, and continues until the handset is replaced.
     * Playback button allows all messages currently saved on SD card through earpiece 
     * 
     * follow the detailed instructions here:
     * https://github.com/DD4WH/audio-guestbook/blob/main/README.md
     * 
     * 
     *   the sketch only works with the latest Teensyduino 1.57 version, so please update your Arduino IDE AND your Teensyduino to Arduino version 1.8.19 and the latest Teensyduino version 1.57
     *   download the following library, unzip it and put it into your local Arduino folder (on my computer, the local Arduino folder is: "C:/Users/DD4WH/Documents/Arduino/libraries/"): https://github.com/KurtE/MTP_Teensy
     *   compile with option: "Serial + MTP Disk (Experimental)"" and with option "CPU speed: 150MHz" (this can save about 70% of battery power)
     *
     * Modifications by Frank DD4WH, August 2022
     * - now uses a Teensy 4.1 with built-in SD card (faster via SDIO), if you want to use a Teensy 4.0, uncomment in the USER CONFIGURATION below
     * - Files are saved on SD card as 44.1kHz, 16-bit mono WAV audio files 
     * - if you plug in the telephones´ USB cable into your computer, the telephone is mounted as a drive and you can acess the recordings 
     * - if there is no "greeting.wav" message on the SD card, the telephone automatically plays an invitation to record this message and then you can record the greeting message 
     * - if you want to record the greeting message again, just delete it from the telephone and lift the handheld again to record the greeting message  
     * --> if your handheld contact switch opens on lifting, simply uncomment in the USER CONFIGURATION below, everything else is done by the software
     * 
     * GNU GPL v3.0 license
     * 
     */
    
    #include <Bounce.h>
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <TimeLib.h>
    #include <MTP_Teensy.h>  // this library has to be downloaded separately (https://github.com/KurtE/MTP_Teensy)
    // unzip the downloaded file and its content into your local Arduino folder (on my computer, the local Arduino folder is: "C:/Users/DD4WH/Documents/Arduino/libraries/")
    
    /***************************************************************************************************************************************************/
    /**USER CONFIGURATION ******************************************************************************************************************************/
    /**COMMENT / UNCOMMENT ACCORDING TO YOUR HARDWARE **************************************************************************************************/
    /***************************************************************************************************************************************************/
    
    // comment this out, if your handheld OPENS the contact on lift
    // use a digital voltmeter to find out
    #define HANDHELD_CLOSES_ON_LIFT
    
    // comment this out, if you want to record your greeting message with an external recorder
    // leave as-is if you want to have the telephone automatically switch to recording the greeting message, in case there is no "greeting.wav" on the SD card 
    #define AUTO_GREETING_MESSAGE
    
    // comment out, if you use a Teensy 4.0 (and thus the SD card slot on the audio board)
    // if you leave this as-is, you have to use the built-in SD card slot on the Teensy 4.1, NOT the SD card slot on the audio board 
    ////#define TEENSY_41
    
    /***************************************************************************************************************************************************/
    /**END OF USER CONFIGURATION ***********************************************************************************************************************/
    /***************************************************************************************************************************************************/
    /***************************************************************************************************************************************************/
    
    // Define pins used by Teensy Audio Shield
    #ifdef TEENSY_41
    #define SDCARD_CS_PIN    BUILTIN_SDCARD
    #else
    #define SDCARD_CS_PIN    10
    #endif
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    // And those used for inputs
    // You can choose the pins you use here:
    //#define HOOK_PIN 40
    //#define PLAYBACK_BUTTON_PIN 41
    #define HOOK_PIN 0              // this is the default
    #define PLAYBACK_BUTTON_PIN 1   // this is the default
    
    
    // GLOBALS
    // Audio initialisation code can be generated using the GUI interface at https://www.pjrc.com/teensy/gui/
    // Inputs
    AudioSynthWaveform          waveform1; // To create the "beep" sfx
    AudioInputI2S               i2s2; // I2S input from microphone on audio shield
    AudioPlaySdWav              playWav1; // Play 44.1kHz 16-bit PCM greeting WAV file
    AudioRecordQueue            queue1; // Creating an audio buffer in memory before saving to SD
    AudioMixer4                 mixer; // Allows merging several inputs to same output
    AudioOutputI2S              i2s1; // I2S interface to Speaker/Line Out on Audio shield
    AudioConnection patchCord1(waveform1, 0, mixer, 0); // wave to mixer 
    AudioConnection patchCord3(playWav1, 0, mixer, 1); // wav file playback mixer
    AudioConnection patchCord4(mixer, 0, i2s1, 0); // mixer output to speaker (L)
    AudioConnection patchCord6(mixer, 0, i2s1, 1); // mixer output to speaker (R)
    AudioConnection patchCord5(i2s2, 0, queue1, 0); // mic input to queue (L)
    AudioControlSGTL5000      sgtl5000_1;
    
    // Filename to save audio recording on SD card
    char filename[15];
    // The file object itself
    File frec;
    
    // Use long 40ms debounce time on both switches
    Bounce buttonRecord = Bounce(HOOK_PIN, 100);
    Bounce buttonPlay = Bounce(PLAYBACK_BUTTON_PIN, 40);
    
    // Keep track of current state of the device
    enum Mode {Initialising, Ready, Prompting, Recording, Playing, Recording_Greeting};
    Mode mode = Mode::Initialising;
    
    float beep_volume = 0.4f; // not too loud :-)
    
    // variables for writing to WAV file
    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;
    // PiProjects variables 
    int recordTimeStamp;
    int recordingTimeLimit = 60000; // This is the recording time limit in milliseconds 
    int LED_PIN = 2;
    
    void setup() {
    
      Serial.begin(9600);
      while (!Serial && millis() < 5000) {
        // wait for serial port to connect.
      }
      Serial.println("Serial set up correctly");
      print_mode();
      // Configure the input pins
      pinMode(HOOK_PIN, INPUT_PULLUP);
      pinMode(PLAYBACK_BUTTON_PIN, INPUT_PULLUP);
      pinMode(LED_PIN, OUTPUT);
      
      // Audio connections require memory, and the record queue
      // uses this memory to buffer incoming audio.
      AudioMemory(60);
    
      // Enable the audio shield, select input, and enable output
      sgtl5000_1.enable();
      // Define which input on the audio shield to use (AUDIO_INPUT_LINEIN / AUDIO_INPUT_MIC)
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.adcHighPassFilterDisable(); //
      sgtl5000_1.volume(1.0);
    
      mixer.gain(0, 1.0f);
      mixer.gain(1, 1.0f);
    
      // Play a beep to indicate system is online
      waveform1.begin(beep_volume, 440, WAVEFORM_SINE);
      wait(500);
      waveform1.amplitude(0);
      delay(500);
    
      // Initialize the SD card
    #ifndef TEENSY_41   // assumes that you are using the SD card slot of the AUDIO BOARD
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
    #endif  
      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(5000);
        }
      }
        else Serial.println("SD card correctly initialized");
    
      // mandatory to begin the MTP session.
        MTP.begin();
    
      // Add SD Card
        MTP.addFilesystem(SD, "My Audio guestbook"); // choose a nice name for the SD card volume to appear in your file explorer
        Serial.println("Added SD card via MTP");
        
        // Value in dB
    //  sgtl5000_1.micGain(15);
      sgtl5000_1.micGain(30); // much lower gain is required for the AOM5024 electret capsule
    
      // Synchronise the Time object used in the program code with the RTC time provider.
      // See https://github.com/PaulStoffregen/Time
      setSyncProvider(getTeensy3Time);
      
      // Define a callback that will assign the correct datetime for any file system operations
      // (i.e. saving a new audio recording onto the SD card)
      FsDateTime::setCallback(dateTime);
    
      mode = Mode::Ready; print_mode();
    }
    
    void loop() { //1
      // First, read the buttons
      buttonRecord.update();
      buttonPlay.update();
    
      switch(mode)
      { //2
        case Mode::Ready:
          // Falling edge occurs when the handset is lifted --> 611 telephone
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if (buttonRecord.fallingEdge()) 
    #else
          if (buttonRecord.risingEdge()) 
    #endif
          {
            Serial.println("Handset lifted");
            mode = Mode::Prompting; print_mode();
          } //3
          else if(buttonPlay.fallingEdge()) 
          { //4
            //playAllRecordings();
            playLastRecording();
          } //4
          break;
    
        case Mode::Prompting:
          // Wait a second for users to put the handset to their ear
          wait(1000);
    
    #if defined(AUTO_GREETING_MESSAGE)
    
        if (!SD.exists("greeting.wav")) 
        { //5
          mode = Mode::Recording_Greeting;
          break;
        } //5
    #endif
         
          // Play the greeting inviting them to record their message
          playWav1.play("greeting.wav");    
          // Wait until the  message has finished playing
    //      while (playWav1.isPlaying()) {
          while (!playWav1.isStopped()) 
          { //6
            // Check whether the handset is replaced
            buttonRecord.update();
            buttonPlay.update();
            // Handset is replaced
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if (buttonRecord.risingEdge()) 
    #else
          if (buttonRecord.fallingEdge())
    #endif
            {
              playWav1.stop();
              mode = Mode::Ready; print_mode();
              return;
            } //7
            if(buttonPlay.fallingEdge()) 
            { //8
              playWav1.stop();
              //playAllRecordings();
              playLastRecording();
              return;
            } //8
            
          }  // 
          
          // Debug message
          Serial.println("Starting Recording");
          // Play the tone sound effect
          waveform1.begin(beep_volume, 440, WAVEFORM_SINE);
          wait(1250);
          waveform1.amplitude(0);
          // Start the recording function
          startRecording();
          digitalWrite(LED_PIN, HIGH);
          recordTimeStamp = millis(); // For recording time limit
          break;
    
        case Mode::Recording:
          // Handset is replaced
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if (buttonRecord.risingEdge()) 
    #else
          if (buttonRecord.fallingEdge())
    #endif
          { //9  
          // Debug log
            Serial.println("Stopping Recording");
            // Stop recording
            stopRecording();
            // Play audio tone to confirm recording has ended
            end_Beep();
            digitalWrite(LED_PIN, LOW);
          } //9
          else 
          { //10
            if(recordTimeStamp + recordingTimeLimit < millis()){
              stopRecording();
               // Play audio tone to confirm recording has ended
              end_Beep();
              digitalWrite(LED_PIN, LOW);
            }
            continueRecording();
          } // 10
          break;
    
        case Mode::Playing: // to make compiler happy
          break;  
    
        case Mode::Initialising: // to make compiler happy
          break;  
    
        case Mode::Recording_Greeting: // to make compiler happy
          startRecordingGreeting();
          mode = Mode::Recording;
          break;  
          } // 2 end switch   
      MTP.loop();  //This is mandatory to be placed in the loop code.
    } // 1 end loop
    
    void startRecordingGreeting() {
        if (SD.exists("greeting.wav")) {
          return;
        }
        // play message "Please record Greeting message now !" 
        playWav1.play("invitation_greeting.wav");
        while (!playWav1.isStopped()) { // this works for playWav
          buttonPlay.update();
          buttonRecord.update();
          // Button is pressed again
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if(buttonPlay.fallingEdge() || buttonRecord.risingEdge())  
    #else
          if(buttonPlay.fallingEdge() || buttonRecord.fallingEdge())  
    #endif
          { 
            playWav1.stop();
            mode = Mode::Ready; print_mode();
            return;
          }   
        }
        // play beep
        two_tone_Beep();
      frec = SD.open("greeting.wav", FILE_WRITE);
      Serial.println("Opened Greeting file !");
      if(frec) {
        Serial.print("Recording to greeting.wav");
        queue1.begin();
        mode = Mode::Recording; print_mode();
        recByteSaved = 0L;
      }
      else {
        Serial.println("Couldn't open file to record!");
      }
    }
    
    void startRecording() {
      // Find the first available file number
    //  for (uint8_t i=0; i<9999; i++) { // BUGFIX uint8_t overflows if it reaches 255  
      for (uint16_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.wav", 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);
      Serial.println("Opened file !");
      if(frec) {
        Serial.print("Recording to ");
        Serial.println(filename);
        queue1.begin();
        mode = Mode::Recording; print_mode();
        recByteSaved = 0L;
      }
      else {
        Serial.println("Couldn't open file to record!");
      }
    }
    
    void continueRecording() {
      // Check if there is data in the queue
      if (queue1.available() >= 2) {
        byte buffer[512];
        // Fetch 2 blocks from the audio library and copy
        // into a 512 byte buffer.  The Arduino SD library
        // is most efficient when full 512 byte sector size
        // writes are used.
        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() {
      // Stop adding any new data to the queue
      queue1.end();
      // Flush all existing remaining data from the queue
      while (queue1.available() > 0) {
        // Save to open file
        frec.write((byte*)queue1.readBuffer(), 256);
        queue1.freeBuffer();
        recByteSaved += 256;
      }
      writeOutHeader();
      // Close the file
      frec.close();
      Serial.println("Closed file");
      mode = Mode::Ready; print_mode();
    }
    
    
    void playAllRecordings() {
      // Recording files are saved in the root directory
      File dir = SD.open("/");
      
      while (true) {
        File entry =  dir.openNextFile();
        if (strstr(entry.name(), "greeting"))
        {
           entry =  dir.openNextFile();
        }
        if (!entry) {
          // no more files
          entry.close();
          end_Beep();
          break;
        }
        //int8_t len = strlen(entry.name()) - 4;
    //    if (strstr(strlwr(entry.name() + (len - 4)), ".raw")) {
    //    if (strstr(strlwr(entry.name() + (len - 4)), ".wav")) {
        // the lines above throw a warning, so I replace them with this (which is also easier to read):
        if (strstr(entry.name(), ".wav") || strstr(entry.name(), ".WAV")) {
          Serial.print("Now playing ");
          Serial.println(entry.name());
          // Play a short beep before each message
          waveform1.amplitude(beep_volume);
          wait(750);
          waveform1.amplitude(0);
          // Play the file
          playWav1.play(entry.name());
          mode = Mode::Playing; print_mode();
        }
        entry.close();
    
    //    while (playWav1.isPlaying()) { // strangely enough, this works for playRaw, but it does not work properly for playWav
        while (!playWav1.isStopped()) { // this works for playWav
          buttonPlay.update();
          buttonRecord.update();
          // Button is pressed again
    #if defined(HANDHELD_CLOSES_ON_LIFT)
          if(buttonPlay.fallingEdge() || buttonRecord.risingEdge())  
    #else
          if(buttonPlay.fallingEdge() || buttonRecord.fallingEdge())  
    #endif
          { 
            playWav1.stop();
            mode = Mode::Ready; print_mode();
            return;
          }   
        }
      }
      // All files have been played
      mode = Mode::Ready; print_mode();
    }
    
    void playLastRecording() { // 1
      // Find the first available file number
      uint16_t idx = 0; 
      for (uint16_t i=0; i<9999; i++) { // 2
        // Format the counter as a five-digit number with leading zeroes, followed by file extension
        snprintf(filename, 11, " %05d.wav", i);
        // check, if file with index i exists
        if (!SD.exists(filename)) { // 3
         idx = i - 1;
         break;
          } // 3
      } // 2
          // now play file with index idx == last recorded file
          snprintf(filename, 11, " %05d.wav", idx);
          Serial.println(filename);
          playWav1.play(filename);
          mode = Mode::Playing; print_mode();
          while (!playWav1.isStopped()) 
          { // 5 // this works for playWav
              buttonPlay.update();
              buttonRecord.update();
              // Button is pressed again
        #if defined(HANDHELD_CLOSES_ON_LIFT)
              if(buttonPlay.fallingEdge() || buttonRecord.risingEdge())  
        #else
              if(buttonPlay.fallingEdge() || buttonRecord.fallingEdge()) 
        #endif
              {
                playWav1.stop();
                mode = Mode::Ready; print_mode();
                return;
              }   //4
          } // 5 end while
          // file has been played
      mode = Mode::Ready; print_mode();  
      end_Beep();
    } // 1 end playLastRecording
    
    
    // Retrieve the current time from Teensy built-in RTC
    time_t getTeensy3Time(){
      return Teensy3Clock.get();
    }
    
    // Callback to assign timestamps for file system operations
    void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) {
    
      // Return date using FS_DATE macro to format fields.
      *date = FS_DATE(year(), month(), day());
    
      // Return time using FS_TIME macro to format fields.
      *time = FS_TIME(hour(), minute(), second());
    
      // Return low time bits in units of 10 ms.
      *ms10 = second() & 1 ? 100 : 0;
    }
    
    // Non-blocking delay, which pauses execution of main program logic,
    // but while still listening for input 
    void wait(unsigned int milliseconds) {
      elapsedMillis msec=0;
    
      while (msec <= milliseconds) {
        buttonRecord.update();
        buttonPlay.update();
        if (buttonRecord.fallingEdge()) Serial.println("Button (pin 0) Press");
        if (buttonPlay.fallingEdge()) Serial.println("Button (pin 1) Press");
        if (buttonRecord.risingEdge()) Serial.println("Button (pin 0) Release");
        if (buttonPlay.risingEdge()) Serial.println("Button (pin 1) Release");
      }
    }
    
    
    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); 
    }
    
    void end_Beep(void) {
            waveform1.frequency(523.25);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
    }
    
    void two_tone_Beep(void) {
            waveform1.frequency(523.25);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            waveform1.frequency(375.0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            waveform1.frequency(523.25);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
            waveform1.frequency(375.0);
            wait(250);
            waveform1.amplitude(beep_volume);
            wait(250);
            waveform1.amplitude(0);
    }
    
    void print_mode(void) { // only for debugging
      Serial.print("Mode switched to: ");
      // Initialising, Ready, Prompting, Recording, Playing
      if(mode == Mode::Ready)           Serial.println(" Ready");
      else if(mode == Mode::Prompting)  Serial.println(" Prompting");
      else if(mode == Mode::Recording)  Serial.println(" Recording");
      else if(mode == Mode::Playing)    Serial.println(" Playing");
      else if(mode == Mode::Initialising)  Serial.println(" Initialising");
      else if(mode == Mode::Recording_Greeting)  Serial.println(" Recording Greeting");
      else Serial.println(" Undefined");
    }

  24. #149
    Junior Member
    Join Date
    Oct 2022
    Posts
    1
    I badly need help. I followed all the steps and connected everything. Copy pasted the code (removed Teensy 4.1 part as I am using 4.0), compiled successfully, then nothing. Not even a beep.

    Checked the serial monitor and it says "Unable to access the SD card" repeatedly. I understand that this is a printed message to check if there is an SD card. I don't know why it is stuck in this loop.

    To check my SD Card, i ran File > Examples > MTP_Teensy > Simplified Examples. My SD card got detected but 0 gb. Not sure if this is purely an SD card problem but at least I should hear a beep, correct?

Posting Permissions

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