comparison data/model/FFTModel.cpp @ 1744:b92bdcd4954b by-id

Update FFT model to ById
author Chris Cannam
date Tue, 02 Jul 2019 11:49:28 +0100
parents d08b560102a1
children 6d09d68165a4
comparison
equal deleted inserted replaced
1743:7001b9570e37 1744:b92bdcd4954b
30 using namespace std; 30 using namespace std;
31 31
32 static HitCount inSmallCache("FFTModel: Small FFT cache"); 32 static HitCount inSmallCache("FFTModel: Small FFT cache");
33 static HitCount inSourceCache("FFTModel: Source data cache"); 33 static HitCount inSourceCache("FFTModel: Source data cache");
34 34
35 FFTModel::FFTModel(const DenseTimeValueModel *model, 35 FFTModel::FFTModel(ModelId modelId,
36 int channel, 36 int channel,
37 WindowType windowType, 37 WindowType windowType,
38 int windowSize, 38 int windowSize,
39 int windowIncrement, 39 int windowIncrement,
40 int fftSize) : 40 int fftSize) :
41 m_model(model), 41 m_model(modelId),
42 m_channel(channel), 42 m_channel(channel),
43 m_windowType(windowType), 43 m_windowType(windowType),
44 m_windowSize(windowSize), 44 m_windowSize(windowSize),
45 m_windowIncrement(windowIncrement), 45 m_windowIncrement(windowIncrement),
46 m_fftSize(fftSize), 46 m_fftSize(fftSize),
59 throw invalid_argument("FFTModel window size may not exceed FFT size"); 59 throw invalid_argument("FFTModel window size may not exceed FFT size");
60 } 60 }
61 61
62 m_fft.initFloat(); 62 m_fft.initFloat();
63 63
64 connect(model, SIGNAL(modelChanged()), 64 auto model = ModelById::getAs<DenseTimeValueModel>(m_model);
65 this, SIGNAL(modelChanged())); 65 if (model) {
66 connect(model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), 66 connect(model.get(), SIGNAL(modelChanged()),
67 this, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t))); 67 this, SIGNAL(modelChanged()));
68 connect(model, SIGNAL(aboutToBeDeleted()), 68 connect(model.get(), SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
69 this, SLOT(sourceModelAboutToBeDeleted())); 69 this, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)));
70 }
70 } 71 }
71 72
72 FFTModel::~FFTModel() 73 FFTModel::~FFTModel()
73 { 74 {
74 } 75 }
75 76
76 void 77 bool
77 FFTModel::sourceModelAboutToBeDeleted() 78 FFTModel::isOK() const
78 { 79 {
79 if (m_model) { 80 auto model = ModelById::getAs<DenseTimeValueModel>(m_model);
80 SVDEBUG << "FFTModel[" << this << "]::sourceModelAboutToBeDeleted(" << m_model << ")" << endl; 81 return (model && model->isOK());
81 m_model = nullptr; 82 }
82 } 83
84 int
85 FFTModel::getCompletion() const
86 {
87 int c = 100;
88 auto model = ModelById::getAs<DenseTimeValueModel>(m_model);
89 if (model) {
90 if (model->isReady(&c)) return 100;
91 }
92 return c;
93 }
94
95 sv_samplerate_t
96 FFTModel::getSampleRate() const
97 {
98 auto model = ModelById::getAs<DenseTimeValueModel>(m_model);
99 if (model) return model->getSampleRate();
100 else return 0;
83 } 101 }
84 102
85 int 103 int
86 FFTModel::getWidth() const 104 FFTModel::getWidth() const
87 { 105 {
88 if (!m_model) return 0; 106 auto model = ModelById::getAs<DenseTimeValueModel>(m_model);
89 return int((m_model->getEndFrame() - m_model->getStartFrame()) 107 if (!model) return 0;
108 return int((model->getEndFrame() - model->getStartFrame())
90 / m_windowIncrement) + 1; 109 / m_windowIncrement) + 1;
91 } 110 }
92 111
93 int 112 int
94 FFTModel::getHeight() const 113 FFTModel::getHeight() const
275 FFTModel::fvec 294 FFTModel::fvec
276 FFTModel::getSourceDataUncached(pair<sv_frame_t, sv_frame_t> range) const 295 FFTModel::getSourceDataUncached(pair<sv_frame_t, sv_frame_t> range) const
277 { 296 {
278 Profiler profiler("FFTModel::getSourceDataUncached"); 297 Profiler profiler("FFTModel::getSourceDataUncached");
279 298
280 if (!m_model) return {}; 299 auto model = ModelById::getAs<DenseTimeValueModel>(m_model);
300 if (!model) return {};
281 301
282 decltype(range.first) pfx = 0; 302 decltype(range.first) pfx = 0;
283 if (range.first < 0) { 303 if (range.first < 0) {
284 pfx = -range.first; 304 pfx = -range.first;
285 range = { 0, range.second }; 305 range = { 0, range.second };
286 } 306 }
287 307
288 auto data = m_model->getData(m_channel, 308 auto data = model->getData(m_channel,
289 range.first, 309 range.first,
290 range.second - range.first); 310 range.second - range.first);
291 311
292 if (data.empty()) { 312 if (data.empty()) {
293 SVDEBUG << "NOTE: empty source data for range (" << range.first << "," 313 SVDEBUG << "NOTE: empty source data for range (" << range.first << ","
294 << range.second << ") (model end frame " 314 << range.second << ") (model end frame "
295 << m_model->getEndFrame() << ")" << endl; 315 << model->getEndFrame() << ")" << endl;
296 } 316 }
297 317
298 // don't return a partial frame 318 // don't return a partial frame
299 data.resize(range.second - range.first, 0.f); 319 data.resize(range.second - range.first, 0.f);
300 320
302 vector<float> pad(pfx, 0.f); 322 vector<float> pad(pfx, 0.f);
303 data.insert(data.begin(), pad.begin(), pad.end()); 323 data.insert(data.begin(), pad.begin(), pad.end());
304 } 324 }
305 325
306 if (m_channel == -1) { 326 if (m_channel == -1) {
307 int channels = m_model->getChannelCount(); 327 int channels = model->getChannelCount();
308 if (channels > 1) { 328 if (channels > 1) {
309 int n = int(data.size()); 329 int n = int(data.size());
310 float factor = 1.f / float(channels); 330 float factor = 1.f / float(channels);
311 // use mean instead of sum for fft model input 331 // use mean instead of sum for fft model input
312 for (int i = 0; i < n; ++i) { 332 for (int i = 0; i < n; ++i) {