Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_coding/neteq4/comfort_noise.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 5.3 KB
Line 
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/neteq4/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/neteq4/decoder_database.h"
17#include "webrtc/modules/audio_coding/neteq4/dsp_helper.h"
18#include "webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h"
19#include "webrtc/modules/audio_coding/neteq4/sync_buffer.h"
20
21namespace webrtc {
22
23void ComfortNoise::Reset() {
24  first_call_ = true;
25  internal_error_code_ = 0;
26}
27
28int 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
52int 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
Note: See TracBrowser for help on using the repository browser.