Urgent.News

600+ sources. One page. See who else covered it.

Editions

Tech

Sound Is Just Numbers: Generating a Tone From Scratch in C++

Before you can build a synthesizer, an audio effect, or anything that makes noise in code, one idea has to click: digital sound is just a list of numbers. No magic, no special hardware required to understand it. If you can fill an array with the right values and write them to a file, you have made a sound. This article does exactly that. We generate a pure tone as a sequence of numbers, save it…

Sound is essentially a collection of numbers in the digital realm. Digital audio can be likened to a wave, with air pressure fluctuating over time. A microphone captures this pressure thousands of times per second and records each measurement as a number. Playback recreates the wave by reading those numbers back in reverse. This digital audio signal essentially consists of a long list of numbers, each representing the height of the wave at a specific moment in time.

Each measurement is a sample. Three key factors define the audio signal: sample rate (measuring samples per second), amplitude (determining sample value size and loudness), and frequency (indicating wave repetitions per second and pitch). To create a tone, we generate a list of numbers that form a wave with the desired pitch and loudness.

The wave is represented by a simple mathematical formula: value = amplitude * sin ( 2 * PI * frequency * time ). Each sample's time is calculated by dividing its index by the sample rate. By iterating through every sample, computing the formula, and storing the results, we trace out the wave. In C++, we use a loop to perform this calculation for each sample.

The sample rate, frequency, and duration are defined as constants. We create a vector of int16_t to store the samples, iterating over the total number of samples. The time is calculated for each sample, and the sine function determines the value. The resulting value is scaled to fit within a 16-bit integer range (-32768 to 32767) before being stored in the samples vector.

The final step involves writing these samples to a WAV file, a common audio format. WAV files consist of a 44-byte header followed by the raw samples. The header contains information about the audio format, such as the sample rate, number of channels, bits per sample, and the size of the audio data. We open an ofstream object in binary mode to write the WAV file.

We specify the number of channels (mono in this case), bits per sample (16), calculate the byte rate and block align, and determine the total data size. We then write the WAV file header, which includes identifiers (RIFF and WAVE), sample rate, and other relevant data. Finally, we write the actual samples to the file, completing the creation of a playable WAV file containing the generated tone.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Django moves to an annual release cycle

The Django Python web-framework project has announced that it has accepted an annual release cycle proposal . This means that the project is moving from a somewhat complicated schedule that…

More from Monday 10 August →