changeset 475:64fc3009d0a3

Switch from DOS to Unix line-endings
author Chris Cannam <cannam@all-day-breakfast.com>
date Thu, 30 May 2019 18:28:11 +0100
parents 16009d8a07de
children 2de6184b2ce0
files base/Restrict.h dsp/keydetection/GetKeyMode.cpp dsp/keydetection/GetKeyMode.h dsp/tempotracking/TempoTrack.h
diffstat 4 files changed, 582 insertions(+), 582 deletions(-) [+]
line wrap: on
line diff
--- a/base/Restrict.h	Thu May 30 18:27:27 2019 +0100
+++ b/base/Restrict.h	Thu May 30 18:28:11 2019 +0100
@@ -1,17 +1,17 @@
-
-#ifndef QM_DSP_RESTRICT_H
-#define QM_DSP_RESTRICT_H
-
-#ifdef _MSC_VER
-#define QM_R__ __restrict
-#endif
-
-#ifdef __GNUC__
-#define QM_R__ __restrict__
-#endif
-
-#ifndef QM_R__
-#define QM_R__
-#endif
-
-#endif
+
+#ifndef QM_DSP_RESTRICT_H
+#define QM_DSP_RESTRICT_H
+
+#ifdef _MSC_VER
+#define QM_R__ __restrict
+#endif
+
+#ifdef __GNUC__
+#define QM_R__ __restrict__
+#endif
+
+#ifndef QM_R__
+#define QM_R__
+#endif
+
+#endif
--- a/dsp/keydetection/GetKeyMode.cpp	Thu May 30 18:27:27 2019 +0100
+++ b/dsp/keydetection/GetKeyMode.cpp	Thu May 30 18:28:11 2019 +0100
@@ -1,363 +1,363 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file 2005-2006 Christian Landone and Katy Noland.
-
-    Fixes to correct chroma offsets and for thread safety contributed
-    by Daniel Schürmann.
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#include "GetKeyMode.h"
-#include "maths/MathUtilities.h"
-#include "base/Pitch.h"
-
-#include <iostream>
-
-#include <cstring>
-#include <cstdlib>
-
-static const int kBinsPerOctave = 36;
-
-// Chords profile
-static double MajProfile[kBinsPerOctave] = {
-    0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267,
-    0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186, 
-    0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098,
-    0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239};
-
-static double MinProfile[kBinsPerOctave] = { 
-    0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257,
-    0.0292, 0.0519, 0.0246, 0.0159, 0.0234, 0.0135, 0.0291, 0.0544, 0.0248,
-    0.0137, 0.0176, 0.0104, 0.0352, 0.0670, 0.0302, 0.0222, 0.0349, 0.0164,
-    0.0174, 0.0297, 0.0166, 0.0222, 0.0401, 0.0202, 0.0175, 0.0270, 0.0146};
-//
-    
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-GetKeyMode::GetKeyMode( int sampleRate, float tuningFrequency,
-                        double hpcpAverage, double medianAverage ) :
-    m_hpcpAverage( hpcpAverage ),
-    m_medianAverage( medianAverage ),
-    m_ChrPointer(0),
-    m_DecimatedBuffer(0),
-    m_ChromaBuffer(0),
-    m_MeanHPCP(0),
-    m_MajCorr(0),
-    m_MinCorr(0),
-    m_MedianFilterBuffer(0),
-    m_SortedBuffer(0),
-    m_keyStrengths(0)
-{
-    m_DecimationFactor = 8;
-        
-    // Chromagram configuration parameters
-    m_ChromaConfig.normalise = MathUtilities::NormaliseUnitMax;
-    m_ChromaConfig.FS = sampleRate/(double)m_DecimationFactor;
-    if (m_ChromaConfig.FS < 1) {
-        m_ChromaConfig.FS = 1;
-    }
-
-    // Set C3 (= MIDI #48) as our base:
-    // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc.
-    m_ChromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency );
-    m_ChromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency );
-
-    m_ChromaConfig.BPO = kBinsPerOctave;
-    m_ChromaConfig.CQThresh = 0.0054;
-
-    // Chromagram inst.
-    m_Chroma = new Chromagram( m_ChromaConfig );
-
-    // Get calculated parameters from chroma object
-    m_ChromaFrameSize = m_Chroma->getFrameSize();
-    // override hopsize for this application
-    m_ChromaHopSize = m_ChromaFrameSize;
-
-//    std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl;
-
-    // Chromagram average and estimated key median filter lengths
-    m_ChromaBuffersize = (int)ceil( m_hpcpAverage * m_ChromaConfig.FS/m_ChromaFrameSize );
-    m_MedianWinsize = (int)ceil( m_medianAverage * m_ChromaConfig.FS/m_ChromaFrameSize );
-    
-    // Reset counters
-    m_bufferindex = 0;
-    m_ChromaBufferFilling = 0;
-    m_MedianBufferFilling = 0;
-
-    // Spawn objectc/arrays
-    m_DecimatedBuffer = new double[m_ChromaFrameSize];
-    
-    m_ChromaBuffer = new double[kBinsPerOctave * m_ChromaBuffersize];
-    memset( m_ChromaBuffer, 0, sizeof(double) * kBinsPerOctave * m_ChromaBuffersize);
-    
-    m_MeanHPCP = new double[kBinsPerOctave];
-    
-    m_MajCorr = new double[kBinsPerOctave];
-    m_MinCorr = new double[kBinsPerOctave];
-    
-    m_MajProfileNorm = new double[kBinsPerOctave];
-    m_MinProfileNorm = new double[kBinsPerOctave];
-
-    double mMaj = MathUtilities::mean( MajProfile, kBinsPerOctave );
-    double mMin = MathUtilities::mean( MinProfile, kBinsPerOctave );
-
-    for( unsigned int i = 0; i < kBinsPerOctave; i++ ) {
-        m_MajProfileNorm[i] = MajProfile[i] - mMaj;
-        m_MinProfileNorm[i] = MinProfile[i] - mMin;
-    }
-
-    m_MedianFilterBuffer = new int[ m_MedianWinsize ];
-    memset( m_MedianFilterBuffer, 0, sizeof(int)*m_MedianWinsize);
-    
-    m_SortedBuffer = new int[ m_MedianWinsize ];
-    memset( m_SortedBuffer, 0, sizeof(int)*m_MedianWinsize);
-    
-    m_Decimator = new Decimator( m_ChromaFrameSize*m_DecimationFactor, m_DecimationFactor );
-
-    m_keyStrengths = new double[24];
-}
-
-GetKeyMode::~GetKeyMode()
-{
-    delete m_Chroma;
-    delete m_Decimator;
-    
-    delete [] m_DecimatedBuffer;
-    delete [] m_ChromaBuffer;
-    delete [] m_MeanHPCP;
-    delete [] m_MajCorr;
-    delete [] m_MinCorr;
-    delete [] m_MajProfileNorm;
-    delete [] m_MinProfileNorm;
-    delete [] m_MedianFilterBuffer;
-    delete [] m_SortedBuffer;
-    delete [] m_keyStrengths;
-}
-
-double GetKeyMode::krumCorr( const double *pDataNorm, const double *pProfileNorm, 
-                             int shiftProfile, unsigned int length)
-{
-    double retVal= 0.0;
-    
-    double num = 0;
-    double den = 0;
-    double sum1 = 0;
-    double sum2 = 0;
-    
-    for( unsigned int i = 0; i <length; i++ )
-    {
-        int k = (i - shiftProfile + length) % length;
-
-        num += pDataNorm[i] * pProfileNorm[k];
-
-        sum1 += ( pDataNorm[i] * pDataNorm[i] );
-        sum2 += ( pProfileNorm[k] * pProfileNorm[k] );
-    }
-	
-    den = sqrt(sum1 * sum2);
-
-    if( den>0 ) {
-        retVal = num/den;
-    } else {
-        retVal = 0;
-    }
-
-    return retVal;
-}
-
-int GetKeyMode::process(double *PCMData)
-{
-    int key;
-    unsigned int j,k;
-
-    //////////////////////////////////////////////
-    m_Decimator->process( PCMData, m_DecimatedBuffer);
-
-    m_ChrPointer = m_Chroma->process( m_DecimatedBuffer );
-
-/*
-    std::cout << "raw chroma: ";
-    for (int ii = 0; ii < kBinsPerOctave; ++ii) {
-      if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
-        std::cout << m_ChrPointer[ii] << " ";
-    }
-    std::cout << std::endl;
-*/
-    // populate hpcp values;
-    int cbidx;
-    for( j = 0; j < kBinsPerOctave; j++ ) {
-        cbidx = (m_bufferindex * kBinsPerOctave) + j;
-        m_ChromaBuffer[ cbidx ] = m_ChrPointer[j];
-    }
-
-    //keep track of input buffers;
-    if( m_bufferindex++ >= m_ChromaBuffersize - 1) {
-        m_bufferindex = 0;
-    }
-
-    // track filling of chroma matrix
-    if( m_ChromaBufferFilling++ >= m_ChromaBuffersize) {
-        m_ChromaBufferFilling = m_ChromaBuffersize;
-    }
-
-    //calculate mean
-    for( k = 0; k < kBinsPerOctave; k++ ) {
-        double mnVal = 0.0;
-        for( j = 0; j < m_ChromaBufferFilling; j++ ) {
-            mnVal += m_ChromaBuffer[ k + (j*kBinsPerOctave) ];
-        }
-
-        m_MeanHPCP[k] = mnVal/(double)m_ChromaBufferFilling;
-    }
-
-    // Normalize for zero average
-    double mHPCP = MathUtilities::mean( m_MeanHPCP, kBinsPerOctave );
-    for( k = 0; k < kBinsPerOctave; k++ )
-    {
-        m_MeanHPCP[k] -= mHPCP;
-    }
-
-
-    for( k = 0; k < kBinsPerOctave; k++ )
-    {
-        // The Cromagram has the center of C at bin 0, while the major
-        // and minor profiles have the center of C at 1. We want to have
-        // the correlation for C result also at 1.
-        // To achieve this we have to shift two times:
-        m_MajCorr[k] = krumCorr( m_MeanHPCP, m_MajProfileNorm, (int)k - 2, kBinsPerOctave );
-        m_MinCorr[k] = krumCorr( m_MeanHPCP, m_MinProfileNorm, (int)k - 2, kBinsPerOctave );
-    }
-
-/*
-  std::cout << "raw keys: ";
-  for (int ii = 0; ii < kBinsPerOctave; ++ii) {
-      if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
-      std::cout << m_MajCorr[ii] << " ";
-  }
-  for (int ii = 0; ii < kBinsPerOctave; ++ii) {
-      if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
-      std::cout << m_MinCorr[ii] << " ";
-  }
-  std::cout << std::endl;
-*/
-
-    // m_MajCorr[1] is C center  1 / 3 + 1 = 1
-    // m_MajCorr[4] is D center  4 / 3 + 1 = 2
-    // '+ 1' because we number keys 1-24, not 0-23.
-    double maxMaj;
-    int maxMajBin = MathUtilities::getMax( m_MajCorr, kBinsPerOctave, &maxMaj );
-    double maxMin;
-    int maxMinBin = MathUtilities::getMax( m_MinCorr, kBinsPerOctave, &maxMin );
-    int maxBin = (maxMaj > maxMin) ? maxMajBin : (maxMinBin + kBinsPerOctave);
-    key = maxBin / 3 + 1;
-
-//    std::cout << "fractional key pre-sorting: " << (maxBin + 2) / 3.0 << std::endl;
-//    std::cout << "key pre-sorting: " << key << std::endl;
-
-
-    //Median filtering
-
-    // track Median buffer initial filling
-    if( m_MedianBufferFilling++ >= m_MedianWinsize) {
-        m_MedianBufferFilling = m_MedianWinsize;
-    }
-
-    //shift median buffer
-    for( k = 1; k < m_MedianWinsize; k++ ) {
-        m_MedianFilterBuffer[ k - 1 ] = m_MedianFilterBuffer[ k ];
-    }
-
-    //write new key value into median buffer
-    m_MedianFilterBuffer[ m_MedianWinsize - 1 ] = key;
-
-
-    //Copy median into sorting buffer, reversed
-    unsigned int ijx = 0;
-    for( k = 0; k < m_MedianWinsize; k++ ) {
-        m_SortedBuffer[k] = m_MedianFilterBuffer[m_MedianWinsize-1-ijx];
-        ijx++;
-    }
-
-    qsort(m_SortedBuffer, m_MedianBufferFilling, sizeof(unsigned int),
-          MathUtilities::compareInt);
-/*
-  std::cout << "sorted: ";
-  for (int ii = 0; ii < m_MedianBufferFilling; ++ii) {
-  std::cout << m_SortedBuffer[ii] << " ";
-  }
-  std::cout << std::endl;
-*/
-    int sortlength = m_MedianBufferFilling;
-    int midpoint = (int)ceil((double)sortlength/2);
-
-//  std::cout << "midpoint = " << midpoint << endl;
-
-    if( midpoint <= 0 ) {
-        midpoint = 1;
-    }
-
-    key = m_SortedBuffer[midpoint-1];
-
-// std::cout << "returning key = " << key << endl;
-
-    return key;
-}
-
-
-bool GetKeyMode::isModeMinor( int key )
-{ 
-    return (key > 12);
-}
-
-unsigned int getChromaSize() 
-{ 
-    return kBinsPerOctave; 
-}
-
-double* GetKeyMode::getKeyStrengths() {
-    unsigned int k;
-
-    for (k = 0; k < 24; ++k) {
-        m_keyStrengths[k] = 0;
-    }
-
-    for( k = 0; k < kBinsPerOctave; k++ )
-    {
-        int idx = k / (kBinsPerOctave/12);
-        int rem = k % (kBinsPerOctave/12);
-        if (rem == 0 || m_MajCorr[k] > m_keyStrengths[idx]) {
-            m_keyStrengths[idx] = m_MajCorr[k];
-        }
-    }
-
-    for( k = 0; k < kBinsPerOctave; k++ )
-    {
-        int idx = (k + kBinsPerOctave) / (kBinsPerOctave/12);
-        int rem = k % (kBinsPerOctave/12);
-        if (rem == 0 || m_MinCorr[k] > m_keyStrengths[idx]) {
-            m_keyStrengths[idx] = m_MinCorr[k];
-        }
-    }
-
-/*
-    std::cout << "key strengths: ";
-    for (int ii = 0; ii < 24; ++ii) {
-        if (ii % 6 == 0) std::cout << "\n";
-        std::cout << m_keyStrengths[ii] << " ";
-    }
-    std::cout << std::endl;
-*/
-
-    return m_keyStrengths;
-}
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+/*
+    QM DSP Library
+
+    Centre for Digital Music, Queen Mary, University of London.
+    This file 2005-2006 Christian Landone and Katy Noland.
+
+    Fixes to correct chroma offsets and for thread safety contributed
+    by Daniel Schürmann.
+
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "GetKeyMode.h"
+#include "maths/MathUtilities.h"
+#include "base/Pitch.h"
+
+#include <iostream>
+
+#include <cstring>
+#include <cstdlib>
+
+static const int kBinsPerOctave = 36;
+
+// Chords profile
+static double MajProfile[kBinsPerOctave] = {
+    0.0384, 0.0629, 0.0258, 0.0121, 0.0146, 0.0106, 0.0364, 0.0610, 0.0267,
+    0.0126, 0.0121, 0.0086, 0.0364, 0.0623, 0.0279, 0.0275, 0.0414, 0.0186, 
+    0.0173, 0.0248, 0.0145, 0.0364, 0.0631, 0.0262, 0.0129, 0.0150, 0.0098,
+    0.0312, 0.0521, 0.0235, 0.0129, 0.0142, 0.0095, 0.0289, 0.0478, 0.0239};
+
+static double MinProfile[kBinsPerOctave] = { 
+    0.0375, 0.0682, 0.0299, 0.0119, 0.0138, 0.0093, 0.0296, 0.0543, 0.0257,
+    0.0292, 0.0519, 0.0246, 0.0159, 0.0234, 0.0135, 0.0291, 0.0544, 0.0248,
+    0.0137, 0.0176, 0.0104, 0.0352, 0.0670, 0.0302, 0.0222, 0.0349, 0.0164,
+    0.0174, 0.0297, 0.0166, 0.0222, 0.0401, 0.0202, 0.0175, 0.0270, 0.0146};
+//
+    
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+GetKeyMode::GetKeyMode( int sampleRate, float tuningFrequency,
+                        double hpcpAverage, double medianAverage ) :
+    m_hpcpAverage( hpcpAverage ),
+    m_medianAverage( medianAverage ),
+    m_ChrPointer(0),
+    m_DecimatedBuffer(0),
+    m_ChromaBuffer(0),
+    m_MeanHPCP(0),
+    m_MajCorr(0),
+    m_MinCorr(0),
+    m_MedianFilterBuffer(0),
+    m_SortedBuffer(0),
+    m_keyStrengths(0)
+{
+    m_DecimationFactor = 8;
+        
+    // Chromagram configuration parameters
+    m_ChromaConfig.normalise = MathUtilities::NormaliseUnitMax;
+    m_ChromaConfig.FS = sampleRate/(double)m_DecimationFactor;
+    if (m_ChromaConfig.FS < 1) {
+        m_ChromaConfig.FS = 1;
+    }
+
+    // Set C3 (= MIDI #48) as our base:
+    // This implies that key = 1 => Cmaj, key = 12 => Bmaj, key = 13 => Cmin, etc.
+    m_ChromaConfig.min = Pitch::getFrequencyForPitch( 48, 0, tuningFrequency );
+    m_ChromaConfig.max = Pitch::getFrequencyForPitch( 96, 0, tuningFrequency );
+
+    m_ChromaConfig.BPO = kBinsPerOctave;
+    m_ChromaConfig.CQThresh = 0.0054;
+
+    // Chromagram inst.
+    m_Chroma = new Chromagram( m_ChromaConfig );
+
+    // Get calculated parameters from chroma object
+    m_ChromaFrameSize = m_Chroma->getFrameSize();
+    // override hopsize for this application
+    m_ChromaHopSize = m_ChromaFrameSize;
+
+//    std::cerr << "chroma frame size = " << m_ChromaFrameSize << ", decimation factor = " << m_DecimationFactor << " therefore block size = " << getBlockSize() << std::endl;
+
+    // Chromagram average and estimated key median filter lengths
+    m_ChromaBuffersize = (int)ceil( m_hpcpAverage * m_ChromaConfig.FS/m_ChromaFrameSize );
+    m_MedianWinsize = (int)ceil( m_medianAverage * m_ChromaConfig.FS/m_ChromaFrameSize );
+    
+    // Reset counters
+    m_bufferindex = 0;
+    m_ChromaBufferFilling = 0;
+    m_MedianBufferFilling = 0;
+
+    // Spawn objectc/arrays
+    m_DecimatedBuffer = new double[m_ChromaFrameSize];
+    
+    m_ChromaBuffer = new double[kBinsPerOctave * m_ChromaBuffersize];
+    memset( m_ChromaBuffer, 0, sizeof(double) * kBinsPerOctave * m_ChromaBuffersize);
+    
+    m_MeanHPCP = new double[kBinsPerOctave];
+    
+    m_MajCorr = new double[kBinsPerOctave];
+    m_MinCorr = new double[kBinsPerOctave];
+    
+    m_MajProfileNorm = new double[kBinsPerOctave];
+    m_MinProfileNorm = new double[kBinsPerOctave];
+
+    double mMaj = MathUtilities::mean( MajProfile, kBinsPerOctave );
+    double mMin = MathUtilities::mean( MinProfile, kBinsPerOctave );
+
+    for( unsigned int i = 0; i < kBinsPerOctave; i++ ) {
+        m_MajProfileNorm[i] = MajProfile[i] - mMaj;
+        m_MinProfileNorm[i] = MinProfile[i] - mMin;
+    }
+
+    m_MedianFilterBuffer = new int[ m_MedianWinsize ];
+    memset( m_MedianFilterBuffer, 0, sizeof(int)*m_MedianWinsize);
+    
+    m_SortedBuffer = new int[ m_MedianWinsize ];
+    memset( m_SortedBuffer, 0, sizeof(int)*m_MedianWinsize);
+    
+    m_Decimator = new Decimator( m_ChromaFrameSize*m_DecimationFactor, m_DecimationFactor );
+
+    m_keyStrengths = new double[24];
+}
+
+GetKeyMode::~GetKeyMode()
+{
+    delete m_Chroma;
+    delete m_Decimator;
+    
+    delete [] m_DecimatedBuffer;
+    delete [] m_ChromaBuffer;
+    delete [] m_MeanHPCP;
+    delete [] m_MajCorr;
+    delete [] m_MinCorr;
+    delete [] m_MajProfileNorm;
+    delete [] m_MinProfileNorm;
+    delete [] m_MedianFilterBuffer;
+    delete [] m_SortedBuffer;
+    delete [] m_keyStrengths;
+}
+
+double GetKeyMode::krumCorr( const double *pDataNorm, const double *pProfileNorm, 
+                             int shiftProfile, unsigned int length)
+{
+    double retVal= 0.0;
+    
+    double num = 0;
+    double den = 0;
+    double sum1 = 0;
+    double sum2 = 0;
+    
+    for( unsigned int i = 0; i <length; i++ )
+    {
+        int k = (i - shiftProfile + length) % length;
+
+        num += pDataNorm[i] * pProfileNorm[k];
+
+        sum1 += ( pDataNorm[i] * pDataNorm[i] );
+        sum2 += ( pProfileNorm[k] * pProfileNorm[k] );
+    }
+	
+    den = sqrt(sum1 * sum2);
+
+    if( den>0 ) {
+        retVal = num/den;
+    } else {
+        retVal = 0;
+    }
+
+    return retVal;
+}
+
+int GetKeyMode::process(double *PCMData)
+{
+    int key;
+    unsigned int j,k;
+
+    //////////////////////////////////////////////
+    m_Decimator->process( PCMData, m_DecimatedBuffer);
+
+    m_ChrPointer = m_Chroma->process( m_DecimatedBuffer );
+
+/*
+    std::cout << "raw chroma: ";
+    for (int ii = 0; ii < kBinsPerOctave; ++ii) {
+      if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
+        std::cout << m_ChrPointer[ii] << " ";
+    }
+    std::cout << std::endl;
+*/
+    // populate hpcp values;
+    int cbidx;
+    for( j = 0; j < kBinsPerOctave; j++ ) {
+        cbidx = (m_bufferindex * kBinsPerOctave) + j;
+        m_ChromaBuffer[ cbidx ] = m_ChrPointer[j];
+    }
+
+    //keep track of input buffers;
+    if( m_bufferindex++ >= m_ChromaBuffersize - 1) {
+        m_bufferindex = 0;
+    }
+
+    // track filling of chroma matrix
+    if( m_ChromaBufferFilling++ >= m_ChromaBuffersize) {
+        m_ChromaBufferFilling = m_ChromaBuffersize;
+    }
+
+    //calculate mean
+    for( k = 0; k < kBinsPerOctave; k++ ) {
+        double mnVal = 0.0;
+        for( j = 0; j < m_ChromaBufferFilling; j++ ) {
+            mnVal += m_ChromaBuffer[ k + (j*kBinsPerOctave) ];
+        }
+
+        m_MeanHPCP[k] = mnVal/(double)m_ChromaBufferFilling;
+    }
+
+    // Normalize for zero average
+    double mHPCP = MathUtilities::mean( m_MeanHPCP, kBinsPerOctave );
+    for( k = 0; k < kBinsPerOctave; k++ )
+    {
+        m_MeanHPCP[k] -= mHPCP;
+    }
+
+
+    for( k = 0; k < kBinsPerOctave; k++ )
+    {
+        // The Cromagram has the center of C at bin 0, while the major
+        // and minor profiles have the center of C at 1. We want to have
+        // the correlation for C result also at 1.
+        // To achieve this we have to shift two times:
+        m_MajCorr[k] = krumCorr( m_MeanHPCP, m_MajProfileNorm, (int)k - 2, kBinsPerOctave );
+        m_MinCorr[k] = krumCorr( m_MeanHPCP, m_MinProfileNorm, (int)k - 2, kBinsPerOctave );
+    }
+
+/*
+  std::cout << "raw keys: ";
+  for (int ii = 0; ii < kBinsPerOctave; ++ii) {
+      if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
+      std::cout << m_MajCorr[ii] << " ";
+  }
+  for (int ii = 0; ii < kBinsPerOctave; ++ii) {
+      if (ii % (kBinsPerOctave/12) == 0) std::cout << "\n";
+      std::cout << m_MinCorr[ii] << " ";
+  }
+  std::cout << std::endl;
+*/
+
+    // m_MajCorr[1] is C center  1 / 3 + 1 = 1
+    // m_MajCorr[4] is D center  4 / 3 + 1 = 2
+    // '+ 1' because we number keys 1-24, not 0-23.
+    double maxMaj;
+    int maxMajBin = MathUtilities::getMax( m_MajCorr, kBinsPerOctave, &maxMaj );
+    double maxMin;
+    int maxMinBin = MathUtilities::getMax( m_MinCorr, kBinsPerOctave, &maxMin );
+    int maxBin = (maxMaj > maxMin) ? maxMajBin : (maxMinBin + kBinsPerOctave);
+    key = maxBin / 3 + 1;
+
+//    std::cout << "fractional key pre-sorting: " << (maxBin + 2) / 3.0 << std::endl;
+//    std::cout << "key pre-sorting: " << key << std::endl;
+
+
+    //Median filtering
+
+    // track Median buffer initial filling
+    if( m_MedianBufferFilling++ >= m_MedianWinsize) {
+        m_MedianBufferFilling = m_MedianWinsize;
+    }
+
+    //shift median buffer
+    for( k = 1; k < m_MedianWinsize; k++ ) {
+        m_MedianFilterBuffer[ k - 1 ] = m_MedianFilterBuffer[ k ];
+    }
+
+    //write new key value into median buffer
+    m_MedianFilterBuffer[ m_MedianWinsize - 1 ] = key;
+
+
+    //Copy median into sorting buffer, reversed
+    unsigned int ijx = 0;
+    for( k = 0; k < m_MedianWinsize; k++ ) {
+        m_SortedBuffer[k] = m_MedianFilterBuffer[m_MedianWinsize-1-ijx];
+        ijx++;
+    }
+
+    qsort(m_SortedBuffer, m_MedianBufferFilling, sizeof(unsigned int),
+          MathUtilities::compareInt);
+/*
+  std::cout << "sorted: ";
+  for (int ii = 0; ii < m_MedianBufferFilling; ++ii) {
+  std::cout << m_SortedBuffer[ii] << " ";
+  }
+  std::cout << std::endl;
+*/
+    int sortlength = m_MedianBufferFilling;
+    int midpoint = (int)ceil((double)sortlength/2);
+
+//  std::cout << "midpoint = " << midpoint << endl;
+
+    if( midpoint <= 0 ) {
+        midpoint = 1;
+    }
+
+    key = m_SortedBuffer[midpoint-1];
+
+// std::cout << "returning key = " << key << endl;
+
+    return key;
+}
+
+
+bool GetKeyMode::isModeMinor( int key )
+{ 
+    return (key > 12);
+}
+
+unsigned int getChromaSize() 
+{ 
+    return kBinsPerOctave; 
+}
+
+double* GetKeyMode::getKeyStrengths() {
+    unsigned int k;
+
+    for (k = 0; k < 24; ++k) {
+        m_keyStrengths[k] = 0;
+    }
+
+    for( k = 0; k < kBinsPerOctave; k++ )
+    {
+        int idx = k / (kBinsPerOctave/12);
+        int rem = k % (kBinsPerOctave/12);
+        if (rem == 0 || m_MajCorr[k] > m_keyStrengths[idx]) {
+            m_keyStrengths[idx] = m_MajCorr[k];
+        }
+    }
+
+    for( k = 0; k < kBinsPerOctave; k++ )
+    {
+        int idx = (k + kBinsPerOctave) / (kBinsPerOctave/12);
+        int rem = k % (kBinsPerOctave/12);
+        if (rem == 0 || m_MinCorr[k] > m_keyStrengths[idx]) {
+            m_keyStrengths[idx] = m_MinCorr[k];
+        }
+    }
+
+/*
+    std::cout << "key strengths: ";
+    for (int ii = 0; ii < 24; ++ii) {
+        if (ii % 6 == 0) std::cout << "\n";
+        std::cout << m_keyStrengths[ii] << " ";
+    }
+    std::cout << std::endl;
+*/
+
+    return m_keyStrengths;
+}
--- a/dsp/keydetection/GetKeyMode.h	Thu May 30 18:27:27 2019 +0100
+++ b/dsp/keydetection/GetKeyMode.h	Thu May 30 18:28:11 2019 +0100
@@ -1,91 +1,91 @@
-/*
-    Copyright (c) 2005 Centre for Digital Music ( C4DM )
-                       Queen Mary Univesrity of London
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
- */
-
-#ifndef GETKEYMODE_H
-#define GETKEYMODE_H
-
-
-#include "dsp/rateconversion/Decimator.h"
-#include "dsp/chromagram/Chromagram.h"
-
-
-class GetKeyMode  
-{
-public:
-	GetKeyMode( int sampleRate, float tuningFrequency,
-		    double hpcpAverage, double medianAverage );
-
-	virtual ~GetKeyMode();
-
-	int process( double* PCMData );
-
-	double krumCorr( const double *pDataNorm, const double *pProfileNorm, 
-                         int shiftProfile, unsigned int length );
-
-	unsigned int getBlockSize() { return m_ChromaFrameSize*m_DecimationFactor; }
-	unsigned int getHopSize() { return m_ChromaHopSize*m_DecimationFactor; }
-
-	double* getChroma() { return m_ChrPointer; }
-	unsigned int getChromaSize();
-
-	double* getMeanHPCP() { return m_MeanHPCP; }
-
-	double* getKeyStrengths();
-
-	bool isModeMinor( int key ); 
-
-protected:
-
-	double m_hpcpAverage;
-	double m_medianAverage;
-	unsigned int m_DecimationFactor;
-
-	//Decimator (fixed)
-	Decimator* m_Decimator;
-
-	//chroma configuration
-	ChromaConfig m_ChromaConfig;
-
-	//Chromagram object
-	Chromagram* m_Chroma;
-
-	//Chromagram output pointer
-	double* m_ChrPointer;
-
-	//Framesize
-	unsigned int m_ChromaFrameSize;
-	//Hop
-	unsigned int m_ChromaHopSize;
-
-
-	unsigned int m_ChromaBuffersize;
-	unsigned int m_MedianWinsize;
-	
-	unsigned int m_bufferindex;
-	unsigned int m_ChromaBufferFilling;
-	unsigned int m_MedianBufferFilling;
-	
-
-	double* m_DecimatedBuffer;
-	double* m_ChromaBuffer;
-	double* m_MeanHPCP;
-
-	double* m_MajProfileNorm;
-	double* m_MinProfileNorm;
-	double* m_MajCorr;
-	double* m_MinCorr;
-	int* m_MedianFilterBuffer;
-	int* m_SortedBuffer;
-
-	double *m_keyStrengths;
-};
-
-#endif // !defined GETKEYMODE_H
+/*
+    Copyright (c) 2005 Centre for Digital Music ( C4DM )
+                       Queen Mary Univesrity of London
+
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+ */
+
+#ifndef GETKEYMODE_H
+#define GETKEYMODE_H
+
+
+#include "dsp/rateconversion/Decimator.h"
+#include "dsp/chromagram/Chromagram.h"
+
+
+class GetKeyMode  
+{
+public:
+	GetKeyMode( int sampleRate, float tuningFrequency,
+		    double hpcpAverage, double medianAverage );
+
+	virtual ~GetKeyMode();
+
+	int process( double* PCMData );
+
+	double krumCorr( const double *pDataNorm, const double *pProfileNorm, 
+                         int shiftProfile, unsigned int length );
+
+	unsigned int getBlockSize() { return m_ChromaFrameSize*m_DecimationFactor; }
+	unsigned int getHopSize() { return m_ChromaHopSize*m_DecimationFactor; }
+
+	double* getChroma() { return m_ChrPointer; }
+	unsigned int getChromaSize();
+
+	double* getMeanHPCP() { return m_MeanHPCP; }
+
+	double* getKeyStrengths();
+
+	bool isModeMinor( int key ); 
+
+protected:
+
+	double m_hpcpAverage;
+	double m_medianAverage;
+	unsigned int m_DecimationFactor;
+
+	//Decimator (fixed)
+	Decimator* m_Decimator;
+
+	//chroma configuration
+	ChromaConfig m_ChromaConfig;
+
+	//Chromagram object
+	Chromagram* m_Chroma;
+
+	//Chromagram output pointer
+	double* m_ChrPointer;
+
+	//Framesize
+	unsigned int m_ChromaFrameSize;
+	//Hop
+	unsigned int m_ChromaHopSize;
+
+
+	unsigned int m_ChromaBuffersize;
+	unsigned int m_MedianWinsize;
+	
+	unsigned int m_bufferindex;
+	unsigned int m_ChromaBufferFilling;
+	unsigned int m_MedianBufferFilling;
+	
+
+	double* m_DecimatedBuffer;
+	double* m_ChromaBuffer;
+	double* m_MeanHPCP;
+
+	double* m_MajProfileNorm;
+	double* m_MinProfileNorm;
+	double* m_MajCorr;
+	double* m_MinCorr;
+	int* m_MedianFilterBuffer;
+	int* m_SortedBuffer;
+
+	double *m_keyStrengths;
+};
+
+#endif // !defined GETKEYMODE_H
--- a/dsp/tempotracking/TempoTrack.h	Thu May 30 18:27:27 2019 +0100
+++ b/dsp/tempotracking/TempoTrack.h	Thu May 30 18:28:11 2019 +0100
@@ -1,111 +1,111 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM DSP Library
-
-    Centre for Digital Music, Queen Mary, University of London.
-    This file 2005-2006 Christian Landone.
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#ifndef TEMPOTRACK_H
-#define TEMPOTRACK_H
-
-
-#include <stdio.h>
-#include <vector>
-
-#include "dsp/signalconditioning/DFProcess.h"
-#include "maths/Correlation.h"
-#include "dsp/signalconditioning/Framer.h"
-
-
-
-using std::vector;
-
-struct WinThresh
-{
-    int pre;
-    int post;
-};
-
-struct TTParams
-{
-    int winLength; //Analysis window length
-    int lagLength; //Lag & Stride size
-    int alpha; //alpha-norm parameter
-    int LPOrd; // low-pass Filter order
-    double* LPACoeffs; //low pass Filter den coefficients
-    double* LPBCoeffs; //low pass Filter num coefficients
-    WinThresh WinT;//window size in frames for adaptive thresholding [pre post]:
-};
-
-
-class TempoTrack  
-{
-public:
-    TempoTrack( TTParams Params );
-    virtual ~TempoTrack();
-
-    vector<int> process( vector <double> DF, vector <double> *tempoReturn = 0);
-
-	
-private:
-    void initialise( TTParams Params );
-    void deInitialise();
-
-    int beatPredict( int FSP, double alignment, double period, int step);
-    int phaseMM( double* DF, double* weighting, int winLength, double period );
-    void createPhaseExtractor( double* Filter, int winLength,  double period,  int fsp, int lastBeat );
-    int findMeter( double* ACF,  int len, double period );
-    void constDetect( double* periodP, int currentIdx, int* flag );
-    void stepDetect( double* periodP, double* periodG, int currentIdx, int* flag );
-    void createCombFilter( double* Filter, int winLength, int TSig, double beatLag );
-    double tempoMM( double* ACF, double* weight, int sig );
-	
-    int m_dataLength;
-    int m_winLength;
-    int m_lagLength;
-
-    double m_rayparam;
-    double m_sigma;
-    double m_DFWVNnorm;
-
-    vector<int>	 m_beats; // Vector of detected beats
-
-    double m_lockedTempo;
-
-    double* m_tempoScratch;
-    double* m_smoothRCF; // Smoothed Output of Comb Filterbank (m_tempoScratch)
-	
-    // Processing Buffers 
-    double* m_rawDFFrame; // Original Detection Function Analysis Frame
-    double* m_smoothDFFrame; // Smoothed Detection Function Analysis Frame
-    double* m_frameACF; // AutoCorrelation of Smoothed Detection Function 
-
-    //Low Pass Coefficients for DF Smoothing
-    double* m_ACoeffs;
-    double* m_BCoeffs;
-	
-    // Objetcs/operators declaration
-    Framer m_DFFramer;
-    DFProcess* m_DFConditioning;
-    Correlation m_correlator;
-    // Config structure for DFProcess
-    DFProcConfig m_DFPParams;
-
-	// also want to smooth m_tempoScratch 
-    DFProcess* m_RCFConditioning;
-    // Config structure for RCFProcess
-    DFProcConfig m_RCFPParams;
-
-
-
-};
-
-#endif
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    QM DSP Library
+
+    Centre for Digital Music, Queen Mary, University of London.
+    This file 2005-2006 Christian Landone.
+
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef TEMPOTRACK_H
+#define TEMPOTRACK_H
+
+
+#include <stdio.h>
+#include <vector>
+
+#include "dsp/signalconditioning/DFProcess.h"
+#include "maths/Correlation.h"
+#include "dsp/signalconditioning/Framer.h"
+
+
+
+using std::vector;
+
+struct WinThresh
+{
+    int pre;
+    int post;
+};
+
+struct TTParams
+{
+    int winLength; //Analysis window length
+    int lagLength; //Lag & Stride size
+    int alpha; //alpha-norm parameter
+    int LPOrd; // low-pass Filter order
+    double* LPACoeffs; //low pass Filter den coefficients
+    double* LPBCoeffs; //low pass Filter num coefficients
+    WinThresh WinT;//window size in frames for adaptive thresholding [pre post]:
+};
+
+
+class TempoTrack  
+{
+public:
+    TempoTrack( TTParams Params );
+    virtual ~TempoTrack();
+
+    vector<int> process( vector <double> DF, vector <double> *tempoReturn = 0);
+
+	
+private:
+    void initialise( TTParams Params );
+    void deInitialise();
+
+    int beatPredict( int FSP, double alignment, double period, int step);
+    int phaseMM( double* DF, double* weighting, int winLength, double period );
+    void createPhaseExtractor( double* Filter, int winLength,  double period,  int fsp, int lastBeat );
+    int findMeter( double* ACF,  int len, double period );
+    void constDetect( double* periodP, int currentIdx, int* flag );
+    void stepDetect( double* periodP, double* periodG, int currentIdx, int* flag );
+    void createCombFilter( double* Filter, int winLength, int TSig, double beatLag );
+    double tempoMM( double* ACF, double* weight, int sig );
+	
+    int m_dataLength;
+    int m_winLength;
+    int m_lagLength;
+
+    double m_rayparam;
+    double m_sigma;
+    double m_DFWVNnorm;
+
+    vector<int>	 m_beats; // Vector of detected beats
+
+    double m_lockedTempo;
+
+    double* m_tempoScratch;
+    double* m_smoothRCF; // Smoothed Output of Comb Filterbank (m_tempoScratch)
+	
+    // Processing Buffers 
+    double* m_rawDFFrame; // Original Detection Function Analysis Frame
+    double* m_smoothDFFrame; // Smoothed Detection Function Analysis Frame
+    double* m_frameACF; // AutoCorrelation of Smoothed Detection Function 
+
+    //Low Pass Coefficients for DF Smoothing
+    double* m_ACoeffs;
+    double* m_BCoeffs;
+	
+    // Objetcs/operators declaration
+    Framer m_DFFramer;
+    DFProcess* m_DFConditioning;
+    Correlation m_correlator;
+    // Config structure for DFProcess
+    DFProcConfig m_DFPParams;
+
+	// also want to smooth m_tempoScratch 
+    DFProcess* m_RCFConditioning;
+    // Config structure for RCFProcess
+    DFProcConfig m_RCFPParams;
+
+
+
+};
+
+#endif