/
minicomputer.h
239 lines (185 loc) · 5.14 KB
/
minicomputer.h
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <lo/lo.h>
#include <string.h>
#include <lv2.h>
#include "event-helpers.h"
#include "uri-map.h"
// some common definitions
#include "../common.h"
// defines
#define _MODCOUNT 32
#define _WAVECOUNT 32
#define _CHOICEMAX 16
#define _MULTITEMP 8
#define TableSize 4096
#define tabM 4095
#define tabF 4096.f
#define NUM_MIDI 127
#define MIDI_COMMANDMASK 0xF0
#define MIDI_CHANNELMASK 0x0F
#define MIDI_NOTEON 0x90
#define MIDI_NOTEOFF 0x80
#define MIDI_CONTROL 0xB0
#define MIDI_PITCHBEND 0xE0
#define MIDI_CHANPRESS 0xD0
static const float anti_denormal = 1e-20;// magic number to get rid of denormalizing
enum modulators {
mod_none=0,
mod_velocity,
mod_pitch_bend,
mod_osc1_fm_out,
mod_osc2_fm_out,
mod_filter=7,
mod_envelope1,
mod_envelope2,
mod_envelope3,
mod_envelope4,
mod_envelope5,
mod_envelope6,
mod_osc,
mod_touch,
mod_wheel,
mod_cc12,
mod_delay,
mod_midi_note,
mod_cc2,
mod_cc3,
mod_cc4,
mod_cc5,
mod_cc14,
mod_cc15,
mod_cc16,
mod_cc17
};
//NOTE: All variables with names ending in _p are ports, and all ending in _c
// are cached normalized values of those ports.
typedef struct _modulator_selector {
float* type_p;
float* amount_p;
float* mod_val; //This is temporary storage for a pointer to the value of
//the modulator referenced.
} mod_selector;
typedef struct _common_osc_params {
float* waveform_p;
float* volume_p;
float volume_c;
float* fix_frequency_p; //This selects whether we use a fixed frequency or not
float fixed_c; //This is just a cached normalized version of fix_frequency_p
float* fixed_frequency_p; //This is the fixed frequency we might use
float* tuned_frequency_p; //Or if we don't use fixed frequency, this is the offset from the MIDI NOTE
float* boost_modulation_p;
float boost_factor_c;
mod_selector freq_mod1;
mod_selector freq_mod2;
mod_selector amp_mod1;
float* fm_output_vol_p;
} common_osc_params;
typedef struct _envelope_settings {
float* attack_p __attribute__((aligned (16)));
float* decay_p __attribute__((aligned (16)));
float* sustain_p __attribute__((aligned (16)));
float* release_p __attribute__((aligned (16)));
float* EGrepeat_p __attribute__((aligned (16)));
int EGrepeat_c __attribute__((aligned (16)));
} envelope_settings;
typedef struct _envelope_generator {
float state __attribute__((aligned (16)));
float Faktor __attribute__((aligned (16)));
unsigned int EGtrigger __attribute__((aligned (16)));
unsigned int EGstate __attribute__((aligned (16)));
} EG;
typedef struct _filter_ports {
float* f_p; //frequency
float* q_p; //resonance
float* v_p; //volume
} filter_ports;
typedef struct _filter_settings {
float f;
float q;
float v;
} filter_settings;
typedef struct _filter {
float high;
float band;
float low;
} filter;
typedef struct _engine {
float phase1;
float phase2;
float mod_midi_note;
float mod_midi_velocity;
EG envelope_generator[7];
filter filt[3];
float * delayBuffer;
float midif __attribute__((aligned (16)));
float *port; // _multitemp * ports + 2 mix and 2 aux
} engine;
struct _engineblock;
typedef struct _listheader {
struct _engineblock * next;
struct _engineblock * previous;
} listheader;
typedef struct _engineblock {
listheader h;
engine e;
}engineblock;
static float table [_WAVECOUNT][TableSize] __attribute__((aligned (16)));
static float midi2freq [128] __attribute__((aligned (16)));
typedef struct _minicomputer {
engineblock * noteson[NUM_MIDI];
listheader freeblocks;
engineblock engines[_MULTITEMP];
float* morph_p;
filter_ports filt_settings[3][2];
mod_selector morph_mod1;
mod_selector morph_mod2;
envelope_settings es[8];
common_osc_params osc1;
mod_selector osc1_amp_mod2;
common_osc_params osc2;
mod_selector osc2_fm_amp_mod;
float* osc2_sync_p;
mod_selector amp_mod;
float* mod_osc_freq_p;
float* mod_osc_waveform_p;
float mod_osc_phase;
float* delay_amount_p;
float* delay_time_p;
float* delay_feedback_p;
float* delay_volume_p;
mod_selector delay_mod;
int delayI,delayO;
float* clear_filter_p;
float *audio_out_volume_p;
float *audio_out_p;
LV2_Event_Buffer *MidiIn;
LV2_Event_Iterator in_iterator;
LV2_Event_Feature* event_ref;
int midi_event_id;
float tabX ;
float srate;
float srDivisor;
int maxDelayTime;
float modulator[_MODCOUNT] __attribute__((aligned (16)));
lo_server_thread st;
} minicomputer;
#define MINICOMPUTER_URI "urn:malte.steiner:plugins:minicomputer"
static void connect_port_minicomputer(LV2_Handle instance, uint32_t port, void *data);
static LV2_Handle instantiateMinicomputer(const LV2_Descriptor *descriptor, double s_rate, const char *path, const LV2_Feature * const* features);
static void run_minicomputer(LV2_Handle instance, uint32_t nframes);
static void cleanupMinicomputer(LV2_Handle instance);
static void activateMinicomputer(LV2_Handle instance);
const LV2_Descriptor miniDescriptor ={
.URI=MINICOMPUTER_URI,
.cleanup=cleanupMinicomputer,
.connect_port=connect_port_minicomputer,
.activate=activateMinicomputer,
.deactivate=NULL,
.instantiate=instantiateMinicomputer,
.run=run_minicomputer,
.extension_data=NULL
};