blob: f4d881cf8710f68bd506c36415fd68e753b9676e [file] [log] [blame]
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +00001/*
2 * Copyright (c) 2012 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
pbos@webrtc.orgfab7ea22013-07-12 08:28:10 +000011#include "testing/gtest/include/gtest/gtest.h"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000012
pbos@webrtc.orgfab7ea22013-07-12 08:28:10 +000013#include "webrtc/modules/interface/module_common_types.h"
14#include "webrtc/modules/utility/interface/audio_frame_operations.h"
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000015
16namespace webrtc {
17namespace {
18
19class AudioFrameOperationsTest : public ::testing::Test {
20 protected:
21 AudioFrameOperationsTest() {
22 // Set typical values.
23 frame_.samples_per_channel_ = 320;
24 frame_.num_channels_ = 2;
25 }
26
27 AudioFrame frame_;
28};
29
30void SetFrameData(AudioFrame* frame, int16_t left, int16_t right) {
31 for (int i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
32 frame->data_[i] = left;
33 frame->data_[i + 1] = right;
34 }
35}
36
37void SetFrameData(AudioFrame* frame, int16_t data) {
38 for (int i = 0; i < frame->samples_per_channel_; i++) {
39 frame->data_[i] = data;
40 }
41}
42
43void VerifyFramesAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) {
44 EXPECT_EQ(frame1.num_channels_, frame2.num_channels_);
45 EXPECT_EQ(frame1.samples_per_channel_,
46 frame2.samples_per_channel_);
47
48 for (int i = 0; i < frame1.samples_per_channel_ * frame1.num_channels_;
49 i++) {
50 EXPECT_EQ(frame1.data_[i], frame2.data_[i]);
51 }
52}
53
54TEST_F(AudioFrameOperationsTest, MonoToStereoFailsWithBadParameters) {
55 EXPECT_EQ(-1, AudioFrameOperations::MonoToStereo(&frame_));
56
57 frame_.samples_per_channel_ = AudioFrame::kMaxDataSizeSamples;
58 frame_.num_channels_ = 1;
59 EXPECT_EQ(-1, AudioFrameOperations::MonoToStereo(&frame_));
60}
61
62TEST_F(AudioFrameOperationsTest, MonoToStereoSucceeds) {
63 frame_.num_channels_ = 1;
64 SetFrameData(&frame_, 1);
andrew@webrtc.org4e629ff2013-01-22 04:44:30 +000065 AudioFrame temp_frame;
66 temp_frame.CopyFrom(frame_);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000067 EXPECT_EQ(0, AudioFrameOperations::MonoToStereo(&frame_));
68
69 AudioFrame stereo_frame;
70 stereo_frame.samples_per_channel_ = 320;
71 stereo_frame.num_channels_ = 2;
72 SetFrameData(&stereo_frame, 1, 1);
73 VerifyFramesAreEqual(stereo_frame, frame_);
74
75 SetFrameData(&frame_, 0);
76 AudioFrameOperations::MonoToStereo(temp_frame.data_,
77 frame_.samples_per_channel_,
78 frame_.data_);
79 frame_.num_channels_ = 2; // Need to set manually.
80 VerifyFramesAreEqual(stereo_frame, frame_);
81}
82
83TEST_F(AudioFrameOperationsTest, StereoToMonoFailsWithBadParameters) {
84 frame_.num_channels_ = 1;
85 EXPECT_EQ(-1, AudioFrameOperations::StereoToMono(&frame_));
86}
87
88TEST_F(AudioFrameOperationsTest, StereoToMonoSucceeds) {
89 SetFrameData(&frame_, 4, 2);
andrew@webrtc.org4e629ff2013-01-22 04:44:30 +000090 AudioFrame temp_frame;
91 temp_frame.CopyFrom(frame_);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +000092 EXPECT_EQ(0, AudioFrameOperations::StereoToMono(&frame_));
93
94 AudioFrame mono_frame;
95 mono_frame.samples_per_channel_ = 320;
96 mono_frame.num_channels_ = 1;
97 SetFrameData(&mono_frame, 3);
98 VerifyFramesAreEqual(mono_frame, frame_);
99
100 SetFrameData(&frame_, 0);
101 AudioFrameOperations::StereoToMono(temp_frame.data_,
102 frame_.samples_per_channel_,
103 frame_.data_);
104 frame_.num_channels_ = 1; // Need to set manually.
105 VerifyFramesAreEqual(mono_frame, frame_);
106}
107
108TEST_F(AudioFrameOperationsTest, StereoToMonoDoesNotWrapAround) {
109 SetFrameData(&frame_, -32768, -32768);
110 EXPECT_EQ(0, AudioFrameOperations::StereoToMono(&frame_));
111
112 AudioFrame mono_frame;
113 mono_frame.samples_per_channel_ = 320;
114 mono_frame.num_channels_ = 1;
115 SetFrameData(&mono_frame, -32768);
116 VerifyFramesAreEqual(mono_frame, frame_);
117}
118
119TEST_F(AudioFrameOperationsTest, SwapStereoChannelsSucceedsOnStereo) {
120 SetFrameData(&frame_, 0, 1);
121
122 AudioFrame swapped_frame;
123 swapped_frame.samples_per_channel_ = 320;
124 swapped_frame.num_channels_ = 2;
125 SetFrameData(&swapped_frame, 1, 0);
126
127 AudioFrameOperations::SwapStereoChannels(&frame_);
128 VerifyFramesAreEqual(swapped_frame, frame_);
129}
130
131TEST_F(AudioFrameOperationsTest, SwapStereoChannelsFailsOnMono) {
132 frame_.num_channels_ = 1;
133 // Set data to "stereo", despite it being a mono frame.
134 SetFrameData(&frame_, 0, 1);
135
andrew@webrtc.org4e629ff2013-01-22 04:44:30 +0000136 AudioFrame orig_frame;
137 orig_frame.CopyFrom(frame_);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000138 AudioFrameOperations::SwapStereoChannels(&frame_);
139 // Verify that no swap occurred.
140 VerifyFramesAreEqual(orig_frame, frame_);
141}
142
143TEST_F(AudioFrameOperationsTest, MuteSucceeds) {
144 SetFrameData(&frame_, 1000, 1000);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000145 AudioFrameOperations::Mute(frame_);
146
147 AudioFrame muted_frame;
148 muted_frame.samples_per_channel_ = 320;
149 muted_frame.num_channels_ = 2;
150 SetFrameData(&muted_frame, 0, 0);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000151 VerifyFramesAreEqual(muted_frame, frame_);
andrew@webrtc.orga7b57da2012-10-22 18:19:23 +0000152}
153
154// TODO(andrew): should not allow negative scales.
155TEST_F(AudioFrameOperationsTest, DISABLED_ScaleFailsWithBadParameters) {
156 frame_.num_channels_ = 1;
157 EXPECT_EQ(-1, AudioFrameOperations::Scale(1.0, 1.0, frame_));
158
159 frame_.num_channels_ = 3;
160 EXPECT_EQ(-1, AudioFrameOperations::Scale(1.0, 1.0, frame_));
161
162 frame_.num_channels_ = 2;
163 EXPECT_EQ(-1, AudioFrameOperations::Scale(-1.0, 1.0, frame_));
164 EXPECT_EQ(-1, AudioFrameOperations::Scale(1.0, -1.0, frame_));
165}
166
167// TODO(andrew): fix the wraparound bug. We should always saturate.
168TEST_F(AudioFrameOperationsTest, DISABLED_ScaleDoesNotWrapAround) {
169 SetFrameData(&frame_, 4000, -4000);
170 EXPECT_EQ(0, AudioFrameOperations::Scale(10.0, 10.0, frame_));
171
172 AudioFrame clipped_frame;
173 clipped_frame.samples_per_channel_ = 320;
174 clipped_frame.num_channels_ = 2;
175 SetFrameData(&clipped_frame, 32767, -32768);
176 VerifyFramesAreEqual(clipped_frame, frame_);
177}
178
179TEST_F(AudioFrameOperationsTest, ScaleSucceeds) {
180 SetFrameData(&frame_, 1, -1);
181 EXPECT_EQ(0, AudioFrameOperations::Scale(2.0, 3.0, frame_));
182
183 AudioFrame scaled_frame;
184 scaled_frame.samples_per_channel_ = 320;
185 scaled_frame.num_channels_ = 2;
186 SetFrameData(&scaled_frame, 2, -3);
187 VerifyFramesAreEqual(scaled_frame, frame_);
188}
189
190// TODO(andrew): should fail with a negative scale.
191TEST_F(AudioFrameOperationsTest, DISABLED_ScaleWithSatFailsWithBadParameters) {
192 EXPECT_EQ(-1, AudioFrameOperations::ScaleWithSat(-1.0, frame_));
193}
194
195TEST_F(AudioFrameOperationsTest, ScaleWithSatDoesNotWrapAround) {
196 frame_.num_channels_ = 1;
197 SetFrameData(&frame_, 4000);
198 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(10.0, frame_));
199
200 AudioFrame clipped_frame;
201 clipped_frame.samples_per_channel_ = 320;
202 clipped_frame.num_channels_ = 1;
203 SetFrameData(&clipped_frame, 32767);
204 VerifyFramesAreEqual(clipped_frame, frame_);
205
206 SetFrameData(&frame_, -4000);
207 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(10.0, frame_));
208 SetFrameData(&clipped_frame, -32768);
209 VerifyFramesAreEqual(clipped_frame, frame_);
210}
211
212TEST_F(AudioFrameOperationsTest, ScaleWithSatSucceeds) {
213 frame_.num_channels_ = 1;
214 SetFrameData(&frame_, 1);
215 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(2.0, frame_));
216
217 AudioFrame scaled_frame;
218 scaled_frame.samples_per_channel_ = 320;
219 scaled_frame.num_channels_ = 1;
220 SetFrameData(&scaled_frame, 2);
221 VerifyFramesAreEqual(scaled_frame, frame_);
222}
223
224} // namespace
225} // namespace webrtc