Forum Rule: Always post complete source code & details to reproduce any issue!
Page 8 of 8 FirstFirst ... 6 7 8
Results 176 to 198 of 198

Thread: Teensy 4.0 - based Audio Guestbook

  1. #176
    Junior Member
    Join Date
    Oct 2022
    Posts
    2
    I think I´m having the same audio issues.
    To exclude programming issues I tested it with the "Recorder" - sample project from the Arduino examples.

    The cracks appear on LineIn and Mic aswell as on different Teensys and Audioboards.
    You can hear the crack on both of the "two"s
    I can confirm that its not a clipping issue, the waveform isn´t touching borders in audacity.
    Attached Files Attached Files

  2. #177
    Senior Member h4yn0nnym0u5e's Avatar
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    520
    More goodness (I hope) pushed to https://github.com/h4yn0nnym0u5e/aud...tter-recording. MTP is now disabled by default, to prevent it interfering with recording; you can enable it by holding the playback button down at power-up, so no re-compile is needed. A message to the serial monitor tells you if it's enabled or not.

    You can also "instrument" the SD card writes by a compile-time option, which emits the worst write time encountered during the last 0.25s.

  3. #178
    Junior Member
    Join Date
    Oct 2022
    Posts
    10
    Quote Originally Posted by h4yn0nnym0u5e View Post
    More goodness (I hope) pushed to https://github.com/h4yn0nnym0u5e/aud...tter-recording. MTP is now disabled by default, to prevent it interfering with recording; you can enable it by holding the playback button down at power-up, so no re-compile is needed. A message to the serial monitor tells you if it's enabled or not.

    You can also "instrument" the SD card writes by a compile-time option, which emits the worst write time encountered during the last 0.25s.
    Tested this and confirmed it's working. Very neat. Thanks!

  4. #179
    Senior Member h4yn0nnym0u5e's Avatar
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    520
    Quote Originally Posted by svperman View Post
    Tested this and confirmed it's working. Very neat. Thanks!
    Great, I've put in a pull request for the original author to consider.

  5. #180
    Junior Member
    Join Date
    Oct 2022
    Posts
    1
    Hi everyone,

    I have been observing this thread for some time, I would like to make an audio guest book, but I am not sure if I can handle it, I don't know much about programming, I have a good understanding of the computer, software etc. Do you think this can be done for a person like me? will it require understanding of this programming despite the ready code?

  6. #181
    Senior Member h4yn0nnym0u5e's Avatar
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    520
    Quote Originally Posted by h4yn0nnym0u5e View Post
    Great, I've put in a pull request for the original author to consider.
    After a bit of discussion, a probable cause of the issues with MTP has been found. However, it'll require a new Teensyduino release (or at least beta) before that fix is in place.

    Meanwhile, I revised my PR to disable MTP polling only while recording is in progress (thanks for the HowTo, @KurtE!), and that's been pulled in by the original author. So if you update to the latest "main" from github, that's what you'll get, and you won't have to mess about with pressing the button at boot time to enable MTP.

  7. #182
    Junior Member
    Join Date
    Nov 2022
    Posts
    5
    Please help. I have a project made from the link https://github.com/DD4WH/audio-guestbook
    One error pops up during programming:[B] C: \ User \ iJackService \ Documents \ Arduino \ libraries \ src \ MTP_Teensy.cpp: In member function "uint32_t MTP_class:: GetObjectInfo (MTP_class:: MTPContainers)":
    After connecting the power, the phone sounds for recording after a while and nothing else happens. It seems to me that it does not respond to putting the handset off. Rather, it doesn't detect the SD card. Formatted in exFat. What should I check?

    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-guest...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");
    }

  8. #183
    Junior Member
    Join Date
    Nov 2022
    Posts
    5
    Everything department. define it was better. breaks off pieces of the recording while recording. It skips. Sandisk extreme u4 a2 v3 memory

  9. #184
    Junior Member
    Join Date
    Nov 2022
    Posts
    2
    Hello

    I have managed to put everything together, works fine but there are a couple of small issues.

    1. My windows pcs and mac doesn't recognize the teensy when connected. It works when connected to another pc that I used to install the code. It should work on computers which are not used for installing codes, right?
    2. I've been working for a while on removing all of the small sources of noise, but there always seems to be something. Do you guys all use shielded microphone cables after changing the original mic? Does it really help with the background noise?

    I would love to hear your advice. Thank you

  10. #185
    Junior Member
    Join Date
    Nov 2022
    Posts
    2
    Quote Originally Posted by tomo_ono View Post
    Hello

    I have managed to put everything together, works fine but there are a couple of small issues.

    1. My windows pcs and mac doesn't recognize the teensy when connected. It works when connected to another pc that I used to install the code. It should work on computers which are not used for installing codes, right?
    2. I've been working for a while on removing all of the small sources of noise, but there always seems to be something. Do you guys all use shielded microphone cables after changing the original mic? Does it really help with the background noise?

    I would love to hear your advice. Thank you
    So just some update if anyone else is having the same issues.

    1. Try different cables, I was trying to use a sh_tty one. Now works fine.
    2. Regarding the noise: remove the original board in the phone - noise stopped completely!


    All the phone we've built so far use the teensy 4.0. When switching to 4.1 another issue has come up and I've seen some comments regarding the issue and tried solving it with the mentioned solutions - but without any luck.

    Code works perfectly, all the functions are fine - but the recordings cut after a few seconds and they speed up for some reason. This has only come up with the 4.1.

    Has anyone else seen this problem? If yes, I would be extremely grateful for any tips.

    Thank you

  11. #186
    Senior Member h4yn0nnym0u5e's Avatar
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    520
    Quote Originally Posted by tomo_ono View Post
    All the phone we've built so far use the teensy 4.0. When switching to 4.1 another issue has come up and I've seen some comments regarding the issue and tried solving it with the mentioned solutions - but without any luck.

    Code works perfectly, all the functions are fine - but the recordings cut after a few seconds and they speed up for some reason. This has only come up with the 4.1.

    Has anyone else seen this problem?
    Have you tried:

    It's hard to tell what's going on when you only say you've tried "the mentioned solutions", without yourself mentioning which solutions you've tried... things that tend to be important are the exact code you tried (in code tags, please!), the SD card specification, which slot it's in, whether it's freshly formatted, IDE and Teensyduino versions. An audio file may be useful, especially if it can be compared to a known, downloadable source; it only needs to be long enough to reproduce the issue, 5 to 10s should typically do it.

  12. #187
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    704
    I am a little puzzled by the mentioned problem of severe recording problems (slowing down, speeding up, large parts of audio lost etc.).

    I have built four of these audio guest books, with T4.0 and T4.1 and both versions work very well. However, they have the same problem as everyone has, when using the Teensy audio lib for recording on SD card: the audio buffer is too small to buffer the long write times that some SD cards need at some occasions.

    From my perspective, it is important to distinguish two test conditions (please note that I am using the latest modified software from https://github.com/DD4WH/audio-guestbook, which is different to the original software, because the original author has not merged my pull request from August, 4th 2022. This recent software also contains the full MTP functionality when plugged into a computer):

    1.) Phone (audio guest book) is connected to the Computer via USB: this is a condition that should NEVER be used to test recording. This is simply because (at least for all my use cases) I would always power the audio guest book by a power bank or separate power supply. Taking a Computer to your cocktail party and have people using the audio guest book while connected to a computer is simply not a use case that can be assumed. As has been nicely demonstrated in the posts above, if connected to a computer (and using the MTP service) all kinds of conflicts/problems can occur when recording.

    2.) Phone (audio guest book) is NOT connected to a computer, but powered by a USB power bank or plug-in power supply. This is the usual use case for the audio guest book (from my perspective). In all my tests, the audio recording in this test condition worked fine, except for the usual occasional hickups in the audio, but these are quite rare. These hickups are generated by the SD cards´ latency and could only be avoided by using a MUCH larger DMA audio buffer while recording.

    So, I think everyone should clearly state whether the severe auio problems remain, if the audio guest book is powered by USB power bank or external power supply. Please test your recording capability without connecting the audio guest book to a computer. This would be my hypothesis, i.e. that the problems should then disappear and only the usual hickups remain.

    Best regards, Frank DD4WH

  13. #188
    Senior Member h4yn0nnym0u5e's Avatar
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    520
    Quote Originally Posted by DD4WH View Post
    I am a little puzzled by the mentioned problem of severe recording problems (slowing down, speeding up, large parts of audio lost etc.).

    I have built four of these audio guest books, with T4.0 and T4.1 and both versions work very well. However, they have the same problem as everyone has, when using the Teensy audio lib for recording on SD card: the audio buffer is too small to buffer the long write times that some SD cards need at some occasions.

    From my perspective, it is important to distinguish two test conditions (please note that I am using the latest modified software from https://github.com/DD4WH/audio-guestbook, which is different to the original software, because the original author has not merged my pull request from August, 4th 2022. This recent software also contains the full MTP functionality when plugged into a computer):

    1.) Phone (audio guest book) is connected to the Computer via USB: this is a condition that should NEVER be used to test recording. This is simply because (at least for all my use cases) I would always power the audio guest book by a power bank or separate power supply. Taking a Computer to your cocktail party and have people using the audio guest book while connected to a computer is simply not a use case that can be assumed. As has been nicely demonstrated in the posts above, if connected to a computer (and using the MTP service) all kinds of conflicts/problems can occur when recording.

    2.) Phone (audio guest book) is NOT connected to a computer, but powered by a USB power bank or plug-in power supply. This is the usual use case for the audio guest book (from my perspective). In all my tests, the audio recording in this test condition worked fine, except for the usual occasional hickups in the audio, but these are quite rare. These hickups are generated by the SD cards´ latency and could only be avoided by using a MUCH larger DMA audio buffer while recording.

    So, I think everyone should clearly state whether the severe auio problems remain, if the audio guest book is powered by USB power bank or external power supply. Please test your recording capability without connecting the audio guest book to a computer. This would be my hypothesis, i.e. that the problems should then disappear and only the usual hickups remain.

    Best regards, Frank DD4WH
    The trouble is, you're an experienced user and know what to do...

    This project clearly appeals to a lot of people with much less experience, and is presented as "hey folks, this is really simple, just plug the stuff together and it'll work". No mention of pitfalls, what to check, examples of what happens if you do something slightly wrong, no diagnostic options in the code etc. Because of this broad appeal, good luck with getting a clear statement of the problems. "Hickups", "speeding up", "audio lost" and other descriptions are extremely vague; few people obey the Forum Rule and post the exact code they're running, they just say "it's the latest" (if they say anything at all); I don't think anyone has said whether their issues are different when connected to a PC or power bank.

    You don't "clearly state" whether your Teensy 4.1 builds use the audio adaptor SD slot or the built-in one, which is supposedly better. The posts here suggested issues with the built-in one, and that's what my testing revealed: combining the Teensy 4.1 built-in slot with an active PC MTP connection causes severe recording problems independent of short-term SD card write delays. Thanks to KurtE's help with the MTP library we managed to get to the bottom of the issue and publish a fix, though it's a bit of a bodge (turn off MTP medium change checks while recording).

    I think for projects like this, those of us who are contributing should be mindful of how a naive user might try to use it, and test to see if it works OK. If so, fine; if not, either fix it or put in a big red warning not to use the combination that doesn't work (and be prepared for the majority of users who don't read the documentation). You presumably didn't test with Teensy 4.1 + PC with MTP + built-in SD card slot, or you'd immediately have spotted the issue! I freely confess that at no time have I tested a stand-alone system with a phone, microphone and power bank ... but I probably should have. Adding MTP is clearly useful, but it did introduce a failure mode that wasn't previously present, and wasn't documented.

  14. #189
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Location
    Central Europe
    Posts
    704
    Thanks for being so open and clear in your statements! I totally agree to most of them :-).

    However, I would like to emphasize a few things:

    * it was the original author of the code, who presented the project in a YouTube video, which lead many people to think this is an easy-peasy project, not me :-). I clearly emphasized the degree of complexity in the readme of my github clone and added a ton of explanations, descriptions, pitfalls etc. etc. etc. For example I added this as the very first sentence in the readme "If you do not have a good soldering iron and a fine solder tip or if you have never soldered, I would recommend NOT to try to build this, but to start with a less complex project!" (however, the original author did not merge my pull request, so this "warning" and the documentation was not included in the original github) --> click this link and you will see what I mean: https://github.com/DD4WH/audio-guestbook

    * Yes, you are correct, I did not state which SD slot I use on the T4.1. It is the built-in T4.1 slot, which is clearly explained in the code AND in the readme . . .

    * I explained the "hickup" problem several times in this thread, but much earlier, some months ago, I think

    * Yes, you are absolutely correct, and it is helpful that you discovered the bug occuring when using Recording and MTP at the same time. I never recorded when the audio guest book was connected to the computer, because that is not a common use case (I would say, it is not a use case at all), for the reasons I gave in my previous post. You would not carry your computer together with the audio guest book to a party. The use case is to take the audio guest book and power it by a power bank or a power supply.

    So, what do we learn from this ? Building the Audio guest book is more complex than some people may think.

    I totally agree with you in all the good points that you make.

    In one aspect I would disagree:

    "be prepared for the majority of users who don't read the documentation"

    No, I am very sorry, that I have to say: I expect people who build this project (the Audio guest book) to read AND follow ALL the documentation steps.

    The documentation is very easy to find:

    The original code and very little documentation how to build this is here:
    https://github.com/playfultechnology/audio-guestbook

    The code modified by me with more detailed documentation can be found here (I added even more warnings on how not to use the Audio Guest Book ;-)):
    https://github.com/DD4WH/audio-guestbook


    Have fun with building the Audio Guest Book, but be prepared for some surprises, especially if you have not read the documentation in ALL details.
    Last edited by DD4WH; 11-24-2022 at 04:08 PM.

  15. #190
    Senior Member h4yn0nnym0u5e's Avatar
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    520
    Quote Originally Posted by DD4WH View Post
    Thanks for being so open and clear in your statements! I totally agree to most of them :-).

    However, I would like to emphasize a few things:

    * it was the original author of the code, who presented the project in a YouTube video, which lead many people to think this is an easy-peasy project, not me :-).
    100% agree .. didn't mean to imply you were implying it was easy
    Quote Originally Posted by DD4WH View Post

    I clearly emphasized the degree of complexity in the readme of my github clone and added a ton of explanations, descriptions, pitfalls etc. etc. etc. For example I added this as the very first sentence in the readme "If you do not have a good soldering iron and a fine solder tip or if you have never soldered, I would recommend NOT to try to build this, but to start with a less complex project!" (however, the original author did not merge my pull request, so this "warning" and the documentation was not included in the original github) --> click this link and you will see what I mean: https://github.com/DD4WH/audio-guestbook

    * Yes, you are correct, I did not state which SD slot I use on the T4.1. It is the built-in T4.1 slot, which is clearly explained in the code AND in the readme . . .
    True, and I agree it would have been very helpful if the author had pulled your still-pending PR. But he hasn't, and thus all your efforts to warn and document are extremely unlikely to be found by the "vanilla user", unless they're astonishingly diligent. You and I might look at unmerged PRs if we had issues, but most people ... don't bet on it.
    Quote Originally Posted by DD4WH View Post
    * I explained the "hickup" problem several times in this thread, but much earlier, some months ago, I think
    Again true, but the MTP / PC issue is more than the usual hiccup of a few ms - in my experience it's a full 1 second, and it's not due to SD card internal latency, it's an interaction of the MTP and SdFat libraries. And it's very clear that a significant proportion of people don't read this whole thread before posting...
    Quote Originally Posted by DD4WH View Post
    * Yes, you are absolutely correct, and it is helpful that you discovered the bug occuring when using Recording and MTP at the same time. I never recorded when the audio guest book was connected to the computer, because that is not a common use case (I would say, it is not a use case at all), for the reasons I gave in my previous post. You would not carry your computer together with the audio guest book to a party. The use case is to take the audio guest book and power it by a power bank or a power supply.
    Final use case, absolutely. Doing a quick test at home to see if you've got it right? Not so much ... especially as the upstream documentation doesn't have a warning NOT to do this, only your unmerged PR's ReadMe. You might even want to move that warning up to the second paragraph. In italics. And bold.
    Quote Originally Posted by DD4WH View Post
    So, what do we learn from this ? Building the Audio guest book is more complex than some people may think.

    I totally agree with you in all the good points that you make.

    In one aspect I would disagree:

    "be prepared for the majority of users who don't read the documentation"

    No, I am very sorry, that I have to say: I expect people who build this project (the Audio guest book) to read AND follow ALL the documentation steps.

    The documentation is very easy to find:

    The original code and very little documentation how to build this is here:
    https://github.com/playfultechnology/audio-guestbook

    The code modified by me with more detailed documentation can be found here (I added even more warnings on how not to use the Audio Guest Book ;-)):
    https://github.com/DD4WH/audio-guestbook


    Have fun with building the Audio Guest Book, but be prepared for some surprises, especially if you have not read the documentation in ALL details.
    If you expect people to read documentation thoroughly, I fear you're likely to be disappointed. Not in every case, but a significant proportion of the time. Just look at the number of people on this forum who fail to follow the Forum Rule, despite it being at the top of every page, with bold and red text and everything. But if you "expect" it, fine ... in the end it's just a difference of opinion on what's going to happen in the Real World, which would be a sad place indeed if we were all the same

    I haven't even built an audio guestbook for myself yet (no use for it just now)! I might, at some point...

  16. #191
    Hi . Sorry for my English.Where can I change the recording time? so people can't leave messages for longer than say 60 seconds? Just in case someone left it off the hook and filled up the card

  17. #192
    Junior Member
    Join Date
    Nov 2022
    Posts
    2
    Hi to everyone.
    Thank you for your hard work on this project. It's around 1 month that i try to work on this, and I never meant to disturb you but I really can't get on with the project.

    I made the project with a Teensy 4.0 + Audio dev board + 4gb micro SD ( EXFAT formatted ).

    The code used is this: https://github-com/DD4WH/audio-guestbook

    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-guest...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");
    }
    I connected everything as in the guide but when I pick up the handset I hear only one "beep", only one, then I hear nothing.
    Nothing is recorded and nothing is written to the SD which remains empty.




    I have no more ideas on how to move forward.
    Last edited by KurtE; 11-28-2022 at 01:47 PM. Reason: code tags

  18. #193
    Junior Member
    Join Date
    Nov 2022
    Posts
    2
    Quote Originally Posted by Nendiu44 View Post
    Hi to everyone.
    Thank you for your hard work on this project. It's around 1 month that i try to work on this, and I never meant to disturb you but I really can't get on with the project.

    I made the project with a Teensy 4.0 + Audio dev board + 4gb micro SD ( EXFAT formatted ).

    The code used is this: https://github-com/DD4WH/audio-guestbook

    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-guest...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");
    }
    I connected everything as in the guide but when I pick up the handset I hear only one "beep", only one, then I hear nothing.
    Nothing is recorded and nothing is written to the SD which remains empty.




    I have no more ideas on how to move forward.

    Hi, sorry but i find some errors in the code and i fix the beep problem ... and now i can record !
    But when I play back the waw files from my computer I hear them as if the audio is speeded up to 10x !
    I don't know if I can explain myself, but it's like I talk very fast!
    How can I fix this thing?

    Thank you.

  19. #194
    Junior Member
    Join Date
    Nov 2022
    Location
    Germany
    Posts
    3
    Hello,
    can you help me please with the lines of code .thank you

    i have this error.

    Arduino: 1.8.19 (Windows 10), TD: 1.57-beta1, Board: "Teensy 4.0, Serial, 600 MHz, Faster, US English, Normal"





















    C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\ccc\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\ccc\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -fqbn=teensy:avr:teensy40:usb=serial,speed=600,opt= o2std,keys=en-us,audiotune=normal -ide-version=10819 -build-path C:\Users\ccc\AppData\Local\Temp\arduino_build_3761 99 -warnings=none -build-cache C:\Users\ccc\AppData\Local\Temp\arduino_cache_7417 01 -verbose C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino

    C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\ccc\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\ccc\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -fqbn=teensy:avr:teensy40:usb=serial,speed=600,opt= o2std,keys=en-us,audiotune=normal -ide-version=10819 -build-path C:\Users\ccc\AppData\Local\Temp\arduino_build_3761 99 -warnings=none -build-cache C:\Users\ccc\AppData\Local\Temp\arduino_cache_7417 01 -verbose C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino

    Using board 'teensy40' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr

    Using core 'teensy4' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr

    Detecting libraries used...

    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy4" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_bui ld_376199\\sketch\\audio-guestbook.ino.cpp" -o nul

    Alternatives for Bounce.h: [Bounce]

    ResolveLibrary(Bounce.h)

    -> candidates: [Bounce]

    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Bounce" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_bui ld_376199\\sketch\\audio-guestbook.ino.cpp" -o nul

    Alternatives for Audio.h: [Audio@1.3]

    ResolveLibrary(Audio.h)

    -> candidates: [Audio@1.3]

    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Audio" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_bui ld_376199\\sketch\\audio-guestbook.ino.cpp" -o nul

    Alternatives for SPI.h: [SPI@1.0]

    ResolveLibrary(SPI.h)

    -> candidates: [SPI@1.0]

    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ SPI" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_bui ld_376199\\sketch\\audio-guestbook.ino.cpp" -o nul

    Alternatives for SD.h: [SD@1.2.4 SD@2.0.0]

    ResolveLibrary(SD.h)

    -> candidates: [SD@1.2.4 SD@2.0.0]

    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ SD\\src" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_bui ld_376199\\sketch\\audio-guestbook.ino.cpp" -o nul

    Alternatives for SdFat.h: [SdFat@2.1.2]

    ResolveLibrary(SdFat.h)

    -> candidates: [SdFat@2.1.2]

    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ SD\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\ SdFat\\src" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_bui ld_376199\\sketch\\audio-guestbook.ino.cpp" -o nul

    Alternatives for SerialFlash.h: []

    In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:129:0,

    ResolveLibrary(SerialFlash.h) from C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:



    -> candidates: []86)\Arduino\hardware\teensy\avr\libraries\Audio/play_serialflash_raw.h:33:25: fatal error: SerialFlash.h: No such file or directory



    compilation terminated.

    Multiple libraries were found for "SD.h"

    Used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD

    Not used: C:\Program Files (x86)\Arduino\libraries\SD

    Using library Bounce in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Bounce (legacy)

    Using library Audio at version 1.3 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio

    Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SPI

    Using library SD at version 2.0.0 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD

    Using library SdFat at version 2.1.2 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SdFat

    Error compiling for board Teensy 4.0.

  20. #195
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,165
    SerialFlash library should have been included in your Teensyduino install.

    For example, building an audio sketch using IDE2 I see:
    Using library SerialFlash at version 0.5 in folder: C:\Users\kurte\AppData\Local\Arduino15\packages\te ensy\hardware\avr\0.58.2\libraries\SerialFlash

    Your post says: TD: 1.57-beta1

    I would suggest that you update to the 1.57 release or the beta 1.58 Beta 2...

  21. #196
    Junior Member
    Join Date
    Nov 2022
    Location
    Germany
    Posts
    3
    Quote Originally Posted by KurtE View Post
    SerialFlash library should have been included in your Teensyduino install.

    For example, building an audio sketch using IDE2 I see:
    Using library SerialFlash at version 0.5 in folder: C:\Users\kurte\AppData\Local\Arduino15\packages\te ensy\hardware\avr\0.58.2\libraries\SerialFlash

    Your post says: TD: 1.57-beta1

    I would suggest that you update to the 1.57 release or the beta 1.58 Beta 2...
    [U]Thanks......
    reinstalled teensyduino 1.57...but the error remained[/U]can you help me with this error

    Arduino: 1.8.19 (Windows 10), TD: 1.57, Board: "Teensy 4.0, Serial + MTP Disk (Experimental), 600 MHz, Faster, US English"



















    Code:
    C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -fqbn=teensy:avr:teensy40:usb=serialmtp,speed=600,opt=o2std,keys=en-us -ide-version=10819 -build-path C:\Users\ccc\AppData\Local\Temp\arduino_build_176380 -warnings=none -build-cache C:\Users\ccc\AppData\Local\Temp\arduino_cache_580773 -verbose C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino
    
    C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -fqbn=teensy:avr:teensy40:usb=serialmtp,speed=600,opt=o2std,keys=en-us -ide-version=10819 -build-path C:\Users\ccc\AppData\Local\Temp\arduino_build_176380 -warnings=none -build-cache C:\Users\ccc\AppData\Local\Temp\arduino_cache_580773 -verbose C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino
    
    Using board 'teensy40' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
    
    Using core 'teensy4' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
    
    Detecting libraries used...
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for Bounce.h: [Bounce]
    
    ResolveLibrary(Bounce.h)
    
      -> candidates: [Bounce]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for Audio.h: [Audio@1.3]
    
    ResolveLibrary(Audio.h)
    
      -> candidates: [Audio@1.3]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for SPI.h: [SPI@1.0]
    
    ResolveLibrary(SPI.h)
    
      -> candidates: [SPI@1.0]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SPI" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for SD.h: [SD@1.2.4 SD@2.0.0]
    
    ResolveLibrary(SD.h)
    
      -> candidates: [SD@1.2.4 SD@2.0.0]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SD\\src" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for SdFat.h: [SdFat@2.1.2]
    
    ResolveLibrary(SdFat.h)
    
      -> candidates: [SdFat@2.1.2]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SD\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SdFat\\src" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for SerialFlash.h: [SerialFlash@0.5]
    
    ResolveLibrary(SerialFlash.h)
    
      -> candidates: [SerialFlash@0.5]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SD\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SdFat\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SerialFlash" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for Wire.h: [Wire@1.0]
    
    ResolveLibrary(Wire.h)
    
      -> candidates: [Wire@1.0]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SD\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SdFat\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SerialFlash" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Wire" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for TimeLib.h: [Time@1.6.1]
    
    ResolveLibrary(TimeLib.h)
    
      -> candidates: [Time@1.6.1]
    
    "C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10819 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_MTPDISK_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Audio" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SD\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SdFat\\src" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\SerialFlash" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Wire" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Time" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_176380\\sketch\\audio-guestbook.ino.cpp" -o nul
    
    Alternatives for MTP_Teensy.h: []
    
    ResolveLibrary(MTP_Teensy.h)
    
      -> candidates: []
    
    C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:111: fatal error: MTP_Teensy.h: No such file or directory
    
    Multiple libraries were found for "SD.h"
    
    compilation terminated.
    
     Used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD
    
     Not used: C:\Program Files (x86)\Arduino\libraries\SD
    
    Using library Bounce in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Bounce (legacy)
    
    Using library Audio at version 1.3 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio 
    
    Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SPI 
    
    Using library SD at version 2.0.0 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD 
    
    Using library SdFat at version 2.1.2 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SdFat 
    
    Using library SerialFlash at version 0.5 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SerialFlash 
    
    Using library Wire at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire 
    
    Using library Time at version 1.6.1 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Time 
    
    Error compiling for board Teensy 4.0.
    Last edited by KurtE; 11-30-2022 at 02:50 PM. Reason: code tag

  22. #197
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,165
    Different error:
    Code:
    C:\Users\ccc\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:37:111: fatal error: MTP_Teensy.h: No such file or directory
    I am hoping that there is a README or the like that explains how to build this sketch. Note: I have never installed/built this sketch.

    But in this case, you need to install the MTP_Teensy library. This library has not yet been released into Teensyduino. Hopefully it will be by the next major Teensyduino release.

    You can download it from github: https://github.com/kurte/mtp_Teensy/

  23. #198
    Junior Member
    Join Date
    Nov 2022
    Location
    Germany
    Posts
    3
    It's a great project..congratulations to everyone who contributed to it....I almost managed to finish it...being a beginner...the only problem is that I'm using a Tesla phone and everything starts when I put the receiver on the hook.. instead of starting when I pick it up.. I saw a picture of this phone model posted by DD4WH but it's taken too close and I can't figure out how the connections are correct. Has anyone else encountered this problem?
    Thank you

Posting Permissions

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