getdetune() coding style cleanup
[zyn.git] / addnote.cpp
bloba5edef519c58d699658efe7441fd31c0cb1330fe
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 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;
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 zyn_sample_type * VoiceOut;
116 /* Wave of the Voice */
117 zyn_sample_type * FMSmp;
119 REALTYPE FMVolume;
120 REALTYPE FMDetune; //in cents
122 Envelope m_fm_frequency_envelope;
123 Envelope m_fm_amplitude_envelope;
126 //FM amplitude tune
127 #define FM_AMP_MULTIPLIER 14.71280603
129 #define OSCIL_SMP_EXTRA_SAMPLES 5
131 // ADDitive note
132 struct addnote
134 // GLOBALS
135 bool stereo; // if the note is stereo (allows note Panning)
136 int midinote;
137 REALTYPE velocity;
138 REALTYPE basefreq;
140 bool note_enabled;
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
152 REALTYPE time;
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
179 //temporary buffer
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
194 bool portamento;
196 //how the fine detunes are made bigger or smaller
197 REALTYPE bandwidth_detune_multiplier;
199 LFO amplitude_lfo;
200 LFO filter_lfo;
201 LFO frequency_lfo;
203 int filter_category; // One of ZYN_FILTER_TYPE_XXX
204 Filter filter_left;
205 Filter filter_right;
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 ]
224 bool punch_enabled;
225 float punch_initial_value;
226 float punch_duration;
227 float punch_t;
230 bool
231 zyn_addnote_create(
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)
243 return false;
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 =
291 pow(
292 2.0,
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, &note_ptr->filter_sv_processor_left))
303 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &note_ptr->filter_sv_processor_right))
307 *handle_ptr = (zyn_addnote_handle)note_ptr;
308 return true;
312 * Get Voice base frequency
314 static
315 inline
316 REALTYPE
317 getvoicebasefreq(
318 struct addnote * note_ptr,
319 int nvoice)
321 REALTYPE detune;
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);
331 else
333 // the fixed freq is enabled
334 REALTYPE fixedfreq = 440.0;
335 int fixedfreqET = note_ptr->voices_ptr[nvoice].fixedfreqET;
336 if (fixedfreqET!=0)
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);
344 else
346 fixedfreq *= pow(3.0,tmp);
350 return fixedfreq * pow(2.0, detune / 12.0);
355 * Get Voice's Modullator base frequency
357 static
358 inline
359 REALTYPE
360 getFMvoicebasefreq(
361 struct addnote * note_ptr,
362 int nvoice)
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
371 static
372 inline
373 void
374 kill_voice(
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
387 static
388 inline
389 void
390 setfreq(
391 struct addnote * note_ptr,
392 int nvoice,
393 REALTYPE freq)
395 REALTYPE speed;
397 freq = fabs(freq);
399 speed = freq * REALTYPE(OSCIL_SIZE) / note_ptr->synth_ptr->sample_rate;
400 if (speed > OSCIL_SIZE)
402 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
413 static
414 inline
415 void
416 setfreqFM(
417 struct addnote * note_ptr,
418 int nvoice,
419 REALTYPE freq)
421 REALTYPE speed;
423 freq = fabs(freq);
425 speed = freq * REALTYPE(OSCIL_SIZE) / note_ptr->synth_ptr->sample_rate;
426 if (speed > OSCIL_SIZE)
428 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"
438 static
439 inline
440 void
441 fadein(
442 struct addnote * note_ptr,
443 REALTYPE *smps)
445 REALTYPE tmp;
446 int zerocrossings;
447 int i;
448 int n;
450 zerocrossings = 0;
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
456 zerocrossings++;
460 tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0;
461 if (tmp < 8.0)
463 tmp=8.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++)
475 // fade-in
476 tmp = 0.5 - cos((REALTYPE)i / (REALTYPE)n * PI) * 0.5;
477 smps[i] *= tmp;
482 * Computes the Oscillator (Without Modulation) - LinearInterpolation
484 static
485 inline
486 void
487 ComputeVoiceOscillator_LinearInterpolation(
488 struct addnote * note_ptr,
489 int voice_index)
491 int i,poshi;
492 REALTYPE poslo;
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];
503 if (poslo >= 1.0)
505 poslo -= 1.0;
506 poshi++;
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){
524 int i,poshi;
525 REALTYPE poslo;
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++){
532 xm1=smps[poshi];
533 x0=smps[poshi+1];
534 x1=smps[poshi+2];
535 x2=smps[poshi+3];
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;
540 printf("a\n");
541 //note_ptr->tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
542 poslo+=note_ptr->osc_freq_lo_ptr[voice_index];
543 if (poslo>=1.0) {
544 poslo-=1.0;
545 poshi++;
547 poshi+=note_ptr->osc_freq_hi_ptr[voice_index];
548 poshi&=OSCIL_SIZE-1;
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)
558 static
559 inline
560 void
561 ComputeVoiceOscillatorMorph(
562 struct addnote * note_ptr,
563 int voice_index)
565 int i;
566 REALTYPE amp;
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],
590 SOUND_BUFFER_SIZE);
592 note_ptr->tmpwave[i] = note_ptr->tmpwave[i] * (1.0 - amp) + amp * note_ptr->voices_ptr[FMVoice].VoiceOut[i];
595 else
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],
606 SOUND_BUFFER_SIZE);
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];
612 if (posloFM >= 1.0)
614 posloFM -= 1.0;
615 poshiFM++;
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)
630 static
631 inline
632 void
633 ComputeVoiceOscillatorRingModulation(
634 struct addnote * note_ptr,
635 int voice_index)
637 int i;
638 REALTYPE amp;
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],
661 SOUND_BUFFER_SIZE);
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];
671 else
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];
683 if (posloFM >= 1.0)
685 posloFM -= 1.0;
686 poshiFM++;
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)
701 static
702 inline
703 void
704 ComputeVoiceOscillatorFrequencyModulation(
705 struct addnote * note_ptr,
706 int voice_index,
707 int FMmode)
709 int carposhi;
710 int i,FMmodfreqhi;
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];
716 } else {
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];
725 if (posloFM>=1.0) {
726 posloFM=fmod(posloFM,1.0);
727 poshiFM++;
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++;
761 //carrier
762 carposhi=note_ptr->osc_pos_hi_ptr[voice_index]+FMmodfreqhi;
763 carposlo=note_ptr->osc_pos_lo_ptr[voice_index]+FMmodfreqlo;
765 if (carposlo>=1.0) {
766 carposhi++;
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;
785 #if 0
786 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
787 static
788 inline
789 void
790 ComputeVoiceOscillatorPitchModulation(
791 struct addnote * note_ptr,
792 int voice_index)
794 // TODO
796 #endif
799 * Computes the Noise
801 static
802 inline
803 void
804 ComputeVoiceNoise(
805 struct addnote * note_ptr,
806 int voice_index)
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)
816 void
817 zyn_addnote_note_on(
818 zyn_addnote_handle handle,
819 float panorama,
820 bool random_grouping,
821 REALTYPE freq,
822 REALTYPE velocity,
823 bool portamento,
824 int midinote)
826 unsigned int voice_index;
827 unsigned int i;
828 float filter_velocity_adjust;
829 int voice_oscillator_index;
830 REALTYPE tmp;
832 note_ptr->portamento = portamento;
833 note_ptr->midinote = midinote;
834 note_ptr->note_enabled = true;
835 note_ptr->basefreq = freq;
837 if (velocity > 1.0)
839 note_ptr->velocity = 1.0;
841 else
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);
863 else
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);
885 else
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 &note_ptr->synth_ptr->voices_params_ptr[voice_index].oscillator,
894 rand());
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)
911 // coarse detune
912 note_ptr->voices_ptr[voice_index].Detune =
913 getdetune(
914 note_ptr->synth_ptr->voices_params_ptr[voice_index].PDetuneType,
915 note_ptr->synth_ptr->voices_params_ptr[voice_index].PCoarseDetune,
916 8192);
918 // fine detune
919 note_ptr->voices_ptr[voice_index].FineDetune =
920 getdetune(
921 note_ptr->synth_ptr->voices_params_ptr[voice_index].PDetuneType,
923 note_ptr->synth_ptr->voices_params_ptr[voice_index].PDetune);
925 else
927 // coarse detune
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,
931 8192);
933 // fine detune
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 =
943 getdetune(
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);
948 else
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;
966 else
968 voice_oscillator_index = voice_index;
971 if (!random_grouping)
973 zyn_oscillator_new_rand_seed(
974 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
975 rand());
978 note_ptr->osc_pos_hi_ptr[voice_index] =
979 zyn_oscillator_get(
980 &note_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;
1008 break;
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;
1013 break;
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;
1017 break;
1018 #endif
1019 default:
1020 if (fmvoldamp > 1.0)
1022 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);
1035 } // voices loop
1037 // Global Parameters
1038 note_ptr->frequency_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_frequency_envelope_params, note_ptr->basefreq);
1040 note_ptr->frequency_lfo.init(
1041 note_ptr->synth_ptr->sample_rate,
1042 note_ptr->basefreq,
1043 &note_ptr->synth_ptr->frequency_lfo_params,
1044 ZYN_LFO_TYPE_FREQUENCY);
1046 note_ptr->amplitude_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_amplitude_envelope_params, note_ptr->basefreq);
1048 note_ptr->amplitude_lfo.init(
1049 note_ptr->synth_ptr->sample_rate,
1050 note_ptr->basefreq,
1051 &note_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, &note_ptr->synth_ptr->m_filter_params);
1062 if (note_ptr->stereo)
1064 note_ptr->filter_right.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_params);
1067 note_ptr->filter_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_envelope_params, note_ptr->basefreq);
1069 note_ptr->filter_lfo.init(
1070 note_ptr->synth_ptr->sample_rate,
1071 note_ptr->basefreq,
1072 &note_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)
1091 continue;
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
1112 else
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 &note_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,
1133 note_ptr->basefreq,
1134 &note_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 &note_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,
1153 note_ptr->basefreq,
1154 &note_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 &note_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 &note_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,
1178 note_ptr->basefreq,
1179 &note_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 &note_ptr->synth_ptr->voices_params_ptr[voice_index].modulator_oscillator,
1191 rand());
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;
1199 else
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);
1210 else
1212 tmp = 1.0;
1215 if (!random_grouping)
1217 zyn_oscillator_new_rand_seed(
1218 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
1219 rand());
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 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
1225 note_ptr->voices_ptr[voice_index].FMSmp,
1226 tmp,
1227 false);
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 &note_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 &note_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);
1274 * Kill the note
1276 void
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;
1293 void
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);
1341 delete note_ptr;
1345 * Compute the ADnote samples
1347 bool
1348 zyn_addnote_noteout(
1349 zyn_addnote_handle handle,
1350 REALTYPE *outl,
1351 REALTYPE *outr)
1353 int i;
1354 unsigned int voice_index;
1355 float filter_adjust;
1357 silence_two_buffers(outl, outr, SOUND_BUFFER_SIZE);
1359 if (!note_ptr->note_enabled)
1361 return false;
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;
1371 float voicefreq;
1372 float voicepitch;
1373 float filterpitch;
1374 float filterfreq;
1375 float FMfreq;
1376 float FMrelativepitch;
1377 float globalpitch;
1378 float temp_filter_frequency;
1380 globalpitch =
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 =
1387 note_ptr->volume *
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)
1421 continue;
1424 note_ptr->voices_ptr[voice_index].DelayTicks -= 1;
1426 if (note_ptr->voices_ptr[voice_index].DelayTicks > 0)
1428 continue;
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();
1447 /****************/
1448 /* Voice Filter */
1449 /****************/
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 /*******************/
1476 voicepitch=0.0;
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);
1491 /***************/
1492 /* Modulator */
1493 /***************/
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)
1524 continue;
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);
1533 break;
1534 case ZYN_FM_TYPE_RING_MOD:
1535 ComputeVoiceOscillatorRingModulation(note_ptr, voice_index);
1536 break;
1537 case ZYN_FM_TYPE_PHASE_MOD:
1538 ComputeVoiceOscillatorFrequencyModulation(note_ptr, voice_index, 0);
1539 break;
1540 case ZYN_FM_TYPE_FREQ_MOD:
1541 ComputeVoiceOscillatorFrequencyModulation(note_ptr, voice_index, 1);
1542 break;
1543 #if 0
1544 case ZYN_FM_TYPE_PITCH_MOD:
1545 ComputeVoiceOscillatorPitchModulation(note_ptr, voice_index);
1546 break;
1547 #endif
1548 default:
1549 ComputeVoiceOscillator_LinearInterpolation(note_ptr, voice_index);
1550 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1553 else
1555 ComputeVoiceNoise(note_ptr, voice_index);
1558 // Voice Processing
1560 // Amplitude
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)){
1565 rest=10;
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];
1576 // Fade in
1577 if (note_ptr->first_tick_ptr[voice_index])
1579 fadein(note_ptr, &note_ptr->tmpwave[0]);
1580 note_ptr->first_tick_ptr[voice_index] = false;
1583 // Filter
1584 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
1586 note_ptr->voices_ptr[voice_index].m_voice_filter.filterout(&note_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)
1616 // no bypass
1618 if (note_ptr->stereo)
1620 // 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;
1627 else
1629 // mono
1630 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1632 outl[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume;}
1635 else
1637 // bypass the filter
1639 if (note_ptr->stereo)
1641 // 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;
1648 else
1650 // mono
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);
1680 else
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++)
1695 outr[i]=outl[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;
1716 else
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;
1725 // Apply the punch
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;
1737 break;
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++)
1748 // fade-out
1750 REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1752 outl[i] *= tmp;
1753 outr[i] *= tmp;
1756 zyn_addnote_force_disable(note_ptr);
1757 return false;
1759 else
1761 return true;
1766 * Relase the key (NoteOff)
1768 void
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)
1778 continue;
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();
1812 #undef note_ptr