Mercurial > hg > qm-dsp
comparison 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 | 
   comparison
  equal
  deleted
  inserted
  replaced
| -1:000000000000 | 225:49844bc8a895 | 
|---|---|
| 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
| 2 | |
| 3 /* | |
| 4 QM DSP Library | |
| 5 | |
| 6 Centre for Digital Music, Queen Mary, University of London. | |
| 7 This file copyright 2005-2006 Christian Landone. | |
| 8 All rights reserved. | |
| 9 */ | |
| 10 | |
| 11 #include <iostream> | |
| 12 #include <cmath> | |
| 13 #include "dsp/maths/MathUtilities.h" | |
| 14 #include "Chromagram.h" | |
| 15 | |
| 16 //---------------------------------------------------------------------------- | |
| 17 | |
| 18 Chromagram::Chromagram( ChromaConfig Config ) | |
| 19 { | |
| 20 initialise( Config ); | |
| 21 } | |
| 22 | |
| 23 int Chromagram::initialise( ChromaConfig Config ) | |
| 24 { | |
| 25 m_FMin = Config.min; // min freq | |
| 26 m_FMax = Config.max; // max freq | |
| 27 m_BPO = Config.BPO; // bins per octave | |
| 28 isNormalised = Config.isNormalised; // true if frame normalisation is required | |
| 29 | |
| 30 // No. of constant Q bins | |
| 31 m_uK = ( unsigned int ) ceil( m_BPO * log(m_FMax/m_FMin)/log(2.0)); | |
| 32 | |
| 33 // Create array for chroma result | |
| 34 m_chromadata = new double[ m_BPO ]; | |
| 35 | |
| 36 // Initialise FFT object | |
| 37 m_FFT = new FFT; | |
| 38 | |
| 39 // Create Config Structure for ConstantQ operator | |
| 40 CQConfig ConstantQConfig; | |
| 41 | |
| 42 // Populate CQ config structure with parameters | |
| 43 // inherited from the Chroma config | |
| 44 ConstantQConfig.FS = Config.FS; | |
| 45 ConstantQConfig.min = m_FMin; | |
| 46 ConstantQConfig.max = m_FMax; | |
| 47 ConstantQConfig.BPO = m_BPO; | |
| 48 ConstantQConfig.CQThresh = Config.CQThresh; | |
| 49 | |
| 50 // Initialise ConstantQ operator | |
| 51 m_ConstantQ = new ConstantQ( ConstantQConfig ); | |
| 52 | |
| 53 // Initialise working arrays | |
| 54 m_frameSize = m_ConstantQ->getfftlength(); | |
| 55 m_hopSize = m_ConstantQ->gethop(); | |
| 56 | |
| 57 m_FFTRe = new double[ m_frameSize ]; | |
| 58 m_FFTIm = new double[ m_frameSize ]; | |
| 59 m_CQRe = new double[ m_uK ]; | |
| 60 m_CQIm = new double[ m_uK ]; | |
| 61 | |
| 62 // Generate CQ Kernel | |
| 63 m_ConstantQ->sparsekernel(); | |
| 64 return 1; | |
| 65 } | |
| 66 | |
| 67 Chromagram::~Chromagram() | |
| 68 { | |
| 69 deInitialise(); | |
| 70 } | |
| 71 | |
| 72 int Chromagram::deInitialise() | |
| 73 { | |
| 74 delete [] m_chromadata; | |
| 75 | |
| 76 delete m_FFT; | |
| 77 | |
| 78 delete m_ConstantQ; | |
| 79 | |
| 80 delete [] m_FFTRe; | |
| 81 delete [] m_FFTIm; | |
| 82 delete [] m_CQRe; | |
| 83 delete [] m_CQIm; | |
| 84 return 1; | |
| 85 } | |
| 86 | |
| 87 //---------------------------------------------------------------------------------- | |
| 88 // returns the absolute value of complex number xx + i*yy | |
| 89 double Chromagram::kabs(double xx, double yy) | |
| 90 { | |
| 91 double ab = sqrt(xx*xx + yy*yy); | |
| 92 return(ab); | |
| 93 } | |
| 94 //----------------------------------------------------------------------------------- | |
| 95 | |
| 96 | |
| 97 void Chromagram::unityNormalise(double *src) | |
| 98 { | |
| 99 double min, max; | |
| 100 | |
| 101 double val = 0; | |
| 102 | |
| 103 MathUtilities::getFrameMinMax( src, m_BPO, & min, &max ); | |
| 104 | |
| 105 for( unsigned int i = 0; i < m_BPO; i++ ) | |
| 106 { | |
| 107 val = src[ i ] / max; | |
| 108 | |
| 109 src[ i ] = val; | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 | |
| 114 double* Chromagram::process( double *data ) | |
| 115 { | |
| 116 //initialise chromadata to 0 | |
| 117 for (unsigned i=0; i<m_BPO; i++) | |
| 118 m_chromadata[i]=0; | |
| 119 | |
| 120 double cmax = 0.0; | |
| 121 double cval = 0; | |
| 122 | |
| 123 // FFT of current frame | |
| 124 m_FFT->process( m_frameSize, 0, data, NULL, m_FFTRe, m_FFTIm ); | |
| 125 | |
| 126 // Calculate ConstantQ frame | |
| 127 m_ConstantQ->process( m_FFTRe, m_FFTIm, m_CQRe, m_CQIm ); | |
| 128 | |
| 129 // add each octave of cq data into Chromagram | |
| 130 const unsigned octaves = (int)floor(double( m_uK/m_BPO))-1; | |
| 131 for (unsigned octave=0; octave<=octaves; octave++) | |
| 132 { | |
| 133 unsigned firstBin = octave*m_BPO; | |
| 134 for (unsigned i=0; i<m_BPO; i++) | |
| 135 { | |
| 136 m_chromadata[i] += kabs( m_CQRe[ firstBin + i ], m_CQIm[ firstBin + i ]); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 if( isNormalised ) | |
| 141 unityNormalise( m_chromadata ); | |
| 142 | |
| 143 return m_chromadata; | |
| 144 } | |
| 145 | |
| 146 | 
