+ Monosynth: increase PWM range, add PWM eye candy
[calf.git] / src / calf / modules_synths.h
blob0bfecb5e4e6d7c68e377b54db2286637f352af1d
1 /* Calf DSP Library
2 * Audio modules - synthesizers
4 * Copyright (C) 2001-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.
21 #ifndef __CALF_MODULES_SYNTHS_H
22 #define __CALF_MODULES_SYNTHS_H
24 #include <assert.h>
25 #include "biquad.h"
26 #include "onepole.h"
27 #include "audio_fx.h"
28 #include "inertia.h"
29 #include "osc.h"
30 #include "synth.h"
31 #include "envelope.h"
32 #include "organ.h"
34 namespace calf_plugins {
36 #define MONOSYNTH_WAVE_BITS 12
38 /// Monosynth-in-making. Parameters may change at any point, so don't make songs with it!
39 /// It lacks inertia for parameters, even for those that really need it.
40 class monosynth_audio_module: public audio_module<monosynth_metadata>, public line_graph_iface
42 public:
43 float *ins[in_count];
44 float *outs[out_count];
45 float *params[param_count];
46 uint32_t srate, crate;
47 static dsp::waveform_family<MONOSYNTH_WAVE_BITS> *waves;
48 dsp::waveform_oscillator<MONOSYNTH_WAVE_BITS> osc1, osc2;
49 dsp::triangle_lfo lfo;
50 bool running, stopping, gate, force_fadeout;
51 int last_key;
53 float buffer[step_size], buffer2[step_size];
54 uint32_t output_pos;
55 dsp::onepole<float> phaseshifter;
56 dsp::biquad_d1_lerp<float> filter;
57 dsp::biquad_d1_lerp<float> filter2;
58 int wave1, wave2, filter_type, last_filter_type;
59 float freq, start_freq, target_freq, cutoff, decay_factor, fgain, fgain_delta, separation;
60 float detune, xpose, xfade, ampctl, fltctl, queue_vel;
61 float odcr, porta_time, lfo_bend, lfo_clock, last_lfov, modwheel_value;
62 int queue_note_on, stop_count, modwheel_value_int;
63 int legato;
64 dsp::adsr envelope;
65 dsp::keystack stack;
66 dsp::gain_smoothing master;
67 dsp::inertia<dsp::exponential_ramp> inertia_cutoff;
68 dsp::inertia<dsp::exponential_ramp> inertia_pitchbend;
70 monosynth_audio_module();
71 static void precalculate_waves(progress_report_iface *reporter);
72 void set_sample_rate(uint32_t sr);
73 void delayed_note_on();
74 /// Handle MIDI Note On message (does not immediately trigger a note, as it must start on
75 /// boundary of step_size samples).
76 void note_on(int note, int vel);
77 /// Handle MIDI Note Off message
78 void note_off(int note, int vel);
79 /// Handle pitch bend message.
80 inline void pitch_bend(int value)
82 inertia_pitchbend.set_inertia(pow(2.0, (value * *params[par_pwhlrange]) / (1200.0 * 8192.0)));
84 /// Update oscillator frequency based on base frequency, detune amount, pitch bend scaling factor and sample rate.
85 inline void set_frequency()
87 float detune_scaled = (detune - 1); // * log(freq / 440);
88 osc1.set_freq(freq * (1 - detune_scaled) * inertia_pitchbend.get_last() * lfo_bend, srate);
89 osc2.set_freq(freq * (1 + detune_scaled) * inertia_pitchbend.get_last() * lfo_bend * xpose, srate);
91 /// Handle control change messages.
92 void control_change(int controller, int value);
93 /// Update variables from control ports.
94 void params_changed() {
95 float sf = 0.001f;
96 envelope.set(*params[par_attack] * sf, *params[par_decay] * sf, std::min(0.999f, *params[par_sustain]), *params[par_release] * sf, srate / step_size);
97 filter_type = dsp::fastf2i_drm(*params[par_filtertype]);
98 decay_factor = odcr * 1000.0 / *params[par_decay];
99 separation = pow(2.0, *params[par_cutoffsep] / 1200.0);
100 wave1 = dsp::clip(dsp::fastf2i_drm(*params[par_wave1]), 0, (int)wave_count - 1);
101 wave2 = dsp::clip(dsp::fastf2i_drm(*params[par_wave2]), 0, (int)wave_count - 1);
102 detune = pow(2.0, *params[par_detune] / 1200.0);
103 xpose = pow(2.0, *params[par_osc2xpose] / 12.0);
104 xfade = *params[par_oscmix];
105 legato = dsp::fastf2i_drm(*params[par_legato]);
106 master.set_inertia(*params[par_master]);
107 set_frequency();
109 void activate();
110 void deactivate();
111 void post_instantiate()
113 precalculate_waves(progress_report);
115 /// Run oscillators
116 void calculate_buffer_oscs(float lfo);
117 /// Run two filters in series to produce mono output samples.
118 void calculate_buffer_ser();
119 /// Run one filter to produce mono output samples.
120 void calculate_buffer_single();
121 /// Run two filters (one per channel) to produce stereo output samples.
122 void calculate_buffer_stereo();
123 /// Retrieve filter graph (which is 'live' so it cannot be generated by get_static_graph), or fall back to get_static_graph.
124 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
125 /// @retval true if the filter 1 is to be used for the left channel and filter 2 for the right channel
126 /// @retval false if filters are to be connected in series and sent (mono) to both channels
127 inline bool is_stereo_filter() const
129 return filter_type == flt_2lp12 || filter_type == flt_2bp6;
131 /// No CV inputs for now
132 bool is_cv(int param_no) { return false; }
133 /// Practically all the stuff here is noisy
134 bool is_noisy(int param_no) { return param_no != par_cutoff; }
135 /// Calculate control signals and produce step_size samples of output.
136 void calculate_step();
137 /// Main processing function
138 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
139 if (!running && queue_note_on == -1) {
140 for (uint32_t i = 0; i < nsamples / step_size; i++)
141 envelope.advance();
142 return 0;
144 uint32_t op = offset;
145 uint32_t op_end = offset + nsamples;
146 while(op < op_end) {
147 if (output_pos == 0) {
148 if (running || queue_note_on != -1)
149 calculate_step();
150 else {
151 envelope.advance();
152 dsp::zero(buffer, step_size);
155 if(op < op_end) {
156 uint32_t ip = output_pos;
157 uint32_t len = std::min(step_size - output_pos, op_end - op);
158 if (is_stereo_filter())
159 for(uint32_t i = 0 ; i < len; i++) {
160 float vol = master.get();
161 outs[0][op + i] = buffer[ip + i] * vol,
162 outs[1][op + i] = buffer2[ip + i] * vol;
164 else
165 for(uint32_t i = 0 ; i < len; i++)
166 outs[0][op + i] = outs[1][op + i] = buffer[ip + i] * master.get();
167 op += len;
168 output_pos += len;
169 if (output_pos == step_size)
170 output_pos = 0;
174 return 3;
178 struct organ_audio_module: public audio_module<organ_metadata>, public dsp::drawbar_organ, public line_graph_iface
180 public:
181 using drawbar_organ::note_on;
182 using drawbar_organ::note_off;
183 using drawbar_organ::control_change;
184 enum { param_count = drawbar_organ::param_count};
185 float *ins[in_count];
186 float *outs[out_count];
187 float *params[param_count];
188 dsp::organ_parameters par_values;
189 uint32_t srate;
190 bool panic_flag;
191 /// Value for configure variable map_curve
192 std::string var_map_curve;
194 organ_audio_module()
195 : drawbar_organ(&par_values)
197 var_map_curve = "2\n0 1\n1 1\n"; // XXXKF hacky bugfix
200 void post_instantiate()
202 dsp::organ_voice_base::precalculate_waves(progress_report);
205 void set_sample_rate(uint32_t sr) {
206 srate = sr;
208 void params_changed() {
209 for (int i = 0; i < param_count - var_count; i++)
210 ((float *)&par_values)[i] = *params[i];
212 unsigned int old_poly = polyphony_limit;
213 polyphony_limit = dsp::clip(dsp::fastf2i_drm(*params[par_polyphony]), 1, 32);
214 if (polyphony_limit < old_poly)
215 trim_voices();
217 update_params();
219 inline void pitch_bend(int amt)
221 drawbar_organ::pitch_bend(amt);
223 void activate() {
224 setup(srate);
225 panic_flag = false;
227 void deactivate();
228 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
229 float *o[2] = { outs[0] + offset, outs[1] + offset };
230 if (panic_flag)
232 control_change(120, 0); // stop all sounds
233 control_change(121, 0); // reset all controllers
234 panic_flag = false;
236 render_separate(o, nsamples);
237 return 3;
239 /// No CV inputs for now
240 bool is_cv(int param_no) { return false; }
241 /// Practically all the stuff here is noisy
242 bool is_noisy(int param_no) { return true; }
243 void execute(int cmd_no);
244 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
246 char *configure(const char *key, const char *value);
247 void send_configures(send_configure_iface *);
248 uint32_t message_run(const void *valid_inputs, void *output_ports) {
249 // silence a default printf (which is kind of a warning about unhandled message_run)
250 return 0;
256 #if ENABLE_EXPERIMENTAL
258 #include "wavetable.h"
260 #endif
262 #endif