tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_mixer_test.cc (6101B)


      1 /*
      2 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "api/audio/audio_mixer.h"
     12 
     13 #include <algorithm>
     14 #include <cstring>
     15 #include <iostream>
     16 #include <memory>
     17 #include <string>
     18 #include <vector>
     19 
     20 #include "absl/flags/flag.h"
     21 #include "absl/flags/parse.h"
     22 #include "absl/strings/string_view.h"
     23 #include "api/audio/audio_frame.h"
     24 #include "api/scoped_refptr.h"
     25 #include "common_audio/wav_file.h"
     26 #include "modules/audio_mixer/audio_mixer_impl.h"
     27 #include "modules/audio_mixer/default_output_rate_calculator.h"
     28 #include "modules/audio_mixer/output_rate_calculator.h"
     29 #include "rtc_base/checks.h"
     30 #include "rtc_base/strings/string_builder.h"
     31 
     32 ABSL_FLAG(int,
     33          sampling_rate,
     34          16000,
     35          "Rate at which to mix (all input streams must have this rate)");
     36 
     37 ABSL_FLAG(bool,
     38          stereo,
     39          false,
     40          "Enable stereo (interleaved). Inputs need not be as this parameter.");
     41 
     42 ABSL_FLAG(bool, limiter, true, "Enable limiter.");
     43 ABSL_FLAG(std::string,
     44          output_file,
     45          "mixed_file.wav",
     46          "File in which to store the mixed result.");
     47 ABSL_FLAG(std::string, input_file_1, "", "First input. Default none.");
     48 ABSL_FLAG(std::string, input_file_2, "", "Second input. Default none.");
     49 ABSL_FLAG(std::string, input_file_3, "", "Third input. Default none.");
     50 ABSL_FLAG(std::string, input_file_4, "", "Fourth input. Default none.");
     51 
     52 namespace webrtc {
     53 namespace test {
     54 
     55 class FilePlayingSource : public AudioMixer::Source {
     56 public:
     57  explicit FilePlayingSource(absl::string_view filename)
     58      : wav_reader_(new WavReader(filename)),
     59        sample_rate_hz_(wav_reader_->sample_rate()),
     60        samples_per_channel_(sample_rate_hz_ / 100),
     61        number_of_channels_(wav_reader_->num_channels()) {}
     62 
     63  AudioFrameInfo GetAudioFrameWithInfo(int target_rate_hz,
     64                                       AudioFrame* frame) override {
     65    frame->samples_per_channel_ = samples_per_channel_;
     66    frame->num_channels_ = number_of_channels_;
     67    frame->sample_rate_hz_ = target_rate_hz;
     68 
     69    RTC_CHECK_EQ(target_rate_hz, sample_rate_hz_);
     70 
     71    const size_t num_to_read = number_of_channels_ * samples_per_channel_;
     72    const size_t num_read =
     73        wav_reader_->ReadSamples(num_to_read, frame->mutable_data());
     74 
     75    file_has_ended_ = num_to_read != num_read;
     76    if (file_has_ended_) {
     77      frame->Mute();
     78    }
     79    return file_has_ended_ ? AudioFrameInfo::kMuted : AudioFrameInfo::kNormal;
     80  }
     81 
     82  int Ssrc() const override { return 0; }
     83 
     84  int PreferredSampleRate() const override { return sample_rate_hz_; }
     85 
     86  bool FileHasEnded() const { return file_has_ended_; }
     87 
     88  std::string ToString() const {
     89    StringBuilder ss;
     90    ss << "{rate: " << sample_rate_hz_ << ", channels: " << number_of_channels_
     91       << ", samples_tot: " << wav_reader_->num_samples() << "}";
     92    return ss.Release();
     93  }
     94 
     95 private:
     96  std::unique_ptr<WavReader> wav_reader_;
     97  int sample_rate_hz_;
     98  int samples_per_channel_;
     99  int number_of_channels_;
    100  bool file_has_ended_ = false;
    101 };
    102 }  // namespace test
    103 }  // namespace webrtc
    104 
    105 namespace {
    106 
    107 const std::vector<std::string> parse_input_files() {
    108  std::vector<std::string> result;
    109  for (auto& x :
    110       {absl::GetFlag(FLAGS_input_file_1), absl::GetFlag(FLAGS_input_file_2),
    111        absl::GetFlag(FLAGS_input_file_3), absl::GetFlag(FLAGS_input_file_4)}) {
    112    if (!x.empty()) {
    113      result.push_back(x);
    114    }
    115  }
    116  return result;
    117 }
    118 }  // namespace
    119 
    120 int main(int argc, char* argv[]) {
    121  absl::ParseCommandLine(argc, argv);
    122 
    123  webrtc::scoped_refptr<webrtc::AudioMixerImpl> mixer(
    124      webrtc::AudioMixerImpl::Create(
    125          std::unique_ptr<webrtc::OutputRateCalculator>(
    126              new webrtc::DefaultOutputRateCalculator()),
    127          absl::GetFlag(FLAGS_limiter)));
    128 
    129  const std::vector<std::string> input_files = parse_input_files();
    130  std::vector<webrtc::test::FilePlayingSource> sources;
    131  const int num_channels = absl::GetFlag(FLAGS_stereo) ? 2 : 1;
    132  sources.reserve(input_files.size());
    133  for (const auto& input_file : input_files) {
    134    sources.emplace_back(input_file);
    135  }
    136 
    137  for (auto& source : sources) {
    138    auto error = mixer->AddSource(&source);
    139    RTC_CHECK(error);
    140  }
    141 
    142  if (sources.empty()) {
    143    std::cout << "Need at least one source!\n";
    144    return 1;
    145  }
    146 
    147  const size_t sample_rate = sources[0].PreferredSampleRate();
    148  for (const auto& source : sources) {
    149    RTC_CHECK_EQ(sample_rate, source.PreferredSampleRate());
    150  }
    151 
    152  // Print stats.
    153  std::cout << "Limiting is: " << (absl::GetFlag(FLAGS_limiter) ? "on" : "off")
    154            << "\n"
    155               "Channels: "
    156            << num_channels
    157            << "\n"
    158               "Rate: "
    159            << sample_rate
    160            << "\n"
    161               "Number of input streams: "
    162            << input_files.size() << "\n";
    163  for (const auto& source : sources) {
    164    std::cout << "\t" << source.ToString() << "\n";
    165  }
    166  std::cout << "Now mixing\n...\n";
    167 
    168  webrtc::WavWriter wav_writer(absl::GetFlag(FLAGS_output_file), sample_rate,
    169                               num_channels);
    170 
    171  webrtc::AudioFrame frame;
    172 
    173  bool all_streams_finished = false;
    174  while (!all_streams_finished) {
    175    mixer->Mix(num_channels, &frame);
    176    RTC_CHECK_EQ(sample_rate / 100, frame.samples_per_channel_);
    177    RTC_CHECK_EQ(sample_rate, frame.sample_rate_hz_);
    178    RTC_CHECK_EQ(num_channels, frame.num_channels_);
    179    wav_writer.WriteSamples(frame.data(),
    180                            num_channels * frame.samples_per_channel_);
    181 
    182    all_streams_finished =
    183        std::all_of(sources.begin(), sources.end(),
    184                    [](const webrtc::test::FilePlayingSource& source) {
    185                      return source.FileHasEnded();
    186                    });
    187  }
    188 
    189  std::cout << "Done!\n" << std::endl;
    190 }