Teensy 4.0 - based Audio Guestbook

I don't know where you are, you have not put that information in when you registered for the PJRC forum, but the Adaptor card can be bought here for worldwide shipment.
 
Hey, so i used my phone at a wedding for the 1st time last night, despite the issues i was having. everything worked pretty will. only a few things i have issues with. 1 is my original problem where after i playback last message and hang up, it switches to recording mode instead of back to ready. 2nd thing i had a problem with last night was if someone listens picks up the phone but hangs up before the greeting ends, it won't go back to ready mode, so upon hang up, it will continue to record until someone else picks up the phone. which brings me to the 3rd thing, is there a way to limit recording size, lets say to 1 minute and it will automatically end the recording and go into ready mode with the phone in hand, AND STAY in ready mode when the phone is hung up? keep in mind, when i have the phone plugged into my laptop, issues 1 and 2 don't exit, the phone behaves properly. can anyone offer any insight?
 
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.

Hello,

I was the same problem.

I find the missing data in this website. https://github.com/PaulStoffregen/

All is good after.
 
I badly need help. I followed all the steps and connected everything. Copy pasted the code (removed Teensy 4.1 part as I am using 4.0), compiled successfully, then nothing. Not even a beep.

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

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

I have the same problem. Wiring and Pin Settings are correct. Any idea how to fix this? Teensy 4.0 with rev d Audio shield
 
I have the same problem. Wiring and Pin Settings are correct. Any idea how to fix this? Teensy 4.0 with rev d Audio shield

Same problem too.

I use teensy 4.0 with audio shield REV D2. I changed too mi SD PIN to 10, 11,13 but the it's the same.

I have this line when I compile. I don't know what is it.

/Users/Jeff/Documents/Teensyduino/libraries/MTP_Teensy-main/src/MTP_Teensy.cpp: In member function 'uint32_t MTP_class::GetObjectInfo(MTP_class::MTPContainer&)':
/Users/Jeff/Documents/Teensyduino/libraries/MTP_Teensy-main/src/MTP_Teensy.cpp:523:34: warning: unknown option after '#pragma GCC diagnostic' kind [-Wpragmas]
#pragma GCC diagnostic ignored "-Wformat-truncation" /* Or "-Wformat-truncation" */
 
Hello,

I was the same problem.

I find the missing data in this website. https://github.com/PaulStoffregen/

All is good after.

Same problem too.

I use teensy 4.0 with audio shield REV D2. I changed too mi SD PIN to 10, 11,13 but the it's the same.

I have this line when I compile. I don't know what is it.

/Users/Jeff/Documents/Teensyduino/libraries/MTP_Teensy-main/src/MTP_Teensy.cpp: In member function 'uint32_t MTP_class::GetObjectInfo(MTP_class::MTPContainer&)':
/Users/Jeff/Documents/Teensyduino/libraries/MTP_Teensy-main/src/MTP_Teensy.cpp:523:34: warning: unknown option after '#pragma GCC diagnostic' kind [-Wpragmas]
#pragma GCC diagnostic ignored "-Wformat-truncation" /* Or "-Wformat-truncation" */

Edit: My problem was bad connexion all is ok now with my SD card. I have a problem with a bad audio quality with the micro but I will test other cable or soldering...
 
Hi, again. Finally get the guestbook working :eek: thank you all in sharing your knowledge. I have some background noise in the audio recording from the original microphone. Seems there are some interferences in the cable. Does anybody has some recommendation how to fix it? Attached is a sample recorded directly on the phone. i have tried to keep the wires short as possible. I have soldered the pins to MIC and GND and attached with regular pin connector. Please see picture attached.
1. Will a new capsule microphone: https://www.reichelt.com/de/en/elec...-5024l-hd-r-p285350.html?&trstct=pol_12&nbc=1
2. Or do i have messed something up with the wiring?

I get the same background noise when i power the teensy with an external power bank. Also i have removed a metal plate on the bottom of the phone.
Thank you.

IMG_7706.jpg
IMG_7707.jpg
IMG_7708.jpg
View attachment greeting.zip
 
Last edited:
That sample is incredibly quiet, so I'm not surprised the noise level is high. From your third image it looks as if you have the mic ground (black wire) connected to the mic input of the audio card ... though of course, as you don't show the other end, that could be wired backwards too, which would cancel the problem out.

As it's so cheap, it seems a reasonable chance to take to try a different microphone. If it works, do report back.
 
That sample is incredibly quiet, so I'm not surprised the noise level is high. From your third image it looks as if you have the mic ground (black wire) connected to the mic input of the audio card ... though of course, as you don't show the other end, that could be wired backwards too, which would cancel the problem out.

As it's so cheap, it seems a reasonable chance to take to try a different microphone. If it works, do report back.

Thanks for coming back to me... I have already tried to switch the black and yellow wires. Unfortunately without look. Still bad audio. If i increase the volume, the background noise seems to be louder as well. I will give it a try again later today to pump up the volume. I will purchase a microphone to check if the result will be better. Will report the result asap.
 
If i increase the volume, the background noise seems to be louder as well.
This isn't very surprising ... if you record a quiet signal with a lot of noise, turning the volume up will just turn the noise up along with the signal. You need to get a better signal into the WAV file.

I just looked at the audio library code, and the mic gain defaults to +52dB. It is possible to increase this to +63db, if you put in a line sgtl5000_1.micGain(63); - this must be after sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);. It will at least make your WAV file louder, though it may be just as noisy - from your images, the mic wires are neither twisted together nor shielded. You could try removing the capsule from the phone and connecting it directly to the audio adaptor with very short wires, which would probably reduce noise though it won't boost the signal.
 
Hi everybody,

I have a problem with my audio guestbook with bad record with my micro.
I test code of DD4WH and there is issus with record. I test code of playfull and all is OK with record. So, I think the MTP during records is the source of my problem.

I am newby in code. I woulds like to keep the code of DD4WH because I can record greeting wav directly to the phone, but I would like add MTP disable during record.

Do you know how I will do?

If I add this line "MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1);" is enough or it's more difficult.

Other solution, integrated auto greeting Wave code in the code of playfull.
One person have made that!

Thank you very much.

Have a good day.

Jeff
 
So, I think the MTP during records is the source of my problem.

I am newby in code. I woulds like to keep the code of DD4WH because I can record greeting wav directly to the phone, but I would like add MTP disable during record.

Do you know how I will do?

If I add this line "MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1);" is enough or it's more difficult.
It's not quite as simple as that, unfortunately. Here's a selection of the MTP enable / disable code, as found in the original repository:
Code:
uint32_t MTPcheckInterval; // default value of device check interval [ms]

...

void setup() {

...

  // mandatory to begin the MTP session.
    MTP.begin();

  // Add SD Card
    MTP.addFilesystem(SD, "Kais Audio guestbook"); // choose a nice name for the SD card volume to appear in your file explorer
    Serial.println("Added SD card via MTP");
    MTPcheckInterval = MTP.storage()->get_DeltaDeviceCheckTimeMS();

...

}

...

void setMTPdeviceChecks(bool nable)
{
  if (nable)
  {
    MTP.storage()->set_DeltaDeviceCheckTimeMS(MTPcheckInterval);
    Serial.print("En");
  }
  else
  {
    MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1);
    Serial.print("Dis");
  }
  Serial.println("abled MTP storage device checks");
}
  
...

void startRecording() {
  setMTPdeviceChecks(false); // disable MTP device checks while recording

...

}

...

void stopRecording() {

...

  setMTPdeviceChecks(true); // enable MTP device checks, recording is finished
}
Key points to note:
  • create storage for the MTP check interval
  • in setup(), find the default value for the MTP check interval
  • before recording starts, disable MTP checks (set interval to -1)
  • after recording finishes, restore checks by setting interval back to the default
I can't be 100% sure that's complete, but it's the main idea. Take a look at the changes made in PR#20 if anything doesn't work.

Unrelated to the MTP issue, but worth noting, is that DD4WH's generation of the WAV chunks is incorrect, which is also fixed in the original repository - look at the calculations of the Subchunk2Size and ChunkSize values. Not every application shows a visible error, but it could be that some will appear to play the files but actually emit no audio. Groove Music and Windows Media Player play without complaining, but GoldWave gives two warnings before it'll load such a file.
 
Unrelated to the MTP issue, but worth noting, is that DD4WH's generation of the WAV chunks is incorrect, which is also fixed in the original repository - look at the calculations of the Subchunk2Size and ChunkSize values. Not every application shows a visible error, but it could be that some will appear to play the files but actually emit no audio. Groove Music and Windows Media Player play without complaining, but GoldWave gives two warnings before it'll load such a file.
Hmm, I cannot reproduce a problem in playing the WAV files recorded with my code, they play correctly and smoothly with different players on different devices.

You may be right that the chunk lengths are inconsistent (I am not a specialist in WAV headers), but the files are playing and sound nicely . . .

As you claim in various threads that there are issues with the code in my repo (which I cannot reproduce, because I built four Audio Guest Books with my code which function flawlessly and I have provided a very detailed Manual how to build the hardware and software !), I will now delete my repo in order for all those people interested in the Audio guest Book to have ONE consistent code source. I am sorry that my code and my manual in the Readme produced problems, but without reproducible issue descriptions, there is no way for me to offer any help. And just claiming that "it could be that some will [...] actually emit no audio" without reproducible facts is just blind guessing/fantasy . . . but from now on it will be easier, no more problems to choose between different code sources.

Have fun with the Teensy !
 
So I am using a teensy 4.1 and the 4x audio sheild. I'm using the original code to program the board. The only change I made is to use a RAW greeting file instead of a wav file because the wav file playback was horrible. Over all it's working but I have run into a horrible issue. In which I haven't found a clear answer to. When ever it records the audio play back is just a buzzing noise nothing else. I do not get buzzing noise on the greetings just the recording. I've even removed the mic input to test and see if the recording would sound silent. Nope it's still buzzing. I've even changed the code to work off of the line in instead of the mic and nothing has changed. I've removed the old microphone and replaced it with a electret mic from Amazon still no audio just buzzing. I'm powering the teensy from a external battery pack. I've checked all of my soldering and wiring.... I do not know how to solve this issue. Could someone please help?
 
Hmm, I cannot reproduce a problem in playing the WAV files recorded with my code, they play correctly and smoothly with different players on different devices.

You may be right that the chunk lengths are inconsistent (I am not a specialist in WAV headers), but the files are playing and sound nicely . . .

As you claim in various threads that there are issues with the code in my repo (which I cannot reproduce, because I built four Audio Guest Books with my code which function flawlessly and I have provided a very detailed Manual how to build the hardware and software !), I will now delete my repo in order for all those people interested in the Audio guest Book to have ONE consistent code source. I am sorry that my code and my manual in the Readme produced problems, but without reproducible issue descriptions, there is no way for me to offer any help. And just claiming that "it could be that some will [...] actually emit no audio" without reproducible facts is just blind guessing/fantasy . . . but from now on it will be easier, no more problems to choose between different code sources.

Have fun with the Teensy !

I am right about the chunk lengths - here's the Goldwave error message:
2023-03-27 18_16_03-GoldWave.png
As I also noted, I have players which play the resulting files without complaint; but I don't think it's totally unreasonable to say "it could be that some will [...] actually emit no audio" - "could be" means just that, and I don't have the resources to test every application on every OS and give an exhaustive list of those that fail. I don't actually think it's very likely that it's causing anyone problems, it seems far more probable that it's defective hardware, given the wording of most of the "I finally got it working" posts.

As far as I can recall this is the only issue with your code I've mentioned in these forums. I would have reported it on your repo, but I couldn't because that option isn't available to me. I'm not a specialist in the WAV file format either, but when I had to create code to read and write WAV files I did the research and tested the results (where Goldwave came in really handy, as it was the only application I have that spots the problems).

Up to you whether you pull your repo. I think it has some really good features that builders seem to want, so it'd be a much more popular result to fix the chunk lengths. I've been waiting for my latest PR to be adopted into the upstream repo, and was then going to see if I could fairly simply merge your features and documentation, but it looks like the author has lost interest in supporting it :( That's just another blind guess...
 
This isn't very surprising ... if you record a quiet signal with a lot of noise, turning the volume up will just turn the noise up along with the signal. You need to get a better signal into the WAV file.

I just looked at the audio library code, and the mic gain defaults to +52dB. It is possible to increase this to +63db, if you put in a line sgtl5000_1.micGain(63); - this must be after sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);. It will at least make your WAV file louder, though it may be just as noisy - from your images, the mic wires are neither twisted together nor shielded. You could try removing the capsule from the phone and connecting it directly to the audio adaptor with very short wires, which would probably reduce noise though it won't boost the signal.
Update: as noted on another thread, there's already a call to sgtl5000_1.micGain(); in the code, which typically sets the gain very low (somewhere between +5 and +15dB, depending on which repo you start from). This is very low, so more level can be achieved for sure - the default is +52dB, and you can set between 0 and +63. However, depending on your hardware quality, and in particular the shielding of the mic cable, you may just get a louder and very noisy WAV file. But at least it won't be an apparently flatline piece of audio that you can't hear at all...
 
It's not quite as simple as that, unfortunately. Here's a selection of the MTP enable / disable code, as found in the original repository:
Code:
uint32_t MTPcheckInterval; // default value of device check interval [ms]

...

void setup() {

...

  // mandatory to begin the MTP session.
    MTP.begin();

  // Add SD Card
    MTP.addFilesystem(SD, "Kais Audio guestbook"); // choose a nice name for the SD card volume to appear in your file explorer
    Serial.println("Added SD card via MTP");
    MTPcheckInterval = MTP.storage()->get_DeltaDeviceCheckTimeMS();

...

}

...

void setMTPdeviceChecks(bool nable)
{
  if (nable)
  {
    MTP.storage()->set_DeltaDeviceCheckTimeMS(MTPcheckInterval);
    Serial.print("En");
  }
  else
  {
    MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1);
    Serial.print("Dis");
  }
  Serial.println("abled MTP storage device checks");
}
  
...

void startRecording() {
  setMTPdeviceChecks(false); // disable MTP device checks while recording

...

}

...

void stopRecording() {

...

  setMTPdeviceChecks(true); // enable MTP device checks, recording is finished
}
Key points to note:
  • create storage for the MTP check interval
  • in setup(), find the default value for the MTP check interval
  • before recording starts, disable MTP checks (set interval to -1)
  • after recording finishes, restore checks by setting interval back to the default
I can't be 100% sure that's complete, but it's the main idea. Take a look at the changes made in PR#20 if anything doesn't work.

Unrelated to the MTP issue, but worth noting, is that DD4WH's generation of the WAV chunks is incorrect, which is also fixed in the original repository - look at the calculations of the Subchunk2Size and ChunkSize values. Not every application shows a visible error, but it could be that some will appear to play the files but actually emit no audio. Groove Music and Windows Media Player play without complaining, but GoldWave gives two warnings before it'll load such a file.

Thank you for your answer. It's a little bit difficult for me without experience in "code".
I will try to incorporate the MTP code in order to disable it during recording. If I don't made that, I will try to incorporate the code of auto greeting wave in the original code because for me, this fonction is very good.
One question : " in setup(), find the default value for the MTP check interval" => I don't find in the original code a value . If I don't write any value, all will be ok?

Thank you.

Have a good day.
Jeff
 
Hmm, I cannot reproduce a problem in playing the WAV files recorded with my code, they play correctly and smoothly with different players on different devices.

You may be right that the chunk lengths are inconsistent (I am not a specialist in WAV headers), but the files are playing and sound nicely . . .

As you claim in various threads that there are issues with the code in my repo (which I cannot reproduce, because I built four Audio Guest Books with my code which function flawlessly and I have provided a very detailed Manual how to build the hardware and software !), I will now delete my repo in order for all those people interested in the Audio guest Book to have ONE consistent code source. I am sorry that my code and my manual in the Readme produced problems, but without reproducible issue descriptions, there is no way for me to offer any help. And just claiming that "it could be that some will [...] actually emit no audio" without reproducible facts is just blind guessing/fantasy . . . but from now on it will be easier, no more problems to choose between different code sources.

Have fun with the Teensy !

I didn't mean to be rude with my question. On the contrary, I am very grateful to you for all the work you have done and share with everyone on this project. I especially like your code because it has the autogreeting function. On the other hand, I work in the food industry so I'm neither good at welding nor at coding. After much wiring or hardware testing, the sound level was better with the original code. but by dint of soldering and other tests I probably damaged my teensy.
I hope you can continue to share on this forum because your work and experience has helped a lot of people.
 
"Reference to 'file' ambiguous" - help!

Hi, I am working on this project and I have gotten pretty far. I was able to solve my duplicate SD problem using the instructions in this thread and on reddit but now I am getting an error when compiling that said "reference to 'file' is ambiguous" full error is immediately below and further down I have included my full code.
Error code:
Code:
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:37: warning: "FILE_READ" redefined
   37 | #define FILE_READ  0
      | 
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:23: note: this is the location of the previous definition
   23 | #define FILE_READ O_READ
      | 
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:38: warning: "FILE_WRITE" redefined
   38 | #define FILE_WRITE 1
      | 
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:24: note: this is the location of the previous definition
   24 | #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)
      | 
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:75:17: error: reference to 'File' is ambiguous
   75 |         virtual File openNextFile(uint8_t mode=0) = 0;
      |                 ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:47:7: note:                 'class File'
   47 | class File;
      |       ^~~~
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h: In member function 'File File::openNextFile(uint8_t)':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:216:33: error: 'class FileImpl' has no member named 'openNextFile'
  216 |                 return (f) ? f->openNextFile(mode) : *this;
      |                                 ^~~~~~~~~~~~
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h: At global scope:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:276:17: error: reference to 'File' is ambiguous
  276 |         virtual File open(const char *filename, uint8_t mode = FILE_READ) = 0;
      |                 ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:290:9: error: reference to 'File' is ambiguous
  290 |         File open(const String &filepath, uint8_t mode = FILE_READ) {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:178:9: error: reference to 'File' is ambiguous
  178 |         File open(uint32_t store, const char *filename, uint32_t mode) {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:287:9: error: reference to 'File' is ambiguous
  287 |         File index_;
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:288:9: error: reference to 'File' is ambiguous
  288 |         File file_;
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:289:9: error: reference to 'File' is ambiguous
  289 |         File child_;
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
In file included from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h: In member function 'uint32_t MTP_class::addFilesystem(SDLib::SDClass&, const char*)':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:78:25: error: no matching function for call to 'MTP_class::addFilesystem(SDLib::SDClass&, const char*&, mtp_fstype_t)'
   78 |     return addFilesystem(disk, diskname, MTP_FSTYPE_SD);
      |            ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:76:12: note: candidate: 'uint32_t MTP_class::addFilesystem(SDLib::SDClass&, const char*)'
   76 |   uint32_t addFilesystem(SDClass &disk, const char *diskname) {
      |            ^~~~~~~~~~~~~
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:76:12: note:   candidate expects 2 arguments, 3 provided
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:82:12: note: candidate: 'uint32_t MTP_class::addFilesystem(FS&, const char*, mtp_fstype_t)'
   82 |   uint32_t addFilesystem(FS &disk, const char *diskname, mtp_fstype_t fstype = MTP_FSTYPE_UNKNOWN);
      |            ^~~~~~~~~~~~~
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:82:30: note:   no known conversion for argument 1 from 'SDLib::SDClass' to 'FS&'
   82 |   uint32_t addFilesystem(FS &disk, const char *diskname, mtp_fstype_t fstype = MTP_FSTYPE_UNKNOWN);
      |                          ~~~~^~~~
In file included from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:31:
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\play_sd_wav.h: At global scope:
play_sd_wav.h:49: error: reference to 'File' is ambiguous
   49 |         File wavfile;
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:63:1: error: reference to 'File' is ambiguous
   63 | File frec;
      | ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void setup()':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:158:3: error: 'FsDateTime' has not been declared
  158 |   FsDateTime::setCallback(dateTime);
      |   ^~~~~~~~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void startRecording()':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:277:3: error: 'frec' was not declared in this scope; did you mean 'free'?
  277 |   frec = SD.open(filename, FILE_WRITE);
      |   ^~~~
      |   free
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void continueRecording()':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:309:5: error: 'frec' was not declared in this scope; did you mean 'free'?
  309 |     frec.write(buffer, sizeof buffer);
      |     ^~~~
      |     free
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void stopRecording()':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:333:5: error: 'frec' was not declared in this scope; did you mean 'free'?
  333 |     frec.write((byte*)queue1.readBuffer(), AUDIO_BLOCK_SAMPLES*sizeof(int16_t));
      |     ^~~~
      |     free
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:339:3: error: 'frec' was not declared in this scope; did you mean 'free'?
  339 |   frec.close();
      |   ^~~~
      |   free
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void playAllRecordings()':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:348:3: error: reference to 'File' is ambiguous
  348 |   File dir = SD.open("/");
      |   ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:351:5: error: reference to 'File' is ambiguous
  351 |     File entry =  dir.openNextFile();
      |     ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/play_sd_raw.h:32,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Audio/Audio.h:127,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:25:
C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:28:9: note: candidates are: 'class SDLib::File'
   28 |   class File : public Stream {
      |         ^~~~
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Storage.h:35,
                 from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\MTP_Teensy-main\src/MTP_Teensy.h:45,
                 from C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:30:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:101:7: note:                 'class File'
  101 | class File final : public Stream {
      |       ^~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:352:16: error: 'entry' was not declared in this scope
  352 |     if (strstr(entry.name(), "greeting"))
      |                ^~~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:354:17: error: 'dir' was not declared in this scope; did you mean 'div'?
  354 |        entry =  dir.openNextFile();
      |                 ^~~
      |                 div
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:356:10: error: 'entry' was not declared in this scope
  356 |     if (!entry) {
      |          ^~~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:366:16: error: 'entry' was not declared in this scope
  366 |     if (strstr(entry.name(), ".wav") || strstr(entry.name(), ".WAV")) {
      |                ^~~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:377:5: error: 'entry' was not declared in this scope
  377 |     entry.close();
      |     ^~~~~
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void dateTime(uint16_t*, uint16_t*, uint8_t*)':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:439:11: error: 'FS_DATE' was not declared in this scope; did you mean 'LS_DATE'?
  439 |   *date = FS_DATE(year(), month(), day());
      |           ^~~~~~~
      |           LS_DATE
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:442:11: error: 'FS_TIME' was not declared in this scope; did you mean 'FAT_TIME'?
  442 |   *time = FS_TIME(hour(), minute(), second());
      |           ^~~~~~~
      |           FAT_TIME
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino: In function 'void writeOutHeader()':
C:\Users\cassi\Downloads\audio-guestbook-main\audio-guestbook-main\audio-guestbook\audio-guestbook.ino:470:3: error: 'frec' was not declared in this scope; did you mean 'free'?
  470 |   frec.seek(0);
      |   ^~~~
      |   free
reference to 'File' is ambiguous


My complete code is here -



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 
 * 
 * Files are saved on SD card as 44.1kHz, 16-bit, mono signed integer RAW audio format 
 * --> changed this to WAV recording, DD4WH 2022_07_31
 * --> added MTP support, which enables copying WAV files from the SD card via the USB connection, DD4WH 2022_08_01
 * 
 * 
 * Frank DD4WH, August 1st 2022 
 * for a DBP 611 telephone (closed contact when handheld is lifted) & with recording to WAV file
 * contact for switch button 0 is closed when handheld is lifted
 * 
 * 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>
#include "play_sd_wav.h" // local copy with fixes

// DEFINES
// Define pins used by Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14
// And those used for inputs
#define HOOK_PIN 0
#define PLAYBACK_BUTTON_PIN 1

#define noINSTRUMENT_SD_WRITE

// 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
AudioPlaySdWavX              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};
Mode mode = Mode::Initialising;

float beep_volume = 0.04f; // not too loud :-)

uint32_t MTPcheckInterval; // default value of device check interval [ms]

// 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");
  Serial.printf("Audio block set to %d samples\n",AUDIO_BLOCK_SAMPLES);
  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.95);

  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
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) 
  {
    // stop here if no SD card, but print a message
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
    else Serial.println("SD card correctly initialized");


  // mandatory to begin the MTP session.
    MTP.begin();

  // Add SD Card
//    MTP.addFilesystem(SD, "SD Card");
    MTP.addFilesystem(SD, "Kais Audio guestbook"); // choose a nice name for the SD card volume to appear in your file explorer
    Serial.println("Added SD card via MTP");
    MTPcheckInterval = MTP.storage()->get_DeltaDeviceCheckTimeMS();
    
    // Value in dB
//  sgtl5000_1.micGain(15);
  sgtl5000_1.micGain(5); // 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() {
  // First, read the buttons
  buttonRecord.update();
  buttonPlay.update();

  switch(mode){
    case Mode::Ready:
      // Falling edge occurs when the handset is lifted --> 611 telephone
      if (buttonRecord.fallingEdge()) {
        Serial.println("Handset lifted");
        mode = Mode::Prompting; print_mode();
      }
      else if(buttonPlay.fallingEdge()) {
        //playAllRecordings();
        playLastRecording();
      }
      break;

    case Mode::Prompting:
      // Wait a second for users to put the handset to their ear
      wait(1000);
      // 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()) {
        // Check whether the handset is replaced
        buttonRecord.update();
        buttonPlay.update();
        // Handset is replaced
        if(buttonRecord.risingEdge()) {
          playWav1.stop();
          mode = Mode::Ready; print_mode();
          return;
        }
        if(buttonPlay.fallingEdge()) {
          playWav1.stop();
          //playAllRecordings();
          playLastRecording();
          return;
        }
        
      }
      // 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(buttonRecord.risingEdge()){
        // Debug log
        Serial.println("Stopping Recording");
        // Stop recording
        stopRecording();
        // Play audio tone to confirm recording has ended
        end_Beep();
      }
      else {
        continueRecording();
      }
      break;

    case Mode::Playing: // to make compiler happy
      break;  

    case Mode::Initialising: // to make compiler happy
      break;  
  }   
  
  MTP.loop();  // This is mandatory to be placed in the loop code.
}

void setMTPdeviceChecks(bool nable)
{
  if (nable)
  {
    MTP.storage()->set_DeltaDeviceCheckTimeMS(MTPcheckInterval);
    Serial.print("En");
  }
  else
  {
    MTP.storage()->set_DeltaDeviceCheckTimeMS((uint32_t) -1);
    Serial.print("Dis");
  }
  Serial.println("abled MTP storage device checks");
}
  

#if defined(INSTRUMENT_SD_WRITE)
static uint32_t worstSDwrite, printNext;
#endif // defined(INSTRUMENT_SD_WRITE)

void startRecording() {
  setMTPdeviceChecks(false); // disable MTP device checks while recording
#if defined(INSTRUMENT_SD_WRITE)
  worstSDwrite = 0;
  printNext = 0;
#endif // defined(INSTRUMENT_SD_WRITE)
  // 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() {
#if defined(INSTRUMENT_SD_WRITE)
  uint32_t started = micros();
#endif // defined(INSTRUMENT_SD_WRITE)
#define NBLOX 16  
  // Check if there is data in the queue
  if (queue1.available() >= NBLOX) {
    byte buffer[NBLOX*AUDIO_BLOCK_SAMPLES*sizeof(int16_t)];
    // 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.
    for (int i=0;i<NBLOX;i++)
    {
      memcpy(buffer+i*AUDIO_BLOCK_SAMPLES*sizeof(int16_t), queue1.readBuffer(), AUDIO_BLOCK_SAMPLES*sizeof(int16_t));
      queue1.freeBuffer();
    }
    // Write all 512 bytes to the SD card
    frec.write(buffer, sizeof buffer);
    recByteSaved += sizeof buffer;
  }
  
#if defined(INSTRUMENT_SD_WRITE)
  started = micros() - started;
  if (started > worstSDwrite)
    worstSDwrite = started;

  if (millis() >= printNext)
  {
    Serial.printf("Worst write took %luus\n",worstSDwrite);
    worstSDwrite = 0;
    printNext = millis()+250;
  }
#endif // defined(INSTRUMENT_SD_WRITE)
}

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(), AUDIO_BLOCK_SAMPLES*sizeof(int16_t));
    queue1.freeBuffer();
    recByteSaved += AUDIO_BLOCK_SAMPLES*sizeof(int16_t);
  }
  writeOutHeader();
  // Close the file
  frec.close();
  Serial.println("Closed file");
  mode = Mode::Ready; print_mode();
  setMTPdeviceChecks(true); // enable MTP device checks, recording is finished
}


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(buttonPlay.risingEdge() || buttonRecord.risingEdge()) { // FIX
      if(buttonPlay.fallingEdge() || buttonRecord.risingEdge()) { 
        playWav1.stop();
        mode = Mode::Ready; print_mode();
        return;
      }   
    }
  }
  // All files have been played
  mode = Mode::Ready; print_mode();
}

void playLastRecording() {
  // Find the first available file number
  uint16_t idx = 0; 
  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);
    // check, if file with index i exists
    if (!SD.exists(filename)) {
     idx = i - 1;
     break;
      }
  }
      // 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()) { // this works for playWav
      buttonPlay.update();
      buttonRecord.update();
      // Button is pressed again
//      if(buttonPlay.risingEdge() || buttonRecord.risingEdge()) { // FIX
      if(buttonPlay.fallingEdge() || buttonRecord.risingEdge()) {
        playWav1.stop();
        mode = Mode::Ready; print_mode();
        return;
      }   
    }
      // file has been played
  mode = Mode::Ready; print_mode();  
  end_Beep();
}


// 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 - 42; // because we didn't make space for the header to start with! Lose 21 samples...
  ChunkSize = Subchunk2Size + 34; // was 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 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 Serial.println(" Undefined");
}
 
Hi,

Almost everything works fine with mine, there is only thing that doesn't work the way I want.
I tried sending myself a voice message through whatsapp, export it as a 16 bit .wav file and name it greeting.wav to have this as the greeting message.
What happens next it that when I pick up the phone, it doesn't play the greeting message and just sounds the beeeep.
When I record a message in the phone and change the name to greeting.wav it works fine. Just not when I import a .wav file not recorded on the phone

Can someone help me with this? Thanks!

Coen
 
Has anyone completed this project with a model 500 rotary phone with a Net 425b module? My code is fully functional and I have completed the project with an Automatic Electric 80, but I have hit a road block when wiring the handset of my Western Electric Model 500. I have successfully wired the hookswitch and can see the indicator light pulse then flash as it does when it is playing my greeting then recording the wav file on the AE 80. I have tried A LOT of different configurations with the four wires from the handset to no avail. The best I can do is get it to play a kinda rhythmic electrical pulse while the greeting is supposed to be playing.

When preparing my WE 500 I removed the ringer and the power cord, perhaps I need to reconnect the power cord? Any thoughts? My wedding is 2 weeks away and I was planning on having a second phone in an alternate location, but relieved to already have one complete after hours upon hours of trial and error (I've never coded or soldered or worked with microcontrollers before). Thanks in advance for any help you may be able to provide!
 
When I pickup my handset, it goes quiet when my greeting should be playing then no beep and it starts like a clicking noise for when it is recording (I noticed the clicking noise is still there when I push the handset switch down as well). It creates files for when it's supposed to be recording but there is no audio when I listen to the file. Any suggestions on what the issue might be?
 
Last edited:
Hi guys, has anyone managed to find a solution to the audio ground loop mic noise issue? I'm using:

Teensy 4
Audio Shield Rev D2

I've successfully built three of these now using DD4WH repository (It works great! - Thank you so much!). The Mic polarity is correct but the earth loop is the only thing I just can't resolve.

I have tried different Microphones, shielded cables, running off battery instead of mains power etc. the only thing that reduces it is if I actually ground the board to me personally - not ideal lol. I've dealt with many audio loops in my lifetime but this one is driving me nuts. Any help will be great!
 
Hi all. I've got my audio guestbook "working", in that it functions like it should and records audio. However, I've got a terrible periodic ticking/thumping happening throughout all the recordings and I just cannot figure out the source.

I've used an inexpensive electret condenser microphone, which seems popular with Teensy in general. I've rewired the whole thing twice, using different cable. The issue persists while using a USB ground isolator between the power source and the board. The periodicity of it makes me wonder the Teensy/Audio shield itself is introducing the noise on each SD card write, which I haven't the first idea how to combat.

Here's a sample of the audio: https://soundcloud.com/johnlago/aud...uIC9tJVey?si=623d78564851444594e39eeffbfdcb21

waveform.jpg

If anyone has any ideas, I'd be so grateful. This is for my wedding across the country, and I'd like to ship it out this week and I'm a bit panicked. I've had surprising success with cleaning up this noise in Izotope RX, but I'd much prefer to fix it at the source.
 
Back
Top