Luke Oliff.

Friday fun: generating test tones for voice AI pipelines

·TIL·5 min read·Luke Oliff

Friday fun: I spent way too long recording myself saying the same test phrases into a microphone before I found a better way.

When you work with speech-to-text APIs, you need test audio. Different sample rates, different durations, different signal characteristics. You need to check that your pipeline handles a 16kHz recording the same way it handles an 8kHz one. You need to verify that silence at the start of a file does not break your VAD threshold. You need test tones for latency measurement so you know exactly when a tone was sent and when your STT detected it.

You do not need to record yourself saying “the quick brown fox” for the hundredth time.

sox -n 16khz-tone.wav synth 2 sine 440 rate 16000

That command generates a two-second 440Hz sine wave at 16kHz sample rate. Mono. WAV. Ready to send to any speech API. No microphone, no room echo, no background noise from your laptop fan.

Where I found it

I knew sox for format conversion. Trim a WAV, convert MP3 to PCM, that sort of thing. The synth effect was a discovery I made while trying to debug a latency issue in a streaming transcription pipeline. I needed a signal with a known start time and a sharp attack so I could measure the delay between sending audio and receiving the first transcript word. A recording of my voice has a soft onset. A sine wave has an instantaneous one.

sox -n latency-test.wav synth 1 sine 1000 rate 16000

A one-second 1kHz tone. Send that to your STT endpoint, measure when the first transcript result arrives, and you have a crude but effective round-trip latency test. It is not as precise as a proper audio probe, but it is a lot better than guessing.

What else synth can do

sine is the default waveform but not the only one. You can generate square waves, sawtooth waves, triangle waves, and noise profiles.

sox -n white-noise.wav synth 2 whitenoise rate 16000
sox -n pink-noise.wav synth 2 pinknoise rate 16000

White noise and pink noise are useful for testing AGC (automatic gain control) behaviour. Some STT APIs handle a wide dynamic range better than others, and running a noise file through your pipeline tells you more about the API’s preprocessor than any voice recording ever could.

Frequency sweeps are another one I use regularly. A sweep from 200Hz to 2000Hz over three seconds tells you whether the API’s frontend applies any filtering below or above the speech band.

sox -n sweep.wav synth 3 sine 200-2000 rate 16000

The workflow that stuck

I keep a make-test-audio.sh script in my project root now. It generates a handful of standard test files so I do not have to remember the syntax every time.

#!/bin/bash
# Generate standard test tones for voice API development
sox -n 8khz-tone.wav synth 2 sine 440 rate 8000
sox -n 16khz-tone.wav synth 2 sine 440 rate 16000
sox -n 44khz-tone.wav synth 2 sine 440 rate 44100
sox -n latency-tone.wav synth 0.5 sine 1000 rate 16000
sox -n sweep.wav synth 3 sine 200-2000 rate 16000
sox -n whitenoise.wav synth 2 whitenoise rate 16000

Run it once, keep the files around, throw them at any speech API during integration testing. When a transcription comes back wrong, you rule out the audio file first before you blame the API.

Why this matters for voice AI

Every streaming speech pipeline starts with a chunk of audio that has specific characteristics. Sample rate, bit depth, channel count, encoding. If you control those characteristics in your test file, you control the variable when something breaks. Generating test tones from the command line is the fastest way to build that control into your workflow.

The recording I would have made instead of writing this script was going to be me saying “one two three four five” at 16kHz into a Blue Yeti with a fan in the background. The sine wave is cleaner, more repeatable, and less embarrassing.

FAQ

Does sox synth work on macOS and Linux?

Yes. sox is available through Homebrew on macOS and most package managers on Linux. The synth effect works the same on both platforms.

Can I generate audio at a specific bit depth?

Yes. Use the -b flag to set bit depth. sox -n -b 16 output.wav synth 2 sine 440 rate 16000 generates a 16-bit file instead of the default 32-bit.

How do I control the output volume?

Chain the vol effect. sox -n quiet.wav synth 2 sine 440 rate 16000 vol 0.5 generates a tone at half amplitude. Useful for testing low-signal behaviour.

Will every STT API transcribe a pure sine wave?

Some will return an empty transcript, some will return a confidence score at the noise floor, and some will hallucinate a word. The lack of a consistent response is itself useful information about the API’s preprocessor.

Can I chain synth with other effects?

Yes. synth is an effect like any other. You can pipe its output into trim, fade, pad, or any other sox effect. Generate a tone, fade it in, pad it with silence, all in one command.