2 * Drawbar organ emulator.
4 * Copyright (C) 2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #ifndef __CALF_ORGAN_H
23 #define __CALF_ORGAN_H
29 #define ORGAN_KEYTRACK_POINTS 4
34 struct organ_parameters
{
35 enum { FilterCount
= 2, EnvCount
= 3 };
36 struct organ_filter_parameters
40 float envmod
[organ_parameters::EnvCount
];
44 struct organ_env_parameters
46 float attack
, decay
, sustain
, release
, velscale
, ampctl
;
49 //////////////////////////////////////////////////////////////////////////
50 // these parameters are binary-copied from control ports (order is important!)
60 float percussion_time
;
61 float percussion_level
;
62 float percussion_wave
;
63 float percussion_harmonic
;
64 float percussion_vel2amp
;
65 float percussion_fm_time
;
66 float percussion_fm_depth
;
67 float percussion_fm_wave
;
68 float percussion_fm_harmonic
;
69 float percussion_vel2fm
;
70 float percussion_trigger
;
71 float percussion_stereo
;
75 organ_filter_parameters filters
[organ_parameters::FilterCount
];
76 organ_env_parameters envs
[organ_parameters::EnvCount
];
83 float global_transpose
;
88 //////////////////////////////////////////////////////////////////////////
89 // these parameters are calculated
91 double perc_decay_const
, perc_fm_decay_const
;
95 unsigned int foldvalue
;
98 float percussion_keytrack
[ORGAN_KEYTRACK_POINTS
][2];
100 organ_parameters() : pitch_bend(1.0f
) {}
102 inline int get_percussion_wave() { return dsp::fastf2i_drm(percussion_wave
); }
103 inline int get_percussion_fm_wave() { return dsp::fastf2i_drm(percussion_fm_wave
); }
106 #define ORGAN_WAVE_BITS 12
107 #define ORGAN_WAVE_SIZE 4096
108 #define ORGAN_BIG_WAVE_BITS 17
109 #define ORGAN_BIG_WAVE_SIZE 131072
110 /// 2^ORGAN_BIG_WAVE_SHIFT = how many (quasi)periods per sample
111 #define ORGAN_BIG_WAVE_SHIFT 5
113 class organ_voice_base
: public calf_plugins::organ_enums
116 typedef waveform_family
<ORGAN_WAVE_BITS
> small_wave_family
;
117 typedef waveform_family
<ORGAN_BIG_WAVE_BITS
> big_wave_family
;
119 organ_parameters
*parameters
;
121 static small_wave_family (*waves
)[wave_count_small
];
122 static big_wave_family (*big_waves
)[wave_count_big
];
124 // dsp::sine_table<float, ORGAN_WAVE_SIZE, 1> sine_wave;
127 /// percussion FM carrier amplitude envelope
129 /// percussion FM modulator amplitude envelope
131 dsp::fixed_point
<int64_t, 20> pphase
, dpphase
;
132 dsp::fixed_point
<int64_t, 20> modphase
, moddphase
;
134 int &sample_rate_ref
;
136 /// pamp per-sample (linear) step during release stage (calculated on release so that it will take 30ms for it to go from "current value at release point" to 0)
139 organ_voice_base(organ_parameters
*_parameters
, int &_sample_rate_ref
, bool &_released_ref
);
141 inline float wave(float *data
, dsp::fixed_point
<int, 20> ph
) {
142 return ph
.lerp_table_lookup_float(data
);
144 inline float big_wave(float *data
, dsp::fixed_point
<int64_t, 20> &ph
) {
145 // wrap to fit within the wave
146 return ph
.lerp_table_lookup_float_mask(data
, ORGAN_BIG_WAVE_SIZE
- 1);
149 static inline small_wave_family
&get_wave(int wave
) {
150 return (*waves
)[wave
];
152 static inline big_wave_family
&get_big_wave(int wave
) {
153 return (*big_waves
)[wave
];
155 static void precalculate_waves(calf_plugins::progress_report_iface
*reporter
);
158 float phase
= dsp::midi_note_to_phase(note
, 100 * parameters
->global_transpose
+ parameters
->global_detune
, sample_rate_ref
);
159 dpphase
.set((long int) (phase
* parameters
->percussion_harmonic
* parameters
->pitch_bend
));
160 moddphase
.set((long int) (phase
* parameters
->percussion_fm_harmonic
* parameters
->pitch_bend
));
162 // this doesn't really have a voice interface
163 void render_percussion_to(float (*buf
)[2], int nsamples
);
164 void perc_note_on(int note
, int vel
);
165 void perc_note_off(int note
, int vel
);
179 enum { VibratoSize
= 6 };
180 float vibrato_x1
[VibratoSize
][2], vibrato_y1
[VibratoSize
][2];
182 dsp::onepole
<float> vibrato
[2];
185 void process(organ_parameters
*parameters
, float (*data
)[2], unsigned int len
, float sample_rate
);
188 class organ_voice
: public dsp::voice
, public organ_voice_base
{
190 enum { Channels
= 2, BlockSize
= 64, EnvCount
= organ_parameters::EnvCount
, FilterCount
= organ_parameters::FilterCount
};
192 float output_buffer
[BlockSize
][Channels
];
193 float aux_buffers
[3][BlockSize
][Channels
];
195 dsp::fixed_point
<int64_t, 52> phase
, dphase
;
196 dsp::biquad_d1
<float> filterL
[2], filterR
[2];
198 dsp::inertia
<dsp::linear_ramp
> expression
;
199 organ_vibrato vibrato
;
202 /// The envelopes have ended and the voice is in final fadeout stage
207 : organ_voice_base(NULL
, sample_rate
, perc_released
),
208 expression(dsp::linear_ramp(16)) {
214 for (int i
= 0; i
< FilterCount
; i
++)
221 void note_on(int note
, int vel
) {
224 perc_released
= false;
228 const float sf
= 0.001f
;
229 for (int i
= 0; i
< EnvCount
; i
++)
231 organ_parameters::organ_env_parameters
&p
= parameters
->envs
[i
];
232 envs
[i
].set(sf
* p
.attack
, sf
* p
.decay
, p
.sustain
, sf
* p
.release
, sample_rate
/ BlockSize
);
236 velocity
= vel
* 1.0 / 127.0;
238 perc_note_on(note
, vel
);
241 void note_off(int /* vel */) {
242 // reset age to 0 (because decay will turn from exponential to linear, necessary because of error cumulation prevention)
243 perc_released
= true;
244 if (pamp
.get_active())
248 rel_age_const
= pamp
.get() * ((1.0/44100.0)/0.03);
249 for (int i
= 0; i
< EnvCount
; i
++)
253 virtual void steal() {
254 perc_released
= true;
261 virtual int get_current_note() {
264 virtual bool get_active() {
265 return (note
!= -1) && (amp
.get_active() || (use_percussion() && pamp
.get_active()));
268 inline bool use_percussion()
270 return dsp::fastf2i_drm(parameters
->percussion_trigger
) == perctrig_polyphonic
;
274 /// Not a true voice, just something with similar-ish interface.
275 class percussion_voice
: public organ_voice_base
{
280 percussion_voice(organ_parameters
*_parameters
)
281 : organ_voice_base(_parameters
, sample_rate
, released
)
287 return (note
!= -1) && pamp
.get_active();
289 bool get_noticable() {
290 return (note
!= -1) && (pamp
.get() > 0.2 * parameters
->percussion_level
);
297 struct drawbar_organ
: public dsp::basic_synth
, public calf_plugins::organ_enums
{
298 organ_parameters
*parameters
;
299 percussion_voice percussion
;
300 organ_vibrato global_vibrato
;
302 drawbar_organ(organ_parameters
*_parameters
)
303 : parameters(_parameters
)
304 , percussion(_parameters
) {
306 void render_separate(float *output
[], int nsamples
)
309 dsp::zero(&buf
[0][0], 2 * nsamples
);
310 basic_synth::render_to(buf
, nsamples
);
311 if (dsp::fastf2i_drm(parameters
->lfo_mode
) == organ_voice_base::lfomode_global
)
313 for (int i
= 0; i
< nsamples
; i
+= 64)
314 global_vibrato
.process(parameters
, buf
+ i
, std::min(64, nsamples
- i
), sample_rate
);
316 if (percussion
.get_active())
317 percussion
.render_percussion_to(buf
, nsamples
);
318 float gain
= parameters
->master
* (1.0 / 8);
319 for (int i
=0; i
<nsamples
; i
++) {
320 output
[0][i
] = gain
*buf
[i
][0];
321 output
[1][i
] = gain
*buf
[i
][1];
324 dsp::voice
*alloc_voice() {
325 block_voice
<organ_voice
> *v
= new block_voice
<organ_voice
>();
326 v
->parameters
= parameters
;
329 virtual void percussion_note_on(int note
, int vel
) {
330 percussion
.perc_note_on(note
, vel
);
332 virtual void params_changed() = 0;
333 virtual void setup(int sr
) {
334 basic_synth::setup(sr
);
335 percussion
.setup(sr
);
336 parameters
->cutoff
= 0;
338 global_vibrato
.reset();
340 void update_params();
341 void control_change(int controller
, int value
)
344 if (controller
== 11)
346 parameters
->cutoff
= value
/ 64.0 - 1;
349 dsp::basic_synth::control_change(controller
, value
);
351 void pitch_bend(int amt
);
352 virtual bool check_percussion() {
353 switch(dsp::fastf2i_drm(parameters
->percussion_trigger
))
355 case organ_voice_base::perctrig_first
:
356 return active_voices
.empty();
357 case organ_voice_base::perctrig_each
:
360 case organ_voice_base::perctrig_eachplus
:
361 return !percussion
.get_noticable();
362 case organ_voice_base::perctrig_polyphonic
: