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 int tmp
[m_synth_ptr
->voices_count
];
121 float filter_velocity_adjust
;
123 m_portamento
= portamento
;
124 m_midinote
= midinote
;
125 m_note_enabled
= true;
134 m_velocity
= velocity
;
139 m_panning
= (panorama
+ 1.0) / 2; // -1..1 -> 0 - 1
141 m_filter_category
= m_synth_ptr
->filter_type
;
143 if (m_filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
145 filter_velocity_adjust
= m_synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
146 (zyn_velocity_scale(m_velocity
, m_synth_ptr
->m_filter_velocity_scale_function
) - 1);
148 zyn_filter_sv_processor_init(m_filter_sv_processor_left
, freq
, filter_velocity_adjust
);
151 zyn_filter_sv_processor_init(m_filter_sv_processor_right
, freq
, filter_velocity_adjust
);
156 m_filter_center_pitch
=
157 m_synth_ptr
->m_filter_params
.getfreq() + // center freq
158 m_synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
159 (zyn_velocity_scale(m_velocity
, m_synth_ptr
->m_filter_velocity_scale_function
) - 1);
160 m_filter_center_pitch
+= m_synth_ptr
->m_filter_params
.getfreqtracking(m_basefreq
);
163 if (m_synth_ptr
->GlobalPar
.PPunchStrength
!= 0)
165 m_punch_enabled
= true;
166 m_punch_t
= 1.0; //start from 1.0 and to 0.0
167 m_punch_initial_value
=
168 ( (pow(10,1.5*m_synth_ptr
->GlobalPar
.PPunchStrength
/127.0)-1.0)
169 *VelF(m_velocity
,m_synth_ptr
->GlobalPar
.PPunchVelocitySensing
) );
170 REALTYPE time
= pow(10,3.0*m_synth_ptr
->GlobalPar
.PPunchTime
/127.0)/10000.0; //0.1 .. 100 ms
171 REALTYPE stretch
= pow(440.0/freq
,m_synth_ptr
->GlobalPar
.PPunchStretch
/64.0);
172 m_punch_duration
= 1.0 / (time
* m_synth_ptr
->sample_rate
* stretch
);
176 m_punch_enabled
= false;
179 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
181 zyn_oscillator_new_rand_seed(
182 &m_synth_ptr
->voices_params_ptr
[voice_index
].oscillator
,
184 m_voices_ptr
[voice_index
].OscilSmp
=NULL
;
185 m_voices_ptr
[voice_index
].FMSmp
=NULL
;
186 m_voices_ptr
[voice_index
].VoiceOut
=NULL
;
188 m_voices_ptr
[voice_index
].FMVoice
=-1;
190 if (!m_synth_ptr
->voices_params_ptr
[voice_index
].enabled
)
192 m_voices_ptr
[voice_index
].enabled
= false;
193 continue; //the voice is disabled
196 m_voices_ptr
[voice_index
].enabled
= true;
197 m_voices_ptr
[voice_index
].fixedfreq
= m_synth_ptr
->voices_params_ptr
[voice_index
].Pfixedfreq
;
198 m_voices_ptr
[voice_index
].fixedfreqET
= m_synth_ptr
->voices_params_ptr
[voice_index
].PfixedfreqET
;
200 // use the Globalpars.detunetype if the detunetype is 0
201 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
!= 0)
204 m_voices_ptr
[voice_index
].Detune
=
206 m_synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
,
207 m_synth_ptr
->voices_params_ptr
[voice_index
].PCoarseDetune
,
211 m_voices_ptr
[voice_index
].FineDetune
=
213 m_synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
,
215 m_synth_ptr
->voices_params_ptr
[voice_index
].PDetune
);
219 m_voices_ptr
[voice_index
].Detune
=getdetune(m_synth_ptr
->GlobalPar
.PDetuneType
220 ,m_synth_ptr
->voices_params_ptr
[voice_index
].PCoarseDetune
,8192);//coarse detune
221 m_voices_ptr
[voice_index
].FineDetune
=getdetune(m_synth_ptr
->GlobalPar
.PDetuneType
222 ,0,m_synth_ptr
->voices_params_ptr
[voice_index
].PDetune
);//fine detune
225 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMDetuneType
!=0)
227 m_voices_ptr
[voice_index
].FMDetune
=
229 m_synth_ptr
->voices_params_ptr
[voice_index
].PFMDetuneType
,
230 m_synth_ptr
->voices_params_ptr
[voice_index
].PFMCoarseDetune
,
231 m_synth_ptr
->voices_params_ptr
[voice_index
].PFMDetune
);
235 m_voices_ptr
[voice_index
].FMDetune
= getdetune(
236 m_synth_ptr
->GlobalPar
.PDetuneType
,
237 m_synth_ptr
->voices_params_ptr
[voice_index
].PFMCoarseDetune
,
238 m_synth_ptr
->voices_params_ptr
[voice_index
].PFMDetune
);
241 m_osc_pos_hi_ptr
[voice_index
] = 0;
242 m_osc_pos_lo_ptr
[voice_index
] = 0.0;
243 m_osc_pos_hi_FM_ptr
[voice_index
] = 0;
244 m_osc_pos_lo_FM_ptr
[voice_index
] = 0.0;
246 m_voices_ptr
[voice_index
].OscilSmp
=new REALTYPE
[OSCIL_SIZE
+OSCIL_SMP_EXTRA_SAMPLES
];//the extra points contains the first point
248 //Get the voice's oscil or external's voice oscil
251 if (m_synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
!= -1)
253 vc
= m_synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
;
256 if (!random_grouping
)
258 zyn_oscillator_new_rand_seed(
259 &m_synth_ptr
->voices_params_ptr
[vc
].oscillator
,
263 m_osc_pos_hi_ptr
[voice_index
] =
265 &m_synth_ptr
->voices_params_ptr
[vc
].oscillator
,
266 m_voices_ptr
[voice_index
].OscilSmp
,
267 getvoicebasefreq(voice_index
),
268 m_synth_ptr
->voices_params_ptr
[voice_index
].resonance
);
270 //I store the first elments to the last position for speedups
271 for (i
=0;i
<OSCIL_SMP_EXTRA_SAMPLES
;i
++) m_voices_ptr
[voice_index
].OscilSmp
[OSCIL_SIZE
+i
]=m_voices_ptr
[voice_index
].OscilSmp
[i
];
273 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);
274 m_osc_pos_hi_ptr
[voice_index
] %= OSCIL_SIZE
;
276 m_voices_ptr
[voice_index
].FilterCenterPitch
=m_synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreq();
277 m_voices_ptr
[voice_index
].filterbypass
=m_synth_ptr
->voices_params_ptr
[voice_index
].Pfilterbypass
;
279 m_voices_ptr
[voice_index
].fm_type
= m_synth_ptr
->voices_params_ptr
[voice_index
].fm_type
;
281 m_voices_ptr
[voice_index
].FMVoice
=m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVoice
;
283 //Compute the Voice's modulator volume (incl. damping)
284 REALTYPE fmvoldamp
=pow(440.0/getvoicebasefreq(voice_index
),m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/64.0-1.0);
285 switch (m_voices_ptr
[voice_index
].fm_type
)
287 case ZYN_FM_TYPE_PHASE_MOD
:
288 fmvoldamp
= pow(440.0/getvoicebasefreq(voice_index
),m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/64.0);
289 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;
291 case ZYN_FM_TYPE_FREQ_MOD
:
292 m_voices_ptr
[voice_index
].FMVolume
= exp(m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * FM_AMP_MULTIPLIER
);
293 m_voices_ptr
[voice_index
].FMVolume
-= 1.0;
294 m_voices_ptr
[voice_index
].FMVolume
*= fmvoldamp
* 4.0;
297 case ZYN_FM_TYPE_PITCH_MOD
:
298 m_voices_ptr
[voice_index
].FMVolume
=(m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/127.0*8.0)*fmvoldamp
;
307 m_voices_ptr
[voice_index
].FMVolume
= m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * fmvoldamp
;
310 //Voice's modulator velocity sensing
311 m_voices_ptr
[voice_index
].FMVolume
*=VelF(m_velocity
,m_synth_ptr
->voices_params_ptr
[voice_index
].PFMVelocityScaleFunction
);
313 m_FM_old_smp_ptr
[voice_index
] = 0.0; // this is for FM (integration)
315 m_first_tick_ptr
[voice_index
] = true;
316 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
);
320 m_frequency_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->m_frequency_envelope_params
, m_basefreq
);
322 m_frequency_lfo
.init(
323 m_synth_ptr
->sample_rate
,
325 &m_synth_ptr
->frequency_lfo_params
,
326 ZYN_LFO_TYPE_FREQUENCY
);
328 m_amplitude_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->m_amplitude_envelope_params
, m_basefreq
);
330 m_amplitude_lfo
.init(
331 m_synth_ptr
->sample_rate
,
333 &m_synth_ptr
->amplitude_lfo_params
,
334 ZYN_LFO_TYPE_AMPLITUDE
);
336 m_volume
= 4.0*pow(0.1,3.0*(1.0-m_synth_ptr
->GlobalPar
.PVolume
/96.0))//-60 dB .. 0 dB
337 *VelF(m_velocity
,m_synth_ptr
->GlobalPar
.PAmpVelocityScaleFunction
);//velocity sensing
339 m_amplitude_envelope
.envout_dB(); // discard the first envelope output
341 globalnewamplitude
= m_volume
* m_amplitude_envelope
.envout_dB() * m_amplitude_lfo
.amplfoout();
343 m_filter_left
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->m_filter_params
);
346 m_filter_right
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->m_filter_params
);
349 m_filter_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->m_filter_envelope_params
, m_basefreq
);
352 m_synth_ptr
->sample_rate
,
354 &m_synth_ptr
->filter_lfo_params
,
355 ZYN_LFO_TYPE_FILTER
);
357 m_filter_q_factor
= m_synth_ptr
->m_filter_params
.getq();
359 // Forbids the Modulation Voice to be greater or equal than voice
360 for (i
= 0 ; i
< m_synth_ptr
->voices_count
; i
++)
362 if (m_voices_ptr
[i
].FMVoice
>= (int)i
)
364 m_voices_ptr
[i
].FMVoice
= -1;
368 // Voice Parameter init
369 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
371 if (!m_voices_ptr
[voice_index
].enabled
)
376 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
);
378 m_voices_ptr
[voice_index
].white_noise
= m_synth_ptr
->voices_params_ptr
[voice_index
].white_noise
;
379 /* Voice Amplitude Parameters Init */
380 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
381 *VelF(m_velocity
,m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpVelocityScaleFunction
);//velocity
383 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PVolumeminus
!=0) m_voices_ptr
[voice_index
].Volume
=-m_voices_ptr
[voice_index
].Volume
;
385 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PPanning
==0)
387 m_voices_ptr
[voice_index
].Panning
= zyn_random(); // random panning
391 m_voices_ptr
[voice_index
].Panning
= m_synth_ptr
->voices_params_ptr
[voice_index
].PPanning
/128.0;
394 m_new_amplitude_ptr
[voice_index
] = 1.0;
395 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
!= 0)
397 m_voices_ptr
[voice_index
].m_amplitude_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->voices_params_ptr
[voice_index
].m_amplitude_envelope_params
, m_basefreq
);
398 m_voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB(); // discard the first envelope sample
399 m_new_amplitude_ptr
[voice_index
] *= m_voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
402 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
!= 0)
404 m_voices_ptr
[voice_index
].m_amplitude_lfo
.init(
405 m_synth_ptr
->sample_rate
,
407 &m_synth_ptr
->voices_params_ptr
[voice_index
].amplitude_lfo_params
,
408 ZYN_LFO_TYPE_AMPLITUDE
);
410 m_new_amplitude_ptr
[voice_index
] *= m_voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
413 /* Voice Frequency Parameters Init */
414 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
!= 0)
416 m_voices_ptr
[voice_index
].m_frequency_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->voices_params_ptr
[voice_index
].m_frequency_envelope_params
, m_basefreq
);
419 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
!= 0)
421 m_voices_ptr
[voice_index
].m_frequency_lfo
.init(
422 m_synth_ptr
->sample_rate
,
424 &m_synth_ptr
->voices_params_ptr
[voice_index
].frequency_lfo_params
,
425 ZYN_LFO_TYPE_FREQUENCY
);
428 /* Voice Filter Parameters Init */
429 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
!= 0)
431 m_voices_ptr
[voice_index
].m_voice_filter
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
);
434 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
!= 0)
436 m_voices_ptr
[voice_index
].m_filter_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->voices_params_ptr
[voice_index
].m_filter_envelope_params
, m_basefreq
);
439 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
!= 0)
441 m_voices_ptr
[voice_index
].m_filter_lfo
.init(
442 m_synth_ptr
->sample_rate
,
444 &m_synth_ptr
->voices_params_ptr
[voice_index
].filter_lfo_params
,
445 ZYN_LFO_TYPE_FILTER
);
448 m_voices_ptr
[voice_index
].FilterFreqTracking
= m_synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreqtracking(m_basefreq
);
450 /* Voice Modulation Parameters Init */
451 if (m_voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
&& m_voices_ptr
[voice_index
].FMVoice
< 0)
453 zyn_oscillator_new_rand_seed(
454 &m_synth_ptr
->voices_params_ptr
[voice_index
].modulator_oscillator
,
457 m_voices_ptr
[voice_index
].FMSmp
= new zyn_sample_type
[OSCIL_SIZE
+ OSCIL_SMP_EXTRA_SAMPLES
];
459 //Perform Anti-aliasing only on MORPH or RING MODULATION
462 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
!=-1) vc
=m_synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
;
465 if ((m_synth_ptr
->voices_params_ptr
[vc
].modulator_oscillator
.Padaptiveharmonics
!= 0) ||
466 (m_voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_MORPH
) ||
467 (m_voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_RING_MOD
))
469 tmp
= getFMvoicebasefreq(voice_index
);
472 if (!random_grouping
)
474 zyn_oscillator_new_rand_seed(
475 &m_synth_ptr
->voices_params_ptr
[vc
].modulator_oscillator
,
479 m_osc_pos_hi_FM_ptr
[voice_index
] = m_osc_pos_hi_ptr
[voice_index
];
480 m_osc_pos_hi_FM_ptr
[voice_index
] += zyn_oscillator_get(
481 &m_synth_ptr
->voices_params_ptr
[vc
].modulator_oscillator
,
482 m_voices_ptr
[voice_index
].FMSmp
,
485 m_osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
487 for (int i
=0;i
<OSCIL_SMP_EXTRA_SAMPLES
;i
++) m_voices_ptr
[voice_index
].FMSmp
[OSCIL_SIZE
+i
]=m_voices_ptr
[voice_index
].FMSmp
[i
];
488 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);
489 m_osc_pos_hi_FM_ptr
[voice_index
]%=OSCIL_SIZE
;
492 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
!= 0)
494 m_voices_ptr
[voice_index
].m_fm_frequency_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->voices_params_ptr
[voice_index
].m_fm_frequency_envelope_params
, m_basefreq
);
497 m_FM_new_amplitude_ptr
[voice_index
] = m_voices_ptr
[voice_index
].FMVolume
;
498 //m_FM_new_amplitude_ptr[voice_index] *= m_ctl->fmamp.relamp; // 0..1
500 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
!= 0)
502 m_voices_ptr
[voice_index
].m_fm_amplitude_envelope
.init(m_synth_ptr
->sample_rate
, &m_synth_ptr
->voices_params_ptr
[voice_index
].m_fm_amplitude_envelope_params
, m_basefreq
);
503 m_FM_new_amplitude_ptr
[voice_index
] *= m_voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
507 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
509 for (i
= voice_index
+ 1 ; i
< m_synth_ptr
->voices_count
; i
++)
514 for (i
= voice_index
+ 1 ; i
< m_synth_ptr
->voices_count
; i
++)
516 if (m_voices_ptr
[i
].FMVoice
== (int)voice_index
&& tmp
[i
] == 0)
518 m_voices_ptr
[voice_index
].VoiceOut
= new REALTYPE
[SOUND_BUFFER_SIZE
];
523 if (m_voices_ptr
[voice_index
].VoiceOut
!= NULL
)
525 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
527 m_voices_ptr
[voice_index
].VoiceOut
[i
] = 0.0;
534 * Kill a voice of ADnote
536 void ADnote::KillVoice(unsigned int voice_index
)
539 delete [] (m_voices_ptr
[voice_index
].OscilSmp
);
541 if ((m_voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
) && (m_voices_ptr
[voice_index
].FMVoice
< 0))
543 delete m_voices_ptr
[voice_index
].FMSmp
;
546 if (m_voices_ptr
[voice_index
].VoiceOut
!= NULL
)
548 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
550 m_voices_ptr
[voice_index
].VoiceOut
[i
] = 0.0;//do not delete, yet: perhaps is used by another voice
554 m_voices_ptr
[voice_index
].enabled
= false;
561 ADnote::force_disable()
563 unsigned int voice_index
;
565 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
567 if (m_voices_ptr
[voice_index
].enabled
)
569 KillVoice(voice_index
);
573 if (m_voices_ptr
[voice_index
].VoiceOut
!= NULL
)
575 delete(m_voices_ptr
[voice_index
].VoiceOut
);
576 m_voices_ptr
[voice_index
].VoiceOut
= NULL
;
580 m_note_enabled
= false;
590 zyn_filter_sv_processor_destroy(m_filter_sv_processor_left
);
591 zyn_filter_sv_processor_destroy(m_filter_sv_processor_right
);
593 free(m_old_amplitude_ptr
);
594 free(m_new_amplitude_ptr
);
596 free(m_FM_old_amplitude_ptr
);
597 free(m_FM_new_amplitude_ptr
);
599 free(m_first_tick_ptr
);
601 free(m_FM_old_smp_ptr
);
603 free(m_osc_freq_hi_ptr
);
604 free(m_osc_freq_lo_ptr
);
605 free(m_osc_freq_hi_FM_ptr
);
606 free(m_osc_freq_lo_FM_ptr
);
608 free(m_osc_pos_hi_ptr
);
609 free(m_osc_pos_lo_ptr
);
610 free(m_osc_pos_hi_FM_ptr
);
611 free(m_osc_pos_lo_FM_ptr
);
621 * Computes the frequency of an oscillator
623 void ADnote::setfreq(int nvoice
,REALTYPE freq
)
629 speed
= freq
* REALTYPE(OSCIL_SIZE
) / m_synth_ptr
->sample_rate
;
630 if (speed
> OSCIL_SIZE
)
635 F2I(speed
, m_osc_freq_hi_ptr
[nvoice
]);
637 m_osc_freq_lo_ptr
[nvoice
] = speed
- floor(speed
);
641 * Computes the frequency of an modullator oscillator
643 void ADnote::setfreqFM(int nvoice
,REALTYPE freq
)
649 speed
= freq
* REALTYPE(OSCIL_SIZE
) / m_synth_ptr
->sample_rate
;
650 if (speed
> OSCIL_SIZE
)
655 F2I(speed
, m_osc_freq_hi_FM_ptr
[nvoice
]);
656 m_osc_freq_lo_FM_ptr
[nvoice
] = speed
- floor(speed
);
660 * Get Voice base frequency
662 REALTYPE
ADnote::getvoicebasefreq(int nvoice
)
666 detune
= m_voices_ptr
[nvoice
].Detune
/ 100.0;
667 detune
+= m_voices_ptr
[nvoice
].FineDetune
/ 100.0 * m_synth_ptr
->bandwidth_relbw
* m_bandwidth_detune_multiplier
;
668 detune
+= m_detune
/ 100.0;
670 if (m_voices_ptr
[nvoice
].fixedfreq
== 0)
672 return m_basefreq
* pow(2, detune
/ 12.0);
676 // the fixed freq is enabled
677 REALTYPE fixedfreq
= 440.0;
678 int fixedfreqET
= m_voices_ptr
[nvoice
].fixedfreqET
;
681 // if the frequency varies according the keyboard note
682 REALTYPE tmp
= (m_midinote
- 69.0) / 12.0 * (pow(2.0,(fixedfreqET
-1)/63.0) - 1.0);
683 if (fixedfreqET
<= 64)
685 fixedfreq
*= pow(2.0,tmp
);
689 fixedfreq
*= pow(3.0,tmp
);
693 return fixedfreq
* pow(2.0, detune
/ 12.0);
698 * Get Voice's Modullator base frequency
700 REALTYPE
ADnote::getFMvoicebasefreq(int nvoice
){
701 REALTYPE detune
=m_voices_ptr
[nvoice
].FMDetune
/100.0;
702 return(getvoicebasefreq(nvoice
)*pow(2,detune
/12.0));
706 * Computes all the parameters for each tick
709 ADnote::computecurrentparameters()
711 unsigned int voice_index
;
717 float FMrelativepitch
;
719 float temp_filter_frequency
;
722 0.01 * (m_frequency_envelope
.envout() +
723 m_frequency_lfo
.lfoout() * m_synth_ptr
->modwheel_relmod
);
725 globaloldamplitude
= globalnewamplitude
;
729 m_amplitude_envelope
.envout_dB() *
730 m_amplitude_lfo
.amplfoout();
732 if (m_filter_category
!= ZYN_FILTER_TYPE_STATE_VARIABLE
)
734 temp_filter_frequency
= m_filter_left
.getrealfreq(m_filter_center_pitch
+ m_filter_envelope
.envout() + m_filter_lfo
.lfoout());
736 m_filter_left
.setfreq_and_q(temp_filter_frequency
, m_filter_q_factor
);
739 m_filter_right
.setfreq_and_q(temp_filter_frequency
, m_filter_q_factor
);
743 // compute the portamento, if it is used by this note
744 REALTYPE portamentofreqrap
=1.0;
747 // this voice use portamento
748 portamentofreqrap
= m_synth_ptr
->portamento
.freqrap
;
750 if (!m_synth_ptr
->portamento
.used
)
752 // the portamento has finished
753 m_portamento
= false; // this note is no longer "portamented"
757 //compute parameters for all voices
758 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
760 if (!m_voices_ptr
[voice_index
].enabled
)
765 m_voices_ptr
[voice_index
].DelayTicks
-= 1;
767 if (m_voices_ptr
[voice_index
].DelayTicks
> 0)
772 /*******************/
773 /* Voice Amplitude */
774 /*******************/
775 m_old_amplitude_ptr
[voice_index
] = m_new_amplitude_ptr
[voice_index
];
776 m_new_amplitude_ptr
[voice_index
] = 1.0;
778 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
780 m_new_amplitude_ptr
[voice_index
] *= m_voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
783 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
)
785 m_new_amplitude_ptr
[voice_index
] *= m_voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
791 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
793 filterpitch
= m_voices_ptr
[voice_index
].FilterCenterPitch
;
795 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
797 filterpitch
+= m_voices_ptr
[voice_index
].m_filter_envelope
.envout();
800 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
)
802 filterpitch
+= m_voices_ptr
[voice_index
].m_filter_lfo
.lfoout();
805 filterfreq
= filterpitch
+ m_voices_ptr
[voice_index
].FilterFreqTracking
;
806 filterfreq
= m_voices_ptr
[voice_index
].m_voice_filter
.getrealfreq(filterfreq
);
808 m_voices_ptr
[voice_index
].m_voice_filter
.setfreq(filterfreq
);
811 // compute only if the voice isn't noise
812 if (!m_voices_ptr
[voice_index
].white_noise
)
814 /*******************/
815 /* Voice Frequency */
816 /*******************/
818 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
)
820 voicepitch
+= m_voices_ptr
[voice_index
].m_frequency_lfo
.lfoout() / 100.0 * m_synth_ptr
->bandwidth_relbw
;
823 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
825 voicepitch
+= m_voices_ptr
[voice_index
].m_frequency_envelope
.envout() / 100.0;
828 voicefreq
= getvoicebasefreq(voice_index
) * pow(2, (voicepitch
+ globalpitch
) / 12.0); // Hz frequency
829 voicefreq
*= m_synth_ptr
->pitch_bend_relative_frequency
; // change the frequency by the controller
830 setfreq(voice_index
, voicefreq
* portamentofreqrap
);
835 if (m_voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
)
837 FMrelativepitch
= m_voices_ptr
[voice_index
].FMDetune
/ 100.0;
838 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
840 FMrelativepitch
+= m_voices_ptr
[voice_index
].m_fm_frequency_envelope
.envout() / 100;
843 FMfreq
= pow(2.0, FMrelativepitch
/ 12.0) * voicefreq
* portamentofreqrap
;
844 setfreqFM(voice_index
, FMfreq
);
846 m_FM_old_amplitude_ptr
[voice_index
] = m_FM_new_amplitude_ptr
[voice_index
];
847 m_FM_new_amplitude_ptr
[voice_index
] = m_voices_ptr
[voice_index
].FMVolume
;
848 //m_FM_new_amplitude_ptr[voice_index] *= m_ctl->fmamp.relamp; // 0..1
850 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
852 m_FM_new_amplitude_ptr
[voice_index
] *= m_voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
858 m_time
+= (REALTYPE
)SOUND_BUFFER_SIZE
/ m_synth_ptr
->sample_rate
;
863 * Fadein in a way that removes clicks but keep sound "punchy"
865 inline void ADnote::fadein(REALTYPE
*smps
){
867 for (int i
=1;i
<SOUND_BUFFER_SIZE
;i
++)
868 if ((smps
[i
-1]<0.0) && (smps
[i
]>0.0)) zerocrossings
++;//this is only the possitive crossings
870 REALTYPE tmp
=(SOUND_BUFFER_SIZE
-1.0)/(zerocrossings
+1)/3.0;
871 if (tmp
<8.0) tmp
=8.0;
874 F2I(tmp
,n
);//how many samples is the fade-in
875 if (n
>SOUND_BUFFER_SIZE
) n
=SOUND_BUFFER_SIZE
;
876 for (int i
=0;i
<n
;i
++) {//fade-in
877 REALTYPE tmp
=0.5-cos((REALTYPE
)i
/(REALTYPE
) n
*PI
)*0.5;
883 * Computes the Oscillator (Without Modulation) - LinearInterpolation
885 inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int voice_index
){
889 poshi
=m_osc_pos_hi_ptr
[voice_index
];
890 poslo
=m_osc_pos_lo_ptr
[voice_index
];
891 REALTYPE
*smps
=m_voices_ptr
[voice_index
].OscilSmp
;
892 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
893 m_tmpwave
[i
]=smps
[poshi
]*(1.0-poslo
)+smps
[poshi
+1]*poslo
;
894 poslo
+=m_osc_freq_lo_ptr
[voice_index
];
899 poshi
+=m_osc_freq_hi_ptr
[voice_index
];
902 m_osc_pos_hi_ptr
[voice_index
]=poshi
;
903 m_osc_pos_lo_ptr
[voice_index
]=poslo
;
909 * Computes the Oscillator (Without Modulation) - CubicInterpolation
911 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
912 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
916 poshi=m_osc_pos_hi_ptr[voice_index];
917 poslo=m_osc_pos_lo_ptr[voice_index];
918 REALTYPE *smps=m_voices_ptr[voice_index].OscilSmp;
919 REALTYPE xm1,x0,x1,x2,a,b,c;
920 for (i=0;i<SOUND_BUFFER_SIZE;i++){
925 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
926 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
927 c = (x1 - xm1) / 2.0;
928 m_tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
930 //m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
931 poslo+=m_osc_freq_lo_ptr[voice_index];
936 poshi+=m_osc_freq_hi_ptr[voice_index];
939 m_osc_pos_hi_ptr[voice_index]=poshi;
940 m_osc_pos_lo_ptr[voice_index]=poslo;
944 * Computes the Oscillator (Morphing)
946 inline void ADnote::ComputeVoiceOscillatorMorph(int voice_index
){
949 ComputeVoiceOscillator_LinearInterpolation(voice_index
);
950 if (m_FM_new_amplitude_ptr
[voice_index
]>1.0) m_FM_new_amplitude_ptr
[voice_index
]=1.0;
951 if (m_FM_old_amplitude_ptr
[voice_index
]>1.0) m_FM_old_amplitude_ptr
[voice_index
]=1.0;
953 if (m_voices_ptr
[voice_index
].FMVoice
>=0){
954 //if I use VoiceOut[] as modullator
955 int FMVoice
=m_voices_ptr
[voice_index
].FMVoice
;
956 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) {
957 amp
=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr
[voice_index
]
958 ,m_FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
959 m_tmpwave
[i
]=m_tmpwave
[i
]*(1.0-amp
)+amp
*m_voices_ptr
[FMVoice
].VoiceOut
[i
];
962 int poshiFM
=m_osc_pos_hi_FM_ptr
[voice_index
];
963 REALTYPE posloFM
=m_osc_pos_lo_FM_ptr
[voice_index
];
965 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
966 amp
=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr
[voice_index
]
967 ,m_FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
968 m_tmpwave
[i
]=m_tmpwave
[i
]*(1.0-amp
)+amp
969 *(m_voices_ptr
[voice_index
].FMSmp
[poshiFM
]*(1-posloFM
)
970 +m_voices_ptr
[voice_index
].FMSmp
[poshiFM
+1]*posloFM
);
971 posloFM
+=m_osc_freq_lo_FM_ptr
[voice_index
];
976 poshiFM
+=m_osc_freq_hi_FM_ptr
[voice_index
];
977 poshiFM
&=OSCIL_SIZE
-1;
979 m_osc_pos_hi_FM_ptr
[voice_index
]=poshiFM
;
980 m_osc_pos_lo_FM_ptr
[voice_index
]=posloFM
;
985 * Computes the Oscillator (Ring Modulation)
987 inline void ADnote::ComputeVoiceOscillatorRingModulation(int voice_index
){
990 ComputeVoiceOscillator_LinearInterpolation(voice_index
);
991 if (m_FM_new_amplitude_ptr
[voice_index
]>1.0) m_FM_new_amplitude_ptr
[voice_index
]=1.0;
992 if (m_FM_old_amplitude_ptr
[voice_index
]>1.0) m_FM_old_amplitude_ptr
[voice_index
]=1.0;
993 if (m_voices_ptr
[voice_index
].FMVoice
>=0){
994 // if I use VoiceOut[] as modullator
995 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) {
996 amp
=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr
[voice_index
]
997 ,m_FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
998 int FMVoice
=m_voices_ptr
[voice_index
].FMVoice
;
999 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1000 m_tmpwave
[i
]*=(1.0-amp
)+amp
*m_voices_ptr
[FMVoice
].VoiceOut
[i
];
1003 int poshiFM
=m_osc_pos_hi_FM_ptr
[voice_index
];
1004 REALTYPE posloFM
=m_osc_pos_lo_FM_ptr
[voice_index
];
1006 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
1007 amp
=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr
[voice_index
]
1008 ,m_FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
1009 m_tmpwave
[i
]*=( m_voices_ptr
[voice_index
].FMSmp
[poshiFM
]*(1.0-posloFM
)
1010 +m_voices_ptr
[voice_index
].FMSmp
[poshiFM
+1]*posloFM
)*amp
1012 posloFM
+=m_osc_freq_lo_FM_ptr
[voice_index
];
1017 poshiFM
+=m_osc_freq_hi_FM_ptr
[voice_index
];
1018 poshiFM
&=OSCIL_SIZE
-1;
1020 m_osc_pos_hi_FM_ptr
[voice_index
]=poshiFM
;
1021 m_osc_pos_lo_FM_ptr
[voice_index
]=posloFM
;
1028 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
1030 inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int voice_index
,int FMmode
){
1033 REALTYPE FMmodfreqlo
,carposlo
;
1035 if (m_voices_ptr
[voice_index
].FMVoice
>=0){
1036 //if I use VoiceOut[] as modulator
1037 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) m_tmpwave
[i
]=m_voices_ptr
[m_voices_ptr
[voice_index
].FMVoice
].VoiceOut
[i
];
1039 //Compute the modulator and store it in m_tmpwave[]
1040 int poshiFM
=m_osc_pos_hi_FM_ptr
[voice_index
];
1041 REALTYPE posloFM
=m_osc_pos_lo_FM_ptr
[voice_index
];
1043 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
1044 m_tmpwave
[i
]=(m_voices_ptr
[voice_index
].FMSmp
[poshiFM
]*(1.0-posloFM
)
1045 +m_voices_ptr
[voice_index
].FMSmp
[poshiFM
+1]*posloFM
);
1046 posloFM
+=m_osc_freq_lo_FM_ptr
[voice_index
];
1048 posloFM
=fmod(posloFM
,1.0);
1051 poshiFM
+=m_osc_freq_hi_FM_ptr
[voice_index
];
1052 poshiFM
&=OSCIL_SIZE
-1;
1054 m_osc_pos_hi_FM_ptr
[voice_index
]=poshiFM
;
1055 m_osc_pos_lo_FM_ptr
[voice_index
]=posloFM
;
1057 // Amplitude interpolation
1058 if (ABOVE_AMPLITUDE_THRESHOLD(m_FM_old_amplitude_ptr
[voice_index
],m_FM_new_amplitude_ptr
[voice_index
])){
1059 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
1060 m_tmpwave
[i
]*=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr
[voice_index
]
1061 ,m_FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
1063 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) m_tmpwave
[i
]*=m_FM_new_amplitude_ptr
[voice_index
];
1066 //normalize makes all sample-rates, oscil_sizes toproduce same sound
1067 if (FMmode
!=0){//Frequency modulation
1068 REALTYPE normalize
= OSCIL_SIZE
/ 262144.0 * 44100.0 / m_synth_ptr
->sample_rate
;
1069 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
1070 m_FM_old_smp_ptr
[voice_index
]=fmod(m_FM_old_smp_ptr
[voice_index
]+m_tmpwave
[i
]*normalize
,OSCIL_SIZE
);
1071 m_tmpwave
[i
]=m_FM_old_smp_ptr
[voice_index
];
1073 } else {//Phase modulation
1074 REALTYPE normalize
=OSCIL_SIZE
/262144.0;
1075 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) m_tmpwave
[i
]*=normalize
;
1078 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
1079 F2I(m_tmpwave
[i
],FMmodfreqhi
);
1080 FMmodfreqlo
=fmod(m_tmpwave
[i
]+0.0000000001,1.0);
1081 if (FMmodfreqhi
<0) FMmodfreqlo
++;
1084 carposhi
=m_osc_pos_hi_ptr
[voice_index
]+FMmodfreqhi
;
1085 carposlo
=m_osc_pos_lo_ptr
[voice_index
]+FMmodfreqlo
;
1087 if (carposlo
>=1.0) {
1089 carposlo
=fmod(carposlo
,1.0);
1091 carposhi
&=(OSCIL_SIZE
-1);
1093 m_tmpwave
[i
]=m_voices_ptr
[voice_index
].OscilSmp
[carposhi
]*(1.0-carposlo
)
1094 +m_voices_ptr
[voice_index
].OscilSmp
[carposhi
+1]*carposlo
;
1096 m_osc_pos_lo_ptr
[voice_index
]+=m_osc_freq_lo_ptr
[voice_index
];
1097 if (m_osc_pos_lo_ptr
[voice_index
]>=1.0) {
1098 m_osc_pos_lo_ptr
[voice_index
]=fmod(m_osc_pos_lo_ptr
[voice_index
],1.0);
1099 m_osc_pos_hi_ptr
[voice_index
]++;
1102 m_osc_pos_hi_ptr
[voice_index
]+=m_osc_freq_hi_ptr
[voice_index
];
1103 m_osc_pos_hi_ptr
[voice_index
]&=OSCIL_SIZE
-1;
1108 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
1109 inline void ADnote::ComputeVoiceOscillatorPitchModulation(int voice_index
){
1114 * Computes the Noise
1116 inline void ADnote::ComputeVoiceNoise(int voice_index
){
1118 for (int i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1120 m_tmpwave
[i
] = zyn_random() * 2.0 - 1.0;
1125 * Compute the ADnote samples
1133 unsigned int voice_index
;
1134 float filter_adjust
;
1136 silence_two_buffers(outl
, outr
, SOUND_BUFFER_SIZE
);
1138 if (!m_note_enabled
)
1143 silence_two_buffers(m_bypassl
, m_bypassr
, SOUND_BUFFER_SIZE
);
1145 computecurrentparameters();
1147 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
1149 if (!m_voices_ptr
[voice_index
].enabled
|| m_voices_ptr
[voice_index
].DelayTicks
> 0)
1154 if (!m_voices_ptr
[voice_index
].white_noise
) //voice mode = sound
1156 switch (m_voices_ptr
[voice_index
].fm_type
)
1158 case ZYN_FM_TYPE_MORPH
:
1159 ComputeVoiceOscillatorMorph(voice_index
);
1161 case ZYN_FM_TYPE_RING_MOD
:
1162 ComputeVoiceOscillatorRingModulation(voice_index
);
1164 case ZYN_FM_TYPE_PHASE_MOD
:
1165 ComputeVoiceOscillatorFrequencyModulation(voice_index
,0);
1167 case ZYN_FM_TYPE_FREQ_MOD
:
1168 ComputeVoiceOscillatorFrequencyModulation(voice_index
,1);
1171 case ZYN_FM_TYPE_PITCH_MOD
:
1172 ComputeVoiceOscillatorPitchModulation(voice_index
);
1176 ComputeVoiceOscillator_LinearInterpolation(voice_index
);
1177 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(voice_index);
1182 ComputeVoiceNoise(voice_index
);
1188 if (ABOVE_AMPLITUDE_THRESHOLD(m_old_amplitude_ptr
[voice_index
],m_new_amplitude_ptr
[voice_index
])){
1189 int rest
=SOUND_BUFFER_SIZE
;
1190 //test if the amplitude if raising and the difference is high
1191 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)){
1193 if (rest
>SOUND_BUFFER_SIZE
) rest
=SOUND_BUFFER_SIZE
;
1194 for (int i
=0;i
<SOUND_BUFFER_SIZE
-rest
;i
++) m_tmpwave
[i
]*=m_old_amplitude_ptr
[voice_index
];
1196 // Amplitude interpolation
1197 for (i
=0;i
<rest
;i
++){
1198 m_tmpwave
[i
+(SOUND_BUFFER_SIZE
-rest
)]*=INTERPOLATE_AMPLITUDE(m_old_amplitude_ptr
[voice_index
]
1199 ,m_new_amplitude_ptr
[voice_index
],i
,rest
);
1201 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) m_tmpwave
[i
]*=m_new_amplitude_ptr
[voice_index
];
1204 if (m_first_tick_ptr
[voice_index
])
1206 fadein(&m_tmpwave
[0]);
1207 m_first_tick_ptr
[voice_index
] = false;
1211 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1213 m_voices_ptr
[voice_index
].m_voice_filter
.filterout(&m_tmpwave
[0]);
1216 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1217 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1219 if (m_voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1221 for (i
=0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1223 m_tmpwave
[i
] *= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1227 // the voice is killed later
1231 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1232 if (m_voices_ptr
[voice_index
].VoiceOut
!=NULL
)
1234 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1236 m_voices_ptr
[voice_index
].VoiceOut
[i
] = m_tmpwave
[i
];
1240 // Add the voice that do not bypass the filter to out
1241 if (m_voices_ptr
[voice_index
].filterbypass
==0)
1248 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1250 outl
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
*m_voices_ptr
[voice_index
].Panning
*2.0;
1251 outr
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
*(1.0-m_voices_ptr
[voice_index
].Panning
)*2.0;
1257 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) outl
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
;
1262 // bypass the filter
1267 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1269 m_bypassl
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
*m_voices_ptr
[voice_index
].Panning
*2.0;
1270 m_bypassr
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
*(1.0-m_voices_ptr
[voice_index
].Panning
)*2.0;
1276 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) m_bypassl
[i
]+=m_tmpwave
[i
]*m_voices_ptr
[voice_index
].Volume
;
1279 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1280 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1282 if (m_voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1284 KillVoice(voice_index
);
1289 // Processing Global parameters
1291 if (m_filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
1293 filter_adjust
= m_filter_envelope
.envout() + m_filter_lfo
.lfoout();
1295 zyn_filter_sv_process(m_filter_sv_processor_left
, filter_adjust
, outl
);
1299 zyn_filter_sv_process(m_filter_sv_processor_right
, filter_adjust
, outr
);
1304 m_filter_left
.filterout(&outl
[0]);
1308 m_filter_right
.filterout(&outr
[0]);
1314 // set the right channel=left channel
1315 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1318 m_bypassr
[i
]=m_bypassl
[i
];
1322 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1324 // outl[i]+=m_bypassl[i];
1325 // outr[i]+=m_bypassr[i];
1328 if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude
,globalnewamplitude
))
1330 // Amplitude Interpolation
1331 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1333 REALTYPE tmpvol
= INTERPOLATE_AMPLITUDE(globaloldamplitude
, globalnewamplitude
, i
, SOUND_BUFFER_SIZE
);
1334 outl
[i
] *= tmpvol
* (1.0 - m_panning
);
1335 outr
[i
] *= tmpvol
* m_panning
;
1340 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1342 outl
[i
] *= globalnewamplitude
* (1.0 - m_panning
);
1343 outr
[i
] *= globalnewamplitude
* m_panning
;
1348 if (m_punch_enabled
)
1350 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1352 REALTYPE punchamp
= m_punch_initial_value
* m_punch_t
+ 1.0;
1353 outl
[i
] *= punchamp
;
1354 outr
[i
] *= punchamp
;
1355 m_punch_t
-= m_punch_duration
;
1356 if (m_punch_t
< 0.0)
1358 m_punch_enabled
= false;
1364 // Check if the global amplitude is finished.
1365 // If it does, disable the note
1366 if (m_amplitude_envelope
.finished())
1368 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1372 REALTYPE tmp
= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1383 * Relase the key (NoteOff)
1385 void ADnote::relasekey()
1387 unsigned int voice_index
;
1389 for (voice_index
= 0 ; voice_index
< m_synth_ptr
->voices_count
; voice_index
++)
1391 if (!m_voices_ptr
[voice_index
].enabled
)
1396 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1398 m_voices_ptr
[voice_index
].m_amplitude_envelope
.relasekey();
1401 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1403 m_voices_ptr
[voice_index
].m_frequency_envelope
.relasekey();
1406 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1408 m_voices_ptr
[voice_index
].m_filter_envelope
.relasekey();
1411 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1413 m_voices_ptr
[voice_index
].m_fm_frequency_envelope
.relasekey();
1416 if (m_synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1418 m_voices_ptr
[voice_index
].m_fm_amplitude_envelope
.relasekey();
1422 m_frequency_envelope
.relasekey();
1423 m_filter_envelope
.relasekey();
1424 m_amplitude_envelope
.relasekey();
1428 * Check if the note is finished
1433 return !m_note_enabled
;