
/*************************************************************************/
/*			      PlayStereo.c				 */
/*		Contains code used to play stereo samples		 */
/*************************************************************************/

#include <exec/types.h>
#include <exec/exec.h>
#include <devices/audio.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <stdlib.h>

#include "dsound.h"

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

extern UBYTE rightAMap[];
extern UBYTE leftAMap[];
extern UBYTE eitherAMap[];
extern UBYTE bothAMap[];

extern UBYTE volume;
extern UWORD speed;
extern ULONG bufSize;

extern BOOL readAll;
extern BOOL loop;
extern struct Window *window;

extern ULONG signalMask;

/*Play a stereo sample out of both speakers*/
/*If the user specifies that just one of the two stereo channels will*/
/*be played, DSound.c calls playMonoSample*/

void playStereoSample(BPTR leftFile,channel audioChannel,
		      struct Voice8Header *vhdr, ULONG length, char *filename)
{
   struct IOAudio *iob1_right,*iob2_right,*iob1_left,*iob2_left;
   struct IOAudio *cur_right,*cur_left,*alt_right,*alt_left;
   ULONG toRead;
   ULONG sampleSize=length;
   BOOL done=FALSE;
   BPTR rightFile;

   /*Open the file again*/
   rightFile=dupFileHandle(leftFile,filename);

   /*And position ourselves at the start of the right channel's data*/
   Seek(rightFile,length,OFFSET_CURRENT);

   /*Read the entire sample into memory, if specified*/
   if(readAll)
   {
      storeLeft(leftFile,length,bufSize);
      storeRight(rightFile,length,bufSize);
      Close(rightFile);
      leftFile=0L;
      rightFile=4L;
   }

   /*Get the first audio channel*/
   iob1_left=GetAudioChannel(bufSize,leftAMap);
   if(iob1_left==NULL)
   {
      WriteMsg("Couldn't create the first stereo buffer\n");
      cleanup(150);
   }

   iob1_right=GetAudioChannel(bufSize,rightAMap);
   if(iob1_right==NULL)
   {
      WriteMsg("Couldn't create the second stereo buffer\n");
      cleanup(150);
   }

   /* If the user didn't specify a volume, get it from the VHDR */
   if(volume==0)
      volume=(vhdr->volume>>10);

   /* If the VHDR gave a volume of zero, use maximum volume*/
   if(volume==0)
      volume=64;

   /* Get the samples/sec rate (either the rate given by the user, or the*/
   /* rate found in the VHDR) */
   if(speed==0)
      speed=1000000000/(vhdr->samplesPerSec*279);
   else
      speed=1000000000/(speed*279);

   InitAudioChannel(iob1_left,volume,speed);
   InitAudioChannel(iob1_right,volume,speed);

   /*Get the 2nd audio channel*/
   iob2_left=DuplicateAudioChannel(iob1_left);

   if(iob2_left==NULL)
   {
      FreeAudioChannel(iob1_left);
      FreeAudioChannel(iob1_right);
      WriteMsg("Couldn't create the second buffer");
      cleanup(175);
   }

   iob2_right=DuplicateAudioChannel(iob1_right);
   if(iob2_right==NULL)
   {
      FreeAudioChannel(iob1_left);
      DeleteDuplication(iob2_left);
      FreeAudioChannel(iob1_right);
      WriteMsg("Couldn't create the second buffer");
      cleanup(175);
   }

   /* Load the first buffer*/
   toRead=MIN(length,bufSize);
   LoadAudioBuffer(leftFile,iob1_left,toRead);
   LoadAudioBuffer(rightFile,iob1_right,toRead);
   iob1_left->ioa_Length=iob1_right->ioa_Length=toRead;

   length-=toRead;
   if(length==0 && loop)
   {
      length=sampleSize;
      Seek(leftFile,-sampleSize,OFFSET_CURRENT);
      Seek(rightFile,-sampleSize,OFFSET_CURRENT);
   }

   /*And queue up the play requests*/
   BeginIO((struct IORequest *)iob1_left);
   BeginIO((struct IORequest *)iob1_right);

   cur_right=iob2_right;
   cur_left=iob2_left;
   alt_right=iob1_right;
   alt_left=iob1_left;

   /*Loop while there's stuff to read*/
   while(!done)
   {
      toRead=MIN(length,bufSize);

      if(toRead!=0)
      {
	 LoadAudioBuffer(leftFile,cur_left,toRead);
	 LoadAudioBuffer(rightFile,cur_right,toRead);
	 cur_left->ioa_Length=cur_right->ioa_Length=toRead;
	 BeginIO((struct IORequest *)cur_left);
	 BeginIO((struct IORequest *)cur_right);
	 length-=toRead;

	 if(length==0 && loop)
	 {
	    length=sampleSize;
	    Seek(leftFile,-sampleSize,OFFSET_CURRENT);
	    Seek(rightFile,-sampleSize,OFFSET_CURRENT);
	 }
	 done=FALSE;
      }
      else
	 done=TRUE;

      /*Wait for the buffer to finish*/
      if((Wait(1<<cur_right->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit |
	   signalMask) & SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C)
	 done=TRUE;

      swapPointers(&cur_left,&alt_left);
      swapPointers(&cur_right,&alt_right);
   }

   /*Restore the buffer lengths, so that FreeAudio() channel, etc., knows*/
   /*how much memory to free*/
   iob1_left->ioa_Length=iob2_left->ioa_Length=bufSize;
   iob1_right->ioa_Length=iob2_right->ioa_Length=bufSize;

   FreeAudioChannel(iob1_left);
   DeleteDuplication(iob2_left);
   FreeAudioChannel(iob1_right);
   DeleteDuplication(iob2_right);

   if(rightFile != 4L)
      Close(rightFile);

   return;
}

/*End of PlayStereo.c*/
