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: 21 AudioFrameOperationsTest() { 22 // Set typical values. 23 frame_.samples_per_channel_ = 320; 24 frame_.num_channels_ = 2; 25 } 26 27 AudioFrame frame_; 28 }; 29 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 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 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 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 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 83 TEST_F(AudioFrameOperationsTest, StereoToMonoFailsWithBadParameters) { 84 frame_.num_channels_ = 1; 85 EXPECT_EQ(-1, AudioFrameOperations::StereoToMono(&frame_)); 86 } 87 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 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 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 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 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. 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. 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 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. 191 TEST_F(AudioFrameOperationsTest, DISABLED_ScaleWithSatFailsWithBadParameters) { 192 EXPECT_EQ(-1, AudioFrameOperations::ScaleWithSat(-1.0, frame_)); 193 } 194 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 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