comparison base/ColumnOp.cpp @ 1267:1d8418cca63a 3.0-integration

Further column op tests and fixes
author Chris Cannam
date Thu, 17 Nov 2016 14:46:03 +0000
parents
children 2f468f43c02c
comparison
equal deleted inserted replaced
1266:dd190086db73 1267:1d8418cca63a
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006-2016 Chris Cannam and QMUL.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "ColumnOp.h"
17
18 #include <cmath>
19 #include <algorithm>
20 #include <iostream>
21
22 using namespace std;
23
24 ColumnOp::Column
25 ColumnOp::fftScale(const Column &in, int fftSize)
26 {
27 return applyGain(in, 2.0 / fftSize);
28 }
29
30 ColumnOp::Column
31 ColumnOp::peakPick(const Column &in)
32 {
33 vector<float> out(in.size(), 0.f);
34
35 for (int i = 0; in_range_for(in, i); ++i) {
36 if (isPeak(in, i)) {
37 out[i] = in[i];
38 }
39 }
40
41 return out;
42 }
43
44 ColumnOp::Column
45 ColumnOp::normalize(const Column &in, ColumnNormalization n) {
46
47 if (n == ColumnNormalization::None || in.empty()) {
48 return in;
49 }
50
51 float scale = 1.f;
52
53 if (n == ColumnNormalization::Sum1) {
54
55 float sum = 0.f;
56
57 for (auto v: in) {
58 sum += fabsf(v);
59 }
60
61 if (sum != 0.f) {
62 scale = 1.f / sum;
63 }
64
65 } else {
66
67 float max = 0.f;
68
69 for (auto v: in) {
70 v = fabsf(v);
71 if (v > max) {
72 max = v;
73 }
74 }
75
76 if (n == ColumnNormalization::Max1) {
77 if (max != 0.f) {
78 scale = 1.f / max;
79 }
80 } else if (n == ColumnNormalization::Hybrid) {
81 if (max > 0.f) {
82 scale = log10f(max + 1.f) / max;
83 }
84 }
85 }
86
87 return applyGain(in, scale);
88 }
89
90 ColumnOp::Column
91 ColumnOp::distribute(const Column &in,
92 int h,
93 const vector<double> &binfory,
94 int minbin,
95 bool interpolate)
96 {
97 vector<float> out(h, 0.f);
98 int bins = int(in.size());
99
100 for (int y = 0; y < h; ++y) {
101
102 if (interpolate && h > bins) {
103
104 double sy = binfory[y] - minbin - 0.5;
105 double syf = floor(sy);
106
107 int mainbin = int(syf);
108 int other = mainbin;
109 if (sy > syf) {
110 other = mainbin + 1;
111 } else if (sy < syf) {
112 other = mainbin - 1;
113 }
114
115 if (mainbin < 0) {
116 mainbin = 0;
117 }
118 if (mainbin >= bins) {
119 mainbin = bins - 1;
120 }
121
122 if (other < 0) {
123 other = 0;
124 }
125 if (other >= bins) {
126 other = bins - 1;
127 }
128
129 double prop = 1.0 - fabs(sy - syf);
130
131 double v0 = in[mainbin];
132 double v1 = in[other];
133
134 out[y] = float(prop * v0 + (1.0 - prop) * v1);
135
136 } else {
137
138 double sy0 = binfory[y] - minbin;
139
140 double sy1;
141 if (y+1 < h) {
142 sy1 = binfory[y+1] - minbin;
143 } else {
144 sy1 = bins;
145 }
146
147 int by0 = int(sy0 + 0.0001);
148 int by1 = int(sy1 + 0.0001);
149
150 for (int bin = by0; bin == by0 || bin < by1; ++bin) {
151
152 float value = in[bin];
153
154 if (bin == by0 || value > out[y]) {
155 out[y] = value;
156 }
157 }
158 }
159 }
160
161 return out;
162 }