From: danny@utkux1.utk.edu (Danny W. McCampbell)
Subject: Re: Sound Loop in a with a Modal Dialog?
Organization: University of Tennessee
Date: Fri, 4 Sep 1992 12:39:10 GMT

In article <1992Sep3.171925.11716@terminator.cc.umich.edu>, potts@itl.itd.umich.edu (Paul Potts) writes:
> 
> In article <1992Sep3.145524.8874@utkux1.utk.edu> danny@utkux1.utk.edu (Danny W. McCampbell) writes:
> >Hi.  I want to play a sound continuously while a modal dialog is 
> >present on the screen.  I have successfully go the loop to work
> >without the modal dialog statement but the loop is only executed
> >twice when I call modal dialog.  Here is  some sample code:
> >
> >dialogtrue := true;
> >while dialogtrue do
> >begin
> >  FlushSndChannel(mySndChan);
> >  if SoundisStopped(mySndChan) then
> >  begin
> >    PlaytheSound(mySndChan);
> >  end;
> >  ModalDialog(nil, itemHit);			{Call Modal Dialog until the user clicks in the dialog}
> >  if itemHit = 1 then
> >    dialogtrue := false;
> >end;
> >StoptheSound(mySndChan);
> >DisposDialog(AboutDialog);				{Dispose of the Dialog}
> >
> >The sound plays only twice then stops playing.  Any ideas how I can
> >do this successfully?  Thanks in advance.
> 
> This seems somewhat convoluted. Can you post the actual code that you use
> to play the sound, and what your dialog should do? It makes a difference.
> 
> Keep in mind also that your sound will restart after each click on a button
> in the dialog, but while the dialog is on the screen, the sound could 
> stop playing and you would then be left sitting there waiting for something
> to happen (for one of the buttons in the dialog to get activated)
> for it to start up again.
> 
> For a dialog in which any of the buttons numbered other than zero
> should dismiss the dialog, I would do something like:
> 
> - start playing sound
> - itemHit =0;
> - while (!itemHit)
>        ModalDialog (nil, &itemHit);
> - Turn off sound
> 
> The technique for playing the sound might influence how you do this; for
> example, are you playing a long sample that might end while the user is
> deciding what to do with the dialog? If so, you could set it to loop. Are
> you dynamically playing notes such that you need to stuff freqDurationCmds
> into the sound queue? If so, you might want to do this from a filter
> procedure to your dialog. It could look at the sound queue during null
> events and if it is nearly empty, stuff some more notes into it.
> 
> You might consider stuffing a copy of the pointer to the sound channel in
> the dialog, so that your filter procedure could look at it when it runs
> without having to access a global. There are various ways to do this kind
> of thing if you are interested.
>  
> >
What I am doing is simply getting a handle to the sound Channel and playing
the sound.  I check to see if the sound has completed in the loop and if it
has I play it again.  The sound is short and I want it to loop as long as the
dialog is displayed.  The dialog only has one button which dismisses it.  Here
is the sound code.


procedure PlaytheSound (mySndChan: SndChannelPtr);
  const
   kAsync = true;
   soundID = 128;
  var
   err: OSErr;
   mySndHandle: Handle;
 begin
  mySndHandle := GetResource('snd ', soundID);
  if mySndHandle <> nil then
   begin
    err := SndPlay(mySndChan, mySndHandle, kAsync);
    if err <> noErr then
     ExitToShell;
   end;
 end;

 function GetmySndChannel: SndChannelPtr;
  var
   err: OSErr;
   mySndChan: SndChannelPtr;
   myCallBackProcedure: ProcPtr;
 begin
  myCallBackProcedure := nil;
  mySndChan := nil;
  err := SndNewChannel(mySndChan, 5, initStereo, myCallBackProcedure);
  if err <> noErr then
   ExitToShell;
  GetmySndChannel := mySndChan;
 end;

 procedure StoptheSound (mySndChan: SndChannelPtr);
  var
   err: OSErr;
 begin
  err := SndDisposeChannel(mySndChan, true);
  if err <> noErr then
   ExitToShell;
 end;

 function SoundisStopped (chan: SndChannelPtr): boolean;
  var
   myErr: OSErr;
   mySCStatus: SCStatus;
 begin
  SoundisStopped := false;
  myErr := SndChannelStatus(chan, Sizeof(SCStatus), @mySCStatus);
  if myErr = noErr then
   SoundisStopped := mySCStatus.scChannelBusy;
 end;

 procedure FlushSndChannel (chan: SndChannelPtr);
  var
   myErr: OSErr;
   mySndCmd: SndCommand;
 begin
  mySndCmd.cmd := flushCmd;
  mySndCmd.param1 := 0;
  mySndCmd.param2 := 0;
  myErr := SndDoImmediate(chan, mySndCmd);
 end;

dialogtrue := true;
while dialogtrue do
begin
  FlushSndChannel(mySndChan);
  if SoundisStopped(mySndChan) then
  begin
    PlaytheSound(mySndChan);
  end;
  ModalDialog(nil, itemHit);			{Call Modal Dialog until the user clicks in the dialog}
  if itemHit = 1 then
    dialogtrue := false;
end;
StoptheSound(mySndChan);
DisposDialog(AboutDialog);				{Dispose of the Dialog}

thanks

Danny
Xref: sparky comp.sys.mac.programmer:15030 comp.sys.mac.system:11637