Mercurial > hg > qm-dsp
diff dsp/chromagram/ChromaProcess.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 | 2e3f5d2d62c1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dsp/chromagram/ChromaProcess.cpp Wed Apr 05 17:35:59 2006 +0000 @@ -0,0 +1,213 @@ +/* -*- 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 copyright 2005-2006 Christian Landone. + All rights reserved. +*/ + + +#include "ChromaProcess.h" +#include "dsp/maths/Histogram.h" +#include <math.h> +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +ChromaProcess::ChromaProcess() +{ + +} + +ChromaProcess::~ChromaProcess() +{ + +} + +int ChromaProcess::findChromaBias( vector<double> chromaVector, unsigned int BPO, unsigned int frames ) +{ + vector<double> newChroma; + vector<int> peakIndex; + vector<int> modPeakIndex; + + unsigned int chromaLength = chromaVector.size(); + + unsigned int newLength = chromaLength + (2*BPO); + + newChroma.resize( newLength ); + newChroma.clear(); + + modPeakIndex.resize( newLength ); + modPeakIndex.clear(); + + //adds last row at the top and first row at the bottom to create + //circularity - effectively adds 2 to the bpo-length of the vectors: + + for( unsigned int i = 0; i < BPO; i++ ) + { + newChroma.push_back( chromaVector[ chromaLength - BPO + i ] ); + } + + for( unsigned i = 0; i < chromaLength; i++ ) + { + newChroma.push_back( chromaVector[ i ] ); + } + + for( unsigned i = 0; i < BPO; i++ ) + { + newChroma.push_back( chromaVector[ i ] ); + } + + // pick peaks in the chroma + peakIndex = getPeaks( newChroma, BPO ); + + // modularises to res = bpo/12 bins: + // corrects the mod value for bin 3 + modPeakIndex = mod( peakIndex, 3 ); + + // finds the highest concentration of peaks on the bpo/12 bin resolution + THistogram<int> m_hist(3); + + double ave, adev, sdev, var, skew, ccurt; + + m_hist.compute(modPeakIndex); + + m_hist.getMoments( modPeakIndex, ave, adev, sdev, var, skew, ccurt ); + + vector <double> histogram = m_hist.geTHistogramD(); + ////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // Find actual bias from histogram + int minIdx, maxIdx; + double min, max; + + findHistMaxMin( histogram, &max, &maxIdx, &min, &minIdx ); + +/* + FILE* foutchroma = fopen("../testdata/newchroma.bin","wb"); + FILE* foutpeaks = fopen("../testdata/peaks.bin","wb"); + + + fwrite( &chromaVector[0], sizeof(double), chromaVector.size(), foutchroma ); + fwrite( &histogram[0], sizeof(double), histogram.size(), foutpeaks ); + + fclose( foutchroma ); + fclose( foutpeaks ); +*/ + return maxIdx - 1; +} + + +vector <int> ChromaProcess::getPeaks(vector <double> chroma, unsigned int BPO) +{ + vector <int> peaks; + + double pre = 0; + double post = 0; + double current = 0; + + unsigned int BPOCounter = 0; + unsigned int mult = 0; + unsigned int idx = 0; + + for( unsigned int i = 0; i < chroma.size() - 0; i++ ) + { + BPOCounter++; + + pre = chroma[ i ]; + current = chroma[ i + 1 ]; + post = chroma[ i + 2 ]; + + if( (current > 0) && (current > pre) && (current > post) ) + { + peaks.push_back( BPOCounter + 1); + } + + + if( BPOCounter == (BPO - 2 ) ) + { + BPOCounter = 0; + i+=2; + } + + } + + /* + for( unsigned int i = 1; i < chroma.size() - 1; i++ ) + { + BPOCounter++ ; + + pre = chroma[ i - 1 ]; + current = chroma[ i ]; + post = chroma[ i + 1 ]; + + if( (current > 0) && (current > pre) && (current > post) ) + { + peaks.push_back( BPOCounter + 1 ); + } + + if( BPOCounter == (PO - 1) ) + { + BPOCounter = 1; + i+=2; + } + } + */ + return peaks; +} + +vector <int> ChromaProcess::mod(vector <int> input, int res) +{ + vector <int> result; + + for( unsigned int i = 0; i < input.size(); i++ ) + { + int val = input[ i ]; + int res = val - res * floor( (double)val / (double)res ); + + if( val != 0 ) + { + if( res == 0 ) + res = 3; + + result.push_back( res ); + } + else + { + result.push_back( val ); + } + } + return result; +} + +void ChromaProcess::findHistMaxMin( vector<double> hist, double* max, int* maxIdx, double* min, int* minIdx ) +{ + double temp = 0.0; + unsigned int vecLength = hist.size(); + + *minIdx = 0; + *maxIdx = 0; + + *min = hist[0]; + *max = *min; + + for( unsigned int u = 0; u < vecLength; u++ ) + { + temp = hist[ u ]; + + if( temp < *min ) + { + *min = temp ; + *minIdx = u; + } + if( temp > *max ) + { + *max = temp ; + *maxIdx = u; + } + + } +}