Adding VoIP specific channel adjustments
This CL introduces a channel remapping for the mono input case that is more tailored to the VoIP usecase. The CL contains a kill-switch that can be used to fall back to the old mapping behavior in case a need for this is perceived. Bug: chromium:1027117 Change-Id: Idaaba6eac952e6436beaaf5a1a697cfab8f63286 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/160280 Commit-Queue: Per Åhgren <peah@webrtc.org> Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org> Reviewed-by: Sam Zackrisson <saza@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29877}
This commit is contained in:
parent
6031716473
commit
5b82ba37cc
@ -30,6 +30,7 @@ rtc_library("audio_frame_operations") {
|
|||||||
"../../rtc_base:checks",
|
"../../rtc_base:checks",
|
||||||
"../../rtc_base:deprecation",
|
"../../rtc_base:deprecation",
|
||||||
"../../rtc_base:rtc_base_approved",
|
"../../rtc_base:rtc_base_approved",
|
||||||
|
"../../system_wrappers:field_trial",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ if (rtc_include_tests) {
|
|||||||
"../../api/audio:audio_frame_api",
|
"../../api/audio:audio_frame_api",
|
||||||
"../../rtc_base:checks",
|
"../../rtc_base:checks",
|
||||||
"../../rtc_base:rtc_base_approved",
|
"../../rtc_base:rtc_base_approved",
|
||||||
|
"../../test:field_trial",
|
||||||
"../../test:test_support",
|
"../../test:test_support",
|
||||||
"//testing/gtest",
|
"//testing/gtest",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -17,9 +17,20 @@
|
|||||||
#include "audio/utility/channel_mixer.h"
|
#include "audio/utility/channel_mixer.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
#include "system_wrappers/include/field_trial.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Selects the default usage of VoIP channel mapping adjustments.
|
||||||
|
bool UseChannelMappingAdjustmentsByDefault() {
|
||||||
|
return !field_trial::IsEnabled(
|
||||||
|
"WebRTC-VoIPChannelRemixingAdjustmentKillSwitch");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static void ValidateLayout(ChannelLayout layout) {
|
static void ValidateLayout(ChannelLayout layout) {
|
||||||
RTC_CHECK_NE(layout, CHANNEL_LAYOUT_NONE);
|
RTC_CHECK_NE(layout, CHANNEL_LAYOUT_NONE);
|
||||||
RTC_CHECK_LE(layout, CHANNEL_LAYOUT_MAX);
|
RTC_CHECK_LE(layout, CHANNEL_LAYOUT_MAX);
|
||||||
@ -55,7 +66,9 @@ ChannelMixingMatrix::ChannelMixingMatrix(ChannelLayout input_layout,
|
|||||||
int input_channels,
|
int input_channels,
|
||||||
ChannelLayout output_layout,
|
ChannelLayout output_layout,
|
||||||
int output_channels)
|
int output_channels)
|
||||||
: input_layout_(input_layout),
|
: use_voip_channel_mapping_adjustments_(
|
||||||
|
UseChannelMappingAdjustmentsByDefault()),
|
||||||
|
input_layout_(input_layout),
|
||||||
input_channels_(input_channels),
|
input_channels_(input_channels),
|
||||||
output_layout_(output_layout),
|
output_layout_(output_layout),
|
||||||
output_channels_(output_channels) {
|
output_channels_(output_channels) {
|
||||||
@ -104,6 +117,20 @@ bool ChannelMixingMatrix::CreateTransformationMatrix(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If specified, use adjusted channel mapping for the VoIP scenario.
|
||||||
|
if (use_voip_channel_mapping_adjustments_ &&
|
||||||
|
input_layout_ == CHANNEL_LAYOUT_MONO &&
|
||||||
|
ChannelLayoutToChannelCount(output_layout_) >= 2) {
|
||||||
|
// Only place the mono input in the front left and right channels.
|
||||||
|
(*matrix_)[0][0] = 1.f;
|
||||||
|
(*matrix_)[1][0] = 1.f;
|
||||||
|
|
||||||
|
for (size_t output_ch = 2; output_ch < matrix_->size(); ++output_ch) {
|
||||||
|
(*matrix_)[output_ch][0] = 0.f;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Route matching channels and figure out which ones aren't accounted for.
|
// Route matching channels and figure out which ones aren't accounted for.
|
||||||
for (Channels ch = LEFT; ch < CHANNELS_MAX + 1;
|
for (Channels ch = LEFT; ch < CHANNELS_MAX + 1;
|
||||||
ch = static_cast<Channels>(ch + 1)) {
|
ch = static_cast<Channels>(ch + 1)) {
|
||||||
|
|||||||
@ -36,6 +36,8 @@ class ChannelMixingMatrix {
|
|||||||
bool CreateTransformationMatrix(std::vector<std::vector<float>>* matrix);
|
bool CreateTransformationMatrix(std::vector<std::vector<float>>* matrix);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const bool use_voip_channel_mapping_adjustments_;
|
||||||
|
|
||||||
// Result transformation of input channels to output channels
|
// Result transformation of input channels to output channels
|
||||||
std::vector<std::vector<float>>* matrix_;
|
std::vector<std::vector<float>>* matrix_;
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "rtc_base/arraysize.h"
|
#include "rtc_base/arraysize.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/strings/string_builder.h"
|
#include "rtc_base/strings/string_builder.h"
|
||||||
|
#include "test/field_trial.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -124,7 +125,9 @@ TEST(ChannelMixingMatrixTest, MonoToStereo) {
|
|||||||
EXPECT_EQ(1.0f, matrix[1][0]);
|
EXPECT_EQ(1.0f, matrix[1][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ChannelMixingMatrixTest, MonoToTwoOne) {
|
TEST(ChannelMixingMatrixTest, MonoToTwoOneWithoutVoIPAdjustments) {
|
||||||
|
test::ScopedFieldTrials field_trials(
|
||||||
|
"WebRTC-VoIPChannelRemixingAdjustmentKillSwitch/Enabled/");
|
||||||
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
||||||
ChannelLayout output_layout = CHANNEL_LAYOUT_2_1;
|
ChannelLayout output_layout = CHANNEL_LAYOUT_2_1;
|
||||||
ChannelMixingMatrix matrix_builder(
|
ChannelMixingMatrix matrix_builder(
|
||||||
@ -147,6 +150,157 @@ TEST(ChannelMixingMatrixTest, MonoToTwoOne) {
|
|||||||
EXPECT_EQ(0.0f, matrix[2][0]);
|
EXPECT_EQ(0.0f, matrix[2][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ChannelMixingMatrixTest, MonoToTwoOneWithVoIPAdjustments) {
|
||||||
|
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
||||||
|
ChannelLayout output_layout = CHANNEL_LAYOUT_2_1;
|
||||||
|
ChannelMixingMatrix matrix_builder(
|
||||||
|
input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
|
||||||
|
ChannelLayoutToChannelCount(output_layout));
|
||||||
|
std::vector<std::vector<float>> matrix;
|
||||||
|
bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
|
||||||
|
|
||||||
|
// Input: mono
|
||||||
|
// CENTER
|
||||||
|
// Output: 2.1 FRONT_LEFT 1
|
||||||
|
// FRONT_RIGHT 1
|
||||||
|
// BACK_CENTER 0
|
||||||
|
//
|
||||||
|
EXPECT_TRUE(remapping);
|
||||||
|
EXPECT_EQ(3u, matrix.size());
|
||||||
|
EXPECT_EQ(1u, matrix[0].size());
|
||||||
|
EXPECT_EQ(1.0f, matrix[0][0]);
|
||||||
|
EXPECT_EQ(1.0f, matrix[1][0]);
|
||||||
|
EXPECT_EQ(0.0f, matrix[2][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChannelMixingMatrixTest, MonoToFiveOneWithoutVoIPAdjustments) {
|
||||||
|
test::ScopedFieldTrials field_trials(
|
||||||
|
"WebRTC-VoIPChannelRemixingAdjustmentKillSwitch/Enabled/");
|
||||||
|
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
||||||
|
ChannelLayout output_layout = CHANNEL_LAYOUT_5_1;
|
||||||
|
const int input_channels = ChannelLayoutToChannelCount(input_layout);
|
||||||
|
const int output_channels = ChannelLayoutToChannelCount(output_layout);
|
||||||
|
ChannelMixingMatrix matrix_builder(input_layout, input_channels,
|
||||||
|
output_layout, output_channels);
|
||||||
|
std::vector<std::vector<float>> matrix;
|
||||||
|
bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
|
||||||
|
// Input: mono
|
||||||
|
// CENTER
|
||||||
|
// Output: 5.1 LEFT 0
|
||||||
|
// RIGHT 0
|
||||||
|
// CENTER 1
|
||||||
|
// LFE 0
|
||||||
|
// SIDE_LEFT 0
|
||||||
|
// SIDE_RIGHT 0
|
||||||
|
//
|
||||||
|
EXPECT_TRUE(remapping);
|
||||||
|
EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
|
||||||
|
for (int n = 0; n < output_channels; n++) {
|
||||||
|
EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
|
||||||
|
if (n == CENTER) {
|
||||||
|
EXPECT_EQ(1.0f, matrix[CENTER][0]);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(0.0f, matrix[n][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChannelMixingMatrixTest, MonoToFiveOneWithVoIPAdjustments) {
|
||||||
|
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
||||||
|
ChannelLayout output_layout = CHANNEL_LAYOUT_5_1;
|
||||||
|
const int input_channels = ChannelLayoutToChannelCount(input_layout);
|
||||||
|
const int output_channels = ChannelLayoutToChannelCount(output_layout);
|
||||||
|
ChannelMixingMatrix matrix_builder(input_layout, input_channels,
|
||||||
|
output_layout, output_channels);
|
||||||
|
std::vector<std::vector<float>> matrix;
|
||||||
|
bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
|
||||||
|
// Input: mono
|
||||||
|
// CENTER
|
||||||
|
// Output: 5.1 LEFT 1
|
||||||
|
// RIGHT 1
|
||||||
|
// CENTER 0
|
||||||
|
// LFE 0
|
||||||
|
// SIDE_LEFT 0
|
||||||
|
// SIDE_RIGHT 0
|
||||||
|
//
|
||||||
|
EXPECT_TRUE(remapping);
|
||||||
|
EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
|
||||||
|
for (int n = 0; n < output_channels; n++) {
|
||||||
|
EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
|
||||||
|
if (n == LEFT || n == RIGHT) {
|
||||||
|
EXPECT_EQ(1.0f, matrix[n][0]);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(0.0f, matrix[n][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChannelMixingMatrixTest, MonoToSevenOneWithoutVoIPAdjustments) {
|
||||||
|
test::ScopedFieldTrials field_trials(
|
||||||
|
"WebRTC-VoIPChannelRemixingAdjustmentKillSwitch/Enabled/");
|
||||||
|
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
||||||
|
ChannelLayout output_layout = CHANNEL_LAYOUT_7_1;
|
||||||
|
const int input_channels = ChannelLayoutToChannelCount(input_layout);
|
||||||
|
const int output_channels = ChannelLayoutToChannelCount(output_layout);
|
||||||
|
ChannelMixingMatrix matrix_builder(input_layout, input_channels,
|
||||||
|
output_layout, output_channels);
|
||||||
|
std::vector<std::vector<float>> matrix;
|
||||||
|
bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
|
||||||
|
// Input: mono
|
||||||
|
// CENTER
|
||||||
|
// Output: 7.1 LEFT 0
|
||||||
|
// RIGHT 0
|
||||||
|
// CENTER 1
|
||||||
|
// LFE 0
|
||||||
|
// SIDE_LEFT 0
|
||||||
|
// SIDE_RIGHT 0
|
||||||
|
// BACK_LEFT 0
|
||||||
|
// BACK_RIGHT 0
|
||||||
|
//
|
||||||
|
EXPECT_TRUE(remapping);
|
||||||
|
EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
|
||||||
|
for (int n = 0; n < output_channels; n++) {
|
||||||
|
EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
|
||||||
|
if (n == CENTER) {
|
||||||
|
EXPECT_EQ(1.0f, matrix[CENTER][0]);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(0.0f, matrix[n][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChannelMixingMatrixTest, MonoToSevenOneWithVoIPAdjustments) {
|
||||||
|
ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
|
||||||
|
ChannelLayout output_layout = CHANNEL_LAYOUT_7_1;
|
||||||
|
const int input_channels = ChannelLayoutToChannelCount(input_layout);
|
||||||
|
const int output_channels = ChannelLayoutToChannelCount(output_layout);
|
||||||
|
ChannelMixingMatrix matrix_builder(input_layout, input_channels,
|
||||||
|
output_layout, output_channels);
|
||||||
|
std::vector<std::vector<float>> matrix;
|
||||||
|
bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
|
||||||
|
// Input: mono
|
||||||
|
// CENTER
|
||||||
|
// Output: 7.1 LEFT 1
|
||||||
|
// RIGHT 1
|
||||||
|
// CENTER 0
|
||||||
|
// LFE 0
|
||||||
|
// SIDE_LEFT 0
|
||||||
|
// SIDE_RIGHT 0
|
||||||
|
// BACK_LEFT 0
|
||||||
|
// BACK_RIGHT 0
|
||||||
|
//
|
||||||
|
EXPECT_TRUE(remapping);
|
||||||
|
EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
|
||||||
|
for (int n = 0; n < output_channels; n++) {
|
||||||
|
EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
|
||||||
|
if (n == LEFT || n == RIGHT) {
|
||||||
|
EXPECT_EQ(1.0f, matrix[n][0]);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(0.0f, matrix[n][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ChannelMixingMatrixTest, FiveOneToMono) {
|
TEST(ChannelMixingMatrixTest, FiveOneToMono) {
|
||||||
ChannelLayout input_layout = CHANNEL_LAYOUT_5_1;
|
ChannelLayout input_layout = CHANNEL_LAYOUT_5_1;
|
||||||
ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
|
ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user