[comp.sys.mac.programmer] Need help with the new sound manager!

stevem@hpvcfs1.HP.COM (Steve Miller) (03/11/90)

OK boys and girls, I'm about at my wits end on the subject of playing 'snd '
resources on the Mac.  I'm trying to use snd's in a simple game where the
sounds are played asynchronously while arcade style animation is occuring.
I'm using Think Pascal 2.01 under system 6.02 (finder 6.1) and my code is
structured like this:

my_sound_hdl := GetResource('snd ',4);  {This is a 1 second digitized sound}
channel_ptr := SndChannelPtr(NewPtr(sizeof(SndChannel)));
error := SndNewChannel(channel_ptr,5,0,nil);

... later, whenever a sound is played, it is done in the following manner ...

command.cmd := flushCmd;  {Flush any currently playing sound in channel_ptr}
command.param1 := 0;
command.param2 := 0;
error := SndDoCommand(channel_ptr,command,FALSE);
error := SndPlay(channel_ptr,my_sound_hdl,TRUE);


What happens is that the sounds start out playing fine.  After the first 3 to 6
instances of the sound, it will stop playing them.  Occasionally they will
start up again for 1 or 2 instances before permanently failing to play.

Then the system will crash with an address error or with an
"internal error 4023" inside SndDisposeChannel at the end of the game:

error := SndDisposeChannel(channel_ptr,TRUE);


If the sounds are played sychronously then everything is OK.  I've tried many
variations on the above scheme with exactly the same results (not flushing
the commands, letting the system allocate the channel pointer, etc...)  Since
I already found one bug in volume 5 of Inside Mac pertaining to the new
sound manager's use of Async. sound, I feel there might be something else I'm
missing.

HELP HELP HELP!!  Does anyone have experience using Asynch sounds under the
new sound manager?

BTW, I've had no problems using async sounds under the old sound manager, but
I need the new sound manager to use 'snd ' resources.

Steven Miller   ...hplabs!hpvcfs1!stevem
Vancouver Division
Hewlett Packard

asl2@tank.uchicago.edu (Aaron "Fish" Lav) (03/11/90)

There's new documentation on the Sound Manager from Apple.  The old docs
are error-ridden and generally bad.  It's available by anonymous
ftp from apple.com, in /pub/dts/mac/doc (or something close).  If you
don't have ftp access, send me some email and I'll send you a copy if 
you want.
                                       Aaron <><|
asl2@tank.uchicago.edu

billkatt@mondo.engin.umich.edu (billkatt) (03/12/90)

In article <900004@hpvcfs1.HP.COM> stevem@hpvcfs1.HP.COM (Steve Miller) writes:
>
>OK boys and girls, I'm about at my wits end on the subject of playing 'snd '
>resources on the Mac.  I'm trying to use snd's in a simple game where the
>sounds are played asynchronously while arcade style animation is occuring.
>I'm using Think Pascal 2.01 under system 6.02 (finder 6.1) and my code is
>structured like this:
>
[sorry, code deleted]
>
>What happens is that the sounds start out playing fine.  After the first 3 to 6
>instances of the sound, it will stop playing them.  Occasionally they will
>start up again for 1 or 2 instances before permanently failing to play.
>
>Then the system will crash with an address error or with an
>"internal error 4023" inside SndDisposeChannel at the end of the game:
>
>error := SndDisposeChannel(channel_ptr,TRUE);
>
>
>If the sounds are played sychronously then everything is OK.  I've tried many
>variations on the above scheme with exactly the same results (not flushing
>the commands, letting the system allocate the channel pointer, etc...)  Since
>I already found one bug in volume 5 of Inside Mac pertaining to the new
>sound manager's use of Async. sound, I feel there might be something else I'm
>missing.
>
Well, digitized sounds are [type 1, type 2 insert correct one here] sounds,
and they not only have a "BufferCmd" in their structure to play the sound, but
they also have a c ommand to add the sampled sounds synthesizer to the channel
so it can play it.  Each time you do a SndPlay it installs another copy of
the sampled sound synthesizer in the channel.

there are three ways to fix this:

1. dispose the channel and allocate another one before you play the sound.
2. remove the synthesizer from the SND resource and install one yourself (once)
3. Use a "SndDoCommand" with a BufferCmd to play just the sampled sound but not
   execute the synthesizer install.

-Steve

stoms@castor.ncgia.ucsb.edu (David Stoms) (03/12/90)

In article <900004@hpvcfs1.HP.COM> stevem@hpvcfs1.HP.COM (Steve Miller) writes:
>OK boys and girls, I'm about at my wits end on the subject of playing 'snd '
>resources on the Mac.  I'm trying to use snd's in a simple game where the
>sounds are played asynchronously while arcade style animation is occuring.

I found this in one of my text directories (I can't verify that this
is right)----

In article <1354@ndmath.UUCP> milo@ndmath.UUCP (Greg Corson) writes:
>
>Would anyone happen to have a code fragment that illustrates how to setup
>the required callback routines so you can have SoundPlay play a sound in the
>background (async) mode?
>
>1. open the channel and specify a callback
>2. play a snd resource
>3. have the callback set a global flag
>4. have my main event loop close the channel when the flag is set.
 
This is the code I am using.  There is NO guarantee or warranty with this
code.  Use at your own risk!  This is NOT Apple DTS sanctioned code.
 
1. the main application needs to keep a global variable is a SndChannelPtr.
Initialize it to NIL.
 
2. Pass in the handle to the snd  resource that you want to play.
 
This should bootstrap to you greater understanding of the world of the 
Sound Manager.
 
PROCEDURE PlayIt(VAR chan: SndChannelPtr; theSound: Handle);
VAR
    err: OSErr;
    myWish: SndCommand;
 
BEGIN
    IF chan <> NIL THEN   {cancel sound in progress}
    BEGIN
        err := SndDisposeChannel(chan, TRUE);  {TRUE means now}
        IF err <> noErr THEN
        BEGIN
            DebugStr('Cannot dispose of old channel');
            Exit(PlayIt);
        END
        ELSE
            chan := NIL;
    END;
   
    err := SndNewChannel(chan, 0, 0, NIL);
    IF err <> noErr THEN
    BEGIN
        DebugStr('Cannot allocate new channel');
        Exit(PlayIt);
    END;
     
    IF theSound <> NIL THEN {we have a handle}
        IF theSound^ <> NIL THEN {and is not a nil handle }
        BEGIN
            err:=SndPlay(chan, theSound, TRUE);     
            IF err <> noErr THEN
            BEGIN
                DebugStr('Cannot play sound');
                Exit(PlayIt);
            END;
 
            WITH myWish DO   { set up a sound mgr command block }
            BEGIN
               cmd := freeCmd;  {to free self when done }
               param1 := 0;
               param2 := 0;
            END; {with}
 
            err := SndDoCommand(chan, myWish, FALSE);
  
            IF err <> noErr THEN
            BEGIN
                DebugStr('cannot add command');
                Exit(PlayIt);
            END;
        END;
END;