annotate dsp/chromagram/Chromagram.cpp @ 0:d7116e3183f8

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