From 77135ab715a2d88610116e184679892970c8c28f Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 25 Sep 2024 16:15:58 -0400 Subject: [PATCH] Add a function to compute the log-spectral distance between two sets of audio samples The function also checks that the resulting distance is below a given threshold. PiperOrigin-RevId: 678820628 --- iamf/cli/tests/BUILD | 4 ++++ iamf/cli/tests/cli_test_utils.cc | 21 +++++++++++++++++++++ iamf/cli/tests/cli_test_utils.h | 18 ++++++++++++++++++ iamf/cli/tests/cli_util_test.cc | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) diff --git a/iamf/cli/tests/BUILD b/iamf/cli/tests/BUILD index 78891ff..62f889b 100644 --- a/iamf/cli/tests/BUILD +++ b/iamf/cli/tests/BUILD @@ -43,8 +43,11 @@ cc_library( "//iamf/obu/decoder_config:lpcm_decoder_config", "//iamf/obu/decoder_config:opus_decoder_config", "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/log", "@com_google_absl//absl/status:status_matchers", + "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", + "@com_google_absl//absl/types:span", "@com_google_googletest//:gtest", ], ) @@ -96,6 +99,7 @@ cc_test( "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/status", "@com_google_absl//absl/status:status_matchers", + "@com_google_absl//absl/types:span", "@com_google_googletest//:gtest_main", "@com_google_protobuf//:protobuf", ], diff --git a/iamf/cli/tests/cli_test_utils.cc b/iamf/cli/tests/cli_test_utils.cc index 292cd05..433c128 100644 --- a/iamf/cli/tests/cli_test_utils.cc +++ b/iamf/cli/tests/cli_test_utils.cc @@ -12,6 +12,7 @@ #include "iamf/cli/tests/cli_test_utils.h" #include +#include #include #include #include @@ -23,9 +24,12 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/log/log.h" #include "absl/status/status_matchers.h" +#include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "iamf/cli/audio_element_with_data.h" @@ -343,4 +347,21 @@ std::string GetAndCreateOutputDirectory(absl::string_view suffix) { return output_directory; } +bool IsLogSpectralDistanceBelowThreshold( + const absl::Span& first_log_spectrum, + const absl::Span& second_log_spectrum, + double threshold_db) { + const int num_samples = first_log_spectrum.size(); + if (num_samples != second_log_spectrum.size()) { + LOG(ERROR) << "Spectrum sizes are not equal."; + return false; + } + double log_spectral_distance = 0.0; + for (int i = 0; i < num_samples; ++i) { + log_spectral_distance += (first_log_spectrum[i] - second_log_spectrum[i]) * + (first_log_spectrum[i] - second_log_spectrum[i]); + } + return (10 * std::sqrt(log_spectral_distance / num_samples)) <= threshold_db; +} + } // namespace iamf_tools diff --git a/iamf/cli/tests/cli_test_utils.h b/iamf/cli/tests/cli_test_utils.h index b57fc0c..9f9528b 100644 --- a/iamf/cli/tests/cli_test_utils.h +++ b/iamf/cli/tests/cli_test_utils.h @@ -19,7 +19,9 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "iamf/cli/audio_element_with_data.h" #include "iamf/cli/demixing_module.h" #include "iamf/cli/renderer/audio_element_renderer_base.h" @@ -190,6 +192,22 @@ std::string GetAndCleanupOutputFileName(absl::string_view suffix); */ std::string GetAndCreateOutputDirectory(absl::string_view suffix); +/*!\brief Computes the log-spectral distance (LSD) between two spectra. + * + * The log-spectral distance (LSD) is a distance measure (expressed in dB) + * between two spectra. + * + * \param first_log_spectrum First log-spectrum to compare. + * \param second_log_spectrum Second log-spectrum to compare. + * \param threshold_db LSD threshold to compare against, in db. + * \return true if the log-spectral distance + * between the two spectra is below the specified threshold, false otherwise. + */ +bool IsLogSpectralDistanceBelowThreshold( + const absl::Span& first_log_spectrum, + const absl::Span& second_log_spectrum, + double threshold_db); + } // namespace iamf_tools #endif // CLI_TESTS_CLI_TEST_UTILS_H_ diff --git a/iamf/cli/tests/cli_util_test.cc b/iamf/cli/tests/cli_util_test.cc index 81beddd..b829f7a 100644 --- a/iamf/cli/tests/cli_util_test.cc +++ b/iamf/cli/tests/cli_util_test.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,7 @@ #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" #include "absl/status/status_matchers.h" +#include "absl/types/span.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "iamf/cli/audio_element_with_data.h" @@ -738,5 +740,35 @@ TEST(GenerateParamIdToMetadataMapTest, EXPECT_FALSE(param_id_to_metadata_map.ok()); } +TEST(IsLogSpectralDistanceBelowThreshold, BelowThresholdSucceeds) { + std::vector first_log_spectrum(10); + std::iota(first_log_spectrum.begin(), first_log_spectrum.end(), 0); + std::vector second_log_spectrum(10); + std::iota(second_log_spectrum.begin(), second_log_spectrum.end(), 1); + EXPECT_TRUE(IsLogSpectralDistanceBelowThreshold( + absl::MakeConstSpan(first_log_spectrum), + absl::MakeConstSpan(second_log_spectrum), 11.0)); +} + +TEST(IsLogSpectralDistanceBelowThreshold, AtThresholdSucceeds) { + std::vector first_log_spectrum(10); + std::iota(first_log_spectrum.begin(), first_log_spectrum.end(), 0); + std::vector second_log_spectrum(10); + std::iota(second_log_spectrum.begin(), second_log_spectrum.end(), 1); + EXPECT_TRUE(IsLogSpectralDistanceBelowThreshold( + absl::MakeConstSpan(first_log_spectrum), + absl::MakeConstSpan(second_log_spectrum), 10.0)); +} + +TEST(ExpectLogSpectralDistanceBelowThreshold, AboveThresholdFails) { + std::vector first_log_spectrum(10); + std::iota(first_log_spectrum.begin(), first_log_spectrum.end(), 0); + std::vector second_log_spectrum(10); + std::iota(second_log_spectrum.begin(), second_log_spectrum.end(), 1); + EXPECT_FALSE(IsLogSpectralDistanceBelowThreshold( + absl::MakeConstSpan(first_log_spectrum), + absl::MakeConstSpan(second_log_spectrum), 9.0)); +} + } // namespace } // namespace iamf_tools