# Render sampler voice effects using DSP module

**URL:** <https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651>\
**Category:** Audio Plugins\
**Created:** [July 20, 2018, 6:49pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651 "2018-07-20T18:49:05Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 20, 2018, 6:49pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/1 "2018-07-20T18:49:05Z")

</div>

I can’t get the SamplerVoice override class to use the DSP modules correctly.

If I pass this into the AudioProcessor block it works fine but when I try to put a filter per voice I receive this error that I’m not sure how to get past.

```
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override
    {
        SamplerVoice::renderNextBlock(outputBuffer, startSample, numSamples);
        dsp::AudioBlock<float> block (outputBuffer);
        lowPassFilter.process(dsp::ProcessContextReplacing<float> (block));
        return;
    }

```

JUCE Assertion failure in juce\_ProcessorDuplicator.h:69

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [July 20, 2018, 6:59pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/2 "2018-07-20T18:59:57Z")

</div>

The assertation tells you, that your block has more channels than your ProcessorDuplicator has processor instances…

Do you call [ProcessorDuplicator::prepare()](https://docs.juce.com/develop/structdsp_1_1ProcessorDuplicator.html#a156e3838fadff518487fbed258959ccd) on your duplicator or the whole chain?

---

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 20, 2018, 7:19pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/3 "2018-07-20T19:19:48Z")

</div>

Not sure where I would set that correctly. I declare and initialize my lowpassfilter with the following:

```
class SynthVoice : public SamplerVoice {
public:
    //==============================================================================
    SynthVoice():lowPassFilter(dsp::IIR::Coefficients <float>::makeLowPass(44100, 20000.0f, 0.1f)) {};
    
    /** Destructor. */
    ~SynthVoice() {};
    
    //==============================================================================
    
    bool canPlaySound(SynthesiserSound* sound) override {
        return dynamic_cast<SynthSound*>(sound) != nullptr;
    }
    
    void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override
    {
        SamplerVoice::renderNextBlock(outputBuffer, startSample, numSamples);
        dsp::AudioBlock<float> block (outputBuffer);
        lowPassFilter.process(dsp::ProcessContextReplacing<float> (block));
        return;
    }
    
    //DSP
    dsp::ProcessorDuplicator<dsp::IIR::Filter <float>, dsp::IIR::Coefficients <float>> lowPassFilter;

private:
    
};

```

EDIT::

I also have this in my prepare to play function.

```
dsp::ProcessSpec spec;
    spec.sampleRate = sampleRate;
    spec.maximumBlockSize = samplesPerBlock;
    spec.numChannels = getTotalNumOutputChannels();
```

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [July 20, 2018, 8:20pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/4 "2018-07-20T20:20:35Z")

</div>

Ah, that is great. Can you somehow hand that information to the constructor, so you can call

```auto
lowPassFilter.prepare (spec);

```

in the constructor of your `SynthVoice`?

I haven’t written a synth yet, so I don’t know. Maybe someone with a better idea can chime in…

---

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 20, 2018, 8:29pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/5 "2018-07-20T20:29:21Z")

</div>

Crap I forgot to add that I’m passing spec already there too.

```
    for (int i = 0; i < mySynth.getNumVoices(); i++) {
        SynthVoice* voxVoice = (SynthVoice*) mySynth.getVoice(i);
        voxVoice->lowPassFilter.prepare(spec);
        voxVoice->lowPassFilter.reset();
    }

```

And if I comment out reset here it works but I get a nasty click from the filter.

---

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 20, 2018, 8:44pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/6 "2018-07-20T20:44:51Z")

</div>

Hmm so now I got it to work there but its not behaving the same as if I were passing it in the processBlock function. Frustrating. Clicks and weird audio behavior.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [July 20, 2018, 8:50pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/7 "2018-07-20T20:50:54Z")

</div>

Where (i.e. on what occasion) are you calling reset()?  
It should only be called, if there is a discontinuity in the signal, and I guess, if the signal is not silent at that moment could have nasty effects…

---

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 20, 2018, 9:08pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/8 "2018-07-20T21:08:37Z")

</div>

I am only calling it in prepareToPlay and it works fine on an entire block. The artifacts happen when I move it to the voice process block.

---

<div class="post-metadata">

**Author:** ![xenakios](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/xenakios/32/4047_2.png) [@xenakios](https://forum.juce.com/u/xenakios)\
**Post date:** [July 21, 2018, 12:19pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/9 "2018-07-21T12:19:37Z")

</div>

You can’t directly do effects in the JUCE synth voice outputbuffer because the renderNextBlock calls must accumulate into the same buffer. So each of your voices is going to need its own buffer where you process the voice and the effects and then sum the processed sound into the voice output buffer.

---

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 21, 2018, 1:48pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/10 "2018-07-21T13:48:58Z")

</div>

Ok. I assumed renderNextBlock is the exclusive voice buffer you can act on. This goes against what has been suggested in other threads unless I am misunderstanding.

“For per-voice effects, you’d just add the effect processing to your voice class’s rendering code.”

[https://forum.juce.com/t/sampler-help/16040/4](https://forum.juce.com/t/sampler-help/16040/4)

Should I iterate the voices in the main audio processor then?

Do you know any examples I can look at?

---

<div class="post-metadata">

**Author:** ![xenakios](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/xenakios/32/4047_2.png) [@xenakios](https://forum.juce.com/u/xenakios)\
**Post date:** [July 21, 2018, 1:57pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/11 "2018-07-21T13:57:48Z")

</div>

> [@bobdole](#):
>
> “For per-voice effects, you’d just add the effect processing to your voice class’s rendering code.”
> 
> [https://forum.juce.com/t/sampler-help/16040/4](https://forum.juce.com/t/sampler-help/16040/4)

Jules just omits mentioning in that post that if the effect code requires manipulating a buffer, the voice output buffer can’t be used. (The output buffer already contains the summed output of the previously rendered synths voices, so you wouldn’t end up having proper per voice effects.)

So, you will either have to do your effects processing without using the shared voice output buffer (if available, use sample by sample processing calls in the DSP) or use a dedicated processing buffer in the voice for the synthesis and the effects. (You might be able to get away with some kind of a shared buffer with that too, since the voices are not rendered in parallel.)

It’s also a possible solution to do your own voice summing that doesn’t use an accumulating shared buffer for the voice outputs.

---

<div class="post-metadata">

**Author:** ![bobdole](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bobdole/32/4560_2.png) [@bobdole](https://forum.juce.com/u/bobdole)\
**Post date:** [July 21, 2018, 2:12pm UTC](https://forum.juce.com/t/render-sampler-voice-effects-using-dsp-module/28651/12 "2018-07-21T14:12:40Z")

</div>

Thank you for the suggestions! Each voice using an accumulated shared buffer was not clear to me.

I’ll take look at how the voices are summed currently and try to alter that path to fit my desired output.
