Mercurial > hg > qm-dsp
comparison dsp/segmentation/ClusterMeltSegmenter.cpp @ 18:8e90a56b4b5f
* merge in segmentation code from soundbite plugin/library repository
author | cannam |
---|---|
date | Wed, 09 Jan 2008 10:46:25 +0000 |
parents | |
children | 8bdbda7fb893 |
comparison
equal
deleted
inserted
replaced
17:a120ac7b26b2 | 18:8e90a56b4b5f |
---|---|
1 /* | |
2 * ClusterMeltSegmenter.cpp | |
3 * soundbite | |
4 * | |
5 * Created by Mark Levy on 23/03/2006. | |
6 * Copyright 2006 Centre for Digital Music, Queen Mary, University of London. All rights reserved. | |
7 * | |
8 */ | |
9 | |
10 #include <cfloat> | |
11 #include <cmath> | |
12 | |
13 #include "ClusterMeltSegmenter.h" | |
14 #include "lib_constQ.h" | |
15 #include "cluster_segmenter.h" | |
16 #include "segment.h" | |
17 | |
18 ClusterMeltSegmenter::ClusterMeltSegmenter(ClusterMeltSegmenterParams params) : window(NULL), | |
19 constq(NULL), | |
20 featureType(params.featureType), | |
21 windowSize(params.windowSize), | |
22 hopSize(params.hopSize), | |
23 fmin(params.fmin), | |
24 fmax(params.fmax), | |
25 nbins(params.nbins), | |
26 ncomponents(params.ncomponents), // NB currently not passed - no. of PCA components is set in cluser_segmenter.c | |
27 nHMMStates(params.nHMMStates), | |
28 nclusters(params.nclusters), | |
29 histogramLength(params.histogramLength), | |
30 neighbourhoodLimit(params.neighbourhoodLimit) | |
31 { | |
32 } | |
33 | |
34 void ClusterMeltSegmenter::initialise(int fs) | |
35 { | |
36 samplerate = fs; | |
37 if (featureType != FEATURE_TYPE_UNKNOWN) | |
38 { | |
39 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 } | |
42 } | |
43 | |
44 ClusterMeltSegmenter::~ClusterMeltSegmenter() | |
45 { | |
46 delete [] window; | |
47 if (constq) | |
48 close_constQ(constq); | |
49 } | |
50 | |
51 void ClusterMeltSegmenter::extractFeatures(double* samples, int nsamples) | |
52 { | |
53 // create a new window if needed | |
54 if (!window || nsamples != windowLength) | |
55 { | |
56 if (window) | |
57 delete [] window; | |
58 window = hamming_p(nsamples); | |
59 windowLength = nsamples; | |
60 } | |
61 | |
62 // copy the samples before windowing in case we need them for something else | |
63 double* frame = new double[nsamples]; | |
64 for (int i = 0; i < nsamples; i++) | |
65 frame[i] = samples[i] * window[i]; | |
66 | |
67 // extract const-Q | |
68 do_constQ(constq, frame, nsamples); | |
69 int ncq = constq->ncoeff; | |
70 | |
71 delete [] frame; | |
72 | |
73 if (ncq == ncoeff) // else feature extraction failed | |
74 { | |
75 vector<double> cq(ncq); | |
76 for (int i = 0; i < ncq; i++) | |
77 cq[i] = constq->absconstQtransform[i]; | |
78 features.push_back(cq); | |
79 } | |
80 } | |
81 | |
82 void ClusterMeltSegmenter::segment(int m) | |
83 { | |
84 nclusters = m; | |
85 segment(); | |
86 } | |
87 | |
88 void ClusterMeltSegmenter::setFeatures(const vector<vector<double> >& f) | |
89 { | |
90 features = f; | |
91 featureType = FEATURE_TYPE_UNKNOWN; | |
92 } | |
93 | |
94 void ClusterMeltSegmenter::segment() | |
95 { | |
96 if (constq) | |
97 { | |
98 close_constQ(constq); // finished extracting features | |
99 constq = NULL; | |
100 } | |
101 | |
102 // for now copy the features to a native array and use the existing C segmenter... | |
103 double** arrFeatures = new double*[features.size()]; | |
104 for (int i = 0; i < features.size(); i++) | |
105 { | |
106 if (featureType == FEATURE_TYPE_UNKNOWN) | |
107 arrFeatures[i] = new double[features[0].size()]; | |
108 else | |
109 arrFeatures[i] = new double[ncoeff+1]; // allow space for the normalised envelope | |
110 for (int j = 0; j < ncoeff; j++) | |
111 arrFeatures[i][j] = features[i][j]; | |
112 } | |
113 | |
114 q = new int[features.size()]; | |
115 | |
116 if (featureType == FEATURE_TYPE_UNKNOWN) | |
117 cluster_segment(q, arrFeatures, features.size(), features[0].size(), nHMMStates, histogramLength, | |
118 nclusters, neighbourhoodLimit); | |
119 else | |
120 constq_segment(q, arrFeatures, features.size(), nbins, ncoeff, featureType, | |
121 nHMMStates, histogramLength, nclusters, neighbourhoodLimit); | |
122 | |
123 // convert the cluster assignment sequence to a segmentation | |
124 makeSegmentation(q, features.size()); | |
125 | |
126 // de-allocate arrays | |
127 delete [] q; | |
128 for (int i = 0; i < features.size(); i++) | |
129 delete [] arrFeatures[i]; | |
130 delete [] arrFeatures; | |
131 | |
132 // clear the features | |
133 clear(); | |
134 } | |
135 | |
136 void ClusterMeltSegmenter::makeSegmentation(int* q, int len) | |
137 { | |
138 segmentation.segments.clear(); | |
139 segmentation.nsegtypes = nclusters; | |
140 segmentation.samplerate = samplerate; | |
141 | |
142 Segment segment; | |
143 segment.start = 0; | |
144 segment.type = q[0]; | |
145 | |
146 for (int i = 1; i < len; i++) | |
147 { | |
148 if (q[i] != q[i-1]) | |
149 { | |
150 segment.end = i * getHopsize(); | |
151 segmentation.segments.push_back(segment); | |
152 segment.type = q[i]; | |
153 segment.start = segment.end; | |
154 } | |
155 } | |
156 segment.end = len * getHopsize(); | |
157 segmentation.segments.push_back(segment); | |
158 } | |
159 | |
160 /* | |
161 void ClusterMeltSegmenter::mpeg7ConstQ() | |
162 { | |
163 // convert to dB scale | |
164 for (int i = 0; i < features.size(); i++) | |
165 for (int j = 0; j < ncoeff; j++) | |
166 features[i][j] = 10.0 * log10(features[i][j] + DBL_EPSILON); | |
167 | |
168 // normalise features and add the norm at the end as an extra feature dimension | |
169 double maxnorm = 0; // track the max of the norms | |
170 for (int i = 0; i < features.size(); i++) | |
171 { | |
172 double norm = 0; | |
173 for (int j = 0; j < ncoeff; j++) | |
174 norm += features[i][j] * features[i][j]; | |
175 norm = sqrt(norm); | |
176 for (int j = 0; j < ncoeff; j++) | |
177 features[i][j] /= norm; | |
178 features[i].push_back(norm); | |
179 if (norm > maxnorm) | |
180 maxnorm = norm; | |
181 } | |
182 | |
183 // normalise the norms | |
184 for (int i = 0; i < features.size(); i++) | |
185 features[i][ncoeff] /= maxnorm; | |
186 } | |
187 */ |