Hi all,
I have some audio samples of single notes played on a piano with “pp” dynamic.
The problem is that the dynamics is not uniform, some notes are slightly louder, others less so. In fact, if I use them to make a chromatic scale (using a MIDI keyboard), I can hear slight accents or gaps.
What is the correct way to make the dynamics of all samples uniform, without distorting the sound?
(If it’s necessary to set a reference dynamic, I could choose the sample that sounds loudest of all, and match all the others to that.)
If you load them as separate regions in Ardour you can select them all, right click gain > normalise, and check the box to use the volume across all the selected regions as a reference (I can’t remember it’s actual name but you’ll see it).
`for file in *.wav; do sox "$file" "n_$file" norm -0.1; done`
Yes, this command line works fine. But all .wav files are maximized, for example, here is an original file and immediately below the same file after SoX:
Thanks, staying in Ardour I have more control than using SoX (it’s very interesting, but I should study how it works…). To choose the correct dBFS value I had to do a bit of experimentation. (Instead I think I understand that setting the LUFS value should be avoided).
However, in both cases (SoX and Ardour) the “leveling” of the dynamics all at once is not perfect, so I have to adjust some notes “by hand” by relying on my ear.
Thank you,
a.
If you are trying to “level” things you need a compressor/expander, not normalization.
Normalization adjusts a given chunk of audio (e.g. a whole file) so that the loudest sample reaches a specified value. It will not “level” the file in the way that I think you want.
By contrast, a compressor/expander will attempt to keep the volume (by some metric, not necessarily LUFS) at a given level, no matter the input level.
If levelling (where the volume is the same across the whole file) is really what you want - and I’m not sure you do with decaying samples like piano - there is a tool I commissioned for this exact purpose. It’s CLI so you can run it from a bash script to quickly loop over lots of files. It requires compiling and takes a bit of experimentation to get satisfactory results - GitHub - sadko4u/spike-bender: Loudness maximization tool
What I suspect you want is the volume of the notes to sound consistent across the range of the instrument? If so then I haven’t found an automated tool that can help you. Even if the dB value of two notes is the same, it doesn’t mean they will be perceived at the same volume by the listener.
What I do is normalise my samples, then I map them in my sample player, then I play them back manually with my keyboard and adjust the volume of each one, within the sampler, until they “sound” balanced.
I think Paul’s answer is the right one, you need to compress your audio. You can do this in batch using ffmpeg. Here is some good documentation: https://mim.mbirgin.com/?c=posts&id=172
Here is a script that does both compression via a lv2 plugin then normalization with sox:
REP_IN=./wav-tmp
REP_LV2=./wav-lv2
REP_NORM=./wav-norm
for filename in $REP_IN/*.wav; do
echo "Convert from: $filename"
fbname=$(basename "$filename")
echo "To: $REP_NORM/$fbname"
#LV2 Calf compressor but u can use the plugins you want
ffmpeg -i $filename -af "lv2=http\\\\://calf.sourceforge.net/plugins/Compressor:c=\
ratio=3|\
threshold=-12.0" $REP_LV2/$fbname
#Sox normalization
sox $REP_LV2/$fbname $REP_NORM/$fbname norm -1
done
too bad, even if I changed the compression level of the plugins in ffmpeg, the signal is not more compressed… See for another solution than ffmpeg for batch processing.
PS: The lv2/ffmpeg solution will work if you build yourself ffmeg with --enable-lv2
I would be tempted to level the notes initially, and then apply a compressor to the bus to even out the notes in the final result.
I’m making a lot of assumptions here about your use case.
@atux perhaps you can describe what you are trying to do, and we can give views on potential workflows.
For instance, are you trying to create a virtual instrument using samples, such as a soundfont? In which case you would be trying to adjust a set of samples to load into a soundfont instrument editor like Swami or Polyphone, and this would be a one-off exercise to get the samples set to the right levels.
Or are you trying to do something else?
You briefly mention using MIDI, but in what context?
Why is this a problem? If you are building a soundfont or other virtual instrument, I would have thought this is what you wanted.
As you can see, understanding the context would allow us to help you better.
By the way, in the sox command I gave you, the -0.1 means -0.1 dB. If you want some other level, change the number. For instance, the following will level the files to -3dB:
for file in *.wav; do sox "$file" "n_$file" norm -3; done
The acompressor solution uses the ffmpeg compressor, the second solution uses the lv2 calf Compressor plugins. They are both compressor-type audio processing which allows the dynamics of the signal to be managed. The important thing is therefore to master the important parameters (Ratio, threshold and the others but these are the main ones). First of all, if you are not familiar with this type of processing, you should do compression tests to familiarize yourself with these tools. Afterwards you will adjust the batch according to what you want to do.
I don’t know if you’re on Linux but if so here’s what you can do (You can probably find an equivalent under other os), you launch the plugins with jalv (A command line host)
The plugin launches, you can then run your audio files one after the other to adjust an average level of compression that you will apply to all your files.
Then you save the compressor setting, and you will find the parameters to apply in the script (File → Save).
What you save is in fact a directory containing two files, edit the state.ttl file, you will find the current plugin settings there:
Maybe there’s a misunderstanding… in Ardour I already use compressors of various types.
The problem was that your script gave me this error:
:~/TEST$ ./test
Conversion de: ./wav-tmp/*.wav
Vers: ./wav-norm/*.wav.
ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 11 (Ubuntu 11.4.0-1ubuntu1~22.04)
configuration:
libavutil 58. 29.100 / 58. 29.100
libavcodec 60. 31.102 / 60. 31.102
libavformat 60. 16.100 / 60. 16.100
libavdevice 60. 3.100 / 60. 3.100
libavfilter 9. 12.100 / 9. 12.100
libswscale 7. 5.100 / 7. 5.100
libswresample 4. 12.100 / 4. 12.100
[in#0 @ 0x557f43ea5480] Error opening input: No such file or directory
Error opening input file ./wav-tmp/*.wav.
Error opening input files: No such file or directory
sox FAIL formats: can't open input file `./wav-lv2/*.wav': No such file or directory
Since you wrote to me: : “if lv2 doesn’t work, you can use acompressor”, I asked you: using acompressor (which I already installed), how should the code be modified.
But maybe it has nothing to do with it, I don’t know. You will be able to understand the error I reported above.
Bye,
a.
Either modify the script to point where your wav-files are (the REP_IN variable) and where you want to put the normalized ones (REP_NORM) or make sure you have your wavs in ./wav-tmp and that you have a ./wav-norm where ffmpeg can put the normalized files.
OK, now REP_IN, with the correct path, find the .wav files.
But… REP_LV2 = ?
What is it exactly? where do I find the correct path? I have a lot of lv2…I don’t know what to look for.
[Ardour on Linux]