"Fossies" - the Fresh Open Source Software archive 
Member "tplay-0.6.1/au.c" of archive tplay-0.6.1.tar.gz:
/*
* tplay - buffered audio player
*
* (c) 1997 ilkka karvinen <ik@iki.fi>
*
* Copyright under the GNU GENERAL PUBLIC LICENSE
* (see the file COPYING in this directory)
*
*
* SunOS audio file header functions.
* Reference: http://www.wotsit.demon.co.uk/formats/au/au.txt
*/
#include "common.h"
#include "audio.h"
/* read_au returns zero if Sun audio file format is found. */
int read_au(byte *buffer)
{
DWORD magic, start, end, encoding, speed, channels;
int bits;
int i, comment_size;
/* If '.snd'-header exits, this should be an au-file */
magic = read_big_endian_long(buffer);
if (magic != SUN_MAGIC) {
if (magic == SUN_INV_MAGIC)
info.swap = TRUE;
else
return(1);
}
start = read_big_endian_long(buffer+0x04);
end = read_big_endian_long(buffer+0x08);
encoding = read_big_endian_long(buffer+0x0C);
speed = read_big_endian_long(buffer+0x10);
channels = read_big_endian_long(buffer+0x14);
bits = DEFAULT_BITS;
switch(encoding) {
case 1 :
/* 8-bit ISDN u-law */
encoding = ULAW_BITS;
bits = 8;
break;
case 2 :
/* 8-bit linear PCM */
encoding = LIN8_BITS;
bits = 8;
break;
case 3 :
/* 16-bit linear PCM */
encoding = LIN_BITS;
bits = 16;
break;
case 4 :
die("24-bit linear PCM Sun audio file not supported");
break;
case 5 :
die("32-bit linear PCM Sun audio file not supported");
break;
case 6 :
die("32-bit IEEE floating point Sun audio file not supported");
break;
case 7 :
die("64-bit IEEE floating point Sun audio file not supported");
break;
case 23 :
die("8-bit ISDN u-law compressed(G.721 ADPCM) Sun audio file \
not supported");
break;
case 27 :
/* 8-bit a-law */
bits = 8;
encoding = ALAW_BITS;
break;
default :
errdie("Unknown Sun audio file");
break;
}
info.filetype = SUN_FILE;
/* Set audio parameters */
info.speed = (int)speed;
info.bits = bits;
info.encoding = encoding;
info.channels = (int)channels;
if (info.verbose) {
printf("Sun audio file: %d samples/s, %d bits, %d channel%s.\n",
(int)speed, (int)bits, (int)channels, ((channels != 1)
? "s" : ""));
if ((comment_size = start - SUN_HDRSIZE) > 0) {
printf("Header info: ");
for (i=0; i<comment_size; i++)
nice_fputc((int)buffer[SUN_HDRSIZE + i], stdout);
printf("\n");
}
}
/* Move data to start from the beginning of the buffer. */
/* This is to ensure the correct behaviour of rounding when 16bits */
/* and/or stereo sample is to be played. */
memmove(buffer, buffer+(start+1), info.blocksize-start-1);
info.headerskip = (int)(start + 1);
return(0);
}
/* write_au returns buffer offset if header is successfully written. */
/* here we overload bits to mean the encoding type */
int write_au(byte *buffer, int speed, int bits, int channels)
{
DWORD encoding;
switch(bits) {
case ULAW_BITS :
encoding = 1;
break;
case ALAW_BITS :
encoding = 27;
break;
case LIN8_BITS :
encoding = 2;
break;
case LIN_BITS :
encoding = 3;
break;
default :
return(0);
break;
}
write_big_endian_long(buffer, (DWORD)SUN_MAGIC);
write_big_endian_long(buffer+0x04, (DWORD)44);
write_big_endian_long(buffer+0x08, (DWORD)~0);
write_big_endian_long(buffer+0x0C, (DWORD)encoding);
write_big_endian_long(buffer+0x10, (DWORD)speed);
write_big_endian_long(buffer+0x14, (DWORD)channels);
return(44);
}