From 9f2c18e237593b5f8cbc7d7a3838ab6596123c53 Mon Sep 17 00:00:00 2001 From: soren Date: Mon, 10 Apr 2017 02:22:46 -0700 Subject: [PATCH] Changed OLA window for neteq. Old code didnt work well with 48khz fixing white spaces updated authors file Changed OLA window to use Q14 as Q5 dosnt work with 48khz. 1 ms @ 48 khz is > 2^5 BUG=webrtc:1361 Review-Url: https://codereview.webrtc.org/2763273003 Cr-Commit-Position: refs/heads/master@{#17611} --- AUTHORS | 1 + .../acm2/audio_coding_module_unittest.cc | 50 +++++++-------- .../audio_coding/neteq/neteq_unittest.cc | 16 ++--- webrtc/modules/audio_coding/neteq/normal.cc | 61 +++++++++++-------- webrtc/modules/audio_coding/neteq/normal.h | 13 +++- 5 files changed, 80 insertions(+), 61 deletions(-) diff --git a/AUTHORS b/AUTHORS index 32cff7bd7a..41dfc8a391 100644 --- a/AUTHORS +++ b/AUTHORS @@ -65,3 +65,4 @@ The Chromium Authors <*@chromium.org> The WebRTC Authors <*@webrtc.org> Wire Swiss GmbH <*@wire.com> Vonage Holdings Corp. <*@vonage.com> +Wire Swiss GmbH <*@wire.com> diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc index 98569a6aeb..58e7b6960c 100644 --- a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc @@ -979,31 +979,31 @@ class AcmReceiverBitExactnessOldApi : public ::testing::Test { #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) && \ defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) TEST_F(AcmReceiverBitExactnessOldApi, 8kHzOutput) { - Run(8000, PlatformChecksum("25cda36a1b967e75c0eb580924247681", - "bbfe6a07f8bca872b5370885825ee061", - "d5b9ae44d03dbd7c921dd9c228e03cc5", - "4d851d1f2e4b8a2f1727fac8fba4b1e1")); + Run(8000, PlatformChecksum("2adede965c6f87de7142c51552111d08", + "028c0fc414b1c9ab7e582dccdf381e98", + "36c95170c1393d4b765d1c17b61ef977", + "4598140b5e4f7ee66c5adad609e65a3e")); } TEST_F(AcmReceiverBitExactnessOldApi, 16kHzOutput) { - Run(16000, PlatformChecksum("9c7b6f586c4b9d6d0195372660991353", - "1ab45baa674e681ec394e0d3824d8605", - "dd4e7f2521b5f47c0016b12f06c08695", - "5401b64b6dbe7f090f846e89b0d858ce")); + Run(16000, PlatformChecksum("c2550a3db7632de409e8db0093df1c12", + "edd31f4b6665cd5b9041fb93f2316594", + "22128bca51650cb61c80bed63b595603", + "f2aad418af974a3b1694d5ae5cc2c3c7")); } TEST_F(AcmReceiverBitExactnessOldApi, 32kHzOutput) { - Run(32000, PlatformChecksum("599b9484ca89615641ebd767cccb149f", - "9f7d51569647eff38026dd815d43ca91", - "78d00d2a3f8f307fc3835ca588a18f3a", - "d335eebc72f4d087aa397a9cf8f4967b")); + Run(32000, PlatformChecksum("85e28d7950132d56f90b099c90f82153", + "7b903f5c89997f271b405e63c245ef45", + "8b8fc6c6fd1dcdcfb3dd90e1ce597f10", + "100869c8dcde51346c2073e52a272d98")); } TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutput) { - Run(48000, PlatformChecksum("5d3b4357c9044264bb4a601b6548bd55", - "8607778183d7ad02b8ce37eeeba4f37c", - "fd71398d336b88cbd4fb5002846e91c6", - "8ce7e0e1c381d920ee7b57751b257de8")); + Run(48000, PlatformChecksum("ab611510e8fd6d5210a23cc04d3f0e8e", + "d8609bc9b495d81f29779344c68bcc47", + "ec5ebb90cda0ea5bb89e79d698af65de", + "bd44bf97e7899186532f91235cef444d")); } TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) { @@ -1083,10 +1083,10 @@ TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) { rtc::scoped_refptr> factory( new rtc::RefCountedObject); - Run(48000, PlatformChecksum("5d3b4357c9044264bb4a601b6548bd55", - "8607778183d7ad02b8ce37eeeba4f37c", - "fd71398d336b88cbd4fb5002846e91c6", - "8ce7e0e1c381d920ee7b57751b257de8"), + Run(48000, PlatformChecksum("ab611510e8fd6d5210a23cc04d3f0e8e", + "d8609bc9b495d81f29779344c68bcc47", + "ec5ebb90cda0ea5bb89e79d698af65de", + "bd44bf97e7899186532f91235cef444d"), factory, [](AudioCodingModule* acm) { acm->RegisterReceiveCodec(0, {"MockPCMu", 8000, 1}); }); @@ -1273,10 +1273,10 @@ class AcmSenderBitExactnessNewApi : public AcmSenderBitExactnessOldApi {}; TEST_F(AcmSenderBitExactnessOldApi, IsacWb30ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 480, 480)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "0b58f9eeee43d5891f5f6c75e77984a3", - "c7e5bdadfa2871df95639fcc297cf23d", - "0499ca260390769b3172136faad925b9", - "866abf524acd2807efbe65e133c23f95"), + "2c9cb15d4ed55b5a0cadd04883bc73b0", + "9336a9b993cbd8a751f0e8958e66c89c", + "bd4682225f7c4ad5f2049f6769713ac2", + "343f1f42be0607c61e6516aece424609"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "3c79f16f34218271f3dca4e2b1dfe1bb", "d42cb5195463da26c8129bbfe73a22e6", @@ -1290,7 +1290,7 @@ TEST_F(AcmSenderBitExactnessOldApi, IsacWb60ms) { Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( "1ad29139a04782a33daad8c2b9b35875", "14d63c5f08127d280e722e3191b73bdd", - "8da003e16c5371af2dc2be79a50f9076", + "edcf26694c289e3d9691faf79b74f09f", "ef75e900e6f375e3061163c53fd09a63"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "9e0a0ab743ad987b55b8e14802769c56", diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc index 47073fb945..33b4005293 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc @@ -443,10 +443,10 @@ TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) { webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"); const std::string output_checksum = PlatformChecksum( - "5a8184bc60c0d7dddb50af8966360675476a8d8b", - "be982d2c5685dd1ca4ea5d352283df50e8e5b46d", - "5a8184bc60c0d7dddb50af8966360675476a8d8b", - "c86aec95439748f4949de95b50c94be291118615"); + "09fa7646e2ad032a0b156177b95f09012430f81f", + "1c64eb8b55ce8878676c6a1e6ddd78f48de0668b", + "09fa7646e2ad032a0b156177b95f09012430f81f", + "759fef89a5de52bd17e733dc255c671ce86be909"); const std::string network_stats_checksum = PlatformChecksum( "f59b3dfdb9b1b8bbb61abedd7c8cf3fc47c21f5f", @@ -480,10 +480,10 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) { webrtc::test::ResourcePath("audio_coding/neteq_opus", "rtp"); const std::string output_checksum = PlatformChecksum( - "9d7d52bc94e941d106aa518f324f16a58d231586", - "9d7d52bc94e941d106aa518f324f16a58d231586", - "9d7d52bc94e941d106aa518f324f16a58d231586", - "9d7d52bc94e941d106aa518f324f16a58d231586"); + "6237dd113ad80d7764fe4c90b55b2ec035eae64e", + "6237dd113ad80d7764fe4c90b55b2ec035eae64e", + "6237dd113ad80d7764fe4c90b55b2ec035eae64e", + "6237dd113ad80d7764fe4c90b55b2ec035eae64e"); const std::string network_stats_checksum = PlatformChecksum( "d8379381d5a619f0616bb3c0a8a9eea1704a8ab8", diff --git a/webrtc/modules/audio_coding/neteq/normal.cc b/webrtc/modules/audio_coding/neteq/normal.cc index 3dee39a8bc..1a7bc68033 100644 --- a/webrtc/modules/audio_coding/neteq/normal.cc +++ b/webrtc/modules/audio_coding/neteq/normal.cc @@ -130,23 +130,25 @@ int Normal::Process(const int16_t* input, // Interpolate the expanded data into the new vector. // (NB/WB/SWB32/SWB48 8/16/32/48 samples.) - RTC_DCHECK_LT(fs_shift, 3); // Will always be 0, 1, or, 2. - increment = 4 >> fs_shift; - int fraction = increment; - // Don't interpolate over more samples than what is in output. When this - // cap strikes, the interpolation will likely sound worse, but this is an - // emergency operation in response to unexpected input. - const size_t interp_len_samples = - std::min(static_cast(8 * fs_mult), output->Size()); - for (size_t i = 0; i < interp_len_samples; ++i) { - // TODO(hlundin): Add 16 instead of 8 for correct rounding. Keeping 8 - // now for legacy bit-exactness. - RTC_DCHECK_LT(channel_ix, output->Channels()); - RTC_DCHECK_LT(i, output->Size()); + size_t win_length = samples_per_ms_; + int16_t win_slope_Q14 = default_win_slope_Q14_; + RTC_DCHECK_LT(channel_ix, output->Channels()); + if (win_length > output->Size()) { + win_length = output->Size(); + win_slope_Q14 = (1 << 14) / static_cast(win_length); + } + int16_t win_up_Q14 = 0; + for (size_t i = 0; i < win_length; i++) { + win_up_Q14 += win_slope_Q14; (*output)[channel_ix][i] = - static_cast((fraction * (*output)[channel_ix][i] + - (32 - fraction) * expanded[channel_ix][i] + 8) >> 5); - fraction += increment; + (win_up_Q14 * (*output)[channel_ix][i] + + ((1 << 14) - win_up_Q14) * expanded[channel_ix][i] + (1 << 13)) >> + 14; + } + if (fs_hz_ == 48000) { + RTC_DCHECK_EQ(win_up_Q14, (1 << 14) - 16); + } else { + RTC_DCHECK_EQ(win_up_Q14, 1 << 14); } } } else if (last_mode == kModeRfc3389Cng) { @@ -171,15 +173,24 @@ int Normal::Process(const int16_t* input, } // Interpolate the CNG into the new vector. // (NB/WB/SWB32/SWB48 8/16/32/48 samples.) - RTC_DCHECK_LT(fs_shift, 3); // Will always be 0, 1, or, 2. - int16_t increment = 4 >> fs_shift; - int16_t fraction = increment; - for (size_t i = 0; i < static_cast(8 * fs_mult); i++) { - // TODO(hlundin): Add 16 instead of 8 for correct rounding. Keeping 8 now - // for legacy bit-exactness. - (*output)[0][i] = (fraction * (*output)[0][i] + - (32 - fraction) * cng_output[i] + 8) >> 5; - fraction += increment; + size_t win_length = samples_per_ms_; + int16_t win_slope_Q14 = default_win_slope_Q14_; + if (win_length > kCngLength) { + win_length = kCngLength; + win_slope_Q14 = (1 << 14) / static_cast(win_length); + } + int16_t win_up_Q14 = 0; + for (size_t i = 0; i < win_length; i++) { + win_up_Q14 += win_slope_Q14; + (*output)[0][i] = + (win_up_Q14 * (*output)[0][i] + + ((1 << 14) - win_up_Q14) * cng_output[i] + (1 << 13)) >> + 14; + } + if (fs_hz_ == 48000) { + RTC_DCHECK_EQ(win_up_Q14, (1 << 14) - 16); + } else { + RTC_DCHECK_EQ(win_up_Q14, 1 << 14); } } else if (external_mute_factor_array[0] < 16384) { // Previous was neither of Expand, FadeToBGN or RFC3389_CNG, but we are diff --git a/webrtc/modules/audio_coding/neteq/normal.h b/webrtc/modules/audio_coding/neteq/normal.h index 23887f5134..019bcf8b14 100644 --- a/webrtc/modules/audio_coding/neteq/normal.h +++ b/webrtc/modules/audio_coding/neteq/normal.h @@ -15,7 +15,9 @@ #include +#include "webrtc/base/checks.h" #include "webrtc/base/constructormagic.h" +#include "webrtc/base/safe_conversions.h" #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h" #include "webrtc/modules/audio_coding/neteq/defines.h" #include "webrtc/typedefs.h" @@ -32,14 +34,17 @@ class Expand; // no other "special circumstances" are at hand. class Normal { public: - Normal(int fs_hz, DecoderDatabase* decoder_database, + Normal(int fs_hz, + DecoderDatabase* decoder_database, const BackgroundNoise& background_noise, Expand* expand) : fs_hz_(fs_hz), decoder_database_(decoder_database), background_noise_(background_noise), - expand_(expand) { - } + expand_(expand), + samples_per_ms_(rtc::CheckedDivExact(fs_hz_, 1000)), + default_win_slope_Q14_( + rtc::dchecked_cast((1 << 14) / samples_per_ms_)) {} virtual ~Normal() {} @@ -60,6 +65,8 @@ class Normal { DecoderDatabase* decoder_database_; const BackgroundNoise& background_noise_; Expand* expand_; + const size_t samples_per_ms_; + const int16_t default_win_slope_Q14_; RTC_DISALLOW_COPY_AND_ASSIGN(Normal); };