[comp.sys.mac.hypercard] Sound And Hypercard

glc@frame.UUCP (Greg Cockroft) (05/07/89)

The following LightSpeed C XCMD shows how to use the sound manager
in an XCMD. I downloaded it from AppleLink. 

	-greg.



/*
	playSound -- XCMD to play a sound in any resource file
	21 Feb 1989 Greg Jorgensen, Mac DTS
	) Apple Computer Inc., 1989
	
	usage: playSound fileName, soundName
	
	returns any error messages in 'the result'
	
	THIS CODE IS NOT SUPPORTED BY APPLE COMPUTER
	It may not work with future releases.
	May be distributed free of charge.
*/

#include <SetupA4.h>
#include <SoundMgr.h>
#include <HyperXCmd.h>

#define	NIL	0x00000000

void	putResult(XCmdBlockPtr, char *);

/***/

pascal void main(paramPtr)
	XCmdBlockPtr	paramPtr;
{
	int				resFile, saveResFile;
	SndChannelPtr	tempChan, theChan;
	Handle			hSnd;
	OSErr			err;

/*	these routines are provided in Think C to address globals off of A4
	rather than A5. We need to do this because this routine uses literal
	strings, which are treated as globals.
*/
	RememberA0();				/* set up for globals */
	SetUpA4();

/* check parameters */

	if (paramPtr->paramCount != 2) {
		putResult(paramPtr, "need two parameters");
		return;
	}
	
	paramPtr->returnValue = NIL;			/* empty return means OK */
	HLock(paramPtr->params[0]);
	CtoPstr( *(paramPtr->params[0]) );
		
	saveResFile = CurResFile();				/* save the current res file id */
	resFile = OpenResFile( *(paramPtr->params[0]) );

	PtoCstr( *(paramPtr->params[0]) );		/* restore file name */
	HUnlock(paramPtr->params[0]);			/*  in case HC cares... */
		
	if (resFile == -1) {
		putResult(paramPtr, "can't open resource file");
		return;
	}
			
	UseResFile(resFile);				/* in case it was already open */
	HLock(paramPtr->params[1]);			/* get name & read resource... */
	CtoPstr( *(paramPtr->params[1]) );
	hSnd = GetNamedResource( (ResType)'snd ', *(paramPtr->params[1]) );
	PtoCstr(*(paramPtr->params[1]) );	/* clean up for HC */
	HUnlock(paramPtr->params[1]);

	if (!hSnd) {
		putResult(paramPtr, "no such snd");
		return;
	}

	tempChan = NIL;					/* open new channel */
	err = SndNewChannel(&tempChan, 0, 0L, NIL);
	if (err) {
		putResult(paramPtr, "open channel err");
		ReleaseResource(hSnd);		/* release snd */
		return;
	}
		
/*	if a sound channel was already open, nextChan will have a pointer to it 
	in tempChan->nextChan; if not nextChan will contain NIL.
*/
		
	theChan = tempChan->nextChan;		/* get pointer to open channel, if any */
	err = SndDisposeChannel(tempChan, FALSE); /* close ours */

/*	Play the sound. If a channel was open, it will be used. If not, theChan will
	be NIL and SndPlay will create a temporary channel.
*/	
	HLock(hSnd);
	err = SndPlay(theChan, hSnd, FALSE);	/* play sound */
	HUnlock(hSnd);
	ReleaseResource(hSnd);
			
	UseResFile(saveResFile);			/* restore original res file */
	
	/* resFile is not closed because it may be in use by Hypercard */
	
	RestoreA4();
}

/*****
	put a string into "the result" for Hypercard
*****/

void putResult(paramPtr, s)
	XCmdBlockPtr	paramPtr;
	char *s;
{
	if (paramPtr->returnValue)					/* already have something? */
		DisposHandle(paramPtr->returnValue);	/* get rid of it */
	
	paramPtr->returnValue = NewHandle(1 + strlen(s) );
	strcpy( *(paramPtr->returnValue), s);
}
	
#include "XCmdGlue.inc.c"