1 // Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <stdio.h> 6 #include <gtest/gtest.h> 7 8 extern "C" { 9 #include "cras_audio_format.h" 10 #include "cras_audio_area.h" 11 } 12 13 static const int8_t stereo[CRAS_CH_MAX] = { 14 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15 }; 16 static const int8_t mono[CRAS_CH_MAX] = { 17 -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 18 }; 19 static const int8_t kb_mic[CRAS_CH_MAX] = { 20 0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, 21 }; 22 23 static uint16_t buf1[32]; 24 static uint16_t buf2[32]; 25 struct cras_audio_area *a1; 26 struct cras_audio_area *a2; 27 28 namespace { 29 30 TEST(AudioArea, CopyAudioArea) { 31 struct cras_audio_format fmt; 32 int i; 33 34 fmt.num_channels = 2; 35 fmt.format = SND_PCM_FORMAT_S16_LE; 36 for (i = 0; i < CRAS_CH_MAX; i++) 37 fmt.channel_layout[i] = stereo[i]; 38 39 a1 = cras_audio_area_create(2); 40 a2 = cras_audio_area_create(2); 41 cras_audio_area_config_channels(a1, &fmt); 42 cras_audio_area_config_channels(a2, &fmt); 43 cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1); 44 cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2); 45 a1->frames = 16; 46 a2->frames = 16; 47 48 memset(buf1, 0, 32 * 2); 49 for (i = 0; i < 32; i++) 50 buf2[i] = rand(); 51 cras_audio_area_copy(a1, 0, &fmt, a2, 0, 1.0); 52 for (i = 0; i < 32; i++) 53 EXPECT_EQ(buf1[i], buf2[i]); 54 55 cras_audio_area_destroy(a1); 56 cras_audio_area_destroy(a2); 57 } 58 59 TEST(AudioArea, CopyAudioAreaWithGain) { 60 struct cras_audio_format fmt; 61 int i; 62 /* Check a gain of 10x can be applied. */ 63 float gain_scaler = 10.0f; 64 65 fmt.num_channels = 2; 66 fmt.format = SND_PCM_FORMAT_S16_LE; 67 for (i = 0; i < CRAS_CH_MAX; i++) 68 fmt.channel_layout[i] = stereo[i]; 69 70 a1 = cras_audio_area_create(2); 71 a2 = cras_audio_area_create(2); 72 cras_audio_area_config_channels(a1, &fmt); 73 cras_audio_area_config_channels(a2, &fmt); 74 cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1); 75 cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2); 76 a1->frames = 16; 77 a2->frames = 16; 78 79 memset(buf1, 0, 32 * 2); 80 /* Let src has some samples smaller than 32768/10 and some samples larger than 81 * 32768/10 to test clipping. */ 82 for (i = 0; i < 16; i++) 83 buf2[i] = rand() % 3270; 84 for (i = 17; i < 32; i++) 85 buf2[i] = 3280 + rand() % 3200; 86 cras_audio_area_copy(a1, 0, &fmt, a2, 0, gain_scaler); 87 for (i = 0; i < 32; i++) { 88 int32_t expected_value = buf2[i] * gain_scaler; 89 if (expected_value > INT16_MAX) 90 expected_value = INT16_MAX; 91 EXPECT_EQ(buf1[i], expected_value); 92 } 93 94 cras_audio_area_destroy(a1); 95 cras_audio_area_destroy(a2); 96 } 97 TEST(AudioArea, CopyAudioAreaOffset) { 98 struct cras_audio_format fmt; 99 int i; 100 101 fmt.num_channels = 2; 102 fmt.format = SND_PCM_FORMAT_S16_LE; 103 for (i = 0; i < CRAS_CH_MAX; i++) 104 fmt.channel_layout[i] = stereo[i]; 105 106 a1 = cras_audio_area_create(2); 107 a2 = cras_audio_area_create(2); 108 cras_audio_area_config_channels(a1, &fmt); 109 cras_audio_area_config_channels(a2, &fmt); 110 cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1); 111 cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2); 112 a1->frames = 16; 113 a2->frames = 14; 114 115 memset(buf1, 0, 32 * 2); 116 for (i = 0; i < 32; i++) 117 buf2[i] = rand(); 118 cras_audio_area_copy(a1, 2, &fmt, a2, 0, 1.0); 119 EXPECT_EQ(buf1[0], 0); 120 EXPECT_EQ(buf1[1], 0); 121 EXPECT_EQ(buf1[2], 0); 122 EXPECT_EQ(buf1[3], 0); 123 for (i = 4; i < 32; i++) 124 EXPECT_EQ(buf1[i], buf2[i-4]); 125 126 cras_audio_area_destroy(a1); 127 cras_audio_area_destroy(a2); 128 } 129 130 TEST(AudioArea, CopyAudioAreaOffsetLimit) { 131 struct cras_audio_format fmt; 132 int i; 133 134 fmt.num_channels = 2; 135 fmt.format = SND_PCM_FORMAT_S16_LE; 136 for (i = 0; i < CRAS_CH_MAX; i++) 137 fmt.channel_layout[i] = stereo[i]; 138 139 a1 = cras_audio_area_create(2); 140 a2 = cras_audio_area_create(2); 141 cras_audio_area_config_channels(a1, &fmt); 142 cras_audio_area_config_channels(a2, &fmt); 143 cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1); 144 cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2); 145 a1->frames = 14; 146 a2->frames = 14; 147 148 memset(buf1, 0, 32 * 2); 149 for (i = 0; i < 32; i++) 150 buf2[i] = rand(); 151 cras_audio_area_copy(a1, 2, &fmt, a2, 0, 1.0); 152 EXPECT_EQ(buf1[0], 0); 153 EXPECT_EQ(buf1[1], 0); 154 EXPECT_EQ(buf1[2], 0); 155 EXPECT_EQ(buf1[3], 0); 156 for (i = 4; i < 28; i++) 157 EXPECT_EQ(buf1[i], buf2[i-4]); 158 EXPECT_EQ(buf1[28], 0); 159 EXPECT_EQ(buf1[29], 0); 160 EXPECT_EQ(buf1[30], 0); 161 EXPECT_EQ(buf1[31], 0); 162 163 cras_audio_area_destroy(a1); 164 cras_audio_area_destroy(a2); 165 } 166 167 TEST(AudioArea, CopyMonoToStereo) { 168 struct cras_audio_format dst_fmt; 169 struct cras_audio_format src_fmt; 170 int i; 171 172 dst_fmt.num_channels = 2; 173 dst_fmt.format = SND_PCM_FORMAT_S16_LE; 174 for (i = 0; i < CRAS_CH_MAX; i++) 175 dst_fmt.channel_layout[i] = stereo[i]; 176 a1 = cras_audio_area_create(2); 177 a1->frames = 16; 178 cras_audio_area_config_channels(a1, &dst_fmt); 179 cras_audio_area_config_buf_pointers(a1, &dst_fmt, (uint8_t *)buf1); 180 181 src_fmt.num_channels = 1; 182 src_fmt.format = SND_PCM_FORMAT_S16_LE; 183 for (i = 0; i < CRAS_CH_MAX; i++) 184 src_fmt.channel_layout[i] = mono[i]; 185 a2 = cras_audio_area_create(1); 186 a2->frames = 16; 187 cras_audio_area_config_channels(a2, &src_fmt); 188 cras_audio_area_config_buf_pointers(a2, &src_fmt, (uint8_t *)buf2); 189 190 memset(buf1, 0, 32 * 2); 191 for (i = 0; i < 32; i++) 192 buf2[i] = rand(); 193 cras_audio_area_copy(a1, 0, &dst_fmt, a2, 0, 1.0); 194 for (i = 0; i < 16; i++) { 195 EXPECT_EQ(buf1[i * 2], buf2[i]); 196 EXPECT_EQ(buf1[i * 2 + 1], buf2[i]); 197 } 198 199 cras_audio_area_destroy(a1); 200 cras_audio_area_destroy(a2); 201 } 202 203 TEST(AudioArea, CopyStereoToMono) { 204 struct cras_audio_format fmt; 205 int i; 206 207 fmt.num_channels = 1; 208 fmt.format = SND_PCM_FORMAT_S16_LE; 209 for (i = 0; i < CRAS_CH_MAX; i++) 210 fmt.channel_layout[i] = mono[i]; 211 a1 = cras_audio_area_create(1); 212 a1->frames = 16; 213 cras_audio_area_config_channels(a1, &fmt); 214 cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1); 215 216 fmt.num_channels = 2; 217 for (i = 0; i < CRAS_CH_MAX; i++) 218 fmt.channel_layout[i] = stereo[i]; 219 a2 = cras_audio_area_create(2); 220 a2->frames = 16; 221 cras_audio_area_config_channels(a2, &fmt); 222 cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2); 223 224 memset(buf1, 0, 32 * 2); 225 for (i = 0; i < 32; i++) 226 buf2[i] = rand() % 10000; 227 cras_audio_area_copy(a1, 0, &fmt, a2, 0, 1.0); 228 for (i = 0; i < 16; i++) 229 EXPECT_EQ(buf1[i], buf2[i * 2] + buf2[i * 2 + 1]); 230 231 cras_audio_area_destroy(a1); 232 cras_audio_area_destroy(a2); 233 } 234 235 TEST(AudioArea, KeyboardMicCopyStereo) { 236 struct cras_audio_format fmt; 237 int i; 238 239 fmt.num_channels = 3; 240 fmt.format = SND_PCM_FORMAT_S16_LE; 241 for (i = 0; i < CRAS_CH_MAX; i++) 242 fmt.channel_layout[i] = kb_mic[i]; 243 a1 = cras_audio_area_create(3); 244 a1->frames = 10; 245 cras_audio_area_config_channels(a1, &fmt); 246 cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1); 247 248 fmt.num_channels = 2; 249 for (i = 0; i < CRAS_CH_MAX; i++) 250 fmt.channel_layout[i] = stereo[i]; 251 a2 = cras_audio_area_create(2); 252 a2->frames = 10; 253 cras_audio_area_config_channels(a2, &fmt); 254 cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2); 255 256 memset(buf1, 0, 32 * 2); 257 for (i = 0; i < 32; i++) 258 buf2[i] = rand(); 259 cras_audio_area_copy(a1, 0, &fmt, a2, 0, 1.0); 260 for (i = 0; i < 10; i++) { 261 EXPECT_EQ(buf1[i * 3], buf2[i * 2]); 262 EXPECT_EQ(buf1[i * 3 + 1], buf2[i * 2 + 1]); 263 EXPECT_EQ(buf1[i * 3 + 2], 0); 264 } 265 266 cras_audio_area_destroy(a1); 267 cras_audio_area_destroy(a2); 268 } 269 270 TEST(AudioArea, KeyboardMicCopyFrontCenter) { 271 struct cras_audio_format dst_fmt; 272 struct cras_audio_format src_fmt; 273 int i; 274 275 dst_fmt.num_channels = 3; 276 dst_fmt.format = SND_PCM_FORMAT_S16_LE; 277 for (i = 0; i < CRAS_CH_MAX; i++) 278 dst_fmt.channel_layout[i] = kb_mic[i]; 279 a1 = cras_audio_area_create(3); 280 a1->frames = 10; 281 cras_audio_area_config_channels(a1, &dst_fmt); 282 cras_audio_area_config_buf_pointers(a1, &dst_fmt, (uint8_t *)buf1); 283 284 /* Test 2 channels area with only front center in layout. */ 285 src_fmt.num_channels = 2; 286 src_fmt.format = SND_PCM_FORMAT_S16_LE; 287 for (i = 0; i < CRAS_CH_MAX; i++) 288 src_fmt.channel_layout[i] = -1; 289 src_fmt.channel_layout[CRAS_CH_FC] = 0; 290 a2 = cras_audio_area_create(2); 291 a2->frames = 10; 292 cras_audio_area_config_channels(a2, &src_fmt); 293 cras_audio_area_config_buf_pointers(a2, &src_fmt, (uint8_t *)buf2); 294 295 memset(buf1, 0, 32 * 2); 296 for (i = 0; i < 32; i++) 297 buf2[i] = rand(); 298 cras_audio_area_copy(a1, 0, &dst_fmt, a2, 0, 1.0); 299 for (i = 0; i < 10; i++) { 300 EXPECT_EQ(buf1[i * 3], 0); 301 EXPECT_EQ(buf1[i * 3 + 1], 0); 302 EXPECT_EQ(buf1[i * 3 + 2], buf2[i * 2]); 303 } 304 305 cras_audio_area_destroy(a1); 306 cras_audio_area_destroy(a2); 307 } 308 309 } // namespace 310 311 extern "C" { 312 313 void cras_mix_add_scale_stride(snd_pcm_format_t fmt, uint8_t *dst, uint8_t *src, 314 unsigned int count, unsigned int dst_stride, 315 unsigned int src_stride, float scaler) 316 { 317 unsigned int i; 318 319 for (i = 0; i < count; i++) { 320 int32_t sum; 321 sum = *(int16_t *)dst + *(int16_t *)src * scaler; 322 if (sum > INT16_MAX) 323 sum = INT16_MAX; 324 else if (sum < INT16_MIN) 325 sum = INT16_MIN; 326 *(int16_t*)dst = sum; 327 dst += dst_stride; 328 src += src_stride; 329 } 330 } 331 332 } // extern "C" 333 334 int main(int argc, char **argv) { 335 ::testing::InitGoogleTest(&argc, argv); 336 return RUN_ALL_TESTS(); 337 } 338