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
28 #include "resonance.h"
30 #include "oscillator.h"
31 #include "resonance.h"
32 #include "envelope_parameters.h"
33 #include "lfo_parameters.h"
34 #include "filter_parameters.h"
36 #include "filter_base.h"
37 #include "analog_filter.h"
38 #include "sv_filter.h"
39 #include "formant_filter.h"
43 #include "portamento.h"
44 #include "addsynth_internal.h"
45 #include "addsynth_voice.h"
48 #define LOG_LEVEL LOG_LEVEL_ERROR
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
;
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
=
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
))
112 bool random_grouping
,
118 unsigned int voice_index
;
120 float filter_velocity_adjust
;
121 int voice_oscillator_index
;
124 m_portamento
= portamento
;
125 m_midinote
= midinote
;
126 m_note_enabled
= true;
135 m_velocity
= velocity
;
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
);
152 zyn_filter_sv_processor_init(m_filter_sv_processor_right
, freq
, filter_velocity_adjust
);
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
);
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
,
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)
207 m_voices_ptr
[voice_index
].Detune
=
209 m_synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
,
210 m_synth_ptr
->voices_params_ptr
[voice_index
].PCoarseDetune
,
214 m_voices_ptr
[voice_index
].FineDetune
=
216 m_synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
,
218 m_synth_ptr
->voices_params_ptr
[voice_index
].PDetune
);
223 m_voices_ptr
[voice_index
].Detune
= getdetune(
224 m_synth_ptr
->GlobalPar
.PDetuneType
,
225 m_synth_ptr
->voices_params_ptr
[voice_index
].PCoarseDetune
,
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
=
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
);
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
;
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
,
276 m_osc_pos_hi_ptr
[voice_index
] =
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;
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;
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
;
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
);
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
,
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
,
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
);
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
);
368 m_synth_ptr
->sample_rate
,
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
)
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
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
;
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
);
515 if (!random_grouping
)
517 zyn_oscillator_new_rand_seed(
518 &m_synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
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
,
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
,
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
,
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;
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
);
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;
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
);
663 * Computes the frequency of an oscillator
665 void ADnote::setfreq(int nvoice
,REALTYPE freq
)
671 speed
= freq
* REALTYPE(OSCIL_SIZE
) / m_synth_ptr
->sample_rate
;
672 if (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
)
691 speed
= freq
* REALTYPE(OSCIL_SIZE
) / m_synth_ptr
->sample_rate
;
692 if (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
)
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);
718 // the fixed freq is enabled
719 REALTYPE fixedfreq
= 440.0;
720 int fixedfreqET
= m_voices_ptr
[nvoice
].fixedfreqET
;
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
);
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
751 ADnote::computecurrentparameters()
753 unsigned int voice_index
;
759 float FMrelativepitch
;
761 float temp_filter_frequency
;
764 0.01 * (m_frequency_envelope
.envout() +
765 m_frequency_lfo
.lfoout() * m_synth_ptr
->modwheel_relmod
);
767 globaloldamplitude
= globalnewamplitude
;
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
);
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;
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
)
807 m_voices_ptr
[voice_index
].DelayTicks
-= 1;
809 if (m_voices_ptr
[voice_index
].DelayTicks
> 0)
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();
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 /*******************/
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
);
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
){
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;
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;
925 * Computes the Oscillator (Without Modulation) - LinearInterpolation
927 inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int voice_index
){
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
];
941 poshi
+=m_osc_freq_hi_ptr
[voice_index
];
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){
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++){
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;
972 //m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
973 poslo+=m_osc_freq_lo_ptr[voice_index];
978 poshi+=m_osc_freq_hi_ptr[voice_index];
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
){
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
];
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
];
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
){
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
];
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
1054 posloFM
+=m_osc_freq_lo_FM_ptr
[voice_index
];
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
){
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
];
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
];
1090 posloFM
=fmod(posloFM
,1.0);
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
++;
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) {
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
){
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
1175 unsigned int voice_index
;
1176 float filter_adjust
;
1178 silence_two_buffers(outl
, outr
, SOUND_BUFFER_SIZE
);
1180 if (!m_note_enabled
)
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)
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
);
1203 case ZYN_FM_TYPE_RING_MOD
:
1204 ComputeVoiceOscillatorRingModulation(voice_index
);
1206 case ZYN_FM_TYPE_PHASE_MOD
:
1207 ComputeVoiceOscillatorFrequencyModulation(voice_index
,0);
1209 case ZYN_FM_TYPE_FREQ_MOD
:
1210 ComputeVoiceOscillatorFrequencyModulation(voice_index
,1);
1213 case ZYN_FM_TYPE_PITCH_MOD
:
1214 ComputeVoiceOscillatorPitchModulation(voice_index
);
1218 ComputeVoiceOscillator_LinearInterpolation(voice_index
);
1219 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(voice_index);
1224 ComputeVoiceNoise(voice_index
);
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)){
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
];
1246 if (m_first_tick_ptr
[voice_index
])
1248 fadein(&m_tmpwave
[0]);
1249 m_first_tick_ptr
[voice_index
] = false;
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)
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;
1299 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) outl
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
;
1304 // bypass the filter
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;
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
);
1341 zyn_filter_sv_process(m_filter_sv_processor_right
, filter_adjust
, outr
);
1346 m_filter_left
.filterout(&outl
[0]);
1350 m_filter_right
.filterout(&outr
[0]);
1356 // set the right channel=left channel
1357 for (i
=0;i
<SOUND_BUFFER_SIZE
;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
;
1382 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1384 outl
[i
] *= globalnewamplitude
* (1.0 - m_panning
);
1385 outr
[i
] *= globalnewamplitude
* m_panning
;
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;
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
++)
1414 REALTYPE tmp
= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
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
)
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
1475 return !m_note_enabled
;