Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b89991f5 authored by Saketh Sathuvalli's avatar Saketh Sathuvalli Committed by Andy Hung
Browse files

libeffects: Added standalone testbench that calculates SNR value

Added a standalone test bench that calculates SNR values using 2 files
as input. This tool is used to test the multichannel changes.

Test: build_and_run_all_unit_tests.sh
Bug: 121353611
Change-Id: I5e67d8113bace7872133f2e02d9ae7b9d90e61ff
parent 875cec7a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -44,3 +44,16 @@ cc_test {
        "-Wextra",
    ],
}

cc_test {
    name: "snr",
    host_supported: false,

    srcs: ["snr.cpp"],

    cflags: [
        "-Wall",
        "-Werror",
        "-Wextra",
    ],
}
+7 −2
Original line number Diff line number Diff line
@@ -25,16 +25,17 @@ echo "testing lvm"
adb shell mkdir -p $testdir
adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw $testdir
adb push $OUT/testcases/lvmtest/arm64/lvmtest $testdir
adb push $OUT/testcases/snr/arm64/snr $testdir

flags_arr=(
    "-csE"
    "-eqE"
    "-tE"
    "-csE -tE -eqE"
    "-bE"
    "-bE -M"
    "-csE -tE"
    "-csE -eqE" "-tE -eqE"
    "-csE -tE -bE -eqE"
    "-csE -tE -bE -M -eqE"
)

fs_arr=(
@@ -79,6 +80,10 @@ do
            then
                adb shell cmp $testdir/sinesweep_2_$((fs)).raw \
                    $testdir/sinesweep_$((ch))_$((fs)).raw
            elif [[ $flags == *"-bE"* ]] && [ "$ch" -gt 2 ]
            then
                adb shell $testdir/snr $testdir/sinesweep_2_$((fs)).raw \
                    $testdir/sinesweep_$((ch))_$((fs)).raw -thr:90.308998
            fi

        done
+103 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <assert.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

template <typename T, typename A = float>
std::pair<A, A> getSignalNoise(FILE *finp, FILE *fref) {
  constexpr size_t framesize = 256;
  std::vector<T> in(framesize);
  std::vector<T> ref(framesize);
  A signal{};
  A noise{};

  for (;;) {
    size_t read_samples_in = fread(&in[0], sizeof(T), framesize, finp);
    const size_t read_samples_ref = fread(&ref[0], sizeof(T), framesize, fref);
    if (read_samples_in != read_samples_ref) {
      printf("file sizes do not match (last %zu %zu)", read_samples_in, read_samples_ref);
      read_samples_in = std::min(read_samples_in, read_samples_ref);
    }
    if (read_samples_in == 0) {
        return { signal, noise };
    }
    for (size_t i = 0; i < read_samples_in; ++i) {
       const A value(ref[i]);
       const A diff(A(in[i]) - value);
       signal += value * value;
       noise += diff * diff;
    }
  }
}

void printUsage() {
  printf("\nUsage: ");
  printf("\n     snr <ref_file> <test_file> [options]\n");
  printf("\nwhere, \n     <ref_file>  is the reference file name");
  printf("\n                  on which will be taken as pure signal");
  printf("\n     <test_file> is test file for snr calculation");
  printf("\n     and options are mentioned below");
  printf("\n");
  printf("\n     -pcm_format:<pcm format of input files>");
  printf("\n           0 - 16 bit pcm");
  printf("\n           1 - 32 bit float");
  printf("\n           default 0");
  printf("\n     -thr:<threshold value>");
  printf("\n           default - negative infinity\n\n");
}

int main(int argc, const char *argv[]) {
  if (argc < 3) {
    printUsage();
    return -1;
  }
  int pcm_format = 0;
  float thr = - std::numeric_limits<float>::infinity();
  FILE *fref = fopen(argv[1], "rb");
  FILE *finp = fopen(argv[2], "rb");
  for (int i = 3; i < argc; i++) {
    if (!strncmp(argv[i], "-pcm_format:", 12)) {
      pcm_format = atoi(argv[i] + 12);
    } else if (!strncmp(argv[i], "-thr:", 5)) {
      thr = atof(argv[i] + 5);
    }
  }
  if (finp == nullptr || fref == nullptr) {
    printf("\nError: missing input/reference files\n");
    return -1;
  }
  auto sn = pcm_format == 0
      ? getSignalNoise<short>(finp, fref)
      : getSignalNoise<float>(finp, fref);
  if (sn.first > 0.f && sn.second > 0.f) {
    float snr = 10.f * log(sn.first / sn.second);
    // compare the measured snr value with threshold
    if (snr < thr) {
      printf("%.6f less than threshold %.6f\n", snr, thr);
    } else {
      printf("%.6f\n", snr);
    }
  }
  fclose(finp);
  fclose(fref);

  return 0;
}