Audio signals exist in the time domain. Sound is a complex mixture of waves at different frequencies. These waves vary in shape and strength. Traditionally, engineers consider audio as a whole bunch of sinusoidal tones mixed together. You can visualize this complex waveform on an oscilloscope.

However, audio signals also live in the frequency domain. This domain will show you the strengths of the various frequencies in the sound. You can visualize this using a spectrum analyzer.

To move back and forth between time and frequency domains, you use math for signal analysis. The math is called a transformation, in particular the Fourier transform. The Fourier transform decomposes a function of time (a signal) into the frequencies that make it up, in a way similar to how a musical chord can be expressed as the amplitude (or loudness) of its constituent notes.

The bad news about the Fourier transform is that the math is way beyond most people. The good news is that there are many published libraries of code that do the job for you. Just plug them in and play.

The frequency domain is the best view for detecting Morse code tones. Say you want to detect a tone which has a frequency of 500 Hz or cycles per second. Transform the audio and check the location for that tone in the frequency domain. If it exists, there is a strong spike. If it does not exist, there is nothing. The picture above shows this idea. The desired tone is the green sine wave.

## Signal Analysis with the Goertzel Filter

Unfortunately, the Fourier transform requires lots of computing power. An Arduino cannot really handle it. Fortunately, there is something called the Goertzel algorithm. This does a very efficient and lightweight signal analysis for a single frequency or tone. The tone decoder from the Danish ham uses Goertzel.

What’s more, Jacob Rosenthal has written a Goertzel library for the Arduino. It’s really simple to detect a tone, as follows:

// Set things up int sensorPin = A0; int led = 13; const float TARGET_FREQUENCY = 500; const int N = 100; const float THRESHOLD = 4000; const float SAMPLING_FREQUENCY = 8900; // Create the filter Goertzel goertzel = Goertzel(TARGET_FREQUENCY, N, SAMPLING_FREQUENCY); void loop() { // Take samples goertzel.sample(sensorPin); // Check samples for tone at target float magnitude = goertzel.detect(); // if the tone is present, light LED if(magnitude>THRESHOLD) digitalWrite(led, HIGH); else digitalWrite(led, LOW); }

## One comment