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
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"
47 #define LOG_LEVEL LOG_LEVEL_ERROR
50 /***********************************************************/
51 /* VOICE PARAMETERS */
52 /***********************************************************/
55 /* If the voice is enabled */
58 /* Voice Type (sound/noise)*/
67 /* Waveform of the Voice */
68 zyn_sample_type
* 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
;
82 /***************************
83 * AMPLITUDE PARAMETERS *
84 ***************************/
86 /* Panning 0.0=left, 0.5 - center, 1.0 = right */
88 REALTYPE Volume
;// [-1.0 .. 1.0]
90 Envelope m_amplitude_envelope
;
93 /*************************
95 *************************/
97 Filter m_voice_filter
;
99 REALTYPE FilterCenterPitch
;/* Filter center Pitch*/
100 REALTYPE FilterFreqTracking
;
102 Envelope m_filter_envelope
;
105 /****************************
106 * MODULLATOR PARAMETERS *
107 ****************************/
109 unsigned int fm_type
;
113 // Voice Output used by other voices if use this as modullator
114 zyn_sample_type
* VoiceOut
;
116 /* Wave of the Voice */
117 zyn_sample_type
* FMSmp
;
120 REALTYPE FMDetune
; //in cents
122 Envelope m_fm_frequency_envelope
;
123 Envelope m_fm_amplitude_envelope
;
127 #define FM_AMP_MULTIPLIER 14.71280603
129 #define OSCIL_SMP_EXTRA_SAMPLES 5
135 bool stereo
; // if the note is stereo (allows note Panning)
142 /***********************************************************/
143 /* VOICE PARAMETERS */
144 /***********************************************************/
145 struct addsynth_voice
* voices_ptr
; // array with one entry per voice
147 /********************************************************/
148 /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */
149 /********************************************************/
151 // time from the start of the note
154 // fractional part (skip)
155 float * osc_pos_lo_ptr
; // array with one entry per voice
156 float * osc_freq_lo_ptr
; // array with one entry per voice
158 // integer part (skip)
159 int * osc_pos_hi_ptr
; // array with one entry per voice
160 int * osc_freq_hi_ptr
; // array with one entry per voice
162 // fractional part (skip) of the Modullator
163 float * osc_pos_lo_FM_ptr
; // array with one entry per voice
164 float * osc_freq_lo_FM_ptr
; // array with one entry per voice
166 // integer part (skip) of the Modullator
167 unsigned short int * osc_pos_hi_FM_ptr
; // array with one entry per voice
168 unsigned short int * osc_freq_hi_FM_ptr
; // array with one entry per voice
170 // used to compute and interpolate the amplitudes of voices and modullators
171 float * old_amplitude_ptr
; // array with one entry per voice
172 float * new_amplitude_ptr
; // array with one entry per voice
173 float * FM_old_amplitude_ptr
; // array with one entry per voice
174 float * FM_new_amplitude_ptr
; // array with one entry per voice
176 // used by Frequency Modulation (for integration)
177 float * FM_old_smp_ptr
; // array with one entry per voice
180 zyn_sample_type
* tmpwave
;
182 //Filter bypass samples
183 zyn_sample_type
* bypassl
;
184 zyn_sample_type
* bypassr
;
186 //interpolate the amplitudes
187 REALTYPE globaloldamplitude
;
188 REALTYPE globalnewamplitude
;
190 // whether it is the first tick (used to fade in the sound)
191 bool * first_tick_ptr
; // array with one entry per voice
193 // whether note has portamento
196 //how the fine detunes are made bigger or smaller
197 REALTYPE bandwidth_detune_multiplier
;
203 int filter_category
; // One of ZYN_FILTER_TYPE_XXX
206 zyn_filter_processor_handle filter_sv_processor_left
;
207 zyn_filter_processor_handle filter_sv_processor_right
;
209 float filter_center_pitch
; // octaves
210 float filter_q_factor
;
212 Envelope amplitude_envelope
;
213 Envelope filter_envelope
;
214 Envelope frequency_envelope
;
216 float detune
; // cents
218 struct zyn_addsynth
* synth_ptr
;
220 float volume
; // [ 0 .. 1 ]
222 float panning
; // [ 0 .. 1 ]
225 float punch_initial_value
;
226 float punch_duration
;
232 struct zyn_addsynth
* synth_ptr
,
233 zyn_addnote_handle
* handle_ptr
)
235 struct addnote
* note_ptr
;
236 unsigned int voice_index
;
238 // we still need to use C++ allocation because some constructors need to be invoked
239 // For example, AnalogFilter has virtual methods
240 note_ptr
= new addnote
;
241 if (note_ptr
== NULL
)
246 note_ptr
->tmpwave
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
247 note_ptr
->bypassl
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
248 note_ptr
->bypassr
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
250 note_ptr
->voices_ptr
= (struct addsynth_voice
*)malloc(sizeof(struct addsynth_voice
) * synth_ptr
->voices_count
);
251 for (voice_index
= 0 ; voice_index
< synth_ptr
->voices_count
; voice_index
++)
253 // the extra points contains the first point
254 note_ptr
->voices_ptr
[voice_index
].OscilSmp
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * (OSCIL_SIZE
+ OSCIL_SMP_EXTRA_SAMPLES
));
255 note_ptr
->voices_ptr
[voice_index
].FMSmp
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * (OSCIL_SIZE
+ OSCIL_SMP_EXTRA_SAMPLES
));
256 note_ptr
->voices_ptr
[voice_index
].VoiceOut
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
259 note_ptr
->osc_pos_hi_ptr
= (int *)malloc(sizeof(int) * synth_ptr
->voices_count
);
260 note_ptr
->osc_pos_lo_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
261 note_ptr
->osc_pos_hi_FM_ptr
= (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr
->voices_count
);
262 note_ptr
->osc_pos_lo_FM_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
264 note_ptr
->osc_freq_hi_ptr
= (int *)malloc(sizeof(int) * synth_ptr
->voices_count
);
265 note_ptr
->osc_freq_lo_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
266 note_ptr
->osc_freq_hi_FM_ptr
= (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr
->voices_count
);
267 note_ptr
->osc_freq_lo_FM_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
269 note_ptr
->FM_old_smp_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
271 note_ptr
->first_tick_ptr
= (bool *)malloc(sizeof(bool) * synth_ptr
->voices_count
);
273 note_ptr
->old_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
274 note_ptr
->new_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
276 note_ptr
->FM_old_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
277 note_ptr
->FM_new_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
279 note_ptr
->stereo
= synth_ptr
->stereo
;
281 note_ptr
->detune
= getdetune(
282 synth_ptr
->GlobalPar
.PDetuneType
,
283 synth_ptr
->GlobalPar
.PCoarseDetune
,
284 synth_ptr
->GlobalPar
.PDetune
);
287 * Get the Multiplier of the fine detunes of the voices
289 note_ptr
->bandwidth_detune_multiplier
= (synth_ptr
->GlobalPar
.PBandwidth
- 64.0) / 64.0;
290 note_ptr
->bandwidth_detune_multiplier
=
293 note_ptr
->bandwidth_detune_multiplier
* pow(fabs(note_ptr
->bandwidth_detune_multiplier
), 0.2) * 5.0);
295 note_ptr
->note_enabled
= false;
297 note_ptr
->synth_ptr
= synth_ptr
;
299 if (!zyn_filter_sv_processor_create(synth_ptr
->filter_sv
, ¬e_ptr
->filter_sv_processor_left
))
303 if (!zyn_filter_sv_processor_create(synth_ptr
->filter_sv
, ¬e_ptr
->filter_sv_processor_right
))
307 *handle_ptr
= (zyn_addnote_handle
)note_ptr
;
312 * Get Voice base frequency
318 struct addnote
* note_ptr
,
323 detune
= note_ptr
->voices_ptr
[nvoice
].Detune
/ 100.0;
324 detune
+= note_ptr
->voices_ptr
[nvoice
].FineDetune
/ 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
* note_ptr
->bandwidth_detune_multiplier
;
325 detune
+= note_ptr
->detune
/ 100.0;
327 if (note_ptr
->voices_ptr
[nvoice
].fixedfreq
== 0)
329 return note_ptr
->basefreq
* pow(2, detune
/ 12.0);
333 // the fixed freq is enabled
334 REALTYPE fixedfreq
= 440.0;
335 int fixedfreqET
= note_ptr
->voices_ptr
[nvoice
].fixedfreqET
;
338 // if the frequency varies according the keyboard note
339 REALTYPE tmp
= (note_ptr
->midinote
- 69.0) / 12.0 * (pow(2.0,(fixedfreqET
-1)/63.0) - 1.0);
340 if (fixedfreqET
<= 64)
342 fixedfreq
*= pow(2.0,tmp
);
346 fixedfreq
*= pow(3.0,tmp
);
350 return fixedfreq
* pow(2.0, detune
/ 12.0);
355 * Get Voice's Modullator base frequency
361 struct addnote
* note_ptr
,
364 REALTYPE detune
= note_ptr
->voices_ptr
[nvoice
].FMDetune
/ 100.0;
365 return getvoicebasefreq(note_ptr
, nvoice
) * pow(2, detune
/ 12.0);
369 * Kill a voice of ADnote
375 struct addnote
* note_ptr
,
376 unsigned int voice_index
)
378 // silence the voice, perhaps is used by another voice
379 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
381 note_ptr
->voices_ptr
[voice_index
].enabled
= false;
385 * Computes the frequency of an oscillator
391 struct addnote
* note_ptr
,
399 speed
= freq
* REALTYPE(OSCIL_SIZE
) / note_ptr
->synth_ptr
->sample_rate
;
400 if (speed
> OSCIL_SIZE
)
405 F2I(speed
, note_ptr
->osc_freq_hi_ptr
[nvoice
]);
407 note_ptr
->osc_freq_lo_ptr
[nvoice
] = speed
- floor(speed
);
411 * Computes the frequency of an modullator oscillator
417 struct addnote
* note_ptr
,
425 speed
= freq
* REALTYPE(OSCIL_SIZE
) / note_ptr
->synth_ptr
->sample_rate
;
426 if (speed
> OSCIL_SIZE
)
431 F2I(speed
, note_ptr
->osc_freq_hi_FM_ptr
[nvoice
]);
432 note_ptr
->osc_freq_lo_FM_ptr
[nvoice
] = speed
- floor(speed
);
436 * Fadein in a way that removes clicks but keep sound "punchy"
442 struct addnote
* note_ptr
,
451 for (i
= 1 ; i
< SOUND_BUFFER_SIZE
; i
++)
453 if ((smps
[i
- 1] < 0.0) && (smps
[i
] > 0.0))
455 // this is only the possitive crossings
460 tmp
= (SOUND_BUFFER_SIZE
- 1.0) / (zerocrossings
+ 1) / 3.0;
466 F2I(tmp
, n
); // how many samples is the fade-in
468 if (n
> SOUND_BUFFER_SIZE
)
470 n
= SOUND_BUFFER_SIZE
;
473 for (i
= 0 ; i
< n
; i
++)
476 tmp
= 0.5 - cos((REALTYPE
)i
/ (REALTYPE
)n
* PI
) * 0.5;
482 * Computes the Oscillator (Without Modulation) - LinearInterpolation
487 ComputeVoiceOscillator_LinearInterpolation(
488 struct addnote
* note_ptr
,
494 poshi
= note_ptr
->osc_pos_hi_ptr
[voice_index
];
495 poslo
= note_ptr
->osc_pos_lo_ptr
[voice_index
];
496 REALTYPE
* smps
= note_ptr
->voices_ptr
[voice_index
].OscilSmp
;
498 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
500 note_ptr
->tmpwave
[i
] = smps
[poshi
] * (1.0 - poslo
) + smps
[poshi
+ 1] * poslo
;
501 poslo
+= note_ptr
->osc_freq_lo_ptr
[voice_index
];
509 poshi
+= note_ptr
->osc_freq_hi_ptr
[voice_index
];
510 poshi
&= OSCIL_SIZE
- 1;
513 note_ptr
->osc_pos_hi_ptr
[voice_index
] = poshi
;
514 note_ptr
->osc_pos_lo_ptr
[voice_index
] = poslo
;
520 * Computes the Oscillator (Without Modulation) - CubicInterpolation
522 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
523 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
527 poshi=note_ptr->osc_pos_hi_ptr[voice_index];
528 poslo=note_ptr->osc_pos_lo_ptr[voice_index];
529 REALTYPE *smps=note_ptr->voices_ptr[voice_index].OscilSmp;
530 REALTYPE xm1,x0,x1,x2,a,b,c;
531 for (i=0;i<SOUND_BUFFER_SIZE;i++){
536 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
537 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
538 c = (x1 - xm1) / 2.0;
539 note_ptr->tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
541 //note_ptr->tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
542 poslo+=note_ptr->osc_freq_lo_ptr[voice_index];
547 poshi+=note_ptr->osc_freq_hi_ptr[voice_index];
550 note_ptr->osc_pos_hi_ptr[voice_index]=poshi;
551 note_ptr->osc_pos_lo_ptr[voice_index]=poslo;
556 * Computes the Oscillator (Morphing)
561 ComputeVoiceOscillatorMorph(
562 struct addnote
* note_ptr
,
568 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
570 if (note_ptr
->FM_new_amplitude_ptr
[voice_index
] > 1.0)
572 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = 1.0;
575 if (note_ptr
->FM_old_amplitude_ptr
[voice_index
] > 1.0)
577 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = 1.0;
580 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>= 0)
582 //if I use VoiceOut[] as modullator
583 int FMVoice
= note_ptr
->voices_ptr
[voice_index
].FMVoice
;
584 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
586 amp
= INTERPOLATE_AMPLITUDE(
587 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
588 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
592 note_ptr
->tmpwave
[i
] = note_ptr
->tmpwave
[i
] * (1.0 - amp
) + amp
* note_ptr
->voices_ptr
[FMVoice
].VoiceOut
[i
];
597 int poshiFM
= note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
598 REALTYPE posloFM
= note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
600 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
602 amp
= INTERPOLATE_AMPLITUDE(
603 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
604 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
608 note_ptr
->tmpwave
[i
] = note_ptr
->tmpwave
[i
] * (1.0 - amp
) + amp
* (note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
] * (1 - posloFM
) + note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
+ 1] * posloFM
);
610 posloFM
+= note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
618 poshiFM
+= note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
619 poshiFM
&= OSCIL_SIZE
- 1;
622 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = poshiFM
;
623 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = posloFM
;
628 * Computes the Oscillator (Ring Modulation)
633 ComputeVoiceOscillatorRingModulation(
634 struct addnote
* note_ptr
,
640 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
642 if (note_ptr
->FM_new_amplitude_ptr
[voice_index
] > 1.0)
644 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = 1.0;
647 if (note_ptr
->FM_old_amplitude_ptr
[voice_index
] > 1.0)
649 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = 1.0;
652 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>= 0)
654 // if I use VoiceOut[] as modullator
655 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
657 amp
= INTERPOLATE_AMPLITUDE(
658 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
659 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
663 int FMVoice
= note_ptr
->voices_ptr
[voice_index
].FMVoice
;
665 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
667 note_ptr
->tmpwave
[i
] *= (1.0 - amp
) + amp
* note_ptr
->voices_ptr
[FMVoice
].VoiceOut
[i
];
673 int poshiFM
=note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
674 REALTYPE posloFM
=note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
676 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
678 amp
= INTERPOLATE_AMPLITUDE(note_ptr
->FM_old_amplitude_ptr
[voice_index
], note_ptr
->FM_new_amplitude_ptr
[voice_index
], i
, SOUND_BUFFER_SIZE
);
679 note_ptr
->tmpwave
[i
] *= (note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
] * (1.0 - posloFM
) + note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
+ 1] * posloFM
) * amp
+ (1.0 - amp
);
681 posloFM
+= note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
689 poshiFM
+= note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
690 poshiFM
&= OSCIL_SIZE
-1;
693 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = poshiFM
;
694 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = posloFM
;
699 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
704 ComputeVoiceOscillatorFrequencyModulation(
705 struct addnote
* note_ptr
,
711 REALTYPE FMmodfreqlo
,carposlo
;
713 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>=0){
714 //if I use VoiceOut[] as modulator
715 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]=note_ptr
->voices_ptr
[note_ptr
->voices_ptr
[voice_index
].FMVoice
].VoiceOut
[i
];
717 //Compute the modulator and store it in note_ptr->tmpwave[]
718 int poshiFM
=note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
719 REALTYPE posloFM
=note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
721 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
722 note_ptr
->tmpwave
[i
]=(note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
]*(1.0-posloFM
)
723 +note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
+1]*posloFM
);
724 posloFM
+=note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
726 posloFM
=fmod(posloFM
,1.0);
729 poshiFM
+=note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
730 poshiFM
&=OSCIL_SIZE
-1;
732 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
]=poshiFM
;
733 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
]=posloFM
;
735 // Amplitude interpolation
736 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->FM_old_amplitude_ptr
[voice_index
],note_ptr
->FM_new_amplitude_ptr
[voice_index
])){
737 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
738 note_ptr
->tmpwave
[i
]*=INTERPOLATE_AMPLITUDE(note_ptr
->FM_old_amplitude_ptr
[voice_index
]
739 ,note_ptr
->FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
741 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->FM_new_amplitude_ptr
[voice_index
];
744 //normalize makes all sample-rates, oscil_sizes toproduce same sound
745 if (FMmode
!=0){//Frequency modulation
746 REALTYPE normalize
= OSCIL_SIZE
/ 262144.0 * 44100.0 / note_ptr
->synth_ptr
->sample_rate
;
747 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
748 note_ptr
->FM_old_smp_ptr
[voice_index
]=fmod(note_ptr
->FM_old_smp_ptr
[voice_index
]+note_ptr
->tmpwave
[i
]*normalize
,OSCIL_SIZE
);
749 note_ptr
->tmpwave
[i
]=note_ptr
->FM_old_smp_ptr
[voice_index
];
751 } else {//Phase modulation
752 REALTYPE normalize
=OSCIL_SIZE
/262144.0;
753 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=normalize
;
756 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
757 F2I(note_ptr
->tmpwave
[i
],FMmodfreqhi
);
758 FMmodfreqlo
=fmod(note_ptr
->tmpwave
[i
]+0.0000000001,1.0);
759 if (FMmodfreqhi
<0) FMmodfreqlo
++;
762 carposhi
=note_ptr
->osc_pos_hi_ptr
[voice_index
]+FMmodfreqhi
;
763 carposlo
=note_ptr
->osc_pos_lo_ptr
[voice_index
]+FMmodfreqlo
;
767 carposlo
=fmod(carposlo
,1.0);
769 carposhi
&=(OSCIL_SIZE
-1);
771 note_ptr
->tmpwave
[i
]=note_ptr
->voices_ptr
[voice_index
].OscilSmp
[carposhi
]*(1.0-carposlo
)
772 +note_ptr
->voices_ptr
[voice_index
].OscilSmp
[carposhi
+1]*carposlo
;
774 note_ptr
->osc_pos_lo_ptr
[voice_index
]+=note_ptr
->osc_freq_lo_ptr
[voice_index
];
775 if (note_ptr
->osc_pos_lo_ptr
[voice_index
]>=1.0) {
776 note_ptr
->osc_pos_lo_ptr
[voice_index
]=fmod(note_ptr
->osc_pos_lo_ptr
[voice_index
],1.0);
777 note_ptr
->osc_pos_hi_ptr
[voice_index
]++;
780 note_ptr
->osc_pos_hi_ptr
[voice_index
]+=note_ptr
->osc_freq_hi_ptr
[voice_index
];
781 note_ptr
->osc_pos_hi_ptr
[voice_index
]&=OSCIL_SIZE
-1;
786 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
790 ComputeVoiceOscillatorPitchModulation(
791 struct addnote
* note_ptr
,
805 struct addnote
* note_ptr
,
808 for (int i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
810 note_ptr
->tmpwave
[i
] = zyn_random() * 2.0 - 1.0;
814 #define note_ptr ((struct addnote *)handle)
818 zyn_addnote_handle handle
,
820 bool random_grouping
,
826 unsigned int voice_index
;
828 float filter_velocity_adjust
;
829 int voice_oscillator_index
;
832 note_ptr
->portamento
= portamento
;
833 note_ptr
->midinote
= midinote
;
834 note_ptr
->note_enabled
= true;
835 note_ptr
->basefreq
= freq
;
839 note_ptr
->velocity
= 1.0;
843 note_ptr
->velocity
= velocity
;
846 note_ptr
->time
= 0.0;
848 note_ptr
->panning
= (panorama
+ 1.0) / 2; // -1..1 -> 0 - 1
850 note_ptr
->filter_category
= note_ptr
->synth_ptr
->filter_type
;
852 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
854 filter_velocity_adjust
= note_ptr
->synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
855 (zyn_velocity_scale(note_ptr
->velocity
, note_ptr
->synth_ptr
->m_filter_velocity_scale_function
) - 1);
857 zyn_filter_sv_processor_init(note_ptr
->filter_sv_processor_left
, freq
, filter_velocity_adjust
);
858 if (note_ptr
->stereo
)
860 zyn_filter_sv_processor_init(note_ptr
->filter_sv_processor_right
, freq
, filter_velocity_adjust
);
865 note_ptr
->filter_center_pitch
=
866 note_ptr
->synth_ptr
->m_filter_params
.getfreq() + // center freq
867 note_ptr
->synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
868 (zyn_velocity_scale(note_ptr
->velocity
, note_ptr
->synth_ptr
->m_filter_velocity_scale_function
) - 1);
869 note_ptr
->filter_center_pitch
+= note_ptr
->synth_ptr
->m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
872 if (note_ptr
->synth_ptr
->GlobalPar
.PPunchStrength
!= 0)
874 note_ptr
->punch_enabled
= true;
875 note_ptr
->punch_t
= 1.0; // start from 1.0 and to 0.0
876 note_ptr
->punch_initial_value
= pow(10, 1.5 * note_ptr
->synth_ptr
->GlobalPar
.PPunchStrength
/ 127.0) - 1.0;
877 note_ptr
->punch_initial_value
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->GlobalPar
.PPunchVelocitySensing
);
879 REALTYPE time
= pow(10, 3.0 * note_ptr
->synth_ptr
->GlobalPar
.PPunchTime
/ 127.0) / 10000.0; // 0.1 .. 100 ms
881 REALTYPE stretch
= pow(440.0/freq
, note_ptr
->synth_ptr
->GlobalPar
.PPunchStretch
/ 64.0);
883 note_ptr
->punch_duration
= 1.0 / (time
* note_ptr
->synth_ptr
->sample_rate
* stretch
);
887 note_ptr
->punch_enabled
= false;
890 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
892 zyn_oscillator_new_rand_seed(
893 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].oscillator
,
896 note_ptr
->voices_ptr
[voice_index
].FMVoice
= -1;
898 if (!note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].enabled
)
900 note_ptr
->voices_ptr
[voice_index
].enabled
= false;
901 continue; // the voice is disabled
904 note_ptr
->voices_ptr
[voice_index
].enabled
= true;
905 note_ptr
->voices_ptr
[voice_index
].fixedfreq
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pfixedfreq
;
906 note_ptr
->voices_ptr
[voice_index
].fixedfreqET
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PfixedfreqET
;
908 // use the Globalpars.detunetype if the detunetype is 0
909 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
!= 0)
912 note_ptr
->voices_ptr
[voice_index
].Detune
=
914 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
,
915 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PCoarseDetune
,
919 note_ptr
->voices_ptr
[voice_index
].FineDetune
=
921 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PDetuneType
,
923 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PDetune
);
928 note_ptr
->voices_ptr
[voice_index
].Detune
= getdetune(
929 note_ptr
->synth_ptr
->GlobalPar
.PDetuneType
,
930 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PCoarseDetune
,
934 note_ptr
->voices_ptr
[voice_index
].FineDetune
= getdetune(
935 note_ptr
->synth_ptr
->GlobalPar
.PDetuneType
,
937 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PDetune
);
940 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMDetuneType
!= 0)
942 note_ptr
->voices_ptr
[voice_index
].FMDetune
=
944 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMDetuneType
,
945 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMCoarseDetune
,
946 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMDetune
);
950 note_ptr
->voices_ptr
[voice_index
].FMDetune
= getdetune(
951 note_ptr
->synth_ptr
->GlobalPar
.PDetuneType
,
952 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMCoarseDetune
,
953 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMDetune
);
956 note_ptr
->osc_pos_hi_ptr
[voice_index
] = 0;
957 note_ptr
->osc_pos_lo_ptr
[voice_index
] = 0.0;
958 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = 0;
959 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = 0.0;
961 // Get the voice's oscil or external's voice oscil
962 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
!= -1)
964 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
;
968 voice_oscillator_index
= voice_index
;
971 if (!random_grouping
)
973 zyn_oscillator_new_rand_seed(
974 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
978 note_ptr
->osc_pos_hi_ptr
[voice_index
] =
980 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
981 note_ptr
->voices_ptr
[voice_index
].OscilSmp
,
982 getvoicebasefreq(note_ptr
, voice_index
),
983 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].resonance
);
985 // I store the first elments to the last position for speedups
986 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
988 note_ptr
->voices_ptr
[voice_index
].OscilSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].OscilSmp
[i
];
991 note_ptr
->osc_pos_hi_ptr
[voice_index
] += (int)((note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Poscilphase
- 64.0) / 128.0 * OSCIL_SIZE
+ OSCIL_SIZE
* 4);
992 note_ptr
->osc_pos_hi_ptr
[voice_index
] %= OSCIL_SIZE
;
994 note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreq();
995 note_ptr
->voices_ptr
[voice_index
].filterbypass
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pfilterbypass
;
997 note_ptr
->voices_ptr
[voice_index
].fm_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_type
;
999 note_ptr
->voices_ptr
[voice_index
].FMVoice
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVoice
;
1001 // Compute the Voice's modulator volume (incl. damping)
1002 REALTYPE fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0 - 1.0);
1003 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1005 case ZYN_FM_TYPE_PHASE_MOD
:
1006 fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0);
1007 note_ptr
->voices_ptr
[voice_index
].FMVolume
= (exp(note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * FM_AMP_MULTIPLIER
) - 1.0) * fmvoldamp
* 4.0;
1009 case ZYN_FM_TYPE_FREQ_MOD
:
1010 note_ptr
->voices_ptr
[voice_index
].FMVolume
= exp(note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * FM_AMP_MULTIPLIER
);
1011 note_ptr
->voices_ptr
[voice_index
].FMVolume
-= 1.0;
1012 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= fmvoldamp
* 4.0;
1014 #if 0 // ???????????
1015 case ZYN_FM_TYPE_PITCH_MOD
:
1016 note_ptr
->voices_ptr
[voice_index
].FMVolume
= (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * 8.0) * fmvoldamp
;
1020 if (fmvoldamp
> 1.0)
1025 note_ptr
->voices_ptr
[voice_index
].FMVolume
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * fmvoldamp
;
1028 // Voice's modulator velocity sensing
1029 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVelocityScaleFunction
);
1031 note_ptr
->FM_old_smp_ptr
[voice_index
] = 0.0; // this is for FM (integration)
1033 note_ptr
->first_tick_ptr
[voice_index
] = true;
1034 note_ptr
->voices_ptr
[voice_index
].DelayTicks
= (int)((exp(note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PDelay
/ 127.0 * log(50.0)) - 1.0) / SOUND_BUFFER_SIZE
/ 10.0 * note_ptr
->synth_ptr
->sample_rate
);
1037 // Global Parameters
1038 note_ptr
->frequency_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_frequency_envelope_params
, note_ptr
->basefreq
);
1040 note_ptr
->frequency_lfo
.init(
1041 note_ptr
->synth_ptr
->sample_rate
,
1043 ¬e_ptr
->synth_ptr
->frequency_lfo_params
,
1044 ZYN_LFO_TYPE_FREQUENCY
);
1046 note_ptr
->amplitude_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_amplitude_envelope_params
, note_ptr
->basefreq
);
1048 note_ptr
->amplitude_lfo
.init(
1049 note_ptr
->synth_ptr
->sample_rate
,
1051 ¬e_ptr
->synth_ptr
->amplitude_lfo_params
,
1052 ZYN_LFO_TYPE_AMPLITUDE
);
1054 note_ptr
->volume
= 4.0 * pow(0.1, 3.0 * (1.0 - note_ptr
->synth_ptr
->GlobalPar
.PVolume
/ 96.0)); // -60 dB .. 0 dB
1055 note_ptr
->volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->GlobalPar
.PAmpVelocityScaleFunction
); // velocity sensing
1057 note_ptr
->amplitude_envelope
.envout_dB(); // discard the first envelope output
1059 note_ptr
->globalnewamplitude
= note_ptr
->volume
* note_ptr
->amplitude_envelope
.envout_dB() * note_ptr
->amplitude_lfo
.amplfoout();
1061 note_ptr
->filter_left
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1062 if (note_ptr
->stereo
)
1064 note_ptr
->filter_right
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1067 note_ptr
->filter_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_envelope_params
, note_ptr
->basefreq
);
1069 note_ptr
->filter_lfo
.init(
1070 note_ptr
->synth_ptr
->sample_rate
,
1072 ¬e_ptr
->synth_ptr
->filter_lfo_params
,
1073 ZYN_LFO_TYPE_FILTER
);
1075 note_ptr
->filter_q_factor
= note_ptr
->synth_ptr
->m_filter_params
.getq();
1077 // Forbids the Modulation Voice to be greater or equal than voice
1078 for (i
= 0 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1080 if (note_ptr
->voices_ptr
[i
].FMVoice
>= (int)i
)
1082 note_ptr
->voices_ptr
[i
].FMVoice
= -1;
1086 // Voice Parameter init
1087 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1089 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1094 LOG_DEBUG("Starting %s voice (%u, %p)", note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].white_noise
? "white noise" : "signal", voice_index
, note_ptr
->synth_ptr
->voices_params_ptr
+ voice_index
);
1096 note_ptr
->voices_ptr
[voice_index
].white_noise
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].white_noise
;
1098 /* Voice Amplitude Parameters Init */
1100 note_ptr
->voices_ptr
[voice_index
].Volume
= pow(0.1, 3.0 * (1.0 - note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PVolume
/ 127.0)); // -60 dB .. 0 dB
1101 note_ptr
->voices_ptr
[voice_index
].Volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpVelocityScaleFunction
); // velocity
1103 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PVolumeminus
!= 0)
1105 note_ptr
->voices_ptr
[voice_index
].Volume
= -note_ptr
->voices_ptr
[voice_index
].Volume
;
1108 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
== 0)
1110 note_ptr
->voices_ptr
[voice_index
].Panning
= zyn_random(); // random panning
1114 note_ptr
->voices_ptr
[voice_index
].Panning
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
/ 128.0;
1117 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1118 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
!= 0)
1120 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.init(
1121 note_ptr
->synth_ptr
->sample_rate
,
1122 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_amplitude_envelope_params
,
1123 note_ptr
->basefreq
);
1125 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB(); // discard the first envelope sample
1126 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1129 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
!= 0)
1131 note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.init(
1132 note_ptr
->synth_ptr
->sample_rate
,
1134 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].amplitude_lfo_params
,
1135 ZYN_LFO_TYPE_AMPLITUDE
);
1137 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1140 /* Voice Frequency Parameters Init */
1141 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
!= 0)
1143 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.init(
1144 note_ptr
->synth_ptr
->sample_rate
,
1145 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_frequency_envelope_params
,
1146 note_ptr
->basefreq
);
1149 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
!= 0)
1151 note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.init(
1152 note_ptr
->synth_ptr
->sample_rate
,
1154 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].frequency_lfo_params
,
1155 ZYN_LFO_TYPE_FREQUENCY
);
1158 /* Voice Filter Parameters Init */
1159 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
!= 0)
1161 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.init(
1162 note_ptr
->synth_ptr
->sample_rate
,
1163 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
);
1166 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
!= 0)
1168 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.init(
1169 note_ptr
->synth_ptr
->sample_rate
,
1170 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_envelope_params
,
1171 note_ptr
->basefreq
);
1174 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
!= 0)
1176 note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.init(
1177 note_ptr
->synth_ptr
->sample_rate
,
1179 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].filter_lfo_params
,
1180 ZYN_LFO_TYPE_FILTER
);
1183 note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
1185 /* Voice Modulation Parameters Init */
1186 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
&&
1187 note_ptr
->voices_ptr
[voice_index
].FMVoice
< 0)
1189 zyn_oscillator_new_rand_seed(
1190 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].modulator_oscillator
,
1193 // Perform Anti-aliasing only on MORPH or RING MODULATION
1195 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
!= -1)
1197 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
;
1201 voice_oscillator_index
= voice_index
;
1204 if ((note_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
.Padaptiveharmonics
!= 0) ||
1205 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_MORPH
) ||
1206 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_RING_MOD
))
1208 tmp
= getFMvoicebasefreq(note_ptr
, voice_index
);
1215 if (!random_grouping
)
1217 zyn_oscillator_new_rand_seed(
1218 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1222 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = note_ptr
->osc_pos_hi_ptr
[voice_index
];
1223 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] += zyn_oscillator_get(
1224 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1225 note_ptr
->voices_ptr
[voice_index
].FMSmp
,
1228 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1230 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
1232 note_ptr
->voices_ptr
[voice_index
].FMSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].FMSmp
[i
];
1235 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] += (int)((note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMoscilphase
- 64.0) / 128.0 * OSCIL_SIZE
+ OSCIL_SIZE
* 4);
1236 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1239 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
!= 0)
1241 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.init(
1242 note_ptr
->synth_ptr
->sample_rate
,
1243 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_frequency_envelope_params
,
1244 note_ptr
->basefreq
);
1247 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1248 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1250 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
!= 0)
1252 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.init(
1253 note_ptr
->synth_ptr
->sample_rate
,
1254 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_amplitude_envelope_params
,
1255 note_ptr
->basefreq
);
1257 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1259 } // voice parameter init loop
1261 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1263 for (i
= voice_index
+ 1 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1265 if (note_ptr
->voices_ptr
[i
].FMVoice
== (int)voice_index
)
1267 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
1277 zyn_addnote_force_disable(
1278 zyn_addnote_handle handle
)
1280 unsigned int voice_index
;
1282 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1284 if (note_ptr
->voices_ptr
[voice_index
].enabled
)
1286 kill_voice(note_ptr
, voice_index
);
1290 note_ptr
->note_enabled
= false;
1294 zyn_addnote_destroy(
1295 zyn_addnote_handle handle
)
1297 unsigned int voice_index
;
1299 if (note_ptr
->note_enabled
)
1301 zyn_addnote_force_disable(handle
);
1304 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_left
);
1305 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_right
);
1307 free(note_ptr
->old_amplitude_ptr
);
1308 free(note_ptr
->new_amplitude_ptr
);
1310 free(note_ptr
->FM_old_amplitude_ptr
);
1311 free(note_ptr
->FM_new_amplitude_ptr
);
1313 free(note_ptr
->first_tick_ptr
);
1315 free(note_ptr
->FM_old_smp_ptr
);
1317 free(note_ptr
->osc_freq_hi_ptr
);
1318 free(note_ptr
->osc_freq_lo_ptr
);
1319 free(note_ptr
->osc_freq_hi_FM_ptr
);
1320 free(note_ptr
->osc_freq_lo_FM_ptr
);
1322 free(note_ptr
->osc_pos_hi_ptr
);
1323 free(note_ptr
->osc_pos_lo_ptr
);
1324 free(note_ptr
->osc_pos_hi_FM_ptr
);
1325 free(note_ptr
->osc_pos_lo_FM_ptr
);
1327 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1329 // the extra points contains the first point
1330 free(note_ptr
->voices_ptr
[voice_index
].OscilSmp
);
1331 free(note_ptr
->voices_ptr
[voice_index
].FMSmp
);
1332 free(note_ptr
->voices_ptr
[voice_index
].VoiceOut
);
1335 free(note_ptr
->voices_ptr
);
1337 free(note_ptr
->tmpwave
);
1338 free(note_ptr
->bypassl
);
1339 free(note_ptr
->bypassr
);
1345 * Compute the ADnote samples
1348 zyn_addnote_noteout(
1349 zyn_addnote_handle handle
,
1354 unsigned int voice_index
;
1355 float filter_adjust
;
1357 silence_two_buffers(outl
, outr
, SOUND_BUFFER_SIZE
);
1359 if (!note_ptr
->note_enabled
)
1364 silence_two_buffers(note_ptr
->bypassl
, note_ptr
->bypassr
, SOUND_BUFFER_SIZE
);
1367 * Compute all the parameters for each tick
1370 unsigned int voice_index
;
1376 float FMrelativepitch
;
1378 float temp_filter_frequency
;
1381 0.01 * (note_ptr
->frequency_envelope
.envout() +
1382 note_ptr
->frequency_lfo
.lfoout() * note_ptr
->synth_ptr
->modwheel_relmod
);
1384 note_ptr
->globaloldamplitude
= note_ptr
->globalnewamplitude
;
1386 note_ptr
->globalnewamplitude
=
1388 note_ptr
->amplitude_envelope
.envout_dB() *
1389 note_ptr
->amplitude_lfo
.amplfoout();
1391 if (note_ptr
->filter_category
!= ZYN_FILTER_TYPE_STATE_VARIABLE
)
1393 temp_filter_frequency
= note_ptr
->filter_left
.getrealfreq(note_ptr
->filter_center_pitch
+ note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout());
1395 note_ptr
->filter_left
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1396 if (note_ptr
->stereo
)
1398 note_ptr
->filter_right
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1402 // compute the portamento, if it is used by this note
1403 REALTYPE portamentofreqrap
=1.0;
1404 if (note_ptr
->portamento
)
1406 // this voice use portamento
1407 portamentofreqrap
= note_ptr
->synth_ptr
->portamento
.freqrap
;
1409 if (!note_ptr
->synth_ptr
->portamento
.used
)
1411 // the portamento has finished
1412 note_ptr
->portamento
= false; // this note is no longer "portamented"
1416 //compute parameters for all voices
1417 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1419 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1424 note_ptr
->voices_ptr
[voice_index
].DelayTicks
-= 1;
1426 if (note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1431 /*******************/
1432 /* Voice Amplitude */
1433 /*******************/
1434 note_ptr
->old_amplitude_ptr
[voice_index
] = note_ptr
->new_amplitude_ptr
[voice_index
];
1435 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1437 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1439 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1442 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
)
1444 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1450 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1452 filterpitch
= note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
;
1454 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1456 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.envout();
1459 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
)
1461 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.lfoout();
1464 filterfreq
= filterpitch
+ note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
;
1465 filterfreq
= note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.getrealfreq(filterfreq
);
1467 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.setfreq(filterfreq
);
1470 // compute only if the voice isn't noise
1471 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
)
1473 /*******************/
1474 /* Voice Frequency */
1475 /*******************/
1477 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
)
1479 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.lfoout() / 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
;
1482 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1484 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.envout() / 100.0;
1487 voicefreq
= getvoicebasefreq(note_ptr
, voice_index
) * pow(2, (voicepitch
+ globalpitch
) / 12.0); // Hz frequency
1488 voicefreq
*= note_ptr
->synth_ptr
->pitch_bend_relative_frequency
; // change the frequency by the controller
1489 setfreq(note_ptr
, voice_index
, voicefreq
* portamentofreqrap
);
1494 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
)
1496 FMrelativepitch
= note_ptr
->voices_ptr
[voice_index
].FMDetune
/ 100.0;
1497 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1499 FMrelativepitch
+= note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.envout() / 100;
1502 FMfreq
= pow(2.0, FMrelativepitch
/ 12.0) * voicefreq
* portamentofreqrap
;
1503 setfreqFM(note_ptr
, voice_index
, FMfreq
);
1505 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = note_ptr
->FM_new_amplitude_ptr
[voice_index
];
1506 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1507 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1509 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1511 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1517 note_ptr
->time
+= (REALTYPE
)SOUND_BUFFER_SIZE
/ note_ptr
->synth_ptr
->sample_rate
;
1520 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1522 if (!note_ptr
->voices_ptr
[voice_index
].enabled
|| note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1527 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
) //voice mode = sound
1529 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1531 case ZYN_FM_TYPE_MORPH
:
1532 ComputeVoiceOscillatorMorph(note_ptr
, voice_index
);
1534 case ZYN_FM_TYPE_RING_MOD
:
1535 ComputeVoiceOscillatorRingModulation(note_ptr
, voice_index
);
1537 case ZYN_FM_TYPE_PHASE_MOD
:
1538 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 0);
1540 case ZYN_FM_TYPE_FREQ_MOD
:
1541 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 1);
1544 case ZYN_FM_TYPE_PITCH_MOD
:
1545 ComputeVoiceOscillatorPitchModulation(note_ptr
, voice_index
);
1549 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
1550 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1555 ComputeVoiceNoise(note_ptr
, voice_index
);
1561 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->old_amplitude_ptr
[voice_index
],note_ptr
->new_amplitude_ptr
[voice_index
])){
1562 int rest
=SOUND_BUFFER_SIZE
;
1563 //test if the amplitude if raising and the difference is high
1564 if ((note_ptr
->new_amplitude_ptr
[voice_index
]>note_ptr
->old_amplitude_ptr
[voice_index
])&&((note_ptr
->new_amplitude_ptr
[voice_index
]-note_ptr
->old_amplitude_ptr
[voice_index
])>0.25)){
1566 if (rest
>SOUND_BUFFER_SIZE
) rest
=SOUND_BUFFER_SIZE
;
1567 for (int i
=0;i
<SOUND_BUFFER_SIZE
-rest
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->old_amplitude_ptr
[voice_index
];
1569 // Amplitude interpolation
1570 for (i
=0;i
<rest
;i
++){
1571 note_ptr
->tmpwave
[i
+(SOUND_BUFFER_SIZE
-rest
)]*=INTERPOLATE_AMPLITUDE(note_ptr
->old_amplitude_ptr
[voice_index
]
1572 ,note_ptr
->new_amplitude_ptr
[voice_index
],i
,rest
);
1574 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->new_amplitude_ptr
[voice_index
];
1577 if (note_ptr
->first_tick_ptr
[voice_index
])
1579 fadein(note_ptr
, ¬e_ptr
->tmpwave
[0]);
1580 note_ptr
->first_tick_ptr
[voice_index
] = false;
1584 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1586 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.filterout(¬e_ptr
->tmpwave
[0]);
1589 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1590 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1592 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1594 for (i
=0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1596 note_ptr
->tmpwave
[i
] *= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1600 // the voice is killed later
1604 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1605 if (note_ptr
->voices_ptr
[voice_index
].VoiceOut
!=NULL
)
1607 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1609 note_ptr
->voices_ptr
[voice_index
].VoiceOut
[i
] = note_ptr
->tmpwave
[i
];
1613 // Add the voice that do not bypass the filter to out
1614 if (note_ptr
->voices_ptr
[voice_index
].filterbypass
==0)
1618 if (note_ptr
->stereo
)
1621 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1623 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1624 outr
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* (1.0 - note_ptr
->voices_ptr
[voice_index
].Panning
) * 2.0;
1630 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1632 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;}
1637 // bypass the filter
1639 if (note_ptr
->stereo
)
1642 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1644 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1645 note_ptr
->bypassr
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* (1.0 - note_ptr
->voices_ptr
[voice_index
].Panning
) * 2.0;
1651 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1653 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;
1657 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1658 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1660 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1662 kill_voice(note_ptr
, voice_index
);
1667 // Processing Global parameters
1669 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
1671 filter_adjust
= note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout();
1673 zyn_filter_sv_process(note_ptr
->filter_sv_processor_left
, filter_adjust
, outl
);
1675 if (note_ptr
->stereo
)
1677 zyn_filter_sv_process(note_ptr
->filter_sv_processor_right
, filter_adjust
, outr
);
1682 note_ptr
->filter_left
.filterout(&outl
[0]);
1684 if (note_ptr
->stereo
)
1686 note_ptr
->filter_right
.filterout(&outr
[0]);
1690 if (!note_ptr
->stereo
)
1692 // set the right channel=left channel
1693 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1696 note_ptr
->bypassr
[i
]=note_ptr
->bypassl
[i
];
1700 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1702 // outl[i]+=note_ptr->bypassl[i];
1703 // outr[i]+=note_ptr->bypassr[i];
1706 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
))
1708 // Amplitude Interpolation
1709 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1711 REALTYPE tmpvol
= INTERPOLATE_AMPLITUDE(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
, i
, SOUND_BUFFER_SIZE
);
1712 outl
[i
] *= tmpvol
* (1.0 - note_ptr
->panning
);
1713 outr
[i
] *= tmpvol
* note_ptr
->panning
;
1718 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1720 outl
[i
] *= note_ptr
->globalnewamplitude
* (1.0 - note_ptr
->panning
);
1721 outr
[i
] *= note_ptr
->globalnewamplitude
* note_ptr
->panning
;
1726 if (note_ptr
->punch_enabled
)
1728 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1730 REALTYPE punchamp
= note_ptr
->punch_initial_value
* note_ptr
->punch_t
+ 1.0;
1731 outl
[i
] *= punchamp
;
1732 outr
[i
] *= punchamp
;
1733 note_ptr
->punch_t
-= note_ptr
->punch_duration
;
1734 if (note_ptr
->punch_t
< 0.0)
1736 note_ptr
->punch_enabled
= false;
1742 // Check if the global amplitude is finished.
1743 // If it does, disable the note
1744 if (note_ptr
->amplitude_envelope
.finished())
1746 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1750 REALTYPE tmp
= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1756 zyn_addnote_force_disable(note_ptr
);
1766 * Relase the key (NoteOff)
1769 zyn_addnote_note_off(
1770 zyn_addnote_handle handle
)
1772 unsigned int voice_index
;
1774 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1776 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1781 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1783 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.relasekey();
1786 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1788 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.relasekey();
1791 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1793 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.relasekey();
1796 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1798 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.relasekey();
1801 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1803 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.relasekey();
1807 note_ptr
->frequency_envelope
.relasekey();
1808 note_ptr
->filter_envelope
.relasekey();
1809 note_ptr
->amplitude_envelope
.relasekey();