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 
16 namespace webrtc {
17 
18 enum {
19   kSidShortIntervalUpdate = 1,
20   kSidNormalIntervalUpdate = 100,
21   kSidLongIntervalUpdate = 10000
22 };
23 
24 enum {
25   kCNGNumParamsLow = 0,
26   kCNGNumParamsNormal = 8,
27   kCNGNumParamsHigh = WEBRTC_CNG_MAX_LPC_ORDER,
28   kCNGNumParamsTooHigh = WEBRTC_CNG_MAX_LPC_ORDER + 1
29 };
30 
31 enum {
32   kNoSid,
33   kForceSid
34 };
35 
36 class 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 
46 CngTest::CngTest()
47     : cng_enc_inst_(NULL),
48       cng_dec_inst_(NULL) {
49 }
50 
51 void 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.
64 TEST_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.
71 TEST_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.
82 TEST_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 
100 TEST_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.
152 TEST_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.
171 TEST_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.
188 TEST_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.
225 TEST_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.
261 TEST_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.
295 TEST_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.
322 TEST_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