[comp.sys.mac.programmer] Think C 'snd ' Resource calls - Almost Working!

mcneely@ncrcae.Columbia.NCR.COM (Alan McNeely) (07/30/90)

Hello all:

Thanks to the information I got after my earlier question,  I've gotten
some 'snd ' resources playing from my Think C Program.  The code is below.
Thanks for the information.

But I'm still having one problem.  At first,  My SndPlay calls just passed
NIL for chan,  the first parameter.  According to IM5, this would cause a
channel to be allocated,  the sound played,  and then the channel would be
unallocated. 

This worked fine,  except there was a noticeable (about .5 second) delay
before each sound was played.  To get the sounds to happen faster,  I
decided to allocate a channel myself,  using the SndNewChannel call,  and
pass the Pointer to the channel to the SndPlay routines.

This worked,  and the sounds happen very quickly now.  But during the
execution of the program,  the sounds sometimes just stop happening.  
Silence for the rest of the run.  And when this happens,  the
SndDisposeChannel call at the bottom causes a system freeze.  SOMETIMES
this DOES NOT happen,  though,  and everything finishes fine and dandy.
And there doesn't seem to be any rhyme or reason to when it does happen!

My first thought was a memory management problem.  Sounds a lot like my
pointers are getting screwed up.  But also according to IM5,  the block
gotten by the SndNewChannel is locked and unrelocatable if you pass NIL
for the pointer to it (which I do).  Then the pointer (a VAR parameter)
comes back pointing to the locked, unrelocatable block.  So the pointer
should always be valid,  right?

Note that the reason I pass a pointer to my pointer (&SoundChannel) in
the SndNewChannel call is because the chan parameter is a VAR parameter,
so according to the THINK C docs,  I need to pass a pointer to the item,
in this case a pointer to a pointer.  Right?

Exasperated,  I tried declaring a variable for a SndChannel structure
in my declerations in main (therefore bypassing any Memory Manager woes
completely).  Then I passed pointers or pointers to pointers to this
structure as necessary,  and got the same results.

Any ideas?  Any help is, as always, much appreciated.

Here's the relevant code.  The SysBeeps are just cheap debug statements. 

...
#include "SoundMgr.h"
...
void main()
{
	/* decs */
	...
	long		ResType;
	SndChannelPtr	SoundChannel;
	Handle		LowClapHandle, HighClapHandle;
	...
	/* allocate sound channel */
	SoundChannel = NIL;
	if (SndNewChannel(&SoundChannel,sampledSynth,NIL,NIL) != noErr)
		SysBeep(30);
	/* get sounds from resource file */
	ResType='snd ';
	LowClapHandle = GetResource(ResType, 27991);
	if (LowClapHandle == NIL)
		SysBeep(1);
	HighClapHandle = GetResource(ResType, 11989);
	if (HighClapHandle == NIL)
		SysBeep(1);
	...
	/* play sounds */
	SndPlay(SoundChannel,LowClapHandle,TRUE);
	...
	SndPlay(SoundChannel,HighClapHandle,TRUE);
	...
	/* close the sound channel */
	if (SndDisposeChannel(SoundChannel, TRUE) != noErr)
		SysBeep(20);
	...
} 

If anybody wants to use this code,  it works fine if you take out the channel
stuff and just pass NIL instead of SoundChannel for the first parameter of
the SndPlay calls (assuming you don't mind that delay).

Thanks in advance for any help with the problem I'm having now, everybody.

Alan McNeely
bigb.columbia.ncr.com!mcneely