1 /*
2 * madplay - MPEG audio decoder and player
3 * Copyright (C) 2000-2004 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id: audio.c,v 1.36 2004/01/23 09:41:31 rob Exp $
20 */
21
22 # ifdef HAVE_CONFIG_H
23 # include "config.h"
24 # endif
25
26 # include "global.h"
27
28 # include <string.h>
29 # include <mad.h>
30
31 # include "audio.h"
32
33 char const *audio_error;
34
35 static struct audio_dither left_dither, right_dither;
36
37 # if defined(_MSC_VER)
38 # pragma warning(disable: 4550) /* expression evaluates to a function which
39 is missing an argument list */
40 # endif
41
42 /*
43 * NAME: audio_output()
44 * DESCRIPTION: choose an audio output module from a specifier pathname
45 */
audio_output(char const ** path)46 audio_ctlfunc_t *audio_output(char const **path)
47 {
48 char const *ext;
49 int i;
50
51 struct map {
52 char const *name;
53 audio_ctlfunc_t *module;
54 };
55
56 struct map const prefixes[] = {
57 { "cdda", audio_cdda },
58 { "aiff", audio_aiff },
59 { "wave", audio_wave },
60 { "wav", audio_wave },
61 { "snd", audio_snd },
62 { "au", audio_snd },
63 { "raw", audio_raw },
64 { "pcm", audio_raw },
65 { "hex", audio_hex },
66 # if defined(HAVE_LIBESD)
67 { "esd", audio_esd },
68 # endif
69 # if defined(HAVE_LIBAUDIO)
70 { "nas", audio_nas },
71 # endif
72 { "null", audio_null },
73 { "nul", audio_null }
74 };
75
76 struct map const extensions[] = {
77 { "cdr", audio_cdda },
78 { "cda", audio_cdda },
79 { "cdda", audio_cdda },
80 { "aif", audio_aiff },
81 { "aiff", audio_aiff },
82 { "wav", audio_wave },
83 { "snd", audio_snd },
84 { "au", audio_snd },
85 { "raw", audio_raw },
86 { "pcm", audio_raw },
87 { "out", audio_raw },
88 { "bin", audio_raw },
89 { "hex", audio_hex },
90 { "txt", audio_hex }
91 };
92
93 if (path == 0)
94 return AUDIO_DEFAULT;
95
96 /* check for prefix specifier */
97
98 ext = strchr(*path, ':');
99 if (ext) {
100 char const *type;
101
102 type = *path;
103 *path = ext + 1;
104
105 for (i = 0; i < sizeof(prefixes) / sizeof(prefixes[0]); ++i) {
106 if (strncasecmp(type, prefixes[i].name, ext - type) == 0 &&
107 strlen(prefixes[i].name) == ext - type)
108 return prefixes[i].module;
109 }
110
111 *path = type;
112 return 0;
113 }
114
115 if (strcmp(*path, "/dev/null") == 0)
116 return audio_null;
117
118 if (strncmp(*path, "/dev/", 5) == 0)
119 return AUDIO_DEFAULT;
120
121 /* check for file extension specifier */
122
123 ext = strrchr(*path, '.');
124 if (ext) {
125 ++ext;
126
127 for (i = 0; i < sizeof(extensions) / sizeof(extensions[0]); ++i) {
128 if (strcasecmp(ext, extensions[i].name) == 0)
129 return extensions[i].module;
130 }
131 }
132
133 return 0;
134 }
135
136 /*
137 * NAME: audio_control_init()
138 * DESCRIPTION: initialize an audio control structure
139 */
audio_control_init(union audio_control * control,enum audio_command command)140 void audio_control_init(union audio_control *control,
141 enum audio_command command)
142 {
143 switch (control->command = command) {
144 case AUDIO_COMMAND_INIT:
145 control->init.path = 0;
146 break;
147
148 case AUDIO_COMMAND_CONFIG:
149 control->config.channels = 0;
150 control->config.speed = 0;
151 control->config.precision = 0;
152 break;
153
154 case AUDIO_COMMAND_PLAY:
155 control->play.nsamples = 0;
156 control->play.samples[0] = 0;
157 control->play.samples[1] = 0;
158 control->play.mode = AUDIO_MODE_DITHER;
159 control->play.stats = 0;
160 break;
161
162 case AUDIO_COMMAND_STOP:
163 control->stop.flush = 0;
164 break;
165
166 case AUDIO_COMMAND_FINISH:
167 break;
168 }
169 }
170
171 /*
172 * NAME: clip()
173 * DESCRIPTION: gather signal statistics while clipping
174 */
175 static inline
clip(mad_fixed_t * sample,struct audio_stats * stats)176 void clip(mad_fixed_t *sample, struct audio_stats *stats)
177 {
178 enum {
179 MIN = -MAD_F_ONE,
180 MAX = MAD_F_ONE - 1
181 };
182
183 if (*sample >= stats->peak_sample) {
184 if (*sample > MAX) {
185 ++stats->clipped_samples;
186 if (*sample - MAX > stats->peak_clipping)
187 stats->peak_clipping = *sample - MAX;
188
189 *sample = MAX;
190 }
191 stats->peak_sample = *sample;
192 }
193 else if (*sample < -stats->peak_sample) {
194 if (*sample < MIN) {
195 ++stats->clipped_samples;
196 if (MIN - *sample > stats->peak_clipping)
197 stats->peak_clipping = MIN - *sample;
198
199 *sample = MIN;
200 }
201 stats->peak_sample = -*sample;
202 }
203 }
204
205 /*
206 * NAME: audio_linear_round()
207 * DESCRIPTION: generic linear sample quantize routine
208 */
209 # if defined(_MSC_VER)
210 extern /* needed to satisfy bizarre MSVC++ interaction with inline */
211 # endif
212 inline
audio_linear_round(unsigned int bits,mad_fixed_t sample,struct audio_stats * stats)213 signed long audio_linear_round(unsigned int bits, mad_fixed_t sample,
214 struct audio_stats *stats)
215 {
216 /* round */
217 sample += (1L << (MAD_F_FRACBITS - bits));
218
219 /* clip */
220 clip(&sample, stats);
221
222 /* quantize and scale */
223 return sample >> (MAD_F_FRACBITS + 1 - bits);
224 }
225
226 /*
227 * NAME: prng()
228 * DESCRIPTION: 32-bit pseudo-random number generator
229 */
230 static inline
prng(unsigned long state)231 unsigned long prng(unsigned long state)
232 {
233 return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
234 }
235
236 /*
237 * NAME: audio_linear_dither()
238 * DESCRIPTION: generic linear sample quantize and dither routine
239 */
240 # if defined(_MSC_VER)
241 extern /* needed to satisfy bizarre MSVC++ interaction with inline */
242 # endif
243 inline
audio_linear_dither(unsigned int bits,mad_fixed_t sample,struct audio_dither * dither,struct audio_stats * stats)244 signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample,
245 struct audio_dither *dither,
246 struct audio_stats *stats)
247 {
248 unsigned int scalebits;
249 mad_fixed_t output, mask, random;
250
251 enum {
252 MIN = -MAD_F_ONE,
253 MAX = MAD_F_ONE - 1
254 };
255
256 /* noise shape */
257 sample += dither->error[0] - dither->error[1] + dither->error[2];
258
259 dither->error[2] = dither->error[1];
260 dither->error[1] = dither->error[0] / 2;
261
262 /* bias */
263 output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));
264
265 scalebits = MAD_F_FRACBITS + 1 - bits;
266 mask = (1L << scalebits) - 1;
267
268 /* dither */
269 random = prng(dither->random);
270 output += (random & mask) - (dither->random & mask);
271
272 dither->random = random;
273
274 /* clip */
275 if (output >= stats->peak_sample) {
276 if (output > MAX) {
277 ++stats->clipped_samples;
278 if (output - MAX > stats->peak_clipping)
279 stats->peak_clipping = output - MAX;
280
281 output = MAX;
282
283 if (sample > MAX)
284 sample = MAX;
285 }
286 stats->peak_sample = output;
287 }
288 else if (output < -stats->peak_sample) {
289 if (output < MIN) {
290 ++stats->clipped_samples;
291 if (MIN - output > stats->peak_clipping)
292 stats->peak_clipping = MIN - output;
293
294 output = MIN;
295
296 if (sample < MIN)
297 sample = MIN;
298 }
299 stats->peak_sample = -output;
300 }
301
302 /* quantize */
303 output &= ~mask;
304
305 /* error feedback */
306 dither->error[0] = sample - output;
307
308 /* scale */
309 return output >> scalebits;
310 }
311
312 /*
313 * NAME: audio_pcm_u8()
314 * DESCRIPTION: write a block of unsigned 8-bit PCM samples
315 */
audio_pcm_u8(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)316 unsigned int audio_pcm_u8(unsigned char *data, unsigned int nsamples,
317 mad_fixed_t const *left, mad_fixed_t const *right,
318 enum audio_mode mode, struct audio_stats *stats)
319 {
320 unsigned int len;
321
322 len = nsamples;
323
324 if (right) { /* stereo */
325 switch (mode) {
326 case AUDIO_MODE_ROUND:
327 while (len--) {
328 data[0] = audio_linear_round(8, *left++, stats) ^ 0x80;
329 data[1] = audio_linear_round(8, *right++, stats) ^ 0x80;
330
331 data += 2;
332 }
333 break;
334
335 case AUDIO_MODE_DITHER:
336 while (len--) {
337 data[0] = audio_linear_dither(8, *left++,
338 &left_dither, stats) ^ 0x80;
339 data[1] = audio_linear_dither(8, *right++,
340 &right_dither, stats) ^ 0x80;
341
342 data += 2;
343 }
344 break;
345
346 default:
347 return 0;
348 }
349
350 return nsamples * 2;
351 }
352 else { /* mono */
353 switch (mode) {
354 case AUDIO_MODE_ROUND:
355 while (len--)
356 *data++ = audio_linear_round(8, *left++, stats) ^ 0x80;
357 break;
358
359 case AUDIO_MODE_DITHER:
360 while (len--)
361 *data++ = audio_linear_dither(8, *left++, &left_dither, stats) ^ 0x80;
362 break;
363
364 default:
365 return 0;
366 }
367
368 return nsamples;
369 }
370 }
371
372 /*
373 * NAME: audio_pcm_s8()
374 * DESCRIPTION: write a block of signed 8-bit PCM samples
375 */
audio_pcm_s8(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)376 unsigned int audio_pcm_s8(unsigned char *data, unsigned int nsamples,
377 mad_fixed_t const *left, mad_fixed_t const *right,
378 enum audio_mode mode, struct audio_stats *stats)
379 {
380 unsigned int len;
381
382 len = nsamples;
383
384 if (right) { /* stereo */
385 switch (mode) {
386 case AUDIO_MODE_ROUND:
387 while (len--) {
388 data[0] = audio_linear_round(8, *left++, stats);
389 data[1] = audio_linear_round(8, *right++, stats);
390
391 data += 2;
392 }
393 break;
394
395 case AUDIO_MODE_DITHER:
396 while (len--) {
397 data[0] = audio_linear_dither(8, *left++,
398 &left_dither, stats);
399 data[1] = audio_linear_dither(8, *right++,
400 &right_dither, stats);
401
402 data += 2;
403 }
404 break;
405
406 default:
407 return 0;
408 }
409
410 return nsamples * 2;
411 }
412 else { /* mono */
413 switch (mode) {
414 case AUDIO_MODE_ROUND:
415 while (len--)
416 *data++ = audio_linear_round(8, *left++, stats);
417 break;
418
419 case AUDIO_MODE_DITHER:
420 while (len--)
421 *data++ = audio_linear_dither(8, *left++, &left_dither, stats);
422 break;
423
424 default:
425 return 0;
426 }
427
428 return nsamples;
429 }
430 }
431
432 /*
433 * NAME: audio_pcm_s16le()
434 * DESCRIPTION: write a block of signed 16-bit little-endian PCM samples
435 */
audio_pcm_s16le(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)436 unsigned int audio_pcm_s16le(unsigned char *data, unsigned int nsamples,
437 mad_fixed_t const *left, mad_fixed_t const *right,
438 enum audio_mode mode, struct audio_stats *stats)
439 {
440 unsigned int len;
441 register signed int sample0, sample1;
442
443 len = nsamples;
444
445 if (right) { /* stereo */
446 switch (mode) {
447 case AUDIO_MODE_ROUND:
448 while (len--) {
449 sample0 = audio_linear_round(16, *left++, stats);
450 sample1 = audio_linear_round(16, *right++, stats);
451
452 data[0] = sample0 >> 0;
453 data[1] = sample0 >> 8;
454 data[2] = sample1 >> 0;
455 data[3] = sample1 >> 8;
456
457 data += 4;
458 }
459 break;
460
461 case AUDIO_MODE_DITHER:
462 while (len--) {
463 sample0 = audio_linear_dither(16, *left++, &left_dither, stats);
464 sample1 = audio_linear_dither(16, *right++, &right_dither, stats);
465
466 data[0] = sample0 >> 0;
467 data[1] = sample0 >> 8;
468 data[2] = sample1 >> 0;
469 data[3] = sample1 >> 8;
470
471 data += 4;
472 }
473 break;
474
475 default:
476 return 0;
477 }
478
479 return nsamples * 2 * 2;
480 }
481 else { /* mono */
482 switch (mode) {
483 case AUDIO_MODE_ROUND:
484 while (len--) {
485 sample0 = audio_linear_round(16, *left++, stats);
486
487 data[0] = sample0 >> 0;
488 data[1] = sample0 >> 8;
489
490 data += 2;
491 }
492 break;
493
494 case AUDIO_MODE_DITHER:
495 while (len--) {
496 sample0 = audio_linear_dither(16, *left++, &left_dither, stats);
497
498 data[0] = sample0 >> 0;
499 data[1] = sample0 >> 8;
500
501 data += 2;
502 }
503 break;
504
505 default:
506 return 0;
507 }
508
509 return nsamples * 2;
510 }
511 }
512
513 /*
514 * NAME: audio_pcm_s16be()
515 * DESCRIPTION: write a block of signed 16-bit big-endian PCM samples
516 */
audio_pcm_s16be(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)517 unsigned int audio_pcm_s16be(unsigned char *data, unsigned int nsamples,
518 mad_fixed_t const *left, mad_fixed_t const *right,
519 enum audio_mode mode, struct audio_stats *stats)
520 {
521 unsigned int len;
522 register signed int sample0, sample1;
523
524 len = nsamples;
525
526 if (right) { /* stereo */
527 switch (mode) {
528 case AUDIO_MODE_ROUND:
529 while (len--) {
530 sample0 = audio_linear_round(16, *left++, stats);
531 sample1 = audio_linear_round(16, *right++, stats);
532
533 data[0] = sample0 >> 8;
534 data[1] = sample0 >> 0;
535 data[2] = sample1 >> 8;
536 data[3] = sample1 >> 0;
537
538 data += 4;
539 }
540 break;
541
542 case AUDIO_MODE_DITHER:
543 while (len--) {
544 sample0 = audio_linear_dither(16, *left++, &left_dither, stats);
545 sample1 = audio_linear_dither(16, *right++, &right_dither, stats);
546
547 data[0] = sample0 >> 8;
548 data[1] = sample0 >> 0;
549 data[2] = sample1 >> 8;
550 data[3] = sample1 >> 0;
551
552 data += 4;
553 }
554 break;
555
556 default:
557 return 0;
558 }
559
560 return nsamples * 2 * 2;
561 }
562 else { /* mono */
563 switch (mode) {
564 case AUDIO_MODE_ROUND:
565 while (len--) {
566 sample0 = audio_linear_round(16, *left++, stats);
567
568 data[0] = sample0 >> 8;
569 data[1] = sample0 >> 0;
570
571 data += 2;
572 }
573 break;
574
575 case AUDIO_MODE_DITHER:
576 while (len--) {
577 sample0 = audio_linear_dither(16, *left++, &left_dither, stats);
578
579 data[0] = sample0 >> 8;
580 data[1] = sample0 >> 0;
581
582 data += 2;
583 }
584 break;
585
586 default:
587 return 0;
588 }
589
590 return nsamples * 2;
591 }
592 }
593
594 /*
595 * NAME: audio_pcm_s24le()
596 * DESCRIPTION: write a block of signed 24-bit little-endian PCM samples
597 */
audio_pcm_s24le(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)598 unsigned int audio_pcm_s24le(unsigned char *data, unsigned int nsamples,
599 mad_fixed_t const *left, mad_fixed_t const *right,
600 enum audio_mode mode, struct audio_stats *stats)
601 {
602 unsigned int len;
603 register signed long sample0, sample1;
604
605 len = nsamples;
606
607 if (right) { /* stereo */
608 switch (mode) {
609 case AUDIO_MODE_ROUND:
610 while (len--) {
611 sample0 = audio_linear_round(24, *left++, stats);
612 sample1 = audio_linear_round(24, *right++, stats);
613
614 data[0] = sample0 >> 0;
615 data[1] = sample0 >> 8;
616 data[2] = sample0 >> 16;
617
618 data[3] = sample1 >> 0;
619 data[4] = sample1 >> 8;
620 data[5] = sample1 >> 16;
621
622 data += 6;
623 }
624 break;
625
626 case AUDIO_MODE_DITHER:
627 while (len--) {
628 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
629 sample1 = audio_linear_dither(24, *right++, &right_dither, stats);
630
631 data[0] = sample0 >> 0;
632 data[1] = sample0 >> 8;
633 data[2] = sample0 >> 16;
634
635 data[3] = sample1 >> 0;
636 data[4] = sample1 >> 8;
637 data[5] = sample1 >> 16;
638
639 data += 6;
640 }
641 break;
642
643 default:
644 return 0;
645 }
646
647 return nsamples * 3 * 2;
648 }
649 else { /* mono */
650 switch (mode) {
651 case AUDIO_MODE_ROUND:
652 while (len--) {
653 sample0 = audio_linear_round(24, *left++, stats);
654
655 data[0] = sample0 >> 0;
656 data[1] = sample0 >> 8;
657 data[2] = sample0 >> 16;
658
659 data += 3;
660 }
661 break;
662
663 case AUDIO_MODE_DITHER:
664 while (len--) {
665 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
666
667 data[0] = sample0 >> 0;
668 data[1] = sample0 >> 8;
669 data[2] = sample0 >> 16;
670
671 data += 3;
672 }
673 break;
674
675 default:
676 return 0;
677 }
678
679 return nsamples * 3;
680 }
681 }
682
683 /*
684 * NAME: audio_pcm_s24be()
685 * DESCRIPTION: write a block of signed 24-bit big-endian PCM samples
686 */
audio_pcm_s24be(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)687 unsigned int audio_pcm_s24be(unsigned char *data, unsigned int nsamples,
688 mad_fixed_t const *left, mad_fixed_t const *right,
689 enum audio_mode mode, struct audio_stats *stats)
690 {
691 unsigned int len;
692 register signed long sample0, sample1;
693
694 len = nsamples;
695
696 if (right) { /* stereo */
697 switch (mode) {
698 case AUDIO_MODE_ROUND:
699 while (len--) {
700 sample0 = audio_linear_round(24, *left++, stats);
701 sample1 = audio_linear_round(24, *right++, stats);
702
703 data[0] = sample0 >> 16;
704 data[1] = sample0 >> 8;
705 data[2] = sample0 >> 0;
706
707 data[3] = sample1 >> 16;
708 data[4] = sample1 >> 8;
709 data[5] = sample1 >> 0;
710
711 data += 6;
712 }
713 break;
714
715 case AUDIO_MODE_DITHER:
716 while (len--) {
717 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
718 sample1 = audio_linear_dither(24, *right++, &right_dither, stats);
719
720 data[0] = sample0 >> 16;
721 data[1] = sample0 >> 8;
722 data[2] = sample0 >> 0;
723
724 data[3] = sample1 >> 16;
725 data[4] = sample1 >> 8;
726 data[5] = sample1 >> 0;
727
728 data += 6;
729 }
730 break;
731
732 default:
733 return 0;
734 }
735
736 return nsamples * 3 * 2;
737 }
738 else { /* mono */
739 switch (mode) {
740 case AUDIO_MODE_ROUND:
741 while (len--) {
742 sample0 = audio_linear_round(24, *left++, stats);
743
744 data[0] = sample0 >> 16;
745 data[1] = sample0 >> 8;
746 data[2] = sample0 >> 0;
747
748 data += 3;
749 }
750 break;
751
752 case AUDIO_MODE_DITHER:
753 while (len--) {
754 sample1 = audio_linear_dither(24, *left++, &left_dither, stats);
755
756 data[0] = sample1 >> 16;
757 data[1] = sample1 >> 8;
758 data[2] = sample1 >> 0;
759
760 data += 3;
761 }
762 break;
763
764 default:
765 return 0;
766 }
767
768 return nsamples * 3;
769 }
770 }
771
772 /*
773 * NAME: audio_pcm_s32le()
774 * DESCRIPTION: write a block of signed 32-bit little-endian PCM samples
775 */
audio_pcm_s32le(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)776 unsigned int audio_pcm_s32le(unsigned char *data, unsigned int nsamples,
777 mad_fixed_t const *left, mad_fixed_t const *right,
778 enum audio_mode mode, struct audio_stats *stats)
779 {
780 unsigned int len;
781 register signed long sample0, sample1;
782
783 len = nsamples;
784
785 if (right) { /* stereo */
786 switch (mode) {
787 case AUDIO_MODE_ROUND:
788 while (len--) {
789 sample0 = audio_linear_round(24, *left++, stats);
790 sample1 = audio_linear_round(24, *right++, stats);
791
792 data[0] = 0;
793 data[1] = sample0 >> 0;
794 data[2] = sample0 >> 8;
795 data[3] = sample0 >> 16;
796
797 data[4] = 0;
798 data[5] = sample1 >> 0;
799 data[6] = sample1 >> 8;
800 data[7] = sample1 >> 16;
801
802 data += 8;
803 }
804 break;
805
806 case AUDIO_MODE_DITHER:
807 while (len--) {
808 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
809 sample1 = audio_linear_dither(24, *right++, &right_dither, stats);
810
811 data[0] = 0;
812 data[1] = sample0 >> 0;
813 data[2] = sample0 >> 8;
814 data[3] = sample0 >> 16;
815
816 data[4] = 0;
817 data[5] = sample1 >> 0;
818 data[6] = sample1 >> 8;
819 data[7] = sample1 >> 16;
820
821 data += 8;
822 }
823 break;
824
825 default:
826 return 0;
827 }
828
829 return nsamples * 4 * 2;
830 }
831 else { /* mono */
832 switch (mode) {
833 case AUDIO_MODE_ROUND:
834 while (len--) {
835 sample0 = audio_linear_round(24, *left++, stats);
836
837 data[0] = 0;
838 data[1] = sample0 >> 0;
839 data[2] = sample0 >> 8;
840 data[3] = sample0 >> 16;
841
842 data += 4;
843 }
844 break;
845
846 case AUDIO_MODE_DITHER:
847 while (len--) {
848 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
849
850 data[0] = 0;
851 data[1] = sample0 >> 0;
852 data[2] = sample0 >> 8;
853 data[3] = sample0 >> 16;
854
855 data += 4;
856 }
857 break;
858
859 default:
860 return 0;
861 }
862
863 return nsamples * 4;
864 }
865 }
866
867 /*
868 * NAME: audio_pcm_s32be()
869 * DESCRIPTION: write a block of signed 32-bit big-endian PCM samples
870 */
audio_pcm_s32be(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)871 unsigned int audio_pcm_s32be(unsigned char *data, unsigned int nsamples,
872 mad_fixed_t const *left, mad_fixed_t const *right,
873 enum audio_mode mode, struct audio_stats *stats)
874 {
875 unsigned int len;
876 register signed long sample0, sample1;
877
878 len = nsamples;
879
880 if (right) { /* stereo */
881 switch (mode) {
882 case AUDIO_MODE_ROUND:
883 while (len--) {
884 sample0 = audio_linear_round(24, *left++, stats);
885 sample1 = audio_linear_round(24, *right++, stats);
886
887 data[0] = sample0 >> 16;
888 data[1] = sample0 >> 8;
889 data[2] = sample0 >> 0;
890 data[3] = 0;
891
892 data[4] = sample1 >> 16;
893 data[5] = sample1 >> 8;
894 data[6] = sample1 >> 0;
895 data[7] = 0;
896
897 data += 8;
898 }
899 break;
900
901 case AUDIO_MODE_DITHER:
902 while (len--) {
903 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
904 sample1 = audio_linear_dither(24, *right++, &right_dither, stats);
905
906 data[0] = sample0 >> 16;
907 data[1] = sample0 >> 8;
908 data[2] = sample0 >> 0;
909 data[3] = 0;
910
911 data[4] = sample1 >> 16;
912 data[5] = sample1 >> 8;
913 data[6] = sample1 >> 0;
914 data[7] = 0;
915
916 data += 8;
917 }
918 break;
919
920 default:
921 return 0;
922 }
923
924 return nsamples * 4 * 2;
925 }
926 else { /* mono */
927 switch (mode) {
928 case AUDIO_MODE_ROUND:
929 while (len--) {
930 sample0 = audio_linear_round(24, *left++, stats);
931
932 data[0] = sample0 >> 16;
933 data[1] = sample0 >> 8;
934 data[2] = sample0 >> 0;
935 data[3] = 0;
936
937 data += 4;
938 }
939 break;
940
941 case AUDIO_MODE_DITHER:
942 while (len--) {
943 sample0 = audio_linear_dither(24, *left++, &left_dither, stats);
944
945 data[0] = sample0 >> 16;
946 data[1] = sample0 >> 8;
947 data[2] = sample0 >> 0;
948 data[3] = 0;
949
950 data += 4;
951 }
952 break;
953
954 default:
955 return 0;
956 }
957
958 return nsamples * 4;
959 }
960 }
961
962 static
linear2mulaw(mad_fixed_t sample)963 unsigned char linear2mulaw(mad_fixed_t sample)
964 {
965 unsigned int sign, mulaw;
966
967 enum {
968 BIAS = (mad_fixed_t) ((0x10 << 1) + 1) << (MAD_F_FRACBITS - 13)
969 };
970
971 if (sample < 0) {
972 sample = BIAS - sample;
973 sign = 0x7f;
974 }
975 else {
976 sample = BIAS + sample;
977 sign = 0xff;
978 }
979
980 mulaw = 0x7f;
981 if (sample < MAD_F_ONE) {
982 unsigned int segment;
983 unsigned long mask;
984
985 segment = 7;
986 for (mask = 1L << (MAD_F_FRACBITS - 1); !(sample & mask); mask >>= 1)
987 --segment;
988
989 mulaw = ((segment << 4) |
990 ((sample >> (MAD_F_FRACBITS - 1 - (7 - segment) - 4)) & 0x0f));
991 }
992
993 mulaw ^= sign;
994
995 # if 0
996 if (mulaw == 0x00)
997 mulaw = 0x02;
998 # endif
999
1000 return mulaw;
1001 }
1002
1003 static
mulaw2linear(unsigned char mulaw)1004 mad_fixed_t mulaw2linear(unsigned char mulaw)
1005 {
1006 int sign, segment, mantissa, value;
1007
1008 enum {
1009 BIAS = (0x10 << 1) + 1
1010 };
1011
1012 mulaw = ~mulaw;
1013 sign = (mulaw >> 7) & 0x01;
1014 segment = (mulaw >> 4) & 0x07;
1015 mantissa = (mulaw >> 0) & 0x0f;
1016
1017 value = ((0x21 | (mantissa << 1)) << segment) - BIAS;
1018 if (sign)
1019 value = -value;
1020
1021 return (mad_fixed_t) value << (MAD_F_FRACBITS - 13);
1022 }
1023
1024 /*
1025 * NAME: audio_mulaw_round()
1026 * DESCRIPTION: convert a linear PCM value to 8-bit ISDN mu-law
1027 */
1028 inline
audio_mulaw_round(mad_fixed_t sample,struct audio_stats * stats)1029 unsigned char audio_mulaw_round(mad_fixed_t sample, struct audio_stats *stats)
1030 {
1031 clip(&sample, stats);
1032
1033 return linear2mulaw(sample);
1034 }
1035
1036 /*
1037 * NAME: audio_mulaw_dither()
1038 * DESCRIPTION: convert a linear PCM value to dithered 8-bit ISDN mu-law
1039 */
1040 inline
audio_mulaw_dither(mad_fixed_t sample,struct audio_dither * dither,struct audio_stats * stats)1041 unsigned char audio_mulaw_dither(mad_fixed_t sample,
1042 struct audio_dither *dither,
1043 struct audio_stats *stats)
1044 {
1045 unsigned char mulaw;
1046
1047 /* noise shape */
1048 sample += dither->error[0];
1049
1050 clip(&sample, stats);
1051
1052 mulaw = linear2mulaw(sample);
1053
1054 /* error feedback */
1055 dither->error[0] = sample - mulaw2linear(mulaw);
1056
1057 return mulaw;
1058 }
1059
1060 /*
1061 * NAME: audio_pcm_mulaw()
1062 * DESCRIPTION: write a block of 8-bit mu-law encoded samples
1063 */
audio_pcm_mulaw(unsigned char * data,unsigned int nsamples,mad_fixed_t const * left,mad_fixed_t const * right,enum audio_mode mode,struct audio_stats * stats)1064 unsigned int audio_pcm_mulaw(unsigned char *data, unsigned int nsamples,
1065 mad_fixed_t const *left, mad_fixed_t const *right,
1066 enum audio_mode mode, struct audio_stats *stats)
1067 {
1068 unsigned int len;
1069
1070 len = nsamples;
1071
1072 if (right) { /* stereo */
1073 switch (mode) {
1074 case AUDIO_MODE_ROUND:
1075 while (len--) {
1076 data[0] = audio_mulaw_round(*left++, stats);
1077 data[1] = audio_mulaw_round(*right++, stats);
1078
1079 data += 2;
1080 }
1081 break;
1082
1083 case AUDIO_MODE_DITHER:
1084 while (len--) {
1085 data[0] = audio_mulaw_dither(*left++, &left_dither, stats);
1086 data[1] = audio_mulaw_dither(*right++, &right_dither, stats);
1087
1088 data += 2;
1089 }
1090 break;
1091
1092 default:
1093 return 0;
1094 }
1095
1096 return nsamples * 2;
1097 }
1098 else { /* mono */
1099 switch (mode) {
1100 case AUDIO_MODE_ROUND:
1101 while (len--)
1102 *data++ = audio_mulaw_round(*left++, stats);
1103 break;
1104
1105 case AUDIO_MODE_DITHER:
1106 while (len--)
1107 *data++ = audio_mulaw_dither(*left++, &left_dither, stats);
1108 break;
1109
1110 default:
1111 return 0;
1112 }
1113
1114 return nsamples;
1115 }
1116 }
1117