/***********************************************************************
*
* FUNCTION: PlayWaveFile
*
* DESCRIPTION: Finds a WAV file on any mounted VFS volume, reads it in
* to memory (entirely) and plays it.
*
* PARAMETERS: fileName - full path to the WAV file e.g. "/Palm/Test.wav"
*
* RETURNED: 0 for success, otherwise an int showing where it failed.
*
***********************************************************************/
int PlayWaveFile(char *fileName)
{
MemPtr ptr;
Err err;
FileRef fileRef=0;
UInt32 vfsMgrVersion;
UInt16 volRefNum;
UInt32 volIterator;
UInt32 fileSize;
// is the VFS manager present?
err = FtrGet(sysFileCVFSMgr, vfsFtrIDVersion, &vfsMgrVersion);
if (err != errNone) return 1;
// are the sampled sound APIs available?
// (commented out for now because as of dr9 the feature wasn't yet published.)
//err = FtrGet(sysFileCSoundMgr, vfsFtrIDVersion, &vfsMgrVersion);
//if (err != errNone) return 1;
// Until the sampled sound feature exists, check the trap address instead.
if (SysGetTrapAddress(sysTrapSndPlayResource) == SysGetTrapAddress(sysTrapSysUnimplemented))
return 1;
// Look for the named file on all mounted volumes (cards, hostfs, RAMdisk, etc.)
// Your application might want to pass in the volRefNum because presumably you know
// it, and don't want to pick a file with that name from any random mounted volume...
volIterator = vfsIteratorStart;
do {
err = VFSVolumeEnumerate(&volRefNum, &volIterator);
if (err)
return 2; // no more volumes to look at; file not found.
err = VFSFileOpen(volRefNum, fileName, vfsModeRead, &fileRef);
} while (err);
// found the file; how big is it?
err = VFSFileSize(fileRef, &fileSize);
if (err != errNone) {
VFSFileClose(fileRef);
return 4;
}
// It would be better to use the streaming API instead of reading the whole file in as
// a huge block, because this way we require that potentially a lot of memory be available.
// Unfortunately, the streaming API only supports uncompressed sound, not WAVs, and some of
// my demo WAVs are compressed, so streaming WAVs is left as an exercise for the reader.
ptr = cimMalloc(fileSize);
if (!ptr) {
VFSFileClose(fileRef);
return 5;
}
// we have memory; read in the contents of the file into memory.
err = VFSFileReadData(fileRef, fileSize, ptr, 0, &fileSize);
VFSFileClose(fileRef);
if (err != errNone) {
cimFree(ptr);
return 6;
}
// play it and clean up!
err = SndPlayResource(ptr, sndGameVolume, sndFlagSync); // must use sync because we're going to free the buffer right away
if (err == sndErrInvalidStream) err=errNone; // don't know why I sometimes get this in dr8...
cimFree(ptr);
if (err != errNone) return 7;
return 0;
}
extern Int16 UpdateBitmapData();
/*PALY COMPLET*/
void kaSndComplFuncType(void *chanP, UInt32 dwUserData)
{
if (g_ESHandle->loop)
{
g_ESHandle->state = _OPSTATE_PLAY;
PostCustomEvent(SoundEvent);
}
}
Boolean kaSndBlockingFuncType(void *chanP, UInt32 dwUserData, Int32 sysTicksAvailable)
{
UpdateBitmapData();
return true;
}
int PlayMidiFile( void *data )
{
Err err;
SndSmfCallbacksType callbacksP;
SndSmfOptionsType selP;
callbacksP.blocking.funcP = kaSndBlockingFuncType;
callbacksP.blocking.dwUserData = NULL;
callbacksP.reserved.dwUserData = NULL;
callbacksP.reserved.funcP = NULL;
callbacksP.completion.funcP = kaSndComplFuncType;
callbacksP.completion.dwUserData = NULL;
selP.dwStartMilliSec = 0;
selP.dwEndMilliSec = sndSmfPlayAllMilliSec;
selP.amplitude = sndMaxAmp;
selP.interruptible = true;
selP.reserved1 = NULL;
selP.reserved = NULL;
err=SndPlaySmf(NULL,sndSmfCmdPlay,data,&selP,NULL,&callbacksP,1);
switch(err)
{
case errNone:
MsgBoxForTrace("Successful");
break;
case sndErrBadParam:
MsgBoxForTrace("Invalid value passed to this function.");
break;
case sndErrBadChannel:
MsgBoxForTrace("Invalid sound channel.");
break;
case sndErrMemory:
MsgBoxForTrace("Insufficient memory.");
break;
case sndErrOpen:
MsgBoxForTrace("Tried to open channel that’s already open.");
break;
case sndErrQFull:
MsgBoxForTrace("Can’t accept more notes.");
break;
case sndErrFormat:
MsgBoxForTrace("Unsupported data format.");
break;
case sndErrBadStream:
MsgBoxForTrace("Invalid data stream.");
break;
case sndErrInterrupted:
MsgBoxForTrace("Play was interrupted.");
break;
}
return 1;
}