[SCM] calf/master: newest analyzer stuff

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:40:56 UTC 2013


The following commit has been merged in the master branch:
commit bd9a31126b5ed45df434d6775594d4782f4794a5
Author: Christian Holschuh <chrischi at chrischi-laptop.(none)>
Date:   Tue Mar 6 00:25:19 2012 +0100

    newest analyzer stuff

diff --git a/gui/gui-analyzer.xml b/gui/gui-analyzer.xml
index 128e61d..aaf4caa 100644
--- a/gui/gui-analyzer.xml
+++ b/gui/gui-analyzer.xml
@@ -17,23 +17,30 @@
                         <hbox>
                             <combo param="analyzer_mode" expand="0" fill="0"/>
                             <combo param="analyzer_smoothing" expand="0" fill="0"/>
+                            <combo param="analyzer_correction" expand="0" fill="0"/>
                         </hbox>
-                        <line-graph refresh="1" width="560" height="240" param="analyzer_level" expand="1" fill="1" use_fade="1" fade="0.6"/>
+                        <line-graph refresh="1" width="560" height="240" param="analyzer_level" expand="1" fill="1" use_fade="1" fade="0.6" bars="1"/>
                         <hbox>
                             <hbox expand="1" fill="1"></hbox>
                             <hbox expand="0" fill="0" spacing="12">
                                 <label text="Accuracy" />
                                 <knob param="analyzer_accuracy" size="1" expand="0" fill="0"/>
-                                <label text="     " />
+                                <label text=" " />
                                 <label text="Speed" />
                                 <knob param="analyzer_speed" size="1" expand="0" fill="0"/>
-                                <label text="     " />
+                                <label text=" " />
                                 <label text="Hold" />
                                 <toggle param="analyzer_hold" size="1" expand="0" fill="0" />
-                                <label text="     " />
+                                <label text=" " />
                                 <label text="Freeze" />
                                 <toggle param="analyzer_freeze" size="1" expand="0" fill="0" />
-                                <label text="     " />
+                                <label text=" " />
+                                <label text="Linear" />
+                                <toggle param="analyzer_linear" size="1" expand="0" fill="0" />
+                                <label text=" " />
+                                <label text="Bars" />
+                                <toggle param="analyzer_bars" size="1" expand="0" fill="0" />
+                                <label text=" " />
                                 <label text="Display" />
                                 <toggle param="analyzer_display" size="1" expand="0" fill="0" />
                             </hbox>
diff --git a/src/calf/custom_ctl.h b/src/calf/custom_ctl.h
index 826b22c..c5c2405 100644
--- a/src/calf/custom_ctl.h
+++ b/src/calf/custom_ctl.h
@@ -47,6 +47,8 @@ struct CalfLineGraph
     bool is_square;
     bool use_fade;
     float fade;
+    bool bars;
+    bool boxes;
     cairo_surface_t *cache_surface;
     cairo_surface_t *fade_surface;
     //GdkPixmap *cache_pixmap;
diff --git a/src/calf/giface.h b/src/calf/giface.h
index eaad925..adfe47f 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -164,7 +164,7 @@ struct line_graph_iface
     /// @param context cairo context to adjust (for multicolour graphs etc.)
     /// @retval true graph data was returned; subindex+1 graph may or may not be available
     /// @retval false graph data was not returned; subindex+1 graph does not exist either
-    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { return false; }
+    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context, bool *bars, bool *blocks) const { return false; }
 
     /// Obtain subindex'th dot of parameter 'index'
     /// @param index parameter/dot number (usually tied to particular plugin control port)
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index b1e0e5e..b2beb59 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -409,7 +409,7 @@ struct analyzer_metadata: public plugin_metadata<analyzer_metadata>
 {
     enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_meter_L, param_meter_R, param_clip_L, param_clip_R,
-           param_analyzer_level, param_analyzer_mode, param_analyzer_accuracy, param_analyzer_speed, param_analyzer_display, param_analyzer_smoothing, param_analyzer_hold, param_analyzer_freeze,
+           param_analyzer_level, param_analyzer_mode, param_analyzer_accuracy, param_analyzer_speed, param_analyzer_display, param_analyzer_smoothing, param_analyzer_hold, param_analyzer_freeze, param_analyzer_linear, param_analyzer_bars, param_analyzer_correction,
            param_gonio_level, param_gonio_mode, param_gonio_use_fade, param_gonio_fade, param_gonio_accuracy, param_gonio_display,
            param_count };
     PLUGIN_NAME_ID_LABEL("analyzer", "analyzer", "Analyzer")
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 8570214..b5d0f75 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -320,7 +320,7 @@ public:
     void deactivate();
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
     bool get_phase_graph(float ** _buffer, int * _length, int * _mode, bool * _use_fade, float * _fade, int * _accuracy, bool * _display) const;
-    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context, bool *bars, bool *boxes) const;
     
 
 protected:
@@ -332,17 +332,22 @@ protected:
     int plength;
     int ppos;
     int fpos;
-    rfftw_plan fft_plan;
+    mutable rfftw_plan fft_plan;
     static const int max_fft_cache_size = 32768;
     static const int max_fft_buffer_size = max_fft_cache_size * 2;
     fftw_real *fft_in;
     fftw_real *fft_out;
     fftw_real *fft_smooth;
+    fftw_real *fft_inL;
+    fftw_real *fft_outL;
+    fftw_real *fft_inR;
+    fftw_real *fft_outR;
     float *fft_delta;
     float *fft_hold;
     float *fft_freeze;
     float _hold;
-
+    mutable int _smoothing;
+    mutable int lintrans;
     mutable int ____analyzer_phase_was_drawn_here;
     mutable int ____analyzer_smooth_dirty;
     mutable int ____analyzer_hold_dirty;
diff --git a/src/custom_ctl.cpp b/src/custom_ctl.cpp
index d4454e1..51a01cd 100644
--- a/src/custom_ctl.cpp
+++ b/src/custom_ctl.cpp
@@ -76,24 +76,43 @@ calf_line_graph_draw_grid( cairo_t *c, std::string &legend, bool vertical, float
 }
 
 static void
-calf_line_graph_draw_graph( cairo_t *c, float *data, int sx, int sy )
+calf_line_graph_draw_graph( cairo_t *c, float *data, int sx, int sy, bool bars, bool boxes )
 {
     int ox=5, oy=5;
-
+    int _last = 0;
+    int y;
     for (int i = 0; i < sx; i++)
     {
-        int y = (int)(oy + sy / 2 - (sy / 2 - 1) * data[i]);
-        //if (y < oy) y = oy;
-        //if (y >= oy + sy) y = oy + sy - 1;
-        if (i and (data[i] < INFINITY or i == sx - 1)) {
-            cairo_line_to(c, ox + i, y);
-        } else if (i) {
-            continue;
+        y = (int)(oy + sy / 2 - (sy / 2 - 1) * data[i]);
+        if(bars) {
+            // we want to draw bars
+            if(!i) {
+                _last = 0;
+            } else if (i and ((data[i] < INFINITY) or i == sx - 1)) {
+                if(boxes)
+                    cairo_rectangle(c, ox + _last, oy + y, i - _last, 3);
+                else
+                    cairo_rectangle(c, ox + _last, oy + y, i - _last, sy - y);
+                _last = i;
+            } else {
+                continue;
+            }
+        } else {
+            // we want to draw a line
+            if (i and (data[i] < INFINITY or i == sx - 1)) {
+                cairo_line_to(c, ox + i, y);
+            } else if (i) {
+                continue;
+            }
+            else
+                cairo_move_to(c, ox, y);
         }
-        else
-            cairo_move_to(c, ox, y);
     }
-    cairo_stroke(c);
+    if(bars) {
+        cairo_fill(c);
+    } else {
+        cairo_stroke(c);
+    }
 }
 
 static gboolean
@@ -222,12 +241,13 @@ calf_line_graph_expose (GtkWidget *widget, GdkEventExpose *event)
             }
             grid_n_save = grid_n;
 
-            gdk_cairo_set_source_color(cache_cr, &sc2);
+            //gdk_cairo_set_source_color(cache_cr, &sc2);
+            cairo_set_source_rgba(cache_cr, 0.15, 0.2, 0.0, 0.5);
             cairo_set_line_join(cache_cr, CAIRO_LINE_JOIN_MITER);
             cairo_set_line_width(cache_cr, 1);
-            for(graph_n = 0; (graph_n<cache_graph_index) && lg->source->get_graph(lg->source_id, graph_n, data, sx, &cache_cimpl); graph_n++)
+            for(graph_n = 0; (graph_n<cache_graph_index) && lg->source->get_graph(lg->source_id, graph_n, data, sx, &cache_cimpl, &lg->bars, &lg->boxes); graph_n++)
             {
-                calf_line_graph_draw_graph( cache_cr, data, sx, sy );
+                calf_line_graph_draw_graph( cache_cr, data, sx, sy, lg->bars, lg->boxes and graph_n );
             }
             gdk_cairo_set_source_color(cache_cr, &sc3);
             for(dot_n = 0; (dot_n<cache_dot_index) && lg->source->get_dot(lg->source_id, dot_n, x, y, size = 3, &cache_cimpl); dot_n++)
@@ -267,12 +287,12 @@ calf_line_graph_expose (GtkWidget *widget, GdkEventExpose *event)
             }
         }
 
-        gdk_cairo_set_source_color(cache_cr, &sc2);
+        cairo_set_source_rgba(cache_cr, 0.15, 0.2, 0.0, 0.5);
         cairo_set_line_join(cache_cr, CAIRO_LINE_JOIN_MITER);
         cairo_set_line_width(cache_cr, 1);
-        for(int gn = graph_n; lg->source->get_graph(lg->source_id, gn, data, sx, &cache_cimpl); gn++)
+        for(int gn = graph_n; lg->source->get_graph(lg->source_id, gn, data, sx, &cache_cimpl, &lg->bars, &lg->boxes); gn++)
         {
-            calf_line_graph_draw_graph( cache_cr, data, sx, sy );
+            calf_line_graph_draw_graph( cache_cr, data, sx, sy, lg->bars, lg->boxes and gn );
         }
         gdk_cairo_set_source_color(cache_cr, &sc3);
         for(int gn = dot_n; lg->source->get_dot(lg->source_id, gn, x, y, size = 3, &cache_cimpl); gn++)
@@ -595,8 +615,8 @@ calf_phase_graph_expose (GtkWidget *widget, GdkEventExpose *event)
         if(display) {
             cairo_rectangle(cache_cr, ox, oy, sx, sy);
             cairo_clip(cache_cr);
-            gdk_cairo_set_source_color(cache_cr, &sc3);
-            
+            //gdk_cairo_set_source_color(cache_cr, &sc3);
+            cairo_set_source_rgba(cache_cr, 0.15, 0.2, 0.0, 0.5);
             double _a;
             for(int i = 0; i < length; i+= accuracy) {
                 float l = phase_buffer[i];
diff --git a/src/gui_controls.cpp b/src/gui_controls.cpp
index b35a6f9..e309435 100644
--- a/src/gui_controls.cpp
+++ b/src/gui_controls.cpp
@@ -919,6 +919,8 @@ GtkWidget *line_graph_param_control::create(plugin_gui *_gui, int _param_no)
     clg->source_id = param_no;
     CALF_LINE_GRAPH(widget)->use_fade = get_int("use_fade", 0);
     CALF_LINE_GRAPH(widget)->fade = get_float("fade", 0.5);
+    CALF_LINE_GRAPH(widget)->bars = get_int("bars", 0);
+    CALF_LINE_GRAPH(widget)->boxes = get_int("boxes", 0);
     gtk_widget_set_name(GTK_WIDGET(widget), "Calf-LineGraph");
     return widget;
 }
diff --git a/src/metadata.cpp b/src/metadata.cpp
index 04cd382..f0c8fed 100644
--- a/src/metadata.cpp
+++ b/src/metadata.cpp
@@ -983,8 +983,9 @@ CALF_PLUGIN_INFO(stereo) = { 0x8588, "StereoTools", "Calf Stereo Tools", "Markus
 
 CALF_PORT_NAMES(analyzer) = {"In L", "In R", "Out L", "Out R"};
 const char *gonio_mode_names[] = { "Small Dots", "Medium Dots", "Big Dots", "Fields", "Lines" };
-const char *analyzer_mode_names[] = { "Average", "Maximum", "Left Channel", "Right Channel" };
+const char *analyzer_mode_names[] = { "Average", "Left Channel", "Right Channel" };
 const char *analyzer_smooth_names[] = { "Falling", "Smoothing", "Off" };
+const char *analyzer_correction_names[] = { "Off", "Additive", "Denoised Peaks", "Phase by Frequeny" };
 CALF_PORT_PROPS(analyzer) = {
     { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_L", "Level L" },
     { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_R", "Level R" },
@@ -992,13 +993,16 @@ CALF_PORT_PROPS(analyzer) = {
     { 0,           0,           1,     0,  PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_R", "Clip R" },
     
     { 1,           0.125,           8,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "analyzer_level", "Analyzer Level" },
-    { 0,           0,           3,     0,  PF_ENUM | PF_CTL_COMBO, analyzer_mode_names, "analyzer_mode", "Analyzer Mode" },
+    { 0,           0,           2,     0,  PF_ENUM | PF_CTL_COMBO, analyzer_mode_names, "analyzer_mode", "Analyzer Mode" },
     { 6,      2,           8,   0,  PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "analyzer_accuracy", "Analyzer Accuracy" },
     { 13,      1,           15,   0,  PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "analyzer_speed", "Analyzer Speed" },
     { 1,           0,           1,     0,  PF_BOOL | PF_CTL_TOGGLE, NULL, "analyzer_display", "Analyzer Display" },
     { 0,           0,           2,     0,  PF_ENUM | PF_CTL_COMBO, analyzer_smooth_names, "analyzer_smoothing", "Analyzer Smoothing" },
     { 0,           0,           1,     0,  PF_BOOL | PF_CTL_TOGGLE, NULL, "analyzer_hold", "Analyzer Hold" },
     { 0,          0, 1,     2, PF_BOOL | PF_CTL_TOGGLE , NULL, "analyzer_freeze", "Analyzer Freeze" },
+    { 1,          0, 1,     2, PF_BOOL | PF_CTL_TOGGLE , NULL, "analyzer_linear", "Analyzer Linear" },
+    { 1,          0, 1,     2, PF_BOOL | PF_CTL_TOGGLE , NULL, "analyzer_bars", "Analyzer Bars" },
+    { 1,           0,           3,     0,  PF_ENUM | PF_CTL_COMBO, analyzer_correction_names, "analyzer_correction", "Analyzer Correction" },
     
     { 1,           0.125,           8,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "gonio_level", "Gonio Level" },
     { 1,           0,           4,     0,  PF_ENUM | PF_CTL_COMBO, gonio_mode_names, "gonio_mode", "Gonio Mode" },
diff --git a/src/modules.cpp b/src/modules.cpp
index 2db8a81..41e0775 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -863,12 +863,17 @@ analyzer_audio_module::analyzer_audio_module() {
     plength = 0;
     fpos = 0;
     _hold = 0.f;
+    _smoothing = 0;
     phase_buffer = (float*) calloc(max_phase_buffer_size, sizeof(float));
     memset(phase_buffer, 0, max_phase_buffer_size * sizeof(float)); // reset buffer to zero
     fft_buffer = (float*) calloc(max_fft_buffer_size, sizeof(float));
     memset(fft_buffer, 0, max_fft_buffer_size * sizeof(float)); // reset buffer to zero
     fft_in = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
     fft_out = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
+    fft_inL = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
+    fft_outL = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
+    fft_inR = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
+    fft_outR = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
     fft_smooth = (fftw_real*) calloc(max_fft_cache_size, sizeof(fftw_real));
     memset(fft_smooth, 0, max_fft_cache_size * sizeof(fftw_real)); // reset buffer to zero
     fft_delta = (float*) calloc(max_fft_cache_size, sizeof(float));
@@ -897,12 +902,18 @@ void analyzer_audio_module::params_changed() {
         _accuracy = pow(2, 7 + *params[param_analyzer_accuracy]);
         _acc_old = *params[param_analyzer_accuracy];
         // recreate fftw plan
+        if (fft_plan) rfftw_destroy_plan (fft_plan);
         fft_plan = rfftw_create_plan(_accuracy, FFTW_FORWARD, 0);
+        lintrans = -1;
     }
     if(*params[param_analyzer_hold] != _hold) {
         ____analyzer_hold_dirty = 1;
         _hold = *params[param_analyzer_hold];
     }
+    if(*params[param_analyzer_smoothing] != _smoothing) {
+        memset(fft_delta, 0, max_fft_cache_size * sizeof(float)); // reset buffer to zero
+        _smoothing = *params[param_analyzer_smoothing];
+    }
 }
 
 uint32_t analyzer_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
@@ -970,48 +981,70 @@ bool analyzer_audio_module::get_phase_graph(float ** _buffer, int *_length, int
     return false;
 }
 
-bool analyzer_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
+bool analyzer_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context, bool *bars, bool *boxes) const
 {
     if (!active or subindex > 1 or !*params[param_analyzer_display]
         or (subindex > 0 and !*params[param_analyzer_hold]))
+        // stop drawing
         return false;
-    float ret;
+
+    if(*params[param_analyzer_bars])
+        *bars = true;
+    else
+        *bars = false;
+    
+    bool fftdone = false; // if fft was renewed, this one is true
     double freq;
-    int _last = 0;
+    int iter = 0;
+    int _iter = 0;
+    int _param_speed = 16 - (int)*params[param_analyzer_speed];
     if(subindex == 0) {
-        ____analyzer_phase_was_drawn_here ++;
-        int _param_speed = 16 - (int)*params[param_analyzer_speed];
+        
         if(!((int)____analyzer_phase_was_drawn_here % _param_speed)) {
+            // seems we have to do a fft, so let's read the latest data from the
+            // buffer to send it to fft
             for(int i = 0; i < _accuracy; i++) {
+                // go to the right position back in time according to accuracy
+                // settings and cycling in the main buffer
                 int _fpos = (fpos - _accuracy * 2 + (i * 2)) % max_fft_buffer_size;
                 if(_fpos < 0)
                     _fpos = max_fft_buffer_size + _fpos;
                 float L = fft_buffer[_fpos];
                 float R = fft_buffer[_fpos + 1];
                 
-                // get the right value for calculations
+                // get the right value for analyzer calculations
                 fftw_real val;
+                
+                //if phase by frequency is active, we need to
+                //compute two FFT's, so store left and right channel
+                fftw_real valL;
+                fftw_real valR;
+                
                 switch((int)*params[param_analyzer_mode]) {
                     case 0:
+                    default:
                         // average
                         val = (L + R) / 2;
                         break;
                     case 1:
-                        // maximum
-                        val = std::max(L, R);
-                        break;
-                    case 2:
                         // left channel
                         val = L;
                         break;
-                    case 3:
+                    case 2:
                         // right channel
                         val = R;
                         break;
                 }
+                // store value in analyzer buffer
                 fft_in[i] = (fftw_real)val;
+                if(*params[param_analyzer_correction] == 3) {
+                    valL = L;
+                    valR = R;
+                    fft_inL[i] = valL;
+                    fft_inR[i] = valR;
+                }
                 
-                // fill smoothing buffer
+                // fill smoothing & falling buffer
                 if(*params[param_analyzer_smoothing] == 1.f)
                     fft_smooth[i] = fabs(fft_out[i]);
                 if(*params[param_analyzer_smoothing] == 0.f and fft_smooth[i] < fabs(fft_out[i])) {
@@ -1030,64 +1063,154 @@ bool analyzer_audio_module::get_graph(int index, int subindex, float *data, int
                     fft_hold[i] = fabs(fft_out[i]);
                 }
             }
+            // run fft
+            // this takes our latest buffer and returns an array with
+            // non-normalized
             rfftw_one(fft_plan, fft_in, fft_out);
+            //run fft for left and right channel while in "phase by freq" mode
+            if(*params[param_analyzer_correction] == 3) {
+            rfftw_one(fft_plan, fft_inL, fft_outL);
+            rfftw_one(fft_plan, fft_inR, fft_outR);
+            }
+            // ...and reset some values
             ____analyzer_hold_dirty = 0;
             ____analyzer_smooth_dirty = 1;
+            fftdone = true;       
         }
-        for (int i = 0; i < points; i++)
-        {
-            ret = 1.f;
-            freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
-            int __last = floor(freq * (float)_accuracy / (float)srate);
-            if(!i or __last > _last) {
-                int iter;
-                if(!i) {
-                    iter = 0;
-                } else {
-                    _last = __last;
-                    iter = _last;
-                }
-                if(____analyzer_smooth_dirty and *params[param_analyzer_smoothing] == 1.f) {
-                    fft_delta[iter] = (fabs(fft_out[iter]) - fft_smooth[iter]) / _param_speed;
-                }
-                if(*params[param_analyzer_smoothing] == 1.f) {
-                    fft_smooth[iter] += fft_delta[iter];
-                }
-                if(*params[param_analyzer_smoothing] == 0.f) {
-                    fft_smooth[iter] += fft_delta[iter];
-                    fft_delta[iter] /= 1.01f;
-                }
-                if (*params[param_analyzer_freeze] > 0.f)
-                    ret =  dB_grid(fabs(fft_freeze[iter]) / 800.f);
-                else if(*params[param_analyzer_smoothing] < 2.f) {
-                    ret =  dB_grid(fabs(fft_smooth[iter]) / 800.f);
-                    fft_freeze[iter] = fft_smooth[iter];
-                } else {
-                    ret =  dB_grid(fabs(fft_out[iter]) / 800.f);
-                    fft_freeze[iter] = fft_out[iter];
+        ____analyzer_phase_was_drawn_here ++;
+    }
+    if (lintrans < 0) {
+        // accuracy was changed so we have to recalc linear transition
+        int _lintrans = (int)((float)points * log((20.f + (float)srate / (float)_accuracy) / 20.f) / log(1000.f));  
+        lintrans = (int)(_lintrans + points % _lintrans / floor(points / _lintrans));
+    } 
+    for (int i = 0; i <= points; i++)
+    {
+        float lastoutL = 0.f;
+        float lastoutR = 0.f;
+        // cycle through the points to draw
+        freq = 20.f * pow (1000.f, (float)i / points); //1000=20000/1000
+        if(*params[param_analyzer_linear]) {
+            // we have linear view enabled
+            if((i % lintrans == 0 and points - i > lintrans) or i == points - 1)
+                _iter = std::max(1, (int)floor(freq * (float)_accuracy / (float)srate));
+        } else {
+            // we have logarithmic view enabled
+            _iter = std::max(1, (int)floor(freq * (float)_accuracy / (float)srate));
+        }
+        if(_iter > iter) {
+            // we have to draw a value
+            if(fftdone and i) {
+                int n = 0;
+                float var1 = 0.f;
+                float var2 = 0.f;
+                
+                switch((int)*params[param_analyzer_correction]) {
+                    case 0:
+                        // nothing to do
+                    break;
+                    case 1:
+                        if(fftdone and i) {
+                            // if fft was renewed, recalc the absolute values if frequencies
+                            // are skipped
+                            for(int j = iter + 1; j < _iter; j++) {
+                                fft_out[_iter] += fabs(fft_out[j]);
+                            }
+                        }
+                    break;
+                    case 2:
+                        for(int k = 0; k < std::max(10 , std::min(400 , (int)(2.f*(float)((_iter - iter))))); k++) {
+                            if(_iter - k > 0) {
+                                var1 += fabs(fft_out[_iter - k]);
+                                n++;
+                            }
+                            if(k != 0) var1 += fabs(fft_out[_iter + k]);
+                            else if(i) var1 += fabs(lastoutL);
+                            else var1 += fabs(fft_out[_iter]);
+                            n++;
+                        }
+                        lastoutL = fft_out[_iter];
+                        fft_out[_iter] = std::max(n * fabs(fft_out[_iter]) - var1 , 1e-20);
+                    break;
+                    case 3:
+//                        for(int k = 0; k < std::max(10 , std::min(400 , (int)(2.f*(float)((_iter - iter))))); k++) {
+//                            if(_iter - k > 0) {
+//                                var1 += fabs(fft_outL[_iter - k]);
+//                                var2 += fabs(fft_outR[_iter - k]);
+//                                n++;
+//                            }
+//                            if(k != 0) {
+//                                var1 += fabs(fft_out[_iter + k]);
+//                                var2 += fabs(fft_out[_iter + k]);
+//                            }
+//                            else if(i) {
+//                                var1 += fabs(lastoutL);
+//                                var2 += fabs(lastoutR);
+//                            }
+//                            else {
+//                                var1 += fabs(fft_out[_iter]);
+//                                var2 += fabs(fft_out[_iter]);
+//                            }
+//                            n++;
+//                        }
+                        float diff_fft;
+                        diff_fft = fabs(fft_outL[_iter]) - fabs(fft_out[_iter]);
+                        printf("i %5d diff %.4f\n", i, diff_fft);
+                        fft_out[_iter] = _accuracy / 2.f * (((float)n +1.f) * (1.f + diff_fft));
+//                        lastoutL = fft_outL[_iter];
+//                        lastoutR = fft_outR[_iter];
+                    break;
+                 }
+            }
+            iter = _iter;
+            float val = 0.f;
+            *boxes = false;
+            if (*params[param_analyzer_freeze]) {
+                // freeze enabled
+                val = fft_freeze[iter];
+            } else if (subindex == 1) {
+                // we draw the hold buffer
+                *boxes = true;
+                val = fft_hold[iter];
+            } else {
+                // we draw normally (no freeze)
+                switch((int)*params[param_analyzer_smoothing]) {
+                    case 0:
+                        // falling
+                        fft_smooth[iter] += fft_delta[iter];
+                        fft_delta[iter] /= 1.01f;
+                        val = fft_smooth[iter];
+                        break;
+                    case 1:
+                        // smoothing
+                        if(____analyzer_smooth_dirty) {
+                            // rebuild delta values
+                            fft_delta[iter] = (fabs(fft_out[iter]) - fft_smooth[iter]) / _param_speed;
+                        }
+                        fft_smooth[iter] += fft_delta[iter];
+                        val = fft_smooth[iter];
+                        break;
+                    case 2:
+                        // off
+                        val = fft_out[iter];
+                        break;
                 }
-            } else
-                ret = INFINITY;
-            data[i] = ret;
-            
+                // fill freeze buffer
+                fft_freeze[iter] = val;
+            }
+            data[i] = dB_grid(fabs(val) / _accuracy * 2.f);
+        } //else if(*params[param_analyzer_correction] == 2) {
+          //  data[i] = dB_grid(fabs(1e-20) / _accuracy * 2.f);
+          //  } 
+        else {
+            data[i] = INFINITY;
         }
-        ____analyzer_smooth_dirty = 0;
-        return true;
-    } else {
+    }
+    ____analyzer_smooth_dirty = 0;
+    if(subindex == 1) {
+        // subtle hold line
         context->set_source_rgba(0.35, 0.4, 0.2, 0.2);
-        for (int i = 0; i < points; i++)
-        {
-            freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
-            int __last = floor(freq * (float)_accuracy / (float)srate);
-            if(!i) {
-                ret =  dB_grid(fft_hold[0] / 800.f);
-            } else if(__last > _last) {
-                _last = __last;
-                ret =  dB_grid(fft_hold[_last] / 800.f);
-            } else
-                ret = INFINITY;
-            data[i] = ret;
-        }
     }
     return true;
 }
+

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list