Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/openmax_dl/dl/sp/src/test/test_fft16.c

Issue 12317152: Add openmax dl routines for review. MUST NOT BE LANDED (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <math.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <time.h>
15 #include <unistd.h>
16
17 #include "dl/sp/api/armSP.h"
18 #include "dl/sp/api/omxSP.h"
19 #include "dl/sp/src/test/aligned_ptr.h"
20 #include "dl/sp/src/test/compare.h"
21 #include "dl/sp/src/test/gensig.h"
22 #include "dl/sp/src/test/test_util.h"
23
24 #define MAX_FFT_ORDER 12
25
26 int verbose = 0;
27 int signal_value = 1024;
28 int scale_factor = 0;
29
30 struct KnownTestFailures known_failures[] = {
31 {11, 0, 1},
32 {11, 0, 2},
33 {11, 0, 3},
34 {12, 0, 1},
35 {12, 0, 2},
36 {12, 0, 3},
37 { 6, 1, 3},
38 { 7, 1, 3},
39 { 8, 1, 3},
40 { 9, 1, 3},
41 {10, 1, 3},
42 {11, 1, 1},
43 {11, 1, 2},
44 {11, 1, 3},
45 {12, 1, 1},
46 {12, 1, 2},
47 {12, 1, 3},
48 /* Marker to terminate array */
49 {-1, 0, 0}
50 };
51
52 void TestFFT(int fftLogSize, int scale_factor, int signalType);
53
54 void main(int argc, char* argv[]) {
55 struct Options options;
56
57 SetDefaultOptions(&options, 0, MAX_FFT_ORDER);
58
59 options.signal_value_ = signal_value;
60 options.scale_factor_ = scale_factor;
61
62 ProcessCommandLine(&options, argc, argv,
63 "Test forward and inverse 16-bit fixed-point FFT\n");
64
65 verbose = options.verbose_;
66 signal_value = options.signal_value_;
67 scale_factor = options.scale_factor_;
68
69 if (verbose > 255)
70 DumpOptions(stderr, &options);
71
72 if (options.test_mode_) {
73 struct TestInfo info;
74
75 info.real_only_ = options.real_only_;
76 info.max_fft_order_ = options.max_fft_order_;
77 info.min_fft_order_ = options.min_fft_order_;
78 info.do_forward_tests_ = options.do_forward_tests_;
79 info.do_inverse_tests_ = options.do_inverse_tests_;
80 info.known_failures_ = known_failures;
81 /*
82 * These SNR threshold values critically depend on the
83 * signal_value that is set for the tests!
84 */
85 info.forward_threshold_ = 33.01;
86 info.inverse_threshold_ = 35.59;
87
88 RunAllTests(&info);
89 } else {
90 TestFFT(options.fft_log_size_,
91 options.signal_type_,
92 options.scale_factor_);
93 }
94 }
95
96 void GenerateSignal(OMX_SC16* x, struct ComplexFloat* fft,
97 struct ComplexFloat* x_true, int size, int sigtype,
98 int scale_factor) {
99 int k;
100
101 GenerateTestSignalAndFFT(x_true, fft, size, sigtype, signal_value, 0);
102
103 /*
104 * Convert the complex result to what we want
105 */
106
107 for (k = 0; k < size; ++k) {
108 x[k].Re = 0.5 + x_true[k].Re;
109 x[k].Im = 0.5 + x_true[k].Im;
110 }
111 }
112
113 void DumpFFTSpec(OMXFFTSpec_C_SC16* pSpec) {
114 ARMsFFTSpec_SC16* p = (ARMsFFTSpec_SC16*) pSpec;
115 printf(" N = %d\n", p->N);
116 printf(" pBitRev = %p\n", p->pBitRev);
117 printf(" pTwiddle = %p\n", p->pTwiddle);
118 printf(" pBuf = %p\n", p->pBuf);
119 }
120
121 void TestFFT(int fft_log_size, int signal_type, int scale_factor) {
122 struct SnrResult snr;
123
124 RunOneForwardTest(fft_log_size, signal_type, signal_value, &snr);
125 printf("Forward float FFT\n");
126 printf("SNR: real part %f dB\n", snr.real_snr_);
127 printf(" imag part %f dB\n", snr.imag_snr_);
128 printf(" complex part %f dB\n", snr.complex_snr_);
129
130 RunOneInverseTest(fft_log_size, signal_type, signal_value, &snr);
131 printf("Inverse float FFT\n");
132 printf("SNR: real part %f dB\n", snr.real_snr_);
133 printf(" imag part %f dB\n", snr.imag_snr_);
134 printf(" complex part %f dB\n", snr.complex_snr_);
135 }
136
137
138 float RunOneForwardTest(int fft_log_size, int signal_type,
139 float unused_signal_value,
140 struct SnrResult* snr) {
141 OMX_SC16* x;
142 OMX_SC16* y;
143
144 struct AlignedPtr* x_aligned;
145 struct AlignedPtr* y_aligned;
146
147 struct ComplexFloat* x_true;
148 struct ComplexFloat* y_true;
149 OMX_SC16* y_scaled;
150
151 OMX_INT n, fft_spec_buffer_size;
152 OMXResult status;
153 OMXFFTSpec_C_SC16 * fft_fwd_spec = NULL;
154 int fft_size;
155
156 /*
157 * With 16-bit numbers, we need to be careful to use all of the
158 * available bits to get good accuracy. Hence, set signal_value to
159 * the max 16-bit value (or close to it).
160 *
161 * To get good FFT results, also set the forward FFT scale factor
162 * to be the same as the order. This was determined by
163 * experimentation, so be careful!
164 */
165 signal_value = 32767;
166 scale_factor = fft_log_size;
167
168 fft_size = 1 << fft_log_size;
169
170 status = omxSP_FFTGetBufSize_C_SC16(fft_log_size, &fft_spec_buffer_size);
171 if (verbose > 63) {
172 printf("bufSize = %d\n", fft_spec_buffer_size);
173 }
174
175 fft_fwd_spec = (OMXFFTSpec_C_SC16*) malloc(fft_spec_buffer_size);
176 status = omxSP_FFTInit_C_SC16(fft_fwd_spec, fft_log_size);
177 if (status) {
178 fprintf(stderr, "Failed to init forward FFT: status = %d\n", status);
179 exit(1);
180 }
181
182 x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
183 y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2));
184
185 x = x_aligned->aligned_pointer_;
186 y = y_aligned->aligned_pointer_;
187
188 x_true = (struct ComplexFloat*) malloc(sizeof(*x_true) * fft_size);
189 y_true = (struct ComplexFloat*) malloc(sizeof(*y_true) * fft_size);
190 y_scaled = (OMX_SC16*) malloc(sizeof(*y_true) * fft_size);
191
192 GenerateSignal(x, y_true, x_true, fft_size, signal_type, scale_factor);
193
194 {
195 float scale = pow(2.0, fft_log_size);
196
197 for (n = 0; n < fft_size; ++n) {
198 y_scaled[n].Re = 0.5 + y_true[n].Re / scale;
199 y_scaled[n].Im = 0.5 + y_true[n].Im / scale;
200 }
201 }
202
203 if (verbose > 63) {
204 printf("Signal\n");
205 DumpArrayComplex16("x", fft_size, x);
206 printf("Expected FFT output\n");
207 DumpArrayComplex16("y", fft_size, y_scaled);
208 }
209
210 status = omxSP_FFTFwd_CToC_SC16_Sfs(x, y, fft_fwd_spec, scale_factor);
211 if (status) {
212 fprintf(stderr, "Forward FFT failed: status = %d\n", status);
213 exit(1);
214 }
215
216 if (verbose > 63) {
217 printf("FFT Output\n");
218 DumpArrayComplex16("y", fft_size, y);
219 }
220
221 CompareComplex16(snr, y, y_scaled, fft_size);
222
223 return snr->complex_snr_;
224 }
225
226 float RunOneInverseTest(int fft_log_size, int signal_type,
227 float unused_signal_value,
228 struct SnrResult* snr) {
229 OMX_SC16* x;
230 OMX_SC16* y;
231 OMX_SC16* z;
232 OMX_SC16* y_scaled;
233
234 struct AlignedPtr* x_aligned;
235 struct AlignedPtr* y_aligned;
236 struct AlignedPtr* z_aligned;
237 struct AlignedPtr* y_scaled_aligned;
238
239 struct ComplexFloat* x_true;
240 struct ComplexFloat* y_true;
241
242 OMX_INT n, fft_spec_buffer_size;
243 OMXResult status;
244 OMXFFTSpec_C_SC16 * fft_fwd_spec = NULL;
245 OMXFFTSpec_C_SC16 * fft_inv_spec = NULL;
246 int fft_size;
247
248 /*
249 * With 16-bit numbers, we need to be careful to use all of the
250 * available bits to get good accuracy. Hence, set signal_value to
251 * the max 16-bit value (or close to it).
252 *
253 * To get good FFT results, also set the forward FFT scale factor
254 * to be the same as the order. This was determined by
255 * experimentation, so be careful!
256 */
257 signal_value = 32767;
258
259 fft_size = 1 << fft_log_size;
260
261 status = omxSP_FFTGetBufSize_C_SC16(fft_log_size, &fft_spec_buffer_size);
262 if (verbose > 3) {
263 printf("bufSize = %d\n", fft_spec_buffer_size);
264 }
265
266 fft_inv_spec = (OMXFFTSpec_C_SC16*)malloc(fft_spec_buffer_size);
267 status = omxSP_FFTInit_C_SC16(fft_inv_spec, fft_log_size);
268 if (status) {
269 fprintf(stderr, "Failed to init backward FFT: status = %d\n", status);
270 exit(1);
271 }
272
273 x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
274 y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2));
275 z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size);
276 y_scaled_aligned = AllocAlignedPointer(32, sizeof(*y_true) * fft_size);
277
278 x = x_aligned->aligned_pointer_;
279 y = y_aligned->aligned_pointer_;
280 z = z_aligned->aligned_pointer_;
281 y_scaled = y_scaled_aligned->aligned_pointer_;
282
283 y_true = (struct ComplexFloat*) malloc(sizeof(*y_true) * fft_size);
284 x_true = (struct ComplexFloat*) malloc(sizeof(*x_true) * fft_size);
285
286
287 GenerateSignal(x, y_true, x_true, fft_size, signal_type, fft_log_size);
288
289 {
290 /*
291 * To get max accuracy, scale the input to the inverse FFT up
292 * to use as many bits as we can.
293 */
294 float scale = 1;
295 float max = 0;
296
297 for (n = 0; n < fft_size; ++n) {
298 float val;
299 val = fabs(y_true[n].Re);
300 if (val > max) {
301 max = val;
302 }
303 val = fabs(y_true[n].Im);
304 if (val > max) {
305 max = val;
306 }
307 }
308
309 scale = 16384 / max;
310 if (verbose > 63)
311 printf("Inverse FFT input scaled factor %g\n", scale);
312
313 /*
314 * Scale both the true FFT signal and the input so we can
315 * compare them correctly later
316 */
317 for (n = 0; n < fft_size; ++n) {
318 y_scaled[n].Re = 0.5 + y_true[n].Re * scale;
319 y_scaled[n].Im = 0.5 + y_true[n].Im * scale;
320 x_true[n].Re *= scale;
321 x_true[n].Im *= scale;
322 }
323 }
324
325
326 if (verbose > 63) {
327 printf("Inverse FFT Input Signal\n");
328 DumpArrayComplex16("yScaled", fft_size, y_scaled);
329 printf("Expected Inverse FFT Output\n");
330 DumpArrayComplexFloat("x_true", fft_size, (OMX_FC32*) x_true);
331 }
332
333 status = omxSP_FFTInv_CToC_SC16_Sfs(y_scaled, z, fft_inv_spec, 0);
334
335 if (verbose > 7)
336 printf("Inverse FFT scaling = %d\n", status);
337
338 if (verbose > 127) {
339 printf("Raw Inverse FFT Output\n");
340 DumpArrayComplex16("z", fft_size, z);
341 }
342
343 /*
344 * The inverse FFT routine returns how much scaling was done. To
345 * compare the output with the expected output, we need to scale
346 * the expected output according to the scale factor returned.
347 */
348 for (n = 0; n < fft_size; ++n) {
349 x[n].Re = 0.5 + x_true[n].Re;
350 x[n].Im = 0.5 + x_true[n].Im;
351 }
352
353 if (verbose > 63) {
354 printf("Inverse FFT Output\n");
355 printf(" Actual\n");
356 DumpArrayComplex16("z", fft_size, z);
357 printf(" Expected (scaled)\n");
358 DumpArrayComplex16("x", fft_size, x);
359 }
360
361 CompareComplex16(snr, z, x, fft_size);
362
363 return snr->complex_snr_;
364 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698