No, Nyquist in Audacity can’t do that. It can only process one track at a time, so although it is possible to find the peak level of each track individually, it is not possible to calculate what the combined level of multiple tracks will be.
You could store the (peak s) value in scratch and then compare it to the (peak s) value of all subsequent tracks but I’m afraid that Audacity then will start to allocate memory for all tracks together and crash, but haven’t tested this yet.
and that’s still not going to tell you what the peak value of mixing the tracks will be. For example, if you have 2 tracks that are equal amplitude and 180 degrees out of phase, the sum (mix) will be zero (silence).
Everything looks as if Steve is right and you just simply can’t do this with Nyquist in Audacity. Mixing the tracks via scratch and then finding the peak afterwards would be the only other way to get the desired result, but this will surely crash Audacity if the tracks are longer than a few seconds.
I don’t think that scratch can hold sounds can it?
It appears to be possible to set scratch to a sound, but the data disappears so when you try to get the sound back out of scratch you have a sound of zero length and zero amplitude - a kind of “null sound”. It’s probably a good thing that it does this.
The only way that I can think of to accomplish this would be to write each track to disk then read the files into Nyquist, mix (sum) them and calculate the peak, but it’s a very inelegant solution.
steve: > I don’t think that scratch can hold sounds can it?
Obama says: yes, we can!
;; store a sound in *scratch*
(let ((len (round len)))
(setq *scratch* (snd-fetch-array s len len)))
;; read a sound from *scratch*
(snd-from-array 0.0 *sound-srate* *scratch*)
A Nyquist “sound” object is a pointer to a linked list of administration data, which in turn point to “blocks” of sound samples, which are read only if really necessary (lazy evaluation = delay computation until really needed). Manipulating a linked list is much faster than reading millions of samples.
If you want to read the samples and not only manipulate the administration data in the list, you must explicitely tell Nyquist to read the samples into an array and then store the array in scratch, otherwise the samples are never read.
It doesn’t work if you just simply store the value of “s” in scratch because in the second plugin run, after the obarray had been cleared and restored by the Audacity Nyquist interface, the pointer of “s” from the previous plugin run will point to an empty list. That’s why Nyquist thinks the sound has zero samples.
But we have the usual problem: Audacity allocates memory for all samples of the entire sound.
Ah ha, that explains some other “unexpected” behaviour that I’ve noticed (unexpected by me, but not unexpected now )
So it’s correct that scratch cannot hold a sound object, but as a workaround the sample data can be stored in scratch as an array.
Rather than holding so much data in scratch, an alternative approach would be a 3 step process:
However, it’s a lot quicker and less resource intensive to adjust levels manually using the Mixer Board.
The Mixer Board has the additional benefit that track levels can be set individually so if one track is too loud or too quiet compared to the others it can be adjusted to fit.