Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Authored by Souvik Mandal, Ph.D.

Project Leader & Instructor, Computational Behavioral Sciences, LS100, FAS, Harvard University | Linkedin ID: souvik-mandal-phd


Last updated: 2026-07-02

Open in Colab Open in GitHub Codespaces

This notebook is the hands-on lab corresponding to the LS100 Guide “Sound as Digital Data”. In this notebook, you’ll:

  1. Learn how audio data is digitally represented.

  2. Load an audio file and inspect basic properties (sample rate, duration).

  3. Visualize the waveform.

  4. Record audio from your microphone (short clip).

  5. Compute and visualize a spectrogram of an audio file.

Requirements: librosa, sounddevice, soundfile, and matplotlib
Install as needed: %pip install librosa sounddevice soundfile matplotlib

Creating Digital Audio from Numbers

1.A. Createing One-tone Audio

Let’s start with creating a simple digital audio file. For that, we have to define a few parameters first.

  1. The sampling rate

  2. The length of the file in seconds

  3. The frequency of the sound

  4. The amplitude of the sound

[ 0.          0.02564218  0.05126355 ... -0.07684329 -0.05126355
 -0.02564218]
Loading...

The produced file audio_signal is not a specialized multimedia format; it is a standard, flat float64 array of raw numbers, corresponding to the amplitudes of the sound and stored thosevalues in a numpy array.

<Figure size 1400x500 with 1 Axes>

1.B: Sequential Playback vs. Linear Superposition

Now, let’s see the Principle of Linear Superposition. We will see that mixing sounds does not require appending parallel tracking columns; it is the point-by-point algebraic summation of values inside a single array.

Sequential Vector Shape: (132300,)
Composite Vector Shape : (66150,)
Loading...

1.C: Parametric Synthesizer (Timbre, Octaves, and Instrument Modelling)

To simulate actual instruments without deep physical modeling, let’s use Additive Fourier Synthesis.

  • Flute: Predominantly a pure sinusoidal wave with weak upper harmonics.

  • Piano: A dense set of decaying overtones combined with a sharp exponential amplitude envelope.

Loading...

2: Hardware Interfacing (Microphone Ingestion)

This block utilizes the standard sounddevice package to interface directly with the local operating system audio subsystem.

Beginning 3.0 second audio recording block. Speak into microphone...
Ingestion complete. Transduced Vector Shape: (132300,)
Loading...

3: Storage Engineering (File I/O)

Let’s now ingest raw Pulse-Code Modulation (PCM) data from storage into native runtime matrix formats.

File written successfully using 16-bit PCM quantization grid[cite: 72, 104].
File Data Ingested: Sample Rate = 44100 Hz | Data Array Type = int16

4: High-Fidelity Signal Visualization

4.A: Time-Domain Waveform Layout

<Figure size 1200x400 with 1 Axes>

4.B: Frequency-Domain Spectrogram Layout

The spectrogram maps the evolution of hidden spectral frequencies over time, computing Short-Time Fourier Transforms (STFT) across discrete windows.

<Figure size 1200x500 with 2 Axes>

5. Load an audio file and inspect properties

Please set audio_path to a real .wav file on your machine.

5.B. Visualize waveform

Load an audio file first.

6. Tasks:

6.A. Record a short sound using your microphone

Recording for 3 seconds...
Saved recording to my_recording.wav

6.B. Compute and visualize a spectrogram of your recording

/Users/souvikmandal/anaconda3/envs/Analysis_Engineering/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 8209 (\N{NON-BREAKING HYPHEN}) missing from font(s) Arial.
  fig.canvas.print_figure(bytes_io, **kw)
<Figure size 1200x400 with 2 Axes>

7. Practice Tasks

7.A. Trim the first 0.5 seconds of the waveform and re‑plot it.

7.B. Change n_fft and hop_length values and observe how the spectrogram changes.

7.C. Compute and visualize a Mel spectrogram

8. Suggested Fun Exercises

These low-cognitive-load, high-impact extensions bridge basic programming directly to acoustic data science:

Extension A: The “Monster Voice” Illusion (Pitch as a Temporal Property)

  • The Exercise: Play the Module 2 voice recording, but pass an artificial sample rate argument to the Audio() constructor (e.g., rate = fs_rec // 2).

It transforms their voice into a slow, deep “monster” register without changing the numbers inside the data vector. This demonstrates that pitch is strictly an emergent temporal property dependent on the playback speed through a DAC, providing a baseline understanding of sample rate conversion algorithms.

Extension B: The Acoustic Fingerprint of Language (Vowel Formant Mapping)

  • The Exercise: Record yourself holding two prolonged vowel sounds separately (e.g., “Sustained ‘Ooo’” vs. “Sustained ‘Eee’”) at the exact same musical pitch. Have them generate spectrograms for both.

You will “physically” see that even at identical fundamental frequencies, different mouth shapes create distinct vertical “energy bands” (called formants) on the spectrogram. This forms the architectural foundation for speech processing, vowel classification, and training machine learning models for voice biometric identification.

Extension C: Simulating Environmental Degradation (Signal-to-Noise Ratio Analysis)

  • The Exercise: Generate computational white noise using np.random.normal() and mathematically append it to their instrument tracks (clean_signal + noise_factor), then visualize the resulting visual fuzz on the spectrogram.

  • It simulates recording audio in a real-world, noisy field environment. This introduces students to the core data science concept of SNR (Signal-to-Noise Ratio) and sets the stage for future research into audio cleaning, filtering, and speech enhancement algorithms.