Minor detune bandwidth optimization
[zyn.git] / addsynth.cpp
bloba1db671c2caa8f12269ff9a8f57f6f1da414da29
1 /* -*- Mode: C++ ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov <nedko@arnaudov.name>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *****************************************************************************/
21 #include <stdlib.h>
22 #include <math.h>
23 #include <assert.h>
25 #include "common.h"
26 #include "addsynth.h"
27 #include "globals.h"
28 #include "resonance.h"
29 #include "fft.h"
30 #include "oscillator.h"
31 #include "envelope_parameters.h"
32 #include "envelope.h"
33 #include "lfo_parameters.h"
34 #include "lfo.h"
35 #include "filter_parameters.h"
36 #include "filter_base.h"
37 #include "analog_filter.h"
38 #include "sv_filter.h"
39 #include "formant_filter.h"
40 #include "filter.h"
41 #include "portamento.h"
42 #include "addsynth_internal.h"
43 #include "addnote.h"
44 #include "util.h"
46 #define LOG_LEVEL LOG_LEVEL_ERROR
47 #include "log.h"
49 #define ZYN_DEFAULT_POLYPHONY 60
51 // (94.0 / 64.0 - 1) * 5.0 = 2.34375
52 #define ZYN_GLOBAL_FILTER_INITIAL_FREQUENCY 2.34375
54 // 40.0 / 127.0 = 0.31496062992125984
55 #define ZYN_GLOBAL_FILTER_INITIAL_Q 0.31496062992125984
57 struct note_channel
59 int midinote; // MIDI note, -1 when note "channel" is not playing
60 zyn_addnote_handle note_handle;
63 bool
64 zyn_addsynth_create(
65 float sample_rate,
66 unsigned int voices_count,
67 zyn_addsynth_handle * handle_ptr)
69 struct zyn_addsynth * zyn_addsynth_ptr;
70 unsigned int note_index;
71 unsigned int voice_index;
73 // printf("zyn_addsynth_create\n");
74 zyn_addsynth_ptr = (struct zyn_addsynth *)malloc(sizeof(struct zyn_addsynth));
75 if (zyn_addsynth_ptr == NULL)
77 goto fail;
80 zyn_addsynth_ptr->sample_rate = sample_rate;
82 zyn_addsynth_ptr->temporary_samples_ptr = (zyn_sample_type *)malloc(sizeof(zyn_sample_type) * OSCIL_SIZE);
83 zyn_fft_freqs_init(&zyn_addsynth_ptr->oscillator_fft_frequencies, OSCIL_SIZE / 2);
85 zyn_addsynth_ptr->polyphony = ZYN_DEFAULT_POLYPHONY;
86 zyn_addsynth_ptr->notes_array = (struct note_channel *)malloc(ZYN_DEFAULT_POLYPHONY * sizeof(struct note_channel));
88 zyn_addsynth_ptr->all_sound_off = false;
90 zyn_addsynth_ptr->velsns = 64;
91 zyn_addsynth_ptr->fft = zyn_fft_create(OSCIL_SIZE);
93 // ADnoteParameters temp begin
95 zyn_addsynth_ptr->m_frequency_envelope_params.init_asr(0, false, 64, 50, 64, 60);
97 zyn_addsynth_ptr->m_amplitude_envelope_params.init_adsr(64, true, 0, 40, 127, 25, false);
99 zyn_addsynth_ptr->filter_type = ZYN_FILTER_TYPE_ANALOG;
100 zyn_addsynth_ptr->m_filter_params.init(sample_rate, ZYN_FILTER_ANALOG_TYPE_LPF2, 94, 40);
101 if (!zyn_filter_sv_create(sample_rate, ZYN_GLOBAL_FILTER_INITIAL_FREQUENCY, ZYN_GLOBAL_FILTER_INITIAL_Q, &zyn_addsynth_ptr->filter_sv))
103 goto fail_free_synth;
106 zyn_addsynth_ptr->m_filter_envelope_params.init_adsr_filter(0, true, 64, 40, 64, 70, 60, 64);
108 zyn_resonance_init(&zyn_addsynth_ptr->resonance);
110 zyn_addsynth_ptr->voices_count = voices_count;
111 zyn_addsynth_ptr->voices_params_ptr = (struct zyn_addnote_voice_parameters *)malloc(sizeof(struct zyn_addnote_voice_parameters) * voices_count);
113 for (voice_index = 0 ; voice_index < voices_count ; voice_index++)
115 zyn_oscillator_init(
116 &zyn_addsynth_ptr->voices_params_ptr[voice_index].oscillator,
117 sample_rate,
118 zyn_addsynth_ptr->fft,
119 &zyn_addsynth_ptr->resonance,
120 zyn_addsynth_ptr->temporary_samples_ptr,
121 &zyn_addsynth_ptr->oscillator_fft_frequencies);
123 zyn_oscillator_init(
124 &zyn_addsynth_ptr->voices_params_ptr[voice_index].modulator_oscillator,
125 sample_rate,
126 zyn_addsynth_ptr->fft,
127 NULL,
128 zyn_addsynth_ptr->temporary_samples_ptr,
129 &zyn_addsynth_ptr->oscillator_fft_frequencies);
131 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_amplitude_envelope_params.init_adsr(64, true, 0, 100, 127, 100, false);
133 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.frequency = 90.0 / 127.0;
134 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.depth = 32.0 / 127.0;
135 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.random_start_phase = false;
136 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.start_phase = 0.5;
137 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.depth_randomness_enabled = false;
138 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.depth = 0;
139 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.frequency_randomness_enabled = false;
140 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.frequency_randomness = 0;
141 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.delay = 30.0 / 127.0 * 4.0;
142 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.stretch = 0;
143 zyn_addsynth_ptr->voices_params_ptr[voice_index].amplitude_lfo_params.shape = ZYN_LFO_SHAPE_TYPE_SINE;
145 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_frequency_envelope_params.init_asr(0, false, 30, 40, 64, 60);
147 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.frequency = 50.0 / 127.0;
148 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.depth = 40.0 / 127.0;
149 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.random_start_phase = false;
150 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.start_phase = 0;
151 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.depth_randomness_enabled = false;
152 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.depth = 0;
153 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.frequency_randomness_enabled = false;
154 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.frequency_randomness = 0;
155 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.delay = 0;
156 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.stretch = 0;
157 zyn_addsynth_ptr->voices_params_ptr[voice_index].frequency_lfo_params.shape = ZYN_LFO_SHAPE_TYPE_SINE;
159 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_filter_params.init(sample_rate, ZYN_FILTER_ANALOG_TYPE_LPF2, 50, 60);
160 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_filter_envelope_params.init_adsr_filter(0, false, 90, 70, 40, 70, 10, 40);
162 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.frequency = 50.0 / 127.0;
163 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.depth = 20.0 / 127.0;
164 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.random_start_phase = false;
165 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.start_phase = 0.5;
166 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.depth_randomness_enabled = false;
167 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.depth = 0;
168 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.frequency_randomness_enabled = false;
169 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.frequency_randomness = 0;
170 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.delay = 0;
171 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.stretch = 0;
172 zyn_addsynth_ptr->voices_params_ptr[voice_index].filter_lfo_params.shape = ZYN_LFO_SHAPE_TYPE_SINE;
174 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_fm_frequency_envelope_params.init_asr(0, false, 20, 90, 40, 80);
175 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_fm_amplitude_envelope_params.init_adsr(64, true, 80, 90, 127, 100, false);
178 /* Frequency Global Parameters */
179 // zyn_addsynth_ptr->GlobalPar.stereo = true; // Stereo
180 zyn_addsynth_ptr->detune.fine = 0.0;
181 zyn_addsynth_ptr->detune.coarse = 0;
182 zyn_addsynth_ptr->detune.octave = 0;
183 zyn_addsynth_ptr->detune.type = ZYN_DETUNE_TYPE_L35CENTS;
184 zyn_addsynth_ptr->detune_bandwidth = 0.0;
186 /* Amplitude Global Parameters */
187 zyn_addsynth_ptr->PVolume=90;
188 zyn_addsynth_ptr->PAmpVelocityScaleFunction=64;
189 zyn_addsynth_ptr->PPunchStrength=0;
190 zyn_addsynth_ptr->PPunchTime=60;
191 zyn_addsynth_ptr->PPunchStretch=64;
192 zyn_addsynth_ptr->PPunchVelocitySensing=72;
194 /* Filter Global Parameters*/
195 zyn_addsynth_ptr->m_filter_velocity_sensing_amount = 0.5;
196 zyn_addsynth_ptr->m_filter_velocity_scale_function = 0;
197 zyn_addsynth_ptr->m_filter_params.defaults();
199 for (voice_index = 0 ; voice_index < voices_count ; voice_index++)
201 zyn_addsynth_ptr->voices_params_ptr[voice_index].enabled = false;
202 zyn_addsynth_ptr->voices_params_ptr[voice_index].white_noise = false;
203 zyn_addsynth_ptr->voices_params_ptr[voice_index].fixed_detune.mode = ZYN_DETUNE_NORMAL;
204 zyn_addsynth_ptr->voices_params_ptr[voice_index].fixed_detune.equal_temperate = 0;
205 zyn_addsynth_ptr->voices_params_ptr[voice_index].resonance = true;
206 zyn_addsynth_ptr->voices_params_ptr[voice_index].Pfilterbypass=0;
207 zyn_addsynth_ptr->voices_params_ptr[voice_index].Pextoscil=-1;
208 zyn_addsynth_ptr->voices_params_ptr[voice_index].PextFMoscil=-1;
209 zyn_addsynth_ptr->voices_params_ptr[voice_index].Poscilphase=64;
210 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMoscilphase=64;
211 zyn_addsynth_ptr->voices_params_ptr[voice_index].PDelay=0;
212 zyn_addsynth_ptr->voices_params_ptr[voice_index].PVolume=100;
213 zyn_addsynth_ptr->voices_params_ptr[voice_index].PVolumeminus=0;
214 zyn_addsynth_ptr->voices_params_ptr[voice_index].PPanning=64;//center
215 zyn_addsynth_ptr->voices_params_ptr[voice_index].detune.fine = 0.0;
216 zyn_addsynth_ptr->voices_params_ptr[voice_index].detune.coarse = 0;
217 zyn_addsynth_ptr->voices_params_ptr[voice_index].detune.octave = 0;
218 zyn_addsynth_ptr->voices_params_ptr[voice_index].detune.type = ZYN_DETUNE_TYPE_GLOBAL;
219 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFreqLfoEnabled=0;
220 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFreqEnvelopeEnabled=0;
221 zyn_addsynth_ptr->voices_params_ptr[voice_index].PAmpEnvelopeEnabled=0;
222 zyn_addsynth_ptr->voices_params_ptr[voice_index].PAmpLfoEnabled=0;
223 zyn_addsynth_ptr->voices_params_ptr[voice_index].PAmpVelocityScaleFunction=127;
224 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFilterEnabled=0;
225 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFilterEnvelopeEnabled=0;
226 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFilterLfoEnabled=0;
227 zyn_addsynth_ptr->voices_params_ptr[voice_index].fm_type = ZYN_FM_TYPE_NONE;
229 //I use the internal oscillator (-1)
230 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMVoice=-1;
232 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMVolume=90;
233 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMVolumeDamp=64;
234 zyn_addsynth_ptr->voices_params_ptr[voice_index].fm_detune.fine = 0.0;
235 zyn_addsynth_ptr->voices_params_ptr[voice_index].fm_detune.coarse = 0;
236 zyn_addsynth_ptr->voices_params_ptr[voice_index].fm_detune.octave = 0;
237 zyn_addsynth_ptr->voices_params_ptr[voice_index].fm_detune.type = ZYN_DETUNE_TYPE_GLOBAL;
238 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMFreqEnvelopeEnabled=0;
239 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMAmpEnvelopeEnabled=0;
240 zyn_addsynth_ptr->voices_params_ptr[voice_index].PFMVelocityScaleFunction=64;
242 zyn_addsynth_ptr->voices_params_ptr[voice_index].m_filter_params.defaults();
245 zyn_addsynth_ptr->voices_params_ptr[0].enabled = true;
247 // ADnoteParameters temp end
249 zyn_addsynth_ptr->bandwidth_depth = 64;
250 zyn_addsynth_ptr->bandwidth_exponential = false;
251 zyn_addsynth_ptr->modwheel_depth = 80;
252 zyn_addsynth_ptr->modwheel_exponential = false;
254 zyn_addsynth_set_bandwidth(zyn_addsynth_ptr, 64);
255 zyn_addsynth_set_modwheel(zyn_addsynth_ptr, 64);
257 zyn_portamento_init(&zyn_addsynth_ptr->portamento);
259 zyn_addsynth_ptr->pitch_bend_range = 200.0; // 200 cents = 2 halftones
260 zyn_addsynth_ptr->pitch_bend = 0; // center
261 ZYN_UPDATE_PITCH_BEND(zyn_addsynth_ptr);
263 zyn_addsynth_ptr->oldfreq = -1.0;
265 zyn_addsynth_ptr->random_panorama = false;
266 zyn_addsynth_ptr->panorama = 0.0;
268 zyn_addsynth_ptr->stereo = true;
270 zyn_addsynth_ptr->random_grouping = false;
272 zyn_addsynth_ptr->amplitude_lfo_params.frequency = 80.0 / 127.0;
273 zyn_addsynth_ptr->amplitude_lfo_params.depth = 0;
274 zyn_addsynth_ptr->amplitude_lfo_params.random_start_phase = false;
275 zyn_addsynth_ptr->amplitude_lfo_params.start_phase = 0.5;
276 zyn_addsynth_ptr->amplitude_lfo_params.depth_randomness_enabled = false;
277 zyn_addsynth_ptr->amplitude_lfo_params.depth_randomness = 0.5;
278 zyn_addsynth_ptr->amplitude_lfo_params.frequency_randomness_enabled = false;
279 zyn_addsynth_ptr->amplitude_lfo_params.frequency_randomness = 0.5;
280 zyn_addsynth_ptr->amplitude_lfo_params.delay = 0;
281 zyn_addsynth_ptr->amplitude_lfo_params.stretch = 0;
282 zyn_addsynth_ptr->amplitude_lfo_params.shape = ZYN_LFO_SHAPE_TYPE_SINE;
284 zyn_addsynth_ptr->filter_lfo_params.frequency = 80.0 / 127.0;
285 zyn_addsynth_ptr->filter_lfo_params.depth = 0;
286 zyn_addsynth_ptr->filter_lfo_params.random_start_phase = false;
287 zyn_addsynth_ptr->filter_lfo_params.start_phase = 0.5;
288 zyn_addsynth_ptr->filter_lfo_params.depth_randomness_enabled = false;
289 zyn_addsynth_ptr->filter_lfo_params.depth_randomness = 0.5;
290 zyn_addsynth_ptr->filter_lfo_params.frequency_randomness_enabled = false;
291 zyn_addsynth_ptr->filter_lfo_params.frequency_randomness = 0.5;
292 zyn_addsynth_ptr->filter_lfo_params.delay = 0;
293 zyn_addsynth_ptr->filter_lfo_params.stretch = 0;
294 zyn_addsynth_ptr->filter_lfo_params.shape = ZYN_LFO_SHAPE_TYPE_SINE;
296 zyn_addsynth_ptr->frequency_lfo_params.frequency = 70.0 / 127.0;
297 zyn_addsynth_ptr->frequency_lfo_params.depth = 0;
298 zyn_addsynth_ptr->frequency_lfo_params.random_start_phase = false;
299 zyn_addsynth_ptr->frequency_lfo_params.start_phase = 0.5;
300 zyn_addsynth_ptr->frequency_lfo_params.depth_randomness_enabled = false;
301 zyn_addsynth_ptr->frequency_lfo_params.depth_randomness = 0.5;
302 zyn_addsynth_ptr->frequency_lfo_params.frequency_randomness_enabled = false;
303 zyn_addsynth_ptr->frequency_lfo_params.frequency_randomness = 0.5;
304 zyn_addsynth_ptr->frequency_lfo_params.delay = 0;
305 zyn_addsynth_ptr->frequency_lfo_params.stretch = 0;
306 zyn_addsynth_ptr->frequency_lfo_params.shape = ZYN_LFO_SHAPE_TYPE_SINE;
308 for (note_index = 0 ; note_index < ZYN_DEFAULT_POLYPHONY ; note_index++)
310 if (!zyn_addnote_create(
311 zyn_addsynth_ptr,
312 &zyn_addsynth_ptr->notes_array[note_index].note_handle))
316 zyn_addsynth_ptr->notes_array[note_index].midinote = -1;
319 // init global components
321 zyn_addsynth_component_init_amp_globals(
322 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_AMP_GLOBALS,
323 zyn_addsynth_ptr);
325 zyn_addsynth_component_init_amp_envelope(
326 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_AMP_ENV,
327 &zyn_addsynth_ptr->m_amplitude_envelope_params);
329 zyn_addsynth_component_init_lfo(
330 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_AMP_LFO,
331 &zyn_addsynth_ptr->amplitude_lfo_params);
333 zyn_addsynth_component_init_filter_globals(
334 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FILTER_GLOBALS,
335 zyn_addsynth_ptr);
337 zyn_addsynth_component_init_filter_analog(
338 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FILTER_ANALOG,
339 zyn_addsynth_ptr);
341 zyn_addsynth_component_init_filter_formant(
342 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FILTER_FORMANT,
343 zyn_addsynth_ptr);
345 zyn_addsynth_component_init_filter_sv(
346 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FILTER_SV,
347 zyn_addsynth_ptr->filter_sv);
349 zyn_addsynth_component_init_filter_envelope(
350 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FILTER_ENV,
351 &zyn_addsynth_ptr->m_filter_envelope_params);
353 zyn_addsynth_component_init_lfo(
354 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FILTER_LFO,
355 &zyn_addsynth_ptr->filter_lfo_params);
357 zyn_addsynth_component_init_frequency_globals(
358 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FREQUENCY_GLOBALS);
360 zyn_addsynth_component_init_frequency_envelope(
361 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FREQUENCY_ENV,
362 &zyn_addsynth_ptr->m_frequency_envelope_params);
364 zyn_addsynth_component_init_lfo(
365 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_FREQUENCY_LFO,
366 &zyn_addsynth_ptr->frequency_lfo_params);
368 zyn_addsynth_component_init_portamento(
369 zyn_addsynth_ptr->global_components + ZYNADD_COMPONENT_PORTAMENTO,
370 &zyn_addsynth_ptr->portamento);
372 // init voices components
374 zyn_addsynth_ptr->voices_components =
375 (struct zyn_component_descriptor *)malloc(
376 sizeof(struct zyn_component_descriptor) * voices_count * ZYNADD_VOICE_COMPONENTS_COUNT);
378 for (voice_index = 0 ; voice_index < voices_count ; voice_index++)
380 zyn_addsynth_component_init_voice_globals(
381 zyn_addsynth_ptr->voices_components + voice_index * ZYNADD_VOICE_COMPONENTS_COUNT + ZYNADD_COMPONENT_VOICE_GLOBALS,
382 zyn_addsynth_ptr->voices_params_ptr + voice_index);
384 zyn_addsynth_component_init_oscillator(
385 zyn_addsynth_ptr->voices_components + voice_index * ZYNADD_VOICE_COMPONENTS_COUNT + ZYNADD_COMPONENT_VOICE_OSCILLATOR,
386 &zyn_addsynth_ptr->voices_params_ptr[voice_index].oscillator);
389 *handle_ptr = (zyn_addsynth_handle)zyn_addsynth_ptr;
391 // printf("zyn_addsynth_create(%08X)\n", (unsigned int)*handle_ptr);
393 return true;
395 fail_free_synth:
397 fail:
398 return false;
401 #define zyn_addsynth_ptr ((struct zyn_addsynth *)handle)
403 void
404 zyn_addsynth_get_audio_output(
405 zyn_addsynth_handle handle,
406 zyn_sample_type * buffer_left,
407 zyn_sample_type * buffer_right)
409 unsigned int note_index;
410 zyn_sample_type note_buffer_left[SOUND_BUFFER_SIZE];
411 zyn_sample_type note_buffer_right[SOUND_BUFFER_SIZE];
412 bool note_active;
414 silence_two_buffers(buffer_left, buffer_right, SOUND_BUFFER_SIZE);
416 for (note_index = 0 ; note_index < zyn_addsynth_ptr->polyphony ; note_index++)
418 if (zyn_addsynth_ptr->notes_array[note_index].midinote != -1)
420 //printf("mixing note channel %u\n", note_index);
422 note_active = zyn_addnote_noteout(
423 zyn_addsynth_ptr->notes_array[note_index].note_handle,
424 note_buffer_left,
425 note_buffer_right);
427 mix_add_two_buffers(
428 buffer_left,
429 buffer_right,
430 note_buffer_left,
431 note_buffer_right,
432 SOUND_BUFFER_SIZE);
434 if (!note_active)
436 zyn_addsynth_ptr->notes_array[note_index].midinote = -1;
441 if (zyn_addsynth_ptr->all_sound_off)
443 fadeout_two_buffers(buffer_left, buffer_right, SOUND_BUFFER_SIZE);
445 for (note_index = 0 ; note_index < zyn_addsynth_ptr->polyphony ; note_index++)
447 if (zyn_addsynth_ptr->notes_array[note_index].midinote != -1)
449 zyn_addnote_force_disable(zyn_addsynth_ptr->notes_array[note_index].note_handle);
450 zyn_addsynth_ptr->notes_array[note_index].midinote = -1;
454 zyn_addsynth_ptr->all_sound_off = false;
457 zyn_portamento_update(&zyn_addsynth_ptr->portamento);
460 void
461 zyn_addsynth_note_on(
462 zyn_addsynth_handle handle,
463 unsigned int note,
464 unsigned int velocity)
466 unsigned int note_index;
467 int masterkeyshift;
468 float vel;
469 zyn_sample_type notebasefreq;
471 for (note_index = 0 ; note_index < zyn_addsynth_ptr->polyphony ; note_index++)
473 if (zyn_addsynth_ptr->notes_array[note_index].midinote == -1)
475 goto unused_note_channel_found;
479 //printf("note on %u - ignored\n", note);
481 return;
483 unused_note_channel_found:
484 //printf("note on %u - channel %u\n", note, note_index);
485 masterkeyshift = 0;
487 vel = VelF(velocity/127.0, zyn_addsynth_ptr->velsns);
488 notebasefreq = 440.0*pow(2.0,(note-69.0)/12.0);
490 // Portamento
492 if (zyn_addsynth_ptr->oldfreq < 1.0) /* only when the first note is played */
494 zyn_addsynth_ptr->oldfreq = notebasefreq;
497 bool portamento = zyn_portamento_start(zyn_addsynth_ptr->sample_rate, &zyn_addsynth_ptr->portamento, zyn_addsynth_ptr->oldfreq, notebasefreq);
499 zyn_addsynth_ptr->oldfreq = notebasefreq;
501 zyn_addsynth_ptr->notes_array[note_index].midinote = note;
503 zyn_addnote_note_on(
504 zyn_addsynth_ptr->notes_array[note_index].note_handle,
505 zyn_addsynth_ptr->random_panorama ? RND : zyn_addsynth_ptr->panorama,
506 zyn_addsynth_ptr->random_grouping,
507 notebasefreq,
508 vel,
509 portamento,
510 note);
513 void
514 zyn_addsynth_note_off(
515 zyn_addsynth_handle handle,
516 unsigned int note)
518 unsigned int note_index;
520 //printf("note off %u\n", note);
522 for (note_index = 0 ; note_index < zyn_addsynth_ptr->polyphony ; note_index++)
524 if (zyn_addsynth_ptr->notes_array[note_index].midinote == (char)note)
526 zyn_addnote_note_off(zyn_addsynth_ptr->notes_array[note_index].note_handle);
531 void
532 zyn_addsynth_all_notes_off(
533 zyn_addsynth_handle handle)
535 unsigned int note_index;
537 for (note_index = 0 ; note_index < zyn_addsynth_ptr->polyphony ; note_index++)
539 if (zyn_addsynth_ptr->notes_array[note_index].midinote != -1)
541 zyn_addnote_note_off(zyn_addsynth_ptr->notes_array[note_index].note_handle);
546 void
547 zyn_addsynth_all_sound_off(
548 zyn_addsynth_handle handle)
550 zyn_addsynth_ptr->all_sound_off = true;
553 void
554 zyn_addsynth_destroy(
555 zyn_addsynth_handle handle)
557 unsigned int voice_index;
559 free(zyn_addsynth_ptr->voices_components);
561 // printf("zyn_addsynth_destroy(%08X)\n", (unsigned int)handle);
562 zyn_fft_destroy(zyn_addsynth_ptr->fft);
564 // ADnoteParameters temp begin
566 for (voice_index = 0 ; voice_index < zyn_addsynth_ptr->voices_count ; voice_index++)
568 zyn_oscillator_uninit(&zyn_addsynth_ptr->voices_params_ptr[voice_index].oscillator);
569 zyn_oscillator_uninit(&zyn_addsynth_ptr->voices_params_ptr[voice_index].modulator_oscillator);
572 zyn_filter_sv_destroy(zyn_addsynth_ptr->filter_sv);
574 // ADnoteParameters temp end
576 free(zyn_addsynth_ptr->voices_params_ptr);
578 free(zyn_addsynth_ptr->notes_array);
580 free(zyn_addsynth_ptr->temporary_samples_ptr);
582 delete zyn_addsynth_ptr;
585 zyn_addsynth_component
586 zyn_addsynth_get_global_component(
587 zyn_addsynth_handle handle,
588 unsigned int component)
590 if (component >= ZYNADD_GLOBAL_COMPONENTS_COUNT)
592 assert(0);
593 return NULL;
596 return zyn_addsynth_ptr->global_components + component;
599 zyn_addsynth_component
600 zyn_addsynth_get_voice_component(
601 zyn_addsynth_handle handle,
602 unsigned int voice,
603 unsigned int component)
605 if (voice >= zyn_addsynth_ptr->voices_count)
607 assert(0);
608 return NULL;
611 if (component >= ZYNADD_VOICE_COMPONENTS_COUNT)
613 assert(0);
614 return NULL;
617 return zyn_addsynth_ptr->voices_components + voice * ZYNADD_VOICE_COMPONENTS_COUNT + component;
620 float percent_from_0_127(unsigned char value)
622 return ((float)(value)/127.0)*100.0; // 0-127 -> percent
625 unsigned char percent_to_0_127(float value)
627 return (unsigned char)roundf(value / 100.0 * 127.0);
630 #define component_ptr ((struct zyn_component_descriptor *)component)
632 float
633 zyn_addsynth_get_float_parameter(
634 zyn_addsynth_component component,
635 unsigned int parameter)
637 return component_ptr->get_float(component_ptr->context, parameter);
640 void
641 zyn_addsynth_set_float_parameter(
642 zyn_addsynth_component component,
643 unsigned int parameter,
644 float value)
646 return component_ptr->set_float(component_ptr->context, parameter, value);
649 bool
650 zyn_addsynth_get_bool_parameter(
651 zyn_addsynth_component component,
652 unsigned int parameter)
654 //LOG_DEBUG("component %p, context %p", component_ptr, component_ptr->context);
655 return component_ptr->get_bool(component_ptr->context, parameter);
658 void
659 zyn_addsynth_set_bool_parameter(
660 zyn_addsynth_component component,
661 unsigned int parameter,
662 bool value)
664 return component_ptr->set_bool(component_ptr->context, parameter, value);
667 signed int
668 zyn_addsynth_get_int_parameter(
669 zyn_addsynth_component component,
670 unsigned int parameter)
672 return component_ptr->get_int(component_ptr->context, parameter);
675 void
676 zyn_addsynth_set_int_parameter(
677 zyn_addsynth_component component,
678 unsigned int parameter,
679 signed int value)
681 return component_ptr->set_int(component_ptr->context, parameter, value);
684 #undef zyn_addsynth_ptr
686 void
687 zyn_addsynth_set_bandwidth(struct zyn_addsynth * zyn_addsynth_ptr, int value)
689 float tmp;
691 if (!zyn_addsynth_ptr->bandwidth_exponential)
693 if (value < 64 && zyn_addsynth_ptr->bandwidth_depth >= 64)
695 tmp = 1.0;
697 else
699 tmp = pow(25.0, pow(zyn_addsynth_ptr->bandwidth_depth / 127.0, 1.5)) - 1.0;
702 zyn_addsynth_ptr->bandwidth_relbw = (value / 64.0 - 1.0) * tmp + 1.0;
703 if (zyn_addsynth_ptr->bandwidth_relbw < 0.01)
705 zyn_addsynth_ptr->bandwidth_relbw = 0.01;
708 else
710 zyn_addsynth_ptr->bandwidth_relbw = pow(25.0, (value - 64.0) / 64.0 * (zyn_addsynth_ptr->bandwidth_depth / 64.0));
714 void
715 zyn_addsynth_set_modwheel(struct zyn_addsynth * zyn_addsynth_ptr, int value)
717 float tmp;
719 if (!zyn_addsynth_ptr->modwheel_exponential)
721 if ((value < 64) && (zyn_addsynth_ptr->modwheel_depth >= 64))
723 tmp = 1.0;
725 else
727 tmp = pow(25.0, pow(zyn_addsynth_ptr->modwheel_depth / 127.0, 1.5) * 2.0) / 25.0;
730 zyn_addsynth_ptr->modwheel_relmod = (value / 64.0 - 1.0) * tmp + 1.0;
731 if (zyn_addsynth_ptr->modwheel_relmod < 0.0)
733 zyn_addsynth_ptr->modwheel_relmod = 0.0;
736 else
738 zyn_addsynth_ptr->modwheel_relmod = pow(25.0 , (value - 64.0) / 64.0 * (zyn_addsynth_ptr->modwheel_depth / 80.0));