Teensy 4.0 - based Audio Guestbook

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.
 

Attachments

  • testaudio.zip
    308.7 KB · Views: 98
More goodness (I hope) pushed to https://github.com/h4yn0nnym0u5e/audio-guestbook/tree/bugfix/better-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.
 
More goodness (I hope) pushed to https://github.com/h4yn0nnym0u5e/audio-guestbook/tree/bugfix/better-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!
 
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?
 
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.
 
Please help. I have a project made from the link https://github.com/DD4WH/audio-guestbook
One error pops up during programming: 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");
}
 
Everything department. define it was better. breaks off pieces of the recording while recording. It skips. Sandisk extreme u4 a2 v3 memory
 
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 :)
 
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
 
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.
 
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
 
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.
 
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:
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 :D
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.
* 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...
* 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.
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...
 
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
 
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:
 * [url]https://github.com/DD4WH/audio-guestbook/blob/main/README.md[/url]
 * 
 * 
 *   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/"): [url]https://github.com/KurtE/MTP_Teensy[/url]
 *   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 ([url]https://github.com/KurtE/MTP_Teensy[/url])
// 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 [url]https://www.pjrc.com/teensy/gui/[/url]
// 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 [url]https://github.com/PaulStoffregen/Time[/url]
  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 a moderator:
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:
 * [url]https://github.com/DD4WH/audio-guestbook/blob/main/README.md[/url]
 * 
 * 
 *   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/"): [url]https://github.com/KurtE/MTP_Teensy[/url]
 *   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 ([url]https://github.com/KurtE/MTP_Teensy[/url])
// 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 [url]https://www.pjrc.com/teensy/gui/[/url]
// 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 [url]https://github.com/PaulStoffregen/Time[/url]
  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.
 
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_376199 -warnings=none -build-cache C:\Users\ccc\AppData\Local\Temp\arduino_cache_741701 -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_376199 -warnings=none -build-cache C:\Users\ccc\AppData\Local\Temp\arduino_cache_741701 -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\\teensy4" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_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\\teensy4" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\libraries\\Bounce" "C:\\Users\\ccc\\AppData\\Local\\Temp\\arduino_build_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\\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_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\\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_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\\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_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\\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_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.
 
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\teensy\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...
 
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\teensy\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 a moderator:
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/
 
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
 
Hi together, I'm trying to get this running...
I have a Teensy 3.6 (4.0/4.1 was not in stock...) with the audio shield.
I downloaded DD4WH´s code and tried to compile as said in the documentation, but I still get this error message:
Code:
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:129:0,
                 from C:\Users\Admin\Documents\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_serialflash_raw.h:33:25: fatal error: SerialFlash.h: No such file or directory
compilation terminated.
Fehler beim Kompilieren für das Board Teensy 3.6.

How can I Solve this? I installed everything like it's in the documentation.
 
Hi together, I'm trying to get this running...
I have a Teensy 3.6 (4.0/4.1 was not in stock...) with the audio shield.
I downloaded DD4WH´s code and tried to compile as said in the documentation, but I still get this error message:
Code:
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:129:0,
                 from C:\Users\Admin\Documents\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:32:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_serialflash_raw.h:33:25: fatal error: SerialFlash.h: No such file or directory
compilation terminated.
Fehler beim Kompilieren für das Board Teensy 3.6.

How can I Solve this? I installed everything like it's in the documentation.

What version of TeensyDuino are you running ?? <This> previous post indicates that TD1.57 or newer may be required.

Mark J Culross
KD5RXT
 
Back
Top