This is GKSound.m in view mode; [Download] [Up]
// 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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.