2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 #include <liboil/liboilfuncs.h>
34 #include <liboil/liboil.h>
36 #include <pulse/timeval.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/core-error.h>
40 #include <pulsecore/macro.h>
41 #include <pulsecore/g711.h>
42 #include <pulsecore/core-util.h>
44 #include "sample-util.h"
45 #include "endianmacros.h"
47 #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
49 pa_memblock
*pa_silence_memblock(pa_memblock
* b
, const pa_sample_spec
*spec
) {
55 data
= pa_memblock_acquire(b
);
56 pa_silence_memory(data
, pa_memblock_get_length(b
), spec
);
57 pa_memblock_release(b
);
62 pa_memchunk
* pa_silence_memchunk(pa_memchunk
*c
, const pa_sample_spec
*spec
) {
66 pa_assert(c
->memblock
);
69 data
= pa_memblock_acquire(c
->memblock
);
70 pa_silence_memory((uint8_t*) data
+c
->index
, c
->length
, spec
);
71 pa_memblock_release(c
->memblock
);
76 static uint8_t silence_byte(pa_sample_format_t format
) {
84 case PA_SAMPLE_FLOAT32LE
:
85 case PA_SAMPLE_FLOAT32BE
:
88 case PA_SAMPLE_S24_32LE
:
89 case PA_SAMPLE_S24_32BE
:
96 pa_assert_not_reached();
100 void* pa_silence_memory(void *p
, size_t length
, const pa_sample_spec
*spec
) {
102 pa_assert(length
> 0);
105 memset(p
, silence_byte(spec
->format
), length
);
109 static void calc_linear_integer_volume(int32_t linear
[], const pa_cvolume
*volume
) {
115 for (channel
= 0; channel
< volume
->channels
; channel
++)
116 linear
[channel
] = (int32_t) lrint(pa_sw_volume_to_linear(volume
->values
[channel
]) * 0x10000);
119 static void calc_linear_float_volume(float linear
[], const pa_cvolume
*volume
) {
125 for (channel
= 0; channel
< volume
->channels
; channel
++)
126 linear
[channel
] = (float) pa_sw_volume_to_linear(volume
->values
[channel
]);
129 static void calc_linear_integer_stream_volumes(pa_mix_info streams
[], unsigned nstreams
, const pa_cvolume
*volume
, const pa_sample_spec
*spec
) {
131 float linear
[PA_CHANNELS_MAX
];
137 calc_linear_float_volume(linear
, volume
);
139 for (k
= 0; k
< nstreams
; k
++) {
141 for (channel
= 0; channel
< spec
->channels
; channel
++) {
142 pa_mix_info
*m
= streams
+ k
;
143 m
->linear
[channel
].i
= (int32_t) lrint(pa_sw_volume_to_linear(m
->volume
.values
[channel
]) * linear
[channel
] * 0x10000);
148 static void calc_linear_float_stream_volumes(pa_mix_info streams
[], unsigned nstreams
, const pa_cvolume
*volume
, const pa_sample_spec
*spec
) {
150 float linear
[PA_CHANNELS_MAX
];
156 calc_linear_float_volume(linear
, volume
);
158 for (k
= 0; k
< nstreams
; k
++) {
160 for (channel
= 0; channel
< spec
->channels
; channel
++) {
161 pa_mix_info
*m
= streams
+ k
;
162 m
->linear
[channel
].f
= (float) (pa_sw_volume_to_linear(m
->volume
.values
[channel
]) * linear
[channel
]);
168 pa_mix_info streams
[],
172 const pa_sample_spec
*spec
,
173 const pa_cvolume
*volume
,
176 pa_cvolume full_volume
;
187 volume
= pa_cvolume_reset(&full_volume
, spec
->channels
);
189 if (mute
|| pa_cvolume_is_muted(volume
) || nstreams
<= 0) {
190 pa_silence_memory(data
, length
, spec
);
194 for (k
= 0; k
< nstreams
; k
++)
195 streams
[k
].ptr
= (uint8_t*) pa_memblock_acquire(streams
[k
].chunk
.memblock
) + streams
[k
].chunk
.index
;
197 for (z
= 0; z
< nstreams
; z
++)
198 if (length
> streams
[z
].chunk
.length
)
199 length
= streams
[z
].chunk
.length
;
201 end
= (uint8_t*) data
+ length
;
203 switch (spec
->format
) {
205 case PA_SAMPLE_S16NE
:{
206 unsigned channel
= 0;
208 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
214 for (i
= 0; i
< nstreams
; i
++) {
215 pa_mix_info
*m
= streams
+ i
;
216 int32_t v
, lo
, hi
, cv
= m
->linear
[channel
].i
;
218 if (PA_UNLIKELY(cv
<= 0))
221 /* Multiplying the 32bit volume factor with the
222 * 16bit sample might result in an 48bit value. We
223 * want to do without 64 bit integers and hence do
224 * the multiplication independantly for the HI and
225 * LO part of the volume. */
230 v
= *((int16_t*) m
->ptr
);
231 v
= ((v
* lo
) >> 16) + (v
* hi
);
234 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
237 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
238 *((int16_t*) data
) = (int16_t) sum
;
240 data
= (uint8_t*) data
+ sizeof(int16_t);
242 if (PA_UNLIKELY(++channel
>= spec
->channels
))
249 case PA_SAMPLE_S16RE
:{
250 unsigned channel
= 0;
252 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
258 for (i
= 0; i
< nstreams
; i
++) {
259 pa_mix_info
*m
= streams
+ i
;
260 int32_t v
, lo
, hi
, cv
= m
->linear
[channel
].i
;
262 if (PA_UNLIKELY(cv
<= 0))
268 v
= PA_INT16_SWAP(*((int16_t*) m
->ptr
));
269 v
= ((v
* lo
) >> 16) + (v
* hi
);
272 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
275 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
276 *((int16_t*) data
) = PA_INT16_SWAP((int16_t) sum
);
278 data
= (uint8_t*) data
+ sizeof(int16_t);
280 if (PA_UNLIKELY(++channel
>= spec
->channels
))
287 case PA_SAMPLE_S32NE
:{
288 unsigned channel
= 0;
290 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
296 for (i
= 0; i
< nstreams
; i
++) {
297 pa_mix_info
*m
= streams
+ i
;
298 int32_t cv
= m
->linear
[channel
].i
;
301 if (PA_UNLIKELY(cv
<= 0))
304 v
= *((int32_t*) m
->ptr
);
308 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
311 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
312 *((int32_t*) data
) = (int32_t) sum
;
314 data
= (uint8_t*) data
+ sizeof(int32_t);
316 if (PA_UNLIKELY(++channel
>= spec
->channels
))
323 case PA_SAMPLE_S32RE
:{
324 unsigned channel
= 0;
326 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
332 for (i
= 0; i
< nstreams
; i
++) {
333 pa_mix_info
*m
= streams
+ i
;
334 int32_t cv
= m
->linear
[channel
].i
;
337 if (PA_UNLIKELY(cv
<= 0))
340 v
= PA_INT32_SWAP(*((int32_t*) m
->ptr
));
344 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
347 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
348 *((int32_t*) data
) = PA_INT32_SWAP((int32_t) sum
);
350 data
= (uint8_t*) data
+ sizeof(int32_t);
352 if (PA_UNLIKELY(++channel
>= spec
->channels
))
359 case PA_SAMPLE_S24NE
: {
360 unsigned channel
= 0;
362 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
368 for (i
= 0; i
< nstreams
; i
++) {
369 pa_mix_info
*m
= streams
+ i
;
370 int32_t cv
= m
->linear
[channel
].i
;
373 if (PA_UNLIKELY(cv
<= 0))
376 v
= (int32_t) (PA_READ24NE(m
->ptr
) << 8);
380 m
->ptr
= (uint8_t*) m
->ptr
+ 3;
383 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
384 PA_WRITE24NE(data
, ((uint32_t) sum
) >> 8);
386 data
= (uint8_t*) data
+ 3;
388 if (PA_UNLIKELY(++channel
>= spec
->channels
))
395 case PA_SAMPLE_S24RE
: {
396 unsigned channel
= 0;
398 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
404 for (i
= 0; i
< nstreams
; i
++) {
405 pa_mix_info
*m
= streams
+ i
;
406 int32_t cv
= m
->linear
[channel
].i
;
409 if (PA_UNLIKELY(cv
<= 0))
412 v
= (int32_t) (PA_READ24RE(m
->ptr
) << 8);
416 m
->ptr
= (uint8_t*) m
->ptr
+ 3;
419 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
420 PA_WRITE24RE(data
, ((uint32_t) sum
) >> 8);
422 data
= (uint8_t*) data
+ 3;
424 if (PA_UNLIKELY(++channel
>= spec
->channels
))
431 case PA_SAMPLE_S24_32NE
: {
432 unsigned channel
= 0;
434 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
440 for (i
= 0; i
< nstreams
; i
++) {
441 pa_mix_info
*m
= streams
+ i
;
442 int32_t cv
= m
->linear
[channel
].i
;
445 if (PA_UNLIKELY(cv
<= 0))
448 v
= (int32_t) (*((uint32_t*)m
->ptr
) << 8);
452 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
455 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
456 *((uint32_t*) data
) = ((uint32_t) (int32_t) sum
) >> 8;
458 data
= (uint8_t*) data
+ sizeof(uint32_t);
460 if (PA_UNLIKELY(++channel
>= spec
->channels
))
467 case PA_SAMPLE_S24_32RE
: {
468 unsigned channel
= 0;
470 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
476 for (i
= 0; i
< nstreams
; i
++) {
477 pa_mix_info
*m
= streams
+ i
;
478 int32_t cv
= m
->linear
[channel
].i
;
481 if (PA_UNLIKELY(cv
<= 0))
484 v
= (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m
->ptr
)) << 8);
488 m
->ptr
= (uint8_t*) m
->ptr
+ 3;
491 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
492 *((uint32_t*) data
) = PA_INT32_SWAP(((uint32_t) (int32_t) sum
) >> 8);
494 data
= (uint8_t*) data
+ sizeof(uint32_t);
496 if (PA_UNLIKELY(++channel
>= spec
->channels
))
504 unsigned channel
= 0;
506 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
512 for (i
= 0; i
< nstreams
; i
++) {
513 pa_mix_info
*m
= streams
+ i
;
514 int32_t v
, cv
= m
->linear
[channel
].i
;
516 if (PA_UNLIKELY(cv
<= 0))
519 v
= (int32_t) *((uint8_t*) m
->ptr
) - 0x80;
523 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
526 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80, 0x7F);
527 *((uint8_t*) data
) = (uint8_t) (sum
+ 0x80);
529 data
= (uint8_t*) data
+ 1;
531 if (PA_UNLIKELY(++channel
>= spec
->channels
))
538 case PA_SAMPLE_ULAW
: {
539 unsigned channel
= 0;
541 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
547 for (i
= 0; i
< nstreams
; i
++) {
548 pa_mix_info
*m
= streams
+ i
;
549 int32_t v
, hi
, lo
, cv
= m
->linear
[channel
].i
;
551 if (PA_UNLIKELY(cv
<= 0))
557 v
= (int32_t) st_ulaw2linear16(*((uint8_t*) m
->ptr
));
558 v
= ((v
* lo
) >> 16) + (v
* hi
);
561 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
564 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
565 *((uint8_t*) data
) = (uint8_t) st_14linear2ulaw((int16_t) sum
>> 2);
567 data
= (uint8_t*) data
+ 1;
569 if (PA_UNLIKELY(++channel
>= spec
->channels
))
576 case PA_SAMPLE_ALAW
: {
577 unsigned channel
= 0;
579 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
585 for (i
= 0; i
< nstreams
; i
++) {
586 pa_mix_info
*m
= streams
+ i
;
587 int32_t v
, hi
, lo
, cv
= m
->linear
[channel
].i
;
589 if (PA_UNLIKELY(cv
<= 0))
595 v
= (int32_t) st_alaw2linear16(*((uint8_t*) m
->ptr
));
596 v
= ((v
* lo
) >> 16) + (v
* hi
);
599 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
602 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
603 *((uint8_t*) data
) = (uint8_t) st_13linear2alaw((int16_t) sum
>> 3);
605 data
= (uint8_t*) data
+ 1;
607 if (PA_UNLIKELY(++channel
>= spec
->channels
))
614 case PA_SAMPLE_FLOAT32NE
: {
615 unsigned channel
= 0;
617 calc_linear_float_stream_volumes(streams
, nstreams
, volume
, spec
);
623 for (i
= 0; i
< nstreams
; i
++) {
624 pa_mix_info
*m
= streams
+ i
;
625 float v
, cv
= m
->linear
[channel
].f
;
627 if (PA_UNLIKELY(cv
<= 0))
630 v
= *((float*) m
->ptr
);
634 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(float);
637 *((float*) data
) = sum
;
639 data
= (uint8_t*) data
+ sizeof(float);
641 if (PA_UNLIKELY(++channel
>= spec
->channels
))
648 case PA_SAMPLE_FLOAT32RE
: {
649 unsigned channel
= 0;
651 calc_linear_float_stream_volumes(streams
, nstreams
, volume
, spec
);
657 for (i
= 0; i
< nstreams
; i
++) {
658 pa_mix_info
*m
= streams
+ i
;
659 float v
, cv
= m
->linear
[channel
].f
;
661 if (PA_UNLIKELY(cv
<= 0))
664 v
= PA_FLOAT32_SWAP(*(float*) m
->ptr
);
668 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(float);
671 *((float*) data
) = PA_FLOAT32_SWAP(sum
);
673 data
= (uint8_t*) data
+ sizeof(float);
675 if (PA_UNLIKELY(++channel
>= spec
->channels
))
683 pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec
->format
));
684 pa_assert_not_reached();
687 for (k
= 0; k
< nstreams
; k
++)
688 pa_memblock_release(streams
[k
].chunk
.memblock
);
693 typedef struct pa_volume_funcs
{
694 void (*u8
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
695 void (*alaw
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
696 void (*ulaw
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
697 void (*s16ne
) (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
698 void (*s16re
) (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
699 void (*float32ne
) (float *samples
, float *volumes
, unsigned channels
, unsigned length
);
700 void (*float32re
) (float *samples
, float *volumes
, unsigned channels
, unsigned length
);
701 void (*s32ne
) (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
702 void (*s32re
) (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
703 void (*s24ne
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
704 void (*s24re
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
705 void (*s24_32ne
) (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
706 void (*s24_32re
) (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
710 pa_volume_u8_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
714 for (channel
= 0; length
; length
--) {
717 hi
= volumes
[channel
] >> 16;
718 lo
= volumes
[channel
] & 0xFFFF;
720 t
= (int32_t) *samples
- 0x80;
721 t
= ((t
* lo
) >> 16) + (t
* hi
);
722 t
= PA_CLAMP_UNLIKELY(t
, -0x80, 0x7F);
723 *samples
++ = (uint8_t) (t
+ 0x80);
725 if (PA_UNLIKELY(++channel
>= channels
))
731 pa_volume_alaw_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
735 for (channel
= 0; length
; length
--) {
738 hi
= volumes
[channel
] >> 16;
739 lo
= volumes
[channel
] & 0xFFFF;
741 t
= (int32_t) st_alaw2linear16(*samples
);
742 t
= ((t
* lo
) >> 16) + (t
* hi
);
743 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
744 *samples
++ = (uint8_t) st_13linear2alaw((int16_t) t
>> 3);
746 if (PA_UNLIKELY(++channel
>= channels
))
752 pa_volume_ulaw_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
756 for (channel
= 0; length
; length
--) {
759 hi
= volumes
[channel
] >> 16;
760 lo
= volumes
[channel
] & 0xFFFF;
762 t
= (int32_t) st_ulaw2linear16(*samples
);
763 t
= ((t
* lo
) >> 16) + (t
* hi
);
764 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
765 *samples
++ = (uint8_t) st_14linear2ulaw((int16_t) t
>> 2);
767 if (PA_UNLIKELY(++channel
>= channels
))
773 pa_volume_s16ne_c (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
777 length
/= sizeof (int16_t);
779 for (channel
= 0; length
; length
--) {
782 /* Multiplying the 32bit volume factor with the 16bit
783 * sample might result in an 48bit value. We want to
784 * do without 64 bit integers and hence do the
785 * multiplication independantly for the HI and LO part
788 hi
= volumes
[channel
] >> 16;
789 lo
= volumes
[channel
] & 0xFFFF;
791 t
= (int32_t)(*samples
);
792 t
= ((t
* lo
) >> 16) + (t
* hi
);
793 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
794 *samples
++ = (int16_t) t
;
796 if (PA_UNLIKELY(++channel
>= channels
))
802 pa_volume_s16re_c (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
806 length
/= sizeof (int16_t);
808 for (channel
= 0; length
; length
--) {
811 hi
= volumes
[channel
] >> 16;
812 lo
= volumes
[channel
] & 0xFFFF;
814 t
= (int32_t) PA_INT16_SWAP(*samples
);
815 t
= ((t
* lo
) >> 16) + (t
* hi
);
816 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
817 *samples
++ = PA_INT16_SWAP((int16_t) t
);
819 if (PA_UNLIKELY(++channel
>= channels
))
825 pa_volume_float32ne_c (float *samples
, float *volumes
, unsigned channels
, unsigned length
)
829 length
/= sizeof (float);
831 for (channel
= 0; length
; length
--) {
832 *samples
++ *= volumes
[channel
];
834 if (PA_UNLIKELY(++channel
>= channels
))
840 pa_volume_float32re_c (float *samples
, float *volumes
, unsigned channels
, unsigned length
)
844 length
/= sizeof (float);
846 for (channel
= 0; length
; length
--) {
849 t
= PA_FLOAT32_SWAP(*samples
);
850 t
*= volumes
[channel
];
851 *samples
++ = PA_FLOAT32_SWAP(t
);
853 if (PA_UNLIKELY(++channel
>= channels
))
859 pa_volume_s32ne_c (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
863 length
/= sizeof (int32_t);
865 for (channel
= 0; length
; length
--) {
868 t
= (int64_t)(*samples
);
869 t
= (t
* volumes
[channel
]) >> 16;
870 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
871 *samples
++ = (int32_t) t
;
873 if (PA_UNLIKELY(++channel
>= channels
))
879 pa_volume_s32re_c (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
883 length
/= sizeof (int32_t);
885 for (channel
= 0; length
; length
--) {
888 t
= (int64_t) PA_INT32_SWAP(*samples
);
889 t
= (t
* volumes
[channel
]) >> 16;
890 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
891 *samples
++ = PA_INT32_SWAP((int32_t) t
);
893 if (PA_UNLIKELY(++channel
>= channels
))
899 pa_volume_s24ne_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
904 e
= samples
+ length
;
906 for (channel
= 0; samples
< e
; samples
+= 3) {
909 t
= (int64_t)((int32_t) (PA_READ24NE(samples
) << 8));
910 t
= (t
* volumes
[channel
]) >> 16;
911 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
912 PA_WRITE24NE(samples
, ((uint32_t) (int32_t) t
) >> 8);
914 if (PA_UNLIKELY(++channel
>= channels
))
920 pa_volume_s24re_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
925 e
= samples
+ length
;
927 for (channel
= 0; samples
< e
; samples
+= 3) {
930 t
= (int64_t)((int32_t) (PA_READ24RE(samples
) << 8));
931 t
= (t
* volumes
[channel
]) >> 16;
932 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
933 PA_WRITE24RE(samples
, ((uint32_t) (int32_t) t
) >> 8);
935 if (PA_UNLIKELY(++channel
>= channels
))
941 pa_volume_s24_32ne_c (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
945 length
/= sizeof (uint32_t);
947 for (channel
= 0; length
; length
--) {
950 t
= (int64_t) ((int32_t) (*samples
<< 8));
951 t
= (t
* volumes
[channel
]) >> 16;
952 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
953 *samples
++ = ((uint32_t) ((int32_t) t
)) >> 8;
955 if (PA_UNLIKELY(++channel
>= channels
))
961 pa_volume_s24_32re_c (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
965 length
/= sizeof (uint32_t);
967 for (channel
= 0; length
; length
--) {
970 t
= (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples
) << 8));
971 t
= (t
* volumes
[channel
]) >> 16;
972 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
973 *samples
++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t
)) >> 8);
975 if (PA_UNLIKELY(++channel
>= channels
))
980 typedef void (*pa_do_volume_func
) (void *samples
, void *volumes
, unsigned channels
, unsigned length
);
981 typedef void (*pa_calc_volume_func
) (void *volumes
, const pa_cvolume
*volume
);
988 static pa_calc_volume_func calc_volume_funcs
[] =
990 (pa_calc_volume_func
) calc_linear_integer_volume
,
991 (pa_calc_volume_func
) calc_linear_integer_volume
,
992 (pa_calc_volume_func
) calc_linear_integer_volume
,
993 (pa_calc_volume_func
) calc_linear_integer_volume
,
994 (pa_calc_volume_func
) calc_linear_integer_volume
,
995 (pa_calc_volume_func
) calc_linear_float_volume
,
996 (pa_calc_volume_func
) calc_linear_float_volume
,
997 (pa_calc_volume_func
) calc_linear_integer_volume
,
998 (pa_calc_volume_func
) calc_linear_integer_volume
,
999 (pa_calc_volume_func
) calc_linear_integer_volume
,
1000 (pa_calc_volume_func
) calc_linear_integer_volume
,
1001 (pa_calc_volume_func
) calc_linear_integer_volume
,
1002 (pa_calc_volume_func
) calc_linear_integer_volume
1005 static pa_do_volume_func do_volume_funcs
[] =
1007 (pa_do_volume_func
) pa_volume_u8_c
,
1008 (pa_do_volume_func
) pa_volume_alaw_c
,
1009 (pa_do_volume_func
) pa_volume_ulaw_c
,
1010 #ifdef WORDS_BIGENDIAN
1011 (pa_do_volume_func
) pa_volume_s16re_c
,
1012 (pa_do_volume_func
) pa_volume_s16ne_c
,
1013 (pa_do_volume_func
) pa_volume_float32re_c
,
1014 (pa_do_volume_func
) pa_volume_float32ne_c
,
1015 (pa_do_volume_func
) pa_volume_s32re_c
,
1016 (pa_do_volume_func
) pa_volume_s32ne_c
,
1017 (pa_do_volume_func
) pa_volume_s24re_c
,
1018 (pa_do_volume_func
) pa_volume_s24ne_c
,
1019 (pa_do_volume_func
) pa_volume_s24_32re_c
1020 (pa_do_volume_func
) pa_volume_s24_32ne_c
,
1022 (pa_do_volume_func
) pa_volume_s16ne_c
,
1023 (pa_do_volume_func
) pa_volume_s16re_c
,
1024 (pa_do_volume_func
) pa_volume_float32ne_c
,
1025 (pa_do_volume_func
) pa_volume_float32re_c
,
1026 (pa_do_volume_func
) pa_volume_s32ne_c
,
1027 (pa_do_volume_func
) pa_volume_s32re_c
,
1028 (pa_do_volume_func
) pa_volume_s24ne_c
,
1029 (pa_do_volume_func
) pa_volume_s24re_c
,
1030 (pa_do_volume_func
) pa_volume_s24_32ne_c
,
1031 (pa_do_volume_func
) pa_volume_s24_32re_c
1035 void pa_volume_memchunk(
1037 const pa_sample_spec
*spec
,
1038 const pa_cvolume
*volume
) {
1041 volume_val linear
[PA_CHANNELS_MAX
];
1045 pa_assert(c
->length
% pa_frame_size(spec
) == 0);
1048 if (pa_memblock_is_silence(c
->memblock
))
1051 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_NORM
))
1054 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_MUTED
)) {
1055 pa_silence_memchunk(c
, spec
);
1059 if (spec
->format
< 0 || spec
->format
> PA_SAMPLE_MAX
) {
1060 pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec
->format
));
1064 ptr
= (uint8_t*) pa_memblock_acquire(c
->memblock
) + c
->index
;
1066 calc_volume_funcs
[spec
->format
] ((void *)linear
, volume
);
1067 do_volume_funcs
[spec
->format
] (ptr
, (void *)linear
, spec
->channels
, c
->length
);
1069 pa_memblock_release(c
->memblock
);
1072 size_t pa_frame_align(size_t l
, const pa_sample_spec
*ss
) {
1077 fs
= pa_frame_size(ss
);
1082 pa_bool_t
pa_frame_aligned(size_t l
, const pa_sample_spec
*ss
) {
1087 fs
= pa_frame_size(ss
);
1092 void pa_interleave(const void *src
[], unsigned channels
, void *dst
, size_t ss
, unsigned n
) {
1097 pa_assert(channels
> 0);
1104 for (c
= 0; c
< channels
; c
++) {
1110 d
= (uint8_t*) dst
+ c
* ss
;
1112 for (j
= 0; j
< n
; j
++) {
1113 oil_memcpy(d
, s
, (int) ss
);
1114 s
= (uint8_t*) s
+ ss
;
1115 d
= (uint8_t*) d
+ fs
;
1120 void pa_deinterleave(const void *src
, void *dst
[], unsigned channels
, size_t ss
, unsigned n
) {
1126 pa_assert(channels
> 0);
1132 for (c
= 0; c
< channels
; c
++) {
1137 s
= (uint8_t*) src
+ c
* ss
;
1140 for (j
= 0; j
< n
; j
++) {
1141 oil_memcpy(d
, s
, (int) ss
);
1142 s
= (uint8_t*) s
+ fs
;
1143 d
= (uint8_t*) d
+ ss
;
1148 static pa_memblock
*silence_memblock_new(pa_mempool
*pool
, uint8_t c
) {
1155 length
= PA_MIN(pa_mempool_block_size_max(pool
), PA_SILENCE_MAX
);
1157 b
= pa_memblock_new(pool
, length
);
1159 data
= pa_memblock_acquire(b
);
1160 memset(data
, c
, length
);
1161 pa_memblock_release(b
);
1163 pa_memblock_set_is_silence(b
, TRUE
);
1168 void pa_silence_cache_init(pa_silence_cache
*cache
) {
1171 memset(cache
, 0, sizeof(pa_silence_cache
));
1174 void pa_silence_cache_done(pa_silence_cache
*cache
) {
1175 pa_sample_format_t f
;
1178 for (f
= 0; f
< PA_SAMPLE_MAX
; f
++)
1179 if (cache
->blocks
[f
])
1180 pa_memblock_unref(cache
->blocks
[f
]);
1182 memset(cache
, 0, sizeof(pa_silence_cache
));
1185 pa_memchunk
* pa_silence_memchunk_get(pa_silence_cache
*cache
, pa_mempool
*pool
, pa_memchunk
* ret
, const pa_sample_spec
*spec
, size_t length
) {
1190 pa_assert(pa_sample_spec_valid(spec
));
1192 if (!(b
= cache
->blocks
[spec
->format
]))
1194 switch (spec
->format
) {
1196 cache
->blocks
[PA_SAMPLE_U8
] = b
= silence_memblock_new(pool
, 0x80);
1198 case PA_SAMPLE_S16LE
:
1199 case PA_SAMPLE_S16BE
:
1200 case PA_SAMPLE_S32LE
:
1201 case PA_SAMPLE_S32BE
:
1202 case PA_SAMPLE_S24LE
:
1203 case PA_SAMPLE_S24BE
:
1204 case PA_SAMPLE_S24_32LE
:
1205 case PA_SAMPLE_S24_32BE
:
1206 case PA_SAMPLE_FLOAT32LE
:
1207 case PA_SAMPLE_FLOAT32BE
:
1208 cache
->blocks
[PA_SAMPLE_S16LE
] = b
= silence_memblock_new(pool
, 0);
1209 cache
->blocks
[PA_SAMPLE_S16BE
] = pa_memblock_ref(b
);
1210 cache
->blocks
[PA_SAMPLE_S32LE
] = pa_memblock_ref(b
);
1211 cache
->blocks
[PA_SAMPLE_S32BE
] = pa_memblock_ref(b
);
1212 cache
->blocks
[PA_SAMPLE_S24LE
] = pa_memblock_ref(b
);
1213 cache
->blocks
[PA_SAMPLE_S24BE
] = pa_memblock_ref(b
);
1214 cache
->blocks
[PA_SAMPLE_S24_32LE
] = pa_memblock_ref(b
);
1215 cache
->blocks
[PA_SAMPLE_S24_32BE
] = pa_memblock_ref(b
);
1216 cache
->blocks
[PA_SAMPLE_FLOAT32LE
] = pa_memblock_ref(b
);
1217 cache
->blocks
[PA_SAMPLE_FLOAT32BE
] = pa_memblock_ref(b
);
1219 case PA_SAMPLE_ALAW
:
1220 cache
->blocks
[PA_SAMPLE_ALAW
] = b
= silence_memblock_new(pool
, 0xd5);
1222 case PA_SAMPLE_ULAW
:
1223 cache
->blocks
[PA_SAMPLE_ULAW
] = b
= silence_memblock_new(pool
, 0xff);
1226 pa_assert_not_reached();
1231 ret
->memblock
= pa_memblock_ref(b
);
1233 l
= pa_memblock_get_length(b
);
1234 if (length
> l
|| length
== 0)
1237 ret
->length
= pa_frame_align(length
, spec
);
1243 void pa_sample_clamp(pa_sample_format_t format
, void *dst
, size_t dstr
, const void *src
, size_t sstr
, unsigned n
) {
1249 if (format
== PA_SAMPLE_FLOAT32NE
) {
1251 float minus_one
= -1.0, plus_one
= 1.0;
1252 oil_clip_f32(d
, (int) dstr
, s
, (int) sstr
, (int) n
, &minus_one
, &plus_one
);
1255 pa_assert(format
== PA_SAMPLE_FLOAT32RE
);
1257 for (; n
> 0; n
--) {
1260 f
= PA_FLOAT32_SWAP(*s
);
1261 f
= PA_CLAMP_UNLIKELY(f
, -1.0f
, 1.0f
);
1262 *d
= PA_FLOAT32_SWAP(f
);
1264 s
= (const float*) ((const uint8_t*) s
+ sstr
);
1265 d
= (float*) ((uint8_t*) d
+ dstr
);
1270 /* Similar to pa_bytes_to_usec() but rounds up, not down */
1272 pa_usec_t
pa_bytes_to_usec_round_up(uint64_t length
, const pa_sample_spec
*spec
) {
1278 fs
= pa_frame_size(spec
);
1279 length
= (length
+ fs
- 1) / fs
;
1281 usec
= (pa_usec_t
) length
* PA_USEC_PER_SEC
;
1283 return (usec
+ spec
->rate
- 1) / spec
->rate
;
1286 /* Similar to pa_usec_to_bytes() but rounds up, not down */
1288 size_t pa_usec_to_bytes_round_up(pa_usec_t t
, const pa_sample_spec
*spec
) {
1292 u
= (uint64_t) t
* (uint64_t) spec
->rate
;
1294 u
= (u
+ PA_USEC_PER_SEC
- 1) / PA_USEC_PER_SEC
;
1296 u
*= pa_frame_size(spec
);
1301 void pa_memchunk_dump_to_file(pa_memchunk
*c
, const char *fn
) {
1308 /* Only for debugging purposes */
1313 pa_log_warn("Failed to open '%s': %s", fn
, pa_cstrerror(errno
));
1317 p
= pa_memblock_acquire(c
->memblock
);
1319 if (fwrite((uint8_t*) p
+ c
->index
, 1, c
->length
, f
) != c
->length
)
1320 pa_log_warn("Failed to write to '%s': %s", fn
, pa_cstrerror(errno
));
1322 pa_memblock_release(c
->memblock
);
1327 static void calc_sine(float *f
, size_t l
, double freq
) {
1332 for (i
= 0; i
< l
; i
++)
1333 *(f
++) = (float) 0.5f
* sin((double) i
*M_PI
*2*freq
/ (double) l
);
1336 void pa_memchunk_sine(pa_memchunk
*c
, pa_mempool
*pool
, unsigned rate
, unsigned freq
) {
1341 pa_memchunk_reset(c
);
1343 gcd
= pa_gcd(rate
, freq
);
1346 l
= pa_mempool_block_size_max(pool
) / sizeof(float);
1352 c
->length
= l
* sizeof(float);
1353 c
->memblock
= pa_memblock_new(pool
, c
->length
);
1355 p
= pa_memblock_acquire(c
->memblock
);
1356 calc_sine(p
, c
->length
, freq
* l
/ rate
);
1357 pa_memblock_release(c
->memblock
);