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