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 <gtest/gtest.h>
6 #include <stdio.h>
7
8 extern "C" {
9 #include "cras_audio_area.h"
10 #include "cras_audio_format.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
TEST(AudioArea,CopyAudioArea)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
TEST(AudioArea,CopyAudioAreaWithGain)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 }
TEST(AudioArea,CopyAudioAreaOffset)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
TEST(AudioArea,CopyAudioAreaOffsetLimit)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
TEST(AudioArea,CopyMonoToStereo)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
TEST(AudioArea,CopyStereoToMono)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
TEST(AudioArea,KeyboardMicCopyStereo)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
TEST(AudioArea,KeyboardMicCopyFrontCenter)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
cras_mix_add_scale_stride(snd_pcm_format_t fmt,uint8_t * dst,uint8_t * src,unsigned int count,unsigned int dst_stride,unsigned int src_stride,float scaler)313 void cras_mix_add_scale_stride(snd_pcm_format_t fmt,
314 uint8_t* dst,
315 uint8_t* src,
316 unsigned int count,
317 unsigned int dst_stride,
318 unsigned int src_stride,
319 float scaler) {
320 unsigned int i;
321
322 for (i = 0; i < count; i++) {
323 int32_t sum;
324 sum = *(int16_t*)dst + *(int16_t*)src * scaler;
325 if (sum > INT16_MAX)
326 sum = INT16_MAX;
327 else if (sum < INT16_MIN)
328 sum = INT16_MIN;
329 *(int16_t*)dst = sum;
330 dst += dst_stride;
331 src += src_stride;
332 }
333 }
334
335 } // extern "C"
336
main(int argc,char ** argv)337 int main(int argc, char** argv) {
338 ::testing::InitGoogleTest(&argc, argv);
339 return RUN_ALL_TESTS();
340 }
341