home *** CD-ROM | disk | FTP | other *** search
-
- // GKSound: se the header file for info on it's use.
-
- #import <gamekit/gamekit.h>
- #import <daymisckit/daymisckit.h>
- #import <sound/sound.h>
-
- @implementation GKSound
-
- - setPlayStream:aStream { streamGroup = aStream; return self; }
- - _initGKSound
- {
- if (!now) now = [[DAYTime alloc] init];
- if (!timeToPlay) timeToPlay = [[DAYTime alloc] init];
- if (!nextPlay) nextPlay = [[DAYTime alloc] initWithCurrentTime];
- return self;
- }
-
- // overridden init methods: (to assure that _initGKSound is called)
- - initFromSoundfile:(const char *)filename
- {
- id ret = [super initFromSoundfile:filename];
- [self _initGKSound];
- [self convert];
- return ret;
- }
-
- - initFromSection:(const char *)sectionName
- {
- id ret = [super initFromSection:sectionName];
- [self _initGKSound];
- [self convert];
- return ret;
- }
-
- - initFromPasteboard:(Pasteboard *)thePboard
- {
- id ret = [super initFromPasteboard:thePboard];
- [self _initGKSound];
- [self convert];
- return ret;
- }
-
- // the new methods:
- - setPercentToPlay:(double)percent // how much to play before next play
- {
- SNDSoundStruct *mySoundData = [self soundStruct];
- // assuming that we're 16bit 22.050kHz mono sound
- long timeOnStream = (mySoundData->dataSize / 2) * 45.3514739229;
- double usecToPlay = timeOnStream * percent;
- [[timeToPlay init] addMicroseconds:(timeOnStream - usecToPlay)];
- #ifdef NOISYDEBUG
- fprintf(stderr, "GKSound: Play %f percent out of %ld usec (%f usec).\n",
- percent, timeOnStream, usecToPlay);
- fprintf(stderr, "GKSound: Play when %s (%d) left to go.\n\n",
- [timeToPlay stringValue], [timeToPlay microsecond]);
- #endif
- return self;
- }
-
- - setTimeToPlay:aTime // how long to play sound before next play
- { // aTime says how long after start of sound play we must wait.
- // we need to find how soon before the sound ends we can start:
- SNDSoundStruct *mySoundData = [self soundStruct];
- // assuming that we're 16bit 22.050kHz mono sound
- long timeOnStream = (mySoundData->dataSize / 2) * 45.3514739229;
- [[[timeToPlay init] addMicroseconds:timeOnStream] subtractTime:aTime];
- #ifdef NOISYDEBUG
- fprintf(stderr, "GKSound: Play after %s (%d).\n",
- [aTime stringValue], [aTime microsecond]);
- fprintf(stderr, "GKSound: Play when %s (%d) left to go.\n\n",
- [timeToPlay stringValue], [timeToPlay microsecond]);
- #endif
- return self;
- }
-
- - convert
- {
- int err;
- if (err = [self convertToFormat:SND_FORMAT_LINEAR_16
- samplingRate:SND_RATE_LOW channelCount:1]) {
- fprintf(stderr, "%s: GKSound convert error %s\n",
- [NXApp appName], SNDSoundError(err));
- }
- return self;
- }
-
- - (int)play // overridden playback method
- {
- id temp; // a DAYTime that says when the sound will finish playing.
-
- // check to see if we can be played or not
- [now initWithCurrentTime];
- #ifdef NOISYDEBUG
- fprintf(stderr, "GKSound: Now is: %s (%d)\n", [now stringValue],
- [now microsecond]);
- fprintf(stderr, "GKSound: Next play at: %s (%d) -- %s\n",
- [nextPlay stringValue], [nextPlay microsecond],
- ([nextPlay isAfter:now] ? "Don't play it." : "Play it."));
- #endif
- if ([nextPlay isAfter:now])
- return SND_ERR_NONE; // not time yet: ignore the play
-
- // do the actual playback:
- if (delegate && [delegate respondsTo:@selector(willPlay:)])
- [delegate willPlay:self]; // we can do this one.
- temp = [streamGroup playSoundStruct:[self soundStruct]];
- // I suppose that if you _really_ need the didPlay, you could set a
- // timed entry to go off when the sound is supposed to finish. *****
- // or hack the GKSoundStream to return/forward the delegate method
- // -soundStream:didCompleteBuffer: which would do the trick (if you
- // have it track the tags; right now it forgets them)
-
- // Calculate when it will be OK to fire off a new sound:
- [nextPlay copyTimeFrom:temp];
- [nextPlay subtractTime:timeToPlay];
- #ifdef NOISYDEBUG
- fprintf(stderr, "GKSound: Sound should end at: %s (%d)\n",
- [temp stringValue], [temp microsecond]);
- fprintf(stderr,
- "GKSound: Subtract %s (%d) and start next sound at %s (%d)\n\n",
- [timeToPlay stringValue], [timeToPlay microsecond],
- [nextPlay stringValue], [nextPlay microsecond]);
- #endif
- return SND_ERR_NONE;
- }
-
- @end
-