# Pitch Shifting Delay, Smoothing Artifacts, and the Doppler Effect

**URL:** <https://forum.juce.com/t/pitch-shifting-delay-smoothing-artifacts-and-the-doppler-effect/41488>\
**Category:** Audio Plugins\
**Created:** [August 29, 2020, 5:40pm UTC](https://forum.juce.com/t/pitch-shifting-delay-smoothing-artifacts-and-the-doppler-effect/41488 "2020-08-29T17:40:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![RDEvans](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@RDEvans](https://forum.juce.com/u/RDEvans)\
**Post date:** [August 29, 2020, 5:40pm UTC](https://forum.juce.com/t/pitch-shifting-delay-smoothing-artifacts-and-the-doppler-effect/41488/1 "2020-08-29T17:40:28Z")

</div>

Hello folks, I hope you are well.

Hoping to get some help with smoothing my delayTimes to eliminate artifacts. The goal is to create a delay plugin that pitch shifts as the delayTime is changed, i.e. the Doppler effect.

Prototyping in SuperCollider has shown me that a control rate delay with no interpolation can still produce this response, yet I have had no luck in JUCE. Here is my process block. delayTime is set in the value tree and retrieved with delayTime.get().

```auto
void ModDelayAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

    if (mustUpdateProcessing)
        update();
    juce::SmoothedValue<float, ValueSmoothingTypes::Linear> delaySmoothed;
    
    delaySmoothed.setTargetValue(delayTime.get() * mSampleRate / 1000); // delay in samples
    delaySmoothed.reset(buffer.getNumSamples());
    
    // initial tap
    for (int channel = 0; channel < totalNumInputChannels; ++channel)
    {
        auto* buffRead = buffer.getReadPointer (channel);
        auto* buffWrite = buffer.getWritePointer(channel);
        
        for (int i = 0; i < buffer.getNumSamples(); ++i)
        {
            delayLine.pushSample(channel, buffRead[i]);
            
            auto dTime = delaySmoothed.getCurrentValue();
            float sample = delayLine.popSample(channel, dTime, true);
            buffWrite[i] = sample;
        }

    }
    
}
```

This text will be hidden

---

<div class="post-metadata">

**Author:** ![pizzafilms](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pizzafilms/32/562_2.png) [@pizzafilms](https://forum.juce.com/u/pizzafilms)\
**Post date:** [August 29, 2020, 7:36pm UTC](https://forum.juce.com/t/pitch-shifting-delay-smoothing-artifacts-and-the-doppler-effect/41488/2 "2020-08-29T19:36:09Z")

</div>

You’re going to need one delayLine per channel.

---

<div class="post-metadata">

**Author:** ![RDEvans](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@RDEvans](https://forum.juce.com/u/RDEvans)\
**Post date:** [August 29, 2020, 8:38pm UTC](https://forum.juce.com/t/pitch-shifting-delay-smoothing-artifacts-and-the-doppler-effect/41488/3 "2020-08-29T20:38:02Z")

</div>

I’m on it, do you have any advice on how to use feedback with this?

---

<div class="post-metadata">

**Author:** ![asimilon](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/asimilon/32/4235_2.png) [@asimilon](https://forum.juce.com/u/asimilon)\
**Post date:** [August 31, 2020, 11:22am UTC](https://forum.juce.com/t/pitch-shifting-delay-smoothing-artifacts-and-the-doppler-effect/41488/4 "2020-08-31T11:22:42Z")

</div>

> [@pizzafilms](#):
>
> You’re going to need one delayLine per channel.

Is it though? The new [dsp::DelayLine](https://docs.juce.com/master/classdsp_1_1DelayLine.html) looks like it handles multiple channels already. I haven’t actually played with it yet, but would certainly appear that way if you pass a `ProcessSpec` to `prepare` with `numChannels` \> 1.
