diff Tuning.cpp @ 35:cf8898a0174c matthiasm-plugin

* Split out NNLSChroma plugin into three plugins (chroma, chordino, tuning) with a common base class. There's still quite a lot of duplication between the getRemainingFeatures functions. Also add copyright / copying headers, etc.
author Chris Cannam
date Fri, 22 Oct 2010 11:30:21 +0100
parents NNLSChroma.cpp@da3195577172
children 1d668695c03b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tuning.cpp	Fri Oct 22 11:30:21 2010 +0100
@@ -0,0 +1,181 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+  NNLS-Chroma / Chordino
+
+  Audio feature extraction plugins for chromagram and chord
+  estimation.
+
+  Centre for Digital Music, Queen Mary University of London.
+  This file copyright 2008-2010 Matthias Mauch and QMUL.
+    
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.  See the file
+  COPYING included with this distribution for more information.
+*/
+
+#include "Tuning.h"
+
+#include "chromamethods.h"
+
+#include <cstdlib>
+#include <fstream>
+#include <cmath>
+
+#include <algorithm>
+
+const bool debug_on = false;
+
+const vector<float> hw(hammingwind, hammingwind+19);
+
+Tuning::Tuning(float inputSampleRate) :
+    NNLSBase(inputSampleRate)
+{
+    if (debug_on) cerr << "--> Tuning" << endl;
+}
+
+Tuning::~Tuning()
+{
+    if (debug_on) cerr << "--> ~Tuning" << endl;
+}
+
+string
+Tuning::getIdentifier() const
+{
+    if (debug_on) cerr << "--> getIdentifier" << endl;
+    return "tuning";
+}
+
+string
+Tuning::getName() const
+{
+    if (debug_on) cerr << "--> getName" << endl;
+    return "Tuning";
+}
+
+string
+Tuning::getDescription() const
+{
+    // Return something helpful here!
+    if (debug_on) cerr << "--> getDescription" << endl;
+    return "This plugin provides a number of features derived from a log-frequency amplitude spectrum of the DFT: some variants of the log-frequency spectrum, including a semitone spectrum derived from approximate transcription using the NNLS algorithm; based on this semitone spectrum, chroma features and a simple chord estimate.";
+}
+
+Tuning::OutputList
+Tuning::getOutputDescriptors() const
+{
+    if (debug_on) cerr << "--> getOutputDescriptors" << endl;
+    OutputList list;
+    
+    int index = 0;
+
+    OutputDescriptor d0;
+    d0.identifier = "tuning";
+    d0.name = "Tuning";
+    d0.description = "The concert pitch.";
+    d0.unit = "Hz";
+    d0.hasFixedBinCount = true;
+    d0.binCount = 0;
+    d0.hasKnownExtents = true;
+    d0.minValue = 427.47;
+    d0.maxValue = 452.89;
+    d0.isQuantized = false;
+    d0.sampleType = OutputDescriptor::VariableSampleRate;
+    d0.hasDuration = false;
+    list.push_back(d0);
+    m_outputTuning = index++;
+	
+    OutputDescriptor d10;
+    d10.identifier = "localtuning";
+    d10.name = "Local tuning";
+    d10.description = "Tuning based on the history up to this timestamp.";
+    d10.unit = "Hz";
+    d10.hasFixedBinCount = true;
+    d10.binCount = 1;
+    d10.hasKnownExtents = true;
+    d10.minValue = 427.47;
+    d10.maxValue = 452.89;
+    d10.isQuantized = false;
+    d10.sampleType = OutputDescriptor::FixedSampleRate;
+    d10.hasDuration = false;
+    // d10.sampleRate = (m_stepSize == 0) ? m_inputSampleRate/2048 : m_inputSampleRate/m_stepSize;
+    list.push_back(d10);
+    m_outputLocalTuning = index++;
+  
+    return list;
+}
+
+
+bool
+Tuning::initialise(size_t channels, size_t stepSize, size_t blockSize)
+{	
+    if (debug_on) {
+        cerr << "--> initialise";
+    }
+	
+    if (!NNLSBase::initialise(channels, stepSize, blockSize)) {
+        return false;
+    }
+
+    return true;
+}
+
+void
+Tuning::reset()
+{
+    if (debug_on) cerr << "--> reset";
+    NNLSBase::reset();
+}
+
+Tuning::FeatureSet
+Tuning::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
+{   
+    if (debug_on) cerr << "--> process" << endl;
+
+    NNLSBase::baseProcess(inputBuffers, timestamp);
+	
+    Feature f10; // local tuning
+    f10.hasTimestamp = true;
+    f10.timestamp = timestamp;
+    float normalisedtuning = m_localTuning[m_localTuning.size()-1];
+    float tuning440 = 440 * pow(2,normalisedtuning/12);
+    f10.values.push_back(tuning440);
+	
+    FeatureSet fs;
+    fs[m_outputLocalTuning].push_back(f10);
+    return fs;	
+}
+
+Tuning::FeatureSet
+Tuning::getRemainingFeatures()
+{
+    if (debug_on) cerr << "--> getRemainingFeatures" << endl;
+    FeatureSet fsOut;
+    if (m_logSpectrum.size() == 0) return fsOut;
+
+    // 
+    /**  Calculate Tuning
+         calculate tuning from (using the angle of the complex number defined by the 
+         cumulative mean real and imag values)
+    **/
+    float meanTuningImag = sinvalue * m_meanTuning1 - sinvalue * m_meanTuning2;
+    float meanTuningReal = m_meanTuning0 + cosvalue * m_meanTuning1 + cosvalue * m_meanTuning2;
+    float cumulativetuning = 440 * pow(2,atan2(meanTuningImag, meanTuningReal)/(24*M_PI));
+		    
+    char buffer0 [50];
+		
+    sprintf(buffer0, "estimated tuning: %0.1f Hz", cumulativetuning);
+		    
+    // push tuning to FeatureSet fsOut
+    Feature f0; // tuning
+    f0.hasTimestamp = true;
+    f0.timestamp = Vamp::RealTime::frame2RealTime(0, lrintf(m_inputSampleRate));;
+    f0.label = buffer0;
+    fsOut[m_outputTuning].push_back(f0);  
+		    
+    return fsOut;     
+
+}
+