Is there a way to normalize volume in a 32-bit wav file using NAudio?
If the volume is clipping, then I want a downward normalize and vice versa if the volume is too low.
There is no built-in feature, but if you use AudioFileReader
you can examine the values of all samples to find the max absolute sample value. From this you can work out how much the original file can be amplified by without clipping.
Then you can use the Volume
property of AudioFileReader
to amplify the audio, and then use WaveFileWriter.CreateWaveFile
to write that out to a new (IEEE floating point) WAV file. WaveFileWriter.CreateWaveFile16
could be used if you wanted a 16 bit output after normalizing.
Here's some very simple sample code
var inPath = @"E:\Audio\wav\input.wav";
var outPath = @"E:\Audio\wav\normalized.wav";
float max = 0;
using (var reader = new AudioFileReader(inPath))
{
// find the max peak
float[] buffer = new float[reader.WaveFormat.SampleRate];
int read;
do
{
read = reader.Read(buffer, 0, buffer.Length);
for (int n = 0; n < read; n++)
{
var abs = Math.Abs(buffer[n]);
if (abs > max) max = abs;
}
} while (read > 0);
Console.WriteLine($"Max sample value: {max}");
if (max == 0 || max > 1.0f)
throw new InvalidOperationException("File cannot be normalized");
// rewind and amplify
reader.Position = 0;
reader.Volume = 1.0f / max;
// write out to a new WAV file
WaveFileWriter.CreateWaveFile(outPath, reader);
}