annotate dsp/chromagram/Chromagram.cpp @ 96:88f3cfcff55f

A threshold (delta) is added in the peak picking parameters structure (PPickParams). It is used as an offset when computing the smoothed detection function. A constructor for the structure PPickParams is also added to set the parameters to 0 when a structure instance is created. Hence programmes using the peak picking parameter structure and which do not set the delta parameter (e.g. QM Vamp note onset detector) won't be affected by the modifications. Functions modified: - dsp/onsets/PeakPicking.cpp - dsp/onsets/PeakPicking.h - dsp/signalconditioning/DFProcess.cpp - dsp/signalconditioning/DFProcess.h
author mathieub <mathieu.barthet@eecs.qmul.ac.uk>
date Mon, 20 Jun 2011 19:01:48 +0100
parents e5907ae6de17
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