chenlh
2026-03-26 36e42207da4c088b5bfd96f2cfc8944f890440d7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "ModulatedAllPassFilter.h"
 
template <typename SampleType>
ModulatedAllPassFilter<SampleType>::ModulatedAllPassFilter()
{
 
}
 
template <typename SampleType>
ModulatedAllPassFilter<SampleType>::~ModulatedAllPassFilter()
{
 
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::prepare(SampleType sampleRate)
{
    this->sampleRate = sampleRate;
    allPassFilter.prepare(sampleRate);
    allPassFilter.setDelayMs(delayTime);
    allPassFilter.setFeedback(feedback);
 
    lfo.prepare(sampleRate);
    lfo.setWaveformType(LFO::Waveforms::Sine);
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::setDelayMs(SampleType delayInMs)
{
    this->delayTime = delayInMs;
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::setDelayInSamples(SampleType delayInSamples)
{
    this->delayTime = (delayInSamples / sampleRate) * 1000.0;
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::setFeedback(SampleType newFeedback)
{
    this->feedback = newFeedback;
    allPassFilter.setFeedback(this->feedback);
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::setRate(SampleType newRate)
{
    this->rate = newRate;
    lfo.setFrequency(this->rate);
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::setDepth(SampleType newDepth)
{
    this->depth = newDepth;
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::setWidth(SampleType newWidth)
{
    this->width = newWidth;
}
 
template <typename SampleType>
SampleType ModulatedAllPassFilter<SampleType>::processSample(SampleType input)
{
    SampleType minDelay = ((this->delayTime / 1000) * sampleRate) - width;
    SampleType maxDelay = ((this->delayTime / 1000) * sampleRate) + width;
    SampleType modMin = minDelay;
    SampleType modMax = maxDelay;
 
    SampleType newDelTime = (doUnipolarModulationFromMin(bipolarToUnipolar(depth * lfo.getNextOutputSample(LFO::LFOPhase::Normal)), modMin, modMax));
 
    allPassFilter.setDelaySamples(newDelTime);                
 
    SampleType output = allPassFilter.processSample(input);
 
    return output;  
}
 
template <typename SampleType>
void ModulatedAllPassFilter<SampleType>::process(SampleType* data, int startSample, int endSample)
{
    for(int sample = startSample; sample < endSample; ++sample)
        data[sample] = processSample(data[sample]);
}
 
template <typename SampleType>
SampleType ModulatedAllPassFilter<SampleType>::doUnipolarModulationFromMin(SampleType unipolarModulatorValue, SampleType minValue, SampleType maxValue)
{
    // --- UNIPOLAR bound
    unipolarModulatorValue = fmin(unipolarModulatorValue, 1.0f);
    unipolarModulatorValue = fmax(unipolarModulatorValue, 0.0f);
 
    // --- modulate from minimum value upwards
    return unipolarModulatorValue * (maxValue - minValue) + minValue;
}
 
template <typename SampleType>
SampleType ModulatedAllPassFilter<SampleType>::bipolarToUnipolar(SampleType value)
{
    return 0.5 * value + 0.5;
}
 
template class ModulatedAllPassFilter<float>;
template class ModulatedAllPassFilter<double>;