An automated Python tool to measure your room's acoustic response and generate a natural, "musical" EQ correction profile.
This script plays pink noise, records the room's frequency response, analyzes it using the Welch PSD method, and generates an optimized GraphicEQ string tailored for Equalizer APO. Instead of forcing a clinically flat response, it focuses on correcting significant peaks and dips while leaving minor variations alone, preserving the natural sound of your speakers.
- Simultaneous Playback & Recording: Automatically generates and plays pink noise while recording the room response.
- ISO Standard Bands: Analyzes audio across the 31 standard 1/3 octave frequencies.
- Musical Algorithm: * Applies a dead-zone to ignore tiny, inaudible room variations (±3 dB).
- Uses partial correction (60% by default) rather than 100% flattening.
- Applies curve smoothing (moving average) to prevent harsh frequency jumps.
- Speaker Safety: Subsonic protection caps boosts at +5 dB for frequencies under 40 Hz.
- Export Ready: Outputs a detailed CSV file complete with a
GraphicEQstring ready to paste into Equalizer APO'sconfig.txt.
Ensure you have Python 3 installed. You will also need your default microphone and speakers active and set up correctly in your operating system.
Install the required Python libraries using pip:
pip install numpy sounddevice scipy- Prepare your environment: Place your measurement microphone in your primary listening position. Ensure the room is as quiet as possible.
- Run the script:
python room_eq_analyzer.py
- Stay quiet: The script will play pink noise for 10 seconds. Do not make any noise during this process.
- Retrieve the output: Once finished, the script will generate a file named
generated_eq_correction.csvin the same directory. - Apply the EQ: Open the CSV, copy the string at the bottom starting with
GraphicEQ:, and paste it directly into your Equalizer APOconfig.txtfile.
You can tweak the behavior of the analyzer by modifying the variables at the top of the Python script.
| Variable | Default | Description |
|---|---|---|
DURATION |
10 |
Duration of the pink noise playback in seconds. |
SAMPLE_RATE |
44100 |
Audio sample rate (Hz). |
MAX_BOOST |
+10.0 |
Hard ceiling for any frequency boost (dB). |
MAX_CUT |
-15.0 |
Hard floor for any frequency cut (dB). |
DEAD_ZONE_DB |
3.0 |
Deviations smaller than this are ignored to prevent chasing micro-variations. |
CORRECTION_STRENGTH |
0.6 |
0.0 = no correction, 1.0 = absolute flat. 0.6 yields a natural result. |
SMOOTHING_PASSES |
2 |
Number of times a 3-band moving average is applied to smooth the EQ curve. |
Click to expand the step-by-step analysis process
- Pink Noise Generation: Generates pink noise using the FFT method, ensuring equal energy per octave, which is ideal for acoustic measurements.
- Recording: Normalizes the noise to ~-6 dBFS to prevent clipping and plays it while simultaneously recording the microphone input.
- Frequency Analysis: Trims the first 1s and last 0.5s of the recording to remove transients. It then applies the Welch Power Spectral Density (PSD) method with a large window (16384) for high-resolution low-frequency data.
- Power Measurement: Calculates the power within each of the 31 ISO 1/3 octave bands.
- EQ Calculation: * Establishes a reference level based on the broad mid-range (315 Hz – 3150 Hz).
- Calculates deviations and applies the fractional
CORRECTION_STRENGTH. - Zeros out deviations falling within the
DEAD_ZONE_DB. - Smooths the final curve and applies hard limits (
MAX_BOOST,MAX_CUT) and subsonic protections.
- Calculates deviations and applies the fractional
The generated generated_eq_correction.csv will look similar to this:
Frequency (Hz),Gain (dB),Notes
20,0.0,Flat — no correction needed
...
1000,-3.5,Significant peak — cut
...
GraphicEQ Line (paste directly into Equalizer APO config.txt):
GraphicEQ: 20 0.0; 25 0.0; 31 0.0; 40 -1.2; ...Generated using Python, NumPy, SciPy, and SoundDevice.