1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <iostream> 18 #include <math.h> 19 20 #include <gtest/gtest.h> 21 22 #include "utility/AAudioUtilities.h" 23 #include "utility/LinearRamp.h" 24 25 TEST(test_linear_ramp, linear_ramp_segments) { 26 LinearRamp ramp; 27 const float source[4] = {1.0f, 1.0f, 1.0f, 1.0f }; 28 float destination[4] = {1.0f, 1.0f, 1.0f, 1.0f }; 29 30 float levelFrom = -1.0f; 31 float levelTo = -1.0f; 32 ramp.setLengthInFrames(8); 33 ramp.setTarget(8.0f); 34 35 EXPECT_EQ(8, ramp.getLengthInFrames()); 36 37 bool ramping = ramp.nextSegment(4, &levelFrom, &levelTo); 38 EXPECT_EQ(1, ramping); 39 EXPECT_EQ(0.0f, levelFrom); 40 EXPECT_EQ(4.0f, levelTo); 41 42 AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo); 43 EXPECT_EQ(0.0f, destination[0]); 44 EXPECT_EQ(1.0f, destination[1]); 45 EXPECT_EQ(2.0f, destination[2]); 46 EXPECT_EQ(3.0f, destination[3]); 47 48 ramping = ramp.nextSegment(4, &levelFrom, &levelTo); 49 EXPECT_EQ(1, ramping); 50 EXPECT_EQ(4.0f, levelFrom); 51 EXPECT_EQ(8.0f, levelTo); 52 53 AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo); 54 EXPECT_EQ(4.0f, destination[0]); 55 EXPECT_EQ(5.0f, destination[1]); 56 EXPECT_EQ(6.0f, destination[2]); 57 EXPECT_EQ(7.0f, destination[3]); 58 59 ramping = ramp.nextSegment(4, &levelFrom, &levelTo); 60 EXPECT_EQ(0, ramping); 61 EXPECT_EQ(8.0f, levelFrom); 62 EXPECT_EQ(8.0f, levelTo); 63 64 AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo); 65 EXPECT_EQ(8.0f, destination[0]); 66 EXPECT_EQ(8.0f, destination[1]); 67 EXPECT_EQ(8.0f, destination[2]); 68 EXPECT_EQ(8.0f, destination[3]); 69 70 }; 71 72 73 TEST(test_linear_ramp, linear_ramp_forced) { 74 LinearRamp ramp; 75 const float source[4] = {1.0f, 1.0f, 1.0f, 1.0f }; 76 float destination[4] = {1.0f, 1.0f, 1.0f, 1.0f }; 77 78 float levelFrom = -1.0f; 79 float levelTo = -1.0f; 80 ramp.setLengthInFrames(4); 81 ramp.setTarget(8.0f); 82 ramp.forceCurrent(4.0f); 83 EXPECT_EQ(4.0f, ramp.getCurrent()); 84 85 bool ramping = ramp.nextSegment(4, &levelFrom, &levelTo); 86 EXPECT_EQ(1, ramping); 87 EXPECT_EQ(4.0f, levelFrom); 88 EXPECT_EQ(8.0f, levelTo); 89 90 AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo); 91 EXPECT_EQ(4.0f, destination[0]); 92 EXPECT_EQ(5.0f, destination[1]); 93 EXPECT_EQ(6.0f, destination[2]); 94 EXPECT_EQ(7.0f, destination[3]); 95 96 ramping = ramp.nextSegment(4, &levelFrom, &levelTo); 97 EXPECT_EQ(0, ramping); 98 EXPECT_EQ(8.0f, levelFrom); 99 EXPECT_EQ(8.0f, levelTo); 100 101 AAudio_linearRamp(source, destination, 4, 1, levelFrom, levelTo); 102 EXPECT_EQ(8.0f, destination[0]); 103 EXPECT_EQ(8.0f, destination[1]); 104 EXPECT_EQ(8.0f, destination[2]); 105 EXPECT_EQ(8.0f, destination[3]); 106 107 }; 108 109 constexpr int16_t kMaxI16 = INT16_MAX; 110 constexpr int16_t kMinI16 = INT16_MIN; 111 constexpr int16_t kHalfI16 = 16384; 112 constexpr int16_t kTenthI16 = 3277; 113 114 //void AAudioConvert_floatToPcm16(const float *source, 115 // int16_t *destination, 116 // int32_t numSamples, 117 // float amplitude); 118 TEST(test_linear_ramp, float_to_i16) { 119 const float source[] = {12345.6f, 1.0f, 0.5f, 0.1f, 0.0f, -0.1f, -0.5f, -1.0f, -12345.6f}; 120 constexpr size_t count = sizeof(source) / sizeof(source[0]); 121 int16_t destination[count]; 122 const int16_t expected[count] = {kMaxI16, kMaxI16, kHalfI16, kTenthI16, 0, 123 -kTenthI16, -kHalfI16, kMinI16, kMinI16}; 124 125 AAudioConvert_floatToPcm16(source, destination, count, 1.0f); 126 for (size_t i = 0; i < count; i++) { 127 EXPECT_EQ(expected[i], destination[i]); 128 } 129 130 } 131 132 //void AAudioConvert_pcm16ToFloat(const int16_t *source, 133 // float *destination, 134 // int32_t numSamples, 135 // float amplitude); 136 TEST(test_linear_ramp, i16_to_float) { 137 const int16_t source[] = {kMaxI16, kHalfI16, kTenthI16, 0, 138 -kTenthI16, -kHalfI16, kMinI16}; 139 constexpr size_t count = sizeof(source) / sizeof(source[0]); 140 float destination[count]; 141 const float expected[count] = {(32767.0f / 32768.0f), 0.5f, 0.1f, 0.0f, -0.1f, -0.5f, -1.0f}; 142 143 AAudioConvert_pcm16ToFloat(source, destination, count, 1.0f); 144 for (size_t i = 0; i < count; i++) { 145 EXPECT_NEAR(expected[i], destination[i], 0.0001f); 146 } 147 148 } 149 150 //void AAudio_linearRamp(const int16_t *source, 151 // int16_t *destination, 152 // int32_t numFrames, 153 // int32_t samplesPerFrame, 154 // float amplitude1, 155 // float amplitude2); 156 TEST(test_linear_ramp, ramp_i16_to_i16) { 157 const int16_t source[] = {1, 1, 1, 1, 1, 1, 1, 1}; 158 constexpr size_t count = sizeof(source) / sizeof(source[0]); 159 int16_t destination[count]; 160 // Ramp will sweep from -1 to almost +1 161 const int16_t expected[count] = { 162 -1, // from -1.00 163 -1, // from -0.75 164 -1, // from -0.55, round away from zero 165 0, // from -0.25, round up to zero 166 0, // from 0.00 167 0, // from 0.25, round down to zero 168 1, // from 0.50, round away from zero 169 1 // from 0.75 170 }; 171 172 // sweep across zero to test symmetry 173 constexpr float amplitude1 = -1.0; 174 constexpr float amplitude2 = 1.0; 175 AAudio_linearRamp(source, destination, count, 1, amplitude1, amplitude2); 176 for (size_t i = 0; i < count; i++) { 177 EXPECT_EQ(expected[i], destination[i]); 178 } 179 180 } 181