Project 12: Audio Waveform Painter 🎵¶

Difficulty: 🟡 Intermediate

Run cells top to bottom. Each step builds on the previous one and saves real files under outputs/audio_waveform_painter/.

← Back to index

Description¶

Synthesize audio waveforms (sine, square, sawtooth) and visualize them — no external audio file needed.

Libraries & Modules¶

  • numpy — signal generation
  • matplotlib.pyplot
  • scipy.io.wavfile or built-in wave — WAV export

Python Concepts You'll Practice¶

NumPy vectorization, sampling rate, wave types, file export

🎛️ Parameter Variations¶

  • FREQUENCY — 220 Hz (A3) vs 880 Hz (A5)
  • DURATION — seconds of audio
  • WAVE_TYPE — 'sine', 'square', 'sawtooth'
  • SAMPLE_RATE — 44100 (CD quality)
In [1]:
# Install dependencies for this project (safe to re-run)
import sys
!{sys.executable} -m pip install pillow numpy matplotlib wordcloud qrcode[pil] python-barcode fpdf2 jinja2 folium plotly pandas scipy ipywidgets -q
Skipping pip install (already installed)
In [2]:
# Interactive Jupyter setup — run this cell first
%matplotlib inline

from pathlib import Path
from IPython.display import display, Image as IPImage, HTML, Markdown, Audio, IFrame

OUTPUT_DIR = Path("outputs") / "audio_waveform_painter"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
print(f"✅ Outputs folder: {OUTPUT_DIR.resolve()}")
✅ Outputs folder: C:\Users\Hansel Yan\Projects\CodeItAll\outputs\audio_waveform_painter

Step 1 — Synthesize waveform¶

In [3]:
import numpy as np
import matplotlib.pyplot as plt

# 🎛️ TWEAK THESE
FREQUENCY = 440       # Hz (A4 note)
DURATION = 2.0        # seconds
SAMPLE_RATE = 44100
WAVE_TYPE = "sine"    # "sine" | "square" | "sawtooth"
AMPLITUDE = 0.5

t = np.linspace(0, DURATION, int(SAMPLE_RATE * DURATION), endpoint=False)

if WAVE_TYPE == "sine":
    signal = AMPLITUDE * np.sin(2 * np.pi * FREQUENCY * t)
elif WAVE_TYPE == "square":
    signal = AMPLITUDE * np.sign(np.sin(2 * np.pi * FREQUENCY * t))
else:
    signal = AMPLITUDE * (2 * (t * FREQUENCY % 1) - 1)

print(f"{WAVE_TYPE} wave: {FREQUENCY}Hz, {DURATION}s, {len(signal)} samples")
sine wave: 440Hz, 2.0s, 88200 samples

Step 2 — Visualize & export WAV¶

In [4]:
fig, axes = plt.subplots(2, 1, figsize=(12, 5), sharex=True)
axes[0].plot(t[:2000], signal[:2000], color="#00d2ff", linewidth=0.8)
axes[0].set_title(f"Waveform Painter — {WAVE_TYPE} @ {FREQUENCY}Hz")
axes[0].set_ylabel("Amplitude")
axes[1].specgram(signal, Fs=SAMPLE_RATE, NFFT=1024, noverlap=512, cmap="magma")
axes[1].set_xlabel("Time (s)")
axes[1].set_ylabel("Frequency (Hz)")
plt.tight_layout()
chart_out = OUTPUT_DIR / f"waveform_{WAVE_TYPE}.png"
fig.savefig(chart_out, dpi=120)
plt.show()

# Export WAV (16-bit PCM)
from scipy.io import wavfile
audio = np.int16(signal / AMPLITUDE * 32767)
wav_out = OUTPUT_DIR / f"tone_{WAVE_TYPE}_{int(FREQUENCY)}hz.wav"
wavfile.write(wav_out, SAMPLE_RATE, audio)
print(f"Chart: {chart_out}\nAudio: {wav_out}")
No description has been provided for this image
Chart: outputs\audio_waveform_painter\waveform_sine.png
Audio: outputs\audio_waveform_painter\tone_sine_440hz.wav

✅ Project complete¶

Check your output folder: outputs/audio_waveform_painter/

Next: Project 13: GIF Animation Studio · Index