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
.coarse
,
285 synth_ptr
->detune
.fine
);
288 * Get the Multiplier of the fine detunes of the voices
290 note_ptr
->bandwidth_detune_multiplier
= synth_ptr
->detune_bandwidth
;
291 note_ptr
->bandwidth_detune_multiplier
=
294 note_ptr
->bandwidth_detune_multiplier
* pow(fabs(note_ptr
->bandwidth_detune_multiplier
), 0.2) * 5.0);
296 note_ptr
->note_enabled
= false;
298 note_ptr
->synth_ptr
= synth_ptr
;
300 if (!zyn_filter_sv_processor_create(synth_ptr
->filter_sv
, ¬e_ptr
->filter_sv_processor_left
))
304 if (!zyn_filter_sv_processor_create(synth_ptr
->filter_sv
, ¬e_ptr
->filter_sv_processor_right
))
308 *handle_ptr
= (zyn_addnote_handle
)note_ptr
;
313 * Get Voice base frequency
319 struct addnote
* note_ptr
,
327 detune
= note_ptr
->voices_ptr
[nvoice
].Detune
/ 100.0;
328 detune
+= note_ptr
->voices_ptr
[nvoice
].FineDetune
/ 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
* note_ptr
->bandwidth_detune_multiplier
;
329 detune
+= note_ptr
->detune
/ 100.0;
331 switch (note_ptr
->voices_ptr
[nvoice
].fixed_detune
.mode
)
333 case ZYN_DETUNE_NORMAL
:
334 frequency
= note_ptr
->basefreq
;
336 case ZYN_DETUNE_FIXED_440
:
339 case ZYN_DETUNE_EQUAL_TEMPERATE
:
340 // the frequency varies according the keyboard note
341 equal_temperate
= note_ptr
->voices_ptr
[nvoice
].fixed_detune
.equal_temperate
;
342 tmp
= (note_ptr
->midinote
- 69.0) / 12.0 * (pow(2.0, (equal_temperate
- 1) / 63.0) - 1.0);
344 if (equal_temperate
<= 64)
346 frequency
= 440 * pow(2.0, tmp
);
350 frequency
= 440 * pow(3.0, tmp
);
358 return frequency
* pow(2.0, detune
/ 12.0);
362 * Get Voice's Modullator base frequency
368 struct addnote
* note_ptr
,
371 REALTYPE detune
= note_ptr
->voices_ptr
[nvoice
].FMDetune
/ 100.0;
372 return getvoicebasefreq(note_ptr
, nvoice
) * pow(2, detune
/ 12.0);
376 * Kill a voice of ADnote
382 struct addnote
* note_ptr
,
383 unsigned int voice_index
)
385 // silence the voice, perhaps is used by another voice
386 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
388 note_ptr
->voices_ptr
[voice_index
].enabled
= false;
392 * Computes the frequency of an oscillator
398 struct addnote
* note_ptr
,
406 speed
= freq
* REALTYPE(OSCIL_SIZE
) / note_ptr
->synth_ptr
->sample_rate
;
407 if (speed
> OSCIL_SIZE
)
412 F2I(speed
, note_ptr
->osc_freq_hi_ptr
[nvoice
]);
414 note_ptr
->osc_freq_lo_ptr
[nvoice
] = speed
- floor(speed
);
418 * Computes the frequency of an modullator oscillator
424 struct addnote
* note_ptr
,
432 speed
= freq
* REALTYPE(OSCIL_SIZE
) / note_ptr
->synth_ptr
->sample_rate
;
433 if (speed
> OSCIL_SIZE
)
438 F2I(speed
, note_ptr
->osc_freq_hi_FM_ptr
[nvoice
]);
439 note_ptr
->osc_freq_lo_FM_ptr
[nvoice
] = speed
- floor(speed
);
443 * Fadein in a way that removes clicks but keep sound "punchy"
449 struct addnote
* note_ptr
,
458 for (i
= 1 ; i
< SOUND_BUFFER_SIZE
; i
++)
460 if ((smps
[i
- 1] < 0.0) && (smps
[i
] > 0.0))
462 // this is only the possitive crossings
467 tmp
= (SOUND_BUFFER_SIZE
- 1.0) / (zerocrossings
+ 1) / 3.0;
473 F2I(tmp
, n
); // how many samples is the fade-in
475 if (n
> SOUND_BUFFER_SIZE
)
477 n
= SOUND_BUFFER_SIZE
;
480 for (i
= 0 ; i
< n
; i
++)
483 tmp
= 0.5 - cos((REALTYPE
)i
/ (REALTYPE
)n
* PI
) * 0.5;
489 * Computes the Oscillator (Without Modulation) - LinearInterpolation
494 ComputeVoiceOscillator_LinearInterpolation(
495 struct addnote
* note_ptr
,
501 poshi
= note_ptr
->osc_pos_hi_ptr
[voice_index
];
502 poslo
= note_ptr
->osc_pos_lo_ptr
[voice_index
];
503 REALTYPE
* smps
= note_ptr
->voices_ptr
[voice_index
].OscilSmp
;
505 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
507 note_ptr
->tmpwave
[i
] = smps
[poshi
] * (1.0 - poslo
) + smps
[poshi
+ 1] * poslo
;
508 poslo
+= note_ptr
->osc_freq_lo_ptr
[voice_index
];
516 poshi
+= note_ptr
->osc_freq_hi_ptr
[voice_index
];
517 poshi
&= OSCIL_SIZE
- 1;
520 note_ptr
->osc_pos_hi_ptr
[voice_index
] = poshi
;
521 note_ptr
->osc_pos_lo_ptr
[voice_index
] = poslo
;
527 * Computes the Oscillator (Without Modulation) - CubicInterpolation
529 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
530 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
534 poshi=note_ptr->osc_pos_hi_ptr[voice_index];
535 poslo=note_ptr->osc_pos_lo_ptr[voice_index];
536 REALTYPE *smps=note_ptr->voices_ptr[voice_index].OscilSmp;
537 REALTYPE xm1,x0,x1,x2,a,b,c;
538 for (i=0;i<SOUND_BUFFER_SIZE;i++){
543 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
544 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
545 c = (x1 - xm1) / 2.0;
546 note_ptr->tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
548 //note_ptr->tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
549 poslo+=note_ptr->osc_freq_lo_ptr[voice_index];
554 poshi+=note_ptr->osc_freq_hi_ptr[voice_index];
557 note_ptr->osc_pos_hi_ptr[voice_index]=poshi;
558 note_ptr->osc_pos_lo_ptr[voice_index]=poslo;
563 * Computes the Oscillator (Morphing)
568 ComputeVoiceOscillatorMorph(
569 struct addnote
* note_ptr
,
575 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
577 if (note_ptr
->FM_new_amplitude_ptr
[voice_index
] > 1.0)
579 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = 1.0;
582 if (note_ptr
->FM_old_amplitude_ptr
[voice_index
] > 1.0)
584 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = 1.0;
587 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>= 0)
589 //if I use VoiceOut[] as modullator
590 int FMVoice
= note_ptr
->voices_ptr
[voice_index
].FMVoice
;
591 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
593 amp
= INTERPOLATE_AMPLITUDE(
594 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
595 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
599 note_ptr
->tmpwave
[i
] = note_ptr
->tmpwave
[i
] * (1.0 - amp
) + amp
* note_ptr
->voices_ptr
[FMVoice
].VoiceOut
[i
];
604 int poshiFM
= note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
605 REALTYPE posloFM
= note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
607 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
609 amp
= INTERPOLATE_AMPLITUDE(
610 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
611 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
615 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
);
617 posloFM
+= note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
625 poshiFM
+= note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
626 poshiFM
&= OSCIL_SIZE
- 1;
629 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = poshiFM
;
630 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = posloFM
;
635 * Computes the Oscillator (Ring Modulation)
640 ComputeVoiceOscillatorRingModulation(
641 struct addnote
* note_ptr
,
647 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
649 if (note_ptr
->FM_new_amplitude_ptr
[voice_index
] > 1.0)
651 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = 1.0;
654 if (note_ptr
->FM_old_amplitude_ptr
[voice_index
] > 1.0)
656 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = 1.0;
659 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>= 0)
661 // if I use VoiceOut[] as modullator
662 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
664 amp
= INTERPOLATE_AMPLITUDE(
665 note_ptr
->FM_old_amplitude_ptr
[voice_index
],
666 note_ptr
->FM_new_amplitude_ptr
[voice_index
],
670 int FMVoice
= note_ptr
->voices_ptr
[voice_index
].FMVoice
;
672 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
674 note_ptr
->tmpwave
[i
] *= (1.0 - amp
) + amp
* note_ptr
->voices_ptr
[FMVoice
].VoiceOut
[i
];
680 int poshiFM
=note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
681 REALTYPE posloFM
=note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
683 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
685 amp
= INTERPOLATE_AMPLITUDE(note_ptr
->FM_old_amplitude_ptr
[voice_index
], note_ptr
->FM_new_amplitude_ptr
[voice_index
], i
, SOUND_BUFFER_SIZE
);
686 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
);
688 posloFM
+= note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
696 poshiFM
+= note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
697 poshiFM
&= OSCIL_SIZE
-1;
700 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = poshiFM
;
701 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = posloFM
;
706 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
711 ComputeVoiceOscillatorFrequencyModulation(
712 struct addnote
* note_ptr
,
718 REALTYPE FMmodfreqlo
,carposlo
;
720 if (note_ptr
->voices_ptr
[voice_index
].FMVoice
>=0){
721 //if I use VoiceOut[] as modulator
722 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
];
724 //Compute the modulator and store it in note_ptr->tmpwave[]
725 int poshiFM
=note_ptr
->osc_pos_hi_FM_ptr
[voice_index
];
726 REALTYPE posloFM
=note_ptr
->osc_pos_lo_FM_ptr
[voice_index
];
728 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
729 note_ptr
->tmpwave
[i
]=(note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
]*(1.0-posloFM
)
730 +note_ptr
->voices_ptr
[voice_index
].FMSmp
[poshiFM
+1]*posloFM
);
731 posloFM
+=note_ptr
->osc_freq_lo_FM_ptr
[voice_index
];
733 posloFM
=fmod(posloFM
,1.0);
736 poshiFM
+=note_ptr
->osc_freq_hi_FM_ptr
[voice_index
];
737 poshiFM
&=OSCIL_SIZE
-1;
739 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
]=poshiFM
;
740 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
]=posloFM
;
742 // Amplitude interpolation
743 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->FM_old_amplitude_ptr
[voice_index
],note_ptr
->FM_new_amplitude_ptr
[voice_index
])){
744 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
745 note_ptr
->tmpwave
[i
]*=INTERPOLATE_AMPLITUDE(note_ptr
->FM_old_amplitude_ptr
[voice_index
]
746 ,note_ptr
->FM_new_amplitude_ptr
[voice_index
],i
,SOUND_BUFFER_SIZE
);
748 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->FM_new_amplitude_ptr
[voice_index
];
751 //normalize makes all sample-rates, oscil_sizes toproduce same sound
752 if (FMmode
!=0){//Frequency modulation
753 REALTYPE normalize
= OSCIL_SIZE
/ 262144.0 * 44100.0 / note_ptr
->synth_ptr
->sample_rate
;
754 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
755 note_ptr
->FM_old_smp_ptr
[voice_index
]=fmod(note_ptr
->FM_old_smp_ptr
[voice_index
]+note_ptr
->tmpwave
[i
]*normalize
,OSCIL_SIZE
);
756 note_ptr
->tmpwave
[i
]=note_ptr
->FM_old_smp_ptr
[voice_index
];
758 } else {//Phase modulation
759 REALTYPE normalize
=OSCIL_SIZE
/262144.0;
760 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=normalize
;
763 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++){
764 F2I(note_ptr
->tmpwave
[i
],FMmodfreqhi
);
765 FMmodfreqlo
=fmod(note_ptr
->tmpwave
[i
]+0.0000000001,1.0);
766 if (FMmodfreqhi
<0) FMmodfreqlo
++;
769 carposhi
=note_ptr
->osc_pos_hi_ptr
[voice_index
]+FMmodfreqhi
;
770 carposlo
=note_ptr
->osc_pos_lo_ptr
[voice_index
]+FMmodfreqlo
;
774 carposlo
=fmod(carposlo
,1.0);
776 carposhi
&=(OSCIL_SIZE
-1);
778 note_ptr
->tmpwave
[i
]=note_ptr
->voices_ptr
[voice_index
].OscilSmp
[carposhi
]*(1.0-carposlo
)
779 +note_ptr
->voices_ptr
[voice_index
].OscilSmp
[carposhi
+1]*carposlo
;
781 note_ptr
->osc_pos_lo_ptr
[voice_index
]+=note_ptr
->osc_freq_lo_ptr
[voice_index
];
782 if (note_ptr
->osc_pos_lo_ptr
[voice_index
]>=1.0) {
783 note_ptr
->osc_pos_lo_ptr
[voice_index
]=fmod(note_ptr
->osc_pos_lo_ptr
[voice_index
],1.0);
784 note_ptr
->osc_pos_hi_ptr
[voice_index
]++;
787 note_ptr
->osc_pos_hi_ptr
[voice_index
]+=note_ptr
->osc_freq_hi_ptr
[voice_index
];
788 note_ptr
->osc_pos_hi_ptr
[voice_index
]&=OSCIL_SIZE
-1;
793 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
797 ComputeVoiceOscillatorPitchModulation(
798 struct addnote
* note_ptr
,
812 struct addnote
* note_ptr
,
815 for (int i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
817 note_ptr
->tmpwave
[i
] = zyn_random() * 2.0 - 1.0;
821 #define note_ptr ((struct addnote *)handle)
825 zyn_addnote_handle handle
,
827 bool random_grouping
,
833 unsigned int voice_index
;
835 float filter_velocity_adjust
;
836 int voice_oscillator_index
;
838 unsigned char detune_type
;
840 note_ptr
->portamento
= portamento
;
841 note_ptr
->midinote
= midinote
;
842 note_ptr
->note_enabled
= true;
843 note_ptr
->basefreq
= freq
;
847 note_ptr
->velocity
= 1.0;
851 note_ptr
->velocity
= velocity
;
854 note_ptr
->time
= 0.0;
856 note_ptr
->panning
= (panorama
+ 1.0) / 2; // -1..1 -> 0 - 1
858 note_ptr
->filter_category
= note_ptr
->synth_ptr
->filter_type
;
860 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
862 filter_velocity_adjust
= note_ptr
->synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
863 (zyn_velocity_scale(note_ptr
->velocity
, note_ptr
->synth_ptr
->m_filter_velocity_scale_function
) - 1);
865 zyn_filter_sv_processor_init(note_ptr
->filter_sv_processor_left
, freq
, filter_velocity_adjust
);
866 if (note_ptr
->stereo
)
868 zyn_filter_sv_processor_init(note_ptr
->filter_sv_processor_right
, freq
, filter_velocity_adjust
);
873 note_ptr
->filter_center_pitch
=
874 note_ptr
->synth_ptr
->m_filter_params
.getfreq() + // center freq
875 note_ptr
->synth_ptr
->m_filter_velocity_sensing_amount
* 6.0 * // velocity sensing
876 (zyn_velocity_scale(note_ptr
->velocity
, note_ptr
->synth_ptr
->m_filter_velocity_scale_function
) - 1);
877 note_ptr
->filter_center_pitch
+= note_ptr
->synth_ptr
->m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
880 if (note_ptr
->synth_ptr
->PPunchStrength
!= 0)
882 note_ptr
->punch_enabled
= true;
883 note_ptr
->punch_t
= 1.0; // start from 1.0 and to 0.0
884 note_ptr
->punch_initial_value
= pow(10, 1.5 * note_ptr
->synth_ptr
->PPunchStrength
/ 127.0) - 1.0;
885 note_ptr
->punch_initial_value
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->PPunchVelocitySensing
);
887 REALTYPE time
= pow(10, 3.0 * note_ptr
->synth_ptr
->PPunchTime
/ 127.0) / 10000.0; // 0.1 .. 100 ms
889 REALTYPE stretch
= pow(440.0/freq
, note_ptr
->synth_ptr
->PPunchStretch
/ 64.0);
891 note_ptr
->punch_duration
= 1.0 / (time
* note_ptr
->synth_ptr
->sample_rate
* stretch
);
895 note_ptr
->punch_enabled
= false;
898 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
900 zyn_oscillator_new_rand_seed(
901 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].oscillator
,
904 note_ptr
->voices_ptr
[voice_index
].FMVoice
= -1;
906 if (!note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].enabled
)
908 note_ptr
->voices_ptr
[voice_index
].enabled
= false;
909 continue; // the voice is disabled
912 note_ptr
->voices_ptr
[voice_index
].enabled
= true;
913 note_ptr
->voices_ptr
[voice_index
].fixed_detune
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fixed_detune
;
915 // calculate voice detune
917 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.type
== ZYN_DETUNE_TYPE_GLOBAL
)
919 detune_type
= note_ptr
->synth_ptr
->detune
.type
;
923 detune_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.type
;
927 note_ptr
->voices_ptr
[voice_index
].Detune
= zyn_get_detune(detune_type
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.coarse
, 8192);
930 note_ptr
->voices_ptr
[voice_index
].FineDetune
= zyn_get_detune(detune_type
, 0, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.fine
);
933 // calculate voice fm detune
935 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.type
== ZYN_DETUNE_TYPE_GLOBAL
)
937 detune_type
= note_ptr
->synth_ptr
->detune
.type
;
941 detune_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.type
;
944 note_ptr
->voices_ptr
[voice_index
].FMDetune
=
947 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.coarse
,
948 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.fine
);
951 note_ptr
->osc_pos_hi_ptr
[voice_index
] = 0;
952 note_ptr
->osc_pos_lo_ptr
[voice_index
] = 0.0;
953 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = 0;
954 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = 0.0;
956 // Get the voice's oscil or external's voice oscil
957 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
!= -1)
959 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
;
963 voice_oscillator_index
= voice_index
;
966 if (!random_grouping
)
968 zyn_oscillator_new_rand_seed(
969 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
973 note_ptr
->osc_pos_hi_ptr
[voice_index
] =
975 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
976 note_ptr
->voices_ptr
[voice_index
].OscilSmp
,
977 getvoicebasefreq(note_ptr
, voice_index
),
978 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].resonance
);
980 // I store the first elments to the last position for speedups
981 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
983 note_ptr
->voices_ptr
[voice_index
].OscilSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].OscilSmp
[i
];
986 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);
987 note_ptr
->osc_pos_hi_ptr
[voice_index
] %= OSCIL_SIZE
;
989 note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreq();
990 note_ptr
->voices_ptr
[voice_index
].filterbypass
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pfilterbypass
;
992 note_ptr
->voices_ptr
[voice_index
].fm_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_type
;
994 note_ptr
->voices_ptr
[voice_index
].FMVoice
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVoice
;
996 // Compute the Voice's modulator volume (incl. damping)
997 REALTYPE fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0 - 1.0);
998 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1000 case ZYN_FM_TYPE_PHASE_MOD
:
1001 fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0);
1002 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;
1004 case ZYN_FM_TYPE_FREQ_MOD
:
1005 note_ptr
->voices_ptr
[voice_index
].FMVolume
= exp(note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * FM_AMP_MULTIPLIER
);
1006 note_ptr
->voices_ptr
[voice_index
].FMVolume
-= 1.0;
1007 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= fmvoldamp
* 4.0;
1009 #if 0 // ???????????
1010 case ZYN_FM_TYPE_PITCH_MOD
:
1011 note_ptr
->voices_ptr
[voice_index
].FMVolume
= (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * 8.0) * fmvoldamp
;
1015 if (fmvoldamp
> 1.0)
1020 note_ptr
->voices_ptr
[voice_index
].FMVolume
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * fmvoldamp
;
1023 // Voice's modulator velocity sensing
1024 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVelocityScaleFunction
);
1026 note_ptr
->FM_old_smp_ptr
[voice_index
] = 0.0; // this is for FM (integration)
1028 note_ptr
->first_tick_ptr
[voice_index
] = true;
1029 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
);
1032 // Global Parameters
1033 note_ptr
->frequency_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_frequency_envelope_params
, note_ptr
->basefreq
);
1035 note_ptr
->frequency_lfo
.init(
1036 note_ptr
->synth_ptr
->sample_rate
,
1038 ¬e_ptr
->synth_ptr
->frequency_lfo_params
,
1039 ZYN_LFO_TYPE_FREQUENCY
);
1041 note_ptr
->amplitude_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_amplitude_envelope_params
, note_ptr
->basefreq
);
1043 note_ptr
->amplitude_lfo
.init(
1044 note_ptr
->synth_ptr
->sample_rate
,
1046 ¬e_ptr
->synth_ptr
->amplitude_lfo_params
,
1047 ZYN_LFO_TYPE_AMPLITUDE
);
1049 note_ptr
->volume
= 4.0 * pow(0.1, 3.0 * (1.0 - note_ptr
->synth_ptr
->PVolume
/ 96.0)); // -60 dB .. 0 dB
1050 note_ptr
->volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->PAmpVelocityScaleFunction
); // velocity sensing
1052 note_ptr
->amplitude_envelope
.envout_dB(); // discard the first envelope output
1054 note_ptr
->globalnewamplitude
= note_ptr
->volume
* note_ptr
->amplitude_envelope
.envout_dB() * note_ptr
->amplitude_lfo
.amplfoout();
1056 note_ptr
->filter_left
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1057 if (note_ptr
->stereo
)
1059 note_ptr
->filter_right
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1062 note_ptr
->filter_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_envelope_params
, note_ptr
->basefreq
);
1064 note_ptr
->filter_lfo
.init(
1065 note_ptr
->synth_ptr
->sample_rate
,
1067 ¬e_ptr
->synth_ptr
->filter_lfo_params
,
1068 ZYN_LFO_TYPE_FILTER
);
1070 note_ptr
->filter_q_factor
= note_ptr
->synth_ptr
->m_filter_params
.getq();
1072 // Forbids the Modulation Voice to be greater or equal than voice
1073 for (i
= 0 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1075 if (note_ptr
->voices_ptr
[i
].FMVoice
>= (int)i
)
1077 note_ptr
->voices_ptr
[i
].FMVoice
= -1;
1081 // Voice Parameter init
1082 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1084 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1089 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
);
1091 note_ptr
->voices_ptr
[voice_index
].white_noise
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].white_noise
;
1093 /* Voice Amplitude Parameters Init */
1095 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
1096 note_ptr
->voices_ptr
[voice_index
].Volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpVelocityScaleFunction
); // velocity
1098 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PVolumeminus
!= 0)
1100 note_ptr
->voices_ptr
[voice_index
].Volume
= -note_ptr
->voices_ptr
[voice_index
].Volume
;
1103 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
== 0)
1105 note_ptr
->voices_ptr
[voice_index
].Panning
= zyn_random(); // random panning
1109 note_ptr
->voices_ptr
[voice_index
].Panning
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
/ 128.0;
1112 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1113 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
!= 0)
1115 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.init(
1116 note_ptr
->synth_ptr
->sample_rate
,
1117 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_amplitude_envelope_params
,
1118 note_ptr
->basefreq
);
1120 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB(); // discard the first envelope sample
1121 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1124 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
!= 0)
1126 note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.init(
1127 note_ptr
->synth_ptr
->sample_rate
,
1129 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].amplitude_lfo_params
,
1130 ZYN_LFO_TYPE_AMPLITUDE
);
1132 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1135 /* Voice Frequency Parameters Init */
1136 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
!= 0)
1138 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.init(
1139 note_ptr
->synth_ptr
->sample_rate
,
1140 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_frequency_envelope_params
,
1141 note_ptr
->basefreq
);
1144 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
!= 0)
1146 note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.init(
1147 note_ptr
->synth_ptr
->sample_rate
,
1149 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].frequency_lfo_params
,
1150 ZYN_LFO_TYPE_FREQUENCY
);
1153 /* Voice Filter Parameters Init */
1154 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
!= 0)
1156 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.init(
1157 note_ptr
->synth_ptr
->sample_rate
,
1158 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
);
1161 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
!= 0)
1163 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.init(
1164 note_ptr
->synth_ptr
->sample_rate
,
1165 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_envelope_params
,
1166 note_ptr
->basefreq
);
1169 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
!= 0)
1171 note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.init(
1172 note_ptr
->synth_ptr
->sample_rate
,
1174 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].filter_lfo_params
,
1175 ZYN_LFO_TYPE_FILTER
);
1178 note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
1180 /* Voice Modulation Parameters Init */
1181 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
&&
1182 note_ptr
->voices_ptr
[voice_index
].FMVoice
< 0)
1184 zyn_oscillator_new_rand_seed(
1185 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].modulator_oscillator
,
1188 // Perform Anti-aliasing only on MORPH or RING MODULATION
1190 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
!= -1)
1192 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
;
1196 voice_oscillator_index
= voice_index
;
1199 if ((note_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
.Padaptiveharmonics
!= 0) ||
1200 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_MORPH
) ||
1201 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_RING_MOD
))
1203 tmp
= getFMvoicebasefreq(note_ptr
, voice_index
);
1210 if (!random_grouping
)
1212 zyn_oscillator_new_rand_seed(
1213 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1217 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = note_ptr
->osc_pos_hi_ptr
[voice_index
];
1218 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] += zyn_oscillator_get(
1219 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1220 note_ptr
->voices_ptr
[voice_index
].FMSmp
,
1223 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1225 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
1227 note_ptr
->voices_ptr
[voice_index
].FMSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].FMSmp
[i
];
1230 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);
1231 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1234 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
!= 0)
1236 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.init(
1237 note_ptr
->synth_ptr
->sample_rate
,
1238 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_frequency_envelope_params
,
1239 note_ptr
->basefreq
);
1242 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1243 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1245 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
!= 0)
1247 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.init(
1248 note_ptr
->synth_ptr
->sample_rate
,
1249 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_amplitude_envelope_params
,
1250 note_ptr
->basefreq
);
1252 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1254 } // voice parameter init loop
1256 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1258 for (i
= voice_index
+ 1 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1260 if (note_ptr
->voices_ptr
[i
].FMVoice
== (int)voice_index
)
1262 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
1272 zyn_addnote_force_disable(
1273 zyn_addnote_handle handle
)
1275 unsigned int voice_index
;
1277 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1279 if (note_ptr
->voices_ptr
[voice_index
].enabled
)
1281 kill_voice(note_ptr
, voice_index
);
1285 note_ptr
->note_enabled
= false;
1289 zyn_addnote_destroy(
1290 zyn_addnote_handle handle
)
1292 unsigned int voice_index
;
1294 if (note_ptr
->note_enabled
)
1296 zyn_addnote_force_disable(handle
);
1299 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_left
);
1300 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_right
);
1302 free(note_ptr
->old_amplitude_ptr
);
1303 free(note_ptr
->new_amplitude_ptr
);
1305 free(note_ptr
->FM_old_amplitude_ptr
);
1306 free(note_ptr
->FM_new_amplitude_ptr
);
1308 free(note_ptr
->first_tick_ptr
);
1310 free(note_ptr
->FM_old_smp_ptr
);
1312 free(note_ptr
->osc_freq_hi_ptr
);
1313 free(note_ptr
->osc_freq_lo_ptr
);
1314 free(note_ptr
->osc_freq_hi_FM_ptr
);
1315 free(note_ptr
->osc_freq_lo_FM_ptr
);
1317 free(note_ptr
->osc_pos_hi_ptr
);
1318 free(note_ptr
->osc_pos_lo_ptr
);
1319 free(note_ptr
->osc_pos_hi_FM_ptr
);
1320 free(note_ptr
->osc_pos_lo_FM_ptr
);
1322 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1324 // the extra points contains the first point
1325 free(note_ptr
->voices_ptr
[voice_index
].OscilSmp
);
1326 free(note_ptr
->voices_ptr
[voice_index
].FMSmp
);
1327 free(note_ptr
->voices_ptr
[voice_index
].VoiceOut
);
1330 free(note_ptr
->voices_ptr
);
1332 free(note_ptr
->tmpwave
);
1333 free(note_ptr
->bypassl
);
1334 free(note_ptr
->bypassr
);
1340 * Compute the ADnote samples
1343 zyn_addnote_noteout(
1344 zyn_addnote_handle handle
,
1349 unsigned int voice_index
;
1350 float filter_adjust
;
1352 silence_two_buffers(outl
, outr
, SOUND_BUFFER_SIZE
);
1354 if (!note_ptr
->note_enabled
)
1359 silence_two_buffers(note_ptr
->bypassl
, note_ptr
->bypassr
, SOUND_BUFFER_SIZE
);
1362 * Compute all the parameters for each tick
1365 unsigned int voice_index
;
1371 float FMrelativepitch
;
1373 float temp_filter_frequency
;
1376 0.01 * (note_ptr
->frequency_envelope
.envout() +
1377 note_ptr
->frequency_lfo
.lfoout() * note_ptr
->synth_ptr
->modwheel_relmod
);
1379 note_ptr
->globaloldamplitude
= note_ptr
->globalnewamplitude
;
1381 note_ptr
->globalnewamplitude
=
1383 note_ptr
->amplitude_envelope
.envout_dB() *
1384 note_ptr
->amplitude_lfo
.amplfoout();
1386 if (note_ptr
->filter_category
!= ZYN_FILTER_TYPE_STATE_VARIABLE
)
1388 temp_filter_frequency
= note_ptr
->filter_left
.getrealfreq(note_ptr
->filter_center_pitch
+ note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout());
1390 note_ptr
->filter_left
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1391 if (note_ptr
->stereo
)
1393 note_ptr
->filter_right
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1397 // compute the portamento, if it is used by this note
1398 REALTYPE portamentofreqrap
=1.0;
1399 if (note_ptr
->portamento
)
1401 // this voice use portamento
1402 portamentofreqrap
= note_ptr
->synth_ptr
->portamento
.freqrap
;
1404 if (!note_ptr
->synth_ptr
->portamento
.used
)
1406 // the portamento has finished
1407 note_ptr
->portamento
= false; // this note is no longer "portamented"
1411 //compute parameters for all voices
1412 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1414 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1419 note_ptr
->voices_ptr
[voice_index
].DelayTicks
-= 1;
1421 if (note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1426 /*******************/
1427 /* Voice Amplitude */
1428 /*******************/
1429 note_ptr
->old_amplitude_ptr
[voice_index
] = note_ptr
->new_amplitude_ptr
[voice_index
];
1430 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1432 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1434 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1437 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
)
1439 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1445 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1447 filterpitch
= note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
;
1449 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1451 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.envout();
1454 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
)
1456 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.lfoout();
1459 filterfreq
= filterpitch
+ note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
;
1460 filterfreq
= note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.getrealfreq(filterfreq
);
1462 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.setfreq(filterfreq
);
1465 // compute only if the voice isn't noise
1466 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
)
1468 /*******************/
1469 /* Voice Frequency */
1470 /*******************/
1472 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
)
1474 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.lfoout() / 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
;
1477 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1479 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.envout() / 100.0;
1482 voicefreq
= getvoicebasefreq(note_ptr
, voice_index
) * pow(2, (voicepitch
+ globalpitch
) / 12.0); // Hz frequency
1483 voicefreq
*= note_ptr
->synth_ptr
->pitch_bend_relative_frequency
; // change the frequency by the controller
1484 setfreq(note_ptr
, voice_index
, voicefreq
* portamentofreqrap
);
1489 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
)
1491 FMrelativepitch
= note_ptr
->voices_ptr
[voice_index
].FMDetune
/ 100.0;
1492 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1494 FMrelativepitch
+= note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.envout() / 100;
1497 FMfreq
= pow(2.0, FMrelativepitch
/ 12.0) * voicefreq
* portamentofreqrap
;
1498 setfreqFM(note_ptr
, voice_index
, FMfreq
);
1500 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = note_ptr
->FM_new_amplitude_ptr
[voice_index
];
1501 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1502 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1504 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1506 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1512 note_ptr
->time
+= (REALTYPE
)SOUND_BUFFER_SIZE
/ note_ptr
->synth_ptr
->sample_rate
;
1515 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1517 if (!note_ptr
->voices_ptr
[voice_index
].enabled
|| note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1522 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
) //voice mode = sound
1524 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1526 case ZYN_FM_TYPE_MORPH
:
1527 ComputeVoiceOscillatorMorph(note_ptr
, voice_index
);
1529 case ZYN_FM_TYPE_RING_MOD
:
1530 ComputeVoiceOscillatorRingModulation(note_ptr
, voice_index
);
1532 case ZYN_FM_TYPE_PHASE_MOD
:
1533 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 0);
1535 case ZYN_FM_TYPE_FREQ_MOD
:
1536 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 1);
1539 case ZYN_FM_TYPE_PITCH_MOD
:
1540 ComputeVoiceOscillatorPitchModulation(note_ptr
, voice_index
);
1544 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
1545 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1550 ComputeVoiceNoise(note_ptr
, voice_index
);
1556 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->old_amplitude_ptr
[voice_index
],note_ptr
->new_amplitude_ptr
[voice_index
])){
1557 int rest
=SOUND_BUFFER_SIZE
;
1558 //test if the amplitude if raising and the difference is high
1559 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)){
1561 if (rest
>SOUND_BUFFER_SIZE
) rest
=SOUND_BUFFER_SIZE
;
1562 for (int i
=0;i
<SOUND_BUFFER_SIZE
-rest
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->old_amplitude_ptr
[voice_index
];
1564 // Amplitude interpolation
1565 for (i
=0;i
<rest
;i
++){
1566 note_ptr
->tmpwave
[i
+(SOUND_BUFFER_SIZE
-rest
)]*=INTERPOLATE_AMPLITUDE(note_ptr
->old_amplitude_ptr
[voice_index
]
1567 ,note_ptr
->new_amplitude_ptr
[voice_index
],i
,rest
);
1569 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->new_amplitude_ptr
[voice_index
];
1572 if (note_ptr
->first_tick_ptr
[voice_index
])
1574 fadein(note_ptr
, ¬e_ptr
->tmpwave
[0]);
1575 note_ptr
->first_tick_ptr
[voice_index
] = false;
1579 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1581 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.filterout(¬e_ptr
->tmpwave
[0]);
1584 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1585 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1587 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1589 for (i
=0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1591 note_ptr
->tmpwave
[i
] *= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1595 // the voice is killed later
1599 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1600 if (note_ptr
->voices_ptr
[voice_index
].VoiceOut
!=NULL
)
1602 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1604 note_ptr
->voices_ptr
[voice_index
].VoiceOut
[i
] = note_ptr
->tmpwave
[i
];
1608 // Add the voice that do not bypass the filter to out
1609 if (note_ptr
->voices_ptr
[voice_index
].filterbypass
==0)
1613 if (note_ptr
->stereo
)
1616 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1618 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1619 outr
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* (1.0 - note_ptr
->voices_ptr
[voice_index
].Panning
) * 2.0;
1625 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1627 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;}
1632 // bypass the filter
1634 if (note_ptr
->stereo
)
1637 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1639 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1640 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;
1646 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1648 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;
1652 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1653 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1655 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1657 kill_voice(note_ptr
, voice_index
);
1662 // Processing Global parameters
1664 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
1666 filter_adjust
= note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout();
1668 zyn_filter_sv_process(note_ptr
->filter_sv_processor_left
, filter_adjust
, outl
);
1670 if (note_ptr
->stereo
)
1672 zyn_filter_sv_process(note_ptr
->filter_sv_processor_right
, filter_adjust
, outr
);
1677 note_ptr
->filter_left
.filterout(&outl
[0]);
1679 if (note_ptr
->stereo
)
1681 note_ptr
->filter_right
.filterout(&outr
[0]);
1685 if (!note_ptr
->stereo
)
1687 // set the right channel=left channel
1688 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1691 note_ptr
->bypassr
[i
]=note_ptr
->bypassl
[i
];
1695 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1697 // outl[i]+=note_ptr->bypassl[i];
1698 // outr[i]+=note_ptr->bypassr[i];
1701 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
))
1703 // Amplitude Interpolation
1704 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1706 REALTYPE tmpvol
= INTERPOLATE_AMPLITUDE(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
, i
, SOUND_BUFFER_SIZE
);
1707 outl
[i
] *= tmpvol
* (1.0 - note_ptr
->panning
);
1708 outr
[i
] *= tmpvol
* note_ptr
->panning
;
1713 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1715 outl
[i
] *= note_ptr
->globalnewamplitude
* (1.0 - note_ptr
->panning
);
1716 outr
[i
] *= note_ptr
->globalnewamplitude
* note_ptr
->panning
;
1721 if (note_ptr
->punch_enabled
)
1723 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1725 REALTYPE punchamp
= note_ptr
->punch_initial_value
* note_ptr
->punch_t
+ 1.0;
1726 outl
[i
] *= punchamp
;
1727 outr
[i
] *= punchamp
;
1728 note_ptr
->punch_t
-= note_ptr
->punch_duration
;
1729 if (note_ptr
->punch_t
< 0.0)
1731 note_ptr
->punch_enabled
= false;
1737 // Check if the global amplitude is finished.
1738 // If it does, disable the note
1739 if (note_ptr
->amplitude_envelope
.finished())
1741 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1745 REALTYPE tmp
= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1751 zyn_addnote_force_disable(note_ptr
);
1761 * Relase the key (NoteOff)
1764 zyn_addnote_note_off(
1765 zyn_addnote_handle handle
)
1767 unsigned int voice_index
;
1769 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1771 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1776 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1778 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.relasekey();
1781 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1783 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.relasekey();
1786 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1788 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.relasekey();
1791 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1793 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.relasekey();
1796 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1798 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.relasekey();
1802 note_ptr
->frequency_envelope
.relasekey();
1803 note_ptr
->filter_envelope
.relasekey();
1804 note_ptr
->amplitude_envelope
.relasekey();