matthiasm@49: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ matthiasm@49: matthiasm@49: /* matthiasm@49: pYIN - A fundamental frequency estimator for monophonic audio matthiasm@49: Centre for Digital Music, Queen Mary, University of London. matthiasm@49: matthiasm@49: This program is free software; you can redistribute it and/or matthiasm@49: modify it under the terms of the GNU General Public License as matthiasm@49: published by the Free Software Foundation; either version 2 of the matthiasm@49: License, or (at your option) any later version. See the file matthiasm@49: COPYING included with this distribution for more information. matthiasm@49: */ matthiasm@49: matthiasm@49: #include "YinVampFreqConstrained.h" matthiasm@49: #include "MonoNote.h" matthiasm@49: matthiasm@49: #include "vamp-sdk/FFT.h" matthiasm@49: matthiasm@49: #include matthiasm@49: #include matthiasm@49: matthiasm@49: #include matthiasm@49: #include matthiasm@49: #include matthiasm@49: matthiasm@49: using std::string; matthiasm@49: using std::vector; matthiasm@49: using Vamp::RealTime; matthiasm@49: matthiasm@49: matthiasm@49: YinVampFreqConstrained::YinVampFreqConstrained(float inputSampleRate) : matthiasm@49: Plugin(inputSampleRate), matthiasm@49: m_channels(0), matthiasm@49: m_stepSize(256), matthiasm@49: m_blockSize(2048), matthiasm@49: m_fmin(40), matthiasm@49: m_fmax(1000), matthiasm@49: m_yin(2048, inputSampleRate, 0.0), matthiasm@49: m_yinFmin(100.f), matthiasm@49: m_yinFmax(400.f) matthiasm@49: { matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::~YinVampFreqConstrained() matthiasm@49: { matthiasm@49: } matthiasm@49: matthiasm@49: string matthiasm@49: YinVampFreqConstrained::getIdentifier() const matthiasm@49: { matthiasm@49: return "yinfc"; matthiasm@49: } matthiasm@49: matthiasm@49: string matthiasm@49: YinVampFreqConstrained::getName() const matthiasm@49: { matthiasm@49: return "Frequency-constrained Yin"; matthiasm@49: } matthiasm@49: matthiasm@49: string matthiasm@49: YinVampFreqConstrained::getDescription() const matthiasm@49: { matthiasm@49: return "A vamp implementation of the Yin algorithm for monophonic frequency estimation with frequency constraints."; matthiasm@49: } matthiasm@49: matthiasm@49: string matthiasm@49: YinVampFreqConstrained::getMaker() const matthiasm@49: { matthiasm@49: return "Matthias Mauch"; matthiasm@49: } matthiasm@49: matthiasm@49: int matthiasm@49: YinVampFreqConstrained::getPluginVersion() const matthiasm@49: { matthiasm@49: // Increment this each time you release a version that behaves matthiasm@49: // differently from the previous one matthiasm@49: return 1; matthiasm@49: } matthiasm@49: matthiasm@49: string matthiasm@49: YinVampFreqConstrained::getCopyright() const matthiasm@49: { matthiasm@49: return "GPL"; matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::InputDomain matthiasm@49: YinVampFreqConstrained::getInputDomain() const matthiasm@49: { matthiasm@49: return TimeDomain; matthiasm@49: } matthiasm@49: matthiasm@49: size_t matthiasm@49: YinVampFreqConstrained::getPreferredBlockSize() const matthiasm@49: { matthiasm@49: return 2048; matthiasm@49: } matthiasm@49: matthiasm@49: size_t matthiasm@49: YinVampFreqConstrained::getPreferredStepSize() const matthiasm@49: { matthiasm@49: return 256; matthiasm@49: } matthiasm@49: matthiasm@49: size_t matthiasm@49: YinVampFreqConstrained::getMinChannelCount() const matthiasm@49: { matthiasm@49: return 1; matthiasm@49: } matthiasm@49: matthiasm@49: size_t matthiasm@49: YinVampFreqConstrained::getMaxChannelCount() const matthiasm@49: { matthiasm@49: return 1; matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::ParameterList matthiasm@49: YinVampFreqConstrained::getParameterDescriptors() const matthiasm@49: { matthiasm@49: ParameterList list; matthiasm@49: matthiasm@49: ParameterDescriptor d; matthiasm@49: matthiasm@49: d.identifier = "minfreq"; matthiasm@49: d.name = "Minimum frequency"; matthiasm@49: d.description = "Minimum frequency used when searching for difference function minimum."; matthiasm@49: d.unit = "Hz"; matthiasm@49: d.minValue = 40.f; matthiasm@49: d.maxValue = 1000.0f; matthiasm@49: d.defaultValue = 100.f; matthiasm@49: d.isQuantized = false; matthiasm@49: d.valueNames.clear(); matthiasm@49: list.push_back(d); matthiasm@49: matthiasm@49: d.identifier = "maxfreq"; matthiasm@49: d.name = "Maximum frequency"; matthiasm@49: d.description = "Maximum frequency used when searching for difference function minimum."; matthiasm@49: d.unit = "Hz"; matthiasm@49: d.minValue = 40.f; matthiasm@49: d.maxValue = 1000.0f; matthiasm@49: d.defaultValue = 400.f; matthiasm@49: d.isQuantized = false; matthiasm@49: d.valueNames.clear(); matthiasm@49: list.push_back(d); matthiasm@49: matthiasm@49: return list; matthiasm@49: } matthiasm@49: matthiasm@49: float matthiasm@49: YinVampFreqConstrained::getParameter(string identifier) const matthiasm@49: { matthiasm@49: if (identifier == "minfreq") { matthiasm@49: return m_yinFmin; matthiasm@49: } matthiasm@49: if (identifier == "maxfreq") { matthiasm@49: return m_yinFmax; matthiasm@49: } matthiasm@49: return 0.f; matthiasm@49: } matthiasm@49: matthiasm@49: void matthiasm@49: YinVampFreqConstrained::setParameter(string identifier, float value) matthiasm@49: { matthiasm@49: if (identifier == "minfreq") matthiasm@49: { matthiasm@49: m_yinFmin = value; matthiasm@49: } matthiasm@49: if (identifier == "maxfreq") matthiasm@49: { matthiasm@49: m_yinFmax = value; matthiasm@49: } matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::ProgramList matthiasm@49: YinVampFreqConstrained::getPrograms() const matthiasm@49: { matthiasm@49: ProgramList list; matthiasm@49: return list; matthiasm@49: } matthiasm@49: matthiasm@49: string matthiasm@49: YinVampFreqConstrained::getCurrentProgram() const matthiasm@49: { matthiasm@49: return ""; // no programs matthiasm@49: } matthiasm@49: matthiasm@49: void matthiasm@49: YinVampFreqConstrained::selectProgram(string name) matthiasm@49: { matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::OutputList matthiasm@49: YinVampFreqConstrained::getOutputDescriptors() const matthiasm@49: { matthiasm@49: OutputList outputs; matthiasm@49: matthiasm@49: OutputDescriptor d; matthiasm@49: matthiasm@49: int outputNumber = 0; matthiasm@49: matthiasm@49: d.identifier = "f0"; matthiasm@49: d.name = "Estimated f0"; matthiasm@49: d.description = "Estimated fundamental frequency"; matthiasm@49: d.unit = "Hz"; matthiasm@49: d.hasFixedBinCount = true; matthiasm@49: d.binCount = 1; matthiasm@49: d.hasKnownExtents = true; matthiasm@49: d.minValue = m_fmin; matthiasm@49: d.maxValue = 500; matthiasm@49: d.isQuantized = false; matthiasm@49: d.sampleType = OutputDescriptor::FixedSampleRate; matthiasm@49: d.sampleRate = (m_inputSampleRate / m_stepSize); matthiasm@49: d.hasDuration = false; matthiasm@49: outputs.push_back(d); matthiasm@49: matthiasm@49: return outputs; matthiasm@49: } matthiasm@49: matthiasm@49: bool matthiasm@49: YinVampFreqConstrained::initialise(size_t channels, size_t stepSize, size_t blockSize) matthiasm@49: { matthiasm@49: if (channels < getMinChannelCount() || matthiasm@49: channels > getMaxChannelCount()) return false; matthiasm@49: matthiasm@49: /* matthiasm@49: std::cerr << "YinVampFreqConstrained::initialise: channels = " << channels matthiasm@49: << ", stepSize = " << stepSize << ", blockSize = " << blockSize matthiasm@49: << std::endl; matthiasm@49: */ matthiasm@49: m_channels = channels; matthiasm@49: m_stepSize = stepSize; matthiasm@49: m_blockSize = blockSize; matthiasm@49: matthiasm@49: reset(); matthiasm@49: matthiasm@49: return true; matthiasm@49: } matthiasm@49: matthiasm@49: void matthiasm@49: YinVampFreqConstrained::reset() matthiasm@49: { matthiasm@49: m_yin.setFrameSize(m_blockSize); matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::FeatureSet matthiasm@49: YinVampFreqConstrained::process(const float *const *inputBuffers, RealTime timestamp) matthiasm@49: { matthiasm@60: timestamp = timestamp + Vamp::RealTime::frame2RealTime(m_blockSize/2, lrintf(m_inputSampleRate)); matthiasm@49: FeatureSet fs; matthiasm@49: matthiasm@49: double *dInputBuffers = new double[m_blockSize]; matthiasm@49: for (size_t i = 0; i < m_blockSize; ++i) dInputBuffers[i] = inputBuffers[0][i]; matthiasm@49: matthiasm@49: // std::cerr << "f0 in YinVampFreqConstrained: " << yo.f0 << std::endl; matthiasm@49: Feature f; matthiasm@49: f.hasTimestamp = true; matthiasm@49: f.timestamp = timestamp; matthiasm@49: f.values.push_back(m_yin.constrainedMinPick(dInputBuffers, m_yinFmin, m_yinFmax)); matthiasm@49: fs[0].push_back(f); matthiasm@49: matthiasm@49: delete [] dInputBuffers; matthiasm@49: return fs; matthiasm@49: } matthiasm@49: matthiasm@49: YinVampFreqConstrained::FeatureSet matthiasm@49: YinVampFreqConstrained::getRemainingFeatures() matthiasm@49: { matthiasm@49: FeatureSet fs; matthiasm@49: return fs; matthiasm@49: }