Mercurial > hg > pyin
changeset 21:70dd2b4e776b interactive
in a hacky way, very basic constraining of frequencies for a certain time period seems to work now
author | matthiasm |
---|---|
date | Fri, 17 Jan 2014 12:09:28 +0000 |
parents | 1625cc4f4221 |
children | 12cab92b7c26 |
files | Makefile.osx PYIN.cpp PYIN.h Yin.cpp Yin.h YinUtil.cpp YinUtil.h |
diffstat | 7 files changed, 163 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.osx Fri Dec 06 16:19:26 2013 +0000 +++ b/Makefile.osx Fri Jan 17 12:09:28 2014 +0000 @@ -1,4 +1,4 @@ -ARCHFLAGS := -arch x86_64 -arch i386 -mmacosx-version-min=10.7 +ARCHFLAGS := -arch x86_64 -mmacosx-version-min=10.7 CFLAGS := $(ARCHFLAGS) -O3 -I../vamp-plugin-sdk -I/usr/local/boost -Wall -fPIC CXXFLAGS := $(CFLAGS)
--- a/PYIN.cpp Fri Dec 06 16:19:26 2013 +0000 +++ b/PYIN.cpp Fri Jan 17 12:09:28 2014 +0000 @@ -45,8 +45,13 @@ m_oNotes(0), m_threshDistr(2.0f), m_outputUnvoiced(0.0f), + m_minLocalFreq(0.f), + m_maxLocalFreq(5000.f), + m_leftBoundary(0.f), + m_rightBoundary(5000.f), // hack m_pitchProb(0), - m_timestamp(0) + m_timestamp(0), + m_currentProgram("") { } @@ -162,6 +167,58 @@ d.valueNames.push_back("Yes"); d.valueNames.push_back("Yes, as negative frequencies"); list.push_back(d); + + d.identifier = "minlocalfreq"; + d.valueNames.clear(); + d.name = "Minimum local frequency."; + d.description = "Minimum frequency in selection."; + d.unit = ""; + d.minValue = 50.f; + d.maxValue = 5000.f; + d.defaultValue = 50.f; + d.isQuantized = false; + d.quantizeStep = 0; + d.valueNames.clear(); + list.push_back(d); + + d.identifier = "maxlocalfreq"; + d.valueNames.clear(); + d.name = "Maximum local frequency."; + d.description = "Maximum frequency in selection."; + d.unit = ""; + d.minValue = 50.f; + d.maxValue = 5000.f; + d.defaultValue = 5000.f; + d.isQuantized = false; + d.quantizeStep = 0; + d.valueNames.clear(); + list.push_back(d); + + d.identifier = "leftboundary"; + d.valueNames.clear(); + d.name = "Left boundary."; + d.description = "Left boundary of time selection."; + d.unit = ""; + d.minValue = 0.f; + d.maxValue = 1000.f; + d.defaultValue = 0.f; + d.isQuantized = false; + d.quantizeStep = 0; + d.valueNames.clear(); + list.push_back(d); + + d.identifier = "rightboundary"; + d.valueNames.clear(); + d.name = "Right boundary."; + d.description = "Right boundary of time selection."; + d.unit = ""; + d.minValue = 0.f; + d.maxValue = 1000.f; + d.defaultValue = 0.f; + d.isQuantized = false; + d.quantizeStep = 0; + d.valueNames.clear(); + list.push_back(d); return list; } @@ -175,12 +232,25 @@ if (identifier == "outputunvoiced") { return m_outputUnvoiced; } + if (identifier == "minlocalfreq") { + return m_minLocalFreq; + } + if (identifier == "maxlocalfreq") { + return m_maxLocalFreq; + } + if (identifier == "leftboundary") { + return m_leftBoundary; + } + if (identifier == "rightboundary") { + return m_rightBoundary; + } return 0.f; } void PYIN::setParameter(string identifier, float value) { + m_currentProgram = "custom"; if (identifier == "threshdistr") { m_threshDistr = value; @@ -189,25 +259,60 @@ { m_outputUnvoiced = value; } - + if (identifier == "minlocalfreq") + { + m_minLocalFreq = value; + } + if (identifier == "maxlocalfreq") + { + m_maxLocalFreq = value; + } + if (identifier == "leftboundary") + { + m_leftBoundary = value; + } + if (identifier == "rightboundary") + { + m_rightBoundary = value; + } } PYIN::ProgramList PYIN::getPrograms() const { ProgramList list; + list.push_back("default"); + list.push_back("custom"); + list.push_back("donttellme"); return list; } string PYIN::getCurrentProgram() const { - return ""; // no programs + return m_currentProgram; } void PYIN::selectProgram(string name) { + if (name == "default") { + m_minLocalFreq = 0; + m_maxLocalFreq = 10000; + m_leftBoundary = 0; + m_rightBoundary = 5000; + } + if (name == "custom") { + // do nothing + } + if (name == "donttellme") + { + m_currentProgram = "donttellme"; + m_minLocalFreq = 0; + m_maxLocalFreq = 400; + m_leftBoundary = 1.9; + m_rightBoundary = 2.9; + } } PYIN::OutputList @@ -360,7 +465,16 @@ double *dInputBuffers = new double[m_blockSize]; for (size_t i = 0; i < m_blockSize; ++i) dInputBuffers[i] = inputBuffers[0][i]; - Yin::YinOutput yo = m_yin.processProbabilisticYin(dInputBuffers); + Yin::YinOutput yo; + float floatTime = timestamp.sec + timestamp.nsec * 1.0 / 1000000000; + std::cerr << timestamp << " " << floatTime << std::endl; + if (floatTime > m_leftBoundary && floatTime < m_rightBoundary) { + // constrained + yo = m_yin.processProbabilisticYin(dInputBuffers, m_minLocalFreq, m_maxLocalFreq); + } else { + yo = m_yin.processProbabilisticYin(dInputBuffers); + } + Feature f; f.hasTimestamp = true;
--- a/PYIN.h Fri Dec 06 16:19:26 2013 +0000 +++ b/PYIN.h Fri Jan 17 12:09:28 2014 +0000 @@ -72,8 +72,13 @@ float m_threshDistr; float m_outputUnvoiced; + float m_minLocalFreq; + float m_maxLocalFreq; + float m_leftBoundary; + float m_rightBoundary; vector<vector<pair<double, double> > > m_pitchProb; vector<Vamp::RealTime> m_timestamp; + std::string m_currentProgram; }; #endif
--- a/Yin.cpp Fri Dec 06 16:19:26 2013 +0000 +++ b/Yin.cpp Fri Jan 17 12:09:28 2014 +0000 @@ -81,7 +81,7 @@ } Yin::YinOutput -Yin::processProbabilisticYin(const double *in) const { +Yin::processProbabilisticYin(const double *in, float minFreq, float maxFreq) const { double* yinBuffer = new double[m_yinBufferSize]; @@ -89,7 +89,18 @@ YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize); YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize); - vector<double> peakProbability = YinUtil::yinProb(yinBuffer, m_threshDistr, m_yinBufferSize); + vector<double> peakProbability; + if ((minFreq < 0 && maxFreq < 0) || maxFreq < minFreq) + { + peakProbability = YinUtil::yinProb(yinBuffer, m_threshDistr, m_yinBufferSize); + } else { + if (minFreq < 0) minFreq = 0; + if (maxFreq < 0) maxFreq = m_inputSampleRate / 2; + int minTau = m_inputSampleRate / maxFreq; + int maxTau = m_inputSampleRate / minFreq; + peakProbability = YinUtil::yinProb(yinBuffer, m_threshDistr, m_yinBufferSize, minTau, maxTau); + } + // calculate overall "probability" from peak probability double probSum = 0;
--- a/Yin.h Fri Dec 06 16:19:26 2013 +0000 +++ b/Yin.h Fri Jan 17 12:09:28 2014 +0000 @@ -55,7 +55,8 @@ int setFrameSize(size_t frameSize); // int setRemoveUnvoiced(bool frameSize); YinOutput process(const double *in) const; - YinOutput processProbabilisticYin(const double *in) const; + YinOutput processProbabilisticYin(const double *in, + float minFreq = -1, float maxFreq = -1) const; private: mutable size_t m_frameSize;
--- a/YinUtil.cpp Fri Dec 06 16:19:26 2013 +0000 +++ b/YinUtil.cpp Fri Jan 17 12:09:28 2014 +0000 @@ -166,10 +166,24 @@ std::vector<double> -YinUtil::yinProb(const double *yinBuffer, const size_t prior, const size_t yinBufferSize) +YinUtil::yinProb(const double *yinBuffer, const size_t prior, + const size_t yinBufferSize, + size_t minTau, size_t maxTau) { double minWeight = 0.01; - size_t tau; + + // sortint out min and max tau -- could be done more elegantly + size_t tau = 2; + if (minTau >= tau && minTau < yinBufferSize) + { + tau = minTau; + } else { + tau = 2; + } + if (maxTau < minTau) maxTau = yinBufferSize; + maxTau = std::min(maxTau, yinBufferSize); + std::cerr << maxTau << std::endl; + std::vector<float> thresholds; std::vector<float> distribution; std::vector<double> peakProb = std::vector<double>(yinBufferSize); @@ -229,11 +243,10 @@ // } // } // if (minYin < 0.01) std::cerr << "min Yin buffer element: " << minYin << std::endl; - - + + int currThreshInd = nThreshold-1; - tau = 2; - + // double factor = 1.0 / (0.25 * (nThresholdInt+1) * (nThresholdInt + 1)); // factor to scale down triangular weight size_t minInd = 0; float minVal = 42.f; @@ -241,7 +254,7 @@ { if (yinBuffer[tau] < thresholds[currThreshInd]) { - while (tau + 1 < yinBufferSize && yinBuffer[tau+1] < yinBuffer[tau]) + while (tau + 1 < maxTau && yinBuffer[tau+1] < yinBuffer[tau]) { tau++; } @@ -258,7 +271,7 @@ } } double nonPeakProb = 1; - for (size_t i = 0; i < yinBufferSize; ++i) + for (size_t i = minTau; i < maxTau; ++i) { nonPeakProb -= peakProb[i]; }
--- a/YinUtil.h Fri Dec 06 16:19:26 2013 +0000 +++ b/YinUtil.h Fri Jan 17 12:09:28 2014 +0000 @@ -33,7 +33,9 @@ static void fastDifference(const double *in, double *yinBuffer, const size_t yinBufferSize); static void cumulativeDifference(double *yinBuffer, const size_t yinBufferSize); static int absoluteThreshold(const double *yinBuffer, const size_t yinBufferSize, const double thresh); - static vector<double> yinProb(const double *yinBuffer, const size_t prior, const size_t yinBufferSize); + static vector<double> yinProb(const double *yinBuffer, const size_t prior, + const size_t yinBufferSize, + const size_t minTau = 2, const size_t maxTau = 0); static double parabolicInterpolation(const double *yinBuffer, const size_t tau, const size_t yinBufferSize); };