1/* 2 * Copyright (c) 2011 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#include <string> 11 12#include "testing/gtest/include/gtest/gtest.h" 13#include "webrtc/test/testsupport/fileutils.h" 14#include "webrtc_cng.h" 15 16namespace webrtc { 17 18enum { 19 kSidShortIntervalUpdate = 1, 20 kSidNormalIntervalUpdate = 100, 21 kSidLongIntervalUpdate = 10000 22}; 23 24enum { 25 kCNGNumParamsLow = 0, 26 kCNGNumParamsNormal = 8, 27 kCNGNumParamsHigh = WEBRTC_CNG_MAX_LPC_ORDER, 28 kCNGNumParamsTooHigh = WEBRTC_CNG_MAX_LPC_ORDER + 1 29}; 30 31enum { 32 kNoSid, 33 kForceSid 34}; 35 36class CngTest : public ::testing::Test { 37 protected: 38 CngTest(); 39 virtual void SetUp(); 40 41 CNG_enc_inst* cng_enc_inst_; 42 CNG_dec_inst* cng_dec_inst_; 43 int16_t speech_data_[640]; // Max size of CNG internal buffers. 44}; 45 46CngTest::CngTest() 47 : cng_enc_inst_(NULL), 48 cng_dec_inst_(NULL) { 49} 50 51void CngTest::SetUp() { 52 FILE* input_file; 53 const std::string file_name = 54 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); 55 input_file = fopen(file_name.c_str(), "rb"); 56 ASSERT_TRUE(input_file != NULL); 57 ASSERT_EQ(640, static_cast<int32_t>(fread(speech_data_, sizeof(int16_t), 58 640, input_file))); 59 fclose(input_file); 60 input_file = NULL; 61} 62 63// Test failing Create. 64TEST_F(CngTest, CngCreateFail) { 65 // Test to see that an invalid pointer is caught. 66 EXPECT_EQ(-1, WebRtcCng_CreateEnc(NULL)); 67 EXPECT_EQ(-1, WebRtcCng_CreateDec(NULL)); 68} 69 70// Test normal Create. 71TEST_F(CngTest, CngCreate) { 72 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 73 EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); 74 EXPECT_TRUE(cng_enc_inst_ != NULL); 75 EXPECT_TRUE(cng_dec_inst_ != NULL); 76 // Free encoder and decoder memory. 77 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 78 EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); 79} 80 81// Create CNG encoder, init with faulty values, free CNG encoder. 82TEST_F(CngTest, CngInitFail) { 83 // Create encoder memory. 84 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 85 86 // Call with too few parameters. 87 EXPECT_EQ(-1, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, 88 kCNGNumParamsLow)); 89 EXPECT_EQ(6130, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); 90 91 // Call with too many parameters. 92 EXPECT_EQ(-1, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, 93 kCNGNumParamsTooHigh)); 94 EXPECT_EQ(6130, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); 95 96 // Free encoder memory. 97 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 98} 99 100TEST_F(CngTest, CngEncode) { 101 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 102 int16_t number_bytes; 103 104 // Create encoder memory. 105 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 106 107 // 8 kHz, Normal number of parameters 108 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, 109 kCNGNumParamsNormal)); 110 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 80, sid_data, 111 &number_bytes, kNoSid)); 112 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 113 cng_enc_inst_, speech_data_, 80, sid_data, &number_bytes, kForceSid)); 114 115 // 16 kHz, Normal number of parameters 116 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, 117 kCNGNumParamsNormal)); 118 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, 119 &number_bytes, kNoSid)); 120 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 121 cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); 122 123 // 32 kHz, Max number of parameters 124 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 32000, kSidNormalIntervalUpdate, 125 kCNGNumParamsHigh)); 126 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 320, sid_data, 127 &number_bytes, kNoSid)); 128 EXPECT_EQ(kCNGNumParamsHigh + 1, WebRtcCng_Encode( 129 cng_enc_inst_, speech_data_, 320, sid_data, &number_bytes, kForceSid)); 130 131 // 48 kHz, Normal number of parameters 132 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 48000, kSidNormalIntervalUpdate, 133 kCNGNumParamsNormal)); 134 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 480, sid_data, 135 &number_bytes, kNoSid)); 136 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 137 cng_enc_inst_, speech_data_, 480, sid_data, &number_bytes, kForceSid)); 138 139 // 64 kHz, Normal number of parameters 140 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 64000, kSidNormalIntervalUpdate, 141 kCNGNumParamsNormal)); 142 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 640, sid_data, 143 &number_bytes, kNoSid)); 144 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 145 cng_enc_inst_, speech_data_, 640, sid_data, &number_bytes, kForceSid)); 146 147 // Free encoder memory. 148 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 149} 150 151// Encode Cng with too long input vector. 152TEST_F(CngTest, CngEncodeTooLong) { 153 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 154 int16_t number_bytes; 155 156 // Create and init encoder memory. 157 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 158 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate, 159 kCNGNumParamsNormal)); 160 161 // Run encoder with too much data. 162 EXPECT_EQ(-1, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 641, sid_data, 163 &number_bytes, kNoSid)); 164 EXPECT_EQ(6140, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); 165 166 // Free encoder memory. 167 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 168} 169 170// Call encode without calling init. 171TEST_F(CngTest, CngEncodeNoInit) { 172 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 173 int16_t number_bytes; 174 175 // Create encoder memory. 176 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 177 178 // Run encoder without calling init. 179 EXPECT_EQ(-1, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 640, sid_data, 180 &number_bytes, kNoSid)); 181 EXPECT_EQ(6120, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_)); 182 183 // Free encoder memory. 184 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 185} 186 187// Update SID parameters, for both 9 and 16 parameters. 188TEST_F(CngTest, CngUpdateSid) { 189 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 190 int16_t number_bytes; 191 192 // Create and initialize encoder and decoder memory. 193 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 194 EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); 195 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, 196 kCNGNumParamsNormal)); 197 EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_)); 198 199 // Run normal Encode and UpdateSid. 200 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 201 cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); 202 EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, 203 kCNGNumParamsNormal + 1)); 204 205 // Reinit with new length. 206 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, 207 kCNGNumParamsHigh)); 208 EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_)); 209 210 // Expect 0 because of unstable parameters after switching length. 211 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, 212 &number_bytes, kForceSid)); 213 EXPECT_EQ(kCNGNumParamsHigh + 1, WebRtcCng_Encode( 214 cng_enc_inst_, speech_data_ + 160, 160, sid_data, &number_bytes, 215 kForceSid)); 216 EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, 217 kCNGNumParamsNormal + 1)); 218 219 // Free encoder and decoder memory. 220 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 221 EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); 222} 223 224// Update SID parameters, with wrong parameters or without calling decode. 225TEST_F(CngTest, CngUpdateSidErroneous) { 226 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 227 int16_t number_bytes; 228 229 // Create encoder and decoder memory. 230 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 231 EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); 232 233 // Encode. 234 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, 235 kCNGNumParamsNormal)); 236 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 237 cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); 238 239 // Update Sid before initializing decoder. 240 EXPECT_EQ(-1, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, 241 kCNGNumParamsNormal + 1)); 242 EXPECT_EQ(6220, WebRtcCng_GetErrorCodeDec(cng_dec_inst_)); 243 244 // Initialize decoder. 245 EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_)); 246 247 // First run with valid parameters, then with too many CNG parameters. 248 // The function will operate correctly by only reading the maximum number of 249 // parameters, skipping the extra. 250 EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, 251 kCNGNumParamsNormal + 1)); 252 EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, 253 kCNGNumParamsTooHigh + 1)); 254 255 // Free encoder and decoder memory. 256 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 257 EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); 258} 259 260// Test to generate cng data, by forcing SID. Both normal and faulty condition. 261TEST_F(CngTest, CngGenerate) { 262 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 263 int16_t out_data[640]; 264 int16_t number_bytes; 265 266 // Create and initialize encoder and decoder memory. 267 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 268 EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); 269 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, 270 kCNGNumParamsNormal)); 271 EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_)); 272 273 // Normal Encode. 274 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 275 cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid)); 276 277 // Normal UpdateSid. 278 EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data, 279 kCNGNumParamsNormal + 1)); 280 281 // Two normal Generate, one with new_period. 282 EXPECT_EQ(0, WebRtcCng_Generate(cng_dec_inst_, out_data, 640, 1)); 283 EXPECT_EQ(0, WebRtcCng_Generate(cng_dec_inst_, out_data, 640, 0)); 284 285 // Call Genereate with too much data. 286 EXPECT_EQ(-1, WebRtcCng_Generate(cng_dec_inst_, out_data, 641, 0)); 287 EXPECT_EQ(6140, WebRtcCng_GetErrorCodeDec(cng_dec_inst_)); 288 289 // Free encoder and decoder memory. 290 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 291 EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); 292} 293 294// Test automatic SID. 295TEST_F(CngTest, CngAutoSid) { 296 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 297 int16_t number_bytes; 298 299 // Create and initialize encoder and decoder memory. 300 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 301 EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); 302 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate, 303 kCNGNumParamsNormal)); 304 EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_)); 305 306 // Normal Encode, 100 msec, where no SID data should be generated. 307 for (int i = 0; i < 10; i++) { 308 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, 309 &number_bytes, kNoSid)); 310 } 311 312 // We have reached 100 msec, and SID data should be generated. 313 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 314 cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kNoSid)); 315 316 // Free encoder and decoder memory. 317 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 318 EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); 319} 320 321// Test automatic SID, with very short interval. 322TEST_F(CngTest, CngAutoSidShort) { 323 uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 324 int16_t number_bytes; 325 326 // Create and initialize encoder and decoder memory. 327 EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_)); 328 EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_)); 329 EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidShortIntervalUpdate, 330 kCNGNumParamsNormal)); 331 EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_)); 332 333 // First call will never generate SID, unless forced to. 334 EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data, 335 &number_bytes, kNoSid)); 336 337 // Normal Encode, 100 msec, SID data should be generated all the time. 338 for (int i = 0; i < 10; i++) { 339 EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode( 340 cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kNoSid)); 341 } 342 343 // Free encoder and decoder memory. 344 EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_)); 345 EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_)); 346} 347 348} // namespace webrtc 349