summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/audio_mixer/audio_mixer_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/audio_mixer/audio_mixer_test.cc')
-rw-r--r--third_party/libwebrtc/modules/audio_mixer/audio_mixer_test.cc182
1 files changed, 182 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_test.cc b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_test.cc
new file mode 100644
index 0000000000..3ee28a7937
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_test.cc
@@ -0,0 +1,182 @@
+/*
+ * 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 "api/audio/audio_mixer.h"
+
+#include <cstring>
+#include <iostream>
+#include <vector>
+
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.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/strings/string_builder.h"
+
+ABSL_FLAG(int,
+ sampling_rate,
+ 16000,
+ "Rate at which to mix (all input streams must have this rate)");
+
+ABSL_FLAG(bool,
+ stereo,
+ false,
+ "Enable stereo (interleaved). Inputs need not be as this parameter.");
+
+ABSL_FLAG(bool, limiter, true, "Enable limiter.");
+ABSL_FLAG(std::string,
+ output_file,
+ "mixed_file.wav",
+ "File in which to store the mixed result.");
+ABSL_FLAG(std::string, input_file_1, "", "First input. Default none.");
+ABSL_FLAG(std::string, input_file_2, "", "Second input. Default none.");
+ABSL_FLAG(std::string, input_file_3, "", "Third input. Default none.");
+ABSL_FLAG(std::string, input_file_4, "", "Fourth input. Default none.");
+
+namespace webrtc {
+namespace test {
+
+class FilePlayingSource : public AudioMixer::Source {
+ public:
+ explicit FilePlayingSource(absl::string_view 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 {
+ rtc::StringBuilder ss;
+ ss << "{rate: " << sample_rate_hz_ << ", channels: " << number_of_channels_
+ << ", samples_tot: " << wav_reader_->num_samples() << "}";
+ return ss.Release();
+ }
+
+ 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 :
+ {absl::GetFlag(FLAGS_input_file_1), absl::GetFlag(FLAGS_input_file_2),
+ absl::GetFlag(FLAGS_input_file_3), absl::GetFlag(FLAGS_input_file_4)}) {
+ if (!x.empty()) {
+ result.push_back(x);
+ }
+ }
+ return result;
+}
+} // namespace
+
+int main(int argc, char* argv[]) {
+ absl::ParseCommandLine(argc, argv);
+
+ rtc::scoped_refptr<webrtc::AudioMixerImpl> mixer(
+ webrtc::AudioMixerImpl::Create(
+ std::unique_ptr<webrtc::OutputRateCalculator>(
+ new webrtc::DefaultOutputRateCalculator()),
+ absl::GetFlag(FLAGS_limiter)));
+
+ const std::vector<std::string> input_files = parse_input_files();
+ std::vector<webrtc::test::FilePlayingSource> sources;
+ const int num_channels = absl::GetFlag(FLAGS_stereo) ? 2 : 1;
+ sources.reserve(input_files.size());
+ for (const 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";
+ 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: " << (absl::GetFlag(FLAGS_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(absl::GetFlag(FLAGS_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;
+}