summaryrefslogtreecommitdiff
path: root/libs/qm-dsp/dsp
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-10-06 01:54:21 +0200
committerRobin Gareus <robin@gareus.org>2016-10-06 01:54:21 +0200
commit344728551d25220398636c22372e5d89e9684497 (patch)
tree52ecb91519cd6cd05eb7846028c447ef39790e29 /libs/qm-dsp/dsp
parenta543ae329c4a3d6af3182ee55f3c865a89db2f08 (diff)
remove more unused qm-dsp code (fixes windows compile no LAPACK)
Diffstat (limited to 'libs/qm-dsp/dsp')
-rw-r--r--libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.cpp398
-rw-r--r--libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.h109
-rw-r--r--libs/qm-dsp/dsp/segmentation/Segmenter.cpp31
-rw-r--r--libs/qm-dsp/dsp/segmentation/Segmenter.h62
-rw-r--r--libs/qm-dsp/dsp/segmentation/cluster_melt.c225
-rw-r--r--libs/qm-dsp/dsp/segmentation/cluster_melt.h39
-rw-r--r--libs/qm-dsp/dsp/segmentation/cluster_segmenter.c285
-rw-r--r--libs/qm-dsp/dsp/segmentation/cluster_segmenter.h51
-rw-r--r--libs/qm-dsp/dsp/segmentation/segment.h50
9 files changed, 0 insertions, 1250 deletions
diff --git a/libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.cpp b/libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.cpp
deleted file mode 100644
index 22835f7116..0000000000
--- a/libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
-
-/*
- * ClusterMeltSegmenter.cpp
- *
- * Created by Mark Levy on 23/03/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- */
-
-#include <cfloat>
-#include <cmath>
-
-#include "ClusterMeltSegmenter.h"
-#include "cluster_segmenter.h"
-#include "segment.h"
-
-#include "dsp/transforms/FFT.h"
-#include "dsp/chromagram/ConstantQ.h"
-#include "dsp/rateconversion/Decimator.h"
-#include "dsp/mfcc/MFCC.h"
-
-ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) :
- window(NULL),
- fft(NULL),
- constq(NULL),
- mfcc(NULL),
- featureType(params.featureType),
- hopSize(params.hopSize),
- windowSize(params.windowSize),
- fmin(params.fmin),
- fmax(params.fmax),
- nbins(params.nbins),
- ncomponents(params.ncomponents), // NB currently not passed - no. of PCA components is set in cluser_segmenter.c
- nHMMStates(params.nHMMStates),
- nclusters(params.nclusters),
- histogramLength(params.histogramLength),
- neighbourhoodLimit(params.neighbourhoodLimit),
- decimator(NULL)
-{
-}
-
-void ClusterMeltSegmenter::initialise(int fs)
-{
- samplerate = fs;
-
- if (featureType == FEATURE_TYPE_CONSTQ ||
- featureType == FEATURE_TYPE_CHROMA) {
-
- // run internal processing at 11025 or thereabouts
- int internalRate = 11025;
- int decimationFactor = samplerate / internalRate;
- if (decimationFactor < 1) decimationFactor = 1;
-
- // must be a power of two
- while (decimationFactor & (decimationFactor - 1)) ++decimationFactor;
-
- if (decimationFactor > Decimator::getHighestSupportedFactor()) {
- decimationFactor = Decimator::getHighestSupportedFactor();
- }
-
- if (decimationFactor > 1) {
- decimator = new Decimator(getWindowsize(), decimationFactor);
- }
-
- CQConfig config;
- config.FS = samplerate / decimationFactor;
- config.min = fmin;
- config.max = fmax;
- config.BPO = nbins;
- config.CQThresh = 0.0054;
-
- constq = new ConstantQ(config);
- constq->sparsekernel();
-
- ncoeff = constq->getK();
-
- fft = new FFTReal(constq->getfftlength());
-
- } else if (featureType == FEATURE_TYPE_MFCC) {
-
- // run internal processing at 22050 or thereabouts
- int internalRate = 22050;
- int decimationFactor = samplerate / internalRate;
- if (decimationFactor < 1) decimationFactor = 1;
-
- // must be a power of two
- while (decimationFactor & (decimationFactor - 1)) ++decimationFactor;
-
- if (decimationFactor > Decimator::getHighestSupportedFactor()) {
- decimationFactor = Decimator::getHighestSupportedFactor();
- }
-
- if (decimationFactor > 1) {
- decimator = new Decimator(getWindowsize(), decimationFactor);
- }
-
- MFCCConfig config(samplerate / decimationFactor);
- config.fftsize = 2048;
- config.nceps = 19;
- config.want_c0 = true;
-
- mfcc = new MFCC(config);
- ncoeff = config.nceps + 1;
- }
-}
-
-ClusterMeltSegmenter::~ClusterMeltSegmenter()
-{
- delete window;
- delete constq;
- delete decimator;
- delete fft;
-}
-
-int
-ClusterMeltSegmenter::getWindowsize()
-{
- return static_cast<int>(windowSize * samplerate + 0.001);
-}
-
-int
-ClusterMeltSegmenter::getHopsize()
-{
- return static_cast<int>(hopSize * samplerate + 0.001);
-}
-
-void ClusterMeltSegmenter::extractFeatures(const double* samples, int nsamples)
-{
- if (featureType == FEATURE_TYPE_CONSTQ ||
- featureType == FEATURE_TYPE_CHROMA) {
- extractFeaturesConstQ(samples, nsamples);
- } else if (featureType == FEATURE_TYPE_MFCC) {
- extractFeaturesMFCC(samples, nsamples);
- }
-}
-
-void ClusterMeltSegmenter::extractFeaturesConstQ(const double* samples, int nsamples)
-{
- if (!constq) {
- std::cerr << "ERROR: ClusterMeltSegmenter::extractFeaturesConstQ: "
- << "No const-q: initialise not called?"
- << std::endl;
- return;
- }
-
- if (nsamples < getWindowsize()) {
- std::cerr << "ERROR: ClusterMeltSegmenter::extractFeatures: nsamples < windowsize (" << nsamples << " < " << getWindowsize() << ")" << std::endl;
- return;
- }
-
- int fftsize = constq->getfftlength();
-
- if (!window || window->getSize() != fftsize) {
- delete window;
- window = new Window<double>(HammingWindow, fftsize);
- }
-
- vector<double> cq(ncoeff);
-
- for (int i = 0; i < ncoeff; ++i) cq[i] = 0.0;
-
- const double *psource = samples;
- int pcount = nsamples;
-
- if (decimator) {
- pcount = nsamples / decimator->getFactor();
- double *decout = new double[pcount];
- decimator->process(samples, decout);
- psource = decout;
- }
-
- int origin = 0;
-
-// std::cerr << "nsamples = " << nsamples << ", pcount = " << pcount << std::endl;
-
- int frames = 0;
-
- double *frame = new double[fftsize];
- double *real = new double[fftsize];
- double *imag = new double[fftsize];
- double *cqre = new double[ncoeff];
- double *cqim = new double[ncoeff];
-
- while (origin <= pcount) {
-
- // always need at least one fft window per block, but after
- // that we want to avoid having any incomplete ones
- if (origin > 0 && origin + fftsize >= pcount) break;
-
- for (int i = 0; i < fftsize; ++i) {
- if (origin + i < pcount) {
- frame[i] = psource[origin + i];
- } else {
- frame[i] = 0.0;
- }
- }
-
- for (int i = 0; i < fftsize/2; ++i) {
- double value = frame[i];
- frame[i] = frame[i + fftsize/2];
- frame[i + fftsize/2] = value;
- }
-
- window->cut(frame);
-
- fft->forward(frame, real, imag);
-
- constq->process(real, imag, cqre, cqim);
-
- for (int i = 0; i < ncoeff; ++i) {
- cq[i] += sqrt(cqre[i] * cqre[i] + cqim[i] * cqim[i]);
- }
- ++frames;
-
- origin += fftsize/2;
- }
-
- delete [] cqre;
- delete [] cqim;
- delete [] real;
- delete [] imag;
- delete [] frame;
-
- for (int i = 0; i < ncoeff; ++i) {
- cq[i] /= frames;
- }
-
- if (decimator) delete[] psource;
-
- features.push_back(cq);
-}
-
-void ClusterMeltSegmenter::extractFeaturesMFCC(const double* samples, int nsamples)
-{
- if (!mfcc) {
- std::cerr << "ERROR: ClusterMeltSegmenter::extractFeaturesMFCC: "
- << "No mfcc: initialise not called?"
- << std::endl;
- return;
- }
-
- if (nsamples < getWindowsize()) {
- std::cerr << "ERROR: ClusterMeltSegmenter::extractFeatures: nsamples < windowsize (" << nsamples << " < " << getWindowsize() << ")" << std::endl;
- return;
- }
-
- int fftsize = mfcc->getfftlength();
-
- vector<double> cc(ncoeff);
-
- for (int i = 0; i < ncoeff; ++i) cc[i] = 0.0;
-
- const double *psource = samples;
- int pcount = nsamples;
-
- if (decimator) {
- pcount = nsamples / decimator->getFactor();
- double *decout = new double[pcount];
- decimator->process(samples, decout);
- psource = decout;
- }
-
- int origin = 0;
- int frames = 0;
-
- double *frame = new double[fftsize];
- double *ccout = new double[ncoeff];
-
- while (origin <= pcount) {
-
- // always need at least one fft window per block, but after
- // that we want to avoid having any incomplete ones
- if (origin > 0 && origin + fftsize >= pcount) break;
-
- for (int i = 0; i < fftsize; ++i) {
- if (origin + i < pcount) {
- frame[i] = psource[origin + i];
- } else {
- frame[i] = 0.0;
- }
- }
-
- mfcc->process(frame, ccout);
-
- for (int i = 0; i < ncoeff; ++i) {
- cc[i] += ccout[i];
- }
- ++frames;
-
- origin += fftsize/2;
- }
-
- delete [] ccout;
- delete [] frame;
-
- for (int i = 0; i < ncoeff; ++i) {
- cc[i] /= frames;
- }
-
- if (decimator) delete[] psource;
-
- features.push_back(cc);
-}
-
-void ClusterMeltSegmenter::segment(int m)
-{
- nclusters = m;
- segment();
-}
-
-void ClusterMeltSegmenter::setFeatures(const vector<vector<double> >& f)
-{
- features = f;
- featureType = FEATURE_TYPE_UNKNOWN;
-}
-
-void ClusterMeltSegmenter::segment()
-{
- delete constq;
- constq = 0;
- delete mfcc;
- mfcc = 0;
- delete decimator;
- decimator = 0;
-
- if (features.size() < histogramLength) return;
-/*
- std::cerr << "ClusterMeltSegmenter::segment: have " << features.size()
- << " features with " << features[0].size() << " coefficients (ncoeff = " << ncoeff << ", ncomponents = " << ncomponents << ")" << std::endl;
-*/
- // copy the features to a native array and use the existing C segmenter...
- double** arrFeatures = new double*[features.size()];
- for (int i = 0; i < features.size(); i++)
- {
- if (featureType == FEATURE_TYPE_UNKNOWN) {
- arrFeatures[i] = new double[features[0].size()];
- for (int j = 0; j < features[0].size(); j++)
- arrFeatures[i][j] = features[i][j];
- } else {
- arrFeatures[i] = new double[ncoeff+1]; // allow space for the normalised envelope
- for (int j = 0; j < ncoeff; j++)
- arrFeatures[i][j] = features[i][j];
- }
- }
-
- q = new int[features.size()];
-
- if (featureType == FEATURE_TYPE_UNKNOWN ||
- featureType == FEATURE_TYPE_MFCC)
- cluster_segment(q, arrFeatures, features.size(), features[0].size(), nHMMStates, histogramLength,
- nclusters, neighbourhoodLimit);
- else
- constq_segment(q, arrFeatures, features.size(), nbins, ncoeff, featureType,
- nHMMStates, histogramLength, nclusters, neighbourhoodLimit);
-
- // convert the cluster assignment sequence to a segmentation
- makeSegmentation(q, features.size());
-
- // de-allocate arrays
- delete [] q;
- for (int i = 0; i < features.size(); i++)
- delete [] arrFeatures[i];
- delete [] arrFeatures;
-
- // clear the features
- clear();
-}
-
-void ClusterMeltSegmenter::makeSegmentation(int* q, int len)
-{
- segmentation.segments.clear();
- segmentation.nsegtypes = nclusters;
- segmentation.samplerate = samplerate;
-
- Segment segment;
- segment.start = 0;
- segment.type = q[0];
-
- for (int i = 1; i < len; i++)
- {
- if (q[i] != q[i-1])
- {
- segment.end = i * getHopsize();
- segmentation.segments.push_back(segment);
- segment.type = q[i];
- segment.start = segment.end;
- }
- }
- segment.end = len * getHopsize();
- segmentation.segments.push_back(segment);
-}
-
diff --git a/libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.h b/libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.h
deleted file mode 100644
index 327a25f073..0000000000
--- a/libs/qm-dsp/dsp/segmentation/ClusterMeltSegmenter.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
-
-/*
- * ClusterMeltSegmenter.h
- *
- * Created by Mark Levy on 23/03/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- */
-
-#include <vector>
-
-#include "segment.h"
-#include "Segmenter.h"
-#include "hmm/hmm.h"
-#include "base/Window.h"
-
-using std::vector;
-
-class Decimator;
-class ConstantQ;
-class MFCC;
-class FFTReal;
-
-class ClusterMeltSegmenterParams
-// defaults are sensible for 11025Hz with 0.2 second hopsize
-{
-public:
- ClusterMeltSegmenterParams() :
- featureType(FEATURE_TYPE_CONSTQ),
- hopSize(0.2),
- windowSize(0.6),
- fmin(62),
- fmax(16000),
- nbins(8),
- ncomponents(20),
- nHMMStates(40),
- nclusters(10),
- histogramLength(15),
- neighbourhoodLimit(20) { }
- feature_types featureType;
- double hopSize; // in secs
- double windowSize; // in secs
- int fmin;
- int fmax;
- int nbins;
- int ncomponents;
- int nHMMStates;
- int nclusters;
- int histogramLength;
- int neighbourhoodLimit;
-};
-
-class ClusterMeltSegmenter : public Segmenter
-{
-public:
- ClusterMeltSegmenter(ClusterMeltSegmenterParams params);
- virtual ~ClusterMeltSegmenter();
- virtual void initialise(int samplerate);
- virtual int getWindowsize();
- virtual int getHopsize();
- virtual void extractFeatures(const 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
- void segment(int m); // segment into m segment-types
- int getNSegmentTypes() { return nclusters; }
-
-protected:
- void makeSegmentation(int* q, int len);
-
- void extractFeaturesConstQ(const double *, int);
- void extractFeaturesMFCC(const double *, int);
-
- Window<double> *window;
- FFTReal *fft;
- ConstantQ* constq;
- MFCC* mfcc;
- model_t* model; // the HMM
- int* q; // the decoded HMM state sequence
- vector<vector<double> > histograms;
-
- feature_types featureType;
- double hopSize; // in seconds
- double windowSize; // in seconds
-
- // constant-Q parameters
- int fmin;
- int fmax;
- int nbins;
- int ncoeff;
-
- // PCA parameters
- int ncomponents;
-
- // HMM parameters
- int nHMMStates;
-
- // clustering parameters
- int nclusters;
- int histogramLength;
- int neighbourhoodLimit;
-
- Decimator *decimator;
-};
diff --git a/libs/qm-dsp/dsp/segmentation/Segmenter.cpp b/libs/qm-dsp/dsp/segmentation/Segmenter.cpp
deleted file mode 100644
index 538eaacc78..0000000000
--- a/libs/qm-dsp/dsp/segmentation/Segmenter.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Segmenter.cpp
- *
- * Created by Mark Levy on 04/04/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-#include <iomanip>
-
-#include "Segmenter.h"
-
-ostream& operator<<(ostream& os, const Segmentation& s)
-{
- os << "structure_name : begin_time end_time\n";
-
- for (int i = 0; i < s.segments.size(); i++)
- {
- Segment seg = s.segments[i];
- os << std::fixed << seg.type << ':' << '\t' << std::setprecision(6) << seg.start / static_cast<double>(s.samplerate)
- << '\t' << std::setprecision(6) << seg.end / static_cast<double>(s.samplerate) << "\n";
- }
-
- return os;
-}
diff --git a/libs/qm-dsp/dsp/segmentation/Segmenter.h b/libs/qm-dsp/dsp/segmentation/Segmenter.h
deleted file mode 100644
index 1ac0679b72..0000000000
--- a/libs/qm-dsp/dsp/segmentation/Segmenter.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef _SEGMENTER_H
-#define _SEGMENTER_H
-
-/*
- * Segmenter.h
- * soundbite
- *
- * Created by Mark Levy on 23/03/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-#include <vector>
-#include <iostream>
-
-using std::vector;
-using std::ostream;
-
-class Segment
-{
-public:
- int start; // in samples
- int end;
- int type;
-};
-
-class Segmentation
-{
-public:
- int nsegtypes; // number of segment types, so possible types are {0,1,...,nsegtypes-1}
- int samplerate;
- vector<Segment> segments;
-};
-
-ostream& operator<<(ostream& os, const Segmentation& s);
-
-class Segmenter
-{
-public:
- Segmenter() {}
- virtual ~Segmenter() {}
- virtual void initialise(int samplerate) = 0; // must be called before any other methods
- virtual int getWindowsize() = 0; // required window size for calls to extractFeatures()
- virtual int getHopsize() = 0; // required hop size for calls to extractFeatures()
- virtual void extractFeatures(const double* samples, int nsamples) = 0;
- virtual void segment() = 0; // call once all the features have been extracted
- virtual void segment(int m) = 0; // specify desired number of segment-types
- virtual void clear() { features.clear(); }
- const Segmentation& getSegmentation() const { return segmentation; }
-protected:
- vector<vector<double> > features;
- Segmentation segmentation;
- int samplerate;
-};
-
-#endif
diff --git a/libs/qm-dsp/dsp/segmentation/cluster_melt.c b/libs/qm-dsp/dsp/segmentation/cluster_melt.c
deleted file mode 100644
index 1441b394c2..0000000000
--- a/libs/qm-dsp/dsp/segmentation/cluster_melt.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * cluster.c
- * cluster_melt
- *
- * Created by Mark Levy on 21/02/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-#include <stdlib.h>
-
-#include "cluster_melt.h"
-
-#define DEFAULT_LAMBDA 0.02;
-#define DEFAULT_LIMIT 20;
-
-double kldist(double* a, double* b, int n) {
- /* NB assume that all a[i], b[i] are non-negative
- because a, b represent probability distributions */
- double q, d;
- int i;
-
- d = 0;
- for (i = 0; i < n; i++)
- {
- q = (a[i] + b[i]) / 2.0;
- if (q > 0)
- {
- if (a[i] > 0)
- d += a[i] * log(a[i] / q);
- if (b[i] > 0)
- d += b[i] * log(b[i] / q);
- }
- }
- return d;
-}
-
-void cluster_melt(double *h, int m, int n, double *Bsched, int t, int k, int l, int *c) {
- double lambda, sum, beta, logsumexp, maxlp;
- int i, j, a, b, b0, b1, limit, B, it, maxiter, maxiter0, maxiter1;
- double** cl; /* reference histograms for each cluster */
- int** nc; /* neighbour counts for each histogram */
- double** lp; /* soft assignment probs for each histogram */
- int* oldc; /* previous hard assignments (to check convergence) */
-
- /* NB h is passed as a 1d row major array */
-
- /* parameter values */
- lambda = DEFAULT_LAMBDA;
- if (l > 0)
- limit = l;
- else
- limit = DEFAULT_LIMIT; /* use default if no valid neighbourhood limit supplied */
- B = 2 * limit + 1;
- maxiter0 = 20; /* number of iterations at initial temperature */
- maxiter1 = 5; /* number of iterations at subsequent temperatures */
-
- /* allocate memory */
- cl = (double**) malloc(k*sizeof(double*));
- for (i= 0; i < k; i++)
- cl[i] = (double*) malloc(m*sizeof(double));
-
- nc = (int**) malloc(n*sizeof(int*));
- for (i= 0; i < n; i++)
- nc[i] = (int*) malloc(k*sizeof(int));
-
- lp = (double**) malloc(n*sizeof(double*));
- for (i= 0; i < n; i++)
- lp[i] = (double*) malloc(k*sizeof(double));
-
- oldc = (int*) malloc(n * sizeof(int));
-
- /* initialise */
- for (i = 0; i < k; i++)
- {
- sum = 0;
- for (j = 0; j < m; j++)
- {
- cl[i][j] = rand(); /* random initial reference histograms */
- sum += cl[i][j] * cl[i][j];
- }
- sum = sqrt(sum);
- for (j = 0; j < m; j++)
- {
- cl[i][j] /= sum; /* normalise */
- }
- }
- //print_array(cl, k, m);
-
- for (i = 0; i < n; i++)
- c[i] = 1; /* initially assign all histograms to cluster 1 */
-
- for (a = 0; a < t; a++)
- {
- beta = Bsched[a];
-
- if (a == 0)
- maxiter = maxiter0;
- else
- maxiter = maxiter1;
-
- for (it = 0; it < maxiter; it++)
- {
- //if (it == maxiter - 1)
- // mexPrintf("hasn't converged after %d iterations\n", maxiter);
-
- for (i = 0; i < n; i++)
- {
- /* save current hard assignments */
- oldc[i] = c[i];
-
- /* calculate soft assignment logprobs for each cluster */
- sum = 0;
- for (j = 0; j < k; j++)
- {
- lp[i][ j] = -beta * kldist(cl[j], &h[i*m], m);
-
- /* update matching neighbour counts for this histogram, based on current hard assignments */
- /* old version:
- nc[i][j] = 0;
- if (i >= limit && i <= n - 1 - limit)
- {
- for (b = i - limit; b <= i + limit; b++)
- {
- if (c[b] == j+1)
- nc[i][j]++;
- }
- nc[i][j] = B - nc[i][j];
- }
- */
- b0 = i - limit;
- if (b0 < 0)
- b0 = 0;
- b1 = i + limit;
- if (b1 >= n)
- b1 = n - 1;
- nc[i][j] = b1 - b0 + 1; /* = B except at edges */
- for (b = b0; b <= b1; b++)
- if (c[b] == j+1)
- nc[i][j]--;
-
- sum += exp(lp[i][j]);
- }
-
- /* normalise responsibilities and add duration logprior */
- logsumexp = log(sum);
- for (j = 0; j < k; j++)
- lp[i][j] -= logsumexp + lambda * nc[i][j];
- }
- //print_array(lp, n, k);
- /*
- for (i = 0; i < n; i++)
- {
- for (j = 0; j < k; j++)
- mexPrintf("%d ", nc[i][j]);
- mexPrintf("\n");
- }
- */
-
-
- /* update the assignments now that we know the duration priors
- based on the current assignments */
- for (i = 0; i < n; i++)
- {
- maxlp = lp[i][0];
- c[i] = 1;
- for (j = 1; j < k; j++)
- if (lp[i][j] > maxlp)
- {
- maxlp = lp[i][j];
- c[i] = j+1;
- }
- }
-
- /* break if assignments haven't changed */
- i = 0;
- while (i < n && oldc[i] == c[i])
- i++;
- if (i == n)
- break;
-
- /* update reference histograms now we know new responsibilities */
- for (j = 0; j < k; j++)
- {
- for (b = 0; b < m; b++)
- {
- cl[j][b] = 0;
- for (i = 0; i < n; i++)
- {
- cl[j][b] += exp(lp[i][j]) * h[i*m+b];
- }
- }
-
- sum = 0;
- for (i = 0; i < n; i++)
- sum += exp(lp[i][j]);
- for (b = 0; b < m; b++)
- cl[j][b] /= sum; /* normalise */
- }
-
- //print_array(cl, k, m);
- //mexPrintf("\n\n");
- }
- }
-
- /* free memory */
- for (i = 0; i < k; i++)
- free(cl[i]);
- free(cl);
- for (i = 0; i < n; i++)
- free(nc[i]);
- free(nc);
- for (i = 0; i < n; i++)
- free(lp[i]);
- free(lp);
- free(oldc);
-}
-
-
diff --git a/libs/qm-dsp/dsp/segmentation/cluster_melt.h b/libs/qm-dsp/dsp/segmentation/cluster_melt.h
deleted file mode 100644
index 9bb9106a28..0000000000
--- a/libs/qm-dsp/dsp/segmentation/cluster_melt.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _CLUSTER_MELT_H
-#define _CLUSTER_MELT_H
-/*
- * cluster_melt.h
- * cluster_melt
- *
- * Created by Mark Levy on 21/02/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-#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 */
- double *Bsched, /* inverse temperature schedule */
- int t, /* length of schedule */
- int k, /* number of clusters */
- int l, /* neighbourhood limit (supply zero to use default value) */
- int *c /* sequence of cluster assignments */
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/libs/qm-dsp/dsp/segmentation/cluster_segmenter.c b/libs/qm-dsp/dsp/segmentation/cluster_segmenter.c
deleted file mode 100644
index 2a6b196921..0000000000
--- a/libs/qm-dsp/dsp/segmentation/cluster_segmenter.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * cluster_segmenter.c
- * soundbite
- *
- * Created by Mark Levy on 06/04/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-#include "cluster_segmenter.h"
-
-extern int readmatarray_size(const char *filepath, int n_array, int* t, int* d);
-extern int readmatarray(const char *filepath, int n_array, int t, int d, double** arr);
-
-/* converts constant-Q features to normalised chroma */
-void cq2chroma(double** cq, int nframes, int ncoeff, int bins, double** chroma)
-{
- int noct = ncoeff / bins; /* number of complete octaves in constant-Q */
- int t, b, oct, ix;
- //double maxchroma; /* max chroma value at each time, for normalisation */
- //double sum; /* for normalisation */
-
- for (t = 0; t < nframes; t++)
- {
- for (b = 0; b < bins; b++)
- chroma[t][b] = 0;
- for (oct = 0; oct < noct; oct++)
- {
- ix = oct * bins;
- for (b = 0; b < bins; b++)
- chroma[t][b] += fabs(cq[t][ix+b]);
- }
- /* normalise to unit sum
- sum = 0;
- for (b = 0; b < bins; b++)
- 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++)
- if (chroma[t][b] > maxchroma)
- maxchroma = chroma[t][b];
- if (maxchroma > 0)
- for (b = 0; b < bins; b++)
- chroma[t][b] /= maxchroma;
- */
- }
-}
-
-/* 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)
-{
- int i, j;
- double ss;
- double env;
- double maxenv = 0;
-
- /* convert const-Q features to dB scale */
- for (i = 0; i < nframes; i++)
- for (j = 0; j < ncoeff; j++)
- features[i][j] = 10.0 * log10(features[i][j]+DBL_EPSILON);
-
- /* normalise each feature vector and add the norm as an extra feature dimension */
- for (i = 0; i < nframes; i++)
- {
- ss = 0;
- for (j = 0; j < ncoeff; j++)
- ss += features[i][j] * features[i][j];
- env = sqrt(ss);
- for (j = 0; j < ncoeff; j++)
- features[i][j] /= env;
- features[i][ncoeff] = env;
- if (env > maxenv)
- maxenv = env;
- }
- /* normalise the envelopes */
- for (i = 0; i < nframes; i++)
- features[i][ncoeff] /= maxenv;
-}
-
-/* return histograms h[nx*m] of data x[nx] into m bins using a sliding window of length h_len (MUST BE ODD) */
-/* NB h is a vector in row major order, as required by cluster_melt() */
-/* for historical reasons we normalise the histograms by their norm (not to sum to one) */
-void create_histograms(int* x, int nx, int m, int hlen, double* h)
-{
- int i, j, t;
- double norm;
-
- for (i = 0; i < nx*m; i++)
- h[i] = 0;
-
- for (i = hlen/2; i < nx-hlen/2; i++)
- {
- for (j = 0; j < m; j++)
- h[i*m+j] = 0;
- for (t = i-hlen/2; t <= i+hlen/2; t++)
- ++h[i*m+x[t]];
- norm = 0;
- for (j = 0; j < m; j++)
- norm += h[i*m+j] * h[i*m+j];
- for (j = 0; j < m; j++)
- h[i*m+j] /= norm;
- }
-
- /* duplicate histograms at beginning and end to create one histogram for each data value supplied */
- for (i = 0; i < hlen/2; i++)
- for (j = 0; j < m; j++)
- h[i*m+j] = h[hlen/2*m+j];
- for (i = nx-hlen/2; i < nx; i++)
- for (j = 0; j < m; j++)
- h[i*m+j] = h[(nx-hlen/2-1)*m+j];
-}
-
-/* segment using HMM and then histogram clustering */
-void cluster_segment(int* q, double** features, int frames_read, int feature_length, int nHMM_states,
- int histogram_length, int nclusters, int neighbour_limit)
-{
- int i, j;
-
- /*****************************/
- if (0) {
- /* try just using the predominant bin number as a 'decoded state' */
- nHMM_states = feature_length + 1; /* allow a 'zero' state */
- double chroma_thresh = 0.05;
- double maxval;
- int maxbin;
- for (i = 0; i < frames_read; i++)
- {
- maxval = 0;
- for (j = 0; j < feature_length; j++)
- {
- if (features[i][j] > maxval)
- {
- maxval = features[i][j];
- maxbin = j;
- }
- }
- if (maxval > chroma_thresh)
- q[i] = maxbin;
- else
- q[i] = feature_length;
- }
-
- }
- if (1) {
- /*****************************/
-
-
- /* scale all the features to 'balance covariances' during HMM training */
- double scale = 10;
- for (i = 0; i < frames_read; i++)
- for (j = 0; j < feature_length; j++)
- features[i][j] *= scale;
-
- /* train an HMM on the features */
-
- /* create a model */
- model_t* model = hmm_init(features, frames_read, feature_length, nHMM_states);
-
- /* train the model */
- hmm_train(features, frames_read, model);
-/*
- printf("\n\nafter training:\n");
- hmm_print(model);
-*/
- /* decode the hidden state sequence */
- viterbi_decode(features, frames_read, model, q);
- hmm_close(model);
-
- /*****************************/
- }
- /*****************************/
-
-
-/*
- fprintf(stderr, "HMM state sequence:\n");
- for (i = 0; i < frames_read; i++)
- fprintf(stderr, "%d ", q[i]);
- fprintf(stderr, "\n\n");
-*/
-
- /* create histograms of states */
- double* h = (double*) malloc(frames_read*nHMM_states*sizeof(double)); /* vector in row major order */
- create_histograms(q, frames_read, nHMM_states, histogram_length, h);
-
- /* cluster the histograms */
- int nbsched = 20; /* length of inverse temperature schedule */
- double* bsched = (double*) malloc(nbsched*sizeof(double)); /* inverse temperature schedule */
- double b0 = 100;
- double alpha = 0.7;
- bsched[0] = b0;
- for (i = 1; i < nbsched; i++)
- bsched[i] = alpha * bsched[i-1];
- cluster_melt(h, nHMM_states, frames_read, bsched, nbsched, nclusters, neighbour_limit, q);
-
- /* now q holds a sequence of cluster assignments */
-
- free(h);
- free(bsched);
-}
-
-/* segment constant-Q or chroma features */
-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)
-{
- int feature_length;
- double** chroma;
- int i;
-
- if (feature_type == FEATURE_TYPE_CONSTQ)
- {
-/* fprintf(stderr, "Converting to dB and normalising...\n");
- */
- mpeg7_constq(features, frames_read, ncoeff);
-/*
- fprintf(stderr, "Running PCA...\n");
-*/
- /* do PCA on the features (but not the envelope) */
- int ncomponents = 20;
- pca_project(features, frames_read, ncoeff, ncomponents);
-
- /* copy the envelope so that it immediatly follows the chosen components */
- for (i = 0; i < frames_read; i++)
- features[i][ncomponents] = features[i][ncoeff];
-
- feature_length = ncomponents + 1;
-
- /**************************************
- //TEST
- // feature file name
- char* dir = "/Users/mark/documents/semma/audio/";
- char* file_name = (char*) malloc((strlen(dir) + strlen(trackname) + strlen("_features_c20r8h0.2f0.6.mat") + 1)*sizeof(char));
- strcpy(file_name, dir);
- strcat(file_name, trackname);
- strcat(file_name, "_features_c20r8h0.2f0.6.mat");
-
- // get the features from Matlab from mat-file
- int frames_in_file;
- readmatarray_size(file_name, 2, &frames_in_file, &feature_length);
- readmatarray(file_name, 2, frames_in_file, feature_length, features);
- // copy final frame to ensure that we get as many as we expected
- int missing_frames = frames_read - frames_in_file;
- while (missing_frames > 0)
- {
- for (i = 0; i < feature_length; i++)
- features[frames_read-missing_frames][i] = features[frames_read-missing_frames-1][i];
- --missing_frames;
- }
-
- free(file_name);
- ******************************************/
-
- cluster_segment(q, features, frames_read, feature_length, nHMM_states, histogram_length, nclusters, neighbour_limit);
- }
-
- if (feature_type == FEATURE_TYPE_CHROMA)
- {
-/*
- fprintf(stderr, "Converting to chroma features...\n");
-*/
- /* convert constant-Q to normalised chroma features */
- chroma = (double**) malloc(frames_read*sizeof(double*));
- for (i = 0; i < frames_read; i++)
- chroma[i] = (double*) malloc(bins*sizeof(double));
- cq2chroma(features, frames_read, ncoeff, bins, chroma);
- feature_length = bins;
-
- cluster_segment(q, chroma, frames_read, feature_length, nHMM_states, histogram_length, nclusters, neighbour_limit);
-
- for (i = 0; i < frames_read; i++)
- free(chroma[i]);
- free(chroma);
- }
-}
-
-
-
diff --git a/libs/qm-dsp/dsp/segmentation/cluster_segmenter.h b/libs/qm-dsp/dsp/segmentation/cluster_segmenter.h
deleted file mode 100644
index e7106d4f81..0000000000
--- a/libs/qm-dsp/dsp/segmentation/cluster_segmenter.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _CLUSTER_SEGMENTER_H
-#define _CLUSTER_SEGMENTER_H
-
-/*
- * cluster_segmenter.h
- * soundbite
- *
- * Created by Mark Levy on 06/04/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
-
-#include "segment.h"
-#include "cluster_melt.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);
-
-/* converts constant-Q features to normalised chroma */
-void cq2chroma(double** cq, int nframes, int ncoeff, int bins, double** chroma);
-
-void create_histograms(int* x, int nx, int m, int hlen, double* h);
-
-void cluster_segment(int* q, double** features, int frames_read, int feature_length, int nHMM_states,
- int histogram_length, int nclusters, int neighbour_limit);
-
-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
diff --git a/libs/qm-dsp/dsp/segmentation/segment.h b/libs/qm-dsp/dsp/segmentation/segment.h
deleted file mode 100644
index 7a4eb8b2b4..0000000000
--- a/libs/qm-dsp/dsp/segmentation/segment.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _SEGMENT_H
-#define _SEGMENT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * segment.h
- *
- * Created by Mark Levy on 06/04/2006.
- * Copyright 2006 Centre for Digital Music, Queen Mary, University 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.
- *
- */
-
-typedef struct segment_t
-{
- long start; /* in samples */
- long end;
- int type;
-} segment_t;
-
-typedef struct segmentation_t
-{
- int nsegs; /* number of segments */
- int nsegtypes; /* number of segment types, so possible types are {0,1,...,nsegtypes-1} */
- int samplerate;
- segment_t* segments;
-} segmentation_t;
-
-typedef enum
-{
- FEATURE_TYPE_UNKNOWN = 0,
- FEATURE_TYPE_CONSTQ = 1,
- FEATURE_TYPE_CHROMA = 2,
- FEATURE_TYPE_MFCC = 3
-} feature_types;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-