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.

  • FFT transforms a time-domain audio signal into its frequency components, making it ideal for identifying multiple frequencies or spectral content. It's accurate for complex signals but may require windowing and smoothing for real-time pitch tracking.

This chapter describes how to do the more lightweight AutoCorrelation and Zero-Crossing. 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);
// FrequencyDetectorAutoCorrelation 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!

Please note that the FrequencyDetectorAutoCorrelation 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 in Audio Frequency Detection

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