tor-browser

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

comfort_noise.cc (5144B)


      1 /*
      2 *  Copyright (c) 2012 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 "modules/audio_coding/neteq/comfort_noise.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <memory>
     16 
     17 #include "api/array_view.h"
     18 #include "modules/audio_coding/codecs/cng/webrtc_cng.h"
     19 #include "modules/audio_coding/neteq/audio_multi_vector.h"
     20 #include "modules/audio_coding/neteq/audio_vector.h"
     21 #include "modules/audio_coding/neteq/decoder_database.h"
     22 #include "modules/audio_coding/neteq/dsp_helper.h"
     23 #include "modules/audio_coding/neteq/sync_buffer.h"
     24 #include "rtc_base/checks.h"
     25 #include "rtc_base/logging.h"
     26 
     27 namespace webrtc {
     28 
     29 void ComfortNoise::Reset() {
     30  first_call_ = true;
     31 }
     32 
     33 int ComfortNoise::UpdateParameters(const Packet& packet) {
     34  // Get comfort noise decoder.
     35  if (decoder_database_->SetActiveCngDecoder(packet.payload_type) != kOK) {
     36    return kUnknownPayloadType;
     37  }
     38  ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
     39  RTC_DCHECK(cng_decoder);
     40  cng_decoder->UpdateSid(packet.payload);
     41  return kOK;
     42 }
     43 
     44 int ComfortNoise::Generate(size_t requested_length, AudioMultiVector* output) {
     45  // TODO(hlundin): Change to an enumerator and skip assert.
     46  RTC_DCHECK(fs_hz_ == 8000 || fs_hz_ == 16000 || fs_hz_ == 32000 ||
     47             fs_hz_ == 48000);
     48  // Not adapted for multi-channel yet.
     49  if (output->Channels() != 1) {
     50    RTC_LOG(LS_ERROR) << "No multi-channel support";
     51    return kMultiChannelNotSupported;
     52  }
     53 
     54  size_t number_of_samples = requested_length;
     55  bool new_period = false;
     56  if (first_call_) {
     57    // Generate noise and overlap slightly with old data.
     58    number_of_samples = requested_length + overlap_length_;
     59    new_period = true;
     60  }
     61  output->AssertSize(number_of_samples);
     62  // Get the decoder from the database.
     63  ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
     64  if (!cng_decoder) {
     65    RTC_LOG(LS_ERROR) << "Unknwown payload type";
     66    return kUnknownPayloadType;
     67  }
     68 
     69  std::unique_ptr<int16_t[]> temp(new int16_t[number_of_samples]);
     70  if (!cng_decoder->Generate(ArrayView<int16_t>(temp.get(), number_of_samples),
     71                             new_period)) {
     72    // Error returned.
     73    output->Zeros(requested_length);
     74    RTC_LOG(LS_ERROR)
     75        << "ComfortNoiseDecoder::Genererate failed to generate comfort noise";
     76    return kInternalError;
     77  }
     78  (*output)[0].OverwriteAt(temp.get(), number_of_samples, 0);
     79 
     80  if (first_call_) {
     81    // Set tapering window parameters. Values are in Q15.
     82    int16_t muting_window;              // Mixing factor for overlap data.
     83    int16_t muting_window_increment;    // Mixing factor increment (negative).
     84    int16_t unmuting_window;            // Mixing factor for comfort noise.
     85    int16_t unmuting_window_increment;  // Mixing factor increment.
     86    if (fs_hz_ == 8000) {
     87      muting_window = DspHelper::kMuteFactorStart8kHz;
     88      muting_window_increment = DspHelper::kMuteFactorIncrement8kHz;
     89      unmuting_window = DspHelper::kUnmuteFactorStart8kHz;
     90      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement8kHz;
     91    } else if (fs_hz_ == 16000) {
     92      muting_window = DspHelper::kMuteFactorStart16kHz;
     93      muting_window_increment = DspHelper::kMuteFactorIncrement16kHz;
     94      unmuting_window = DspHelper::kUnmuteFactorStart16kHz;
     95      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement16kHz;
     96    } else if (fs_hz_ == 32000) {
     97      muting_window = DspHelper::kMuteFactorStart32kHz;
     98      muting_window_increment = DspHelper::kMuteFactorIncrement32kHz;
     99      unmuting_window = DspHelper::kUnmuteFactorStart32kHz;
    100      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement32kHz;
    101    } else {  // fs_hz_ == 48000
    102      muting_window = DspHelper::kMuteFactorStart48kHz;
    103      muting_window_increment = DspHelper::kMuteFactorIncrement48kHz;
    104      unmuting_window = DspHelper::kUnmuteFactorStart48kHz;
    105      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement48kHz;
    106    }
    107 
    108    // Do overlap-add between new vector and overlap.
    109    size_t start_ix = sync_buffer_->Size() - overlap_length_;
    110    for (size_t i = 0; i < overlap_length_; i++) {
    111      /* overlapVec[i] = WinMute * overlapVec[i] + WinUnMute * outData[i] */
    112      // The expression (*output)[0][i] is the i-th element in the first
    113      // channel.
    114      (*sync_buffer_)[0][start_ix + i] =
    115          (((*sync_buffer_)[0][start_ix + i] * muting_window) +
    116           ((*output)[0][i] * unmuting_window) + 16384) >>
    117          15;
    118      muting_window += muting_window_increment;
    119      unmuting_window += unmuting_window_increment;
    120    }
    121    // Remove `overlap_length_` samples from the front of `output` since they
    122    // were mixed into `sync_buffer_` above.
    123    output->PopFront(overlap_length_);
    124  }
    125  first_call_ = false;
    126  return kOK;
    127 }
    128 
    129 }  // namespace webrtc