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

Coda 2.6 - One-window Web development su...
Coda is a powerful Web editor that puts everything in one place. An editor. Terminal. CSS. Files. With Coda 2, we went beyond expectations. With loads of new, much-requested features, a few surprises... Read more
File Juicer 4.51 - Extract images, video...
File Juicer is a drag-and-drop can opener and data archaeologist. Its specialty is to find and extract images, video, audio, or text from files which are hard to open in other ways. In computer... Read more
PDFpenPro 8.3 - $124.95
PDFpenPro allows users to edit PDF's easily. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Create fillable forms and tables of content... Read more
PDFpen 8.3 - $74.95
PDFpen allows users to easily edit PDF's. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Features... Read more
BetterTouchTool 1.963 - Customize Multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom... Read more
iFFmpeg 6.2.2 - Convert multimedia files...
iFFmpeg is a comprehensive media tool to convert movie, audio and media files between formats. The FFmpeg command line instructions can be very hard to master/understand, so iFFmpeg does all the hard... Read more
ForeverSave 2.1.6 - Universal auto-save...
ForeverSave auto-saves all documents you're working on while simultaneously doing backup versioning in the background. Lost data can be quickly restored at any time. Define your preferred time... Read more
NTFS 14.3.318 - $19.95
This latest version supports the new macOS 10.12 Sierra! NTFS breaks down the barriers between Windows and OS X. Paragon NTFS effectively solves the communication problems between the Mac system and... Read more
BetterTouchTool 1.961 - Customize Multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom... Read more
NTFS 14.3.318 - $19.95
This latest version supports the new macOS 10.12 Sierra! NTFS breaks down the barriers between Windows and OS X. Paragon NTFS effectively solves the communication problems between the Mac system and... Read more

Latest Forum Discussions

See All

Clash of Clans is getting its own animat...
Riding on its unending wave of fame and success, Clash of Clans is getting an animated web series based on its Clash-A-Rama animated shorts.As opposed to the current shorts' 60 second run time, the new and improved Clash-A-Rama will be comprised of... | Read more »
Leaks hint at Pokémon GO and Starbucks C...
Leaked images from a hub for Starbucks employees suggests that a big Pokémon GO event with the coffee giant could begin this very week. The images appeared on Reddit and hint at some exciting new things to come for Niantic's smash hit game. | Read more »
Silent Depth Submarine Simulation (Game...
Silent Depth Submarine Simulation 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: | Read more »
Enneas Saga lets you lead your own demon...
Defend the land of Enneas Continent from the forces of evil in the new fantasy MMORPG from Lyto Mobi: Enneas Saga. Can’t wait? No problem. It’s available to download now on Android devices. | Read more »
Great zombie games in the spirit of Dead...
Dead Rising 4 arrives tomorrow, giving enthusiasts a fresh chance to take selfies with zombies and get up to other ridiculous end-of-the-world shenanigans. To really get into the spirit of things, we've gone and gathered the best zombie games that... | Read more »
Amateur Surgeon 4 Guide: Advanced tips a...
Amateur Surgeon 4 is still tackling the competition at the top of the App Store charts, so if you haven't tried it out yet, you should probably do that right away. If you've been at it for a while, though, perhaps you're ready to start expanding... | Read more »
Amateur Surgeon 4 Guide: Become the worl...
It's time to wield your trusty pizza cutter again, as Amateur Surgeon has returned with a whole fresh set of challenges (and some old, familiar ones, too). Starting anew isn't easy, especially when all you have at your disposal is a lighter, the... | Read more »
Le Parker: Sous Chef Extraordinaire (Ga...
Le Parker: Sous Chef Extraordinaire 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »
Telltale Games really is working on a Gu...
Telltale Games' next episodic adventure is indeed Guardians of the Galaxy. A document tied to the voice actors strike suggested that the project was in the work, but now we have direct confirmation following an announcement at the Game Awards that... | Read more »
Amateur Surgeon returns to iOS and Andro...
Amateur Surgeon and its two sequels disappeared from the App Store some time and it was sad days for all. But now, just in time for the holidays, the Adult Swim favorite makes its joyous return in the shape of Amateur Surgeon 4, a remake with... | Read more »

Price Scanner via MacPrices.net

Back in stock! 13-inch 2.7GHz Retina MacBook...
Apple has Apple Certified Refurbished 2015 13″ 2.7GHz/128GB Retina MacBook Pros (MF839LL/A) available again for $1099 including free shipping. That’s $200 off MSRP, and it’s the lowest price... Read more
Slate Tablet Market Share to Fall Below 75% i...
After two years of decline, the tablet market is showing signs of new life as productivity trumps entertainment, and tablets become cost-effective computing devices for both entertainment and... Read more
Yostand Launches Indigogo campaign for iStand...
China-based startup Yostand (meaning ‘your stand’), has announced the launch of its Indigogo campaign for their newly awaited iStand7. This product is a one of a kind iPhone battery case that offers... Read more
Green App – Budget Forecasting Now Available...
Indianapolis, Indiana based CoopToons has announced the release of Green – Budget Forecasting 1.5, an update to their personal budgeting app developed exclusively for iOS devices. Green aims to be a... Read more
New 2016 13-inch 2.0GHz MacBook Pros in stock...
Overstock.com has the non-Touch Bar 13″ MacBook Pros in stock today for $150 off MSRP. Shipping is free: - 13″ 2.0GHz MacBook Pro Space Gray (MLL42LL/A): $1349.99 $150 off MSRP - 13″ 2.0GHz MacBook... Read more
15-inch 2.6GHz Silver Touch Bar MacBook Pro o...
Adorama has the new 2016 15″ 2.6GHz Silver Touch Bar MacBook Pro (MLW72LL/A) in stock and available for $2349 including free shipping. Adorama charges sales tax in NY & NJ only. Their price is $... Read more
13-inch MacBook Airs on sale for up to $180 o...
Overstock.com has 13″ MacBook Airs on sale for up to $180 off MSRP including free shipping: - 13″ 1.6GHz/128GB MacBook Air (MMGF2LL/A): $869.99 $130 off MSRP - 13″ 1.6GHz/256GB MacBook Air (sku... Read more
13-inch 2.5GHz MacBook Pro (Apple refurbished...
Apple has Certified Refurbished 13″ 2.5GHz MacBook Pros (MD101LL/A) available for $829, or $270 off original MSRP. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz MacBook... Read more
Monday roundup of Holiday Mac sales: Up to $3...
Take up to $300 off MSRP on the price of a new Apple Mac at B&H Photo today as part of their Holiday sale. Shipping is free, and B&H charges NY sales tax only. Touch Bar MacBook Pros are in... Read more
12-inch WiFi Apple iPad Pros on sale for up t...
B&H Photo has 12″ WiFi Apple iPad Pros on sale for up to $50 off MSRP, each including free shipping. B&H charges sales tax in NY only: - 12″ Space Gray 32GB WiFi iPad Pro: $749 $50 off MSRP... Read more

Jobs Board

*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Lead *Apple* Solutions Consultant - Apple (...
# Lead Apple Solutions Consultant Job Number: 53586123 Pittsburgh, Pennsylvania, United States Posted: Nov. 28, 2016 Weekly Hours: 40.00 **Job Summary** The Lead ASC Read more
*Apple* Retail - Multiple Positions- Plano,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions- Kansas...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions- Chicago...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.