home *** CD-ROM | disk | FTP | other *** search
- /*
- ***********************************************************************
- *
- * This is a whimsy set of functions that lets one play the sound
- * picked at random from the sound folder.
- * The sound folder name is supposed to be specified as a "Sound Folder"
- * STR resource. Even if you bastard forgot to set this resource,
- * the folder "Sounds" in the system folder would be assumed.
- *
- ***********************************************************************
- */
-
- /* MacHeaders Included */
-
- #include <Folders.h>
- #include <Sound.h>
-
- /*
- *-----------------------------------------------------------------------------------
- * Some standard I/O classes
- */
- class ParamBlockHdr
- {
- char internal[12]; // Managed by the File/Queue Managers exclusively
- int (*completion_routine)(void * param_block); // Completion routine
- OSErr result; // Result code, =0 means OK, <0 means error
- public:
- StringPtr name; // Pointer to some name
- short VRefNum; // Vol ref number (if <0), drive ref number (if >0)
- // or working dir reference number
-
- ParamBlockHdr(void);
- ~ParamBlockHdr(void) {}
- OSErr io_error(void) const { return result; }
- };
-
- ParamBlockHdr::ParamBlockHdr(void)
- {
- completion_routine = nil;
- result = 1; // Work is in progress
- }
-
- class DIRInfo: public ParamBlockHdr
- {
- public:
- short ioFRefNum; // File ref number
- signed char ioFVersNum; // Version number
- signed char filler1; // Not used
- short ioFDirIndex; // Index for the directory
- signed char ioFlAttrib; // File Attribute
- signed char filler2; // Not used
- DInfo ioDrUsrWds; // Finder Info
- long ioDrDirId; // Directory ID
- short ioDrNmFls; // No. files and directories inside this dir
- short filler3[9]; // Not used
- long ioDrCrDat; // Creation date
- long ioDrMdDat; // Modification date
- long ioDrBkDat; // Backup date
- DXInfo ioDrFndrInfo; // Additional info for the finder
- long ioDRParID; // Dir ID of the parent dir
-
- DIRInfo(const short vol_refno, const long parent_dirid, StringPtr dir_name);
- ~DIRInfo(void) {}
-
- };
-
- // Getting a directory info
- // Dir is specified by the volume refno,
- // parent ID and its name
- DIRInfo::DIRInfo(const short vol_refno, const long parent_dirid, StringPtr dir_name)
- {
- VRefNum = vol_refno;
- name = dir_name;
- ioFDirIndex = 0; // not used here
- ioDrDirId = parent_dirid;
- do_well( PBGetCatInfo((CInfoPBRec *)this,FALSE) );
- assert( io_error() == noErr );
- }
-
- class FLInfo: public ParamBlockHdr
- {
- public:
- short ioFRefNum; // File ref number
- signed char ioFVersNum; // Version number
- signed char filler1; // Not used
- short ioFDirIndex; // Index for the directory
- signed char ioFlAttrib; // File Attribute
- signed char ioFlVersNum; // Version number
- FInfo ioFlFndrInfo; // Finder Info
- long ioDirId; // Directory ID
- short ioFlStBlk; // First alloc block of data fork
- long ioFlLgLen; // Logical end-of-file of data fork
- long ioFlPyLen; // Physical end-of-file of data fork
- short ioFlRStBlk; // First alloc block of resource fork
- long ioFlRLgLen; // Logical end-of-file of resource fork
- long ioFlRPyLen; // Physical end-of-file of resource fork
- long ioFlCrDat; // Creation date
- long ioFlMdDat; // Modification date
-
- Str63 file_name;
- FLInfo(const short vol_refno, const long parent_dirid, const int index);
- ~FLInfo(void) {}
-
- };
-
- // Getting a file info
- // File is specified by the volume refno,
- // dir ID and the index
- // Check io_error() for possible fnfErr
- FLInfo::FLInfo(const short vol_refno, const long parent_dirid, const int index)
- {
-
- VRefNum = vol_refno;
- name = file_name;
- ioFDirIndex = index; // not used here
- ioDirId = parent_dirid;
- OSErr err = PBHGetFInfo((HParamBlockRec *)this,FALSE);
- if( err != noErr && err != fnfErr )
- _error("Failed to get a file info for a file indexed %d; error code %d",index,
- err);
- }
-
- /*
- *-----------------------------------------------------------------------------------
- * Sound Directory class that contains all the info about
- * the directory with sound files
- */
-
- class SoundDirectory
- {
- short volume_refno;
- long dir_id; // Directory ID of the Sound directory
- long no_files; // No. of files and folders in the directory
- void locate_sound_directory(void);
- // Locate the file with given index and tries
- // to open it as a resource. Returns the resource
- // refnumber if succeeded, or -1
- short locate_file_open_resource(const int file_no);
-
- public:
- SoundDirectory(void) { volume_refno = 0; dir_id = -1; }
- ~SoundDirectory(void) {}
- void play_at_random(void);
- };
-
- /*
- *-----------------------------------------------------------------------------------
- * Selecting a folder that contains sound files
- */
-
-
- // The present version locates the
- // directory named Sound inside the
- // system folder
- void SoundDirectory::locate_sound_directory(void)
- {
- // First locate the system directory
- long system_dir_id;
- do_well( ::FindFolder(kOnSystemDisk,kSystemFolderType,kDontCreateFolder,
- &volume_refno,&system_dir_id) );
-
- // Then get the directory ID of the "Sound"
- // folder within it
- DIRInfo sound_dir(volume_refno, system_dir_id, "\pSounds");
- assure( sound_dir.ioFlAttrib & 0x10, "The named thing is not a directory!");
- dir_id = sound_dir.ioDrDirId;
- no_files = sound_dir.ioDrNmFls;
- // message("Dir Id of the sound dir is %d, no. files %d",dir_id,no_files);
- }
-
-
- /*
- *-----------------------------------------------------------------------------------
- * Picking a file at random and playing it
- */
-
- // Locating a file in the sound dir with a
- // specified index. The program then tries
- // to open it as a resource. Returns the resource
- // refnumber if succeeded, or -1
- short SoundDirectory::locate_file_open_resource(const int file_index)
- {
- assert( file_index > 0 && file_index <= no_files );
- FLInfo file_info(volume_refno,dir_id,file_index);
- if( file_info.io_error() != noErr )
- return -1;
- // message("File name is %#s",file_info.file_name);
- short res_refno = HOpenResFile(volume_refno,dir_id,file_info.file_name,fsRdPerm);
- if( res_refno == -1 )
- message("Failed to open the resource fork because of error %d",ResError());
- return res_refno;
- }
-
-
- // Plays and closes the resource file
- void SoundDirectory::play_at_random(void)
- {
- if( dir_id < 0 )
- locate_sound_directory();
- GetDateTime((unsigned long *)&randSeed);
- const int max_no_tries = 5;
- register int try;
- for(try=1; try <= max_no_tries; try++)
- {
- int file_index = Random() % no_files;
- file_index = (file_index < 0 ? file_index + no_files : file_index ) + 1;
- short res_refno = locate_file_open_resource(file_index);
- if( res_refno == -1 )
- continue;
-
- Handle sound_handle = Get1IndResource('snd ',1); // Get the first sound found
- if( ResError() != noErr )
- {
- message("Failed to load a sound resource because of error %d",ResError());
- CloseResFile(res_refno);
- continue;
- }
- if( sound_handle != nil )
- {
- LoadResource(sound_handle);
- do_well( SndPlay(nil,sound_handle,FALSE) ); // Play sound in sync mode
- DisposeHandle(sound_handle);
- CloseResFile(res_refno);
- break;
- }
- }
- }
-
- /*
- *-----------------------------------------------------------------------------------
- * Routing module
- */
-
- static SoundDirectory sound_bundle;
-
- void play_random_sound(void)
- {
- sound_bundle.play_at_random();
- }
-