addnote.cpp cleanup
[zyn.git] / addnote.cpp
blobde5073babbd2053d7b669dba27a181c1adf47988
1 /*
2 ZynAddSubFX - a software synthesizer
4 ADnote.C - The "additive" synthesizer
5 Copyright (C) 2006,2007 Nedko Arnaudov <nedko@arnaudov.name>
6 Copyright (C) 2002-2005 Nasca Octavian Paul
7 Author: Nasca Octavian Paul
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of version 2 of the GNU General Public License
11 as published by the Free Software Foundation.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License (version 2) for more details.
18 You should have received a copy of the GNU General Public License (version 2)
19 along with this program; if not, write to the Free Software Foundation,
20 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
27 #include "globals.h"
28 #include "resonance.h"
29 #include "fft.h"
30 #include "oscillator.h"
31 #include "resonance.h"
32 #include "envelope_parameters.h"
33 #include "lfo_parameters.h"
34 #include "filter_parameters.h"
35 #include "lfo.h"
36 #include "filter_base.h"
37 #include "analog_filter.h"
38 #include "sv_filter.h"
39 #include "formant_filter.h"
40 #include "filter.h"
41 #include "envelope.h"
42 #include "addsynth.h"
43 #include "portamento.h"
44 #include "addsynth_internal.h"
45 #include "addsynth_voice.h"
46 #include "addnote.h"
48 #define LOG_LEVEL LOG_LEVEL_ERROR
49 #include "log.h"
51 ADnote::ADnote(
52 struct zyn_addsynth * synth_ptr)
54 m_tmpwave = new REALTYPE [SOUND_BUFFER_SIZE];
55 m_bypassl = new REALTYPE [SOUND_BUFFER_SIZE];
56 m_bypassr = new REALTYPE [SOUND_BUFFER_SIZE];
58 m_voices_ptr = (struct addsynth_voice *)malloc(sizeof(struct addsynth_voice) * synth_ptr->voices_count);
60 m_osc_pos_hi_ptr = (int *)malloc(sizeof(int) * synth_ptr->voices_count);
61 m_osc_pos_lo_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
62 m_osc_pos_hi_FM_ptr = (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr->voices_count);
63 m_osc_pos_lo_FM_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
65 m_osc_freq_hi_ptr = (int *)malloc(sizeof(int) * synth_ptr->voices_count);
66 m_osc_freq_lo_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
67 m_osc_freq_hi_FM_ptr = (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr->voices_count);
68 m_osc_freq_lo_FM_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
70 m_FM_old_smp_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
72 m_first_tick_ptr = (bool *)malloc(sizeof(bool) * synth_ptr->voices_count);
74 m_old_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
75 m_new_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
77 m_FM_old_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
78 m_FM_new_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
80 m_stereo = synth_ptr->stereo;
82 m_detune = getdetune(
83 synth_ptr->GlobalPar.PDetuneType,
84 synth_ptr->GlobalPar.PCoarseDetune,
85 synth_ptr->GlobalPar.PDetune);
88 * Get the Multiplier of the fine detunes of the voices
90 m_bandwidth_detune_multiplier = (synth_ptr->GlobalPar.PBandwidth - 64.0) / 64.0;
91 m_bandwidth_detune_multiplier =
92 pow(
93 2.0,
94 m_bandwidth_detune_multiplier * pow(fabs(m_bandwidth_detune_multiplier), 0.2) * 5.0);
96 m_note_enabled = false;
98 m_synth_ptr = synth_ptr;
100 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &m_filter_sv_processor_left))
104 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &m_filter_sv_processor_right))
109 void
110 ADnote::note_on(
111 float panorama,
112 bool random_grouping,
113 REALTYPE freq,
114 REALTYPE velocity,
115 bool portamento,
116 int midinote)
118 unsigned int voice_index;
119 unsigned int i;
120 float filter_velocity_adjust;
121 int voice_oscillator_index;
122 REALTYPE tmp;
124 m_portamento = portamento;
125 m_midinote = midinote;
126 m_note_enabled = true;
127 m_basefreq = freq;
129 if (velocity > 1.0)
131 m_velocity = 1.0;
133 else
135 m_velocity = velocity;
138 m_time = 0.0;
140 m_panning = (panorama + 1.0) / 2; // -1..1 -> 0 - 1
142 m_filter_category = m_synth_ptr->filter_type;
144 if (m_filter_category == ZYN_FILTER_TYPE_STATE_VARIABLE)
146 filter_velocity_adjust = m_synth_ptr->m_filter_velocity_sensing_amount * 6.0 * // velocity sensing
147 (zyn_velocity_scale(m_velocity, m_synth_ptr->m_filter_velocity_scale_function) - 1);
149 zyn_filter_sv_processor_init(m_filter_sv_processor_left, freq, filter_velocity_adjust);
150 if (m_stereo)
152 zyn_filter_sv_processor_init(m_filter_sv_processor_right, freq, filter_velocity_adjust);
155 else
157 m_filter_center_pitch =
158 m_synth_ptr->m_filter_params.getfreq() + // center freq
159 m_synth_ptr->m_filter_velocity_sensing_amount * 6.0 * // velocity sensing
160 (zyn_velocity_scale(m_velocity, m_synth_ptr->m_filter_velocity_scale_function) - 1);
161 m_filter_center_pitch += m_synth_ptr->m_filter_params.getfreqtracking(m_basefreq);
164 if (m_synth_ptr->GlobalPar.PPunchStrength != 0)
166 m_punch_enabled = true;
167 m_punch_t = 1.0; // start from 1.0 and to 0.0
168 m_punch_initial_value = pow(10, 1.5 * m_synth_ptr->GlobalPar.PPunchStrength / 127.0) - 1.0;
169 m_punch_initial_value *= VelF(m_velocity, m_synth_ptr->GlobalPar.PPunchVelocitySensing);
171 REALTYPE time = pow(10, 3.0 * m_synth_ptr->GlobalPar.PPunchTime / 127.0) / 10000.0; // 0.1 .. 100 ms
173 REALTYPE stretch = pow(440.0/freq, m_synth_ptr->GlobalPar.PPunchStretch / 64.0);
175 m_punch_duration = 1.0 / (time * m_synth_ptr->sample_rate * stretch);
177 else
179 m_punch_enabled = false;
182 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
184 zyn_oscillator_new_rand_seed(
185 &m_synth_ptr->voices_params_ptr[voice_index].oscillator,
186 rand());
187 m_voices_ptr[voice_index].OscilSmp = NULL;
188 m_voices_ptr[voice_index].FMSmp = NULL;
189 m_voices_ptr[voice_index].VoiceOut = NULL;
191 m_voices_ptr[voice_index].FMVoice = -1;
193 if (!m_synth_ptr->voices_params_ptr[voice_index].enabled)
195 m_voices_ptr[voice_index].enabled = false;
196 continue; // the voice is disabled
199 m_voices_ptr[voice_index].enabled = true;
200 m_voices_ptr[voice_index].fixedfreq = m_synth_ptr->voices_params_ptr[voice_index].Pfixedfreq;
201 m_voices_ptr[voice_index].fixedfreqET = m_synth_ptr->voices_params_ptr[voice_index].PfixedfreqET;
203 // use the Globalpars.detunetype if the detunetype is 0
204 if (m_synth_ptr->voices_params_ptr[voice_index].PDetuneType != 0)
206 // coarse detune
207 m_voices_ptr[voice_index].Detune =
208 getdetune(
209 m_synth_ptr->voices_params_ptr[voice_index].PDetuneType,
210 m_synth_ptr->voices_params_ptr[voice_index].PCoarseDetune,
211 8192);
213 // fine detune
214 m_voices_ptr[voice_index].FineDetune =
215 getdetune(
216 m_synth_ptr->voices_params_ptr[voice_index].PDetuneType,
218 m_synth_ptr->voices_params_ptr[voice_index].PDetune);
220 else
222 // coarse detune
223 m_voices_ptr[voice_index].Detune = getdetune(
224 m_synth_ptr->GlobalPar.PDetuneType,
225 m_synth_ptr->voices_params_ptr[voice_index].PCoarseDetune,
226 8192);
228 // fine detune
229 m_voices_ptr[voice_index].FineDetune = getdetune(
230 m_synth_ptr->GlobalPar.PDetuneType,
232 m_synth_ptr->voices_params_ptr[voice_index].PDetune);
235 if (m_synth_ptr->voices_params_ptr[voice_index].PFMDetuneType != 0)
237 m_voices_ptr[voice_index].FMDetune =
238 getdetune(
239 m_synth_ptr->voices_params_ptr[voice_index].PFMDetuneType,
240 m_synth_ptr->voices_params_ptr[voice_index].PFMCoarseDetune,
241 m_synth_ptr->voices_params_ptr[voice_index].PFMDetune);
243 else
245 m_voices_ptr[voice_index].FMDetune = getdetune(
246 m_synth_ptr->GlobalPar.PDetuneType,
247 m_synth_ptr->voices_params_ptr[voice_index].PFMCoarseDetune,
248 m_synth_ptr->voices_params_ptr[voice_index].PFMDetune);
251 m_osc_pos_hi_ptr[voice_index] = 0;
252 m_osc_pos_lo_ptr[voice_index] = 0.0;
253 m_osc_pos_hi_FM_ptr[voice_index] = 0;
254 m_osc_pos_lo_FM_ptr[voice_index] = 0.0;
256 // the extra points contains the first point
257 m_voices_ptr[voice_index].OscilSmp = new REALTYPE [OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES];
259 // Get the voice's oscil or external's voice oscil
260 if (m_synth_ptr->voices_params_ptr[voice_index].Pextoscil != -1)
262 voice_oscillator_index = m_synth_ptr->voices_params_ptr[voice_index].Pextoscil;
264 else
266 voice_oscillator_index = voice_index;
269 if (!random_grouping)
271 zyn_oscillator_new_rand_seed(
272 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
273 rand());
276 m_osc_pos_hi_ptr[voice_index] =
277 zyn_oscillator_get(
278 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
279 m_voices_ptr[voice_index].OscilSmp,
280 getvoicebasefreq(voice_index),
281 m_synth_ptr->voices_params_ptr[voice_index].resonance);
283 // I store the first elments to the last position for speedups
284 for (i = 0 ; i < OSCIL_SMP_EXTRA_SAMPLES ; i++)
286 m_voices_ptr[voice_index].OscilSmp[OSCIL_SIZE + i] = m_voices_ptr[voice_index].OscilSmp[i];
289 m_osc_pos_hi_ptr[voice_index] += (int)((m_synth_ptr->voices_params_ptr[voice_index].Poscilphase - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4);
290 m_osc_pos_hi_ptr[voice_index] %= OSCIL_SIZE;
292 m_voices_ptr[voice_index].FilterCenterPitch = m_synth_ptr->voices_params_ptr[voice_index].m_filter_params.getfreq();
293 m_voices_ptr[voice_index].filterbypass = m_synth_ptr->voices_params_ptr[voice_index].Pfilterbypass;
295 m_voices_ptr[voice_index].fm_type = m_synth_ptr->voices_params_ptr[voice_index].fm_type;
297 m_voices_ptr[voice_index].FMVoice=m_synth_ptr->voices_params_ptr[voice_index].PFMVoice;
299 // Compute the Voice's modulator volume (incl. damping)
300 REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq(voice_index), m_synth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp / 64.0 - 1.0);
301 switch (m_voices_ptr[voice_index].fm_type)
303 case ZYN_FM_TYPE_PHASE_MOD:
304 fmvoldamp = pow(440.0 / getvoicebasefreq(voice_index), m_synth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp / 64.0);
305 m_voices_ptr[voice_index].FMVolume = (exp(m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0;
306 break;
307 case ZYN_FM_TYPE_FREQ_MOD:
308 m_voices_ptr[voice_index].FMVolume = exp(m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * FM_AMP_MULTIPLIER);
309 m_voices_ptr[voice_index].FMVolume -= 1.0;
310 m_voices_ptr[voice_index].FMVolume *= fmvoldamp * 4.0;
311 break;
312 #if 0 // ???????????
313 case ZYN_FM_TYPE_PITCH_MOD:
314 m_voices_ptr[voice_index].FMVolume = (m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * 8.0) * fmvoldamp;
315 break;
316 #endif
317 default:
318 if (fmvoldamp > 1.0)
320 fmvoldamp = 1.0;
323 m_voices_ptr[voice_index].FMVolume = m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * fmvoldamp;
326 // Voice's modulator velocity sensing
327 m_voices_ptr[voice_index].FMVolume *= VelF(m_velocity, m_synth_ptr->voices_params_ptr[voice_index].PFMVelocityScaleFunction);
329 m_FM_old_smp_ptr[voice_index] = 0.0; // this is for FM (integration)
331 m_first_tick_ptr[voice_index] = true;
332 m_voices_ptr[voice_index].DelayTicks = (int)((exp(m_synth_ptr->voices_params_ptr[voice_index].PDelay / 127.0 * log(50.0)) - 1.0) / SOUND_BUFFER_SIZE / 10.0 * m_synth_ptr->sample_rate);
333 } // voices loop
335 // Global Parameters
336 m_frequency_envelope.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_frequency_envelope_params, m_basefreq);
338 m_frequency_lfo.init(
339 m_synth_ptr->sample_rate,
340 m_basefreq,
341 &m_synth_ptr->frequency_lfo_params,
342 ZYN_LFO_TYPE_FREQUENCY);
344 m_amplitude_envelope.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_amplitude_envelope_params, m_basefreq);
346 m_amplitude_lfo.init(
347 m_synth_ptr->sample_rate,
348 m_basefreq,
349 &m_synth_ptr->amplitude_lfo_params,
350 ZYN_LFO_TYPE_AMPLITUDE);
352 m_volume = 4.0 * pow(0.1, 3.0 * (1.0 - m_synth_ptr->GlobalPar.PVolume / 96.0)); // -60 dB .. 0 dB
353 m_volume *= VelF(m_velocity, m_synth_ptr->GlobalPar.PAmpVelocityScaleFunction); // velocity sensing
355 m_amplitude_envelope.envout_dB(); // discard the first envelope output
357 globalnewamplitude = m_volume * m_amplitude_envelope.envout_dB() * m_amplitude_lfo.amplfoout();
359 m_filter_left.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_filter_params);
360 if (m_stereo)
362 m_filter_right.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_filter_params);
365 m_filter_envelope.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_filter_envelope_params, m_basefreq);
367 m_filter_lfo.init(
368 m_synth_ptr->sample_rate,
369 m_basefreq,
370 &m_synth_ptr->filter_lfo_params,
371 ZYN_LFO_TYPE_FILTER);
373 m_filter_q_factor = m_synth_ptr->m_filter_params.getq();
375 // Forbids the Modulation Voice to be greater or equal than voice
376 for (i = 0 ; i < m_synth_ptr->voices_count ; i++)
378 if (m_voices_ptr[i].FMVoice >= (int)i)
380 m_voices_ptr[i].FMVoice = -1;
384 // Voice Parameter init
385 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
387 if (!m_voices_ptr[voice_index].enabled)
389 continue;
392 LOG_DEBUG("Starting %s voice (%u, %p)", m_synth_ptr->voices_params_ptr[voice_index].white_noise ? "white noise" : "signal", voice_index, m_synth_ptr->voices_params_ptr + voice_index);
394 m_voices_ptr[voice_index].white_noise = m_synth_ptr->voices_params_ptr[voice_index].white_noise;
396 /* Voice Amplitude Parameters Init */
398 m_voices_ptr[voice_index].Volume = pow(0.1, 3.0 * (1.0 - m_synth_ptr->voices_params_ptr[voice_index].PVolume / 127.0)); // -60 dB .. 0 dB
399 m_voices_ptr[voice_index].Volume *= VelF(m_velocity, m_synth_ptr->voices_params_ptr[voice_index].PAmpVelocityScaleFunction); // velocity
401 if (m_synth_ptr->voices_params_ptr[voice_index].PVolumeminus != 0)
403 m_voices_ptr[voice_index].Volume = -m_voices_ptr[voice_index].Volume;
406 if (m_synth_ptr->voices_params_ptr[voice_index].PPanning == 0)
408 m_voices_ptr[voice_index].Panning = zyn_random(); // random panning
410 else
412 m_voices_ptr[voice_index].Panning = m_synth_ptr->voices_params_ptr[voice_index].PPanning / 128.0;
415 m_new_amplitude_ptr[voice_index] = 1.0;
416 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled != 0)
418 m_voices_ptr[voice_index].m_amplitude_envelope.init(
419 m_synth_ptr->sample_rate,
420 &m_synth_ptr->voices_params_ptr[voice_index].m_amplitude_envelope_params,
421 m_basefreq);
423 m_voices_ptr[voice_index].m_amplitude_envelope.envout_dB(); // discard the first envelope sample
424 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_envelope.envout_dB();
427 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled != 0)
429 m_voices_ptr[voice_index].m_amplitude_lfo.init(
430 m_synth_ptr->sample_rate,
431 m_basefreq,
432 &m_synth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params,
433 ZYN_LFO_TYPE_AMPLITUDE);
435 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_lfo.amplfoout();
438 /* Voice Frequency Parameters Init */
439 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled != 0)
441 m_voices_ptr[voice_index].m_frequency_envelope.init(
442 m_synth_ptr->sample_rate,
443 &m_synth_ptr->voices_params_ptr[voice_index].m_frequency_envelope_params,
444 m_basefreq);
447 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled != 0)
449 m_voices_ptr[voice_index].m_frequency_lfo.init(
450 m_synth_ptr->sample_rate,
451 m_basefreq,
452 &m_synth_ptr->voices_params_ptr[voice_index].frequency_lfo_params,
453 ZYN_LFO_TYPE_FREQUENCY);
456 /* Voice Filter Parameters Init */
457 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnabled != 0)
459 m_voices_ptr[voice_index].m_voice_filter.init(
460 m_synth_ptr->sample_rate,
461 &m_synth_ptr->voices_params_ptr[voice_index].m_filter_params);
464 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled != 0)
466 m_voices_ptr[voice_index].m_filter_envelope.init(
467 m_synth_ptr->sample_rate,
468 &m_synth_ptr->voices_params_ptr[voice_index].m_filter_envelope_params,
469 m_basefreq);
472 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled != 0)
474 m_voices_ptr[voice_index].m_filter_lfo.init(
475 m_synth_ptr->sample_rate,
476 m_basefreq,
477 &m_synth_ptr->voices_params_ptr[voice_index].filter_lfo_params,
478 ZYN_LFO_TYPE_FILTER);
481 m_voices_ptr[voice_index].FilterFreqTracking = m_synth_ptr->voices_params_ptr[voice_index].m_filter_params.getfreqtracking(m_basefreq);
483 /* Voice Modulation Parameters Init */
484 if (m_voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE &&
485 m_voices_ptr[voice_index].FMVoice < 0)
487 zyn_oscillator_new_rand_seed(
488 &m_synth_ptr->voices_params_ptr[voice_index].modulator_oscillator,
489 rand());
491 m_voices_ptr[voice_index].FMSmp = new zyn_sample_type[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES];
493 // Perform Anti-aliasing only on MORPH or RING MODULATION
495 if (m_synth_ptr->voices_params_ptr[voice_index].PextFMoscil != -1)
497 voice_oscillator_index = m_synth_ptr->voices_params_ptr[voice_index].PextFMoscil;
499 else
501 voice_oscillator_index = voice_index;
504 if ((m_synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator.Padaptiveharmonics != 0) ||
505 (m_voices_ptr[voice_index].fm_type == ZYN_FM_TYPE_MORPH) ||
506 (m_voices_ptr[voice_index].fm_type == ZYN_FM_TYPE_RING_MOD))
508 tmp = getFMvoicebasefreq(voice_index);
510 else
512 tmp = 1.0;
515 if (!random_grouping)
517 zyn_oscillator_new_rand_seed(
518 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
519 rand());
522 m_osc_pos_hi_FM_ptr[voice_index] = m_osc_pos_hi_ptr[voice_index];
523 m_osc_pos_hi_FM_ptr[voice_index] += zyn_oscillator_get(
524 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
525 m_voices_ptr[voice_index].FMSmp,
526 tmp,
527 false);
528 m_osc_pos_hi_FM_ptr[voice_index] %= OSCIL_SIZE;
530 for (i = 0 ; i < OSCIL_SMP_EXTRA_SAMPLES ; i++)
532 m_voices_ptr[voice_index].FMSmp[OSCIL_SIZE + i] = m_voices_ptr[voice_index].FMSmp[i];
535 m_osc_pos_hi_FM_ptr[voice_index] += (int)((m_synth_ptr->voices_params_ptr[voice_index].PFMoscilphase - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4);
536 m_osc_pos_hi_FM_ptr[voice_index] %= OSCIL_SIZE;
539 if (m_synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled != 0)
541 m_voices_ptr[voice_index].m_fm_frequency_envelope.init(
542 m_synth_ptr->sample_rate,
543 &m_synth_ptr->voices_params_ptr[voice_index].m_fm_frequency_envelope_params,
544 m_basefreq);
547 m_FM_new_amplitude_ptr[voice_index] = m_voices_ptr[voice_index].FMVolume;
548 //m_FM_new_amplitude_ptr[voice_index] *= m_ctl->fmamp.relamp; // 0..1
550 if (m_synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled != 0)
552 m_voices_ptr[voice_index].m_fm_amplitude_envelope.init(
553 m_synth_ptr->sample_rate,
554 &m_synth_ptr->voices_params_ptr[voice_index].m_fm_amplitude_envelope_params,
555 m_basefreq);
557 m_FM_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_fm_amplitude_envelope.envout_dB();
559 } // voice parameter init loop
561 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
563 for (i = voice_index + 1 ; i < m_synth_ptr->voices_count ; i++)
565 if (m_voices_ptr[i].FMVoice == (int)voice_index)
567 m_voices_ptr[voice_index].VoiceOut = new REALTYPE[SOUND_BUFFER_SIZE];
571 if (m_voices_ptr[voice_index].VoiceOut != NULL)
573 silence_buffer(m_voices_ptr[voice_index].VoiceOut, SOUND_BUFFER_SIZE);
579 * Kill a voice of ADnote
581 void ADnote::KillVoice(unsigned int voice_index)
583 delete [] (m_voices_ptr[voice_index].OscilSmp);
585 if ((m_voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE) && (m_voices_ptr[voice_index].FMVoice < 0))
587 delete m_voices_ptr[voice_index].FMSmp;
590 if (m_voices_ptr[voice_index].VoiceOut != NULL)
592 // do not delete, yet: perhaps is used by another voice
593 silence_buffer(m_voices_ptr[voice_index].VoiceOut, SOUND_BUFFER_SIZE);
596 m_voices_ptr[voice_index].enabled = false;
600 * Kill the note
602 void
603 ADnote::force_disable()
605 unsigned int voice_index;
607 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
609 if (m_voices_ptr[voice_index].enabled)
611 KillVoice(voice_index);
614 // delete VoiceOut
615 if (m_voices_ptr[voice_index].VoiceOut != NULL)
617 delete(m_voices_ptr[voice_index].VoiceOut);
618 m_voices_ptr[voice_index].VoiceOut = NULL;
622 m_note_enabled = false;
625 ADnote::~ADnote()
627 if (m_note_enabled)
629 force_disable();
632 zyn_filter_sv_processor_destroy(m_filter_sv_processor_left);
633 zyn_filter_sv_processor_destroy(m_filter_sv_processor_right);
635 free(m_old_amplitude_ptr);
636 free(m_new_amplitude_ptr);
638 free(m_FM_old_amplitude_ptr);
639 free(m_FM_new_amplitude_ptr);
641 free(m_first_tick_ptr);
643 free(m_FM_old_smp_ptr);
645 free(m_osc_freq_hi_ptr);
646 free(m_osc_freq_lo_ptr);
647 free(m_osc_freq_hi_FM_ptr);
648 free(m_osc_freq_lo_FM_ptr);
650 free(m_osc_pos_hi_ptr);
651 free(m_osc_pos_lo_ptr);
652 free(m_osc_pos_hi_FM_ptr);
653 free(m_osc_pos_lo_FM_ptr);
655 free(m_voices_ptr);
657 delete [] m_tmpwave;
658 delete [] m_bypassl;
659 delete [] m_bypassr;
663 * Computes the frequency of an oscillator
665 void ADnote::setfreq(int nvoice,REALTYPE freq)
667 REALTYPE speed;
669 freq = fabs(freq);
671 speed = freq * REALTYPE(OSCIL_SIZE) / m_synth_ptr->sample_rate;
672 if (speed > OSCIL_SIZE)
674 speed = OSCIL_SIZE;
677 F2I(speed, m_osc_freq_hi_ptr[nvoice]);
679 m_osc_freq_lo_ptr[nvoice] = speed - floor(speed);
683 * Computes the frequency of an modullator oscillator
685 void ADnote::setfreqFM(int nvoice,REALTYPE freq)
687 REALTYPE speed;
689 freq = fabs(freq);
691 speed = freq * REALTYPE(OSCIL_SIZE) / m_synth_ptr->sample_rate;
692 if (speed > OSCIL_SIZE)
694 speed = OSCIL_SIZE;
697 F2I(speed, m_osc_freq_hi_FM_ptr[nvoice]);
698 m_osc_freq_lo_FM_ptr[nvoice] = speed - floor(speed);
702 * Get Voice base frequency
704 REALTYPE ADnote::getvoicebasefreq(int nvoice)
706 REALTYPE detune;
708 detune = m_voices_ptr[nvoice].Detune / 100.0;
709 detune += m_voices_ptr[nvoice].FineDetune / 100.0 * m_synth_ptr->bandwidth_relbw * m_bandwidth_detune_multiplier;
710 detune += m_detune / 100.0;
712 if (m_voices_ptr[nvoice].fixedfreq == 0)
714 return m_basefreq * pow(2, detune / 12.0);
716 else
718 // the fixed freq is enabled
719 REALTYPE fixedfreq = 440.0;
720 int fixedfreqET = m_voices_ptr[nvoice].fixedfreqET;
721 if (fixedfreqET!=0)
723 // if the frequency varies according the keyboard note
724 REALTYPE tmp = (m_midinote - 69.0) / 12.0 * (pow(2.0,(fixedfreqET-1)/63.0) - 1.0);
725 if (fixedfreqET <= 64)
727 fixedfreq *= pow(2.0,tmp);
729 else
731 fixedfreq *= pow(3.0,tmp);
735 return fixedfreq * pow(2.0, detune / 12.0);
740 * Get Voice's Modullator base frequency
742 REALTYPE ADnote::getFMvoicebasefreq(int nvoice){
743 REALTYPE detune=m_voices_ptr[nvoice].FMDetune/100.0;
744 return(getvoicebasefreq(nvoice)*pow(2,detune/12.0));
748 * Computes all the parameters for each tick
750 void
751 ADnote::computecurrentparameters()
753 unsigned int voice_index;
754 float voicefreq;
755 float voicepitch;
756 float filterpitch;
757 float filterfreq;
758 float FMfreq;
759 float FMrelativepitch;
760 float globalpitch;
761 float temp_filter_frequency;
763 globalpitch =
764 0.01 * (m_frequency_envelope.envout() +
765 m_frequency_lfo.lfoout() * m_synth_ptr->modwheel_relmod);
767 globaloldamplitude = globalnewamplitude;
769 globalnewamplitude =
770 m_volume *
771 m_amplitude_envelope.envout_dB() *
772 m_amplitude_lfo.amplfoout();
774 if (m_filter_category != ZYN_FILTER_TYPE_STATE_VARIABLE)
776 temp_filter_frequency = m_filter_left.getrealfreq(m_filter_center_pitch + m_filter_envelope.envout() + m_filter_lfo.lfoout());
778 m_filter_left.setfreq_and_q(temp_filter_frequency, m_filter_q_factor);
779 if (m_stereo)
781 m_filter_right.setfreq_and_q(temp_filter_frequency, m_filter_q_factor);
785 // compute the portamento, if it is used by this note
786 REALTYPE portamentofreqrap=1.0;
787 if (m_portamento)
789 // this voice use portamento
790 portamentofreqrap = m_synth_ptr->portamento.freqrap;
792 if (!m_synth_ptr->portamento.used)
794 // the portamento has finished
795 m_portamento = false; // this note is no longer "portamented"
799 //compute parameters for all voices
800 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
802 if (!m_voices_ptr[voice_index].enabled)
804 continue;
807 m_voices_ptr[voice_index].DelayTicks -= 1;
809 if (m_voices_ptr[voice_index].DelayTicks > 0)
811 continue;
814 /*******************/
815 /* Voice Amplitude */
816 /*******************/
817 m_old_amplitude_ptr[voice_index] = m_new_amplitude_ptr[voice_index];
818 m_new_amplitude_ptr[voice_index] = 1.0;
820 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
822 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_envelope.envout_dB();
825 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled)
827 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_lfo.amplfoout();
830 /****************/
831 /* Voice Filter */
832 /****************/
833 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
835 filterpitch = m_voices_ptr[voice_index].FilterCenterPitch;
837 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled)
839 filterpitch += m_voices_ptr[voice_index].m_filter_envelope.envout();
842 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled)
844 filterpitch += m_voices_ptr[voice_index].m_filter_lfo.lfoout();
847 filterfreq = filterpitch + m_voices_ptr[voice_index].FilterFreqTracking;
848 filterfreq = m_voices_ptr[voice_index].m_voice_filter.getrealfreq(filterfreq);
850 m_voices_ptr[voice_index].m_voice_filter.setfreq(filterfreq);
853 // compute only if the voice isn't noise
854 if (!m_voices_ptr[voice_index].white_noise)
856 /*******************/
857 /* Voice Frequency */
858 /*******************/
859 voicepitch=0.0;
860 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled)
862 voicepitch += m_voices_ptr[voice_index].m_frequency_lfo.lfoout() / 100.0 * m_synth_ptr->bandwidth_relbw;
865 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled)
867 voicepitch += m_voices_ptr[voice_index].m_frequency_envelope.envout() / 100.0;
870 voicefreq = getvoicebasefreq(voice_index) * pow(2, (voicepitch + globalpitch) / 12.0); // Hz frequency
871 voicefreq *= m_synth_ptr->pitch_bend_relative_frequency; // change the frequency by the controller
872 setfreq(voice_index, voicefreq * portamentofreqrap);
874 /***************/
875 /* Modulator */
876 /***************/
877 if (m_voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE)
879 FMrelativepitch = m_voices_ptr[voice_index].FMDetune / 100.0;
880 if (m_synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled)
882 FMrelativepitch += m_voices_ptr[voice_index].m_fm_frequency_envelope.envout() / 100;
885 FMfreq = pow(2.0, FMrelativepitch / 12.0) * voicefreq * portamentofreqrap;
886 setfreqFM(voice_index, FMfreq);
888 m_FM_old_amplitude_ptr[voice_index] = m_FM_new_amplitude_ptr[voice_index];
889 m_FM_new_amplitude_ptr[voice_index] = m_voices_ptr[voice_index].FMVolume;
890 //m_FM_new_amplitude_ptr[voice_index] *= m_ctl->fmamp.relamp; // 0..1
892 if (m_synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled)
894 m_FM_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_fm_amplitude_envelope.envout_dB();
900 m_time += (REALTYPE)SOUND_BUFFER_SIZE / m_synth_ptr->sample_rate;
905 * Fadein in a way that removes clicks but keep sound "punchy"
907 inline void ADnote::fadein(REALTYPE *smps){
908 int zerocrossings=0;
909 for (int i=1;i<SOUND_BUFFER_SIZE;i++)
910 if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings
912 REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0;
913 if (tmp<8.0) tmp=8.0;
915 int n;
916 F2I(tmp,n);//how many samples is the fade-in
917 if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
918 for (int i=0;i<n;i++) {//fade-in
919 REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5;
920 smps[i]*=tmp;
925 * Computes the Oscillator (Without Modulation) - LinearInterpolation
927 inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int voice_index){
928 int i,poshi;
929 REALTYPE poslo;
931 poshi=m_osc_pos_hi_ptr[voice_index];
932 poslo=m_osc_pos_lo_ptr[voice_index];
933 REALTYPE *smps=m_voices_ptr[voice_index].OscilSmp;
934 for (i=0;i<SOUND_BUFFER_SIZE;i++){
935 m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
936 poslo+=m_osc_freq_lo_ptr[voice_index];
937 if (poslo>=1.0) {
938 poslo-=1.0;
939 poshi++;
941 poshi+=m_osc_freq_hi_ptr[voice_index];
942 poshi&=OSCIL_SIZE-1;
944 m_osc_pos_hi_ptr[voice_index]=poshi;
945 m_osc_pos_lo_ptr[voice_index]=poslo;
951 * Computes the Oscillator (Without Modulation) - CubicInterpolation
953 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
954 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
955 int i,poshi;
956 REALTYPE poslo;
958 poshi=m_osc_pos_hi_ptr[voice_index];
959 poslo=m_osc_pos_lo_ptr[voice_index];
960 REALTYPE *smps=m_voices_ptr[voice_index].OscilSmp;
961 REALTYPE xm1,x0,x1,x2,a,b,c;
962 for (i=0;i<SOUND_BUFFER_SIZE;i++){
963 xm1=smps[poshi];
964 x0=smps[poshi+1];
965 x1=smps[poshi+2];
966 x2=smps[poshi+3];
967 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
968 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
969 c = (x1 - xm1) / 2.0;
970 m_tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
971 printf("a\n");
972 //m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
973 poslo+=m_osc_freq_lo_ptr[voice_index];
974 if (poslo>=1.0) {
975 poslo-=1.0;
976 poshi++;
978 poshi+=m_osc_freq_hi_ptr[voice_index];
979 poshi&=OSCIL_SIZE-1;
981 m_osc_pos_hi_ptr[voice_index]=poshi;
982 m_osc_pos_lo_ptr[voice_index]=poslo;
986 * Computes the Oscillator (Morphing)
988 inline void ADnote::ComputeVoiceOscillatorMorph(int voice_index){
989 int i;
990 REALTYPE amp;
991 ComputeVoiceOscillator_LinearInterpolation(voice_index);
992 if (m_FM_new_amplitude_ptr[voice_index]>1.0) m_FM_new_amplitude_ptr[voice_index]=1.0;
993 if (m_FM_old_amplitude_ptr[voice_index]>1.0) m_FM_old_amplitude_ptr[voice_index]=1.0;
995 if (m_voices_ptr[voice_index].FMVoice>=0){
996 //if I use VoiceOut[] as modullator
997 int FMVoice=m_voices_ptr[voice_index].FMVoice;
998 for (i=0;i<SOUND_BUFFER_SIZE;i++) {
999 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1000 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1001 m_tmpwave[i]=m_tmpwave[i]*(1.0-amp)+amp*m_voices_ptr[FMVoice].VoiceOut[i];
1003 } else {
1004 int poshiFM=m_osc_pos_hi_FM_ptr[voice_index];
1005 REALTYPE posloFM=m_osc_pos_lo_FM_ptr[voice_index];
1007 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1008 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1009 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1010 m_tmpwave[i]=m_tmpwave[i]*(1.0-amp)+amp
1011 *(m_voices_ptr[voice_index].FMSmp[poshiFM]*(1-posloFM)
1012 +m_voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM);
1013 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1014 if (posloFM>=1.0) {
1015 posloFM-=1.0;
1016 poshiFM++;
1018 poshiFM+=m_osc_freq_hi_FM_ptr[voice_index];
1019 poshiFM&=OSCIL_SIZE-1;
1021 m_osc_pos_hi_FM_ptr[voice_index]=poshiFM;
1022 m_osc_pos_lo_FM_ptr[voice_index]=posloFM;
1027 * Computes the Oscillator (Ring Modulation)
1029 inline void ADnote::ComputeVoiceOscillatorRingModulation(int voice_index){
1030 int i;
1031 REALTYPE amp;
1032 ComputeVoiceOscillator_LinearInterpolation(voice_index);
1033 if (m_FM_new_amplitude_ptr[voice_index]>1.0) m_FM_new_amplitude_ptr[voice_index]=1.0;
1034 if (m_FM_old_amplitude_ptr[voice_index]>1.0) m_FM_old_amplitude_ptr[voice_index]=1.0;
1035 if (m_voices_ptr[voice_index].FMVoice>=0){
1036 // if I use VoiceOut[] as modullator
1037 for (i=0;i<SOUND_BUFFER_SIZE;i++) {
1038 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1039 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1040 int FMVoice=m_voices_ptr[voice_index].FMVoice;
1041 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1042 m_tmpwave[i]*=(1.0-amp)+amp*m_voices_ptr[FMVoice].VoiceOut[i];
1044 } else {
1045 int poshiFM=m_osc_pos_hi_FM_ptr[voice_index];
1046 REALTYPE posloFM=m_osc_pos_lo_FM_ptr[voice_index];
1048 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1049 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1050 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1051 m_tmpwave[i]*=( m_voices_ptr[voice_index].FMSmp[poshiFM]*(1.0-posloFM)
1052 +m_voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM)*amp
1053 +(1.0-amp);
1054 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1055 if (posloFM>=1.0) {
1056 posloFM-=1.0;
1057 poshiFM++;
1059 poshiFM+=m_osc_freq_hi_FM_ptr[voice_index];
1060 poshiFM&=OSCIL_SIZE-1;
1062 m_osc_pos_hi_FM_ptr[voice_index]=poshiFM;
1063 m_osc_pos_lo_FM_ptr[voice_index]=posloFM;
1070 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
1072 inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int voice_index,int FMmode){
1073 int carposhi;
1074 int i,FMmodfreqhi;
1075 REALTYPE FMmodfreqlo,carposlo;
1077 if (m_voices_ptr[voice_index].FMVoice>=0){
1078 //if I use VoiceOut[] as modulator
1079 for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]=m_voices_ptr[m_voices_ptr[voice_index].FMVoice].VoiceOut[i];
1080 } else {
1081 //Compute the modulator and store it in m_tmpwave[]
1082 int poshiFM=m_osc_pos_hi_FM_ptr[voice_index];
1083 REALTYPE posloFM=m_osc_pos_lo_FM_ptr[voice_index];
1085 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1086 m_tmpwave[i]=(m_voices_ptr[voice_index].FMSmp[poshiFM]*(1.0-posloFM)
1087 +m_voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM);
1088 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1089 if (posloFM>=1.0) {
1090 posloFM=fmod(posloFM,1.0);
1091 poshiFM++;
1093 poshiFM+=m_osc_freq_hi_FM_ptr[voice_index];
1094 poshiFM&=OSCIL_SIZE-1;
1096 m_osc_pos_hi_FM_ptr[voice_index]=poshiFM;
1097 m_osc_pos_lo_FM_ptr[voice_index]=posloFM;
1099 // Amplitude interpolation
1100 if (ABOVE_AMPLITUDE_THRESHOLD(m_FM_old_amplitude_ptr[voice_index],m_FM_new_amplitude_ptr[voice_index])){
1101 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1102 m_tmpwave[i]*=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1103 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1105 } else for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]*=m_FM_new_amplitude_ptr[voice_index];
1108 //normalize makes all sample-rates, oscil_sizes toproduce same sound
1109 if (FMmode!=0){//Frequency modulation
1110 REALTYPE normalize = OSCIL_SIZE / 262144.0 * 44100.0 / m_synth_ptr->sample_rate;
1111 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1112 m_FM_old_smp_ptr[voice_index]=fmod(m_FM_old_smp_ptr[voice_index]+m_tmpwave[i]*normalize,OSCIL_SIZE);
1113 m_tmpwave[i]=m_FM_old_smp_ptr[voice_index];
1115 } else {//Phase modulation
1116 REALTYPE normalize=OSCIL_SIZE/262144.0;
1117 for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]*=normalize;
1120 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1121 F2I(m_tmpwave[i],FMmodfreqhi);
1122 FMmodfreqlo=fmod(m_tmpwave[i]+0.0000000001,1.0);
1123 if (FMmodfreqhi<0) FMmodfreqlo++;
1125 //carrier
1126 carposhi=m_osc_pos_hi_ptr[voice_index]+FMmodfreqhi;
1127 carposlo=m_osc_pos_lo_ptr[voice_index]+FMmodfreqlo;
1129 if (carposlo>=1.0) {
1130 carposhi++;
1131 carposlo=fmod(carposlo,1.0);
1133 carposhi&=(OSCIL_SIZE-1);
1135 m_tmpwave[i]=m_voices_ptr[voice_index].OscilSmp[carposhi]*(1.0-carposlo)
1136 +m_voices_ptr[voice_index].OscilSmp[carposhi+1]*carposlo;
1138 m_osc_pos_lo_ptr[voice_index]+=m_osc_freq_lo_ptr[voice_index];
1139 if (m_osc_pos_lo_ptr[voice_index]>=1.0) {
1140 m_osc_pos_lo_ptr[voice_index]=fmod(m_osc_pos_lo_ptr[voice_index],1.0);
1141 m_osc_pos_hi_ptr[voice_index]++;
1144 m_osc_pos_hi_ptr[voice_index]+=m_osc_freq_hi_ptr[voice_index];
1145 m_osc_pos_hi_ptr[voice_index]&=OSCIL_SIZE-1;
1150 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
1151 inline void ADnote::ComputeVoiceOscillatorPitchModulation(int voice_index){
1152 //TODO
1156 * Computes the Noise
1158 inline void ADnote::ComputeVoiceNoise(int voice_index){
1160 for (int i=0;i<SOUND_BUFFER_SIZE;i++)
1162 m_tmpwave[i] = zyn_random() * 2.0 - 1.0;
1167 * Compute the ADnote samples
1169 void
1170 ADnote::noteout(
1171 REALTYPE * outl,
1172 REALTYPE * outr)
1174 int i;
1175 unsigned int voice_index;
1176 float filter_adjust;
1178 silence_two_buffers(outl, outr, SOUND_BUFFER_SIZE);
1180 if (!m_note_enabled)
1182 return;
1185 silence_two_buffers(m_bypassl, m_bypassr, SOUND_BUFFER_SIZE);
1187 computecurrentparameters();
1189 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
1191 if (!m_voices_ptr[voice_index].enabled || m_voices_ptr[voice_index].DelayTicks > 0)
1193 continue;
1196 if (!m_voices_ptr[voice_index].white_noise) //voice mode = sound
1198 switch (m_voices_ptr[voice_index].fm_type)
1200 case ZYN_FM_TYPE_MORPH:
1201 ComputeVoiceOscillatorMorph(voice_index);
1202 break;
1203 case ZYN_FM_TYPE_RING_MOD:
1204 ComputeVoiceOscillatorRingModulation(voice_index);
1205 break;
1206 case ZYN_FM_TYPE_PHASE_MOD:
1207 ComputeVoiceOscillatorFrequencyModulation(voice_index,0);
1208 break;
1209 case ZYN_FM_TYPE_FREQ_MOD:
1210 ComputeVoiceOscillatorFrequencyModulation(voice_index,1);
1211 break;
1212 #if 0
1213 case ZYN_FM_TYPE_PITCH_MOD:
1214 ComputeVoiceOscillatorPitchModulation(voice_index);
1215 break;
1216 #endif
1217 default:
1218 ComputeVoiceOscillator_LinearInterpolation(voice_index);
1219 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(voice_index);
1222 else
1224 ComputeVoiceNoise(voice_index);
1227 // Voice Processing
1229 // Amplitude
1230 if (ABOVE_AMPLITUDE_THRESHOLD(m_old_amplitude_ptr[voice_index],m_new_amplitude_ptr[voice_index])){
1231 int rest=SOUND_BUFFER_SIZE;
1232 //test if the amplitude if raising and the difference is high
1233 if ((m_new_amplitude_ptr[voice_index]>m_old_amplitude_ptr[voice_index])&&((m_new_amplitude_ptr[voice_index]-m_old_amplitude_ptr[voice_index])>0.25)){
1234 rest=10;
1235 if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE;
1236 for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) m_tmpwave[i]*=m_old_amplitude_ptr[voice_index];
1238 // Amplitude interpolation
1239 for (i=0;i<rest;i++){
1240 m_tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(m_old_amplitude_ptr[voice_index]
1241 ,m_new_amplitude_ptr[voice_index],i,rest);
1243 } else for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]*=m_new_amplitude_ptr[voice_index];
1245 // Fade in
1246 if (m_first_tick_ptr[voice_index])
1248 fadein(&m_tmpwave[0]);
1249 m_first_tick_ptr[voice_index] = false;
1252 // Filter
1253 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
1255 m_voices_ptr[voice_index].m_voice_filter.filterout(&m_tmpwave[0]);
1258 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1259 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1261 if (m_voices_ptr[voice_index].m_amplitude_envelope.finished())
1263 for (i=0 ; i < SOUND_BUFFER_SIZE ; i++)
1265 m_tmpwave[i] *= 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1269 // the voice is killed later
1273 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1274 if (m_voices_ptr[voice_index].VoiceOut!=NULL)
1276 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1278 m_voices_ptr[voice_index].VoiceOut[i] = m_tmpwave[i];
1282 // Add the voice that do not bypass the filter to out
1283 if (m_voices_ptr[voice_index].filterbypass==0)
1285 // no bypass
1287 if (m_stereo)
1289 // stereo
1290 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1292 outl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*m_voices_ptr[voice_index].Panning*2.0;
1293 outr[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*(1.0-m_voices_ptr[voice_index].Panning)*2.0;
1296 else
1298 // mono
1299 for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume;
1302 else
1304 // bypass the filter
1306 if (m_stereo)
1308 // stereo
1309 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1311 m_bypassl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*m_voices_ptr[voice_index].Panning*2.0;
1312 m_bypassr[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*(1.0-m_voices_ptr[voice_index].Panning)*2.0;
1315 else
1317 // mono
1318 for (i=0;i<SOUND_BUFFER_SIZE;i++) m_bypassl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume;
1321 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1322 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1324 if (m_voices_ptr[voice_index].m_amplitude_envelope.finished())
1326 KillVoice(voice_index);
1331 // Processing Global parameters
1333 if (m_filter_category == ZYN_FILTER_TYPE_STATE_VARIABLE)
1335 filter_adjust = m_filter_envelope.envout() + m_filter_lfo.lfoout();
1337 zyn_filter_sv_process(m_filter_sv_processor_left, filter_adjust, outl);
1339 if (m_stereo)
1341 zyn_filter_sv_process(m_filter_sv_processor_right, filter_adjust, outr);
1344 else
1346 m_filter_left.filterout(&outl[0]);
1348 if (m_stereo)
1350 m_filter_right.filterout(&outr[0]);
1354 if (!m_stereo)
1356 // set the right channel=left channel
1357 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1359 outr[i]=outl[i];
1360 m_bypassr[i]=m_bypassl[i];
1364 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1366 // outl[i]+=m_bypassl[i];
1367 // outr[i]+=m_bypassr[i];
1370 if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude))
1372 // Amplitude Interpolation
1373 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1375 REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude, globalnewamplitude, i, SOUND_BUFFER_SIZE);
1376 outl[i] *= tmpvol * (1.0 - m_panning);
1377 outr[i] *= tmpvol * m_panning;
1380 else
1382 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1384 outl[i] *= globalnewamplitude * (1.0 - m_panning);
1385 outr[i] *= globalnewamplitude * m_panning;
1389 // Apply the punch
1390 if (m_punch_enabled)
1392 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1394 REALTYPE punchamp = m_punch_initial_value * m_punch_t + 1.0;
1395 outl[i] *= punchamp;
1396 outr[i] *= punchamp;
1397 m_punch_t -= m_punch_duration;
1398 if (m_punch_t < 0.0)
1400 m_punch_enabled = false;
1401 break;
1406 // Check if the global amplitude is finished.
1407 // If it does, disable the note
1408 if (m_amplitude_envelope.finished())
1410 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1412 // fade-out
1414 REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1416 outl[i] *= tmp;
1417 outr[i] *= tmp;
1420 force_disable();
1425 * Relase the key (NoteOff)
1427 void ADnote::relasekey()
1429 unsigned int voice_index;
1431 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
1433 if (!m_voices_ptr[voice_index].enabled)
1435 continue;
1438 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1440 m_voices_ptr[voice_index].m_amplitude_envelope.relasekey();
1443 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled)
1445 m_voices_ptr[voice_index].m_frequency_envelope.relasekey();
1448 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled)
1450 m_voices_ptr[voice_index].m_filter_envelope.relasekey();
1453 if (m_synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled)
1455 m_voices_ptr[voice_index].m_fm_frequency_envelope.relasekey();
1458 if (m_synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled)
1460 m_voices_ptr[voice_index].m_fm_amplitude_envelope.relasekey();
1464 m_frequency_envelope.relasekey();
1465 m_filter_envelope.relasekey();
1466 m_amplitude_envelope.relasekey();
1470 * Check if the note is finished
1472 bool
1473 ADnote::finished()
1475 return !m_note_enabled;