Skip to content

Simple Frequency Detection

Phil Schatzmann edited this page Jun 14, 2025 · 10 revisions

Audio frequency detection is the process of identifying the pitch or dominant frequency of a sound signal. Three common methods used are Fast Fourier Transform (FFT), AutoCorrelation, and Zero-Crossing.

  • AutoCorrelation compares a signal with delayed versions of itself to detect repeating patterns, which correspond to pitch. It's effective for monophonic signals and works well in noisy environments, but can be computationally intensive.

  • Zero-Crossing counts how often the signal crosses the zero amplitude axis to estimate frequency. It is simple and fast but only reliable for clean, single-frequency signals and can be inaccurate with harmonics or noise.

This chapter describes how to use the more lightweight FrequencyDetectorAutoCorrelation and FrequencyDetectorZeroCrossing classes.

Here is a simple example:

#include "AudioTools.h"

AudioInfo info(44100, 2, 16);
SineWaveGenerator<int16_t> sineWave;
GeneratedSoundStream<int16_t> sound(sineWave);
FrequencyDetectorAutoCorrelation out(1024);
// FrequencyDetectorZeroCrossing out;
StreamCopy copier(out, sound, 10 * 1024);

// Arduino Setup
void setup(void) {
  // Open Serial
  Serial.begin(115200);

  AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);

  // start I2S
  Serial.println("starting ...");
  out.begin(info);

  // Setup sine wave
  sineWave.begin(info, 200);
  Serial.println("started...");
}

// Arduino loop - copy sound to out
void loop() {
  copier.copy();
  Serial.print(out.frequency(0));
  Serial.print(" ");
  Serial.println(out.frequency(1));
}

In the example above we use the FrequencyDetector as output class. However you can specify an audio source in the constructor and treat the FrequencyDetector itself as audio source which will as a side effect give you the frequencies. On the output side you can also specify an output class: in this case the frequency detector will just forward the data written to that output, so that you can use this class in an output chain!

The FrequencyDetectorZeroCrossing uses the write size (=copy size), so if you want to increase the number of analysed samples, just increase this size!

The FrequencyDetectorAutoCorrelation however requires a buffer size in samples that needs to be big enough, but this depends on the minimum frequency that you want to measure.

Recommended Buffer Size for AutoCorrelation

The recommended buffer size for AutoCorrelation depends on the lowest frequency you want to detect, since the algorithm must capture at least one full period of the waveform.

Rule of Thumb

Use a buffer that spans at least 2–3 periods of the lowest frequency you're analyzing.

Formula

Buffer size = (Sampling Rate / Lowest Frequency) × N

Where:

  • Sampling Rate is in Hz (e.g., 44100 Hz)
  • Lowest Frequency is the minimum expected frequency (e.g., 80 Hz for a bass note)
  • N is the number of waveform cycles (usually 2–3)

Example

To detect down to 80 Hz with a sampling rate of 44100 Hz:

Buffer size = (44100 / 80) × 3 ≈ 1650 samples

So a buffer size of 1024 to 2048 samples is common for pitch detection in voice or music.

Use Case Recommended Buffer Size
Voice / Melody Detection 1024–2048 samples
Broad Range / Low Frequencies 2048–4096 samples
  • Smaller buffers ➜ faster response, less low-frequency accuracy
  • Larger buffers ➜ better pitch accuracy, more latency

Choose the buffer size based on the trade-off between accuracy and latency.

Clone this wiki locally