home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.0
/
NeXTSTEP3.0.iso
/
NextDeveloper
/
Examples
/
AppKit
/
BreakApp
/
SoundEffect.m
< prev
next >
Wrap
Text File
|
1992-04-29
|
4KB
|
180 lines
/*
* SoundEffect.m, class to play sounds
* Originally by Terry Donahue, modified by Ali Ozer
*
* SoundEffect is a class which conveniently groups the 3.0
* sound stream functionality with sound data using the Sound
* class.
*
* You may freely copy, distribute and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied,
* as to its fitness for any particular use.
*/
#import "SoundEffect.h"
#import <soundkit/NXSoundOut.h>
#import <appkit/nextstd.h>
#import <objc/List.h>
@implementation SoundEffect
static BOOL soundEnabled = YES;
+ (void)setSoundEnabled:(BOOL)flag
{
soundEnabled = flag;
}
+ (BOOL)soundEnabled
{
return soundEnabled;
}
#define DEFAULTMAXSOUNDSTREAMS 20
static List *soundStreams = nil;
static unsigned int soundStreamsAllocated = 0;
static unsigned int maxSoundStreams = DEFAULTMAXSOUNDSTREAMS;
// These two methods let the client set/get the maximum number of
// sound streams to allocate. If this number is excee@ sound requests
// are simply not honored until sound streams are freed up.
+ (void)setMaxSoundStreams:(unsigned int)max
{
maxSoundStreams = max;
}
+ (unsigned int)maxSoundStreams
{
return maxSoundStreams;
}
// This method returns a sound stream to be used in playing a sound.
// Sound streams allocated through this method should be given back
// via releaseSoundStream:. Note that this is for internal use only;
// it however might be overridden if necessary.
- (NXPlayStream *)soundStream
{
static NXSoundOut *dev = nil; // We only have one instance of this...
NXPlayStream *newStream = nil;
if (!dev && !(dev = [[NXSoundOut alloc] init])) { // We allocate this from the default zone so that
NXLogError ("Couldn't create NXSoundOut"); // freeing this zone won't accidentally blast it
return nil;
}
if (!soundStreams) {
soundStreams = [[List alloc] init];
}
if (![soundStreams count]) {
if (soundStreamsAllocated < maxSoundStreams) {
newStream = [[NXPlayStream allocFromZone:[self zone]] initOnDevice:dev];
soundStreamsAllocated++;
}
} else {
newStream = [soundStreams removeLastObject];
}
if (newStream) {
[newStream setDelegate:self];
if (![newStream isActive]) {
[newStream activate];
}
}
return newStream;
}
- (void)releaseSoundStream:(NXPlayStream *)soundStream
{
[soundStreams addObject:soundStream];
}
// This method lets you create new instances of SoundEffect. If the specified
// sound file does not exist, the allocated instance is freed and nil is returned.
- initFromSection:(const char *)path
{
[super init];
if (!(sound = [[Sound allocFromZone:[self zone]] initFromSection:path])) {
NXLogError ("Couldn't load sound from %s", path);
[self free];
return nil;
}
return self;
}
// Free frees the SoundEffect. If this sound effect is being played at the time,
// the free is delayed and happens as soon as all pending sounds are finished.
- free
{
if (flags.refCount) {
flags.freeWhenDone = YES;
return nil;
} else {
if (sound) [sound free];
return [super free];
}
}
// These two methods play the sound effect.
- play
{
return [self play:1.0 pan:0.0];
}
- play:(float)volume pan:(float)pan
{
float left, right;
NXPlayStream *soundStream;
if (![@f class] soundEnabled]) {
return self;
}
if (!(soundStream = [self soundStream])) {
NXLogError ("No sound stream to play sound %x", self);
return self;
}
left = right = volume;
if (pan > 0.0) left *= 1.0 - pan;
else if (pan < 0.0) right *= 1.0 + pan;
[soundStream setGainLeft:left right:right];
[soundStream playBuffer:(void *)[sound data]
size:(unsigned int)[sound dataSize]
tag:0
channelCount:(unsigned int)[sound channelCount]
samplingRate:[sound samplingRate]];
flags.refCount++;
return self;
}
// Delegate methods for internal use only.
- soundStream:sender didCompleteBuffer:(int)tag
{
flags.refCount--;
[self releaseSoundStream:sender];
if (flags.freeWhenDone && flags.refCount == 0) {
[self free];
}
return sender;
}
- soundStreamDidAbort:sender deviceReserved:(BOOL)flag
{
return [self soundStream:sender didCompleteBuffer:0];
}
@end