// ------------------------------------------------------------------------------------------------
// MyStream.c
//
// This has some higher level stream functions
//
// COPYRIGHT (C) SEGA OF AMERICA, INC. 1998
// All rights reserved.
//
// Information and source code samples contained herein are 
// provided "as-is", without representations or warranties, and 
// are subject to change without notice.
//
// SEGA OF AMERICA, INC. cannot support modifications or 
// derivative works created from the sample source code provided. 
// Developers may use, reproduce, and modify portions or entire 
// sections of the sample source code for the purposes of creating
// Dreamcast applications.  
//
// Sample source code contained herein may not be appropriate 
// for use under all circumstances.  Please consult Developer 
// documentation provided along with your Dreamcast unit for
// additional information and suggestions.
//
//
// Author: Ralph "Cooksey" Thomas
//
// Tabs:	4
//
// Rev:		04/05/99	Added this header
//			04/07/99	Cleaned up.
// ------------------------------------------------------------------------------------------------


#include <am.h>
#include "MyStream.h"

void _amStreamIsr0(KTU32 streamPtr); // the new unified ISR format

#define STREAM_TEST_PLAY_BUFFER_SIZE		16384
#define STREAM_TEST_TRANSFER_BUFFER_SIZE	(STREAM_TEST_PLAY_BUFFER_SIZE * 2)

volatile KTBOOL		gStreamCallbackFlag	=	KTFALSE;

KTBOOL MyStreamSetVolume(AM_STREAM_PTR theStream,KTU32 volume)
{
return amStreamSetVolume(theStream,volume,0);
}


KTBOOL MyStreamStop(AM_STREAM_PTR theStream)
{
return amStreamStop(theStream);
}

void MyStreamCallback(KTU32 voiceChannelNumber)
{
gStreamCallbackFlag	=	KTTRUE;
}

void MyStreamServer(AM_STREAM_PTR theStream)
{
amStreamServer(theStream);
}

KTBOOL MyStreamIsPlaying(void)
{
return (gStreamCallbackFlag==KTTRUE)?KTFALSE:KTTRUE;
}


KTBOOL MyStreamIsDone(void)
{
return (gStreamCallbackFlag==KTTRUE)?KTTRUE:KTFALSE;
}

void MyStreamClearCallbackFlag(void)
{
gStreamCallbackFlag	=	KTFALSE;
}

KTBOOL MyStreamStart(AM_STREAM_PTR theStream,char *streamFileName)
{
KTU32 						volume				=	AM_MAX_VOLUME;	//	127
KTU32 						pan					=	AM_PAN_CENTER;	// 64
volatile KTU32 *			playBuffer			=	KTNULL;
KTU32						playBufferSize		=	0;
volatile KTU32 *			transferBuffer		=	KTNULL;
KTU32						transferBufferSize	=	STREAM_TEST_TRANSFER_BUFFER_SIZE;

// ----------------------------------------------------------------------------------------------
// init the stream object
// ----------------------------------------------------------------------------------------------

if(amStreamInit(theStream,streamFileName)==KTFALSE)
	{
	acPrintf("amStreamInit(theStream,%s,%u,%u) FAIL\n",streamFileName,volume,pan);
	return KTFALSE;
	}
else
	acPrintf("amStreamInit(theStream,%s,%u,%u)\t\t// init the stream object\n",streamFileName,volume,pan);

// ----------------------------------------------------------------------------------------------
// set the buffer sizes
// ----------------------------------------------------------------------------------------------

if(amStreamSetBufferSizes(theStream,STREAM_TEST_TRANSFER_BUFFER_SIZE,STREAM_TEST_PLAY_BUFFER_SIZE)==KTFALSE)
	{
	acPrintf("amStreamSetBufferSizes(theStream,transferBufferSize=%u,playBufferSize=%u) FAIL// set the buffer sizes\n",STREAM_TEST_TRANSFER_BUFFER_SIZE,STREAM_TEST_PLAY_BUFFER_SIZE);
	return KTFALSE;
	}
else
	acPrintf("amStreamSetBufferSizes(theStream,transferBufferSize=%u,playBufferSize=%u)// set the buffer sizes\n",STREAM_TEST_TRANSFER_BUFFER_SIZE,STREAM_TEST_PLAY_BUFFER_SIZE);

// ----------------------------------------------------------------------------------------------
// open the stream
// ----------------------------------------------------------------------------------------------

if(amStreamOpen(theStream)==KTFALSE)
	{
	acPrintf("amStreamOpen(theStream) FAIL\n");
	return KTFALSE;
	}
else
	acPrintf("amStreamOpen(theStream)\t// open the stream file\n");

// ----------------------------------------------------------------------------------------------
// Get the memory requirements, this allows more flexability over the setMono and 
// setStereoBuffers calls, these will be removed and this interface will remain to allow
// for multitrack stream files with n tracks.
// ----------------------------------------------------------------------------------------------

if(amStreamGetMemoryRequirement(theStream,&transferBufferSize,&playBufferSize)==KTFALSE)
	{
	acPrintf("amStreamGetMemoryRequirement(theStream,&transferBufferSize,&playBufferSize) FAIL\n");
	return KTFALSE;
	}
else
	acPrintf("amStreamGetMemoryRequirement(theStream,%u,%u) // find out how much memory is required\n",transferBufferSize,playBufferSize);

// ----------------------------------------------------------------------------------------------
// get the necessary buffers lined up for the stream
//
// play buffer in sound memory only, using this system playBufferSize will be the following,
// playBufferSize	=	(theStream->playBufferSizeInBytes * theStream->channels)
// ----------------------------------------------------------------------------------------------

if(amHeapAlloc(&playBuffer,playBufferSize,32,AM_PURGABLE_MEMORY,KTNULL)==KTFALSE)
	{
	acPrintf("amHeapAlloc(0x%x,%u,%u,AM_PURGABLE_MEMORY,KTNULL) FAIL\n",playBuffer,playBufferSize,32);
	return KTFALSE;
	}
else
	acPrintf("amHeapAlloc(0x%x,%u,%u,AM_PURGABLE_MEMORY,KTNULL)\n",playBuffer,playBufferSize,32);

// ----------------------------------------------------------------------------------------------
// transfer buffer in sound memory or sh4 memory, in this example it is in sound memory
// the transfer buffer MUST! be 32 byte aligned or file reads will fail with the GD file
// system, the alignment is not necessary for the memory system in this module to work.
// This is done so that by commenting out the call to amStreamIoInstallAlternateIoManager
// this example will read directly from the disk.
// ----------------------------------------------------------------------------------------------

if(amHeapAlloc(&transferBuffer,transferBufferSize,32,AM_PURGABLE_MEMORY,KTNULL)==KTFALSE)
	{
	acPrintf("amHeapAlloc(0x%x,%u,%u,AM_PURGABLE_MEMORY,KTNULL) FAIL\n",transferBuffer,transferBufferSize,32);
	return KTFALSE;
	}
else
	acPrintf("amHeapAlloc(0x%x,%u,%u,AM_PURGABLE_MEMORY,KTNULL)\n",transferBuffer,transferBufferSize,32);


// ----------------------------------------------------------------------------------------------
// give the stream the buffers
// ----------------------------------------------------------------------------------------------

if(amStreamSetBuffers(theStream,transferBuffer,playBuffer)==KTFALSE)
	{
	acPrintf("amStreamSetBuffers(theStream,0x%x,0x%x) FAIL\n",transferBuffer,playBuffer);
	return KTFALSE;
	}
else
	acPrintf("amStreamSetBuffers(theStream,0x%x,0x%x) // set the buffers\n",transferBuffer,playBuffer);

// ----------------------------------------------------------------------------------------------
// allocate the voice channels
// ----------------------------------------------------------------------------------------------

if(amStreamAllocateVoiceChannels(theStream)==KTFALSE)
	{
	acPrintf("amStreamAllocateVoiceChannels(theStream) FAIL\n");
	return KTFALSE;
	}
else
	acPrintf("amStreamAllocateVoiceChannels(theStream)\t// allocate voice channels\n");

// ----------------------------------------------------------------------------------------------
// prime buffers
// ----------------------------------------------------------------------------------------------

if(amStreamPrimeBuffers(theStream)==KTFALSE)
	{
	acPrintf("amStreamPrimeBuffers(theStream) FAIL\n");
	return KTFALSE;
	}
else
	acPrintf("amStreamPrimeBuffers(theStream)\t// prime the play buffer\n");


// ----------------------------------------------------------------------------------------------
// set the isr, must be called after the voice channel(s) are allocated
// ----------------------------------------------------------------------------------------------

if(amStreamSetIsr(theStream,_amStreamIsr0)==KTFALSE)
	{
	acPrintf("amStreamSetIsr(theStream,_amStreamStereoIsr0) FAIL\n");
	return KTFALSE;
	}
else
	acPrintf("amStreamSetIsr(theStream,_amStreamStereoIsr0)\t// set the stream ISR\n");

// ----------------------------------------------------------------------------------------------
// install a user callback
// ----------------------------------------------------------------------------------------------

if(amStreamInstallUserCallback(theStream,MyStreamCallback)==KTFALSE)
	{
	acPrintf("amStreamInstallUserCallback(theStream,MyStreamCallback) FAIL\n");
	return KTFALSE;
	}
else
	acPrintf("amStreamInstallUserCallback(theStream,0x%x)\t// install a user callback\n",MyStreamCallback);


acPrintf("amStreamStart(theStream) // start the stream\n");

// ----------------------------------------------------------------------------------------------
// set the volume to max 
// ----------------------------------------------------------------------------------------------

amStreamSetVolume(theStream,AM_MAX_VOLUME,0);


// ----------------------------------------------------------------------------------------------
// start the stream
// ----------------------------------------------------------------------------------------------

if(amStreamStart(theStream)==KTFALSE)
	{
	acPrintf("amStreamStart(theStream)==KTFALSE\n");
	return KTFALSE;
	}


return KTTRUE;
}


KTBOOL MyStreamRestart(AM_STREAM_PTR theStream)
{
// ----------------------------------------------------------------------------------------------
// rewind to the beginning of the file
// ----------------------------------------------------------------------------------------------

if(amStreamRewind(theStream)==KTFALSE)
	{
	acPrintf("amStreamRewind(theStream) FAIL\n");
	return;
	}

// ----------------------------------------------------------------------------------------------
// allocate the voice channel
// ----------------------------------------------------------------------------------------------

if(amStreamAllocateVoiceChannels(theStream)==KTFALSE)
	{
	acPrintf("amStreamAllocateVoiceChannels(theStream) FAIL\n");
	return;
	}

// ----------------------------------------------------------------------------------------------
// prime buffers
// ----------------------------------------------------------------------------------------------

if(amStreamPrimeBuffers(theStream)==KTFALSE)
	{
	acPrintf("amStreamPrimeBuffers(theStream) FAIL\n");
	return;
	}

// ----------------------------------------------------------------------------------------------
// set the isr, must be called after the voice channel(s) are allocated
// ----------------------------------------------------------------------------------------------

if(amStreamSetIsr(theStream,_amStreamIsr0)==KTFALSE)
	{
	acPrintf("amStreamSetIsr(theStream,_amStreamStereoIsr0) FAIL\n");
	return;
	}

// ----------------------------------------------------------------------------------------------
// install a user callback
// ----------------------------------------------------------------------------------------------

if(amStreamInstallUserCallback(theStream,MyStreamCallback)==KTFALSE)
	{
	acPrintf("amStreamInstallUserCallback(theStream,MyMemoryStreamCallback) FAIL\n");
	return;
	}

// ----------------------------------------------------------------------------------------------
// start the stream
// ----------------------------------------------------------------------------------------------

if(amStreamStart(theStream)==KTFALSE)
	{
	acPrintf("amStreamStart(theStream)==KTFALSE\n");
	return;
	}
}

