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