• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #include "tensorflow/core/lib/wav/wav_io.h"
17 
18 #include <string>
19 
20 #include "tensorflow/core/lib/core/status_test_util.h"
21 #include "tensorflow/core/lib/strings/str_util.h"
22 #include "tensorflow/core/platform/test.h"
23 #include "tensorflow/core/platform/types.h"
24 #include "tensorflow/core/protobuf/error_codes.pb.h"
25 
26 namespace tensorflow {
27 namespace wav {
28 
29 // These are defined in wav_io.cc, and the signatures are here so we don't have
30 // to expose them in the public header.
31 Status ExpectText(const string& data, const string& expected_text, int* offset);
32 Status ReadString(const string& data, int expected_length, string* value,
33                   int* offset);
34 
TEST(WavIO,BadArguments)35 TEST(WavIO, BadArguments) {
36   float audio[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f};
37   tstring result;
38 
39   EXPECT_EQ(error::INVALID_ARGUMENT,
40             EncodeAudioAsS16LEWav(nullptr, 44100, 2, 3, &result).code());
41   TF_EXPECT_OK(EncodeAudioAsS16LEWav(nullptr, 44100, 2, 0, &result));
42 
43   EXPECT_EQ(
44       error::INVALID_ARGUMENT,
45       EncodeAudioAsS16LEWav(audio, 44100, 2, 3, (tstring*)nullptr).code());
46 
47   const size_t kuint32max_plus_one = static_cast<size_t>(kuint32max) + 1;
48   const size_t kuint16max_plus_one = static_cast<size_t>(kuint16max) + 1;
49 
50   // Zero values are invalid.
51   EXPECT_EQ(error::INVALID_ARGUMENT,
52             EncodeAudioAsS16LEWav(audio, 0, 2, 3, &result).code());
53   EXPECT_EQ(error::INVALID_ARGUMENT,
54             EncodeAudioAsS16LEWav(audio, 44100, 0, 3, &result).code());
55 
56   // Sample rates 2^32 and greater are invalid.
57   EXPECT_EQ(
58       error::INVALID_ARGUMENT,
59       EncodeAudioAsS16LEWav(audio, kuint32max_plus_one, 2, 3, &result).code());
60 
61   // Channels 2^16 and greater are invalid.
62   EXPECT_EQ(error::INVALID_ARGUMENT,
63             EncodeAudioAsS16LEWav(audio, 44100, kuint16max_plus_one, 3, &result)
64                 .code());
65 
66   // Frames that push the file size above 2^32 are invalid.
67   EXPECT_EQ(error::INVALID_ARGUMENT,
68             EncodeAudioAsS16LEWav(audio, 44100, 2, 1073741813, &result).code());
69 }
70 
TEST(WavIO,BasicEven)71 TEST(WavIO, BasicEven) {
72   float audio[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f};
73   string result;
74   TF_EXPECT_OK(EncodeAudioAsS16LEWav(audio, 44100, 2, 3, &result));
75   EXPECT_EQ(56, result.size());
76   TF_EXPECT_OK(EncodeAudioAsS16LEWav(audio, 22050, 1, 6, &result));
77   EXPECT_EQ(56, result.size());
78   TF_EXPECT_OK(EncodeAudioAsS16LEWav(audio, 8000, 1, 6, &result));
79   EXPECT_EQ(56, result.size());
80 }
81 
TEST(WavIO,BasicOdd)82 TEST(WavIO, BasicOdd) {
83   float audio[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f};
84   string result;
85   TF_EXPECT_OK(EncodeAudioAsS16LEWav(audio, 22050, 1, 5, &result));
86   EXPECT_EQ(54, result.size());
87 }
88 
TEST(WavIO,EncodeThenDecode)89 TEST(WavIO, EncodeThenDecode) {
90   float audio[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f};
91   string wav_data;
92   TF_ASSERT_OK(EncodeAudioAsS16LEWav(audio, 44100, 2, 3, &wav_data));
93   std::vector<float> decoded_audio;
94   uint32 decoded_sample_count;
95   uint16 decoded_channel_count;
96   uint32 decoded_sample_rate;
97   TF_ASSERT_OK(DecodeLin16WaveAsFloatVector(
98       wav_data, &decoded_audio, &decoded_sample_count, &decoded_channel_count,
99       &decoded_sample_rate));
100   EXPECT_EQ(2, decoded_channel_count);
101   EXPECT_EQ(3, decoded_sample_count);
102   EXPECT_EQ(44100, decoded_sample_rate);
103   for (int i = 0; i < 6; ++i) {
104     EXPECT_NEAR(audio[i], decoded_audio[i], 1e-4f) << "i=" << i;
105   }
106 }
107 
TEST(WavIO,BasicMono)108 TEST(WavIO, BasicMono) {
109   std::vector<uint8> wav_data = {
110       'R', 'I', 'F', 'F',  // ChunkID
111       44, 0, 0, 0,         // ChunkSize: 36 + SubChunk2Size
112       'W', 'A', 'V', 'E',  // Format
113       'f', 'm', 't', ' ',  // Subchunk1ID
114       16, 0, 0, 0,         // Subchunk1Size
115       1, 0,                // AudioFormat: 1=PCM
116       1, 0,                // NumChannels
117       0x44, 0xac, 0, 0,    // SampleRate: 44100
118       0x88, 0x58, 0x1, 0,  // BytesPerSecond: SampleRate * NumChannels *
119                            //                 BitsPerSample/8
120       2, 0,                // BytesPerSample: NumChannels * BitsPerSample/8
121       16, 0,               // BitsPerSample
122       'd', 'a', 't', 'a',  // Subchunk2ID
123       8, 0, 0, 0,          // Subchunk2Size: NumSamples * NumChannels *
124                            //                BitsPerSample/8
125       0, 0,                // Sample 1: 0
126       0xff, 0x7f,          // Sample 2: 32767 (saturated)
127       0, 0,                // Sample 3: 0
128       0x00, 0x80,          // Sample 4: -32768 (saturated)
129   };
130   string expected(wav_data.begin(), wav_data.end());
131   float audio[] = {0.0f, 1.0f, 0.0f, -1.0f};
132   string result;
133   TF_EXPECT_OK(EncodeAudioAsS16LEWav(audio, 44100, 1, 4, &result));
134   EXPECT_EQ(expected, result);
135 }
136 
TEST(WavIO,BasicStereo)137 TEST(WavIO, BasicStereo) {
138   std::vector<uint8> wav_data = {
139       'R', 'I', 'F', 'F',  // ChunkID
140       44, 0, 0, 0,         // ChunkSize: 36 + SubChunk2Size
141       'W', 'A', 'V', 'E',  // Format
142       'f', 'm', 't', ' ',  // Subchunk1ID
143       16, 0, 0, 0,         // Subchunk1Size
144       1, 0,                // AudioFormat: 1=PCM
145       2, 0,                // NumChannels
146       0x44, 0xac, 0, 0,    // SampleRate: 44100
147       0x10, 0xb1, 0x2, 0,  // BytesPerSecond: SampleRate * NumChannels *
148                            //                 BitsPerSample/8
149       4, 0,                // BytesPerSample: NumChannels * BitsPerSample/8
150       16, 0,               // BitsPerSample
151       'd', 'a', 't', 'a',  // Subchunk2ID
152       8, 0, 0, 0,          // Subchunk2Size: NumSamples * NumChannels *
153                            //                BitsPerSample/8
154       0, 0,                // Sample 1: 0
155       0xff, 0x7f,          // Sample 2: 32767 (saturated)
156       0, 0,                // Sample 3: 0
157       0x00, 0x80,          // Sample 4: -32768 (saturated)
158   };
159   string expected(wav_data.begin(), wav_data.end());
160   float audio[] = {0.0f, 1.0f, 0.0f, -1.0f};
161   string result;
162   TF_EXPECT_OK(EncodeAudioAsS16LEWav(audio, 44100, 2, 2, &result));
163   EXPECT_EQ(expected, result);
164 }
165 
166 // Test how chunk sizes larger than 2GB are handled, since they're stored as
167 // unsigned int32s, so there are lots of ways for conversions to confuse the
168 // decoding logic. The expected behavior is to fail with an error, since such
169 // large WAV files are not common, and are unsupported by many readers.
170 // See b/72655902.
TEST(WavIO,ChunkSizeOverflow)171 TEST(WavIO, ChunkSizeOverflow) {
172   std::vector<uint8> wav_data = {
173       'R', 'I', 'F', 'F',      // ChunkID
174       60, 0, 0, 0,             // ChunkSize: 36 + SubChunk2Size
175       'W', 'A', 'V', 'E',      // Format
176       'f', 'm', 't', ' ',      // Subchunk1ID
177       16, 0, 0, 0,             // Subchunk1Size
178       1, 0,                    // AudioFormat: 1=PCM
179       1, 0,                    // NumChannels
180       0x44, 0xac, 0, 0,        // SampleRate: 44100
181       0x88, 0x58, 0x1, 0,      // BytesPerSecond: SampleRate * NumChannels *
182                                //                 BitsPerSample/8
183       2, 0,                    // BytesPerSample: NumChannels * BitsPerSample/8
184       16, 0,                   // BitsPerSample
185       'd', 'a', 't', 'a',      // Subchunk2ID
186       8, 0, 0, 0,              // Subchunk2Size: NumSamples * NumChannels *
187                                //                BitsPerSample/8
188       0, 0,                    // Sample 1: 0
189       0xff, 0x7f,              // Sample 2: 32767 (saturated)
190       0, 0,                    // Sample 3: 0
191       0x00, 0x80,              // Sample 4: -32768 (saturated)
192       'f', 'o', 'o', 'o',      // Subchunk2ID
193       0xff, 0xff, 0xff, 0xf8,  // Chunk size that could cause an infinite loop.
194       0, 0,                    // Sample 1: 0
195       0xff, 0x7f,              // Sample 2: 32767 (saturated)
196       0, 0,                    // Sample 3: 0
197       0x00, 0x80,              // Sample 4: -32768 (saturated)
198   };
199   string wav_data_string(wav_data.begin(), wav_data.end());
200   std::vector<float> decoded_audio;
201   uint32 decoded_sample_count;
202   uint16 decoded_channel_count;
203   uint32 decoded_sample_rate;
204   Status decode_status = DecodeLin16WaveAsFloatVector(
205       wav_data_string, &decoded_audio, &decoded_sample_count,
206       &decoded_channel_count, &decoded_sample_rate);
207   EXPECT_FALSE(decode_status.ok());
208   EXPECT_TRUE(absl::StrContains(decode_status.error_message(), "too large"))
209       << decode_status.error_message();
210 }
211 
TEST(WavIO,IncrementOffset)212 TEST(WavIO, IncrementOffset) {
213   int new_offset = -1;
214   TF_EXPECT_OK(IncrementOffset(0, 10, 20, &new_offset));
215   EXPECT_EQ(10, new_offset);
216 
217   new_offset = -1;
218   TF_EXPECT_OK(IncrementOffset(10, 4, 20, &new_offset));
219   EXPECT_EQ(14, new_offset);
220 
221   new_offset = -1;
222   TF_EXPECT_OK(IncrementOffset(99, 1, 100, &new_offset));
223   EXPECT_EQ(100, new_offset);
224 
225   new_offset = -1;
226   EXPECT_FALSE(IncrementOffset(-1, 1, 100, &new_offset).ok());
227 
228   new_offset = -1;
229   EXPECT_FALSE(IncrementOffset(0, -1, 100, &new_offset).ok());
230 
231   new_offset = -1;
232   EXPECT_FALSE(IncrementOffset(std::numeric_limits<int>::max(), 1,
233                                std::numeric_limits<int>::max(), &new_offset)
234                    .ok());
235 
236   new_offset = -1;
237   EXPECT_FALSE(IncrementOffset(101, 1, 100, &new_offset).ok());
238 }
239 
TEST(WavIO,ExpectText)240 TEST(WavIO, ExpectText) {
241   std::vector<uint8> test_data = {
242       'E', 'x', 'p', 'e', 'c', 't', 'e', 'd',
243   };
244   string test_string(test_data.begin(), test_data.end());
245 
246   int offset = 0;
247   TF_EXPECT_OK(ExpectText(test_string, "Expected", &offset));
248   EXPECT_EQ(8, offset);
249 
250   offset = 0;
251   Status expect_status = ExpectText(test_string, "Unexpected", &offset);
252   EXPECT_FALSE(expect_status.ok());
253 
254   offset = 0;
255   TF_EXPECT_OK(ExpectText(test_string, "Exp", &offset));
256   EXPECT_EQ(3, offset);
257   TF_EXPECT_OK(ExpectText(test_string, "ected", &offset));
258   EXPECT_EQ(8, offset);
259   expect_status = ExpectText(test_string, "foo", &offset);
260   EXPECT_FALSE(expect_status.ok());
261 }
262 
TEST(WavIO,ReadString)263 TEST(WavIO, ReadString) {
264   std::vector<uint8> test_data = {
265       'E', 'x', 'p', 'e', 'c', 't', 'e', 'd',
266   };
267   string test_string(test_data.begin(), test_data.end());
268 
269   int offset = 0;
270   string read_value;
271   TF_EXPECT_OK(ReadString(test_string, 2, &read_value, &offset));
272   EXPECT_EQ("Ex", read_value);
273   EXPECT_EQ(2, offset);
274 
275   TF_EXPECT_OK(ReadString(test_string, 6, &read_value, &offset));
276   EXPECT_EQ("pected", read_value);
277   EXPECT_EQ(8, offset);
278 
279   Status read_status = ReadString(test_string, 3, &read_value, &offset);
280   EXPECT_FALSE(read_status.ok());
281 }
282 
TEST(WavIO,ReadValueInt8)283 TEST(WavIO, ReadValueInt8) {
284   std::vector<uint8> test_data = {0x00, 0x05, 0xff, 0x80};
285   string test_string(test_data.begin(), test_data.end());
286 
287   int offset = 0;
288   int8_t read_value;
289   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
290   EXPECT_EQ(0, read_value);
291   EXPECT_EQ(1, offset);
292 
293   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
294   EXPECT_EQ(5, read_value);
295   EXPECT_EQ(2, offset);
296 
297   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
298   EXPECT_EQ(-1, read_value);
299   EXPECT_EQ(3, offset);
300 
301   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
302   EXPECT_EQ(-128, read_value);
303   EXPECT_EQ(4, offset);
304 
305   Status read_status = ReadValue(test_string, &read_value, &offset);
306   EXPECT_FALSE(read_status.ok());
307 }
308 
TEST(WavIO,ReadValueUInt8)309 TEST(WavIO, ReadValueUInt8) {
310   std::vector<uint8> test_data = {0x00, 0x05, 0xff, 0x80};
311   string test_string(test_data.begin(), test_data.end());
312 
313   int offset = 0;
314   uint8 read_value;
315   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
316   EXPECT_EQ(0, read_value);
317   EXPECT_EQ(1, offset);
318 
319   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
320   EXPECT_EQ(5, read_value);
321   EXPECT_EQ(2, offset);
322 
323   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
324   EXPECT_EQ(255, read_value);
325   EXPECT_EQ(3, offset);
326 
327   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
328   EXPECT_EQ(128, read_value);
329   EXPECT_EQ(4, offset);
330 
331   Status read_status = ReadValue(test_string, &read_value, &offset);
332   EXPECT_FALSE(read_status.ok());
333 }
334 
TEST(WavIO,ReadValueInt16)335 TEST(WavIO, ReadValueInt16) {
336   std::vector<uint8> test_data = {
337       0x00, 0x00,  // 0
338       0xff, 0x00,  // 255
339       0x00, 0x01,  // 256
340       0xff, 0xff,  // -1
341       0x00, 0x80,  // -32768
342   };
343   string test_string(test_data.begin(), test_data.end());
344 
345   int offset = 0;
346   int16_t read_value;
347   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
348   EXPECT_EQ(0, read_value);
349   EXPECT_EQ(2, offset);
350 
351   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
352   EXPECT_EQ(255, read_value);
353   EXPECT_EQ(4, offset);
354 
355   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
356   EXPECT_EQ(256, read_value);
357   EXPECT_EQ(6, offset);
358 
359   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
360   EXPECT_EQ(-1, read_value);
361   EXPECT_EQ(8, offset);
362 
363   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
364   EXPECT_EQ(-32768, read_value);
365   EXPECT_EQ(10, offset);
366 
367   Status read_status = ReadValue(test_string, &read_value, &offset);
368   EXPECT_FALSE(read_status.ok());
369 }
370 
TEST(WavIO,ReadValueUInt16)371 TEST(WavIO, ReadValueUInt16) {
372   std::vector<uint8> test_data = {
373       0x00, 0x00,  // 0
374       0xff, 0x00,  // 255
375       0x00, 0x01,  // 256
376       0xff, 0xff,  // 65535
377       0x00, 0x80,  // 32768
378   };
379   string test_string(test_data.begin(), test_data.end());
380 
381   int offset = 0;
382   uint16 read_value;
383   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
384   EXPECT_EQ(0, read_value);
385   EXPECT_EQ(2, offset);
386 
387   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
388   EXPECT_EQ(255, read_value);
389   EXPECT_EQ(4, offset);
390 
391   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
392   EXPECT_EQ(256, read_value);
393   EXPECT_EQ(6, offset);
394 
395   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
396   EXPECT_EQ(65535, read_value);
397   EXPECT_EQ(8, offset);
398 
399   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
400   EXPECT_EQ(32768, read_value);
401   EXPECT_EQ(10, offset);
402 
403   Status read_status = ReadValue(test_string, &read_value, &offset);
404   EXPECT_FALSE(read_status.ok());
405 }
406 
TEST(WavIO,ReadValueInt32)407 TEST(WavIO, ReadValueInt32) {
408   std::vector<uint8> test_data = {
409       0x00, 0x00, 0x00, 0x00,  // 0
410       0xff, 0x00, 0x00, 0x00,  // 255
411       0x00, 0xff, 0x00, 0x00,  // 65280
412       0x00, 0x00, 0xff, 0x00,  // 16,711,680
413       0xff, 0xff, 0xff, 0xff,  // -1
414   };
415   string test_string(test_data.begin(), test_data.end());
416 
417   int offset = 0;
418   int32_t read_value;
419   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
420   EXPECT_EQ(0, read_value);
421   EXPECT_EQ(4, offset);
422 
423   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
424   EXPECT_EQ(255, read_value);
425   EXPECT_EQ(8, offset);
426 
427   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
428   EXPECT_EQ(65280, read_value);
429   EXPECT_EQ(12, offset);
430 
431   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
432   EXPECT_EQ(16711680, read_value);
433   EXPECT_EQ(16, offset);
434 
435   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
436   EXPECT_EQ(-1, read_value);
437   EXPECT_EQ(20, offset);
438 
439   Status read_status = ReadValue(test_string, &read_value, &offset);
440   EXPECT_FALSE(read_status.ok());
441 }
442 
TEST(WavIO,ReadValueUInt32)443 TEST(WavIO, ReadValueUInt32) {
444   std::vector<uint8> test_data = {
445       0x00, 0x00, 0x00, 0x00,  // 0
446       0xff, 0x00, 0x00, 0x00,  // 255
447       0x00, 0xff, 0x00, 0x00,  // 65280
448       0x00, 0x00, 0xff, 0x00,  // 16,711,680
449       0xff, 0xff, 0xff, 0xff,  // 4,294,967,295
450   };
451   string test_string(test_data.begin(), test_data.end());
452 
453   int offset = 0;
454   uint32 read_value;
455   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
456   EXPECT_EQ(0, read_value);
457   EXPECT_EQ(4, offset);
458 
459   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
460   EXPECT_EQ(255, read_value);
461   EXPECT_EQ(8, offset);
462 
463   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
464   EXPECT_EQ(65280, read_value);
465   EXPECT_EQ(12, offset);
466 
467   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
468   EXPECT_EQ(16711680, read_value);
469   EXPECT_EQ(16, offset);
470 
471   TF_EXPECT_OK(ReadValue(test_string, &read_value, &offset));
472   EXPECT_EQ(4294967295, read_value);
473   EXPECT_EQ(20, offset);
474 
475   Status read_status = ReadValue(test_string, &read_value, &offset);
476   EXPECT_FALSE(read_status.ok());
477 }
478 
479 }  // namespace wav
480 }  // namespace tensorflow
481