Update copyright years
[zyn.git] / addnote.cpp
blob38510a10fc46f89ae6aa561313c0ef548b66934f
1 /*
2 ZynAddSubFX - a software synthesizer
4 ADnote.C - The "additive" synthesizer
5 Copyright (C) 2006,2007,2008,2009 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 "addnote.h"
47 #define LOG_LEVEL LOG_LEVEL_ERROR
48 #include "log.h"
50 /***********************************************************/
51 /* VOICE PARAMETERS */
52 /***********************************************************/
53 struct addsynth_voice
55 /* If the voice is enabled */
56 bool enabled;
58 /* Voice Type (sound/noise)*/
59 bool white_noise;
61 /* Filter Bypass */
62 int filterbypass;
64 /* Delay (ticks) */
65 int DelayTicks;
67 /* Waveform of the Voice */
68 REALTYPE *OscilSmp;
70 /************************************
71 * FREQUENCY PARAMETERS *
72 ************************************/
73 int fixedfreq;//if the frequency is fixed to 440 Hz
74 int fixedfreqET;//if the "fixed" frequency varies according to the note (ET)
76 // cents = basefreq*VoiceDetune
77 REALTYPE Detune,FineDetune;
79 Envelope m_frequency_envelope;
80 LFO m_frequency_lfo;
82 /***************************
83 * AMPLITUDE PARAMETERS *
84 ***************************/
86 /* Panning 0.0=left, 0.5 - center, 1.0 = right */
87 REALTYPE Panning;
88 REALTYPE Volume;// [-1.0 .. 1.0]
90 Envelope m_amplitude_envelope;
91 LFO m_amplitude_lfo;
93 /*************************
94 * FILTER PARAMETERS *
95 *************************/
97 Filter m_voice_filter;
99 REALTYPE FilterCenterPitch;/* Filter center Pitch*/
100 REALTYPE FilterFreqTracking;
102 Envelope m_filter_envelope;
103 LFO m_filter_lfo;
105 /****************************
106 * MODULLATOR PARAMETERS *
107 ****************************/
109 unsigned int fm_type;
111 int FMVoice;
113 // Voice Output used by other voices if use this as modullator
114 REALTYPE *VoiceOut;
116 /* Wave of the Voice */
117 REALTYPE *FMSmp;
119 REALTYPE FMVolume;
120 REALTYPE FMDetune; //in cents
122 Envelope m_fm_frequency_envelope;
123 Envelope m_fm_amplitude_envelope;
126 ADnote::ADnote(
127 struct zyn_addsynth * synth_ptr)
129 m_tmpwave = new REALTYPE [SOUND_BUFFER_SIZE];
130 m_bypassl = new REALTYPE [SOUND_BUFFER_SIZE];
131 m_bypassr = new REALTYPE [SOUND_BUFFER_SIZE];
133 m_voices_ptr = (struct addsynth_voice *)malloc(sizeof(struct addsynth_voice) * synth_ptr->voices_count);
135 m_osc_pos_hi_ptr = (int *)malloc(sizeof(int) * synth_ptr->voices_count);
136 m_osc_pos_lo_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
137 m_osc_pos_hi_FM_ptr = (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr->voices_count);
138 m_osc_pos_lo_FM_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
140 m_osc_freq_hi_ptr = (int *)malloc(sizeof(int) * synth_ptr->voices_count);
141 m_osc_freq_lo_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
142 m_osc_freq_hi_FM_ptr = (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr->voices_count);
143 m_osc_freq_lo_FM_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
145 m_FM_old_smp_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
147 m_first_tick_ptr = (bool *)malloc(sizeof(bool) * synth_ptr->voices_count);
149 m_old_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
150 m_new_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
152 m_FM_old_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
153 m_FM_new_amplitude_ptr = (float *)malloc(sizeof(float) * synth_ptr->voices_count);
155 m_stereo = synth_ptr->stereo;
157 m_detune = getdetune(
158 synth_ptr->GlobalPar.PDetuneType,
159 synth_ptr->GlobalPar.PCoarseDetune,
160 synth_ptr->GlobalPar.PDetune);
163 * Get the Multiplier of the fine detunes of the voices
165 m_bandwidth_detune_multiplier = (synth_ptr->GlobalPar.PBandwidth - 64.0) / 64.0;
166 m_bandwidth_detune_multiplier =
167 pow(
168 2.0,
169 m_bandwidth_detune_multiplier * pow(fabs(m_bandwidth_detune_multiplier), 0.2) * 5.0);
171 m_note_enabled = false;
173 m_synth_ptr = synth_ptr;
175 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &m_filter_sv_processor_left))
179 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &m_filter_sv_processor_right))
184 void
185 ADnote::note_on(
186 float panorama,
187 bool random_grouping,
188 REALTYPE freq,
189 REALTYPE velocity,
190 bool portamento,
191 int midinote)
193 unsigned int voice_index;
194 unsigned int i;
195 float filter_velocity_adjust;
196 int voice_oscillator_index;
197 REALTYPE tmp;
199 m_portamento = portamento;
200 m_midinote = midinote;
201 m_note_enabled = true;
202 m_basefreq = freq;
204 if (velocity > 1.0)
206 m_velocity = 1.0;
208 else
210 m_velocity = velocity;
213 m_time = 0.0;
215 m_panning = (panorama + 1.0) / 2; // -1..1 -> 0 - 1
217 m_filter_category = m_synth_ptr->filter_type;
219 if (m_filter_category == ZYN_FILTER_TYPE_STATE_VARIABLE)
221 filter_velocity_adjust = m_synth_ptr->m_filter_velocity_sensing_amount * 6.0 * // velocity sensing
222 (zyn_velocity_scale(m_velocity, m_synth_ptr->m_filter_velocity_scale_function) - 1);
224 zyn_filter_sv_processor_init(m_filter_sv_processor_left, freq, filter_velocity_adjust);
225 if (m_stereo)
227 zyn_filter_sv_processor_init(m_filter_sv_processor_right, freq, filter_velocity_adjust);
230 else
232 m_filter_center_pitch =
233 m_synth_ptr->m_filter_params.getfreq() + // center freq
234 m_synth_ptr->m_filter_velocity_sensing_amount * 6.0 * // velocity sensing
235 (zyn_velocity_scale(m_velocity, m_synth_ptr->m_filter_velocity_scale_function) - 1);
236 m_filter_center_pitch += m_synth_ptr->m_filter_params.getfreqtracking(m_basefreq);
239 if (m_synth_ptr->GlobalPar.PPunchStrength != 0)
241 m_punch_enabled = true;
242 m_punch_t = 1.0; // start from 1.0 and to 0.0
243 m_punch_initial_value = pow(10, 1.5 * m_synth_ptr->GlobalPar.PPunchStrength / 127.0) - 1.0;
244 m_punch_initial_value *= VelF(m_velocity, m_synth_ptr->GlobalPar.PPunchVelocitySensing);
246 REALTYPE time = pow(10, 3.0 * m_synth_ptr->GlobalPar.PPunchTime / 127.0) / 10000.0; // 0.1 .. 100 ms
248 REALTYPE stretch = pow(440.0/freq, m_synth_ptr->GlobalPar.PPunchStretch / 64.0);
250 m_punch_duration = 1.0 / (time * m_synth_ptr->sample_rate * stretch);
252 else
254 m_punch_enabled = false;
257 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
259 zyn_oscillator_new_rand_seed(
260 &m_synth_ptr->voices_params_ptr[voice_index].oscillator,
261 rand());
262 m_voices_ptr[voice_index].OscilSmp = NULL;
263 m_voices_ptr[voice_index].FMSmp = NULL;
264 m_voices_ptr[voice_index].VoiceOut = NULL;
266 m_voices_ptr[voice_index].FMVoice = -1;
268 if (!m_synth_ptr->voices_params_ptr[voice_index].enabled)
270 m_voices_ptr[voice_index].enabled = false;
271 continue; // the voice is disabled
274 m_voices_ptr[voice_index].enabled = true;
275 m_voices_ptr[voice_index].fixedfreq = m_synth_ptr->voices_params_ptr[voice_index].Pfixedfreq;
276 m_voices_ptr[voice_index].fixedfreqET = m_synth_ptr->voices_params_ptr[voice_index].PfixedfreqET;
278 // use the Globalpars.detunetype if the detunetype is 0
279 if (m_synth_ptr->voices_params_ptr[voice_index].PDetuneType != 0)
281 // coarse detune
282 m_voices_ptr[voice_index].Detune =
283 getdetune(
284 m_synth_ptr->voices_params_ptr[voice_index].PDetuneType,
285 m_synth_ptr->voices_params_ptr[voice_index].PCoarseDetune,
286 8192);
288 // fine detune
289 m_voices_ptr[voice_index].FineDetune =
290 getdetune(
291 m_synth_ptr->voices_params_ptr[voice_index].PDetuneType,
293 m_synth_ptr->voices_params_ptr[voice_index].PDetune);
295 else
297 // coarse detune
298 m_voices_ptr[voice_index].Detune = getdetune(
299 m_synth_ptr->GlobalPar.PDetuneType,
300 m_synth_ptr->voices_params_ptr[voice_index].PCoarseDetune,
301 8192);
303 // fine detune
304 m_voices_ptr[voice_index].FineDetune = getdetune(
305 m_synth_ptr->GlobalPar.PDetuneType,
307 m_synth_ptr->voices_params_ptr[voice_index].PDetune);
310 if (m_synth_ptr->voices_params_ptr[voice_index].PFMDetuneType != 0)
312 m_voices_ptr[voice_index].FMDetune =
313 getdetune(
314 m_synth_ptr->voices_params_ptr[voice_index].PFMDetuneType,
315 m_synth_ptr->voices_params_ptr[voice_index].PFMCoarseDetune,
316 m_synth_ptr->voices_params_ptr[voice_index].PFMDetune);
318 else
320 m_voices_ptr[voice_index].FMDetune = getdetune(
321 m_synth_ptr->GlobalPar.PDetuneType,
322 m_synth_ptr->voices_params_ptr[voice_index].PFMCoarseDetune,
323 m_synth_ptr->voices_params_ptr[voice_index].PFMDetune);
326 m_osc_pos_hi_ptr[voice_index] = 0;
327 m_osc_pos_lo_ptr[voice_index] = 0.0;
328 m_osc_pos_hi_FM_ptr[voice_index] = 0;
329 m_osc_pos_lo_FM_ptr[voice_index] = 0.0;
331 // the extra points contains the first point
332 m_voices_ptr[voice_index].OscilSmp = new REALTYPE [OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES];
334 // Get the voice's oscil or external's voice oscil
335 if (m_synth_ptr->voices_params_ptr[voice_index].Pextoscil != -1)
337 voice_oscillator_index = m_synth_ptr->voices_params_ptr[voice_index].Pextoscil;
339 else
341 voice_oscillator_index = voice_index;
344 if (!random_grouping)
346 zyn_oscillator_new_rand_seed(
347 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
348 rand());
351 m_osc_pos_hi_ptr[voice_index] =
352 zyn_oscillator_get(
353 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
354 m_voices_ptr[voice_index].OscilSmp,
355 getvoicebasefreq(voice_index),
356 m_synth_ptr->voices_params_ptr[voice_index].resonance);
358 // I store the first elments to the last position for speedups
359 for (i = 0 ; i < OSCIL_SMP_EXTRA_SAMPLES ; i++)
361 m_voices_ptr[voice_index].OscilSmp[OSCIL_SIZE + i] = m_voices_ptr[voice_index].OscilSmp[i];
364 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);
365 m_osc_pos_hi_ptr[voice_index] %= OSCIL_SIZE;
367 m_voices_ptr[voice_index].FilterCenterPitch = m_synth_ptr->voices_params_ptr[voice_index].m_filter_params.getfreq();
368 m_voices_ptr[voice_index].filterbypass = m_synth_ptr->voices_params_ptr[voice_index].Pfilterbypass;
370 m_voices_ptr[voice_index].fm_type = m_synth_ptr->voices_params_ptr[voice_index].fm_type;
372 m_voices_ptr[voice_index].FMVoice=m_synth_ptr->voices_params_ptr[voice_index].PFMVoice;
374 // Compute the Voice's modulator volume (incl. damping)
375 REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq(voice_index), m_synth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp / 64.0 - 1.0);
376 switch (m_voices_ptr[voice_index].fm_type)
378 case ZYN_FM_TYPE_PHASE_MOD:
379 fmvoldamp = pow(440.0 / getvoicebasefreq(voice_index), m_synth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp / 64.0);
380 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;
381 break;
382 case ZYN_FM_TYPE_FREQ_MOD:
383 m_voices_ptr[voice_index].FMVolume = exp(m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * FM_AMP_MULTIPLIER);
384 m_voices_ptr[voice_index].FMVolume -= 1.0;
385 m_voices_ptr[voice_index].FMVolume *= fmvoldamp * 4.0;
386 break;
387 #if 0 // ???????????
388 case ZYN_FM_TYPE_PITCH_MOD:
389 m_voices_ptr[voice_index].FMVolume = (m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * 8.0) * fmvoldamp;
390 break;
391 #endif
392 default:
393 if (fmvoldamp > 1.0)
395 fmvoldamp = 1.0;
398 m_voices_ptr[voice_index].FMVolume = m_synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * fmvoldamp;
401 // Voice's modulator velocity sensing
402 m_voices_ptr[voice_index].FMVolume *= VelF(m_velocity, m_synth_ptr->voices_params_ptr[voice_index].PFMVelocityScaleFunction);
404 m_FM_old_smp_ptr[voice_index] = 0.0; // this is for FM (integration)
406 m_first_tick_ptr[voice_index] = true;
407 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);
408 } // voices loop
410 // Global Parameters
411 m_frequency_envelope.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_frequency_envelope_params, m_basefreq);
413 m_frequency_lfo.init(
414 m_synth_ptr->sample_rate,
415 m_basefreq,
416 &m_synth_ptr->frequency_lfo_params,
417 ZYN_LFO_TYPE_FREQUENCY);
419 m_amplitude_envelope.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_amplitude_envelope_params, m_basefreq);
421 m_amplitude_lfo.init(
422 m_synth_ptr->sample_rate,
423 m_basefreq,
424 &m_synth_ptr->amplitude_lfo_params,
425 ZYN_LFO_TYPE_AMPLITUDE);
427 m_volume = 4.0 * pow(0.1, 3.0 * (1.0 - m_synth_ptr->GlobalPar.PVolume / 96.0)); // -60 dB .. 0 dB
428 m_volume *= VelF(m_velocity, m_synth_ptr->GlobalPar.PAmpVelocityScaleFunction); // velocity sensing
430 m_amplitude_envelope.envout_dB(); // discard the first envelope output
432 globalnewamplitude = m_volume * m_amplitude_envelope.envout_dB() * m_amplitude_lfo.amplfoout();
434 m_filter_left.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_filter_params);
435 if (m_stereo)
437 m_filter_right.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_filter_params);
440 m_filter_envelope.init(m_synth_ptr->sample_rate, &m_synth_ptr->m_filter_envelope_params, m_basefreq);
442 m_filter_lfo.init(
443 m_synth_ptr->sample_rate,
444 m_basefreq,
445 &m_synth_ptr->filter_lfo_params,
446 ZYN_LFO_TYPE_FILTER);
448 m_filter_q_factor = m_synth_ptr->m_filter_params.getq();
450 // Forbids the Modulation Voice to be greater or equal than voice
451 for (i = 0 ; i < m_synth_ptr->voices_count ; i++)
453 if (m_voices_ptr[i].FMVoice >= (int)i)
455 m_voices_ptr[i].FMVoice = -1;
459 // Voice Parameter init
460 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
462 if (!m_voices_ptr[voice_index].enabled)
464 continue;
467 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);
469 m_voices_ptr[voice_index].white_noise = m_synth_ptr->voices_params_ptr[voice_index].white_noise;
471 /* Voice Amplitude Parameters Init */
473 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
474 m_voices_ptr[voice_index].Volume *= VelF(m_velocity, m_synth_ptr->voices_params_ptr[voice_index].PAmpVelocityScaleFunction); // velocity
476 if (m_synth_ptr->voices_params_ptr[voice_index].PVolumeminus != 0)
478 m_voices_ptr[voice_index].Volume = -m_voices_ptr[voice_index].Volume;
481 if (m_synth_ptr->voices_params_ptr[voice_index].PPanning == 0)
483 m_voices_ptr[voice_index].Panning = zyn_random(); // random panning
485 else
487 m_voices_ptr[voice_index].Panning = m_synth_ptr->voices_params_ptr[voice_index].PPanning / 128.0;
490 m_new_amplitude_ptr[voice_index] = 1.0;
491 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled != 0)
493 m_voices_ptr[voice_index].m_amplitude_envelope.init(
494 m_synth_ptr->sample_rate,
495 &m_synth_ptr->voices_params_ptr[voice_index].m_amplitude_envelope_params,
496 m_basefreq);
498 m_voices_ptr[voice_index].m_amplitude_envelope.envout_dB(); // discard the first envelope sample
499 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_envelope.envout_dB();
502 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled != 0)
504 m_voices_ptr[voice_index].m_amplitude_lfo.init(
505 m_synth_ptr->sample_rate,
506 m_basefreq,
507 &m_synth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params,
508 ZYN_LFO_TYPE_AMPLITUDE);
510 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_lfo.amplfoout();
513 /* Voice Frequency Parameters Init */
514 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled != 0)
516 m_voices_ptr[voice_index].m_frequency_envelope.init(
517 m_synth_ptr->sample_rate,
518 &m_synth_ptr->voices_params_ptr[voice_index].m_frequency_envelope_params,
519 m_basefreq);
522 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled != 0)
524 m_voices_ptr[voice_index].m_frequency_lfo.init(
525 m_synth_ptr->sample_rate,
526 m_basefreq,
527 &m_synth_ptr->voices_params_ptr[voice_index].frequency_lfo_params,
528 ZYN_LFO_TYPE_FREQUENCY);
531 /* Voice Filter Parameters Init */
532 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnabled != 0)
534 m_voices_ptr[voice_index].m_voice_filter.init(
535 m_synth_ptr->sample_rate,
536 &m_synth_ptr->voices_params_ptr[voice_index].m_filter_params);
539 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled != 0)
541 m_voices_ptr[voice_index].m_filter_envelope.init(
542 m_synth_ptr->sample_rate,
543 &m_synth_ptr->voices_params_ptr[voice_index].m_filter_envelope_params,
544 m_basefreq);
547 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled != 0)
549 m_voices_ptr[voice_index].m_filter_lfo.init(
550 m_synth_ptr->sample_rate,
551 m_basefreq,
552 &m_synth_ptr->voices_params_ptr[voice_index].filter_lfo_params,
553 ZYN_LFO_TYPE_FILTER);
556 m_voices_ptr[voice_index].FilterFreqTracking = m_synth_ptr->voices_params_ptr[voice_index].m_filter_params.getfreqtracking(m_basefreq);
558 /* Voice Modulation Parameters Init */
559 if (m_voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE &&
560 m_voices_ptr[voice_index].FMVoice < 0)
562 zyn_oscillator_new_rand_seed(
563 &m_synth_ptr->voices_params_ptr[voice_index].modulator_oscillator,
564 rand());
566 m_voices_ptr[voice_index].FMSmp = new zyn_sample_type[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES];
568 // Perform Anti-aliasing only on MORPH or RING MODULATION
570 if (m_synth_ptr->voices_params_ptr[voice_index].PextFMoscil != -1)
572 voice_oscillator_index = m_synth_ptr->voices_params_ptr[voice_index].PextFMoscil;
574 else
576 voice_oscillator_index = voice_index;
579 if ((m_synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator.Padaptiveharmonics != 0) ||
580 (m_voices_ptr[voice_index].fm_type == ZYN_FM_TYPE_MORPH) ||
581 (m_voices_ptr[voice_index].fm_type == ZYN_FM_TYPE_RING_MOD))
583 tmp = getFMvoicebasefreq(voice_index);
585 else
587 tmp = 1.0;
590 if (!random_grouping)
592 zyn_oscillator_new_rand_seed(
593 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
594 rand());
597 m_osc_pos_hi_FM_ptr[voice_index] = m_osc_pos_hi_ptr[voice_index];
598 m_osc_pos_hi_FM_ptr[voice_index] += zyn_oscillator_get(
599 &m_synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
600 m_voices_ptr[voice_index].FMSmp,
601 tmp,
602 false);
603 m_osc_pos_hi_FM_ptr[voice_index] %= OSCIL_SIZE;
605 for (i = 0 ; i < OSCIL_SMP_EXTRA_SAMPLES ; i++)
607 m_voices_ptr[voice_index].FMSmp[OSCIL_SIZE + i] = m_voices_ptr[voice_index].FMSmp[i];
610 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);
611 m_osc_pos_hi_FM_ptr[voice_index] %= OSCIL_SIZE;
614 if (m_synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled != 0)
616 m_voices_ptr[voice_index].m_fm_frequency_envelope.init(
617 m_synth_ptr->sample_rate,
618 &m_synth_ptr->voices_params_ptr[voice_index].m_fm_frequency_envelope_params,
619 m_basefreq);
622 m_FM_new_amplitude_ptr[voice_index] = m_voices_ptr[voice_index].FMVolume;
623 //m_FM_new_amplitude_ptr[voice_index] *= m_ctl->fmamp.relamp; // 0..1
625 if (m_synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled != 0)
627 m_voices_ptr[voice_index].m_fm_amplitude_envelope.init(
628 m_synth_ptr->sample_rate,
629 &m_synth_ptr->voices_params_ptr[voice_index].m_fm_amplitude_envelope_params,
630 m_basefreq);
632 m_FM_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_fm_amplitude_envelope.envout_dB();
634 } // voice parameter init loop
636 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
638 for (i = voice_index + 1 ; i < m_synth_ptr->voices_count ; i++)
640 if (m_voices_ptr[i].FMVoice == (int)voice_index)
642 m_voices_ptr[voice_index].VoiceOut = new zyn_sample_type[SOUND_BUFFER_SIZE];
646 if (m_voices_ptr[voice_index].VoiceOut != NULL)
648 silence_buffer(m_voices_ptr[voice_index].VoiceOut, SOUND_BUFFER_SIZE);
654 * Kill a voice of ADnote
656 void ADnote::KillVoice(unsigned int voice_index)
658 delete [] (m_voices_ptr[voice_index].OscilSmp);
660 if ((m_voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE) && (m_voices_ptr[voice_index].FMVoice < 0))
662 delete m_voices_ptr[voice_index].FMSmp;
665 if (m_voices_ptr[voice_index].VoiceOut != NULL)
667 // do not delete, yet: perhaps is used by another voice
668 silence_buffer(m_voices_ptr[voice_index].VoiceOut, SOUND_BUFFER_SIZE);
671 m_voices_ptr[voice_index].enabled = false;
675 * Kill the note
677 void
678 ADnote::force_disable()
680 unsigned int voice_index;
682 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
684 if (m_voices_ptr[voice_index].enabled)
686 KillVoice(voice_index);
689 // delete VoiceOut
690 if (m_voices_ptr[voice_index].VoiceOut != NULL)
692 delete(m_voices_ptr[voice_index].VoiceOut);
693 m_voices_ptr[voice_index].VoiceOut = NULL;
697 m_note_enabled = false;
700 ADnote::~ADnote()
702 if (m_note_enabled)
704 force_disable();
707 zyn_filter_sv_processor_destroy(m_filter_sv_processor_left);
708 zyn_filter_sv_processor_destroy(m_filter_sv_processor_right);
710 free(m_old_amplitude_ptr);
711 free(m_new_amplitude_ptr);
713 free(m_FM_old_amplitude_ptr);
714 free(m_FM_new_amplitude_ptr);
716 free(m_first_tick_ptr);
718 free(m_FM_old_smp_ptr);
720 free(m_osc_freq_hi_ptr);
721 free(m_osc_freq_lo_ptr);
722 free(m_osc_freq_hi_FM_ptr);
723 free(m_osc_freq_lo_FM_ptr);
725 free(m_osc_pos_hi_ptr);
726 free(m_osc_pos_lo_ptr);
727 free(m_osc_pos_hi_FM_ptr);
728 free(m_osc_pos_lo_FM_ptr);
730 free(m_voices_ptr);
732 delete [] m_tmpwave;
733 delete [] m_bypassl;
734 delete [] m_bypassr;
738 * Computes the frequency of an oscillator
740 void ADnote::setfreq(int nvoice,REALTYPE freq)
742 REALTYPE speed;
744 freq = fabs(freq);
746 speed = freq * REALTYPE(OSCIL_SIZE) / m_synth_ptr->sample_rate;
747 if (speed > OSCIL_SIZE)
749 speed = OSCIL_SIZE;
752 F2I(speed, m_osc_freq_hi_ptr[nvoice]);
754 m_osc_freq_lo_ptr[nvoice] = speed - floor(speed);
758 * Computes the frequency of an modullator oscillator
760 void ADnote::setfreqFM(int nvoice,REALTYPE freq)
762 REALTYPE speed;
764 freq = fabs(freq);
766 speed = freq * REALTYPE(OSCIL_SIZE) / m_synth_ptr->sample_rate;
767 if (speed > OSCIL_SIZE)
769 speed = OSCIL_SIZE;
772 F2I(speed, m_osc_freq_hi_FM_ptr[nvoice]);
773 m_osc_freq_lo_FM_ptr[nvoice] = speed - floor(speed);
777 * Get Voice base frequency
779 REALTYPE ADnote::getvoicebasefreq(int nvoice)
781 REALTYPE detune;
783 detune = m_voices_ptr[nvoice].Detune / 100.0;
784 detune += m_voices_ptr[nvoice].FineDetune / 100.0 * m_synth_ptr->bandwidth_relbw * m_bandwidth_detune_multiplier;
785 detune += m_detune / 100.0;
787 if (m_voices_ptr[nvoice].fixedfreq == 0)
789 return m_basefreq * pow(2, detune / 12.0);
791 else
793 // the fixed freq is enabled
794 REALTYPE fixedfreq = 440.0;
795 int fixedfreqET = m_voices_ptr[nvoice].fixedfreqET;
796 if (fixedfreqET!=0)
798 // if the frequency varies according the keyboard note
799 REALTYPE tmp = (m_midinote - 69.0) / 12.0 * (pow(2.0,(fixedfreqET-1)/63.0) - 1.0);
800 if (fixedfreqET <= 64)
802 fixedfreq *= pow(2.0,tmp);
804 else
806 fixedfreq *= pow(3.0,tmp);
810 return fixedfreq * pow(2.0, detune / 12.0);
815 * Get Voice's Modullator base frequency
817 REALTYPE ADnote::getFMvoicebasefreq(int nvoice){
818 REALTYPE detune=m_voices_ptr[nvoice].FMDetune/100.0;
819 return(getvoicebasefreq(nvoice)*pow(2,detune/12.0));
823 * Computes all the parameters for each tick
825 void
826 ADnote::computecurrentparameters()
828 unsigned int voice_index;
829 float voicefreq;
830 float voicepitch;
831 float filterpitch;
832 float filterfreq;
833 float FMfreq;
834 float FMrelativepitch;
835 float globalpitch;
836 float temp_filter_frequency;
838 globalpitch =
839 0.01 * (m_frequency_envelope.envout() +
840 m_frequency_lfo.lfoout() * m_synth_ptr->modwheel_relmod);
842 globaloldamplitude = globalnewamplitude;
844 globalnewamplitude =
845 m_volume *
846 m_amplitude_envelope.envout_dB() *
847 m_amplitude_lfo.amplfoout();
849 if (m_filter_category != ZYN_FILTER_TYPE_STATE_VARIABLE)
851 temp_filter_frequency = m_filter_left.getrealfreq(m_filter_center_pitch + m_filter_envelope.envout() + m_filter_lfo.lfoout());
853 m_filter_left.setfreq_and_q(temp_filter_frequency, m_filter_q_factor);
854 if (m_stereo)
856 m_filter_right.setfreq_and_q(temp_filter_frequency, m_filter_q_factor);
860 // compute the portamento, if it is used by this note
861 REALTYPE portamentofreqrap=1.0;
862 if (m_portamento)
864 // this voice use portamento
865 portamentofreqrap = m_synth_ptr->portamento.freqrap;
867 if (!m_synth_ptr->portamento.used)
869 // the portamento has finished
870 m_portamento = false; // this note is no longer "portamented"
874 //compute parameters for all voices
875 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
877 if (!m_voices_ptr[voice_index].enabled)
879 continue;
882 m_voices_ptr[voice_index].DelayTicks -= 1;
884 if (m_voices_ptr[voice_index].DelayTicks > 0)
886 continue;
889 /*******************/
890 /* Voice Amplitude */
891 /*******************/
892 m_old_amplitude_ptr[voice_index] = m_new_amplitude_ptr[voice_index];
893 m_new_amplitude_ptr[voice_index] = 1.0;
895 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
897 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_envelope.envout_dB();
900 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled)
902 m_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_amplitude_lfo.amplfoout();
905 /****************/
906 /* Voice Filter */
907 /****************/
908 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
910 filterpitch = m_voices_ptr[voice_index].FilterCenterPitch;
912 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled)
914 filterpitch += m_voices_ptr[voice_index].m_filter_envelope.envout();
917 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled)
919 filterpitch += m_voices_ptr[voice_index].m_filter_lfo.lfoout();
922 filterfreq = filterpitch + m_voices_ptr[voice_index].FilterFreqTracking;
923 filterfreq = m_voices_ptr[voice_index].m_voice_filter.getrealfreq(filterfreq);
925 m_voices_ptr[voice_index].m_voice_filter.setfreq(filterfreq);
928 // compute only if the voice isn't noise
929 if (!m_voices_ptr[voice_index].white_noise)
931 /*******************/
932 /* Voice Frequency */
933 /*******************/
934 voicepitch=0.0;
935 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled)
937 voicepitch += m_voices_ptr[voice_index].m_frequency_lfo.lfoout() / 100.0 * m_synth_ptr->bandwidth_relbw;
940 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled)
942 voicepitch += m_voices_ptr[voice_index].m_frequency_envelope.envout() / 100.0;
945 voicefreq = getvoicebasefreq(voice_index) * pow(2, (voicepitch + globalpitch) / 12.0); // Hz frequency
946 voicefreq *= m_synth_ptr->pitch_bend_relative_frequency; // change the frequency by the controller
947 setfreq(voice_index, voicefreq * portamentofreqrap);
949 /***************/
950 /* Modulator */
951 /***************/
952 if (m_voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE)
954 FMrelativepitch = m_voices_ptr[voice_index].FMDetune / 100.0;
955 if (m_synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled)
957 FMrelativepitch += m_voices_ptr[voice_index].m_fm_frequency_envelope.envout() / 100;
960 FMfreq = pow(2.0, FMrelativepitch / 12.0) * voicefreq * portamentofreqrap;
961 setfreqFM(voice_index, FMfreq);
963 m_FM_old_amplitude_ptr[voice_index] = m_FM_new_amplitude_ptr[voice_index];
964 m_FM_new_amplitude_ptr[voice_index] = m_voices_ptr[voice_index].FMVolume;
965 //m_FM_new_amplitude_ptr[voice_index] *= m_ctl->fmamp.relamp; // 0..1
967 if (m_synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled)
969 m_FM_new_amplitude_ptr[voice_index] *= m_voices_ptr[voice_index].m_fm_amplitude_envelope.envout_dB();
975 m_time += (REALTYPE)SOUND_BUFFER_SIZE / m_synth_ptr->sample_rate;
980 * Fadein in a way that removes clicks but keep sound "punchy"
982 inline void ADnote::fadein(REALTYPE *smps){
983 int zerocrossings=0;
984 for (int i=1;i<SOUND_BUFFER_SIZE;i++)
985 if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings
987 REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0;
988 if (tmp<8.0) tmp=8.0;
990 int n;
991 F2I(tmp,n);//how many samples is the fade-in
992 if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
993 for (int i=0;i<n;i++) {//fade-in
994 REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5;
995 smps[i]*=tmp;
1000 * Computes the Oscillator (Without Modulation) - LinearInterpolation
1002 inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int voice_index){
1003 int i,poshi;
1004 REALTYPE poslo;
1006 poshi=m_osc_pos_hi_ptr[voice_index];
1007 poslo=m_osc_pos_lo_ptr[voice_index];
1008 REALTYPE *smps=m_voices_ptr[voice_index].OscilSmp;
1009 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1010 m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
1011 poslo+=m_osc_freq_lo_ptr[voice_index];
1012 if (poslo>=1.0) {
1013 poslo-=1.0;
1014 poshi++;
1016 poshi+=m_osc_freq_hi_ptr[voice_index];
1017 poshi&=OSCIL_SIZE-1;
1019 m_osc_pos_hi_ptr[voice_index]=poshi;
1020 m_osc_pos_lo_ptr[voice_index]=poslo;
1026 * Computes the Oscillator (Without Modulation) - CubicInterpolation
1028 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
1029 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
1030 int i,poshi;
1031 REALTYPE poslo;
1033 poshi=m_osc_pos_hi_ptr[voice_index];
1034 poslo=m_osc_pos_lo_ptr[voice_index];
1035 REALTYPE *smps=m_voices_ptr[voice_index].OscilSmp;
1036 REALTYPE xm1,x0,x1,x2,a,b,c;
1037 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1038 xm1=smps[poshi];
1039 x0=smps[poshi+1];
1040 x1=smps[poshi+2];
1041 x2=smps[poshi+3];
1042 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
1043 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
1044 c = (x1 - xm1) / 2.0;
1045 m_tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
1046 printf("a\n");
1047 //m_tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
1048 poslo+=m_osc_freq_lo_ptr[voice_index];
1049 if (poslo>=1.0) {
1050 poslo-=1.0;
1051 poshi++;
1053 poshi+=m_osc_freq_hi_ptr[voice_index];
1054 poshi&=OSCIL_SIZE-1;
1056 m_osc_pos_hi_ptr[voice_index]=poshi;
1057 m_osc_pos_lo_ptr[voice_index]=poslo;
1061 * Computes the Oscillator (Morphing)
1063 inline void ADnote::ComputeVoiceOscillatorMorph(int voice_index){
1064 int i;
1065 REALTYPE amp;
1066 ComputeVoiceOscillator_LinearInterpolation(voice_index);
1067 if (m_FM_new_amplitude_ptr[voice_index]>1.0) m_FM_new_amplitude_ptr[voice_index]=1.0;
1068 if (m_FM_old_amplitude_ptr[voice_index]>1.0) m_FM_old_amplitude_ptr[voice_index]=1.0;
1070 if (m_voices_ptr[voice_index].FMVoice>=0){
1071 //if I use VoiceOut[] as modullator
1072 int FMVoice=m_voices_ptr[voice_index].FMVoice;
1073 for (i=0;i<SOUND_BUFFER_SIZE;i++) {
1074 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1075 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1076 m_tmpwave[i]=m_tmpwave[i]*(1.0-amp)+amp*m_voices_ptr[FMVoice].VoiceOut[i];
1078 } else {
1079 int poshiFM=m_osc_pos_hi_FM_ptr[voice_index];
1080 REALTYPE posloFM=m_osc_pos_lo_FM_ptr[voice_index];
1082 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1083 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1084 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1085 m_tmpwave[i]=m_tmpwave[i]*(1.0-amp)+amp
1086 *(m_voices_ptr[voice_index].FMSmp[poshiFM]*(1-posloFM)
1087 +m_voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM);
1088 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1089 if (posloFM>=1.0) {
1090 posloFM-=1.0;
1091 poshiFM++;
1093 poshiFM+=m_osc_freq_hi_FM_ptr[voice_index];
1094 poshiFM&=OSCIL_SIZE-1;
1096 m_osc_pos_hi_FM_ptr[voice_index]=poshiFM;
1097 m_osc_pos_lo_FM_ptr[voice_index]=posloFM;
1102 * Computes the Oscillator (Ring Modulation)
1104 inline void ADnote::ComputeVoiceOscillatorRingModulation(int voice_index){
1105 int i;
1106 REALTYPE amp;
1107 ComputeVoiceOscillator_LinearInterpolation(voice_index);
1108 if (m_FM_new_amplitude_ptr[voice_index]>1.0) m_FM_new_amplitude_ptr[voice_index]=1.0;
1109 if (m_FM_old_amplitude_ptr[voice_index]>1.0) m_FM_old_amplitude_ptr[voice_index]=1.0;
1110 if (m_voices_ptr[voice_index].FMVoice>=0){
1111 // if I use VoiceOut[] as modullator
1112 for (i=0;i<SOUND_BUFFER_SIZE;i++) {
1113 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1114 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1115 int FMVoice=m_voices_ptr[voice_index].FMVoice;
1116 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1117 m_tmpwave[i]*=(1.0-amp)+amp*m_voices_ptr[FMVoice].VoiceOut[i];
1119 } else {
1120 int poshiFM=m_osc_pos_hi_FM_ptr[voice_index];
1121 REALTYPE posloFM=m_osc_pos_lo_FM_ptr[voice_index];
1123 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1124 amp=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1125 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1126 m_tmpwave[i]*=( m_voices_ptr[voice_index].FMSmp[poshiFM]*(1.0-posloFM)
1127 +m_voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM)*amp
1128 +(1.0-amp);
1129 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1130 if (posloFM>=1.0) {
1131 posloFM-=1.0;
1132 poshiFM++;
1134 poshiFM+=m_osc_freq_hi_FM_ptr[voice_index];
1135 poshiFM&=OSCIL_SIZE-1;
1137 m_osc_pos_hi_FM_ptr[voice_index]=poshiFM;
1138 m_osc_pos_lo_FM_ptr[voice_index]=posloFM;
1145 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
1147 inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int voice_index,int FMmode){
1148 int carposhi;
1149 int i,FMmodfreqhi;
1150 REALTYPE FMmodfreqlo,carposlo;
1152 if (m_voices_ptr[voice_index].FMVoice>=0){
1153 //if I use VoiceOut[] as modulator
1154 for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]=m_voices_ptr[m_voices_ptr[voice_index].FMVoice].VoiceOut[i];
1155 } else {
1156 //Compute the modulator and store it in m_tmpwave[]
1157 int poshiFM=m_osc_pos_hi_FM_ptr[voice_index];
1158 REALTYPE posloFM=m_osc_pos_lo_FM_ptr[voice_index];
1160 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1161 m_tmpwave[i]=(m_voices_ptr[voice_index].FMSmp[poshiFM]*(1.0-posloFM)
1162 +m_voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM);
1163 posloFM+=m_osc_freq_lo_FM_ptr[voice_index];
1164 if (posloFM>=1.0) {
1165 posloFM=fmod(posloFM,1.0);
1166 poshiFM++;
1168 poshiFM+=m_osc_freq_hi_FM_ptr[voice_index];
1169 poshiFM&=OSCIL_SIZE-1;
1171 m_osc_pos_hi_FM_ptr[voice_index]=poshiFM;
1172 m_osc_pos_lo_FM_ptr[voice_index]=posloFM;
1174 // Amplitude interpolation
1175 if (ABOVE_AMPLITUDE_THRESHOLD(m_FM_old_amplitude_ptr[voice_index],m_FM_new_amplitude_ptr[voice_index])){
1176 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1177 m_tmpwave[i]*=INTERPOLATE_AMPLITUDE(m_FM_old_amplitude_ptr[voice_index]
1178 ,m_FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
1180 } else for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]*=m_FM_new_amplitude_ptr[voice_index];
1183 //normalize makes all sample-rates, oscil_sizes toproduce same sound
1184 if (FMmode!=0){//Frequency modulation
1185 REALTYPE normalize = OSCIL_SIZE / 262144.0 * 44100.0 / m_synth_ptr->sample_rate;
1186 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1187 m_FM_old_smp_ptr[voice_index]=fmod(m_FM_old_smp_ptr[voice_index]+m_tmpwave[i]*normalize,OSCIL_SIZE);
1188 m_tmpwave[i]=m_FM_old_smp_ptr[voice_index];
1190 } else {//Phase modulation
1191 REALTYPE normalize=OSCIL_SIZE/262144.0;
1192 for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]*=normalize;
1195 for (i=0;i<SOUND_BUFFER_SIZE;i++){
1196 F2I(m_tmpwave[i],FMmodfreqhi);
1197 FMmodfreqlo=fmod(m_tmpwave[i]+0.0000000001,1.0);
1198 if (FMmodfreqhi<0) FMmodfreqlo++;
1200 //carrier
1201 carposhi=m_osc_pos_hi_ptr[voice_index]+FMmodfreqhi;
1202 carposlo=m_osc_pos_lo_ptr[voice_index]+FMmodfreqlo;
1204 if (carposlo>=1.0) {
1205 carposhi++;
1206 carposlo=fmod(carposlo,1.0);
1208 carposhi&=(OSCIL_SIZE-1);
1210 m_tmpwave[i]=m_voices_ptr[voice_index].OscilSmp[carposhi]*(1.0-carposlo)
1211 +m_voices_ptr[voice_index].OscilSmp[carposhi+1]*carposlo;
1213 m_osc_pos_lo_ptr[voice_index]+=m_osc_freq_lo_ptr[voice_index];
1214 if (m_osc_pos_lo_ptr[voice_index]>=1.0) {
1215 m_osc_pos_lo_ptr[voice_index]=fmod(m_osc_pos_lo_ptr[voice_index],1.0);
1216 m_osc_pos_hi_ptr[voice_index]++;
1219 m_osc_pos_hi_ptr[voice_index]+=m_osc_freq_hi_ptr[voice_index];
1220 m_osc_pos_hi_ptr[voice_index]&=OSCIL_SIZE-1;
1225 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
1226 inline void ADnote::ComputeVoiceOscillatorPitchModulation(int voice_index){
1227 //TODO
1231 * Computes the Noise
1233 inline void ADnote::ComputeVoiceNoise(int voice_index){
1235 for (int i=0;i<SOUND_BUFFER_SIZE;i++)
1237 m_tmpwave[i] = zyn_random() * 2.0 - 1.0;
1242 * Compute the ADnote samples
1244 void
1245 ADnote::noteout(
1246 REALTYPE * outl,
1247 REALTYPE * outr)
1249 int i;
1250 unsigned int voice_index;
1251 float filter_adjust;
1253 silence_two_buffers(outl, outr, SOUND_BUFFER_SIZE);
1255 if (!m_note_enabled)
1257 return;
1260 silence_two_buffers(m_bypassl, m_bypassr, SOUND_BUFFER_SIZE);
1262 computecurrentparameters();
1264 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
1266 if (!m_voices_ptr[voice_index].enabled || m_voices_ptr[voice_index].DelayTicks > 0)
1268 continue;
1271 if (!m_voices_ptr[voice_index].white_noise) //voice mode = sound
1273 switch (m_voices_ptr[voice_index].fm_type)
1275 case ZYN_FM_TYPE_MORPH:
1276 ComputeVoiceOscillatorMorph(voice_index);
1277 break;
1278 case ZYN_FM_TYPE_RING_MOD:
1279 ComputeVoiceOscillatorRingModulation(voice_index);
1280 break;
1281 case ZYN_FM_TYPE_PHASE_MOD:
1282 ComputeVoiceOscillatorFrequencyModulation(voice_index,0);
1283 break;
1284 case ZYN_FM_TYPE_FREQ_MOD:
1285 ComputeVoiceOscillatorFrequencyModulation(voice_index,1);
1286 break;
1287 #if 0
1288 case ZYN_FM_TYPE_PITCH_MOD:
1289 ComputeVoiceOscillatorPitchModulation(voice_index);
1290 break;
1291 #endif
1292 default:
1293 ComputeVoiceOscillator_LinearInterpolation(voice_index);
1294 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(voice_index);
1297 else
1299 ComputeVoiceNoise(voice_index);
1302 // Voice Processing
1304 // Amplitude
1305 if (ABOVE_AMPLITUDE_THRESHOLD(m_old_amplitude_ptr[voice_index],m_new_amplitude_ptr[voice_index])){
1306 int rest=SOUND_BUFFER_SIZE;
1307 //test if the amplitude if raising and the difference is high
1308 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)){
1309 rest=10;
1310 if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE;
1311 for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) m_tmpwave[i]*=m_old_amplitude_ptr[voice_index];
1313 // Amplitude interpolation
1314 for (i=0;i<rest;i++){
1315 m_tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(m_old_amplitude_ptr[voice_index]
1316 ,m_new_amplitude_ptr[voice_index],i,rest);
1318 } else for (i=0;i<SOUND_BUFFER_SIZE;i++) m_tmpwave[i]*=m_new_amplitude_ptr[voice_index];
1320 // Fade in
1321 if (m_first_tick_ptr[voice_index])
1323 fadein(&m_tmpwave[0]);
1324 m_first_tick_ptr[voice_index] = false;
1327 // Filter
1328 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
1330 m_voices_ptr[voice_index].m_voice_filter.filterout(&m_tmpwave[0]);
1333 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1334 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1336 if (m_voices_ptr[voice_index].m_amplitude_envelope.finished())
1338 for (i=0 ; i < SOUND_BUFFER_SIZE ; i++)
1340 m_tmpwave[i] *= 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1344 // the voice is killed later
1348 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1349 if (m_voices_ptr[voice_index].VoiceOut!=NULL)
1351 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1353 m_voices_ptr[voice_index].VoiceOut[i] = m_tmpwave[i];
1357 // Add the voice that do not bypass the filter to out
1358 if (m_voices_ptr[voice_index].filterbypass==0)
1360 // no bypass
1362 if (m_stereo)
1364 // stereo
1365 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1367 outl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*m_voices_ptr[voice_index].Panning*2.0;
1368 outr[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*(1.0-m_voices_ptr[voice_index].Panning)*2.0;
1371 else
1373 // mono
1374 for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume;
1377 else
1379 // bypass the filter
1381 if (m_stereo)
1383 // stereo
1384 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1386 m_bypassl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*m_voices_ptr[voice_index].Panning*2.0;
1387 m_bypassr[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume*(1.0-m_voices_ptr[voice_index].Panning)*2.0;
1390 else
1392 // mono
1393 for (i=0;i<SOUND_BUFFER_SIZE;i++) m_bypassl[i]+=m_tmpwave[i]*m_voices_ptr[voice_index].Volume;
1396 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1397 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1399 if (m_voices_ptr[voice_index].m_amplitude_envelope.finished())
1401 KillVoice(voice_index);
1406 // Processing Global parameters
1408 if (m_filter_category == ZYN_FILTER_TYPE_STATE_VARIABLE)
1410 filter_adjust = m_filter_envelope.envout() + m_filter_lfo.lfoout();
1412 zyn_filter_sv_process(m_filter_sv_processor_left, filter_adjust, outl);
1414 if (m_stereo)
1416 zyn_filter_sv_process(m_filter_sv_processor_right, filter_adjust, outr);
1419 else
1421 m_filter_left.filterout(&outl[0]);
1423 if (m_stereo)
1425 m_filter_right.filterout(&outr[0]);
1429 if (!m_stereo)
1431 // set the right channel=left channel
1432 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1434 outr[i]=outl[i];
1435 m_bypassr[i]=m_bypassl[i];
1439 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1441 // outl[i]+=m_bypassl[i];
1442 // outr[i]+=m_bypassr[i];
1445 if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude))
1447 // Amplitude Interpolation
1448 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1450 REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude, globalnewamplitude, i, SOUND_BUFFER_SIZE);
1451 outl[i] *= tmpvol * (1.0 - m_panning);
1452 outr[i] *= tmpvol * m_panning;
1455 else
1457 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1459 outl[i] *= globalnewamplitude * (1.0 - m_panning);
1460 outr[i] *= globalnewamplitude * m_panning;
1464 // Apply the punch
1465 if (m_punch_enabled)
1467 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1469 REALTYPE punchamp = m_punch_initial_value * m_punch_t + 1.0;
1470 outl[i] *= punchamp;
1471 outr[i] *= punchamp;
1472 m_punch_t -= m_punch_duration;
1473 if (m_punch_t < 0.0)
1475 m_punch_enabled = false;
1476 break;
1481 // Check if the global amplitude is finished.
1482 // If it does, disable the note
1483 if (m_amplitude_envelope.finished())
1485 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1487 // fade-out
1489 REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1491 outl[i] *= tmp;
1492 outr[i] *= tmp;
1495 force_disable();
1500 * Relase the key (NoteOff)
1502 void ADnote::relasekey()
1504 unsigned int voice_index;
1506 for (voice_index = 0 ; voice_index < m_synth_ptr->voices_count ; voice_index++)
1508 if (!m_voices_ptr[voice_index].enabled)
1510 continue;
1513 if (m_synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1515 m_voices_ptr[voice_index].m_amplitude_envelope.relasekey();
1518 if (m_synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled)
1520 m_voices_ptr[voice_index].m_frequency_envelope.relasekey();
1523 if (m_synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled)
1525 m_voices_ptr[voice_index].m_filter_envelope.relasekey();
1528 if (m_synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled)
1530 m_voices_ptr[voice_index].m_fm_frequency_envelope.relasekey();
1533 if (m_synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled)
1535 m_voices_ptr[voice_index].m_fm_amplitude_envelope.relasekey();
1539 m_frequency_envelope.relasekey();
1540 m_filter_envelope.relasekey();
1541 m_amplitude_envelope.relasekey();
1545 * Check if the note is finished
1547 bool
1548 ADnote::finished()
1550 return !m_note_enabled;