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 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
31 #include <liboil/liboilfuncs.h>
32 #include <liboil/liboil.h>
34 #include <pulsecore/log.h>
35 #include <pulsecore/macro.h>
36 #include <pulsecore/g711.h>
38 #include "sample-util.h"
39 #include "endianmacros.h"
41 #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
43 pa_memblock
*pa_silence_memblock(pa_memblock
* b
, const pa_sample_spec
*spec
) {
49 data
= pa_memblock_acquire(b
);
50 pa_silence_memory(data
, pa_memblock_get_length(b
), spec
);
51 pa_memblock_release(b
);
56 pa_memchunk
* pa_silence_memchunk(pa_memchunk
*c
, const pa_sample_spec
*spec
) {
60 pa_assert(c
->memblock
);
63 data
= pa_memblock_acquire(c
->memblock
);
64 pa_silence_memory((uint8_t*) data
+c
->index
, c
->length
, spec
);
65 pa_memblock_release(c
->memblock
);
70 static uint8_t silence_byte(pa_sample_format_t format
) {
78 case PA_SAMPLE_FLOAT32LE
:
79 case PA_SAMPLE_FLOAT32BE
:
86 pa_assert_not_reached();
90 void* pa_silence_memory(void *p
, size_t length
, const pa_sample_spec
*spec
) {
92 pa_assert(length
> 0);
95 memset(p
, silence_byte(spec
->format
), length
);
99 static void calc_linear_integer_stream_volumes(pa_mix_info streams
[], unsigned nstreams
, const pa_sample_spec
*spec
) {
105 for (k
= 0; k
< nstreams
; k
++) {
108 for (channel
= 0; channel
< spec
->channels
; channel
++) {
109 pa_mix_info
*m
= streams
+ k
;
110 m
->linear
[channel
].i
= (int32_t) (pa_sw_volume_to_linear(m
->volume
.values
[channel
]) * 0x10000);
115 static void calc_linear_integer_volume(int32_t linear
[], const pa_cvolume
*volume
) {
121 for (channel
= 0; channel
< volume
->channels
; channel
++)
122 linear
[channel
] = (int32_t) (pa_sw_volume_to_linear(volume
->values
[channel
]) * 0x10000);
125 static void calc_linear_float_stream_volumes(pa_mix_info streams
[], unsigned nstreams
, const pa_sample_spec
*spec
) {
131 for (k
= 0; k
< nstreams
; k
++) {
134 for (channel
= 0; channel
< spec
->channels
; channel
++) {
135 pa_mix_info
*m
= streams
+ k
;
136 m
->linear
[channel
].f
= (float) pa_sw_volume_to_linear(m
->volume
.values
[channel
]);
141 static void calc_linear_float_volume(float linear
[], const pa_cvolume
*volume
) {
147 for (channel
= 0; channel
< volume
->channels
; channel
++)
148 linear
[channel
] = (float) pa_sw_volume_to_linear(volume
->values
[channel
]);
152 pa_mix_info streams
[],
156 const pa_sample_spec
*spec
,
157 const pa_cvolume
*volume
,
160 pa_cvolume full_volume
;
171 volume
= pa_cvolume_reset(&full_volume
, spec
->channels
);
173 if (mute
|| pa_cvolume_is_muted(volume
) || nstreams
<= 0) {
174 pa_silence_memory(data
, length
, spec
);
178 for (k
= 0; k
< nstreams
; k
++)
179 streams
[k
].ptr
= (uint8_t*) pa_memblock_acquire(streams
[k
].chunk
.memblock
) + streams
[k
].chunk
.index
;
181 for (z
= 0; z
< nstreams
; z
++)
182 if (length
> streams
[z
].chunk
.length
)
183 length
= streams
[z
].chunk
.length
;
185 end
= (uint8_t*) data
+ length
;
187 switch (spec
->format
) {
189 case PA_SAMPLE_S16NE
:{
190 unsigned channel
= 0;
191 int32_t linear
[PA_CHANNELS_MAX
];
193 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
194 calc_linear_integer_volume(linear
, volume
);
200 for (i
= 0; i
< nstreams
; i
++) {
201 pa_mix_info
*m
= streams
+ i
;
202 int32_t v
, cv
= m
->linear
[channel
].i
;
204 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
207 v
= *((int16_t*) m
->ptr
);
208 v
= (v
* cv
) / 0x10000;
212 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
215 sum
= (sum
* linear
[channel
]) / 0x10000;
216 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
217 *((int16_t*) data
) = (int16_t) sum
;
219 data
= (uint8_t*) data
+ sizeof(int16_t);
221 if (PA_UNLIKELY(++channel
>= spec
->channels
))
228 case PA_SAMPLE_S16RE
:{
229 unsigned channel
= 0;
230 int32_t linear
[PA_CHANNELS_MAX
];
232 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
233 calc_linear_integer_volume(linear
, volume
);
239 for (i
= 0; i
< nstreams
; i
++) {
240 pa_mix_info
*m
= streams
+ i
;
241 int32_t v
, cv
= m
->linear
[channel
].i
;
243 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
246 v
= PA_INT16_SWAP(*((int16_t*) m
->ptr
));
247 v
= (v
* cv
) / 0x10000;
251 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int16_t);
254 sum
= (sum
* linear
[channel
]) / 0x10000;
255 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
256 *((int16_t*) data
) = PA_INT16_SWAP((int16_t) sum
);
258 data
= (uint8_t*) data
+ sizeof(int16_t);
260 if (PA_UNLIKELY(++channel
>= spec
->channels
))
267 case PA_SAMPLE_S32NE
:{
268 unsigned channel
= 0;
269 int32_t linear
[PA_CHANNELS_MAX
];
271 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
272 calc_linear_integer_volume(linear
, volume
);
278 for (i
= 0; i
< nstreams
; i
++) {
279 pa_mix_info
*m
= streams
+ i
;
281 int32_t cv
= m
->linear
[channel
].i
;
283 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
286 v
= *((int32_t*) m
->ptr
);
287 v
= (v
* cv
) / 0x10000;
291 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
294 sum
= (sum
* linear
[channel
]) / 0x10000;
295 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
296 *((int32_t*) data
) = (int32_t) sum
;
298 data
= (uint8_t*) data
+ sizeof(int32_t);
300 if (PA_UNLIKELY(++channel
>= spec
->channels
))
307 case PA_SAMPLE_S32RE
:{
308 unsigned channel
= 0;
309 int32_t linear
[PA_CHANNELS_MAX
];
311 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
312 calc_linear_integer_volume(linear
, volume
);
318 for (i
= 0; i
< nstreams
; i
++) {
319 pa_mix_info
*m
= streams
+ i
;
321 int32_t cv
= m
->linear
[channel
].i
;
323 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
326 v
= PA_INT32_SWAP(*((int32_t*) m
->ptr
));
327 v
= (v
* cv
) / 0x10000;
331 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(int32_t);
334 sum
= (sum
* linear
[channel
]) / 0x10000;
335 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80000000LL
, 0x7FFFFFFFLL
);
336 *((int32_t*) data
) = PA_INT32_SWAP((int32_t) sum
);
338 data
= (uint8_t*) data
+ sizeof(int32_t);
340 if (PA_UNLIKELY(++channel
>= spec
->channels
))
348 unsigned channel
= 0;
349 int32_t linear
[PA_CHANNELS_MAX
];
351 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
352 calc_linear_integer_volume(linear
, volume
);
358 for (i
= 0; i
< nstreams
; i
++) {
359 pa_mix_info
*m
= streams
+ i
;
360 int32_t v
, cv
= m
->linear
[channel
].i
;
362 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
365 v
= (int32_t) *((uint8_t*) m
->ptr
) - 0x80;
366 v
= (v
* cv
) / 0x10000;
370 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
373 sum
= (sum
* linear
[channel
]) / 0x10000;
374 sum
= PA_CLAMP_UNLIKELY(sum
, -0x80, 0x7F);
375 *((uint8_t*) data
) = (uint8_t) (sum
+ 0x80);
377 data
= (uint8_t*) data
+ 1;
379 if (PA_UNLIKELY(++channel
>= spec
->channels
))
386 case PA_SAMPLE_ULAW
: {
387 unsigned channel
= 0;
388 int32_t linear
[PA_CHANNELS_MAX
];
390 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
391 calc_linear_integer_volume(linear
, volume
);
397 for (i
= 0; i
< nstreams
; i
++) {
398 pa_mix_info
*m
= streams
+ i
;
399 int32_t v
, cv
= m
->linear
[channel
].i
;
401 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
404 v
= (int32_t) st_ulaw2linear16(*((uint8_t*) m
->ptr
));
405 v
= (v
* cv
) / 0x10000;
409 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
412 sum
= (sum
* linear
[channel
]) / 0x10000;
413 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
414 *((uint8_t*) data
) = (uint8_t) st_14linear2ulaw((int16_t) sum
>> 2);
416 data
= (uint8_t*) data
+ 1;
418 if (PA_UNLIKELY(++channel
>= spec
->channels
))
425 case PA_SAMPLE_ALAW
: {
426 unsigned channel
= 0;
427 int32_t linear
[PA_CHANNELS_MAX
];
429 calc_linear_integer_stream_volumes(streams
, nstreams
, spec
);
430 calc_linear_integer_volume(linear
, volume
);
436 for (i
= 0; i
< nstreams
; i
++) {
437 pa_mix_info
*m
= streams
+ i
;
438 int32_t v
, cv
= m
->linear
[channel
].i
;
440 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
443 v
= (int32_t) st_alaw2linear16(*((uint8_t*) m
->ptr
));
444 v
= (v
* cv
) / 0x10000;
448 m
->ptr
= (uint8_t*) m
->ptr
+ 1;
451 sum
= (sum
* linear
[channel
]) / 0x10000;
452 sum
= PA_CLAMP_UNLIKELY(sum
, -0x8000, 0x7FFF);
453 *((uint8_t*) data
) = (uint8_t) st_13linear2alaw((int16_t) sum
>> 3);
455 data
= (uint8_t*) data
+ 1;
457 if (PA_UNLIKELY(++channel
>= spec
->channels
))
464 case PA_SAMPLE_FLOAT32NE
: {
465 unsigned channel
= 0;
466 float linear
[PA_CHANNELS_MAX
];
468 calc_linear_float_stream_volumes(streams
, nstreams
, spec
);
469 calc_linear_float_volume(linear
, volume
);
475 for (i
= 0; i
< nstreams
; i
++) {
476 pa_mix_info
*m
= streams
+ i
;
477 float v
, cv
= m
->linear
[channel
].f
;
479 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
482 v
= *((float*) m
->ptr
);
487 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(float);
490 sum
*= linear
[channel
];
491 *((float*) data
) = sum
;
493 data
= (uint8_t*) data
+ sizeof(float);
495 if (PA_UNLIKELY(++channel
>= spec
->channels
))
502 case PA_SAMPLE_FLOAT32RE
: {
503 unsigned channel
= 0;
504 float linear
[PA_CHANNELS_MAX
];
506 calc_linear_float_stream_volumes(streams
, nstreams
, spec
);
507 calc_linear_float_volume(linear
, volume
);
513 for (i
= 0; i
< nstreams
; i
++) {
514 pa_mix_info
*m
= streams
+ i
;
515 float v
, cv
= m
->linear
[channel
].f
;
517 if (PA_UNLIKELY(cv
<= 0) || PA_UNLIKELY(linear
[channel
] <= 0))
520 v
= PA_FLOAT32_SWAP(*(float*) m
->ptr
) *cv
;
523 m
->ptr
= (uint8_t*) m
->ptr
+ sizeof(float);
526 sum
*= linear
[channel
];
527 *((float*) data
) = PA_FLOAT32_SWAP(sum
);
529 data
= (uint8_t*) data
+ sizeof(float);
531 if (PA_UNLIKELY(++channel
>= spec
->channels
))
539 pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec
->format
));
540 pa_assert_not_reached();
543 for (k
= 0; k
< nstreams
; k
++)
544 pa_memblock_release(streams
[k
].chunk
.memblock
);
550 void pa_volume_memchunk(
552 const pa_sample_spec
*spec
,
553 const pa_cvolume
*volume
) {
559 pa_assert(c
->length
% pa_frame_size(spec
) == 0);
562 if (pa_memblock_is_silence(c
->memblock
))
565 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_NORM
))
568 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_MUTED
)) {
569 pa_silence_memchunk(c
, spec
);
573 ptr
= (uint8_t*) pa_memblock_acquire(c
->memblock
) + c
->index
;
575 switch (spec
->format
) {
577 case PA_SAMPLE_S16NE
: {
580 int32_t linear
[PA_CHANNELS_MAX
];
582 calc_linear_integer_volume(linear
, volume
);
584 e
= (int16_t*) ptr
+ c
->length
/sizeof(int16_t);
586 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
590 t
= (t
* linear
[channel
]) / 0x10000;
591 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
594 if (PA_UNLIKELY(++channel
>= spec
->channels
))
600 case PA_SAMPLE_S16RE
: {
603 int32_t linear
[PA_CHANNELS_MAX
];
605 calc_linear_integer_volume(linear
, volume
);
607 e
= (int16_t*) ptr
+ c
->length
/sizeof(int16_t);
609 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
612 t
= (int32_t) PA_INT16_SWAP(*d
);
613 t
= (t
* linear
[channel
]) / 0x10000;
614 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
615 *d
= PA_INT16_SWAP((int16_t) t
);
617 if (PA_UNLIKELY(++channel
>= spec
->channels
))
624 case PA_SAMPLE_S32NE
: {
627 int32_t linear
[PA_CHANNELS_MAX
];
629 calc_linear_integer_volume(linear
, volume
);
631 e
= (int32_t*) ptr
+ c
->length
/sizeof(int32_t);
633 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
637 t
= (t
* linear
[channel
]) / 0x10000;
638 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
641 if (PA_UNLIKELY(++channel
>= spec
->channels
))
647 case PA_SAMPLE_S32RE
: {
650 int32_t linear
[PA_CHANNELS_MAX
];
652 calc_linear_integer_volume(linear
, volume
);
654 e
= (int32_t*) ptr
+ c
->length
/sizeof(int32_t);
656 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
659 t
= (int64_t) PA_INT32_SWAP(*d
);
660 t
= (t
* linear
[channel
]) / 0x10000;
661 t
= PA_CLAMP_UNLIKELY(t
, -0x80000000LL
, 0x7FFFFFFFLL
);
662 *d
= PA_INT32_SWAP((int32_t) t
);
664 if (PA_UNLIKELY(++channel
>= spec
->channels
))
674 int32_t linear
[PA_CHANNELS_MAX
];
676 calc_linear_integer_volume(linear
, volume
);
678 e
= (uint8_t*) ptr
+ c
->length
;
680 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
683 t
= (int32_t) *d
- 0x80;
684 t
= (t
* linear
[channel
]) / 0x10000;
685 t
= PA_CLAMP_UNLIKELY(t
, -0x80, 0x7F);
686 *d
= (uint8_t) (t
+ 0x80);
688 if (PA_UNLIKELY(++channel
>= spec
->channels
))
694 case PA_SAMPLE_ULAW
: {
697 int32_t linear
[PA_CHANNELS_MAX
];
699 calc_linear_integer_volume(linear
, volume
);
701 e
= (uint8_t*) ptr
+ c
->length
;
703 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
706 t
= (int32_t) st_ulaw2linear16(*d
);
707 t
= (t
* linear
[channel
]) / 0x10000;
708 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
709 *d
= (uint8_t) st_14linear2ulaw((int16_t) t
>> 2);
711 if (PA_UNLIKELY(++channel
>= spec
->channels
))
717 case PA_SAMPLE_ALAW
: {
720 int32_t linear
[PA_CHANNELS_MAX
];
722 calc_linear_integer_volume(linear
, volume
);
724 e
= (uint8_t*) ptr
+ c
->length
;
726 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
729 t
= (int32_t) st_alaw2linear16(*d
);
730 t
= (t
* linear
[channel
]) / 0x10000;
731 t
= PA_CLAMP_UNLIKELY(t
, -0x8000, 0x7FFF);
732 *d
= (uint8_t) st_13linear2alaw((int16_t) t
>> 3);
734 if (PA_UNLIKELY(++channel
>= spec
->channels
))
740 case PA_SAMPLE_FLOAT32NE
: {
747 skip
= (int) (spec
->channels
* sizeof(float));
748 n
= (unsigned) (c
->length
/sizeof(float)/spec
->channels
);
750 for (channel
= 0; channel
< spec
->channels
; channel
++) {
753 if (PA_UNLIKELY(volume
->values
[channel
] == PA_VOLUME_NORM
))
756 v
= (float) pa_sw_volume_to_linear(volume
->values
[channel
]);
758 oil_scalarmult_f32(t
, skip
, t
, skip
, &v
, (int) n
);
763 case PA_SAMPLE_FLOAT32RE
: {
766 float linear
[PA_CHANNELS_MAX
];
768 calc_linear_float_volume(linear
, volume
);
770 e
= (float*) ptr
+ c
->length
/sizeof(float);
772 for (channel
= 0, d
= ptr
; d
< e
; d
++) {
775 t
= PA_FLOAT32_SWAP(*d
);
776 t
*= linear
[channel
];
777 *d
= PA_FLOAT32_SWAP(t
);
779 if (PA_UNLIKELY(++channel
>= spec
->channels
))
788 pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec
->format
));
789 /* If we cannot change the volume, we just don't do it */
792 pa_memblock_release(c
->memblock
);
795 size_t pa_frame_align(size_t l
, const pa_sample_spec
*ss
) {
800 fs
= pa_frame_size(ss
);
805 int pa_frame_aligned(size_t l
, const pa_sample_spec
*ss
) {
810 fs
= pa_frame_size(ss
);
815 void pa_interleave(const void *src
[], unsigned channels
, void *dst
, size_t ss
, unsigned n
) {
820 pa_assert(channels
> 0);
827 for (c
= 0; c
< channels
; c
++) {
833 d
= (uint8_t*) dst
+ c
* ss
;
835 for (j
= 0; j
< n
; j
++) {
836 oil_memcpy(d
, s
, (int) ss
);
837 s
= (uint8_t*) s
+ ss
;
838 d
= (uint8_t*) d
+ fs
;
843 void pa_deinterleave(const void *src
, void *dst
[], unsigned channels
, size_t ss
, unsigned n
) {
849 pa_assert(channels
> 0);
855 for (c
= 0; c
< channels
; c
++) {
860 s
= (uint8_t*) src
+ c
* ss
;
863 for (j
= 0; j
< n
; j
++) {
864 oil_memcpy(d
, s
, (int) ss
);
865 s
= (uint8_t*) s
+ fs
;
866 d
= (uint8_t*) d
+ ss
;
871 static pa_memblock
*silence_memblock_new(pa_mempool
*pool
, uint8_t c
) {
878 length
= PA_MIN(pa_mempool_block_size_max(pool
), PA_SILENCE_MAX
);
880 b
= pa_memblock_new(pool
, length
);
882 data
= pa_memblock_acquire(b
);
883 memset(data
, c
, length
);
884 pa_memblock_release(b
);
886 pa_memblock_set_is_silence(b
, TRUE
);
891 void pa_silence_cache_init(pa_silence_cache
*cache
) {
894 memset(cache
, 0, sizeof(pa_silence_cache
));
897 void pa_silence_cache_done(pa_silence_cache
*cache
) {
898 pa_sample_format_t f
;
901 for (f
= 0; f
< PA_SAMPLE_MAX
; f
++)
902 if (cache
->blocks
[f
])
903 pa_memblock_unref(cache
->blocks
[f
]);
905 memset(cache
, 0, sizeof(pa_silence_cache
));
908 pa_memchunk
* pa_silence_memchunk_get(pa_silence_cache
*cache
, pa_mempool
*pool
, pa_memchunk
* ret
, const pa_sample_spec
*spec
, size_t length
) {
913 pa_assert(pa_sample_spec_valid(spec
));
915 if (!(b
= cache
->blocks
[spec
->format
]))
917 switch (spec
->format
) {
919 cache
->blocks
[PA_SAMPLE_U8
] = b
= silence_memblock_new(pool
, 0x80);
921 case PA_SAMPLE_S16LE
:
922 case PA_SAMPLE_S16BE
:
923 case PA_SAMPLE_S32LE
:
924 case PA_SAMPLE_S32BE
:
925 case PA_SAMPLE_FLOAT32LE
:
926 case PA_SAMPLE_FLOAT32BE
:
927 cache
->blocks
[PA_SAMPLE_S16LE
] = b
= silence_memblock_new(pool
, 0);
928 cache
->blocks
[PA_SAMPLE_S16BE
] = pa_memblock_ref(b
);
929 cache
->blocks
[PA_SAMPLE_S32LE
] = pa_memblock_ref(b
);
930 cache
->blocks
[PA_SAMPLE_S32BE
] = pa_memblock_ref(b
);
931 cache
->blocks
[PA_SAMPLE_FLOAT32LE
] = pa_memblock_ref(b
);
932 cache
->blocks
[PA_SAMPLE_FLOAT32BE
] = pa_memblock_ref(b
);
935 cache
->blocks
[PA_SAMPLE_ALAW
] = b
= silence_memblock_new(pool
, 0xd5);
938 cache
->blocks
[PA_SAMPLE_ULAW
] = b
= silence_memblock_new(pool
, 0xff);
941 pa_assert_not_reached();
946 ret
->memblock
= pa_memblock_ref(b
);
948 l
= pa_memblock_get_length(b
);
949 if (length
> l
|| length
== 0)
952 ret
->length
= pa_frame_align(length
, spec
);
958 void pa_sample_clamp(pa_sample_format_t format
, void *dst
, size_t dstr
, const void *src
, size_t sstr
, unsigned n
) {
964 if (format
== PA_SAMPLE_FLOAT32NE
) {
966 float minus_one
= -1.0, plus_one
= 1.0;
967 oil_clip_f32(d
, (int) dstr
, s
, (int) sstr
, (int) n
, &minus_one
, &plus_one
);
970 pa_assert(format
== PA_SAMPLE_FLOAT32RE
);
975 f
= PA_FLOAT32_SWAP(*s
);
976 f
= PA_CLAMP_UNLIKELY(f
, -1.0f
, 1.0f
);
977 *d
= PA_FLOAT32_SWAP(f
);
979 s
= (const float*) ((const uint8_t*) s
+ sstr
);
980 d
= (float*) ((uint8_t*) d
+ dstr
);