cannam@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@0: cannam@0: /* cannam@0: QM DSP Library cannam@0: cannam@0: Centre for Digital Music, Queen Mary, University of London. cannam@0: This file copyright 2005-2006 Christian Landone. cannam@0: All rights reserved. cannam@0: */ cannam@0: cannam@0: #include cannam@0: #include cannam@0: #include "dsp/maths/MathUtilities.h" cannam@0: #include "Chromagram.h" cannam@0: cannam@0: //---------------------------------------------------------------------------- cannam@0: cannam@0: Chromagram::Chromagram( ChromaConfig Config ) cannam@0: { cannam@0: initialise( Config ); cannam@0: } cannam@0: cannam@0: int Chromagram::initialise( ChromaConfig Config ) cannam@0: { cannam@0: m_FMin = Config.min; // min freq cannam@0: m_FMax = Config.max; // max freq cannam@0: m_BPO = Config.BPO; // bins per octave cannam@0: isNormalised = Config.isNormalised; // true if frame normalisation is required cannam@0: cannam@0: // No. of constant Q bins cannam@0: m_uK = ( unsigned int ) ceil( m_BPO * log(m_FMax/m_FMin)/log(2.0)); cannam@0: cannam@0: // Create array for chroma result cannam@0: m_chromadata = new double[ m_BPO ]; cannam@0: cannam@0: // Initialise FFT object cannam@0: m_FFT = new FFT; cannam@0: cannam@0: // Create Config Structure for ConstantQ operator cannam@0: CQConfig ConstantQConfig; cannam@0: cannam@0: // Populate CQ config structure with parameters cannam@0: // inherited from the Chroma config cannam@0: ConstantQConfig.FS = Config.FS; cannam@0: ConstantQConfig.min = m_FMin; cannam@0: ConstantQConfig.max = m_FMax; cannam@0: ConstantQConfig.BPO = m_BPO; cannam@0: ConstantQConfig.CQThresh = Config.CQThresh; cannam@0: cannam@0: // Initialise ConstantQ operator cannam@0: m_ConstantQ = new ConstantQ( ConstantQConfig ); cannam@0: cannam@0: // Initialise working arrays cannam@0: m_frameSize = m_ConstantQ->getfftlength(); cannam@0: m_hopSize = m_ConstantQ->gethop(); cannam@0: cannam@0: m_FFTRe = new double[ m_frameSize ]; cannam@0: m_FFTIm = new double[ m_frameSize ]; cannam@0: m_CQRe = new double[ m_uK ]; cannam@0: m_CQIm = new double[ m_uK ]; cannam@0: cannam@0: // Generate CQ Kernel cannam@0: m_ConstantQ->sparsekernel(); cannam@0: return 1; cannam@0: } cannam@0: cannam@0: Chromagram::~Chromagram() cannam@0: { cannam@0: deInitialise(); cannam@0: } cannam@0: cannam@0: int Chromagram::deInitialise() cannam@0: { cannam@0: delete [] m_chromadata; cannam@0: cannam@0: delete m_FFT; cannam@0: cannam@0: delete m_ConstantQ; cannam@0: cannam@0: delete [] m_FFTRe; cannam@0: delete [] m_FFTIm; cannam@0: delete [] m_CQRe; cannam@0: delete [] m_CQIm; cannam@0: return 1; cannam@0: } cannam@0: cannam@0: //---------------------------------------------------------------------------------- cannam@0: // returns the absolute value of complex number xx + i*yy cannam@0: double Chromagram::kabs(double xx, double yy) cannam@0: { cannam@0: double ab = sqrt(xx*xx + yy*yy); cannam@0: return(ab); cannam@0: } cannam@0: //----------------------------------------------------------------------------------- cannam@0: cannam@0: cannam@0: void Chromagram::unityNormalise(double *src) cannam@0: { cannam@0: double min, max; cannam@0: cannam@0: double val = 0; cannam@0: cannam@0: MathUtilities::getFrameMinMax( src, m_BPO, & min, &max ); cannam@0: cannam@0: for( unsigned int i = 0; i < m_BPO; i++ ) cannam@0: { cannam@0: val = src[ i ] / max; cannam@0: cannam@0: src[ i ] = val; cannam@0: } cannam@0: } cannam@0: cannam@0: cannam@0: double* Chromagram::process( double *data ) cannam@0: { cannam@0: //initialise chromadata to 0 cannam@0: for (unsigned i=0; iprocess( m_frameSize, 0, data, NULL, m_FFTRe, m_FFTIm ); cannam@0: cannam@0: // Calculate ConstantQ frame cannam@0: m_ConstantQ->process( m_FFTRe, m_FFTIm, m_CQRe, m_CQIm ); cannam@0: cannam@0: // add each octave of cq data into Chromagram cannam@0: const unsigned octaves = (int)floor(double( m_uK/m_BPO))-1; cannam@0: for (unsigned octave=0; octave<=octaves; octave++) cannam@0: { cannam@0: unsigned firstBin = octave*m_BPO; cannam@0: for (unsigned i=0; i