This is SoundMgr.m in view mode; [Download] [Up]
// SoundMgr.m // Port to the new soundkit by Derek B. Clegg for BoinkOut // Munged again by sam for XoX #import <appkit/appkit.h> #import "SoundMgr.h" #import "xoxDefs.h" @implementation SoundMgr #define str_copy(str) ((str == NULL) ? NULL : NXCopyStringBuffer(str)) #define str_free(str) {if (str) free(str);} typedef struct { id sound; char *name; id bundle; } SoundInfo; - init { int k; [super init]; device = [[NXSoundOut allocFromZone:[self zone]] init]; if (device == nil) return nil; for (k = 0; k < MAX_STREAMS; k++) { streamList[k] = [[NXPlayStream allocFromZone:[self zone]] initOnDevice:device]; if (streamList[k] == nil) return nil; } // soundList = [[List allocFromZone:[self zone]] init]; soundList = [[Storage allocFromZone:[self zone]] initCount:8 elementSize: sizeof(SoundInfo) description: @encode(SoundInfo)]; currentSounds = [[Storage allocFromZone:[self zone]] initCount:8 elementSize: sizeof(int) description: @encode(int)]; return self; } - (Sound *)_loadSound: (const char *)name bundle:bndl { char path[MAXPATHLEN+1]; id theSound; if ([bndl getPath:path forResource:name ofType:"snd"]) { theSound = [[Sound allocFromZone:[self zone]] initFromSoundfile:path]; [theSound convertToFormat:SND_FORMAT_LINEAR_16 samplingRate:SND_RATE_LOW channelCount:1]; return theSound; } return nil; } - oneStep { [currentSounds empty]; return self; } // returns a positive int index for the new sound, or -1 on failure - (int) addSound:(const char *)name sender:whom { int ret; SoundInfo si; si.sound = nil; si.name = str_copy(name); si.bundle = [NXBundle bundleForClass:[whom class]]; ret = [soundList count] + 1; [soundList addElement:&si]; return ret; } - (int) addSound:(const char *)name sender:whom cache:(BOOL)cacheit { int ret = [self addSound:name sender:whom]; if (cacheit) [self cacheSound:ret]; return ret; } - cacheSound:(int)whichSound { SoundInfo *sip; whichSound--; // make it zero based sip = soundList->dataPtr; if ((sip[whichSound].sound == 0) && sip[whichSound].name) { sip[whichSound].sound = [self _loadSound:sip[whichSound].name bundle:sip[whichSound].bundle]; str_free(sip[whichSound].name); sip[whichSound].name = 0; } return self; } - (char *)soundName:(int)whichSound { SoundInfo *sip; whichSound--; // make it zero based sip = soundList->dataPtr; return sip[whichSound].name; } - (BOOL)_enable { int k; #if 0 NXSoundOut *soundOut = [[NXSoundOut alloc] init]; NXSoundParameterTag *encodings; unsigned int numEncodings; /* see if sound out streams support sound data */ [soundOut getStreamDataEncodings:&encodings count:&numEncodings]; if (numEncodings == 0) printf("sound out streams do not support sound data\n"); #endif for (k = 0; k < MAX_STREAMS; k++) if ([streamList[k] activate] != NX_SoundDeviceErrorNone) return NO; return YES; } - _disable { int k; for (k = 0; k < MAX_STREAMS; k++) [streamList[k] deactivate]; return self; } - playSound: (int)whichSound at: (float)mix { NXPlayStream *stream; Sound *sound; int count, i, *intArray; SoundInfo *sip; if ((!glSoundEnabled) || whichSound <= 0) return nil; // is the sound loaded? whichSound--; // make it zero based sip = soundList->dataPtr; if ((sip[whichSound].sound == 0)) [self cacheSound:(whichSound+1)]; // test if we've already played this sound this iteration intArray = currentSounds->dataPtr; count = [currentSounds count]; for (i=0; i<count; i++) { if (whichSound == intArray[i]) return self; } [currentSounds addElement:&whichSound]; stream = streamList[currentStream++]; if (currentStream == MAX_STREAMS) currentStream = 0; sound = sip[whichSound].sound; if (!sound) return nil; [stream abort:self]; [stream setGainLeft: (1-mix) right: mix]; [stream playBuffer:[sound data] size:[sound dataSize] tag:0 channelCount:[sound channelCount] samplingRate:[sound samplingRate]]; return self; } - free { int k, count = [soundList count]; SoundInfo *sip = soundList->dataPtr; for (k=0; k<count; k++) { [sip[k].sound free]; str_free(sip[k].name); } [soundList free]; for (k = 0; k < MAX_STREAMS; k++) [streamList[k] free]; [device free]; return [super free]; } - (BOOL)turnSoundOn:sender { if (![self _enable]) { if (sender) NXRunAlertPanel(NULL, NXLocalString("Can't do sound, dude.", NULL, NULL), NXLocalString("Bummer", NULL, NULL), NULL, NULL); glSoundEnabled = NO; return NO; } glSoundEnabled = YES; return YES; } - turnSoundOff { [self _disable]; glSoundEnabled = NO; return self; } - (BOOL)isSoundEnabled { return glSoundEnabled; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.