/*
 * This file plays sounds from a pipe.
 * 
 * Paul Lindner (lindner@boombox.micro.umn.edu)
 */ 
#import	<stdio.h>
#import	<sound/sound.h>

#define	NUM_BUFFERS	2
#define	BUF_SIZE	1024
#define	SECONDS		10000.0

static SNDSoundStruct *buffers[NUM_BUFFERS];
static int requestedDataSize, recordedDataSize = 0;
static int lastBufNum;

static void playit(int tag);

/*
 * Called before the sample is played
 */

static int beforePlay(SNDSoundStruct *s, int tag, int err)
{
     int size;

     if (err)
	  fprintf(stderr, "beforePlay: %s\n", SNDSoundError(err));

     size = fread((void*)((char*)s + s->dataLocation), 1, s->dataSize, stdin);

     /*** If the size is zero, then we're probably done,
          This is a really ugly hack though...... ***/

     if (size == 0)
          sleep(1), exit(0);

     /*** This is probably the last buffer, so we'll fill the excess with
          zeros ***/
     if (size != s->dataSize) {
	bzero((void*)((char*)s + s->dataLocation + size), BUF_SIZE-size);
     }
}

static int playDone(SNDSoundStruct *s, int tag, int err)
/*
 * Called when a buffer has been played.
 */
{
    playit((lastBufNum + 1) % NUM_BUFFERS);
    return 0;
}

static void playit(int bufNum)
/*
 * Initiates playing into a buffers[bufNum].
 */
{
    int err;
    static int tag = 1;
    
    lastBufNum = bufNum;
    if (err = SNDStartPlaying(buffers[bufNum], tag++, 0, 0, beforePlay,
				playDone))
        fprintf(stderr, "play: %s\n", SNDSoundError(err));
}


/*
 * Allocate n sound buffers.
 */
static void init(int n, int size)
{
    int i, err;
    SNDSoundStruct s;

    for (i = 0; i < n; i++)
        if (err = SNDAlloc(&buffers[i], size, SND_FORMAT_MULAW_8,
			   SND_RATE_CODEC, 1, 4))
	    fprintf(stderr, "init: %s\n", SNDSoundError(err));
}

static void startup(void)
/*
 * Read the soundfile header.
 */
{
    SNDSoundStruct s;

    s.magic = SND_MAGIC;
    s.dataLocation = sizeof(SNDSoundStruct);
    s.dataSize = recordedDataSize;
    s.dataFormat = SND_FORMAT_MULAW_8;
    s.samplingRate = SND_RATE_CODEC;
    s.channelCount = 1;

    if (fread((void *)&s, sizeof(SNDSoundStruct), 1, stdin) != 1)
	fprintf(stderr, "cleanup: could not read header\n");

/*    if (s.magic != SND_MAGIC)
	 fprintf(stderr, "Not a valid sound file....\n"), exit(-1);
*/
}

main(int argc, char *argv[])
{
    int i;

    requestedDataSize = SECONDS * SND_RATE_CODEC;
    startup();
    init(NUM_BUFFERS, BUF_SIZE);
    for (i=0; i<NUM_BUFFERS; i++)
		playit(i);
    SNDWait(0);
}

