diff base/ColumnOp.h @ 1193:927d329252bf spectrogram-minor-refactor

Convert ColumnNormalization to an enum class, and separate out normalize-visible
author Chris Cannam
date Thu, 14 Jul 2016 16:12:05 +0100
parents f6998e304b36
children c118d2022ffa
line wrap: on
line diff
--- a/base/ColumnOp.h	Thu Jul 14 14:49:04 2016 +0100
+++ b/base/ColumnOp.h	Thu Jul 14 16:12:05 2016 +0100
@@ -21,6 +21,25 @@
 #include <cmath>
 
 /**
+ * Display normalization types for columns in e.g. grid plots.
+ *
+ * Max1 means to normalize to max value = 1.0.
+ * Sum1 means to normalize to sum of values = 1.0.
+ *
+ * Hybrid means normalize to max = 1.0 and then multiply by
+ * log10 of the max value, to retain some difference between
+ * levels of neighbouring columns.
+ *
+ * Area normalization is handled separately.
+ */
+enum class ColumnNormalization {
+    None,
+    Max1,
+    Sum1,
+    Hybrid
+};
+
+/**
  * Class containing static functions for simple operations on data
  * columns, for use by display layers.
  */
@@ -33,25 +52,6 @@
     typedef std::vector<float> Column;
 
     /**
-     * Normalization types.
-     *
-     * NormalizeColumns means to normalize to max value = 1.
-     * NormalizeHybrid means normalize to max = 1 and then multiply by
-     * log10 of the max value, to retain some difference between
-     * levels of neighbouring columns.
-     *
-     * NormalizeVisibleArea is ignored here and is included only so as
-     * to match the set of normalization options historically provided
-     * in the SV spectrogram layer.
-     */
-    enum Normalization {
-        NoNormalization,
-        NormalizeColumns,
-        NormalizeVisibleArea,
-        NormalizeHybrid
-    };
-
-    /**
      * Scale an FFT output by half the FFT size.
      */
     static Column fftScale(const Column &in, int fftSize) {
@@ -99,35 +99,47 @@
      * Return a column normalized from the input column according to
      * the given normalization scheme.
      */
-    static Column normalize(const Column &in, Normalization n) {
+    static Column normalize(const Column &in, ColumnNormalization n) {
 
-	if (n == NoNormalization || n == NormalizeVisibleArea) {
-	    return in;
-	}
-	
-	float max = *max_element(in.begin(), in.end());
-
-	if (n == NormalizeColumns && max == 0.f) {
+	if (n == ColumnNormalization::None) {
 	    return in;
 	}
 
-	if (n == NormalizeHybrid && max <= 0.f) {
-	    return in;
-	}
+        float scale = 1.f;
+        
+        if (n == ColumnNormalization::Sum1) {
+
+            float sum = 0.f;
+
+            for (auto v: in) {
+                sum += v;
+            }
+
+            if (sum != 0.f) {
+                scale = 1.f / sum;
+            }
+        } else {
+        
+            float max = *max_element(in.begin(), in.end());
+
+            if (n == ColumnNormalization::Max1) {
+                if (max != 0.f) {
+                    scale = 1.f / max;
+                }
+            } else if (n == ColumnNormalization::Hybrid) {
+                if (max > 0.f) {
+                    scale = log10f(max + 1.f) / max;
+                }
+            }
+        }
     
 	std::vector<float> out;
 	out.reserve(in.size());
 
-	float scale;
-	if (n == NormalizeHybrid) {
-	    scale = log10f(max + 1.f) / max;
-	} else {
-	    scale = 1.f / max;
-	}
-    
 	for (auto v: in) {
 	    out.push_back(v * scale);
 	}
+        
 	return out;
     }