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 <pulse/timeval.h>
35 #include <pulsecore/log.h>
36 #include <pulsecore/core-error.h>
37 #include <pulsecore/macro.h>
38 #include <pulsecore/g711.h>
39 #include <pulsecore/core-util.h>
41 #include "sample-util.h"
42 #include "endianmacros.h"
44 #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
46 pa_memblock
*pa_silence_memblock(pa_memblock
* b
, const pa_sample_spec
*spec
) {
52 data
= pa_memblock_acquire(b
);
53 pa_silence_memory(data
, pa_memblock_get_length(b
), spec
);
54 pa_memblock_release(b
);
59 pa_memchunk
* pa_silence_memchunk(pa_memchunk
*c
, const pa_sample_spec
*spec
) {
63 pa_assert(c
->memblock
);
66 data
= pa_memblock_acquire(c
->memblock
);
67 pa_silence_memory((uint8_t*) data
+c
->index
, c
->length
, spec
);
68 pa_memblock_release(c
->memblock
);
73 static uint8_t silence_byte(pa_sample_format_t format
) {
81 case PA_SAMPLE_FLOAT32LE
:
82 case PA_SAMPLE_FLOAT32BE
:
85 case PA_SAMPLE_S24_32LE
:
86 case PA_SAMPLE_S24_32BE
:
93 pa_assert_not_reached();
97 void* pa_silence_memory(void *p
, size_t length
, const pa_sample_spec
*spec
) {
99 pa_assert(length
> 0);
102 memset(p
, silence_byte(spec
->format
), length
);
106 static void calc_linear_integer_volume(int32_t linear
[], const pa_cvolume
*volume
) {
112 for (channel
= 0; channel
< volume
->channels
; channel
++)
113 linear
[channel
] = (int32_t) lrint(pa_sw_volume_to_linear(volume
->values
[channel
]) * 0x10000);
116 static void calc_linear_float_volume(float linear
[], const pa_cvolume
*volume
) {
122 for (channel
= 0; channel
< volume
->channels
; channel
++)
123 linear
[channel
] = (float) pa_sw_volume_to_linear(volume
->values
[channel
]);
126 static void calc_linear_integer_stream_volumes(pa_mix_info streams
[], unsigned nstreams
, const pa_cvolume
*volume
, const pa_sample_spec
*spec
) {
128 float linear
[PA_CHANNELS_MAX
];
134 calc_linear_float_volume(linear
, volume
);
136 for (k
= 0; k
< nstreams
; k
++) {
138 for (channel
= 0; channel
< spec
->channels
; channel
++) {
139 pa_mix_info
*m
= streams
+ k
;
140 m
->linear
[channel
].i
= (int32_t) lrint(pa_sw_volume_to_linear(m
->volume
.values
[channel
]) * linear
[channel
] * 0x10000);
145 static void calc_linear_float_stream_volumes(pa_mix_info streams
[], unsigned nstreams
, const pa_cvolume
*volume
, const pa_sample_spec
*spec
) {
147 float linear
[PA_CHANNELS_MAX
];
153 calc_linear_float_volume(linear
, volume
);
155 for (k
= 0; k
< nstreams
; k
++) {
157 for (channel
= 0; channel
< spec
->channels
; channel
++) {
158 pa_mix_info
*m
= streams
+ k
;
159 m
->linear
[channel
].f
= (float) (pa_sw_volume_to_linear(m
->volume
.values
[channel
]) * linear
[channel
]);
165 pa_mix_info streams
[],
169 const pa_sample_spec
*spec
,
170 const pa_cvolume
*volume
,
173 pa_cvolume full_volume
;
184 volume
= pa_cvolume_reset(&full_volume
, spec
->channels
);
186 if (mute
|| pa_cvolume_is_muted(volume
) || nstreams
<= 0) {
187 pa_silence_memory(data
, length
, spec
);
191 for (k
= 0; k
< nstreams
; k
++)
192 streams
[k
].ptr
= (uint8_t*) pa_memblock_acquire(streams
[k
].chunk
.memblock
) + streams
[k
].chunk
.index
;
194 for (z
= 0; z
< nstreams
; z
++)
195 if (length
> streams
[z
].chunk
.length
)
196 length
= streams
[z
].chunk
.length
;
198 end
= (uint8_t*) data
+ length
;
200 switch (spec
->format
) {
202 case PA_SAMPLE_S16NE
:{
203 unsigned channel
= 0;
205 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
211 for (i
= 0; i
< nstreams
; i
++) {
212 pa_mix_info
*m
= streams
+ i
;
213 int32_t v
, lo
, hi
, cv
= m
->linear
[channel
].i
;
215 if (PA_UNLIKELY(cv
<= 0))
218 /* Multiplying the 32bit volume factor with the
219 * 16bit sample might result in an 48bit value. We
220 * want to do without 64 bit integers and hence do
221 * the multiplication independantly for the HI and
222 * LO part of the volume. */
227 v
= *((int16_t*) m
->ptr
);
228 v
= ((v
* lo
) >> 16) + (v
* hi
);
231 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
234 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
235 *((int16_t*) data
) = (int16_t) sum
;
237 data
= (uint8_t*) data
+ sizeof(int16_t);
239 if (PA_UNLIKELY(++channel
>= spec
->channels
))
246 case PA_SAMPLE_S16RE
:{
247 unsigned channel
= 0;
249 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
255 for (i
= 0; i
< nstreams
; i
++) {
256 pa_mix_info
*m
= streams
+ i
;
257 int32_t v
, lo
, hi
, cv
= m
->linear
[channel
].i
;
259 if (PA_UNLIKELY(cv
<= 0))
265 v
= PA_INT16_SWAP(*((int16_t*) m
->ptr
));
266 v
= ((v
* lo
) >> 16) + (v
* hi
);
269 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
272 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
273 *((int16_t*) data
) = PA_INT16_SWAP((int16_t) sum
);
275 data
= (uint8_t*) data
+ sizeof(int16_t);
277 if (PA_UNLIKELY(++channel
>= spec
->channels
))
284 case PA_SAMPLE_S32NE
:{
285 unsigned channel
= 0;
287 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
293 for (i
= 0; i
< nstreams
; i
++) {
294 pa_mix_info
*m
= streams
+ i
;
295 int32_t cv
= m
->linear
[channel
].i
;
298 if (PA_UNLIKELY(cv
<= 0))
301 v
= *((int32_t*) m
->ptr
);
305 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
308 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
309 *((int32_t*) data
) = (int32_t) sum
;
311 data
= (uint8_t*) data
+ sizeof(int32_t);
313 if (PA_UNLIKELY(++channel
>= spec
->channels
))
320 case PA_SAMPLE_S32RE
:{
321 unsigned channel
= 0;
323 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
329 for (i
= 0; i
< nstreams
; i
++) {
330 pa_mix_info
*m
= streams
+ i
;
331 int32_t cv
= m
->linear
[channel
].i
;
334 if (PA_UNLIKELY(cv
<= 0))
337 v
= PA_INT32_SWAP(*((int32_t*) m
->ptr
));
341 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
344 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
345 *((int32_t*) data
) = PA_INT32_SWAP((int32_t) sum
);
347 data
= (uint8_t*) data
+ sizeof(int32_t);
349 if (PA_UNLIKELY(++channel
>= spec
->channels
))
356 case PA_SAMPLE_S24NE
: {
357 unsigned channel
= 0;
359 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
365 for (i
= 0; i
< nstreams
; i
++) {
366 pa_mix_info
*m
= streams
+ i
;
367 int32_t cv
= m
->linear
[channel
].i
;
370 if (PA_UNLIKELY(cv
<= 0))
373 v
= (int32_t) (PA_READ24NE(m
->ptr
) << 8);
377 m
->ptr
= (uint8_t*) m
->ptr
+ 3;
380 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
381 PA_WRITE24NE(data
, ((uint32_t) sum
) >> 8);
383 data
= (uint8_t*) data
+ 3;
385 if (PA_UNLIKELY(++channel
>= spec
->channels
))
392 case PA_SAMPLE_S24RE
: {
393 unsigned channel
= 0;
395 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
401 for (i
= 0; i
< nstreams
; i
++) {
402 pa_mix_info
*m
= streams
+ i
;
403 int32_t cv
= m
->linear
[channel
].i
;
406 if (PA_UNLIKELY(cv
<= 0))
409 v
= (int32_t) (PA_READ24RE(m
->ptr
) << 8);
413 m
->ptr
= (uint8_t*) m
->ptr
+ 3;
416 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
417 PA_WRITE24RE(data
, ((uint32_t) sum
) >> 8);
419 data
= (uint8_t*) data
+ 3;
421 if (PA_UNLIKELY(++channel
>= spec
->channels
))
428 case PA_SAMPLE_S24_32NE
: {
429 unsigned channel
= 0;
431 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
437 for (i
= 0; i
< nstreams
; i
++) {
438 pa_mix_info
*m
= streams
+ i
;
439 int32_t cv
= m
->linear
[channel
].i
;
442 if (PA_UNLIKELY(cv
<= 0))
445 v
= (int32_t) (*((uint32_t*)m
->ptr
) << 8);
449 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
452 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
453 *((uint32_t*) data
) = ((uint32_t) (int32_t) sum
) >> 8;
455 data
= (uint8_t*) data
+ sizeof(uint32_t);
457 if (PA_UNLIKELY(++channel
>= spec
->channels
))
464 case PA_SAMPLE_S24_32RE
: {
465 unsigned channel
= 0;
467 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
473 for (i
= 0; i
< nstreams
; i
++) {
474 pa_mix_info
*m
= streams
+ i
;
475 int32_t cv
= m
->linear
[channel
].i
;
478 if (PA_UNLIKELY(cv
<= 0))
481 v
= (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m
->ptr
)) << 8);
485 m
->ptr
= (uint8_t*) m
->ptr
+ 3;
488 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
489 *((uint32_t*) data
) = PA_INT32_SWAP(((uint32_t) (int32_t) sum
) >> 8);
491 data
= (uint8_t*) data
+ sizeof(uint32_t);
493 if (PA_UNLIKELY(++channel
>= spec
->channels
))
501 unsigned channel
= 0;
503 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
509 for (i
= 0; i
< nstreams
; i
++) {
510 pa_mix_info
*m
= streams
+ i
;
511 int32_t v
, cv
= m
->linear
[channel
].i
;
513 if (PA_UNLIKELY(cv
<= 0))
516 v
= (int32_t) *((uint8_t*) m
->ptr
) - 0x80;
520 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
523 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80, 0x7F);
524 *((uint8_t*) data
) = (uint8_t) (sum
+ 0x80);
526 data
= (uint8_t*) data
+ 1;
528 if (PA_UNLIKELY(++channel
>= spec
->channels
))
535 case PA_SAMPLE_ULAW
: {
536 unsigned channel
= 0;
538 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
544 for (i
= 0; i
< nstreams
; i
++) {
545 pa_mix_info
*m
= streams
+ i
;
546 int32_t v
, hi
, lo
, cv
= m
->linear
[channel
].i
;
548 if (PA_UNLIKELY(cv
<= 0))
554 v
= (int32_t) st_ulaw2linear16(*((uint8_t*) m
->ptr
));
555 v
= ((v
* lo
) >> 16) + (v
* hi
);
558 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
561 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
562 *((uint8_t*) data
) = (uint8_t) st_14linear2ulaw((int16_t) sum
>> 2);
564 data
= (uint8_t*) data
+ 1;
566 if (PA_UNLIKELY(++channel
>= spec
->channels
))
573 case PA_SAMPLE_ALAW
: {
574 unsigned channel
= 0;
576 calc_linear_integer_stream_volumes(streams
, nstreams
, volume
, spec
);
582 for (i
= 0; i
< nstreams
; i
++) {
583 pa_mix_info
*m
= streams
+ i
;
584 int32_t v
, hi
, lo
, cv
= m
->linear
[channel
].i
;
586 if (PA_UNLIKELY(cv
<= 0))
592 v
= (int32_t) st_alaw2linear16(*((uint8_t*) m
->ptr
));
593 v
= ((v
* lo
) >> 16) + (v
* hi
);
596 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
599 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
600 *((uint8_t*) data
) = (uint8_t) st_13linear2alaw((int16_t) sum
>> 3);
602 data
= (uint8_t*) data
+ 1;
604 if (PA_UNLIKELY(++channel
>= spec
->channels
))
611 case PA_SAMPLE_FLOAT32NE
: {
612 unsigned channel
= 0;
614 calc_linear_float_stream_volumes(streams
, nstreams
, volume
, spec
);
620 for (i
= 0; i
< nstreams
; i
++) {
621 pa_mix_info
*m
= streams
+ i
;
622 float v
, cv
= m
->linear
[channel
].f
;
624 if (PA_UNLIKELY(cv
<= 0))
627 v
= *((float*) m
->ptr
);
631 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(float);
634 *((float*) data
) = sum
;
636 data
= (uint8_t*) data
+ sizeof(float);
638 if (PA_UNLIKELY(++channel
>= spec
->channels
))
645 case PA_SAMPLE_FLOAT32RE
: {
646 unsigned channel
= 0;
648 calc_linear_float_stream_volumes(streams
, nstreams
, volume
, spec
);
654 for (i
= 0; i
< nstreams
; i
++) {
655 pa_mix_info
*m
= streams
+ i
;
656 float v
, cv
= m
->linear
[channel
].f
;
658 if (PA_UNLIKELY(cv
<= 0))
661 v
= PA_FLOAT32_SWAP(*(float*) m
->ptr
);
665 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(float);
668 *((float*) data
) = PA_FLOAT32_SWAP(sum
);
670 data
= (uint8_t*) data
+ sizeof(float);
672 if (PA_UNLIKELY(++channel
>= spec
->channels
))
680 pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec
->format
));
681 pa_assert_not_reached();
684 for (k
= 0; k
< nstreams
; k
++)
685 pa_memblock_release(streams
[k
].chunk
.memblock
);
690 typedef struct pa_volume_funcs
{
691 void (*u8
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
692 void (*alaw
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
693 void (*ulaw
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
694 void (*s16ne
) (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
695 void (*s16re
) (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
696 void (*float32ne
) (float *samples
, float *volumes
, unsigned channels
, unsigned length
);
697 void (*float32re
) (float *samples
, float *volumes
, unsigned channels
, unsigned length
);
698 void (*s32ne
) (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
699 void (*s32re
) (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
700 void (*s24ne
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
701 void (*s24re
) (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
702 void (*s24_32ne
) (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
703 void (*s24_32re
) (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
);
707 pa_volume_u8_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
711 for (channel
= 0; length
; length
--) {
714 hi
= volumes
[channel
] >> 16;
715 lo
= volumes
[channel
] & 0xFFFF;
717 t
= (int32_t) *samples
- 0x80;
718 t
= ((t
* lo
) >> 16) + (t
* hi
);
719 t
= PA_CLAMP_UNLIKELY(t
, -0x80, 0x7F);
720 *samples
++ = (uint8_t) (t
+ 0x80);
722 if (PA_UNLIKELY(++channel
>= channels
))
728 pa_volume_alaw_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
732 for (channel
= 0; length
; length
--) {
735 hi
= volumes
[channel
] >> 16;
736 lo
= volumes
[channel
] & 0xFFFF;
738 t
= (int32_t) st_alaw2linear16(*samples
);
739 t
= ((t
* lo
) >> 16) + (t
* hi
);
740 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
741 *samples
++ = (uint8_t) st_13linear2alaw((int16_t) t
>> 3);
743 if (PA_UNLIKELY(++channel
>= channels
))
749 pa_volume_ulaw_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
753 for (channel
= 0; length
; length
--) {
756 hi
= volumes
[channel
] >> 16;
757 lo
= volumes
[channel
] & 0xFFFF;
759 t
= (int32_t) st_ulaw2linear16(*samples
);
760 t
= ((t
* lo
) >> 16) + (t
* hi
);
761 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
762 *samples
++ = (uint8_t) st_14linear2ulaw((int16_t) t
>> 2);
764 if (PA_UNLIKELY(++channel
>= channels
))
770 pa_volume_s16ne_c (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
774 length
/= sizeof (int16_t);
776 for (channel
= 0; length
; length
--) {
779 /* Multiplying the 32bit volume factor with the 16bit
780 * sample might result in an 48bit value. We want to
781 * do without 64 bit integers and hence do the
782 * multiplication independantly for the HI and LO part
785 hi
= volumes
[channel
] >> 16;
786 lo
= volumes
[channel
] & 0xFFFF;
788 t
= (int32_t)(*samples
);
789 t
= ((t
* lo
) >> 16) + (t
* hi
);
790 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
791 *samples
++ = (int16_t) t
;
793 if (PA_UNLIKELY(++channel
>= channels
))
799 pa_volume_s16re_c (int16_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
803 length
/= sizeof (int16_t);
805 for (channel
= 0; length
; length
--) {
808 hi
= volumes
[channel
] >> 16;
809 lo
= volumes
[channel
] & 0xFFFF;
811 t
= (int32_t) PA_INT16_SWAP(*samples
);
812 t
= ((t
* lo
) >> 16) + (t
* hi
);
813 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
814 *samples
++ = PA_INT16_SWAP((int16_t) t
);
816 if (PA_UNLIKELY(++channel
>= channels
))
822 pa_volume_float32ne_c (float *samples
, float *volumes
, unsigned channels
, unsigned length
)
826 length
/= sizeof (float);
828 for (channel
= 0; length
; length
--) {
829 *samples
++ *= volumes
[channel
];
831 if (PA_UNLIKELY(++channel
>= channels
))
837 pa_volume_float32re_c (float *samples
, float *volumes
, unsigned channels
, unsigned length
)
841 length
/= sizeof (float);
843 for (channel
= 0; length
; length
--) {
846 t
= PA_FLOAT32_SWAP(*samples
);
847 t
*= volumes
[channel
];
848 *samples
++ = PA_FLOAT32_SWAP(t
);
850 if (PA_UNLIKELY(++channel
>= channels
))
856 pa_volume_s32ne_c (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
860 length
/= sizeof (int32_t);
862 for (channel
= 0; length
; length
--) {
865 t
= (int64_t)(*samples
);
866 t
= (t
* volumes
[channel
]) >> 16;
867 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
868 *samples
++ = (int32_t) t
;
870 if (PA_UNLIKELY(++channel
>= channels
))
876 pa_volume_s32re_c (int32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
880 length
/= sizeof (int32_t);
882 for (channel
= 0; length
; length
--) {
885 t
= (int64_t) PA_INT32_SWAP(*samples
);
886 t
= (t
* volumes
[channel
]) >> 16;
887 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
888 *samples
++ = PA_INT32_SWAP((int32_t) t
);
890 if (PA_UNLIKELY(++channel
>= channels
))
896 pa_volume_s24ne_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
901 e
= samples
+ length
;
903 for (channel
= 0; samples
< e
; samples
+= 3) {
906 t
= (int64_t)((int32_t) (PA_READ24NE(samples
) << 8));
907 t
= (t
* volumes
[channel
]) >> 16;
908 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
909 PA_WRITE24NE(samples
, ((uint32_t) (int32_t) t
) >> 8);
911 if (PA_UNLIKELY(++channel
>= channels
))
917 pa_volume_s24re_c (uint8_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
922 e
= samples
+ length
;
924 for (channel
= 0; samples
< e
; samples
+= 3) {
927 t
= (int64_t)((int32_t) (PA_READ24RE(samples
) << 8));
928 t
= (t
* volumes
[channel
]) >> 16;
929 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
930 PA_WRITE24RE(samples
, ((uint32_t) (int32_t) t
) >> 8);
932 if (PA_UNLIKELY(++channel
>= channels
))
938 pa_volume_s24_32ne_c (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
942 length
/= sizeof (uint32_t);
944 for (channel
= 0; length
; length
--) {
947 t
= (int64_t) ((int32_t) (*samples
<< 8));
948 t
= (t
* volumes
[channel
]) >> 16;
949 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
950 *samples
++ = ((uint32_t) ((int32_t) t
)) >> 8;
952 if (PA_UNLIKELY(++channel
>= channels
))
958 pa_volume_s24_32re_c (uint32_t *samples
, int32_t *volumes
, unsigned channels
, unsigned length
)
962 length
/= sizeof (uint32_t);
964 for (channel
= 0; length
; length
--) {
967 t
= (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples
) << 8));
968 t
= (t
* volumes
[channel
]) >> 16;
969 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
970 *samples
++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t
)) >> 8);
972 if (PA_UNLIKELY(++channel
>= channels
))
977 typedef void (*pa_do_volume_func_t
) (void *samples
, void *volumes
, unsigned channels
, unsigned length
);
978 typedef void (*pa_calc_volume_func_t
) (void *volumes
, const pa_cvolume
*volume
);
985 typedef struct pa_sample_func_t
{
986 pa_calc_volume_func_t calc_volume
;
987 pa_do_volume_func_t do_volume
;
990 static const pa_calc_volume_func_t calc_volume_table
[] = {
991 [PA_SAMPLE_U8
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
992 [PA_SAMPLE_ALAW
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
993 [PA_SAMPLE_ULAW
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
994 [PA_SAMPLE_S16LE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
995 [PA_SAMPLE_S16BE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
996 [PA_SAMPLE_FLOAT32LE
] = (pa_calc_volume_func_t
) calc_linear_float_volume
,
997 [PA_SAMPLE_FLOAT32BE
] = (pa_calc_volume_func_t
) calc_linear_float_volume
,
998 [PA_SAMPLE_S32LE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
999 [PA_SAMPLE_S32BE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
1000 [PA_SAMPLE_S24LE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
1001 [PA_SAMPLE_S24BE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
1002 [PA_SAMPLE_S24_32LE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
,
1003 [PA_SAMPLE_S24_32BE
] = (pa_calc_volume_func_t
) calc_linear_integer_volume
1006 static pa_do_volume_func_t do_volume_table
[] =
1008 [PA_SAMPLE_U8
] = (pa_do_volume_func_t
) pa_volume_u8_c
,
1009 [PA_SAMPLE_ALAW
] = (pa_do_volume_func_t
) pa_volume_alaw_c
,
1010 [PA_SAMPLE_ULAW
] = (pa_do_volume_func_t
) pa_volume_ulaw_c
,
1011 [PA_SAMPLE_S16NE
] = (pa_do_volume_func_t
) pa_volume_s16ne_c
,
1012 [PA_SAMPLE_S16RE
] = (pa_do_volume_func_t
) pa_volume_s16re_c
,
1013 [PA_SAMPLE_FLOAT32NE
] = (pa_do_volume_func_t
) pa_volume_float32ne_c
,
1014 [PA_SAMPLE_FLOAT32RE
] = (pa_do_volume_func_t
) pa_volume_float32re_c
,
1015 [PA_SAMPLE_S32NE
] = (pa_do_volume_func_t
) pa_volume_s32ne_c
,
1016 [PA_SAMPLE_S32RE
] = (pa_do_volume_func_t
) pa_volume_s32re_c
,
1017 [PA_SAMPLE_S24NE
] = (pa_do_volume_func_t
) pa_volume_s24ne_c
,
1018 [PA_SAMPLE_S24RE
] = (pa_do_volume_func_t
) pa_volume_s24re_c
,
1019 [PA_SAMPLE_S24_32NE
] = (pa_do_volume_func_t
) pa_volume_s24_32ne_c
,
1020 [PA_SAMPLE_S24_32RE
] = (pa_do_volume_func_t
) pa_volume_s24_32re_c
1023 void pa_volume_memchunk(
1025 const pa_sample_spec
*spec
,
1026 const pa_cvolume
*volume
) {
1029 volume_val linear
[PA_CHANNELS_MAX
];
1033 pa_assert(c
->length
% pa_frame_size(spec
) == 0);
1036 if (pa_memblock_is_silence(c
->memblock
))
1039 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_NORM
))
1042 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_MUTED
)) {
1043 pa_silence_memchunk(c
, spec
);
1047 if (spec
->format
< 0 || spec
->format
> PA_SAMPLE_MAX
) {
1048 pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec
->format
));
1052 ptr
= (uint8_t*) pa_memblock_acquire(c
->memblock
) + c
->index
;
1054 calc_volume_table
[spec
->format
] ((void *)linear
, volume
);
1055 do_volume_table
[spec
->format
] (ptr
, (void *)linear
, spec
->channels
, c
->length
);
1057 pa_memblock_release(c
->memblock
);
1060 size_t pa_frame_align(size_t l
, const pa_sample_spec
*ss
) {
1065 fs
= pa_frame_size(ss
);
1070 pa_bool_t
pa_frame_aligned(size_t l
, const pa_sample_spec
*ss
) {
1075 fs
= pa_frame_size(ss
);
1080 void pa_interleave(const void *src
[], unsigned channels
, void *dst
, size_t ss
, unsigned n
) {
1085 pa_assert(channels
> 0);
1092 for (c
= 0; c
< channels
; c
++) {
1098 d
= (uint8_t*) dst
+ c
* ss
;
1100 for (j
= 0; j
< n
; j
++) {
1101 memcpy(d
, s
, (int) ss
);
1102 s
= (uint8_t*) s
+ ss
;
1103 d
= (uint8_t*) d
+ fs
;
1108 void pa_deinterleave(const void *src
, void *dst
[], unsigned channels
, size_t ss
, unsigned n
) {
1114 pa_assert(channels
> 0);
1120 for (c
= 0; c
< channels
; c
++) {
1125 s
= (uint8_t*) src
+ c
* ss
;
1128 for (j
= 0; j
< n
; j
++) {
1129 memcpy(d
, s
, (int) ss
);
1130 s
= (uint8_t*) s
+ fs
;
1131 d
= (uint8_t*) d
+ ss
;
1136 static pa_memblock
*silence_memblock_new(pa_mempool
*pool
, uint8_t c
) {
1143 length
= PA_MIN(pa_mempool_block_size_max(pool
), PA_SILENCE_MAX
);
1145 b
= pa_memblock_new(pool
, length
);
1147 data
= pa_memblock_acquire(b
);
1148 memset(data
, c
, length
);
1149 pa_memblock_release(b
);
1151 pa_memblock_set_is_silence(b
, TRUE
);
1156 void pa_silence_cache_init(pa_silence_cache
*cache
) {
1159 memset(cache
, 0, sizeof(pa_silence_cache
));
1162 void pa_silence_cache_done(pa_silence_cache
*cache
) {
1163 pa_sample_format_t f
;
1166 for (f
= 0; f
< PA_SAMPLE_MAX
; f
++)
1167 if (cache
->blocks
[f
])
1168 pa_memblock_unref(cache
->blocks
[f
]);
1170 memset(cache
, 0, sizeof(pa_silence_cache
));
1173 pa_memchunk
* pa_silence_memchunk_get(pa_silence_cache
*cache
, pa_mempool
*pool
, pa_memchunk
* ret
, const pa_sample_spec
*spec
, size_t length
) {
1178 pa_assert(pa_sample_spec_valid(spec
));
1180 if (!(b
= cache
->blocks
[spec
->format
]))
1182 switch (spec
->format
) {
1184 cache
->blocks
[PA_SAMPLE_U8
] = b
= silence_memblock_new(pool
, 0x80);
1186 case PA_SAMPLE_S16LE
:
1187 case PA_SAMPLE_S16BE
:
1188 case PA_SAMPLE_S32LE
:
1189 case PA_SAMPLE_S32BE
:
1190 case PA_SAMPLE_S24LE
:
1191 case PA_SAMPLE_S24BE
:
1192 case PA_SAMPLE_S24_32LE
:
1193 case PA_SAMPLE_S24_32BE
:
1194 case PA_SAMPLE_FLOAT32LE
:
1195 case PA_SAMPLE_FLOAT32BE
:
1196 cache
->blocks
[PA_SAMPLE_S16LE
] = b
= silence_memblock_new(pool
, 0);
1197 cache
->blocks
[PA_SAMPLE_S16BE
] = pa_memblock_ref(b
);
1198 cache
->blocks
[PA_SAMPLE_S32LE
] = pa_memblock_ref(b
);
1199 cache
->blocks
[PA_SAMPLE_S32BE
] = pa_memblock_ref(b
);
1200 cache
->blocks
[PA_SAMPLE_S24LE
] = pa_memblock_ref(b
);
1201 cache
->blocks
[PA_SAMPLE_S24BE
] = pa_memblock_ref(b
);
1202 cache
->blocks
[PA_SAMPLE_S24_32LE
] = pa_memblock_ref(b
);
1203 cache
->blocks
[PA_SAMPLE_S24_32BE
] = pa_memblock_ref(b
);
1204 cache
->blocks
[PA_SAMPLE_FLOAT32LE
] = pa_memblock_ref(b
);
1205 cache
->blocks
[PA_SAMPLE_FLOAT32BE
] = pa_memblock_ref(b
);
1207 case PA_SAMPLE_ALAW
:
1208 cache
->blocks
[PA_SAMPLE_ALAW
] = b
= silence_memblock_new(pool
, 0xd5);
1210 case PA_SAMPLE_ULAW
:
1211 cache
->blocks
[PA_SAMPLE_ULAW
] = b
= silence_memblock_new(pool
, 0xff);
1214 pa_assert_not_reached();
1219 ret
->memblock
= pa_memblock_ref(b
);
1221 l
= pa_memblock_get_length(b
);
1222 if (length
> l
|| length
== 0)
1225 ret
->length
= pa_frame_align(length
, spec
);
1231 void pa_sample_clamp(pa_sample_format_t format
, void *dst
, size_t dstr
, const void *src
, size_t sstr
, unsigned n
) {
1237 if (format
== PA_SAMPLE_FLOAT32NE
) {
1238 for (; n
> 0; n
--) {
1242 *d
= PA_CLAMP_UNLIKELY(f
, -1.0f
, 1.0f
);
1244 s
= (const float*) ((const uint8_t*) s
+ sstr
);
1245 d
= (float*) ((uint8_t*) d
+ dstr
);
1248 pa_assert(format
== PA_SAMPLE_FLOAT32RE
);
1250 for (; n
> 0; n
--) {
1253 f
= PA_FLOAT32_SWAP(*s
);
1254 f
= PA_CLAMP_UNLIKELY(f
, -1.0f
, 1.0f
);
1255 *d
= PA_FLOAT32_SWAP(f
);
1257 s
= (const float*) ((const uint8_t*) s
+ sstr
);
1258 d
= (float*) ((uint8_t*) d
+ dstr
);
1263 /* Similar to pa_bytes_to_usec() but rounds up, not down */
1265 pa_usec_t
pa_bytes_to_usec_round_up(uint64_t length
, const pa_sample_spec
*spec
) {
1271 fs
= pa_frame_size(spec
);
1272 length
= (length
+ fs
- 1) / fs
;
1274 usec
= (pa_usec_t
) length
* PA_USEC_PER_SEC
;
1276 return (usec
+ spec
->rate
- 1) / spec
->rate
;
1279 /* Similar to pa_usec_to_bytes() but rounds up, not down */
1281 size_t pa_usec_to_bytes_round_up(pa_usec_t t
, const pa_sample_spec
*spec
) {
1285 u
= (uint64_t) t
* (uint64_t) spec
->rate
;
1287 u
= (u
+ PA_USEC_PER_SEC
- 1) / PA_USEC_PER_SEC
;
1289 u
*= pa_frame_size(spec
);
1294 void pa_memchunk_dump_to_file(pa_memchunk
*c
, const char *fn
) {
1301 /* Only for debugging purposes */
1306 pa_log_warn("Failed to open '%s': %s", fn
, pa_cstrerror(errno
));
1310 p
= pa_memblock_acquire(c
->memblock
);
1312 if (fwrite((uint8_t*) p
+ c
->index
, 1, c
->length
, f
) != c
->length
)
1313 pa_log_warn("Failed to write to '%s': %s", fn
, pa_cstrerror(errno
));
1315 pa_memblock_release(c
->memblock
);
1320 static void calc_sine(float *f
, size_t l
, double freq
) {
1325 for (i
= 0; i
< l
; i
++)
1326 *(f
++) = (float) 0.5f
* sin((double) i
*M_PI
*2*freq
/ (double) l
);
1329 void pa_memchunk_sine(pa_memchunk
*c
, pa_mempool
*pool
, unsigned rate
, unsigned freq
) {
1334 pa_memchunk_reset(c
);
1336 gcd
= pa_gcd(rate
, freq
);
1339 l
= pa_mempool_block_size_max(pool
) / sizeof(float);
1345 c
->length
= l
* sizeof(float);
1346 c
->memblock
= pa_memblock_new(pool
, c
->length
);
1348 p
= pa_memblock_acquire(c
->memblock
);
1349 calc_sine(p
, c
->length
, freq
* l
/ rate
);
1350 pa_memblock_release(c
->memblock
);