annotate dsp/chromagram/Chromagram.cpp @ 84:e5907ae6de17

* Add GPL and README; some tidying
author Chris Cannam
date Mon, 13 Dec 2010 14:55:28 +0000
parents dcb555b90924
children f6ccde089491
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.
Chris@84 7 This file 2005-2006 Christian Landone.
Chris@84 8
Chris@84 9 This program is free software; you can redistribute it and/or
Chris@84 10 modify it under the terms of the GNU General Public License as
Chris@84 11 published by the Free Software Foundation; either version 2 of the
Chris@84 12 License, or (at your option) any later version. See the file
Chris@84 13 COPYING included with this distribution for more information.
cannam@0 14 */
cannam@0 15
cannam@0 16 #include <iostream>
cannam@0 17 #include <cmath>
cannam@16 18 #include "maths/MathUtilities.h"
cannam@0 19 #include "Chromagram.h"
cannam@0 20
cannam@0 21 //----------------------------------------------------------------------------
cannam@0 22
cannam@51 23 Chromagram::Chromagram( ChromaConfig Config ) :
cannam@51 24 m_skGenerated(false)
cannam@0 25 {
cannam@0 26 initialise( Config );
cannam@0 27 }
cannam@0 28
cannam@0 29 int Chromagram::initialise( ChromaConfig Config )
cannam@0 30 {
cannam@0 31 m_FMin = Config.min; // min freq
cannam@0 32 m_FMax = Config.max; // max freq
cannam@0 33 m_BPO = Config.BPO; // bins per octave
cannam@34 34 m_normalise = Config.normalise; // if frame normalisation is required
cannam@0 35
cannam@0 36 // No. of constant Q bins
cannam@0 37 m_uK = ( unsigned int ) ceil( m_BPO * log(m_FMax/m_FMin)/log(2.0));
cannam@0 38
cannam@0 39 // Create array for chroma result
cannam@0 40 m_chromadata = new double[ m_BPO ];
cannam@0 41
cannam@0 42 // Create Config Structure for ConstantQ operator
cannam@0 43 CQConfig ConstantQConfig;
cannam@0 44
cannam@0 45 // Populate CQ config structure with parameters
cannam@0 46 // inherited from the Chroma config
cannam@0 47 ConstantQConfig.FS = Config.FS;
cannam@0 48 ConstantQConfig.min = m_FMin;
cannam@0 49 ConstantQConfig.max = m_FMax;
cannam@0 50 ConstantQConfig.BPO = m_BPO;
cannam@0 51 ConstantQConfig.CQThresh = Config.CQThresh;
cannam@0 52
cannam@0 53 // Initialise ConstantQ operator
cannam@0 54 m_ConstantQ = new ConstantQ( ConstantQConfig );
cannam@0 55
cannam@0 56 // Initialise working arrays
cannam@0 57 m_frameSize = m_ConstantQ->getfftlength();
cannam@0 58 m_hopSize = m_ConstantQ->gethop();
cannam@0 59
cannam@64 60 // Initialise FFT object
cannam@64 61 m_FFT = new FFTReal(m_frameSize);
cannam@64 62
cannam@0 63 m_FFTRe = new double[ m_frameSize ];
cannam@0 64 m_FFTIm = new double[ m_frameSize ];
cannam@0 65 m_CQRe = new double[ m_uK ];
cannam@0 66 m_CQIm = new double[ m_uK ];
cannam@0 67
cannam@32 68 m_window = 0;
cannam@32 69 m_windowbuf = 0;
cannam@32 70
cannam@0 71 return 1;
cannam@0 72 }
cannam@0 73
cannam@0 74 Chromagram::~Chromagram()
cannam@0 75 {
cannam@0 76 deInitialise();
cannam@0 77 }
cannam@0 78
cannam@0 79 int Chromagram::deInitialise()
cannam@0 80 {
cannam@32 81 delete[] m_windowbuf;
cannam@32 82 delete m_window;
cannam@32 83
cannam@0 84 delete [] m_chromadata;
cannam@0 85
cannam@0 86 delete m_FFT;
cannam@0 87
cannam@0 88 delete m_ConstantQ;
cannam@0 89
cannam@0 90 delete [] m_FFTRe;
cannam@0 91 delete [] m_FFTIm;
cannam@0 92 delete [] m_CQRe;
cannam@0 93 delete [] m_CQIm;
cannam@0 94 return 1;
cannam@0 95 }
cannam@0 96
cannam@0 97 //----------------------------------------------------------------------------------
cannam@0 98 // returns the absolute value of complex number xx + i*yy
cannam@0 99 double Chromagram::kabs(double xx, double yy)
cannam@0 100 {
cannam@0 101 double ab = sqrt(xx*xx + yy*yy);
cannam@0 102 return(ab);
cannam@0 103 }
cannam@0 104 //-----------------------------------------------------------------------------------
cannam@0 105
cannam@0 106
cannam@0 107 void Chromagram::unityNormalise(double *src)
cannam@0 108 {
cannam@0 109 double min, max;
cannam@0 110
cannam@0 111 double val = 0;
cannam@0 112
cannam@0 113 MathUtilities::getFrameMinMax( src, m_BPO, & min, &max );
cannam@0 114
cannam@0 115 for( unsigned int i = 0; i < m_BPO; i++ )
cannam@0 116 {
cannam@0 117 val = src[ i ] / max;
cannam@0 118
cannam@0 119 src[ i ] = val;
cannam@0 120 }
cannam@0 121 }
cannam@0 122
cannam@0 123
cannam@32 124 double* Chromagram::process( const double *data )
cannam@0 125 {
cannam@51 126 if (!m_skGenerated) {
cannam@51 127 // Generate CQ Kernel
cannam@51 128 m_ConstantQ->sparsekernel();
cannam@51 129 m_skGenerated = true;
cannam@51 130 }
cannam@51 131
cannam@32 132 if (!m_window) {
cannam@32 133 m_window = new Window<double>(HammingWindow, m_frameSize);
cannam@32 134 m_windowbuf = new double[m_frameSize];
cannam@32 135 }
cannam@32 136
cannam@32 137 for (int i = 0; i < m_frameSize; ++i) {
cannam@32 138 m_windowbuf[i] = data[i];
cannam@32 139 }
cannam@32 140 m_window->cut(m_windowbuf);
cannam@32 141
cannam@3 142 // FFT of current frame
cannam@73 143 m_FFT->process(false, m_windowbuf, m_FFTRe, m_FFTIm);
cannam@3 144
cannam@3 145 return process(m_FFTRe, m_FFTIm);
cannam@3 146 }
cannam@3 147
cannam@32 148 double* Chromagram::process( const double *real, const double *imag )
cannam@3 149 {
cannam@51 150 if (!m_skGenerated) {
cannam@51 151 // Generate CQ Kernel
cannam@51 152 m_ConstantQ->sparsekernel();
cannam@51 153 m_skGenerated = true;
cannam@51 154 }
cannam@51 155
cannam@3 156 // initialise chromadata to 0
cannam@3 157 for (unsigned i = 0; i < m_BPO; i++) m_chromadata[i] = 0;
cannam@0 158
cannam@0 159 double cmax = 0.0;
cannam@0 160 double cval = 0;
cannam@0 161
cannam@0 162 // Calculate ConstantQ frame
cannam@3 163 m_ConstantQ->process( real, imag, m_CQRe, m_CQIm );
cannam@0 164
cannam@0 165 // add each octave of cq data into Chromagram
cannam@0 166 const unsigned octaves = (int)floor(double( m_uK/m_BPO))-1;
cannam@3 167 for (unsigned octave = 0; octave <= octaves; octave++)
cannam@0 168 {
cannam@0 169 unsigned firstBin = octave*m_BPO;
cannam@3 170 for (unsigned i = 0; i < m_BPO; i++)
cannam@0 171 {
cannam@0 172 m_chromadata[i] += kabs( m_CQRe[ firstBin + i ], m_CQIm[ firstBin + i ]);
cannam@0 173 }
cannam@0 174 }
cannam@0 175
cannam@34 176 MathUtilities::normalise(m_chromadata, m_BPO, m_normalise);
cannam@0 177
cannam@0 178 return m_chromadata;
cannam@0 179 }
cannam@0 180
cannam@0 181