1 /*
2  * liquidsfz - sfz sampler
3  *
4  * Copyright (C) 2019  Stefan Westerfeld
5  *
6  * This library is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation; either version 2.1 of the License, or (at your
9  * option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #include <math.h>
22 
23 #include <array>
24 
25 #include "voice.hh"
26 #include "synth.hh"
27 
28 using namespace LiquidSFZInternal;
29 
30 using std::clamp;
31 
32 double
pan_stereo_factor(double region_pan,int ch)33 Voice::pan_stereo_factor (double region_pan, int ch)
34 {
35   /* sine panning law (constant power panning) */
36   const double pan = ch == 0 ? -region_pan : region_pan;
37   return sin ((pan + 100) / 400 * M_PI);
38 }
39 
40 double
velocity_track_factor(const Region & r,int midi_velocity)41 Voice::velocity_track_factor (const Region& r, int midi_velocity)
42 {
43   double curve;
44   if (r.amp_velcurve.empty())
45     curve = (midi_velocity * midi_velocity) / (127.0 * 127.0);
46   else
47     curve = r.amp_velcurve.get (midi_velocity);
48 
49   double veltrack_factor = r.amp_veltrack * 0.01;
50 
51   double offset = (veltrack_factor >= 0) ? 1 : 0;
52   double v = (offset - veltrack_factor) + veltrack_factor * curve;
53 
54   return v;
55 }
56 
57 void
update_replay_speed(bool now)58 Voice::update_replay_speed (bool now)
59 {
60   double semi_tones = (key_ - region_->pitch_keycenter) * (region_->pitch_keytrack * 0.01);
61   semi_tones += (region_->tune + pitch_random_cent_) * 0.01;
62   semi_tones += region_->transpose;
63 
64   /* pitch bend */
65   if (pitch_bend_value_ >= 0)
66     semi_tones += pitch_bend_value_ * (region_->bend_up * 0.01);
67   else
68     semi_tones += pitch_bend_value_ * (region_->bend_down * -0.01);
69 
70   semi_tones += synth_->get_cc_vec_value (channel_, region_->tune_cc) * 0.01; // tune_oncc
71 
72   replay_speed_.set (exp2f (semi_tones / 12) * region_->cached_sample->sample_rate / sample_rate_, now);
73 }
74 
75 uint
off_by()76 Voice::off_by()
77 {
78   return region_->off_by;
79 }
80 
81 void
start(const Region & region,int channel,int key,int velocity,double time_since_note_on,uint64_t global_frame_count,uint sample_rate)82 Voice::start (const Region& region, int channel, int key, int velocity, double time_since_note_on, uint64_t global_frame_count, uint sample_rate)
83 {
84   start_frame_count_ = global_frame_count;
85   sample_rate_ = sample_rate;
86   region_ = &region;
87   channel_ = channel;
88   key_ = key;
89   velocity_ = velocity;
90   trigger_ = region.trigger;
91   left_gain_.reset (sample_rate, 0.020);
92   right_gain_.reset (sample_rate, 0.020);
93   replay_speed_.reset (sample_rate, 0.020);
94 
95   amp_random_gain_ = db_to_factor (region.amp_random * synth_->normalized_random_value());
96   pitch_random_cent_ = region.pitch_random * synth_->normalized_random_value();
97 
98   velocity_gain_ = velocity_track_factor (region, velocity);
99   rt_decay_gain_ = 1.0;
100   if (region.trigger == Trigger::RELEASE)
101     {
102       rt_decay_gain_ = db_to_factor (-time_since_note_on * region.rt_decay);
103       synth_->debug ("rt_decay_gain %f\n", rt_decay_gain_);
104     }
105 
106   double delay = region.delay;
107   delay += synth_->get_cc_vec_value (channel_, region_->delay_cc); // delay_oncc
108   delay_samples_ = std::max (delay * sample_rate, 0.0);
109 
110   /* loop? */
111   loop_enabled_ = false;
112   if (region_->loop_mode == LoopMode::SUSTAIN || region_->loop_mode == LoopMode::CONTINUOUS)
113     {
114       if (region_->loop_end > region_->loop_start)
115         loop_enabled_ = true;
116     }
117 
118   /* play start position */
119   uint offset = region.offset;
120   offset += lrint (region.offset_random * synth_->normalized_random_value());
121   offset += lrint (synth_->get_cc_vec_value (channel_, region.offset_cc));
122   ppos_ = offset;
123   if (ppos_ > region.loop_end)
124     loop_enabled_ = false;
125 
126   update_volume_gain();
127   update_amplitude_gain();
128   update_pan_gain();
129   update_lr_gain (true);
130 
131   set_pitch_bend (synth_->get_pitch_bend (channel));
132   update_replay_speed (true);
133 
134   const float vnorm = velocity * (1 / 127.f);
135   envelope_.set_delay (amp_value (vnorm, region.ampeg_delay));
136   envelope_.set_attack (amp_value (vnorm, region.ampeg_attack));
137   envelope_.set_hold (amp_value (vnorm, region.ampeg_hold));
138   envelope_.set_decay (amp_value (vnorm, region.ampeg_decay));
139   envelope_.set_sustain (amp_value (vnorm, region.ampeg_sustain));
140   envelope_.set_release (amp_value (vnorm, region.ampeg_release));
141   envelope_.start (region, sample_rate_);
142 
143   state_ = ACTIVE;
144   synth_->debug ("location %s\n", region.location.c_str());
145   synth_->debug ("new voice %s - channels %d\n", region.sample.c_str(), region.cached_sample->channels);
146 
147   filter_envelope_.set_shape (Envelope::Shape::LINEAR);
148   filter_envelope_.set_delay (amp_value (vnorm, region.fileg_delay));
149   filter_envelope_.set_attack (amp_value (vnorm, region.fileg_attack));
150   filter_envelope_.set_hold (amp_value (vnorm, region.fileg_hold));
151   filter_envelope_.set_decay (amp_value (vnorm, region.fileg_decay));
152   filter_envelope_.set_sustain (amp_value (vnorm, region.fileg_sustain));
153   filter_envelope_.set_release (amp_value (vnorm, region.fileg_release));
154   filter_envelope_.start (region, sample_rate_);
155 
156   filter_envelope_depth_ = amp_value (vnorm, region.fileg_depth);
157 
158   start_filter (fimpl_, &region.fil);
159   start_filter (fimpl2_, &region.fil2);
160 
161   lfo_gen_.start (region, channel_, sample_rate_);
162 }
163 
164 void
start_filter(FImpl & fi,const FilterParams * params)165 Voice::start_filter (FImpl& fi, const FilterParams *params)
166 {
167   fi.params = params;
168 
169   fi.filter.reset (params->type, sample_rate_);
170 
171   fi.cutoff_smooth.reset (sample_rate_, 0.005);
172   fi.resonance_smooth.reset (sample_rate_, 0.005);
173 
174   update_cutoff (fi, true);
175   update_resonance (fi, true);
176 }
177 
178 float
amp_value(float vnorm,const EGParam & amp_param)179 Voice::amp_value (float vnorm, const EGParam& amp_param)
180 {
181   float value = amp_param.base + amp_param.vel2 * vnorm;
182   value += synth_->get_cc_vec_value (channel_, amp_param.cc_vec);
183 
184   return value;
185 }
186 
187 void
update_pan_gain()188 Voice::update_pan_gain()
189 {
190   float pan = region_->pan;
191   pan += synth_->get_cc_vec_value (channel_, region_->pan_cc);
192   pan = clamp (pan, -100.f, 100.f);
193 
194   pan_left_gain_ = pan_stereo_factor (pan, 0);
195   pan_right_gain_ = pan_stereo_factor (pan, 1);
196 }
197 
198 void
update_lr_gain(bool now)199 Voice::update_lr_gain (bool now)
200 {
201   const float global_gain = (1 / 32768.) * synth_->gain() * volume_gain_ * velocity_gain_ * rt_decay_gain_ * amplitude_gain_;
202 
203   synth_->debug (" - gain l=%.2f r=%.2f\n", 32768 * pan_left_gain_ * global_gain, 32768 * pan_right_gain_ * global_gain);
204   left_gain_.set (pan_left_gain_ * global_gain, now);
205   right_gain_.set (pan_right_gain_ * global_gain, now);
206 }
207 
208 float
apply_xfcurve(float f,XFCurve curve)209 Voice::apply_xfcurve (float f, XFCurve curve)
210 {
211   if (curve == XFCurve::POWER)
212     return sqrtf (f);
213   else
214     return f;
215 }
216 
217 float
xfin_gain(int value,int lo,int hi,XFCurve curve)218 Voice::xfin_gain (int value, int lo, int hi, XFCurve curve)
219 {
220   if (value < lo)
221     return 0;
222   if (value < hi && hi > lo)
223     return apply_xfcurve (float (value - lo) / (hi - lo), curve);
224   else
225     return 1;
226 }
227 
228 float
xfout_gain(int value,int lo,int hi,XFCurve curve)229 Voice::xfout_gain (int value, int lo, int hi, XFCurve curve)
230 {
231   if (value > hi)
232     return 0;
233   if (value > lo && hi > lo)
234     return apply_xfcurve (1 - float (value - lo) / (hi - lo), curve);
235   else
236     return 1;
237 }
238 
239 void
update_volume_gain()240 Voice::update_volume_gain()
241 {
242   float volume = region_->volume;
243   volume += synth_->get_cc_vec_value (channel_, region_->gain_cc);
244 
245   volume_gain_ = db_to_factor (volume);
246 
247   volume_gain_ *= amp_random_gain_;
248   volume_gain_ *= xfin_gain (velocity_, region_->xfin_lovel, region_->xfin_hivel, region_->xf_velcurve);
249   volume_gain_ *= xfout_gain (velocity_, region_->xfout_lovel, region_->xfout_hivel, region_->xf_velcurve);
250 
251   volume_gain_ *= xfin_gain (key_, region_->xfin_lokey, region_->xfin_hikey, region_->xf_keycurve);
252   volume_gain_ *= xfout_gain (key_, region_->xfout_lokey, region_->xfout_hikey, region_->xf_keycurve);
253 
254   // xfin_locc / xfin_hicc
255   for (auto xfcc : region_->xfin_ccs)
256     volume_gain_ *= xfin_gain (synth_->get_cc (channel_, xfcc.cc), xfcc.lo, xfcc.hi, region_->xf_cccurve);
257 
258   // xfout_locc / xfout_hicc
259   for (auto xfcc : region_->xfout_ccs)
260     volume_gain_ *= xfout_gain (synth_->get_cc (channel_, xfcc.cc), xfcc.lo, xfcc.hi, region_->xf_cccurve);
261 }
262 
263 void
update_amplitude_gain()264 Voice::update_amplitude_gain()
265 {
266   float gain = region_->amplitude * 0.01f;
267 
268   /* for CCs modulating amplitude, the amplitudes of the individual CCs are multiplied (not added) */
269   for (const auto& entry : region_->amplitude_cc)
270     gain *= synth_->get_cc_curve (channel_, entry) * entry.value * 0.01f;
271 
272   amplitude_gain_ = gain;
273 }
274 
275 void
update_cutoff(FImpl & fi,bool now)276 Voice::update_cutoff (FImpl& fi, bool now)
277 {
278   float delta_cent = synth_->get_cc_vec_value (channel_, fi.params->cutoff_cc);
279 
280   // key tracking
281   delta_cent += (key_ - fi.params->keycenter) * fi.params->keytrack;
282 
283   // velocity tracking
284   delta_cent += velocity_ * (1 / 127.f) * fi.params->veltrack;
285 
286   /* FIXME: maybe smooth only cc value */
287   fi.cutoff_smooth.set (fi.params->cutoff * exp2f (delta_cent * (1 / 1200.f)), now);
288 }
289 
290 void
update_resonance(FImpl & fi,bool now)291 Voice::update_resonance (FImpl& fi, bool now)
292 {
293   fi.resonance_smooth.set (fi.params->resonance + synth_->get_cc_vec_value (channel_, fi.params->resonance_cc), now);
294 }
295 
296 void
stop(OffMode off_mode)297 Voice::stop (OffMode off_mode)
298 {
299   state_ = Voice::RELEASED;
300   envelope_.stop (off_mode);
301   filter_envelope_.stop (OffMode::NORMAL);
302 }
303 
304 void
kill()305 Voice::kill()
306 {
307   state_ = Voice::IDLE;
308 }
309 
310 void
update_cc(int controller)311 Voice::update_cc (int controller)
312 {
313   if (region_->xfin_ccs.size() || region_->xfout_ccs.size())
314     {
315       update_volume_gain();
316       update_lr_gain (false);
317     }
318   if (region_->pan_cc.contains (controller))
319     {
320       update_pan_gain();
321       update_lr_gain (false);
322     }
323   if (region_->gain_cc.contains (controller))
324     {
325       update_volume_gain();
326       update_lr_gain (false);
327     }
328   if (region_->amplitude_cc.contains (controller))
329     {
330       update_amplitude_gain();
331       update_lr_gain (false);
332     }
333 
334   if (region_->tune_cc.contains (controller))
335     update_replay_speed (false);
336 
337   auto update_filter = [controller, this] (FImpl& fi)
338     {
339       if (fi.params->cutoff_cc.contains (controller))
340         update_cutoff (fi, false);
341 
342       if (fi.params->resonance_cc.contains (controller))
343         update_resonance (fi, false);
344     };
345   update_filter (fimpl_);
346   update_filter (fimpl2_);
347   lfo_gen_.update_ccs();
348 }
349 
350 void
update_gain()351 Voice::update_gain()
352 {
353   update_lr_gain (false);
354 }
355 
356 void
set_pitch_bend(int bend)357 Voice::set_pitch_bend (int bend)
358 {
359   pitch_bend_value_ = bend / double (0x2000) - 1.0;
360 }
361 
362 void
update_pitch_bend(int bend)363 Voice::update_pitch_bend (int bend)
364 {
365   set_pitch_bend (bend);
366   update_replay_speed (false);
367 }
368 
369 void
process(float ** orig_outputs,uint orig_n_frames)370 Voice::process (float **orig_outputs, uint orig_n_frames)
371 {
372   const auto csample = region_->cached_sample;
373   const auto channels = csample->channels;
374 
375   auto get_samples_mono = [csample, this] (uint x, auto& fsamples)
376     {
377       for (uint i = 0; i < fsamples.size(); i++)
378         {
379           if (x >= csample->samples.size())
380             {
381               fsamples[i] = 0;
382             }
383           else
384             {
385               fsamples[i] = csample->samples[x];
386               x++;
387 
388               if (loop_enabled_)
389                 if (x > uint (region_->loop_end))
390                   x = region_->loop_start;
391             }
392         }
393     };
394 
395   auto get_samples_stereo = [csample, this] (uint x, auto& fsamples)
396     {
397       for (uint i = 0; i < fsamples.size(); i += 2)
398         {
399           if (x >= csample->samples.size())
400             {
401               fsamples[i]     = 0;
402               fsamples[i + 1] = 0;
403             }
404           else
405             {
406               fsamples[i]     = csample->samples[x];
407               fsamples[i + 1] = csample->samples[x + 1];
408               x += 2;
409 
410               if (loop_enabled_)
411                 if (x > uint (region_->loop_end * 2))
412                   x = region_->loop_start * 2;
413             }
414         }
415     };
416   /* delay start of voice for delay_samples_ frames */
417   uint dframes = std::min (orig_n_frames, delay_samples_);
418   delay_samples_ -= dframes;
419 
420   /* compute n_frames / outputs according to delay */
421   uint n_frames = orig_n_frames - dframes;
422   float *outputs[2] =
423     {
424       orig_outputs[0] + dframes,
425       orig_outputs[1] + dframes
426     };
427 
428   /* render lfos */
429   float lfo_buffer[lfo_gen_.buffer_size (n_frames)];
430   lfo_gen_.process (lfo_buffer, n_frames);
431 
432   const float *lfo_pitch = lfo_gen_.get (LFOGen::PITCH);
433   if (!lfo_pitch)
434     lfo_pitch = synth_->const_block_1();
435 
436   const float *lfo_volume = lfo_gen_.get (LFOGen::VOLUME);
437   if (!lfo_volume)
438     lfo_volume = synth_->const_block_1();
439 
440   /* render voice */
441   float out_l[n_frames];
442   float out_r[n_frames];
443 
444   for (uint i = 0; i < n_frames; i++)
445     {
446       const uint ii = ppos_;
447       const uint x = ii * channels;
448       const float frac = ppos_ - ii;
449       if (x < csample->samples.size() && !envelope_.done())
450         {
451           const float amp_gain = envelope_.get_next();
452           if (channels == 1)
453             {
454               std::array<float, 2> fsamples;
455               get_samples_mono (x, fsamples);
456 
457               const float interp = fsamples[0] * (1 - frac) + fsamples[1] * frac;
458               out_l[i] = interp * amp_gain;
459               out_r[i] = interp * amp_gain;
460             }
461           else if (channels == 2)
462             {
463               std::array<float, 4> fsamples;
464               get_samples_stereo (x, fsamples);
465 
466               out_l[i] = (fsamples[0] * (1 - frac) + fsamples[2] * frac) * amp_gain;
467               out_r[i] = (fsamples[1] * (1 - frac) + fsamples[3] * frac) * amp_gain;
468             }
469           else
470             {
471               assert (false);
472             }
473         }
474       else
475         {
476           state_ = IDLE;
477 
478           /* output memory is uninitialized, so we need to explicitely write every sampl when done */
479           out_l[i] = 0;
480           out_r[i] = 0;
481         }
482       ppos_ += replay_speed_.get_next() * lfo_pitch[i];
483       if (loop_enabled_)
484         while (ppos_ > region_->loop_end)
485           ppos_ -= (region_->loop_end - region_->loop_start);
486     }
487 
488   /* process filters */
489   process_filter (fimpl_, true, out_l, out_r, n_frames, lfo_gen_.get (LFOGen::CUTOFF));
490   process_filter (fimpl2_, false, out_l, out_r, n_frames, nullptr);
491 
492   /* add samples to output buffer */
493   if (channels == 2)
494     {
495       for (uint i = 0; i < n_frames; i++)
496         {
497           outputs[0][i] += out_l[i] * lfo_volume[i] * left_gain_.get_next();
498           outputs[1][i] += out_r[i] * lfo_volume[i] * right_gain_.get_next();
499         }
500     }
501   else
502     {
503       for (uint i = 0; i < n_frames; i++)
504         {
505           outputs[0][i] += out_l[i] * lfo_volume[i] * left_gain_.get_next();
506           outputs[1][i] += out_l[i] * lfo_volume[i] * right_gain_.get_next();
507         }
508     }
509 }
510 
511 void
process_filter(FImpl & fi,bool envelope,float * left,float * right,uint n_frames,const float * lfo_cutoff_factor)512 Voice::process_filter (FImpl& fi, bool envelope, float *left, float *right, uint n_frames, const float *lfo_cutoff_factor)
513 {
514   if (fi.params->type == Filter::Type::NONE)
515     return;
516 
517   float mod_cutoff[n_frames];
518   float mod_resonance[n_frames];
519   float mod_env[n_frames];
520 
521   auto run_filter = [&] (const auto& cr_func)
522     {
523       const auto csample = region_->cached_sample;
524       const auto channels = csample->channels;
525 
526       if (channels == 2)
527         fi.filter.process_mod (left, right, cr_func, n_frames);
528       else
529         fi.filter.process_mod_mono (left, cr_func, n_frames);
530     };
531 
532   if (envelope && filter_envelope_depth_)
533     {
534       const float depth_factor = filter_envelope_depth_ / 1200.;
535 
536       if (fi.cutoff_smooth.is_constant() && filter_envelope_.is_constant() && fi.resonance_smooth.is_constant() && !lfo_cutoff_factor)
537         {
538           float cutoff = fi.cutoff_smooth.get_next() * exp2f (filter_envelope_.get_next() * depth_factor);
539           float resonance = fi.resonance_smooth.get_next();
540 
541           run_filter ([&] (int i)
542             {
543               return Filter::CR (cutoff, resonance);
544             });
545         }
546       else
547         {
548           for (uint i = 0; i < n_frames; i++)
549             {
550               mod_cutoff[i]    = fi.cutoff_smooth.get_next();
551               mod_env[i]       = filter_envelope_.get_next();
552               mod_resonance[i] = fi.resonance_smooth.get_next();
553             }
554 
555           run_filter ([&] (int i)
556             {
557               float cutoff = mod_cutoff[i] * exp2f (mod_env[i] * depth_factor);
558               if (lfo_cutoff_factor)
559                 cutoff *= lfo_cutoff_factor[i];
560 
561               return Filter::CR (cutoff, mod_resonance[i]);
562             });
563         }
564     }
565   else
566     {
567       if (fi.cutoff_smooth.is_constant() && fi.resonance_smooth.is_constant() && !lfo_cutoff_factor)
568         {
569           float cutoff    = fi.cutoff_smooth.get_next();
570           float resonance = fi.resonance_smooth.get_next();
571 
572           run_filter ([&] (int i)
573             {
574               return Filter::CR (cutoff, resonance);
575             });
576         }
577       else
578         {
579           for (uint i = 0; i < n_frames; i++)
580             {
581               mod_cutoff[i]    = fi.cutoff_smooth.get_next();
582               mod_resonance[i] = fi.resonance_smooth.get_next();
583             }
584           run_filter ([&] (int i)
585             {
586               float cutoff = mod_cutoff[i];
587               if (lfo_cutoff_factor)
588                 cutoff *= lfo_cutoff_factor[i];
589 
590               return Filter::CR (cutoff, mod_resonance[i]);
591             });
592         }
593     }
594 }
595