Chris@1536
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1536
|
2
|
Chris@1536
|
3 /*
|
Chris@1536
|
4 Sonic Visualiser
|
Chris@1536
|
5 An audio file viewer and annotation editor.
|
Chris@1536
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1536
|
7
|
Chris@1536
|
8 This program is free software; you can redistribute it and/or
|
Chris@1536
|
9 modify it under the terms of the GNU General Public License as
|
Chris@1536
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@1536
|
11 License, or (at your option) any later version. See the file
|
Chris@1536
|
12 COPYING included with this distribution for more information.
|
Chris@1536
|
13 */
|
Chris@1536
|
14
|
Chris@1536
|
15 #include "WaveformOversampler.h"
|
Chris@1536
|
16
|
Chris@1544
|
17 #include "base/Profiler.h"
|
Chris@1544
|
18
|
Chris@1536
|
19 #include "data/model/DenseTimeValueModel.h"
|
Chris@1536
|
20
|
Chris@1536
|
21 floatvec_t
|
Chris@1745
|
22 WaveformOversampler::getOversampledData(const DenseTimeValueModel &source,
|
Chris@1536
|
23 int channel,
|
Chris@1536
|
24 sv_frame_t sourceStartFrame,
|
Chris@1536
|
25 sv_frame_t sourceFrameCount,
|
Chris@1536
|
26 int oversampleBy)
|
Chris@1536
|
27 {
|
Chris@1544
|
28 Profiler profiler("WaveformOversampler::getOversampledData");
|
Chris@1544
|
29
|
Chris@1536
|
30 // Oversampled at a fixed ratio of m_filterRatio
|
Chris@1536
|
31 floatvec_t fixedRatio = getFixedRatioData(source, channel,
|
Chris@1536
|
32 sourceStartFrame,
|
Chris@1536
|
33 sourceFrameCount);
|
Chris@1536
|
34 sv_frame_t fixedCount = fixedRatio.size();
|
Chris@1536
|
35 sv_frame_t targetCount = (fixedCount / m_filterRatio) * oversampleBy;
|
Chris@1536
|
36
|
Chris@1536
|
37 // And apply linear interpolation to the desired factor
|
Chris@1536
|
38
|
Chris@1536
|
39 floatvec_t result(targetCount, 0.f);
|
Chris@1536
|
40
|
Chris@1536
|
41 for (int i = 0; i < targetCount; ++i) {
|
Chris@1536
|
42 double pos = (double(i) / oversampleBy) * m_filterRatio;
|
Chris@1536
|
43 double diff = pos - floor(pos);
|
Chris@1536
|
44 int ix = int(floor(pos));
|
Chris@1538
|
45 double interpolated = (1.0 - diff) * fixedRatio[ix];
|
Chris@1536
|
46 if (in_range_for(fixedRatio, ix + 1)) {
|
Chris@1536
|
47 interpolated += diff * fixedRatio[ix + 1];
|
Chris@1536
|
48 }
|
Chris@1538
|
49 result[i] = float(interpolated);
|
Chris@1536
|
50 }
|
Chris@1536
|
51
|
Chris@1536
|
52 return result;
|
Chris@1536
|
53 }
|
Chris@1536
|
54
|
Chris@1536
|
55 floatvec_t
|
Chris@1745
|
56 WaveformOversampler::getFixedRatioData(const DenseTimeValueModel &source,
|
Chris@1536
|
57 int channel,
|
Chris@1536
|
58 sv_frame_t sourceStartFrame,
|
Chris@1536
|
59 sv_frame_t sourceFrameCount)
|
Chris@1536
|
60 {
|
Chris@1544
|
61 Profiler profiler("WaveformOversampler::getFixedRatioData");
|
Chris@1544
|
62
|
Chris@1745
|
63 sv_frame_t sourceLength = source.getEndFrame();
|
Chris@1536
|
64
|
Chris@1536
|
65 if (sourceStartFrame + sourceFrameCount > sourceLength) {
|
Chris@1536
|
66 sourceFrameCount = sourceLength - sourceStartFrame;
|
Chris@1536
|
67 if (sourceFrameCount <= 0) return {};
|
Chris@1536
|
68 }
|
Chris@1536
|
69
|
Chris@1536
|
70 sv_frame_t targetFrameCount = sourceFrameCount * m_filterRatio;
|
Chris@1536
|
71
|
Chris@1536
|
72 sv_frame_t filterLength = m_filter.size(); // NB this is known to be odd
|
Chris@1536
|
73 sv_frame_t filterTailOut = (filterLength - 1) / 2;
|
Chris@1538
|
74 sv_frame_t filterTailIn = filterTailOut / m_filterRatio;
|
Chris@1536
|
75
|
Chris@1536
|
76 floatvec_t oversampled(targetFrameCount, 0.f);
|
Chris@1536
|
77
|
Chris@1536
|
78 sv_frame_t i0 = sourceStartFrame - filterTailIn;
|
Chris@1536
|
79 if (i0 < 0) {
|
Chris@1536
|
80 i0 = 0;
|
Chris@1536
|
81 }
|
Chris@1536
|
82 sv_frame_t i1 = sourceStartFrame + sourceFrameCount + filterTailIn;
|
Chris@1536
|
83 if (i1 > sourceLength) {
|
Chris@1536
|
84 i1 = sourceLength;
|
Chris@1536
|
85 }
|
Chris@1538
|
86
|
Chris@1745
|
87 floatvec_t sourceData = source.getData(channel, i0, i1 - i0);
|
Chris@1536
|
88
|
Chris@1536
|
89 for (sv_frame_t i = i0; i < i1; ++i) {
|
Chris@1536
|
90 float v = sourceData[i - i0];
|
Chris@1536
|
91 sv_frame_t outOffset =
|
Chris@1536
|
92 (i - sourceStartFrame) * m_filterRatio - filterTailOut;
|
Chris@1536
|
93 for (sv_frame_t j = 0; j < filterLength; ++j) {
|
Chris@1536
|
94 sv_frame_t outIndex = outOffset + j;
|
Chris@1536
|
95 if (outIndex < 0 || outIndex >= targetFrameCount) {
|
Chris@1536
|
96 continue;
|
Chris@1536
|
97 }
|
Chris@1536
|
98 oversampled[outIndex] += v * m_filter[j];
|
Chris@1536
|
99 }
|
Chris@1536
|
100 }
|
Chris@1536
|
101
|
Chris@1536
|
102 return oversampled;
|
Chris@1536
|
103 }
|
Chris@1536
|
104
|
Chris@1536
|
105 int
|
Chris@1536
|
106 WaveformOversampler::m_filterRatio = 8;
|
Chris@1536
|
107
|
Chris@1536
|
108 /// Precalculated windowed sinc FIR filter for oversampling ratio of 8
|
Chris@1536
|
109 floatvec_t
|
Chris@1536
|
110 WaveformOversampler::m_filter {
|
Chris@1536
|
111 2.0171043153063023E-4, 2.887198196326776E-4,
|
Chris@1536
|
112 3.410439309101285E-4, 3.4267123819805857E-4,
|
Chris@1536
|
113 2.843462511901066E-4, 1.6636986363946504E-4,
|
Chris@1536
|
114 -4.5940658605786285E-18, -1.9299665002484582E-4,
|
Chris@1536
|
115 -3.8279951732549946E-4, -5.357990649609105E-4,
|
Chris@1536
|
116 -6.201170748425957E-4, -6.11531555444137E-4,
|
Chris@1536
|
117 -4.987822892899791E-4, -2.872272251922189E-4,
|
Chris@1536
|
118 -7.822991648518709E-19, 3.2382854144162815E-4,
|
Chris@1536
|
119 6.341027017666046E-4, 8.769331519465396E-4,
|
Chris@1536
|
120 0.001003535186382615, 9.791732608026272E-4,
|
Chris@1536
|
121 7.906678783612421E-4, 4.5101220009813206E-4,
|
Chris@1536
|
122 -3.039648514978356E-18, -4.996532051508215E-4,
|
Chris@1536
|
123 -9.704877518513666E-4, -0.0013318083550190923,
|
Chris@1536
|
124 -0.0015128911871247466, -0.0014658111457301016,
|
Chris@1536
|
125 -0.0011756800671747431, -6.663214707558645E-4,
|
Chris@1536
|
126 1.0713650598357415E-17, 7.292959363289514E-4,
|
Chris@1536
|
127 0.0014084768982220279, 0.0019222969998680237,
|
Chris@1536
|
128 0.0021721723797956524, 0.0020938999751673173,
|
Chris@1536
|
129 0.0016712330766289326, 9.427050283841188E-4,
|
Chris@1536
|
130 -5.656965938821965E-18, -0.0010225643654040554,
|
Chris@1536
|
131 -0.001966437013513757, -0.002672722670880038,
|
Chris@1536
|
132 -0.00300806671037164, -0.00288843624179131,
|
Chris@1536
|
133 -0.0022967244980623574, -0.0012908081494665458,
|
Chris@1536
|
134 -5.1499690577098E-18, 0.0013904094522721,
|
Chris@1536
|
135 0.0026648961861419334, 0.0036103002009868065,
|
Chris@1536
|
136 0.004050469159316014, 0.0038774554290217484,
|
Chris@1536
|
137 0.0030739396559265075, 0.001722603817632299,
|
Chris@1536
|
138 -9.130030250503607E-18, -0.0018451873718735516,
|
Chris@1536
|
139 -0.0035270571169279162, -0.004765847116110058,
|
Chris@1536
|
140 -0.0053332982334767624, -0.005092831604550132,
|
Chris@1536
|
141 -0.00402770012894082, -0.0022517645624319594,
|
Chris@1536
|
142 3.2752446397299053E-17, 0.0024010765839506923,
|
Chris@1536
|
143 0.004579613038976446, 0.006174912111845945,
|
Chris@1536
|
144 0.00689578873526276, 0.006571541332393174,
|
Chris@1536
|
145 0.005186887306036285, 0.002894248521447605,
|
Chris@1536
|
146 -1.336645565990815E-17, -0.0030747336558684963,
|
Chris@1536
|
147 -0.0058540294958507235, -0.007879546416595632,
|
Chris@1536
|
148 -0.008784519668338507, -0.008357645279493864,
|
Chris@1536
|
149 -0.006586046547485615, -0.003669217725935383,
|
Chris@1536
|
150 -1.9348975378752276E-17, 0.0038863208094135626,
|
Chris@1536
|
151 0.007388553022623823, 0.009931080628244226,
|
Chris@1536
|
152 0.011056594746806033, 0.010505398026651453,
|
Chris@1536
|
153 0.008267906564613223, 0.00460048159140493,
|
Chris@1536
|
154 -1.816145184081109E-17, -0.004861124757802925,
|
Chris@1536
|
155 -0.009231379891669668, -0.012394511669674028,
|
Chris@1536
|
156 -0.01378467517229709, -0.013084177592430083,
|
Chris@1536
|
157 -0.010287380585427207, -0.00571879407588959,
|
Chris@1536
|
158 7.520535431851951E-17, 0.006032144534828161,
|
Chris@1536
|
159 0.011445734103106982, 0.015355551390625357,
|
Chris@1536
|
160 0.017065088242935025, 0.016186450815185452,
|
Chris@1536
|
161 0.012718051439340603, 0.0070655888687995785,
|
Chris@1536
|
162 -2.3209664144996714E-17, -0.007444328311482942,
|
Chris@1536
|
163 -0.01411821163125819, -0.018932253281654043,
|
Chris@1536
|
164 -0.02103125585328301, -0.019941019333653123,
|
Chris@1536
|
165 -0.015663002335303704, -0.008699245445932525,
|
Chris@1536
|
166 2.5712475624993567E-17, 0.009161748270723635,
|
Chris@1536
|
167 0.0173729814451255, 0.023294901939595228,
|
Chris@1536
|
168 0.02587678878709242, 0.02453592568963366,
|
Chris@1536
|
169 0.01927365323131565, 0.010706050935569809,
|
Chris@1536
|
170 -2.8133472199037193E-17, -0.011280308241551094,
|
Chris@1536
|
171 -0.02139710071477064, -0.02870170641615764,
|
Chris@1536
|
172 -0.031897218249350504, -0.030260140480986304,
|
Chris@1536
|
173 -0.023784294156618507, -0.013220449772289724,
|
Chris@1536
|
174 3.042099156841831E-17, 0.013951594368737923,
|
Chris@1536
|
175 0.0264884258371512, 0.03556693609945249,
|
Chris@1536
|
176 0.03957036852169639, 0.0375845888664677,
|
Chris@1536
|
177 0.029579845398822833, 0.016465167405787955,
|
Chris@1536
|
178 -3.2524514488155654E-17, -0.017431115375410273,
|
Chris@1536
|
179 -0.03315356952091943, -0.04460179422099746,
|
Chris@1536
|
180 -0.0497244634100025, -0.04733366619358394,
|
Chris@1536
|
181 -0.037341081614037944, -0.020838316594689998,
|
Chris@1536
|
182 3.439626695384943E-17, 0.022185914535618936,
|
Chris@1536
|
183 0.04232958202159685, 0.05713801867687856,
|
Chris@1536
|
184 0.06393033000280622, 0.06109191933191721,
|
Chris@1536
|
185 0.04839482380906132, 0.027127167584840003,
|
Chris@1536
|
186 -3.5992766927138734E-17, -0.029168755716052385,
|
Chris@1536
|
187 -0.055960213335110184, -0.07598693477350407,
|
Chris@1536
|
188 -0.08556575102599769, -0.08233350786406181,
|
Chris@1536
|
189 -0.06571046000158454, -0.03713224848702707,
|
Chris@1536
|
190 3.727625511036616E-17, 0.04066438975848791,
|
Chris@1536
|
191 0.07882920057770397, 0.10826166115536123,
|
Chris@1536
|
192 0.12343378955977465, 0.12040455825217859,
|
Chris@1536
|
193 0.09755344650130694, 0.056053367635801106,
|
Chris@1536
|
194 -3.8215953158245473E-17, -0.0638435745677513,
|
Chris@1536
|
195 -0.12667849902789644, -0.17861887575594584,
|
Chris@1536
|
196 -0.20985333136704623, -0.21188193950868073,
|
Chris@1536
|
197 -0.17867464086818077, -0.10760048593620072,
|
Chris@1536
|
198 3.8789099095340224E-17, 0.13868670259490817,
|
Chris@1536
|
199 0.29927055936918734, 0.46961864377510765,
|
Chris@1536
|
200 0.6358321371992203, 0.7836674214332147,
|
Chris@1536
|
201 0.9000377382311825, 0.9744199685311685,
|
Chris@1536
|
202 1.0000000000000004, 0.9744199685311685,
|
Chris@1536
|
203 0.9000377382311825, 0.7836674214332147,
|
Chris@1536
|
204 0.6358321371992203, 0.46961864377510765,
|
Chris@1536
|
205 0.29927055936918734, 0.13868670259490817,
|
Chris@1536
|
206 3.8789099095340224E-17, -0.10760048593620072,
|
Chris@1536
|
207 -0.17867464086818077, -0.21188193950868073,
|
Chris@1536
|
208 -0.20985333136704623, -0.17861887575594584,
|
Chris@1536
|
209 -0.12667849902789644, -0.0638435745677513,
|
Chris@1536
|
210 -3.8215953158245473E-17, 0.056053367635801106,
|
Chris@1536
|
211 0.09755344650130694, 0.12040455825217859,
|
Chris@1536
|
212 0.12343378955977465, 0.10826166115536123,
|
Chris@1536
|
213 0.07882920057770397, 0.04066438975848791,
|
Chris@1536
|
214 3.727625511036616E-17, -0.03713224848702707,
|
Chris@1536
|
215 -0.06571046000158454, -0.08233350786406181,
|
Chris@1536
|
216 -0.08556575102599769, -0.07598693477350407,
|
Chris@1536
|
217 -0.055960213335110184, -0.029168755716052385,
|
Chris@1536
|
218 -3.5992766927138734E-17, 0.027127167584840003,
|
Chris@1536
|
219 0.04839482380906132, 0.06109191933191721,
|
Chris@1536
|
220 0.06393033000280622, 0.05713801867687856,
|
Chris@1536
|
221 0.04232958202159685, 0.022185914535618936,
|
Chris@1536
|
222 3.439626695384943E-17, -0.020838316594689998,
|
Chris@1536
|
223 -0.037341081614037944, -0.04733366619358394,
|
Chris@1536
|
224 -0.0497244634100025, -0.04460179422099746,
|
Chris@1536
|
225 -0.03315356952091943, -0.017431115375410273,
|
Chris@1536
|
226 -3.2524514488155654E-17, 0.016465167405787955,
|
Chris@1536
|
227 0.029579845398822833, 0.0375845888664677,
|
Chris@1536
|
228 0.03957036852169639, 0.03556693609945249,
|
Chris@1536
|
229 0.0264884258371512, 0.013951594368737923,
|
Chris@1536
|
230 3.042099156841831E-17, -0.013220449772289724,
|
Chris@1536
|
231 -0.023784294156618507, -0.030260140480986304,
|
Chris@1536
|
232 -0.031897218249350504, -0.02870170641615764,
|
Chris@1536
|
233 -0.02139710071477064, -0.011280308241551094,
|
Chris@1536
|
234 -2.8133472199037193E-17, 0.010706050935569809,
|
Chris@1536
|
235 0.01927365323131565, 0.02453592568963366,
|
Chris@1536
|
236 0.02587678878709242, 0.023294901939595228,
|
Chris@1536
|
237 0.0173729814451255, 0.009161748270723635,
|
Chris@1536
|
238 2.5712475624993567E-17, -0.008699245445932525,
|
Chris@1536
|
239 -0.015663002335303704, -0.019941019333653123,
|
Chris@1536
|
240 -0.02103125585328301, -0.018932253281654043,
|
Chris@1536
|
241 -0.01411821163125819, -0.007444328311482942,
|
Chris@1536
|
242 -2.3209664144996714E-17, 0.0070655888687995785,
|
Chris@1536
|
243 0.012718051439340603, 0.016186450815185452,
|
Chris@1536
|
244 0.017065088242935025, 0.015355551390625357,
|
Chris@1536
|
245 0.011445734103106982, 0.006032144534828161,
|
Chris@1536
|
246 7.520535431851951E-17, -0.00571879407588959,
|
Chris@1536
|
247 -0.010287380585427207, -0.013084177592430083,
|
Chris@1536
|
248 -0.01378467517229709, -0.012394511669674028,
|
Chris@1536
|
249 -0.009231379891669668, -0.004861124757802925,
|
Chris@1536
|
250 -1.816145184081109E-17, 0.00460048159140493,
|
Chris@1536
|
251 0.008267906564613223, 0.010505398026651453,
|
Chris@1536
|
252 0.011056594746806033, 0.009931080628244226,
|
Chris@1536
|
253 0.007388553022623823, 0.0038863208094135626,
|
Chris@1536
|
254 -1.9348975378752276E-17, -0.003669217725935383,
|
Chris@1536
|
255 -0.006586046547485615, -0.008357645279493864,
|
Chris@1536
|
256 -0.008784519668338507, -0.007879546416595632,
|
Chris@1536
|
257 -0.0058540294958507235, -0.0030747336558684963,
|
Chris@1536
|
258 -1.336645565990815E-17, 0.002894248521447605,
|
Chris@1536
|
259 0.005186887306036285, 0.006571541332393174,
|
Chris@1536
|
260 0.00689578873526276, 0.006174912111845945,
|
Chris@1536
|
261 0.004579613038976446, 0.0024010765839506923,
|
Chris@1536
|
262 3.2752446397299053E-17, -0.0022517645624319594,
|
Chris@1536
|
263 -0.00402770012894082, -0.005092831604550132,
|
Chris@1536
|
264 -0.0053332982334767624, -0.004765847116110058,
|
Chris@1536
|
265 -0.0035270571169279162, -0.0018451873718735516,
|
Chris@1536
|
266 -9.130030250503607E-18, 0.001722603817632299,
|
Chris@1536
|
267 0.0030739396559265075, 0.0038774554290217484,
|
Chris@1536
|
268 0.004050469159316014, 0.0036103002009868065,
|
Chris@1536
|
269 0.0026648961861419334, 0.0013904094522721,
|
Chris@1536
|
270 -5.1499690577098E-18, -0.0012908081494665458,
|
Chris@1536
|
271 -0.0022967244980623574, -0.00288843624179131,
|
Chris@1536
|
272 -0.00300806671037164, -0.002672722670880038,
|
Chris@1536
|
273 -0.001966437013513757, -0.0010225643654040554,
|
Chris@1536
|
274 -5.656965938821965E-18, 9.427050283841188E-4,
|
Chris@1536
|
275 0.0016712330766289326, 0.0020938999751673173,
|
Chris@1536
|
276 0.0021721723797956524, 0.0019222969998680237,
|
Chris@1536
|
277 0.0014084768982220279, 7.292959363289514E-4,
|
Chris@1536
|
278 1.0713650598357415E-17, -6.663214707558645E-4,
|
Chris@1536
|
279 -0.0011756800671747431, -0.0014658111457301016,
|
Chris@1536
|
280 -0.0015128911871247466, -0.0013318083550190923,
|
Chris@1536
|
281 -9.704877518513666E-4, -4.996532051508215E-4,
|
Chris@1536
|
282 -3.039648514978356E-18, 4.5101220009813206E-4,
|
Chris@1536
|
283 7.906678783612421E-4, 9.791732608026272E-4,
|
Chris@1536
|
284 0.001003535186382615, 8.769331519465396E-4,
|
Chris@1536
|
285 6.341027017666046E-4, 3.2382854144162815E-4,
|
Chris@1536
|
286 -7.822991648518709E-19, -2.872272251922189E-4,
|
Chris@1536
|
287 -4.987822892899791E-4, -6.11531555444137E-4,
|
Chris@1536
|
288 -6.201170748425957E-4, -5.357990649609105E-4,
|
Chris@1536
|
289 -3.8279951732549946E-4, -1.9299665002484582E-4,
|
Chris@1536
|
290 -4.5940658605786285E-18, 1.6636986363946504E-4,
|
Chris@1536
|
291 2.843462511901066E-4, 3.4267123819805857E-4,
|
Chris@1536
|
292 3.410439309101285E-4, 2.887198196326776E-4,
|
Chris@1536
|
293 2.0171043153063023E-4
|
Chris@1536
|
294 };
|
Chris@1536
|
295
|