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
=
294 synth_ptr
->detune_bandwidth
* pow(fabs(synth_ptr
->detune_bandwidth
), 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_MODE_NORMAL
:
334 frequency
= note_ptr
->basefreq
;
336 case ZYN_DETUNE_MODE_FIXED_440
:
339 case ZYN_DETUNE_MODE_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
=
930 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.octave
,
931 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.coarse
,
935 note_ptr
->voices_ptr
[voice_index
].FineDetune
= zyn_get_detune(
939 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].detune
.fine
);
942 // calculate voice fm detune
944 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.type
== ZYN_DETUNE_TYPE_GLOBAL
)
946 detune_type
= note_ptr
->synth_ptr
->detune
.type
;
950 detune_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.type
;
953 note_ptr
->voices_ptr
[voice_index
].FMDetune
=
956 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.octave
,
957 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.coarse
,
958 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_detune
.fine
);
961 note_ptr
->osc_pos_hi_ptr
[voice_index
] = 0;
962 note_ptr
->osc_pos_lo_ptr
[voice_index
] = 0.0;
963 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = 0;
964 note_ptr
->osc_pos_lo_FM_ptr
[voice_index
] = 0.0;
966 // Get the voice's oscil or external's voice oscil
967 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
!= -1)
969 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pextoscil
;
973 voice_oscillator_index
= voice_index
;
976 if (!random_grouping
)
978 zyn_oscillator_new_rand_seed(
979 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
983 note_ptr
->osc_pos_hi_ptr
[voice_index
] =
985 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].oscillator
,
986 note_ptr
->voices_ptr
[voice_index
].OscilSmp
,
987 getvoicebasefreq(note_ptr
, voice_index
),
988 note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].resonance
);
990 // I store the first elments to the last position for speedups
991 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
993 note_ptr
->voices_ptr
[voice_index
].OscilSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].OscilSmp
[i
];
996 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);
997 note_ptr
->osc_pos_hi_ptr
[voice_index
] %= OSCIL_SIZE
;
999 note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreq();
1000 note_ptr
->voices_ptr
[voice_index
].filterbypass
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].Pfilterbypass
;
1002 note_ptr
->voices_ptr
[voice_index
].fm_type
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].fm_type
;
1004 note_ptr
->voices_ptr
[voice_index
].FMVoice
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVoice
;
1006 // Compute the Voice's modulator volume (incl. damping)
1007 REALTYPE fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0 - 1.0);
1008 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1010 case ZYN_FM_TYPE_PHASE_MOD
:
1011 fmvoldamp
= pow(440.0 / getvoicebasefreq(note_ptr
, voice_index
), note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolumeDamp
/ 64.0);
1012 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;
1014 case ZYN_FM_TYPE_FREQ_MOD
:
1015 note_ptr
->voices_ptr
[voice_index
].FMVolume
= exp(note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * FM_AMP_MULTIPLIER
);
1016 note_ptr
->voices_ptr
[voice_index
].FMVolume
-= 1.0;
1017 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= fmvoldamp
* 4.0;
1019 #if 0 // ???????????
1020 case ZYN_FM_TYPE_PITCH_MOD
:
1021 note_ptr
->voices_ptr
[voice_index
].FMVolume
= (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * 8.0) * fmvoldamp
;
1025 if (fmvoldamp
> 1.0)
1030 note_ptr
->voices_ptr
[voice_index
].FMVolume
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVolume
/ 127.0 * fmvoldamp
;
1033 // Voice's modulator velocity sensing
1034 note_ptr
->voices_ptr
[voice_index
].FMVolume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMVelocityScaleFunction
);
1036 note_ptr
->FM_old_smp_ptr
[voice_index
] = 0.0; // this is for FM (integration)
1038 note_ptr
->first_tick_ptr
[voice_index
] = true;
1039 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
);
1042 // Global Parameters
1043 note_ptr
->frequency_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_frequency_envelope_params
, note_ptr
->basefreq
);
1045 note_ptr
->frequency_lfo
.init(
1046 note_ptr
->synth_ptr
->sample_rate
,
1048 ¬e_ptr
->synth_ptr
->frequency_lfo_params
,
1049 ZYN_LFO_TYPE_FREQUENCY
);
1051 note_ptr
->amplitude_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_amplitude_envelope_params
, note_ptr
->basefreq
);
1053 note_ptr
->amplitude_lfo
.init(
1054 note_ptr
->synth_ptr
->sample_rate
,
1056 ¬e_ptr
->synth_ptr
->amplitude_lfo_params
,
1057 ZYN_LFO_TYPE_AMPLITUDE
);
1059 note_ptr
->volume
= 4.0 * pow(0.1, 3.0 * (1.0 - note_ptr
->synth_ptr
->PVolume
/ 96.0)); // -60 dB .. 0 dB
1060 note_ptr
->volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->PAmpVelocityScaleFunction
); // velocity sensing
1062 note_ptr
->amplitude_envelope
.envout_dB(); // discard the first envelope output
1064 note_ptr
->globalnewamplitude
= note_ptr
->volume
* note_ptr
->amplitude_envelope
.envout_dB() * note_ptr
->amplitude_lfo
.amplfoout();
1066 note_ptr
->filter_left
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1067 if (note_ptr
->stereo
)
1069 note_ptr
->filter_right
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_params
);
1072 note_ptr
->filter_envelope
.init(note_ptr
->synth_ptr
->sample_rate
, ¬e_ptr
->synth_ptr
->m_filter_envelope_params
, note_ptr
->basefreq
);
1074 note_ptr
->filter_lfo
.init(
1075 note_ptr
->synth_ptr
->sample_rate
,
1077 ¬e_ptr
->synth_ptr
->filter_lfo_params
,
1078 ZYN_LFO_TYPE_FILTER
);
1080 note_ptr
->filter_q_factor
= note_ptr
->synth_ptr
->m_filter_params
.getq();
1082 // Forbids the Modulation Voice to be greater or equal than voice
1083 for (i
= 0 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1085 if (note_ptr
->voices_ptr
[i
].FMVoice
>= (int)i
)
1087 note_ptr
->voices_ptr
[i
].FMVoice
= -1;
1091 // Voice Parameter init
1092 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1094 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1099 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
);
1101 note_ptr
->voices_ptr
[voice_index
].white_noise
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].white_noise
;
1103 /* Voice Amplitude Parameters Init */
1105 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
1106 note_ptr
->voices_ptr
[voice_index
].Volume
*= VelF(note_ptr
->velocity
, note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpVelocityScaleFunction
); // velocity
1108 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PVolumeminus
!= 0)
1110 note_ptr
->voices_ptr
[voice_index
].Volume
= -note_ptr
->voices_ptr
[voice_index
].Volume
;
1113 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
== 0)
1115 note_ptr
->voices_ptr
[voice_index
].Panning
= zyn_random(); // random panning
1119 note_ptr
->voices_ptr
[voice_index
].Panning
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PPanning
/ 128.0;
1122 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1123 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
!= 0)
1125 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.init(
1126 note_ptr
->synth_ptr
->sample_rate
,
1127 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_amplitude_envelope_params
,
1128 note_ptr
->basefreq
);
1130 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB(); // discard the first envelope sample
1131 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1134 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
!= 0)
1136 note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.init(
1137 note_ptr
->synth_ptr
->sample_rate
,
1139 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].amplitude_lfo_params
,
1140 ZYN_LFO_TYPE_AMPLITUDE
);
1142 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1145 /* Voice Frequency Parameters Init */
1146 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
!= 0)
1148 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.init(
1149 note_ptr
->synth_ptr
->sample_rate
,
1150 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_frequency_envelope_params
,
1151 note_ptr
->basefreq
);
1154 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
!= 0)
1156 note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.init(
1157 note_ptr
->synth_ptr
->sample_rate
,
1159 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].frequency_lfo_params
,
1160 ZYN_LFO_TYPE_FREQUENCY
);
1163 /* Voice Filter Parameters Init */
1164 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
!= 0)
1166 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.init(
1167 note_ptr
->synth_ptr
->sample_rate
,
1168 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
);
1171 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
!= 0)
1173 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.init(
1174 note_ptr
->synth_ptr
->sample_rate
,
1175 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_envelope_params
,
1176 note_ptr
->basefreq
);
1179 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
!= 0)
1181 note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.init(
1182 note_ptr
->synth_ptr
->sample_rate
,
1184 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].filter_lfo_params
,
1185 ZYN_LFO_TYPE_FILTER
);
1188 note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_filter_params
.getfreqtracking(note_ptr
->basefreq
);
1190 /* Voice Modulation Parameters Init */
1191 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
&&
1192 note_ptr
->voices_ptr
[voice_index
].FMVoice
< 0)
1194 zyn_oscillator_new_rand_seed(
1195 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].modulator_oscillator
,
1198 // Perform Anti-aliasing only on MORPH or RING MODULATION
1200 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
!= -1)
1202 voice_oscillator_index
= note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PextFMoscil
;
1206 voice_oscillator_index
= voice_index
;
1209 if ((note_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
.Padaptiveharmonics
!= 0) ||
1210 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_MORPH
) ||
1211 (note_ptr
->voices_ptr
[voice_index
].fm_type
== ZYN_FM_TYPE_RING_MOD
))
1213 tmp
= getFMvoicebasefreq(note_ptr
, voice_index
);
1220 if (!random_grouping
)
1222 zyn_oscillator_new_rand_seed(
1223 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1227 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] = note_ptr
->osc_pos_hi_ptr
[voice_index
];
1228 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] += zyn_oscillator_get(
1229 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_oscillator_index
].modulator_oscillator
,
1230 note_ptr
->voices_ptr
[voice_index
].FMSmp
,
1233 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1235 for (i
= 0 ; i
< OSCIL_SMP_EXTRA_SAMPLES
; i
++)
1237 note_ptr
->voices_ptr
[voice_index
].FMSmp
[OSCIL_SIZE
+ i
] = note_ptr
->voices_ptr
[voice_index
].FMSmp
[i
];
1240 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);
1241 note_ptr
->osc_pos_hi_FM_ptr
[voice_index
] %= OSCIL_SIZE
;
1244 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
!= 0)
1246 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.init(
1247 note_ptr
->synth_ptr
->sample_rate
,
1248 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_frequency_envelope_params
,
1249 note_ptr
->basefreq
);
1252 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1253 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1255 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
!= 0)
1257 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.init(
1258 note_ptr
->synth_ptr
->sample_rate
,
1259 ¬e_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].m_fm_amplitude_envelope_params
,
1260 note_ptr
->basefreq
);
1262 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1264 } // voice parameter init loop
1266 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1268 for (i
= voice_index
+ 1 ; i
< note_ptr
->synth_ptr
->voices_count
; i
++)
1270 if (note_ptr
->voices_ptr
[i
].FMVoice
== (int)voice_index
)
1272 silence_buffer(note_ptr
->voices_ptr
[voice_index
].VoiceOut
, SOUND_BUFFER_SIZE
);
1282 zyn_addnote_force_disable(
1283 zyn_addnote_handle handle
)
1285 unsigned int voice_index
;
1287 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1289 if (note_ptr
->voices_ptr
[voice_index
].enabled
)
1291 kill_voice(note_ptr
, voice_index
);
1295 note_ptr
->note_enabled
= false;
1299 zyn_addnote_destroy(
1300 zyn_addnote_handle handle
)
1302 unsigned int voice_index
;
1304 if (note_ptr
->note_enabled
)
1306 zyn_addnote_force_disable(handle
);
1309 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_left
);
1310 zyn_filter_sv_processor_destroy(note_ptr
->filter_sv_processor_right
);
1312 free(note_ptr
->old_amplitude_ptr
);
1313 free(note_ptr
->new_amplitude_ptr
);
1315 free(note_ptr
->FM_old_amplitude_ptr
);
1316 free(note_ptr
->FM_new_amplitude_ptr
);
1318 free(note_ptr
->first_tick_ptr
);
1320 free(note_ptr
->FM_old_smp_ptr
);
1322 free(note_ptr
->osc_freq_hi_ptr
);
1323 free(note_ptr
->osc_freq_lo_ptr
);
1324 free(note_ptr
->osc_freq_hi_FM_ptr
);
1325 free(note_ptr
->osc_freq_lo_FM_ptr
);
1327 free(note_ptr
->osc_pos_hi_ptr
);
1328 free(note_ptr
->osc_pos_lo_ptr
);
1329 free(note_ptr
->osc_pos_hi_FM_ptr
);
1330 free(note_ptr
->osc_pos_lo_FM_ptr
);
1332 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1334 // the extra points contains the first point
1335 free(note_ptr
->voices_ptr
[voice_index
].OscilSmp
);
1336 free(note_ptr
->voices_ptr
[voice_index
].FMSmp
);
1337 free(note_ptr
->voices_ptr
[voice_index
].VoiceOut
);
1340 free(note_ptr
->voices_ptr
);
1342 free(note_ptr
->tmpwave
);
1343 free(note_ptr
->bypassl
);
1344 free(note_ptr
->bypassr
);
1350 * Compute the ADnote samples
1353 zyn_addnote_noteout(
1354 zyn_addnote_handle handle
,
1359 unsigned int voice_index
;
1360 float filter_adjust
;
1362 silence_two_buffers(outl
, outr
, SOUND_BUFFER_SIZE
);
1364 if (!note_ptr
->note_enabled
)
1369 silence_two_buffers(note_ptr
->bypassl
, note_ptr
->bypassr
, SOUND_BUFFER_SIZE
);
1372 * Compute all the parameters for each tick
1375 unsigned int voice_index
;
1381 float FMrelativepitch
;
1383 float temp_filter_frequency
;
1386 0.01 * (note_ptr
->frequency_envelope
.envout() +
1387 note_ptr
->frequency_lfo
.lfoout() * note_ptr
->synth_ptr
->modwheel_relmod
);
1389 note_ptr
->globaloldamplitude
= note_ptr
->globalnewamplitude
;
1391 note_ptr
->globalnewamplitude
=
1393 note_ptr
->amplitude_envelope
.envout_dB() *
1394 note_ptr
->amplitude_lfo
.amplfoout();
1396 if (note_ptr
->filter_category
!= ZYN_FILTER_TYPE_STATE_VARIABLE
)
1398 temp_filter_frequency
= note_ptr
->filter_left
.getrealfreq(note_ptr
->filter_center_pitch
+ note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout());
1400 note_ptr
->filter_left
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1401 if (note_ptr
->stereo
)
1403 note_ptr
->filter_right
.setfreq_and_q(temp_filter_frequency
, note_ptr
->filter_q_factor
);
1407 // compute the portamento, if it is used by this note
1408 REALTYPE portamentofreqrap
=1.0;
1409 if (note_ptr
->portamento
)
1411 // this voice use portamento
1412 portamentofreqrap
= note_ptr
->synth_ptr
->portamento
.freqrap
;
1414 if (!note_ptr
->synth_ptr
->portamento
.used
)
1416 // the portamento has finished
1417 note_ptr
->portamento
= false; // this note is no longer "portamented"
1421 //compute parameters for all voices
1422 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1424 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1429 note_ptr
->voices_ptr
[voice_index
].DelayTicks
-= 1;
1431 if (note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1436 /*******************/
1437 /* Voice Amplitude */
1438 /*******************/
1439 note_ptr
->old_amplitude_ptr
[voice_index
] = note_ptr
->new_amplitude_ptr
[voice_index
];
1440 note_ptr
->new_amplitude_ptr
[voice_index
] = 1.0;
1442 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1444 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.envout_dB();
1447 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpLfoEnabled
)
1449 note_ptr
->new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_amplitude_lfo
.amplfoout();
1455 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1457 filterpitch
= note_ptr
->voices_ptr
[voice_index
].FilterCenterPitch
;
1459 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1461 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.envout();
1464 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterLfoEnabled
)
1466 filterpitch
+= note_ptr
->voices_ptr
[voice_index
].m_filter_lfo
.lfoout();
1469 filterfreq
= filterpitch
+ note_ptr
->voices_ptr
[voice_index
].FilterFreqTracking
;
1470 filterfreq
= note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.getrealfreq(filterfreq
);
1472 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.setfreq(filterfreq
);
1475 // compute only if the voice isn't noise
1476 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
)
1478 /*******************/
1479 /* Voice Frequency */
1480 /*******************/
1482 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqLfoEnabled
)
1484 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_lfo
.lfoout() / 100.0 * note_ptr
->synth_ptr
->bandwidth_relbw
;
1487 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1489 voicepitch
+= note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.envout() / 100.0;
1492 voicefreq
= getvoicebasefreq(note_ptr
, voice_index
) * pow(2, (voicepitch
+ globalpitch
) / 12.0); // Hz frequency
1493 voicefreq
*= note_ptr
->synth_ptr
->pitch_bend_relative_frequency
; // change the frequency by the controller
1494 setfreq(note_ptr
, voice_index
, voicefreq
* portamentofreqrap
);
1499 if (note_ptr
->voices_ptr
[voice_index
].fm_type
!= ZYN_FM_TYPE_NONE
)
1501 FMrelativepitch
= note_ptr
->voices_ptr
[voice_index
].FMDetune
/ 100.0;
1502 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1504 FMrelativepitch
+= note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.envout() / 100;
1507 FMfreq
= pow(2.0, FMrelativepitch
/ 12.0) * voicefreq
* portamentofreqrap
;
1508 setfreqFM(note_ptr
, voice_index
, FMfreq
);
1510 note_ptr
->FM_old_amplitude_ptr
[voice_index
] = note_ptr
->FM_new_amplitude_ptr
[voice_index
];
1511 note_ptr
->FM_new_amplitude_ptr
[voice_index
] = note_ptr
->voices_ptr
[voice_index
].FMVolume
;
1512 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1514 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1516 note_ptr
->FM_new_amplitude_ptr
[voice_index
] *= note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.envout_dB();
1522 note_ptr
->time
+= (REALTYPE
)SOUND_BUFFER_SIZE
/ note_ptr
->synth_ptr
->sample_rate
;
1525 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1527 if (!note_ptr
->voices_ptr
[voice_index
].enabled
|| note_ptr
->voices_ptr
[voice_index
].DelayTicks
> 0)
1532 if (!note_ptr
->voices_ptr
[voice_index
].white_noise
) //voice mode = sound
1534 switch (note_ptr
->voices_ptr
[voice_index
].fm_type
)
1536 case ZYN_FM_TYPE_MORPH
:
1537 ComputeVoiceOscillatorMorph(note_ptr
, voice_index
);
1539 case ZYN_FM_TYPE_RING_MOD
:
1540 ComputeVoiceOscillatorRingModulation(note_ptr
, voice_index
);
1542 case ZYN_FM_TYPE_PHASE_MOD
:
1543 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 0);
1545 case ZYN_FM_TYPE_FREQ_MOD
:
1546 ComputeVoiceOscillatorFrequencyModulation(note_ptr
, voice_index
, 1);
1549 case ZYN_FM_TYPE_PITCH_MOD
:
1550 ComputeVoiceOscillatorPitchModulation(note_ptr
, voice_index
);
1554 ComputeVoiceOscillator_LinearInterpolation(note_ptr
, voice_index
);
1555 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1560 ComputeVoiceNoise(note_ptr
, voice_index
);
1566 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->old_amplitude_ptr
[voice_index
],note_ptr
->new_amplitude_ptr
[voice_index
])){
1567 int rest
=SOUND_BUFFER_SIZE
;
1568 //test if the amplitude if raising and the difference is high
1569 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)){
1571 if (rest
>SOUND_BUFFER_SIZE
) rest
=SOUND_BUFFER_SIZE
;
1572 for (int i
=0;i
<SOUND_BUFFER_SIZE
-rest
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->old_amplitude_ptr
[voice_index
];
1574 // Amplitude interpolation
1575 for (i
=0;i
<rest
;i
++){
1576 note_ptr
->tmpwave
[i
+(SOUND_BUFFER_SIZE
-rest
)]*=INTERPOLATE_AMPLITUDE(note_ptr
->old_amplitude_ptr
[voice_index
]
1577 ,note_ptr
->new_amplitude_ptr
[voice_index
],i
,rest
);
1579 } else for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++) note_ptr
->tmpwave
[i
]*=note_ptr
->new_amplitude_ptr
[voice_index
];
1582 if (note_ptr
->first_tick_ptr
[voice_index
])
1584 fadein(note_ptr
, ¬e_ptr
->tmpwave
[0]);
1585 note_ptr
->first_tick_ptr
[voice_index
] = false;
1589 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnabled
)
1591 note_ptr
->voices_ptr
[voice_index
].m_voice_filter
.filterout(¬e_ptr
->tmpwave
[0]);
1594 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1595 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1597 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1599 for (i
=0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1601 note_ptr
->tmpwave
[i
] *= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1605 // the voice is killed later
1609 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1610 if (note_ptr
->voices_ptr
[voice_index
].VoiceOut
!=NULL
)
1612 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1614 note_ptr
->voices_ptr
[voice_index
].VoiceOut
[i
] = note_ptr
->tmpwave
[i
];
1618 // Add the voice that do not bypass the filter to out
1619 if (note_ptr
->voices_ptr
[voice_index
].filterbypass
==0)
1623 if (note_ptr
->stereo
)
1626 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1628 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1629 outr
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* (1.0 - note_ptr
->voices_ptr
[voice_index
].Panning
) * 2.0;
1635 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1637 outl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;}
1642 // bypass the filter
1644 if (note_ptr
->stereo
)
1647 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1649 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
* note_ptr
->voices_ptr
[voice_index
].Panning
* 2.0;
1650 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;
1656 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1658 note_ptr
->bypassl
[i
] += note_ptr
->tmpwave
[i
] * note_ptr
->voices_ptr
[voice_index
].Volume
;
1662 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1663 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1665 if (note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.finished())
1667 kill_voice(note_ptr
, voice_index
);
1672 // Processing Global parameters
1674 if (note_ptr
->filter_category
== ZYN_FILTER_TYPE_STATE_VARIABLE
)
1676 filter_adjust
= note_ptr
->filter_envelope
.envout() + note_ptr
->filter_lfo
.lfoout();
1678 zyn_filter_sv_process(note_ptr
->filter_sv_processor_left
, filter_adjust
, outl
);
1680 if (note_ptr
->stereo
)
1682 zyn_filter_sv_process(note_ptr
->filter_sv_processor_right
, filter_adjust
, outr
);
1687 note_ptr
->filter_left
.filterout(&outl
[0]);
1689 if (note_ptr
->stereo
)
1691 note_ptr
->filter_right
.filterout(&outr
[0]);
1695 if (!note_ptr
->stereo
)
1697 // set the right channel=left channel
1698 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1701 note_ptr
->bypassr
[i
]=note_ptr
->bypassl
[i
];
1705 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1707 // outl[i]+=note_ptr->bypassl[i];
1708 // outr[i]+=note_ptr->bypassr[i];
1711 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
))
1713 // Amplitude Interpolation
1714 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1716 REALTYPE tmpvol
= INTERPOLATE_AMPLITUDE(note_ptr
->globaloldamplitude
, note_ptr
->globalnewamplitude
, i
, SOUND_BUFFER_SIZE
);
1717 outl
[i
] *= tmpvol
* (1.0 - note_ptr
->panning
);
1718 outr
[i
] *= tmpvol
* note_ptr
->panning
;
1723 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1725 outl
[i
] *= note_ptr
->globalnewamplitude
* (1.0 - note_ptr
->panning
);
1726 outr
[i
] *= note_ptr
->globalnewamplitude
* note_ptr
->panning
;
1731 if (note_ptr
->punch_enabled
)
1733 for (i
=0;i
<SOUND_BUFFER_SIZE
;i
++)
1735 REALTYPE punchamp
= note_ptr
->punch_initial_value
* note_ptr
->punch_t
+ 1.0;
1736 outl
[i
] *= punchamp
;
1737 outr
[i
] *= punchamp
;
1738 note_ptr
->punch_t
-= note_ptr
->punch_duration
;
1739 if (note_ptr
->punch_t
< 0.0)
1741 note_ptr
->punch_enabled
= false;
1747 // Check if the global amplitude is finished.
1748 // If it does, disable the note
1749 if (note_ptr
->amplitude_envelope
.finished())
1751 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
1755 REALTYPE tmp
= 1.0 - (REALTYPE
)i
/ (REALTYPE
)SOUND_BUFFER_SIZE
;
1761 zyn_addnote_force_disable(note_ptr
);
1771 * Relase the key (NoteOff)
1774 zyn_addnote_note_off(
1775 zyn_addnote_handle handle
)
1777 unsigned int voice_index
;
1779 for (voice_index
= 0 ; voice_index
< note_ptr
->synth_ptr
->voices_count
; voice_index
++)
1781 if (!note_ptr
->voices_ptr
[voice_index
].enabled
)
1786 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PAmpEnvelopeEnabled
)
1788 note_ptr
->voices_ptr
[voice_index
].m_amplitude_envelope
.relasekey();
1791 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFreqEnvelopeEnabled
)
1793 note_ptr
->voices_ptr
[voice_index
].m_frequency_envelope
.relasekey();
1796 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFilterEnvelopeEnabled
)
1798 note_ptr
->voices_ptr
[voice_index
].m_filter_envelope
.relasekey();
1801 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMFreqEnvelopeEnabled
)
1803 note_ptr
->voices_ptr
[voice_index
].m_fm_frequency_envelope
.relasekey();
1806 if (note_ptr
->synth_ptr
->voices_params_ptr
[voice_index
].PFMAmpEnvelopeEnabled
)
1808 note_ptr
->voices_ptr
[voice_index
].m_fm_amplitude_envelope
.relasekey();
1812 note_ptr
->frequency_envelope
.relasekey();
1813 note_ptr
->filter_envelope
.relasekey();
1814 note_ptr
->amplitude_envelope
.relasekey();