Mercurial > hg > xemacs-beta
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; |