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.