Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / comfort_noise.cc
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 = cng_decoder->CngDecoderInstance();
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 = cng_decoder->CngDecoderInstance();
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