annotate data/model/WaveformOversampler.cpp @ 1784:4eac4bf35b45

More graceful handling of failure to construct FFT models in the case where the source model has already been deleted before this occurs
author Chris Cannam
date Tue, 17 Sep 2019 11:21:33 +0100
parents 074b860a7828
children
rev   line source
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