Teensy 4.0 - based Audio Guestbook

I'm curious what sort of application you have that can't allow 6.3ms?

You can get lower latency by editing AudioStream.h. Look for this line:

Code:
#define AUDIO_BLOCK_SAMPLES  128

The audio library processes in blocks of 128 samples, which is ~2.9ms. The latency you're seeing is probably 2 blocks, plus a small amount in the ADC and DAC hardware.

Most of the audio library code will adapt. But some things, like WAV file playing and FFT might depend on the block size.
 
Hello

I have a small defect with my assembly. The greeting message plays when I pick up the handset, but the recording does not stop when I hang up, I have to lift the handset to stop recording.
I don't know where it can come from. may be the switch?

Thank you.

Best regards
Jeff
 
We are having the same problem on ours. Did you ever get a response/fix for this? I looked through the forum and could not find one.

TIA

I had this problem before during my tests. This happened when I miswired the switch. reverse to GND. I have an old telephone with I think a reverse switch with 3 outputs and I had to do several tests...

I hope this will help you.
 
To allow for stereo operation, the TEENSY Buffer size must be a minimum of 16 for each channel or a total of 32 so reducing the buffer size to 32 is as far as it goes resulting in a latency of 2 ms.
I found the code that controls latency in the TEENSY Audio Stream. It is in the Audiostream.h file. When I discovered how to reduce audio latency from input to output, I did not consider if the TEENSY was dropping portions of the audio stream, which sounds like clicking or buzzing in the output. Dropout or what is called UNDRRUN is caused by the audio buffer reaching its end before it is refreshed with new samples from the input. By reducing the #define AUDIO_BLOCK_SAMPLES to 32 from its default of 128, the TEENSY was dropping the output stream periodically.
So there is a direct relationship between UNDERRUN and System clock speed.
The default system clock is 600 MHz.
The TEENSY has a feature that allows it to be Overclocked. I increased the system clock frequency to the default 800 MHz resulting in no UNDERRUN dropout of the output stream with the #define AUDIO_BLOCK_SAMPLES size of 32.
I do anticipate the the TEENSY will have UNDERRUN problems when I start programming complex operations.
 
Not sure what you’re trying to get at here. The Audio library doesn’t do stereo except in a few modules, otherwise everything is mono and you have to duplicate stuff if you want stereo. The lower limit of the audio block size is slightly variable, depending on what modules you want to use: I think 16 samples is the accepted limit, though I’ve seen code changes in pull requests suggesting some people are using 4.

The issues described in this thread tend to be very specific. Putting aside non-audio ones like switches being NC when the code is expecting NO, and old phones not working too reliably, the audio issues tend to be as follows: slow SD cards holding up the audio file writes; a bug in the libraries exacerbating the effect of the slow writing; and a hardware issue (I believe) resulting in power supply noise coupling to the microphone signal during SD card writing.

With smaller audio buffers and write sizes these all manifest as buzzing; with larger buffers the reports start saying files are noisy, or recordings are sped up. The hardware issues have variously been reported as buzzing or clicking. I believe the current version of the code eliminates the software issues, so a decent SD card and hardware setup should be robust.

The Teensy 4.x boards are incredibly capable for the size and price, and the audio library is pretty robust, though not without some issues. Unless your application tries to do too much (executing all modules takes longer than the audio update interval) or you trigger one of the obscure interactions (e.g. use the stock SD card playback at the same time as doing file access in your sketch), you won’t see underruns. Note … it’s recommended to underclock the Teensy to 150MHz for this project, to save battery. And it still works.

If you do have problems, many here are eager to help. It’s best to start a new thread unless you’re 100% sure you’re seeing an old issue, and it’s unclear if it was solved. Also note the Forum Rule: always post minimal code that reproduces the issue. Long programs or ones which need specific hardware will reduce people’s inclination and ability to help you!
 
I was using the PassThroughStereo example to test latency. With AUDIO_BLOCK_SAMPLES set to 128, the latency was 6.8 milliseconds. I added a delay to adjust the latency to exact millisecond values. Even with zero delay with AUDIO_BLOCK_SAMPLES set to 16 or 32 caused UNDERRUN dropout at 600 MHz System Clock. Overclocking prevented UNDERRUN dropout. My objective is stereo delay of precise durations.
 
After preliminary testing for UNDERRUN errors, I have determined that there is a direct/indirect relationship between:
1. #define AUDIO_BLOCK_SAMPLES size in the AudioStream.h Library.
2. CPU speed.
3. AudioMemory(XX); size in the sketch.
4. delay1.delay(0, XXX); size in the sketch
5. the amount or number and complexity of the effects in the sketch

Modified PassThroughStereo.ino with no UNDERRUN errors: AudioMemory(200); delay1.delay(0, 100); (#define AUDIO_BLOCK_SAMPLES 32)(CPU speed 600 MHz)
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code 
AudioInputI2S            i2s1;        
AudioEffectDelay         delay1;   
AudioOutputI2S           i2s2;       
AudioConnection          patchCord1(i2s1, 1, delay1, 0);
AudioConnection          patchCord2(delay1, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;    
// GUItool: end automatically generated code
 
const int myInput = AUDIO_INPUT_LINEIN;

void setup() {
  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(200);

  // Enable the audio shield, select input, and enable output
  sgtl5000_1.enable();
  sgtl5000_1.inputSelect(myInput);
  sgtl5000_1.volume(0.5);

  delay1.delay(0, 100);
}

elapsedMillis volmsec=0;

void loop() {
  // every 50 ms, adjust the volume
  if (volmsec > 50) {
    float vol = analogRead(15);
    vol = vol / 1023.0;
    //audioShield.volume(vol); // <-- uncomment if you have the optional
    volmsec = 0;               //     volume pot on your audio shield
  }
}
 
Last edited:
After preliminary testing for UNDERRUN errors, I have determined that there is a direct/indirect relationship between:

The way the library works should give an insight into whats happening here.

Firstly the block size determines how often the audio chain runs (this is triggered typically from an interrupt from either the input or output devices - the system picks just one device to be the trigger). If you don't include at least one device that's interrupt driven the audio chain never runs at all, a common cause of confusion.

Its vital the audio system completes it processing before the next trigger interrupt is due, so having a smaller block size can cause issues if other, higher priority, interrupts are using a significant amount of time. Thus larger blocks can avoid this problem, as can ensuring high priority interrupts only take a few microseconds (good practice). The audio chain drops its interrupt priority to minimum to play nicely with other ISRs.

Also larger blocks mean the processing is more efficient, as the setup/teardown around the block processing is amortized over more samples. Thus the total processor cycles used with a block size of 16 might be a lot more than with 128, leading to processor saturation (and dropped blocks/clicking/buzzing or worse). Block size is a compromise between efficiency and latency.

However larger blocks will require more audio memory to be used, note.

Clicking or buzzing is usually because you've run out of processor cycles, you haven't declared enough audio memory and the system is starved of blocks, or you've monkeyed with the order of declaration of the audio objects from that auto-generated by the audio tool and created unwanted block delays where they aren't needed or desirable.

You should declare objects after their sources and before their destinations as much as possible. Any signal travelling the other way will force a block delay and a extra block needs to be available to hold that data between triggerings of the audio chain. The audio tool handles generating an efficient order of creation of the audio objects for you.

And one final thing, the sigma-delta style DAC and ADC typically used for audio have a lot of latency built-in, often dozens of samples - they are not the devices to chose for a real-time signal processing system - SAR ADCs and fast DACs are needed for rapid response, as these each have a latency of less than one sample time.
 
I've got my first audio guestbook done and it is working like a charm. :eek:

I'm just wondering if there is a way to limit each audio message to like 90 seconds? Does anyone know where to set this in the code?
 
I've got my first audio guestbook done and it is working like a charm. :eek:

I'm just wondering if there is a way to limit each audio message to like 90 seconds? Does anyone know where to set this in the code?
There wasn't a way before ... but there is now! Grab it from this commit. Change the value of MAX_RECORDING_TIME_MS from the 120 seconds I randomly picked to whatever value you choose.

This commit also enables the auto volume control, so there's a slightly better chance of getting usable results from a whisper to a shout. Delete or comment out the relevant lines if you don't want this.

Code:
...
[COLOR="#FF0000"]#define MAX_RECORDING_TIME_MS 120'000 // limit recordings to this long (milliseconds)[/COLOR]
...
  // ----- Level settings -----
  sgtl5000_1.micGain(39); // set to suit your microphone
[COLOR="#FF0000"]  sgtl5000_1.audioPreProcessorEnable(); // optional: could be a good plan...
  sgtl5000_1.autoVolumeEnable();        // ...to prevent shouty people overloading the file[/COLOR]
  sgtl5000_1.volume(0.5); // overall speaker volume

  mixer.gain(0, 0.1f); // beeps
  mixer.gain(1, 0.5f); // greeting
  mixer.gain(2, 1.0f); // message playback
  // --------------------------
 
There wasn't a way before ... but there is now! Grab it from this commit. Change the value of MAX_RECORDING_TIME_MS from the 120 seconds I randomly picked to whatever value you choose.

This commit also enables the auto volume control, so there's a slightly better chance of getting usable results from a whisper to a shout. Delete or comment out the relevant lines if you don't want this.

Code:
...
[COLOR="#FF0000"]#define MAX_RECORDING_TIME_MS 120'000 // limit recordings to this long (milliseconds)[/COLOR]
...
  // ----- Level settings -----
  sgtl5000_1.micGain(39); // set to suit your microphone
[COLOR="#FF0000"]  sgtl5000_1.audioPreProcessorEnable(); // optional: could be a good plan...
  sgtl5000_1.autoVolumeEnable();        // ...to prevent shouty people overloading the file[/COLOR]
  sgtl5000_1.volume(0.5); // overall speaker volume

  mixer.gain(0, 0.1f); // beeps
  mixer.gain(1, 0.5f); // greeting
  mixer.gain(2, 1.0f); // message playback
  // --------------------------


Thank you so much, this works for me :)
Great work!



One last question.
The modified & created timestamp is always starting on 01-01-2019 00:00 when I plug the telephone into a usb power supply. Is there a way to set the proper date?

Cheers
 
Last edited:
Hello, I'm trying to make the audio guest book but i'm a beginner in coding. I use the code ont the GitHub and download the MTP_teensy on an other but I still have a error :

In file included from /Users/Aurelien/Downloads/audio-guestbook-main/audio-guestbook/audio-guestbook.ino:30:
/Users/Aurelien/Documents/Arduino/libraries/MTP_Teensy-main/src/MTP_Teensy.h:32:2: error: #error "You need to select USB Type: 'MTP Disk (Experimental)' or 'Serial + MTP Disk (Experimental)'"
32 | #error "You need to select USB Type: 'MTP Disk (Experimental)' or 'Serial + MTP Disk (Experimental)'"
| ^~~~~
Multiple libraries were found for "Audio.h"
Used: /Users/Aurelien/Library/Arduino15/packages/teensy/hardware/avr/1.58.1/libraries/Audio
Not used: /Users/Aurelien/Documents/Arduino/libraries/Audio
Multiple libraries were found for "SD.h"
Used: /Users/Aurelien/Library/Arduino15/packages/teensy/hardware/avr/1.58.1/libraries/SD
Not used: /Users/Aurelien/Library/Arduino15/libraries/SD
Multiple libraries were found for "TimeLib.h"
Used: /Users/Aurelien/Documents/Arduino/libraries/Time
Not used: /Users/Aurelien/Library/Arduino15/packages/teensy/hardware/avr/1.58.1/libraries/Time
exit status 1

Compilation error: exit status 1


Could you help me please ?
 
Hello, I'm trying to make the audio guest book but i'm a beginner in coding. I use the code ont the GitHub and download the MTP_teensy on an other but I still have a error :

Code:
In file included from /Users/Aurelien/Downloads/audio-guestbook-main/audio-guestbook/audio-guestbook.ino:30:
[COLOR="#FF0000"]/Users/Aurelien/Documents/Arduino/libraries/MTP_Teensy-main/src/MTP_Teensy.h:32:2: error: #error "You need to select USB Type: 'MTP Disk (Experimental)' or 'Serial + MTP Disk (Experimental)'"
   32 | #error "You need to select USB Type: 'MTP Disk (Experimental)' or 'Serial + MTP Disk (Experimental)'"
      |  ^~~~~[/COLOR]
Multiple libraries were found for "Audio.h"
  Used: /Users/Aurelien/Library/Arduino15/packages/teensy/hardware/avr/1.58.1/libraries/Audio
  Not used: /Users/Aurelien/Documents/Arduino/libraries/Audio
Multiple libraries were found for "SD.h"
  Used: /Users/Aurelien/Library/Arduino15/packages/teensy/hardware/avr/1.58.1/libraries/SD
  Not used: /Users/Aurelien/Library/Arduino15/libraries/SD
Multiple libraries were found for "TimeLib.h"
  Used: /Users/Aurelien/Documents/Arduino/libraries/Time
  Not used: /Users/Aurelien/Library/Arduino15/packages/teensy/hardware/avr/1.58.1/libraries/Time
exit status 1

Compilation error: exit status 1


Could you help me please ?
See screenshot in this post.
 


I don't have the "audio tweaks" section :/
Capture d’écran 2023-08-13 à 18.25.42.png
 
But you do have USB Type. Which is what the highlighted (in my quote) and very clear error message in your build output was telling you to change. And is shown correctly set in the linked image.

Audio tweaks are made available if you install a version of the code that I worked on, which attempts to fix audio recording issues that many here have encountered. Variously described as stuttering, glitches, fast playback…

Please read this thread thoroughly, it has much valuable guidance and it’s pretty unlikely you’ll come across a problem that hasn’t been discussed here.
 
I just wanted to write here that the suggestion h4yn0nnym0u5e of using the built in teensy sd card solves the motorboarding issue with the audio. Just had to comment the following lines and replace them with the ones below them:

Code:
  // 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");


  const int chipSelect = BUILTIN_SDCARD; 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

With this (and obviously changing the sd card from the audio shield to the teensy board). The audio is great now.

Something weird, that needs further testing from my end, is that, when powered with a powerbank, the audio is completely clean. However, when powered via a usb port from the pc, I can hear a distinct high freqency buzz. I can not say exactly where this is coming from, but it doesn't really matter, as the final prodcut will be powered with a powerbank.
 
The high frequency noise is from power systems. Noise like this can be heard when there are two or more active power systems being used on the TEENSY. Since there are no ground loop pathways when using a power brick, there is no chance inverter noise (the high frequency whistle sound) from the numerous power systems can make its way into the signal path of your speakers which I assume are active speakers with a different power system from that used to power the TEENSY. Try disconnecting any output device like powered speakers from the TEENSY and listen to the TEENSY with headphones/earbuds. With a passive listening system like headphones, there are no multiple paths to the listening device; this way the whistle should not be there. If it is, the USB supply (+5VDC) is noisy and should be filtered between the computer and the TEENSY.
 
Actually the speakers are not being powered with a different power system, the only power input is the power brick connected via usb cable to the teensy 4.1 power input. The speaker is the one from the telephone handset.
 
In your post you said "when powered via a usb port from the pc, I can hear a distinct high freqency buzz". If you unplug the speakers and the noise is not heard in headphones from the TEENSY, you have a ground loop problem, thus, the active Speakers are amplifying the ground current from the Computer. This is a common problem and is solved by isolating the power to the speakers.
 
What I meant by that is "when the teensy 4.1 is connected with a usb cable to the pc", instead of using a standalone powerbank to power the teensy.
 
If you hear noise when connected to the computer, you are hearing ground induced current from the computer, another common problem with computer USB Power when powering Audio Systems. There are many ways to remedy this but are too complex to describe here. Perhaps a solution to this common problem with programming the TEENSY could be pursued in a new Thread. For instance, I use a powered USB HUB so the TEENSY is not drawing power from the Computer Hosting the USB for programming, however this technique may not fully eliminate your noise.
 
I had this problem before during my tests. This happened when I miswired the switch. reverse to GND. I have an old telephone with I think a reverse switch with 3 outputs and I had to do several tests...

I hope this will help you.

Hey! Thanks for the reply. I'm just now seeing this.

I ended up cutting off most of the components off the phone board (resistors, etc.,) because my dad had a thought that those may be causing some interference. Between that and adding some fork spades to the end of my wires going into the screw terminals on the phone board which created a more solid connection, it seems to have dealt with the clicking! I have my software tones back and the greeting no longer has crackles during playback. One interesting thing I did note during testing when that crackling was going on, is it always happened in the same 3 spots which I thought was suspicious.

I hope this helps someone else that might be struggling!
 
I am struggling with the MTP files, I’ve added them but it’s failed to still find them?
More context needed, really. OS in use? IDE (version?) has failed to find the MTP library, or you can't find the files on the SD card when the Teensy's plugged in? Error messages output by the compiler? (if you post those, please use the # button to add code tags, makes life a lot easier for the reader. The Go Advanced button is helpful to see what your post is going to look like, too.)

I did a bunch of improvements you can find here, which includes (with pictures) what an example Windows filesystem looks like when properly set up.
 
Back
Top