[comp.sys.mac.programmer] Synchronous sounds using the Sound Manager

wras@walt.cc.utexas.edu (Steve Mariotti) (06/05/90)

Hi.

Has anyone had experience using the Sound Manager to play a 'snd ' resource
synchronously (simultaneous with other processing)?  I've been wracking my
poor brain trying to do it every way possible with only spotty success.
What I've been doing is opening my own SndChannel and using SndPlay to play
previously loaded 'snd ' resources with it's async field set to FALSE.
I've had every conceivable hang/crash/crater at various places.  Let me be
more specific.

The way I understand it, you do:

err = SndNewChannel(myChanPtr, sampledSynth, initMono, NULL);
if (!err) {
    err = SndPlay(myChanPtr, soundHandle1, FALSE);
    err = SndPlay(myChanPtr, soundHandle2, FALSE);
}

and they play without pop/click etc.  I considered also using SndDoCommand() to
send it noteCommand's and soundCmd's when I want to change the sound it plays.

I'm doing this in THINK C on a Mac SE with 4 megs of memory (if it matters), so
I don't have the Apple Sound chip.

I had a partial success with synchronous sound, but I can't duplicate it now.

Thanks in advance for any suggestions.

Steve


 ______  _____________________________________________________________________
| ____ |   Steve Mariotti -- University of Texas at Austin -- CS Undergrad(e) |
||    || ---------------------------------------------------------------------|
||    || wras@ccwf.cc.utexas.edu | csar242@ix1.cc.utexas.edu | AOL:SteveM16   |
| ---- | ---------------------------------------------------------------------|
|.  -- |          "Wouldn't be prudent, not at this juncture."                |
|______| ---------------------------------------------------------------------'
|______|          function introspanish(time : longint) : pain;

mwilkins@jarthur.Claremont.EDU (Mark Wilkins) (06/05/90)

In article <30976@ut-emx.UUCP> wras@walt.cc.utexas.edu (Steve Mariotti) writes:
>Has anyone had experience using the Sound Manager to play a 'snd ' resource
>synchronously (simultaneous with other processing)?

  Well, one of your problems might be that playing a sound ASYNCHRONOUSLY
means simultaneously with other processing.  SYNCHRONOUSLY playing a sound
means that you put everything on hold while the sound is being played.
Therefore, you should set the asynch parameter to TRUE.

  I don't know what other assumptions your program makes, but this may cause
some of your problems.

-- Mark Wilkins
-- 
  "According  to  our  contract, at  precisely  midnight  of  the  night 
  of her greatest triumph,  the party of the first  part,  (that's you), 
  agrees to render up  her soul,  now and  forevermore,  to the party of 
  the second part.  (That's me).  Shall we go?"                          

lsr@Apple.COM (Larry Rosenstein) (06/06/90)

In article <30976@ut-emx.UUCP> wras@walt.cc.utexas.edu (Steve Mariotti) 
writes:
> err = SndNewChannel(myChanPtr, sampledSynth, initMono, NULL);
> if (!err) {
>     err = SndPlay(myChanPtr, soundHandle1, FALSE);
>     err = SndPlay(myChanPtr, soundHandle2, FALSE);
> }

First, to play a sound while your programs continue, you need to pass TRUE 
for the last parameter.  This specifies asynchronous playing, which is 
what you want.

Also, you can't (in general) play 2 snd resources with the same channel.  
When you play a resource, the synthesizer required by the resource is 
linked to the channel.  If you link a syntehsizer more than once, you will 
(at best) not get any sound, and will probably crash.

For this reason, it is best to dispose of a channel after the sound is 
finished playing.  To do this pass a call back routine when you create the 
channel, and send a callBack command after the SndPlay.

For the same reason, you should pass 0 instead of sampledSynth when 
creating the channel, in case the resource you play wants to use a 
different synthesizer.  

If you know the structure of the resources you are going to play (ie, they 
have no synthesizer information) then you can play several sounds on the 
same channel.  Or you can parse the sound resource to extract the actual 
samples and play them.

All this information comes from the revised Sound Manager documentation, 
which I think is available on Apple.COM (in /pub/dts/mac/docs).  I've also 
got sample MPW Pascal code which implements an asynchronous SndPlay call.


Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

cak3g@astsun9.astro.Virginia.EDU (Colin Klipsch) (06/06/90)

In article <8548@goofy.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes:
>In article <30976@ut-emx.UUCP> wras@walt.cc.utexas.edu (Steve Mariotti) 
>writes:
>> err = SndNewChannel(myChanPtr, sampledSynth, initMono, NULL);
>> if (!err) {
>>     err = SndPlay(myChanPtr, soundHandle1, FALSE);
>>     err = SndPlay(myChanPtr, soundHandle2, FALSE);
>> }

A minor point that I missed on first reading of the Sound Manager
chapter: the first parameter is a VARIABLE sound channel pointer; i.e.
the calling definition of SndNewChannel goes like:

	function SndNewChannel (VAR: chanPtr; ...)

In assembly language this requires extra care.  You must be sure that you:
a) set your chanPtr to NULL or to the pointer of your own created
pointer-block (using _NewPtr, size 1060 bytes); b) pass the ADDRESS of your
chanPtr to _SndNewChannel, NOT the pointer itself.

So it goes like this. . .  (with the appropriate push/pop macros)

	clr.l	myChanPtr(A5)	;if you're lazy; otherwise make your own
	push.w	#0		;space for the function result
	pea	myChanPtr(A5)	;NOT push.l myChanPtr(A5)!
	push.w	#0		;let SndPlay link a synthesizer typically
	push.l	#0		;(is this a longint? my docs aren't handy)
	pea	MyCallBack	;you definitely want this if you're going
				; to be playing asynchronously
	_SndNewChannel
	pop.w	D0		;error, if any
	...			;and on and on

MyCallBack	; This routine will execute in response to a callBack
		; command, which you pass to your channel with _SndDoCommand 
		; after you're finished with the channel.  This routine
		; should set a flag somewhere indicating the channel
		; is to be killed with _SndDisposeChannel as soon as is
		; convenient, but this routine should NOT do the disposing
		; itself, since it is not allowed to use the Memory Manager.

I realize the original poster was using Pascal, not assembly language, but
I hope this can help anyway.

>Also, you can't (in general) play 2 snd resources with the same channel.  
>When you play a resource, the synthesizer required by the resource is 
>linked to the channel.  If you link a syntehsizer more than once, you will 
>(at best) not get any sound, and will probably crash.

Precisely, although I have never understood why the Sound Manager works
in this way.  Why can't SndPlay check to see if a particular
synthesizer has already been linked to this channel, and if so, don't try
relinking?  SndPlay could be much more robust, it seems to me, but
then again I wouldn't want to have to write it. . .

----------------------------------------------------------------------
"May the forces of evil become confused on the way to your house."
                                                      -- George Carlin
Bemusedly,                   | DISCLAIMER:
  Colin Klipsch              |   This text is actually a horrendously
  UVa Astronomy Department   |   garbled excerpt from _Mating_Rituals_
  Charlottesville, Virginia  |   of_West_African_Ostriches_, Vol IV,
  cak3g@virginia.edu         |   by Davis & Griffin, 1913, p. 137
____________________________/ \_______________________________________

wras@walt.cc.utexas.edu (Steve Mariotti) (06/06/90)

In article <7401@jarthur.Claremont.EDU> mwilkins@jarthur.Claremont.EDU (Mark Wilkins) writes:
>In article <30976@ut-emx.UUCP> wras@walt.cc.utexas.edu (Steve Mariotti) writes:
>>Has anyone had experience using the Sound Manager to play a 'snd ' resource
>>synchronously (simultaneous with other processing)?

>  Well, one of your problems might be that playing a sound ASYNCHRONOUSLY
>means simultaneously with other processing.  SYNCHRONOUSLY playing a sound
>means that you put everything on hold while the sound is being played.
>Therefore, you should set the asynch parameter to TRUE.

This seems to be the consensus, but doesn't the very definition of
'synchronous' imply concurrence?  Asynchronous should mean 'not simultaneous'.
Is this Apple's way of confusing us even further?

>  I don't know what other assumptions your program makes, but this may cause
>some of your problems.

My program assumed that Inside Mac V was correct, and now it doesn't since I've
been happily pointed to apple.com for the update to that travesty of a chapter.

Thanks to all who've responded.

Steve
 ______  _____________________________________________________________________
| ____ |   Steve Mariotti -- University of Texas at Austin -- CS Undergrad(e) |
||    || ---------------------------------------------------------------------|
||    || wras@ccwf.cc.utexas.edu | csar242@ix1.cc.utexas.edu | AOL:SteveM16   |
| ---- | ---------------------------------------------------------------------|
|.  -- |          "Wouldn't be prudent, not at this juncture."                |
|______| ---------------------------------------------------------------------'
|______|          function introspanish(time : longint) : pain;

minich@d.cs.okstate.edu (Robert Minich) (06/06/90)

> This seems to be the consensus, but doesn't the very definition of
> 'synchronous' imply concurrence?  Asynchronous should mean 'not simultaneous'.
> Is this Apple's way of confusing us even further?

  Synchronous means everything happens in a predictable, organized
manner. If something is asynch, you don't know what will happen when. 
When you call a routine asynchronously, you don't know when it will finish. 
That is, the routine you call and your program aren't synchronized. (Thus
the use of completion routines and status variables.) 

Hope this helps
-- 
| _    /| | Robert Minich             |
| \'o.O'  | Oklahoma State University |  
| =(___)= | minich@d.cs.okstate.edu   | 
|    U    | - Bill sez "Ackphtth"     |

amanda@mermaid.intercon.com (Amanda Walker) (06/06/90)

In article <31011@ut-emx.UUCP>, wras@walt.cc.utexas.edu (Steve Mariotti)
writes:
> This seems to be the consensus, but doesn't the very definition of
> 'synchronous' imply concurrence?  Asynchronous should mean 'not simultaneous'.
> Is this Apple's way of confusing us even further?

No, it's Apple's way of using a term the same way the rest of the industry
does.  A synchronous operation is one where continued execution is
synchronized to the completion of the operation.  An asynchronous operation
is one which is performed independently of continued execution, and is
completed at a (usually indefinite) later point in time.

--
Amanda Walker, InterCon Systems Corporation
--
"If we don't succeed, then we run the risk of failure."  -- Dan Quayle