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