home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
-
- #include "FabWmemman.h"
- #include "FabTaskManager.h"
- #include "SoundHandling.h"
-
- static SndCallBackUPP gmyCallbackUPP = nil;
- static unsigned int gNumAsyncSnds = 0;
-
- static pascal void myCallback(SndChannelPtr theChan, const SndCommand *sc);
- static void CloseSoundChannel(void *sndChan);
- static void GetRidOfSndChannel(SndChannelPtr sndChan);
- static void NewSoundData(SndListHandle sndH);
- static Boolean IncrementSnd(SndListHandle sndH);
- static void DeleteSoundData(SndListHandle sndH);
-
- unsigned short GetSoundsRemaining(void)
- {
- return gNumAsyncSnds;
- }
-
- void InitMySoundHandling(void)
- {
- gmyCallbackUPP = NewSndCallBackProc(myCallback);
- }
-
- pascal void myCallback(SndChannelPtr /*theChan*/, const SndCommand *sc)
- {
- Fab_ScheduleSystemTask((void *)sc->param2);
- }
-
- void DoSound(short sndResID)
- {
- SndListHandle sndH;
-
- if (sndH = (SndListHandle)Get1Resource(soundListRsrc, sndResID))
- DoSoundHandle(sndH);
- }
-
- void DoSoundHandle(SndListHandle sndH)
- {
- enum {
- kMyQueueLen = 4
- };
- SndCommand mySndCmd;
- SndChannelPtr mySndChan;
-
- mySndChan = (SndChannelPtr)fmalloc(sizeof(SndChannel) - stdQLength * sizeof(SndCommand) + kMyQueueLen * sizeof(SndCommand));
- if (mySndChan) {
- mySndChan->qLength = kMyQueueLen;
- if (SndNewChannel(&mySndChan, 0, 0, gmyCallbackUPP) == noErr) {
- mySndChan->userInfo = (long)sndH;
- mySndCmd.cmd = callBackCmd;
- mySndCmd.param2 = (long)Fab_CreateSystemTask(CloseSoundChannel, mySndChan, true);
- if (mySndCmd.param2) {
- NewSoundData(sndH);
- (void) SndPlay(mySndChan, sndH, true);
- ++gNumAsyncSnds;
- // InitTaskRecord(CloseSoundChannel, (TMInfoPtr)mySndCmd.param2);
- (void)SndDoCommand(mySndChan, &mySndCmd, true);
- }
- else
- GetRidOfSndChannel(mySndChan);
- }
- }
- }
-
- void CloseSoundChannel(void *sndChan)
- {
- --gNumAsyncSnds;
- DeleteSoundData((SndListHandle)((SndChannelPtr)sndChan)->userInfo);
- GetRidOfSndChannel((SndChannelPtr)sndChan);
- }
-
- static void GetRidOfSndChannel(SndChannelPtr sndChan)
- {
- (void)SndDisposeChannel(sndChan, false);
- ffree((Ptr)sndChan);
- }
-
-
- enum {
- kInitialSlots = 8
- };
-
- struct CountLocks {
- SndListHandle sndH;
- UInt32 count;
- };
-
- typedef struct CountLocks CountLocks;
-
- static Handle gWarr = nil;
- static int gWcount = 0, gWmaxcount = kInitialSlots;
-
- void NewSoundData(SndListHandle sndH)
- {
- if (IncrementSnd(sndH) == false) {
- if (gWarr == nil) {
- gWarr = NewHandle(sizeof(CountLocks) * kInitialSlots);
- }
- else if (gWcount == gWmaxcount) {
- gWmaxcount += kInitialSlots;
- SetHandleSize(gWarr, sizeof(CountLocks) * gWmaxcount);
- }
-
- ((CountLocks *)(*gWarr))[gWcount].sndH = sndH;
- ((CountLocks *)(*gWarr))[gWcount++].count = 1;
- HLockHi((Handle)sndH);
- }
- }
-
- Boolean IncrementSnd(SndListHandle sndH)
- {
- CountLocks *deref;
- int i;
-
- if (gWarr) {
- deref = (CountLocks *)*gWarr;
- for (i = 0; i < gWcount; i++)
- if (sndH == deref[i].sndH) {
- ++(deref[i].count);
- return true;
- }
- }
- return false;
- }
-
- void DeleteSoundData(SndListHandle sndH)
- {
- CountLocks *deref;
- int i;
- int newCount;
-
- deref = (CountLocks *)*gWarr;
- // find sound in array
- for (i = 0; i < gWcount; i++)
- if (sndH == deref[i].sndH) {
- // move items
- if (--(deref[i].count) == 0) {
- newCount = gWcount - 1;
- if (i != newCount)
- (void) memmove(&deref[i], &deref[i+1], (newCount - i) * sizeof(CountLocks));
- gWcount = newCount; // updated last to avoid concurrency problems
- HUnlock((Handle)sndH);
- }
- break;
- }
- }
-
-