tor-browser

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

test_audio_device.cc (18228B)


      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 #include "modules/audio_device/include/test_audio_device.h"
     11 
     12 #include <algorithm>
     13 #include <cstdint>
     14 #include <cstdlib>
     15 #include <cstring>
     16 #include <memory>
     17 #include <string>
     18 #include <utility>
     19 #include <vector>
     20 
     21 #include "absl/strings/string_view.h"
     22 #include "api/array_view.h"
     23 #include "api/audio/audio_device.h"
     24 #include "api/environment/environment.h"
     25 #include "api/make_ref_counted.h"
     26 #include "api/scoped_refptr.h"
     27 #include "common_audio/wav_file.h"
     28 #include "modules/audio_device/audio_device_impl.h"
     29 #include "modules/audio_device/test_audio_device_impl.h"
     30 #include "rtc_base/buffer.h"
     31 #include "rtc_base/checks.h"
     32 #include "rtc_base/numerics/safe_conversions.h"
     33 #include "rtc_base/random.h"
     34 #include "rtc_base/synchronization/mutex.h"
     35 #include "rtc_base/system/file_wrapper.h"
     36 #include "rtc_base/thread_annotations.h"
     37 #include "rtc_base/time_utils.h"
     38 
     39 namespace webrtc {
     40 
     41 namespace {
     42 
     43 constexpr int kFrameLengthUs = 10000;
     44 constexpr int kFramesPerSecond = kNumMicrosecsPerSec / kFrameLengthUs;
     45 
     46 // A fake capturer that generates pulses with random samples between
     47 // -max_amplitude and +max_amplitude.
     48 class PulsedNoiseCapturerImpl final
     49    : public TestAudioDeviceModule::PulsedNoiseCapturer {
     50 public:
     51  // Assuming 10ms audio packets.
     52  PulsedNoiseCapturerImpl(int16_t max_amplitude,
     53                          int sampling_frequency_in_hz,
     54                          int num_channels)
     55      : sampling_frequency_in_hz_(sampling_frequency_in_hz),
     56        fill_with_zero_(false),
     57        random_generator_(1),
     58        max_amplitude_(max_amplitude),
     59        num_channels_(num_channels) {
     60    RTC_DCHECK_GT(max_amplitude, 0);
     61  }
     62 
     63  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
     64 
     65  int NumChannels() const override { return num_channels_; }
     66 
     67  bool Capture(BufferT<int16_t>* buffer) override {
     68    fill_with_zero_ = !fill_with_zero_;
     69    int16_t max_amplitude;
     70    {
     71      MutexLock lock(&lock_);
     72      max_amplitude = max_amplitude_;
     73    }
     74    buffer->SetData(
     75        TestAudioDeviceModule::SamplesPerFrame(sampling_frequency_in_hz_) *
     76            num_channels_,
     77        [&](ArrayView<int16_t> data) {
     78          if (fill_with_zero_) {
     79            std::fill(data.begin(), data.end(), 0);
     80          } else {
     81            std::generate(data.begin(), data.end(), [&]() {
     82              return random_generator_.Rand(-max_amplitude, max_amplitude);
     83            });
     84          }
     85          return data.size();
     86        });
     87    return true;
     88  }
     89 
     90  void SetMaxAmplitude(int16_t amplitude) override {
     91    MutexLock lock(&lock_);
     92    max_amplitude_ = amplitude;
     93  }
     94 
     95 private:
     96  int sampling_frequency_in_hz_;
     97  bool fill_with_zero_;
     98  Random random_generator_;
     99  Mutex lock_;
    100  int16_t max_amplitude_ RTC_GUARDED_BY(lock_);
    101  const int num_channels_;
    102 };
    103 
    104 class WavFileReader final : public TestAudioDeviceModule::Capturer {
    105 public:
    106  WavFileReader(absl::string_view filename,
    107                int sampling_frequency_in_hz,
    108                int num_channels,
    109                bool repeat)
    110      : WavFileReader(std::make_unique<WavReader>(filename),
    111                      sampling_frequency_in_hz,
    112                      num_channels,
    113                      repeat) {}
    114 
    115  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
    116 
    117  int NumChannels() const override { return num_channels_; }
    118 
    119  bool Capture(BufferT<int16_t>* buffer) override {
    120    buffer->SetData(
    121        TestAudioDeviceModule::SamplesPerFrame(sampling_frequency_in_hz_) *
    122            num_channels_,
    123        [&](ArrayView<int16_t> data) {
    124          size_t read = wav_reader_->ReadSamples(data.size(), data.data());
    125          if (read < data.size() && repeat_) {
    126            do {
    127              wav_reader_->Reset();
    128              size_t delta = wav_reader_->ReadSamples(
    129                  data.size() - read, data.subview(read).data());
    130              RTC_CHECK_GT(delta, 0) << "No new data read from file";
    131              read += delta;
    132            } while (read < data.size());
    133          }
    134          return read;
    135        });
    136    return !buffer->empty();
    137  }
    138 
    139 private:
    140  WavFileReader(std::unique_ptr<WavReader> wav_reader,
    141                int sampling_frequency_in_hz,
    142                int num_channels,
    143                bool repeat)
    144      : sampling_frequency_in_hz_(sampling_frequency_in_hz),
    145        num_channels_(num_channels),
    146        wav_reader_(std::move(wav_reader)),
    147        repeat_(repeat) {
    148    RTC_CHECK_EQ(wav_reader_->sample_rate(), sampling_frequency_in_hz);
    149    RTC_CHECK_EQ(wav_reader_->num_channels(), num_channels);
    150  }
    151 
    152  const int sampling_frequency_in_hz_;
    153  const int num_channels_;
    154  std::unique_ptr<WavReader> wav_reader_;
    155  const bool repeat_;
    156 };
    157 
    158 class WavFileWriter final : public TestAudioDeviceModule::Renderer {
    159 public:
    160  WavFileWriter(absl::string_view filename,
    161                int sampling_frequency_in_hz,
    162                int num_channels)
    163      : WavFileWriter(std::make_unique<WavWriter>(filename,
    164                                                  sampling_frequency_in_hz,
    165                                                  num_channels),
    166                      sampling_frequency_in_hz,
    167                      num_channels) {}
    168 
    169  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
    170 
    171  int NumChannels() const override { return num_channels_; }
    172 
    173  bool Render(ArrayView<const int16_t> data) override {
    174    wav_writer_->WriteSamples(data.data(), data.size());
    175    return true;
    176  }
    177 
    178 private:
    179  WavFileWriter(std::unique_ptr<WavWriter> wav_writer,
    180                int sampling_frequency_in_hz,
    181                int num_channels)
    182      : sampling_frequency_in_hz_(sampling_frequency_in_hz),
    183        wav_writer_(std::move(wav_writer)),
    184        num_channels_(num_channels) {}
    185 
    186  int sampling_frequency_in_hz_;
    187  std::unique_ptr<WavWriter> wav_writer_;
    188  const int num_channels_;
    189 };
    190 
    191 class BoundedWavFileWriter : public TestAudioDeviceModule::Renderer {
    192 public:
    193  BoundedWavFileWriter(absl::string_view filename,
    194                       int sampling_frequency_in_hz,
    195                       int num_channels)
    196      : sampling_frequency_in_hz_(sampling_frequency_in_hz),
    197        wav_writer_(filename, sampling_frequency_in_hz, num_channels),
    198        num_channels_(num_channels),
    199        silent_audio_(
    200            TestAudioDeviceModule::SamplesPerFrame(sampling_frequency_in_hz) *
    201                num_channels,
    202            0),
    203        started_writing_(false),
    204        trailing_zeros_(0) {}
    205 
    206  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
    207 
    208  int NumChannels() const override { return num_channels_; }
    209 
    210  bool Render(ArrayView<const int16_t> data) override {
    211    const int16_t kAmplitudeThreshold = 5;
    212 
    213    const int16_t* begin = data.begin();
    214    const int16_t* end = data.end();
    215    if (!started_writing_) {
    216      // Cut off silence at the beginning.
    217      while (begin < end) {
    218        if (std::abs(*begin) > kAmplitudeThreshold) {
    219          started_writing_ = true;
    220          break;
    221        }
    222        ++begin;
    223      }
    224    }
    225    if (started_writing_) {
    226      // Cut off silence at the end.
    227      while (begin < end) {
    228        if (*(end - 1) != 0) {
    229          break;
    230        }
    231        --end;
    232      }
    233      if (begin < end) {
    234        // If it turns out that the silence was not final, need to write all the
    235        // skipped zeros and continue writing audio.
    236        while (trailing_zeros_ > 0) {
    237          const size_t zeros_to_write =
    238              std::min(trailing_zeros_, silent_audio_.size());
    239          wav_writer_.WriteSamples(silent_audio_.data(), zeros_to_write);
    240          trailing_zeros_ -= zeros_to_write;
    241        }
    242        wav_writer_.WriteSamples(begin, end - begin);
    243      }
    244      // Save the number of zeros we skipped in case this needs to be restored.
    245      trailing_zeros_ += data.end() - end;
    246    }
    247    return true;
    248  }
    249 
    250 private:
    251  int sampling_frequency_in_hz_;
    252  WavWriter wav_writer_;
    253  const int num_channels_;
    254  std::vector<int16_t> silent_audio_;
    255  bool started_writing_;
    256  size_t trailing_zeros_;
    257 };
    258 
    259 class DiscardRenderer final : public TestAudioDeviceModule::Renderer {
    260 public:
    261  explicit DiscardRenderer(int sampling_frequency_in_hz, int num_channels)
    262      : sampling_frequency_in_hz_(sampling_frequency_in_hz),
    263        num_channels_(num_channels) {}
    264 
    265  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
    266 
    267  int NumChannels() const override { return num_channels_; }
    268 
    269  bool Render(ArrayView<const int16_t> /* data */) override { return true; }
    270 
    271 private:
    272  int sampling_frequency_in_hz_;
    273  const int num_channels_;
    274 };
    275 
    276 class RawFileReader final : public TestAudioDeviceModule::Capturer {
    277 public:
    278  RawFileReader(absl::string_view input_file_name,
    279                int sampling_frequency_in_hz,
    280                int num_channels,
    281                bool repeat)
    282      : input_file_name_(input_file_name),
    283        sampling_frequency_in_hz_(sampling_frequency_in_hz),
    284        num_channels_(num_channels),
    285        repeat_(repeat),
    286        read_buffer_(
    287            TestAudioDeviceModule::SamplesPerFrame(sampling_frequency_in_hz) *
    288                num_channels * 2,
    289            0) {
    290    input_file_ = FileWrapper::OpenReadOnly(input_file_name_);
    291    RTC_CHECK(input_file_.is_open())
    292        << "Failed to open audio input file: " << input_file_name_;
    293  }
    294 
    295  ~RawFileReader() override { input_file_.Close(); }
    296 
    297  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
    298 
    299  int NumChannels() const override { return num_channels_; }
    300 
    301  bool Capture(BufferT<int16_t>* buffer) override {
    302    buffer->SetData(
    303        TestAudioDeviceModule::SamplesPerFrame(SamplingFrequency()) *
    304            NumChannels(),
    305        [&](ArrayView<int16_t> data) {
    306          ArrayView<int8_t> read_buffer_view = ReadBufferView();
    307          size_t size = data.size() * 2;
    308          size_t read = input_file_.Read(read_buffer_view.data(), size);
    309          if (read < size && repeat_) {
    310            do {
    311              input_file_.Rewind();
    312              size_t delta = input_file_.Read(
    313                  read_buffer_view.subview(read).data(), size - read);
    314              RTC_CHECK_GT(delta, 0) << "No new data to read from file";
    315              read += delta;
    316            } while (read < size);
    317          }
    318          memcpy(data.data(), read_buffer_view.data(), size);
    319          return read / 2;
    320        });
    321    return !buffer->empty();
    322  }
    323 
    324 private:
    325  ArrayView<int8_t> ReadBufferView() { return read_buffer_; }
    326 
    327  const std::string input_file_name_;
    328  const int sampling_frequency_in_hz_;
    329  const int num_channels_;
    330  const bool repeat_;
    331  FileWrapper input_file_;
    332  std::vector<int8_t> read_buffer_;
    333 };
    334 
    335 class RawFileWriter : public TestAudioDeviceModule::Renderer {
    336 public:
    337  RawFileWriter(absl::string_view output_file_name,
    338                int sampling_frequency_in_hz,
    339                int num_channels)
    340      : output_file_name_(output_file_name),
    341        sampling_frequency_in_hz_(sampling_frequency_in_hz),
    342        num_channels_(num_channels),
    343        silent_audio_(
    344            TestAudioDeviceModule::SamplesPerFrame(sampling_frequency_in_hz) *
    345                num_channels * 2,
    346            0),
    347        write_buffer_(
    348            TestAudioDeviceModule::SamplesPerFrame(sampling_frequency_in_hz) *
    349                num_channels * 2,
    350            0),
    351        started_writing_(false),
    352        trailing_zeros_(0) {
    353    output_file_ = FileWrapper::OpenWriteOnly(output_file_name_);
    354    RTC_CHECK(output_file_.is_open())
    355        << "Failed to open playout file" << output_file_name_;
    356  }
    357  ~RawFileWriter() override { output_file_.Close(); }
    358 
    359  int SamplingFrequency() const override { return sampling_frequency_in_hz_; }
    360 
    361  int NumChannels() const override { return num_channels_; }
    362 
    363  bool Render(ArrayView<const int16_t> data) override {
    364    const int16_t kAmplitudeThreshold = 5;
    365 
    366    const int16_t* begin = data.begin();
    367    const int16_t* end = data.end();
    368    if (!started_writing_) {
    369      // Cut off silence at the beginning.
    370      while (begin < end) {
    371        if (std::abs(*begin) > kAmplitudeThreshold) {
    372          started_writing_ = true;
    373          break;
    374        }
    375        ++begin;
    376      }
    377    }
    378    if (started_writing_) {
    379      // Cut off silence at the end.
    380      while (begin < end) {
    381        if (*(end - 1) != 0) {
    382          break;
    383        }
    384        --end;
    385      }
    386      if (begin < end) {
    387        // If it turns out that the silence was not final, need to write all the
    388        // skipped zeros and continue writing audio.
    389        while (trailing_zeros_ > 0) {
    390          const size_t zeros_to_write =
    391              std::min(trailing_zeros_, silent_audio_.size());
    392          output_file_.Write(silent_audio_.data(), zeros_to_write * 2);
    393          trailing_zeros_ -= zeros_to_write;
    394        }
    395        WriteInt16(begin, end);
    396      }
    397      // Save the number of zeros we skipped in case this needs to be restored.
    398      trailing_zeros_ += data.end() - end;
    399    }
    400    return true;
    401  }
    402 
    403 private:
    404  void WriteInt16(const int16_t* begin, const int16_t* end) {
    405    int size = (end - begin) * sizeof(int16_t);
    406    memcpy(write_buffer_.data(), begin, size);
    407    output_file_.Write(write_buffer_.data(), size);
    408  }
    409 
    410  const std::string output_file_name_;
    411  const int sampling_frequency_in_hz_;
    412  const int num_channels_;
    413  FileWrapper output_file_;
    414  std::vector<int8_t> silent_audio_;
    415  std::vector<int8_t> write_buffer_;
    416  bool started_writing_;
    417  size_t trailing_zeros_;
    418 };
    419 
    420 }  // namespace
    421 
    422 size_t TestAudioDeviceModule::SamplesPerFrame(int sampling_frequency_in_hz) {
    423  return CheckedDivExact(sampling_frequency_in_hz, kFramesPerSecond);
    424 }
    425 
    426 scoped_refptr<AudioDeviceModule> TestAudioDeviceModule::Create(
    427    const Environment& env,
    428    std::unique_ptr<TestAudioDeviceModule::Capturer> capturer,
    429    std::unique_ptr<TestAudioDeviceModule::Renderer> renderer,
    430    float speed) {
    431  auto audio_device = make_ref_counted<AudioDeviceModuleImpl>(
    432      env, AudioDeviceModule::AudioLayer::kDummyAudio,
    433      std::make_unique<TestAudioDevice>(env, std::move(capturer),
    434                                        std::move(renderer), speed),
    435      /*create_detached=*/true);
    436 
    437  // Ensure that the current platform is supported.
    438  if (audio_device->CheckPlatform() == -1) {
    439    return nullptr;
    440  }
    441 
    442  // Create the platform-dependent implementation.
    443  if (audio_device->CreatePlatformSpecificObjects(env) == -1) {
    444    return nullptr;
    445  }
    446 
    447  // Ensure that the generic audio buffer can communicate with the platform
    448  // specific parts.
    449  if (audio_device->AttachAudioBuffer() == -1) {
    450    return nullptr;
    451  }
    452 
    453  return audio_device;
    454 }
    455 
    456 std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer>
    457 TestAudioDeviceModule::CreatePulsedNoiseCapturer(int16_t max_amplitude,
    458                                                 int sampling_frequency_in_hz,
    459                                                 int num_channels) {
    460  return std::make_unique<PulsedNoiseCapturerImpl>(
    461      max_amplitude, sampling_frequency_in_hz, num_channels);
    462 }
    463 
    464 std::unique_ptr<TestAudioDeviceModule::Renderer>
    465 TestAudioDeviceModule::CreateDiscardRenderer(int sampling_frequency_in_hz,
    466                                             int num_channels) {
    467  return std::make_unique<DiscardRenderer>(sampling_frequency_in_hz,
    468                                           num_channels);
    469 }
    470 
    471 std::unique_ptr<TestAudioDeviceModule::Capturer>
    472 TestAudioDeviceModule::CreateWavFileReader(absl::string_view filename,
    473                                           int sampling_frequency_in_hz,
    474                                           int num_channels) {
    475  return std::make_unique<WavFileReader>(filename, sampling_frequency_in_hz,
    476                                         num_channels, false);
    477 }
    478 
    479 std::unique_ptr<TestAudioDeviceModule::Capturer>
    480 TestAudioDeviceModule::CreateWavFileReader(absl::string_view filename,
    481                                           bool repeat) {
    482  WavReader reader(filename);
    483  int sampling_frequency_in_hz = reader.sample_rate();
    484  int num_channels = checked_cast<int>(reader.num_channels());
    485  return std::make_unique<WavFileReader>(filename, sampling_frequency_in_hz,
    486                                         num_channels, repeat);
    487 }
    488 
    489 std::unique_ptr<TestAudioDeviceModule::Renderer>
    490 TestAudioDeviceModule::CreateWavFileWriter(absl::string_view filename,
    491                                           int sampling_frequency_in_hz,
    492                                           int num_channels) {
    493  return std::make_unique<WavFileWriter>(filename, sampling_frequency_in_hz,
    494                                         num_channels);
    495 }
    496 
    497 std::unique_ptr<TestAudioDeviceModule::Renderer>
    498 TestAudioDeviceModule::CreateBoundedWavFileWriter(absl::string_view filename,
    499                                                  int sampling_frequency_in_hz,
    500                                                  int num_channels) {
    501  return std::make_unique<BoundedWavFileWriter>(
    502      filename, sampling_frequency_in_hz, num_channels);
    503 }
    504 
    505 std::unique_ptr<TestAudioDeviceModule::Capturer>
    506 TestAudioDeviceModule::CreateRawFileReader(absl::string_view filename,
    507                                           int sampling_frequency_in_hz,
    508                                           int num_channels,
    509                                           bool repeat) {
    510  return std::make_unique<RawFileReader>(filename, sampling_frequency_in_hz,
    511                                         num_channels, repeat);
    512 }
    513 
    514 std::unique_ptr<TestAudioDeviceModule::Renderer>
    515 TestAudioDeviceModule::CreateRawFileWriter(absl::string_view filename,
    516                                           int sampling_frequency_in_hz,
    517                                           int num_channels) {
    518  return std::make_unique<RawFileWriter>(filename, sampling_frequency_in_hz,
    519                                         num_channels);
    520 }
    521 
    522 }  // namespace webrtc