diff --git a/Audio/AudioPlayer.h b/Audio/AudioPlayer.h index 90a68db80..a65c0b97f 100644 --- a/Audio/AudioPlayer.h +++ b/Audio/AudioPlayer.h @@ -16,6 +16,9 @@ { BufferChain *bufferChain; OutputNode *output; + + BOOL stoppingReQueue; + NSOperationQueue *reQueue; double volume; diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 9ff3b6df3..e9276bc7e 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -27,13 +27,23 @@ bufferChain = nil; outputLaunched = NO; endOfInputReached = NO; - - chainQueue = [[NSMutableArray alloc] init]; + + stoppingReQueue = NO; + reQueue = [[NSOperationQueue alloc] init]; + [reQueue setMaxConcurrentOperationCount:1]; + + chainQueue = [[NSMutableArray alloc] init]; } return self; } +- (void)dealloc +{ + stoppingReQueue = YES; + [reQueue waitUntilAllOperationsAreFinished]; +} + - (void)setDelegate:(id)d { delegate = d; @@ -206,7 +216,9 @@ - (void)stop { - //Set shouldoContinue to NO on allll things + //Set shouldoContinue to NO on all things + stoppingReQueue = YES; + [reQueue waitUntilAllOperationsAreFinished]; [self setShouldContinue:NO]; [self setPlaybackStatus:CogStatusStopped waitUntilDone:YES]; } @@ -282,6 +294,8 @@ [anObject setShouldContinue:NO]; } [chainQueue removeAllObjects]; + stoppingReQueue = YES; + [reQueue waitUntilAllOperationsAreFinished]; if (endOfInputReached) { [self endOfInputReached:bufferChain]; @@ -329,8 +343,45 @@ [newChain setShouldContinue:YES]; [newChain launchThreads]; - - [chainQueue insertObject:newChain atIndex:[chainQueue count]]; + + stoppingReQueue = NO; + + if (([chainQueue count] + [reQueue operationCount]) >= 5) { + NSBlockOperation *op = [[NSBlockOperation alloc] init]; + + [op addExecutionBlock:^{ + unsigned long queueCount; + + if (self->stoppingReQueue) { + return; + } + + for (;;) + { + @synchronized (self->chainQueue) { + queueCount = [self->chainQueue count]; + } + + if (queueCount < 5) { + @synchronized (self->chainQueue) { + [self->chainQueue insertObject:newChain atIndex:[self->chainQueue count]]; + } + break; + } + + if (self->stoppingReQueue) { + break; + } + + usleep(5000); + } + }]; + + [reQueue addOperation:op]; + } + else { + [chainQueue insertObject:newChain atIndex:[chainQueue count]]; + } } - (BOOL)endOfInputReached:(BufferChain *)sender //Sender is a BufferChain @@ -348,24 +399,21 @@ } } + queueCount = [chainQueue count] + [reQueue operationCount]; + } + + if (queueCount >= 5) + { + [reQueue waitUntilAllOperationsAreFinished]; + } + + @synchronized (chainQueue) { // We don't want to do this, it may happen with a lot of short files //if ([chainQueue count] >= 5) //{ // return YES; //} - queueCount = [chainQueue count]; - } - - while (queueCount >= 5) - { - usleep(2000); - @synchronized (chainQueue) { - queueCount = [chainQueue count]; - } - } - - @synchronized (chainQueue) { BufferChain *newChain = nil; nextStreamUserInfo = [sender userInfo];