Expose voice detune parameter of the lv2 plugin
[zyn.git] / addnote.cpp
blobf3835d5e6816b98bfae1344ea6d4dfdb79e0f4de
1 /*
2 ZynAddSubFX - a software synthesizer
4 ADnote.C - The "additive" synthesizer
5 Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov <nedko@arnaudov.name>
6 Copyright (C) 2002-2005 Nasca Octavian Paul
7 Author: Nasca Octavian Paul
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of version 2 of the GNU General Public License
11 as published by the Free Software Foundation.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License (version 2) for more details.
18 You should have received a copy of the GNU General Public License (version 2)
19 along with this program; if not, write to the Free Software Foundation,
20 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <assert.h>
28 #include "globals.h"
29 #include "resonance.h"
30 #include "fft.h"
31 #include "oscillator.h"
32 #include "resonance.h"
33 #include "envelope_parameters.h"
34 #include "lfo_parameters.h"
35 #include "filter_parameters.h"
36 #include "lfo.h"
37 #include "filter_base.h"
38 #include "analog_filter.h"
39 #include "sv_filter.h"
40 #include "formant_filter.h"
41 #include "filter.h"
42 #include "envelope.h"
43 #include "addsynth.h"
44 #include "portamento.h"
45 #include "addsynth_internal.h"
46 #include "addnote.h"
48 #define LOG_LEVEL LOG_LEVEL_ERROR
49 #include "log.h"
51 /***********************************************************/
52 /* VOICE PARAMETERS */
53 /***********************************************************/
54 struct addsynth_voice
56 /* If the voice is enabled */
57 bool enabled;
59 /* Voice Type (sound/noise)*/
60 bool white_noise;
62 /* Filter Bypass */
63 int filterbypass;
65 /* Delay (ticks) */
66 int DelayTicks;
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;
81 LFO m_frequency_lfo;
83 /***************************
84 * AMPLITUDE PARAMETERS *
85 ***************************/
87 /* Panning 0.0=left, 0.5 - center, 1.0 = right */
88 REALTYPE Panning;
89 REALTYPE Volume;// [-1.0 .. 1.0]
91 Envelope m_amplitude_envelope;
92 LFO m_amplitude_lfo;
94 /*************************
95 * FILTER PARAMETERS *
96 *************************/
98 Filter m_voice_filter;
100 REALTYPE FilterCenterPitch;/* Filter center Pitch*/
101 REALTYPE FilterFreqTracking;
103 Envelope m_filter_envelope;
104 LFO m_filter_lfo;
106 /****************************
107 * MODULLATOR PARAMETERS *
108 ****************************/
110 unsigned int fm_type;
112 int FMVoice;
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;
120 REALTYPE FMVolume;
121 REALTYPE FMDetune; //in cents
123 Envelope m_fm_frequency_envelope;
124 Envelope m_fm_amplitude_envelope;
127 //FM amplitude tune
128 #define FM_AMP_MULTIPLIER 14.71280603
130 #define OSCIL_SMP_EXTRA_SAMPLES 5
132 // ADDitive note
133 struct addnote
135 // GLOBALS
136 bool stereo; // if the note is stereo (allows note Panning)
137 int midinote;
138 REALTYPE velocity;
139 REALTYPE basefreq;
141 bool note_enabled;
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
153 REALTYPE time;
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
180 //temporary buffer
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
195 bool portamento;
197 //how the fine detunes are made bigger or smaller
198 REALTYPE bandwidth_detune_multiplier;
200 LFO amplitude_lfo;
201 LFO filter_lfo;
202 LFO frequency_lfo;
204 int filter_category; // One of ZYN_FILTER_TYPE_XXX
205 Filter filter_left;
206 Filter filter_right;
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 ]
225 bool punch_enabled;
226 float punch_initial_value;
227 float punch_duration;
228 float punch_t;
231 bool
232 zyn_addnote_create(
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)
244 return false;
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 =
292 pow(
293 2.0,
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, &note_ptr->filter_sv_processor_left))
304 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &note_ptr->filter_sv_processor_right))
308 *handle_ptr = (zyn_addnote_handle)note_ptr;
309 return true;
313 * Get Voice base frequency
315 static
316 inline
317 REALTYPE
318 getvoicebasefreq(
319 struct addnote * note_ptr,
320 int nvoice)
322 REALTYPE detune;
323 REALTYPE frequency;
324 int equal_temperate;
325 REALTYPE tmp;
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;
335 break;
336 case ZYN_DETUNE_MODE_FIXED_440:
337 frequency = 440.0;
338 break;
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);
348 else
350 frequency = 440 * pow(3.0, tmp);
352 break;
353 default:
354 assert(0);
355 return 440;
358 return frequency * pow(2.0, detune / 12.0);
362 * Get Voice's Modullator base frequency
364 static
365 inline
366 REALTYPE
367 getFMvoicebasefreq(
368 struct addnote * note_ptr,
369 int nvoice)
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
378 static
379 inline
380 void
381 kill_voice(
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
394 static
395 inline
396 void
397 setfreq(
398 struct addnote * note_ptr,
399 int nvoice,
400 REALTYPE freq)
402 REALTYPE speed;
404 freq = fabs(freq);
406 speed = freq * REALTYPE(OSCIL_SIZE) / note_ptr->synth_ptr->sample_rate;
407 if (speed > OSCIL_SIZE)
409 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
420 static
421 inline
422 void
423 setfreqFM(
424 struct addnote * note_ptr,
425 int nvoice,
426 REALTYPE freq)
428 REALTYPE speed;
430 freq = fabs(freq);
432 speed = freq * REALTYPE(OSCIL_SIZE) / note_ptr->synth_ptr->sample_rate;
433 if (speed > OSCIL_SIZE)
435 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"
445 static
446 inline
447 void
448 fadein(
449 struct addnote * note_ptr,
450 REALTYPE *smps)
452 REALTYPE tmp;
453 int zerocrossings;
454 int i;
455 int n;
457 zerocrossings = 0;
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
463 zerocrossings++;
467 tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0;
468 if (tmp < 8.0)
470 tmp=8.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++)
482 // fade-in
483 tmp = 0.5 - cos((REALTYPE)i / (REALTYPE)n * PI) * 0.5;
484 smps[i] *= tmp;
489 * Computes the Oscillator (Without Modulation) - LinearInterpolation
491 static
492 inline
493 void
494 ComputeVoiceOscillator_LinearInterpolation(
495 struct addnote * note_ptr,
496 int voice_index)
498 int i,poshi;
499 REALTYPE poslo;
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];
510 if (poslo >= 1.0)
512 poslo -= 1.0;
513 poshi++;
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){
531 int i,poshi;
532 REALTYPE poslo;
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++){
539 xm1=smps[poshi];
540 x0=smps[poshi+1];
541 x1=smps[poshi+2];
542 x2=smps[poshi+3];
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;
547 printf("a\n");
548 //note_ptr->tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
549 poslo+=note_ptr->osc_freq_lo_ptr[voice_index];
550 if (poslo>=1.0) {
551 poslo-=1.0;
552 poshi++;
554 poshi+=note_ptr->osc_freq_hi_ptr[voice_index];
555 poshi&=OSCIL_SIZE-1;
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)
565 static
566 inline
567 void
568 ComputeVoiceOscillatorMorph(
569 struct addnote * note_ptr,
570 int voice_index)
572 int i;
573 REALTYPE amp;
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],
597 SOUND_BUFFER_SIZE);
599 note_ptr->tmpwave[i] = note_ptr->tmpwave[i] * (1.0 - amp) + amp * note_ptr->voices_ptr[FMVoice].VoiceOut[i];
602 else
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],
613 SOUND_BUFFER_SIZE);
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];
619 if (posloFM >= 1.0)
621 posloFM -= 1.0;
622 poshiFM++;
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)
637 static
638 inline
639 void
640 ComputeVoiceOscillatorRingModulation(
641 struct addnote * note_ptr,
642 int voice_index)
644 int i;
645 REALTYPE amp;
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],
668 SOUND_BUFFER_SIZE);
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];
678 else
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];
690 if (posloFM >= 1.0)
692 posloFM -= 1.0;
693 poshiFM++;
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)
708 static
709 inline
710 void
711 ComputeVoiceOscillatorFrequencyModulation(
712 struct addnote * note_ptr,
713 int voice_index,
714 int FMmode)
716 int carposhi;
717 int i,FMmodfreqhi;
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];
723 } else {
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];
732 if (posloFM>=1.0) {
733 posloFM=fmod(posloFM,1.0);
734 poshiFM++;
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++;
768 //carrier
769 carposhi=note_ptr->osc_pos_hi_ptr[voice_index]+FMmodfreqhi;
770 carposlo=note_ptr->osc_pos_lo_ptr[voice_index]+FMmodfreqlo;
772 if (carposlo>=1.0) {
773 carposhi++;
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;
792 #if 0
793 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
794 static
795 inline
796 void
797 ComputeVoiceOscillatorPitchModulation(
798 struct addnote * note_ptr,
799 int voice_index)
801 // TODO
803 #endif
806 * Computes the Noise
808 static
809 inline
810 void
811 ComputeVoiceNoise(
812 struct addnote * note_ptr,
813 int voice_index)
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)
823 void
824 zyn_addnote_note_on(
825 zyn_addnote_handle handle,
826 float panorama,
827 bool random_grouping,
828 REALTYPE freq,
829 REALTYPE velocity,
830 bool portamento,
831 int midinote)
833 unsigned int voice_index;
834 unsigned int i;
835 float filter_velocity_adjust;
836 int voice_oscillator_index;
837 REALTYPE tmp;
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;
845 if (velocity > 1.0)
847 note_ptr->velocity = 1.0;
849 else
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);
871 else
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);
893 else
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 &note_ptr->synth_ptr->voices_params_ptr[voice_index].oscillator,
902 rand());
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;
921 else
923 detune_type = note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.type;
926 // coarse detune
927 note_ptr->voices_ptr[voice_index].Detune =
928 zyn_get_detune(
929 detune_type,
930 note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.octave,
931 note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.coarse,
932 0.0);
934 // fine detune
935 note_ptr->voices_ptr[voice_index].FineDetune = zyn_get_detune(
936 detune_type,
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;
948 else
950 detune_type = note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_detune.type;
953 note_ptr->voices_ptr[voice_index].FMDetune =
954 zyn_get_detune(
955 detune_type,
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;
971 else
973 voice_oscillator_index = voice_index;
976 if (!random_grouping)
978 zyn_oscillator_new_rand_seed(
979 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
980 rand());
983 note_ptr->osc_pos_hi_ptr[voice_index] =
984 zyn_oscillator_get(
985 &note_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;
1013 break;
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;
1018 break;
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;
1022 break;
1023 #endif
1024 default:
1025 if (fmvoldamp > 1.0)
1027 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);
1040 } // voices loop
1042 // Global Parameters
1043 note_ptr->frequency_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_frequency_envelope_params, note_ptr->basefreq);
1045 note_ptr->frequency_lfo.init(
1046 note_ptr->synth_ptr->sample_rate,
1047 note_ptr->basefreq,
1048 &note_ptr->synth_ptr->frequency_lfo_params,
1049 ZYN_LFO_TYPE_FREQUENCY);
1051 note_ptr->amplitude_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_amplitude_envelope_params, note_ptr->basefreq);
1053 note_ptr->amplitude_lfo.init(
1054 note_ptr->synth_ptr->sample_rate,
1055 note_ptr->basefreq,
1056 &note_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, &note_ptr->synth_ptr->m_filter_params);
1067 if (note_ptr->stereo)
1069 note_ptr->filter_right.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_params);
1072 note_ptr->filter_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_envelope_params, note_ptr->basefreq);
1074 note_ptr->filter_lfo.init(
1075 note_ptr->synth_ptr->sample_rate,
1076 note_ptr->basefreq,
1077 &note_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)
1096 continue;
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
1117 else
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 &note_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,
1138 note_ptr->basefreq,
1139 &note_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 &note_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,
1158 note_ptr->basefreq,
1159 &note_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 &note_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 &note_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,
1183 note_ptr->basefreq,
1184 &note_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 &note_ptr->synth_ptr->voices_params_ptr[voice_index].modulator_oscillator,
1196 rand());
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;
1204 else
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);
1215 else
1217 tmp = 1.0;
1220 if (!random_grouping)
1222 zyn_oscillator_new_rand_seed(
1223 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
1224 rand());
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 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
1230 note_ptr->voices_ptr[voice_index].FMSmp,
1231 tmp,
1232 false);
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 &note_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 &note_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);
1279 * Kill the note
1281 void
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;
1298 void
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);
1346 delete note_ptr;
1350 * Compute the ADnote samples
1352 bool
1353 zyn_addnote_noteout(
1354 zyn_addnote_handle handle,
1355 REALTYPE *outl,
1356 REALTYPE *outr)
1358 int i;
1359 unsigned int voice_index;
1360 float filter_adjust;
1362 silence_two_buffers(outl, outr, SOUND_BUFFER_SIZE);
1364 if (!note_ptr->note_enabled)
1366 return false;
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;
1376 float voicefreq;
1377 float voicepitch;
1378 float filterpitch;
1379 float filterfreq;
1380 float FMfreq;
1381 float FMrelativepitch;
1382 float globalpitch;
1383 float temp_filter_frequency;
1385 globalpitch =
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 =
1392 note_ptr->volume *
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)
1426 continue;
1429 note_ptr->voices_ptr[voice_index].DelayTicks -= 1;
1431 if (note_ptr->voices_ptr[voice_index].DelayTicks > 0)
1433 continue;
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();
1452 /****************/
1453 /* Voice Filter */
1454 /****************/
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 /*******************/
1481 voicepitch=0.0;
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);
1496 /***************/
1497 /* Modulator */
1498 /***************/
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)
1529 continue;
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);
1538 break;
1539 case ZYN_FM_TYPE_RING_MOD:
1540 ComputeVoiceOscillatorRingModulation(note_ptr, voice_index);
1541 break;
1542 case ZYN_FM_TYPE_PHASE_MOD:
1543 ComputeVoiceOscillatorFrequencyModulation(note_ptr, voice_index, 0);
1544 break;
1545 case ZYN_FM_TYPE_FREQ_MOD:
1546 ComputeVoiceOscillatorFrequencyModulation(note_ptr, voice_index, 1);
1547 break;
1548 #if 0
1549 case ZYN_FM_TYPE_PITCH_MOD:
1550 ComputeVoiceOscillatorPitchModulation(note_ptr, voice_index);
1551 break;
1552 #endif
1553 default:
1554 ComputeVoiceOscillator_LinearInterpolation(note_ptr, voice_index);
1555 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1558 else
1560 ComputeVoiceNoise(note_ptr, voice_index);
1563 // Voice Processing
1565 // Amplitude
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)){
1570 rest=10;
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];
1581 // Fade in
1582 if (note_ptr->first_tick_ptr[voice_index])
1584 fadein(note_ptr, &note_ptr->tmpwave[0]);
1585 note_ptr->first_tick_ptr[voice_index] = false;
1588 // Filter
1589 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
1591 note_ptr->voices_ptr[voice_index].m_voice_filter.filterout(&note_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)
1621 // no bypass
1623 if (note_ptr->stereo)
1625 // 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;
1632 else
1634 // mono
1635 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1637 outl[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume;}
1640 else
1642 // bypass the filter
1644 if (note_ptr->stereo)
1646 // 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;
1653 else
1655 // mono
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);
1685 else
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++)
1700 outr[i]=outl[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;
1721 else
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;
1730 // Apply the punch
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;
1742 break;
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++)
1753 // fade-out
1755 REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1757 outl[i] *= tmp;
1758 outr[i] *= tmp;
1761 zyn_addnote_force_disable(note_ptr);
1762 return false;
1764 else
1766 return true;
1771 * Relase the key (NoteOff)
1773 void
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)
1783 continue;
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();
1817 #undef note_ptr