Trying to do some DSP processing on single voices

Working on my synth so far is going great. Now I want to try and add a DSP processing effect ONLY to a single voice, and are starting out with just trying to apply some gain.

My project started from Projucer - Audio Plugin, so I got PluginProcessor, Editor, SynthSound (not using at all at the moment), and SynthVoice where in renderNextBlock audio data is pulled from a wavetable.

So in SynthVoice I got a bunch of initializers, but relevant now is;

class SynthVoice : public SynthesiserVoice {
	SynthVoice ()
        auto& masterGain = processorChain.get<masterGainIndex> ();
		masterGain.setGainLinear (0.5f);

Then related to the DSP processing I got;

	void reset () noexcept
		processorChain.reset ();

	template <typename ProcessContext>
	void process (const ProcessContext& context) noexcept
		processorChain.process (context);

	void prepare (const juce::dsp::ProcessSpec& spec)
		tempBlock = juce::dsp::AudioBlock<float> (heapBlock, spec.numChannels, 
		processorChain.prepare (spec);

In Private I got;

    juce::HeapBlock<char> heapBlock;
	juce::dsp::AudioBlock<float> tempBlock;

	enum { masterGainIndex };

    juce::dsp::ProcessorChain<juce::dsp::LadderFilter<float>, juce::dsp::Gain<float>>

Finally in renderNextBlock I got;

void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples)
		size_t start = startSample;
		size_t samples = numSamples;
		auto output = tempBlock.getSubBlock (startSample, (size_t) numSamples);
		output.clear ();

		while (--numSamples >= 0)
			// Reset combined audio
			combinedAudioLeft = 0.0f;
			combinedAudioRight = 0.0f;

            // Here I get my audio data from a wavetable

			// Output audio
			outputBuffer.addSample (0, startSample, combinedAudioLeft);
			outputBuffer.addSample (1, startSample, combinedAudioRight);

        // Here I am attempting to DSP process the mastergain
        auto block = output.getSubBlock (start, samples);
		juce::dsp::ProcessContextReplacing<float> context (block);
		processorChain.process (context);

Code compiles without a hiccup, but gain is not changed when running.


So what am I missing / doing wrong? Any help is ^^^^^^ appreciated!

Ok I have some progress as I totally forgot about prepare, silly me.

Anyways in SynthVoice I am trying to figure where to put;

prepare ({ gbSampleRate, (uint32) gbSamplesPerBlock, 2 });

Where gbSampleRate and gbSamplesPerBlock was copied from their respective in PluginProcessor’s prepareToPlay.

Now if I put the above prepare in my SynthVoice startNote with a flag so each voice only calls it once, I get some sound, but still it is not processing, and it crashes after a few notes.

If in PluginProcessor I set voices to only 1, it is more stable, but still does not DSP process the gain.

Applying a gain is just multiplying the signal by a number (usually between 0.0 and 1.0). If your signal is 0.0f because you set so in the combinedAudio variables, no matter how much gain you apply, multiplying anything for 0 is 0 so no sound will come out. Test your processorChain functions in a JUCE demo that generates sound to see if it works. Or just generate random numbers between -1.0 and 1.0 (white noise), put them in the signal and apply gain to that.

Hi john, perhaps my comment “// Here I get my audio data from a wavetable” was a bit unclear, but right at that comment I am actually getting samples from a wavetable. Anyways thanks a lot for taking the time to chime in.

Besides I did what you suggested and for now moved my DSP test processing into the PluginProcessor and found some issues but it now works there. I have not had time to “move” it back to the SynthVoice, where I needed it to be to test an idea, but I will try this morning, and if it works I will post my solution here…

edit : hmm, nevermind, the code is doing something else which I can’t figure out based on the stuff you posted.

Yeah I was figuring that, and was brain storming how to make a separate buffer and then sum it.

No you were right.

Anyway, if your purpose is to control the master gain, the voice class isn’t the appropriate place to do that. Do it for example in your AudioProcessor’s processBlock method.

Again you’re right, but as I insinuated on in my original post, the gain was just used as a simple test if DSP processing could work in SynthVoice.

It doesn’t, without using an extra buffer, but it looks like your code maybe was attempting to do that…?

Actually at that point I had taken some code from JUCE tutorials, where it used a subblock for LFO processing, and as I did not understand it fully I kept it there. I took that part away when I moved it to PluginProcessor, but know now that I need to do something like that in SynthVoice, and thanks for confirming that.