Mercurial > hg > qm-dsp
view dsp/chromagram/Chromagram.cpp @ 51:114e833c07ac
* Do not calculate CQ sparse kernel when chromagram is constructed: only
when it's actually used
* Pre-calculate CQ sparse kernels in the sizes required for the default
configurations of some of our transforms
author | cannam |
---|---|
date | Thu, 04 Dec 2008 11:59:29 +0000 |
parents | ad645e404d0c |
children | 6cb2b3cd5356 |
line wrap: on
line source
/* -*- 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 "maths/MathUtilities.h" #include "Chromagram.h" //---------------------------------------------------------------------------- Chromagram::Chromagram( ChromaConfig Config ) : m_skGenerated(false) { 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 m_normalise = Config.normalise; // 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 ]; m_window = 0; m_windowbuf = 0; return 1; } Chromagram::~Chromagram() { deInitialise(); } int Chromagram::deInitialise() { delete[] m_windowbuf; delete m_window; 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( const double *data ) { if (!m_skGenerated) { // Generate CQ Kernel m_ConstantQ->sparsekernel(); m_skGenerated = true; } if (!m_window) { m_window = new Window<double>(HammingWindow, m_frameSize); m_windowbuf = new double[m_frameSize]; } for (int i = 0; i < m_frameSize; ++i) { m_windowbuf[i] = data[i]; } m_window->cut(m_windowbuf); // FFT of current frame m_FFT->process(m_frameSize, 0, m_windowbuf, NULL, m_FFTRe, m_FFTIm); return process(m_FFTRe, m_FFTIm); } double* Chromagram::process( const double *real, const double *imag ) { if (!m_skGenerated) { // Generate CQ Kernel m_ConstantQ->sparsekernel(); m_skGenerated = true; } // initialise chromadata to 0 for (unsigned i = 0; i < m_BPO; i++) m_chromadata[i] = 0; double cmax = 0.0; double cval = 0; // Calculate ConstantQ frame m_ConstantQ->process( real, imag, 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 ]); } } MathUtilities::normalise(m_chromadata, m_BPO, m_normalise); return m_chromadata; }