Mercurial > hg > qm-dsp
diff dsp/chromagram/Chromagram.cpp @ 225:49844bc8a895
* Queen Mary C++ DSP library
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 05 Apr 2006 17:35:59 +0000 |
parents | |
children | 07ac3de1e53b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsp/chromagram/Chromagram.cpp Wed Apr 05 17:35:59 2006 +0000 @@ -0,0 +1,146 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2005-2006 Christian Landone. + All rights reserved. +*/ + +#include <iostream> +#include <cmath> +#include "dsp/maths/MathUtilities.h" +#include "Chromagram.h" + +//---------------------------------------------------------------------------- + +Chromagram::Chromagram( ChromaConfig Config ) +{ + initialise( Config ); +} + +int Chromagram::initialise( ChromaConfig Config ) +{ + m_FMin = Config.min; // min freq + m_FMax = Config.max; // max freq + m_BPO = Config.BPO; // bins per octave + isNormalised = Config.isNormalised; // true if frame normalisation is required + + // No. of constant Q bins + m_uK = ( unsigned int ) ceil( m_BPO * log(m_FMax/m_FMin)/log(2.0)); + + // Create array for chroma result + m_chromadata = new double[ m_BPO ]; + + // Initialise FFT object + m_FFT = new FFT; + + // Create Config Structure for ConstantQ operator + CQConfig ConstantQConfig; + + // Populate CQ config structure with parameters + // inherited from the Chroma config + ConstantQConfig.FS = Config.FS; + ConstantQConfig.min = m_FMin; + ConstantQConfig.max = m_FMax; + ConstantQConfig.BPO = m_BPO; + ConstantQConfig.CQThresh = Config.CQThresh; + + // Initialise ConstantQ operator + m_ConstantQ = new ConstantQ( ConstantQConfig ); + + // Initialise working arrays + m_frameSize = m_ConstantQ->getfftlength(); + m_hopSize = m_ConstantQ->gethop(); + + m_FFTRe = new double[ m_frameSize ]; + m_FFTIm = new double[ m_frameSize ]; + m_CQRe = new double[ m_uK ]; + m_CQIm = new double[ m_uK ]; + + // Generate CQ Kernel + m_ConstantQ->sparsekernel(); + return 1; +} + +Chromagram::~Chromagram() +{ + deInitialise(); +} + +int Chromagram::deInitialise() +{ + delete [] m_chromadata; + + delete m_FFT; + + delete m_ConstantQ; + + delete [] m_FFTRe; + delete [] m_FFTIm; + delete [] m_CQRe; + delete [] m_CQIm; + return 1; +} + +//---------------------------------------------------------------------------------- +// returns the absolute value of complex number xx + i*yy +double Chromagram::kabs(double xx, double yy) +{ + double ab = sqrt(xx*xx + yy*yy); + return(ab); +} +//----------------------------------------------------------------------------------- + + +void Chromagram::unityNormalise(double *src) +{ + double min, max; + + double val = 0; + + MathUtilities::getFrameMinMax( src, m_BPO, & min, &max ); + + for( unsigned int i = 0; i < m_BPO; i++ ) + { + val = src[ i ] / max; + + src[ i ] = val; + } +} + + +double* Chromagram::process( double *data ) +{ + //initialise chromadata to 0 + for (unsigned i=0; i<m_BPO; i++) + m_chromadata[i]=0; + + double cmax = 0.0; + double cval = 0; + + // FFT of current frame + m_FFT->process( m_frameSize, 0, data, NULL, m_FFTRe, m_FFTIm ); + + // Calculate ConstantQ frame + m_ConstantQ->process( m_FFTRe, m_FFTIm, m_CQRe, m_CQIm ); + + // add each octave of cq data into Chromagram + const unsigned octaves = (int)floor(double( m_uK/m_BPO))-1; + for (unsigned octave=0; octave<=octaves; octave++) + { + unsigned firstBin = octave*m_BPO; + for (unsigned i=0; i<m_BPO; i++) + { + m_chromadata[i] += kabs( m_CQRe[ firstBin + i ], m_CQIm[ firstBin + i ]); + } + } + + if( isNormalised ) + unityNormalise( m_chromadata ); + + return m_chromadata; +} + +