[Audio Output] Stop immediately, and fix deadlocks
Stop output when requested, except on natural completion of the last track in the play queue. Also fix deadlocks with stopping and restarting. Signed-off-by: Christopher Snowhill <kode54@gmail.com>swiftingly
parent
50b7390181
commit
d2eb4af3d5
|
@ -62,9 +62,10 @@
|
||||||
[self waitUntilCallbacksExit];
|
[self waitUntilCallbacksExit];
|
||||||
if(output) {
|
if(output) {
|
||||||
[output setShouldContinue:NO];
|
[output setShouldContinue:NO];
|
||||||
output = nil;
|
|
||||||
}
|
}
|
||||||
output = [[OutputNode alloc] initWithController:self previous:nil];
|
if(!output) {
|
||||||
|
output = [[OutputNode alloc] initWithController:self previous:nil];
|
||||||
|
}
|
||||||
[output setup];
|
[output setup];
|
||||||
[output setVolume:volume];
|
[output setVolume:volume];
|
||||||
@synchronized(chainQueue) {
|
@synchronized(chainQueue) {
|
||||||
|
@ -133,6 +134,9 @@
|
||||||
bufferChain = nil;
|
bufferChain = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(output) {
|
||||||
|
[output setShouldContinue:NO];
|
||||||
|
}
|
||||||
output = nil;
|
output = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +282,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)endEqualizer:(AudioUnit)eq {
|
- (void)endEqualizer:(AudioUnit)eq {
|
||||||
[self sendDelegateMethod:@selector(audioPlayer:removeEqualizer:) withVoid:eq waitUntilDone:YES];
|
[self sendDelegateMethod:@selector(audioPlayer:removeEqualizer:) withVoid:eq waitUntilDone:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addChainToQueue:(BufferChain *)newChain {
|
- (void)addChainToQueue:(BufferChain *)newChain {
|
||||||
|
|
|
@ -156,6 +156,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s {
|
- (void)setShouldContinue:(BOOL)s {
|
||||||
|
if(output && !s) {
|
||||||
|
[output stop];
|
||||||
|
}
|
||||||
|
|
||||||
[super setShouldContinue:s];
|
[super setShouldContinue:s];
|
||||||
|
|
||||||
// if (s == NO)
|
// if (s == NO)
|
||||||
|
|
|
@ -43,6 +43,7 @@ using std::atomic_long;
|
||||||
double lastVisRate;
|
double lastVisRate;
|
||||||
|
|
||||||
BOOL stopInvoked;
|
BOOL stopInvoked;
|
||||||
|
BOOL stopCompleted;
|
||||||
BOOL running;
|
BOOL running;
|
||||||
BOOL stopping;
|
BOOL stopping;
|
||||||
BOOL stopped;
|
BOOL stopped;
|
||||||
|
@ -50,6 +51,7 @@ using std::atomic_long;
|
||||||
BOOL paused;
|
BOOL paused;
|
||||||
BOOL restarted;
|
BOOL restarted;
|
||||||
BOOL stopFlush;
|
BOOL stopFlush;
|
||||||
|
BOOL commandStop;
|
||||||
|
|
||||||
BOOL eqEnabled;
|
BOOL eqEnabled;
|
||||||
BOOL eqInitialized;
|
BOOL eqInitialized;
|
||||||
|
|
|
@ -212,20 +212,16 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stopping) return 0;
|
||||||
|
|
||||||
float volumeScale = 1.0;
|
float volumeScale = 1.0;
|
||||||
double sustained;
|
double sustained;
|
||||||
@synchronized(self) {
|
sustained = secondsHdcdSustained;
|
||||||
sustained = secondsHdcdSustained;
|
|
||||||
}
|
|
||||||
if(sustained > 0) {
|
if(sustained > 0) {
|
||||||
if(sustained < amountRead) {
|
if(sustained < amountRead) {
|
||||||
@synchronized(self) {
|
secondsHdcdSustained = 0;
|
||||||
secondsHdcdSustained = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
@synchronized(self) {
|
secondsHdcdSustained -= chunkDuration;
|
||||||
secondsHdcdSustained -= chunkDuration;
|
|
||||||
}
|
|
||||||
volumeScale = 0.5;
|
volumeScale = 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,9 +311,8 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)processEndOfStream {
|
- (BOOL)processEndOfStream {
|
||||||
if([outputController endOfStream] == YES && [self signalEndOfStream:secondsLatency]) {
|
if(stopping || ([outputController endOfStream] == YES && [self signalEndOfStream:secondsLatency])) {
|
||||||
stopping = YES;
|
stopping = YES;
|
||||||
stopFlush = YES;
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -378,7 +373,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
|
|
||||||
stopped = YES;
|
stopped = YES;
|
||||||
if(!stopInvoked) {
|
if(!stopInvoked) {
|
||||||
[self stop];
|
[self doStop];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,6 +798,8 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
stopInvoked = NO;
|
stopInvoked = NO;
|
||||||
|
stopCompleted = NO;
|
||||||
|
commandStop = NO;
|
||||||
|
|
||||||
running = NO;
|
running = NO;
|
||||||
stopping = NO;
|
stopping = NO;
|
||||||
|
@ -1000,8 +997,21 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stop {
|
- (void)stop {
|
||||||
|
commandStop = YES;
|
||||||
|
[self doStop];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)doStop {
|
||||||
|
if(stopInvoked) {
|
||||||
|
while(!stopCompleted) {
|
||||||
|
usleep(5000);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(stopInvoked) return;
|
if(commandStop) {
|
||||||
|
stopFlush = NO;
|
||||||
|
}
|
||||||
stopInvoked = YES;
|
stopInvoked = YES;
|
||||||
if(observersapplied) {
|
if(observersapplied) {
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.outputDevice" context:kOutputAVFoundationContext];
|
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.outputDevice" context:kOutputAVFoundationContext];
|
||||||
|
@ -1094,6 +1104,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
r8bstate_delete(r8bvis);
|
r8bstate_delete(r8bvis);
|
||||||
r8bvis = NULL;
|
r8bvis = NULL;
|
||||||
}
|
}
|
||||||
|
stopCompleted = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,9 +1125,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sustainHDCD {
|
- (void)sustainHDCD {
|
||||||
@synchronized(self) {
|
secondsHdcdSustained = 10.0;
|
||||||
secondsHdcdSustained = 10.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in New Issue