Fix ranges of detune parameters
[zyn.git] / addnote.cpp
blob54498413d58010c99ce618e4f41e0a8858768c62
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 = synth_ptr->detune_bandwidth;
292 note_ptr->bandwidth_detune_multiplier =
293 pow(
294 2.0,
295 note_ptr->bandwidth_detune_multiplier * pow(fabs(note_ptr->bandwidth_detune_multiplier), 0.2) * 5.0);
297 note_ptr->note_enabled = false;
299 note_ptr->synth_ptr = synth_ptr;
301 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &note_ptr->filter_sv_processor_left))
305 if (!zyn_filter_sv_processor_create(synth_ptr->filter_sv, &note_ptr->filter_sv_processor_right))
309 *handle_ptr = (zyn_addnote_handle)note_ptr;
310 return true;
314 * Get Voice base frequency
316 static
317 inline
318 REALTYPE
319 getvoicebasefreq(
320 struct addnote * note_ptr,
321 int nvoice)
323 REALTYPE detune;
324 REALTYPE frequency;
325 int equal_temperate;
326 REALTYPE tmp;
328 detune = note_ptr->voices_ptr[nvoice].Detune / 100.0;
329 detune += note_ptr->voices_ptr[nvoice].FineDetune / 100.0 * note_ptr->synth_ptr->bandwidth_relbw * note_ptr->bandwidth_detune_multiplier;
330 detune += note_ptr->detune / 100.0;
332 switch (note_ptr->voices_ptr[nvoice].fixed_detune.mode)
334 case ZYN_DETUNE_NORMAL:
335 frequency = note_ptr->basefreq;
336 break;
337 case ZYN_DETUNE_FIXED_440:
338 frequency = 440.0;
339 break;
340 case ZYN_DETUNE_EQUAL_TEMPERATE:
341 // the frequency varies according the keyboard note
342 equal_temperate = note_ptr->voices_ptr[nvoice].fixed_detune.equal_temperate;
343 tmp = (note_ptr->midinote - 69.0) / 12.0 * (pow(2.0, (equal_temperate - 1) / 63.0) - 1.0);
345 if (equal_temperate <= 64)
347 frequency = 440 * pow(2.0, tmp);
349 else
351 frequency = 440 * pow(3.0, tmp);
353 break;
354 default:
355 assert(0);
356 return 440;
359 return frequency * pow(2.0, detune / 12.0);
363 * Get Voice's Modullator base frequency
365 static
366 inline
367 REALTYPE
368 getFMvoicebasefreq(
369 struct addnote * note_ptr,
370 int nvoice)
372 REALTYPE detune = note_ptr->voices_ptr[nvoice].FMDetune / 100.0;
373 return getvoicebasefreq(note_ptr, nvoice) * pow(2, detune / 12.0);
377 * Kill a voice of ADnote
379 static
380 inline
381 void
382 kill_voice(
383 struct addnote * note_ptr,
384 unsigned int voice_index)
386 // silence the voice, perhaps is used by another voice
387 silence_buffer(note_ptr->voices_ptr[voice_index].VoiceOut, SOUND_BUFFER_SIZE);
389 note_ptr->voices_ptr[voice_index].enabled = false;
393 * Computes the frequency of an oscillator
395 static
396 inline
397 void
398 setfreq(
399 struct addnote * note_ptr,
400 int nvoice,
401 REALTYPE freq)
403 REALTYPE speed;
405 freq = fabs(freq);
407 speed = freq * REALTYPE(OSCIL_SIZE) / note_ptr->synth_ptr->sample_rate;
408 if (speed > OSCIL_SIZE)
410 speed = OSCIL_SIZE;
413 F2I(speed, note_ptr->osc_freq_hi_ptr[nvoice]);
415 note_ptr->osc_freq_lo_ptr[nvoice] = speed - floor(speed);
419 * Computes the frequency of an modullator oscillator
421 static
422 inline
423 void
424 setfreqFM(
425 struct addnote * note_ptr,
426 int nvoice,
427 REALTYPE freq)
429 REALTYPE speed;
431 freq = fabs(freq);
433 speed = freq * REALTYPE(OSCIL_SIZE) / note_ptr->synth_ptr->sample_rate;
434 if (speed > OSCIL_SIZE)
436 speed = OSCIL_SIZE;
439 F2I(speed, note_ptr->osc_freq_hi_FM_ptr[nvoice]);
440 note_ptr->osc_freq_lo_FM_ptr[nvoice] = speed - floor(speed);
444 * Fadein in a way that removes clicks but keep sound "punchy"
446 static
447 inline
448 void
449 fadein(
450 struct addnote * note_ptr,
451 REALTYPE *smps)
453 REALTYPE tmp;
454 int zerocrossings;
455 int i;
456 int n;
458 zerocrossings = 0;
459 for (i = 1 ; i < SOUND_BUFFER_SIZE ; i++)
461 if ((smps[i - 1] < 0.0) && (smps[i] > 0.0))
463 // this is only the possitive crossings
464 zerocrossings++;
468 tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0;
469 if (tmp < 8.0)
471 tmp=8.0;
474 F2I(tmp, n); // how many samples is the fade-in
476 if (n > SOUND_BUFFER_SIZE)
478 n = SOUND_BUFFER_SIZE;
481 for (i = 0 ; i < n ; i++)
483 // fade-in
484 tmp = 0.5 - cos((REALTYPE)i / (REALTYPE)n * PI) * 0.5;
485 smps[i] *= tmp;
490 * Computes the Oscillator (Without Modulation) - LinearInterpolation
492 static
493 inline
494 void
495 ComputeVoiceOscillator_LinearInterpolation(
496 struct addnote * note_ptr,
497 int voice_index)
499 int i,poshi;
500 REALTYPE poslo;
502 poshi = note_ptr->osc_pos_hi_ptr[voice_index];
503 poslo = note_ptr->osc_pos_lo_ptr[voice_index];
504 REALTYPE * smps = note_ptr->voices_ptr[voice_index].OscilSmp;
506 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
508 note_ptr->tmpwave[i] = smps[poshi] * (1.0 - poslo) + smps[poshi + 1] * poslo;
509 poslo += note_ptr->osc_freq_lo_ptr[voice_index];
511 if (poslo >= 1.0)
513 poslo -= 1.0;
514 poshi++;
517 poshi += note_ptr->osc_freq_hi_ptr[voice_index];
518 poshi &= OSCIL_SIZE - 1;
521 note_ptr->osc_pos_hi_ptr[voice_index] = poshi;
522 note_ptr->osc_pos_lo_ptr[voice_index] = poslo;
528 * Computes the Oscillator (Without Modulation) - CubicInterpolation
530 The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
531 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int voice_index){
532 int i,poshi;
533 REALTYPE poslo;
535 poshi=note_ptr->osc_pos_hi_ptr[voice_index];
536 poslo=note_ptr->osc_pos_lo_ptr[voice_index];
537 REALTYPE *smps=note_ptr->voices_ptr[voice_index].OscilSmp;
538 REALTYPE xm1,x0,x1,x2,a,b,c;
539 for (i=0;i<SOUND_BUFFER_SIZE;i++){
540 xm1=smps[poshi];
541 x0=smps[poshi+1];
542 x1=smps[poshi+2];
543 x2=smps[poshi+3];
544 a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
545 b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
546 c = (x1 - xm1) / 2.0;
547 note_ptr->tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
548 printf("a\n");
549 //note_ptr->tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
550 poslo+=note_ptr->osc_freq_lo_ptr[voice_index];
551 if (poslo>=1.0) {
552 poslo-=1.0;
553 poshi++;
555 poshi+=note_ptr->osc_freq_hi_ptr[voice_index];
556 poshi&=OSCIL_SIZE-1;
558 note_ptr->osc_pos_hi_ptr[voice_index]=poshi;
559 note_ptr->osc_pos_lo_ptr[voice_index]=poslo;
564 * Computes the Oscillator (Morphing)
566 static
567 inline
568 void
569 ComputeVoiceOscillatorMorph(
570 struct addnote * note_ptr,
571 int voice_index)
573 int i;
574 REALTYPE amp;
576 ComputeVoiceOscillator_LinearInterpolation(note_ptr, voice_index);
578 if (note_ptr->FM_new_amplitude_ptr[voice_index] > 1.0)
580 note_ptr->FM_new_amplitude_ptr[voice_index] = 1.0;
583 if (note_ptr->FM_old_amplitude_ptr[voice_index] > 1.0)
585 note_ptr->FM_old_amplitude_ptr[voice_index] = 1.0;
588 if (note_ptr->voices_ptr[voice_index].FMVoice >= 0)
590 //if I use VoiceOut[] as modullator
591 int FMVoice = note_ptr->voices_ptr[voice_index].FMVoice;
592 for (i=0;i<SOUND_BUFFER_SIZE;i++)
594 amp = INTERPOLATE_AMPLITUDE(
595 note_ptr->FM_old_amplitude_ptr[voice_index],
596 note_ptr->FM_new_amplitude_ptr[voice_index],
598 SOUND_BUFFER_SIZE);
600 note_ptr->tmpwave[i] = note_ptr->tmpwave[i] * (1.0 - amp) + amp * note_ptr->voices_ptr[FMVoice].VoiceOut[i];
603 else
605 int poshiFM = note_ptr->osc_pos_hi_FM_ptr[voice_index];
606 REALTYPE posloFM = note_ptr->osc_pos_lo_FM_ptr[voice_index];
608 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
610 amp = INTERPOLATE_AMPLITUDE(
611 note_ptr->FM_old_amplitude_ptr[voice_index],
612 note_ptr->FM_new_amplitude_ptr[voice_index],
614 SOUND_BUFFER_SIZE);
616 note_ptr->tmpwave[i] = note_ptr->tmpwave[i] * (1.0 - amp) + amp * (note_ptr->voices_ptr[voice_index].FMSmp[poshiFM] * (1 - posloFM) + note_ptr->voices_ptr[voice_index].FMSmp[poshiFM + 1] * posloFM);
618 posloFM += note_ptr->osc_freq_lo_FM_ptr[voice_index];
620 if (posloFM >= 1.0)
622 posloFM -= 1.0;
623 poshiFM++;
626 poshiFM += note_ptr->osc_freq_hi_FM_ptr[voice_index];
627 poshiFM &= OSCIL_SIZE - 1;
630 note_ptr->osc_pos_hi_FM_ptr[voice_index] = poshiFM;
631 note_ptr->osc_pos_lo_FM_ptr[voice_index] = posloFM;
636 * Computes the Oscillator (Ring Modulation)
638 static
639 inline
640 void
641 ComputeVoiceOscillatorRingModulation(
642 struct addnote * note_ptr,
643 int voice_index)
645 int i;
646 REALTYPE amp;
648 ComputeVoiceOscillator_LinearInterpolation(note_ptr, voice_index);
650 if (note_ptr->FM_new_amplitude_ptr[voice_index] > 1.0)
652 note_ptr->FM_new_amplitude_ptr[voice_index] = 1.0;
655 if (note_ptr->FM_old_amplitude_ptr[voice_index] > 1.0)
657 note_ptr->FM_old_amplitude_ptr[voice_index] = 1.0;
660 if (note_ptr->voices_ptr[voice_index].FMVoice >= 0)
662 // if I use VoiceOut[] as modullator
663 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
665 amp = INTERPOLATE_AMPLITUDE(
666 note_ptr->FM_old_amplitude_ptr[voice_index],
667 note_ptr->FM_new_amplitude_ptr[voice_index],
669 SOUND_BUFFER_SIZE);
671 int FMVoice = note_ptr->voices_ptr[voice_index].FMVoice;
673 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
675 note_ptr->tmpwave[i] *= (1.0 - amp) + amp * note_ptr->voices_ptr[FMVoice].VoiceOut[i];
679 else
681 int poshiFM=note_ptr->osc_pos_hi_FM_ptr[voice_index];
682 REALTYPE posloFM=note_ptr->osc_pos_lo_FM_ptr[voice_index];
684 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
686 amp = INTERPOLATE_AMPLITUDE(note_ptr->FM_old_amplitude_ptr[voice_index], note_ptr->FM_new_amplitude_ptr[voice_index], i, SOUND_BUFFER_SIZE);
687 note_ptr->tmpwave[i] *= (note_ptr->voices_ptr[voice_index].FMSmp[poshiFM] * (1.0 - posloFM) + note_ptr->voices_ptr[voice_index].FMSmp[poshiFM + 1] * posloFM) * amp + (1.0 - amp);
689 posloFM += note_ptr->osc_freq_lo_FM_ptr[voice_index];
691 if (posloFM >= 1.0)
693 posloFM -= 1.0;
694 poshiFM++;
697 poshiFM += note_ptr->osc_freq_hi_FM_ptr[voice_index];
698 poshiFM &= OSCIL_SIZE-1;
701 note_ptr->osc_pos_hi_FM_ptr[voice_index] = poshiFM;
702 note_ptr->osc_pos_lo_FM_ptr[voice_index] = posloFM;
707 * Computes the Oscillator (Phase Modulation or Frequency Modulation)
709 static
710 inline
711 void
712 ComputeVoiceOscillatorFrequencyModulation(
713 struct addnote * note_ptr,
714 int voice_index,
715 int FMmode)
717 int carposhi;
718 int i,FMmodfreqhi;
719 REALTYPE FMmodfreqlo,carposlo;
721 if (note_ptr->voices_ptr[voice_index].FMVoice>=0){
722 //if I use VoiceOut[] as modulator
723 for (i=0;i<SOUND_BUFFER_SIZE;i++) note_ptr->tmpwave[i]=note_ptr->voices_ptr[note_ptr->voices_ptr[voice_index].FMVoice].VoiceOut[i];
724 } else {
725 //Compute the modulator and store it in note_ptr->tmpwave[]
726 int poshiFM=note_ptr->osc_pos_hi_FM_ptr[voice_index];
727 REALTYPE posloFM=note_ptr->osc_pos_lo_FM_ptr[voice_index];
729 for (i=0;i<SOUND_BUFFER_SIZE;i++){
730 note_ptr->tmpwave[i]=(note_ptr->voices_ptr[voice_index].FMSmp[poshiFM]*(1.0-posloFM)
731 +note_ptr->voices_ptr[voice_index].FMSmp[poshiFM+1]*posloFM);
732 posloFM+=note_ptr->osc_freq_lo_FM_ptr[voice_index];
733 if (posloFM>=1.0) {
734 posloFM=fmod(posloFM,1.0);
735 poshiFM++;
737 poshiFM+=note_ptr->osc_freq_hi_FM_ptr[voice_index];
738 poshiFM&=OSCIL_SIZE-1;
740 note_ptr->osc_pos_hi_FM_ptr[voice_index]=poshiFM;
741 note_ptr->osc_pos_lo_FM_ptr[voice_index]=posloFM;
743 // Amplitude interpolation
744 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr->FM_old_amplitude_ptr[voice_index],note_ptr->FM_new_amplitude_ptr[voice_index])){
745 for (i=0;i<SOUND_BUFFER_SIZE;i++){
746 note_ptr->tmpwave[i]*=INTERPOLATE_AMPLITUDE(note_ptr->FM_old_amplitude_ptr[voice_index]
747 ,note_ptr->FM_new_amplitude_ptr[voice_index],i,SOUND_BUFFER_SIZE);
749 } else for (i=0;i<SOUND_BUFFER_SIZE;i++) note_ptr->tmpwave[i]*=note_ptr->FM_new_amplitude_ptr[voice_index];
752 //normalize makes all sample-rates, oscil_sizes toproduce same sound
753 if (FMmode!=0){//Frequency modulation
754 REALTYPE normalize = OSCIL_SIZE / 262144.0 * 44100.0 / note_ptr->synth_ptr->sample_rate;
755 for (i=0;i<SOUND_BUFFER_SIZE;i++){
756 note_ptr->FM_old_smp_ptr[voice_index]=fmod(note_ptr->FM_old_smp_ptr[voice_index]+note_ptr->tmpwave[i]*normalize,OSCIL_SIZE);
757 note_ptr->tmpwave[i]=note_ptr->FM_old_smp_ptr[voice_index];
759 } else {//Phase modulation
760 REALTYPE normalize=OSCIL_SIZE/262144.0;
761 for (i=0;i<SOUND_BUFFER_SIZE;i++) note_ptr->tmpwave[i]*=normalize;
764 for (i=0;i<SOUND_BUFFER_SIZE;i++){
765 F2I(note_ptr->tmpwave[i],FMmodfreqhi);
766 FMmodfreqlo=fmod(note_ptr->tmpwave[i]+0.0000000001,1.0);
767 if (FMmodfreqhi<0) FMmodfreqlo++;
769 //carrier
770 carposhi=note_ptr->osc_pos_hi_ptr[voice_index]+FMmodfreqhi;
771 carposlo=note_ptr->osc_pos_lo_ptr[voice_index]+FMmodfreqlo;
773 if (carposlo>=1.0) {
774 carposhi++;
775 carposlo=fmod(carposlo,1.0);
777 carposhi&=(OSCIL_SIZE-1);
779 note_ptr->tmpwave[i]=note_ptr->voices_ptr[voice_index].OscilSmp[carposhi]*(1.0-carposlo)
780 +note_ptr->voices_ptr[voice_index].OscilSmp[carposhi+1]*carposlo;
782 note_ptr->osc_pos_lo_ptr[voice_index]+=note_ptr->osc_freq_lo_ptr[voice_index];
783 if (note_ptr->osc_pos_lo_ptr[voice_index]>=1.0) {
784 note_ptr->osc_pos_lo_ptr[voice_index]=fmod(note_ptr->osc_pos_lo_ptr[voice_index],1.0);
785 note_ptr->osc_pos_hi_ptr[voice_index]++;
788 note_ptr->osc_pos_hi_ptr[voice_index]+=note_ptr->osc_freq_hi_ptr[voice_index];
789 note_ptr->osc_pos_hi_ptr[voice_index]&=OSCIL_SIZE-1;
793 #if 0
794 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
795 static
796 inline
797 void
798 ComputeVoiceOscillatorPitchModulation(
799 struct addnote * note_ptr,
800 int voice_index)
802 // TODO
804 #endif
807 * Computes the Noise
809 static
810 inline
811 void
812 ComputeVoiceNoise(
813 struct addnote * note_ptr,
814 int voice_index)
816 for (int i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
818 note_ptr->tmpwave[i] = zyn_random() * 2.0 - 1.0;
822 #define note_ptr ((struct addnote *)handle)
824 void
825 zyn_addnote_note_on(
826 zyn_addnote_handle handle,
827 float panorama,
828 bool random_grouping,
829 REALTYPE freq,
830 REALTYPE velocity,
831 bool portamento,
832 int midinote)
834 unsigned int voice_index;
835 unsigned int i;
836 float filter_velocity_adjust;
837 int voice_oscillator_index;
838 REALTYPE tmp;
839 unsigned char detune_type;
841 note_ptr->portamento = portamento;
842 note_ptr->midinote = midinote;
843 note_ptr->note_enabled = true;
844 note_ptr->basefreq = freq;
846 if (velocity > 1.0)
848 note_ptr->velocity = 1.0;
850 else
852 note_ptr->velocity = velocity;
855 note_ptr->time = 0.0;
857 note_ptr->panning = (panorama + 1.0) / 2; // -1..1 -> 0 - 1
859 note_ptr->filter_category = note_ptr->synth_ptr->filter_type;
861 if (note_ptr->filter_category == ZYN_FILTER_TYPE_STATE_VARIABLE)
863 filter_velocity_adjust = note_ptr->synth_ptr->m_filter_velocity_sensing_amount * 6.0 * // velocity sensing
864 (zyn_velocity_scale(note_ptr->velocity, note_ptr->synth_ptr->m_filter_velocity_scale_function) - 1);
866 zyn_filter_sv_processor_init(note_ptr->filter_sv_processor_left, freq, filter_velocity_adjust);
867 if (note_ptr->stereo)
869 zyn_filter_sv_processor_init(note_ptr->filter_sv_processor_right, freq, filter_velocity_adjust);
872 else
874 note_ptr->filter_center_pitch =
875 note_ptr->synth_ptr->m_filter_params.getfreq() + // center freq
876 note_ptr->synth_ptr->m_filter_velocity_sensing_amount * 6.0 * // velocity sensing
877 (zyn_velocity_scale(note_ptr->velocity, note_ptr->synth_ptr->m_filter_velocity_scale_function) - 1);
878 note_ptr->filter_center_pitch += note_ptr->synth_ptr->m_filter_params.getfreqtracking(note_ptr->basefreq);
881 if (note_ptr->synth_ptr->PPunchStrength != 0)
883 note_ptr->punch_enabled = true;
884 note_ptr->punch_t = 1.0; // start from 1.0 and to 0.0
885 note_ptr->punch_initial_value = pow(10, 1.5 * note_ptr->synth_ptr->PPunchStrength / 127.0) - 1.0;
886 note_ptr->punch_initial_value *= VelF(note_ptr->velocity, note_ptr->synth_ptr->PPunchVelocitySensing);
888 REALTYPE time = pow(10, 3.0 * note_ptr->synth_ptr->PPunchTime / 127.0) / 10000.0; // 0.1 .. 100 ms
890 REALTYPE stretch = pow(440.0/freq, note_ptr->synth_ptr->PPunchStretch / 64.0);
892 note_ptr->punch_duration = 1.0 / (time * note_ptr->synth_ptr->sample_rate * stretch);
894 else
896 note_ptr->punch_enabled = false;
899 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
901 zyn_oscillator_new_rand_seed(
902 &note_ptr->synth_ptr->voices_params_ptr[voice_index].oscillator,
903 rand());
905 note_ptr->voices_ptr[voice_index].FMVoice = -1;
907 if (!note_ptr->synth_ptr->voices_params_ptr[voice_index].enabled)
909 note_ptr->voices_ptr[voice_index].enabled = false;
910 continue; // the voice is disabled
913 note_ptr->voices_ptr[voice_index].enabled = true;
914 note_ptr->voices_ptr[voice_index].fixed_detune = note_ptr->synth_ptr->voices_params_ptr[voice_index].fixed_detune;
916 // calculate voice detune
918 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.type == ZYN_DETUNE_TYPE_GLOBAL)
920 detune_type = note_ptr->synth_ptr->detune.type;
922 else
924 detune_type = note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.type;
927 // coarse detune
928 note_ptr->voices_ptr[voice_index].Detune =
929 zyn_get_detune(
930 detune_type,
931 note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.octave,
932 note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.coarse,
933 0.0);
935 // fine detune
936 note_ptr->voices_ptr[voice_index].FineDetune = zyn_get_detune(
937 detune_type,
940 note_ptr->synth_ptr->voices_params_ptr[voice_index].detune.fine);
943 // calculate voice fm detune
945 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_detune.type == ZYN_DETUNE_TYPE_GLOBAL)
947 detune_type = note_ptr->synth_ptr->detune.type;
949 else
951 detune_type = note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_detune.type;
954 note_ptr->voices_ptr[voice_index].FMDetune =
955 zyn_get_detune(
956 detune_type,
957 note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_detune.octave,
958 note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_detune.coarse,
959 note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_detune.fine);
962 note_ptr->osc_pos_hi_ptr[voice_index] = 0;
963 note_ptr->osc_pos_lo_ptr[voice_index] = 0.0;
964 note_ptr->osc_pos_hi_FM_ptr[voice_index] = 0;
965 note_ptr->osc_pos_lo_FM_ptr[voice_index] = 0.0;
967 // Get the voice's oscil or external's voice oscil
968 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].Pextoscil != -1)
970 voice_oscillator_index = note_ptr->synth_ptr->voices_params_ptr[voice_index].Pextoscil;
972 else
974 voice_oscillator_index = voice_index;
977 if (!random_grouping)
979 zyn_oscillator_new_rand_seed(
980 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
981 rand());
984 note_ptr->osc_pos_hi_ptr[voice_index] =
985 zyn_oscillator_get(
986 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].oscillator,
987 note_ptr->voices_ptr[voice_index].OscilSmp,
988 getvoicebasefreq(note_ptr, voice_index),
989 note_ptr->synth_ptr->voices_params_ptr[voice_index].resonance);
991 // I store the first elments to the last position for speedups
992 for (i = 0 ; i < OSCIL_SMP_EXTRA_SAMPLES ; i++)
994 note_ptr->voices_ptr[voice_index].OscilSmp[OSCIL_SIZE + i] = note_ptr->voices_ptr[voice_index].OscilSmp[i];
997 note_ptr->osc_pos_hi_ptr[voice_index] += (int)((note_ptr->synth_ptr->voices_params_ptr[voice_index].Poscilphase - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4);
998 note_ptr->osc_pos_hi_ptr[voice_index] %= OSCIL_SIZE;
1000 note_ptr->voices_ptr[voice_index].FilterCenterPitch = note_ptr->synth_ptr->voices_params_ptr[voice_index].m_filter_params.getfreq();
1001 note_ptr->voices_ptr[voice_index].filterbypass = note_ptr->synth_ptr->voices_params_ptr[voice_index].Pfilterbypass;
1003 note_ptr->voices_ptr[voice_index].fm_type = note_ptr->synth_ptr->voices_params_ptr[voice_index].fm_type;
1005 note_ptr->voices_ptr[voice_index].FMVoice = note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVoice;
1007 // Compute the Voice's modulator volume (incl. damping)
1008 REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq(note_ptr, voice_index), note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp / 64.0 - 1.0);
1009 switch (note_ptr->voices_ptr[voice_index].fm_type)
1011 case ZYN_FM_TYPE_PHASE_MOD:
1012 fmvoldamp = pow(440.0 / getvoicebasefreq(note_ptr, voice_index), note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp / 64.0);
1013 note_ptr->voices_ptr[voice_index].FMVolume = (exp(note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0;
1014 break;
1015 case ZYN_FM_TYPE_FREQ_MOD:
1016 note_ptr->voices_ptr[voice_index].FMVolume = exp(note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * FM_AMP_MULTIPLIER);
1017 note_ptr->voices_ptr[voice_index].FMVolume -= 1.0;
1018 note_ptr->voices_ptr[voice_index].FMVolume *= fmvoldamp * 4.0;
1019 break;
1020 #if 0 // ???????????
1021 case ZYN_FM_TYPE_PITCH_MOD:
1022 note_ptr->voices_ptr[voice_index].FMVolume = (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * 8.0) * fmvoldamp;
1023 break;
1024 #endif
1025 default:
1026 if (fmvoldamp > 1.0)
1028 fmvoldamp = 1.0;
1031 note_ptr->voices_ptr[voice_index].FMVolume = note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVolume / 127.0 * fmvoldamp;
1034 // Voice's modulator velocity sensing
1035 note_ptr->voices_ptr[voice_index].FMVolume *= VelF(note_ptr->velocity, note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMVelocityScaleFunction);
1037 note_ptr->FM_old_smp_ptr[voice_index] = 0.0; // this is for FM (integration)
1039 note_ptr->first_tick_ptr[voice_index] = true;
1040 note_ptr->voices_ptr[voice_index].DelayTicks = (int)((exp(note_ptr->synth_ptr->voices_params_ptr[voice_index].PDelay / 127.0 * log(50.0)) - 1.0) / SOUND_BUFFER_SIZE / 10.0 * note_ptr->synth_ptr->sample_rate);
1041 } // voices loop
1043 // Global Parameters
1044 note_ptr->frequency_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_frequency_envelope_params, note_ptr->basefreq);
1046 note_ptr->frequency_lfo.init(
1047 note_ptr->synth_ptr->sample_rate,
1048 note_ptr->basefreq,
1049 &note_ptr->synth_ptr->frequency_lfo_params,
1050 ZYN_LFO_TYPE_FREQUENCY);
1052 note_ptr->amplitude_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_amplitude_envelope_params, note_ptr->basefreq);
1054 note_ptr->amplitude_lfo.init(
1055 note_ptr->synth_ptr->sample_rate,
1056 note_ptr->basefreq,
1057 &note_ptr->synth_ptr->amplitude_lfo_params,
1058 ZYN_LFO_TYPE_AMPLITUDE);
1060 note_ptr->volume = 4.0 * pow(0.1, 3.0 * (1.0 - note_ptr->synth_ptr->PVolume / 96.0)); // -60 dB .. 0 dB
1061 note_ptr->volume *= VelF(note_ptr->velocity, note_ptr->synth_ptr->PAmpVelocityScaleFunction); // velocity sensing
1063 note_ptr->amplitude_envelope.envout_dB(); // discard the first envelope output
1065 note_ptr->globalnewamplitude = note_ptr->volume * note_ptr->amplitude_envelope.envout_dB() * note_ptr->amplitude_lfo.amplfoout();
1067 note_ptr->filter_left.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_params);
1068 if (note_ptr->stereo)
1070 note_ptr->filter_right.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_params);
1073 note_ptr->filter_envelope.init(note_ptr->synth_ptr->sample_rate, &note_ptr->synth_ptr->m_filter_envelope_params, note_ptr->basefreq);
1075 note_ptr->filter_lfo.init(
1076 note_ptr->synth_ptr->sample_rate,
1077 note_ptr->basefreq,
1078 &note_ptr->synth_ptr->filter_lfo_params,
1079 ZYN_LFO_TYPE_FILTER);
1081 note_ptr->filter_q_factor = note_ptr->synth_ptr->m_filter_params.getq();
1083 // Forbids the Modulation Voice to be greater or equal than voice
1084 for (i = 0 ; i < note_ptr->synth_ptr->voices_count ; i++)
1086 if (note_ptr->voices_ptr[i].FMVoice >= (int)i)
1088 note_ptr->voices_ptr[i].FMVoice = -1;
1092 // Voice Parameter init
1093 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1095 if (!note_ptr->voices_ptr[voice_index].enabled)
1097 continue;
1100 LOG_DEBUG("Starting %s voice (%u, %p)", note_ptr->synth_ptr->voices_params_ptr[voice_index].white_noise ? "white noise" : "signal", voice_index, note_ptr->synth_ptr->voices_params_ptr + voice_index);
1102 note_ptr->voices_ptr[voice_index].white_noise = note_ptr->synth_ptr->voices_params_ptr[voice_index].white_noise;
1104 /* Voice Amplitude Parameters Init */
1106 note_ptr->voices_ptr[voice_index].Volume = pow(0.1, 3.0 * (1.0 - note_ptr->synth_ptr->voices_params_ptr[voice_index].PVolume / 127.0)); // -60 dB .. 0 dB
1107 note_ptr->voices_ptr[voice_index].Volume *= VelF(note_ptr->velocity, note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpVelocityScaleFunction); // velocity
1109 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PVolumeminus != 0)
1111 note_ptr->voices_ptr[voice_index].Volume = -note_ptr->voices_ptr[voice_index].Volume;
1114 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PPanning == 0)
1116 note_ptr->voices_ptr[voice_index].Panning = zyn_random(); // random panning
1118 else
1120 note_ptr->voices_ptr[voice_index].Panning = note_ptr->synth_ptr->voices_params_ptr[voice_index].PPanning / 128.0;
1123 note_ptr->new_amplitude_ptr[voice_index] = 1.0;
1124 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled != 0)
1126 note_ptr->voices_ptr[voice_index].m_amplitude_envelope.init(
1127 note_ptr->synth_ptr->sample_rate,
1128 &note_ptr->synth_ptr->voices_params_ptr[voice_index].m_amplitude_envelope_params,
1129 note_ptr->basefreq);
1131 note_ptr->voices_ptr[voice_index].m_amplitude_envelope.envout_dB(); // discard the first envelope sample
1132 note_ptr->new_amplitude_ptr[voice_index] *= note_ptr->voices_ptr[voice_index].m_amplitude_envelope.envout_dB();
1135 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled != 0)
1137 note_ptr->voices_ptr[voice_index].m_amplitude_lfo.init(
1138 note_ptr->synth_ptr->sample_rate,
1139 note_ptr->basefreq,
1140 &note_ptr->synth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params,
1141 ZYN_LFO_TYPE_AMPLITUDE);
1143 note_ptr->new_amplitude_ptr[voice_index] *= note_ptr->voices_ptr[voice_index].m_amplitude_lfo.amplfoout();
1146 /* Voice Frequency Parameters Init */
1147 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled != 0)
1149 note_ptr->voices_ptr[voice_index].m_frequency_envelope.init(
1150 note_ptr->synth_ptr->sample_rate,
1151 &note_ptr->synth_ptr->voices_params_ptr[voice_index].m_frequency_envelope_params,
1152 note_ptr->basefreq);
1155 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled != 0)
1157 note_ptr->voices_ptr[voice_index].m_frequency_lfo.init(
1158 note_ptr->synth_ptr->sample_rate,
1159 note_ptr->basefreq,
1160 &note_ptr->synth_ptr->voices_params_ptr[voice_index].frequency_lfo_params,
1161 ZYN_LFO_TYPE_FREQUENCY);
1164 /* Voice Filter Parameters Init */
1165 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnabled != 0)
1167 note_ptr->voices_ptr[voice_index].m_voice_filter.init(
1168 note_ptr->synth_ptr->sample_rate,
1169 &note_ptr->synth_ptr->voices_params_ptr[voice_index].m_filter_params);
1172 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled != 0)
1174 note_ptr->voices_ptr[voice_index].m_filter_envelope.init(
1175 note_ptr->synth_ptr->sample_rate,
1176 &note_ptr->synth_ptr->voices_params_ptr[voice_index].m_filter_envelope_params,
1177 note_ptr->basefreq);
1180 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled != 0)
1182 note_ptr->voices_ptr[voice_index].m_filter_lfo.init(
1183 note_ptr->synth_ptr->sample_rate,
1184 note_ptr->basefreq,
1185 &note_ptr->synth_ptr->voices_params_ptr[voice_index].filter_lfo_params,
1186 ZYN_LFO_TYPE_FILTER);
1189 note_ptr->voices_ptr[voice_index].FilterFreqTracking = note_ptr->synth_ptr->voices_params_ptr[voice_index].m_filter_params.getfreqtracking(note_ptr->basefreq);
1191 /* Voice Modulation Parameters Init */
1192 if (note_ptr->voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE &&
1193 note_ptr->voices_ptr[voice_index].FMVoice < 0)
1195 zyn_oscillator_new_rand_seed(
1196 &note_ptr->synth_ptr->voices_params_ptr[voice_index].modulator_oscillator,
1197 rand());
1199 // Perform Anti-aliasing only on MORPH or RING MODULATION
1201 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PextFMoscil != -1)
1203 voice_oscillator_index = note_ptr->synth_ptr->voices_params_ptr[voice_index].PextFMoscil;
1205 else
1207 voice_oscillator_index = voice_index;
1210 if ((note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator.Padaptiveharmonics != 0) ||
1211 (note_ptr->voices_ptr[voice_index].fm_type == ZYN_FM_TYPE_MORPH) ||
1212 (note_ptr->voices_ptr[voice_index].fm_type == ZYN_FM_TYPE_RING_MOD))
1214 tmp = getFMvoicebasefreq(note_ptr, voice_index);
1216 else
1218 tmp = 1.0;
1221 if (!random_grouping)
1223 zyn_oscillator_new_rand_seed(
1224 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
1225 rand());
1228 note_ptr->osc_pos_hi_FM_ptr[voice_index] = note_ptr->osc_pos_hi_ptr[voice_index];
1229 note_ptr->osc_pos_hi_FM_ptr[voice_index] += zyn_oscillator_get(
1230 &note_ptr->synth_ptr->voices_params_ptr[voice_oscillator_index].modulator_oscillator,
1231 note_ptr->voices_ptr[voice_index].FMSmp,
1232 tmp,
1233 false);
1234 note_ptr->osc_pos_hi_FM_ptr[voice_index] %= OSCIL_SIZE;
1236 for (i = 0 ; i < OSCIL_SMP_EXTRA_SAMPLES ; i++)
1238 note_ptr->voices_ptr[voice_index].FMSmp[OSCIL_SIZE + i] = note_ptr->voices_ptr[voice_index].FMSmp[i];
1241 note_ptr->osc_pos_hi_FM_ptr[voice_index] += (int)((note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMoscilphase - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4);
1242 note_ptr->osc_pos_hi_FM_ptr[voice_index] %= OSCIL_SIZE;
1245 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled != 0)
1247 note_ptr->voices_ptr[voice_index].m_fm_frequency_envelope.init(
1248 note_ptr->synth_ptr->sample_rate,
1249 &note_ptr->synth_ptr->voices_params_ptr[voice_index].m_fm_frequency_envelope_params,
1250 note_ptr->basefreq);
1253 note_ptr->FM_new_amplitude_ptr[voice_index] = note_ptr->voices_ptr[voice_index].FMVolume;
1254 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1256 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled != 0)
1258 note_ptr->voices_ptr[voice_index].m_fm_amplitude_envelope.init(
1259 note_ptr->synth_ptr->sample_rate,
1260 &note_ptr->synth_ptr->voices_params_ptr[voice_index].m_fm_amplitude_envelope_params,
1261 note_ptr->basefreq);
1263 note_ptr->FM_new_amplitude_ptr[voice_index] *= note_ptr->voices_ptr[voice_index].m_fm_amplitude_envelope.envout_dB();
1265 } // voice parameter init loop
1267 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1269 for (i = voice_index + 1 ; i < note_ptr->synth_ptr->voices_count ; i++)
1271 if (note_ptr->voices_ptr[i].FMVoice == (int)voice_index)
1273 silence_buffer(note_ptr->voices_ptr[voice_index].VoiceOut, SOUND_BUFFER_SIZE);
1280 * Kill the note
1282 void
1283 zyn_addnote_force_disable(
1284 zyn_addnote_handle handle)
1286 unsigned int voice_index;
1288 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1290 if (note_ptr->voices_ptr[voice_index].enabled)
1292 kill_voice(note_ptr, voice_index);
1296 note_ptr->note_enabled = false;
1299 void
1300 zyn_addnote_destroy(
1301 zyn_addnote_handle handle)
1303 unsigned int voice_index;
1305 if (note_ptr->note_enabled)
1307 zyn_addnote_force_disable(handle);
1310 zyn_filter_sv_processor_destroy(note_ptr->filter_sv_processor_left);
1311 zyn_filter_sv_processor_destroy(note_ptr->filter_sv_processor_right);
1313 free(note_ptr->old_amplitude_ptr);
1314 free(note_ptr->new_amplitude_ptr);
1316 free(note_ptr->FM_old_amplitude_ptr);
1317 free(note_ptr->FM_new_amplitude_ptr);
1319 free(note_ptr->first_tick_ptr);
1321 free(note_ptr->FM_old_smp_ptr);
1323 free(note_ptr->osc_freq_hi_ptr);
1324 free(note_ptr->osc_freq_lo_ptr);
1325 free(note_ptr->osc_freq_hi_FM_ptr);
1326 free(note_ptr->osc_freq_lo_FM_ptr);
1328 free(note_ptr->osc_pos_hi_ptr);
1329 free(note_ptr->osc_pos_lo_ptr);
1330 free(note_ptr->osc_pos_hi_FM_ptr);
1331 free(note_ptr->osc_pos_lo_FM_ptr);
1333 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1335 // the extra points contains the first point
1336 free(note_ptr->voices_ptr[voice_index].OscilSmp);
1337 free(note_ptr->voices_ptr[voice_index].FMSmp);
1338 free(note_ptr->voices_ptr[voice_index].VoiceOut);
1341 free(note_ptr->voices_ptr);
1343 free(note_ptr->tmpwave);
1344 free(note_ptr->bypassl);
1345 free(note_ptr->bypassr);
1347 delete note_ptr;
1351 * Compute the ADnote samples
1353 bool
1354 zyn_addnote_noteout(
1355 zyn_addnote_handle handle,
1356 REALTYPE *outl,
1357 REALTYPE *outr)
1359 int i;
1360 unsigned int voice_index;
1361 float filter_adjust;
1363 silence_two_buffers(outl, outr, SOUND_BUFFER_SIZE);
1365 if (!note_ptr->note_enabled)
1367 return false;
1370 silence_two_buffers(note_ptr->bypassl, note_ptr->bypassr, SOUND_BUFFER_SIZE);
1373 * Compute all the parameters for each tick
1376 unsigned int voice_index;
1377 float voicefreq;
1378 float voicepitch;
1379 float filterpitch;
1380 float filterfreq;
1381 float FMfreq;
1382 float FMrelativepitch;
1383 float globalpitch;
1384 float temp_filter_frequency;
1386 globalpitch =
1387 0.01 * (note_ptr->frequency_envelope.envout() +
1388 note_ptr->frequency_lfo.lfoout() * note_ptr->synth_ptr->modwheel_relmod);
1390 note_ptr->globaloldamplitude = note_ptr->globalnewamplitude;
1392 note_ptr->globalnewamplitude =
1393 note_ptr->volume *
1394 note_ptr->amplitude_envelope.envout_dB() *
1395 note_ptr->amplitude_lfo.amplfoout();
1397 if (note_ptr->filter_category != ZYN_FILTER_TYPE_STATE_VARIABLE)
1399 temp_filter_frequency = note_ptr->filter_left.getrealfreq(note_ptr->filter_center_pitch + note_ptr->filter_envelope.envout() + note_ptr->filter_lfo.lfoout());
1401 note_ptr->filter_left.setfreq_and_q(temp_filter_frequency, note_ptr->filter_q_factor);
1402 if (note_ptr->stereo)
1404 note_ptr->filter_right.setfreq_and_q(temp_filter_frequency, note_ptr->filter_q_factor);
1408 // compute the portamento, if it is used by this note
1409 REALTYPE portamentofreqrap=1.0;
1410 if (note_ptr->portamento)
1412 // this voice use portamento
1413 portamentofreqrap = note_ptr->synth_ptr->portamento.freqrap;
1415 if (!note_ptr->synth_ptr->portamento.used)
1417 // the portamento has finished
1418 note_ptr->portamento = false; // this note is no longer "portamented"
1422 //compute parameters for all voices
1423 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1425 if (!note_ptr->voices_ptr[voice_index].enabled)
1427 continue;
1430 note_ptr->voices_ptr[voice_index].DelayTicks -= 1;
1432 if (note_ptr->voices_ptr[voice_index].DelayTicks > 0)
1434 continue;
1437 /*******************/
1438 /* Voice Amplitude */
1439 /*******************/
1440 note_ptr->old_amplitude_ptr[voice_index] = note_ptr->new_amplitude_ptr[voice_index];
1441 note_ptr->new_amplitude_ptr[voice_index] = 1.0;
1443 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1445 note_ptr->new_amplitude_ptr[voice_index] *= note_ptr->voices_ptr[voice_index].m_amplitude_envelope.envout_dB();
1448 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled)
1450 note_ptr->new_amplitude_ptr[voice_index] *= note_ptr->voices_ptr[voice_index].m_amplitude_lfo.amplfoout();
1453 /****************/
1454 /* Voice Filter */
1455 /****************/
1456 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
1458 filterpitch = note_ptr->voices_ptr[voice_index].FilterCenterPitch;
1460 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled)
1462 filterpitch += note_ptr->voices_ptr[voice_index].m_filter_envelope.envout();
1465 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled)
1467 filterpitch += note_ptr->voices_ptr[voice_index].m_filter_lfo.lfoout();
1470 filterfreq = filterpitch + note_ptr->voices_ptr[voice_index].FilterFreqTracking;
1471 filterfreq = note_ptr->voices_ptr[voice_index].m_voice_filter.getrealfreq(filterfreq);
1473 note_ptr->voices_ptr[voice_index].m_voice_filter.setfreq(filterfreq);
1476 // compute only if the voice isn't noise
1477 if (!note_ptr->voices_ptr[voice_index].white_noise)
1479 /*******************/
1480 /* Voice Frequency */
1481 /*******************/
1482 voicepitch=0.0;
1483 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled)
1485 voicepitch += note_ptr->voices_ptr[voice_index].m_frequency_lfo.lfoout() / 100.0 * note_ptr->synth_ptr->bandwidth_relbw;
1488 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled)
1490 voicepitch += note_ptr->voices_ptr[voice_index].m_frequency_envelope.envout() / 100.0;
1493 voicefreq = getvoicebasefreq(note_ptr, voice_index) * pow(2, (voicepitch + globalpitch) / 12.0); // Hz frequency
1494 voicefreq *= note_ptr->synth_ptr->pitch_bend_relative_frequency; // change the frequency by the controller
1495 setfreq(note_ptr, voice_index, voicefreq * portamentofreqrap);
1497 /***************/
1498 /* Modulator */
1499 /***************/
1500 if (note_ptr->voices_ptr[voice_index].fm_type != ZYN_FM_TYPE_NONE)
1502 FMrelativepitch = note_ptr->voices_ptr[voice_index].FMDetune / 100.0;
1503 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled)
1505 FMrelativepitch += note_ptr->voices_ptr[voice_index].m_fm_frequency_envelope.envout() / 100;
1508 FMfreq = pow(2.0, FMrelativepitch / 12.0) * voicefreq * portamentofreqrap;
1509 setfreqFM(note_ptr, voice_index, FMfreq);
1511 note_ptr->FM_old_amplitude_ptr[voice_index] = note_ptr->FM_new_amplitude_ptr[voice_index];
1512 note_ptr->FM_new_amplitude_ptr[voice_index] = note_ptr->voices_ptr[voice_index].FMVolume;
1513 //m_FM_new_amplitude_ptr[voice_index] *= note_ptr->ctl->fmamp.relamp; // 0..1
1515 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled)
1517 note_ptr->FM_new_amplitude_ptr[voice_index] *= note_ptr->voices_ptr[voice_index].m_fm_amplitude_envelope.envout_dB();
1523 note_ptr->time += (REALTYPE)SOUND_BUFFER_SIZE / note_ptr->synth_ptr->sample_rate;
1526 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1528 if (!note_ptr->voices_ptr[voice_index].enabled || note_ptr->voices_ptr[voice_index].DelayTicks > 0)
1530 continue;
1533 if (!note_ptr->voices_ptr[voice_index].white_noise) //voice mode = sound
1535 switch (note_ptr->voices_ptr[voice_index].fm_type)
1537 case ZYN_FM_TYPE_MORPH:
1538 ComputeVoiceOscillatorMorph(note_ptr, voice_index);
1539 break;
1540 case ZYN_FM_TYPE_RING_MOD:
1541 ComputeVoiceOscillatorRingModulation(note_ptr, voice_index);
1542 break;
1543 case ZYN_FM_TYPE_PHASE_MOD:
1544 ComputeVoiceOscillatorFrequencyModulation(note_ptr, voice_index, 0);
1545 break;
1546 case ZYN_FM_TYPE_FREQ_MOD:
1547 ComputeVoiceOscillatorFrequencyModulation(note_ptr, voice_index, 1);
1548 break;
1549 #if 0
1550 case ZYN_FM_TYPE_PITCH_MOD:
1551 ComputeVoiceOscillatorPitchModulation(note_ptr, voice_index);
1552 break;
1553 #endif
1554 default:
1555 ComputeVoiceOscillator_LinearInterpolation(note_ptr, voice_index);
1556 //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(note_ptr, voice_index);
1559 else
1561 ComputeVoiceNoise(note_ptr, voice_index);
1564 // Voice Processing
1566 // Amplitude
1567 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr->old_amplitude_ptr[voice_index],note_ptr->new_amplitude_ptr[voice_index])){
1568 int rest=SOUND_BUFFER_SIZE;
1569 //test if the amplitude if raising and the difference is high
1570 if ((note_ptr->new_amplitude_ptr[voice_index]>note_ptr->old_amplitude_ptr[voice_index])&&((note_ptr->new_amplitude_ptr[voice_index]-note_ptr->old_amplitude_ptr[voice_index])>0.25)){
1571 rest=10;
1572 if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE;
1573 for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) note_ptr->tmpwave[i]*=note_ptr->old_amplitude_ptr[voice_index];
1575 // Amplitude interpolation
1576 for (i=0;i<rest;i++){
1577 note_ptr->tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(note_ptr->old_amplitude_ptr[voice_index]
1578 ,note_ptr->new_amplitude_ptr[voice_index],i,rest);
1580 } else for (i=0;i<SOUND_BUFFER_SIZE;i++) note_ptr->tmpwave[i]*=note_ptr->new_amplitude_ptr[voice_index];
1582 // Fade in
1583 if (note_ptr->first_tick_ptr[voice_index])
1585 fadein(note_ptr, &note_ptr->tmpwave[0]);
1586 note_ptr->first_tick_ptr[voice_index] = false;
1589 // Filter
1590 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnabled)
1592 note_ptr->voices_ptr[voice_index].m_voice_filter.filterout(&note_ptr->tmpwave[0]);
1595 //check if the amplitude envelope is finished, if yes, the voice will be fadeout
1596 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1598 if (note_ptr->voices_ptr[voice_index].m_amplitude_envelope.finished())
1600 for (i=0 ; i < SOUND_BUFFER_SIZE ; i++)
1602 note_ptr->tmpwave[i] *= 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1606 // the voice is killed later
1610 // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
1611 if (note_ptr->voices_ptr[voice_index].VoiceOut!=NULL)
1613 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1615 note_ptr->voices_ptr[voice_index].VoiceOut[i] = note_ptr->tmpwave[i];
1619 // Add the voice that do not bypass the filter to out
1620 if (note_ptr->voices_ptr[voice_index].filterbypass==0)
1622 // no bypass
1624 if (note_ptr->stereo)
1626 // stereo
1627 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1629 outl[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume * note_ptr->voices_ptr[voice_index].Panning * 2.0;
1630 outr[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume * (1.0 - note_ptr->voices_ptr[voice_index].Panning) * 2.0;
1633 else
1635 // mono
1636 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1638 outl[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume;}
1641 else
1643 // bypass the filter
1645 if (note_ptr->stereo)
1647 // stereo
1648 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1650 note_ptr->bypassl[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume * note_ptr->voices_ptr[voice_index].Panning * 2.0;
1651 note_ptr->bypassr[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume * (1.0 - note_ptr->voices_ptr[voice_index].Panning) * 2.0;
1654 else
1656 // mono
1657 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1659 note_ptr->bypassl[i] += note_ptr->tmpwave[i] * note_ptr->voices_ptr[voice_index].Volume;
1663 // check if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
1664 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1666 if (note_ptr->voices_ptr[voice_index].m_amplitude_envelope.finished())
1668 kill_voice(note_ptr, voice_index);
1673 // Processing Global parameters
1675 if (note_ptr->filter_category == ZYN_FILTER_TYPE_STATE_VARIABLE)
1677 filter_adjust = note_ptr->filter_envelope.envout() + note_ptr->filter_lfo.lfoout();
1679 zyn_filter_sv_process(note_ptr->filter_sv_processor_left, filter_adjust, outl);
1681 if (note_ptr->stereo)
1683 zyn_filter_sv_process(note_ptr->filter_sv_processor_right, filter_adjust, outr);
1686 else
1688 note_ptr->filter_left.filterout(&outl[0]);
1690 if (note_ptr->stereo)
1692 note_ptr->filter_right.filterout(&outr[0]);
1696 if (!note_ptr->stereo)
1698 // set the right channel=left channel
1699 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1701 outr[i]=outl[i];
1702 note_ptr->bypassr[i]=note_ptr->bypassl[i];
1706 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1708 // outl[i]+=note_ptr->bypassl[i];
1709 // outr[i]+=note_ptr->bypassr[i];
1712 if (ABOVE_AMPLITUDE_THRESHOLD(note_ptr->globaloldamplitude, note_ptr->globalnewamplitude))
1714 // Amplitude Interpolation
1715 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1717 REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(note_ptr->globaloldamplitude, note_ptr->globalnewamplitude, i, SOUND_BUFFER_SIZE);
1718 outl[i] *= tmpvol * (1.0 - note_ptr->panning);
1719 outr[i] *= tmpvol * note_ptr->panning;
1722 else
1724 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1726 outl[i] *= note_ptr->globalnewamplitude * (1.0 - note_ptr->panning);
1727 outr[i] *= note_ptr->globalnewamplitude * note_ptr->panning;
1731 // Apply the punch
1732 if (note_ptr->punch_enabled)
1734 for (i=0;i<SOUND_BUFFER_SIZE;i++)
1736 REALTYPE punchamp = note_ptr->punch_initial_value * note_ptr->punch_t + 1.0;
1737 outl[i] *= punchamp;
1738 outr[i] *= punchamp;
1739 note_ptr->punch_t -= note_ptr->punch_duration;
1740 if (note_ptr->punch_t < 0.0)
1742 note_ptr->punch_enabled = false;
1743 break;
1748 // Check if the global amplitude is finished.
1749 // If it does, disable the note
1750 if (note_ptr->amplitude_envelope.finished())
1752 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
1754 // fade-out
1756 REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE;
1758 outl[i] *= tmp;
1759 outr[i] *= tmp;
1762 zyn_addnote_force_disable(note_ptr);
1763 return false;
1765 else
1767 return true;
1772 * Relase the key (NoteOff)
1774 void
1775 zyn_addnote_note_off(
1776 zyn_addnote_handle handle)
1778 unsigned int voice_index;
1780 for (voice_index = 0 ; voice_index < note_ptr->synth_ptr->voices_count ; voice_index++)
1782 if (!note_ptr->voices_ptr[voice_index].enabled)
1784 continue;
1787 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled)
1789 note_ptr->voices_ptr[voice_index].m_amplitude_envelope.relasekey();
1792 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled)
1794 note_ptr->voices_ptr[voice_index].m_frequency_envelope.relasekey();
1797 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled)
1799 note_ptr->voices_ptr[voice_index].m_filter_envelope.relasekey();
1802 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled)
1804 note_ptr->voices_ptr[voice_index].m_fm_frequency_envelope.relasekey();
1807 if (note_ptr->synth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled)
1809 note_ptr->voices_ptr[voice_index].m_fm_amplitude_envelope.relasekey();
1813 note_ptr->frequency_envelope.relasekey();
1814 note_ptr->filter_envelope.relasekey();
1815 note_ptr->amplitude_envelope.relasekey();
1818 #undef note_ptr