LMMS
Loading...
Searching...
No Matches
nekobee_voice_render.c
Go to the documentation of this file.
1/* nekobee DSSI software synthesizer plugin
2 */
3
4#define _BSD_SOURCE 1
5#define _SVID_SOURCE 1
6#define _ISOC99_SOURCE 1
7
8#include <math.h>
9
10#include "nekobee.h"
11#include "nekobee_synth.h"
12#include "nekobee_voice.h"
13
14#ifndef M_PI
15#define M_PI 3.14159265358979323846
16#endif
17
18#define M_2PI_F (2.0f * (float)M_PI)
19#define M_PI_F (float)M_PI
20
21#define VCF_FREQ_MAX (0.825f) /* original filters only stable to this frequency */
22
23static int tables_initialized = 0;
24
25float nekobee_pitch[128];
26
27#define pitch_ref_note 69
28
29#define volume_to_amplitude_scale 128
30
32
33static float velocity_to_attenuation[128];
34
35static float qdB_to_amplitude_table[4 + 256 + 0];
36
37void
39{
40 int i;
41 float pexp;
42 float volume, volume_exponent;
43 float ol, amp;
44
46 return;
47
48 /* MIDI note to pitch */
49 for (i = 0; i < 128; ++i) {
50 pexp = (float)(i - pitch_ref_note) / 12.0f;
51 nekobee_pitch[i] = powf(2.0f, pexp);
52 }
53
54 /* volume to amplitude
55 *
56 * This generates a curve which is:
57 * volume_to_amplitude_table[128 + 4] = 0.25 * 3.16... ~= -2dB
58 * volume_to_amplitude_table[64 + 4] = 0.25 * 1.0 ~= -12dB
59 * volume_to_amplitude_table[32 + 4] = 0.25 * 0.316... ~= -22dB
60 * volume_to_amplitude_table[16 + 4] = 0.25 * 0.1 ~= -32dB
61 * etc.
62 */
63 volume_exponent = 1.0f / (2.0f * log10f(2.0f));
64 for (i = 0; i <= volume_to_amplitude_scale; i++) {
65 volume = (float)i / (float)volume_to_amplitude_scale;
66 volume_to_amplitude_table[i + 4] = powf(2.0f * volume, volume_exponent) / 4.0f;
67 }
68 volume_to_amplitude_table[ -1 + 4] = 0.0f;
70
71 /* velocity to attenuation
72 *
73 * Creates the velocity to attenuation lookup table, for converting
74 * velocities [1, 127] to full-velocity-sensitivity attenuation in
75 * quarter decibels. Modeled after my TX-7's velocity response.*/
76 velocity_to_attenuation[0] = 253.9999f;
77 for (i = 1; i < 127; i++) {
78 if (i >= 10) {
79 ol = (powf(((float)i / 127.0f), 0.32f) - 1.0f) * 100.0f;
80 amp = powf(2.0f, ol / 8.0f);
81 } else {
82 ol = (powf(((float)10 / 127.0f), 0.32f) - 1.0f) * 100.0f;
83 amp = powf(2.0f, ol / 8.0f) * (float)i / 10.0f;
84 }
85 velocity_to_attenuation[i] = log10f(amp) * -80.0f;
86 }
87 velocity_to_attenuation[127] = 0.0f;
88
89 /* quarter-decibel attenuation to amplitude */
90 qdB_to_amplitude_table[-1 + 4] = 1.0f;
91 for (i = 0; i <= 255; i++) {
92 qdB_to_amplitude_table[i + 4] = powf(10.0f, (float)i / -80.0f);
93 }
94
96}
97
98static inline float
99volume(float level)
100{
101 unsigned char segment;
102 float fract;
103
104 level *= (float)volume_to_amplitude_scale;
105 segment = lrintf(level - 0.5f);
106 fract = level - (float)segment;
107
108 return volume_to_amplitude_table[segment + 4] + fract *
109 (volume_to_amplitude_table[segment + 5] -
110 volume_to_amplitude_table[segment + 4]);
111}
112
113static inline float
115{
116 int i = lrintf(qdB - 0.5f);
117 float f = qdB - (float)i;
118 return qdB_to_amplitude_table[i + 4] + f *
121}
122
123void blosc_place_step_dd(float *buffer, int index, float phase, float w, float scale){
124 float r;
125 int i;
126
127 r = MINBLEP_PHASES * phase / w;
128 i = lrintf(r - 0.5f);
129 r -= (float)i;
130 i &= MINBLEP_PHASE_MASK; /* port changes can cause i to be out-of-range */
131 /* This would be better than the above, but more expensive:
132 * while (i < 0) {
133 * i += MINBLEP_PHASES;
134 * index++;
135 * }
136 */
137
139 buffer[index] += scale * (step_dd_table[i].value + r * step_dd_table[i].delta);
140 i += MINBLEP_PHASES;
141 index++;
142 }
143}
144
145
146void vco(unsigned long sample_count, nekobee_voice_t *voice, struct blosc *osc,
147 int index, float w)
148
149{
150 unsigned long sample;
151 float pos = osc->pos;
152 float pw, gain, halfgain, out;
153 pw=0.46f;
154 gain=1.0f;
155 halfgain=gain*0.5f;
156 int bp_high = osc->bp_high;
157 out=(bp_high ? halfgain : -halfgain);
158
159 switch (osc->waveform)
160 {
161 default:
162 case 0: {
163
164 for (sample = 0; sample < sample_count; sample++) {
165 pos += w;
166 if (bp_high) {
167 if (pos >= pw) {
168 blosc_place_step_dd(voice->osc_audio, index, pos - pw, w, -gain);
169 bp_high = 0;
170 out = -halfgain;
171 }
172 if (pos >= 1.0f) {
173 pos -= 1.0f;
174 blosc_place_step_dd(voice->osc_audio, index, pos, w, gain);
175 bp_high = 1;
176 out = halfgain;
177 }
178 } else {
179 if (pos >= 1.0f) {
180 pos -= 1.0f;
181 blosc_place_step_dd(voice->osc_audio, index, pos, w, gain);
182 bp_high = 1;
183 out = halfgain;
184 }
185
186 if (bp_high && pos >= pw) {
187 blosc_place_step_dd(voice->osc_audio, index, pos - pw, w, -gain);
188 bp_high = 0;
189 out = -halfgain;
190 }
191 }
192
193 voice->osc_audio[index + DD_SAMPLE_DELAY] += out;
194
195 index++;
196 }
197
198 osc->pos = pos;
199 osc->bp_high = bp_high;
200 break;
201 }
202 case 1: // sawtooth wave
203 {
204 for (sample=0; sample < sample_count; sample++) {
205 pos += w;
206 if (pos >= 1.0f) {
207 pos -= 1.0f;
208 blosc_place_step_dd(voice->osc_audio, index, pos, w, gain);
209 }
210 voice->osc_audio[index + DD_SAMPLE_DELAY] += gain * (0.5f - pos);
211
212 index++;
213 }
214
215 break;
216 }
217
218 }
219
220 osc->pos=pos;
221}
222
223static inline void
224vcf_4pole(nekobee_voice_t *voice, unsigned long sample_count,
225 float *in, float *out, float *cutoff, float qres, float *amp)
226{
227 unsigned long sample;
228 float freqcut, freqcut2, highpass,
229 delay1 = voice->delay1,
230 delay2 = voice->delay2,
231 delay3 = voice->delay3,
232 delay4 = voice->delay4;
233
234 qres = 2.0f - qres * 1.995f;
235
236 for (sample = 0; sample < sample_count; sample++) {
237
238 /* Hal Chamberlin's state variable filter */
239
240 freqcut = cutoff[sample] * 2.0f;
241 freqcut2 = cutoff[sample] * 4.0f;
242
243
244 if (freqcut > VCF_FREQ_MAX) freqcut = VCF_FREQ_MAX;
245 if (freqcut2 > VCF_FREQ_MAX) freqcut2 = VCF_FREQ_MAX;
246
247 delay2 = delay2 + freqcut * delay1; /* delay2/4 = lowpass output */
248 highpass = in[sample] - delay2 - qres * delay1;
249 delay1 = freqcut * highpass + delay1; /* delay1/3 = bandpass output */
250
251 delay4 = delay4 + freqcut2 * delay3;
252 highpass = delay2 - delay4 - qres * delay3;
253 delay3 = freqcut2 * highpass + delay3;
254
255 /* mix filter output into output buffer */
256 out[sample] += 0.1*atan(3*delay4 * amp[sample]);
257 }
258
259 voice->delay1 = delay1;
260 voice->delay2 = delay2;
261 voice->delay3 = delay3;
262 voice->delay4 = delay4;
263 voice->c5 = 0.0f;
264}
265
266
267/*
268 * nekobee_voice_render
269 *
270 * generate the actual sound data for this voice
271 */
272void
274 float *out, unsigned long sample_count,
275 int do_control_update)
276{
277 unsigned long sample;
278
279 /* state variables saved in voice */
280 float lfo_pos = voice->lfo_pos,
281 vca_eg = voice->vca_eg,
282 vcf_eg = voice->vcf_eg;
283 unsigned char vca_eg_phase = voice->vca_eg_phase,
284 vcf_eg_phase = voice->vcf_eg_phase;
285 int osc_index = voice->osc_index;
286
287 /* temporary variables used in calculating voice */
288 float fund_pitch;
289 float deltat = synth->deltat;
290 float freq, cutoff, vcf_amt;
291 float vcf_acc_amt;
292
293 /* set up synthesis variables from patch */
294 float omega;
295 float vca_eg_amp = qdB_to_amplitude(velocity_to_attenuation[voice->velocity] * 0);
296
297 float vca_eg_rate_level[3], vca_eg_one_rate[3];
298 float vcf_eg_amp = qdB_to_amplitude(velocity_to_attenuation[voice->velocity] * 0);
299
300 float vcf_eg_rate_level[3], vcf_eg_one_rate[3];
301 float qres = synth->resonance;
302 float vol_out = volume(synth->volume);
303
304 float velocity = (voice->velocity);
305
306 float vcf_egdecay = synth->decay;
307
308 fund_pitch = 0.1f*voice->target_pitch +0.9 * voice->prev_pitch; /* glide */
309
310 if (do_control_update) {
311 voice->prev_pitch = fund_pitch; /* save pitch for next time */
312 }
313
314 fund_pitch *= 440.0f;
315
316 omega = synth->tuning * fund_pitch;
317
318 // if we have triggered ACCENT
319 // we need a shorter decay
320 // we should probably have something like this in the note on code
321 // that could trigger an ACCENT light
322 if (velocity>90) {
323 vcf_egdecay=.0005;
324 }
325
326 // VCA - In a real 303, it is set for around 2 seconds
327 vca_eg_rate_level[0] = 0.1f * vca_eg_amp; // instant on attack
328 vca_eg_one_rate[0] = 0.9f; // very fast
329 vca_eg_rate_level[1] = 0.0f; // sustain is zero
330 vca_eg_one_rate[1] = 1.0f - 0.00001f; // decay time is very slow
331 vca_eg_rate_level[2] = 0.0f; // decays to zero
332 vca_eg_one_rate[2] = 0.975f; // very fast release
333
334 // VCF - funny things go on with the accent
335
336 vcf_eg_rate_level[0] = 0.1f * vcf_eg_amp;
337 vcf_eg_one_rate[0] = 1-0.1f; //0.9f;
338 vcf_eg_rate_level[1] = 0.0f; // vcf_egdecay * *(synth->vcf_eg_sustain_level) * vcf_eg_amp;
339 vcf_eg_one_rate[1] = 1.0f - vcf_egdecay;
340 vcf_eg_rate_level[2] = 0.0f;
341 vcf_eg_one_rate[2] = 0.9995f; // 1.0f - *(synth->vcf_eg_release_time);
342
343 vca_eg_amp *= 0.99f;
344 vcf_eg_amp *= 0.99f;
345
346 freq = M_PI_F * deltat * fund_pitch * synth->mod_wheel; /* now (0 to 1) * pi */
347
348 cutoff = 0.008f * synth->cutoff;
349
350 // 303 always has slight VCF mod
351 vcf_amt = 0.05f+(synth->envmod*0.75);
352
353 /* copy some things so oscillator functions can see them */
354 voice->osc1.waveform = lrintf(synth->waveform);
355
356 // work out how much the accent will affect the filter
357 vcf_acc_amt=.333f+ (synth->resonance/1.5f);
358
359 for (sample = 0; sample < sample_count; sample++) {
360 vca_eg = vca_eg_rate_level[vca_eg_phase] + vca_eg_one_rate[vca_eg_phase] * vca_eg;
361 vcf_eg = vcf_eg_rate_level[vcf_eg_phase] + vcf_eg_one_rate[vcf_eg_phase] * vcf_eg;
362
363 voice->freqcut_buf[sample] = (cutoff + (vcf_amt * vcf_eg/2.0f) + (synth->vcf_accent * synth->accent*0.5f));
364
365 voice->vca_buf[sample] = vca_eg * vol_out*(1.0f + synth->accent*synth->vca_accent);
366
367 if (!vca_eg_phase && vca_eg > vca_eg_amp) vca_eg_phase = 1; /* flip from attack to decay */
368 if (!vcf_eg_phase && vcf_eg > vcf_eg_amp) vcf_eg_phase = 1; /* flip from attack to decay */
369 }
370
371 // oscillator
372 vco(sample_count, voice, &voice->osc1, osc_index, deltat * omega);
373
374 // VCF and VCA
375 vcf_4pole(voice, sample_count, voice->osc_audio + osc_index, out, voice->freqcut_buf, qres, voice->vca_buf);
376
377 osc_index += sample_count;
378
379 if (do_control_update) {
380 /* do those things should be done only once per control-calculation
381 * interval ("nugget"), such as voice check-for-dead, pitch envelope
382 * calculations, volume envelope phase transition checks, etc. */
383 /* check if we've decayed to nothing, turn off voice if so */
384 if (vca_eg_phase == 2 && voice->vca_buf[sample_count - 1] < 6.26e-6f) {
385 // sound has completed its release phase (>96dB below volume '5' max)
386 XDB_MESSAGE(XDB_NOTE, " nekobee_voice_render check for dead: killing note id %d\n", voice->note_id);
387 nekobee_voice_off(voice);
388 return; // we're dead now, so return
389 }
390
391 /* already saved prev_pitch above */
392
393 /* check oscillator audio buffer index, shift buffer if necessary */
395 memcpy(voice->osc_audio, voice->osc_audio + osc_index,
396 LONGEST_DD_PULSE_LENGTH * sizeof (float));
397 memset(voice->osc_audio + LONGEST_DD_PULSE_LENGTH, 0,
399 osc_index = 0;
400 }
401 }
402
403 /* save things for next time around */
404 voice->lfo_pos = lfo_pos;
405 voice->vca_eg = vca_eg;
406 voice->vca_eg_phase = vca_eg_phase;
407 voice->vcf_eg = vcf_eg;
408 voice->vcf_eg_phase = vcf_eg_phase;
409 voice->osc_index = osc_index;
410
411 return;
412 (void)freq;
413 (void)vcf_acc_amt;
414}
SYNTH_T * synth
Definition LocalZynAddSubFx.cpp:47
UINT_D64 w
Definition inflate.c:942
register unsigned i
Definition inflate.c:1575
unsigned f
Definition inflate.c:1572
JHUFF_TBL long freq[]
Definition jchuff.h:50
long int lrintf(float x)
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
float_value_delta step_dd_table[MINBLEP_PHASES *STEP_DD_PULSE_LENGTH+1]
Definition minblep_tables.c:49
#define XDB_MESSAGE(type, fmt...)
Definition nekobee.h:66
#define XDB_NOTE
Definition nekobee.h:32
struct _nekobee_synth_t nekobee_synth_t
Definition nekobee_types.h:26
struct _nekobee_voice_t nekobee_voice_t
Definition nekobee_types.h:27
#define MINBLEP_BUFFER_LENGTH
Definition nekobee_voice.h:49
#define STEP_DD_PULSE_LENGTH
Definition nekobee_voice.h:42
static void nekobee_voice_off(nekobee_voice_t *voice)
Definition nekobee_voice.h:165
#define MINBLEP_PHASE_MASK
Definition nekobee_voice.h:40
#define DD_SAMPLE_DELAY
Definition nekobee_voice.h:51
#define MINBLEP_PHASES
Definition nekobee_voice.h:38
float nekobee_pitch[128]
Definition nekobee_voice_render.c:25
#define XSYNTH_NUGGET_SIZE
Definition nekobee_voice.h:34
#define LONGEST_DD_PULSE_LENGTH
Definition nekobee_voice.h:46
static float qdB_to_amplitude_table[4+256+0]
Definition nekobee_voice_render.c:35
void nekobee_voice_render(nekobee_synth_t *synth, nekobee_voice_t *voice, float *out, unsigned long sample_count, int do_control_update)
Definition nekobee_voice_render.c:273
static int tables_initialized
Definition nekobee_voice_render.c:23
static float volume(float level)
Definition nekobee_voice_render.c:99
static float volume_to_amplitude_table[4+volume_to_amplitude_scale+2]
Definition nekobee_voice_render.c:31
void nekobee_init_tables(void)
Definition nekobee_voice_render.c:38
void vco(unsigned long sample_count, nekobee_voice_t *voice, struct blosc *osc, int index, float w)
Definition nekobee_voice_render.c:146
#define pitch_ref_note
Definition nekobee_voice_render.c:27
#define VCF_FREQ_MAX
Definition nekobee_voice_render.c:21
void blosc_place_step_dd(float *buffer, int index, float phase, float w, float scale)
Definition nekobee_voice_render.c:123
static void vcf_4pole(nekobee_voice_t *voice, unsigned long sample_count, float *in, float *out, float *cutoff, float qres, float *amp)
Definition nekobee_voice_render.c:224
#define M_PI_F
Definition nekobee_voice_render.c:19
static float qdB_to_amplitude(float qdB)
Definition nekobee_voice_render.c:114
static float velocity_to_attenuation[128]
Definition nekobee_voice_render.c:33
#define volume_to_amplitude_scale
Definition nekobee_voice_render.c:29
float prev_pitch
Definition nekobee_voice.h:98
float delay3
Definition nekobee_voice.h:107
float vcf_eg
Definition nekobee_voice.h:103
struct blosc osc1
Definition nekobee_voice.h:101
float delay1
Definition nekobee_voice.h:105
unsigned char vca_eg_phase
Definition nekobee_voice.h:110
unsigned char vcf_eg_phase
Definition nekobee_voice.h:111
float c5
Definition nekobee_voice.h:109
float freqcut_buf[XSYNTH_NUGGET_SIZE]
Definition nekobee_voice.h:114
float delay2
Definition nekobee_voice.h:106
int osc_index
Definition nekobee_voice.h:112
float vca_buf[XSYNTH_NUGGET_SIZE]
Definition nekobee_voice.h:115
float target_pitch
Definition nekobee_voice.h:99
unsigned char velocity
Definition nekobee_voice.h:91
float vca_eg
Definition nekobee_voice.h:102
float delay4
Definition nekobee_voice.h:108
float osc_audio[MINBLEP_BUFFER_LENGTH]
Definition nekobee_voice.h:113
float lfo_pos
Definition nekobee_voice.h:100
unsigned int note_id
Definition nekobee_voice.h:87
Definition nekobee_voice.h:74
int bp_high
Definition nekobee_voice.h:77
float pos
Definition nekobee_voice.h:78
int waveform
Definition nekobee_voice.h:76
signed int sample
Definition tap_dynamics_m.c:41
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
#define void
Definition unzip.h:396