aboutsummaryrefslogtreecommitdiff
path: root/common_audio
diff options
context:
space:
mode:
authorHenrik Andreassson <henrika@webrtc.org>2019-08-16 10:40:01 +0000
committerCommit Bot <commit-bot@chromium.org>2019-08-16 10:40:11 +0000
commit533c225c939a33bb46eb25ba7a36f4ecb0b40704 (patch)
treebc5703c62340d7a58b3b022c8ad12f8754b81596 /common_audio
parent07a665286519458fb6d4ac8199eaa60905702413 (diff)
downloadwebrtc-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.cc5
-rw-r--r--common_audio/audio_util_unittest.cc41
-rw-r--r--common_audio/include/audio_util.h36
-rw-r--r--common_audio/resampler/push_sinc_resampler_unittest.cc18
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)));