Mercurial > hg > qm-dsp
changeset 509:3f0a96460c33
Switch to config-struct constructor; add frameOverlapFactor parameter
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Thu, 06 Jun 2019 14:20:53 +0100 |
parents | 855d862cf02b |
children | 2adcd94c2079 |
files | dsp/keydetection/GetKeyMode.cpp dsp/keydetection/GetKeyMode.h |
diffstat | 2 files changed, 72 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/dsp/keydetection/GetKeyMode.cpp Wed Jun 05 16:05:09 2019 +0100 +++ b/dsp/keydetection/GetKeyMode.cpp Thu Jun 06 14:20:53 2019 +0100 @@ -16,6 +16,10 @@ */ #include "GetKeyMode.h" + +#include "dsp/rateconversion/Decimator.h" +#include "dsp/chromagram/Chromagram.h" + #include "maths/MathUtilities.h" #include "base/Pitch.h" @@ -47,10 +51,10 @@ // Construction/Destruction ////////////////////////////////////////////////////////////////////// -GetKeyMode::GetKeyMode( int sampleRate, float tuningFrequency, - double hpcpAverage, double medianAverage ) : - m_hpcpAverage( hpcpAverage ), - m_medianAverage( medianAverage ), +GetKeyMode::GetKeyMode(Config config) : + m_hpcpAverage(config.hpcpAverage), + m_medianAverage(config.medianAverage), + m_decimationFactor(config.decimationFactor), m_chrPointer(0), m_decimatedBuffer(0), m_chromaBuffer(0), @@ -61,38 +65,41 @@ m_sortedBuffer(0), m_keyStrengths(0) { - m_decimationFactor = 8; - + ChromaConfig chromaConfig; + // Chromagram configuration parameters - m_chromaConfig.normalise = MathUtilities::NormaliseUnitMax; - m_chromaConfig.FS = sampleRate / (double)m_decimationFactor; - if (m_chromaConfig.FS < 1) { - m_chromaConfig.FS = 1; + chromaConfig.normalise = MathUtilities::NormaliseUnitMax; + chromaConfig.FS = config.sampleRate / (double)m_decimationFactor; + if (chromaConfig.FS < 1) { + chromaConfig.FS = 1; } // Set C3 (= MIDI #48) as our base: // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc. - m_chromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency ); - m_chromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency ); + chromaConfig.min = + Pitch::getFrequencyForPitch( 48, 0, config.tuningFrequency ); + chromaConfig.max = + Pitch::getFrequencyForPitch( 96, 0, config.tuningFrequency ); - m_chromaConfig.BPO = kBinsPerOctave; - m_chromaConfig.CQThresh = 0.0054; + chromaConfig.BPO = kBinsPerOctave; + chromaConfig.CQThresh = 0.0054; // Chromagram inst. - m_chroma = new Chromagram( m_chromaConfig ); + m_chroma = new Chromagram(chromaConfig); // Get calculated parameters from chroma object m_chromaFrameSize = m_chroma->getFrameSize(); + // override hopsize for this application - m_chromaHopSize = m_chromaFrameSize; + m_chromaHopSize = m_chromaFrameSize / config.frameOverlapFactor; // std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl; // Chromagram average and estimated key median filter lengths m_chromaBufferSize = (int)ceil - (m_hpcpAverage * m_chromaConfig.FS / m_chromaFrameSize); + (m_hpcpAverage * chromaConfig.FS / m_chromaFrameSize); m_medianWinSize = (int)ceil - (m_medianAverage * m_chromaConfig.FS / m_chromaFrameSize); + (m_medianAverage * chromaConfig.FS / m_chromaFrameSize); // Reset counters m_bufferIndex = 0; @@ -282,17 +289,6 @@ return key; } - -bool GetKeyMode::isModeMinor( int key ) -{ - return (key > 12); -} - -int GetKeyMode::getChromaSize() -{ - return kBinsPerOctave; -} - double* GetKeyMode::getKeyStrengths() { int k;
--- a/dsp/keydetection/GetKeyMode.h Wed Jun 05 16:05:09 2019 +0100 +++ b/dsp/keydetection/GetKeyMode.h Thu Jun 06 14:20:53 2019 +0100 @@ -13,37 +13,64 @@ #ifndef QM_DSP_GETKEYMODE_H #define QM_DSP_GETKEYMODE_H - -#include "dsp/rateconversion/Decimator.h" -#include "dsp/chromagram/Chromagram.h" - +class Decimator; +class Chromagram; class GetKeyMode { public: - GetKeyMode( int sampleRate, float tuningFrequency, - double hpcpAverage, double medianAverage ); + struct Config { + double sampleRate; + float tuningFrequency; + double hpcpAverage; + double medianAverage; + int frameOverlapFactor; // 1 = none (default, fast, but means + // we skip a fair bit of input data); + // 8 = normal chroma overlap + int decimationFactor; + + Config(double _sampleRate, float _tuningFrequency) : + sampleRate(_sampleRate), + tuningFrequency(_tuningFrequency), + hpcpAverage(10), + medianAverage(10), + frameOverlapFactor(1), + decimationFactor(8) { + } + }; + + GetKeyMode(Config config); virtual ~GetKeyMode(); - int process( double* PCMData ); + /** + * Process a single time-domain input sample frame of length + * getBlockSize(). Successive calls should provide overlapped data + * with an advance of getHopSize() between frames. + * + * Return a key index in the range 0-24, where 0 indicates no key + * detected, 1 is C major, and 13 is C minor. + */ + int process(double *pcmData); - double krumCorr( const double *pDataNorm, const double *pProfileNorm, - int shiftProfile, int length ); + /** + * Return a pointer to an internal 24-element array containing the + * correlation of the chroma vector generated in the last + * process() call against the stored key profiles for the 12 major + * and 12 minor keys, where index 0 is C major and 12 is C minor. + */ + double *getKeyStrengths(); - int getBlockSize() { return m_chromaFrameSize * m_decimationFactor; } - int getHopSize() { return m_chromaHopSize * m_decimationFactor; } - - double* getChroma() { return m_chrPointer; } - int getChromaSize(); - - double* getMeanHPCP() { return m_meanHPCP; } - - double* getKeyStrengths(); - - bool isModeMinor( int key ); + int getBlockSize() { + return m_chromaFrameSize * m_decimationFactor; + } + int getHopSize() { + return m_chromaHopSize * m_decimationFactor; + } protected: + double krumCorr(const double *pDataNorm, const double *pProfileNorm, + int shiftProfile, int length); double m_hpcpAverage; double m_medianAverage; @@ -52,9 +79,6 @@ // Decimator (fixed) Decimator* m_decimator; - // Chroma configuration - ChromaConfig m_chromaConfig; - // Chromagram object Chromagram* m_chroma;