1 /*
2 * Copyright (c) 2013 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_processing/transient/file_utils.h"
12
13 #include <string.h>
14 #include <string>
15
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/system_wrappers/include/file_wrapper.h"
19 #include "webrtc/test/testsupport/fileutils.h"
20 #include "webrtc/test/testsupport/gtest_disable.h"
21 #include "webrtc/typedefs.h"
22
23 namespace webrtc {
24
25 static const uint8_t kPiBytesf[4] = {0xDB, 0x0F, 0x49, 0x40};
26 static const uint8_t kEBytesf[4] = {0x54, 0xF8, 0x2D, 0x40};
27 static const uint8_t kAvogadroBytesf[4] = {0x2F, 0x0C, 0xFF, 0x66};
28
29 static const uint8_t kPiBytes[8] =
30 {0x18, 0x2D, 0x44, 0x54, 0xFB, 0x21, 0x09, 0x40};
31 static const uint8_t kEBytes[8] =
32 {0x69, 0x57, 0x14, 0x8B, 0x0A, 0xBF, 0x05, 0x40};
33 static const uint8_t kAvogadroBytes[8] =
34 {0xF4, 0xBC, 0xA8, 0xDF, 0x85, 0xE1, 0xDF, 0x44};
35
36 static const double kPi = 3.14159265358979323846;
37 static const double kE = 2.71828182845904523536;
38 static const double kAvogadro = 602214100000000000000000.0;
39
40 class TransientFileUtilsTest: public ::testing::Test {
41 protected:
TransientFileUtilsTest()42 TransientFileUtilsTest()
43 : kTestFileName(
44 test::ResourcePath("audio_processing/transient/double-utils",
45 "dat")),
46 kTestFileNamef(
47 test::ResourcePath("audio_processing/transient/float-utils",
48 "dat")) {}
49 // This file (used in some tests) contains binary data. The data correspond to
50 // the double representation of the constants: Pi, E, and the Avogadro's
51 // Number;
52 // appended in that order.
53 const std::string kTestFileName;
54
55 // This file (used in some tests) contains binary data. The data correspond to
56 // the float representation of the constants: Pi, E, and the Avogadro's
57 // Number;
58 // appended in that order.
59 const std::string kTestFileNamef;
60 };
61
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ConvertByteArrayToFloat))62 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ConvertByteArrayToFloat)) {
63 float value = 0.0;
64
65 EXPECT_EQ(0, ConvertByteArrayToFloat(kPiBytesf, &value));
66 EXPECT_FLOAT_EQ(kPi, value);
67
68 EXPECT_EQ(0, ConvertByteArrayToFloat(kEBytesf, &value));
69 EXPECT_FLOAT_EQ(kE, value);
70
71 EXPECT_EQ(0, ConvertByteArrayToFloat(kAvogadroBytesf, &value));
72 EXPECT_FLOAT_EQ(kAvogadro, value);
73 }
74
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ConvertByteArrayToDouble))75 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ConvertByteArrayToDouble)) {
76 double value = 0.0;
77
78 EXPECT_EQ(0, ConvertByteArrayToDouble(kPiBytes, &value));
79 EXPECT_DOUBLE_EQ(kPi, value);
80
81 EXPECT_EQ(0, ConvertByteArrayToDouble(kEBytes, &value));
82 EXPECT_DOUBLE_EQ(kE, value);
83
84 EXPECT_EQ(0, ConvertByteArrayToDouble(kAvogadroBytes, &value));
85 EXPECT_DOUBLE_EQ(kAvogadro, value);
86 }
87
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ConvertFloatToByteArray))88 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ConvertFloatToByteArray)) {
89 rtc::scoped_ptr<uint8_t[]> bytes(new uint8_t[4]);
90
91 EXPECT_EQ(0, ConvertFloatToByteArray(kPi, bytes.get()));
92 EXPECT_EQ(0, memcmp(bytes.get(), kPiBytesf, 4));
93
94 EXPECT_EQ(0, ConvertFloatToByteArray(kE, bytes.get()));
95 EXPECT_EQ(0, memcmp(bytes.get(), kEBytesf, 4));
96
97 EXPECT_EQ(0, ConvertFloatToByteArray(kAvogadro, bytes.get()));
98 EXPECT_EQ(0, memcmp(bytes.get(), kAvogadroBytesf, 4));
99 }
100
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ConvertDoubleToByteArray))101 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ConvertDoubleToByteArray)) {
102 rtc::scoped_ptr<uint8_t[]> bytes(new uint8_t[8]);
103
104 EXPECT_EQ(0, ConvertDoubleToByteArray(kPi, bytes.get()));
105 EXPECT_EQ(0, memcmp(bytes.get(), kPiBytes, 8));
106
107 EXPECT_EQ(0, ConvertDoubleToByteArray(kE, bytes.get()));
108 EXPECT_EQ(0, memcmp(bytes.get(), kEBytes, 8));
109
110 EXPECT_EQ(0, ConvertDoubleToByteArray(kAvogadro, bytes.get()));
111 EXPECT_EQ(0, memcmp(bytes.get(), kAvogadroBytes, 8));
112 }
113
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ReadInt16BufferFromFile))114 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ReadInt16BufferFromFile)) {
115 std::string test_filename = kTestFileName;
116
117 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
118
119 file->OpenFile(test_filename.c_str(),
120 true, // Read only.
121 true, // Loop.
122 false); // No text.
123 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
124 << kTestFileName.c_str();
125
126 const size_t kBufferLength = 12;
127 rtc::scoped_ptr<int16_t[]> buffer(new int16_t[kBufferLength]);
128
129 EXPECT_EQ(kBufferLength, ReadInt16BufferFromFile(file.get(),
130 kBufferLength,
131 buffer.get()));
132 EXPECT_EQ(22377, buffer[4]);
133 EXPECT_EQ(16389, buffer[7]);
134 EXPECT_EQ(17631, buffer[kBufferLength - 1]);
135
136 file->Rewind();
137
138 // The next test is for checking the case where there are not as much data as
139 // needed in the file, but reads to the end, and it returns the number of
140 // int16s read.
141 const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
142 buffer.reset(new int16_t[kBufferLenghtLargerThanFile]);
143 EXPECT_EQ(kBufferLength, ReadInt16BufferFromFile(file.get(),
144 kBufferLenghtLargerThanFile,
145 buffer.get()));
146 EXPECT_EQ(11544, buffer[0]);
147 EXPECT_EQ(22377, buffer[4]);
148 EXPECT_EQ(16389, buffer[7]);
149 EXPECT_EQ(17631, buffer[kBufferLength - 1]);
150 }
151
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ReadInt16FromFileToFloatBuffer))152 TEST_F(TransientFileUtilsTest,
153 DISABLED_ON_IOS(ReadInt16FromFileToFloatBuffer)) {
154 std::string test_filename = kTestFileName;
155
156 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
157
158 file->OpenFile(test_filename.c_str(),
159 true, // Read only.
160 true, // Loop.
161 false); // No text.
162 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
163 << kTestFileName.c_str();
164
165 const size_t kBufferLength = 12;
166 rtc::scoped_ptr<float[]> buffer(new float[kBufferLength]);
167
168 EXPECT_EQ(kBufferLength, ReadInt16FromFileToFloatBuffer(file.get(),
169 kBufferLength,
170 buffer.get()));
171
172 EXPECT_DOUBLE_EQ(11544, buffer[0]);
173 EXPECT_DOUBLE_EQ(22377, buffer[4]);
174 EXPECT_DOUBLE_EQ(16389, buffer[7]);
175 EXPECT_DOUBLE_EQ(17631, buffer[kBufferLength - 1]);
176
177 file->Rewind();
178
179 // The next test is for checking the case where there are not as much data as
180 // needed in the file, but reads to the end, and it returns the number of
181 // int16s read.
182 const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
183 buffer.reset(new float[kBufferLenghtLargerThanFile]);
184 EXPECT_EQ(kBufferLength,
185 ReadInt16FromFileToFloatBuffer(file.get(),
186 kBufferLenghtLargerThanFile,
187 buffer.get()));
188 EXPECT_DOUBLE_EQ(11544, buffer[0]);
189 EXPECT_DOUBLE_EQ(22377, buffer[4]);
190 EXPECT_DOUBLE_EQ(16389, buffer[7]);
191 EXPECT_DOUBLE_EQ(17631, buffer[kBufferLength - 1]);
192 }
193
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ReadInt16FromFileToDoubleBuffer))194 TEST_F(TransientFileUtilsTest,
195 DISABLED_ON_IOS(ReadInt16FromFileToDoubleBuffer)) {
196 std::string test_filename = kTestFileName;
197
198 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
199
200 file->OpenFile(test_filename.c_str(),
201 true, // Read only.
202 true, // Loop.
203 false); // No text.
204 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
205 << kTestFileName.c_str();
206
207 const size_t kBufferLength = 12;
208 rtc::scoped_ptr<double[]> buffer(new double[kBufferLength]);
209
210 EXPECT_EQ(kBufferLength, ReadInt16FromFileToDoubleBuffer(file.get(),
211 kBufferLength,
212 buffer.get()));
213 EXPECT_DOUBLE_EQ(11544, buffer[0]);
214 EXPECT_DOUBLE_EQ(22377, buffer[4]);
215 EXPECT_DOUBLE_EQ(16389, buffer[7]);
216 EXPECT_DOUBLE_EQ(17631, buffer[kBufferLength - 1]);
217
218 file->Rewind();
219
220 // The next test is for checking the case where there are not as much data as
221 // needed in the file, but reads to the end, and it returns the number of
222 // int16s read.
223 const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
224 buffer.reset(new double[kBufferLenghtLargerThanFile]);
225 EXPECT_EQ(kBufferLength,
226 ReadInt16FromFileToDoubleBuffer(file.get(),
227 kBufferLenghtLargerThanFile,
228 buffer.get()));
229 EXPECT_DOUBLE_EQ(11544, buffer[0]);
230 EXPECT_DOUBLE_EQ(22377, buffer[4]);
231 EXPECT_DOUBLE_EQ(16389, buffer[7]);
232 EXPECT_DOUBLE_EQ(17631, buffer[kBufferLength - 1]);
233 }
234
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ReadFloatBufferFromFile))235 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ReadFloatBufferFromFile)) {
236 std::string test_filename = kTestFileNamef;
237
238 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
239
240 file->OpenFile(test_filename.c_str(),
241 true, // Read only.
242 true, // Loop.
243 false); // No text.
244 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
245 << kTestFileNamef.c_str();
246
247 const size_t kBufferLength = 3;
248 rtc::scoped_ptr<float[]> buffer(new float[kBufferLength]);
249
250 EXPECT_EQ(kBufferLength, ReadFloatBufferFromFile(file.get(),
251 kBufferLength,
252 buffer.get()));
253 EXPECT_FLOAT_EQ(kPi, buffer[0]);
254 EXPECT_FLOAT_EQ(kE, buffer[1]);
255 EXPECT_FLOAT_EQ(kAvogadro, buffer[2]);
256
257 file->Rewind();
258
259 // The next test is for checking the case where there are not as much data as
260 // needed in the file, but reads to the end, and it returns the number of
261 // doubles read.
262 const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
263 buffer.reset(new float[kBufferLenghtLargerThanFile]);
264 EXPECT_EQ(kBufferLength, ReadFloatBufferFromFile(file.get(),
265 kBufferLenghtLargerThanFile,
266 buffer.get()));
267 EXPECT_FLOAT_EQ(kPi, buffer[0]);
268 EXPECT_FLOAT_EQ(kE, buffer[1]);
269 EXPECT_FLOAT_EQ(kAvogadro, buffer[2]);
270 }
271
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ReadDoubleBufferFromFile))272 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ReadDoubleBufferFromFile)) {
273 std::string test_filename = kTestFileName;
274
275 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
276
277 file->OpenFile(test_filename.c_str(),
278 true, // Read only.
279 true, // Loop.
280 false); // No text.
281 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
282 << kTestFileName.c_str();
283
284 const size_t kBufferLength = 3;
285 rtc::scoped_ptr<double[]> buffer(new double[kBufferLength]);
286
287 EXPECT_EQ(kBufferLength, ReadDoubleBufferFromFile(file.get(),
288 kBufferLength,
289 buffer.get()));
290 EXPECT_DOUBLE_EQ(kPi, buffer[0]);
291 EXPECT_DOUBLE_EQ(kE, buffer[1]);
292 EXPECT_DOUBLE_EQ(kAvogadro, buffer[2]);
293
294 file->Rewind();
295
296 // The next test is for checking the case where there are not as much data as
297 // needed in the file, but reads to the end, and it returns the number of
298 // doubles read.
299 const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
300 buffer.reset(new double[kBufferLenghtLargerThanFile]);
301 EXPECT_EQ(kBufferLength, ReadDoubleBufferFromFile(file.get(),
302 kBufferLenghtLargerThanFile,
303 buffer.get()));
304 EXPECT_DOUBLE_EQ(kPi, buffer[0]);
305 EXPECT_DOUBLE_EQ(kE, buffer[1]);
306 EXPECT_DOUBLE_EQ(kAvogadro, buffer[2]);
307 }
308
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (WriteInt16BufferToFile))309 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(WriteInt16BufferToFile)) {
310 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
311
312 std::string kOutFileName = test::TempFilename(test::OutputPath(),
313 "utils_test");
314
315 file->OpenFile(kOutFileName.c_str(),
316 false, // Write mode.
317 false, // No loop.
318 false); // No text.
319 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
320 << kOutFileName.c_str();
321
322 const size_t kBufferLength = 3;
323 rtc::scoped_ptr<int16_t[]> written_buffer(new int16_t[kBufferLength]);
324 rtc::scoped_ptr<int16_t[]> read_buffer(new int16_t[kBufferLength]);
325
326 written_buffer[0] = 1;
327 written_buffer[1] = 2;
328 written_buffer[2] = 3;
329
330 EXPECT_EQ(kBufferLength, WriteInt16BufferToFile(file.get(),
331 kBufferLength,
332 written_buffer.get()));
333
334 file->CloseFile();
335
336 file->OpenFile(kOutFileName.c_str(),
337 true, // Read only.
338 false, // No loop.
339 false); // No text.
340 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
341 << kOutFileName.c_str();
342
343 EXPECT_EQ(kBufferLength, ReadInt16BufferFromFile(file.get(),
344 kBufferLength,
345 read_buffer.get()));
346 EXPECT_EQ(0, memcmp(written_buffer.get(),
347 read_buffer.get(),
348 kBufferLength * sizeof(written_buffer[0])));
349 }
350
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (WriteFloatBufferToFile))351 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(WriteFloatBufferToFile)) {
352 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
353
354 std::string kOutFileName = test::TempFilename(test::OutputPath(),
355 "utils_test");
356
357 file->OpenFile(kOutFileName.c_str(),
358 false, // Write mode.
359 false, // No loop.
360 false); // No text.
361 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
362 << kOutFileName.c_str();
363
364 const size_t kBufferLength = 3;
365 rtc::scoped_ptr<float[]> written_buffer(new float[kBufferLength]);
366 rtc::scoped_ptr<float[]> read_buffer(new float[kBufferLength]);
367
368 written_buffer[0] = kPi;
369 written_buffer[1] = kE;
370 written_buffer[2] = kAvogadro;
371
372 EXPECT_EQ(kBufferLength, WriteFloatBufferToFile(file.get(),
373 kBufferLength,
374 written_buffer.get()));
375
376 file->CloseFile();
377
378 file->OpenFile(kOutFileName.c_str(),
379 true, // Read only.
380 false, // No loop.
381 false); // No text.
382 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
383 << kOutFileName.c_str();
384
385 EXPECT_EQ(kBufferLength, ReadFloatBufferFromFile(file.get(),
386 kBufferLength,
387 read_buffer.get()));
388 EXPECT_EQ(0, memcmp(written_buffer.get(),
389 read_buffer.get(),
390 kBufferLength * sizeof(written_buffer[0])));
391 }
392
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (WriteDoubleBufferToFile))393 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(WriteDoubleBufferToFile)) {
394 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
395
396 std::string kOutFileName = test::TempFilename(test::OutputPath(),
397 "utils_test");
398
399 file->OpenFile(kOutFileName.c_str(),
400 false, // Write mode.
401 false, // No loop.
402 false); // No text.
403 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
404 << kOutFileName.c_str();
405
406 const size_t kBufferLength = 3;
407 rtc::scoped_ptr<double[]> written_buffer(new double[kBufferLength]);
408 rtc::scoped_ptr<double[]> read_buffer(new double[kBufferLength]);
409
410 written_buffer[0] = kPi;
411 written_buffer[1] = kE;
412 written_buffer[2] = kAvogadro;
413
414 EXPECT_EQ(kBufferLength, WriteDoubleBufferToFile(file.get(),
415 kBufferLength,
416 written_buffer.get()));
417
418 file->CloseFile();
419
420 file->OpenFile(kOutFileName.c_str(),
421 true, // Read only.
422 false, // No loop.
423 false); // No text.
424 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
425 << kOutFileName.c_str();
426
427 EXPECT_EQ(kBufferLength, ReadDoubleBufferFromFile(file.get(),
428 kBufferLength,
429 read_buffer.get()));
430 EXPECT_EQ(0, memcmp(written_buffer.get(),
431 read_buffer.get(),
432 kBufferLength * sizeof(written_buffer[0])));
433 }
434
TEST_F(TransientFileUtilsTest,DISABLED_ON_IOS (ExpectedErrorReturnValues))435 TEST_F(TransientFileUtilsTest, DISABLED_ON_IOS(ExpectedErrorReturnValues)) {
436 std::string test_filename = kTestFileName;
437
438 double value;
439 rtc::scoped_ptr<int16_t[]> int16_buffer(new int16_t[1]);
440 rtc::scoped_ptr<double[]> double_buffer(new double[1]);
441 rtc::scoped_ptr<FileWrapper> file(FileWrapper::Create());
442
443 EXPECT_EQ(-1, ConvertByteArrayToDouble(NULL, &value));
444 EXPECT_EQ(-1, ConvertByteArrayToDouble(kPiBytes, NULL));
445
446 EXPECT_EQ(-1, ConvertDoubleToByteArray(kPi, NULL));
447
448 // Tests with file not opened.
449 EXPECT_EQ(0u, ReadInt16BufferFromFile(file.get(), 1, int16_buffer.get()));
450 EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(file.get(),
451 1,
452 double_buffer.get()));
453 EXPECT_EQ(0u, ReadDoubleBufferFromFile(file.get(), 1, double_buffer.get()));
454 EXPECT_EQ(0u, WriteInt16BufferToFile(file.get(), 1, int16_buffer.get()));
455 EXPECT_EQ(0u, WriteDoubleBufferToFile(file.get(), 1, double_buffer.get()));
456
457 file->OpenFile(test_filename.c_str(),
458 true, // Read only.
459 true, // Loop.
460 false); // No text.
461 ASSERT_TRUE(file->Open()) << "File could not be opened:\n"
462 << kTestFileName.c_str();
463
464 EXPECT_EQ(0u, ReadInt16BufferFromFile(NULL, 1, int16_buffer.get()));
465 EXPECT_EQ(0u, ReadInt16BufferFromFile(file.get(), 1, NULL));
466 EXPECT_EQ(0u, ReadInt16BufferFromFile(file.get(), 0, int16_buffer.get()));
467
468 EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(NULL, 1, double_buffer.get()));
469 EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(file.get(), 1, NULL));
470 EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(file.get(),
471 0,
472 double_buffer.get()));
473
474 EXPECT_EQ(0u, ReadDoubleBufferFromFile(NULL, 1, double_buffer.get()));
475 EXPECT_EQ(0u, ReadDoubleBufferFromFile(file.get(), 1, NULL));
476 EXPECT_EQ(0u, ReadDoubleBufferFromFile(file.get(), 0, double_buffer.get()));
477
478 EXPECT_EQ(0u, WriteInt16BufferToFile(NULL, 1, int16_buffer.get()));
479 EXPECT_EQ(0u, WriteInt16BufferToFile(file.get(), 1, NULL));
480 EXPECT_EQ(0u, WriteInt16BufferToFile(file.get(), 0, int16_buffer.get()));
481
482 EXPECT_EQ(0u, WriteDoubleBufferToFile(NULL, 1, double_buffer.get()));
483 EXPECT_EQ(0u, WriteDoubleBufferToFile(file.get(), 1, NULL));
484 EXPECT_EQ(0u, WriteDoubleBufferToFile(file.get(), 0, double_buffer.get()));
485 }
486
487 } // namespace webrtc
488
489