For many tasks involving audio (e.g. compressing WAV files to MP3), it's nice to have a utility which can normalize audio files. The purpose of this is to make all audio files sound equally loud. I used to use CoolEdit (from Syntrillium) to do this task, but since this audio editor is capable of doing much more than just normalizing waves, it's a bit slow for this task. Besides, it cannot be easily called from a batch file.
So I looked for a better alternative, but found none. That was when I decided to write my own normalizer. It's a small Win32 console mode application called normalize. It can handle 8-bit and 16-bit PCM WAV files of up to 4 GBs (larger WAV files are not possible anyway), and it is fast. Hell, faster than your disk I/O anyway.
How it works
It works like this: if you do not specify an amplification factor (either just
as a factor or in decibels), it will first search the whole file for the negative
and positive peaks. Then it will divide either 32767 or 127 (depending on whether
the file is 16-bit or 8-bit) by the highest amplitude found (negative or positive,
whichever is greater), and the result is the amplification factor. A substitution
table is built in memory that contains the new (amplified) sample value for
each possible input value. Thus the time-consuming task of doing floating-point
multiplication has to be done only once (and at most 65536 multiplications).
When these steps have been completed, normalize will pass over the file again, reading
blocks of 64 KB to memory, amplifying them (by substituting sample values from
the table), and writing them back to the file (of course overwriting the original
data).
Fighting spurious peaks
Sometimes WAV files have peak samples that occur so rarely or in non-critical
passages that it can be afforded to clip them without introducing audible artifacts.
If these are not clipped, they prevent normalizing the whole file to "normal"
levels (as by default normalize does not clip any sample at all). To help combat
this problem, Lapo Luchini contributed some code which internally produces a
full statistic of the sample values and only considers peak values that have
a given percentile in the statistic. It's called "smartpeak" (-s option);
start with a percentile of 99.99% and decrease if necessary.
Speed
On an AMD Athlon 1.1 GHz with an IBM 30 GB/7200 RPM/UDMA100 hard
disk, a 1.3 GB WAV file can be normalized in about 3 minutes.
Improving Speed
About the biggest speed gain can be achieved when using two hard disks
instead of one. On one disk you put the source file, and let normalize
write the output to a file on the other disk. Thus both disks can be
working at the same time (one reading, the other writing), and the
effective speed you get will be about the physical write speed of your
disk. If you use only one disk, it will have to seek every now and then
to read new data, and then again to write the normalized data back.
|
|
|
But I want a GUI!
Bruce Heller made a very nice GUI for those of you who don't like fiddling around
with command line arguments. Check out his web site at http://www.bheller.com/.
Thanks, Bruce!
License
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later version.
normalize is © 2000-2004 Manuel Kasper. All rights reserved.
Thanks
Big thanks go to Georges Wanderstok; he
invested much time to do some thorough tests on normalize and sent me
many good suggestions. Some of them have already been incorporated in
v0.21, others will be integrated in the next versions. Thank you,
Georges!
Thanks also to Terje Mathisen for providing me with
some ideas to improve the speed of normalize... Thanks to him normalize now
has MMX and SSE support for the min/max sample scanner.
I also want to thank Lapo Luchini for contributing
the smartpeak search code.
Notes/Bugs/Caveats
Links
Disclaimer
Read this (if you care)
Version history
0.253 - the absolute value of the amplification factor is now used when comparing with the -x option (thanks to Dave Case for reporting this)
0.252 - the WAV reader now skips all unknown subchunks
0.25 - incorporated some code contributed by Lapo Luchini to help fight "spurious peaks"
0.241 - added '-d' flag (don't abort) - see usage above
0.24 - Jack Vande Bunte suggested to add wildcard support. Here it is! Now you can call normalize like this: 'normalize *.wav' and it will normalize all files with a .wav extension in the current directory.
0.232 - I seriously messed up something in the compile of the v0.231 which went to the website (see the red box above). This is fixed now. No changes to the code were made in this release.
0.231 - normalizing a file consisting only of
null samples (digital silence) resulted in the output being all -32768
samples (or maybe even a crash). Thanks again to Georges Wanderstok for
pointing this out.
(Note: this is not fixed yet in 0.3-beta)
0.23 - the -o option was defunct for 16-bit
WAV files - all it did was to write silence to the output file. Fixed
this one now (forgot to move two lines of code while I was changing the
parameter parser); thanks to Cyber who brought this to my
attention.
0.22 - samples are now clipped correctly when "over-normalizing"
- instead of producing overflows and very strange results, they're just
clipped to the highest/lowest possible sample value (no speed penalty
since normalize is table-driven)
0.21 - added new options: -p, -x, -m, -o; changed default buffer size to 64 KB (faster on most systems)
0.1.2 - minor cosmetic changes; added a timer which tells you how long it took; added the '-q' switch which disables all screen output (useful in batch scripts) - first version to be released
0.1.1 - some small changes to handle the strange 'fact' header that some audio recorders insert (never released)
0.1 - made it table-driven: speed is now MUCH better (never released)
0.0.1 - first version. It worked. :) (never released)