audio_frame_operations_unittest.cc (16674B)
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 "audio/utility/audio_frame_operations.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 16 #include "api/audio/audio_frame.h" 17 #include "api/audio/audio_view.h" 18 #include "rtc_base/checks.h" 19 #include "test/gtest.h" 20 21 namespace webrtc { 22 namespace { 23 24 class AudioFrameOperationsTest : public ::testing::Test { 25 protected: 26 AudioFrameOperationsTest() = default; 27 28 // Set typical values. 29 AudioFrame frame_{/*sample_rate_hz=*/32000, /*num_channels=*/2}; 30 }; 31 32 class AudioFrameOperationsDeathTest : public AudioFrameOperationsTest {}; 33 34 void SetFrameData(int16_t ch1, 35 int16_t ch2, 36 int16_t ch3, 37 int16_t ch4, 38 AudioFrame* frame) { 39 InterleavedView<int16_t> frame_data = 40 frame->mutable_data(frame->samples_per_channel_, 4); 41 for (size_t i = 0; i < frame->samples_per_channel_ * 4; i += 4) { 42 frame_data[i] = ch1; 43 frame_data[i + 1] = ch2; 44 frame_data[i + 2] = ch3; 45 frame_data[i + 3] = ch4; 46 } 47 } 48 49 void SetFrameData(int16_t left, int16_t right, AudioFrame* frame) { 50 InterleavedView<int16_t> frame_data = 51 frame->mutable_data(frame->samples_per_channel_, 2); 52 for (size_t i = 0; i < frame->samples_per_channel_ * 2; i += 2) { 53 frame_data[i] = left; 54 frame_data[i + 1] = right; 55 } 56 } 57 58 void SetFrameData(int16_t data, AudioFrame* frame) { 59 InterleavedView<int16_t> frame_data = 60 frame->mutable_data(frame->samples_per_channel_, 1); 61 for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_; 62 i++) { 63 frame_data[i] = data; 64 } 65 } 66 67 void VerifyFramesAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) { 68 ASSERT_EQ(frame1.num_channels_, frame2.num_channels_); 69 ASSERT_EQ(frame1.samples_per_channel_, frame2.samples_per_channel_); 70 EXPECT_EQ(frame1.muted(), frame2.muted()); 71 const int16_t* frame1_data = frame1.data(); 72 const int16_t* frame2_data = frame2.data(); 73 // TODO(tommi): Use sample_count() or data_view(). 74 for (size_t i = 0; i < frame1.samples_per_channel_ * frame1.num_channels_; 75 i++) { 76 EXPECT_EQ(frame1_data[i], frame2_data[i]); 77 if (frame1_data[i] != frame2_data[i]) 78 break; // To avoid spamming the log. 79 } 80 } 81 82 void InitFrame(AudioFrame* frame, 83 size_t channels, 84 size_t samples_per_channel, 85 int16_t left_data, 86 int16_t right_data) { 87 RTC_DCHECK_GE(2, channels); 88 RTC_DCHECK_GE(AudioFrame::kMaxDataSizeSamples, 89 samples_per_channel * channels); 90 frame->samples_per_channel_ = samples_per_channel; 91 if (channels == 2) { 92 SetFrameData(left_data, right_data, frame); 93 } else if (channels == 1) { 94 SetFrameData(left_data, frame); 95 } 96 ASSERT_EQ(frame->num_channels_, channels); 97 } 98 99 int16_t GetChannelData(const AudioFrame& frame, size_t channel, size_t index) { 100 RTC_DCHECK_LT(channel, frame.num_channels_); 101 RTC_DCHECK_LT(index, frame.samples_per_channel_); 102 return frame.data()[index * frame.num_channels_ + channel]; 103 } 104 105 void VerifyFrameDataBounds(const AudioFrame& frame, 106 size_t channel, 107 int16_t max, 108 int16_t min) { 109 for (size_t i = 0; i < frame.samples_per_channel_; ++i) { 110 int16_t s = GetChannelData(frame, channel, i); 111 EXPECT_LE(min, s); 112 EXPECT_GE(max, s); 113 } 114 } 115 116 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 117 TEST_F(AudioFrameOperationsDeathTest, MonoToStereoFailsWithBadParameters) { 118 EXPECT_DEATH(AudioFrameOperations::UpmixChannels(2, &frame_), ""); 119 frame_.samples_per_channel_ = AudioFrame::kMaxDataSizeSamples; 120 frame_.num_channels_ = 1; 121 EXPECT_DEATH(AudioFrameOperations::UpmixChannels(2, &frame_), ""); 122 } 123 #endif 124 125 TEST_F(AudioFrameOperationsTest, MonoToStereoSucceeds) { 126 SetFrameData(1, &frame_); 127 128 AudioFrameOperations::UpmixChannels(2, &frame_); 129 EXPECT_EQ(2u, frame_.num_channels_); 130 131 AudioFrame stereo_frame; 132 stereo_frame.samples_per_channel_ = 320; 133 SetFrameData(1, 1, &stereo_frame); 134 VerifyFramesAreEqual(stereo_frame, frame_); 135 } 136 137 TEST_F(AudioFrameOperationsTest, MonoToStereoMuted) { 138 frame_.num_channels_ = 1; 139 ASSERT_TRUE(frame_.muted()); 140 AudioFrameOperations::UpmixChannels(2, &frame_); 141 EXPECT_EQ(2u, frame_.num_channels_); 142 EXPECT_TRUE(frame_.muted()); 143 } 144 145 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 146 TEST_F(AudioFrameOperationsDeathTest, StereoToMonoFailsWithBadParameters) { 147 frame_.num_channels_ = 1; 148 EXPECT_DEATH(AudioFrameOperations::DownmixChannels(1, &frame_), ""); 149 } 150 #endif 151 152 TEST_F(AudioFrameOperationsTest, StereoToMonoSucceeds) { 153 SetFrameData(4, 2, &frame_); 154 AudioFrameOperations::DownmixChannels(1, &frame_); 155 EXPECT_EQ(1u, frame_.num_channels_); 156 157 AudioFrame mono_frame; 158 mono_frame.samples_per_channel_ = 320; 159 SetFrameData(3, &mono_frame); 160 VerifyFramesAreEqual(mono_frame, frame_); 161 } 162 163 TEST_F(AudioFrameOperationsTest, StereoToMonoMuted) { 164 ASSERT_TRUE(frame_.muted()); 165 AudioFrameOperations::DownmixChannels(1, &frame_); 166 EXPECT_EQ(1u, frame_.num_channels_); 167 EXPECT_TRUE(frame_.muted()); 168 } 169 170 TEST_F(AudioFrameOperationsTest, StereoToMonoBufferSucceeds) { 171 AudioFrame target_frame; 172 SetFrameData(4, 2, &frame_); 173 174 AudioFrameOperations::DownmixChannels( 175 frame_.data_view(), 176 target_frame.mutable_data(frame_.samples_per_channel_, 1)); 177 178 AudioFrame mono_frame; 179 mono_frame.samples_per_channel_ = 320; 180 SetFrameData(3, &mono_frame); 181 VerifyFramesAreEqual(mono_frame, target_frame); 182 } 183 184 TEST_F(AudioFrameOperationsTest, StereoToMonoDoesNotWrapAround) { 185 SetFrameData(-32768, -32768, &frame_); 186 AudioFrameOperations::DownmixChannels(1, &frame_); 187 EXPECT_EQ(1u, frame_.num_channels_); 188 AudioFrame mono_frame; 189 mono_frame.samples_per_channel_ = 320; 190 SetFrameData(-32768, &mono_frame); 191 VerifyFramesAreEqual(mono_frame, frame_); 192 } 193 194 TEST_F(AudioFrameOperationsTest, QuadToMonoSucceeds) { 195 SetFrameData(4, 2, 6, 8, &frame_); 196 197 AudioFrameOperations::DownmixChannels(1, &frame_); 198 EXPECT_EQ(1u, frame_.num_channels_); 199 200 AudioFrame mono_frame; 201 mono_frame.samples_per_channel_ = 320; 202 SetFrameData(5, &mono_frame); 203 VerifyFramesAreEqual(mono_frame, frame_); 204 } 205 206 TEST_F(AudioFrameOperationsTest, QuadToMonoMuted) { 207 frame_.num_channels_ = 4; 208 ASSERT_TRUE(frame_.muted()); 209 AudioFrameOperations::DownmixChannels(1, &frame_); 210 EXPECT_EQ(1u, frame_.num_channels_); 211 EXPECT_TRUE(frame_.muted()); 212 } 213 214 TEST_F(AudioFrameOperationsTest, QuadToMonoBufferSucceeds) { 215 AudioFrame target_frame; 216 SetFrameData(4, 2, 6, 8, &frame_); 217 218 AudioFrameOperations::DownmixChannels( 219 frame_.data_view(), 220 target_frame.mutable_data(frame_.samples_per_channel_, 1)); 221 AudioFrame mono_frame; 222 mono_frame.samples_per_channel_ = 320; 223 SetFrameData(5, &mono_frame); 224 VerifyFramesAreEqual(mono_frame, target_frame); 225 } 226 227 TEST_F(AudioFrameOperationsTest, QuadToMonoDoesNotWrapAround) { 228 SetFrameData(-32768, -32768, -32768, -32768, &frame_); 229 AudioFrameOperations::DownmixChannels(1, &frame_); 230 EXPECT_EQ(1u, frame_.num_channels_); 231 232 AudioFrame mono_frame; 233 mono_frame.samples_per_channel_ = 320; 234 SetFrameData(-32768, &mono_frame); 235 VerifyFramesAreEqual(mono_frame, frame_); 236 } 237 238 TEST_F(AudioFrameOperationsTest, QuadToStereoFailsWithBadParameters) { 239 frame_.num_channels_ = 1; 240 EXPECT_EQ(-1, AudioFrameOperations::QuadToStereo(&frame_)); 241 frame_.num_channels_ = 2; 242 EXPECT_EQ(-1, AudioFrameOperations::QuadToStereo(&frame_)); 243 } 244 245 TEST_F(AudioFrameOperationsTest, QuadToStereoSucceeds) { 246 SetFrameData(4, 2, 6, 8, &frame_); 247 EXPECT_EQ(0, AudioFrameOperations::QuadToStereo(&frame_)); 248 249 AudioFrame stereo_frame; 250 stereo_frame.samples_per_channel_ = 320; 251 SetFrameData(3, 7, &stereo_frame); 252 VerifyFramesAreEqual(stereo_frame, frame_); 253 } 254 255 TEST_F(AudioFrameOperationsTest, QuadToStereoMuted) { 256 frame_.num_channels_ = 4; 257 ASSERT_TRUE(frame_.muted()); 258 EXPECT_EQ(0, AudioFrameOperations::QuadToStereo(&frame_)); 259 EXPECT_TRUE(frame_.muted()); 260 } 261 262 TEST_F(AudioFrameOperationsTest, QuadToStereoBufferSucceeds) { 263 AudioFrame target_frame; 264 SetFrameData(4, 2, 6, 8, &frame_); 265 266 AudioFrameOperations::QuadToStereo( 267 frame_.data_view(), 268 target_frame.mutable_data(frame_.samples_per_channel_, 2)); 269 AudioFrame stereo_frame; 270 stereo_frame.samples_per_channel_ = 320; 271 SetFrameData(3, 7, &stereo_frame); 272 VerifyFramesAreEqual(stereo_frame, target_frame); 273 } 274 275 TEST_F(AudioFrameOperationsTest, QuadToStereoDoesNotWrapAround) { 276 SetFrameData(-32768, -32768, -32768, -32768, &frame_); 277 EXPECT_EQ(0, AudioFrameOperations::QuadToStereo(&frame_)); 278 279 AudioFrame stereo_frame; 280 stereo_frame.samples_per_channel_ = 320; 281 SetFrameData(-32768, -32768, &stereo_frame); 282 VerifyFramesAreEqual(stereo_frame, frame_); 283 } 284 285 TEST_F(AudioFrameOperationsTest, SwapStereoChannelsSucceedsOnStereo) { 286 SetFrameData(0, 1, &frame_); 287 288 AudioFrame swapped_frame; 289 swapped_frame.samples_per_channel_ = 320; 290 SetFrameData(1, 0, &swapped_frame); 291 292 AudioFrameOperations::SwapStereoChannels(&frame_); 293 VerifyFramesAreEqual(swapped_frame, frame_); 294 } 295 296 TEST_F(AudioFrameOperationsTest, SwapStereoChannelsMuted) { 297 ASSERT_TRUE(frame_.muted()); 298 AudioFrameOperations::SwapStereoChannels(&frame_); 299 EXPECT_TRUE(frame_.muted()); 300 } 301 302 TEST_F(AudioFrameOperationsTest, SwapStereoChannelsFailsOnMono) { 303 // Set data to "stereo", despite it being a mono frame. 304 SetFrameData(0, 1, &frame_); 305 frame_.num_channels_ = 1; // Reset to mono after SetFrameData(). 306 307 AudioFrame orig_frame; 308 orig_frame.CopyFrom(frame_); 309 AudioFrameOperations::SwapStereoChannels(&frame_); 310 // Verify that no swap occurred. 311 VerifyFramesAreEqual(orig_frame, frame_); 312 } 313 314 TEST_F(AudioFrameOperationsTest, MuteDisabled) { 315 SetFrameData(1000, -1000, &frame_); 316 AudioFrameOperations::Mute(&frame_, false, false); 317 318 AudioFrame muted_frame; 319 muted_frame.samples_per_channel_ = 320; 320 SetFrameData(1000, -1000, &muted_frame); 321 VerifyFramesAreEqual(muted_frame, frame_); 322 } 323 324 TEST_F(AudioFrameOperationsTest, MuteEnabled) { 325 SetFrameData(1000, -1000, &frame_); 326 AudioFrameOperations::Mute(&frame_, true, true); 327 328 AudioFrame muted_frame; 329 muted_frame.samples_per_channel_ = frame_.samples_per_channel_; 330 muted_frame.num_channels_ = frame_.num_channels_; 331 ASSERT_TRUE(muted_frame.muted()); 332 VerifyFramesAreEqual(muted_frame, frame_); 333 } 334 335 // Verify that *beginning* to mute works for short and long (>128) frames, mono 336 // and stereo. Beginning mute should yield a ramp down to zero. 337 TEST_F(AudioFrameOperationsTest, MuteBeginMonoLong) { 338 InitFrame(&frame_, 1, 228, 1000, -1000); 339 AudioFrameOperations::Mute(&frame_, false, true); 340 VerifyFrameDataBounds(frame_, 0, 1000, 0); 341 EXPECT_EQ(1000, GetChannelData(frame_, 0, 99)); 342 EXPECT_EQ(992, GetChannelData(frame_, 0, 100)); 343 EXPECT_EQ(7, GetChannelData(frame_, 0, 226)); 344 EXPECT_EQ(0, GetChannelData(frame_, 0, 227)); 345 } 346 347 TEST_F(AudioFrameOperationsTest, MuteBeginMonoShort) { 348 InitFrame(&frame_, 1, 93, 1000, -1000); 349 AudioFrameOperations::Mute(&frame_, false, true); 350 VerifyFrameDataBounds(frame_, 0, 1000, 0); 351 EXPECT_EQ(989, GetChannelData(frame_, 0, 0)); 352 EXPECT_EQ(978, GetChannelData(frame_, 0, 1)); 353 EXPECT_EQ(10, GetChannelData(frame_, 0, 91)); 354 EXPECT_EQ(0, GetChannelData(frame_, 0, 92)); 355 } 356 357 TEST_F(AudioFrameOperationsTest, MuteBeginStereoLong) { 358 InitFrame(&frame_, 2, 228, 1000, -1000); 359 AudioFrameOperations::Mute(&frame_, false, true); 360 VerifyFrameDataBounds(frame_, 0, 1000, 0); 361 VerifyFrameDataBounds(frame_, 1, 0, -1000); 362 EXPECT_EQ(1000, GetChannelData(frame_, 0, 99)); 363 EXPECT_EQ(-1000, GetChannelData(frame_, 1, 99)); 364 EXPECT_EQ(992, GetChannelData(frame_, 0, 100)); 365 EXPECT_EQ(-992, GetChannelData(frame_, 1, 100)); 366 EXPECT_EQ(7, GetChannelData(frame_, 0, 226)); 367 EXPECT_EQ(-7, GetChannelData(frame_, 1, 226)); 368 EXPECT_EQ(0, GetChannelData(frame_, 0, 227)); 369 EXPECT_EQ(0, GetChannelData(frame_, 1, 227)); 370 } 371 372 TEST_F(AudioFrameOperationsTest, MuteBeginStereoShort) { 373 InitFrame(&frame_, 2, 93, 1000, -1000); 374 AudioFrameOperations::Mute(&frame_, false, true); 375 VerifyFrameDataBounds(frame_, 0, 1000, 0); 376 VerifyFrameDataBounds(frame_, 1, 0, -1000); 377 EXPECT_EQ(989, GetChannelData(frame_, 0, 0)); 378 EXPECT_EQ(-989, GetChannelData(frame_, 1, 0)); 379 EXPECT_EQ(978, GetChannelData(frame_, 0, 1)); 380 EXPECT_EQ(-978, GetChannelData(frame_, 1, 1)); 381 EXPECT_EQ(10, GetChannelData(frame_, 0, 91)); 382 EXPECT_EQ(-10, GetChannelData(frame_, 1, 91)); 383 EXPECT_EQ(0, GetChannelData(frame_, 0, 92)); 384 EXPECT_EQ(0, GetChannelData(frame_, 1, 92)); 385 } 386 387 // Verify that *ending* to mute works for short and long (>128) frames, mono 388 // and stereo. Ending mute should yield a ramp up from zero. 389 TEST_F(AudioFrameOperationsTest, MuteEndMonoLong) { 390 InitFrame(&frame_, 1, 228, 1000, -1000); 391 AudioFrameOperations::Mute(&frame_, true, false); 392 VerifyFrameDataBounds(frame_, 0, 1000, 0); 393 EXPECT_EQ(7, GetChannelData(frame_, 0, 0)); 394 EXPECT_EQ(15, GetChannelData(frame_, 0, 1)); 395 EXPECT_EQ(1000, GetChannelData(frame_, 0, 127)); 396 EXPECT_EQ(1000, GetChannelData(frame_, 0, 128)); 397 } 398 399 TEST_F(AudioFrameOperationsTest, MuteEndMonoShort) { 400 InitFrame(&frame_, 1, 93, 1000, -1000); 401 AudioFrameOperations::Mute(&frame_, true, false); 402 VerifyFrameDataBounds(frame_, 0, 1000, 0); 403 EXPECT_EQ(10, GetChannelData(frame_, 0, 0)); 404 EXPECT_EQ(21, GetChannelData(frame_, 0, 1)); 405 EXPECT_EQ(989, GetChannelData(frame_, 0, 91)); 406 EXPECT_EQ(999, GetChannelData(frame_, 0, 92)); 407 } 408 409 TEST_F(AudioFrameOperationsTest, MuteEndStereoLong) { 410 InitFrame(&frame_, 2, 228, 1000, -1000); 411 AudioFrameOperations::Mute(&frame_, true, false); 412 VerifyFrameDataBounds(frame_, 0, 1000, 0); 413 VerifyFrameDataBounds(frame_, 1, 0, -1000); 414 EXPECT_EQ(7, GetChannelData(frame_, 0, 0)); 415 EXPECT_EQ(-7, GetChannelData(frame_, 1, 0)); 416 EXPECT_EQ(15, GetChannelData(frame_, 0, 1)); 417 EXPECT_EQ(-15, GetChannelData(frame_, 1, 1)); 418 EXPECT_EQ(1000, GetChannelData(frame_, 0, 127)); 419 EXPECT_EQ(-1000, GetChannelData(frame_, 1, 127)); 420 EXPECT_EQ(1000, GetChannelData(frame_, 0, 128)); 421 EXPECT_EQ(-1000, GetChannelData(frame_, 1, 128)); 422 } 423 424 TEST_F(AudioFrameOperationsTest, MuteEndStereoShort) { 425 InitFrame(&frame_, 2, 93, 1000, -1000); 426 AudioFrameOperations::Mute(&frame_, true, false); 427 VerifyFrameDataBounds(frame_, 0, 1000, 0); 428 VerifyFrameDataBounds(frame_, 1, 0, -1000); 429 EXPECT_EQ(10, GetChannelData(frame_, 0, 0)); 430 EXPECT_EQ(-10, GetChannelData(frame_, 1, 0)); 431 EXPECT_EQ(21, GetChannelData(frame_, 0, 1)); 432 EXPECT_EQ(-21, GetChannelData(frame_, 1, 1)); 433 EXPECT_EQ(989, GetChannelData(frame_, 0, 91)); 434 EXPECT_EQ(-989, GetChannelData(frame_, 1, 91)); 435 EXPECT_EQ(999, GetChannelData(frame_, 0, 92)); 436 EXPECT_EQ(-999, GetChannelData(frame_, 1, 92)); 437 } 438 439 TEST_F(AudioFrameOperationsTest, MuteBeginAlreadyMuted) { 440 ASSERT_TRUE(frame_.muted()); 441 AudioFrameOperations::Mute(&frame_, false, true); 442 EXPECT_TRUE(frame_.muted()); 443 } 444 445 TEST_F(AudioFrameOperationsTest, MuteEndAlreadyMuted) { 446 ASSERT_TRUE(frame_.muted()); 447 AudioFrameOperations::Mute(&frame_, true, false); 448 EXPECT_TRUE(frame_.muted()); 449 } 450 451 // TODO(andrew): should fail with a negative scale. 452 TEST_F(AudioFrameOperationsTest, DISABLED_ScaleWithSatFailsWithBadParameters) { 453 EXPECT_EQ(-1, AudioFrameOperations::ScaleWithSat(-1.0, &frame_)); 454 } 455 456 TEST_F(AudioFrameOperationsTest, ScaleWithSatDoesNotWrapAround) { 457 SetFrameData(4000, &frame_); 458 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(10.0, &frame_)); 459 460 AudioFrame clipped_frame; 461 clipped_frame.samples_per_channel_ = 320; 462 SetFrameData(32767, &clipped_frame); 463 VerifyFramesAreEqual(clipped_frame, frame_); 464 465 SetFrameData(-4000, &frame_); 466 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(10.0, &frame_)); 467 SetFrameData(-32768, &clipped_frame); 468 VerifyFramesAreEqual(clipped_frame, frame_); 469 } 470 471 TEST_F(AudioFrameOperationsTest, ScaleWithSatSucceeds) { 472 SetFrameData(1, &frame_); 473 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(2.0, &frame_)); 474 475 AudioFrame scaled_frame; 476 scaled_frame.samples_per_channel_ = 320; 477 SetFrameData(2, &scaled_frame); 478 VerifyFramesAreEqual(scaled_frame, frame_); 479 } 480 481 TEST_F(AudioFrameOperationsTest, ScaleWithSatMuted) { 482 ASSERT_TRUE(frame_.muted()); 483 EXPECT_EQ(0, AudioFrameOperations::ScaleWithSat(2.0, &frame_)); 484 EXPECT_TRUE(frame_.muted()); 485 } 486 487 } // namespace 488 } // namespace webrtc