# Pure tones

In my previous post, I showed you how to generate and play a pure tone from a Python interactive session. But I didn’t explain what pure tones are, why they are useful, or how the line of code that generated the tone actually worked. This post fills in these gaps.

## What is a pure tone?

*A pure tone. Scaling of the axes is arbitrary.*

A pure tone is a sound whose waveform is *sinusoidal*, or like a sine wave, smoothly
cycling from positive to negative pressure and back again. They are sometimes called
*sinusoids*. Pure tones can be fully defined by four features. The first is *duration*,
normally expressed in seconds (s) or milliseconds (ms).

*Two pure tones. The tone represented by the solid orange curve has a slightly longer
duration than the tone represented by the dashed blue curve.*

The second is *frequency*, or rate of change from positive to negative pressure, normally
expressed in cycles per second (Hz).

*Two more pure tones. The green curve represents a tone with a higher frequency.*

The third is *starting phase*, or where it begins its cycle, normally expressed in radians
(rad).

*Two pure tones with different phases.*

The fourth is *level*, expressed in decibels (dB). Level is related to *amplitude*, or the
instantaneous pressure at the peaks.

*Two more pure tones. The purple curve represents a tone with a larger amplitude, and
therefore a higher level*

Conceptually, level is a bit more complicated than duration, frequency, and starting phase. Firstly, it depends on several factors that don’t influence the other three features, such as the distance and material between you and the sound source. This should be obvious: if you stand further away from a loudspeaker, or cover your ears, any sounds emitted from the speaker will have a lower level at your ears. Even different models of headphones will deliver pure tones at wildly different levels, all else being equal.

A second complication is that level is relative rather than absolute. When we say a pure
tone is presented at 60 dB, we actually mean it is presented 60 dB above some reference
pressure value. The typical choice of reference pressure is 0.00002 pascals (Pa). When a
pure tone has a root mean square (RMS) pressure of 0.00002 Pa, it is said to have *sound
pressure level (SPL)* of 0 dB. Thus, SPL is level relative to a fixed standard. Another
standardized level is *hearing level (HL)*, where 0 dB HL represents a typical person’s
*hearing threshold*, or the lowest level they can hear. A third is *sensation level (SL)*,
where 0 dB SL represents a specific person’s threshold. Because thresholds differ at
different frequencies, and everyone’s thresholds are different, the relationships between
SPL, HL, and SL are not constant across frequencies.

It is possible to create tones whose frequencies and amplitudes change mid-waveform. Such
changes are called *frequency modulation (FM)* and *amplitude modulation (AM)*,
respectively. Technically, FM and AM tones are not pure tones and are beyond the scope of
this post.

Pure tones are arguably the simplest sounds that exist (certainly the simplest *periodic*
sounds, anyway). This property makes them extremely important for psychoacoustics. Indeed,
some of the most fundamental discoveries of psychoacoustics were made using pure tones.
These include critical bands, equal-loudness contours, streaming, and numerous auditory
illusions.

Perhaps the commonest use of pure tones is in *audiometry*, which aims to measure a
listener’s thresholds. Pure tones at different frequencies—commonly 250, 500, 1000, 2000,
4000, and 8000 Hz—are presented *monaurally*, or one ear at a time, and the listener
indicates whether they heard them. The levels of these tones are varied across trials in
such a way as to converge upon a threshold value. Audiometry is one of many clinical tools
used diagnose hearing impairments, and to screen for normal hearing.

Provided that they are of sufficient duration and level, and their frequencies are within
certain limits, pure tones evoke the sensation of *pitch*. This means that they can be
used to create musical melodies. Such melodies typically sound quite boring because pure
tones have no real *timbre* to speak of. The pitch of a pure tone is related to its
frequency, but frequency and pitch are not the same thing. Pitch and timbre are
complicated and fascinating phenomena. I’ll return to them in future posts.

Pure tones that are presented at a higher level tend to sound louder. However, just like
frequency and pitch aren’t the same thing, neither are level and *loudness*. Loudness is
complicated, too.

Things get very interesting (and complicated) when two or more pure tones with different frequencies are presented at the same time. Again, this is a topic for another post.

## Mathematical definition

Let represent the function that generates a pure tone, such that gives the instantaneous pressure of a pure tone at time point in s. The formula is

where is the amplitude in Pa, is the so-called *angular frequency* in
rad/s, and is the starting phase in rad. Angular frequency is related to
*ordinary frequency*, denoted by and expressed in Hz, by

We usually prefer to define pure tones in terms of SPL rather than amplitude. To convert between these two quantities, we first need to observe that the relationship between the amplitude and RMS pressure of a pure tone, denoted by and expressed in Pa, is

Note that this is only true for pure tones. The relationship is different for other types of sounds. For example, it is for square waves and for sawtooth waves.

The SPL of a pure tone, denoted by , is related to its RMS pressure by

where is the reference pressure mentioned earlier (0.00002 Pa). Now the previous equations can be combined to yield the following

where is the reference amplitude, Pa. Notice that to define a pure tone whose level is expressed relative to some other reference we simply use a different value of .

## Python function

In a moment, we will write a Python function that creates digital representations of pure tones with specified durations, frequencies, phases, and levels by sampling from equation at regular time intervals. But first we need to choose a reference amplitude and a sample rate.

It is extremely difficult to figure out at what SPL you are playing a sound over headphones with consumer-grade electronics. Even if you knew all the specs of your computer’s sound card and headphones, you wouldn’t know the SPL for sure unless you measured it, and a $20 sound level meter from RadioShack won’t cut any mustard. Thus, for the present purposes, we’ll just choose a very small value of , say . We will be able to specify the level of a tone relative to a tone with this amplitude, but not its SPL. I recommend experimenting with your volume settings and this value until a 0-dB tone is just detectable, a 60-dB is comfortable to listen to, and a 85-dB tone is loud, approaching uncomfortable.

The *sample rate* is how many times per second we should sample. A sensible choice is
44100 Hz.

Now here’s the code:

```
"""Contains a function to generate pure tones.
"""
import numpy as np
import sounddevice as sd
a0 = 1e-5 # reference amplitude
sr = 44100 # sample rate
def sinusoid(d, f, phi, l, a0=a0, sr=sr):
"""Generates a pure tone.
A pure tone or sinusoid is a periodic waveform that is some variation on the sine
wave.
Args:
d (float): Duration in s.
f (float): Ordinary in Hz.
phi (float): Starting phase in rad.
l (float): Level in dB.
a0 (:obj:`float`, optional): Amplitude of a 0-dB tone. Default is 1e-5.
sr (:obj:`int`, optional): Sample rate in Hz. Default is 44100.
Returns:
waveform (np.ndarray): Sinusoidal waveform.
"""
t = np.arange(0, int(round(d * sr))) / sr
return a0 * 10 ** (l / 20) * np.sin(2 * np.pi * f * t + phi)
if __name__ == "__main__":
tone = sinusoid(1, 1000, 0, 60)
sd.play(tone, 44100)
sd.wait()
```

## Next steps

The next post tackles the issue of spectral splatter, which affects pure tones and other periodic stimuli.

## Version history

- Originally posted March 22, 2019.
- Added links on March 27, 2019.
- Added figure captions on March 28, 2019.