Sound waves are vibrations that travel through a medium, creating oscillating pressure changes. They can take on various shapes, each producing a unique auditory experience. In this post, we explore the four basic types of sound waves: sine, square, triangle, and sawtooth, and their mathematical representations.

Sine Wave

The sine wave is the purest form of a sound wave. It contains only a single frequency, making it mathematically simple and audibly clean.

Sine waves are foundational in sound synthesis and are often used as test signals in audio engineering. They produce a smooth, hollow tone because they lack any harmonics.

Mathematical Representation

Where:

  • is the amplitude, which determines the loudness of the sound.
  • is the frequency, measured in Hertz (Hz), which defines the pitch of the sound.
  • is the time in seconds.
  • is the phase in radians, indicating the starting point of the wave at .

C++ Code

#include <cmath>
#include <vector>
 
const int sample_rate = 44000;
const double amplitude = 1.0;
const double frequency = 440.0;
const int duration = 1.0;
const int data_size = sample_rate * duration;
 
int main(void) {
  std::vector<double> data(data_size, 0.0);
  for (int t = 0; t < data_size; t++) {
    data[t] = amplitude * sin(2 * M_PI * frequency * t / sample_rate);
  }
  return 0;
}

Square Wave

A square wave alternates sharply between high and low states, creating a bold and abrupt sound. It is rich in odd harmonics, which contribute to its distinctive buzzy tone.

Square waves are widely used in electronic music and digital signal processing. Their sharp transitions make them ideal for control signals and modulation.

Mathematical Representation

Where:

  • is the sign function, returning or depending on the sign of .
  • , , and are the same as in the sine wave equation.

C++ Code

#include <cmath>
#include <vector>
 
const int sample_rate = 44000;
const double amplitude = 1.0;
const double frequency = 440.0;
const int duration = 1.0;
const int data_size = sample_rate * duration;
 
inline double sgn(double x) {
  return x >= 0 ? 1.0 : -1.0;
}
 
int main(void) {
  std::vector<double> data(data_size, 0.0);
  for (int t = 0; t < data_size; t++) {
    data[t] = amplitude * sgn(sin(2 * M_PI * frequency * t / sample_rate));
  }
  return 0;
}

Triangle Wave

The triangle wave rises and falls linearly, producing a softer sound than the square wave. Like the square wave, it contains only odd harmonics, but their amplitudes diminish faster, resulting in a smoother tone.

Triangle waves are often used in music synthesis for creating flute-like tones and soft sounds in electronic instruments.

Mathematical Representation

Where:

  • is the inverse sine function, which shapes the waveform into a triangle.
  • , , and are the same as in the sine wave equation.

C++ Code

#include <cmath>
#include <vector>
 
const int sample_rate = 44000;
const double amplitude = 1.0;
const double frequency = 440.0;
const int duration = 1.0;
const int data_size = sample_rate * duration;
 
int main(void) {
  std::vector<double> data(data_size, 0.0);
  for (int t = 0; t < data_size; t++) {
    data[t] = 2 * amplitude / M_PI * asin(sin(2 * M_PI * frequency * t / sample_rate));
  }
  return 0;
}

Sawtooth Wave

The sawtooth wave ramps upward linearly and drops sharply, resembling the teeth of a saw. It is rich in both even and odd harmonics, giving it a bright, harsh, and harmonically dense sound.

Sawtooth waves are commonly used in sound synthesis to emulate string instruments and create dynamic, rich tones in electronic music.

Mathematical Representation

Where:

  • is the floor function, which removes the fractional part of .
  • , , and are the same as in the sine wave equation.

C++ Code

#include <cmath>
#include <vector>
 
const int sample_rate = 44000;
const double amplitude = 1.0;
const double frequency = 440.0;
const int duration = 1.0;
const int data_size = sample_rate * duration;
 
int main(void) {
  std::vector<double> data(data_size, 0.0);
  for (int t = 0; t < data_size; t++) {
    data[t] = 2 * amplitude / M_PI * (frequency * t / sample_rate - floor(frequency * t / sample_rate) - 0.5);
  }
  return 0;
}

References