Mercurial > hg > tuning-difference
changeset 1:141bda033074
First hack at it
author | Chris Cannam |
---|---|
date | Fri, 23 Jan 2015 18:17:09 +0000 |
parents | 8a8d8c1f3968 |
children | c8f872a620be |
files | Makefile.inc TuningDifference.cpp TuningDifference.h |
diffstat | 3 files changed, 99 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.inc Fri Jan 23 17:41:22 2015 +0000 +++ b/Makefile.inc Fri Jan 23 18:17:09 2015 +0000 @@ -71,3 +71,7 @@ depend: makedepend -Y -fMakefile.inc $(PLUGIN_SOURCES) $(PLUGIN_HEADERS) +# DO NOT DELETE + +TuningDifference.o: TuningDifference.h +plugins.o: TuningDifference.h
--- a/TuningDifference.cpp Fri Jan 23 17:41:22 2015 +0000 +++ b/TuningDifference.cpp Fri Jan 23 18:17:09 2015 +0000 @@ -1,6 +1,11 @@ #include "TuningDifference.h" +#include <iostream> + +using std::cerr; +using std::endl; + TuningDifference::TuningDifference(float inputSampleRate) : Plugin(inputSampleRate) @@ -14,13 +19,13 @@ string TuningDifference::getIdentifier() const { - return "myplugin"; + return "tuning-difference"; } string TuningDifference::getName() const { - return "My Plugin"; + return "Tuning Difference"; } string @@ -58,90 +63,55 @@ TuningDifference::InputDomain TuningDifference::getInputDomain() const { - return TimeDomain; + return FrequencyDomain; } size_t TuningDifference::getPreferredBlockSize() const { - return 0; // 0 means "I can handle any block size" + return 16386; } size_t TuningDifference::getPreferredStepSize() const { - return 0; // 0 means "anything sensible"; in practice this - // means the same as the block size for TimeDomain - // plugins, or half of it for FrequencyDomain plugins + return 0; } size_t TuningDifference::getMinChannelCount() const { - return 1; + return 2; } size_t TuningDifference::getMaxChannelCount() const { - return 1; + return 2; } TuningDifference::ParameterList TuningDifference::getParameterDescriptors() const { ParameterList list; - - // If the plugin has no adjustable parameters, return an empty - // list here (and there's no need to provide implementations of - // getParameter and setParameter in that case either). - - // Note that it is your responsibility to make sure the parameters - // start off having their default values (e.g. in the constructor - // above). The host needs to know the default value so it can do - // things like provide a "reset to default" function, but it will - // not explicitly set your parameters to their defaults for you if - // they have not changed in the mean time. - - ParameterDescriptor d; - d.identifier = "parameter"; - d.name = "Some Parameter"; - d.description = ""; - d.unit = ""; - d.minValue = 0; - d.maxValue = 10; - d.defaultValue = 5; - d.isQuantized = false; - list.push_back(d); - return list; } float -TuningDifference::getParameter(string identifier) const +TuningDifference::getParameter(string) const { - if (identifier == "parameter") { - return 5; // return the ACTUAL current value of your parameter here! - } return 0; } void -TuningDifference::setParameter(string identifier, float value) +TuningDifference::setParameter(string, float) { - if (identifier == "parameter") { - // set the actual value of your parameter - } } TuningDifference::ProgramList TuningDifference::getPrograms() const { ProgramList list; - - // If you have no programs, return an empty list (or simply don't - // implement this function or getCurrentProgram/selectProgram) - return list; } @@ -152,7 +122,7 @@ } void -TuningDifference::selectProgram(string name) +TuningDifference::selectProgram(string) { } @@ -161,19 +131,41 @@ { OutputList list; - // See OutputDescriptor documentation for the possibilities here. - // Every plugin must have at least one output. + OutputDescriptor d; + d.identifier = "cents"; + d.name = "Tuning Difference"; + d.description = "Difference in averaged frequency profile between channels 1 and 2, in cents. A positive value means channel 2 is higher."; + d.unit = "cents"; + d.hasFixedBinCount = true; + d.binCount = 1; + d.hasKnownExtents = false; + d.isQuantized = false; + d.sampleType = OutputDescriptor::VariableSampleRate; + d.hasDuration = false; + list.push_back(d); - OutputDescriptor d; - d.identifier = "output"; - d.name = "My Output"; + d.identifier = "tuningfreq"; + d.name = "Relative Tuning Frequency"; + d.description = "Tuning frequency of channel 2, if channel 1 is assumed to contain the same music as it at a tuning frequency of A=440Hz."; + d.unit = "cents"; + d.hasFixedBinCount = true; + d.binCount = 1; + d.hasKnownExtents = false; + d.isQuantized = false; + d.sampleType = OutputDescriptor::VariableSampleRate; + d.hasDuration = false; + list.push_back(d); + + d.identifier = "correlation"; + d.name = "Frequency-shift correlation curve"; d.description = ""; d.unit = ""; d.hasFixedBinCount = true; d.binCount = 1; d.hasKnownExtents = false; d.isQuantized = false; - d.sampleType = OutputDescriptor::OneSamplePerStep; + d.sampleType = OutputDescriptor::FixedSampleRate; + d.sampleRate = 100; d.hasDuration = false; list.push_back(d); @@ -186,27 +178,71 @@ if (channels < getMinChannelCount() || channels > getMaxChannelCount()) return false; - // Real initialisation work goes here! + if (blockSize != getPreferredBlockSize() || + stepSize != blockSize/2) return false; + m_blockSize = blockSize; + + reset(); + return true; } void TuningDifference::reset() { - // Clear buffers, reset stored values, etc + m_sum[0].clear(); + m_sum[1].clear(); + m_frameCount = 0; } TuningDifference::FeatureSet TuningDifference::process(const float *const *inputBuffers, Vamp::RealTime timestamp) { - // Do actual work! + for (int c = 0; c < 2; ++c) { + m_sum[c].resize(m_blockSize/2 - 1); + for (int i = 1; i < m_blockSize/2; ++i) { // discarding DC and Nyquist + double energy = + inputBuffers[c][i*2 ] * inputBuffers[c][i*2 ] + + inputBuffers[c][i*2+1] * inputBuffers[c][i*2+1]; + m_sum[c][i-1] += energy; + } + } + + ++m_frameCount; return FeatureSet(); } TuningDifference::FeatureSet TuningDifference::getRemainingFeatures() { - return FeatureSet(); + int n = m_sum[0].size(); + if (n == 0) return FeatureSet(); + + Feature f; + FeatureSet fs; + + vector<double> corr(n * 2 - 1, 0.0); + for (int shift = -(n-1); shift <= n-1; ++shift) { + int index = shift + n-1; + int count = 0; + cerr << "index = " << index << ", n = " << n << endl; + for (int i = 0; i < n; ++i) { + int j = i + shift; + if (j >= 0 && j < n) { + corr[index] += m_sum[1][i] * m_sum[0][j]; + ++count; + } + } + if (count > 0) { + corr[index] /= count; + } + f.values.clear(); + cerr << "value = " << corr[index] << endl; + f.values.push_back(corr[index]); + fs[2].push_back(f); + } + + return fs; }
--- a/TuningDifference.h Fri Jan 23 17:41:22 2015 +0000 +++ b/TuningDifference.h Fri Jan 23 18:17:09 2015 +0000 @@ -4,7 +4,7 @@ #include <vamp-sdk/Plugin.h> using std::string; - +using std::vector; class TuningDifference : public Vamp::Plugin { @@ -44,7 +44,9 @@ FeatureSet getRemainingFeatures(); protected: - // plugin-specific data and methods go here + int m_blockSize; + vector<double> m_sum[2]; + int m_frameCount; };