Mercurial > hg > libxtract
comparison src/vector.c @ 1:b8f2448f7207
Initial import
author | Jamie Bullock <jamie@postlude.co.uk> |
---|---|
date | Mon, 02 Oct 2006 14:18:15 +0000 |
parents | |
children | 3977eb18153b |
comparison
equal
deleted
inserted
replaced
0:28af86ad3cc1 | 1:b8f2448f7207 |
---|---|
1 /* libxtract feature extraction library | |
2 * | |
3 * Copyright (C) 2006 Jamie Bullock | |
4 * | |
5 * This program is free software; you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License as published by | |
7 * the Free Software Foundation; either version 2 of the License, or | |
8 * (at your option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 * GNU General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public License | |
16 * along with this program; if not, write to the Free Software | |
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | |
18 * USA. | |
19 */ | |
20 | |
21 | |
22 /* xtract_vector.c: defines functions that extract a feature as a single value from an input vector */ | |
23 | |
24 #include "xtract/libxtract.h" | |
25 #include <math.h> | |
26 #include <fftw3.h> | |
27 | |
28 int xtract_magnitude_spectrum(float *data, int N, void *argv, float *result){ | |
29 | |
30 float *temp; | |
31 int n , M = N >> 1; | |
32 fftwf_plan plan; | |
33 | |
34 temp = (float *)fftwf_malloc(N * sizeof(float)); | |
35 | |
36 plan = fftwf_plan_r2r_1d(N, data, temp, FFTW_R2HC, FFTW_ESTIMATE); | |
37 | |
38 fftwf_execute(plan); | |
39 | |
40 for(n = 1; n < M; n++){ | |
41 result[n] = sqrt(SQ(temp[n]) + SQ(temp[N - n])) / N; | |
42 result[N-n] = 0.0f; | |
43 } | |
44 | |
45 result[0] = fabs(temp[0]) / N; | |
46 result[M] = fabs(temp[M]) / N; | |
47 | |
48 fftwf_destroy_plan(plan); | |
49 fftwf_free(temp); | |
50 | |
51 } | |
52 | |
53 int xtract_autocorrelation(float *data, int N, void *argv, float *result){ | |
54 | |
55 /* Naive time domain implementation */ | |
56 | |
57 int n = N, i; | |
58 | |
59 float corr; | |
60 | |
61 while(n--){ | |
62 corr = 0; | |
63 for(i = 0; i < N - n; i++){ | |
64 corr += data[i] * data[i + n]; | |
65 } | |
66 result[n] = corr / N; | |
67 } | |
68 } | |
69 | |
70 int xtract_autocorrelation_fft(float *data, int N, void *argv, float *result){ | |
71 | |
72 float *temp; | |
73 int n; | |
74 fftwf_plan plan; | |
75 | |
76 temp = (float *)fftwf_malloc(N * sizeof(float)); | |
77 plan = fftwf_plan_r2r_1d(N, data, temp, FFTW_HC2R, FFTW_ESTIMATE); | |
78 | |
79 fftwf_execute(plan); | |
80 | |
81 for(n = 0; n < N - 1; n++) | |
82 result[n] = temp[n+1]; | |
83 | |
84 fftwf_destroy_plan(plan); | |
85 fftwf_free(temp); | |
86 } | |
87 | |
88 int xtract_amdf(float *data, int N, void *argv, float *result){ | |
89 | |
90 int n = N, i; | |
91 | |
92 float md; | |
93 | |
94 while(n--){ | |
95 md = 0; | |
96 for(i = 0; i < N - n; i++){ | |
97 md += abs(data[i] - data[i + n]); | |
98 } | |
99 result[n] = md / N; | |
100 } | |
101 } | |
102 | |
103 int xtract_asdf(float *data, int N, void *argv, float *result){ | |
104 | |
105 int n = N, i; | |
106 | |
107 float sd; | |
108 | |
109 while(n--){ | |
110 sd = 0; | |
111 for(i = 0; i < N - n; i++){ | |
112 sd = 1; | |
113 sd += SQ(data[i] - data[i + n]); | |
114 } | |
115 result[n] = sd / N; | |
116 } | |
117 } | |
118 | |
119 int xtract_mfcc(float *data, int N, void *argv, float *result){ | |
120 | |
121 xtract_mel_filter *f; | |
122 int n, filter; | |
123 fftwf_plan plan; | |
124 | |
125 f = (xtract_mel_filter *)argv; | |
126 | |
127 for(filter = 0; filter < f->n_filters; filter++){ | |
128 for(n = 0; n < N; n++){ | |
129 result[filter] += data[n] * f->filters[filter][n]; | |
130 } | |
131 if(result[filter] < LOG_LIMIT) result[filter] = LOG_LIMIT; | |
132 result[filter] = log(result[filter]); | |
133 } | |
134 | |
135 for(n = filter + 1; n < N; n++) result[n] = 0; | |
136 | |
137 xtract_dct(result, f->n_filters, NULL, result); | |
138 | |
139 } | |
140 | |
141 int xtract_dct(float *data, int N, void *argv, float *result){ | |
142 | |
143 fftwf_plan plan; | |
144 | |
145 plan = | |
146 fftwf_plan_r2r_1d(N, data, result, FFTW_REDFT00, FFTW_ESTIMATE); | |
147 | |
148 fftwf_execute(plan); | |
149 fftwf_destroy_plan(plan); | |
150 } | |
151 | |
152 int xtract_bark_coefficients(float *data, int N, void *argv, float *result){ | |
153 | |
154 int *limits, band, n; | |
155 | |
156 limits = (int *)argv; | |
157 | |
158 for(band = 0; band < BARK_BANDS; band++){ | |
159 for(n = limits[band]; n < limits[band + 1]; n++) | |
160 result[band] += data[n]; | |
161 } | |
162 } | |
163 | |
164 int xtract_peaks(float *data, int N, void *argv, float *result){ | |
165 | |
166 float thresh, max, y, y2, y3, p, width, sr; | |
167 int n = N, M, return_code; | |
168 | |
169 if(argv != NULL){ | |
170 thresh = ((float *)argv)[0]; | |
171 sr = ((float *)argv)[1]; | |
172 return_code = BAD_ARGV; | |
173 } | |
174 else{ | |
175 thresh = 0; | |
176 sr = 44100; | |
177 } | |
178 | |
179 M = N >> 1; | |
180 width = sr / N; | |
181 | |
182 y = y2 = y3 = p = max = 0; | |
183 | |
184 if(thresh < 0 || thresh > 100){ | |
185 thresh = 0; | |
186 return_code = BAD_ARGV; | |
187 } | |
188 | |
189 if(!sr){ | |
190 sr = 44100; | |
191 return_code = BAD_ARGV; | |
192 } | |
193 | |
194 while(n--){ | |
195 max = MAX(max, data[n]); | |
196 /* ensure we never take log10(0) */ | |
197 /*data[n] = (data[n] < LOG_LIMIT ? LOG_LIMIT : data[n]);*/ | |
198 if ((data[n] * 100000) <= 1) | |
199 /* We get a more stable peak this way */ | |
200 data[n] = 1; | |
201 | |
202 } | |
203 | |
204 thresh *= .01 * max; | |
205 | |
206 result[0] = 0; | |
207 result[M] = 0; | |
208 | |
209 for(n = 1; n < M; n++){ | |
210 if(data[n] >= thresh){ | |
211 if(data[n] > data[n - 1] && data[n] > data[n + 1]){ | |
212 result[n] = width * (n + (p = .5 * (y = 20 * log10(data[n-1]) - (y3 = 20 * log10(data[n+1]))) / (20 * log10(data[n - 1]) - 2 * (y2 = 20 * log10(data[n])) + 20 * log10(data[n + 1])))); | |
213 result[M + n] = y2 - .25 * (y - y3) * p; | |
214 } | |
215 else{ | |
216 result[n] = 0; | |
217 result[M + n] = 0; | |
218 } | |
219 } | |
220 else{ | |
221 result[n] = 0; | |
222 result[M + n] = 0; | |
223 } | |
224 } | |
225 | |
226 return (return_code ? return_code : SUCCESS); | |
227 } | |
228 |