[SCM] calf/master: + Organ: polyphonic percussion mode (ugly ugly code)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:28 UTC 2013


The following commit has been merged in the master branch:
commit 2127eb94d39512415feed4e7bc7fc63db06e7e6f
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Mon Aug 4 19:37:45 2008 +0000

    + Organ: polyphonic percussion mode (ugly ugly code)
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@255 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/organ.h b/src/calf/organ.h
index da9d412..4b6696b 100644
--- a/src/calf/organ.h
+++ b/src/calf/organ.h
@@ -148,10 +148,13 @@ public:
         perctrig_first = 0,
         perctrig_each,
         perctrig_eachplus,
+        perctrig_polyphonic,
         perctrig_count
     };
     typedef waveform_family<ORGAN_WAVE_BITS> small_wave_family;
     typedef waveform_family<ORGAN_BIG_WAVE_BITS> big_wave_family;
+public:
+    organ_parameters *parameters;
 protected:
     static small_wave_family (*waves)[wave_count_small];
     static big_wave_family (*big_waves)[wave_count_big];
@@ -159,8 +162,16 @@ protected:
     // dsp::sine_table<float, ORGAN_WAVE_SIZE, 1> sine_wave;
     int note;
     dsp::decay amp;
+    /// percussion FM carrier amplitude envelope
+    dsp::decay pamp;
+    /// percussion FM modulator amplitude envelope
+    dsp::decay fm_amp;
+    dsp::fixed_point<int64_t, 20> pphase, dpphase;
+    dsp::fixed_point<int64_t, 20> modphase, moddphase;
+    float fm_keytrack;
+    int &sample_rate_ref;
 
-    organ_voice_base(organ_parameters *_parameters);
+    organ_voice_base(organ_parameters *_parameters, int &_sample_rate_ref);
     
     inline float wave(float *data, dsp::fixed_point<int, 20> ph) {
         return ph.lerp_table_lookup_float(data);
@@ -170,7 +181,6 @@ protected:
         return ph.lerp_table_lookup_float_mask(data, ORGAN_BIG_WAVE_SIZE - 1);
     }
 public:
-    organ_parameters *parameters;
     static inline small_wave_family &get_wave(int wave) {
         return (*waves)[wave];
     }
@@ -178,6 +188,23 @@ public:
         return (*big_waves)[wave];
     }
     static void precalculate_waves();
+    void update_pitch()
+    {
+        float phase = synth::midi_note_to_phase(note, 100 * parameters->global_transpose + parameters->global_detune, sample_rate_ref);
+        dpphase.set(phase * parameters->percussion_harmonic * parameters->pitch_bend);
+        moddphase.set(phase * parameters->percussion_fm_harmonic * parameters->pitch_bend);
+    }
+    // this doesn't really have a voice interface
+    void render_percussion_to(float (*buf)[2], int nsamples);
+    void perc_note_on(int note, int vel);
+    void perc_reset()
+    {
+        pphase = 0;
+        modphase = 0;
+        dpphase = 0;
+        moddphase = 0;
+        note = -1;
+    }
 };
 
 class organ_vibrato
@@ -209,7 +236,7 @@ protected:
 
 public:
     organ_voice()
-    : organ_voice_base(NULL),
+    : organ_voice_base(NULL, sample_rate),
     expression(linear_ramp(16)) {
     }
 
@@ -237,6 +264,7 @@ public:
         velocity = vel * 1.0 / 127.0;
         amp.set(1.0f);
         released = false;
+        perc_note_on(note, vel);
     }
 
     void note_off(int /* vel */) {
@@ -250,48 +278,30 @@ public:
         return note;
     }
     virtual bool get_active() {
-        return (note != -1) && amp.get_active();
+        return (note != -1) && (amp.get_active() || (use_percussion() && pamp.get_active()));
     }
     void update_pitch();
+    inline bool use_percussion()
+    {
+        return dsp::fastf2i_drm(parameters->percussion_trigger) == perctrig_polyphonic;
+    }
 };
 
 /// Not a true voice, just something with similar-ish interface.
 class percussion_voice: public organ_voice_base {
 public:
     int sample_rate;
-    dsp::fixed_point<int64_t, 20> phase, modphase, dphase, moddphase;
-    dsp::decay fm_amp;
-    float fm_keytrack;
 
     percussion_voice(organ_parameters *_parameters)
-    : organ_voice_base(_parameters)
+    : organ_voice_base(_parameters, sample_rate)
     {
     }
     
-    void reset() {
-        phase = 0;
-        modphase = 0;
-        dphase = 0;
-        moddphase = 0;
-        note = -1;
-    }
-
-    void note_on(int note, int vel);
-    
-    void update_pitch()
-    {
-        float phase = synth::midi_note_to_phase(note, 0, sample_rate);
-        dphase.set(phase * parameters->percussion_harmonic * parameters->pitch_bend);
-        moddphase.set(phase * parameters->percussion_fm_harmonic * parameters->pitch_bend);
-    }
-
-    // this doesn't really have a voice interface
-    void render_to(float (*buf)[2], int nsamples);
     bool get_active() {
-        return (note != -1) && amp.get_active();
+        return (note != -1) && pamp.get_active();
     }
     bool get_noticable() {
-        return (note != -1) && (amp.get() > 0.2);
+        return (note != -1) && (pamp.get() > 0.2 * parameters->percussion_level);
     }
     void setup(int sr) {
         sample_rate = sr;
@@ -343,7 +353,7 @@ struct drawbar_organ: public synth::basic_synth {
                 global_vibrato.process(parameters, buf + i, min(64, nsamples - i), sample_rate);
         }
         if (percussion.get_active())
-            percussion.render_to(buf, nsamples);
+            percussion.render_percussion_to(buf, nsamples);
         float gain = parameters->master * (1.0 / (9 * 8));
         for (int i=0; i<nsamples; i++) {
             output[0][i] = gain*buf[i][0];
@@ -356,7 +366,7 @@ struct drawbar_organ: public synth::basic_synth {
         return v;
     }
     virtual void percussion_note_on(int note, int vel) {
-        percussion.note_on(note, vel);
+        percussion.perc_note_on(note, vel);
     }
     virtual void params_changed() = 0;
     virtual void setup(int sr) {
@@ -386,6 +396,8 @@ struct drawbar_organ: public synth::basic_synth {
                 return true;
             case organ_voice_base::perctrig_eachplus:
                 return !percussion.get_noticable();
+            case organ_voice_base::perctrig_polyphonic:
+                return false;
         }
     }
 };
diff --git a/src/organ.cpp b/src/organ.cpp
index e5e7509..b36465f 100644
--- a/src/organ.cpp
+++ b/src/organ.cpp
@@ -417,7 +417,7 @@ bool organ_audio_module::get_graph(int index, int subindex, float *data, int poi
 
 const char *organ_audio_module::port_names[] = {"Out L", "Out R"};
 
-const char *organ_percussion_trigger_names[] = { "First note", "Each note", "Each, no retrig" };
+const char *organ_percussion_trigger_names[] = { "First note", "Each note", "Each, no retrig", "Polyphonic" };
 
 const char *organ_wave_names[] = { 
     "Sin", 
@@ -927,12 +927,56 @@ void organ_voice_base::precalculate_waves()
     }
 }
 
-organ_voice_base::organ_voice_base(organ_parameters *_parameters)
+organ_voice_base::organ_voice_base(organ_parameters *_parameters, int &_sample_rate_ref)
 : parameters(_parameters)
+, sample_rate_ref(_sample_rate_ref)
 {
     note = -1;
 }
 
+void organ_voice_base::render_percussion_to(float (*buf)[2], int nsamples)
+{
+    if (note == -1)
+        return;
+
+    if (!pamp.get_active())
+        return;
+    if (parameters->percussion_level < small_value<float>())
+        return;
+    float level = parameters->percussion_level * 9;
+    static float zeros[ORGAN_WAVE_SIZE];
+    // XXXKF the decay needs work!
+    double age_const = parameters->perc_decay_const;
+    double fm_age_const = parameters->perc_fm_decay_const;
+    int timbre = parameters->get_percussion_wave();
+    if (timbre < 0 || timbre >= wave_count_small)
+        return;
+    int timbre2 = parameters->get_percussion_fm_wave();
+    if (timbre2 < 0 || timbre2 >= wave_count_small)
+        timbre2 = wave_sine;
+    float *fmdata = (*waves)[timbre2].get_level(moddphase.get());
+    if (!fmdata)
+        fmdata = zeros;
+    float *data = (*waves)[timbre].get_level(dpphase.get());
+    if (!data) {
+        pamp.set(0.0);
+        return;
+    }
+    float s = parameters->percussion_stereo * ORGAN_WAVE_SIZE * (0.5 / 360.0);
+    for (int i = 0; i < nsamples; i++) {
+        float fm = wave(fmdata, modphase);
+        fm *= ORGAN_WAVE_SIZE * parameters->percussion_fm_depth * fm_amp.get();
+        modphase += moddphase;
+        fm_amp.age_exp(fm_age_const, 1.0 / 32768.0);
+        
+        float lamp = level * pamp.get();
+        buf[i][0] += lamp * wave(data, pphase + dsp::fixed_point<int64_t, 52>(fm - s));
+        buf[i][1] += lamp * wave(data, pphase + dsp::fixed_point<int64_t, 52>(fm + s));
+        pamp.age_exp(age_const, 1.0 / 32768.0);
+        pphase += dpphase;
+    }
+}
+
 void organ_vibrato::reset()
 {
     for (int i = 0; i < VibratoSize; i++)
@@ -975,6 +1019,7 @@ void organ_vibrato::process(organ_parameters *parameters, float (*data)[2], unsi
 
 void organ_voice::update_pitch()
 {
+    organ_voice_base::update_pitch();
     dphase.set(synth::midi_note_to_phase(note, 100 * parameters->global_transpose + parameters->global_detune, sample_rate) * parameters->pitch_bend);
 }
 
@@ -985,7 +1030,11 @@ void organ_voice::render_block() {
     dsp::zero(&output_buffer[0][0], Channels * BlockSize);
     dsp::zero(&aux_buffers[1][0][0], 2 * Channels * BlockSize);
     if (!amp.get_active())
+    {
+        if (use_percussion())
+            render_percussion_to(output_buffer, BlockSize);
         return;
+    }
 
     update_pitch();
     dsp::fixed_point<int, 20> tphase, tdphase;
@@ -1130,6 +1179,9 @@ void organ_voice::render_block() {
             amp.age_lin((1.0/44100.0)/0.03,0.0);
         }
     }
+    
+    if (use_percussion())
+        render_percussion_to(output_buffer, BlockSize);
 }
 
 void drawbar_organ::update_params()
@@ -1166,16 +1218,15 @@ void organ_audio_module::execute(int cmd_no)
     }
 }
 
-void percussion_voice::note_on(int note, int vel)
+void organ_voice_base::perc_note_on(int note, int vel)
 {
     // do not reset phase if voice is still running (to prevent clicks, even at cost of slight loss of "percussiveness")
-    if (!amp.get_active())
+    if (!pamp.get_active())
     {
-        phase = 0;
-        modphase = 0;
+        perc_reset();
     }
     this->note = note;
-    amp.set(1.0f + (vel - 127) * parameters->percussion_vel2amp / 127.0);
+    pamp.set(1.0f + (vel - 127) * parameters->percussion_vel2amp / 127.0);
     update_pitch();
     float (*kt)[2] = parameters->percussion_keytrack;
     // assume last point (will be put there by padding)
@@ -1193,49 +1244,6 @@ void percussion_voice::note_on(int note, int vel)
     fm_amp.set(fm_keytrack * (1.0f + (vel - 127) * parameters->percussion_vel2fm / 127.0));
 }
 
-void percussion_voice::render_to(float (*buf)[2], int nsamples)
-{
-    if (note == -1)
-        return;
-
-    if (!amp.get_active())
-        return;
-    if (parameters->percussion_level < small_value<float>())
-        return;
-    float level = parameters->percussion_level * 9;
-    static float zeros[ORGAN_WAVE_SIZE];
-    // XXXKF the decay needs work!
-    double age_const = parameters->perc_decay_const;
-    double fm_age_const = parameters->perc_fm_decay_const;
-    int timbre = parameters->get_percussion_wave();
-    if (timbre < 0 || timbre >= wave_count_small)
-        return;
-    int timbre2 = parameters->get_percussion_fm_wave();
-    if (timbre2 < 0 || timbre2 >= wave_count_small)
-        timbre2 = wave_sine;
-    float *fmdata = (*waves)[timbre2].get_level(moddphase.get());
-    if (!fmdata)
-        fmdata = zeros;
-    float *data = (*waves)[timbre].get_level(dphase.get());
-    if (!data) {
-        amp.set(0.0);
-        return;
-    }
-    float s = parameters->percussion_stereo * ORGAN_WAVE_SIZE * (0.5 / 360.0);
-    for (int i = 0; i < nsamples; i++) {
-        float fm = wave(fmdata, modphase);
-        fm *= ORGAN_WAVE_SIZE * parameters->percussion_fm_depth * fm_amp.get();
-        modphase += moddphase;
-        fm_amp.age_exp(fm_age_const, 1.0 / 32768.0);
-        
-        float lamp = level * amp.get();
-        buf[i][0] += lamp * wave(data, phase + dsp::fixed_point<int64_t, 20>(fm - s));
-        buf[i][1] += lamp * wave(data, phase + dsp::fixed_point<int64_t, 20>(fm + s));
-        amp.age_exp(age_const, 1.0 / 32768.0);
-        phase += dphase;
-    }
-}
-
 char *organ_audio_module::configure(const char *key, const char *value)
 {
     if (!strcmp(key, "map_curve"))

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list