TweetFollow Us on Twitter

Playing sound
Volume Number:7
Issue Number:1
Column Tag:XCMD Corner

Playing With Sound

By Donald Koscheka, Contributing Editor

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

The Importance of XCMDs

One of the questions that is raised by Hypercard 2.0’s new XCMD interface is, “How important are XCMDs to the vitality of the Macintosh?”. One cannot imagine that XCMDs would be very important at all so it would be useful to the xcmd programmer to ponder the future of xcmds in the Macintosh programming world.

After studying Hypercard 2.0 in great detail, I’ve concluded that XCMDs are very important to the success of this product and that Apple Computer, Inc. is acknowledging this by providing more services to the XCMD programmer such as windoids and script manipulation capability. But another event in the small computer world lends even more credence to XCMD as programming art. That event is quietly taking over the MS-DOS world as Microsoft successfully evangelizes the concept of Dynamic Link Libraries, or DLLs.

If you’re not a PC programmer (and who can afford not to be), then you may not know that DLLs are code modules that are written in such a way as to be loadable and thus callable at any time. DLLs are code segments that have a standard programming interface associated with them. In effect, DLLs allow you to build re-usable code modules that in theory can be used in any application. Well, if every application had such an interface on the Mac, let’s call it XCmdPtr, then xcmds would serve the same purpose -- the ability to call xcmds from any program that runs on the mac. Without a lot of induction, one can come to the conclusion that if xcmds can give you this type of capability on the Mac, then they are indeed important, at least at the conceptual level.

If xcmds become callable from any application then they become an integral part of the future of the Macintosh. It is not unimaginable to believe that someday you will flesh-out your application with some sort of screen generator and then build a set of xcmds to implement the application-specific code. I find it impossible to believe that this effective approach to programming won’t become the norm for all programmers in the future. In fact, Michael Swain suggests exactly this approach for PC programmers using ToolBook ( “Dr. Dobbs Journal”, November, 1990). When I read this column, my eyes popped out of my head. Mr. Swain’s concept of marrying rapid prototyping with rapid code development via DLL’s is exactly what we’ve been doing with Hypercard for the last three years. Any Windows developer that takes his advice will wonder what all the fuss was about; Windows will appear to be an easy and natural development environment.

So now I can rest easy. I am convinced that the XCMD approach to programming will prevail over time. It’s working for me. By forcing me to avoid globals and to think modularly, XCMDs have allowed me to write code that is re-usable in a wide-variety of applications. Each time I write an XCMD, I create a piece of code that I not only know I will use again but that I can comfortably extract from Hypercard without worrying about breaking it. That is the programmer’s holy grail and that is why XCMDs not only have a future, they are the future.

Playsound

Several months ago, I got a call from Bill Leitman, a fellow Mac developer in the New York area. He was working with a small film company in Brooklyn that needed an xcmd that played a portion of a sound resource. Bill’s approach was quite reasonable, he took a piece of code that he knew to be working from another application and dropped it into an xcmd. Lo and behold, it didn’t work. He called me in desperation to see if there was anything that I knew about xcmds that was causing his problem. To no avail, I also tried to get the sound manager to work from within an xcmd but after hours of head scratching and staring at TMON windows, I came to the conclusion that Hypercard just wasn’t going to let me use the sound manager.

This was unfortunate and unbelievable, but I’ve never been able to find a way to get the sampled synth playing in an xcmd. Imagine my surprise when I first encountered the following callbacks in Hypercard 2.0: BEGINXSOUND and ENDXSOUND. Is it possible that it wasn’t me? Did Hypercard actually work the way I thought it did by taking over the sound driver and not making it available to anyone else. I don’t know the answer to this question, ‘tho I’d like to so please write if you have some input. I do know that this must have been a problem since Apple went to the motions of adding these callbacks, which work quite perfectly for me.

This month’s playsound xcmd (listing 1) was inspired by Mr. Leitman and I am grateful to him that he gave me an excuse to explore the sound manager. It’s more daunting than the Sunday Times crossword puzzle and just as much fun!

Playsound takes up to four parameters: the first is the name of the file to retrieve the sound resource from. The second parameter is the name of the sound resource to retrieve. The third parameter is the index to the sample to start playing from (0 means play from the beginning of the sound). The fourth parameter is the last sample to play to. These last two parameters are optional, if they are left out, the entire sound resource will be played.

For simplicity, this code makes two assumptions that you can modify to meet your own needs: (1) you want to play the sound using the sampled synthesizer and (2) the sound is a format 2 ‘snd ‘ resource. I chose not to support format 1 ‘snd ‘ resources because Inside Macintosh indicates that format 2 snd resources should be adopted by developers as a standard. Should you decide that you want to support format 1 resources, refer to page 491 of Inside Macintosh Volume V for details on that format.

The xcmd parses out the parameters, opens the appropriate resource file and loads the ‘snd ‘ resource which it then detaches from the resource map. This is important because we are going to modify the resource and we don’t want the changes to be written back out by mistake. We call BEGINXSOUND to advise hypercard that we want to take over the sound drive for a while. Next we call PlayRunSound to play the sound, or sound fragment, and then we call ENDXSOUND to give the sound driver back to Hypercard.

PlayRunSound() is the heart and soul of this xcmd. The first thing that it does is check to see if the appropriate synthesizer is available. If so, it then allocates a new channel via the SndNewChannel call. This call returns a pointer to our new channel, initialized for the sampled synthesizer in theChan. We will pass this pointer to SndDoCommand to play this sound on that channel.

Once the channel is initialized and we know that we can use it, we set the start and stop time of the sound and play it. The first thing we need to do is check to see if we have the correct resource format which we do by testing to make sure that the first word in the resource (sndHdl) is set to 2. If it is, then we can access the fields in the snd resource by referring to the documentation on page 494 of IM vol V.

Figure 1. A typical format 2 ‘snd ‘ resource.

Here is how the sound fragment scheme works: The snd resource contains some header information (6 bytes) followed by a number of 8 byte sound commands (the sample sound resource in figure 1 contains only one sound command). The sound data immediately follows the sound commands. If there is only one sound command, then the sampled data table will begin at offset 14 (0x0E) in the record.

The first two long words in the sound data table tell us where the samples start and how many of them there are. The where is usually set to 0 and the how much is usually set to the number of samples to play back. We can modify these fields to change the starting point and the number of samples to play. Or, we can set just the new starting point and play back to the end of the sound. Playsound doesn’t use the sound command (in this case, ‘soundCmd’) but rather uses the ‘bufferCmd’ instead.

So, we modify the sound table by stuffing new values for the pointer and length and then call the sound manager via the bufferCmd. Once the sound is done playing, we call SndDisposeChannel to remove our allocated channel, in effect freeing up the sampled synthesizer in preparing to give it back to Hypercard. That’s all there is to it. You might want to use this xcmd to continue to explore the sound manager. It appears to have rich and intriguing repertoire. In fact, I hope to present more on the sound manager in the future. In the meantime, I will continue to illuminate Hypercard 2.0. Happy Hacking.

Listing 1:  PlaySndFrag.c
/********************************/
/* File: PlaySndFrag.c    */
/********************************/
#define UsingHypercard

#include  <SoundMgr.h>
#include<SetupA4.h>
#include  <HyperXCmd.h>
/* usage: playSndFrag fileName, soundName, start ,stop
 project requires the following files or libraries:
 ANSI-A4-- the A4 based standard “C” libraries
 HyperXLib-- the xcmd callback glue
 MacTraps -- what it is
 PlaySnd.c-- this file */
 
void    putResult( XCmdPtr pp, char *msg);
void  PlayRunSound( Handle sndHdl, long start, long stop );
long  paramtoNum( XCmdPtr pp, short i );
void  paramtoPString( XCmdPtr pp, short i, char *str );
Handle  strToParam( char  *str );

#ifndef NIL
 #defineNIL (void *)0L
#endif

pascal void main( XCmdPtr pp )
/******************************************
* The main entry point 
******************************************/
{
 short resFile;  /*** resource file holding ‘snd ‘ ***/
 short saveResFile; /*** previous resource file id ***/
 Handle sndHdl; /*** handle to the sound resource ***/
 long start; /*** start sample in sound ***/
 long stop; /*** end sample in sound ***/
 char  *temp[256]; 
 /*** for converting to pascal strings ***/
   
 pp->returnValue = NIL;  /* empty return means OK */
 if (pp->paramCount == 1){
 if ( **(pp->params[0]) == ‘!’ ){
 pp->returnValue = strToParam(“Play Sound XCMD, version 1.0, ©Donald 
Koscheka, 1990”);
 return;
 }
 
 if ( **(pp->params[0]) == ‘?’ ){
 pp->returnValue = strToParam(“PlaySound FILE, ‘snd ‘ rsrc id [,start][,stop]”);
 return;
 }
 }

 paramtoPString( pp, 0, (char *)&temp );           
 start  = paramtoNum( pp, 2 );
 stop   = paramtoNum( pp, 3 );
  
 saveResFile = CurResFile(); /* save current res file id */
 resFile = OpenResFile( temp );
  
 if (resFile == -1) {
 putResult( pp, “can’t open resource file” );
 return;
 }
 
 UseResFile( resFile );  /* in case it was already open */
 paramtoPString( pp, 1, (char *)&temp );
 sndHdl = Get1NamedResource( ‘snd ‘, &temp );
 /* getting the resource ok */
 
 if(!sndHdl){
   putResult( pp, “no such snd” );
 UseResFile( saveResFile ); 
   return;
 }
 
   BEGINXSOUND( pp, NIL );
 DetachResource( sndHdl );
    PlayRunSound( sndHdl, start, stop );
 DisposHandle( sndHdl );
    ENDXSOUND( pp );
    
 UseResFile( saveResFile ); 
}
 
void  PlayRunSound( sndHdl, start, stop )
 Handle sndHdl;
 long   start;
 long stop;
/**********************************
* st[0] determines whether we have a
* format 2 or a format 1 ‘snd ‘ resource.    
* currently use the 44K sampler. Refer to Inside Macintosh Vol V p.494 
for the format of a format 2 ‘snd ‘ resource
**********************************/
{
    short *st;
    long  *lt;
    SndCommand   sndCmd;
   long idx;
 SndChannelPtr theChan  = NIL;
 OSErr    err;
   
 sndCmd.cmd = availableCmd;
 
 if( err = SndControl( sampledSynth, &sndCmd ) ) return;
 if( err = SndNewChannel( &theChan, sampledSynth, initSRate44k, NIL ) 
) return; 
  
 HLock( sndHdl );
   st = (short *)*sndHdl;
 sndCmd.cmd = bufferCmd;
   sndCmd.param1 = 0L;
 if( *st == 2){
 idx  = 6L + ((long)st[2] << 3);
 /* offset to start of commands    */
 lt     = *sndHdl + idx;
   sndCmd.param2 = (long)lt;
   
   if( start )
   lt[0]= (long)*sndHdl + idx + start; 
   
   if( stop )
        lt[1]  = stop  - start;  
        
 err = SndDoCommand( theChan, &sndCmd, FALSE );
   err = SndDisposeChannel( theChan, FALSE );
 }
 HUnlock( sndHdl );
}
 
void putResult( XCmdPtr pp , char *msg )
{
   if (pp->returnValue)   
 DisposHandle(pp->returnValue);  
 
   pp->returnValue = (Handle)NewHandle(1 + strlen(msg) );
   strcpy( *(pp->returnValue), msg);
}
 
Handle  strToParam( char  *str )
/***************************
* Given a pointer to a string, copy that string into a handle
* and return the handle.
* The input and output strings are both null-terminated
***************************/
{
 Handle outH = NIL;
 long len = 0;
 
 len = strlen( str );
 if( len )
 if( outH = NewHandle( len ) )
 BlockMove( str, *outH, len + 1 );
 return( outH );
}

void  paramtoPString( XCmdPtr pp, short i, char *str )
/************************
* Given an index into the parameter list, convert the data
* in the Block into a pstring
*
* This sequence is so common in XCMDs that it makes sense to make it 
a subr. This is a generic routine that you can use in any xcmd.
************************/
{
 if( pp->params[i] ){
 HLock( pp->params[i] );
 ZEROTOPAS( pp, (Ptr)*(pp->params[i]), (StringPtr)str );
 HUnlock( pp->params[i] );
 }
 else
 *str = ‘\0’;
}

long  paramtoNum( XCmdPtr pp, short i )
/************************
* Given a Block to an input argument in the paramBlk
* return an integer representation of the data.
************************/
{
 char   theStr[32];
 
 theStr[0] = ‘\0’;
 if( pp->params[i] ){
 HLock( pp->params[ i ] );
 ZEROTOPAS( pp, (char *)*(pp->params[ i ]), theStr );
 HUnlock( pp->params[ i ] );
 return STRTOLONG( pp, theStr );
 }
 return 0L;
}

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Aether Gazer unveils Chapter 16 of its m...
After a bit of maintenance, Aether Gazer has released Chapter 16 of its main storyline, titled Night Parade of the Beasts. This big update brings a new character, a special outfit, some special limited-time events, and, of course, an engaging... | Read more »
Challenge those pesky wyverns to a dance...
After recently having you do battle against your foes by wildly flailing Hello Kitty and friends at them, GungHo Online has whipped out another surprising collaboration for Puzzle & Dragons. It is now time to beat your opponents by cha-cha... | Read more »
Pack a magnifying glass and practice you...
Somehow it has already been a year since Torchlight: Infinite launched, and XD Games is celebrating by blending in what sounds like a truly fantastic new update. Fans of Cthulhu rejoice, as Whispering Mist brings some horror elements, and tests... | Read more »
Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »
Embark into the frozen tundra of certain...
Chucklefish, developers of hit action-adventure sandbox game Starbound and owner of one of the cutest logos in gaming, has released their roguelike deck-builder Wildfrost. Created alongside developers Gaziter and Deadpan Games, Wildfrost will... | Read more »
MoreFun Studios has announced Season 4,...
Tension has escalated in the ever-volatile world of Arena Breakout, as your old pal Randall Fisher and bosses Fred and Perrero continue to lob insults and explosives at each other, bringing us to a new phase of warfare. Season 4, Into The Fog of... | Read more »

Price Scanner via MacPrices.net

Free iPhone 15 plus Unlimited service for $60...
Boost Infinite, part of MVNO Boost Mobile using AT&T and T-Mobile’s networks, is offering a free 128GB iPhone 15 for $60 per month including their Unlimited service plan (30GB of premium data).... Read more
$300 off any new iPhone with service at Red P...
Red Pocket Mobile has new Apple iPhones on sale for $300 off MSRP when you switch and open up a new line of service. Red Pocket Mobile is a nationwide MVNO using all the major wireless carrier... Read more
Clearance 13-inch M1 MacBook Airs available a...
Apple has clearance 13″ M1 MacBook Airs, Certified Refurbished, available for $759 for 8-Core CPU/7-Core GPU/256GB models and $929 for 8-Core CPU/8-Core GPU/512GB models. Apple’s one-year warranty is... Read more
Updated Apple MacBook Price Trackers
Our Apple award-winning MacBook Price Trackers are continually updated with the latest information on prices, bundles, and availability for 16″ and 14″ MacBook Pros along with 13″ and 15″ MacBook... Read more
Every model of Apple’s 13-inch M3 MacBook Air...
Best Buy has Apple 13″ MacBook Airs with M3 CPUs in stock and on sale today for $100 off MSRP. Prices start at $999. Their prices are the lowest currently available for new 13″ M3 MacBook Airs among... Read more
Sunday Sale: Apple iPad Magic Keyboards for 1...
Walmart has Apple Magic Keyboards for 12.9″ iPad Pros, in Black, on sale for $150 off MSRP on their online store. Sale price for online orders only, in-store price may vary. Order online and choose... Read more
Apple Watch Ultra 2 now available at Apple fo...
Apple has, for the first time, begun offering Certified Refurbished Apple Watch Ultra 2 models in their online store for $679, or $120 off MSRP. Each Watch includes Apple’s standard one-year warranty... Read more
AT&T has the iPhone 14 on sale for only $...
AT&T has the 128GB Apple iPhone 14 available for only $5.99 per month for new and existing customers when you activate unlimited service and use AT&T’s 36 month installment plan. The fine... Read more
Amazon is offering a $100 discount on every M...
Amazon is offering a $100 instant discount on each configuration of Apple’s new 13″ M3 MacBook Air, in Midnight, this weekend. These are the lowest prices currently available for new 13″ M3 MacBook... Read more
You can save $300-$480 on a 14-inch M3 Pro/Ma...
Apple has 14″ M3 Pro and M3 Max MacBook Pros in stock today and available, Certified Refurbished, starting at $1699 and ranging up to $480 off MSRP. Each model features a new outer case, shipping is... Read more

Jobs Board

Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
IT Systems Engineer ( *Apple* Platforms) - S...
IT Systems Engineer ( Apple Platforms) at SpaceX Hawthorne, CA SpaceX was founded under the belief that a future where humanity is out exploring the stars is Read more
*Apple* Systems Administrator - JAMF - Activ...
…**Public Trust/Other Required:** None **Job Family:** Systems Administration **Skills:** Apple Platforms,Computer Servers,Jamf Pro **Experience:** 3 + years of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.