]>
code.delx.au - pulseaudio/blob - src/tests/mix-special-test.c
2 This file is part of PulseAudio.
4 PulseAudio is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published
6 by the Free Software Foundation; either version 2.1 of the License,
7 or (at your option) any later version.
9 PulseAudio is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with PulseAudio; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29 #include <pulse/rtclock.h>
30 #include <pulsecore/random.h>
31 #include <pulsecore/macro.h>
32 #include <pulsecore/mix.h>
33 #include <pulsecore/sample-util.h>
35 #include "runtime-test-util.h"
37 static void acquire_mix_streams(pa_mix_info streams
[], unsigned nstreams
) {
40 for (i
= 0; i
< nstreams
; i
++)
41 streams
[i
].ptr
= pa_memblock_acquire_chunk(&streams
[i
].chunk
);
44 static void release_mix_streams(pa_mix_info streams
[], unsigned nstreams
) {
47 for (i
= 0; i
< nstreams
; i
++)
48 pa_memblock_release(streams
[i
].chunk
.memblock
);
51 /* special case: mix 2 s16ne streams, 1 channel each */
52 static void pa_mix2_ch1_s16ne(pa_mix_info streams
[], int16_t *data
, unsigned length
) {
53 const int16_t *ptr0
= streams
[0].ptr
;
54 const int16_t *ptr1
= streams
[1].ptr
;
56 const int32_t cv0
= streams
[0].linear
[0].i
;
57 const int32_t cv1
= streams
[1].linear
[0].i
;
59 length
/= sizeof(int16_t);
61 for (; length
> 0; length
--) {
64 sum
= pa_mult_s16_volume(*ptr0
++, cv0
);
65 sum
+= pa_mult_s16_volume(*ptr1
++, cv1
);
67 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
72 /* special case: mix 2 s16ne streams, 2 channels each */
73 static void pa_mix2_ch2_s16ne(pa_mix_info streams
[], int16_t *data
, unsigned length
) {
74 const int16_t *ptr0
= streams
[0].ptr
;
75 const int16_t *ptr1
= streams
[1].ptr
;
77 length
/= sizeof(int16_t) * 2;
79 for (; length
> 0; length
--) {
82 sum
= pa_mult_s16_volume(*ptr0
++, streams
[0].linear
[0].i
);
83 sum
+= pa_mult_s16_volume(*ptr1
++, streams
[1].linear
[0].i
);
85 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
88 sum
= pa_mult_s16_volume(*ptr0
++, streams
[0].linear
[1].i
);
89 sum
+= pa_mult_s16_volume(*ptr1
++, streams
[1].linear
[1].i
);
91 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
96 /* special case: mix 2 s16ne streams */
97 static void pa_mix2_s16ne(pa_mix_info streams
[], unsigned channels
, int16_t *data
, unsigned length
) {
98 const int16_t *ptr0
= streams
[0].ptr
;
99 const int16_t *ptr1
= streams
[1].ptr
;
100 unsigned channel
= 0;
102 length
/= sizeof(int16_t);
104 for (; length
> 0; length
--) {
107 sum
= pa_mult_s16_volume(*ptr0
++, streams
[0].linear
[channel
].i
);
108 sum
+= pa_mult_s16_volume(*ptr1
++, streams
[1].linear
[channel
].i
);
110 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
113 if (PA_UNLIKELY(++channel
>= channels
))
118 /* special case: mix s16ne streams, 2 channels each */
119 static void pa_mix_ch2_s16ne(pa_mix_info streams
[], unsigned nstreams
, int16_t *data
, unsigned length
) {
121 length
/= sizeof(int16_t) * 2;
123 for (; length
> 0; length
--) {
124 int32_t sum0
= 0, sum1
= 0;
127 for (i
= 0; i
< nstreams
; i
++) {
128 pa_mix_info
*m
= streams
+ i
;
129 int32_t cv0
= m
->linear
[0].i
;
130 int32_t cv1
= m
->linear
[1].i
;
132 sum0
+= pa_mult_s16_volume(*((int16_t*) m
->ptr
), cv0
);
133 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
135 sum1
+= pa_mult_s16_volume(*((int16_t*) m
->ptr
), cv1
);
136 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
139 *data
++ = PA_CLAMP_UNLIKELY(sum0
, -0x8000, 0x7FFF);
140 *data
++ = PA_CLAMP_UNLIKELY(sum1
, -0x8000, 0x7FFF);
144 static void pa_mix_generic_s16ne(pa_mix_info streams
[], unsigned nstreams
, unsigned channels
, int16_t *data
, unsigned length
) {
145 unsigned channel
= 0;
147 length
/= sizeof(int16_t);
149 for (; length
> 0; length
--) {
153 for (i
= 0; i
< nstreams
; i
++) {
154 pa_mix_info
*m
= streams
+ i
;
155 int32_t cv
= m
->linear
[channel
].i
;
157 if (PA_LIKELY(cv
> 0))
158 sum
+= pa_mult_s16_volume(*((int16_t*) m
->ptr
), cv
);
159 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
162 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
165 if (PA_UNLIKELY(++channel
>= channels
))
174 START_TEST (mix_special_1ch_test
) {
175 int16_t samples0
[SAMPLES
];
176 int16_t samples1
[SAMPLES
];
177 int16_t out
[SAMPLES
];
178 int16_t out_ref
[SAMPLES
];
182 unsigned nsamples
= SAMPLES
;
184 fail_unless((pool
= pa_mempool_new(false, 0)) != NULL
, NULL
);
186 pa_random(samples0
, nsamples
* sizeof(int16_t));
187 c0
.memblock
= pa_memblock_new_fixed(pool
, samples0
, nsamples
* sizeof(int16_t), false);
188 c0
.length
= pa_memblock_get_length(c0
.memblock
);
191 pa_random(samples1
, nsamples
* sizeof(int16_t));
192 c1
.memblock
= pa_memblock_new_fixed(pool
, samples1
, nsamples
* sizeof(int16_t), false);
193 c1
.length
= pa_memblock_get_length(c1
.memblock
);
197 m
[0].volume
.channels
= 1;
198 m
[0].volume
.values
[0] = PA_VOLUME_NORM
;
199 m
[0].linear
[0].i
= 0x5555;
202 m
[1].volume
.channels
= 1;
203 m
[1].volume
.values
[0] = PA_VOLUME_NORM
;
204 m
[1].linear
[0].i
= 0x6789;
206 PA_RUNTIME_TEST_RUN_START("mix s16 generic 1 channel", TIMES
, TIMES2
) {
207 acquire_mix_streams(m
, 2);
208 pa_mix_generic_s16ne(m
, 2, 1, out_ref
, nsamples
* sizeof(int16_t));
209 release_mix_streams(m
, 2);
210 } PA_RUNTIME_TEST_RUN_STOP
212 PA_RUNTIME_TEST_RUN_START("mix s16 2 streams 1 channel", TIMES
, TIMES2
) {
213 acquire_mix_streams(m
, 2);
214 pa_mix2_ch1_s16ne(m
, out
, nsamples
* sizeof(int16_t));
215 release_mix_streams(m
, 2);
216 } PA_RUNTIME_TEST_RUN_STOP
218 fail_unless(memcmp(out
, out_ref
, nsamples
* sizeof(int16_t)) == 0);
220 pa_memblock_unref(c0
.memblock
);
221 pa_memblock_unref(c1
.memblock
);
223 pa_mempool_free(pool
);
227 START_TEST (mix_special_2ch_test
) {
228 int16_t samples0
[SAMPLES
*2];
229 int16_t samples1
[SAMPLES
*2];
230 int16_t out
[SAMPLES
*2];
231 int16_t out_ref
[SAMPLES
*2];
236 unsigned nsamples
= SAMPLES
* 2;
238 fail_unless((pool
= pa_mempool_new(false, 0)) != NULL
, NULL
);
240 pa_random(samples0
, nsamples
* sizeof(int16_t));
241 c0
.memblock
= pa_memblock_new_fixed(pool
, samples0
, nsamples
* sizeof(int16_t), false);
242 c0
.length
= pa_memblock_get_length(c0
.memblock
);
245 pa_random(samples1
, nsamples
* sizeof(int16_t));
246 c1
.memblock
= pa_memblock_new_fixed(pool
, samples1
, nsamples
* sizeof(int16_t), false);
247 c1
.length
= pa_memblock_get_length(c1
.memblock
);
251 m
[0].volume
.channels
= 2;
252 for (i
= 0; i
< m
[0].volume
.channels
; i
++) {
253 m
[0].volume
.values
[i
] = PA_VOLUME_NORM
;
254 m
[0].linear
[i
].i
= 0x5555;
258 m
[1].volume
.channels
= 2;
259 for (i
= 0; i
< m
[1].volume
.channels
; i
++) {
260 m
[1].volume
.values
[i
] = PA_VOLUME_NORM
;
261 m
[1].linear
[i
].i
= 0x6789;
264 PA_RUNTIME_TEST_RUN_START("mix s16 generic 2 channels", TIMES
, TIMES2
) {
265 acquire_mix_streams(m
, 2);
266 pa_mix_generic_s16ne(m
, 2, 2, out_ref
, nsamples
* sizeof(int16_t));
267 release_mix_streams(m
, 2);
268 } PA_RUNTIME_TEST_RUN_STOP
270 PA_RUNTIME_TEST_RUN_START("mix s16 2 channels", TIMES
, TIMES2
) {
271 acquire_mix_streams(m
, 2);
272 pa_mix_ch2_s16ne(m
, 2, out
, nsamples
* sizeof(int16_t));
273 release_mix_streams(m
, 2);
274 } PA_RUNTIME_TEST_RUN_STOP
276 fail_unless(memcmp(out
, out_ref
, nsamples
* sizeof(int16_t)) == 0);
278 PA_RUNTIME_TEST_RUN_START("mix s16 2 streams", TIMES
, TIMES2
) {
279 acquire_mix_streams(m
, 2);
280 pa_mix2_s16ne(m
, 2, out
, nsamples
* sizeof(int16_t));
281 release_mix_streams(m
, 2);
282 } PA_RUNTIME_TEST_RUN_STOP
284 fail_unless(memcmp(out
, out_ref
, nsamples
* sizeof(int16_t)) == 0);
286 PA_RUNTIME_TEST_RUN_START("mix s16 2 streams 2 channels", TIMES
, TIMES2
) {
287 acquire_mix_streams(m
, 2);
288 pa_mix2_ch2_s16ne(m
, out
, nsamples
* sizeof(int16_t));
289 release_mix_streams(m
, 2);
290 } PA_RUNTIME_TEST_RUN_STOP
292 fail_unless(memcmp(out
, out_ref
, nsamples
* sizeof(int16_t)) == 0);
294 pa_memblock_unref(c0
.memblock
);
295 pa_memblock_unref(c1
.memblock
);
297 pa_mempool_free(pool
);
301 int main(int argc
, char *argv
[]) {
307 if (!getenv("MAKE_CHECK"))
308 pa_log_set_level(PA_LOG_DEBUG
);
310 s
= suite_create("Mix-special");
311 tc
= tcase_create("mix-special 1ch");
312 tcase_add_test(tc
, mix_special_1ch_test
);
313 tcase_set_timeout(tc
, 120);
314 suite_add_tcase(s
, tc
);
315 tc
= tcase_create("mix-special 2ch");
316 tcase_add_test(tc
, mix_special_2ch_test
);
317 tcase_set_timeout(tc
, 120);
318 suite_add_tcase(s
, tc
);
320 sr
= srunner_create(s
);
321 srunner_run_all(sr
, CK_NORMAL
);
322 failed
= srunner_ntests_failed(sr
);
325 return (failed
== 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;