cannam@484: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@475: /* cannam@475: Copyright (c) 2005 Centre for Digital Music ( C4DM ) cannam@475: Queen Mary Univesrity of London cannam@475: cannam@475: This program is free software; you can redistribute it and/or cannam@475: modify it under the terms of the GNU General Public License as cannam@475: published by the Free Software Foundation; either version 2 of the cannam@475: License, or (at your option) any later version. See the file cannam@475: COPYING included with this distribution for more information. cannam@475: */ cannam@475: cannam@489: #ifndef QM_DSP_GETKEYMODE_H cannam@489: #define QM_DSP_GETKEYMODE_H cannam@475: cannam@509: class Decimator; cannam@509: class Chromagram; cannam@475: cannam@475: class GetKeyMode cannam@475: { cannam@475: public: cannam@509: struct Config { cannam@509: double sampleRate; cannam@509: float tuningFrequency; cannam@509: double hpcpAverage; cannam@509: double medianAverage; cannam@509: int frameOverlapFactor; // 1 = none (default, fast, but means cannam@509: // we skip a fair bit of input data); cannam@509: // 8 = normal chroma overlap cannam@509: int decimationFactor; cannam@509: cannam@509: Config(double _sampleRate, float _tuningFrequency) : cannam@509: sampleRate(_sampleRate), cannam@509: tuningFrequency(_tuningFrequency), cannam@509: hpcpAverage(10), cannam@509: medianAverage(10), cannam@509: frameOverlapFactor(1), cannam@509: decimationFactor(8) { cannam@509: } cannam@509: }; cannam@509: cannam@509: GetKeyMode(Config config); cannam@475: cannam@478: virtual ~GetKeyMode(); cannam@475: cannam@509: /** cannam@509: * Process a single time-domain input sample frame of length cannam@509: * getBlockSize(). Successive calls should provide overlapped data cannam@509: * with an advance of getHopSize() between frames. cannam@509: * cannam@509: * Return a key index in the range 0-24, where 0 indicates no key cannam@509: * detected, 1 is C major, and 13 is C minor. cannam@509: */ cannam@509: int process(double *pcmData); cannam@475: cannam@509: /** cannam@509: * Return a pointer to an internal 24-element array containing the cannam@509: * correlation of the chroma vector generated in the last cannam@509: * process() call against the stored key profiles for the 12 major cannam@509: * and 12 minor keys, where index 0 is C major and 12 is C minor. cannam@509: */ cannam@509: double *getKeyStrengths(); cannam@475: cannam@509: int getBlockSize() { cannam@509: return m_chromaFrameSize * m_decimationFactor; cannam@509: } cannam@509: int getHopSize() { cannam@509: return m_chromaHopSize * m_decimationFactor; cannam@509: } cannam@475: cannam@475: protected: cannam@509: double krumCorr(const double *pDataNorm, const double *pProfileNorm, cannam@509: int shiftProfile, int length); cannam@475: cannam@478: double m_hpcpAverage; cannam@478: double m_medianAverage; cannam@499: int m_decimationFactor; cannam@475: cannam@499: // Decimator (fixed) cannam@499: Decimator* m_decimator; cannam@475: cannam@499: // Chromagram object cannam@499: Chromagram* m_chroma; cannam@475: cannam@499: // Chromagram output pointer cannam@499: double* m_chrPointer; cannam@475: cannam@499: // Framesize cannam@499: int m_chromaFrameSize; cannam@475: cannam@499: // Hop cannam@499: int m_chromaHopSize; cannam@475: cannam@499: int m_chromaBufferSize; cannam@499: int m_medianWinSize; cannam@478: cannam@499: int m_bufferIndex; cannam@499: int m_chromaBufferFilling; cannam@499: int m_medianBufferFilling; cannam@475: cannam@499: double* m_decimatedBuffer; cannam@499: double* m_chromaBuffer; cannam@499: double* m_meanHPCP; cannam@475: cannam@499: double* m_majProfileNorm; cannam@499: double* m_minProfileNorm; cannam@499: double* m_majCorr; cannam@499: double* m_minCorr; cannam@499: int* m_medianFilterBuffer; cannam@499: int* m_sortedBuffer; cannam@475: cannam@478: double *m_keyStrengths; cannam@475: }; cannam@475: cannam@499: #endif // !defined QM_DSP_GETKEYMODE_H