blob: 9efe96e3010c87393ee1b69f5f703d6d0aa670b2 [file] [log] [blame]
kwiberg@webrtc.org877083c2014-08-20 07:42:46 +00001/*
2 * Copyright (c) 2014 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// MSVC++ requires this to be set before any other includes to get M_PI.
12#define _USE_MATH_DEFINES
13
14#include <cmath>
15#include <limits>
16
17#include "testing/gtest/include/gtest/gtest.h"
18#include "webrtc/base/compile_assert.h"
19#include "webrtc/common_audio/wav_header.h"
20#include "webrtc/common_audio/wav_writer.h"
21#include "webrtc/test/testsupport/fileutils.h"
22
23static const float kSamples[] = {0.0, 10.0, 4e4, -1e9};
24
25// Write a tiny WAV file with the C++ interface and verify the result.
26TEST(WavWriterTest, CPP) {
27 const std::string outfile = webrtc::test::OutputPath() + "wavtest1.wav";
28 static const int kNumSamples = 3;
29 {
30 webrtc::WavFile w(outfile, 14099, 1);
31 w.WriteSamples(kSamples, kNumSamples);
32 }
33 static const uint8_t kExpectedContents[] = {
34 'R', 'I', 'F', 'F',
35 42, 0, 0, 0, // size of whole file - 8: 6 + 44 - 8
36 'W', 'A', 'V', 'E',
37 'f', 'm', 't', ' ',
38 16, 0, 0, 0, // size of fmt block - 8: 24 - 8
39 1, 0, // format: PCM (1)
40 1, 0, // channels: 1
41 0x13, 0x37, 0, 0, // sample rate: 14099
42 0x26, 0x6e, 0, 0, // byte rate: 2 * 14099
43 2, 0, // block align: NumChannels * BytesPerSample
44 16, 0, // bits per sample: 2 * 8
45 'd', 'a', 't', 'a',
46 6, 0, 0, 0, // size of payload: 6
47 0, 0, // first sample: 0.0
48 10, 0, // second sample: 10.0
49 0xff, 0x7f, // third sample: 4e4 (saturated)
50 };
51 static const int kContentSize =
52 webrtc::kWavHeaderSize + kNumSamples * sizeof(int16_t);
53 COMPILE_ASSERT(sizeof(kExpectedContents) == kContentSize, content_size);
54 EXPECT_EQ(size_t(kContentSize), webrtc::test::GetFileSize(outfile));
55 FILE* f = fopen(outfile.c_str(), "rb");
56 ASSERT_TRUE(f);
57 uint8_t contents[kContentSize];
58 ASSERT_EQ(1u, fread(contents, kContentSize, 1, f));
59 EXPECT_EQ(0, fclose(f));
60 EXPECT_EQ(0, memcmp(kExpectedContents, contents, kContentSize));
61}
62
63// Write a tiny WAV file with the C interface and verify the result.
64TEST(WavWriterTest, C) {
65 const std::string outfile = webrtc::test::OutputPath() + "wavtest2.wav";
66 rtc_WavFile *w = rtc_WavOpen(outfile.c_str(), 11904, 2);
67 static const int kNumSamples = 4;
68 rtc_WavWriteSamples(w, &kSamples[0], 2);
69 rtc_WavWriteSamples(w, &kSamples[2], kNumSamples - 2);
70 rtc_WavClose(w);
71 static const uint8_t kExpectedContents[] = {
72 'R', 'I', 'F', 'F',
73 44, 0, 0, 0, // size of whole file - 8: 8 + 44 - 8
74 'W', 'A', 'V', 'E',
75 'f', 'm', 't', ' ',
76 16, 0, 0, 0, // size of fmt block - 8: 24 - 8
77 1, 0, // format: PCM (1)
78 2, 0, // channels: 2
79 0x80, 0x2e, 0, 0, // sample rate: 11904
80 0, 0xba, 0, 0, // byte rate: 2 * 2 * 11904
81 4, 0, // block align: NumChannels * BytesPerSample
82 16, 0, // bits per sample: 2 * 8
83 'd', 'a', 't', 'a',
84 8, 0, 0, 0, // size of payload: 8
85 0, 0, // first sample: 0.0
86 10, 0, // second sample: 10.0
87 0xff, 0x7f, // third sample: 4e4 (saturated)
88 0, 0x80, // fourth sample: -1e9 (saturated)
89 };
90 static const int kContentSize =
91 webrtc::kWavHeaderSize + kNumSamples * sizeof(int16_t);
92 COMPILE_ASSERT(sizeof(kExpectedContents) == kContentSize, content_size);
93 EXPECT_EQ(size_t(kContentSize), webrtc::test::GetFileSize(outfile));
94 FILE* f = fopen(outfile.c_str(), "rb");
95 ASSERT_TRUE(f);
96 uint8_t contents[kContentSize];
97 ASSERT_EQ(1u, fread(contents, kContentSize, 1, f));
98 EXPECT_EQ(0, fclose(f));
99 EXPECT_EQ(0, memcmp(kExpectedContents, contents, kContentSize));
100}
101
102// Write a larger WAV file. You can listen to this file to sanity-check it.
103TEST(WavWriterTest, LargeFile) {
104 std::string outfile = webrtc::test::OutputPath() + "wavtest3.wav";
105 static const int kSampleRate = 8000;
106 static const int kNumChannels = 2;
107 static const int kNumSamples = 3 * kSampleRate * kNumChannels;
108 float samples[kNumSamples];
109 for (int i = 0; i < kNumSamples; i += kNumChannels) {
110 // A nice periodic beeping sound.
111 static const double kToneHz = 440;
112 const double t = static_cast<double>(i) / (kNumChannels * kSampleRate);
113 const double x =
114 std::numeric_limits<int16_t>::max() * std::sin(t * kToneHz * 2 * M_PI);
115 samples[i] = std::pow(std::sin(t * 2 * 2 * M_PI), 10) * x;
116 samples[i + 1] = std::pow(std::cos(t * 2 * 2 * M_PI), 10) * x;
117 }
118 {
119 webrtc::WavFile w(outfile, kSampleRate, kNumChannels);
120 w.WriteSamples(samples, kNumSamples);
121 }
122 EXPECT_EQ(sizeof(int16_t) * kNumSamples + webrtc::kWavHeaderSize,
123 webrtc::test::GetFileSize(outfile));
124}