Mercurial > hg > qm-dsp
comparison dsp/segmentation/ClusterMeltSegmenter.cpp @ 505:930b5b0f707d
Merge branch 'codestyle-and-tidy'
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Wed, 05 Jun 2019 12:55:15 +0100 |
parents | 1bea13b8f951 |
children |
comparison
equal
deleted
inserted
replaced
471:e3335cb213da | 505:930b5b0f707d |
---|---|
22 | 22 |
23 #include "dsp/transforms/FFT.h" | 23 #include "dsp/transforms/FFT.h" |
24 #include "dsp/chromagram/ConstantQ.h" | 24 #include "dsp/chromagram/ConstantQ.h" |
25 #include "dsp/rateconversion/Decimator.h" | 25 #include "dsp/rateconversion/Decimator.h" |
26 #include "dsp/mfcc/MFCC.h" | 26 #include "dsp/mfcc/MFCC.h" |
27 | |
28 using std::vector; | |
27 | 29 |
28 ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) : | 30 ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) : |
29 window(NULL), | 31 window(NULL), |
30 fft(NULL), | 32 fft(NULL), |
31 constq(NULL), | 33 constq(NULL), |
34 hopSize(params.hopSize), | 36 hopSize(params.hopSize), |
35 windowSize(params.windowSize), | 37 windowSize(params.windowSize), |
36 fmin(params.fmin), | 38 fmin(params.fmin), |
37 fmax(params.fmax), | 39 fmax(params.fmax), |
38 nbins(params.nbins), | 40 nbins(params.nbins), |
39 ncomponents(params.ncomponents), // NB currently not passed - no. of PCA components is set in cluser_segmenter.c | 41 ncomponents(params.ncomponents), // NB currently not passed - no. of PCA components is set in cluser_segmenter.c |
40 nHMMStates(params.nHMMStates), | 42 nHMMStates(params.nHMMStates), |
41 nclusters(params.nclusters), | 43 nclusters(params.nclusters), |
42 histogramLength(params.histogramLength), | 44 histogramLength(params.histogramLength), |
43 neighbourhoodLimit(params.neighbourhoodLimit), | 45 neighbourhoodLimit(params.neighbourhoodLimit), |
44 decimator(NULL) | 46 decimator(NULL) |
78 constq = new ConstantQ(config); | 80 constq = new ConstantQ(config); |
79 constq->sparsekernel(); | 81 constq->sparsekernel(); |
80 | 82 |
81 ncoeff = constq->getK(); | 83 ncoeff = constq->getK(); |
82 | 84 |
83 fft = new FFTReal(constq->getfftlength()); | 85 fft = new FFTReal(constq->getFFTLength()); |
84 | 86 |
85 } else if (featureType == FEATURE_TYPE_MFCC) { | 87 } else if (featureType == FEATURE_TYPE_MFCC) { |
86 | 88 |
87 // run internal processing at 22050 or thereabouts | 89 // run internal processing at 22050 or thereabouts |
88 int internalRate = 22050; | 90 int internalRate = 22050; |
152 if (nsamples < getWindowsize()) { | 154 if (nsamples < getWindowsize()) { |
153 std::cerr << "ERROR: ClusterMeltSegmenter::extractFeatures: nsamples < windowsize (" << nsamples << " < " << getWindowsize() << ")" << std::endl; | 155 std::cerr << "ERROR: ClusterMeltSegmenter::extractFeatures: nsamples < windowsize (" << nsamples << " < " << getWindowsize() << ")" << std::endl; |
154 return; | 156 return; |
155 } | 157 } |
156 | 158 |
157 int fftsize = constq->getfftlength(); | 159 int fftsize = constq->getFFTLength(); |
158 | 160 |
159 if (!window || window->getSize() != fftsize) { | 161 if (!window || window->getSize() != fftsize) { |
160 delete window; | 162 delete window; |
161 window = new Window<double>(HammingWindow, fftsize); | 163 window = new Window<double>(HammingWindow, fftsize); |
162 } | 164 } |
210 window->cut(frame); | 212 window->cut(frame); |
211 | 213 |
212 fft->forward(frame, real, imag); | 214 fft->forward(frame, real, imag); |
213 | 215 |
214 constq->process(real, imag, cqre, cqim); | 216 constq->process(real, imag, cqre, cqim); |
215 | 217 |
216 for (int i = 0; i < ncoeff; ++i) { | 218 for (int i = 0; i < ncoeff; ++i) { |
217 cq[i] += sqrt(cqre[i] * cqre[i] + cqim[i] * cqim[i]); | 219 cq[i] += sqrt(cqre[i] * cqre[i] + cqim[i] * cqim[i]); |
218 } | 220 } |
219 ++frames; | 221 ++frames; |
220 | 222 |
285 frame[i] = 0.0; | 287 frame[i] = 0.0; |
286 } | 288 } |
287 } | 289 } |
288 | 290 |
289 mfcc->process(frame, ccout); | 291 mfcc->process(frame, ccout); |
290 | 292 |
291 for (int i = 0; i < ncoeff; ++i) { | 293 for (int i = 0; i < ncoeff; ++i) { |
292 cc[i] += ccout[i]; | 294 cc[i] += ccout[i]; |
293 } | 295 } |
294 ++frames; | 296 ++frames; |
295 | 297 |
335 /* | 337 /* |
336 std::cerr << "ClusterMeltSegmenter::segment: have " << features.size() | 338 std::cerr << "ClusterMeltSegmenter::segment: have " << features.size() |
337 << " features with " << features[0].size() << " coefficients (ncoeff = " << ncoeff << ", ncomponents = " << ncomponents << ")" << std::endl; | 339 << " features with " << features[0].size() << " coefficients (ncoeff = " << ncoeff << ", ncomponents = " << ncomponents << ")" << std::endl; |
338 */ | 340 */ |
339 // copy the features to a native array and use the existing C segmenter... | 341 // copy the features to a native array and use the existing C segmenter... |
340 double** arrFeatures = new double*[features.size()]; | 342 double** arrFeatures = new double*[features.size()]; |
341 for (int i = 0; i < sz; i++) | 343 for (int i = 0; i < sz; i++) { |
342 { | |
343 if (featureType == FEATURE_TYPE_UNKNOWN) { | 344 if (featureType == FEATURE_TYPE_UNKNOWN) { |
344 arrFeatures[i] = new double[features[0].size()]; | 345 arrFeatures[i] = new double[features[0].size()]; |
345 for (int j = 0; j < int(features[0].size()); j++) { | 346 for (int j = 0; j < int(features[0].size()); j++) { |
346 arrFeatures[i][j] = features[i][j]; | 347 arrFeatures[i][j] = features[i][j]; |
347 } | 348 } |
348 } else { | 349 } else { |
349 arrFeatures[i] = new double[ncoeff+1]; // allow space for the normalised envelope | 350 arrFeatures[i] = new double[ncoeff+1]; // allow space for the normalised envelope |
350 for (int j = 0; j < ncoeff; j++) { | 351 for (int j = 0; j < ncoeff; j++) { |
351 arrFeatures[i][j] = features[i][j]; | 352 arrFeatures[i][j] = features[i][j]; |
352 } | 353 } |
353 } | 354 } |
354 } | 355 } |
355 | 356 |
356 q = new int[features.size()]; | 357 q = new int[features.size()]; |
357 | 358 |
358 if (featureType == FEATURE_TYPE_UNKNOWN || | 359 if (featureType == FEATURE_TYPE_UNKNOWN || |
359 featureType == FEATURE_TYPE_MFCC) | 360 featureType == FEATURE_TYPE_MFCC) { |
360 cluster_segment(q, arrFeatures, features.size(), features[0].size(), nHMMStates, histogramLength, | 361 cluster_segment(q, arrFeatures, features.size(), features[0].size(), nHMMStates, histogramLength, |
361 nclusters, neighbourhoodLimit); | 362 nclusters, neighbourhoodLimit); |
362 else | 363 } else { |
363 constq_segment(q, arrFeatures, features.size(), nbins, ncoeff, featureType, | 364 constq_segment(q, arrFeatures, features.size(), nbins, ncoeff, featureType, |
364 nHMMStates, histogramLength, nclusters, neighbourhoodLimit); | 365 nHMMStates, histogramLength, nclusters, neighbourhoodLimit); |
365 | 366 } |
367 | |
366 // convert the cluster assignment sequence to a segmentation | 368 // convert the cluster assignment sequence to a segmentation |
367 makeSegmentation(q, features.size()); | 369 makeSegmentation(q, features.size()); |
368 | 370 |
369 // de-allocate arrays | 371 // de-allocate arrays |
370 delete [] q; | 372 delete [] q; |
371 for (int i = 0; i < int(features.size()); i++) delete [] arrFeatures[i]; | 373 for (int i = 0; i < int(features.size()); i++) delete [] arrFeatures[i]; |
372 delete [] arrFeatures; | 374 delete [] arrFeatures; |
373 | 375 |
374 // clear the features | 376 // clear the features |
375 clear(); | 377 clear(); |
376 } | 378 } |
377 | 379 |
378 void ClusterMeltSegmenter::makeSegmentation(int* q, int len) | 380 void ClusterMeltSegmenter::makeSegmentation(int* q, int len) |
379 { | 381 { |
380 segmentation.segments.clear(); | 382 segmentation.segments.clear(); |
381 segmentation.nsegtypes = nclusters; | 383 segmentation.nsegtypes = nclusters; |
382 segmentation.samplerate = samplerate; | 384 segmentation.samplerate = samplerate; |
383 | 385 |
384 Segment segment; | 386 Segment segment; |
385 segment.start = 0; | 387 segment.start = 0; |
386 segment.type = q[0]; | 388 segment.type = q[0]; |
387 | 389 |
388 for (int i = 1; i < len; i++) | 390 for (int i = 1; i < len; i++) { |
389 { | 391 if (q[i] != q[i-1]) { |
390 if (q[i] != q[i-1]) | |
391 { | |
392 segment.end = i * getHopsize(); | 392 segment.end = i * getHopsize(); |
393 segmentation.segments.push_back(segment); | 393 segmentation.segments.push_back(segment); |
394 segment.type = q[i]; | 394 segment.type = q[i]; |
395 segment.start = segment.end; | 395 segment.start = segment.end; |
396 } | 396 } |