home *** CD-ROM | disk | FTP | other *** search
- 18-Jun-88 14:51:42-MDT,6055;000000000001
- Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:51:34 MDT
- Received: by cs.utah.edu (5.54/utah-2.0-cs)
- id AA22810; Sat, 18 Jun 88 14:51:32 MDT
- Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- id AA24890; Sat, 18 Jun 88 14:51:30 MDT
- Date: Sat, 18 Jun 88 14:51:30 MDT
- From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- Message-Id: <8806182051.AA24890@sunset.utah.edu>
- To: rthum@simtel20.arpa
- Subject: play.c
-
- /*
- * play.c - use the mac II sound chip to play a sampled sound in chunks.
- * The eventual purpose is to do some animation in synch with the music.
- * Written in MPW C by Dwight Hare, March, 1988.
- */
-
- /* The following defines and data structures are used from sound.h:
- *
- * #define callBackCmd 13
- * #define bufferCmd 81
- * #define initMono 0x80
- *
- * typedef struct SndCommand {
- * unsigned short cmd;
- * short param1;
- * long param2;
- * } SndCommand;
- *
- * typedef struct SndChannel {
- * struct SndChannel *nextChan;
- * ModifierStubPtr firstMod;
- * ProcPtr callBack;
- * long userInfo;
- * Time wait;
- * SndCommand cmdInProgress;
- * short flags;
- * short qLength;
- * short qHead;
- * short qTail;
- * SndCommand queue[stdQLength];
- * } SndChannel, *SndChannelPtr;
- *
- * typedef struct SoundHeader {
- * char * samplePtr;
- * unsigned long length;
- * Fixed sampleRate;
- * unsigned long loopStart;
- * unsigned long loopEnd;
- * short baseNote;
- * char sampleArea[0];
- * } SoundHeader, *SoundHeaderPtr;
- */
-
-
- #define __ALLNU__ /* needed to get new sound stuff in Sound.h */
- #include <memory.h>
- #include <sound.h>
- #include <toolutils.h>
-
- #define NIL (Ptr)0
-
- /*
- * This callback routine is used to indicate when a sound has finished
- * (I haven't found any other way to do it).
- */
- pascal void
- snd_done(chan, cmd)
- SndChannelPtr chan;
- SndCommand *cmd;
- {
- chan->userInfo = 1;
- }
-
- /*
- * play plays the given sound in "sample" of length "len" at the sampled
- * rate "rate" (typically 22255 for a Soundwave sample at the highest
- * rate) and plays the sound in "incr" chunks (22255 would play in
- * one second chunks at the rate of 22255).
- */
- OSErr
- play(sample, len, rate, incr)
- unsigned char *sample;
- long len, rate, incr;
- {
- unsigned char *Sp;
- SndChannelPtr sndp = NIL;
- SndCommand playcmd, callcmd;
- SoundHeaderPtr playbuf, playbuf1, playbuf2;
- long i;
- OSErr err;
-
- /*
- * We need two buffers for the bufferCmd since the first one
- * isn't quite finished when we set up the second one.
- */
- playbuf1 = (SoundHeaderPtr)NewPtr(sizeof(SoundHeader));
- playbuf2 = (SoundHeaderPtr)NewPtr(sizeof(SoundHeader));
- if (playbuf1 == NIL || playbuf2 == NIL) {
- return(-1);
- }
- /*
- * The loopStart, loopEnd, and baseNote are for playing the
- * sampled sounds as notes, we are not using that feature.
- */
- playbuf1->sampleRate = FixRatio(rate, 1);
- playbuf2->sampleRate = FixRatio(rate, 1);
- playbuf1->loopStart = 0;
- playbuf2->loopStart = 0;
- playbuf1->loopEnd = 0;
- playbuf2->loopEnd = 0;
- playbuf1->baseNote = 60;
- playbuf2->baseNote = 60;
-
- /*
- * Create a new sound channel using the sampled synthesizer played
- * in mono. The callback routine will be used below to determine
- * the end of the sound.
- */
- if ((err = SndNewChannel(&sndp, sampledSynth, initMono, snd_done))
- != noErr) {
- return(err);
- }
-
- /*
- * The playcmd is used in a SndDoCommand. The bufferCmd plays the
- * buffer pointed to by param2 (set below).
- */
- playcmd.cmd = bufferCmd;
- playcmd.param1 = 0;
-
- /*
- * The callcmd is used in a SndDoCommand. The callBackCmd calls
- * the callback routine (snd_done) specified in the SndNewChannel
- * call. This callback will be put after each play cmd to indicate
- * when a sound has (almost) finished.
- */
- callcmd.cmd = callBackCmd;
- callcmd.param1 = 0;
- callcmd.param2 = 0;
-
- /* We start with the first playbuf */
- playbuf = playbuf1;
-
- for (i = len, Sp = sample; i > 0; i -= incr, Sp += incr) {
- /* change buffers */
- if (playbuf == playbuf1)
- playbuf = playbuf2;
- else playbuf = playbuf1;
- /* set the buffer length to either the increment or
- the rest of the sample */
- playbuf->length = i < incr? i : incr;
- /* Set the pointer to the sound to be played */
- playbuf->samplePtr = Sp;
- /*
- * Set the bufferCmd pointer to this buffer. This command
- * buffer is copied by the SndDoCommand so we don't need
- * two of them
- */
- playcmd.param2 = (long)playbuf;
- /* set the flag we use in snd_done to indicate the finish */
- sndp->userInfo = 0;
- /* Play the buffer */
- if ((err = SndDoCommand(sndp, &playcmd, true)) != noErr) {
- return(err);
- }
- /* Put the callback in the queue after the sound */
- if ((err = SndDoCommand(sndp, &callcmd, true)) != noErr) {
- return(err);
- }
- /* Now wait for the sound to finish (later we'll do some
- animation) */
- while(sndp->userInfo != 1);
- }
- /*
- * Cleanup
- */
- if ((err = SndDisposeChannel(sndp, false)) != noErr) {
- return(err);
- }
- DisposPtr(playbuf1); DisposPtr(playbuf2);
- return(noErr);
- }
- 18-Jun-88 14:51:42-MDT,6055;000000000001
- Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:51:34 MDT
- Received: by cs.utah.edu (5.54/utah-2.0-cs)
- id AA22810; Sat, 18 Jun 88 14:51:32 MDT
- Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- id AA24890; Sat, 18 Jun 88 14:51:30 MDT
- Date: Sat, 18 Jun 88 14:51:30 MDT
- From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- Message-Id: <8806182051.AA24890@sunset.utah.edu>
- To: rthum@simtel20.arpa
- Subject: play.c
-
- /*
- * play.c - use the mac II sound chip to play a sampled sound in chunks.
- * The eventual purpose is to do some animation in synch with the music.
- * Written in MPW C by Dwight Hare, March, 1988.
- */
-
- /* The following defines and data structures are used from sound.h:
- *
- * #define callBackCmd 13
- * #define bufferCmd 81
- * #define initMono 0x80
- *
- * typedef struct SndCommand {
- * unsigned short cmd;
- * short param1;
- * long param2;
- * } SndCommand;
- *
- * typedef struct SndChannel {
- * struct SndChannel *nextChan;
- * ModifierStubPtr firstMod;
- * ProcPtr callBack;
- * long userInfo;
- * Time wait;
- * SndCommand cmdInProgress;
- * short flags;
- * short qLength;
- * short qHead;
- * short qTail;
- * SndCommand queue[stdQLength];
- * } SndChannel, *SndChannelPtr;
- *
- * typedef struct SoundHeader {
- * char * samplePtr;
- * unsigned long length;
- * Fixed sampleRate;
- * unsigned long loopStart;
- * unsigned long loopEnd;
- * short baseNote;
- * char sampleArea[0];
- * } SoundHeader, *SoundHeaderPtr;
- */
-
-
- #define __ALLNU__ /* needed to get new sound stuff in Sound.h */
- #include <memory.h>
- #include <sound.h>
- #include <toolutils.h>
-
- #define NIL (Ptr)0
-
- /*
- * This callback routine is used to indicate when a sound has finished
- * (I haven't found any other way to do it).
- */
- pascal void
- snd_done(chan, cmd)
- SndChannelPtr chan;
- SndCommand *cmd;
- {
- chan->userInfo = 1;
- }
-
- /*
- * play plays the given sound in "sample" of length "len" at the sampled
- * rate "rate" (typically 22255 for a Soundwave sample at the highest
- * rate) and plays the sound in "incr" chunks (22255 would play in
- * one second chunks at the rate of 22255).
- */
- OSErr
- play(sample, len, rate, incr)
- unsigned char *sample;
- long len, rate, incr;
- {
- unsigned char *Sp;
- SndChannelPtr sndp = NIL;
- SndCommand playcmd, callcmd;
- SoundHeaderPtr playbuf, playbuf1, playbuf2;
- long i;
- OSErr err;
-
- /*
- * We need two buffers for the bufferCmd since the first one
- * isn't quite finished when we set up the second one.
- */
- playbuf1 = (SoundHeaderPtr)NewPtr(sizeof(SoundHeader));
- playbuf2 = (SoundHeaderPtr)NewPtr(sizeof(SoundHeader));
- if (playbuf1 == NIL || playbuf2 == NIL) {
- return(-1);
- }
- /*
- * The loopStart, loopEnd, and baseNote are for playing the
- * sampled sounds as notes, we are not using that feature.
- */
- playbuf1->sampleRate = FixRatio(rate, 1);
- playbuf2->sampleRate = FixRatio(rate, 1);
- playbuf1->loopStart = 0;
- playbuf2->loopStart = 0;
- playbuf1->loopEnd = 0;
- playbuf2->loopEnd = 0;
- playbuf1->baseNote = 60;
- playbuf2->baseNote = 60;
-
- /*
- * Create a new sound channel using the sampled synthesizer played
- * in mono. The callback routine will be used below to determine
- * the end of the sound.
- */
- if ((err = SndNewChannel(&sndp, sampledSynth, initMono, snd_done))
- != noErr) {
- return(err);
- }
-
- /*
- * The playcmd is used in a SndDoCommand. The bufferCmd plays the
- * buffer pointed to by param2 (set below).
- */
- playcmd.cmd = bufferCmd;
- playcmd.param1 = 0;
-
- /*
- * The callcmd is used in a SndDoCommand. The callBackCmd calls
- * the callback routine (snd_done) specified in the SndNewChannel
- * call. This callback will be put after each play cmd to indicate
- * when a sound has (almost) finished.
- */
- callcmd.cmd = callBackCmd;
- callcmd.param1 = 0;
- callcmd.param2 = 0;
-
- /* We start with the first playbuf */
- playbuf = playbuf1;
-
- for (i = len, Sp = sample; i > 0; i -= incr, Sp += incr) {
- /* change buffers */
- if (playbuf == playbuf1)
- playbuf = playbuf2;
- else playbuf = playbuf1;
- /* set the buffer length to either the increment or
- the rest of the sample */
- playbuf->length = i < incr? i : incr;
- /* Set the pointer to the sound to be played */
- playbuf->samplePtr = Sp;
- /*
- * Set the bufferCmd pointer to this buffer. This command
- * buffer is copied by the SndDoCommand so we don't need
- * two of them
- */
- playcmd.param2 = (long)playbuf;
- /* set the flag we use in snd_done to indicate the finish */
- sndp->userInfo = 0;
- /* Play the buffer */
- if ((err = SndDoCommand(sndp, &playcmd, true)) != noErr) {
- return(err);
- }
- /* Put the callback in the queue after the sound */
- if ((err = SndDoCommand(sndp, &callcmd, true)) != noErr) {
- return(err);
- }
- /* Now wait for the sound to finish (later we'll do some
- animation) */
- while(sndp->userInfo != 1);
- }
- /*
- * Cleanup
- */
- if ((err = SndDisposeChannel(sndp, false)) != noErr) {
- return(err);
- }
- DisposPtr(playbuf1); DisposPtr(playbuf2);
- return(noErr);
- }
-