annotate dsp/chromagram/Chromagram.cpp @ 515:08bcc06c38ec tip master

Remove fast-math
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 28 Jan 2020 15:27:37 +0000
parents 1bea13b8f951
children
rev   line source
c@225 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@225 2 /*
c@225 3 QM DSP Library
c@225 4
c@225 5 Centre for Digital Music, Queen Mary, University of London.
c@309 6 This file 2005-2006 Christian Landone.
c@309 7
c@309 8 This program is free software; you can redistribute it and/or
c@309 9 modify it under the terms of the GNU General Public License as
c@309 10 published by the Free Software Foundation; either version 2 of the
c@309 11 License, or (at your option) any later version. See the file
c@309 12 COPYING included with this distribution for more information.
c@225 13 */
c@225 14
c@225 15 #include <iostream>
c@225 16 #include <cmath>
c@241 17 #include "maths/MathUtilities.h"
c@225 18 #include "Chromagram.h"
c@225 19
c@225 20 //----------------------------------------------------------------------------
c@225 21
c@276 22 Chromagram::Chromagram( ChromaConfig Config ) :
c@276 23 m_skGenerated(false)
c@225 24 {
c@225 25 initialise( Config );
c@225 26 }
c@225 27
c@225 28 int Chromagram::initialise( ChromaConfig Config )
cannam@483 29 {
cannam@483 30 m_FMin = Config.min; // min freq
cannam@483 31 m_FMax = Config.max; // max freq
cannam@483 32 m_BPO = Config.BPO; // bins per octave
c@259 33 m_normalise = Config.normalise; // if frame normalisation is required
c@225 34
cannam@468 35 // Extend range to a full octave
cannam@468 36 double octaves = log(m_FMax / m_FMin) / log(2.0);
cannam@468 37 m_FMax = m_FMin * pow(2.0, ceil(octaves));
c@225 38
c@225 39 // Create array for chroma result
c@225 40 m_chromadata = new double[ m_BPO ];
c@225 41
c@225 42 // Create Config Structure for ConstantQ operator
c@225 43 CQConfig ConstantQConfig;
c@225 44
c@225 45 // Populate CQ config structure with parameters
c@225 46 // inherited from the Chroma config
cannam@465 47 ConstantQConfig.FS = Config.FS;
c@225 48 ConstantQConfig.min = m_FMin;
c@225 49 ConstantQConfig.max = m_FMax;
c@225 50 ConstantQConfig.BPO = m_BPO;
c@225 51 ConstantQConfig.CQThresh = Config.CQThresh;
cannam@483 52
c@225 53 // Initialise ConstantQ operator
c@225 54 m_ConstantQ = new ConstantQ( ConstantQConfig );
c@225 55
cannam@468 56 // No. of constant Q bins
cannam@468 57 m_uK = m_ConstantQ->getK();
cannam@468 58
c@225 59 // Initialise working arrays
cannam@495 60 m_frameSize = m_ConstantQ->getFFTLength();
cannam@495 61 m_hopSize = m_ConstantQ->getHop();
c@225 62
cannam@483 63 // Initialise FFT object
c@289 64 m_FFT = new FFTReal(m_frameSize);
c@289 65
c@225 66 m_FFTRe = new double[ m_frameSize ];
c@225 67 m_FFTIm = new double[ m_frameSize ];
c@225 68 m_CQRe = new double[ m_uK ];
c@225 69 m_CQIm = new double[ m_uK ];
c@225 70
c@257 71 m_window = 0;
c@257 72 m_windowbuf = 0;
c@257 73
c@225 74 return 1;
c@225 75 }
c@225 76
c@225 77 Chromagram::~Chromagram()
c@225 78 {
c@225 79 deInitialise();
c@225 80 }
c@225 81
c@225 82 int Chromagram::deInitialise()
c@225 83 {
c@257 84 delete[] m_windowbuf;
c@257 85 delete m_window;
c@257 86
c@225 87 delete [] m_chromadata;
c@225 88
c@225 89 delete m_FFT;
c@225 90
c@225 91 delete m_ConstantQ;
c@225 92
c@225 93 delete [] m_FFTRe;
c@225 94 delete [] m_FFTIm;
c@225 95 delete [] m_CQRe;
c@225 96 delete [] m_CQIm;
c@225 97 return 1;
c@225 98 }
c@225 99
c@225 100 //----------------------------------------------------------------------------------
c@225 101 // returns the absolute value of complex number xx + i*yy
c@225 102 double Chromagram::kabs(double xx, double yy)
c@225 103 {
c@225 104 double ab = sqrt(xx*xx + yy*yy);
c@225 105 return(ab);
c@225 106 }
c@225 107 //-----------------------------------------------------------------------------------
c@225 108
c@225 109
c@225 110 void Chromagram::unityNormalise(double *src)
c@225 111 {
c@225 112 double min, max;
c@225 113 double val = 0;
c@225 114
c@225 115 MathUtilities::getFrameMinMax( src, m_BPO, & min, &max );
c@225 116
cannam@483 117 for (int i = 0; i < m_BPO; i++) {
cannam@483 118 val = src[ i ] / max;
cannam@483 119 src[ i ] = val;
c@225 120 }
c@225 121 }
c@225 122
c@225 123
cannam@467 124 double *Chromagram::process(const double *data)
c@225 125 {
c@276 126 if (!m_skGenerated) {
c@276 127 // Generate CQ Kernel
c@276 128 m_ConstantQ->sparsekernel();
c@276 129 m_skGenerated = true;
c@276 130 }
c@276 131
c@257 132 if (!m_window) {
c@257 133 m_window = new Window<double>(HammingWindow, m_frameSize);
c@257 134 m_windowbuf = new double[m_frameSize];
c@257 135 }
c@257 136
c@257 137 for (int i = 0; i < m_frameSize; ++i) {
c@257 138 m_windowbuf[i] = data[i];
c@257 139 }
c@257 140 m_window->cut(m_windowbuf);
c@257 141
cannam@467 142 // The frequency-domain version expects pre-fftshifted input - so
cannam@467 143 // we must do the same here
cannam@467 144 for (int i = 0; i < m_frameSize/2; ++i) {
cannam@467 145 double tmp = m_windowbuf[i];
cannam@467 146 m_windowbuf[i] = m_windowbuf[i + m_frameSize/2];
cannam@467 147 m_windowbuf[i + m_frameSize/2] = tmp;
cannam@467 148 }
cannam@467 149
c@339 150 m_FFT->forward(m_windowbuf, m_FFTRe, m_FFTIm);
c@228 151
c@228 152 return process(m_FFTRe, m_FFTIm);
c@228 153 }
c@228 154
cannam@467 155 double *Chromagram::process(const double *real, const double *imag)
c@228 156 {
c@276 157 if (!m_skGenerated) {
c@276 158 // Generate CQ Kernel
c@276 159 m_ConstantQ->sparsekernel();
c@276 160 m_skGenerated = true;
c@276 161 }
c@276 162
c@228 163 // initialise chromadata to 0
c@414 164 for (int i = 0; i < m_BPO; i++) m_chromadata[i] = 0;
c@225 165
c@225 166 // Calculate ConstantQ frame
c@228 167 m_ConstantQ->process( real, imag, m_CQRe, m_CQIm );
cannam@483 168
c@225 169 // add each octave of cq data into Chromagram
cannam@466 170 const int octaves = m_uK / m_BPO;
cannam@483 171 for (int octave = 0; octave < octaves; octave++) {
cannam@483 172 int firstBin = octave*m_BPO;
cannam@483 173 for (int i = 0; i < m_BPO; i++) {
cannam@483 174 m_chromadata[i] += kabs( m_CQRe[ firstBin + i ],
cannam@483 175 m_CQIm[ firstBin + i ]);
cannam@483 176 }
c@225 177 }
c@225 178
c@259 179 MathUtilities::normalise(m_chromadata, m_BPO, m_normalise);
c@225 180
c@225 181 return m_chromadata;
c@225 182 }
c@225 183
c@225 184