
/*************************************************************************/
/*			      PlayMono2.c				 */
/*     Contains code used to play mono samples out of both speakers.	 */
/*************************************************************************/

#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 mono sample (or a single channel of a stereo sample) out of */
/*both speakers simultaneously*/
void playMonoTwice(BPTR file,channel audioChannel,struct Voice8Header *vhdr,
		   ULONG length)
{
   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;

   /*Read the entire sample into memory, if the user so specified*/
   if(readAll)
   {
      storeLeft(file,length,bufSize);
      file=0L;
   }

   /*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);
   }
   FreeMem(iob1_right->ioa_Data,iob1_right->ioa_Length);
   iob1_right->ioa_Data=iob1_left->ioa_Data;

   /* 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);
   }
   FreeMem(iob2_right->ioa_Data,iob2_right->ioa_Length);
   iob2_right->ioa_Data=iob2_left->ioa_Data;

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

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

   /*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(file,cur_left,toRead);
	 cur_right->ioa_Length=cur_left->ioa_Length=toRead;
	 length-=toRead;
	 BeginIO((struct IORequest *)cur_left);
	 BeginIO((struct IORequest *)cur_right);

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

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

      if(window!=NULL && GetMsg(window->UserPort)!=NULL)
      {
	 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;

   iob1_right->ioa_Data=NULL;
   iob2_right->ioa_Data=NULL;

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

   return;
}

/*End of Play.c*/
