Mercurial > hg > svcore
comparison transform/FeatureExtractionModelTransformer.cpp @ 1365:3382d914e110
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:44 +0000 |
parents | a99641535e02 |
children | d163b04c3ec4 |
comparison
equal
deleted
inserted
replaced
1272:6a7ea3bd0e10 | 1365:3382d914e110 |
---|---|
14 */ | 14 */ |
15 | 15 |
16 #include "FeatureExtractionModelTransformer.h" | 16 #include "FeatureExtractionModelTransformer.h" |
17 | 17 |
18 #include "plugin/FeatureExtractionPluginFactory.h" | 18 #include "plugin/FeatureExtractionPluginFactory.h" |
19 | |
19 #include "plugin/PluginXml.h" | 20 #include "plugin/PluginXml.h" |
20 #include <vamp-hostsdk/Plugin.h> | 21 #include <vamp-hostsdk/Plugin.h> |
21 | 22 |
22 #include "data/model/Model.h" | 23 #include "data/model/Model.h" |
23 #include "base/Window.h" | 24 #include "base/Window.h" |
40 #include <QSettings> | 41 #include <QSettings> |
41 | 42 |
42 FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, | 43 FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, |
43 const Transform &transform) : | 44 const Transform &transform) : |
44 ModelTransformer(in, transform), | 45 ModelTransformer(in, transform), |
45 m_plugin(0) | 46 m_plugin(0), |
47 m_haveOutputs(false) | |
46 { | 48 { |
47 SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << m_transforms.begin()->getPluginIdentifier() << ", outputName " << m_transforms.begin()->getOutput() << endl; | 49 SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << m_transforms.begin()->getPluginIdentifier() << ", outputName " << m_transforms.begin()->getOutput() << endl; |
48 | |
49 initialise(); | |
50 } | 50 } |
51 | 51 |
52 FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, | 52 FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, |
53 const Transforms &transforms) : | 53 const Transforms &transforms) : |
54 ModelTransformer(in, transforms), | 54 ModelTransformer(in, transforms), |
55 m_plugin(0) | 55 m_plugin(0), |
56 m_haveOutputs(false) | |
56 { | 57 { |
57 if (m_transforms.empty()) { | 58 if (m_transforms.empty()) { |
58 SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: " << transforms.size() << " transform(s)" << endl; | 59 SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: " << transforms.size() << " transform(s)" << endl; |
59 } else { | 60 } else { |
60 SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: " << transforms.size() << " transform(s), first has plugin " << m_transforms.begin()->getPluginIdentifier() << ", outputName " << m_transforms.begin()->getOutput() << endl; | 61 SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: " << transforms.size() << " transform(s), first has plugin " << m_transforms.begin()->getPluginIdentifier() << ", outputName " << m_transforms.begin()->getOutput() << endl; |
61 } | 62 } |
62 | |
63 initialise(); | |
64 } | 63 } |
65 | 64 |
66 static bool | 65 static bool |
67 areTransformsSimilar(const Transform &t1, const Transform &t2) | 66 areTransformsSimilar(const Transform &t1, const Transform &t2) |
68 { | 67 { |
72 } | 71 } |
73 | 72 |
74 bool | 73 bool |
75 FeatureExtractionModelTransformer::initialise() | 74 FeatureExtractionModelTransformer::initialise() |
76 { | 75 { |
76 // This is (now) called from the run thread. The plugin is | |
77 // constructed, initialised, used, and destroyed all from a single | |
78 // thread. | |
79 | |
77 // All transforms must use the same plugin, parameters, and | 80 // All transforms must use the same plugin, parameters, and |
78 // inputs: they can differ only in choice of plugin output. So we | 81 // inputs: they can differ only in choice of plugin output. So we |
79 // initialise based purely on the first transform in the list (but | 82 // initialise based purely on the first transform in the list (but |
80 // first check that they are actually similar as promised) | 83 // first check that they are actually similar as promised) |
81 | 84 |
89 Transform primaryTransform = m_transforms[0]; | 92 Transform primaryTransform = m_transforms[0]; |
90 | 93 |
91 QString pluginId = primaryTransform.getPluginIdentifier(); | 94 QString pluginId = primaryTransform.getPluginIdentifier(); |
92 | 95 |
93 FeatureExtractionPluginFactory *factory = | 96 FeatureExtractionPluginFactory *factory = |
94 FeatureExtractionPluginFactory::instanceFor(pluginId); | 97 FeatureExtractionPluginFactory::instance(); |
95 | 98 |
96 if (!factory) { | 99 if (!factory) { |
97 m_message = tr("No factory available for feature extraction plugin id \"%1\" (unknown plugin type, or internal error?)").arg(pluginId); | 100 m_message = tr("No factory available for feature extraction plugin id \"%1\" (unknown plugin type, or internal error?)").arg(pluginId); |
98 return false; | 101 return false; |
99 } | 102 } |
102 if (!input) { | 105 if (!input) { |
103 m_message = tr("Input model for feature extraction plugin \"%1\" is of wrong type (internal error?)").arg(pluginId); | 106 m_message = tr("Input model for feature extraction plugin \"%1\" is of wrong type (internal error?)").arg(pluginId); |
104 return false; | 107 return false; |
105 } | 108 } |
106 | 109 |
110 SVDEBUG << "FeatureExtractionModelTransformer: Instantiating plugin for transform in thread " | |
111 << QThread::currentThreadId() << endl; | |
112 | |
107 m_plugin = factory->instantiatePlugin(pluginId, input->getSampleRate()); | 113 m_plugin = factory->instantiatePlugin(pluginId, input->getSampleRate()); |
108 if (!m_plugin) { | 114 if (!m_plugin) { |
109 m_message = tr("Failed to instantiate plugin \"%1\"").arg(pluginId); | 115 m_message = tr("Failed to instantiate plugin \"%1\"").arg(pluginId); |
110 return false; | 116 return false; |
111 } | 117 } |
128 .arg(input->getChannelCount()); | 134 .arg(input->getChannelCount()); |
129 return false; | 135 return false; |
130 } | 136 } |
131 | 137 |
132 SVDEBUG << "Initialising feature extraction plugin with channels = " | 138 SVDEBUG << "Initialising feature extraction plugin with channels = " |
133 << channelCount << ", step = " << primaryTransform.getStepSize() | 139 << channelCount << ", step = " << primaryTransform.getStepSize() |
134 << ", block = " << primaryTransform.getBlockSize() << endl; | 140 << ", block = " << primaryTransform.getBlockSize() << endl; |
135 | 141 |
136 if (!m_plugin->initialise(channelCount, | 142 if (!m_plugin->initialise(channelCount, |
137 primaryTransform.getStepSize(), | 143 primaryTransform.getStepSize(), |
138 primaryTransform.getBlockSize())) { | 144 primaryTransform.getBlockSize())) { |
139 | 145 |
140 int pstep = primaryTransform.getStepSize(); | 146 int pstep = primaryTransform.getStepSize(); |
141 int pblock = primaryTransform.getBlockSize(); | 147 int pblock = primaryTransform.getBlockSize(); |
142 | 148 |
143 ///!!! hang on, this isn't right -- we're modifying a copy | 149 ///!!! hang on, this isn't right -- we're modifying a copy |
144 primaryTransform.setStepSize(0); | 150 primaryTransform.setStepSize(0); |
146 TransformFactory::getInstance()->makeContextConsistentWithPlugin | 152 TransformFactory::getInstance()->makeContextConsistentWithPlugin |
147 (primaryTransform, m_plugin); | 153 (primaryTransform, m_plugin); |
148 | 154 |
149 if (primaryTransform.getStepSize() != pstep || | 155 if (primaryTransform.getStepSize() != pstep || |
150 primaryTransform.getBlockSize() != pblock) { | 156 primaryTransform.getBlockSize() != pblock) { |
157 | |
158 SVDEBUG << "Initialisation failed, trying again with default step = " | |
159 << primaryTransform.getStepSize() | |
160 << ", block = " << primaryTransform.getBlockSize() << endl; | |
151 | 161 |
152 if (!m_plugin->initialise(channelCount, | 162 if (!m_plugin->initialise(channelCount, |
153 primaryTransform.getStepSize(), | 163 primaryTransform.getStepSize(), |
154 primaryTransform.getBlockSize())) { | 164 primaryTransform.getBlockSize())) { |
155 | 165 |
166 SVDEBUG << "Initialisation failed again" << endl; | |
167 | |
156 m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId); | 168 m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId); |
157 return false; | 169 return false; |
158 | 170 |
159 } else { | 171 } else { |
160 | 172 |
173 SVDEBUG << "Initialisation succeeded this time" << endl; | |
174 | |
161 m_message = tr("Feature extraction plugin \"%1\" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead") | 175 m_message = tr("Feature extraction plugin \"%1\" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead") |
162 .arg(pluginId) | 176 .arg(pluginId) |
163 .arg(pstep) | 177 .arg(pstep) |
164 .arg(pblock) | 178 .arg(pblock) |
165 .arg(primaryTransform.getStepSize()) | 179 .arg(primaryTransform.getStepSize()) |
166 .arg(primaryTransform.getBlockSize()); | 180 .arg(primaryTransform.getBlockSize()); |
167 } | 181 } |
168 | 182 |
169 } else { | 183 } else { |
170 | 184 |
185 SVDEBUG << "Initialisation failed" << endl; | |
186 | |
171 m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId); | 187 m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId); |
172 return false; | 188 return false; |
173 } | 189 } |
190 } else { | |
191 SVDEBUG << "Initialisation succeeded" << endl; | |
174 } | 192 } |
175 | 193 |
176 if (primaryTransform.getPluginVersion() != "") { | 194 if (primaryTransform.getPluginVersion() != "") { |
177 QString pv = QString("%1").arg(m_plugin->getPluginVersion()); | 195 QString pv = QString("%1").arg(m_plugin->getPluginVersion()); |
178 if (pv != primaryTransform.getPluginVersion()) { | 196 if (pv != primaryTransform.getPluginVersion()) { |
218 | 236 |
219 for (int j = 0; j < (int)m_transforms.size(); ++j) { | 237 for (int j = 0; j < (int)m_transforms.size(); ++j) { |
220 createOutputModels(j); | 238 createOutputModels(j); |
221 } | 239 } |
222 | 240 |
241 m_outputMutex.lock(); | |
242 m_haveOutputs = true; | |
243 m_outputsCondition.wakeAll(); | |
244 m_outputMutex.unlock(); | |
245 | |
223 return true; | 246 return true; |
247 } | |
248 | |
249 void | |
250 FeatureExtractionModelTransformer::deinitialise() | |
251 { | |
252 SVDEBUG << "FeatureExtractionModelTransformer: deleting plugin for transform in thread " | |
253 << QThread::currentThreadId() << endl; | |
254 | |
255 delete m_plugin; | |
256 for (int j = 0; j < (int)m_descriptors.size(); ++j) { | |
257 delete m_descriptors[j]; | |
258 } | |
224 } | 259 } |
225 | 260 |
226 void | 261 void |
227 FeatureExtractionModelTransformer::createOutputModels(int n) | 262 FeatureExtractionModelTransformer::createOutputModels(int n) |
228 { | 263 { |
229 DenseTimeValueModel *input = getConformingInput(); | 264 DenseTimeValueModel *input = getConformingInput(); |
230 | |
231 // cerr << "FeatureExtractionModelTransformer::createOutputModel: sample type " << m_descriptor->sampleType << ", rate " << m_descriptor->sampleRate << endl; | |
232 | 265 |
233 PluginRDFDescription description(m_transforms[n].getPluginIdentifier()); | 266 PluginRDFDescription description(m_transforms[n].getPluginIdentifier()); |
234 QString outputId = m_transforms[n].getOutput(); | 267 QString outputId = m_transforms[n].getOutput(); |
235 | 268 |
236 int binCount = 1; | 269 int binCount = 1; |
252 maxValue = m_descriptors[n]->maxValue; | 285 maxValue = m_descriptors[n]->maxValue; |
253 haveExtents = true; | 286 haveExtents = true; |
254 } | 287 } |
255 | 288 |
256 sv_samplerate_t modelRate = input->getSampleRate(); | 289 sv_samplerate_t modelRate = input->getSampleRate(); |
290 sv_samplerate_t outputRate = modelRate; | |
257 int modelResolution = 1; | 291 int modelResolution = 1; |
258 | 292 |
259 if (m_descriptors[n]->sampleType != | 293 if (m_descriptors[n]->sampleType != |
260 Vamp::Plugin::OutputDescriptor::OneSamplePerStep) { | 294 Vamp::Plugin::OutputDescriptor::OneSamplePerStep) { |
261 if (m_descriptors[n]->sampleRate > input->getSampleRate()) { | 295 |
262 cerr << "WARNING: plugin reports output sample rate as " | 296 outputRate = m_descriptors[n]->sampleRate; |
263 << m_descriptors[n]->sampleRate << " (can't display features with finer resolution than the input rate of " << input->getSampleRate() << ")" << endl; | 297 |
264 } | |
265 } | |
266 | |
267 switch (m_descriptors[n]->sampleType) { | |
268 | |
269 case Vamp::Plugin::OutputDescriptor::VariableSampleRate: | |
270 if (m_descriptors[n]->sampleRate != 0.0) { | |
271 modelResolution = int(round(modelRate / m_descriptors[n]->sampleRate)); | |
272 } | |
273 break; | |
274 | |
275 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: | |
276 modelResolution = m_transforms[n].getStepSize(); | |
277 break; | |
278 | |
279 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: | |
280 //!!! SV doesn't actually support display of models that have | 298 //!!! SV doesn't actually support display of models that have |
281 //!!! different underlying rates together -- so we always set | 299 //!!! different underlying rates together -- so we always set |
282 //!!! the model rate to be the input model's rate, and adjust | 300 //!!! the model rate to be the input model's rate, and adjust |
283 //!!! the resolution appropriately. We can't properly display | 301 //!!! the resolution appropriately. We can't properly display |
284 //!!! data with a higher resolution than the base model at all | 302 //!!! data with a higher resolution than the base model at all |
285 if (m_descriptors[n]->sampleRate > input->getSampleRate()) { | 303 if (outputRate > input->getSampleRate()) { |
286 modelResolution = 1; | 304 SVDEBUG << "WARNING: plugin reports output sample rate as " |
287 } else if (m_descriptors[n]->sampleRate <= 0.0) { | 305 << outputRate |
288 cerr << "WARNING: Fixed sample-rate plugin reports invalid sample rate " << m_descriptors[n]->sampleRate << "; defaulting to input rate of " << input->getSampleRate() << endl; | 306 << " (can't display features with finer resolution than the input rate of " |
307 << modelRate << ")" << endl; | |
308 outputRate = modelRate; | |
309 } | |
310 } | |
311 | |
312 switch (m_descriptors[n]->sampleType) { | |
313 | |
314 case Vamp::Plugin::OutputDescriptor::VariableSampleRate: | |
315 if (outputRate != 0.0) { | |
316 modelResolution = int(round(modelRate / outputRate)); | |
317 } | |
318 break; | |
319 | |
320 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: | |
321 modelResolution = m_transforms[n].getStepSize(); | |
322 break; | |
323 | |
324 case Vamp::Plugin::OutputDescriptor::FixedSampleRate: | |
325 if (outputRate <= 0.0) { | |
326 SVDEBUG << "WARNING: Fixed sample-rate plugin reports invalid sample rate " << m_descriptors[n]->sampleRate << "; defaulting to input rate of " << input->getSampleRate() << endl; | |
289 modelResolution = 1; | 327 modelResolution = 1; |
290 } else { | 328 } else { |
291 modelResolution = int(round(modelRate / m_descriptors[n]->sampleRate)); | 329 modelResolution = int(round(modelRate / outputRate)); |
330 // cerr << "modelRate = " << modelRate << ", descriptor rate = " << outputRate << ", modelResolution = " << modelResolution << endl; | |
292 } | 331 } |
293 break; | 332 break; |
294 } | 333 } |
295 | 334 |
296 bool preDurationPlugin = (m_plugin->getVampApiVersion() < 2); | 335 bool preDurationPlugin = (m_plugin->getVampApiVersion() < 2); |
477 out->setSourceModel(input); | 516 out->setSourceModel(input); |
478 m_outputs.push_back(out); | 517 m_outputs.push_back(out); |
479 } | 518 } |
480 } | 519 } |
481 | 520 |
521 void | |
522 FeatureExtractionModelTransformer::awaitOutputModels() | |
523 { | |
524 m_outputMutex.lock(); | |
525 while (!m_haveOutputs) { | |
526 m_outputsCondition.wait(&m_outputMutex); | |
527 } | |
528 m_outputMutex.unlock(); | |
529 } | |
530 | |
482 FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer() | 531 FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer() |
483 { | 532 { |
484 // SVDEBUG << "FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer()" << endl; | 533 // Parent class dtor set the abandoned flag and waited for the run |
485 delete m_plugin; | 534 // thread to exit; the run thread owns the plugin, and should have |
486 for (int j = 0; j < (int)m_descriptors.size(); ++j) { | 535 // destroyed it before exiting (via a call to deinitialise) |
487 delete m_descriptors[j]; | |
488 } | |
489 } | 536 } |
490 | 537 |
491 FeatureExtractionModelTransformer::Models | 538 FeatureExtractionModelTransformer::Models |
492 FeatureExtractionModelTransformer::getAdditionalOutputModels() | 539 FeatureExtractionModelTransformer::getAdditionalOutputModels() |
493 { | 540 { |
564 } | 611 } |
565 | 612 |
566 void | 613 void |
567 FeatureExtractionModelTransformer::run() | 614 FeatureExtractionModelTransformer::run() |
568 { | 615 { |
616 initialise(); | |
617 | |
569 DenseTimeValueModel *input = getConformingInput(); | 618 DenseTimeValueModel *input = getConformingInput(); |
570 if (!input) return; | 619 if (!input) return; |
571 | 620 |
572 if (m_outputs.empty()) return; | 621 if (m_outputs.empty()) return; |
573 | 622 |
604 (getConformingInput(), | 653 (getConformingInput(), |
605 channelCount == 1 ? m_input.getChannel() : ch, | 654 channelCount == 1 ? m_input.getChannel() : ch, |
606 primaryTransform.getWindowType(), | 655 primaryTransform.getWindowType(), |
607 blockSize, | 656 blockSize, |
608 stepSize, | 657 stepSize, |
609 blockSize, | 658 blockSize); |
610 false, | |
611 StorageAdviser::PrecisionCritical); | |
612 if (!model->isOK() || model->getError() != "") { | 659 if (!model->isOK() || model->getError() != "") { |
613 QString err = model->getError(); | 660 QString err = model->getError(); |
614 delete model; | 661 delete model; |
615 for (int j = 0; j < (int)m_outputNos.size(); ++j) { | 662 for (int j = 0; j < (int)m_outputNos.size(); ++j) { |
616 setCompletion(j, 100); | 663 setCompletion(j, 100); |
617 } | 664 } |
618 //!!! need a better way to handle this -- previously we were using a QMessageBox but that isn't an appropriate thing to do here either | 665 //!!! need a better way to handle this -- previously we were using a QMessageBox but that isn't an appropriate thing to do here either |
619 throw AllocationFailed("Failed to create the FFT model for this feature extraction model transformer: error is: " + err); | 666 throw AllocationFailed("Failed to create the FFT model for this feature extraction model transformer: error is: " + err); |
620 } | 667 } |
621 model->resume(); | |
622 fftModels.push_back(model); | 668 fftModels.push_back(model); |
623 cerr << "created model for channel " << ch << endl; | 669 cerr << "created model for channel " << ch << endl; |
624 } | 670 } |
625 } | 671 } |
626 | 672 |
698 buffers[ch][i*2+1] = 0.f; | 744 buffers[ch][i*2+1] = 0.f; |
699 } | 745 } |
700 } | 746 } |
701 error = fftModels[ch]->getError(); | 747 error = fftModels[ch]->getError(); |
702 if (error != "") { | 748 if (error != "") { |
703 cerr << "FeatureExtractionModelTransformer::run: Abandoning, error is " << error << endl; | 749 SVDEBUG << "FeatureExtractionModelTransformer::run: Abandoning, error is " << error << endl; |
704 m_abandoned = true; | 750 m_abandoned = true; |
705 m_message = error; | 751 m_message = error; |
706 break; | 752 break; |
707 } | 753 } |
708 } | 754 } |
759 | 805 |
760 for (int ch = 0; ch < channelCount; ++ch) { | 806 for (int ch = 0; ch < channelCount; ++ch) { |
761 delete[] buffers[ch]; | 807 delete[] buffers[ch]; |
762 } | 808 } |
763 delete[] buffers; | 809 delete[] buffers; |
810 | |
811 deinitialise(); | |
764 } | 812 } |
765 | 813 |
766 void | 814 void |
767 FeatureExtractionModelTransformer::getFrames(int channelCount, | 815 FeatureExtractionModelTransformer::getFrames(int channelCount, |
768 sv_frame_t startFrame, | 816 sv_frame_t startFrame, |
788 | 836 |
789 sv_frame_t got = 0; | 837 sv_frame_t got = 0; |
790 | 838 |
791 if (channelCount == 1) { | 839 if (channelCount == 1) { |
792 | 840 |
793 got = input->getData(m_input.getChannel(), startFrame, size, | 841 auto data = input->getData(m_input.getChannel(), startFrame, size); |
794 buffers[0] + offset); | 842 got = data.size(); |
843 | |
844 copy(data.begin(), data.end(), buffers[0] + offset); | |
795 | 845 |
796 if (m_input.getChannel() == -1 && input->getChannelCount() > 1) { | 846 if (m_input.getChannel() == -1 && input->getChannelCount() > 1) { |
797 // use mean instead of sum, as plugin input | 847 // use mean instead of sum, as plugin input |
798 float cc = float(input->getChannelCount()); | 848 float cc = float(input->getChannelCount()); |
799 for (sv_frame_t i = 0; i < size; ++i) { | 849 for (sv_frame_t i = 0; i < got; ++i) { |
800 buffers[0][i + offset] /= cc; | 850 buffers[0][i + offset] /= cc; |
801 } | 851 } |
802 } | 852 } |
803 | 853 |
804 } else { | 854 } else { |
805 | 855 |
806 float **writebuf = buffers; | 856 auto data = input->getMultiChannelData(0, channelCount-1, startFrame, size); |
807 if (offset > 0) { | 857 if (!data.empty()) { |
808 writebuf = new float *[channelCount]; | 858 got = data[0].size(); |
809 for (int i = 0; i < channelCount; ++i) { | 859 for (int c = 0; in_range_for(data, c); ++c) { |
810 writebuf[i] = buffers[i] + offset; | 860 copy(data[c].begin(), data[c].end(), buffers[c] + offset); |
811 } | 861 } |
812 } | 862 } |
813 | |
814 got = input->getMultiChannelData | |
815 (0, channelCount-1, startFrame, size, writebuf); | |
816 | |
817 if (writebuf != buffers) delete[] writebuf; | |
818 } | 863 } |
819 | 864 |
820 while (got < size) { | 865 while (got < size) { |
821 for (int c = 0; c < channelCount; ++c) { | 866 for (int c = 0; c < channelCount; ++c) { |
822 buffers[c][got + offset] = 0.0; | 867 buffers[c][got + offset] = 0.0; |
842 | 887 |
843 if (m_descriptors[n]->sampleType == | 888 if (m_descriptors[n]->sampleType == |
844 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { | 889 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { |
845 | 890 |
846 if (!feature.hasTimestamp) { | 891 if (!feature.hasTimestamp) { |
847 cerr | 892 SVDEBUG |
848 << "WARNING: FeatureExtractionModelTransformer::addFeature: " | 893 << "WARNING: FeatureExtractionModelTransformer::addFeature: " |
849 << "Feature has variable sample rate but no timestamp!" | 894 << "Feature has variable sample rate but no timestamp!" |
850 << endl; | 895 << endl; |
851 return; | 896 return; |
852 } else { | 897 } else { |
878 frame = lrint((double(m_fixedRateFeatureNos[n]) / rate) * inputRate); | 923 frame = lrint((double(m_fixedRateFeatureNos[n]) / rate) * inputRate); |
879 // cerr << frame << endl; | 924 // cerr << frame << endl; |
880 } | 925 } |
881 | 926 |
882 if (frame < 0) { | 927 if (frame < 0) { |
883 cerr | 928 SVDEBUG |
884 << "WARNING: FeatureExtractionModelTransformer::addFeature: " | 929 << "WARNING: FeatureExtractionModelTransformer::addFeature: " |
885 << "Negative frame counts are not supported (frame = " << frame | 930 << "Negative frame counts are not supported (frame = " << frame |
886 << " from timestamp " << feature.timestamp | 931 << " from timestamp " << feature.timestamp |
887 << "), dropping feature" | 932 << "), dropping feature" |
888 << endl; | 933 << endl; |
1011 } | 1056 } |
1012 } | 1057 } |
1013 | 1058 |
1014 } else if (isOutput<EditableDenseThreeDimensionalModel>(n)) { | 1059 } else if (isOutput<EditableDenseThreeDimensionalModel>(n)) { |
1015 | 1060 |
1016 DenseThreeDimensionalModel::Column values = | 1061 DenseThreeDimensionalModel::Column values = feature.values; |
1017 DenseThreeDimensionalModel::Column::fromStdVector(feature.values); | |
1018 | 1062 |
1019 EditableDenseThreeDimensionalModel *model = | 1063 EditableDenseThreeDimensionalModel *model = |
1020 getConformingOutput<EditableDenseThreeDimensionalModel>(n); | 1064 getConformingOutput<EditableDenseThreeDimensionalModel>(n); |
1021 if (!model) return; | 1065 if (!model) return; |
1022 | 1066 |