18  static const int WIDTH = 13;
 
   19  static const int WSHIFT = 6; 
 
   20  static const int OVERSAMPLE = 64;
 
   22  static const float blep_table[WIDTH * OVERSAMPLE + 1];
 
   25  double frequency_base   = 440;
 
   26  double frequency_factor = 1;
 
   28  double freq_mod_octaves = 0;
 
   30  double shape_base       = 0; 
 
   31  double shape_mod        = 1.0;
 
   33  double pulse_width_base = 0.5;
 
   34  double pulse_width_mod  = 0.0;
 
   42  double sub_width_base   = 0.5;
 
   43  double sub_width_mod    = 0.0;
 
   45  bool   need_reset_voice_state;
 
   56    double freq_factor     = 1;
 
   57    double left_factor     = 1;
 
   58    double right_factor    = 0;
 
   60    double master_phase    = 0;
 
   61    double slave_phase     = 0;
 
   63    double last_value      = 0; 
 
   64    double current_level   = 0; 
 
   73    State  state           = State::A;
 
   87      const float f = future[future_pos++];
 
   88      if (future_pos == WIDTH)
 
   91          for (
int i = 0; i < WIDTH; i++)
 
   93              future[i] = future[WIDTH + i];
 
   94              future[WIDTH + i] = 0;
 
 
  106    set_unison (1, 0, 0); 
 
  111    const bool randomize_phase = unison_voices.size() > 1;
 
  113    for (
auto& voice : unison_voices)
 
  125            reset_master (voice, 0);
 
  130  reset_master (UnisonVoice& voice, 
double master_phase)
 
  132    voice.master_phase = master_phase;
 
  133    need_reset_voice_state = 
true;
 
  136  set_unison (
size_t n_voices, 
float detune, 
float stereo)
 
  138    const bool unison_voices_changed = unison_voices.size() != n_voices;
 
  140    unison_voices.resize (n_voices);
 
  142    bool left_channel = 
true; 
 
  143    for (
size_t i = 0; i < unison_voices.size(); i++)
 
  146          unison_voices[i].freq_factor = 1;
 
  149            const float detune_cent = -detune / 2.0 + i / 
float (n_voices - 1) * detune;
 
  150            unison_voices[i].freq_factor = 
pow (2, detune_cent / 1200);
 
  153        double left_factor, right_factor;
 
  154        bool odd_n_voices = unison_voices.size() & 1;
 
  155        if (odd_n_voices && i == unison_voices.size() / 2)  
 
  157            left_factor  = (1 - stereo) + stereo * 0.5;
 
  158            right_factor = (1 - stereo) + stereo * 0.5;
 
  160        else if (left_channel) 
 
  162            left_factor  = 0.5 + stereo / 2;
 
  163            right_factor = 0.5 - stereo / 2;
 
  164            left_channel = 
false;
 
  168            left_factor  = 0.5 - stereo / 2;
 
  169            right_factor = 0.5 + stereo / 2;
 
  180        const double norm = 
sqrt (left_factor * left_factor + right_factor * right_factor) * 
sqrt (n_voices / 2.0);
 
  181        unison_voices[i].left_factor  = left_factor / norm;
 
  182        unison_voices[i].right_factor = right_factor / norm;
 
  184    if (unison_voices_changed)
 
  188  set_rate (
double rate)
 
  193    const double leaky_ms = 10;
 
  194    leaky_a = 
pow (2.0, -1000.0 / (rate_ * leaky_ms));
 
  202  estimate_dc (
double shape,
 
  208    const double bound_a = sub_width * pulse_width;
 
  209    const double bound_b = 2 * sub_width * pulse_width + 1 - sub_width - pulse_width;
 
  210    const double bound_c = sub_width * pulse_width + (1 - sub_width);
 
  211    const double bound_d = 1.0;
 
  213    const double saw_slope = -4.0 * (shape + 1) * (1 - sub);
 
  216    const double a2 = a1 + saw_slope * bound_a;
 
  218    const double b1 = a2 + 2.0 * (shape * (1 - sub) - sub);
 
  219    const double b2 = b1 + saw_slope * (bound_b - bound_a);
 
  221    const double c1 = b2 + 2 * (1 - sub);
 
  222    const double c2 = c1 + saw_slope * (bound_c - bound_b);
 
  224    const double d1 = c2 + 2.0 * (shape * (1 - sub) + sub);
 
  225    const double d2 = d1 + saw_slope * (bound_d - bound_c);
 
  228    const double dc_base = (a1 + a2) / 2 * bound_a
 
  229                         + (b1 + b2) / 2 * (bound_b - bound_a)
 
  230                         + (c1 + c2) / 2 * (bound_c - bound_b)
 
  231                         + (d1 + d2) / 2 * (bound_d - bound_c);
 
  234    if (sync_factor < 1.01)
 
  238    const double sync_phase = sync_factor - 
int (sync_factor);
 
  240    double a_avg = (a1 + a2) / 2;
 
  241    double b_avg = (b1 + b2) / 2;
 
  242    double c_avg = (c1 + c2) / 2;
 
  243    double d_avg = (d1 + d2) / 2;
 
  245    if (sync_phase < bound_a)
 
  247        const double frac = (bound_a - sync_phase) / bound_a;
 
  248        const double sync_a2 = a1 * frac + a2 * (1 - frac);
 
  250        a_avg = (1 - frac) * (a1 + sync_a2) / 2;
 
  251        b_avg = c_avg = d_avg = 0;
 
  253    else if (sync_phase < bound_b)
 
  255        const double frac = (bound_b - sync_phase) / (bound_b - bound_a);
 
  256        const double sync_b2 = b1 * frac + b2 * (1 - frac);
 
  258        b_avg = (1 - frac) * (b1 + sync_b2) / 2;
 
  261    else if (sync_phase < bound_c)
 
  263        const double frac = (bound_c - sync_phase) / (bound_c - bound_b);
 
  264        const double sync_c2 = c1 * frac + c2 * (1 - frac);
 
  266        c_avg = (1 - frac) * (c1 + sync_c2) / 2;
 
  271        const double frac = (bound_d - sync_phase) / (bound_d - bound_c);
 
  272        const double sync_d2 = d1 * frac + d2 * (1 - frac);
 
  274        d_avg = (1 - frac) * (d1 + sync_d2) / 2;
 
  278    const double dc_sync = a_avg * bound_a
 
  279                         + b_avg * (bound_b - bound_a)
 
  280                         + c_avg * (bound_c - bound_b)
 
  281                         + d_avg * (bound_d - bound_c);
 
  282    const double dc = (dc_base * (
int) sync_factor + dc_sync) / sync_factor;
 
  288  reset_voice_state (
double shape,
 
  294    const double bound_a = sub_width * pulse_width;
 
  295    const double bound_b = 2 * sub_width * pulse_width + 1 - sub_width - pulse_width;
 
  296    const double bound_c = sub_width * pulse_width + (1 - sub_width);
 
  297    const double bound_d = 1.0;
 
  299    const double saw_slope = -4.0 * (shape + 1) * (1 - sub);
 
  302    const double a2 = a1 + saw_slope * bound_a;
 
  304    const double b1 = a2 + 2.0 * (shape * (1 - sub) - sub);
 
  305    const double b2 = b1 + saw_slope * (bound_b - bound_a);
 
  307    const double c1 = b2 + 2 * (1 - sub);
 
  308    const double c2 = c1 + saw_slope * (bound_c - bound_b);
 
  310    const double d1 = c2 + 2.0 * (shape * (1 - sub) + sub);
 
  311    const double d2 = d1 + saw_slope * (bound_d - bound_c);
 
  314    const double dc_base = (a1 + a2) / 2 * bound_a
 
  315                         + (b1 + b2) / 2 * (bound_b - bound_a)
 
  316                         + (c1 + c2) / 2 * (bound_c - bound_b)
 
  317                         + (d1 + d2) / 2 * (bound_d - bound_c);
 
  320    const double sync_phase = sync_factor - 
int (sync_factor);
 
  322    double a_avg = (a1 + a2) / 2;
 
  323    double b_avg = (b1 + b2) / 2;
 
  324    double c_avg = (c1 + c2) / 2;
 
  325    double d_avg = (d1 + d2) / 2;
 
  327    if (sync_phase < bound_a)
 
  329        const double frac = (bound_a - sync_phase) / bound_a;
 
  330        const double sync_a2 = a1 * frac + a2 * (1 - frac);
 
  332        a_avg = (1 - frac) * (a1 + sync_a2) / 2;
 
  333        b_avg = c_avg = d_avg = 0;
 
  335    else if (sync_phase < bound_b)
 
  337        const double frac = (bound_b - sync_phase) / (bound_b - bound_a);
 
  338        const double sync_b2 = b1 * frac + b2 * (1 - frac);
 
  340        b_avg = (1 - frac) * (b1 + sync_b2) / 2;
 
  343    else if (sync_phase < bound_c)
 
  345        const double frac = (bound_c - sync_phase) / (bound_c - bound_b);
 
  346        const double sync_c2 = c1 * frac + c2 * (1 - frac);
 
  348        c_avg = (1 - frac) * (c1 + sync_c2) / 2;
 
  353        const double frac = (bound_d - sync_phase) / (bound_d - bound_c);
 
  354        const double sync_d2 = d1 * frac + d2 * (1 - frac);
 
  356        d_avg = (1 - frac) * (d1 + sync_d2) / 2;
 
  360    double dc_sync = a_avg * bound_a
 
  361                   + b_avg * (bound_b - bound_a)
 
  362                   + c_avg * (bound_c - bound_b)
 
  363                   + d_avg * (bound_d - bound_c);
 
  365    const double dc = (dc_base * (
int) sync_factor + dc_sync) / sync_factor;
 
  367    for (
auto& voice : unison_voices)
 
  369        double dest_phase = voice.master_phase;
 
  373        dest_phase *= sync_factor;
 
  374        dest_phase -= (
int) dest_phase;
 
  376        voice.slave_phase = dest_phase;
 
  379        if (dest_phase < bound_a)
 
  381            double frac = (bound_a - dest_phase) / bound_a;
 
  382            last_value = a1 * frac + a2 * (1 - frac);
 
  384            voice.state = State::A;
 
  386        else if (dest_phase < bound_b)
 
  388            double frac = (bound_b - dest_phase) / (bound_b - bound_a);
 
  389            last_value = b1 * frac + b2 * (1 - frac);
 
  391            voice.state = State::B;
 
  393        else if (dest_phase < bound_c)
 
  395            double frac = (bound_c - dest_phase) / (bound_c - bound_b);
 
  396            last_value = c1 * frac + c2 * (1 - frac);
 
  398            voice.state = State::C;
 
  402            double frac = (bound_d - dest_phase) / (bound_d - bound_c);
 
  403            last_value = d1 * frac + d2 * (1 - frac);
 
  405            voice.state = State::D;
 
  407        voice.last_value    = last_value - dc;
 
  409        voice.current_level = last_value - 1;
 
  413  insert_blep (UnisonVoice& voice, 
double frac, 
double weight)
 
  415    int pos = frac * OVERSAMPLE;
 
  416    const float inter_frac = frac * OVERSAMPLE - pos;
 
  417    const float weight_left = (1 - inter_frac) * weight;
 
  418    const float weight_right = inter_frac * weight;
 
  421    pos = 
std::min (pos, OVERSAMPLE - 1);
 
  423    for (
int i = 0; i < WIDTH; i++)
 
  425        voice.future[i + voice.future_pos] += blep_table[pos] * weight_left + blep_table[pos + 1] * weight_right;
 
  431  insert_future_delta (UnisonVoice& voice, 
double weight)
 
  433    voice.future[voice.future_pos + WSHIFT] += weight;
 
  437  clamp (
double d, 
double min, 
double max)
 
  448  check_slave_before_master (UnisonVoice& voice, 
double target_phase, 
double sync_factor)
 
  450    if (voice.slave_phase > target_phase)
 
  452        if (voice.master_phase > 1)
 
  454            const double slave_frac = (voice.slave_phase - target_phase) / sync_factor;
 
  455            const double master_frac = voice.master_phase - 1;
 
  457            return master_frac < slave_frac;
 
  465  process_sample_stereo (
float *left_out, 
float *right_out, 
unsigned int n_values,
 
  466                         const float *freq_in = 
nullptr,
 
  467                         const float *freq_mod_in = 
nullptr,
 
  468                         const float *shape_mod_in = 
nullptr,
 
  469                         const float *sub_mod_in = 
nullptr,
 
  470                         const float *sync_mod_in = 
nullptr,
 
  471                         const float *pulse_mod_in = 
nullptr,
 
  472                         const float *sub_width_mod_in = 
nullptr)
 
  477    double master_freq = frequency_factor * frequency_base;
 
  478    double pulse_width = clamp (pulse_width_base, 0.01, 0.99);
 
  479    double sub         = clamp (sub_base, 0.0, 1.0);
 
  480    double sub_width   = clamp (sub_width_base, 0.01, 0.99);
 
  481    double shape       = clamp (shape_base, -1.0, 1.0);
 
  482    double sync_factor = 
fast_exp2 (clamp (sync_base, 0.0, 60.0) / 12);
 
  485    const int dc_steps = 
max (
irintf (rate_ / 4000), 1);
 
  487    for (
auto& voice : unison_voices)
 
  489        const double master_freq2inc = 0.5 / rate_ * voice.freq_factor;
 
  491        for (
unsigned int n = 0; n < n_values; n++)
 
  496            double master_inc = master_freq * master_freq2inc;
 
  498              master_inc *= 
fast_exp2 (freq_mod_in[n] * freq_mod_octaves);
 
  501              shape = clamp (shape_base + shape_mod * shape_mod_in[n], -1.0, 1.0);
 
  504              sub = clamp (sub_base + sub_mod * sub_mod_in[n], 0.0, 1.0);
 
  507              sync_factor = 
fast_exp2 (clamp (sync_base + sync_mod * sync_mod_in[n], 0.0, 60.0) / 12);
 
  510              pulse_width = clamp (pulse_width_base + pulse_width_mod * pulse_mod_in[n], 0.01, 0.99);
 
  512            if (sub_width_mod_in)
 
  513              sub_width = clamp (sub_width_base + sub_width_mod * sub_width_mod_in[n], 0.01, 0.99);
 
  516            if (need_reset_voice_state)
 
  518                reset_voice_state (shape, pulse_width, sub, sub_width, sync_factor);
 
  519                need_reset_voice_state = 
false;
 
  522            const double slave_inc = master_inc * sync_factor;
 
  523            const double saw_delta = -4.0 * slave_inc * (shape + 1) * (1 - sub);
 
  525            voice.master_phase += master_inc;
 
  526            voice.slave_phase  += slave_inc;
 
  531                state_changed = 
false;
 
  533                if (voice.state == State::A)
 
  535                    const double bound_a = sub_width * pulse_width;
 
  537                    if (check_slave_before_master (voice, bound_a, sync_factor))
 
  539                        const double slave_frac = (voice.slave_phase - bound_a) / slave_inc;
 
  541                        const double jump_a = 2.0 * (shape * (1 - sub) - sub);
 
  542                        const double saw = -4.0 * (shape + 1) * (1 - sub) * bound_a;
 
  543                        const double blep_height = jump_a + saw - (voice.current_level + (1 - slave_frac) * saw_delta);
 
  545                        insert_blep (voice, slave_frac, blep_height);
 
  546                        voice.current_level += blep_height;
 
  547                        voice.state = State::B;
 
  548                        state_changed = 
true;
 
  551                if (voice.state == State::B)
 
  553                    const double bound_b = 2 * sub_width * pulse_width + 1 - sub_width - pulse_width;
 
  555                    if (check_slave_before_master (voice, bound_b, sync_factor))
 
  557                        const double slave_frac = (voice.slave_phase - bound_b) / slave_inc;
 
  559                        const double jump_ab = 2.0 * ((shape + 1) * (1 - sub) - sub);
 
  560                        const double saw = -4.0 * (shape + 1) * (1 - sub) * bound_b;
 
  561                        const double blep_height = jump_ab + saw - (voice.current_level + (1 - slave_frac) * saw_delta);
 
  563                        insert_blep (voice, slave_frac, blep_height);
 
  564                        voice.current_level += blep_height;
 
  565                        voice.state = State::C;
 
  566                        state_changed = 
true;
 
  569                if (voice.state == State::C)
 
  571                    const double bound_c = sub_width * pulse_width + (1 - sub_width);
 
  573                    if (check_slave_before_master (voice, bound_c, sync_factor))
 
  575                        const double slave_frac = (voice.slave_phase - bound_c) / slave_inc;
 
  577                        const double jump_abc = 2.0 * (2 * shape + 1) * (1 - sub);
 
  578                        const double saw = -4.0 * (shape + 1) * (1 - sub) * bound_c;
 
  579                        const double blep_height = jump_abc + saw - (voice.current_level + (1 - slave_frac) * saw_delta);
 
  581                        insert_blep (voice, slave_frac, blep_height);
 
  582                        voice.current_level += blep_height;
 
  583                        voice.state = State::D;
 
  584                        state_changed = 
true;
 
  587                if (voice.state == State::D)
 
  589                    if (check_slave_before_master (voice, 1, sync_factor))
 
  591                        voice.slave_phase -= 1;
 
  593                        const double slave_frac = voice.slave_phase / slave_inc;
 
  595                        voice.current_level += (1 - slave_frac) * saw_delta;
 
  597                        insert_blep (voice, slave_frac, -voice.current_level);
 
  599                        voice.current_level = saw_delta * slave_frac - saw_delta;
 
  600                        voice.state = State::A;
 
  601                        state_changed = 
true;
 
  604                if (!state_changed && voice.master_phase > 1)
 
  606                    voice.master_phase -= 1;
 
  608                    const double master_frac = voice.master_phase / master_inc;
 
  610                    const double new_slave_phase = voice.master_phase * sync_factor;
 
  612                    voice.current_level += (1 - master_frac) * saw_delta;
 
  614                    insert_blep (voice, master_frac, -voice.current_level);
 
  616                    voice.current_level = saw_delta * master_frac - saw_delta;
 
  617                    voice.slave_phase = new_slave_phase;
 
  619                    voice.state = State::A;
 
  620                    state_changed = 
true;
 
  623            while (state_changed); 
 
  625            if (voice.dc_steps > 0)
 
  631                const double dc = estimate_dc (shape, pulse_width, sub, sub_width, sync_factor);
 
  633                voice.dc_steps = dc_steps - 1;
 
  634                voice.dc_delta = (voice.last_dc - dc) / dc_steps;
 
  638            voice.current_level += saw_delta;
 
  639            insert_future_delta (voice, saw_delta + voice.dc_delta); 
 
  642            double value = leaky_a * voice.last_value + voice.pop_future();
 
  643            voice.last_value = value;
 
  645            left_out[n] += value * voice.left_factor;
 
  646            right_out[n] += value * voice.right_factor;