Mercurial > hg > vamp-plugin-sdk
changeset 22:1eb44d33a371
* Rename simplehost to vamp-simple-host
* Add a temporary test for validity of plugin instances with overlapping
lifespans
author | cannam |
---|---|
date | Mon, 24 Apr 2006 12:58:27 +0000 |
parents | 16eeab18bf72 |
children | db01ce9e7657 |
files | Makefile host/simplehost.cpp host/vamp-simple-host.cpp vamp-sdk/PluginAdapter.cpp |
diffstat | 4 files changed, 529 insertions(+), 430 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Apr 14 09:37:46 2006 +0000 +++ b/Makefile Mon Apr 24 12:58:27 2006 +0000 @@ -13,7 +13,7 @@ # Compile flags # -CXXFLAGS := $(CXXFLAGS) -O2 -Wall -I$(SDKDIR) -I$(APIDIR) -I. +CXXFLAGS := $(CXXFLAGS) -g -Wall -I$(SDKDIR) -I$(APIDIR) -I. # Libraries required for the host at link time # @@ -74,10 +74,10 @@ $(HOSTDIR)/system.h HOST_OBJECTS = \ - $(HOSTDIR)/simplehost.o + $(HOSTDIR)/vamp-simple-host.o HOST_TARGET = \ - $(HOSTDIR)/simplehost + $(HOSTDIR)/vamp-simple-host all: $(SDK_TARGET) $(PLUGIN_TARGET) $(HOST_TARGET) test
--- a/host/simplehost.cpp Fri Apr 14 09:37:46 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,427 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Vamp - - An API for audio analysis and feature extraction plugins. - - Centre for Digital Music, Queen Mary, University of London. - Copyright 2006 Chris Cannam. - FFT code from Don Cross's public domain FFT implementation. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and Chris Cannam - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#include "PluginHostAdapter.h" -#include "vamp.h" - -#include <iostream> -#include <sndfile.h> - -#include "system.h" - -#include <cmath> - -using std::cout; -using std::cerr; -using std::endl; -using std::string; - -void printFeatures(int, int, int, Vamp::Plugin::FeatureSet); -void transformInput(float *, size_t); -void fft(unsigned int, bool, double *, double *, double *, double *); - -/* - A very simple Vamp plugin host. Given the name of a plugin - library and the name of a sound file on the command line, it loads - the first plugin in the library and runs it on the sound file, - dumping the plugin's first output to stdout. -*/ - -int main(int argc, char **argv) -{ - if (argc < 2 || argc > 4) { - cerr << "Usage: " << argv[0] << " pluginlibrary.so[:plugin] [file.wav] [outputno]" << endl; - return 2; - } - - cerr << endl << argv[0] << ": Running..." << endl; - - string soname = argv[1]; - string plugname = ""; - string wavname; - if (argc >= 3) wavname = argv[2]; - - int sep = soname.find(":"); - if (sep >= 0 && sep < soname.length()) { - plugname = soname.substr(sep + 1); - soname = soname.substr(0, sep); - } - - void *libraryHandle = DLOPEN(soname, RTLD_LAZY); - - if (!libraryHandle) { - cerr << argv[0] << ": Failed to open plugin library " - << soname << ": " << DLERROR() << endl; - return 1; - } - - cerr << argv[0] << ": Opened plugin library " << soname << endl; - - VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) - DLSYM(libraryHandle, "vampGetPluginDescriptor"); - - if (!fn) { - cerr << argv[0] << ": No Vamp descriptor function in library " - << soname << endl; - DLCLOSE(libraryHandle); - return 1; - } - - cerr << argv[0] << ": Found plugin descriptor function" << endl; - - int index = 0; - int plugnumber = -1; - const VampPluginDescriptor *descriptor = 0; - - while ((descriptor = fn(index))) { - - Vamp::PluginHostAdapter plugin(descriptor, 48000); - cerr << argv[0] << ": Plugin " << (index+1) - << " is \"" << plugin.getName() << "\"" << endl; - - if (plugin.getName() == plugname) plugnumber = index; - - ++index; - } - - cerr << argv[0] << ": Done\n" << endl; - - if (wavname == "") { - DLCLOSE(libraryHandle); - return 0; - } - - if (plugnumber < 0) { - if (plugname != "") { - cerr << "ERROR: No such plugin as " << plugname << " in library" - << endl; - DLCLOSE(libraryHandle); - return 0; - } else { - plugnumber = 0; - } - } - - descriptor = fn(plugnumber); - if (!descriptor) { - DLCLOSE(libraryHandle); - return 0; - } - - SNDFILE *sndfile; - SF_INFO sfinfo; - memset(&sfinfo, 0, sizeof(SF_INFO)); - - sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo); - if (!sndfile) { - cerr << "ERROR: Failed to open input file \"" << wavname << "\": " - << sf_strerror(sndfile) << endl; - DLCLOSE(libraryHandle); - return 1; - } - - Vamp::PluginHostAdapter *plugin = - new Vamp::PluginHostAdapter(descriptor, sfinfo.samplerate); - - cerr << "Running " << plugin->getName() << "..." << endl; - - int blockSize = plugin->getPreferredBlockSize(); - int stepSize = plugin->getPreferredStepSize(); - - cerr << "Preferred block size = " << blockSize << ", step size = " - << stepSize << endl; - - if (blockSize == 0) blockSize = 1024; - if (stepSize == 0) stepSize = blockSize; - - 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]; - - cerr << "Using block size = " << blockSize << ", step size = " - << stepSize << endl; - - int minch = plugin->getMinChannelCount(); - int maxch = plugin->getMaxChannelCount(); - cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl; - - Vamp::Plugin::OutputList outputs = plugin->getOutputDescriptors(); - Vamp::Plugin::OutputDescriptor od; - - int output = 0; - if (argc == 4) output = atoi(argv[3]); - - bool mix = false; - - if (minch > channels || maxch < channels) { - if (minch == 1) { - cerr << "WARNING: Sound file has " << channels << " channels, mixing down to 1" << endl; - mix = true; - channels = 1; - } else { - cerr << "ERROR: Sound file has " << channels << " channels, out of range for plugin" << endl; - goto done; - } - } - - if (outputs.empty()) { - cerr << "Plugin has no outputs!" << endl; - goto done; - } - - if (int(outputs.size()) <= output) { - cerr << "Output " << output << " requested, but plugin has only " << outputs.size() << " output(s)" << endl; - goto done; - } - - od = outputs[output]; - cerr << "Output is " << od.name << endl; - - plugin->initialise(channels, stepSize, blockSize); - - for (size_t i = 0; i < sfinfo.frames; i += stepSize) { - - int count; - - if (sf_seek(sndfile, i, SEEK_SET) < 0) { - cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl; - break; - } - - if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) { - cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl; - break; - } - - for (int c = 0; c < channels; ++c) { - for (int j = 0; j < blockSize; ++j) { - plugbuf[c][j] = 0.0f; - } - } - - for (int c = 0; c < sfinfo.channels; ++c) { - int tc = c; - if (mix) tc = 0; - for (int j = 0; j < blockSize && j < count; ++j) { - plugbuf[tc][j] += filebuf[j * channels + c]; - } - - if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) { - transformInput(plugbuf[tc], blockSize); - } - } - - printFeatures - (i, sfinfo.samplerate, output, plugin->process - (plugbuf, Vamp::RealTime::frame2RealTime(i, sfinfo.samplerate))); - } - - printFeatures(sfinfo.frames, sfinfo.samplerate, output, - plugin->getRemainingFeatures()); - -done: - delete plugin; - - DLCLOSE(libraryHandle); - sf_close(sndfile); - return 0; -} - -void -printFeatures(int frame, int sr, int output, Vamp::Plugin::FeatureSet features) -{ - for (unsigned int i = 0; i < features[output].size(); ++i) { - Vamp::RealTime rt = Vamp::RealTime::frame2RealTime(frame, sr); - if (features[output][i].hasTimestamp) { - rt = features[output][i].timestamp; - } - cout << rt.toString() << ":"; - for (unsigned int j = 0; j < features[output][i].values.size(); ++j) { - cout << " " << features[output][i].values[j]; - } - cout << endl; - } -} - -void -transformInput(float *buffer, size_t size) -{ - double *inbuf = new double[size * 2]; - double *outbuf = new double[size * 2]; - - // Copy across with Hanning window - for (size_t i = 0; i < size; ++i) { - inbuf[i] = double(buffer[i]) * (0.50 - 0.50 * cos(2 * M_PI * i / size)); - inbuf[i + size] = 0.0; - } - - for (size_t i = 0; i < size/2; ++i) { - double temp = inbuf[i]; - inbuf[i] = inbuf[i + size/2]; - inbuf[i + size/2] = temp; - } - - fft(size, false, inbuf, inbuf + size, outbuf, outbuf + size); - - for (size_t i = 0; i < size/2; ++i) { - buffer[i * 2] = outbuf[i]; - buffer[i * 2 + 1] = outbuf[i + size]; - } - - delete inbuf; - delete outbuf; -} - -void -fft(unsigned int n, bool inverse, double *ri, double *ii, double *ro, double *io) -{ - if (!ri || !ro || !io) return; - - unsigned int bits; - unsigned int i, j, k, m; - unsigned int blockSize, blockEnd; - - double tr, ti; - - if (n < 2) return; - if (n & (n-1)) return; - - double angle = 2.0 * M_PI; - if (inverse) angle = -angle; - - for (i = 0; ; ++i) { - if (n & (1 << i)) { - bits = i; - break; - } - } - - static unsigned int tableSize = 0; - static int *table = 0; - - if (tableSize != n) { - - delete[] table; - - table = new int[n]; - - for (i = 0; i < n; ++i) { - - m = i; - - for (j = k = 0; j < bits; ++j) { - k = (k << 1) | (m & 1); - m >>= 1; - } - - table[i] = k; - } - - tableSize = n; - } - - if (ii) { - for (i = 0; i < n; ++i) { - ro[table[i]] = ri[i]; - io[table[i]] = ii[i]; - } - } else { - for (i = 0; i < n; ++i) { - ro[table[i]] = ri[i]; - io[table[i]] = 0.0; - } - } - - blockEnd = 1; - - for (blockSize = 2; blockSize <= n; blockSize <<= 1) { - - double delta = angle / (double)blockSize; - double sm2 = -sin(-2 * delta); - double sm1 = -sin(-delta); - double cm2 = cos(-2 * delta); - double cm1 = cos(-delta); - double w = 2 * cm1; - double ar[3], ai[3]; - - for (i = 0; i < n; i += blockSize) { - - ar[2] = cm2; - ar[1] = cm1; - - ai[2] = sm2; - ai[1] = sm1; - - for (j = i, m = 0; m < blockEnd; j++, m++) { - - ar[0] = w * ar[1] - ar[2]; - ar[2] = ar[1]; - ar[1] = ar[0]; - - ai[0] = w * ai[1] - ai[2]; - ai[2] = ai[1]; - ai[1] = ai[0]; - - k = j + blockEnd; - tr = ar[0] * ro[k] - ai[0] * io[k]; - ti = ar[0] * io[k] + ai[0] * ro[k]; - - ro[k] = ro[j] - tr; - io[k] = io[j] - ti; - - ro[j] += tr; - io[j] += ti; - } - } - - blockEnd = blockSize; - } - - if (inverse) { - - double denom = (double)n; - - for (i = 0; i < n; i++) { - ro[i] /= denom; - io[i] /= denom; - } - } -} - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host/vamp-simple-host.cpp Mon Apr 24 12:58:27 2006 +0000 @@ -0,0 +1,433 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + FFT code from Don Cross's public domain FFT implementation. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginHostAdapter.h" +#include "vamp.h" + +#include <iostream> +#include <sndfile.h> + +#include "system.h" + +#include <cmath> + +using std::cout; +using std::cerr; +using std::endl; +using std::string; + +void printFeatures(int, int, int, Vamp::Plugin::FeatureSet); +void transformInput(float *, size_t); +void fft(unsigned int, bool, double *, double *, double *, double *); + +/* + A very simple Vamp plugin host. Given the name of a plugin + library and the name of a sound file on the command line, it loads + the first plugin in the library and runs it on the sound file, + dumping the plugin's first output to stdout. +*/ + +int main(int argc, char **argv) +{ + if (argc < 2 || argc > 4) { + cerr << "Usage: " << argv[0] << " pluginlibrary.so[:plugin] [file.wav] [outputno]" << endl; + return 2; + } + + cerr << endl << argv[0] << ": Running..." << endl; + + string soname = argv[1]; + string plugname = ""; + string wavname; + if (argc >= 3) wavname = argv[2]; + + int sep = soname.find(":"); + if (sep >= 0 && sep < soname.length()) { + plugname = soname.substr(sep + 1); + soname = soname.substr(0, sep); + } + + void *libraryHandle = DLOPEN(soname, RTLD_LAZY); + + if (!libraryHandle) { + cerr << argv[0] << ": Failed to open plugin library " + << soname << ": " << DLERROR() << endl; + return 1; + } + + cerr << argv[0] << ": Opened plugin library " << soname << endl; + + VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) + DLSYM(libraryHandle, "vampGetPluginDescriptor"); + + if (!fn) { + cerr << argv[0] << ": No Vamp descriptor function in library " + << soname << endl; + DLCLOSE(libraryHandle); + return 1; + } + + cerr << argv[0] << ": Found plugin descriptor function" << endl; + + int index = 0; + int plugnumber = -1; + const VampPluginDescriptor *descriptor = 0; + + while ((descriptor = fn(index))) { + + Vamp::PluginHostAdapter plugin(descriptor, 48000); + cerr << argv[0] << ": Plugin " << (index+1) + << " is \"" << plugin.getName() << "\"" << endl; + + if (plugin.getName() == plugname) plugnumber = index; + + cerr << "(testing overlap...)" << endl; + { + Vamp::PluginHostAdapter otherPlugin(descriptor, 48000); + cerr << "(other plugin reports min " << otherPlugin.getMinChannelCount() << " channels)" << endl; + } + + ++index; + } + + cerr << argv[0] << ": Done\n" << endl; + + if (wavname == "") { + DLCLOSE(libraryHandle); + return 0; + } + + if (plugnumber < 0) { + if (plugname != "") { + cerr << "ERROR: No such plugin as " << plugname << " in library" + << endl; + DLCLOSE(libraryHandle); + return 0; + } else { + plugnumber = 0; + } + } + + descriptor = fn(plugnumber); + if (!descriptor) { + DLCLOSE(libraryHandle); + return 0; + } + + SNDFILE *sndfile; + SF_INFO sfinfo; + memset(&sfinfo, 0, sizeof(SF_INFO)); + + sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo); + if (!sndfile) { + cerr << "ERROR: Failed to open input file \"" << wavname << "\": " + << sf_strerror(sndfile) << endl; + DLCLOSE(libraryHandle); + return 1; + } + + Vamp::PluginHostAdapter *plugin = + new Vamp::PluginHostAdapter(descriptor, sfinfo.samplerate); + + cerr << "Running " << plugin->getName() << "..." << endl; + + int blockSize = plugin->getPreferredBlockSize(); + int stepSize = plugin->getPreferredStepSize(); + + cerr << "Preferred block size = " << blockSize << ", step size = " + << stepSize << endl; + + if (blockSize == 0) blockSize = 1024; + if (stepSize == 0) stepSize = blockSize; + + 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]; + + cerr << "Using block size = " << blockSize << ", step size = " + << stepSize << endl; + + int minch = plugin->getMinChannelCount(); + int maxch = plugin->getMaxChannelCount(); + cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl; + + Vamp::Plugin::OutputList outputs = plugin->getOutputDescriptors(); + Vamp::Plugin::OutputDescriptor od; + + int output = 0; + if (argc == 4) output = atoi(argv[3]); + + bool mix = false; + + if (minch > channels || maxch < channels) { + if (minch == 1) { + cerr << "WARNING: Sound file has " << channels << " channels, mixing down to 1" << endl; + mix = true; + channels = 1; + } else { + cerr << "ERROR: Sound file has " << channels << " channels, out of range for plugin" << endl; + goto done; + } + } + + if (outputs.empty()) { + cerr << "Plugin has no outputs!" << endl; + goto done; + } + + if (int(outputs.size()) <= output) { + cerr << "Output " << output << " requested, but plugin has only " << outputs.size() << " output(s)" << endl; + goto done; + } + + od = outputs[output]; + cerr << "Output is " << od.name << endl; + + plugin->initialise(channels, stepSize, blockSize); + + for (size_t i = 0; i < sfinfo.frames; i += stepSize) { + + int count; + + if (sf_seek(sndfile, i, SEEK_SET) < 0) { + cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl; + break; + } + + if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) { + cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl; + break; + } + + for (int c = 0; c < channels; ++c) { + for (int j = 0; j < blockSize; ++j) { + plugbuf[c][j] = 0.0f; + } + } + + for (int c = 0; c < sfinfo.channels; ++c) { + int tc = c; + if (mix) tc = 0; + for (int j = 0; j < blockSize && j < count; ++j) { + plugbuf[tc][j] += filebuf[j * channels + c]; + } + + if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) { + transformInput(plugbuf[tc], blockSize); + } + } + + printFeatures + (i, sfinfo.samplerate, output, plugin->process + (plugbuf, Vamp::RealTime::frame2RealTime(i, sfinfo.samplerate))); + } + + printFeatures(sfinfo.frames, sfinfo.samplerate, output, + plugin->getRemainingFeatures()); + +done: + delete plugin; + + DLCLOSE(libraryHandle); + sf_close(sndfile); + return 0; +} + +void +printFeatures(int frame, int sr, int output, Vamp::Plugin::FeatureSet features) +{ + for (unsigned int i = 0; i < features[output].size(); ++i) { + Vamp::RealTime rt = Vamp::RealTime::frame2RealTime(frame, sr); + if (features[output][i].hasTimestamp) { + rt = features[output][i].timestamp; + } + cout << rt.toString() << ":"; + for (unsigned int j = 0; j < features[output][i].values.size(); ++j) { + cout << " " << features[output][i].values[j]; + } + cout << endl; + } +} + +void +transformInput(float *buffer, size_t size) +{ + double *inbuf = new double[size * 2]; + double *outbuf = new double[size * 2]; + + // Copy across with Hanning window + for (size_t i = 0; i < size; ++i) { + inbuf[i] = double(buffer[i]) * (0.50 - 0.50 * cos(2 * M_PI * i / size)); + inbuf[i + size] = 0.0; + } + + for (size_t i = 0; i < size/2; ++i) { + double temp = inbuf[i]; + inbuf[i] = inbuf[i + size/2]; + inbuf[i + size/2] = temp; + } + + fft(size, false, inbuf, inbuf + size, outbuf, outbuf + size); + + for (size_t i = 0; i < size/2; ++i) { + buffer[i * 2] = outbuf[i]; + buffer[i * 2 + 1] = outbuf[i + size]; + } + + delete inbuf; + delete outbuf; +} + +void +fft(unsigned int n, bool inverse, double *ri, double *ii, double *ro, double *io) +{ + if (!ri || !ro || !io) return; + + unsigned int bits; + unsigned int i, j, k, m; + unsigned int blockSize, blockEnd; + + double tr, ti; + + if (n < 2) return; + if (n & (n-1)) return; + + double angle = 2.0 * M_PI; + if (inverse) angle = -angle; + + for (i = 0; ; ++i) { + if (n & (1 << i)) { + bits = i; + break; + } + } + + static unsigned int tableSize = 0; + static int *table = 0; + + if (tableSize != n) { + + delete[] table; + + table = new int[n]; + + for (i = 0; i < n; ++i) { + + m = i; + + for (j = k = 0; j < bits; ++j) { + k = (k << 1) | (m & 1); + m >>= 1; + } + + table[i] = k; + } + + tableSize = n; + } + + if (ii) { + for (i = 0; i < n; ++i) { + ro[table[i]] = ri[i]; + io[table[i]] = ii[i]; + } + } else { + for (i = 0; i < n; ++i) { + ro[table[i]] = ri[i]; + io[table[i]] = 0.0; + } + } + + blockEnd = 1; + + for (blockSize = 2; blockSize <= n; blockSize <<= 1) { + + double delta = angle / (double)blockSize; + double sm2 = -sin(-2 * delta); + double sm1 = -sin(-delta); + double cm2 = cos(-2 * delta); + double cm1 = cos(-delta); + double w = 2 * cm1; + double ar[3], ai[3]; + + for (i = 0; i < n; i += blockSize) { + + ar[2] = cm2; + ar[1] = cm1; + + ai[2] = sm2; + ai[1] = sm1; + + for (j = i, m = 0; m < blockEnd; j++, m++) { + + ar[0] = w * ar[1] - ar[2]; + ar[2] = ar[1]; + ar[1] = ar[0]; + + ai[0] = w * ai[1] - ai[2]; + ai[2] = ai[1]; + ai[1] = ai[0]; + + k = j + blockEnd; + tr = ar[0] * ro[k] - ai[0] * io[k]; + ti = ar[0] * io[k] + ai[0] * ro[k]; + + ro[k] = ro[j] - tr; + io[k] = io[j] - ti; + + ro[j] += tr; + io[j] += ti; + } + } + + blockEnd = blockSize; + } + + if (inverse) { + + double denom = (double)n; + + for (i = 0; i < n; i++) { + ro[i] /= denom; + io[i] /= denom; + } + } +} + +
--- a/vamp-sdk/PluginAdapter.cpp Fri Apr 14 09:37:46 2006 +0000 +++ b/vamp-sdk/PluginAdapter.cpp Mon Apr 24 12:58:27 2006 +0000 @@ -36,16 +36,26 @@ #include "PluginAdapter.h" +#define DEBUG_PLUGIN_ADAPTER 1 + + namespace Vamp { PluginAdapterBase::PluginAdapterBase() : m_populated(false) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase[" << this << "]::PluginAdapterBase" << std::endl; +#endif } const VampPluginDescriptor * PluginAdapterBase::getDescriptor() { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase[" << this << "]::getDescriptor" << std::endl; +#endif + if (m_populated) return &m_descriptor; Plugin *plugin = createPlugin(48000); @@ -134,6 +144,10 @@ PluginAdapterBase::~PluginAdapterBase() { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase[" << this << "]::~PluginAdapterBase" << std::endl; +#endif + if (!m_populated) return; free((void *)m_descriptor.name); @@ -174,6 +188,10 @@ PluginAdapterBase * PluginAdapterBase::lookupAdapter(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::lookupAdapter(" << handle << ")" << std::endl; +#endif + if (!m_adapterMap) return 0; AdapterMap::const_iterator i = m_adapterMap->find(handle); if (i == m_adapterMap->end()) return 0; @@ -184,6 +202,10 @@ PluginAdapterBase::vampInstantiate(const VampPluginDescriptor *desc, float inputSampleRate) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampInstantiate(" << desc << ")" << std::endl; +#endif + if (!m_adapterMap) { m_adapterMap = new AdapterMap(); } @@ -201,12 +223,20 @@ (*m_adapterMap)[plugin] = adapter; } +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl; +#endif + return plugin; } void PluginAdapterBase::vampCleanup(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampCleanup(" << handle << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) { delete ((Plugin *)handle); @@ -221,6 +251,10 @@ unsigned int stepSize, unsigned int blockSize) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl; +#endif + bool result = ((Plugin *)handle)->initialise (channels, stepSize, blockSize); return result ? 1 : 0; @@ -229,6 +263,10 @@ void PluginAdapterBase::vampReset(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampReset(" << handle << ")" << std::endl; +#endif + ((Plugin *)handle)->reset(); } @@ -236,6 +274,10 @@ PluginAdapterBase::vampGetParameter(VampPluginHandle handle, int param) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetParameter(" << handle << ", " << param << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) return 0.0; Plugin::ParameterList &list = adapter->m_parameters; @@ -246,6 +288,10 @@ PluginAdapterBase::vampSetParameter(VampPluginHandle handle, int param, float value) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) return; Plugin::ParameterList &list = adapter->m_parameters; @@ -255,6 +301,10 @@ unsigned int PluginAdapterBase::vampGetCurrentProgram(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetCurrentProgram(" << handle << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) return 0; Plugin::ProgramList &list = adapter->m_programs; @@ -269,6 +319,10 @@ PluginAdapterBase::vampSelectProgram(VampPluginHandle handle, unsigned int program) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampSelectProgram(" << handle << ", " << program << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) return; Plugin::ProgramList &list = adapter->m_programs; @@ -278,30 +332,50 @@ unsigned int PluginAdapterBase::vampGetPreferredStepSize(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetPreferredStepSize(" << handle << ")" << std::endl; +#endif + return ((Plugin *)handle)->getPreferredStepSize(); } unsigned int PluginAdapterBase::vampGetPreferredBlockSize(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetPreferredBlockSize(" << handle << ")" << std::endl; +#endif + return ((Plugin *)handle)->getPreferredBlockSize(); } unsigned int PluginAdapterBase::vampGetMinChannelCount(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetMinChannelCount(" << handle << ")" << std::endl; +#endif + return ((Plugin *)handle)->getMinChannelCount(); } unsigned int PluginAdapterBase::vampGetMaxChannelCount(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetMaxChannelCount(" << handle << ")" << std::endl; +#endif + return ((Plugin *)handle)->getMaxChannelCount(); } unsigned int PluginAdapterBase::vampGetOutputCount(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetOutputCount(" << handle << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl; @@ -314,6 +388,10 @@ PluginAdapterBase::vampGetOutputDescriptor(VampPluginHandle handle, unsigned int i) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl; @@ -325,6 +403,10 @@ void PluginAdapterBase::vampReleaseOutputDescriptor(VampOutputDescriptor *desc) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampReleaseOutputDescriptor(" << desc << ")" << std::endl; +#endif + if (desc->name) free((void *)desc->name); if (desc->description) free((void *)desc->description); if (desc->unit) free((void *)desc->unit); @@ -341,6 +423,10 @@ int sec, int nsec) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) return 0; return adapter->process((Plugin *)handle, @@ -350,6 +436,10 @@ VampFeatureList * PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampGetRemainingFeatures(" << handle << ")" << std::endl; +#endif + PluginAdapterBase *adapter = lookupAdapter(handle); if (!adapter) return 0; return adapter->getRemainingFeatures((Plugin *)handle); @@ -358,6 +448,9 @@ void PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList *fs) { +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::vampReleaseFeatureSet" << std::endl; +#endif } void