.gitignore file
[zyn.git] / addnote.cpp
blobec97f6a29cff212af5d212c4d87c263fab97aecc
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 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;
126 m_basefreq = freq;
128 if (velocity > 1.0)
130 m_velocity = 1.0;
132 else
134 m_velocity = velocity;
137 m_time = 0.0;
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);
149 if (m_stereo)
151 zyn_filter_sv_processor_init(m_filter_sv_processor_right, freq, filter_velocity_adjust);
154 else
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);
174 else
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,
183 rand());
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)
203 // coarse detune
204 m_voices_ptr[voice_index].Detune =
205 getdetune(
206 m_synth_ptr->voices_params_ptr[voice_index].PDetuneType,
207 m_synth_ptr->voices_params_ptr[voice_index].PCoarseDetune,
208 8192);
210 // fine detune
211 m_voices_ptr[voice_index].FineDetune =
212 getdetune(
213 m_synth_ptr->voices_params_ptr[voice_index].PDetuneType,
215 m_synth_ptr->voices_params_ptr[voice_index].PDetune);
217 else
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 =
228 getdetune(
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);
233 else
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
249 int vc=voice_index;
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,
260 rand());
263 m_osc_pos_hi_ptr[voice_index] =
264 zyn_oscillator_get(
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;
290 break;
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;
295 break;
296 #if 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;
299 break;
300 #endif
301 default:
302 if (fmvoldamp > 1.0)
304 fmvoldamp = 1.0;
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);
319 // Global Parameters
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,
324 m_basefreq,
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,
332 m_basefreq,
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);
344 if (m_stereo)
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);
351 m_filter_lfo.init(
352 m_synth_ptr->sample_rate,
353 m_basefreq,
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)
373 continue;
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
389 else
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,
406 m_basefreq,
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,
423 m_basefreq,
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,
443 m_basefreq,
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,
455 rand());
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
461 int vc=voice_index;
462 if (m_synth_ptr->voices_params_ptr[voice_index].PextFMoscil!=-1) vc=m_synth_ptr->voices_params_ptr[voice_index].PextFMoscil;
464 REALTYPE tmp=1.0;
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,
476 rand());
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,
483 tmp,
484 false);
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++)
511 tmp[i] = 0;
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];
519 tmp[i] = 1;
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)
538 int i;
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;
558 * Kill the note
560 void
561 ADnote::KillNote()
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);
572 // delete VoiceOut
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;
583 ADnote::~ADnote()
585 if (m_note_enabled)
587 KillNote();
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);
613 free(m_voices_ptr);
615 delete [] m_tmpwave;
616 delete [] m_bypassl;
617 delete [] m_bypassr;
621 * Computes the frequency of an oscillator
623 void ADnote::setfreq(int nvoice,REALTYPE freq)
625 REALTYPE speed;
627 freq = fabs(freq);
629 speed = freq * REALTYPE(OSCIL_SIZE) / m_synth_ptr->sample_rate;
630 if (speed > OSCIL_SIZE)
632 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)
645 REALTYPE speed;
647 freq = fabs(freq);
649 speed = freq * REALTYPE(OSCIL_SIZE) / m_synth_ptr->sample_rate;
650 if (speed > OSCIL_SIZE)
652 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)
664 REALTYPE detune;
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);
674 else
676 // the fixed freq is enabled
677 REALTYPE fixedfreq = 440.0;
678 int fixedfreqET = m_voices_ptr[nvoice].fixedfreqET;
679 if (fixedfreqET!=0)
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);
687 else
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
708 void
709 ADnote::computecurrentparameters()
711 unsigned int voice_index;
712 float voicefreq;
713 float voicepitch;
714 float filterpitch;
715 float filterfreq;
716 float FMfreq;
717 float FMrelativepitch;
718 float globalpitch;
719 float temp_filter_frequency;
721 globalpitch =
722 0.01 * (m_frequency_envelope.envout() +
723 m_frequency_lfo.lfoout() * m_synth_ptr->modwheel_relmod);
725 globaloldamplitude = globalnewamplitude;
727 globalnewamplitude =
728 m_volume *
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);
737 if (m_stereo)
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;
745 if (m_portamento)
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)
762 continue;
765 m_voices_ptr[voice_index].DelayTicks -= 1;
767 if (m_voices_ptr[voice_index].DelayTicks > 0)
769 continue;
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();
788 /****************/
789 /* Voice Filter */
790 /****************/
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 /*******************/
817 voicepitch=0.0;
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);
832 /***************/
833 /* Modulator */
834 /***************/
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){
866 int zerocrossings=0;
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;
873 int n;
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;
878 smps[i]*=tmp;
883 * Computes the Oscillator (Without Modulation) - LinearInterpolation
885 inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int voice_index){
886 int i,poshi;
887 REALTYPE poslo;
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];
895 if (poslo>=1.0) {
896 poslo-=1.0;
897 poshi++;
899 poshi+=m_osc_freq_hi_ptr[voice_index];
900 poshi&=OSCIL_SIZE-1;
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){
913 int i,poshi;
914 REALTYPE poslo;
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++){
921 xm1=smps[poshi];
922 x0=smps[poshi+1];
923 x1=smps[poshi+2];
924 x2=smps[poshi+3];
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;
929 printf("a\n");
930 //m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
931 poslo+=m_osc_freq_lo_ptr[voice_index];
932 if (poslo>=1.0) {
933 poslo-=1.0;
934 poshi++;
936 poshi+=m_osc_freq_hi_ptr[voice_index];
937 poshi&=OSCIL_SIZE-1;
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){
947 int i;
948 REALTYPE amp;
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];
961 } else {
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];
972 if (posloFM>=1.0) {
973 posloFM-=1.0;
974 poshiFM++;
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){
988 int i;
989 REALTYPE amp;
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];
1002 } else {
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
1011 +(1.0-amp);
1012 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1013 if (posloFM>=1.0) {
1014 posloFM-=1.0;
1015 poshiFM++;
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){
1031 int carposhi;
1032 int i,FMmodfreqhi;
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];
1038 } else {
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];
1047 if (posloFM>=1.0) {
1048 posloFM=fmod(posloFM,1.0);
1049 poshiFM++;
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++;
1083 //carrier
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) {
1088 carposhi++;
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){
1110 //TODO
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
1127 void
1128 ADnote::noteout(
1129 REALTYPE * outl,
1130 REALTYPE * outr)
1132 int i;
1133 unsigned int voice_index;
1134 float filter_adjust;
1136 silence_two_buffers(outl, outr, SOUND_BUFFER_SIZE);
1138 if (!m_note_enabled)
1140 return;
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)
1151 continue;
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);
1160 break;
1161 case ZYN_FM_TYPE_RING_MOD:
1162 ComputeVoiceOscillatorRingModulation(voice_index);
1163 break;
1164 case ZYN_FM_TYPE_PHASE_MOD:
1165 ComputeVoiceOscillatorFrequencyModulation(voice_index,0);
1166 break;
1167 case ZYN_FM_TYPE_FREQ_MOD:
1168 ComputeVoiceOscillatorFrequencyModulation(voice_index,1);
1169 break;
1170 #if 0
1171 case ZYN_FM_TYPE_PITCH_MOD:
1172 ComputeVoiceOscillatorPitchModulation(voice_index);
1173 break;
1174 #endif
1175 default:
1176 ComputeVoiceOscillator_LinearInterpolation(voice_index);
1177 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(voice_index);
1180 else
1182 ComputeVoiceNoise(voice_index);
1185 // Voice Processing
1187 // Amplitude
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)){
1192 rest=10;
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];
1203 // Fade in
1204 if (m_first_tick_ptr[voice_index])
1206 fadein(&m_tmpwave[0]);
1207 m_first_tick_ptr[voice_index] = false;
1210 // Filter
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)
1243 // no bypass
1245 if (m_stereo)
1247 // stereo
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;
1254 else
1256 // mono
1257 for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume;
1260 else
1262 // bypass the filter
1264 if (m_stereo)
1266 // stereo
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;
1273 else
1275 // mono
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);
1297 if (m_stereo)
1299 zyn_filter_sv_process(m_filter_sv_processor_right, filter_adjust, outr);
1302 else
1304 m_filter_left.filterout(&outl[0]);
1306 if (m_stereo)
1308 m_filter_right.filterout(&outr[0]);
1312 if (!m_stereo)
1314 // set the right channel=left channel
1315 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1317 outr[i]=outl[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;
1338 else
1340 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1342 outl[i] *= globalnewamplitude * (1.0 - m_panning);
1343 outr[i] *= globalnewamplitude * m_panning;
1347 // Apply the punch
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;
1359 break;
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++)
1370 // fade-out
1372 REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1374 outl[i] *= tmp;
1375 outr[i] *= tmp;
1378 KillNote();
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)
1393 continue;
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
1430 bool
1431 ADnote::finished()
1433 return !m_note_enabled;