Mercurial > hg > qm-dsp
changeset 245:cdfd0948a852
* First cut at properly integrating the segmenter and making it work right
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 09 Jan 2008 16:50:04 +0000 |
parents | f599563a4663 |
children | 0105e9b916a9 |
files | dsp/chromagram/ConstantQ.cpp dsp/chromagram/ConstantQ.h dsp/segmentation/ClusterMeltSegmenter.cpp dsp/segmentation/ClusterMeltSegmenter.h dsp/segmentation/SavedFeatureSegmenter.h dsp/segmentation/cluster_melt.h dsp/segmentation/cluster_segmenter.c dsp/segmentation/cluster_segmenter.h dsp/segmentation/segment.h hmm/hmm.h maths/pca/pca.h qm-dsp.pro |
diffstat | 12 files changed, 157 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/dsp/chromagram/ConstantQ.cpp Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/chromagram/ConstantQ.cpp Wed Jan 09 16:50:04 2008 +0000 @@ -10,6 +10,8 @@ #include "ConstantQ.h" #include "dsp/transforms/FFT.h" +#include <iostream> + //--------------------------------------------------------------------------- // nextpow2 returns the smallest integer n such that 2^n >= x. static double nextpow2(double x) { @@ -168,11 +170,15 @@ m_dQ = 1/(pow(2,(1/(double)m_BPO))-1); // Work out Q value for Filter bank m_uK = (unsigned int) ceil(m_BPO * log(m_FMax/m_FMin)/log(2.0)); // No. of constant Q bins + std::cerr << "ConstantQ::initialise: rate = " << m_FS << ", fmin = " << m_FMin << ", fmax = " << m_FMax << ", bpo = " << m_BPO << ", K = " << m_uK << ", Q = " << m_dQ << std::endl; + // work out length of fft required for this constant Q Filter bank m_FFTLength = (int) pow(2, nextpow2(ceil( m_dQ*m_FS/m_FMin ))); m_hop = m_FFTLength/8; // <------ hop size is window length divided by 32 + std::cerr << "ConstantQ::initialise: -> fft length = " << m_FFTLength << ", hop = " << m_hop << std::endl; + // allocate memory for cqdata m_CQdata = new double [2*m_uK]; }
--- a/dsp/chromagram/ConstantQ.h Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/chromagram/ConstantQ.h Wed Jan 09 16:50:04 2008 +0000 @@ -16,11 +16,11 @@ #include "maths/MathUtilities.h" struct CQConfig{ - unsigned int FS; - double min; - double max; - unsigned int BPO; - double CQThresh; + unsigned int FS; // samplerate + double min; // minimum frequency + double max; // maximum frequency + unsigned int BPO; // bins per octave + double CQThresh; // threshold }; class ConstantQ {
--- a/dsp/segmentation/ClusterMeltSegmenter.cpp Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/ClusterMeltSegmenter.cpp Wed Jan 09 16:50:04 2008 +0000 @@ -11,15 +11,16 @@ #include <cmath> #include "ClusterMeltSegmenter.h" -#include "lib_constQ.h" #include "cluster_segmenter.h" #include "segment.h" +#include "dsp/transforms/FFT.h" + ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) : window(NULL), constq(NULL), featureType(params.featureType), +hopSize(params.hopSize), windowSize(params.windowSize), -hopSize(params.hopSize), fmin(params.fmin), fmax(params.fmax), nbins(params.nbins), @@ -36,47 +37,102 @@ samplerate = fs; if (featureType != FEATURE_TYPE_UNKNOWN) { - ncoeff = static_cast<int>(ceil(nbins * (log(fmax / static_cast<double>(fmin))) / log(2.0))); - constq = init_constQ(fmin, fmax, nbins, samplerate, ncoeff); +//!!! ncoeff = static_cast<int>(ceil(nbins * (log(fmax / static_cast<double>(fmin))) / log(2.0))); + CQConfig config; + config.FS = samplerate; + config.min = fmin; + config.max = fmax; + config.BPO = nbins; + config.CQThresh = 0.0054; + constq = new ConstantQ(config); +//!!! constq = init_constQ(fmin, fmax, nbins, samplerate, ncoeff); + ncoeff = constq->getK(); } } ClusterMeltSegmenter::~ClusterMeltSegmenter() { - delete [] window; - if (constq) - close_constQ(constq); + delete window; + delete constq; +//!!! if (constq) +// close_constQ(constq); +} + +int +ClusterMeltSegmenter::getWindowsize() +{ + if (featureType != FEATURE_TYPE_UNKNOWN) { + std::cerr << "rate = " << samplerate << ", fft length = " << constq->getfftlength() << ", fmin = " << fmin << ", fmax = " << fmax << ", nbins = " << nbins << ", K = " << constq->getK() << ", Q = " << constq->getQ() << std::endl; + return constq->getfftlength(); + } else { + return static_cast<int>(windowSize * samplerate); + } +} + +int +ClusterMeltSegmenter::getHopsize() +{ + return static_cast<int>(hopSize * samplerate); } void ClusterMeltSegmenter::extractFeatures(double* samples, int nsamples) { // create a new window if needed +/*!!! if (!window || nsamples != windowLength) { if (window) delete [] window; - window = hamming_p(nsamples); +// Window<double>(HammingWindow, nsamples).cut +//!!! window = hamming_p(nsamples); windowLength = nsamples; } - +*/ + if (!window || window->getSize() != nsamples) { + delete window; + window = new Window<double>(HammingWindow, nsamples); + } + // copy the samples before windowing in case we need them for something else double* frame = new double[nsamples]; - for (int i = 0; i < nsamples; i++) - frame[i] = samples[i] * window[i]; +// for (int i = 0; i < nsamples; i++) +// frame[i] = samples[i] * window[i]; + window->cut(frame); + std::cerr << "nsamples = " << nsamples << std::endl; + + double *real = new double[nsamples]; + double *imag = new double[nsamples]; + + FFT::process(nsamples, false, frame, 0, real, imag); + + double *cqre = new double[ncoeff]; + double *cqim = new double[ncoeff]; + + constq->process(real, imag, cqre, cqim); + // extract const-Q - do_constQ(constq, frame, nsamples); - int ncq = constq->ncoeff; +//!!! do_constQ(constq, frame, nsamples); +// int ncq = constq->ncoeff; + + delete [] frame; + delete [] real; + delete [] imag; - delete [] frame; - - if (ncq == ncoeff) // else feature extraction failed - { - vector<double> cq(ncq); - for (int i = 0; i < ncq; i++) - cq[i] = constq->absconstQtransform[i]; +//!!! if (ncq == ncoeff) // else feature extraction failed +// { +// vector<double> cq(ncq); +// for (int i = 0; i < ncq; i++) +// cq[i] = constq->absconstQtransform[i]; + vector<double> cq(ncoeff); + for (int i = 0; i < ncoeff; ++i) { + cq[i] = sqrt(cqre[i] * cqre[i] + cqim[i] * cqim[i]); + } features.push_back(cq); - } +// } + + delete[] cqre; + delete[] cqim; } void ClusterMeltSegmenter::segment(int m) @@ -95,7 +151,8 @@ { if (constq) { - close_constQ(constq); // finished extracting features +//!!! close_constQ(constq); // finished extracting features + delete constq; constq = NULL; }
--- a/dsp/segmentation/ClusterMeltSegmenter.h Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/ClusterMeltSegmenter.h Wed Jan 09 16:50:04 2008 +0000 @@ -11,8 +11,9 @@ #include "segment.h" #include "Segmenter.h" -#include "hmm.h" -#include "lib_constQ.h" +#include "hmm/hmm.h" +#include "base/Window.h" +#include "dsp/chromagram/ConstantQ.h" using std::vector; @@ -40,8 +41,8 @@ ClusterMeltSegmenter(ClusterMeltSegmenterParams params); virtual ~ClusterMeltSegmenter(); virtual void initialise(int samplerate); - virtual int getWindowsize() { return static_cast<int>(windowSize * samplerate); } - virtual int getHopsize() { return static_cast<int>(hopSize * samplerate); } + virtual int getWindowsize(); + virtual int getHopsize(); virtual void extractFeatures(double* samples, int nsamples); void setFeatures(const vector<vector<double> >& f); // provide the features yourself virtual void segment(); // segment into default number of segment-types @@ -51,9 +52,9 @@ //void mpeg7ConstQ(); void makeSegmentation(int* q, int len); - double* window; - int windowLength; // in samples - constQ_t* constq; + Window<double> *window; +// int windowLength; // in samples + ConstantQ* constq; model_t* model; // the HMM //vector<int> stateSequence; //vector<int> segmentTypeSequence;
--- a/dsp/segmentation/SavedFeatureSegmenter.h Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/SavedFeatureSegmenter.h Wed Jan 09 16:50:04 2008 +0000 @@ -11,7 +11,7 @@ #include "segment.h" #include "Segmenter.h" -#include "hmm.h" +#include "hmm/hmm.h" using std::vector; @@ -58,4 +58,5 @@ int nclusters; int histogramLength; int neighbourhoodLimit; -}; \ No newline at end of file +}; +
--- a/dsp/segmentation/cluster_melt.h Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/cluster_melt.h Wed Jan 09 16:50:04 2008 +0000 @@ -12,6 +12,10 @@ #include <stdlib.h> #include <math.h> +#ifdef __cplusplus +extern "C" { +#endif + void cluster_melt(double *h, /* normalised histograms, as a vector in row major order */ int m, /* number of dimensions (i.e. histogram bins) */ int n, /* number of histograms */ @@ -22,4 +26,8 @@ int *c /* sequence of cluster assignments */ ); -#endif \ No newline at end of file +#ifdef __cplusplus +} +#endif + +#endif
--- a/dsp/segmentation/cluster_segmenter.c Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/cluster_segmenter.c Wed Jan 09 16:50:04 2008 +0000 @@ -36,6 +36,7 @@ sum += chroma[t][b]; for (b = 0; b < bins; b++) chroma[t][b] /= sum; + */ /* normalise to unit max - NO this made results much worse! maxchroma = 0; for (b = 0; b < bins; b++)
--- a/dsp/segmentation/cluster_segmenter.h Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/cluster_segmenter.h Wed Jan 09 16:50:04 2008 +0000 @@ -17,8 +17,12 @@ #include "segment.h" #include "cluster_melt.h" -#include "hmm.h" -#include "pca.h" +#include "hmm/hmm.h" +#include "maths/pca/pca.h" + +#ifdef __cplusplus +extern "C" { +#endif /* applies MPEG-7 normalisation to constant-Q features, storing normalised envelope (norm) in last feature dimension */ void mpeg7_constq(double** features, int nframes, int ncoeff); @@ -34,5 +38,8 @@ void constq_segment(int* q, double** features, int frames_read, int bins, int ncoeff, int feature_type, int nHMM_states, int histogram_length, int nclusters, int neighbour_limit); +#ifdef __cplusplus +} +#endif -#endif \ No newline at end of file +#endif
--- a/dsp/segmentation/segment.h Wed Jan 09 10:48:08 2008 +0000 +++ b/dsp/segmentation/segment.h Wed Jan 09 16:50:04 2008 +0000 @@ -1,6 +1,10 @@ #ifndef _SEGMENT_H #define _SEGMENT_H +#ifdef __cplusplus +extern "C" { +#endif + /* * segment.h * soundbite @@ -32,5 +36,9 @@ FEATURE_TYPE_CHROMA } feature_types; +#ifdef __cplusplus +} #endif +#endif +
--- a/hmm/hmm.h Wed Jan 09 10:48:08 2008 +0000 +++ b/hmm/hmm.h Wed Jan 09 16:50:04 2008 +0000 @@ -1,6 +1,10 @@ #ifndef _HMM_H #define _HMM_H +#ifdef __cplusplus +extern "C" { +#endif + /* * hmm.h * soundbite @@ -35,5 +39,9 @@ double loggauss(double* x, int L, double* mu, double** icov, double detcov, double* y, double* z); void hmm_print(model_t* model); +#ifdef __cplusplus +} #endif +#endif +
--- a/maths/pca/pca.h Wed Jan 09 10:48:08 2008 +0000 +++ b/maths/pca/pca.h Wed Jan 09 16:50:04 2008 +0000 @@ -1,6 +1,10 @@ #ifndef _PCA_H #define _PCA_H +#ifdef __cplusplus +extern "C" { +#endif + /* * pca.h * soundbite @@ -12,6 +16,10 @@ void pca_project(double** data, int n, int m, int ncomponents); +#ifdef __cplusplus +} +#endif + #endif
--- a/qm-dsp.pro Wed Jan 09 10:48:08 2008 +0000 +++ b/qm-dsp.pro Wed Jan 09 16:50:04 2008 +0000 @@ -1,5 +1,5 @@ TEMPLATE = lib -CONFIG += release warn_on staticlib +CONFIG += warn_on staticlib release CONFIG -= qt OBJECTS_DIR = tmp_obj MOC_DIR = tmp_moc @@ -28,6 +28,12 @@ dsp/onsets/PeakPicking.h \ dsp/phasevocoder/PhaseVocoder.h \ dsp/rateconversion/Decimator.h \ + dsp/segmentation/cluster_melt.h \ + dsp/segmentation/ClusterMeltSegmenter.h \ + dsp/segmentation/cluster_segmenter.h \ + dsp/segmentation/SavedFeatureSegmenter.h \ + dsp/segmentation/Segmenter.h \ + dsp/segmentation/segment.h \ dsp/signalconditioning/DFProcess.h \ dsp/signalconditioning/Filter.h \ dsp/signalconditioning/FiltFilt.h \ @@ -53,6 +59,11 @@ dsp/onsets/PeakPicking.cpp \ dsp/phasevocoder/PhaseVocoder.cpp \ dsp/rateconversion/Decimator.cpp \ + dsp/segmentation/cluster_melt.c \ + dsp/segmentation/ClusterMeltSegmenter.cpp \ + dsp/segmentation/cluster_segmenter.c \ + dsp/segmentation/SavedFeatureSegmenter.cpp \ + dsp/segmentation/Segmenter.cpp \ dsp/signalconditioning/DFProcess.cpp \ dsp/signalconditioning/Filter.cpp \ dsp/signalconditioning/FiltFilt.cpp \