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 |