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
/
iffplay.c
< prev
next >
Wrap
Text File
|
1995-03-25
|
6KB
|
263 lines
/* iffplay.c - play IFF/8SVX Amiga file on MM/1 - Andrzej Kotanski 1994 */
#include "play.h"
static struct header1 {
char magic1[4];
u_int32 totlength;
char magic2[4];
char magic3[4];
u_int32 header_length;
} hdr1;
static struct header {
u_int32 one_shot_length;
u_int32 repeat_length;
u_int32 high_oct;
unsigned short sample_rate;
unsigned char octaves;
unsigned char compress;
u_int32 volume;
} hdr;
static struct header2 {
char name[4];
u_int32 size;
} hdr2;
static int data_size;
static char *buf1, *buf2, *buf;
static int channels = 1;
static char title[1000];
char *malloc();
iffplay(fd,fname)
path_id fd;
char *fname;
{
u_int32 res, sleepTime;
u_int32 chan, i;
u_int32 _gs_pos(), lseek(), offset;
u_int32 position;
path_id fd2;
char *Lchan, *Rchan, *Stereobuf;
size = sizeof(hdr1);
if ((read(fd, &hdr1, size)) == -1) {
cleanup(errno, "cannot read header");
}
if ( strncmp(hdr1.magic1, "FORM", 4)
|| strncmp(hdr1.magic2, "8SVX", 4)
|| strncmp(hdr1.magic3, "VHDR", 4) ) {
cleanup(0, "bad magic number");
}
if ( hdr1.header_length != 0x14 ) {
cleanup(0, "non-standard header length");
}
size = sizeof(hdr);
if ((read(fd, &hdr, size)) == -1) {
cleanup(errno, "cannot read header");
}
do {
size = sizeof(hdr2);
if ((read(fd, &hdr2, size)) == -1) {
cleanup(errno, "cannot read chunk header");
}
if ( strncmp(hdr2.name, "NAME", 4) == 0 ) {
size = hdr2.size;
if ((read(fd, title, size)) == -1) {
cleanup(errno, "cannot read NAME");
}
if (!quiet) {
fprintf(stderr, "Name: %s\n", title);
}
} else if ( strncmp(hdr2.name, "ANNO", 4) == 0 ) {
size = hdr2.size;
if ((read(fd, title, size)) == -1) {
cleanup(errno, "cannot read ANNO");
}
if (!quiet) {
fprintf(stderr, "ANNO: %s\n", title);
}
} else if ( strncmp(hdr2.name, "CHAN", 4) == 0 ) {
size = 4;
if ((read(fd, &chan, size)) == -1) {
cleanup(errno, "cannot read CHAN");
}
channels = 0;
for (i = 1; i < 31; i++) {
if (chan & (1 << i))
channels++;
}
if (channels == 0)
channels = 1;
} else if ( strncmp(hdr2.name, "BODY", 4) ) {
if (!quiet) {
fprintf(stderr, "Unknown chunk: %s, trying to skip...\n", hdr2.name);
}
position = _gs_pos(fd);
if ((lseek(fd, position + hdr2.size,SEEK_SET)) == -1) {
cleanup(errno, "cannot seek...");
}
}
} while ( strncmp(hdr2.name, "BODY", 4) );
data_size = hdr2.size;
if (!quiet) {
fprintf(stderr, "Length: %d\n", data_size);
fprintf(stderr, "Sample rate: %d\n", hdr.sample_rate);
fprintf(stderr, "Channels: %d\n", channels);
}
if (channels == 1) {
buf1 = malloc(bufferSize*2);
buf2 = malloc(bufferSize*2);
} else {
/* open a path for our second channel */
if ((fd2 = open(fname, S_IREAD)) == -1) {
cleanup(errno, "cannot open second channel...");
}
/* calc offset to second channel's data */
offset = data_size / channels;
/* reassign data_size to the channel size */
data_size = offset;
if ((position = _gs_pos(fd)) == -1) {
cleanup(errno, "cannot get current file position...");
}
/* seek to 2nd channel */
if ((lseek(fd, offset ,SEEK_CUR)) == -1) {
cleanup(errno, "cannot seek into second channel...");
}
#if 0
printf("Second channel is at %d\n",_gs_pos(fd));
#endif
/* seek to 1st channel */
if ((lseek(fd2, position,SEEK_SET)) == -1) {
cleanup(errno, "cannot seek to first channel...");
}
#if 0
printf("First channel is at %d\n",_gs_pos(fd2));
#endif
/* get play buffers */
buf1 = malloc(bufferSize);
buf2 = malloc(bufferSize);
/* allocate our buffer */
Stereobuf = malloc(bufferSize);
if (Stereobuf == NULL) {
cleanup(errno, "cannot allocate stereo buffer");
}
/* assign our pointers into the buffer */
Lchan = Stereobuf;
Rchan = Stereobuf + (bufferSize / 2);
}
if (buf1 == NULL || buf2 == NULL) {
cleanup(errno, "cannot allocate buffer");
}
buf = buf2;
sigarrived = 1;
do {
buf = buf == buf1 ? buf2 : buf1;
if ( channels == 1 ) {
/* only read remaining or bufferSize bytes */
res = (data_size > bufferSize) ? bufferSize : data_size;
if ((read(fd, buf, res)) == -1) {
if (errno == E_EOF) {
break;
} else {
cleanup(errno, "cannot read file");
}
}
data_size -= res;
process1(buf, res);
} else {
/* only read remaining or bufferSize / 2 bytes */
res = (data_size > bufferSize/2) ? bufferSize/2 : data_size;
if ((read(fd, Rchan, res)) != res) {
cleanup(errno, "cannot read right channel");
}
if ((read(fd2, Lchan, res)) != res) {
cleanup(errno, "cannot read left channel");
}
data_size -= res;
#if 0
printf("This read (%d)\n",res);
#endif
combine(Lchan,Rchan,buf,res);
}
if ( sigarrived == 0) {
sleepTime = 0;
tsleep(sleepTime);
}
sigarrived = 0;
#if 0
printf("Len (%d), Srate (%d)\n",res * 2, hdr.sample_rate);
#endif
_ss_play(1, buf, res*2, hdr.sample_rate, SND_SENDSIG, SIG_CODE);
} while ( data_size > 0 );
/* clean up if stereo */
if (channels > 1)
{
close(fd2);
free(Stereobuf);
}
sleepTime = 0;
tsleep(sleepTime);
/* free up memory */
free(buf1);
free(buf2);
close(fd);
}
static int process1(buf, n)
unsigned char *buf;
int n;
{
int32 i;
for (i = n - 1; i >= 0 ; i--) {
buf[2*i + 1] = buf[2*i] = buf[i];
}
}
static int combine(left,right,buf, n)
unsigned char *left,*right,*buf;
int n;
{
int32 i,j;
#if 0
printf("Combining %d bytes\n",n);
#endif
for (j = 0,i = 0; i < n; i++,j += 2) {
buf[j] = right[i];
buf[j+1] = left[i];
}
#if 0
printf("Done i(%d),j(%d),n(%d)\n",i,j,n);
#endif
}