]>
code.delx.au - pulseaudio/blob - polyp/sample-util.c
52974c46a7930746cb133560a37742ef83d43b0b
4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <liboil/liboilfuncs.h>
34 #include "sample-util.h"
36 pa_memblock
*pa_silence_memblock(pa_memblock
* b
, const pa_sample_spec
*spec
) {
37 assert(b
&& b
->data
&& spec
);
38 pa_silence_memory(b
->data
, b
->length
, spec
);
42 void pa_silence_memchunk(pa_memchunk
*c
, const pa_sample_spec
*spec
) {
43 assert(c
&& c
->memblock
&& c
->memblock
->data
&& spec
&& c
->length
);
45 pa_silence_memory((uint8_t*) c
->memblock
->data
+c
->index
, c
->length
, spec
);
48 void pa_silence_memory(void *p
, size_t length
, const pa_sample_spec
*spec
) {
50 assert(p
&& length
&& spec
);
52 switch (spec
->format
) {
58 case PA_SAMPLE_FLOAT32
:
73 const pa_mix_info streams
[],
77 const pa_sample_spec
*spec
,
78 const pa_cvolume
*volume
) {
80 assert(streams
&& data
&& length
&& spec
);
82 switch (spec
->format
) {
83 case PA_SAMPLE_S16NE
:{
87 for (d
= 0;; d
+= sizeof(int16_t)) {
93 if (volume
->values
[channel
] != PA_VOLUME_MUTED
) {
96 for (i
= 0; i
< nstreams
; i
++) {
98 pa_volume_t cvolume
= streams
[i
].volume
.values
[channel
];
100 if (d
>= streams
[i
].chunk
.length
)
103 if (cvolume
== PA_VOLUME_MUTED
)
106 v
= *((int16_t*) ((uint8_t*) streams
[i
].chunk
.memblock
->data
+ streams
[i
].chunk
.index
+ d
));
108 if (cvolume
!= PA_VOLUME_NORM
) {
117 if (volume
->values
[channel
] != PA_VOLUME_NORM
) {
118 sum
*= volume
->values
[channel
];
119 sum
/= PA_VOLUME_NORM
;
122 if (sum
< -0x8000) sum
= -0x8000;
123 if (sum
> 0x7FFF) sum
= 0x7FFF;
127 *((int16_t*) data
) = sum
;
128 data
= (uint8_t*) data
+ sizeof(int16_t);
130 if (++channel
>= spec
->channels
)
137 unsigned channel
= 0;
145 if (volume
->values
[channel
] != PA_VOLUME_MUTED
) {
148 for (i
= 0; i
< nstreams
; i
++) {
150 pa_volume_t cvolume
= streams
[i
].volume
.values
[channel
];
152 if (d
>= streams
[i
].chunk
.length
)
155 if (cvolume
== PA_VOLUME_MUTED
)
158 v
= (int32_t) *((uint8_t*) streams
[i
].chunk
.memblock
->data
+ streams
[i
].chunk
.index
+ d
) - 0x80;
160 if (cvolume
!= PA_VOLUME_NORM
) {
169 if (volume
->values
[channel
] != PA_VOLUME_NORM
) {
170 sum
*= volume
->values
[channel
];
171 sum
/= PA_VOLUME_NORM
;
174 if (sum
< -0x80) sum
= -0x80;
175 if (sum
> 0x7F) sum
= 0x7F;
179 *((uint8_t*) data
) = (uint8_t) (sum
+ 0x80);
180 data
= (uint8_t*) data
+ 1;
182 if (++channel
>= spec
->channels
)
187 case PA_SAMPLE_FLOAT32NE
: {
189 unsigned channel
= 0;
191 for (d
= 0;; d
+= sizeof(float)) {
197 if (volume
->values
[channel
] != PA_VOLUME_MUTED
) {
200 for (i
= 0; i
< nstreams
; i
++) {
202 pa_volume_t cvolume
= streams
[i
].volume
.values
[channel
];
204 if (d
>= streams
[i
].chunk
.length
)
207 if (cvolume
== PA_VOLUME_MUTED
)
210 v
= *((float*) ((uint8_t*) streams
[i
].chunk
.memblock
->data
+ streams
[i
].chunk
.index
+ d
));
212 if (cvolume
!= PA_VOLUME_NORM
) {
221 if (volume
->values
[channel
] != PA_VOLUME_NORM
) {
222 sum
*= volume
->values
[channel
];
223 sum
/= PA_VOLUME_NORM
;
227 *((float*) data
) = sum
;
228 data
= (uint8_t*) data
+ sizeof(float);
230 if (++channel
>= spec
->channels
)
241 void pa_volume_memchunk(pa_memchunk
*c
, const pa_sample_spec
*spec
, const pa_cvolume
*volume
) {
242 assert(c
&& spec
&& (c
->length
% pa_frame_size(spec
) == 0));
245 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_NORM
))
248 if (pa_cvolume_channels_equal_to(volume
, PA_VOLUME_MUTED
)) {
249 pa_silence_memchunk(c
, spec
);
253 switch (spec
->format
) {
254 case PA_SAMPLE_S16NE
: {
257 unsigned channel
= 0;
259 for (d
= (int16_t*) ((uint8_t*) c
->memblock
->data
+c
->index
), n
= c
->length
/sizeof(int16_t); n
> 0; d
++, n
--) {
260 int32_t t
= (int32_t)(*d
);
262 t
*= volume
->values
[channel
];
265 if (t
< -0x8000) t
= -0x8000;
266 if (t
> 0x7FFF) t
= 0x7FFF;
270 if (++channel
>= spec
->channels
)
279 unsigned channel
= 0;
281 for (d
= (uint8_t*) c
->memblock
->data
+ c
->index
, n
= c
->length
; n
> 0; d
++, n
--) {
282 int32_t t
= (int32_t) *d
- 0x80;
284 t
*= volume
->values
[channel
];
287 if (t
< -0x80) t
= -0x80;
288 if (t
> 0x7F) t
= 0x7F;
290 *d
= (uint8_t) (t
+ 0x80);
292 if (++channel
>= spec
->channels
)
298 case PA_SAMPLE_FLOAT32NE
: {
304 d
= (float*) ((uint8_t*) c
->memblock
->data
+ c
->index
);
305 skip
= spec
->channels
* sizeof(float);
306 n
= c
->length
/sizeof(float)/spec
->channels
;
308 for (channel
= 0; channel
< spec
->channels
; channel
++) {
311 if (volume
->values
[channel
] == PA_VOLUME_NORM
)
314 v
= (float) volume
->values
[channel
] / PA_VOLUME_NORM
;
317 oil_scalarmult_f32(t
, skip
, t
, skip
, &v
, n
);
323 pa_log_error(__FILE__
": ERROR: Unable to change volume of format %s.\n",
324 pa_sample_format_to_string(spec
->format
));