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 }