blob: 928bb4109faf8836b335590016323e2dba3d4b7c [file] [log] [blame]
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "dl/sp/src/test/test_util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dl/sp/api/armSP.h"
#include "dl/sp/src/test/compare.h"
/*
* Return the program name, fur usage messages and debugging
*/
char* ProgramName(char* argv0) {
char* slash = strrchr(argv0, '/');
return slash ? slash + 1 : argv0;
}
/*
* Print usage message for the command line options.
*/
void usage(char* prog, int real_only, int max_fft_order, const char *summary) {
fprintf(stderr, "\n%s: [-hTFI] [-n logsize] [-s scale] [-g signal-type] "
"[-S signal value]\n\t\t[-v verbose] [-m minFFT] [-M maxFFT]\n",
ProgramName(prog));
fprintf(stderr, summary);
fprintf(stderr, " -h\t\tThis help\n");
fprintf(stderr, " -T\t\tIndividual test mode, otherwise run all tests\n");
fprintf(stderr, " -F\t\tDo not run forward FFT tests\n");
fprintf(stderr, " -I\t\tDo not run inverse FFT tests\n");
fprintf(stderr, " -m min\tMinium FFT order to test (default 2)\n");
fprintf(stderr, " -M min\tMaximum FFT order to test (default %d)\n",
max_fft_order);
fprintf(stderr, " -n logsize\tLog2 of FFT size\n");
fprintf(stderr, " -s scale\tScale factor for forward FFT (default = 0)\n");
fprintf(stderr, " -S signal\tBase value for the test signal "
"(default = 1024)\n");
fprintf(stderr, " -v level\tVerbose output level (default = 1)\n");
fprintf(stderr, " -g type\tInput signal type:\n");
fprintf(stderr, "\t\t 0 - Constant signal S + i*S. (Default value.)\n");
fprintf(stderr, "\t\t 1 - Real ramp starting at S/N, N = FFT size\n");
fprintf(stderr, "\t\t 2 - Sine wave of amplitude S\n");
if (!real_only)
fprintf(stderr, "\t\t 3 - Complex signal whose transform is a sine "
"wave.\n");
exit(0);
}
/*
* Set default values for all command line options.
*/
void SetDefaultOptions(struct Options* options, int real_only,
int max_fft_order) {
options->real_only_ = real_only;
options->verbose_ = 1;
/*
* Test mode options, defaulting to non-test mode
*/
options->test_mode_ = 1;
options->do_forward_tests_ = 1;
options->do_inverse_tests_ = 1;
options->min_fft_order_ = 1;
options->max_fft_order_ = max_fft_order;
/*
* Individual test options
*/
options->fft_log_size_ = 4;
options->scale_factor_ = 0;
options->signal_type_ = 0;
options->signal_value_ = 32767;
options->signal_value_given_ = 0;
}
/*
* Print values of command line options, for debugging.
*/
void DumpOptions(FILE* f, const struct Options* options) {
fprintf(f, "real_only = %d\n", options->real_only_);
fprintf(f, "verbose = %d\n", options->verbose_);
fprintf(f, "test_mode = %d\n", options->test_mode_);
fprintf(f, "do_forward_tests = %d\n", options->do_forward_tests_);
fprintf(f, "do_inverse_tests = %d\n", options->do_inverse_tests_);
fprintf(f, "min_fft_order = %d\n", options->min_fft_order_);
fprintf(f, "max_fft_order = %d\n", options->max_fft_order_);
fprintf(f, "fft_log_size = %d\n", options->fft_log_size_);
fprintf(f, "scale_factor = %d\n", options->scale_factor_);
fprintf(f, "signal_type = %d\n", options->signal_type_);
fprintf(f, "signal_value = %g\n", options->signal_value_);
fprintf(f, "signal_value_given = %d\n", options->signal_value_given_);
}
/*
* Process command line options, returning the values in |options|.
*/
void ProcessCommandLine(struct Options *options, int argc, char* argv[],
const char* summary) {
int opt;
int max_fft_order = options->max_fft_order_;
options->signal_value_given_ = 0;
while ((opt = getopt(argc, argv, "hTFIn:s:S:g:v:m:M:")) != -1) {
switch (opt) {
case 'h':
usage(argv[0], options->real_only_, max_fft_order, summary);
break;
case 'T':
options->test_mode_ = 0;
break;
case 'F':
options->do_forward_tests_ = 0;
break;
case 'I':
options->do_inverse_tests_ = 0;
break;
case 'm':
options->min_fft_order_ = atoi(optarg);
break;
case 'M':
options->max_fft_order_ = atoi(optarg);
break;
case 'n':
options->fft_log_size_ = atoi(optarg);
break;
case 'S':
options->signal_value_ = atof(optarg);
options->signal_value_given_ = 1;
break;
case 's':
options->scale_factor_ = atoi(optarg);
break;
case 'g':
options->signal_type_ = atoi(optarg);
break;
case 'v':
options->verbose_ = atoi(optarg);
break;
default:
usage(argv[0], options->real_only_, max_fft_order, summary);
break;
}
}
}
/*
* Return true if the given test is known to fail. The array of known
* failures is in |knownFailures|. The FFT order is |fft_order|,
* |is_inverse_fft| is true, if the test fails for the inverse FFT
* (otherwise for forward FFT), and |signal_type| specifies the test
* signal used.
*/
int IsKnownFailure(int fft_order, int is_inverse_fft, int signal_type,
struct KnownTestFailures* known_failures) {
if (known_failures) {
/*
* Look through array of known failures and see if an FFT
* (forward or inverse) of the given order and signal type
* matches. Return true if so.
*/
while (known_failures->fft_order_ > 0) {
if ((fft_order == known_failures->fft_order_)
&& (is_inverse_fft == known_failures->is_inverse_fft_test_)
&& (signal_type == known_failures->signal_type_)) {
return 1;
}
++known_failures;
}
}
return 0;
}
/*
* Print the contents of an array to stdout, one element per line.
* |array_name| is the name of the array to be used in the header
* line.
*
* Arrays with elements of type OMX_S16, OMX_S32, OMX_SC32, OMX_F32,
* and OMX_FC32 are supported.
*/
void DumpArrayReal16(const char* array_name, int count,
const OMX_S16* array) {
int n;
printf("%4s\t%5s[n]\n", "n", array_name);
for (n = 0; n < count; ++n) {
printf("%4d\t%8d\n", n, array[n]);
}
}
void DumpArrayReal32(const char* array_name, int count, const OMX_S32* array) {
int n;
printf("%4s\t%5s[n]\n", "n", array_name);
for (n = 0; n < count; ++n) {
printf("%4d\t%8d\n", n, array[n]);
}
}
void DumpArrayComplex32(const char* array_name, int count,
const OMX_SC32* array) {
int n;
printf("%4s\t%10s.re[n]\t%10s.im[n]\n", "n", array_name, array_name);
for (n = 0; n < count; ++n) {
printf("%4d\t%16d\t%16d\n", n, array[n].Re, array[n].Im);
}
}
void DumpArrayComplex16(const char* array_name, int count,
const OMX_SC16* array) {
int n;
printf("%4s\t%10s.re[n]\t%10s.im[n]\n", "n", array_name, array_name);
for (n = 0; n < count; ++n) {
printf("%4d\t%16d\t%16d\n", n, array[n].Re, array[n].Im);
}
}
void DumpArrayFloat(const char* array_name, int count, const OMX_F32* array) {
int n;
printf("%4s\t%13s[n]\n", "n", array_name);
for (n = 0; n < count; ++n) {
printf("%4d\t%16g\n", n, array[n]);
}
}
void DumpArrayComplexFloat(const char* array_name, int count,
const OMX_FC32* array) {
int n;
printf("%4s\t%10s.re[n]\t%10s.im[n]\n", "n", array_name, array_name);
for (n = 0; n < count; ++n) {
printf("%4d\t%16g\t%16g\n", n, array[n].Re, array[n].Im);
}
}