summaryrefslogtreecommitdiff
path: root/rotord/vampHost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/vampHost.cpp')
-rw-r--r--rotord/vampHost.cpp815
1 files changed, 0 insertions, 815 deletions
diff --git a/rotord/vampHost.cpp b/rotord/vampHost.cpp
deleted file mode 100644
index 65755eb..0000000
--- a/rotord/vampHost.cpp
+++ /dev/null
@@ -1,815 +0,0 @@
-#include "vampHost.h"
-
-int vampHost::runPlugin(string myname, string soname, string id, string output,
- int outputNo, string inputFile, ostream& out, bool useFrames)
-{
- PluginLoader *loader = PluginLoader::getInstance();
-
- PluginLoader::PluginKey key = loader->composePluginKey(soname, id);
-
- SNDFILE *sndfile;
- SF_INFO sfinfo;
- memset(&sfinfo, 0, sizeof(SF_INFO));
-
- sndfile = sf_open(inputFile.c_str(), SFM_READ, &sfinfo);
- if (!sndfile) {
- cerr << myname << ": ERROR: Failed to open input file \""
- << inputFile << "\": " << sf_strerror(sndfile) << endl;
- return 1;
- }
-
- Plugin *plugin = loader->loadPlugin
- (key, sfinfo.samplerate, PluginLoader::ADAPT_ALL_SAFE);
- if (!plugin) {
- cerr << myname << ": ERROR: Failed to load plugin \"" << id
- << "\" from library \"" << soname << "\"" << endl;
- sf_close(sndfile);
- return 1;
- }
-
- cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
-
- // Note that the following would be much simpler if we used a
- // PluginBufferingAdapter as well -- i.e. if we had passed
- // PluginLoader::ADAPT_ALL to loader->loadPlugin() above, instead
- // of ADAPT_ALL_SAFE. Then we could simply specify our own block
- // size, keep the step size equal to the block size, and ignore
- // the plugin's bleatings. However, there are some issues with
- // using a PluginBufferingAdapter that make the results sometimes
- // technically different from (if effectively the same as) the
- // un-adapted plugin, so we aren't doing that here. See the
- // PluginBufferingAdapter documentation for details.
-
- int blockSize = plugin->getPreferredBlockSize();
- int stepSize = plugin->getPreferredStepSize();
-
- if (blockSize == 0) {
- blockSize = 1024;
- }
- if (stepSize == 0) {
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- stepSize = blockSize/2;
- } else {
- stepSize = blockSize;
- }
- } else if (stepSize > blockSize) {
- cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- blockSize = stepSize * 2;
- } else {
- blockSize = stepSize;
- }
- cerr << blockSize << endl;
- }
- int overlapSize = blockSize - stepSize;
- sf_count_t currentStep = 0;
- int finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
-
- int channels = sfinfo.channels;
-
- float *filebuf = new float[blockSize * channels];
- float **plugbuf = new float*[channels];
- for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
-
- cerr << "Using block size = " << blockSize << ", step size = "
- << stepSize << endl;
-
- // The channel queries here are for informational purposes only --
- // a PluginChannelAdapter is being used automatically behind the
- // scenes, and it will take case of any channel mismatch
-
- int minch = plugin->getMinChannelCount();
- int maxch = plugin->getMaxChannelCount();
- cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
- cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
-
- Plugin::OutputList outputs = plugin->getOutputDescriptors();
- Plugin::OutputDescriptor od;
-
- int returnValue = 1;
- int progress = 0;
-
- RealTime rt;
- PluginWrapper *wrapper = 0;
- RealTime adjustment = RealTime::zeroTime;
-
- if (outputs.empty()) {
- cerr << "ERROR: Plugin has no outputs!" << endl;
- goto done;
- }
-
- if (outputNo < 0) {
-
- for (size_t oi = 0; oi < outputs.size(); ++oi) {
- if (outputs[oi].identifier == output) {
- outputNo = oi;
- break;
- }
- }
-
- if (outputNo < 0) {
- cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
- goto done;
- }
-
- } else {
-
- if (int(outputs.size()) <= outputNo) {
- cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
- goto done;
- }
- }
-
- od = outputs[outputNo];
- cerr << "Output is: \"" << od.identifier << "\"" << endl;
-
- if (!plugin->initialise(channels, stepSize, blockSize)) {
- cerr << "ERROR: Plugin initialise (channels = " << channels
- << ", stepSize = " << stepSize << ", blockSize = "
- << blockSize << ") failed." << endl;
- goto done;
- }
-
- wrapper = dynamic_cast<PluginWrapper *>(plugin);
- if (wrapper) {
- // See documentation for
- // PluginInputDomainAdapter::getTimestampAdjustment
- PluginInputDomainAdapter *ida =
- wrapper->getWrapper<PluginInputDomainAdapter>();
- if (ida) adjustment = ida->getTimestampAdjustment();
- }
-
- // Here we iterate over the frames, avoiding asking the numframes in case it's streaming input.
- do {
-
- int count;
-
- if ((blockSize==stepSize) || (currentStep==0)) {
- // read a full fresh block
- if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
- cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
- break;
- }
- if (count != blockSize) --finalStepsRemaining;
- } else {
- // otherwise shunt the existing data down and read the remainder.
- memmove(filebuf, filebuf + (stepSize * channels), overlapSize * channels * sizeof(float));
- if ((count = sf_readf_float(sndfile, filebuf + (overlapSize * channels), stepSize)) < 0) {
- cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
- break;
- }
- if (count != stepSize) --finalStepsRemaining;
- count += overlapSize;
- }
-
- for (int c = 0; c < channels; ++c) {
- int j = 0;
- while (j < count) {
- plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
- ++j;
- }
- while (j < blockSize) {
- plugbuf[c][j] = 0.0f;
- ++j;
- }
- }
-
- rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
-
- vampHost::printFeatures
- (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
- sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
- out, useFrames);
-
- if (sfinfo.frames > 0){
- int pp = progress;
- progress = lrintf((float(currentStep * stepSize) / sfinfo.frames) * 100.f);
- if (progress != pp && out) {
- cerr << "\r" << progress << "%";
- }
- }
-
- ++currentStep;
-
- } while (finalStepsRemaining > 0);
-
- if (out) cerr << "\rDone" << endl;
-
- rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
-
- vampHost::printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
- sfinfo.samplerate, outputNo,
- plugin->getRemainingFeatures(), out, useFrames);
-
- returnValue = 0;
-
-done:
- delete plugin;
- sf_close(sndfile);
- return returnValue;
-}
-
-int vampHost::rotorRunPlugin(string soname, string id, string output,
- int outputNo, string inputFile, vector<float>& out, float& progress)
-{
- PluginLoader *loader = PluginLoader::getInstance();
-
- PluginLoader::PluginKey key = loader->composePluginKey(soname, id);
-
- SNDFILE *sndfile;
- SF_INFO sfinfo;
- memset(&sfinfo, 0, sizeof(SF_INFO));
-
- sndfile = sf_open(inputFile.c_str(), SFM_READ, &sfinfo);
- if (!sndfile) {
- cerr << ": ERROR: Failed to open input file \""
- << inputFile << "\": " << sf_strerror(sndfile) << endl;
- return 1;
- }
-
- Plugin *plugin = loader->loadPlugin
- (key, sfinfo.samplerate, PluginLoader::ADAPT_ALL_SAFE);
- if (!plugin) {
- cerr << ": ERROR: Failed to load plugin \"" << id
- << "\" from library \"" << soname << "\"" << endl;
- sf_close(sndfile);
- return 1;
- }
-
- cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
-
- // Note that the following would be much simpler if we used a
- // PluginBufferingAdapter as well -- i.e. if we had passed
- // PluginLoader::ADAPT_ALL to loader->loadPlugin() above, instead
- // of ADAPT_ALL_SAFE. Then we could simply specify our own block
- // size, keep the step size equal to the block size, and ignore
- // the plugin's bleatings. However, there are some issues with
- // using a PluginBufferingAdapter that make the results sometimes
- // technically different from (if effectively the same as) the
- // un-adapted plugin, so we aren't doing that here. See the
- // PluginBufferingAdapter documentation for details.
-
- int blockSize = plugin->getPreferredBlockSize();
- int stepSize = plugin->getPreferredStepSize();
-
- if (blockSize == 0) {
- blockSize = 1024;
- }
- if (stepSize == 0) {
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- stepSize = blockSize/2;
- } else {
- stepSize = blockSize;
- }
- } else if (stepSize > blockSize) {
- cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- blockSize = stepSize * 2;
- } else {
- blockSize = stepSize;
- }
- cerr << blockSize << endl;
- }
- int overlapSize = blockSize - stepSize;
- sf_count_t currentStep = 0;
- int finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
-
- int channels = sfinfo.channels;
-
- float *filebuf = new float[blockSize * channels];
- float **plugbuf = new float*[channels];
- for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
-
- cerr << "Using block size = " << blockSize << ", step size = "
- << stepSize << endl;
-
- // The channel queries here are for informational purposes only --
- // a PluginChannelAdapter is being used automatically behind the
- // scenes, and it will take case of any channel mismatch
-
- int minch = plugin->getMinChannelCount();
- int maxch = plugin->getMaxChannelCount();
- cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
- cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
-
- Plugin::OutputList outputs = plugin->getOutputDescriptors();
- Plugin::OutputDescriptor od;
-
- int returnValue = 1;
- int prog = 0;
-
- RealTime rt;
- PluginWrapper *wrapper = 0;
- RealTime adjustment = RealTime::zeroTime;
-
- if (outputs.empty()) {
- cerr << "ERROR: Plugin has no outputs!" << endl;
- goto done;
- }
-
- if (outputNo < 0) {
-
- for (size_t oi = 0; oi < outputs.size(); ++oi) {
- if (outputs[oi].identifier == output) {
- outputNo = oi;
- break;
- }
- }
-
- if (outputNo < 0) {
- cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
- goto done;
- }
-
- } else {
-
- if (int(outputs.size()) <= outputNo) {
- cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
- goto done;
- }
- }
-
- od = outputs[outputNo];
- cerr << "Output is: \"" << od.identifier << "\"" << endl;
-
- if (!plugin->initialise(channels, stepSize, blockSize)) {
- cerr << "ERROR: Plugin initialise (channels = " << channels
- << ", stepSize = " << stepSize << ", blockSize = "
- << blockSize << ") failed." << endl;
- goto done;
- }
-
- wrapper = dynamic_cast<PluginWrapper *>(plugin);
- if (wrapper) {
- // See documentation for
- // PluginInputDomainAdapter::getTimestampAdjustment
- PluginInputDomainAdapter *ida =
- wrapper->getWrapper<PluginInputDomainAdapter>();
- if (ida) adjustment = ida->getTimestampAdjustment();
- }
-
- // Here we iterate over the frames, avoiding asking the numframes in case it's streaming input.
- do {
-
- int count;
-
- if ((blockSize==stepSize) || (currentStep==0)) {
- // read a full fresh block
- if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
- cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
- break;
- }
- if (count != blockSize) --finalStepsRemaining;
- } else {
- // otherwise shunt the existing data down and read the remainder.
- memmove(filebuf, filebuf + (stepSize * channels), overlapSize * channels * sizeof(float));
- if ((count = sf_readf_float(sndfile, filebuf + (overlapSize * channels), stepSize)) < 0) {
- cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
- break;
- }
- if (count != stepSize) --finalStepsRemaining;
- count += overlapSize;
- }
-
- for (int c = 0; c < channels; ++c) {
- int j = 0;
- while (j < count) {
- plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
- ++j;
- }
- while (j < blockSize) {
- plugbuf[c][j] = 0.0f;
- ++j;
- }
- }
-
- rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
-
- vampHost::rotorGetFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),sfinfo.samplerate, outputNo,plugin->getRemainingFeatures(), out, progress);
-
- if (sfinfo.frames > 0){
- int pp = prog;
- prog = lrintf((float(currentStep * stepSize) / sfinfo.frames) * 100.f);
- if (prog != pp ) {
- cerr << "\r" << progress << "%";
- }
- }
-
- ++currentStep;
-
- } while (finalStepsRemaining > 0);
-
- cerr << "\rDone" << endl;
-
- rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
-
- vampHost::rotorGetFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),sfinfo.samplerate, outputNo,plugin->getRemainingFeatures(), out, progress);
-
- returnValue = 0;
-
-done:
- delete plugin;
- sf_close(sndfile);
- return returnValue;
-}
-
-void vampHost::printFeatures(int frame, int sr, int output,
- Plugin::FeatureSet features, ostream& out, bool useFrames)
-{
- if (features[output].size()) {
- cout << "." << features[output].size();
- }
- for (unsigned int i = 0; i < features[output].size(); ++i) {
-
- if (useFrames) {
-
- int displayFrame = frame;
-
- if (features[output][i].hasTimestamp) {
- displayFrame = RealTime::realTime2Frame
- (features[output][i].timestamp, sr);
- }
-
- out << displayFrame;
-
- if (features[output][i].hasDuration) {
- displayFrame = RealTime::realTime2Frame
- (features[output][i].duration, sr);
- out << "," << displayFrame;
- }
-
- out << ":";
-
- } else {
-
- RealTime rt = RealTime::frame2RealTime(frame, sr);
-
- if (features[output][i].hasTimestamp) {
- rt = features[output][i].timestamp;
- }
-
- out << rt.toString();
-
- if (features[output][i].hasDuration) {
- rt = features[output][i].duration;
- out<< "," << rt.toString();
- }
-
- out << ":";
- }
-
- for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
- out<< " " << features[output][i].values[j];
- }
- out << " " << features[output][i].label;
-
- out << endl;
- }
-
-}
-
-
-
-void vampHost::rotorGetFeatures(int frame, int sr, int output,Plugin::FeatureSet features, vector<float>& out, float& progress)
-{
- if (features[output].size()) {
- cout << "." << features[output].size();
- }
- for (unsigned int i = 0; i < features[output].size(); ++i) {
-
-
-
- int displayFrame = frame;
-
- if (features[output][i].hasTimestamp) {
- displayFrame = RealTime::realTime2Frame
- (features[output][i].timestamp, sr);
- }
-
- cout << displayFrame;
-
-
- cout << endl;
- }
-
-}
-
-
-int vampHost::QMAnalyser::process(const string inputFile){
- //vampHost::runPlugin("",settings.soname,settings.filtername, "",0, settings.inputFile, ostr,true);
- //would run the plugin, outputting progress to cerr and the data to ostr
- //
- //int runPlugin(string myname, string soname, string id, string output,int outputNo, string inputFile, ostream& out, bool frames);
-
-
- //we want to run a specific plugin, outputting progress to a mutex-protected passed variable
- //and ultimately passing the data back as a string?
- //or capture it as an array of floats?
- //get the progress as a float
- //how to handle errors?
-
- //debugger fucking up! program stalls after 1 request in debug!?
-
- string soname="qm-vamp-plugins";
- string id="qm-tempotracker";
- string myname="";
- string output="";
- int outputNo=0;
-
- vampHost::rotorRunPlugin(soname,id,output,outputNo,inputFile,beats,progress);
-
-}
-
-void vampHost::getTimestamps(int output,Plugin::FeatureSet features, vector<float>& out){
-
- /*
- vamp-simple-host qm-vamp-plugins:qm-tempotracker 01.wav
-
- 0.046439908: 156.61 bpm
- 0.429569160: 156.61 bpm
- 0.812698412: 161.50 bpm
- 1.184217686: 152.00 bpm
-
-
- vamp-simple-host qm-vamp-plugins:qm-segmenter 01.wav
-
- 0.000000000: 4 4
- 23.800000000: 6 6
- 44.600000000: 5 5
- 55.000000000: 7 7
- 72.800000000: 1 1
- 90.600000000: 2 2
- 109.200000000: 5 5
- 116.000000000: 3 3
- 143.800000000: 5 5
- 153.400000000: 3 3
- 163.000000000: 8 8
-
- seems to be FP seconds then another metric
- for now we can just take the first part
-
- features[output][i].timestamp is of type RealTime: represents time values to nanosecond precision
- int sec;
- int nsec;
- 1 sec = 10^9 nanosec
-
- actually maybe this would be the way to go for rotor- avoiding rounding errors etc
- for now - ideally will get a float representation
-
- features[output][i].values is a vector of floats + a description
- WE DON'T CARE ABOUT ANYTHING <.01 seconds
-
- static long realTime2Frame(const RealTime &r, unsigned int sampleRate);
-
- get a vector of floats out, using frames, presuming data has a timestamp
-
-
- this is crashing with "Aborted (core dumped)"
- if we check for timestamp
-
- */
-
- cout << "." << features[output].size();
-
- //if (!features[output][0].hasTimestamp) {
- // cerr << output << " channel, getTimestamps: error, featureset doesn't support timestamp" << endl;
- //}_
- //else {
- for (unsigned int i = 0; i < features[output].size(); ++i) {
- out.push_back( ((float)RealTime::realTime2Frame(features[output][i].timestamp, 1000))*.001f);
- cout << "feature found.\n";
- }
- //}
-}
-float vampHost::QMAnalyser::get_progress(){
- float p;
- mutex.lock();
- p=progress;
- mutex.unlock();
- return p;
-}
-bool vampHost::Analyser::init(const string &soname,const string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,int _outputNo,const map<string,float> &params){
-
- //stuff that only happens once
- channels =_channels;
- samples=_samples;
- rate=_rate;
- bits=_bits;
- outputNo=_outputNo;
- //output=_output;
-
- //http://www.mega-nerd.com/libsndfile/api.html#note1
- //libsndfile returns -1..1 for fp data
- bytes=(bits>>3);
- stride=channels*bytes;
- scale=(1.0f/pow(2.0f,bits));
-
- features.clear(); //in case of reuse
- features[0.0f]=0;
-
- loader = PluginLoader::getInstance();
- key = loader->composePluginKey(soname, id);
- plugin = loader->loadPlugin(key, _rate, PluginLoader::ADAPT_ALL_SAFE);
- if (!plugin) {
- cerr << ": ERROR: Failed to load plugin \"" << id
- << "\" from library \"" << soname << "\"" << endl;
- return false;
- }
-
- cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"... Domain:";
-
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- cerr << "frequency" << endl;
- }
- else {
-
- cerr << "time" << endl;
-
- }
-
- blockSize = plugin->getPreferredBlockSize();
- stepSize = plugin->getPreferredStepSize();
-
- if (blockSize == 0) {
- blockSize = 1024;
- }
- if (stepSize == 0) {
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- stepSize = blockSize/2;
- } else {
- stepSize = blockSize;
- }
- }
- else if (stepSize > blockSize) {
- cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
- if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
- blockSize = stepSize * 2;
- } else {
- blockSize = stepSize;
- }
- cerr << blockSize << endl;
- }
- overlapSize = blockSize - stepSize;
- currentStep = 0;
- finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
-
- plugbuf = new float*[channels];
- for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
-
- cerr << "Using block size = " << blockSize << ", step size = "
- << stepSize << endl;
-
- // The channel queries here are for informational purposes only --
- // a PluginChannelAdapter is being used automatically behind the
- // scenes, and it will take case of any channel mismatch
-
- int minch = plugin->getMinChannelCount();
- int maxch = plugin->getMaxChannelCount();
- cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
- cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
-
- Plugin::OutputList outputs = plugin->getOutputDescriptors();
- Plugin::OutputDescriptor od;
-
- int returnValue = 1;
- int prog = 0;
-
- RealTime rt;
- PluginWrapper *wrapper = 0;
- RealTime adjustment = RealTime::zeroTime;
-
- if (outputs.empty()) {
- cerr << "ERROR: Plugin has no outputs!" << endl;
- return false;
- }
-
- if (outputNo < 0) {
- for (size_t oi = 0; oi < outputs.size(); ++oi) {
- if (outputs[oi].identifier == output) {
- outputNo = oi;
- break;
- }
- }
- if (outputNo < 0) {
- cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
- return false;
- }
- }
- else {
- if (int(outputs.size()) <= outputNo) {
- cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
- return false;
- }
- }
- od = outputs[outputNo];
- cerr << "Output number "<<outputNo<<": \"" << od.identifier << "\"" << endl;
-
-
- for (auto i:params){
- plugin->setParameter(i.first,i.second);
- cerr << "Set plugin parameter: "<<i.first<<" : "<<i.second<<endl;
- }
-
- if (!plugin->initialise(channels, stepSize, blockSize)) {
- cerr << "ERROR: Plugin initialise (channels = " << channels
- << ", stepSize = " << stepSize << ", blockSize = "
- << blockSize << ") failed." << endl;
- return false;
- }
-
- wrapper = dynamic_cast<PluginWrapper *>(plugin);
- if (wrapper) {
- // See documentation for
- // PluginInputDomainAdapter::getTimestampAdjustment
- PluginInputDomainAdapter *ida =wrapper->getWrapper<PluginInputDomainAdapter>();
- if (ida) adjustment = ida->getTimestampAdjustment();
- }
-
- //everything is prepared to start consuming data in blocks
-
- in_block=0;
- blocks_processed=0;
- currentStep=0;
-
- featureNo=1;
-
- return true;
-}
-void vampHost::Analyser::process_frame(uint8_t *data,int samples_in_frame){
- int sample=0;
-
- uint16_t *_data=(uint16_t*)data;
- //process the whole frame which may be f>1<f blocks
- //when the frame is finished leave the partial block for the next frame
- while(sample<samples_in_frame) {
- while(sample<samples_in_frame&&in_block<blockSize) {
- for (int i=0;i<channels;i++) {
- //unsigned int this_val=0;
- // this_val+=data[(sample*stride)+(i*bytes)+j]<<((1-j)*8);
- //}
- //plugbuf[i][in_block]=((float)((int16_t)this_val))*scale;
- plugbuf[i][in_block]=((float)_data[sample])*scale;
- }
- in_block++;
- sample++;
- }
- if (in_block==blockSize) {
- //block is ready to be processed
- //cerr<<plugin->getIdentifier()<<" processed block "<<blocks_processed<<endl;
-
- //I /think/ that the vamp plugin keeps processing through the plugbuf until it encounters 0s
- rt = RealTime::frame2RealTime(currentStep * stepSize, rate); //48000); //setting different rate doesn't affect it
-
- Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
-
- for (unsigned int i = 0; i < feat[outputNo].size(); ++i) {
- features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo;
- featureNo++;
- }
-
- //shunt it down
- for (int i=0;i<blockSize-stepSize;i++){
- for (int j=0;j<channels;j++){
- plugbuf[j][i]=plugbuf[j][i+stepSize];
- }
- }
-
- in_block-=stepSize;
- currentStep++;
- }
- }
-}
-void vampHost::Analyser::cleanup(){
-
- //process final block
- while(in_block<blockSize) {
- for (int i=0;i<channels;i++) {
- plugbuf[i][in_block]=0.0f;
- }
- in_block++;
- }
-
- rt = RealTime::frame2RealTime(currentStep * stepSize, rate); // //setting different
-
- Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
-
- for (unsigned int i = 0; i < feat[outputNo].size(); ++i) {
- features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo;
- featureNo++;
- }
-
- feat=plugin->getRemainingFeatures();
-
- for (unsigned int i = 0; i < feat[outputNo].size(); ++i) {
- features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo;
- featureNo++;
- }
-
- //cerr<<plugin->getIdentifier()<<" found "<<(features.size()-1)<<" features"<<endl;
- //deal with left over data?
- for (int c = 0; c < channels; ++c) {
- delete[] plugbuf[c];
- }
- delete[] plugbuf;
- delete plugin;
-}