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