tor-browser

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

push_resampler.cc (4618B)


      1 /*
      2 *  Copyright (c) 2013 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 "common_audio/resampler/include/push_resampler.h"
     12 
     13 #include <cstdint>
     14 #include <cstring>
     15 #include <memory>
     16 
     17 #include "api/audio/audio_view.h"
     18 #include "common_audio/include/audio_util.h"
     19 #include "common_audio/resampler/push_sinc_resampler.h"
     20 #include "rtc_base/checks.h"
     21 
     22 namespace webrtc {
     23 
     24 namespace {
     25 // Maximum concurrent number of channels for `PushResampler<>`.
     26 // Note that this may be different from what the maximum is for audio codecs.
     27 constexpr int kMaxNumberOfChannels = 8;
     28 }  // namespace
     29 
     30 template <typename T>
     31 PushResampler<T>::PushResampler() = default;
     32 
     33 template <typename T>
     34 PushResampler<T>::PushResampler(size_t src_samples_per_channel,
     35                                size_t dst_samples_per_channel,
     36                                size_t num_channels) {
     37  EnsureInitialized(src_samples_per_channel, dst_samples_per_channel,
     38                    num_channels);
     39 }
     40 
     41 template <typename T>
     42 PushResampler<T>::~PushResampler() = default;
     43 
     44 template <typename T>
     45 void PushResampler<T>::EnsureInitialized(size_t src_samples_per_channel,
     46                                         size_t dst_samples_per_channel,
     47                                         size_t num_channels) {
     48  RTC_DCHECK_GT(src_samples_per_channel, 0);
     49  RTC_DCHECK_GT(dst_samples_per_channel, 0);
     50  RTC_DCHECK_GT(num_channels, 0);
     51  RTC_DCHECK_LE(src_samples_per_channel, kMaxSamplesPerChannel10ms);
     52  RTC_DCHECK_LE(dst_samples_per_channel, kMaxSamplesPerChannel10ms);
     53  RTC_DCHECK_LE(num_channels, kMaxNumberOfChannels);
     54 
     55  if (src_samples_per_channel == SamplesPerChannel(source_view_) &&
     56      dst_samples_per_channel == SamplesPerChannel(destination_view_) &&
     57      num_channels == NumChannels(source_view_)) {
     58    // No-op if settings haven't changed.
     59    return;
     60  }
     61 
     62  // Allocate two buffers for all source and destination channels.
     63  // Then organize source and destination views together with an array of
     64  // resamplers for each channel in the deinterlaved buffers.
     65  source_.reset(new T[src_samples_per_channel * num_channels]);
     66  destination_.reset(new T[dst_samples_per_channel * num_channels]);
     67  source_view_ = DeinterleavedView<T>(source_.get(), src_samples_per_channel,
     68                                      num_channels);
     69  destination_view_ = DeinterleavedView<T>(
     70      destination_.get(), dst_samples_per_channel, num_channels);
     71  resamplers_.resize(num_channels);
     72  for (size_t i = 0; i < num_channels; ++i) {
     73    resamplers_[i] = std::make_unique<PushSincResampler>(
     74        src_samples_per_channel, dst_samples_per_channel);
     75  }
     76 }
     77 
     78 template <typename T>
     79 void PushResampler<T>::Resample(InterleavedView<const T> src,
     80                                InterleavedView<T> dst) {
     81  EnsureInitialized(SamplesPerChannel(src), SamplesPerChannel(dst),
     82                    NumChannels(src));
     83 
     84  RTC_DCHECK_EQ(NumChannels(src), NumChannels(source_view_));
     85  RTC_DCHECK_EQ(NumChannels(dst), NumChannels(destination_view_));
     86  RTC_DCHECK_EQ(SamplesPerChannel(src), SamplesPerChannel(source_view_));
     87  RTC_DCHECK_EQ(SamplesPerChannel(dst), SamplesPerChannel(destination_view_));
     88 
     89  if (SamplesPerChannel(src) == SamplesPerChannel(dst)) {
     90    // The old resampler provides this memcpy facility in the case of matching
     91    // sample rates, so reproduce it here for the sinc resampler.
     92    CopySamples(dst, src);
     93    return;
     94  }
     95 
     96  Deinterleave(src, source_view_);
     97 
     98  for (size_t i = 0; i < resamplers_.size(); ++i) {
     99    size_t dst_length_mono =
    100        resamplers_[i]->Resample(source_view_[i], destination_view_[i]);
    101    RTC_DCHECK_EQ(dst_length_mono, SamplesPerChannel(dst));
    102  }
    103 
    104  Interleave<T>(destination_view_, dst);
    105 }
    106 
    107 template <typename T>
    108 void PushResampler<T>::Resample(MonoView<const T> src, MonoView<T> dst) {
    109  RTC_DCHECK_EQ(resamplers_.size(), 1);
    110  RTC_DCHECK_EQ(SamplesPerChannel(src), SamplesPerChannel(source_view_));
    111  RTC_DCHECK_EQ(SamplesPerChannel(dst), SamplesPerChannel(destination_view_));
    112 
    113  if (SamplesPerChannel(src) == SamplesPerChannel(dst)) {
    114    CopySamples(dst, src);
    115  } else {
    116    resamplers_[0]->Resample(src, dst);
    117  }
    118 }
    119 
    120 // Explictly generate required instantiations.
    121 template class PushResampler<int16_t>;
    122 template class PushResampler<float>;
    123 
    124 }  // namespace webrtc