summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rotord/vampHost.cpp102
-rw-r--r--rotord/vampHost.h2
2 files changed, 95 insertions, 9 deletions
diff --git a/rotord/vampHost.cpp b/rotord/vampHost.cpp
index 805481c..21f5db5 100644
--- a/rotord/vampHost.cpp
+++ b/rotord/vampHost.cpp
@@ -643,6 +643,7 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_
currentStep = 0;
finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
+ filebuf = new float[blockSize * channels];
plugbuf = new float*[channels];
for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
@@ -721,9 +722,66 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_
}
void vampHost::Analyser::process_frame(uint8_t *data,int samples_in_frame){
int sample=0;
- RealTime rt;
+
//process the whole frame which may be f>1<f blocks
//when the frame is finished leave the partial block for the next frame
+
+ //seems that the vamp plugin needs to be given a block context bigger than the step that it processes
+ /*
+ each frame that comes in contains samples_in_frame samples (samples*bytes*channels data)
+ we may have part of a block remaining from the previous frames/s
+
+ filebuf is filled from incoming frames
+
+ when filebuf is full, fill plugbuf from filebuf (necessary?)
+
+ the point is, each step is smaller than a block, but we manage the steps and blocks- seems a bit stupid
+
+ after each processing step, 'shunt down' the data and prepare the pointer to fill the next
+
+
+ ///
+ 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);
+
+ ///
+
+
+ */
+
+
+
while(sample<samples_in_frame) {
while(sample<samples_in_frame&&in_block<blockSize) {
for (int i=0;i<channels;i++) {
@@ -737,11 +795,7 @@ void vampHost::Analyser::process_frame(uint8_t *data,int samples_in_frame){
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(in_block * stepSize, rate);
+ rt = RealTime::frame2RealTime(currentStep * stepSize, rate);
Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
@@ -750,14 +804,44 @@ void vampHost::Analyser::process_frame(uint8_t *data,int samples_in_frame){
featureNo++;
}
- //all good but no features! what gives?
+ in_block-=stepSize;
+ currentStep++;
- in_block=0;
- blocks_processed++;
+ //shunt down the data
+
+ for (int i=0;i<in_block;i++){
+ for (int j=0;j<channels;j++){
+ plugbuf[j][i]=plugbuf[j][i+stepSize];
+ }
+ }
}
}
}
void vampHost::Analyser::cleanup(){
+
+ //fill remainder of final block with zeroes
+ for (int i=in_block;i<blockSize;i++){
+ for (int j=0;j<channels;j++){
+ plugbuf[j][i]=0.0f;
+ }
+ }
+
+ rt = RealTime::frame2RealTime(currentStep * stepSize, rate);
+
+ 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()<<" features"<<endl;
//deal with left over data?
for (int c = 0; c < channels; ++c) {
diff --git a/rotord/vampHost.h b/rotord/vampHost.h
index f6693a9..c632e44 100644
--- a/rotord/vampHost.h
+++ b/rotord/vampHost.h
@@ -69,7 +69,9 @@ namespace vampHost {
int blockSize,stepSize,overlapSize,finalStepsRemaining,currentStep,outputNo;
int in_block,blocks_processed;
string output;
+ float *filebuf;
float **plugbuf;
+ RealTime rt;
int featureNo;
map<float,int> features;