Mercurial > hg > xemacs-beta
comparison src/linuxplay.c @ 124:9b50b4588a93 r20-1b15
Import from CVS: tag r20-1b15
| author | cvs |
|---|---|
| date | Mon, 13 Aug 2007 09:26:39 +0200 |
| parents | fe104dbd9147 |
| children | e292c9648bb9 |
comparison
equal
deleted
inserted
replaced
| 123:c77884c6318d | 124:9b50b4588a93 |
|---|---|
| 61 | 61 |
| 62 #include <errno.h> | 62 #include <errno.h> |
| 63 #include <fcntl.h> | 63 #include <fcntl.h> |
| 64 #ifdef __FreeBSD__ | 64 #ifdef __FreeBSD__ |
| 65 # include <machine/soundcard.h> | 65 # include <machine/soundcard.h> |
| 66 #elif defined(__bsdi__) | |
| 67 # include <sys/soundcard.h> | |
| 66 #else | 68 #else |
| 67 # include <linux/soundcard.h> | 69 # include <linux/soundcard.h> |
| 68 #endif | 70 #endif |
| 69 #include <stdio.h> | 71 #include <stdio.h> |
| 70 #include <stdlib.h> | 72 #include <stdlib.h> |
| 117 } audio; | 119 } audio; |
| 118 } parsestate; | 120 } parsestate; |
| 119 | 121 |
| 120 /* Use a global buffer as scratch-pad for possible conversions of the | 122 /* Use a global buffer as scratch-pad for possible conversions of the |
| 121 sampling format */ | 123 sampling format */ |
| 122 static unsigned char sndbuf[SNDBUFSZ]; | 124 unsigned char linuxplay_sndbuf[SNDBUFSZ]; |
| 123 | 125 |
| 124 static int mix_fd = -1; | 126 int mix_fd = -1; |
| 125 static int audio_vol = -1; | 127 int audio_vol = -1; |
| 126 static int audio_fd = -1; | 128 int audio_fd = -1; |
| 127 static char *audio_dev = ""; | 129 char *audio_dev = ""; |
| 128 | 130 |
| 129 typedef enum {fmtIllegal,fmtRaw,fmtVoc,fmtWave,fmtSunAudio} fmtType; | 131 typedef enum {fmtIllegal,fmtRaw,fmtVoc,fmtWave,fmtSunAudio} fmtType; |
| 130 | 132 |
| 131 /* Intercept SIGINT and SIGHUP in order to close the audio and mixer | 133 /* Intercept SIGINT and SIGHUP in order to close the audio and mixer |
| 132 devices before terminating sound output; this requires reliable | 134 devices before terminating sound output; this requires reliable |
| 419 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 421 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 420 else *sz = 0; | 422 else *sz = 0; |
| 421 rc = count; | 423 rc = count; |
| 422 src = *data; | 424 src = *data; |
| 423 *outbuf = | 425 *outbuf = |
| 424 dest = sndbuf; | 426 dest = linuxplay_sndbuf; |
| 425 while (count--) | 427 while (count--) |
| 426 *dest++ = (unsigned char)(((int)*((unsigned char *)src)++ + | 428 *dest++ = (unsigned char)(((int)*((unsigned char *)src)++ + |
| 427 (int)*((unsigned char *)src)++) / 2); | 429 (int)*((unsigned char *)src)++) / 2); |
| 428 *data = src; | 430 *data = src; |
| 429 return(rc); | 431 return(rc); |
| 440 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 442 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 441 else *sz = 0; | 443 else *sz = 0; |
| 442 rc = count; | 444 rc = count; |
| 443 src = *data; | 445 src = *data; |
| 444 *outbuf = | 446 *outbuf = |
| 445 dest = sndbuf; | 447 dest = linuxplay_sndbuf; |
| 446 while (count--) | 448 while (count--) |
| 447 *dest++ = (unsigned char)(((int)*((signed char *)src)++ + | 449 *dest++ = (unsigned char)(((int)*((signed char *)src)++ + |
| 448 (int)*((signed char *)src)++) / 2); | 450 (int)*((signed char *)src)++) / 2); |
| 449 *data = src; | 451 *data = src; |
| 450 return(rc); | 452 return(rc); |
| 461 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 463 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 462 else *sz = 0; | 464 else *sz = 0; |
| 463 rc = count; | 465 rc = count; |
| 464 src = *data; | 466 src = *data; |
| 465 *outbuf = | 467 *outbuf = |
| 466 dest = sndbuf; | 468 dest = linuxplay_sndbuf; |
| 467 while (count--) | 469 while (count--) |
| 468 *dest++ = (unsigned char)(((int)*((signed char *)src)++ + | 470 *dest++ = (unsigned char)(((int)*((signed char *)src)++ + |
| 469 (int)*((signed char *)src)++) / 2) ^ 0x80; | 471 (int)*((signed char *)src)++) / 2) ^ 0x80; |
| 470 *data = src; | 472 *data = src; |
| 471 return(rc); | 473 return(rc); |
| 482 if (count > SNDBUFSZ) { *sz -= SNDBUFSZ; count = SNDBUFSZ; } | 484 if (count > SNDBUFSZ) { *sz -= SNDBUFSZ; count = SNDBUFSZ; } |
| 483 else *sz = 0; | 485 else *sz = 0; |
| 484 rc = count; | 486 rc = count; |
| 485 src = *data; | 487 src = *data; |
| 486 *outbuf = | 488 *outbuf = |
| 487 dest = sndbuf; | 489 dest = linuxplay_sndbuf; |
| 488 while (count--) | 490 while (count--) |
| 489 *dest++ = *((unsigned char *)src)++ ^ 0x80; | 491 *dest++ = *((unsigned char *)src)++ ^ 0x80; |
| 490 *data = src; | 492 *data = src; |
| 491 return(rc); | 493 return(rc); |
| 492 } | 494 } |
| 561 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 563 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 562 else *sz = 0; | 564 else *sz = 0; |
| 563 rc = count; | 565 rc = count; |
| 564 src = *data; | 566 src = *data; |
| 565 *outbuf = | 567 *outbuf = |
| 566 dest = sndbuf; | 568 dest = linuxplay_sndbuf; |
| 567 while (count--) | 569 while (count--) |
| 568 /* it is not possible to directly interpolate between two ulaw encoded | 570 /* it is not possible to directly interpolate between two ulaw encoded |
| 569 data bytes, thus we need to convert to linear format first and later | 571 data bytes, thus we need to convert to linear format first and later |
| 570 we convert back to ulaw format */ | 572 we convert back to ulaw format */ |
| 571 *dest++ = int2ulaw(ulaw2int[*((unsigned char *)src)++] + | 573 *dest++ = int2ulaw(ulaw2int[*((unsigned char *)src)++] + |
| 587 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 589 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 588 else *sz = 0; | 590 else *sz = 0; |
| 589 rc = count; | 591 rc = count; |
| 590 src = *data; | 592 src = *data; |
| 591 *outbuf = | 593 *outbuf = |
| 592 dest = sndbuf; | 594 dest = linuxplay_sndbuf; |
| 593 for (count /= 2; count--; ) { | 595 for (count /= 2; count--; ) { |
| 594 i = ((int)(((unsigned char *)src)[0]) + | 596 i = ((int)(((unsigned char *)src)[0]) + |
| 595 256*(int)(((unsigned char *)src)[1]) + | 597 256*(int)(((unsigned char *)src)[1]) + |
| 596 (int)(((unsigned char *)src)[2]) + | 598 (int)(((unsigned char *)src)[2]) + |
| 597 256*(int)(((unsigned char *)src)[3])) / 2; | 599 256*(int)(((unsigned char *)src)[3])) / 2; |
| 615 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 617 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 616 else *sz = 0; | 618 else *sz = 0; |
| 617 rc = count; | 619 rc = count; |
| 618 src = *data; | 620 src = *data; |
| 619 *outbuf = | 621 *outbuf = |
| 620 dest = sndbuf; | 622 dest = linuxplay_sndbuf; |
| 621 for (count /= 2; count--; ) { | 623 for (count /= 2; count--; ) { |
| 622 i = ((int)(((unsigned char *)src)[1]) + | 624 i = ((int)(((unsigned char *)src)[1]) + |
| 623 256*(int)(((unsigned char *)src)[0]) + | 625 256*(int)(((unsigned char *)src)[0]) + |
| 624 (int)(((unsigned char *)src)[3]) + | 626 (int)(((unsigned char *)src)[3]) + |
| 625 256*(int)(((unsigned char *)src)[2])) / 2; | 627 256*(int)(((unsigned char *)src)[2])) / 2; |
| 641 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 643 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 642 else *sz = 0; | 644 else *sz = 0; |
| 643 rc = count; | 645 rc = count; |
| 644 src = *data; | 646 src = *data; |
| 645 *outbuf = | 647 *outbuf = |
| 646 dest = sndbuf; | 648 dest = linuxplay_sndbuf; |
| 647 while (count--) { | 649 while (count--) { |
| 648 *dest++ = (unsigned char)(((signed char *)src)[1] ^ (signed char)0x80); | 650 *dest++ = (unsigned char)(((signed char *)src)[1] ^ (signed char)0x80); |
| 649 ((char *)src) += 2; } | 651 ((char *)src) += 2; } |
| 650 *data = src; | 652 *data = src; |
| 651 return(rc); | 653 return(rc); |
| 662 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } | 664 if (count > SNDBUFSZ) { *sz -= 2*SNDBUFSZ; count = SNDBUFSZ; } |
| 663 else *sz = 0; | 665 else *sz = 0; |
| 664 rc = count; | 666 rc = count; |
| 665 src = *data; | 667 src = *data; |
| 666 *outbuf = | 668 *outbuf = |
| 667 dest = sndbuf; | 669 dest = linuxplay_sndbuf; |
| 668 while (count--) { | 670 while (count--) { |
| 669 *dest++ = (unsigned char)(((signed char *)src)[0] ^ (signed char)0x80); | 671 *dest++ = (unsigned char)(((signed char *)src)[0] ^ (signed char)0x80); |
| 670 ((char *)src) += 2; } | 672 ((char *)src) += 2; } |
| 671 *data = src; | 673 *data = src; |
| 672 return(rc); | 674 return(rc); |
| 684 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; } | 686 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; } |
| 685 else *sz = 0; | 687 else *sz = 0; |
| 686 rc = count; | 688 rc = count; |
| 687 src = *data; | 689 src = *data; |
| 688 *outbuf = | 690 *outbuf = |
| 689 dest = sndbuf; | 691 dest = linuxplay_sndbuf; |
| 690 while (count--) { | 692 while (count--) { |
| 691 *dest++ = (unsigned char)(((int)((signed char *)src)[1] + | 693 *dest++ = (unsigned char)(((int)((signed char *)src)[1] + |
| 692 (int)((signed char *)src)[3]) / 2 ^ 0x80); | 694 (int)((signed char *)src)[3]) / 2 ^ 0x80); |
| 693 ((char *)src) += 4; } | 695 ((char *)src) += 4; } |
| 694 *data = src; | 696 *data = src; |
| 707 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; } | 709 if (count > SNDBUFSZ) { *sz -= 4*SNDBUFSZ; count = SNDBUFSZ; } |
| 708 else *sz = 0; | 710 else *sz = 0; |
| 709 rc = count; | 711 rc = count; |
| 710 src = *data; | 712 src = *data; |
| 711 *outbuf = | 713 *outbuf = |
| 712 dest = sndbuf; | 714 dest = linuxplay_sndbuf; |
| 713 while (count--) { | 715 while (count--) { |
| 714 *dest++ = (unsigned char)(((int)((signed char *)src)[0] + | 716 *dest++ = (unsigned char)(((int)((signed char *)src)[0] + |
| 715 (int)((signed char *)src)[2]) / 2 ^ 0x80); | 717 (int)((signed char *)src)[2]) / 2 ^ 0x80); |
| 716 ((char *)src) += 4; } | 718 ((char *)src) += 4; } |
| 717 *data = src; | 719 *data = src; |
| 960 /* We need to read at least the header information before we can start | 962 /* We need to read at least the header information before we can start |
| 961 doing anything */ | 963 doing anything */ |
| 962 if (!data || length < HEADERSZ) | 964 if (!data || length < HEADERSZ) |
| 963 if (fd < 0) return; | 965 if (fd < 0) return; |
| 964 else { | 966 else { |
| 965 length = read(fd,sndbuf,SNDBUFSZ); | 967 length = read(fd,linuxplay_sndbuf,SNDBUFSZ); |
| 966 if (length < HEADERSZ) | 968 if (length < HEADERSZ) |
| 967 return; | 969 return; |
| 968 data = sndbuf; | 970 data = linuxplay_sndbuf; |
| 969 length = SNDBUFSZ; } | 971 length = SNDBUFSZ; } |
| 970 | 972 |
| 971 ffmt = analyze_format(data,&fmt,&speed,&tracks,&parsesndfile); | 973 ffmt = analyze_format(data,&fmt,&speed,&tracks,&parsesndfile); |
| 972 | 974 |
| 973 if (ffmt != fmtRaw && ffmt != fmtSunAudio && ffmt != fmtWave) { | 975 if (ffmt != fmtRaw && ffmt != fmtSunAudio && ffmt != fmtWave) { |
| 1015 char buf[255]; | 1017 char buf[255]; |
| 1016 sprintf(buf,"play: crtn = %d, wrtn = %d",crtn,wrtn); | 1018 sprintf(buf,"play: crtn = %d, wrtn = %d",crtn,wrtn); |
| 1017 warn(buf); | 1019 warn(buf); |
| 1018 goto END_OF_PLAY; } } | 1020 goto END_OF_PLAY; } } |
| 1019 if (fd >= 0) { | 1021 if (fd >= 0) { |
| 1020 if ((rrtn = read(fd,sndbuf,SNDBUFSZ)) < 0) { | 1022 if ((rrtn = read(fd,linuxplay_sndbuf,SNDBUFSZ)) < 0) { |
| 1021 perror("read"); goto END_OF_PLAY; } } | 1023 perror("read"); goto END_OF_PLAY; } } |
| 1022 else | 1024 else |
| 1023 break; | 1025 break; |
| 1024 } while (rrtn > 0); | 1026 } while (rrtn > 0); |
| 1025 | 1027 |
