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
29 #include "resonance.h"
31 #include "oscillator.h"
32 #include "resonance.h"
33 #include "envelope_parameters.h"
34 #include "lfo_parameters.h"
35 #include "filter_parameters.h"
37 #include "filter_base.h"
38 #include "analog_filter.h"
39 #include "sv_filter.h"
40 #include "formant_filter.h"
44 #include "portamento.h"
45 #include "addsynth_internal.h"
48 #define LOG_LEVEL LOG_LEVEL_ERROR
51 /***********************************************************/
52 /* VOICE PARAMETERS */
53 /***********************************************************/
56 /* If the voice is enabled */
59 /* Voice Type (sound/noise)*/
68 /* Waveform of the Voice */
69 zyn_sample_type
* OscilSmp
;
71 /************************************
72 * FREQUENCY PARAMETERS *
73 ************************************/
75 struct zyn_fixed_detune fixed_detune
;
77 // cents = basefreq*VoiceDetune
78 REALTYPE Detune
,FineDetune
;
80 Envelope m_frequency_envelope
;
83 /***************************
84 * AMPLITUDE PARAMETERS *
85 ***************************/
87 /* Panning 0.0=left, 0.5 - center, 1.0 = right */
89 REALTYPE Volume
;// [-1.0 .. 1.0]
91 Envelope m_amplitude_envelope
;
94 /*************************
96 *************************/
98 Filter m_voice_filter
;
100 REALTYPE FilterCenterPitch
;/* Filter center Pitch*/
101 REALTYPE FilterFreqTracking
;
103 Envelope m_filter_envelope
;
106 /****************************
107 * MODULLATOR PARAMETERS *
108 ****************************/
110 unsigned int fm_type
;
114 // Voice Output used by other voices if use this as modullator
115 zyn_sample_type
* VoiceOut
;
117 /* Wave of the Voice */
118 zyn_sample_type
* FMSmp
;
121 REALTYPE FMDetune
; //in cents
123 Envelope m_fm_frequency_envelope
;
124 Envelope m_fm_amplitude_envelope
;
128 #define FM_AMP_MULTIPLIER 14.71280603
130 #define OSCIL_SMP_EXTRA_SAMPLES 5
136 bool stereo
; // if the note is stereo (allows note Panning)
143 /***********************************************************/
144 /* VOICE PARAMETERS */
145 /***********************************************************/
146 struct addsynth_voice
* voices_ptr
; // array with one entry per voice
148 /********************************************************/
149 /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */
150 /********************************************************/
152 // time from the start of the note
155 // fractional part (skip)
156 float * osc_pos_lo_ptr
; // array with one entry per voice
157 float * osc_freq_lo_ptr
; // array with one entry per voice
159 // integer part (skip)
160 int * osc_pos_hi_ptr
; // array with one entry per voice
161 int * osc_freq_hi_ptr
; // array with one entry per voice
163 // fractional part (skip) of the Modullator
164 float * osc_pos_lo_FM_ptr
; // array with one entry per voice
165 float * osc_freq_lo_FM_ptr
; // array with one entry per voice
167 // integer part (skip) of the Modullator
168 unsigned short int * osc_pos_hi_FM_ptr
; // array with one entry per voice
169 unsigned short int * osc_freq_hi_FM_ptr
; // array with one entry per voice
171 // used to compute and interpolate the amplitudes of voices and modullators
172 float * old_amplitude_ptr
; // array with one entry per voice
173 float * new_amplitude_ptr
; // array with one entry per voice
174 float * FM_old_amplitude_ptr
; // array with one entry per voice
175 float * FM_new_amplitude_ptr
; // array with one entry per voice
177 // used by Frequency Modulation (for integration)
178 float * FM_old_smp_ptr
; // array with one entry per voice
181 zyn_sample_type
* tmpwave
;
183 //Filter bypass samples
184 zyn_sample_type
* bypassl
;
185 zyn_sample_type
* bypassr
;
187 //interpolate the amplitudes
188 REALTYPE globaloldamplitude
;
189 REALTYPE globalnewamplitude
;
191 // whether it is the first tick (used to fade in the sound)
192 bool * first_tick_ptr
; // array with one entry per voice
194 // whether note has portamento
197 //how the fine detunes are made bigger or smaller
198 REALTYPE bandwidth_detune_multiplier
;
204 int filter_category
; // One of ZYN_FILTER_TYPE_XXX
207 zyn_filter_processor_handle filter_sv_processor_left
;
208 zyn_filter_processor_handle filter_sv_processor_right
;
210 float filter_center_pitch
; // octaves
211 float filter_q_factor
;
213 Envelope amplitude_envelope
;
214 Envelope filter_envelope
;
215 Envelope frequency_envelope
;
217 float detune
; // cents
219 struct zyn_addsynth
* synth_ptr
;
221 float volume
; // [ 0 .. 1 ]
223 float panning
; // [ 0 .. 1 ]
226 float punch_initial_value
;
227 float punch_duration
;
233 struct zyn_addsynth
* synth_ptr
,
234 zyn_addnote_handle
* handle_ptr
)
236 struct addnote
* note_ptr
;
237 unsigned int voice_index
;
239 // we still need to use C++ allocation because some constructors need to be invoked
240 // For example, AnalogFilter has virtual methods
241 note_ptr
= new addnote
;
242 if (note_ptr
== NULL
)
247 note_ptr
->tmpwave
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
248 note_ptr
->bypassl
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
249 note_ptr
->bypassr
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
251 note_ptr
->voices_ptr
= (struct addsynth_voice
*)malloc(sizeof(struct addsynth_voice
) * synth_ptr
->voices_count
);
252 for (voice_index
= 0 ; voice_index
< synth_ptr
->voices_count
; voice_index
++)
254 // the extra points contains the first point
255 note_ptr
->voices_ptr
[voice_index
].OscilSmp
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * (OSCIL_SIZE
+ OSCIL_SMP_EXTRA_SAMPLES
));
256 note_ptr
->voices_ptr
[voice_index
].FMSmp
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * (OSCIL_SIZE
+ OSCIL_SMP_EXTRA_SAMPLES
));
257 note_ptr
->voices_ptr
[voice_index
].VoiceOut
= (zyn_sample_type
*)malloc(sizeof(zyn_sample_type
) * SOUND_BUFFER_SIZE
);
260 note_ptr
->osc_pos_hi_ptr
= (int *)malloc(sizeof(int) * synth_ptr
->voices_count
);
261 note_ptr
->osc_pos_lo_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
262 note_ptr
->osc_pos_hi_FM_ptr
= (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr
->voices_count
);
263 note_ptr
->osc_pos_lo_FM_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
265 note_ptr
->osc_freq_hi_ptr
= (int *)malloc(sizeof(int) * synth_ptr
->voices_count
);
266 note_ptr
->osc_freq_lo_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
267 note_ptr
->osc_freq_hi_FM_ptr
= (unsigned short int *)malloc(sizeof(unsigned short int) * synth_ptr
->voices_count
);
268 note_ptr
->osc_freq_lo_FM_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
270 note_ptr
->FM_old_smp_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
272 note_ptr
->first_tick_ptr
= (bool *)malloc(sizeof(bool) * synth_ptr
->voices_count
);
274 note_ptr
->old_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
275 note_ptr
->new_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
277 note_ptr
->FM_old_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
278 note_ptr
->FM_new_amplitude_ptr
= (float *)malloc(sizeof(float) * synth_ptr
->voices_count
);
280 note_ptr
->stereo
= synth_ptr
->stereo
;
282 note_ptr
->detune
= zyn_get_detune(
283 synth_ptr
->detune
.type
,
284 synth_ptr
->detune
.octave
,
285 synth_ptr
->detune
.coarse
,
286 synth_ptr
->detune
.fine
);
289 * Get the Multiplier of the fine detunes of the voices
291 note_ptr
->bandwidth_detune_multiplier
= synth_ptr
->detune_bandwidth
;
292 note_ptr
->bandwidth_detune_multiplier
=
295 note_ptr
->bandwidth_detune_multiplier
* pow(fabs(note_ptr
->bandwidth_detune_multiplier
), 0.2) * 5.0);
297 note_ptr
->note_enabled
= false;
299 note_ptr
->synth_ptr
= synth_ptr
;
301 if (!zyn_filter_sv_processor_create(synth_ptr
->filter_sv
, ¬e_ptr
->filter_sv_processor_left
))
305 if (!zyn_filter_sv_processor_create(synth_ptr
->filter_sv
, ¬e_ptr
->filter_sv_processor_right
))
309 *handle_ptr
= (zyn_addnote_handle
)note_ptr
;
314 * Get Voice base frequency
320 struct addnote
* note_ptr
,
328 detune
= note_ptr
->voices_ptr
[nvoice
].Detune
/ 100.0;
329 detune
+= note_ptr
->voices_ptr
[nvoice
].FineDetune
/ 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
* note_ptr
->bandwidth_detune_multiplier
;
330 detune
+= note_ptr
->detune
/ 100.0;
332 switch (note_ptr
->voices_ptr
[nvoice
].fixed_detune
.mode
)
334 case ZYN_DETUNE_NORMAL
:
335 frequency
= note_ptr
->basefreq
;
337 case ZYN_DETUNE_FIXED_440
:
340 case ZYN_DETUNE_EQUAL_TEMPERATE
:
341 // the frequency varies according the keyboard note
342 equal_temperate
= note_ptr
->voices_ptr
[nvoice
].fixed_detune
.equal_temperate
;
343 tmp
= (note_ptr
->midinote
- 69.0) / 12.0 * (pow(2.0, (equal_temperate
- 1) / 63.0) - 1.0);
345 if (equal_temperate
<= 64)
347 frequency
= 440 * pow(2.0, tmp
);
351 frequency
= 440 * pow(3.0, tmp
);
359 return frequency
* pow(2.0, detune
/ 12.0);
363 * Get Voice's Modullator base frequency
369 struct addnote
* note_ptr
,
372 REALTYPE detune
= note_ptr
->voices_ptr
[nvoice
].FMDetune
/ 100.0;
373 return getvoicebasefreq(note_ptr
, nvoice
) * pow(2, detune
/ 12.0);
377 * Kill a voice of ADnote
383 struct addnote
* note_ptr
,
384 unsigned int voice_index
)
386 // silence the voice, perhaps is used by another voice
387 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
389 note_ptr
->voices_ptr
[voice_index
].enabled
= false;
393 * Computes the frequency of an oscillator
399 struct addnote
* note_ptr
,
407 speed
= freq
* REALTYPE(OSCIL_SIZE
) / note_ptr
->synth_ptr
->sample_rate
;
408 if (speed
> OSCIL_SIZE
)
413 F2I(speed
, note_ptr
->osc_freq_hi_ptr
[nvoice
]);
415 note_ptr
->osc_freq_lo_ptr
[nvoice
] = speed
- floor(speed
);
419 * Computes the frequency of an modullator oscillator
425 struct addnote
* note_ptr
,
433 speed
= freq
* REALTYPE(OSCIL_SIZE
) / note_ptr
->synth_ptr
->sample_rate
;
434 if (speed
> OSCIL_SIZE
)
439 F2I(speed
, note_ptr
->osc_freq_hi_FM_ptr
[nvoice
]);
440 note_ptr
->osc_freq_lo_FM_ptr
[nvoice
] = speed
- floor(speed
);
444 * Fadein in a way that removes clicks but keep sound "punchy"
450 struct addnote
* note_ptr
,
459 for (i
= 1 ; i
< SOUND_BUFFER_SIZE
; i
++)
461 if ((smps
[i
- 1] < 0.0) && (smps
[i
] > 0.0))
463 // this is only the possitive crossings
468 tmp
= (SOUND_BUFFER_SIZE
- 1.0) / (zerocrossings
+ 1) / 3.0;
474 F2I(tmp
, n
); // how many samples is the fade-in
476 if (n
> SOUND_BUFFER_SIZE
)
478 n
= SOUND_BUFFER_SIZE
;
481 for (i
= 0 ; i
< n
; i
++)
484 tmp
= 0.5 - cos((REALTYPE
)i
/ (REALTYPE
)n
* PI
) * 0.5;
490 * Computes the Oscillator (Without Modulation) - LinearInterpolation
495 ComputeVoiceOscillator_LinearInterpolation(
496 struct addnote
* note_ptr
,
502 poshi
= note_ptr
->osc_pos_hi_ptr
[voice_index
];
503 poslo
= note_ptr
->osc_pos_lo_ptr
[voice_index
];
504 REALTYPE
* smps
= note_ptr
->voices_ptr
[voice_index
].OscilSmp
;
506 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
508 note_ptr
->tmpwave
[i
] = smps
[poshi
] * (1.0 - poslo
) + smps
[poshi
+ 1] * poslo
;
509 poslo
+= note_ptr
->osc_freq_lo_ptr
[voice_index
];
517 poshi
+= note_ptr
->osc_freq_hi_ptr
[voice_index
];
518 poshi
&= OSCIL_SIZE
- 1;
521 note_ptr
->osc_pos_hi_ptr
[voice_index
] = poshi
;
522 note_ptr
->osc_pos_lo_ptr
[voice_index
] = poslo
;
528 * Computes the Oscillator (Without Modulation) - CubicInterpolation
530 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
531 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
535 poshi=note_ptr->osc_pos_hi_ptr[voice_index];
536 poslo=note_ptr->osc_pos_lo_ptr[voice_index];
537 REALTYPE *smps=note_ptr->voices_ptr[voice_index].OscilSmp;
538 REALTYPE xm1,x0,x1,x2,a,b,c;
539 for (i=0;i<SOUND_BUFFER_SIZE;i++){
544 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
545 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
546 c = (x1 - xm1) / 2.0;
547 note_ptr->tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
549 //note_ptr->tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
550 poslo+=note_ptr->osc_freq_lo_ptr[voice_index];
555 poshi+=note_ptr->osc_freq_hi_ptr[voice_index];
558 note_ptr->osc_pos_hi_ptr[voice_index]=poshi;
559 note_ptr->osc_pos_lo_ptr[voice_index]=poslo;
564 * Computes the Oscillator (Morphing)
569 ComputeVoiceOscillatorMorph(
570 struct addnote
* note_ptr
,
576 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
578 if (note_ptr
->FM_new_amplitude_ptr
[voice_index
] > 1.0)
580 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = 1.0;
583 if (note_ptr
->FM_old_amplitude_ptr
[voice_index
] > 1.0)
585 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = 1.0;
588 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>= 0)
590 //if I use VoiceOut[] as modullator
591 int FMVoice
= note_ptr
->voices_ptr
[voice_index
].FMVoice
;
592 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
594 amp
= INTERPOLATE_AMPLITUDE(
595 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
596 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
600 note_ptr
->tmpwave
[i
] = note_ptr
->tmpwave
[i
] * (1.0 - amp
) + amp
* note_ptr
->voices_ptr
[FMVoice
].VoiceOut
[i
];
605 int poshiFM
= note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
606 REALTYPE posloFM
= note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
608 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
610 amp
= INTERPOLATE_AMPLITUDE(
611 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
612 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
616 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
);
618 posloFM
+= note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
626 poshiFM
+= note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
627 poshiFM
&= OSCIL_SIZE
- 1;
630 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = poshiFM
;
631 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = posloFM
;
636 * Computes the Oscillator (Ring Modulation)
641 ComputeVoiceOscillatorRingModulation(
642 struct addnote
* note_ptr
,
648 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
650 if (note_ptr
->FM_new_amplitude_ptr
[voice_index
] > 1.0)
652 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = 1.0;
655 if (note_ptr
->FM_old_amplitude_ptr
[voice_index
] > 1.0)
657 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = 1.0;
660 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>= 0)
662 // if I use VoiceOut[] as modullator
663 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
665 amp
= INTERPOLATE_AMPLITUDE(
666 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
667 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
671 int FMVoice
= note_ptr
->voices_ptr
[voice_index
].FMVoice
;
673 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
675 note_ptr
->tmpwave
[i
] *= (1.0 - amp
) + amp
* note_ptr
->voices_ptr
[FMVoice
].VoiceOut
[i
];
681 int poshiFM
=note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
682 REALTYPE posloFM
=note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
684 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
686 amp
= INTERPOLATE_AMPLITUDE(note_ptr
->FM_old_amplitude_ptr
[voice_index
], note_ptr
->FM_new_amplitude_ptr
[voice_index
], i
, SOUND_BUFFER_SIZE
);
687 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
);
689 posloFM
+= note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
697 poshiFM
+= note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
698 poshiFM
&= OSCIL_SIZE
-1;
701 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = poshiFM
;
702 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = posloFM
;
707 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
712 ComputeVoiceOscillatorFrequencyModulation(
713 struct addnote
* note_ptr
,
719 REALTYPE FMmodfreqlo
,carposlo
;
721 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>=0){
722 //if I use VoiceOut[] as modulator
723 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
];
725 //Compute the modulator and store it in note_ptr->tmpwave[]
726 int poshiFM
=note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
727 REALTYPE posloFM
=note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
729 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
730 note_ptr
->tmpwave
[i
]=(note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
]*(1.0-posloFM
)
731 +note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
+1]*posloFM
);
732 posloFM
+=note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
734 posloFM
=fmod(posloFM
,1.0);
737 poshiFM
+=note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
738 poshiFM
&=OSCIL_SIZE
-1;
740 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
]=poshiFM
;
741 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
]=posloFM
;
743 // Amplitude interpolation
744 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->FM_old_amplitude_ptr
[voice_index
],note_ptr
->FM_new_amplitude_ptr
[voice_index
])){
745 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
746 note_ptr
->tmpwave
[i
]*=INTERPOLATE_AMPLITUDE(note_ptr
->FM_old_amplitude_ptr
[voice_index
]
747 ,note_ptr
->FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
749 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->FM_new_amplitude_ptr
[voice_index
];
752 //normalize makes all sample-rates, oscil_sizes toproduce same sound
753 if (FMmode
!=0){//Frequency modulation
754 REALTYPE normalize
= OSCIL_SIZE
/ 262144.0 * 44100.0 / note_ptr
->synth_ptr
->sample_rate
;
755 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
756 note_ptr
->FM_old_smp_ptr
[voice_index
]=fmod(note_ptr
->FM_old_smp_ptr
[voice_index
]+note_ptr
->tmpwave
[i
]*normalize
,OSCIL_SIZE
);
757 note_ptr
->tmpwave
[i
]=note_ptr
->FM_old_smp_ptr
[voice_index
];
759 } else {//Phase modulation
760 REALTYPE normalize
=OSCIL_SIZE
/262144.0;
761 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=normalize
;
764 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
765 F2I(note_ptr
->tmpwave
[i
],FMmodfreqhi
);
766 FMmodfreqlo
=fmod(note_ptr
->tmpwave
[i
]+0.0000000001,1.0);
767 if (FMmodfreqhi
<0) FMmodfreqlo
++;
770 carposhi
=note_ptr
->osc_pos_hi_ptr
[voice_index
]+FMmodfreqhi
;
771 carposlo
=note_ptr
->osc_pos_lo_ptr
[voice_index
]+FMmodfreqlo
;
775 carposlo
=fmod(carposlo
,1.0);
777 carposhi
&=(OSCIL_SIZE
-1);
779 note_ptr
->tmpwave
[i
]=note_ptr
->voices_ptr
[voice_index
].OscilSmp
[carposhi
]*(1.0-carposlo
)
780 +note_ptr
->voices_ptr
[voice_index
].OscilSmp
[carposhi
+1]*carposlo
;
782 note_ptr
->osc_pos_lo_ptr
[voice_index
]+=note_ptr
->osc_freq_lo_ptr
[voice_index
];
783 if (note_ptr
->osc_pos_lo_ptr
[voice_index
]>=1.0) {
784 note_ptr
->osc_pos_lo_ptr
[voice_index
]=fmod(note_ptr
->osc_pos_lo_ptr
[voice_index
],1.0);
785 note_ptr
->osc_pos_hi_ptr
[voice_index
]++;
788 note_ptr
->osc_pos_hi_ptr
[voice_index
]+=note_ptr
->osc_freq_hi_ptr
[voice_index
];
789 note_ptr
->osc_pos_hi_ptr
[voice_index
]&=OSCIL_SIZE
-1;
794 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
798 ComputeVoiceOscillatorPitchModulation(
799 struct addnote
* note_ptr
,
813 struct addnote
* note_ptr
,
816 for (int i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
818 note_ptr
->tmpwave
[i
] = zyn_random() * 2.0 - 1.0;
822 #define note_ptr ((struct addnote *)handle)
826 zyn_addnote_handle handle
,
828 bool random_grouping
,
834 unsigned int voice_index
;
836 float filter_velocity_adjust
;
837 int voice_oscillator_index
;
839 unsigned char detune_type
;
841 note_ptr
->portamento
= portamento
;
842 note_ptr
->midinote
= midinote
;
843 note_ptr
->note_enabled
= true;
844 note_ptr
->basefreq
= freq
;
848 note_ptr
->velocity
= 1.0;
852 note_ptr
->velocity
= velocity
;
855 note_ptr
->time
= 0.0;
857 note_ptr
->panning
= (panorama
+ 1.0) / 2; // -1..1 -> 0 - 1
859 note_ptr
->filter_category
= note_ptr
->synth_ptr
->filter_type
;
861 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
863 filter_velocity_adjust
= note_ptr
->synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
864 (zyn_velocity_scale(note_ptr
->velocity
, note_ptr
->synth_ptr
->m_filter_velocity_scale_function
) - 1);
866 zyn_filter_sv_processor_init(note_ptr
->filter_sv_processor_left
, freq
, filter_velocity_adjust
);
867 if (note_ptr
->stereo
)
869 zyn_filter_sv_processor_init(note_ptr
->filter_sv_processor_right
, freq
, filter_velocity_adjust
);
874 note_ptr
->filter_center_pitch
=
875 note_ptr
->synth_ptr
->m_filter_params
.getfreq() + // center freq
876 note_ptr
->synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
877 (zyn_velocity_scale(note_ptr
->velocity
, note_ptr
->synth_ptr
->m_filter_velocity_scale_function
) - 1);
878 note_ptr
->filter_center_pitch
+= note_ptr
->synth_ptr
->m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
881 if (note_ptr
->synth_ptr
->PPunchStrength
!= 0)
883 note_ptr
->punch_enabled
= true;
884 note_ptr
->punch_t
= 1.0; // start from 1.0 and to 0.0
885 note_ptr
->punch_initial_value
= pow(10, 1.5 * note_ptr
->synth_ptr
->PPunchStrength
/ 127.0) - 1.0;
886 note_ptr
->punch_initial_value
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->PPunchVelocitySensing
);
888 REALTYPE time
= pow(10, 3.0 * note_ptr
->synth_ptr
->PPunchTime
/ 127.0) / 10000.0; // 0.1 .. 100 ms
890 REALTYPE stretch
= pow(440.0/freq
, note_ptr
->synth_ptr
->PPunchStretch
/ 64.0);
892 note_ptr
->punch_duration
= 1.0 / (time
* note_ptr
->synth_ptr
->sample_rate
* stretch
);
896 note_ptr
->punch_enabled
= false;
899 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
901 zyn_oscillator_new_rand_seed(
902 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].oscillator
,
905 note_ptr
->voices_ptr
[voice_index
].FMVoice
= -1;
907 if (!note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].enabled
)
909 note_ptr
->voices_ptr
[voice_index
].enabled
= false;
910 continue; // the voice is disabled
913 note_ptr
->voices_ptr
[voice_index
].enabled
= true;
914 note_ptr
->voices_ptr
[voice_index
].fixed_detune
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fixed_detune
;
916 // calculate voice detune
918 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.type
== ZYN_DETUNE_TYPE_GLOBAL
)
920 detune_type
= note_ptr
->synth_ptr
->detune
.type
;
924 detune_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.type
;
928 note_ptr
->voices_ptr
[voice_index
].Detune
=
931 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.octave
,
932 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.coarse
,
936 note_ptr
->voices_ptr
[voice_index
].FineDetune
= zyn_get_detune(
940 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.fine
);
943 // calculate voice fm detune
945 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.type
== ZYN_DETUNE_TYPE_GLOBAL
)
947 detune_type
= note_ptr
->synth_ptr
->detune
.type
;
951 detune_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.type
;
954 note_ptr
->voices_ptr
[voice_index
].FMDetune
=
957 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.octave
,
958 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.coarse
,
959 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.fine
);
962 note_ptr
->osc_pos_hi_ptr
[voice_index
] = 0;
963 note_ptr
->osc_pos_lo_ptr
[voice_index
] = 0.0;
964 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = 0;
965 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = 0.0;
967 // Get the voice's oscil or external's voice oscil
968 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
!= -1)
970 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
;
974 voice_oscillator_index
= voice_index
;
977 if (!random_grouping
)
979 zyn_oscillator_new_rand_seed(
980 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
984 note_ptr
->osc_pos_hi_ptr
[voice_index
] =
986 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
987 note_ptr
->voices_ptr
[voice_index
].OscilSmp
,
988 getvoicebasefreq(note_ptr
, voice_index
),
989 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].resonance
);
991 // I store the first elments to the last position for speedups
992 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
994 note_ptr
->voices_ptr
[voice_index
].OscilSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].OscilSmp
[i
];
997 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);
998 note_ptr
->osc_pos_hi_ptr
[voice_index
] %= OSCIL_SIZE
;
1000 note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreq();
1001 note_ptr
->voices_ptr
[voice_index
].filterbypass
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pfilterbypass
;
1003 note_ptr
->voices_ptr
[voice_index
].fm_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_type
;
1005 note_ptr
->voices_ptr
[voice_index
].FMVoice
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVoice
;
1007 // Compute the Voice's modulator volume (incl. damping)
1008 REALTYPE fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0 - 1.0);
1009 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1011 case ZYN_FM_TYPE_PHASE_MOD
:
1012 fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0);
1013 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;
1015 case ZYN_FM_TYPE_FREQ_MOD
:
1016 note_ptr
->voices_ptr
[voice_index
].FMVolume
= exp(note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * FM_AMP_MULTIPLIER
);
1017 note_ptr
->voices_ptr
[voice_index
].FMVolume
-= 1.0;
1018 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= fmvoldamp
* 4.0;
1020 #if 0 // ???????????
1021 case ZYN_FM_TYPE_PITCH_MOD
:
1022 note_ptr
->voices_ptr
[voice_index
].FMVolume
= (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * 8.0) * fmvoldamp
;
1026 if (fmvoldamp
> 1.0)
1031 note_ptr
->voices_ptr
[voice_index
].FMVolume
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * fmvoldamp
;
1034 // Voice's modulator velocity sensing
1035 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVelocityScaleFunction
);
1037 note_ptr
->FM_old_smp_ptr
[voice_index
] = 0.0; // this is for FM (integration)
1039 note_ptr
->first_tick_ptr
[voice_index
] = true;
1040 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
);
1043 // Global Parameters
1044 note_ptr
->frequency_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_frequency_envelope_params
, note_ptr
->basefreq
);
1046 note_ptr
->frequency_lfo
.init(
1047 note_ptr
->synth_ptr
->sample_rate
,
1049 ¬e_ptr
->synth_ptr
->frequency_lfo_params
,
1050 ZYN_LFO_TYPE_FREQUENCY
);
1052 note_ptr
->amplitude_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_amplitude_envelope_params
, note_ptr
->basefreq
);
1054 note_ptr
->amplitude_lfo
.init(
1055 note_ptr
->synth_ptr
->sample_rate
,
1057 ¬e_ptr
->synth_ptr
->amplitude_lfo_params
,
1058 ZYN_LFO_TYPE_AMPLITUDE
);
1060 note_ptr
->volume
= 4.0 * pow(0.1, 3.0 * (1.0 - note_ptr
->synth_ptr
->PVolume
/ 96.0)); // -60 dB .. 0 dB
1061 note_ptr
->volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->PAmpVelocityScaleFunction
); // velocity sensing
1063 note_ptr
->amplitude_envelope
.envout_dB(); // discard the first envelope output
1065 note_ptr
->globalnewamplitude
= note_ptr
->volume
* note_ptr
->amplitude_envelope
.envout_dB() * note_ptr
->amplitude_lfo
.amplfoout();
1067 note_ptr
->filter_left
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1068 if (note_ptr
->stereo
)
1070 note_ptr
->filter_right
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1073 note_ptr
->filter_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_envelope_params
, note_ptr
->basefreq
);
1075 note_ptr
->filter_lfo
.init(
1076 note_ptr
->synth_ptr
->sample_rate
,
1078 ¬e_ptr
->synth_ptr
->filter_lfo_params
,
1079 ZYN_LFO_TYPE_FILTER
);
1081 note_ptr
->filter_q_factor
= note_ptr
->synth_ptr
->m_filter_params
.getq();
1083 // Forbids the Modulation Voice to be greater or equal than voice
1084 for (i
= 0 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1086 if (note_ptr
->voices_ptr
[i
].FMVoice
>= (int)i
)
1088 note_ptr
->voices_ptr
[i
].FMVoice
= -1;
1092 // Voice Parameter init
1093 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1095 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1100 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
);
1102 note_ptr
->voices_ptr
[voice_index
].white_noise
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].white_noise
;
1104 /* Voice Amplitude Parameters Init */
1106 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
1107 note_ptr
->voices_ptr
[voice_index
].Volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpVelocityScaleFunction
); // velocity
1109 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PVolumeminus
!= 0)
1111 note_ptr
->voices_ptr
[voice_index
].Volume
= -note_ptr
->voices_ptr
[voice_index
].Volume
;
1114 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
== 0)
1116 note_ptr
->voices_ptr
[voice_index
].Panning
= zyn_random(); // random panning
1120 note_ptr
->voices_ptr
[voice_index
].Panning
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
/ 128.0;
1123 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1124 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
!= 0)
1126 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.init(
1127 note_ptr
->synth_ptr
->sample_rate
,
1128 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_amplitude_envelope_params
,
1129 note_ptr
->basefreq
);
1131 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB(); // discard the first envelope sample
1132 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1135 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
!= 0)
1137 note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.init(
1138 note_ptr
->synth_ptr
->sample_rate
,
1140 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].amplitude_lfo_params
,
1141 ZYN_LFO_TYPE_AMPLITUDE
);
1143 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1146 /* Voice Frequency Parameters Init */
1147 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
!= 0)
1149 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.init(
1150 note_ptr
->synth_ptr
->sample_rate
,
1151 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_frequency_envelope_params
,
1152 note_ptr
->basefreq
);
1155 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
!= 0)
1157 note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.init(
1158 note_ptr
->synth_ptr
->sample_rate
,
1160 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].frequency_lfo_params
,
1161 ZYN_LFO_TYPE_FREQUENCY
);
1164 /* Voice Filter Parameters Init */
1165 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
!= 0)
1167 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.init(
1168 note_ptr
->synth_ptr
->sample_rate
,
1169 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
);
1172 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
!= 0)
1174 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.init(
1175 note_ptr
->synth_ptr
->sample_rate
,
1176 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_envelope_params
,
1177 note_ptr
->basefreq
);
1180 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
!= 0)
1182 note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.init(
1183 note_ptr
->synth_ptr
->sample_rate
,
1185 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].filter_lfo_params
,
1186 ZYN_LFO_TYPE_FILTER
);
1189 note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
1191 /* Voice Modulation Parameters Init */
1192 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
&&
1193 note_ptr
->voices_ptr
[voice_index
].FMVoice
< 0)
1195 zyn_oscillator_new_rand_seed(
1196 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].modulator_oscillator
,
1199 // Perform Anti-aliasing only on MORPH or RING MODULATION
1201 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
!= -1)
1203 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
;
1207 voice_oscillator_index
= voice_index
;
1210 if ((note_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
.Padaptiveharmonics
!= 0) ||
1211 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_MORPH
) ||
1212 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_RING_MOD
))
1214 tmp
= getFMvoicebasefreq(note_ptr
, voice_index
);
1221 if (!random_grouping
)
1223 zyn_oscillator_new_rand_seed(
1224 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1228 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = note_ptr
->osc_pos_hi_ptr
[voice_index
];
1229 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] += zyn_oscillator_get(
1230 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1231 note_ptr
->voices_ptr
[voice_index
].FMSmp
,
1234 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1236 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
1238 note_ptr
->voices_ptr
[voice_index
].FMSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].FMSmp
[i
];
1241 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);
1242 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1245 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
!= 0)
1247 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.init(
1248 note_ptr
->synth_ptr
->sample_rate
,
1249 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_frequency_envelope_params
,
1250 note_ptr
->basefreq
);
1253 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1254 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1256 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
!= 0)
1258 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.init(
1259 note_ptr
->synth_ptr
->sample_rate
,
1260 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_amplitude_envelope_params
,
1261 note_ptr
->basefreq
);
1263 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1265 } // voice parameter init loop
1267 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1269 for (i
= voice_index
+ 1 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1271 if (note_ptr
->voices_ptr
[i
].FMVoice
== (int)voice_index
)
1273 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
1283 zyn_addnote_force_disable(
1284 zyn_addnote_handle handle
)
1286 unsigned int voice_index
;
1288 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1290 if (note_ptr
->voices_ptr
[voice_index
].enabled
)
1292 kill_voice(note_ptr
, voice_index
);
1296 note_ptr
->note_enabled
= false;
1300 zyn_addnote_destroy(
1301 zyn_addnote_handle handle
)
1303 unsigned int voice_index
;
1305 if (note_ptr
->note_enabled
)
1307 zyn_addnote_force_disable(handle
);
1310 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_left
);
1311 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_right
);
1313 free(note_ptr
->old_amplitude_ptr
);
1314 free(note_ptr
->new_amplitude_ptr
);
1316 free(note_ptr
->FM_old_amplitude_ptr
);
1317 free(note_ptr
->FM_new_amplitude_ptr
);
1319 free(note_ptr
->first_tick_ptr
);
1321 free(note_ptr
->FM_old_smp_ptr
);
1323 free(note_ptr
->osc_freq_hi_ptr
);
1324 free(note_ptr
->osc_freq_lo_ptr
);
1325 free(note_ptr
->osc_freq_hi_FM_ptr
);
1326 free(note_ptr
->osc_freq_lo_FM_ptr
);
1328 free(note_ptr
->osc_pos_hi_ptr
);
1329 free(note_ptr
->osc_pos_lo_ptr
);
1330 free(note_ptr
->osc_pos_hi_FM_ptr
);
1331 free(note_ptr
->osc_pos_lo_FM_ptr
);
1333 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1335 // the extra points contains the first point
1336 free(note_ptr
->voices_ptr
[voice_index
].OscilSmp
);
1337 free(note_ptr
->voices_ptr
[voice_index
].FMSmp
);
1338 free(note_ptr
->voices_ptr
[voice_index
].VoiceOut
);
1341 free(note_ptr
->voices_ptr
);
1343 free(note_ptr
->tmpwave
);
1344 free(note_ptr
->bypassl
);
1345 free(note_ptr
->bypassr
);
1351 * Compute the ADnote samples
1354 zyn_addnote_noteout(
1355 zyn_addnote_handle handle
,
1360 unsigned int voice_index
;
1361 float filter_adjust
;
1363 silence_two_buffers(outl
, outr
, SOUND_BUFFER_SIZE
);
1365 if (!note_ptr
->note_enabled
)
1370 silence_two_buffers(note_ptr
->bypassl
, note_ptr
->bypassr
, SOUND_BUFFER_SIZE
);
1373 * Compute all the parameters for each tick
1376 unsigned int voice_index
;
1382 float FMrelativepitch
;
1384 float temp_filter_frequency
;
1387 0.01 * (note_ptr
->frequency_envelope
.envout() +
1388 note_ptr
->frequency_lfo
.lfoout() * note_ptr
->synth_ptr
->modwheel_relmod
);
1390 note_ptr
->globaloldamplitude
= note_ptr
->globalnewamplitude
;
1392 note_ptr
->globalnewamplitude
=
1394 note_ptr
->amplitude_envelope
.envout_dB() *
1395 note_ptr
->amplitude_lfo
.amplfoout();
1397 if (note_ptr
->filter_category
!= ZYN_FILTER_TYPE_STATE_VARIABLE
)
1399 temp_filter_frequency
= note_ptr
->filter_left
.getrealfreq(note_ptr
->filter_center_pitch
+ note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout());
1401 note_ptr
->filter_left
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1402 if (note_ptr
->stereo
)
1404 note_ptr
->filter_right
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1408 // compute the portamento, if it is used by this note
1409 REALTYPE portamentofreqrap
=1.0;
1410 if (note_ptr
->portamento
)
1412 // this voice use portamento
1413 portamentofreqrap
= note_ptr
->synth_ptr
->portamento
.freqrap
;
1415 if (!note_ptr
->synth_ptr
->portamento
.used
)
1417 // the portamento has finished
1418 note_ptr
->portamento
= false; // this note is no longer "portamented"
1422 //compute parameters for all voices
1423 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1425 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1430 note_ptr
->voices_ptr
[voice_index
].DelayTicks
-= 1;
1432 if (note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1437 /*******************/
1438 /* Voice Amplitude */
1439 /*******************/
1440 note_ptr
->old_amplitude_ptr
[voice_index
] = note_ptr
->new_amplitude_ptr
[voice_index
];
1441 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1443 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1445 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1448 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
)
1450 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1456 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1458 filterpitch
= note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
;
1460 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1462 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.envout();
1465 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
)
1467 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.lfoout();
1470 filterfreq
= filterpitch
+ note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
;
1471 filterfreq
= note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.getrealfreq(filterfreq
);
1473 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.setfreq(filterfreq
);
1476 // compute only if the voice isn't noise
1477 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
)
1479 /*******************/
1480 /* Voice Frequency */
1481 /*******************/
1483 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
)
1485 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.lfoout() / 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
;
1488 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1490 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.envout() / 100.0;
1493 voicefreq
= getvoicebasefreq(note_ptr
, voice_index
) * pow(2, (voicepitch
+ globalpitch
) / 12.0); // Hz frequency
1494 voicefreq
*= note_ptr
->synth_ptr
->pitch_bend_relative_frequency
; // change the frequency by the controller
1495 setfreq(note_ptr
, voice_index
, voicefreq
* portamentofreqrap
);
1500 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
)
1502 FMrelativepitch
= note_ptr
->voices_ptr
[voice_index
].FMDetune
/ 100.0;
1503 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1505 FMrelativepitch
+= note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.envout() / 100;
1508 FMfreq
= pow(2.0, FMrelativepitch
/ 12.0) * voicefreq
* portamentofreqrap
;
1509 setfreqFM(note_ptr
, voice_index
, FMfreq
);
1511 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = note_ptr
->FM_new_amplitude_ptr
[voice_index
];
1512 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1513 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1515 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1517 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1523 note_ptr
->time
+= (REALTYPE
)SOUND_BUFFER_SIZE
/ note_ptr
->synth_ptr
->sample_rate
;
1526 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1528 if (!note_ptr
->voices_ptr
[voice_index
].enabled
|| note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1533 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
) //voice mode = sound
1535 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1537 case ZYN_FM_TYPE_MORPH
:
1538 ComputeVoiceOscillatorMorph(note_ptr
, voice_index
);
1540 case ZYN_FM_TYPE_RING_MOD
:
1541 ComputeVoiceOscillatorRingModulation(note_ptr
, voice_index
);
1543 case ZYN_FM_TYPE_PHASE_MOD
:
1544 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 0);
1546 case ZYN_FM_TYPE_FREQ_MOD
:
1547 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 1);
1550 case ZYN_FM_TYPE_PITCH_MOD
:
1551 ComputeVoiceOscillatorPitchModulation(note_ptr
, voice_index
);
1555 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
1556 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1561 ComputeVoiceNoise(note_ptr
, voice_index
);
1567 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->old_amplitude_ptr
[voice_index
],note_ptr
->new_amplitude_ptr
[voice_index
])){
1568 int rest
=SOUND_BUFFER_SIZE
;
1569 //test if the amplitude if raising and the difference is high
1570 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)){
1572 if (rest
>SOUND_BUFFER_SIZE
) rest
=SOUND_BUFFER_SIZE
;
1573 for (int i
=0;i
<SOUND_BUFFER_SIZE
-rest
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->old_amplitude_ptr
[voice_index
];
1575 // Amplitude interpolation
1576 for (i
=0;i
<rest
;i
++){
1577 note_ptr
->tmpwave
[i
+(SOUND_BUFFER_SIZE
-rest
)]*=INTERPOLATE_AMPLITUDE(note_ptr
->old_amplitude_ptr
[voice_index
]
1578 ,note_ptr
->new_amplitude_ptr
[voice_index
],i
,rest
);
1580 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->new_amplitude_ptr
[voice_index
];
1583 if (note_ptr
->first_tick_ptr
[voice_index
])
1585 fadein(note_ptr
, ¬e_ptr
->tmpwave
[0]);
1586 note_ptr
->first_tick_ptr
[voice_index
] = false;
1590 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1592 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.filterout(¬e_ptr
->tmpwave
[0]);
1595 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1596 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1598 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1600 for (i
=0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1602 note_ptr
->tmpwave
[i
] *= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1606 // the voice is killed later
1610 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1611 if (note_ptr
->voices_ptr
[voice_index
].VoiceOut
!=NULL
)
1613 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1615 note_ptr
->voices_ptr
[voice_index
].VoiceOut
[i
] = note_ptr
->tmpwave
[i
];
1619 // Add the voice that do not bypass the filter to out
1620 if (note_ptr
->voices_ptr
[voice_index
].filterbypass
==0)
1624 if (note_ptr
->stereo
)
1627 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1629 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1630 outr
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* (1.0 - note_ptr
->voices_ptr
[voice_index
].Panning
) * 2.0;
1636 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1638 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;}
1643 // bypass the filter
1645 if (note_ptr
->stereo
)
1648 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1650 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1651 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;
1657 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1659 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;
1663 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1664 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1666 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1668 kill_voice(note_ptr
, voice_index
);
1673 // Processing Global parameters
1675 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
1677 filter_adjust
= note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout();
1679 zyn_filter_sv_process(note_ptr
->filter_sv_processor_left
, filter_adjust
, outl
);
1681 if (note_ptr
->stereo
)
1683 zyn_filter_sv_process(note_ptr
->filter_sv_processor_right
, filter_adjust
, outr
);
1688 note_ptr
->filter_left
.filterout(&outl
[0]);
1690 if (note_ptr
->stereo
)
1692 note_ptr
->filter_right
.filterout(&outr
[0]);
1696 if (!note_ptr
->stereo
)
1698 // set the right channel=left channel
1699 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1702 note_ptr
->bypassr
[i
]=note_ptr
->bypassl
[i
];
1706 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1708 // outl[i]+=note_ptr->bypassl[i];
1709 // outr[i]+=note_ptr->bypassr[i];
1712 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
))
1714 // Amplitude Interpolation
1715 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1717 REALTYPE tmpvol
= INTERPOLATE_AMPLITUDE(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
, i
, SOUND_BUFFER_SIZE
);
1718 outl
[i
] *= tmpvol
* (1.0 - note_ptr
->panning
);
1719 outr
[i
] *= tmpvol
* note_ptr
->panning
;
1724 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1726 outl
[i
] *= note_ptr
->globalnewamplitude
* (1.0 - note_ptr
->panning
);
1727 outr
[i
] *= note_ptr
->globalnewamplitude
* note_ptr
->panning
;
1732 if (note_ptr
->punch_enabled
)
1734 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1736 REALTYPE punchamp
= note_ptr
->punch_initial_value
* note_ptr
->punch_t
+ 1.0;
1737 outl
[i
] *= punchamp
;
1738 outr
[i
] *= punchamp
;
1739 note_ptr
->punch_t
-= note_ptr
->punch_duration
;
1740 if (note_ptr
->punch_t
< 0.0)
1742 note_ptr
->punch_enabled
= false;
1748 // Check if the global amplitude is finished.
1749 // If it does, disable the note
1750 if (note_ptr
->amplitude_envelope
.finished())
1752 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1756 REALTYPE tmp
= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1762 zyn_addnote_force_disable(note_ptr
);
1772 * Relase the key (NoteOff)
1775 zyn_addnote_note_off(
1776 zyn_addnote_handle handle
)
1778 unsigned int voice_index
;
1780 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1782 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1787 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1789 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.relasekey();
1792 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1794 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.relasekey();
1797 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1799 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.relasekey();
1802 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1804 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.relasekey();
1807 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1809 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.relasekey();
1813 note_ptr
->frequency_envelope
.relasekey();
1814 note_ptr
->filter_envelope
.relasekey();
1815 note_ptr
->amplitude_envelope
.relasekey();