tor-browser

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

opus_bandwidth_unittest.cc (6329B)


      1 /*
      2 *  Copyright (c) 2017 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 <complex>
     12 #include <cstddef>
     13 #include <cstdint>
     14 #include <cstdlib>
     15 #include <memory>
     16 #include <optional>
     17 #include <string>
     18 #include <vector>
     19 
     20 #include "api/audio_codecs/audio_decoder.h"
     21 #include "api/audio_codecs/audio_encoder.h"
     22 #include "api/audio_codecs/opus/audio_decoder_opus.h"
     23 #include "api/audio_codecs/opus/audio_encoder_opus.h"
     24 #include "api/audio_codecs/opus/audio_encoder_opus_config.h"
     25 #include "api/environment/environment.h"
     26 #include "api/environment/environment_factory.h"
     27 #include "api/field_trials.h"
     28 #include "common_audio/include/audio_util.h"
     29 #include "common_audio/window_generator.h"
     30 #include "modules/audio_coding/codecs/opus/test/lapped_transform.h"
     31 #include "modules/audio_coding/neteq/tools/audio_loop.h"
     32 #include "rtc_base/buffer.h"
     33 #include "test/create_test_field_trials.h"
     34 #include "test/gtest.h"
     35 #include "test/testsupport/file_utils.h"
     36 
     37 namespace webrtc {
     38 namespace {
     39 
     40 constexpr size_t kNumChannels = 1u;
     41 constexpr int kSampleRateHz = 48000;
     42 constexpr size_t kMaxLoopLengthSamples = kSampleRateHz * 50;  // 50 seconds.
     43 constexpr size_t kInputBlockSizeSamples = 10 * kSampleRateHz / 1000;   // 10 ms
     44 constexpr size_t kOutputBlockSizeSamples = 20 * kSampleRateHz / 1000;  // 20 ms
     45 constexpr size_t kFftSize = 1024;
     46 constexpr size_t kNarrowbandSize = 4000 * kFftSize / kSampleRateHz;
     47 constexpr float kKbdAlpha = 1.5f;
     48 
     49 class PowerRatioEstimator : public LappedTransform::Callback {
     50 public:
     51  PowerRatioEstimator() : low_pow_(0.f), high_pow_(0.f) {
     52    WindowGenerator::KaiserBesselDerived(kKbdAlpha, kFftSize, window_);
     53    transform_.reset(new LappedTransform(kNumChannels, 0u,
     54                                         kInputBlockSizeSamples, window_,
     55                                         kFftSize, kFftSize / 2, this));
     56  }
     57 
     58  void ProcessBlock(float* data) { transform_->ProcessChunk(&data, nullptr); }
     59 
     60  float PowerRatio() { return high_pow_ / low_pow_; }
     61 
     62 protected:
     63  void ProcessAudioBlock(const std::complex<float>* const* input,
     64                         size_t num_input_channels,
     65                         size_t /* num_freq_bins */,
     66                         size_t /* num_output_channels */,
     67                         std::complex<float>* const* /* output */) override {
     68    float low_pow = 0.f;
     69    float high_pow = 0.f;
     70    for (size_t i = 0u; i < num_input_channels; ++i) {
     71      for (size_t j = 0u; j < kNarrowbandSize; ++j) {
     72        float low_mag = std::abs(input[i][j]);
     73        low_pow += low_mag * low_mag;
     74        float high_mag = std::abs(input[i][j + kNarrowbandSize]);
     75        high_pow += high_mag * high_mag;
     76      }
     77    }
     78    low_pow_ += low_pow / (num_input_channels * kFftSize);
     79    high_pow_ += high_pow / (num_input_channels * kFftSize);
     80  }
     81 
     82 private:
     83  std::unique_ptr<LappedTransform> transform_;
     84  float window_[kFftSize];
     85  float low_pow_;
     86  float high_pow_;
     87 };
     88 
     89 float EncodedPowerRatio(AudioEncoder* encoder,
     90                        AudioDecoder* decoder,
     91                        test::AudioLoop* audio_loop) {
     92  // Encode and decode.
     93  uint32_t rtp_timestamp = 0u;
     94  constexpr size_t kBufferSize = 500;
     95  Buffer encoded(kBufferSize);
     96  std::vector<int16_t> decoded(kOutputBlockSizeSamples);
     97  std::vector<float> decoded_float(kOutputBlockSizeSamples);
     98  AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
     99  PowerRatioEstimator power_ratio_estimator;
    100  for (size_t i = 0; i < 1000; ++i) {
    101    encoded.Clear();
    102    AudioEncoder::EncodedInfo encoder_info =
    103        encoder->Encode(rtp_timestamp, audio_loop->GetNextBlock(), &encoded);
    104    rtp_timestamp += kInputBlockSizeSamples;
    105    if (!encoded.empty()) {
    106      int decoder_info = decoder->Decode(
    107          encoded.data(), encoded.size(), kSampleRateHz,
    108          decoded.size() * sizeof(decoded[0]), decoded.data(), &speech_type);
    109      if (decoder_info > 0) {
    110        S16ToFloat(decoded.data(), decoded.size(), decoded_float.data());
    111        power_ratio_estimator.ProcessBlock(decoded_float.data());
    112      }
    113    }
    114  }
    115  return power_ratio_estimator.PowerRatio();
    116 }
    117 
    118 }  // namespace
    119 
    120 // TODO(ivoc): Remove this test, WebRTC-AdjustOpusBandwidth is obsolete.
    121 TEST(BandwidthAdaptationTest, BandwidthAdaptationTest) {
    122  const Environment env = CreateEnvironment(std::make_unique<FieldTrials>(
    123      CreateTestFieldTrials("WebRTC-AdjustOpusBandwidth/Enabled/")));
    124 
    125  constexpr float kMaxNarrowbandRatio = 0.0035f;
    126  constexpr float kMinWidebandRatio = 0.01f;
    127 
    128  // Create encoder.
    129  AudioEncoderOpusConfig enc_config;
    130  enc_config.bitrate_bps = std::optional<int>(7999);
    131  enc_config.num_channels = kNumChannels;
    132  auto encoder =
    133      AudioEncoderOpus::MakeAudioEncoder(env, enc_config, {.payload_type = 17});
    134 
    135  // Create decoder.
    136  AudioDecoderOpus::Config dec_config;
    137  dec_config.num_channels = kNumChannels;
    138  auto decoder = AudioDecoderOpus::MakeAudioDecoder(env, dec_config);
    139 
    140  // Open speech file.
    141  const std::string kInputFileName =
    142      test::ResourcePath("audio_coding/speech_mono_32_48kHz", "pcm");
    143  test::AudioLoop audio_loop;
    144  EXPECT_EQ(kSampleRateHz, encoder->SampleRateHz());
    145  ASSERT_TRUE(audio_loop.Init(kInputFileName, kMaxLoopLengthSamples,
    146                              kInputBlockSizeSamples));
    147 
    148  EXPECT_LT(EncodedPowerRatio(encoder.get(), decoder.get(), &audio_loop),
    149            kMaxNarrowbandRatio);
    150 
    151  encoder->OnReceivedTargetAudioBitrate(9000);
    152  EXPECT_LT(EncodedPowerRatio(encoder.get(), decoder.get(), &audio_loop),
    153            kMaxNarrowbandRatio);
    154 
    155  encoder->OnReceivedTargetAudioBitrate(9001);
    156  EXPECT_GT(EncodedPowerRatio(encoder.get(), decoder.get(), &audio_loop),
    157            kMinWidebandRatio);
    158 
    159  encoder->OnReceivedTargetAudioBitrate(8000);
    160  EXPECT_GT(EncodedPowerRatio(encoder.get(), decoder.get(), &audio_loop),
    161            kMinWidebandRatio);
    162 
    163  encoder->OnReceivedTargetAudioBitrate(12001);
    164  EXPECT_GT(EncodedPowerRatio(encoder.get(), decoder.get(), &audio_loop),
    165            kMinWidebandRatio);
    166 }
    167 
    168 }  // namespace webrtc