comparison src/linuxplay.c @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents 52952cbfc5b5
children c42ec1d1cded
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
75 #define perror(str) fprintf(stderr,"audio: %s %s\n",str,strerror(errno)); 75 #define perror(str) fprintf(stderr,"audio: %s %s\n",str,strerror(errno));
76 #define warn(str) fprintf(stderr,"audio: %s\n",str); 76 #define warn(str) fprintf(stderr,"audio: %s\n",str);
77 #else 77 #else
78 #include "lisp.h" 78 #include "lisp.h"
79 #include "syssignal.h" 79 #include "syssignal.h"
80 #include "sysfile.h"
80 #define perror(str) message("audio: %s, %s ",str,strerror(errno)) 81 #define perror(str) message("audio: %s, %s ",str,strerror(errno))
81 #define warn(str) message("audio: %s ",GETTEXT(str)) 82 #define warn(str) message("audio: %s ",GETTEXT(str))
82 #endif 83 #endif
83 84
84 #ifdef __GNUC__ 85 #ifdef __GNUC__
85 #define UNUSED(x) ((void)(x)) 86 #define UNUSED(x) ((void)(x))
86 #else 87 #else
87 #define UNUSED(x) 88 #define UNUSED(x)
88 #define __inline__ 89 #define __inline__
93 94
94 /* Maintain global variable for keeping parser state information; this struct 95 /* Maintain global variable for keeping parser state information; this struct
95 is set to zero before the first invocation of the parser. The use of a 96 is set to zero before the first invocation of the parser. The use of a
96 global variable prevents multiple concurrent executions of this code, but 97 global variable prevents multiple concurrent executions of this code, but
97 this does not happen anyways... */ 98 this does not happen anyways... */
99 enum wvState
100 { wvMain,
101 wvSubchunk,
102 wvOutOfBlock,
103 wvSkipChunk,
104 wvSoundChunk,
105 wvFatal,
106 wvFatalNotify
107 };
108
98 static union { 109 static union {
99 struct { 110 struct {
100 int align; 111 int align;
101 enum {wvMain,wvSubchunk,wvOutOfBlock,wvSkipChunk, 112 enum wvState state;
102 wvSoundChunk,wvFatal,wvFatalNotify} state;
103 size_t left; 113 size_t left;
104 unsigned char leftover[HEADERSZ]; 114 unsigned char leftover[HEADERSZ];
105 signed long chunklength; 115 signed long chunklength;
106 } wave; 116 } wave;
107 struct { 117 struct {
184 if ((rq -= parsestate.wave.left) <= 0) 194 if ((rq -= parsestate.wave.left) <= 0)
185 return(rc); 195 return(rc);
186 if (rq > *sz) {rq = *sz; rc = 0;} 196 if (rq > *sz) {rq = *sz; rc = 0;}
187 memcpy(parsestate.wave.leftover+parsestate.wave.left, 197 memcpy(parsestate.wave.leftover+parsestate.wave.left,
188 *data,rq); 198 *data,rq);
189 parsestate.wave.left += rq; 199 parsestate.wave.left += rq;
190 ((unsigned char *)*data) += rq; 200 (*(unsigned char **)data) += rq;
191 *sz -= rq; 201 *sz -= rq;
192 return(rc); 202 return(rc);
193 } 203 }
194 204
195 /* ...and next we remove this many bytes from the buffer */ 205 /* ...and next we remove this many bytes from the buffer */
196 static __inline__ void waveremove(size_t rq) 206 static __inline__ void waveremove(size_t rq)
256 parsestate.wave.chunklength -= *sz; 266 parsestate.wave.chunklength -= *sz;
257 *sz = 0; } 267 *sz = 0; }
258 else { 268 else {
259 if (parsestate.wave.chunklength > 0 && *sz > 0) { 269 if (parsestate.wave.chunklength > 0 && *sz > 0) {
260 *sz -= parsestate.wave.chunklength; 270 *sz -= parsestate.wave.chunklength;
261 ((unsigned char *)*data) += parsestate.wave.chunklength; } 271 (*(unsigned char **)data) += parsestate.wave.chunklength; }
262 parsestate.wave.state = wvOutOfBlock; } 272 parsestate.wave.state = wvOutOfBlock; }
263 break; 273 break;
264 case wvSoundChunk: { 274 case wvSoundChunk: {
265 size_t count,rq; 275 size_t count,rq;
266 if (parsestate.wave.left) { /* handle leftover bytes from last 276 if (parsestate.wave.left) { /* handle leftover bytes from last
267 alignment operation */ 277 alignment operation */
268 count = parsestate.wave.left; 278 count = parsestate.wave.left;
269 rq = HEADERSZ-count; 279 rq = HEADERSZ-count;
270 if (rq > parsestate.wave.chunklength) 280 if (rq > (size_t) parsestate.wave.chunklength)
271 rq = parsestate.wave.chunklength; 281 rq = parsestate.wave.chunklength;
272 if (!waverequire(data,sz,rq)) { 282 if (!waverequire(data,sz,rq)) {
273 parsestate.wave.chunklength -= parsestate.wave.left - count; 283 parsestate.wave.chunklength -= parsestate.wave.left - count;
274 return(0); } 284 return(0); }
275 parsestate.wave.chunklength -= rq; 285 parsestate.wave.chunklength -= rq;
276 *outbuf = parsestate.wave.leftover; 286 *outbuf = parsestate.wave.leftover;
277 parsestate.wave.left = 0; 287 parsestate.wave.left = 0;
278 return(rq); } 288 return(rq); }
279 if (*sz >= parsestate.wave.chunklength) { 289 if (*sz >= (size_t) parsestate.wave.chunklength) {
280 count = parsestate.wave.chunklength; 290 count = parsestate.wave.chunklength;
281 rq = 0; } 291 rq = 0; }
282 else { 292 else {
283 count = *sz; 293 count = *sz;
284 count -= rq = count % parsestate.wave.align; } 294 count -= rq = count % parsestate.wave.align; }
285 *outbuf = *data; 295 *outbuf = *data;
286 ((unsigned char *)*data) += count; 296 (*(unsigned char **)data) += count;
287 *sz -= count; 297 *sz -= count;
288 if ((parsestate.wave.chunklength -= count) < parsestate.wave.align) { 298 if ((parsestate.wave.chunklength -= count) < parsestate.wave.align) {
289 parsestate.wave.state = wvOutOfBlock; 299 parsestate.wave.state = wvOutOfBlock;
290 /* Some broken software (e.g. SOX) attaches junk to the end of a sound 300 /* Some broken software (e.g. SOX) attaches junk to the end of a sound
291 chunk; so, let's ignore this... */ 301 chunk; so, let's ignore this... */
292 if (parsestate.wave.chunklength) 302 if (parsestate.wave.chunklength)
315 { 325 {
316 /* There is data left over from the last invocation of this function; join 326 /* There is data left over from the last invocation of this function; join
317 it with the new data and return a sound chunk that is as big as a 327 it with the new data and return a sound chunk that is as big as a
318 single entry */ 328 single entry */
319 if (parsestate.audio.left) { 329 if (parsestate.audio.left) {
320 if (parsestate.audio.left + *sz > parsestate.audio.align) { 330 if (parsestate.audio.left + *sz > (size_t) parsestate.audio.align) {
321 int count; 331 int count;
322 memmove(parsestate.audio.leftover + parsestate.audio.left, 332 memmove(parsestate.audio.leftover + parsestate.audio.left,
323 *data, 333 *data,
324 count = parsestate.audio.align - parsestate.audio.left); 334 count = parsestate.audio.align - parsestate.audio.left);
325 *outbuf = parsestate.audio.leftover; 335 *outbuf = parsestate.audio.leftover;
352 362
353 /* This is the first invocation of this function; we need to parse the 363 /* This is the first invocation of this function; we need to parse the
354 header information and determine how many bytes we need to skip until 364 header information and determine how many bytes we need to skip until
355 the start of the sound chunk */ 365 the start of the sound chunk */
356 if (!parsestate.audio.skipping) { 366 if (!parsestate.audio.skipping) {
357 unsigned char *header = *data; 367 unsigned char *header = (unsigned char *) *data;
358 if (*sz < 8) { 368 if (*sz < 8) {
359 warn("Irrecoverable error while parsing Sun/DEC audio file"); 369 warn("Irrecoverable error while parsing Sun/DEC audio file");
360 return(0); } 370 return(0); }
361 /* Keep compatibility with Linux 68k, etc. by not relying on byte-sex */ 371 /* Keep compatibility with Linux 68k, etc. by not relying on byte-sex */
362 if (header[3]) { /* Sun audio (big endian) */ 372 if (header[3]) { /* Sun audio (big endian) */
371 /* We are skipping extra data that has been attached to header; most usually 381 /* We are skipping extra data that has been attached to header; most usually
372 this will be just a comment, such as the original filename and/or the 382 this will be just a comment, such as the original filename and/or the
373 creation date. Make sure that we do not return less than one single sound 383 creation date. Make sure that we do not return less than one single sound
374 sample entry to the caller; if this happens, rather decide to move those 384 sample entry to the caller; if this happens, rather decide to move those
375 few bytes into the leftover buffer and deal with it later */ 385 few bytes into the leftover buffer and deal with it later */
376 if (*sz >= parsestate.audio.skipping) { 386 if (*sz >= (size_t) parsestate.audio.skipping) {
377 /* Skip just the header information and return the sound chunk */ 387 /* Skip just the header information and return the sound chunk */
378 int rc = *sz - parsestate.audio.skipping; 388 int rc = *sz - parsestate.audio.skipping;
379 *outbuf = (char *)*data + parsestate.audio.skipping; 389 *outbuf = (char *)*data + parsestate.audio.skipping;
380 if ((parsestate.audio.left = rc % parsestate.audio.align) != 0) { 390 if ((parsestate.audio.left = rc % parsestate.audio.align) != 0) {
381 memmove(parsestate.audio.leftover, 391 memmove(parsestate.audio.leftover,
413 423
414 count = *sz / 2; 424 count = *sz / 2;
415 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 425 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
416 else *sz = 0; 426 else *sz = 0;
417 rc = count; 427 rc = count;
418 src = *data; 428 src = (unsigned char *) *data;
419 *outbuf = 429 *outbuf =
420 dest = linuxplay_sndbuf; 430 dest = linuxplay_sndbuf;
421 while (count--) 431 while (count--)
422 *dest++ = (unsigned char)(((int)*((unsigned char *)src)++ + 432 *dest++ = (unsigned char)(((int)*(src)++ +
423 (int)*((unsigned char *)src)++) / 2); 433 (int)*(src)++) / 2);
424 *data = src; 434 *data = src;
425 return(rc); 435 return(rc);
426 } 436 }
427 437
428 /* Convert 8 bit signed stereo data to 8 bit signed mono data */ 438 /* Convert 8 bit signed stereo data to 8 bit signed mono data */
429 static size_t sndcnv8S_2mono(void **data,size_t *sz,void **outbuf) 439 static size_t sndcnv8S_2mono(void **data,size_t *sz,void **outbuf)
430 { 440 {
431 REGISTER unsigned char *src; 441 REGISTER unsigned char *src;
432 REGISTER unsigned char *dest; 442 REGISTER unsigned char *dest;
433 int rc,count; 443 int rc, count;
434 444
435 count = *sz / 2; 445 count = *sz / 2;
436 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 446 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
437 else *sz = 0; 447 else *sz = 0;
438 rc = count; 448 rc = count;
439 src = *data; 449 src = (unsigned char *) *data;
440 *outbuf = 450 *outbuf =
441 dest = linuxplay_sndbuf; 451 dest = linuxplay_sndbuf;
442 while (count--) 452 while (count--)
443 *dest++ = (unsigned char)(((int)*((signed char *)src)++ + 453 *dest++ = (unsigned char)(((int)*((signed char *)(src++)) +
444 (int)*((signed char *)src)++) / 2); 454 (int)*((signed char *)(src++))) / 2);
445 *data = src; 455 *data = src;
446 return(rc); 456 return(rc);
447 } 457 }
448 458
449 /* Convert 8 bit signed stereo data to 8 bit unsigned mono data */ 459 /* Convert 8 bit signed stereo data to 8 bit unsigned mono data */
455 465
456 count = *sz / 2; 466 count = *sz / 2;
457 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 467 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
458 else *sz = 0; 468 else *sz = 0;
459 rc = count; 469 rc = count;
460 src = *data; 470 src = (unsigned char *) *data;
461 *outbuf = 471 *outbuf =
462 dest = linuxplay_sndbuf; 472 dest = linuxplay_sndbuf;
463 while (count--) 473 while (count--)
464 *dest++ = (unsigned char)(((int)*((signed char *)src)++ + 474 *dest++ = (unsigned char)(((int)*((signed char *)(src++)) +
465 (int)*((signed char *)src)++) / 2) ^ 0x80; 475 (int)*((signed char *)(src++))) / 2) ^ 0x80;
466 *data = src; 476 *data = src;
467 return(rc); 477 return(rc);
468 } 478 }
469 479
470 /* Convert 8 bit signed mono data to 8 bit unsigned mono data */ 480 /* Convert 8 bit signed mono data to 8 bit unsigned mono data */
476 486
477 count = *sz; 487 count = *sz;
478 if (count > SNDBUFSZ) { *sz -= SNDBUFSZ; count = SNDBUFSZ; } 488 if (count > SNDBUFSZ) { *sz -= SNDBUFSZ; count = SNDBUFSZ; }
479 else *sz = 0; 489 else *sz = 0;
480 rc = count; 490 rc = count;
481 src = *data; 491 src = (unsigned char *) *data;
482 *outbuf = 492 *outbuf =
483 dest = linuxplay_sndbuf; 493 dest = linuxplay_sndbuf;
484 while (count--) 494 while (count--)
485 *dest++ = *((unsigned char *)src)++ ^ 0x80; 495 *dest++ = *(src)++ ^ 0x80;
486 *data = src; 496 *data = src;
487 return(rc); 497 return(rc);
488 } 498 }
489 499
490 /* Convert a number in the range -32768..32767 to an 8 bit ulaw encoded 500 /* Convert a number in the range -32768..32767 to an 8 bit ulaw encoded
555 565
556 count = *sz / 2; 566 count = *sz / 2;
557 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 567 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
558 else *sz = 0; 568 else *sz = 0;
559 rc = count; 569 rc = count;
560 src = *data; 570 src = (unsigned char *) *data;
561 *outbuf = 571 *outbuf =
562 dest = linuxplay_sndbuf; 572 dest = linuxplay_sndbuf;
563 while (count--) 573 while (count--)
564 /* it is not possible to directly interpolate between two ulaw encoded 574 /* it is not possible to directly interpolate between two ulaw encoded
565 data bytes, thus we need to convert to linear format first and later 575 data bytes, thus we need to convert to linear format first and later
566 we convert back to ulaw format */ 576 we convert back to ulaw format */
567 *dest++ = int2ulaw(ulaw2int[*((unsigned char *)src)++] + 577 *dest++ = int2ulaw(ulaw2int[*(src)++] +
568 ulaw2int[*((unsigned char *)src)++]); 578 ulaw2int[*(src)++]);
569 *data = src; 579 *data = src;
570 return(rc); 580 return(rc);
571 } 581 }
572 582
573 /* Convert 16 bit little endian signed stereo data to 16 bit little endian 583 /* Convert 16 bit little endian signed stereo data to 16 bit little endian
574 signed mono data */ 584 signed mono data */
581 591
582 count = *sz / 2; 592 count = *sz / 2;
583 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 593 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
584 else *sz = 0; 594 else *sz = 0;
585 rc = count; 595 rc = count;
586 src = *data; 596 src = (unsigned char *) *data;
587 *outbuf = 597 *outbuf =
588 dest = linuxplay_sndbuf; 598 dest = linuxplay_sndbuf;
589 for (count /= 2; count--; ) { 599 for (count /= 2; count--; ) {
590 i = ((int)(((unsigned char *)src)[0]) + 600 i = ((int)(src[0]) +
591 256*(int)(((unsigned char *)src)[1]) + 601 256*(int)(src[1]) +
592 (int)(((unsigned char *)src)[2]) + 602 (int)(src[2]) +
593 256*(int)(((unsigned char *)src)[3])) / 2; 603 256*(int)(src[3])) / 2;
594 src += 4; 604 src += 4;
595 *dest++ = (unsigned char)(i & 0xFF); 605 *dest++ = (unsigned char)(i & 0xFF);
596 *dest++ = (unsigned char)((i / 256) & 0xFF); } 606 *dest++ = (unsigned char)((i / 256) & 0xFF); }
597 *data = src; 607 *data = src;
598 return(rc); 608 return(rc);
599 } 609 }
600 610
601 /* Convert 16 bit big endian signed stereo data to 16 bit big endian 611 /* Convert 16 bit big endian signed stereo data to 16 bit big endian
602 signed mono data */ 612 signed mono data */
609 619
610 count = *sz / 2; 620 count = *sz / 2;
611 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 621 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
612 else *sz = 0; 622 else *sz = 0;
613 rc = count; 623 rc = count;
614 src = *data; 624 src = (unsigned char *) *data;
615 *outbuf = 625 *outbuf =
616 dest = linuxplay_sndbuf; 626 dest = linuxplay_sndbuf;
617 for (count /= 2; count--; ) { 627 for (count /= 2; count--; ) {
618 i = ((int)(((unsigned char *)src)[1]) + 628 i = ((int)(src[1]) +
619 256*(int)(((unsigned char *)src)[0]) + 629 256*(int)(src[0]) +
620 (int)(((unsigned char *)src)[3]) + 630 (int)(src[3]) +
621 256*(int)(((unsigned char *)src)[2])) / 2; 631 256*(int)(src[2])) / 2;
622 src += 4; 632 src += 4;
623 *dest++ = (unsigned char)((i / 256) & 0xFF); 633 *dest++ = (unsigned char)((i / 256) & 0xFF);
624 *dest++ = (unsigned char)(i & 0xFF); } 634 *dest++ = (unsigned char)(i & 0xFF); }
625 *data = src; 635 *data = src;
626 return(rc); 636 return(rc);
627 } 637 }
628 638
629 /* Convert 16 bit little endian signed data to 8 bit unsigned data */ 639 /* Convert 16 bit little endian signed data to 8 bit unsigned data */
630 static size_t sndcnv2byteLE(void **data,size_t *sz,void **outbuf) 640 static size_t sndcnv2byteLE(void **data,size_t *sz,void **outbuf)
635 645
636 count = *sz / 2; 646 count = *sz / 2;
637 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 647 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
638 else *sz = 0; 648 else *sz = 0;
639 rc = count; 649 rc = count;
640 src = *data; 650 src = (unsigned char *) *data;
641 *outbuf = 651 *outbuf =
642 dest = linuxplay_sndbuf; 652 dest = linuxplay_sndbuf;
643 while (count--) { 653 while (count--) {
644 *dest++ = (unsigned char)(((signed char *)src)[1] ^ (signed char)0x80); 654 *dest++ = (unsigned char)(((signed char *)src)[1] ^ (signed char)0x80);
645 ((char *)src) += 2; } 655 src += 2;
646 *data = src; 656 }
657 *data = src;
647 return(rc); 658 return(rc);
648 } 659 }
649 660
650 /* Convert 16 bit big endian signed data to 8 bit unsigned data */ 661 /* Convert 16 bit big endian signed data to 8 bit unsigned data */
651 static size_t sndcnv2byteBE(void **data,size_t *sz,void **outbuf) 662 static size_t sndcnv2byteBE(void **data,size_t *sz,void **outbuf)
656 667
657 count = *sz / 2; 668 count = *sz / 2;
658 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } 669 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; }
659 else *sz = 0; 670 else *sz = 0;
660 rc = count; 671 rc = count;
661 src = *data; 672 src = (unsigned char *) *data;
662 *outbuf = 673 *outbuf =
663 dest = linuxplay_sndbuf; 674 dest = linuxplay_sndbuf;
664 while (count--) { 675 while (count--) {
665 *dest++ = (unsigned char)(((signed char *)src)[0] ^ (signed char)0x80); 676 *dest++ = (unsigned char)(((signed char *)src)[0] ^ (signed char)0x80);
666 ((char *)src) += 2; } 677 src += 2;
667 *data = src; 678 }
679 *data = src;
668 return(rc); 680 return(rc);
669 } 681 }
670 682
671 /* Convert 16 bit little endian signed stereo data to 8 bit unsigned 683 /* Convert 16 bit little endian signed stereo data to 8 bit unsigned
672 mono data */ 684 mono data */
678 690
679 count = *sz / 4; 691 count = *sz / 4;
680 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; } 692 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; }
681 else *sz = 0; 693 else *sz = 0;
682 rc = count; 694 rc = count;
683 src = *data; 695 src = (unsigned char *) *data;
684 *outbuf = 696 *outbuf =
685 dest = linuxplay_sndbuf; 697 dest = linuxplay_sndbuf;
686 while (count--) { 698 while (count--) {
687 *dest++ = (unsigned char)(((int)((signed char *)src)[1] + 699 *dest++ = (unsigned char)(((int)((signed char *)src)[1] +
688 (int)((signed char *)src)[3]) / 2 ^ 0x80); 700 (int)((signed char *)src)[3]) / 2 ^ 0x80);
689 ((char *)src) += 4; } 701 src += 4;
690 *data = src; 702 }
703 *data = src;
691 return(rc); 704 return(rc);
692 } 705 }
693 706
694 /* Convert 16 bit big endian signed stereo data to 8 bit unsigned 707 /* Convert 16 bit big endian signed stereo data to 8 bit unsigned
695 mono data */ 708 mono data */
701 714
702 count = *sz / 4; 715 count = *sz / 4;
703 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; } 716 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; }
704 else *sz = 0; 717 else *sz = 0;
705 rc = count; 718 rc = count;
706 src = *data; 719 src = (unsigned char *) *data;
707 *outbuf = 720 *outbuf =
708 dest = linuxplay_sndbuf; 721 dest = linuxplay_sndbuf;
709 while (count--) { 722 while (count--) {
710 *dest++ = (unsigned char)(((int)((signed char *)src)[0] + 723 *dest++ = (unsigned char)(((int)((signed char *)src)[0] +
711 (int)((signed char *)src)[2]) / 2 ^ 0x80); 724 (int)((signed char *)src)[2]) / 2 ^ 0x80);
712 ((char *)src) += 4; } 725 src += 4;
713 *data = src; 726 }
727 *data = src;
714 return(rc); 728 return(rc);
715 } 729 }
716 730
717 /* Look at the header of the sound file and try to determine the format; 731 /* Look at the header of the sound file and try to determine the format;
718 we can recognize files in VOC, WAVE, and, Sun/DEC-audio format--- everything 732 we can recognize files in VOC, WAVE, and, Sun/DEC-audio format--- everything
805 if (ioctl(auddio_fd,SNDCTL_DSP_SYNC,NULL) < 0) { 819 if (ioctl(auddio_fd,SNDCTL_DSP_SYNC,NULL) < 0) {
806 perror("SNDCTL_DSP_SYNC"); 820 perror("SNDCTL_DSP_SYNC");
807 return(0); } 821 return(0); }
808 822
809 /* Initialize sound hardware with prefered parameters */ 823 /* Initialize sound hardware with prefered parameters */
810 824
811 /* If the sound hardware cannot support 16 bit format or requires a 825 /* If the sound hardware cannot support 16 bit format or requires a
812 different byte sex then try to drop to 8 bit format */ 826 different byte sex then try to drop to 8 bit format */
813 827
814 the_fmt = fmt; 828 the_fmt = fmt;
815 if(ioctl(audio_fd,SNDCTL_DSP_SETFMT,&the_fmt) < 0) { 829 if(ioctl(audio_fd,SNDCTL_DSP_SETFMT,&the_fmt) < 0) {
837 fmt != the_fmt) { 851 fmt != the_fmt) {
838 perror("SNDCTRL_DSP_SETFMT"); 852 perror("SNDCTRL_DSP_SETFMT");
839 return(0); } } 853 return(0); } }
840 854
841 /* The PCSP driver does not support reading of the sampling rate via the 855 /* The PCSP driver does not support reading of the sampling rate via the
842 SOUND_PCM_READ_RATE ioctl; determine "the_speed" here */ 856 SOUND_PCM_READ_RATE ioctl; determine "the_speed" here */
843 the_speed = speed; ioctl(audio_fd,SNDCTL_DSP_SPEED,&the_speed); 857 the_speed = speed; ioctl(audio_fd,SNDCTL_DSP_SPEED,&the_speed);
844 /* The PCSP driver does not support reading of the mono/stereo flag, thus 858 /* The PCSP driver does not support reading of the mono/stereo flag, thus
845 we assume, that failure to change this mode means we are in mono mode */ 859 we assume, that failure to change this mode means we are in mono mode */
846 if (((i = (the_stereo = tracks)-1),ioctl(audio_fd,SNDCTL_DSP_STEREO,&i)) < 0) 860 if (((i = (the_stereo = tracks)-1),ioctl(audio_fd,SNDCTL_DSP_STEREO,&i)) < 0)
847 the_stereo = 1; 861 the_stereo = 1;
903 if (speed*14 < the_speed*10 || speed*6 > the_speed*10) { 917 if (speed*14 < the_speed*10 || speed*6 > the_speed*10) {
904 char buffer[256]; 918 char buffer[256];
905 sprintf(buffer,"SNDCTL_DSP_SPEED (req: %d, rtn: %d)",speed,the_speed); 919 sprintf(buffer,"SNDCTL_DSP_SPEED (req: %d, rtn: %d)",speed,the_speed);
906 perror(buffer); 920 perror(buffer);
907 return(0); } 921 return(0); }
908 922
909 /* Use the mixer device for setting the playback volume */ 923 /* Use the mixer device for setting the playback volume */
910 if (mixx_fd > 0) { 924 if (mixx_fd > 0) {
911 int vol = *volume & 0xFF; 925 int vol = *volume & 0xFF;
912 if (ioctl(mixx_fd,SOUND_MIXER_READ_PCM,volume) < 0) 926 if (ioctl(mixx_fd,SOUND_MIXER_READ_PCM,volume) < 0)
913 *volume = -1; 927 *volume = -1;
1003 /* Mainloop: read a block of data, parse its contents, perform all 1017 /* Mainloop: read a block of data, parse its contents, perform all
1004 the necessary conversions and output it to the sound 1018 the necessary conversions and output it to the sound
1005 device; repeat until all data has been processed */ 1019 device; repeat until all data has been processed */
1006 rrtn = length; 1020 rrtn = length;
1007 do { 1021 do {
1008 for (pptr = data; (prtn = parsesndfile((void **)&pptr,&rrtn, 1022 for (pptr = data; (prtn = parsesndfile((void **)&pptr,(size_t *)&rrtn,
1009 (void **)&optr)) > 0; ) 1023 (void **)&optr)) > 0; )
1010 for (cptr = optr; (crtn = sndcnv((void **)&cptr,&prtn, 1024 for (cptr = optr; (crtn = sndcnv((void **)&cptr,(size_t *) &prtn,
1011 (void **)&sptr)) > 0; ) { 1025 (void **)&sptr)) > 0; ) {
1012 for (;;) { 1026 for (;;) {
1013 if ((wrtn = write(audio_fd,sptr,crtn)) < 0) { 1027 if ((wrtn = write(audio_fd,sptr,crtn)) < 0) {
1014 perror("write"); goto END_OF_PLAY; } 1028 perror("write"); goto END_OF_PLAY; }
1015 else if (wrtn) break; 1029 else if (wrtn) break;