Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc

Issue 1415173005: Prevent Opus DTX from generating intermittent noise during silence (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 #include <string> 10 #include <string>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 int EncodeDecode(WebRtcOpusEncInst* encoder, 46 int EncodeDecode(WebRtcOpusEncInst* encoder,
47 const int16_t* input_audio, 47 const int16_t* input_audio,
48 size_t input_samples, 48 size_t input_samples,
49 WebRtcOpusDecInst* decoder, 49 WebRtcOpusDecInst* decoder,
50 int16_t* output_audio, 50 int16_t* output_audio,
51 int16_t* audio_type); 51 int16_t* audio_type);
52 52
53 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, 53 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder,
54 opus_int32 expect, int32_t set); 54 opus_int32 expect, int32_t set);
55 55
56 // Verify that all samples in |audio| are bounded in [-|bound|, |bound|].
57 void CheckAudioBounded(int16_t* audio, size_t samples, int channels,
58 uint16_t bound);
59
56 WebRtcOpusEncInst* opus_encoder_; 60 WebRtcOpusEncInst* opus_encoder_;
57 WebRtcOpusDecInst* opus_decoder_; 61 WebRtcOpusDecInst* opus_decoder_;
58 62
59 AudioLoop speech_data_; 63 AudioLoop speech_data_;
60 uint8_t bitstream_[kMaxBytes]; 64 uint8_t bitstream_[kMaxBytes];
61 size_t encoded_bytes_; 65 size_t encoded_bytes_;
62 int channels_; 66 int channels_;
63 int application_; 67 int application_;
64 }; 68 };
65 69
(...skipping 22 matching lines...) Expand all
88 void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, 92 void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder,
89 opus_int32 expect, 93 opus_int32 expect,
90 int32_t set) { 94 int32_t set) {
91 opus_int32 bandwidth; 95 opus_int32 bandwidth;
92 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set)); 96 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set));
93 opus_encoder_ctl(opus_encoder_->encoder, 97 opus_encoder_ctl(opus_encoder_->encoder,
94 OPUS_GET_MAX_BANDWIDTH(&bandwidth)); 98 OPUS_GET_MAX_BANDWIDTH(&bandwidth));
95 EXPECT_EQ(expect, bandwidth); 99 EXPECT_EQ(expect, bandwidth);
96 } 100 }
97 101
102 void OpusTest::CheckAudioBounded(int16_t* audio, size_t samples, int channels,
103 uint16_t bound) {
104 for (size_t i = 0; i < samples; ++i) {
105 for (int c = 0; c < channels; ++c, ++audio) {
106 EXPECT_GE(*audio, -bound);
107 EXPECT_LE(*audio, bound);
108 }
109 }
110 }
111
98 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, 112 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder,
99 const int16_t* input_audio, 113 const int16_t* input_audio,
100 size_t input_samples, 114 size_t input_samples,
101 WebRtcOpusDecInst* decoder, 115 WebRtcOpusDecInst* decoder,
102 int16_t* output_audio, 116 int16_t* output_audio,
103 int16_t* audio_type) { 117 int16_t* audio_type) {
104 int encoded_bytes_int = WebRtcOpus_Encode(encoder, input_audio, input_samples, 118 int encoded_bytes_int = WebRtcOpus_Encode(encoder, input_audio, input_samples,
105 kMaxBytes, bitstream_); 119 kMaxBytes, bitstream_);
106 EXPECT_GE(encoded_bytes_int, 0); 120 EXPECT_GE(encoded_bytes_int, 0);
107 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int); 121 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } else if (encoded_bytes_ == 1) { 184 } else if (encoded_bytes_ == 1) {
171 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); 185 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
172 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); 186 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
173 EXPECT_EQ(2, audio_type); // Comfort noise. 187 EXPECT_EQ(2, audio_type); // Comfort noise.
174 break; 188 break;
175 } 189 }
176 } 190 }
177 191
178 // When Opus is in DTX, it wakes up in a regular basis. It sends two packets, 192 // When Opus is in DTX, it wakes up in a regular basis. It sends two packets,
179 // one with an arbitrary size and the other of 1-byte, then stops sending for 193 // one with an arbitrary size and the other of 1-byte, then stops sending for
180 // 19 frames. 194 // 19 frames. We run 10 second of pure silence, which is about 25 cycles
181 const int cycles = 5; 195 // (420 ms/cycle).
182 for (int j = 0; j < cycles; ++j) { 196 const int kCycles = 24;
197
198 // We check that, after a certain cycles (given that the CNG in Opus needs
199 // time to adapt), the values of DTX decoded signal are bounded by [-1, 1].
200 const int kOutputValueCheckCycle = 18;
201 const uint16_t kOutputValueBound = 1;
202
203 for (int j = 0; j < kCycles; ++j) {
183 // DTX mode is maintained 19 frames. 204 // DTX mode is maintained 19 frames.
184 for (int i = 0; i < 19; ++i) { 205 for (int i = 0; i < 19; ++i) {
185 EXPECT_EQ(kOpus20msFrameSamples, 206 EXPECT_EQ(kOpus20msFrameSamples,
186 static_cast<size_t>(EncodeDecode( 207 static_cast<size_t>(EncodeDecode(
187 opus_encoder_, silence, kOpus20msFrameSamples, 208 opus_encoder_, silence, kOpus20msFrameSamples,
188 opus_decoder_, output_data_decode, &audio_type))); 209 opus_decoder_, output_data_decode, &audio_type)));
189 if (dtx) { 210 if (dtx) {
190 EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte. 211 EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte.
191 << "Opus should have entered DTX mode."; 212 << "Opus should have entered DTX mode.";
192 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); 213 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
193 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); 214 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
194 EXPECT_EQ(2, audio_type); // Comfort noise. 215 EXPECT_EQ(2, audio_type); // Comfort noise.
216 if (j >= kOutputValueCheckCycle) {
217 CheckAudioBounded(output_data_decode, kOpus20msFrameSamples,
218 channels_, kOutputValueBound);
219 }
195 } else { 220 } else {
196 EXPECT_GT(encoded_bytes_, 1U); 221 EXPECT_GT(encoded_bytes_, 1U);
197 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); 222 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
198 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); 223 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
199 EXPECT_EQ(0, audio_type); // Speech. 224 EXPECT_EQ(0, audio_type); // Speech.
200 } 225 }
201 } 226 }
202 227
203 // Quit DTX after 19 frames. 228 // Quit DTX after 19 frames.
204 EXPECT_EQ(kOpus20msFrameSamples, 229 EXPECT_EQ(kOpus20msFrameSamples,
205 static_cast<size_t>(EncodeDecode( 230 static_cast<size_t>(EncodeDecode(
206 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, 231 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_,
207 output_data_decode, &audio_type))); 232 output_data_decode, &audio_type)));
208 233
209 EXPECT_GT(encoded_bytes_, 1U); 234 EXPECT_GT(encoded_bytes_, 1U);
210 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); 235 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
211 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); 236 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
212 EXPECT_EQ(0, audio_type); // Speech. 237 EXPECT_EQ(0, audio_type); // Speech.
213 238
214 // Enters DTX again immediately. 239 // Enters DTX again immediately.
215 EXPECT_EQ(kOpus20msFrameSamples, 240 EXPECT_EQ(kOpus20msFrameSamples,
216 static_cast<size_t>(EncodeDecode( 241 static_cast<size_t>(EncodeDecode(
217 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, 242 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_,
218 output_data_decode, &audio_type))); 243 output_data_decode, &audio_type)));
219 if (dtx) { 244 if (dtx) {
220 EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte. 245 EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte.
221 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); 246 EXPECT_EQ(1, opus_encoder_->in_dtx_mode);
222 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); 247 EXPECT_EQ(1, opus_decoder_->in_dtx_mode);
223 EXPECT_EQ(2, audio_type); // Comfort noise. 248 EXPECT_EQ(2, audio_type); // Comfort noise.
249 if (j >= kOutputValueCheckCycle) {
250 CheckAudioBounded(output_data_decode, kOpus20msFrameSamples,
251 channels_, kOutputValueBound);
252 }
224 } else { 253 } else {
225 EXPECT_GT(encoded_bytes_, 1U); 254 EXPECT_GT(encoded_bytes_, 1U);
226 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); 255 EXPECT_EQ(0, opus_encoder_->in_dtx_mode);
227 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); 256 EXPECT_EQ(0, opus_decoder_->in_dtx_mode);
228 EXPECT_EQ(0, audio_type); // Speech. 257 EXPECT_EQ(0, audio_type); // Speech.
229 } 258 }
230 } 259 }
231 260
232 silence[0] = 10000; 261 silence[0] = 10000;
233 if (dtx) { 262 if (dtx) {
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); 646 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
618 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); 647 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
619 } 648 }
620 649
621 INSTANTIATE_TEST_CASE_P(VariousMode, 650 INSTANTIATE_TEST_CASE_P(VariousMode,
622 OpusTest, 651 OpusTest,
623 Combine(Values(1, 2), Values(0, 1))); 652 Combine(Values(1, 2), Values(0, 1)));
624 653
625 654
626 } // namespace webrtc 655 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698