Proper way to apply gain


#1

Hi,

I’m creating a Synthesiser which plays sound files using an AudioAppComponent, an overridden SamplerSound class and a SamplerVoice. Everything works fine, except I’m getting a ridiculous high volume when I play the sounds if I don’t gain it (my left and right ear have now merged together in the middle of my head :p)

I want to lower/rise the gain for each sound/voice depending on note in renderNextBlock in the voice. My problem is that the volume gets even louder or no audio at all depending on the value.

example:

void FreedrumSamplerVoice::renderNextBlock(AudioBuffer& outputBuffer, int startSample, int numSamples)
{
SamplerVoice::renderNextBlock(outputBuffer, startSample, numSamples);
float gain = Decibels::decibelsToGain(-30.0);
outputBuffer.applyGain(gain);
}

Can anyone tell me what I am doing wrong ? :wink:

applying master gain in the getNextAudioBlock in the AudioAppComponent works fine :wink:

Cheers!


#2

You are supposed to sum your audio into the incoming buffer, so you can’t really do your voice gain change like this…If you need custom audio processing in the voice, you have to implement the whole renderNextBlock method yourself, you can’t call the parent class method in your subclass and then attempt changing the audio. (Because the parent class already summed its audio into the buffer which contains the audio of all the voices in the synthesizer.)

Another thing to note is that the velocity value coming into startNote is a floating point number in the range 0.0 to 1.0, not a value in the range 0 to 127, so maybe you also have some issue when handling that.


#3

So if I would like to change the gain depending note, which way would be a best practice for that ? I’m still getting familiar with api’s and call orders. Is there any good example? (I can’t find any good ones in the examples folder) :slight_smile:

Thanks!


#4

The Juce SamplerVoice already does some rough note velocity handling. Didn’t that work for you?

However, for completely custom handling of it, you will need to implement both startNote and renderNextBlock (and probably stopNote) in your subclass yourself without relying on calling the Juce SamplerVoice methods. You can of course just copy paste the code from the Juce class and modify as needed…(My own sampler inherits SynthesiserVoice and SynthesiserSound directly, not SamplerVoice and SamplerSound, because the Juce sampler classes are not flexible enough for customization.)

@jules For the Juce developers : the Juce SamplerVoice probably should be marked “final” because subclassing it is not very useful in its current form.


#5

It’s not for velocities, thoose are working fine. But I think I understand now. Thanks for getting me into the right direction :slight_smile: