home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
SOUNDUTILS
/
audioplay.lzh
/
AUDIOPLAY
/
SRC
/
auplay.c
< prev
next >
Wrap
Text File
|
1995-03-29
|
5KB
|
251 lines
/* auplay.c - play NeXT/Sun *.au file on MM/1 - Andrzej Kotanski 1994 */
#include "play.h"
#include "audio_filehdr.h"
#include "ulaw.h"
static Audio_filehdr hdr;
static char title[100];
static char *buf1, *buf2, *buf;
char *malloc();
static char *Encoding[] = {
"Not Set",
"8 Bit U-Law",
"8 Bit Linear",
"16 Bit Linear",
"24 Bit Linear",
"32 Bit Linear",
"Encoded IEEE Float",
"Encoded IEEE Double"
};
auplay(fd)
path_id fd;
{
u_int32 res, sleepTime;
u_int inverted;
unsigned char ch;
size = sizeof(hdr);
if ((read(fd, &hdr, size)) == -1) {
cleanup(errno, "cannot read header");
}
if (hdr.magic == DecDiva)
{
lseek(fd,0xa5,SEEK_SET);
read(fd, &ch, 1);
lseek(fd,0x26 + ch,SEEK_SET);
if ((read(fd, &hdr, size)) == -1) {
cleanup(errno, "cannot read header");
}
}
switch(hdr.magic) {
case MagicSun:
case MagicDec:
inverted = FALSE;
break;
case MagicSunI:
case MagicDecI:
inverted = TRUE;
swab4(&hdr.hdr_size);
swab4(&hdr.data_size); /* data size */
swab4(&hdr.encoding); /* encoding */
swab4(&hdr.sample_rate); /* sample rate */
swab4(&hdr.channels); /* number of channels */
break;
default:
cleanup(0, "bad magic number");
}
size = hdr.hdr_size - sizeof(hdr);
if ((read(fd, title, size)) == -1) {
cleanup(errno, "cannot read header");
}
if ( hdr.encoding < AUDIO_FILE_ENCODING_MULAW_8
|| hdr.encoding > AUDIO_FILE_ENCODING_DOUBLE ) {
cleanup(0, "encoding type uknown");
}
if ( hdr.channels != 1 && hdr.channels != 2 ) {
cleanup(0, "invalid number of channels");
}
if (!quiet) {
fprintf(stderr, "Title: %s\n", title);
fprintf(stderr, "Length: %d\n", hdr.data_size);
fprintf(stderr, "Sample rate: %d\n", hdr.sample_rate);
fprintf(stderr, "Channels: %d\n", hdr.channels);
fprintf(stderr, "Encoding: %s\n", Encoding[hdr.encoding]);
}
if ( hdr.encoding > AUDIO_FILE_ENCODING_LINEAR_16) {
cleanup(0, "cannot decode this type of encoding");
}
if (hdr.channels == 1) {
buf1 = malloc(bufferSize*2);
buf2 = malloc(bufferSize*2);
} else {
buf1 = malloc(bufferSize);
buf2 = malloc(bufferSize);
}
if (buf1 == NULL || buf2 == NULL) {
cleanup(errno, "cannot allocate memory");
}
buf = buf2;
sigarrived = 1;
do {
buf = buf == buf1 ? buf2 : buf1;
res = (hdr.data_size > bufferSize) ? bufferSize : hdr.data_size;
if ((read(fd, buf, res)) != res) {
hdr.data_size = 0;
#if 0
if (errno == E_EOF) {
break;
} else {
cleanup(errno, "cannot read file");
}
#endif
}
else
hdr.data_size -= res;
if ( hdr.encoding == AUDIO_FILE_ENCODING_LINEAR_16) {
res >>= 1;
crunch(buf,res,inverted);
}
if ( hdr.channels == 2 ) {
if (hdr.encoding == AUDIO_FILE_ENCODING_MULAW_8)
process(buf, res);
} else {
process1(buf, res, hdr.encoding);
}
if ( sigarrived == 0) {
sleepTime = 0;
tsleep(sleepTime);
}
sigarrived = 0;
_ss_play(1, buf, hdr.channels == 1 ? res*2 : res,
hdr.sample_rate, SND_SENDSIG, SIG_CODE);
} while ( hdr.data_size > 0 );
sleepTime = 0;
tsleep(sleepTime);
/* free up our memory */
free(buf1);
free(buf2);
close(fd);
}
static process(buf, n)
unsigned char *buf;
int n;
{
u_int32 i;
for ( i = 0; i < n ; i++ ) {
buf[i] = ulaw_to_byte_linear(buf[i] & 0xFF);
}
}
static process1(buf, n, encoding)
char *buf;
int n;
int encoding;
{
int32 i;
if (hdr.encoding == AUDIO_FILE_ENCODING_MULAW_8) {
for (i = n - 1; i >= 0 ; i--) {
buf[2*i + 1] = buf[2*i] = ulaw_to_byte_linear(buf[i] & 0xFF);
}
} else {
for (i = n - 1; i >= 0 ; i--) {
buf[2*i + 1] = buf[2*i] = buf[i];
}
}
}
static crunch(buf, n, inv)
unsigned char *buf;
int n;
int inv;
{
u_int32 i;
unsigned short *src = (unsigned short *)buf;
if (inv) {
for ( i = 0; i < n ; i++ ) {
buf[i] = src[i] & 0xFF;
}
} else {
for ( i = 0; i < n ; i++ ) {
buf[i] = (src[i] >> 8) & 0xFF;
}
}
}
#if 0
/*
** This routine converts from ulaw to 16 bit linear.
**
** Craig Reese: IDA/Supercomputing Research Center
** 29 September 1989
**
** References:
** 1) CCITT Recommendation G.711 (very difficult to follow)
** 2) MIL-STD-188-113,"Interoperability and Performance Standards
** for Analog-to_Digital Conversion Techniques,"
** 17 February 1987
**
** Input: 8 bit ulaw sample
** Output: signed 16 bit linear sample
*/
static int ulaw2linear(ulawbyte)
register unsigned char ulawbyte;
{
static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
register int sign, exponent, mantissa, sample;
ulawbyte = ~ulawbyte;
sign = (ulawbyte & 0x80);
exponent = (ulawbyte >> 4) & 0x07;
mantissa = ulawbyte & 0x0F;
sample = exp_lut[exponent] + (mantissa << (exponent + 3));
if (sign != 0) sample = -sample;
return(sample >> 8);
}
#endif
static swab4(x)
register unsigned short *x;
{
register unsigned char a, b, c, d;
a = *(unsigned char *) x;
b = *((unsigned char *) x + 1);
c = *((unsigned char *) x + 2);
d = *((unsigned char *) x + 3);
*(unsigned char *) x = d;
*((unsigned char *) x + 1) = c;
*((unsigned char *) x + 2) = b;
*((unsigned char *) x + 3) = a;
}