comparison 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
comparison
equal deleted inserted replaced
1192:9884efa1f88a 1193:927d329252bf
19 #include "BaseTypes.h" 19 #include "BaseTypes.h"
20 20
21 #include <cmath> 21 #include <cmath>
22 22
23 /** 23 /**
24 * Display normalization types for columns in e.g. grid plots.
25 *
26 * Max1 means to normalize to max value = 1.0.
27 * Sum1 means to normalize to sum of values = 1.0.
28 *
29 * Hybrid means normalize to max = 1.0 and then multiply by
30 * log10 of the max value, to retain some difference between
31 * levels of neighbouring columns.
32 *
33 * Area normalization is handled separately.
34 */
35 enum class ColumnNormalization {
36 None,
37 Max1,
38 Sum1,
39 Hybrid
40 };
41
42 /**
24 * Class containing static functions for simple operations on data 43 * Class containing static functions for simple operations on data
25 * columns, for use by display layers. 44 * columns, for use by display layers.
26 */ 45 */
27 class ColumnOp 46 class ColumnOp
28 { 47 {
31 * Column type. 50 * Column type.
32 */ 51 */
33 typedef std::vector<float> Column; 52 typedef std::vector<float> Column;
34 53
35 /** 54 /**
36 * Normalization types.
37 *
38 * NormalizeColumns means to normalize to max value = 1.
39 * NormalizeHybrid means normalize to max = 1 and then multiply by
40 * log10 of the max value, to retain some difference between
41 * levels of neighbouring columns.
42 *
43 * NormalizeVisibleArea is ignored here and is included only so as
44 * to match the set of normalization options historically provided
45 * in the SV spectrogram layer.
46 */
47 enum Normalization {
48 NoNormalization,
49 NormalizeColumns,
50 NormalizeVisibleArea,
51 NormalizeHybrid
52 };
53
54 /**
55 * Scale an FFT output by half the FFT size. 55 * Scale an FFT output by half the FFT size.
56 */ 56 */
57 static Column fftScale(const Column &in, int fftSize) { 57 static Column fftScale(const Column &in, int fftSize) {
58 58
59 Column out; 59 Column out;
97 97
98 /** 98 /**
99 * Return a column normalized from the input column according to 99 * Return a column normalized from the input column according to
100 * the given normalization scheme. 100 * the given normalization scheme.
101 */ 101 */
102 static Column normalize(const Column &in, Normalization n) { 102 static Column normalize(const Column &in, ColumnNormalization n) {
103 103
104 if (n == NoNormalization || n == NormalizeVisibleArea) { 104 if (n == ColumnNormalization::None) {
105 return in; 105 return in;
106 } 106 }
107 107
108 float max = *max_element(in.begin(), in.end()); 108 float scale = 1.f;
109 109
110 if (n == NormalizeColumns && max == 0.f) { 110 if (n == ColumnNormalization::Sum1) {
111 return in; 111
112 } 112 float sum = 0.f;
113 113
114 if (n == NormalizeHybrid && max <= 0.f) { 114 for (auto v: in) {
115 return in; 115 sum += v;
116 } 116 }
117
118 if (sum != 0.f) {
119 scale = 1.f / sum;
120 }
121 } else {
122
123 float max = *max_element(in.begin(), in.end());
124
125 if (n == ColumnNormalization::Max1) {
126 if (max != 0.f) {
127 scale = 1.f / max;
128 }
129 } else if (n == ColumnNormalization::Hybrid) {
130 if (max > 0.f) {
131 scale = log10f(max + 1.f) / max;
132 }
133 }
134 }
117 135
118 std::vector<float> out; 136 std::vector<float> out;
119 out.reserve(in.size()); 137 out.reserve(in.size());
120 138
121 float scale;
122 if (n == NormalizeHybrid) {
123 scale = log10f(max + 1.f) / max;
124 } else {
125 scale = 1.f / max;
126 }
127
128 for (auto v: in) { 139 for (auto v: in) {
129 out.push_back(v * scale); 140 out.push_back(v * scale);
130 } 141 }
142
131 return out; 143 return out;
132 } 144 }
133 145
134 /** 146 /**
135 * Scale the given column using the given gain multiplier. 147 * Scale the given column using the given gain multiplier.