diff options
author | Henrik Andreassson <henrika@webrtc.org> | 2019-08-16 10:40:01 +0000 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-08-16 10:40:11 +0000 |
commit | 533c225c939a33bb46eb25ba7a36f4ecb0b40704 (patch) | |
tree | bc5703c62340d7a58b3b022c8ad12f8754b81596 /common_audio | |
parent | 07a665286519458fb6d4ac8199eaa60905702413 (diff) | |
download | webrtc-533c225c939a33bb46eb25ba7a36f4ecb0b40704.tar.gz |
Revert "Correct conversion between float and fixed formats"
This reverts commit 67e43c8b95057a889ba9946e47d50a265e1e9ac9.
Reason for revert: speculative revert since we see failing bots on Android after this change
https://ci.chromium.org/p/chromium/builders/webrtc.fyi/WebRTC%20Chromium%20FYI%20Android%20Tests%20%28dbg%29%20%28K%20Nexus5%29/4124
Original change's description:
> Correct conversion between float and fixed formats
>
> This CL changes the way that values are converted
> between fixed and floating point to
> -Avoid the former asymmetric conversion causing
> nonlinear distortions.
> -Reduce the complexity.
>
> Bug: webrtc:6594
> Change-Id: I64d0cc31c5d16f397686a59a062cfbc4b336d94d
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132783
> Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
> Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
> Commit-Queue: Per Ã…hgren <peah@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28867}
TBR=henrik.lundin@webrtc.org,gustaf@webrtc.org,peah@webrtc.org
Change-Id: Id828a09de7075e48556fe2d0beba7a0c6ec227f6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:6594
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/149165
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Commit-Queue: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28872}
Diffstat (limited to 'common_audio')
-rw-r--r-- | common_audio/audio_util.cc | 5 | ||||
-rw-r--r-- | common_audio/audio_util_unittest.cc | 41 | ||||
-rw-r--r-- | common_audio/include/audio_util.h | 36 | ||||
-rw-r--r-- | common_audio/resampler/push_sinc_resampler_unittest.cc | 18 |
4 files changed, 61 insertions, 39 deletions
diff --git a/common_audio/audio_util.cc b/common_audio/audio_util.cc index eb132ca633..735ba5f188 100644 --- a/common_audio/audio_util.cc +++ b/common_audio/audio_util.cc @@ -12,6 +12,11 @@ namespace webrtc { +void FloatToS16(const float* src, size_t size, int16_t* dest) { + for (size_t i = 0; i < size; ++i) + dest[i] = FloatToS16(src[i]); +} + void S16ToFloat(const int16_t* src, size_t size, float* dest) { for (size_t i = 0; i < size; ++i) dest[i] = S16ToFloat(src[i]); diff --git a/common_audio/audio_util_unittest.cc b/common_audio/audio_util_unittest.cc index a215a123b1..cf85a2d46c 100644 --- a/common_audio/audio_util_unittest.cc +++ b/common_audio/audio_util_unittest.cc @@ -31,6 +31,25 @@ void ExpectArraysEq(const float* ref, const float* test, size_t length) { } } +TEST(AudioUtilTest, FloatToS16) { + static constexpr float kInput[] = {0.f, + 0.4f / 32767.f, + 0.6f / 32767.f, + -0.4f / 32768.f, + -0.6f / 32768.f, + 1.f, + -1.f, + 1.1f, + -1.1f}; + static constexpr int16_t kReference[] = {0, 0, 1, 0, -1, + 32767, -32768, 32767, -32768}; + static constexpr size_t kSize = arraysize(kInput); + static_assert(arraysize(kReference) == kSize, ""); + int16_t output[kSize]; + FloatToS16(kInput, kSize, output); + ExpectArraysEq(kReference, output, kSize); +} + TEST(AudioUtilTest, S16ToFloat) { static constexpr int16_t kInput[] = {0, 1, -1, 16384, -16384, 32767, -32768}; static constexpr float kReference[] = { @@ -55,16 +74,16 @@ TEST(AudioUtilTest, FloatS16ToS16) { TEST(AudioUtilTest, FloatToFloatS16) { static constexpr float kInput[] = {0.f, - 0.4f / 32768.f, - 0.6f / 32768.f, + 0.4f / 32767.f, + 0.6f / 32767.f, -0.4f / 32768.f, -0.6f / 32768.f, 1.f, -1.f, - 1.f, - -1.f}; + 1.1f, + -1.1f}; static constexpr float kReference[] = { - 0.f, 0.4f, 0.6f, -0.4f, -0.6f, 32768.f, -32768.f, 32768.f, -32768.f}; + 0.f, 0.4f, 0.6f, -0.4f, -0.6f, 32767.f, -32768.f, 36043.7f, -36044.8f}; static constexpr size_t kSize = arraysize(kInput); static_assert(arraysize(kReference) == kSize, ""); float output[kSize]; @@ -73,17 +92,17 @@ TEST(AudioUtilTest, FloatToFloatS16) { } TEST(AudioUtilTest, FloatS16ToFloat) { - static constexpr float kInput[] = {0.f, 0.4f, 0.6f, -0.4f, -0.6f, - 32767.f, -32768.f, 32767.f, -32768.f}; + static constexpr float kInput[] = { + 0.f, 0.4f, 0.6f, -0.4f, -0.6f, 32767.f, -32768.f, 36043.7f, -36044.8f}; static constexpr float kReference[] = {0.f, - 0.4f / 32768.f, - 0.6f / 32768.f, + 0.4f / 32767.f, + 0.6f / 32767.f, -0.4f / 32768.f, -0.6f / 32768.f, 1.f, -1.f, - 1.f, - -1.f}; + 1.1f, + -1.1f}; static constexpr size_t kSize = arraysize(kInput); static_assert(arraysize(kReference) == kSize, ""); float output[kSize]; diff --git a/common_audio/include/audio_util.h b/common_audio/include/audio_util.h index 255abcc0f7..50c9cf282c 100644 --- a/common_audio/include/audio_util.h +++ b/common_audio/include/audio_util.h @@ -27,35 +27,45 @@ typedef std::numeric_limits<int16_t> limits_int16; // The conversion functions use the following naming convention: // S16: int16_t [-32768, 32767] // Float: float [-1.0, 1.0] -// FloatS16: float [-32768.0, 32768.0] +// FloatS16: float [-32768.0, 32767.0] // Dbfs: float [-20.0*log(10, 32768), 0] = [-90.3, 0] // The ratio conversion functions use this naming convention: // Ratio: float (0, +inf) // Db: float (-inf, +inf) +static inline int16_t FloatToS16(float v) { + if (v > 0) + return v >= 1 ? limits_int16::max() + : static_cast<int16_t>(v * limits_int16::max() + 0.5f); + return v <= -1 ? limits_int16::min() + : static_cast<int16_t>(-v * limits_int16::min() - 0.5f); +} + static inline float S16ToFloat(int16_t v) { - constexpr float kScaling = 1.f / 32768.f; - return v * kScaling; + static const float kMaxInt16Inverse = 1.f / limits_int16::max(); + static const float kMinInt16Inverse = 1.f / limits_int16::min(); + return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse); } static inline int16_t FloatS16ToS16(float v) { - v = std::min(v, 32767.f); - v = std::max(v, -32768.f); - return static_cast<int16_t>(v + std::copysign(0.5f, v)); + static const float kMaxRound = limits_int16::max() - 0.5f; + static const float kMinRound = limits_int16::min() + 0.5f; + if (v > 0) + return v >= kMaxRound ? limits_int16::max() + : static_cast<int16_t>(v + 0.5f); + return v <= kMinRound ? limits_int16::min() : static_cast<int16_t>(v - 0.5f); } static inline float FloatToFloatS16(float v) { - RTC_DCHECK_LE(v, 1.f); - RTC_DCHECK_GE(v, -1.f); - return v * 32768.f; + return v * (v > 0 ? limits_int16::max() : -limits_int16::min()); } static inline float FloatS16ToFloat(float v) { - RTC_DCHECK_LE(v, 32768.f); - RTC_DCHECK_GE(v, -32768.f); - constexpr float kScaling = 1.f / 32768.f; - return v * kScaling; + static const float kMaxInt16Inverse = 1.f / limits_int16::max(); + static const float kMinInt16Inverse = 1.f / limits_int16::min(); + return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse); } +void FloatToS16(const float* src, size_t size, int16_t* dest); void S16ToFloat(const int16_t* src, size_t size, float* dest); void FloatS16ToS16(const float* src, size_t size, int16_t* dest); void FloatToFloatS16(const float* src, size_t size, float* dest); diff --git a/common_audio/resampler/push_sinc_resampler_unittest.cc b/common_audio/resampler/push_sinc_resampler_unittest.cc index f9943b3cc8..1a25a8c3e8 100644 --- a/common_audio/resampler/push_sinc_resampler_unittest.cc +++ b/common_audio/resampler/push_sinc_resampler_unittest.cc @@ -33,18 +33,6 @@ T DBFS(T x) { return 20 * std::log10(x); } -void FloatToS16(const float* src, size_t size, int16_t* dest) { - for (size_t i = 0; i < size; ++i) { - RTC_DCHECK_GE(32767.f, src[i]); - RTC_DCHECK_LE(-32768.f, src[i]); - if (src[i] >= 1.f) - dest[i] = 32767; - if (src[i] <= -1.f) - dest[i] = -32768; - dest[i] = static_cast<int16_t>(src[i] * 32767.5f); - } -} - } // namespace class PushSincResamplerTest : public ::testing::TestWithParam< @@ -334,14 +322,14 @@ INSTANTIATE_TEST_SUITE_P( ::testing::make_tuple(32000, 16000, -18.48, -28.59), ::testing::make_tuple(44100, 16000, -19.30, -19.67), ::testing::make_tuple(48000, 16000, -19.81, -18.11), - ::testing::make_tuple(96000, 16000, -20.95, -10.9596), + ::testing::make_tuple(96000, 16000, -20.95, -10.96), // To 32 kHz ::testing::make_tuple(8000, 32000, kResamplingRMSError, -70.30), ::testing::make_tuple(16000, 32000, kResamplingRMSError, -75.51), ::testing::make_tuple(32000, 32000, kResamplingRMSError, -75.51), - ::testing::make_tuple(44100, 32000, -16.44, -51.0349), - ::testing::make_tuple(48000, 32000, -16.90, -43.9967), + ::testing::make_tuple(44100, 32000, -16.44, -51.10), + ::testing::make_tuple(48000, 32000, -16.90, -44.03), ::testing::make_tuple(96000, 32000, -19.61, -18.04), ::testing::make_tuple(192000, 32000, -21.02, -10.94))); |