1 /*
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
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 #include "webrtc/modules/include/module_common_types.h"
14 #include "webrtc/modules/utility/include/audio_frame_operations.h"
15
16 namespace webrtc {
17 namespace {
18
19 class AudioFrameOperationsTest : public ::testing::Test {
20 protected:
AudioFrameOperationsTest()21 AudioFrameOperationsTest() {
22 // Set typical values.
23 frame_.samples_per_channel_ = 320;
24 frame_.num_channels_ = 2;
25 }
26
27 AudioFrame frame_;
28 };
29
SetFrameData(AudioFrame * frame,int16_t left,int16_t right)30 void SetFrameData(AudioFrame* frame, int16_t left, int16_t right) {
31 for (size_t i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
32 frame->data_[i] = left;
33 frame->data_[i + 1] = right;
34 }
35 }
36
SetFrameData(AudioFrame * frame,int16_t data)37 void SetFrameData(AudioFrame* frame, int16_t data) {
38 for (size_t i = 0; i < frame->samples_per_channel_; i++) {
39 frame->data_[i] = data;
40 }
41 }
42
VerifyFramesAreEqual(const AudioFrame & frame1,const AudioFrame & frame2)43 void 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 (size_t i = 0; i < frame1.samples_per_channel_ * frame1.num_channels_;
49 i++) {
50 EXPECT_EQ(frame1.data_[i], frame2.data_[i]);
51 }
52 }
53
TEST_F(AudioFrameOperationsTest,MonoToStereoFailsWithBadParameters)54 TEST_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
TEST_F(AudioFrameOperationsTest,MonoToStereoSucceeds)62 TEST_F(AudioFrameOperationsTest, MonoToStereoSucceeds) {
63 frame_.num_channels_ = 1;
64 SetFrameData(&frame_, 1);
65 AudioFrame temp_frame;
66 temp_frame.CopyFrom(frame_);
67 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
TEST_F(AudioFrameOperationsTest,StereoToMonoFailsWithBadParameters)83 TEST_F(AudioFrameOperationsTest, StereoToMonoFailsWithBadParameters) {
84 frame_.num_channels_ = 1;
85 EXPECT_EQ(-1, AudioFrameOperations::StereoToMono(&frame_));
86 }
87
TEST_F(AudioFrameOperationsTest,StereoToMonoSucceeds)88 TEST_F(AudioFrameOperationsTest, StereoToMonoSucceeds) {
89 SetFrameData(&frame_, 4, 2);
90 AudioFrame temp_frame;
91 temp_frame.CopyFrom(frame_);
92 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
TEST_F(AudioFrameOperationsTest,StereoToMonoDoesNotWrapAround)108 TEST_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
TEST_F(AudioFrameOperationsTest,SwapStereoChannelsSucceedsOnStereo)119 TEST_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
TEST_F(AudioFrameOperationsTest,SwapStereoChannelsFailsOnMono)131 TEST_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
136 AudioFrame orig_frame;
137 orig_frame.CopyFrom(frame_);
138 AudioFrameOperations::SwapStereoChannels(&frame_);
139 // Verify that no swap occurred.
140 VerifyFramesAreEqual(orig_frame, frame_);
141 }
142
TEST_F(AudioFrameOperationsTest,MuteSucceeds)143 TEST_F(AudioFrameOperationsTest, MuteSucceeds) {
144 SetFrameData(&frame_, 1000, 1000);
145 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);
151 VerifyFramesAreEqual(muted_frame, frame_);
152 }
153
154 // TODO(andrew): should not allow negative scales.
TEST_F(AudioFrameOperationsTest,DISABLED_ScaleFailsWithBadParameters)155 TEST_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.
TEST_F(AudioFrameOperationsTest,DISABLED_ScaleDoesNotWrapAround)168 TEST_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
TEST_F(AudioFrameOperationsTest,ScaleSucceeds)179 TEST_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.
TEST_F(AudioFrameOperationsTest,DISABLED_ScaleWithSatFailsWithBadParameters)191 TEST_F(AudioFrameOperationsTest, DISABLED_ScaleWithSatFailsWithBadParameters) {
192 EXPECT_EQ(-1, AudioFrameOperations::ScaleWithSat(-1.0, frame_));
193 }
194
TEST_F(AudioFrameOperationsTest,ScaleWithSatDoesNotWrapAround)195 TEST_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
TEST_F(AudioFrameOperationsTest,ScaleWithSatSucceeds)212 TEST_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
226