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