diff options
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.cc | 182 |
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; +} |