[comp.sys.mac.programmer] HELP - Asynchronous Sound Manager Calls

iand@mullian.ee.mu.OZ.AU (Ian Robert DOBSON) (02/18/91)

I am writing a program which must be able to play sounds asynchronously
when in both the foreground and background (it's a BBS system - I need
to alert the system operator when a remote user wants to chat)

I have tried using the Sound Manager as follows:

1. Allocated a sound channel
2. Issued a SndPlay call with a TRUE for the 'async' parameter
3. Added a completion callBack routine into the queue.  The callback
   routine sets a global flag saying the sound is finished playing.
4. Go through the main event loop until the sound is finished.
5. Deallocate the sound channel

Trouble is, when the sound is playing and a context switch occurs (eg.
I click on a window from another application) or when After Dark
switches in, the system bombs.

I have seen other applications doing what I want (eg. QuickGIF) so I know
it's possible to do.  Can anybody tell me what is going wrong?


Please send e-mail

Ian R. Dobson
University of Melbourne
iand@mullian.ee.mu.OZ.AU

trotter@ENUXHA.EAS.ASU.EDU (Russell T. Trotter) (02/18/91)

I have heard that one should dispose of the channel immediately after
playing the sound (SndPlay call), everything else looks OK!

You may find some help in the Usenet Mac programmers guide, it has
some sample code and stuff specifically for doing async sound. 
Also I recommend getting the latest docs on the Sound manager.
These are availiable from apple.com.  They say that these docs
replace the incorrect and outdated Sound Manager stuff in IM V.
Hope that helps.  

One more thing about your code .  Make sure your callback routine is
doing the "right " thing with A5 and all.

rmh@apple.com (Rick Holzgrafe) (02/19/91)

In article <9102180558.AA13374@enuxha.eas.asu.edu> 
trotter@ENUXHA.EAS.ASU.EDU (Russell T. Trotter) writes:
>  Make sure your callback routine is
> doing the "right " thing with A5 and all.

Russell's right - let me explain a bit. Your program (all Mac programs) 
access their code and global variables via offsets from the value of 
register A5. The Mac sets up A5 for you just before your program begins, 
and MultiFinder makes sure it's always correct when you're running in the 
foreground, or when you're given time to run in the background.

But when other apps are running, A5 is set for *their* code and data. And 
the catch is that async completion routines happen below MultiFinder's 
level - so A5 is not guaranteed correct when these routines run.

A simple solution for you, since your routine needs to access only one 
variable, is to declare a record that contains (first) the sound 
managerparameter block, followed by a pointer to your "soundIsDone" 
variable. Initialize that pointer before calling SoundPlay. The sound 
manager won't mind the extra baggage on the parameter block; it will just 
look at what it needs and ignore the rest. When your completion routine is 
called, retrieve the pointer and use it to set the variable; this avoids 
any use of A5.

It's also possible to pass the value of A5 itself, set it, and then access 
your code and globals as usual. When you're done, you *must* restore the 
former A5 before exiting.

Hope this helps.

==========================================================================
Rick Holzgrafe              |    {sun,voder,nsc,mtxinu,dual}!apple!rmh
Software Engineer           | AppleLink HOLZGRAFE1          rmh@apple.com
Apple Computer, Inc.        |  "All opinions expressed are mine, and do
20525 Mariani Ave. MS: 3-PK |    not necessarily represent those of my
Cupertino, CA 95014         |        employer, Apple Computer Inc."