]> code.delx.au - pulseaudio/blob - src/pulsecore/sample-util.c
sample-utils: coding style cleanup
[pulseaudio] / src / pulsecore / sample-util.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <errno.h>
32
33 #include <pulse/timeval.h>
34
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>
40
41 #include "sample-util.h"
42 #include "endianmacros.h"
43
44 #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
45
46 pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) {
47 void *data;
48
49 pa_assert(b);
50 pa_assert(spec);
51
52 data = pa_memblock_acquire(b);
53 pa_silence_memory(data, pa_memblock_get_length(b), spec);
54 pa_memblock_release(b);
55
56 return b;
57 }
58
59 pa_memchunk* pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) {
60 void *data;
61
62 pa_assert(c);
63 pa_assert(c->memblock);
64 pa_assert(spec);
65
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);
69
70 return c;
71 }
72
73 static uint8_t silence_byte(pa_sample_format_t format) {
74 switch (format) {
75 case PA_SAMPLE_U8:
76 return 0x80;
77 case PA_SAMPLE_S16LE:
78 case PA_SAMPLE_S16BE:
79 case PA_SAMPLE_S32LE:
80 case PA_SAMPLE_S32BE:
81 case PA_SAMPLE_FLOAT32LE:
82 case PA_SAMPLE_FLOAT32BE:
83 case PA_SAMPLE_S24LE:
84 case PA_SAMPLE_S24BE:
85 case PA_SAMPLE_S24_32LE:
86 case PA_SAMPLE_S24_32BE:
87 return 0;
88 case PA_SAMPLE_ALAW:
89 return 0xd5;
90 case PA_SAMPLE_ULAW:
91 return 0xff;
92 default:
93 pa_assert_not_reached();
94 }
95 }
96
97 void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {
98 pa_assert(p);
99 pa_assert(length > 0);
100 pa_assert(spec);
101
102 memset(p, silence_byte(spec->format), length);
103 return p;
104 }
105
106 static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
107 unsigned channel;
108
109 pa_assert(linear);
110 pa_assert(volume);
111
112 for (channel = 0; channel < volume->channels; channel++)
113 linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
114 }
115
116 static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
117 unsigned channel;
118
119 pa_assert(linear);
120 pa_assert(volume);
121
122 for (channel = 0; channel < volume->channels; channel++)
123 linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
124 }
125
126 static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
127 unsigned k, channel;
128 float linear[PA_CHANNELS_MAX];
129
130 pa_assert(streams);
131 pa_assert(spec);
132 pa_assert(volume);
133
134 calc_linear_float_volume(linear, volume);
135
136 for (k = 0; k < nstreams; k++) {
137
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);
141 }
142 }
143 }
144
145 static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
146 unsigned k, channel;
147 float linear[PA_CHANNELS_MAX];
148
149 pa_assert(streams);
150 pa_assert(spec);
151 pa_assert(volume);
152
153 calc_linear_float_volume(linear, volume);
154
155 for (k = 0; k < nstreams; k++) {
156
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]);
160 }
161 }
162 }
163
164 size_t pa_mix(
165 pa_mix_info streams[],
166 unsigned nstreams,
167 void *data,
168 size_t length,
169 const pa_sample_spec *spec,
170 const pa_cvolume *volume,
171 pa_bool_t mute) {
172
173 pa_cvolume full_volume;
174 unsigned k;
175 unsigned z;
176 void *end;
177
178 pa_assert(streams);
179 pa_assert(data);
180 pa_assert(length);
181 pa_assert(spec);
182
183 if (!volume)
184 volume = pa_cvolume_reset(&full_volume, spec->channels);
185
186 if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) {
187 pa_silence_memory(data, length, spec);
188 return length;
189 }
190
191 for (k = 0; k < nstreams; k++)
192 streams[k].ptr = (uint8_t*) pa_memblock_acquire(streams[k].chunk.memblock) + streams[k].chunk.index;
193
194 for (z = 0; z < nstreams; z++)
195 if (length > streams[z].chunk.length)
196 length = streams[z].chunk.length;
197
198 end = (uint8_t*) data + length;
199
200 switch (spec->format) {
201
202 case PA_SAMPLE_S16NE:{
203 unsigned channel = 0;
204
205 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
206
207 while (data < end) {
208 int32_t sum = 0;
209 unsigned i;
210
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;
214
215 if (PA_UNLIKELY(cv <= 0))
216 continue;
217
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. */
223
224 hi = cv >> 16;
225 lo = cv & 0xFFFF;
226
227 v = *((int16_t*) m->ptr);
228 v = ((v * lo) >> 16) + (v * hi);
229 sum += v;
230
231 m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
232 }
233
234 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
235 *((int16_t*) data) = (int16_t) sum;
236
237 data = (uint8_t*) data + sizeof(int16_t);
238
239 if (PA_UNLIKELY(++channel >= spec->channels))
240 channel = 0;
241 }
242
243 break;
244 }
245
246 case PA_SAMPLE_S16RE:{
247 unsigned channel = 0;
248
249 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
250
251 while (data < end) {
252 int32_t sum = 0;
253 unsigned i;
254
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;
258
259 if (PA_UNLIKELY(cv <= 0))
260 continue;
261
262 hi = cv >> 16;
263 lo = cv & 0xFFFF;
264
265 v = PA_INT16_SWAP(*((int16_t*) m->ptr));
266 v = ((v * lo) >> 16) + (v * hi);
267 sum += v;
268
269 m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
270 }
271
272 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
273 *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum);
274
275 data = (uint8_t*) data + sizeof(int16_t);
276
277 if (PA_UNLIKELY(++channel >= spec->channels))
278 channel = 0;
279 }
280
281 break;
282 }
283
284 case PA_SAMPLE_S32NE:{
285 unsigned channel = 0;
286
287 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
288
289 while (data < end) {
290 int64_t sum = 0;
291 unsigned i;
292
293 for (i = 0; i < nstreams; i++) {
294 pa_mix_info *m = streams + i;
295 int32_t cv = m->linear[channel].i;
296 int64_t v;
297
298 if (PA_UNLIKELY(cv <= 0))
299 continue;
300
301 v = *((int32_t*) m->ptr);
302 v = (v * cv) >> 16;
303 sum += v;
304
305 m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
306 }
307
308 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
309 *((int32_t*) data) = (int32_t) sum;
310
311 data = (uint8_t*) data + sizeof(int32_t);
312
313 if (PA_UNLIKELY(++channel >= spec->channels))
314 channel = 0;
315 }
316
317 break;
318 }
319
320 case PA_SAMPLE_S32RE:{
321 unsigned channel = 0;
322
323 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
324
325 while (data < end) {
326 int64_t sum = 0;
327 unsigned i;
328
329 for (i = 0; i < nstreams; i++) {
330 pa_mix_info *m = streams + i;
331 int32_t cv = m->linear[channel].i;
332 int64_t v;
333
334 if (PA_UNLIKELY(cv <= 0))
335 continue;
336
337 v = PA_INT32_SWAP(*((int32_t*) m->ptr));
338 v = (v * cv) >> 16;
339 sum += v;
340
341 m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
342 }
343
344 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
345 *((int32_t*) data) = PA_INT32_SWAP((int32_t) sum);
346
347 data = (uint8_t*) data + sizeof(int32_t);
348
349 if (PA_UNLIKELY(++channel >= spec->channels))
350 channel = 0;
351 }
352
353 break;
354 }
355
356 case PA_SAMPLE_S24NE: {
357 unsigned channel = 0;
358
359 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
360
361 while (data < end) {
362 int64_t sum = 0;
363 unsigned i;
364
365 for (i = 0; i < nstreams; i++) {
366 pa_mix_info *m = streams + i;
367 int32_t cv = m->linear[channel].i;
368 int64_t v;
369
370 if (PA_UNLIKELY(cv <= 0))
371 continue;
372
373 v = (int32_t) (PA_READ24NE(m->ptr) << 8);
374 v = (v * cv) >> 16;
375 sum += v;
376
377 m->ptr = (uint8_t*) m->ptr + 3;
378 }
379
380 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
381 PA_WRITE24NE(data, ((uint32_t) sum) >> 8);
382
383 data = (uint8_t*) data + 3;
384
385 if (PA_UNLIKELY(++channel >= spec->channels))
386 channel = 0;
387 }
388
389 break;
390 }
391
392 case PA_SAMPLE_S24RE: {
393 unsigned channel = 0;
394
395 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
396
397 while (data < end) {
398 int64_t sum = 0;
399 unsigned i;
400
401 for (i = 0; i < nstreams; i++) {
402 pa_mix_info *m = streams + i;
403 int32_t cv = m->linear[channel].i;
404 int64_t v;
405
406 if (PA_UNLIKELY(cv <= 0))
407 continue;
408
409 v = (int32_t) (PA_READ24RE(m->ptr) << 8);
410 v = (v * cv) >> 16;
411 sum += v;
412
413 m->ptr = (uint8_t*) m->ptr + 3;
414 }
415
416 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
417 PA_WRITE24RE(data, ((uint32_t) sum) >> 8);
418
419 data = (uint8_t*) data + 3;
420
421 if (PA_UNLIKELY(++channel >= spec->channels))
422 channel = 0;
423 }
424
425 break;
426 }
427
428 case PA_SAMPLE_S24_32NE: {
429 unsigned channel = 0;
430
431 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
432
433 while (data < end) {
434 int64_t sum = 0;
435 unsigned i;
436
437 for (i = 0; i < nstreams; i++) {
438 pa_mix_info *m = streams + i;
439 int32_t cv = m->linear[channel].i;
440 int64_t v;
441
442 if (PA_UNLIKELY(cv <= 0))
443 continue;
444
445 v = (int32_t) (*((uint32_t*)m->ptr) << 8);
446 v = (v * cv) >> 16;
447 sum += v;
448
449 m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
450 }
451
452 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
453 *((uint32_t*) data) = ((uint32_t) (int32_t) sum) >> 8;
454
455 data = (uint8_t*) data + sizeof(uint32_t);
456
457 if (PA_UNLIKELY(++channel >= spec->channels))
458 channel = 0;
459 }
460
461 break;
462 }
463
464 case PA_SAMPLE_S24_32RE: {
465 unsigned channel = 0;
466
467 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
468
469 while (data < end) {
470 int64_t sum = 0;
471 unsigned i;
472
473 for (i = 0; i < nstreams; i++) {
474 pa_mix_info *m = streams + i;
475 int32_t cv = m->linear[channel].i;
476 int64_t v;
477
478 if (PA_UNLIKELY(cv <= 0))
479 continue;
480
481 v = (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m->ptr)) << 8);
482 v = (v * cv) >> 16;
483 sum += v;
484
485 m->ptr = (uint8_t*) m->ptr + 3;
486 }
487
488 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
489 *((uint32_t*) data) = PA_INT32_SWAP(((uint32_t) (int32_t) sum) >> 8);
490
491 data = (uint8_t*) data + sizeof(uint32_t);
492
493 if (PA_UNLIKELY(++channel >= spec->channels))
494 channel = 0;
495 }
496
497 break;
498 }
499
500 case PA_SAMPLE_U8: {
501 unsigned channel = 0;
502
503 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
504
505 while (data < end) {
506 int32_t sum = 0;
507 unsigned i;
508
509 for (i = 0; i < nstreams; i++) {
510 pa_mix_info *m = streams + i;
511 int32_t v, cv = m->linear[channel].i;
512
513 if (PA_UNLIKELY(cv <= 0))
514 continue;
515
516 v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
517 v = (v * cv) >> 16;
518 sum += v;
519
520 m->ptr = (uint8_t*) m->ptr + 1;
521 }
522
523 sum = PA_CLAMP_UNLIKELY(sum, -0x80, 0x7F);
524 *((uint8_t*) data) = (uint8_t) (sum + 0x80);
525
526 data = (uint8_t*) data + 1;
527
528 if (PA_UNLIKELY(++channel >= spec->channels))
529 channel = 0;
530 }
531
532 break;
533 }
534
535 case PA_SAMPLE_ULAW: {
536 unsigned channel = 0;
537
538 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
539
540 while (data < end) {
541 int32_t sum = 0;
542 unsigned i;
543
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;
547
548 if (PA_UNLIKELY(cv <= 0))
549 continue;
550
551 hi = cv >> 16;
552 lo = cv & 0xFFFF;
553
554 v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
555 v = ((v * lo) >> 16) + (v * hi);
556 sum += v;
557
558 m->ptr = (uint8_t*) m->ptr + 1;
559 }
560
561 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
562 *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);
563
564 data = (uint8_t*) data + 1;
565
566 if (PA_UNLIKELY(++channel >= spec->channels))
567 channel = 0;
568 }
569
570 break;
571 }
572
573 case PA_SAMPLE_ALAW: {
574 unsigned channel = 0;
575
576 calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
577
578 while (data < end) {
579 int32_t sum = 0;
580 unsigned i;
581
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;
585
586 if (PA_UNLIKELY(cv <= 0))
587 continue;
588
589 hi = cv >> 16;
590 lo = cv & 0xFFFF;
591
592 v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
593 v = ((v * lo) >> 16) + (v * hi);
594 sum += v;
595
596 m->ptr = (uint8_t*) m->ptr + 1;
597 }
598
599 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
600 *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);
601
602 data = (uint8_t*) data + 1;
603
604 if (PA_UNLIKELY(++channel >= spec->channels))
605 channel = 0;
606 }
607
608 break;
609 }
610
611 case PA_SAMPLE_FLOAT32NE: {
612 unsigned channel = 0;
613
614 calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
615
616 while (data < end) {
617 float sum = 0;
618 unsigned i;
619
620 for (i = 0; i < nstreams; i++) {
621 pa_mix_info *m = streams + i;
622 float v, cv = m->linear[channel].f;
623
624 if (PA_UNLIKELY(cv <= 0))
625 continue;
626
627 v = *((float*) m->ptr);
628 v *= cv;
629 sum += v;
630
631 m->ptr = (uint8_t*) m->ptr + sizeof(float);
632 }
633
634 *((float*) data) = sum;
635
636 data = (uint8_t*) data + sizeof(float);
637
638 if (PA_UNLIKELY(++channel >= spec->channels))
639 channel = 0;
640 }
641
642 break;
643 }
644
645 case PA_SAMPLE_FLOAT32RE: {
646 unsigned channel = 0;
647
648 calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
649
650 while (data < end) {
651 float sum = 0;
652 unsigned i;
653
654 for (i = 0; i < nstreams; i++) {
655 pa_mix_info *m = streams + i;
656 float v, cv = m->linear[channel].f;
657
658 if (PA_UNLIKELY(cv <= 0))
659 continue;
660
661 v = PA_FLOAT32_SWAP(*(float*) m->ptr);
662 v *= cv;
663 sum += v;
664
665 m->ptr = (uint8_t*) m->ptr + sizeof(float);
666 }
667
668 *((float*) data) = PA_FLOAT32_SWAP(sum);
669
670 data = (uint8_t*) data + sizeof(float);
671
672 if (PA_UNLIKELY(++channel >= spec->channels))
673 channel = 0;
674 }
675
676 break;
677 }
678
679 default:
680 pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format));
681 pa_assert_not_reached();
682 }
683
684 for (k = 0; k < nstreams; k++)
685 pa_memblock_release(streams[k].chunk.memblock);
686
687 return length;
688 }
689
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);
704 } pa_volume_funcs;
705
706 static void
707 pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
708 {
709 unsigned channel;
710
711 for (channel = 0; length; length--) {
712 int32_t t, hi, lo;
713
714 hi = volumes[channel] >> 16;
715 lo = volumes[channel] & 0xFFFF;
716
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);
721
722 if (PA_UNLIKELY(++channel >= channels))
723 channel = 0;
724 }
725 }
726
727 static void
728 pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
729 {
730 unsigned channel;
731
732 for (channel = 0; length; length--) {
733 int32_t t, hi, lo;
734
735 hi = volumes[channel] >> 16;
736 lo = volumes[channel] & 0xFFFF;
737
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);
742
743 if (PA_UNLIKELY(++channel >= channels))
744 channel = 0;
745 }
746 }
747
748 static void
749 pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
750 {
751 unsigned channel;
752
753 for (channel = 0; length; length--) {
754 int32_t t, hi, lo;
755
756 hi = volumes[channel] >> 16;
757 lo = volumes[channel] & 0xFFFF;
758
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);
763
764 if (PA_UNLIKELY(++channel >= channels))
765 channel = 0;
766 }
767 }
768
769 static void
770 pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
771 {
772 unsigned channel;
773
774 length /= sizeof (int16_t);
775
776 for (channel = 0; length; length--) {
777 int32_t t, hi, lo;
778
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
783 * of the volume. */
784
785 hi = volumes[channel] >> 16;
786 lo = volumes[channel] & 0xFFFF;
787
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;
792
793 if (PA_UNLIKELY(++channel >= channels))
794 channel = 0;
795 }
796 }
797
798 static void
799 pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
800 {
801 unsigned channel;
802
803 length /= sizeof (int16_t);
804
805 for (channel = 0; length; length--) {
806 int32_t t, hi, lo;
807
808 hi = volumes[channel] >> 16;
809 lo = volumes[channel] & 0xFFFF;
810
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);
815
816 if (PA_UNLIKELY(++channel >= channels))
817 channel = 0;
818 }
819 }
820
821 static void
822 pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
823 {
824 unsigned channel;
825
826 length /= sizeof (float);
827
828 for (channel = 0; length; length--) {
829 *samples++ *= volumes[channel];
830
831 if (PA_UNLIKELY(++channel >= channels))
832 channel = 0;
833 }
834 }
835
836 static void
837 pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
838 {
839 unsigned channel;
840
841 length /= sizeof (float);
842
843 for (channel = 0; length; length--) {
844 float t;
845
846 t = PA_FLOAT32_SWAP(*samples);
847 t *= volumes[channel];
848 *samples++ = PA_FLOAT32_SWAP(t);
849
850 if (PA_UNLIKELY(++channel >= channels))
851 channel = 0;
852 }
853 }
854
855 static void
856 pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
857 {
858 unsigned channel;
859
860 length /= sizeof (int32_t);
861
862 for (channel = 0; length; length--) {
863 int64_t t;
864
865 t = (int64_t)(*samples);
866 t = (t * volumes[channel]) >> 16;
867 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
868 *samples++ = (int32_t) t;
869
870 if (PA_UNLIKELY(++channel >= channels))
871 channel = 0;
872 }
873 }
874
875 static void
876 pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
877 {
878 unsigned channel;
879
880 length /= sizeof (int32_t);
881
882 for (channel = 0; length; length--) {
883 int64_t t;
884
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);
889
890 if (PA_UNLIKELY(++channel >= channels))
891 channel = 0;
892 }
893 }
894
895 static void
896 pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
897 {
898 unsigned channel;
899 uint8_t *e;
900
901 e = samples + length;
902
903 for (channel = 0; samples < e; samples += 3) {
904 int64_t t;
905
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);
910
911 if (PA_UNLIKELY(++channel >= channels))
912 channel = 0;
913 }
914 }
915
916 static void
917 pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
918 {
919 unsigned channel;
920 uint8_t *e;
921
922 e = samples + length;
923
924 for (channel = 0; samples < e; samples += 3) {
925 int64_t t;
926
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);
931
932 if (PA_UNLIKELY(++channel >= channels))
933 channel = 0;
934 }
935 }
936
937 static void
938 pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
939 {
940 unsigned channel;
941
942 length /= sizeof (uint32_t);
943
944 for (channel = 0; length; length--) {
945 int64_t t;
946
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;
951
952 if (PA_UNLIKELY(++channel >= channels))
953 channel = 0;
954 }
955 }
956
957 static void
958 pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
959 {
960 unsigned channel;
961
962 length /= sizeof (uint32_t);
963
964 for (channel = 0; length; length--) {
965 int64_t t;
966
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);
971
972 if (PA_UNLIKELY(++channel >= channels))
973 channel = 0;
974 }
975 }
976
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);
979
980 typedef union {
981 float f;
982 uint32_t i;
983 } volume_val;
984
985 typedef struct pa_sample_func_t {
986 pa_calc_volume_func_t calc_volume;
987 pa_do_volume_func_t do_volume;
988 } pa_sample_func_t;
989
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
1004 };
1005
1006 static pa_do_volume_func_t do_volume_table[] =
1007 {
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
1021 };
1022
1023 void pa_volume_memchunk(
1024 pa_memchunk*c,
1025 const pa_sample_spec *spec,
1026 const pa_cvolume *volume) {
1027
1028 void *ptr;
1029 volume_val linear[PA_CHANNELS_MAX];
1030
1031 pa_assert(c);
1032 pa_assert(spec);
1033 pa_assert(c->length % pa_frame_size(spec) == 0);
1034 pa_assert(volume);
1035
1036 if (pa_memblock_is_silence(c->memblock))
1037 return;
1038
1039 if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
1040 return;
1041
1042 if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)) {
1043 pa_silence_memchunk(c, spec);
1044 return;
1045 }
1046
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));
1049 return;
1050 }
1051
1052 ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
1053
1054 calc_volume_table[spec->format] ((void *)linear, volume);
1055 do_volume_table[spec->format] (ptr, (void *)linear, spec->channels, c->length);
1056
1057 pa_memblock_release(c->memblock);
1058 }
1059
1060 size_t pa_frame_align(size_t l, const pa_sample_spec *ss) {
1061 size_t fs;
1062
1063 pa_assert(ss);
1064
1065 fs = pa_frame_size(ss);
1066
1067 return (l/fs) * fs;
1068 }
1069
1070 pa_bool_t pa_frame_aligned(size_t l, const pa_sample_spec *ss) {
1071 size_t fs;
1072
1073 pa_assert(ss);
1074
1075 fs = pa_frame_size(ss);
1076
1077 return l % fs == 0;
1078 }
1079
1080 void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, unsigned n) {
1081 unsigned c;
1082 size_t fs;
1083
1084 pa_assert(src);
1085 pa_assert(channels > 0);
1086 pa_assert(dst);
1087 pa_assert(ss > 0);
1088 pa_assert(n > 0);
1089
1090 fs = ss * channels;
1091
1092 for (c = 0; c < channels; c++) {
1093 unsigned j;
1094 void *d;
1095 const void *s;
1096
1097 s = src[c];
1098 d = (uint8_t*) dst + c * ss;
1099
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;
1104 }
1105 }
1106 }
1107
1108 void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, unsigned n) {
1109 size_t fs;
1110 unsigned c;
1111
1112 pa_assert(src);
1113 pa_assert(dst);
1114 pa_assert(channels > 0);
1115 pa_assert(ss > 0);
1116 pa_assert(n > 0);
1117
1118 fs = ss * channels;
1119
1120 for (c = 0; c < channels; c++) {
1121 unsigned j;
1122 const void *s;
1123 void *d;
1124
1125 s = (uint8_t*) src + c * ss;
1126 d = dst[c];
1127
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;
1132 }
1133 }
1134 }
1135
1136 static pa_memblock *silence_memblock_new(pa_mempool *pool, uint8_t c) {
1137 pa_memblock *b;
1138 size_t length;
1139 void *data;
1140
1141 pa_assert(pool);
1142
1143 length = PA_MIN(pa_mempool_block_size_max(pool), PA_SILENCE_MAX);
1144
1145 b = pa_memblock_new(pool, length);
1146
1147 data = pa_memblock_acquire(b);
1148 memset(data, c, length);
1149 pa_memblock_release(b);
1150
1151 pa_memblock_set_is_silence(b, TRUE);
1152
1153 return b;
1154 }
1155
1156 void pa_silence_cache_init(pa_silence_cache *cache) {
1157 pa_assert(cache);
1158
1159 memset(cache, 0, sizeof(pa_silence_cache));
1160 }
1161
1162 void pa_silence_cache_done(pa_silence_cache *cache) {
1163 pa_sample_format_t f;
1164 pa_assert(cache);
1165
1166 for (f = 0; f < PA_SAMPLE_MAX; f++)
1167 if (cache->blocks[f])
1168 pa_memblock_unref(cache->blocks[f]);
1169
1170 memset(cache, 0, sizeof(pa_silence_cache));
1171 }
1172
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) {
1174 pa_memblock *b;
1175 size_t l;
1176
1177 pa_assert(cache);
1178 pa_assert(pa_sample_spec_valid(spec));
1179
1180 if (!(b = cache->blocks[spec->format]))
1181
1182 switch (spec->format) {
1183 case PA_SAMPLE_U8:
1184 cache->blocks[PA_SAMPLE_U8] = b = silence_memblock_new(pool, 0x80);
1185 break;
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);
1206 break;
1207 case PA_SAMPLE_ALAW:
1208 cache->blocks[PA_SAMPLE_ALAW] = b = silence_memblock_new(pool, 0xd5);
1209 break;
1210 case PA_SAMPLE_ULAW:
1211 cache->blocks[PA_SAMPLE_ULAW] = b = silence_memblock_new(pool, 0xff);
1212 break;
1213 default:
1214 pa_assert_not_reached();
1215 }
1216
1217 pa_assert(b);
1218
1219 ret->memblock = pa_memblock_ref(b);
1220
1221 l = pa_memblock_get_length(b);
1222 if (length > l || length == 0)
1223 length = l;
1224
1225 ret->length = pa_frame_align(length, spec);
1226 ret->index = 0;
1227
1228 return ret;
1229 }
1230
1231 void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const void *src, size_t sstr, unsigned n) {
1232 const float *s;
1233 float *d;
1234
1235 s = src; d = dst;
1236
1237 if (format == PA_SAMPLE_FLOAT32NE) {
1238 for (; n > 0; n--) {
1239 float f;
1240
1241 f = *s;
1242 *d = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
1243
1244 s = (const float*) ((const uint8_t*) s + sstr);
1245 d = (float*) ((uint8_t*) d + dstr);
1246 }
1247 } else {
1248 pa_assert(format == PA_SAMPLE_FLOAT32RE);
1249
1250 for (; n > 0; n--) {
1251 float f;
1252
1253 f = PA_FLOAT32_SWAP(*s);
1254 f = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
1255 *d = PA_FLOAT32_SWAP(f);
1256
1257 s = (const float*) ((const uint8_t*) s + sstr);
1258 d = (float*) ((uint8_t*) d + dstr);
1259 }
1260 }
1261 }
1262
1263 /* Similar to pa_bytes_to_usec() but rounds up, not down */
1264
1265 pa_usec_t pa_bytes_to_usec_round_up(uint64_t length, const pa_sample_spec *spec) {
1266 size_t fs;
1267 pa_usec_t usec;
1268
1269 pa_assert(spec);
1270
1271 fs = pa_frame_size(spec);
1272 length = (length + fs - 1) / fs;
1273
1274 usec = (pa_usec_t) length * PA_USEC_PER_SEC;
1275
1276 return (usec + spec->rate - 1) / spec->rate;
1277 }
1278
1279 /* Similar to pa_usec_to_bytes() but rounds up, not down */
1280
1281 size_t pa_usec_to_bytes_round_up(pa_usec_t t, const pa_sample_spec *spec) {
1282 uint64_t u;
1283 pa_assert(spec);
1284
1285 u = (uint64_t) t * (uint64_t) spec->rate;
1286
1287 u = (u + PA_USEC_PER_SEC - 1) / PA_USEC_PER_SEC;
1288
1289 u *= pa_frame_size(spec);
1290
1291 return (size_t) u;
1292 }
1293
1294 void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) {
1295 FILE *f;
1296 void *p;
1297
1298 pa_assert(c);
1299 pa_assert(fn);
1300
1301 /* Only for debugging purposes */
1302
1303 f = fopen(fn, "a");
1304
1305 if (!f) {
1306 pa_log_warn("Failed to open '%s': %s", fn, pa_cstrerror(errno));
1307 return;
1308 }
1309
1310 p = pa_memblock_acquire(c->memblock);
1311
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));
1314
1315 pa_memblock_release(c->memblock);
1316
1317 fclose(f);
1318 }
1319
1320 static void calc_sine(float *f, size_t l, double freq) {
1321 size_t i;
1322
1323 l /= sizeof(float);
1324
1325 for (i = 0; i < l; i++)
1326 *(f++) = (float) 0.5f * sin((double) i*M_PI*2*freq / (double) l);
1327 }
1328
1329 void pa_memchunk_sine(pa_memchunk *c, pa_mempool *pool, unsigned rate, unsigned freq) {
1330 size_t l;
1331 unsigned gcd, n;
1332 void *p;
1333
1334 pa_memchunk_reset(c);
1335
1336 gcd = pa_gcd(rate, freq);
1337 n = rate / gcd;
1338
1339 l = pa_mempool_block_size_max(pool) / sizeof(float);
1340
1341 l /= n;
1342 if (l <= 0) l = 1;
1343 l *= n;
1344
1345 c->length = l * sizeof(float);
1346 c->memblock = pa_memblock_new(pool, c->length);
1347
1348 p = pa_memblock_acquire(c->memblock);
1349 calc_sine(p, c->length, freq * l / rate);
1350 pa_memblock_release(c->memblock);
1351 }