comparison dsp/segmentation/ClusterMeltSegmenter.cpp @ 20:8bdbda7fb893

* First cut at properly integrating the segmenter and making it work right
author cannam
date Wed, 09 Jan 2008 16:50:04 +0000
parents 8e90a56b4b5f
children 2b74bd60c61f
comparison
equal deleted inserted replaced
19:d3a856b44c43 20:8bdbda7fb893
9 9
10 #include <cfloat> 10 #include <cfloat>
11 #include <cmath> 11 #include <cmath>
12 12
13 #include "ClusterMeltSegmenter.h" 13 #include "ClusterMeltSegmenter.h"
14 #include "lib_constQ.h"
15 #include "cluster_segmenter.h" 14 #include "cluster_segmenter.h"
16 #include "segment.h" 15 #include "segment.h"
16
17 #include "dsp/transforms/FFT.h"
17 18
18 ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) : window(NULL), 19 ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) : window(NULL),
19 constq(NULL), 20 constq(NULL),
20 featureType(params.featureType), 21 featureType(params.featureType),
22 hopSize(params.hopSize),
21 windowSize(params.windowSize), 23 windowSize(params.windowSize),
22 hopSize(params.hopSize),
23 fmin(params.fmin), 24 fmin(params.fmin),
24 fmax(params.fmax), 25 fmax(params.fmax),
25 nbins(params.nbins), 26 nbins(params.nbins),
26 ncomponents(params.ncomponents), // NB currently not passed - no. of PCA components is set in cluser_segmenter.c 27 ncomponents(params.ncomponents), // NB currently not passed - no. of PCA components is set in cluser_segmenter.c
27 nHMMStates(params.nHMMStates), 28 nHMMStates(params.nHMMStates),
34 void ClusterMeltSegmenter::initialise(int fs) 35 void ClusterMeltSegmenter::initialise(int fs)
35 { 36 {
36 samplerate = fs; 37 samplerate = fs;
37 if (featureType != FEATURE_TYPE_UNKNOWN) 38 if (featureType != FEATURE_TYPE_UNKNOWN)
38 { 39 {
39 ncoeff = static_cast<int>(ceil(nbins * (log(fmax / static_cast<double>(fmin))) / log(2.0))); 40 //!!! ncoeff = static_cast<int>(ceil(nbins * (log(fmax / static_cast<double>(fmin))) / log(2.0)));
40 constq = init_constQ(fmin, fmax, nbins, samplerate, ncoeff); 41 CQConfig config;
42 config.FS = samplerate;
43 config.min = fmin;
44 config.max = fmax;
45 config.BPO = nbins;
46 config.CQThresh = 0.0054;
47 constq = new ConstantQ(config);
48 //!!! constq = init_constQ(fmin, fmax, nbins, samplerate, ncoeff);
49 ncoeff = constq->getK();
41 } 50 }
42 } 51 }
43 52
44 ClusterMeltSegmenter::~ClusterMeltSegmenter() 53 ClusterMeltSegmenter::~ClusterMeltSegmenter()
45 { 54 {
46 delete [] window; 55 delete window;
47 if (constq) 56 delete constq;
48 close_constQ(constq); 57 //!!! if (constq)
58 // close_constQ(constq);
59 }
60
61 int
62 ClusterMeltSegmenter::getWindowsize()
63 {
64 if (featureType != FEATURE_TYPE_UNKNOWN) {
65 std::cerr << "rate = " << samplerate << ", fft length = " << constq->getfftlength() << ", fmin = " << fmin << ", fmax = " << fmax << ", nbins = " << nbins << ", K = " << constq->getK() << ", Q = " << constq->getQ() << std::endl;
66 return constq->getfftlength();
67 } else {
68 return static_cast<int>(windowSize * samplerate);
69 }
70 }
71
72 int
73 ClusterMeltSegmenter::getHopsize()
74 {
75 return static_cast<int>(hopSize * samplerate);
49 } 76 }
50 77
51 void ClusterMeltSegmenter::extractFeatures(double* samples, int nsamples) 78 void ClusterMeltSegmenter::extractFeatures(double* samples, int nsamples)
52 { 79 {
53 // create a new window if needed 80 // create a new window if needed
81 /*!!!
54 if (!window || nsamples != windowLength) 82 if (!window || nsamples != windowLength)
55 { 83 {
56 if (window) 84 if (window)
57 delete [] window; 85 delete [] window;
58 window = hamming_p(nsamples); 86 // Window<double>(HammingWindow, nsamples).cut
87 //!!! window = hamming_p(nsamples);
59 windowLength = nsamples; 88 windowLength = nsamples;
60 } 89 }
61 90 */
91 if (!window || window->getSize() != nsamples) {
92 delete window;
93 window = new Window<double>(HammingWindow, nsamples);
94 }
95
62 // copy the samples before windowing in case we need them for something else 96 // copy the samples before windowing in case we need them for something else
63 double* frame = new double[nsamples]; 97 double* frame = new double[nsamples];
64 for (int i = 0; i < nsamples; i++) 98 // for (int i = 0; i < nsamples; i++)
65 frame[i] = samples[i] * window[i]; 99 // frame[i] = samples[i] * window[i];
66 100 window->cut(frame);
101
102 std::cerr << "nsamples = " << nsamples << std::endl;
103
104 double *real = new double[nsamples];
105 double *imag = new double[nsamples];
106
107 FFT::process(nsamples, false, frame, 0, real, imag);
108
109 double *cqre = new double[ncoeff];
110 double *cqim = new double[ncoeff];
111
112 constq->process(real, imag, cqre, cqim);
113
67 // extract const-Q 114 // extract const-Q
68 do_constQ(constq, frame, nsamples); 115 //!!! do_constQ(constq, frame, nsamples);
69 int ncq = constq->ncoeff; 116 // int ncq = constq->ncoeff;
70 117
71 delete [] frame; 118 delete [] frame;
72 119 delete [] real;
73 if (ncq == ncoeff) // else feature extraction failed 120 delete [] imag;
74 { 121
75 vector<double> cq(ncq); 122 //!!! if (ncq == ncoeff) // else feature extraction failed
76 for (int i = 0; i < ncq; i++) 123 // {
77 cq[i] = constq->absconstQtransform[i]; 124 // vector<double> cq(ncq);
125 // for (int i = 0; i < ncq; i++)
126 // cq[i] = constq->absconstQtransform[i];
127 vector<double> cq(ncoeff);
128 for (int i = 0; i < ncoeff; ++i) {
129 cq[i] = sqrt(cqre[i] * cqre[i] + cqim[i] * cqim[i]);
130 }
78 features.push_back(cq); 131 features.push_back(cq);
79 } 132 // }
133
134 delete[] cqre;
135 delete[] cqim;
80 } 136 }
81 137
82 void ClusterMeltSegmenter::segment(int m) 138 void ClusterMeltSegmenter::segment(int m)
83 { 139 {
84 nclusters = m; 140 nclusters = m;
93 149
94 void ClusterMeltSegmenter::segment() 150 void ClusterMeltSegmenter::segment()
95 { 151 {
96 if (constq) 152 if (constq)
97 { 153 {
98 close_constQ(constq); // finished extracting features 154 //!!! close_constQ(constq); // finished extracting features
155 delete constq;
99 constq = NULL; 156 constq = NULL;
100 } 157 }
101 158
102 // for now copy the features to a native array and use the existing C segmenter... 159 // for now copy the features to a native array and use the existing C segmenter...
103 double** arrFeatures = new double*[features.size()]; 160 double** arrFeatures = new double*[features.size()];