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#include "dl/sp/src/test/test_util.h"
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <unistd.h>
16
17#include "dl/sp/api/armSP.h"
18#include "dl/sp/src/test/compare.h"
19
20/*
21 * Return the program name, fur usage messages and debugging
22 */
23char* ProgramName(char* argv0) {
24  char* slash = strrchr(argv0, '/');
25
26  return slash ? slash + 1 : argv0;
27}
28
29/*
30 * Print usage message for the command line options.
31 */
32void usage(char* prog, int real_only, int max_fft_order, const char *summary) {
33  fprintf(stderr, "\n%s: [-hTFI] [-n logsize] [-s scale] [-g signal-type] "
34          "[-S signal value]\n\t\t[-v verbose] [-m minFFT] [-M maxFFT]\n",
35          ProgramName(prog));
36  fprintf(stderr, summary);
37  fprintf(stderr, "  -h\t\tThis help\n");
38  fprintf(stderr, "  -T\t\tIndividual test mode, otherwise run all tests\n");
39  fprintf(stderr, "  -F\t\tDo not run forward FFT tests\n");
40  fprintf(stderr, "  -I\t\tDo not run inverse FFT tests\n");
41  fprintf(stderr, "  -m min\tMinium FFT order to test (default 2)\n");
42  fprintf(stderr, "  -M min\tMaximum FFT order to test (default %d)\n",
43          max_fft_order);
44  fprintf(stderr, "  -n logsize\tLog2 of FFT size\n");
45  fprintf(stderr, "  -s scale\tScale factor for forward FFT (default = 0)\n");
46  fprintf(stderr, "  -S signal\tBase value for the test signal "
47          "(default = 1024)\n");
48  fprintf(stderr, "  -v level\tVerbose output level (default = 1)\n");
49  fprintf(stderr, "  -g type\tInput signal type:\n");
50  fprintf(stderr, "\t\t  0 - Constant signal S + i*S. (Default value.)\n");
51  fprintf(stderr, "\t\t  1 - Real ramp starting at S/N, N = FFT size\n");
52  fprintf(stderr, "\t\t  2 - Sine wave of amplitude S\n");
53  if (!real_only)
54    fprintf(stderr, "\t\t  3 - Complex signal whose transform is a sine "
55            "wave.\n");
56  exit(0);
57}
58
59/*
60 * Set default values for all command line options.
61 */
62void SetDefaultOptions(struct Options* options, int real_only,
63                       int max_fft_order) {
64  options->real_only_ = real_only;
65
66  options->verbose_ = 1;
67
68  /*
69   * Test mode options, defaulting to non-test mode
70   */
71  options->test_mode_ = 1;
72  options->do_forward_tests_ = 1;
73  options->do_inverse_tests_ = 1;
74  options->min_fft_order_ = 1;
75  options->max_fft_order_ = max_fft_order;
76
77  /*
78   * Individual test options
79   */
80  options->fft_log_size_ = 4;
81  options->scale_factor_ = 0;
82  options->signal_type_ = 0;
83  options->signal_value_ = 32767;
84  options->signal_value_given_ = 0;
85}
86
87/*
88 * Print values of command line options, for debugging.
89 */
90void DumpOptions(FILE* f, const struct Options* options) {
91    fprintf(f, "real_only          = %d\n", options->real_only_);
92    fprintf(f, "verbose            = %d\n", options->verbose_);
93    fprintf(f, "test_mode          = %d\n", options->test_mode_);
94    fprintf(f, "do_forward_tests   = %d\n", options->do_forward_tests_);
95    fprintf(f, "do_inverse_tests   = %d\n", options->do_inverse_tests_);
96    fprintf(f, "min_fft_order      = %d\n", options->min_fft_order_);
97    fprintf(f, "max_fft_order      = %d\n", options->max_fft_order_);
98    fprintf(f, "fft_log_size       = %d\n", options->fft_log_size_);
99    fprintf(f, "scale_factor       = %d\n", options->scale_factor_);
100    fprintf(f, "signal_type        = %d\n", options->signal_type_);
101    fprintf(f, "signal_value       = %g\n", options->signal_value_);
102    fprintf(f, "signal_value_given = %d\n", options->signal_value_given_);
103}
104
105/*
106 * Process command line options, returning the values in |options|.
107 */
108void ProcessCommandLine(struct Options *options, int argc, char* argv[],
109                        const char* summary) {
110  int opt;
111  int max_fft_order = options->max_fft_order_;
112
113  options->signal_value_given_ = 0;
114
115  while ((opt = getopt(argc, argv, "hTFIn:s:S:g:v:m:M:")) != -1) {
116    switch (opt) {
117      case 'h':
118        usage(argv[0], options->real_only_, max_fft_order, summary);
119        break;
120      case 'T':
121        options->test_mode_ = 0;
122        break;
123      case 'F':
124        options->do_forward_tests_ = 0;
125        break;
126      case 'I':
127        options->do_inverse_tests_ = 0;
128        break;
129      case 'm':
130        options->min_fft_order_ = atoi(optarg);
131        break;
132      case 'M':
133        options->max_fft_order_ = atoi(optarg);
134        break;
135      case 'n':
136        options->fft_log_size_ = atoi(optarg);
137        break;
138      case 'S':
139        options->signal_value_ = atof(optarg);
140        options->signal_value_given_ = 1;
141        break;
142      case 's':
143        options->scale_factor_ = atoi(optarg);
144        break;
145      case 'g':
146        options->signal_type_ = atoi(optarg);
147        break;
148      case 'v':
149        options->verbose_ = atoi(optarg);
150        break;
151      default:
152        usage(argv[0], options->real_only_, max_fft_order, summary);
153        break;
154    }
155  }
156}
157
158/*
159 * Return true if the given test is known to fail.  The array of known
160 * failures is in |knownFailures|.  The FFT order is |fft_order|,
161 * |is_inverse_fft| is true, if the test fails for the inverse FFT
162 * (otherwise for forward FFT), and |signal_type| specifies the test
163 * signal used.
164 */
165int IsKnownFailure(int fft_order, int is_inverse_fft, int signal_type,
166                   struct KnownTestFailures* known_failures) {
167  if (known_failures) {
168    /*
169     * Look through array of known failures and see if an FFT
170     * (forward or inverse) of the given order and signal type
171     * matches.  Return true if so.
172     */
173    while (known_failures->fft_order_ > 0) {
174      if ((fft_order == known_failures->fft_order_)
175          && (is_inverse_fft == known_failures->is_inverse_fft_test_)
176          && (signal_type == known_failures->signal_type_)) {
177        return 1;
178      }
179      ++known_failures;
180    }
181  }
182  return 0;
183}
184
185
186/*
187 * Print the contents of an array to stdout, one element per line.
188 * |array_name| is the name of the array to be used in the header
189 * line.
190 *
191 * Arrays with elements of type OMX_S16, OMX_S32, OMX_SC32, OMX_F32,
192 * and OMX_FC32 are supported.
193 */
194void DumpArrayReal16(const char* array_name, int count,
195                     const OMX_S16* array) {
196  int n;
197
198  printf("%4s\t%5s[n]\n", "n", array_name);
199  for (n = 0; n < count; ++n) {
200    printf("%4d\t%8d\n", n, array[n]);
201  }
202}
203
204void DumpArrayReal32(const char* array_name, int count, const OMX_S32* array) {
205  int n;
206
207  printf("%4s\t%5s[n]\n", "n", array_name);
208  for (n = 0; n < count; ++n) {
209    printf("%4d\t%8d\n", n, array[n]);
210  }
211}
212
213void DumpArrayComplex32(const char* array_name, int count,
214                        const OMX_SC32* array) {
215  int n;
216
217  printf("%4s\t%10s.re[n]\t%10s.im[n]\n", "n", array_name);
218  for (n = 0; n < count; ++n) {
219    printf("%4d\t%16d\t%16d\n", n, array[n].Re, array[n].Im);
220  }
221}
222
223void DumpArrayComplex16(const char* array_name, int count,
224                        const OMX_SC16* array) {
225  int n;
226
227  printf("%4s\t%10s.re[n]\t%10s.im[n]\n", "n", array_name, array_name);
228  for (n = 0; n < count; ++n) {
229    printf("%4d\t%16d\t%16d\n", n, array[n].Re, array[n].Im);
230  }
231}
232
233void DumpArrayFloat(const char* array_name, int count, const OMX_F32* array) {
234  int n;
235
236  printf("%4s\t%13s[n]\n", "n", array_name);
237  for (n = 0; n < count; ++n) {
238    printf("%4d\t%16g\n", n, array[n]);
239  }
240}
241
242void DumpArrayComplexFloat(const char* array_name, int count,
243                           const OMX_FC32* array) {
244  int n;
245
246  printf("%4s\t%10s.re[n]\t%10s.im[n]\n", "n", array_name, array_name);
247  for (n = 0; n < count; ++n) {
248    printf("%4d\t%16g\t%16g\n", n, array[n].Re, array[n].Im);
249  }
250}
251