Big refactor to remove remanents of AudioQueue code. Added safety locks when working with 64bit floats and ints across threads

This commit is contained in:
Thong Nguyen 2014-01-31 20:20:20 +00:00
parent ddc6cf4b2f
commit a0a9553631
8 changed files with 345 additions and 319 deletions

View File

@ -57,7 +57,7 @@
{
NSURL* url = [NSURL URLWithString:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
STKAutoRecoveringHTTPDataSource* dataSource = [[STKAutoRecoveringHTTPDataSource alloc] initWithHTTPDataSource:(STKHTTPDataSource*)[audioPlayer dataSourceFromURL:url]];
STKAutoRecoveringHTTPDataSource* dataSource = [[STKAutoRecoveringHTTPDataSource alloc] initWithHTTPDataSource:(STKHTTPDataSource*)[STKAudioPlayer dataSourceFromURL:url]];
[audioPlayer setDataSource:dataSource withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
}
@ -67,7 +67,7 @@
NSString* path = [[NSBundle mainBundle] pathForResource:@"airplane" ofType:@"aac"];
NSURL* url = [NSURL fileURLWithPath:path];
[audioPlayer queueDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
[audioPlayer queueDataSource:[STKAudioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
}
-(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView
@ -75,7 +75,7 @@
NSString* path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"m4a"];
NSURL* url = [NSURL fileURLWithPath:path];
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
[audioPlayer setDataSource:[STKAudioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
}
@end

View File

@ -181,8 +181,8 @@
-(void) disposeButtonPressed
{
[audioPlayer dispose];
audioPlayer = nil;
[audioPlayer stop];
// audioPlayer = nil;
}
-(void) playButtonPressed
@ -283,7 +283,7 @@
NSLog(@"Requeuing: %@", [queueId.url description]);
[self->audioPlayer queueDataSource:[self->audioPlayer dataSourceFromURL:queueId.url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:queueId.url andCount:queueId.count + 1]];
[self->audioPlayer queueDataSource:[STKAudioPlayer dataSourceFromURL:queueId.url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:queueId.url andCount:queueId.count + 1]];
}
}

View File

@ -11,6 +11,7 @@
@interface NSMutableArray (STKAudioPlayer)
-(void) enqueue:(id)obj;
-(void) skipQueue:(id)obj;
-(void) skipQueueWithQueue:(NSMutableArray*)queue;
-(id) dequeue;
-(id) peek;
@end

View File

@ -20,6 +20,14 @@
[self addObject:obj];
}
-(void) skipQueueWithQueue:(NSMutableArray*)queue
{
for (id item in queue)
{
[self addObject:item];
}
}
-(id) dequeue
{
if ([self count] == 0)
@ -39,14 +47,4 @@
return [self lastObject];
}
-(id) peekRecent
{
if (self.count == 0)
{
return nil;
}
return [self objectAtIndex:0];
}
@end

View File

@ -55,7 +55,6 @@ typedef enum
/* Same as STKAudioPlayerInternalStateWaitingForData but isn't immediately raised as a buffering event */
STKAudioPlayerInternalStateWaitingForDataAfterSeek = (1 << 5) | STKAudioPlayerInternalStateRunning,
STKAudioPlayerInternalStatePaused = (1 << 6) | STKAudioPlayerInternalStateRunning,
STKAudioPlayerInternalStateStopping = (1 << 8),
STKAudioPlayerInternalStateStopped = (1 << 9),
STKAudioPlayerInternalStatePendingNext = (1 << 10),
STKAudioPlayerInternalStateDisposed = (1 << 30),
@ -78,9 +77,9 @@ STKAudioPlayerState;
typedef enum
{
AudioPlayerStopReasonNoStop = 0,
AudioPlayerStopReasonEof,
AudioPlayerStopReasonUserAction
STKAudioPlayerStopReasonNoStop = 0,
STKAudioPlayerStopReasonEof,
STKAudioPlayerStopReasonUserAction
}
STKAudioPlayerStopReason;
@ -89,12 +88,9 @@ typedef enum
STKAudioPlayerErrorNone = 0,
STKAudioPlayerErrorDataSource,
STKAudioPlayerErrorStreamParseBytesFailed,
STKAudioPlayerErrorAudioSystemError,
STKAudioPlayerErrorCodecError,
STKAudioPlayerErrorDataNotFound,
STKAudioPlayerErrorQueueStartFailed,
STKAudioPlayerErrorQueuePauseFailed,
STKAudioPlayerErrorUnknownBuffer,
STKAudioPlayerErrorQueueStopFailed,
STKAudioPlayerErrorQueueCreationFailed,
STKAudioPlayerErrorOther = -1
}
STKAudioPlayerErrorCode;
@ -125,20 +121,35 @@ STKAudioPlayerErrorCode;
-(id) init;
-(id) initWithReadBufferSize:(int)readBufferSizeIn;
-(STKDataSource*) dataSourceFromURL:(NSURL*)url;
+(STKDataSource*) dataSourceFromURL:(NSURL*)url;
/// Plays an item from the given URL (all pending queued items are removed)
-(void) play:(NSString*)urlString;
/// Plays an item from the given URL (all pending queued items are removed)
-(void) playWithURL:(NSURL*)url;
/// Plays the given item (all pending queued items are removed)
-(void) playWithDataSource:(STKDataSource*)dataSource;
/// Queues a DataSource with the given Item ID for playback
-(void) queueDataSource:(STKDataSource*)dataSource withQueueItemId:(NSObject*)queueItemId;
/// Plays the given item (all pending queued items are removed)
-(void) setDataSource:(STKDataSource*)dataSourceIn withQueueItemId:(NSObject*)queueItemId;
/// Seeks to a specific time (in seconds)
-(void) seekToTime:(double)value;
/// Clears any upcoming items already queued for playback (does not stop the current item)
-(void) clearQueue;
/// Pauses playback
-(void) pause;
/// Resumes playback from pause
-(void) resume;
/// Stops playback of the current file, flushes all the buffers and removes any pending queued items
-(void) stop;
/// Mutes playback
-(void) mute;
/// Unmutes playback
-(void) unmute;
/// Disposes the STKAudioPlayer and frees up all resources before returning
-(void) dispose;
/// The QueueItemId of the currently playing item
-(NSObject*) currentlyPlayingQueueItemId;
@end

File diff suppressed because it is too large Load Diff

View File

@ -7,47 +7,40 @@
//
#import "STKDataSource.h"
#import "libkern/OSAtomic.h"
#import "AudioToolbox/AudioToolbox.h"
@interface STKQueueEntry : NSObject
{
@public
OSSpinLock spinLock;
BOOL parsedHeader;
double sampleRate;
double lastProgress;
Float64 sampleRate;
double packetDuration;
int framesQueued;
int framesPlayed;
Float64 lastFrameQueued;
UInt64 audioDataOffset;
UInt64 audioDataByteCount;
UInt32 packetBufferSize;
volatile BOOL cancel;
volatile BOOL finished;
volatile Float64 seekTime;
volatile int64_t framesQueued;
volatile int64_t framesPlayed;
volatile int64_t lastFrameQueued;
volatile int processedPacketsCount;
volatile int processedPacketsSizeTotal;
AudioStreamBasicDescription audioStreamBasicDescription;
}
@property (readonly) UInt64 audioDataLengthInBytes;
@property (readwrite, retain) NSObject* queueItemId;
@property (readwrite, retain) STKDataSource* dataSource;
@property (readwrite) Float64 seekTime;
@property (readwrite) int bytesBuffered;
@property (readwrite) int lastByteIndex;
@property (readwrite) Float64 lastFrameIndex;
@property (readwrite) Float64 timeWhenLastBufferReturned;
@property (readwrite) Float64 firstFrameIndex;
@property (readonly) UInt64 audioDataLengthInBytes;
-(id) initWithDataSource:(STKDataSource*)dataSource andQueueItemId:(NSObject*)queueItemId;
-(void) reset;
-(double) duration;
-(Float64) progressInFrames;
-(double) calculatedBitRate;
-(void) updateAudioDataSource;
-(BOOL) isDefinitelyCompatible:(AudioStreamBasicDescription*)basicDescription;
-(BOOL) isKnownToBeIncompatible:(AudioStreamBasicDescription*)basicDescription;
-(BOOL) couldBeIncompatible:(AudioStreamBasicDescription*)basicDescription;
-(Float64) calculateProgressWithTotalFramesPlayed:(Float64)framesPlayed;
-(id) initWithDataSource:(STKDataSource*)dataSource andQueueItemId:(NSObject*)queueItemId;
@end

View File

@ -19,14 +19,21 @@
{
self.dataSource = dataSourceIn;
self.queueItemId = queueItemIdIn;
self.lastFrameIndex = -1;
self.lastByteIndex = -1;
self->lastFrameQueued = -1;
}
return self;
}
-(void) reset
{
OSSpinLockLock(&self->spinLock);
self->framesQueued = 0;
self->framesPlayed = 0;
self->lastFrameQueued = -1;
OSSpinLockUnlock(&self->spinLock);
}
-(double) calculatedBitRate
{
double retval;
@ -58,29 +65,6 @@
}
}
-(Float64) calculateProgressWithTotalFramesPlayed:(Float64)framesPlayedIn
{
return (Float64)self.seekTime + ((framesPlayedIn - self.firstFrameIndex) / (Float64)self->audioStreamBasicDescription.mSampleRate);
}
-(double) calculateProgressWithBytesPlayed:(Float64)bytesPlayed
{
double retval = lastProgress;
if (self->sampleRate > 0)
{
double calculatedBitrate = [self calculatedBitRate];
retval = bytesPlayed / calculatedBitrate * 8;
retval = self.seekTime + retval;
[self updateAudioDataSource];
}
return retval;
}
-(double) duration
{
if (self->sampleRate <= 0)
@ -127,29 +111,13 @@
return (memcmp(&(self->audioStreamBasicDescription), basicDescription, sizeof(*basicDescription)) == 0);
}
-(BOOL) isKnownToBeIncompatible:(AudioStreamBasicDescription*)basicDescription
{
if (self->audioStreamBasicDescription.mSampleRate == 0)
{
return NO;
}
return (memcmp(&(self->audioStreamBasicDescription), basicDescription, sizeof(*basicDescription)) != 0);
}
-(BOOL) couldBeIncompatible:(AudioStreamBasicDescription*)basicDescription
{
if (self->audioStreamBasicDescription.mSampleRate == 0)
{
return YES;
}
return memcmp(&(self->audioStreamBasicDescription), basicDescription, sizeof(*basicDescription)) != 0;
}
-(Float64) progressInFrames
{
return self.seekTime + self->framesPlayed;
OSSpinLockLock(&self->spinLock);
Float64 retval = self->seekTime + self->framesPlayed;
OSSpinLockUnlock(&self->spinLock);
return retval;
}
-(NSString*) description