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 } |
