End the Loudness War between DJs
WaveAlign is a Python command-line tool designed to end the loudness war between DJs by aligning the loudness levels of songs to a specific LUFS level. Loudness Units relative to Full Scale (LUFS) alignment provides several advantages as compared to peak normalization:
Quickstart • Details • Full Featureset • Run Tests
Navigate to your desired directory and use the following command to clone the repository:
git clone https://github.com/y-brehm/wavealign
Navigate to the mp3processor
directory and use cmake
to build the mp3processor:
cd src/wavealign/mp3processor
cmake -DCMAKE_BUILD_TYPE=Release .
cmake --build . --config Release
python3 -m wavealign.batch_process_files -h
Determine the LUFS levels of your songs and an overall possible maximum LUFS level without clipping for your library.
python3 -m wavealign.batch_process_files -i ./your/songs --read_only
An audio output folder is optional, however not specifying it will overwrite your original files with the loudness-aligned versions. Nested input folder structures are supported but will be dissolved in the case of a specified output directory.
The default target is set to -12 dB LUFS, but is user-adjustable between -10 dB LUFS and -30 dB LUFS. If a target value would result in clipping, waveAlign will skip all potentially clipped filed. Additionally a log file is created with information on skipped files.
Processing files from the ./your/songs folder with a loudness target of -16 dB LUFS, storing the processed files in the ./output folder:
python3 -m wavealign.batch_process_files -i ./your/songs -o ./output -t -16
All Rekordbox(r) supported file types except .m4a and .aac are supported:
.wav, .aiff, .aif, .mp3, .flac
We recommend running waveAlign on your USB stick every time you export new tracks from your library management tool (e.g. Rekordbox(r)). Simply run:
python3 -m wavealign.batch_process_files -i ./<path_to_your_stick>
This will ensure that your mobile music library is always loudness-aligned.
Running waveAlign on your USB stick has an additional advantage: It leaves your original music library on your PC untouched. This means you always have access to your original files, while your USB stick carries the loudness-aligned tracks for your gigs.
While it is recommended to use waveAlign directly on the files on your USB stick, it is also possible to run waveAlign on your full music library. Please make sure to backup your source files before running. Also you will need to re-analyze your files within your music library tool (e.g. Rekordbox(r)) after waveAlignment.
All metadata as well as timing information, such as cue points, will be retained after processing your library. This is also true for lossy formats (e.g. mp3) which usually require de-coding and en-coding for processing.
In case you add new tracks after processing just run waveAlign again.
The default settings of WaveAlign, -12 LUFS (target level) and LUFS-S (window size), are optimized for most use cases, so there's usually no need to specify a user target level or a different target window.
python wavealign.py [-i INPUT] [-o OUTPUT] [-w WINDOW_SIZE] [-t TARGET] [-r]
-i, --input (str): Specify an input directory to look for audio. Nested structures are allowed.
-o, --output (str): Specify the output directory to save the processed data. If set to None, the original data is overwritten. Nested folder structures will be dissolved.
-w, --window_size (enum, optional): Specify the window size. Follows the Reaper LUFS calculation windows: LUFS-S (3 seconds), LUFS-M (4 seconds), LUFS-I (integrated - whole file)
-t, --target (int, optional): Specify the target loudness level in dB. Has to be between -30 and -9. Default is -14.
-r, --read_only (bool, optional): Run in read-only mode. Only outputs LUFS of input files without processing them. Also outputs library dependent maximum LUFS. Default is False.
-v, --verbose (bool, optional): Save additional debugging information in log file.
WaveAlign employs an efficient caching mechanism to optimize its processing time, which is utilized when input and output folders are identical. Caching makes use of a YAML file, which is generated in the input folder after each run. The cache file is a record of all processed files in previous runs including the filepath, last modification time and target LUFS.
When running waveAlign the cache file is read and input files are checked against the cache. The input file is skipped if the file path, last modification date as well as current LUFS target setting match with cache data.
If you apply changes to your USB stick after waveAlignment, just re-run the waveAlign.
WaveAlign utilizes a modified version of mp3gain to prevent unnecessary de- and encoding of lossy file formats such as .mp3. This ensures the timing accuracy of output files and maintains the integrity of timing-dependent information such as cue points.
Make sure you have poetry installed.
Create a local virtual environment using poetry and activate it:
cd <path_to_wavealign_repository>
poetry install --with dev
poetry shell
After that tests can be run from the main directory:
pytest