mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-19 08:37:54 +01:00

The FrameCombiner sub-module of the AudioMixer uses one of two limiters. One is an AudioProcessingModule with AGC1 enabled and configured as a limiter. The other is the limiter part of AGC2. This change removes the APM-AGC1 limiter. This requires small changes to FrameCombiner, AudioMixerImpl and tests. We also stop using the finch experiment flag. Bug: webrtc:8925 Change-Id: Id7b8349ec4720b6417b15eaf70ed1a850b6ddbed Reviewed-on: https://webrtc-review.googlesource.com/84620 Reviewed-by: Sam Zackrisson <saza@webrtc.org> Commit-Queue: Alex Loiko <aleloi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23727}
174 lines
5.5 KiB
C++
174 lines
5.5 KiB
C++
/*
|
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "api/audio/audio_mixer.h"
|
|
#include "common_audio/wav_file.h"
|
|
#include "modules/audio_mixer/audio_mixer_impl.h"
|
|
#include "modules/audio_mixer/default_output_rate_calculator.h"
|
|
#include "rtc_base/flags.h"
|
|
|
|
DEFINE_bool(help, false, "Prints this message");
|
|
DEFINE_int(sampling_rate,
|
|
16000,
|
|
"Rate at which to mix (all input streams must have this rate)");
|
|
|
|
DEFINE_bool(
|
|
stereo,
|
|
false,
|
|
"Enable stereo (interleaved). Inputs need not be as this parameter.");
|
|
|
|
DEFINE_bool(limiter, true, "Enable limiter.");
|
|
DEFINE_string(output_file,
|
|
"mixed_file.wav",
|
|
"File in which to store the mixed result.");
|
|
DEFINE_string(input_file_1, "", "First input. Default none.");
|
|
DEFINE_string(input_file_2, "", "Second input. Default none.");
|
|
DEFINE_string(input_file_3, "", "Third input. Default none.");
|
|
DEFINE_string(input_file_4, "", "Fourth input. Default none.");
|
|
|
|
namespace webrtc {
|
|
namespace test {
|
|
|
|
class FilePlayingSource : public AudioMixer::Source {
|
|
public:
|
|
explicit FilePlayingSource(std::string filename)
|
|
: wav_reader_(new WavReader(filename)),
|
|
sample_rate_hz_(wav_reader_->sample_rate()),
|
|
samples_per_channel_(sample_rate_hz_ / 100),
|
|
number_of_channels_(wav_reader_->num_channels()) {}
|
|
|
|
AudioFrameInfo GetAudioFrameWithInfo(int target_rate_hz,
|
|
AudioFrame* frame) override {
|
|
frame->samples_per_channel_ = samples_per_channel_;
|
|
frame->num_channels_ = number_of_channels_;
|
|
frame->sample_rate_hz_ = target_rate_hz;
|
|
|
|
RTC_CHECK_EQ(target_rate_hz, sample_rate_hz_);
|
|
|
|
const size_t num_to_read = number_of_channels_ * samples_per_channel_;
|
|
const size_t num_read =
|
|
wav_reader_->ReadSamples(num_to_read, frame->mutable_data());
|
|
|
|
file_has_ended_ = num_to_read != num_read;
|
|
if (file_has_ended_) {
|
|
frame->Mute();
|
|
}
|
|
return file_has_ended_ ? AudioFrameInfo::kMuted : AudioFrameInfo::kNormal;
|
|
}
|
|
|
|
int Ssrc() const override { return 0; }
|
|
|
|
int PreferredSampleRate() const override { return sample_rate_hz_; }
|
|
|
|
bool FileHasEnded() const { return file_has_ended_; }
|
|
|
|
std::string ToString() const {
|
|
std::stringstream ss;
|
|
ss << "{rate: " << sample_rate_hz_ << ", channels: " << number_of_channels_
|
|
<< ", samples_tot: " << wav_reader_->num_samples() << "}";
|
|
return ss.str();
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<WavReader> wav_reader_;
|
|
int sample_rate_hz_;
|
|
int samples_per_channel_;
|
|
int number_of_channels_;
|
|
bool file_has_ended_ = false;
|
|
};
|
|
} // namespace test
|
|
} // namespace webrtc
|
|
|
|
namespace {
|
|
|
|
const std::vector<std::string> parse_input_files() {
|
|
std::vector<std::string> result;
|
|
for (auto* x : {FLAG_input_file_1, FLAG_input_file_2, FLAG_input_file_3,
|
|
FLAG_input_file_4}) {
|
|
if (strcmp(x, "") != 0) {
|
|
result.push_back(x);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
} // namespace
|
|
|
|
int main(int argc, char* argv[]) {
|
|
rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, false);
|
|
if (FLAG_help) {
|
|
rtc::FlagList::Print(nullptr, false);
|
|
return 0;
|
|
}
|
|
|
|
rtc::scoped_refptr<webrtc::AudioMixerImpl> mixer(
|
|
webrtc::AudioMixerImpl::Create(
|
|
std::unique_ptr<webrtc::OutputRateCalculator>(
|
|
new webrtc::DefaultOutputRateCalculator()),
|
|
FLAG_limiter));
|
|
|
|
const std::vector<std::string> input_files = parse_input_files();
|
|
std::vector<webrtc::test::FilePlayingSource> sources;
|
|
const int num_channels = FLAG_stereo ? 2 : 1;
|
|
for (auto input_file : input_files) {
|
|
sources.emplace_back(input_file);
|
|
}
|
|
|
|
for (auto& source : sources) {
|
|
auto error = mixer->AddSource(&source);
|
|
RTC_CHECK(error);
|
|
}
|
|
|
|
if (sources.empty()) {
|
|
std::cout << "Need at least one source!\n";
|
|
rtc::FlagList::Print(nullptr, false);
|
|
return 1;
|
|
}
|
|
|
|
const size_t sample_rate = sources[0].PreferredSampleRate();
|
|
for (const auto& source : sources) {
|
|
RTC_CHECK_EQ(sample_rate, source.PreferredSampleRate());
|
|
}
|
|
|
|
// Print stats.
|
|
std::cout << "Limiting is: " << (FLAG_limiter ? "on" : "off") << "\n"
|
|
<< "Channels: " << num_channels << "\n"
|
|
<< "Rate: " << sample_rate << "\n"
|
|
<< "Number of input streams: " << input_files.size() << "\n";
|
|
for (const auto& source : sources) {
|
|
std::cout << "\t" << source.ToString() << "\n";
|
|
}
|
|
std::cout << "Now mixing\n...\n";
|
|
|
|
webrtc::WavWriter wav_writer(FLAG_output_file, sample_rate, num_channels);
|
|
|
|
webrtc::AudioFrame frame;
|
|
|
|
bool all_streams_finished = false;
|
|
while (!all_streams_finished) {
|
|
mixer->Mix(num_channels, &frame);
|
|
RTC_CHECK_EQ(sample_rate / 100, frame.samples_per_channel_);
|
|
RTC_CHECK_EQ(sample_rate, frame.sample_rate_hz_);
|
|
RTC_CHECK_EQ(num_channels, frame.num_channels_);
|
|
wav_writer.WriteSamples(frame.data(),
|
|
num_channels * frame.samples_per_channel_);
|
|
|
|
all_streams_finished =
|
|
std::all_of(sources.begin(), sources.end(),
|
|
[](const webrtc::test::FilePlayingSource& source) {
|
|
return source.FileHasEnded();
|
|
});
|
|
}
|
|
|
|
std::cout << "Done!\n" << std::endl;
|
|
}
|