OK, this is the architecture design I've come up with...
FYI: I deviated slightly from what I was originally thinking. I'm going to
start a thread using NSThread's
-detachNewThreadWithSelector:toTarget:withObject: which will have a while
loop in it that streams the audio data. I figured the playback methods
should just command the thread... -play starts the thread, -stop cancels it,
-pause blocks it, and -resume unblocks it (I'm still not sure how I'll
manage to do this).
So here's what I have, as far as interfaces go (i'm only presenting relevant
methods):
:
+ (BOOL)canInitWithSound: (NSSound *)aSound
Will verify this bundle can open the sound (be it raw, wav, ogg, mp3, etc)
- (id)initWithSound: (NSSound *)aSound
Will initialize the sound data for playback
- (NSUInteger)readBytes: (void *)bytes length: (NSUInteger)length
Reads the data
These next few match 1-to-1 with NSSound's methods and will be called by
NSSound...
- (NSTimeInterval)duration
- (void)setCurrentTime: (NSTimeInterval)
- (NSTimeInterval)currentTime
These are straight forward...
- (NSUInteger)bitsPerSample
- (NSUInteger)channelCount
- (NSUInteger)sampleRate
- (NSByteOrder)byteOrder
:
- (id) initWithBits: (NSUInteger)bitsPerSample
channels: (NSUInteger)channelCount
sampleRate: (NSUInteger)sampleRate
byteOrder: (NSByteOrder)byteOrder
Initializes the device for playback with this info (see GSSoundInput's
methods)
- (BOOL)open
-initWithBits:... doesn't actually open the device, this does.
- (BOOL)close
Closes the device
- (NSUInteger)writeBytes: (void *)bytes length: (NSUInteger)length
Writes the data to the device (keep in mind the device can be anything that
accepts data, like a NSData object).
These next few match 1-to-1 with NSSound's methods and will be called by
NSSound...
- (void)setVolume: (float)volume
- (float)volume
- (NSString *)playbackDeviceIdentifier
- (void)setPlaybackDeviceIdentifier: (NSString *)playbackDeviceIdentifier
- (NSArray *)channelMapping
- (void)setChannelMapping: (NSArray *)channelMapping
NSSound:
- (id)initWithContentsOfFile:(NSString *)path byReference:(BOOL)byRef
Loads file in path using NSData's -initWithContentsOfMappedFile:
- (id)initWithData:(NSData *)data
Finds GSSoundInput and GSSoundOutput compatible bundles and initializes
them.
- (BOOL)pause
Blocks the thread.
- (BOOL)play
Makes sure there's no "stream" thread running for this NSSound and starts
one.
- (BOOL)resume
Unblocks/resume the thread.
- (BOOL)stop
Tell the thread to exit.
- (BOOL)isPlaying
If "stream" thread exists and is unblocked will return YES, otherwise NO.
- (void)_stream
This is where the stream loop actually occurs.
Is this a sensible design? I'm not sure this is the best way to go, but it's
the best I could come up with so far and I'd really like some feedback.
Like I mentioned before, I'm not really sure how to block and unblock the
thread, so I'll need some help there (the Apple docs are really confusing
with the whole thread thing, specially with the "this is how you do it...
you can also do it this way with 10.5 but we don't recommend it since it's
new").
Stefan
___
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev