| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <gtest/gtest.h> |
| #include <stdio.h> |
| |
| extern "C" { |
| #include "cras_mix.h" |
| #include "cras_shm.h" |
| #include "cras_types.h" |
| } |
| |
| namespace { |
| |
| static const size_t kBufferFrames = 8192; |
| static const size_t kNumChannels = 2; |
| static const size_t kNumSamples = kBufferFrames * kNumChannels; |
| static const float kMaxVolumeToScale = 0.9999999; |
| static const float kMinVolumeToScale = 0.0000001; |
| |
| static inline int need_to_scale(float scaler) { |
| return (scaler < 0.99 || scaler > 1.01); |
| } |
| |
| class MixTestSuiteS16_LE : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| fmt_ = SND_PCM_FORMAT_S16_LE; |
| mix_buffer_ = (int16_t*)malloc(kBufferFrames * 4); |
| src_buffer_ = static_cast<int16_t*>( |
| calloc(1, kBufferFrames * 4 + sizeof(cras_audio_shm_header))); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) { |
| src_buffer_[i] = i; |
| mix_buffer_[i] = -i; |
| } |
| |
| compare_buffer_ = (int16_t*)malloc(kBufferFrames * 4); |
| } |
| |
| virtual void TearDown() { |
| free(mix_buffer_); |
| free(compare_buffer_); |
| free(src_buffer_); |
| } |
| |
| void _SetupBuffer() { |
| for (size_t i = 0; i < kBufferFrames; i++) { |
| src_buffer_[i] = i + (INT16_MAX >> 2); |
| mix_buffer_[i] = i + (INT16_MAX >> 2); |
| compare_buffer_[i] = mix_buffer_[i]; |
| } |
| for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) { |
| src_buffer_[i] = i - (INT16_MAX >> 2); |
| mix_buffer_[i] = i - (INT16_MAX >> 2); |
| compare_buffer_[i] = mix_buffer_[i]; |
| } |
| } |
| |
| void TestScaleStride(float scaler) { |
| _SetupBuffer(); |
| for (size_t i = 0; i < kBufferFrames * 2; i += 2) { |
| int32_t tmp; |
| if (need_to_scale(scaler)) |
| tmp = mix_buffer_[i] + src_buffer_[i / 2] * scaler; |
| else |
| tmp = mix_buffer_[i] + src_buffer_[i / 2]; |
| if (tmp > INT16_MAX) |
| tmp = INT16_MAX; |
| else if (tmp < INT16_MIN) |
| tmp = INT16_MIN; |
| compare_buffer_[i] = tmp; |
| } |
| |
| cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_, |
| (uint8_t*)src_buffer_, kBufferFrames, 4, 2, |
| scaler); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| void ScaleIncrement(float start_scaler, float increment, float target) { |
| float scaler = start_scaler; |
| for (size_t i = 0; i < kBufferFrames * 2; i++) { |
| float applied_scaler = scaler; |
| |
| if ((applied_scaler > target && increment > 0) || |
| (applied_scaler < target && increment < 0)) |
| applied_scaler = target; |
| |
| if (applied_scaler > kMaxVolumeToScale) { |
| } else if (applied_scaler < kMinVolumeToScale) { |
| compare_buffer_[i] = 0; |
| } else { |
| compare_buffer_[i] = mix_buffer_[i] * applied_scaler; |
| } |
| |
| if (i % 2 == 1) |
| scaler += increment; |
| } |
| } |
| |
| int16_t* mix_buffer_; |
| int16_t* src_buffer_; |
| int16_t* compare_buffer_; |
| snd_pcm_format_t fmt_; |
| }; |
| |
| TEST_F(MixTestSuiteS16_LE, MixFirst) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, MixTwo) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] * 2; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, MixTwoClip) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| src_buffer_[i] = INT16_MAX; |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = INT16_MAX; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, MixFirstMuted) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 1, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, MixFirstZeroVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, MixFirstHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] * 0.5; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, MixTwoSecondHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] + (int16_t)(src_buffer_[i] * 0.5); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleFullVolumeIncrement) { |
| float increment = 0.01; |
| int step = 2; |
| float start_scaler = 0.999999999; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| // Scale full volume with positive increment will not change buffer. |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * 4); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleMinVolumeIncrement) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.000000001; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| // Scale min volume with negative increment will change buffer to zeros. |
| memset(compare_buffer_, 0, kBufferFrames * 4); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleVolumePositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleVolumeNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleVolumeStartFullNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 1.0; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleVolumeStartZeroPositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.0; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleVolumePositiveIncrementCappedByTarget) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleVolumeNegativeIncrementCappedByTarget) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleFullVolume) { |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * 4); |
| cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleMinVolume) { |
| memset(compare_buffer_, 0, kBufferFrames * 4); |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, ScaleHalfVolume) { |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] * 0.5; |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS16_LE, StrideCopy) { |
| TestScaleStride(1.0); |
| TestScaleStride(100); |
| TestScaleStride(0.5); |
| } |
| |
| class MixTestSuiteS24_LE : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| fmt_ = SND_PCM_FORMAT_S24_LE; |
| fr_bytes_ = 4 * kNumChannels; |
| mix_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_); |
| src_buffer_ = static_cast<int32_t*>( |
| calloc(1, kBufferFrames * fr_bytes_ + sizeof(cras_audio_shm_header))); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) { |
| src_buffer_[i] = i; |
| mix_buffer_[i] = -i; |
| } |
| |
| compare_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_); |
| } |
| |
| virtual void TearDown() { |
| free(mix_buffer_); |
| free(compare_buffer_); |
| free(src_buffer_); |
| } |
| |
| void _SetupBuffer() { |
| for (size_t i = 0; i < kBufferFrames; i++) { |
| src_buffer_[i] = i + (0x007fffff >> 2); |
| mix_buffer_[i] = i + (0x007fffff >> 2); |
| compare_buffer_[i] = mix_buffer_[i]; |
| } |
| for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) { |
| src_buffer_[i] = -i - (0x007fffff >> 2); |
| mix_buffer_[i] = -i - (0x007fffff >> 2); |
| compare_buffer_[i] = mix_buffer_[i]; |
| } |
| } |
| |
| void TestScaleStride(float scaler) { |
| _SetupBuffer(); |
| for (size_t i = 0; i < kBufferFrames * 2; i += 2) { |
| int32_t tmp; |
| if (need_to_scale(scaler)) |
| tmp = mix_buffer_[i] + Scale(src_buffer_[i / 2], scaler); |
| else |
| tmp = mix_buffer_[i] + src_buffer_[i / 2]; |
| if (tmp > 0x007fffff) |
| tmp = 0x007fffff; |
| else if (tmp < (int32_t)0xff800000) |
| tmp = (int32_t)0xff800000; |
| compare_buffer_[i] = tmp; |
| } |
| |
| cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_, |
| (uint8_t*)src_buffer_, kBufferFrames, 8, 4, |
| scaler); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 8)); |
| } |
| |
| void ScaleIncrement(float start_scaler, float increment, float target) { |
| float scaler = start_scaler; |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) { |
| float applied_scaler = scaler; |
| |
| if ((applied_scaler > target && increment > 0) || |
| (applied_scaler < target && increment < 0)) |
| applied_scaler = target; |
| |
| if (applied_scaler > kMaxVolumeToScale) { |
| } else if (applied_scaler < kMinVolumeToScale) { |
| compare_buffer_[i] = 0; |
| } else { |
| compare_buffer_[i] = Scale(mix_buffer_[i], applied_scaler); |
| } |
| |
| if (i % 2 == 1) |
| scaler += increment; |
| } |
| } |
| |
| int32_t Scale(int32_t value, float scaler) { |
| value = ((uint32_t)(value & 0x00ffffff)) << 8; |
| value *= scaler; |
| return (value >> 8) & 0x00ffffff; |
| } |
| |
| int32_t* mix_buffer_; |
| int32_t* src_buffer_; |
| int32_t* compare_buffer_; |
| snd_pcm_format_t fmt_; |
| unsigned int fr_bytes_; |
| }; |
| |
| TEST_F(MixTestSuiteS24_LE, MixFirst) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, MixTwo) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = Scale(src_buffer_[i], 2); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, MixTwoClip) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| src_buffer_[i] = 0x007fffff; |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0x007fffff; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, MixFirstMuted) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 1, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, MixFirstZeroVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, MixFirstHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = Scale(src_buffer_[i], 0.5); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, MixTwoSecondHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] + Scale(src_buffer_[i], 0.5); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleFullVolumeIncrement) { |
| float increment = 0.01; |
| int step = 2; |
| float start_scaler = 0.999999999; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| // Scale full volume with positive increment will not change buffer. |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleMinVolumeIncrement) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.000000001; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| // Scale min volume with negative increment will change buffer to zeros. |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleVolumePositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleVolumeNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleVolumeStartFullNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 1.0; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleVolumeStartZeroPositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.0; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleVolumePositiveIncrementCappedByTarget) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleVolumeNegativeIncrementCappedByTarget) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleFullVolume) { |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_); |
| cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleMinVolume) { |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, ScaleHalfVolume) { |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = Scale(src_buffer_[i], 0.5); |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_LE, StrideCopy) { |
| TestScaleStride(1.0); |
| TestScaleStride(100); |
| TestScaleStride(0.1); |
| } |
| |
| class MixTestSuiteS32_LE : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| fmt_ = SND_PCM_FORMAT_S32_LE; |
| fr_bytes_ = 4 * kNumChannels; |
| mix_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_); |
| src_buffer_ = static_cast<int32_t*>( |
| calloc(1, kBufferFrames * fr_bytes_ + sizeof(cras_audio_shm_header))); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) { |
| src_buffer_[i] = i; |
| mix_buffer_[i] = -i; |
| } |
| |
| compare_buffer_ = (int32_t*)malloc(kBufferFrames * fr_bytes_); |
| } |
| |
| virtual void TearDown() { |
| free(mix_buffer_); |
| free(compare_buffer_); |
| free(src_buffer_); |
| } |
| |
| void _SetupBuffer() { |
| for (size_t i = 0; i < kBufferFrames; i++) { |
| src_buffer_[i] = i + (INT32_MAX >> 2); |
| mix_buffer_[i] = i + (INT32_MAX >> 2); |
| compare_buffer_[i] = mix_buffer_[i]; |
| } |
| for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) { |
| src_buffer_[i] = i - (INT32_MAX >> 2); |
| mix_buffer_[i] = i - (INT32_MAX >> 2); |
| compare_buffer_[i] = mix_buffer_[i]; |
| } |
| } |
| |
| void TestScaleStride(float scaler) { |
| _SetupBuffer(); |
| for (size_t i = 0; i < kBufferFrames * 2; i += 2) { |
| int64_t tmp; |
| if (need_to_scale(scaler)) |
| tmp = mix_buffer_[i] + src_buffer_[i / 2] * scaler; |
| else |
| tmp = mix_buffer_[i] + src_buffer_[i / 2]; |
| if (tmp > INT32_MAX) |
| tmp = INT32_MAX; |
| else if (tmp < INT32_MIN) |
| tmp = INT32_MIN; |
| compare_buffer_[i] = tmp; |
| } |
| |
| cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_, |
| (uint8_t*)src_buffer_, kBufferFrames, 8, 4, |
| scaler); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 8)); |
| } |
| |
| void ScaleIncrement(float start_scaler, float increment, float target) { |
| float scaler = start_scaler; |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) { |
| float applied_scaler = scaler; |
| |
| if ((applied_scaler > target && increment > 0) || |
| (applied_scaler < target && increment < 0)) |
| applied_scaler = target; |
| |
| if (applied_scaler > kMaxVolumeToScale) { |
| } else if (applied_scaler < kMinVolumeToScale) { |
| compare_buffer_[i] = 0; |
| } else { |
| compare_buffer_[i] = mix_buffer_[i] * applied_scaler; |
| } |
| |
| if (i % 2 == 1) |
| scaler += increment; |
| } |
| } |
| |
| int32_t* mix_buffer_; |
| int32_t* src_buffer_; |
| int32_t* compare_buffer_; |
| snd_pcm_format_t fmt_; |
| unsigned int fr_bytes_; |
| }; |
| |
| TEST_F(MixTestSuiteS32_LE, MixFirst) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, MixTwo) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] * 2; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, MixTwoClip) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| src_buffer_[i] = INT32_MAX; |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = INT32_MAX; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, MixFirstMuted) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 1, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, MixFirstZeroVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.0); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = 0; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, MixFirstHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] * 0.5; |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, MixTwoSecondHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] + (int32_t)(src_buffer_[i] * 0.5); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleFullVolumeIncrement) { |
| float increment = 0.01; |
| int step = 2; |
| float start_scaler = 0.999999999; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| // Scale full volume with positive increment will not change buffer. |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleMinVolumeIncrement) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.000000001; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| // Scale min volume with negative increment will change buffer to zeros. |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleVolumePositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleVolumeNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleVolumeStartFullNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 1.0; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleVolumeStartZeroPositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.0; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleVolumePositiveIncrementCappedByTarget) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleVolumeNegativeIncrementCappedByTarget) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleFullVolume) { |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_); |
| cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleMinVolume) { |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, ScaleHalfVolume) { |
| for (size_t i = 0; i < kBufferFrames * 2; i++) |
| compare_buffer_[i] = src_buffer_[i] * 0.5; |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS32_LE, StrideCopy) { |
| TestScaleStride(1.0); |
| TestScaleStride(100); |
| TestScaleStride(0.1); |
| } |
| |
| class MixTestSuiteS24_3LE : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| fmt_ = SND_PCM_FORMAT_S24_3LE; |
| fr_bytes_ = 3 * kNumChannels; |
| mix_buffer_ = (uint8_t*)malloc(kBufferFrames * fr_bytes_); |
| src_buffer_ = static_cast<uint8_t*>( |
| calloc(1, kBufferFrames * fr_bytes_ + sizeof(cras_audio_shm_header))); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| memcpy(src_buffer_ + 3 * i, &i, 3); |
| int32_t tmp = -i * 256; |
| memcpy(mix_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| |
| compare_buffer_ = (uint8_t*)malloc(kBufferFrames * fr_bytes_); |
| } |
| |
| virtual void TearDown() { |
| free(mix_buffer_); |
| free(compare_buffer_); |
| free(src_buffer_); |
| } |
| |
| void _SetupBuffer() { |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| for (size_t i = 0; i < kBufferFrames; i++) { |
| int32_t tmp = (i << 8) + (INT32_MAX >> 2); |
| memcpy(src_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| memcpy(mix_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| for (size_t i = kBufferFrames; i < kBufferFrames * 2; i++) { |
| int32_t tmp = (i << 8) - (INT32_MAX >> 2); |
| memcpy(src_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| memcpy(mix_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| } |
| |
| void TestScaleStride(float scaler) { |
| _SetupBuffer(); |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i += 2) { |
| int64_t tmp; |
| int32_t src_frame = 0; |
| int32_t dst_frame = 0; |
| memcpy((uint8_t*)&src_frame + 1, src_buffer_ + 3 * i / 2, 3); |
| memcpy((uint8_t*)&dst_frame + 1, mix_buffer_ + 3 * i, 3); |
| if (need_to_scale(scaler)) |
| tmp = (int64_t)dst_frame + (int64_t)src_frame * scaler; |
| else |
| tmp = (int64_t)dst_frame + (int64_t)src_frame; |
| if (tmp > INT32_MAX) |
| tmp = INT32_MAX; |
| else if (tmp < INT32_MIN) |
| tmp = INT32_MIN; |
| dst_frame = (int32_t)tmp; |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&dst_frame + 1, 3); |
| } |
| |
| cras_mix_add_scale_stride(fmt_, (uint8_t*)mix_buffer_, |
| (uint8_t*)src_buffer_, kBufferFrames, 6, 3, |
| scaler); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 6)); |
| } |
| |
| void ScaleIncrement(float start_scaler, float increment, float target) { |
| float scaler = start_scaler; |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| float applied_scaler = scaler; |
| int32_t tmp = 0; |
| memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3); |
| |
| if ((applied_scaler > target && increment > 0) || |
| (applied_scaler < target && increment < 0)) |
| applied_scaler = target; |
| |
| if (applied_scaler > kMaxVolumeToScale) { |
| } else if (applied_scaler < kMinVolumeToScale) { |
| tmp = 0; |
| } else { |
| tmp *= applied_scaler; |
| } |
| |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| |
| if (i % 2 == 1) |
| scaler += increment; |
| } |
| } |
| |
| uint8_t* mix_buffer_; |
| uint8_t* src_buffer_; |
| uint8_t* compare_buffer_; |
| snd_pcm_format_t fmt_; |
| unsigned int fr_bytes_; |
| }; |
| |
| TEST_F(MixTestSuiteS24_3LE, MixFirst) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| EXPECT_EQ(0, memcmp(mix_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, MixTwo) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| int32_t tmp = 0; |
| memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3); |
| tmp *= 2; |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, MixTwoClip) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| int32_t tmp = INT32_MAX; |
| memcpy(src_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| int32_t tmp = INT32_MAX; |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, MixFirstMuted) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 1, 1.0); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) |
| memset(compare_buffer_ + 3 * i, 0, 3); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, MixFirstZeroVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.0); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) |
| memset(compare_buffer_ + 3 * i, 0, 3); |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, MixFirstHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| int32_t tmp = 0; |
| memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3); |
| tmp *= 0.5; |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, MixTwoSecondHalfVolume) { |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 0, 0, 1.0); |
| cras_mix_add(fmt_, (uint8_t*)mix_buffer_, (uint8_t*)src_buffer_, kNumSamples, |
| 1, 0, 0.5); |
| |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| int32_t tmp1 = 0, tmp2 = 0; |
| memcpy((uint8_t*)&tmp1 + 1, src_buffer_ + 3 * i, 3); |
| memcpy((uint8_t*)&tmp2 + 1, src_buffer_ + 3 * i, 3); |
| tmp1 = tmp1 + (int32_t)(tmp2 * 0.5); |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp1 + 1, 3); |
| } |
| EXPECT_EQ(0, memcmp(mix_buffer_, compare_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleFullVolumeIncrement) { |
| float increment = 0.01; |
| int step = 2; |
| float start_scaler = 0.999999999; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| // Scale full volume with positive increment will not change buffer. |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleMinVolumeIncrement) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.000000001; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| // Scale min volume with negative increment will change buffer to zeros. |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleVolumePositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleVolumeNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleVolumeStartFullNegativeIncrement) { |
| float increment = -0.0001; |
| int step = 2; |
| float start_scaler = 1.0; |
| float target = 0.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleVolumeStartZeroPositiveIncrement) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.0; |
| float target = 1.0; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * 4)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleVolumePositiveIncrementCappedByTarget) { |
| float increment = 0.0001; |
| int step = 2; |
| float start_scaler = 0.1; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleVolumeNegativeIncrementCappedByTarget) { |
| float increment = -0.01; |
| int step = 2; |
| float start_scaler = 0.8; |
| float target = 0.5; |
| |
| _SetupBuffer(); |
| ScaleIncrement(start_scaler, increment, target); |
| |
| cras_scale_buffer_increment(fmt_, (uint8_t*)mix_buffer_, kBufferFrames, |
| start_scaler, increment, target, step); |
| EXPECT_EQ(0, memcmp(compare_buffer_, mix_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleFullVolume) { |
| memcpy(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_); |
| cras_scale_buffer(fmt_, (uint8_t*)mix_buffer_, kNumSamples, 0.999999999); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleMinVolume) { |
| memset(compare_buffer_, 0, kBufferFrames * fr_bytes_); |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.0000000001); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, ScaleHalfVolume) { |
| for (size_t i = 0; i < kBufferFrames * kNumChannels; i++) { |
| int32_t tmp = 0; |
| memcpy((uint8_t*)&tmp + 1, src_buffer_ + 3 * i, 3); |
| tmp *= 0.5; |
| memcpy(compare_buffer_ + 3 * i, (uint8_t*)&tmp + 1, 3); |
| } |
| cras_scale_buffer(fmt_, (uint8_t*)src_buffer_, kNumSamples, 0.5); |
| |
| EXPECT_EQ(0, memcmp(compare_buffer_, src_buffer_, kBufferFrames * fr_bytes_)); |
| } |
| |
| TEST_F(MixTestSuiteS24_3LE, StrideCopy) { |
| TestScaleStride(1.0); |
| TestScaleStride(100); |
| TestScaleStride(0.1); |
| } |
| |
| /* Stubs */ |
| extern "C" {} // extern "C" |
| |
| } // namespace |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| return RUN_ALL_TESTS(); |
| } |