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