it every day, and so does everyone in this room. “Hey Siri” Spotify wake-word detection decoding, resampling, listening without loudness normalisation recording Hearing aids Every video call real-time filtering, echo cancellation, noise suppression silence detection
Web Developer Short Bio I'm passionate about technology and love tackling big challenges. As a Software Engineering enthusiast, I find joy in the dynamic world of coding, always eager to learn and build meaningful projects. Whether leading a team or collaborating, I thrive in problem-solving, combining creativity with innovative solutions.
behind audio signals 02. How Python is used in audio, The packages that make it possible 03. Where this actually matters, Real-world uses of voice transformation 04. How the demo itself was built, The packages of focus, line by line 05. See it run, live, on stage
It pushes the air next to it. That push travels outward, and when it reaches your eardrum, or a microphone, it moves it. A microphone is a thing that turns that movement into voltage. Property What it is Unit Human range Frequency how fast the wave repeats Hz 20 Hz – 20,000 Hz Amplitude how hard it pushes dBFS (Decibels relative to Full Scale) −∞ to 0 dBFS Speed how fast it travels m/s ≈ 343 m/s in air Frequency = pitch Amplitude = loudness Double the frequency and you go up one octave. 220 → 440 → 880 Hz. Bigger push, louder sound. Past the maximum it clips and crackles.
→ microphone → voltage → ADC sample + quantize → numpy array float32 Analog-to-Digital Converter. It turns a continuously-changing voltage (from the mic) into a finite list of numbers, by doing two separate things: Sample - How often do we measure? Quantize - How precisely do we store each measurement? Do both, and a sound wave becomes a list of numbers. Setting What it decides This project Sample rate how many measurements per second 16,000 Hz (16 kHz) Bit depth how many values each measurement can be 32-bit float (float32) in memory — WAV exports convert to 16-bit (65,536 values) Channels how many streams of measurements 1 (mono) — shape (samples,)
it gives you Where you'll see it today sounddevice microphone and speaker access — wraps CoreAudio, ALSA (Advanced Linux Sound Architecture), WASAPI (Windows Audio Session API) every demo's recording step numpy audio IS a numpy array. Slicing, maths, statistics level metering, all the effects scipy real signal processing: resample, filters, spectrogram pitch shifting in the live demo rich live terminal UI — meters, panels, tables everything you see on screen
API, direct mic/speaker access, no boilerplate. sd.rec() - it's the exact number of samples to capture samplerate=44100 - Tells the sound card how fast to take those samples, must match the rate you used to compute the sample count. channels=1 - Mono (one stream of measurements.) sd.wait() - Pauses your program until that recording actually finishes. sd.play(recording, samplerate=44100) - Plays the array back. recording is just numbers, sounddevice has no idea what rate they were captured at unless you tell it again here
gives it to you: one number per sample rms(Root mean square) — loudness in 3 steps: square (removes sign) → average (power) → square-root (back to amplitude) dbfs — that amplitude converted to dB; + 1e-10 just stops silence (rms = 0) from crashing log10 once sound is numpy, every numpy/scipy skill you already have applies to audio.
sound, over and over, many times a second. Each slice gets shown three ways: 1. Waveform, A wiggly line showing loudness over time, exactly as it sounds 2. Frequency Spectrum, Fast Fourier Transform (FFT) un-mixes that same slice into its separate pitches, and shows how loud each pitch is right now 3. Spectrogram, Those pitch-snapshots get stacked on top of each other as time passes, so you get a scrolling picture of how the pitches change
applies Privacy & Anonymization Whistleblower interviews, journalism, sensitive support hotlines, disguise a voice without losing intelligibility Accessibility Adjusting pitch/tone for hearing-impaired listeners, or normalizing voice for people with speech differences Content creation Podcast character voices, YouTube skits, game NPC dialogue, all built on the same resample-based pitch shift Music production Vocal doubling, harmony effects, classic tape-echo sound Telecom/call center Voice masking for anonymized customer support recordings
tool scipy.signal.resample pitch_shift() Resampling to fewer/more points changes pitch and duration together — the same trick as speeding up a cassette tape numpy echo() Echo is just a delayed, decayed copy added back onto the original — plain array math
fewer numbers than the original, sounds faster and higher (chipmunk) If factor is smaller than 1, it keeps more numbers than the original, sounds slower and lower (deep voice) The whole thing is one line: resample(audio, new_count), you tell it how many numbers you want instead, and it picks new values to match. That's it. No separate "make it higher" or "make it lower" logic, just one resize operation, and which way you resize decides the direction.
Makes a copy of it 2. Slides that copy later in time (by sticking silence in front of it) 3. Turns that copy's volume down a bit 4. Adds it on top of the original Then it repeats steps 1–3 two or three more times, each new copy pushed later and made quieter than the one before. At the very end, if adding all those copies together made anything too loud, it turns the whole thing down so it doesn't distort.