Index: third_party/openmax_dl/dl/sp/src/test/test_util.c |
diff --git a/third_party/openmax_dl/dl/sp/src/test/test_util.c b/third_party/openmax_dl/dl/sp/src/test/test_util.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..88d697b78135d792c069423846dd826c20eead1e |
--- /dev/null |
+++ b/third_party/openmax_dl/dl/sp/src/test/test_util.c |
@@ -0,0 +1,408 @@ |
+/* |
+ * 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" |
+ |
+/* |
+ * Test resuls from running either forward or inverse FFT tests |
+ */ |
+struct TestResult { |
+ /* Number of tests that failed */ |
+ int failed_count_; |
+ |
+ /* Number of tests run */ |
+ int test_count_; |
+ |
+ /* Number of tests that were expected to fail */ |
+ int expected_failure_count_; |
+ |
+ /* The minimum SNR found for all of the tests */ |
+ float min_snr_; |
+}; |
+ |
+/* |
+ * 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_ = 2; |
+ 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_ = 1024; |
+ 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; |
+} |
+ |
+/* |
+ * Run a set of tests, printing out the result of each test. |
+ */ |
+void RunTests(struct TestResult* result, |
+ float (*test_function)(int, int, float, struct SnrResult*), |
+ const char* id, |
+ int is_inverse_test, |
+ const struct TestInfo* info, |
+ float snr_threshold) { |
+ int fft_order; |
+ int signal_type; |
+ float snr; |
+ int tests = 0; |
+ int failures = 0; |
+ int expected_failures = 0; |
+ float min_snr = 1e10; |
+ struct SnrResult snrResults; |
+ |
+ for (fft_order = info->min_fft_order_; fft_order <= info->max_fft_order_; |
+ ++fft_order) { |
+ for (signal_type = 0; signal_type < MaxSignalType(info->real_only_); |
+ ++signal_type) { |
+ int known_failure = 0; |
+ int test_failed = 0; |
+ ++tests; |
+ snr = test_function(fft_order, signal_type, 1024.0, &snrResults); |
+ if (snr < min_snr) |
+ min_snr = snr; |
+ known_failure = IsKnownFailure(fft_order, is_inverse_test, |
+ signal_type, info->known_failures_); |
+ if (snr < snr_threshold) { |
+ ++failures; |
+ test_failed = 1; |
+ if (known_failure) { |
+ ++expected_failures; |
+ printf(" *FAILED: %s ", id); |
+ } else { |
+ printf("**FAILED: %s ", id); |
+ } |
+ } else { |
+ test_failed = 0; |
+ printf(" PASSED: %s ", id); |
+ } |
+ printf("order %2d signal %d: SNR = %9.3f", |
+ fft_order, signal_type, snr); |
+ if (known_failure) { |
+ if (test_failed) { |
+ printf(" (expected failure)"); |
+ } else { |
+ printf(" (**Expected to fail, but passed)"); |
+ } |
+ } |
+ printf("\n"); |
+ } |
+ } |
+ |
+ printf("%sSummary: %d %s tests failed out of %d tests. " |
+ "(Success rate %.2f%%.)\n", |
+ failures ? "**" : "", |
+ failures, |
+ id, |
+ tests, |
+ (100.0 * (tests - failures)) / tests); |
+ if (expected_failures) |
+ printf(" (%d expected failures)\n", expected_failures); |
+ printf(" (Minimum SNR = %.3f dB)\n", min_snr); |
+ |
+ result->failed_count_ = failures; |
+ result->test_count_ = tests; |
+ result->expected_failure_count_ = expected_failures; |
+ result->min_snr_ = min_snr; |
+} |
+ |
+/* |
+ * For all FFT orders and signal types, run the forward FFT. |
+ * runOneForwardTest must be defined to compute the forward FFT and |
+ * return the SNR beween the actual and expected FFT. |
+ * |
+ * Also finds the minium SNR from all of the tests and returns the |
+ * minimum SNR value. |
+ */ |
+void RunForwardTests(struct TestResult* result, const struct TestInfo* info, |
+ float snr_threshold) { |
+ RunTests(result, RunOneForwardTest, "FwdFFT", 0, info, snr_threshold); |
+} |
+ |
+/* |
+ * For all FFT orders and signal types, run the inverse FFT. |
+ * runOneInverseTest must be defined to compute the forward FFT and |
+ * return the SNR beween the actual and expected FFT. |
+ * |
+ * Also finds the minium SNR from all of the tests and returns the |
+ * minimum SNR value. |
+ */ |
+void RunInverseTests(struct TestResult* result, const struct TestInfo* info, |
+ float snr_threshold) { |
+ RunTests(result, RunOneInverseTest, "InvFFT", 1, info, snr_threshold); |
+} |
+ |
+/* |
+ * Run all forward and inverse FFT tests, printing a summary of the |
+ * results. |
+ */ |
+void RunAllTests(const struct TestInfo* info) { |
+ int failed; |
+ int total; |
+ float min_forward_snr; |
+ float min_inverse_snr; |
+ struct TestResult forward_results; |
+ struct TestResult inverse_results; |
+ |
+ if (info->do_forward_tests_) |
+ RunForwardTests(&forward_results, info, info->forward_threshold_); |
+ if (info->do_inverse_tests_) |
+ RunInverseTests(&inverse_results, info, info->inverse_threshold_); |
+ |
+ failed = forward_results.failed_count_ + inverse_results.failed_count_; |
+ total = forward_results.test_count_ + inverse_results.test_count_; |
+ min_forward_snr = forward_results.min_snr_; |
+ min_inverse_snr = inverse_results.min_snr_; |
+ |
+ if (total) { |
+ printf("%sTotal: %d tests failed out of %d tests. " |
+ "(Success rate = %.2f%%.)\n", |
+ failed ? "**" : "", |
+ failed, |
+ total, |
+ (100.0 * (total - failed)) / total); |
+ if (forward_results.expected_failure_count_ |
+ + inverse_results.expected_failure_count_) { |
+ printf(" (%d expected failures)\n", |
+ forward_results.expected_failure_count_ |
+ + inverse_results.expected_failure_count_); |
+ } |
+ printf(" Min forward SNR = %.3f dB, min inverse SNR = %.3f dB\n", |
+ min_forward_snr, |
+ min_inverse_snr); |
+ } else { |
+ printf("No tests run\n"); |
+ } |
+} |
+ |
+/* |
+ * 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); |
+ 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); |
+ 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); |
+ } |
+} |