Running AudioAnalyzeNoteFrequency as quickly as possible

Sandwich

Member
Hello,

I've done some digging to get .reads of AudioAnalyzeNoteFrequency to happen as quickly as possible and have been trying different things, including from this thread: https://forum.pjrc.com/threads/58467-Detection-time-for-noteFrequency-in-teensy-audio-lib

I'm not sure if it's because I'm running on a teensy 4.0 but I can't seem to get quite where I want to be. My project is taking in audio signal from the LINE IN header of a teensy audio board and one of the teensy's tasks is to be able to detect the frequency of the incoming signal and set a new audio out waveform to be the same frequency, basically as an input driven synthesizer.

I notice a few things seem to not be working like I would expect. First, it seems to be explained that the AudioAnalyzeNoteFrequency is continually filling a form of buffer with input and it averages the buffer to give an output, but for my project that doesn't seem to be the case. It is either a yes it detects a frequency or no, and it appears to be taking 70ms for each reading to complete, instead of continually scrolling a buffer. At least that is how I've interpreted the way my code runs... For example, if I run:

Code:
//find current incoming frequency
  if (notefreq1.available()) {
      wave1Freq = notefreq1.read();
      freqMillis = currentMillis; 
  } else  wave1Freq = 0;

I get a 'continual' frequency of 0, because each time it updates and marks .available as TRUE, after reading it becomes FALSE again for approx 70ms until another reading completes and it's TRUE again while playing a single continual note. So only one program cycle out of 70ms will have available as TRUE and I get no sound output because of the overwhelming majority of the time the .available is false. The best way I have found to compensate for this at the moment is to use:

Code:
 //find current incoming frequency
  //have to add in delays before note cut-off because of how slow available() becomes active again after reading
  if (notefreq1.available()) {
      wave1Freq = notefreq1.read();
      freqMillis = currentMillis; 
  }
  //if no new note data has been received in 70+ms (apparently how long it takes for library to determine if .available)
  if (currentMillis >= freqMillis + 80) {
    wave1Freq = 0;
  }

Unfortunately, this is slow enough to notice a lot of delay synthesizing the sound. In the previous thread I link above I read about editing the analyze_notefreq.h and setting
Code:
#define AUDIO_GUITARTUNER_BLOCKS
to a lower number to take fewer samples, making the detection run faster, but also making it unable to detect notes below a threshold (depending on how low the number is set). However, in practice, changing that define doesn't seem to have any effect. I currently have it saved to 0, and the program appears to show no difference in operation, I can still detect notes down as low as my keyboard goes. Looking at the corresponding .cpp file it looks like it should have an effect, as the .update method uses this variable for looping and I'm under the impression that .update is running continually after using .begin.

I appreciate any input, if I could get this running a bit faster it will be extremely helpful. I understand that low notes will take longer to find because they take longer to complete and detect, but if I could get this running at the speed I think it's capable of it would work well for my project.
 
I realized the problem editing analyze_notefreq.h in the Audio library, the library is in two locations (install dir and sketchbook dir in documents) and the program was choosing the unedited library in the install dir each time I compiled. Now I've been able to scale down AUDIO_GUITARTUNER_BLOCKS lower and it has definitely improved the speed a little at the cost of losing some low notes, but for this project the tradeoff works out well.

Everything else still seems to apply. Is anyone aware of a way to get it to run a little faster overall, at the cost of some program cycles maybe?
 
Is the IDE being used to build? It uses the sketchbook copy first, some alternates do not AFAIK.

Also when Verbose build details are shown - at least from IDE - it points out which library was used ... maybe that is where it became apparent.

Always confusing to have two copies. I've caught myself in the editor saving over the wrong version when wrong editor copy was changed.

As far as the speed question - not used this but it seems other posts have perhaps dealt with this but they'd have to be found to see the details.

Perhaps this post with a note above about minimum blocks :: pjrc.com/threads/60516-need-help-with-audio-latency-and-noteFreq-object

That post links to this "adjusting the threshold value" :: github.com/PaulStoffregen/Audio/blob/master/examples/Analysis/NoteFrequency/NoteFrequency.ino#L83
 
defragster,

Thank you very much, I had played with the detection threshold a bit when I first started but it wasn't having much of an effect. Now that I lowered the AUDIO_GUITARTUNER_BLOCKS it is much more responsive speed-wise. This helps a lot, I'll have to play with it now to find the sweet spot.

Also, yeah, the verbose mode is what let me know I was compiling from a different location than I assumed. I'm using the standard IDE, and even if I do #include "Audio.h" instead of #include <Audio.h> it still pulls it from the install dir. So, to make everything easier on myself, I copied the library in the sketchbook and renamed it and am referencing that new copy for just this sketch. Seems to be working great, and any changes I make to accommodate this program won't carry over into others since the default library is unchanged now.

If anyone has any other ideas to speed things up I'm all ears, as the tradeoffs seem to be working but I'm open to trying other methods to see if the outcome is better for the program.
 
Also, yeah, the verbose mode is what let me know I was compiling from a different location than I assumed. I'm using the standard IDE, and even if I do #include "Audio.h" instead of #include <Audio.h> it still pulls it from the install dir. So, to make everything easier on myself, I copied the library in the sketchbook and renamed it and am referencing that new copy for just this sketch. Seems to be working great, and any changes I make to accommodate this program won't carry over into others since the default library is unchanged now.

Hi Sandwich - I'm also trying to change the value of the AUDIO_GUITARTUNER_BLOCKS and running into a similar issue where Teensyduino will compile with the application / install directory version of analyze_notefreq.h - instead of the changed one in the sketch directory. Would you mind sharing some more details about what you did to get everything to compile with the correct libraries? Such as - what libraries / files did you need to have in the sketch directory to get everything to compile properly. Thanks!
 
Back
Top