-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDelayWithFreeze.h
More file actions
92 lines (84 loc) · 2.55 KB
/
Copy pathDelayWithFreeze.h
File metadata and controls
92 lines (84 loc) · 2.55 KB
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
#pragma once
#include "vessl/vessl.h"
template<typename T>
class DelayWithFreeze : public vessl::unitProcessor<T>, protected vessl::plist<5>
{
using param = vessl::parameter;
public:
DelayWithFreeze(vessl::array<T> buffer, float sampleRate, float delayInSeconds = 0, float feedback = 0)
: vessl::unitProcessor<T>()
, fader(0.95f, 0)
, delayProc(buffer, sampleRate, delayInSeconds, feedback)
, freezeProc(buffer, sampleRate)
{
}
const parameters& getParameters() const override { return *this; } // NOLINT(portability-template-virtual-member-function)
param time() const { return delayProc.time(); }
param feedback() const { return delayProc.feedback(); }
param freezeEnabled() const { return params.freezeEnabled({ "freeze enabled", 'e', vessl::binary_p::type }); }
param freezePosition() const { return freezeProc.position(); }
param freezeSize() const { return freezeProc.size(); }
T process(const T& in) override // NOLINT(portability-template-virtual-member-function)
{
vessl::binary_t frozen = params.freezeEnabled.value;
vessl::analog_t fade = fader = (frozen ? 1.0f : 0.0f);
T s1 = frozen ? in : delayProc.process(in);
if (!frozen)
{
freezeProc.getBuffer().setWriteIndex(delayProc.getBuffer().getWriteIndex());
}
T s2 = fade > 0 ? freezeProc.generate() : 0.f;
return vessl::mixing::crossfade(s1, s2, fade);
}
template<vessl::duration::mode TimeMode = vessl::duration::mode::slew>
void process(vessl::array<T> input, vessl::array<T> output)
{
if (params.freezeEnabled.value)
{
freezeProc.getBuffer().setWriteIndex(delayProc.getBuffer().getWriteIndex());
if (fader.value < 0.999f)
{
auto r = input.getReader();
auto w = output.getWriter();
while (r)
{
w << process(r.read());
}
}
else
{
freezeProc.template generate<TimeMode>(output);
}
}
else
{
if (fader.value > 0.001f)
{
auto r = input.getReader();
auto w = output.getWriter();
while (r)
{
w << process(r.read());
}
}
else
{
delayProc.template process<TimeMode>(input, output);
}
}
}
protected:
param elementAt(vessl::size_t index) const override
{
param p[plsz] = { time(), feedback(), freezeEnabled(), freezePosition(), freezeSize() };
return p[index];
}
private:
struct
{
vessl::binary_p freezeEnabled;
} params;
vessl::smoother<> fader;
vessl::delay<T> delayProc;
vessl::freeze<T> freezeProc;
};