rcook@eagle.wesleyan.edu (04/30/91)
Inside Mac and the tech notes say that you should only hold on to a channel while it is making a sound. This seems reasonable; you just put a callback in that sets a flag to delete the channel at the next available opportunity. Nevertheless, I have some questions about this method. (I am only concerned with sampled sounds, though that really shouldn't matter, should it?) 1) What happens if you are playing a long sound and your program decides to call sysBeep? Since before 6.0.7 you can only have one channel open, does your channel get trashed? If it does get trashed, what happens when your callback comes along and tries to dispose of your channel? 2) Suppose you are clever and somehow make sure that your program newver calls SysBeep when it has a channel going. What if some sort of background task uses the all powerful Notification Manager to flash the apple menu and make a sound while one of yours is playing? 3) What if you are writing a game where you need to play a sound after just about every keystroke, and even in between keystrokes, so that you need to play a new sound before the last one is finished? Do you use SndDoImmediate commands, SndDoCommand, or just SndPlay? Could you possibly have more than one callbackCmd in the queue at the same time? I looked at the Sound Manager source code example on Apple.com and it uses SndPlay (and works a hell of a lot better than my attempt :-), though once it did manage to go silent for a few seconds, but then sprang back to life, with no problems since. This source code I mention is very well commented and quite valuable to the Mac programming community, but when you play a new sampled sound when an old one is still playing, the old one stops and the new one starts immediately. In my case, this is what I wanted, but what if you wanted the first one to finish before starting the second? Do you have to remove the call back command that is (I assume) sitting in the queue before you put a new buffer command in the queue followed by a new call back command? Will IM-VI explain all this accurately, unambiguously, and clearly? I don't think these are easy questions to answer. I hope someone out there can. If you want, I'll post back the most informative of the e-mail I receive on the subject. Thanks. rc ------------------------ Randall Cook rcook@eagle.wesleyan.edu ------------------------
REEKES@applelink.apple.com (Jim Reekes) (05/01/91)
In article <1991Apr29.163227.42312@eagle.wesleyan.edu>, rcook@eagle.wesleyan.edu writes: > What happens if you are playing a long sound and your program > decides to call sysBeep? Since before 6.0.7 you can only have one > channel open, does your channel get trashed? Sometimes, but it depends on the machine and the System version your running. That's why I recommended (I wrote the replacement chapter for Inside Mac) to dispose of your channel ASAP. If you refer to my sample code "SoundApp" you'll see that I even avoid the Dialog Manager calling SysBeep by replacing the ErrorSound routine to only flash the menubar. > If it does get trashed, what happens when your callback comes along > and tries to dispose of your channel? If it does get trashed, you often crash the system. If your callBack comes along at all, you might crash when you call SndDisposeChannel. > What if some sort of background task uses the all powerful > Notification Manager to flash the apple menu and make a sound while > one of yours is playing? While your application is the foreground app, you can avoid the Dialog Manager calling SysBeep by using ErrorSound as I just described. If you wanted to, you could even patch SysBeep. But, this will only prevent beeps from happening while your application is in the foreground, which is exactly why I recommend to dispose of channels while switching into the background. I haven't seen any apps calling SysBeep from the background. Although, it is possible to play your own sound using the Notification Mgr. I think QuickMail does this. That might be a problem. > What if you are writing a game where you need to play a sound after > just about every keystroke, and even in between keystrokes, so that > you need to play a new sound before the last one is finished? You can stop the current sound by calling flushCmd and quietCmd using SndDoImmediate. Then use the bufferCmd with SndDoCommand to queue up the next sound. Don't use SndPlay because of it limitations as noted in Inside Mac's replacement chapter (you can generally only use it once on a channel). > Could you possibly have more than one callbackCmd in the queue at > the same time? You can any number of callBackCmds in a channel. They are just markers that will call your CallBackProc when they become the current command. In order to tell which callBackCmd is happening, you can use the command's param1 and param2 fields to contain any value you want. You can use the callBackCmd to impliment a double buffer technique which works great. Other callBackCmds can be used to signal when you're all done with the sound and then dispose of the channel. > I looked at the Sound Manager source code example on Apple.com and > it uses SndPlay (and works a hell of a lot better than my attempt > :-), though once it did manage to go silent for a few seconds, but > then sprang back to life, with no problems since. This source code > I mention is very well commented and quite valuable to the Mac > programming community, Thanks, I wrote SoundApp. It is much more than _just_ a Sound Manager example. It shows how to write good Macintosh code, and is full of useful tips. I'm also very big on commenting and using a style that is readable. > but when you play a new sampled sound when an old one is still > playing, the old one stops and the new one starts immediately. In > my case, this is what I wanted, but what if you wanted the first > one to finish before starting the second? Do you have to remove > the call back command that is (I assume) sitting in the queue > before you put a new buffer command in the queue followed by a new > call back command? Will IM-VI explain all this accurately, > unambiguously, and clearly? As for the silence, it might be that I am doing some house cleaning of the old sound and channel, then started up a new sound and channel. That can be avoided if you want to special case it. If you're going to start a new sound while a channel is already open, then just send the flushCmd and quietCmd, then start the new sound. If you want the new sound to play *after* the current sound has completed, then don't send the flushCmd and quietCmd. Just queue the new sound using SndDoCommand and a bufferCmd. As for an existing callBackCmd waiting in the queue, that could be avoided by keeping a global count of the callBacks that suppose to be processed. For example, decrement this count every time in the CallBackProc. Once the count goes to zero, dispose of the channel. So, if you have one sound and callBackCmd already queued and want to add another sound with a callBackCmd, just increment the global count when you send the new bufferCmd. If you flush the channel, then set the count to zero. > Will IM-VI explain all this accurately, unambiguously, and clearly? Well, the new Sound Mgr chapter of IM-VI is a great chapter. It is accurate, and hopefully not ambiguous. You should note that it is talking about the Sound Manager of System 7. As for the Sound Mgr of System 6.0.x, you should continue to refer to my replacement version of the chapter for the limitations and bugs. System 6.0.7 is unique. It is basically what Inside Mac VI is documenting, but has a couple limitations and bugs. I'm trying to put a Tech Note together about all the Sound Manager issues. Bugs are not the sort of thing that should be documented in Inside Mac, unless IM could be updated with every System release. As for design, the best solution is sample code. Inside Mac might be able to provide tips and suggestions, but I feel this is beyond the scope of what IM is trying to accomplish. Jim Reekes E.O., Macintosh Toolbox Engineering (working on the Sound Manager)