/*
Example mpeg layer3 player for truesound.device
By Pontus Fuchs 1997
*/

#include <stdio.h>

#include <exec/exec.h>
#include <dos/dos.h>

#include <proto/dos.h>
#include <proto/exec.h>

#define BUFFSIZE 0x10000 /*Must be even*/

/*protos*/
int startup(void);
void closedown(void);
int getargs(void);
void mainloop(void);
ULONG fillbuffer(struct IOStdReq *ioreq, char *buffer);

/*Globala variabler*/
char *filename=0;
struct RDArgs *args=0;
struct MsgPort *msgport1;
struct MsgPort *msgport2;
struct IOStdReq *ioreq1;
struct IOStdReq *ioreq2;
int deviceopen=0;
BPTR file=0;

char buffer1[BUFFSIZE];
char buffer2[BUFFSIZE];

void main(void)
{
  if(startup())
  {
    printf("Example MPEG layer3-player for truesound.device\nCopyright © 1997 by Pontus Fuchs\n");
    printf("Now playing: %s\n", filename);
    mainloop();
    printf("\n");
  }
  closedown();
}

void mainloop(void)
{
ULONG sigrcvd;
int done=1;
ULONG buffsize1;
ULONG buffsize2;

  buffsize1=fillbuffer(ioreq1, buffer1);
  buffsize2=fillbuffer(ioreq2, buffer2);

  while(done)
  {
    sigrcvd=Wait(SIGBREAKF_CTRL_C|1<<msgport1->mp_SigBit|1<<msgport2->mp_SigBit);

    if(sigrcvd & SIGBREAKF_CTRL_C) /* ctrl_c? */
      done=0;

    if(sigrcvd & (1<<msgport1->mp_SigBit))
    {
      WaitIO( (struct IORequest*) ioreq1);
      buffsize1=fillbuffer(ioreq1, buffer1);
      /*printf("Filled buffer1 with %d bytes\n", buffsize1);*/

    }

    if(sigrcvd & (1<<msgport2->mp_SigBit))
    {
      WaitIO( (struct IORequest*) ioreq2);
      buffsize2=fillbuffer(ioreq2, buffer2);
      /*printf("Filled buffer2 with %d bytes\n", buffsize2);*/
    }

    if((buffsize1==0) & (buffsize2==0))  /*exit if both buffers are empty*/
      done=0;

  }

/*Abort any active IO-requests*/
  if(buffsize1)
  {
    AbortIO( (struct IORequest*) ioreq1);
    WaitIO( (struct IORequest*) ioreq1);
  }

  if(buffsize2)
  {
    AbortIO( (struct IORequest*) ioreq2);
    WaitIO( (struct IORequest*) ioreq2);
  }
 }

ULONG fillbuffer(struct IOStdReq *ioreq, char *buffer)
{
ULONG readsize;

  readsize=Read(file, buffer, BUFFSIZE);
  if(readsize==-1)
  {
    printf("Read error!\n");
    return 0;
  }

  if(readsize)
  {
    ioreq->io_Command=CMD_WRITE;
    ioreq->io_Data=buffer;
    ioreq->io_Length=readsize;
    SendIO((struct IORequest*) ioreq);
  }
  
  return readsize;
}

int startup(void)
{
  if(!getargs())
    return 0;

  if((msgport1=CreateMsgPort())==0)
    return 0;
  if((ioreq1=CreateIORequest(msgport1, sizeof(struct IOStdReq)))==0)
    return 0;
  if(OpenDevice("truesound.device", 0, (struct IORequest*) ioreq1, 0))
    return 0;
  deviceopen++;

  if((msgport2=CreateMsgPort())==0)
    return 0;
  if((ioreq2=CreateIORequest(msgport2, sizeof(struct IOStdReq)))==0)
    return 0;
  if(OpenDevice("truesound.device", 0, (struct IORequest*) ioreq2, 0))
    return 0;
  deviceopen++;

  if((file=Open(filename, MODE_OLDFILE))==0)
  {
    printf("Error: Could't open %s\n",filename);
    return 0;
  }

  return 1;
}

void closedown(void)
{
  if(file)
    Close(file);

  if(deviceopen) /*Check if IOreq1 was opened*/
    {
      CloseDevice((struct IORequest*) ioreq1);
      deviceopen--;
    }

  if(deviceopen) /*Check if IOreq2 was opened*/
    CloseDevice((struct IORequest*) ioreq2);

  DeleteIORequest(ioreq1); /*passing NULL is safe*/
  DeleteMsgPort(msgport1);
  DeleteIORequest(ioreq2);
  DeleteMsgPort(msgport2);

  FreeArgs(args);
}

int getargs(void)
{
LONG array[2]={0,};

  if(args=ReadArgs("FILE/A",array,NULL))
  {
    if(array[0])
      filename=(char*)array[0];
  }

  if(filename==0)
  {
    printf("Play WHAT?\n");
    return 0;
  }
  else
    return 1;
}
