Building a Simple Audio Compressor in Python

Exploring audio compression/normalization in Python.

1. Intro / Motivation

After experimenting with simple audio filters (bass, treble, telephone), I wanted to try something more dynamic: a compressor.
Compression is one of the most important tools in audio production. It helps balance quiet and loud parts of a recording, making the overall sound more consistent and polished.

This project is part of my ongoing journey of exploring audio processing in Python, and of course, building experience that I hope will help me one day work at Dolby.

2. Project Overview

The compressor script works as a command-line tool that:

  • Reads a WAV file.
  • Applies dynamic range compression with adjustable parameters.
  • Outputs a new, compressed WAV file.
  • Optionally generates a visualization showing both waveforms and the gain reduction applied.

The adjustable parameters include:

  • Threshold (when compression kicks in)
  • Ratio (how strongly loud parts are reduced)
  • Attack / Release (how fast compression reacts)
  • Makeup gain (boost after compression to restore volume)

3. Technical Approach / Key Concepts

Like my filtering project, this script was built to use only a small number of dependencies:

  • numpy for numeric processing
  • scipy.io.wavfile for reading and writing WAV files
  • argparse for command-line arguments
  • matplotlib for optional visualization

The key steps are:

  1. Convert audio to float32 and normalize (so it works between -1 and 1).
  2. Calculate input levels in dB for each sample.
  3. Compare to threshold:
    • If louder, reduce by the chosen ratio.
    • If softer, leave unchanged.
  4. Smooth transitions using attack and release.
  5. Apply makeup gain to bring overall volume back up.
  6. Write the result back to a 16-bit WAV file.

Here’s a graph showing what it looks like in action (example using a copy of AJR's The Big Goodbye):

Compressor Visualization

In the first graph, you can see the original waveform (blue) vs. the compressed waveform (orange). In the second, the gain reduction applied to each stereo channel.

4. Challenges / Lessons Learned

  • Getting the attack and release smoothing right was tricky. Without smoothing, the sound was unnatural and choppy. With it, the compressor reacts more musically.
  • Stereo audio had to be handled carefully — each channel is processed independently, so the compressor works correctly on both left and right.
  • The visualization was harder than expected, but ultimately very useful. Seeing gain reduction over time made it clear how the compressor behaved.

5. Next Steps / Future Experiments

Some improvements I’d like to explore:

  • Add a sidechain input (classic “ducking” effect).
  • Try different compression curves (soft knee, multiband).
  • Add support for real-time processing, instead of just offline WAV files.
  • Combine this with my filters into a larger “audio lab” toolkit.

6. Conclusion / Takeaways

This project gave me a much better understanding of how compression works under the hood, and why it’s such a powerful tool.
Even though it’s a basic script, it’s exciting to see how much the sound changes — and to visualize it clearly.

I plan to keep building on this, moving toward more advanced effects and possibly chaining them together into a more complete processor.

Thanks for reading!
- Heath / MinoDab492

(Note: the code used in this project is not open-source or available on GitHub or other platforms. If you'd like to request access to the code for whatever reason, you can email me at heath.garvin@minodabproductions.dev, or contact me on Discord @minodab492.)