/
polyalias.d
116 lines (99 loc) · 3.05 KB
/
polyalias.d
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
108
109
110
111
112
113
114
115
116
/**
Aliased polyphonic syntesizer.
Copyright: Elias Batek 2018.
License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
*/
import std.math;
import dplug.core, dplug.client;
import synthesis;
// This define entry points for plugin formats,
// depending on which version identifiers are defined.
mixin(pluginEntryPoints!PolyAlias);
version(LV2)
{
// This creates the LV2 entry point
import dplug.lv2;
mixin(LV2EntryPoint!PolyAlias);
}
private
{
// Number of max notes playing at the same time
enum maxVoices = 4;
enum Params : int
{
osc1WaveForm,
}
immutable waveFormNames = [__traits(allMembers, WaveForm)];
}
/// Polyphonic digital-aliasing synth
final class PolyAlias : dplug.client.Client
{
nothrow @nogc:
private
{
Synth!maxVoices _synth;
}
public this()
{
super();
assumeNothrowNoGC((PolyAlias this_) {
this_._synth = mallocNew!(typeof(this._synth))(WaveForm.saw);
})(this);
}
public override
{
PluginInfo buildPluginInfo()
{
// Plugin info is parsed from plugin.json here at compile time.
// Indeed it is strongly recommended that you do not fill PluginInfo
// manually, else the information could diverge.
static immutable PluginInfo pluginInfo = parsePluginInfo(import("plugin.json"));
return pluginInfo;
}
override Parameter[] buildParameters()
{
auto params = makeVec!Parameter();
params ~= mallocNew!EnumParameter(Params.osc1WaveForm, "Osc 1: Waveform", waveFormNames, 0);
return params.releaseData();
}
override LegalIO[] buildLegalIO()
{
auto io = makeVec!LegalIO();
io ~= LegalIO(0, 1);
io ~= LegalIO(0, 2);
return io.releaseData();
}
override int maxFramesInProcess() pure const
{
return 32; // samples only processed by a maximum of 32 samples
}
override void reset(double sampleRate, int maxFrames, int numInputs, int numOutputs)
{
this._synth.reset(sampleRate);
}
override void processAudio(const(float*)[] inputs, float*[] outputs, int frames, TimeInfo info)
{
foreach (msg; getNextMidiMessages(frames))
{
if (msg.isNoteOn())
{
this._synth.markNoteOn(msg.noteNumber());
}
else if (msg.isNoteOff())
{
this._synth.markNoteOff(msg.noteNumber());
}
}
this._synth.waveForm = readParam!WaveForm(Params.osc1WaveForm);
foreach (ref sample; outputs[0][0 .. frames])
{
sample = this._synth.synthesizeNext();
}
// Copy output to every channel
foreach (chan; 1 .. outputs.length)
{
outputs[chan][0 .. frames] = outputs[0][0 .. frames];
}
}
}
}