From 447a60afd9c375a45b06b54471828f8db3aa2c89 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Fri, 9 Dec 2022 21:14:45 -0800 Subject: [PATCH] Audio Player: Add new method of signaling stop This new method should cause all stops to default to immediate stoppage, and only stops that occur after an end of track signal should indicate to play out the entire buffer. Signed-off-by: Christopher Snowhill --- Audio/AudioPlayer.m | 13 +++++++++++++ Audio/Chain/OutputNode.h | 2 ++ Audio/Chain/OutputNode.m | 4 ++++ Audio/Output/OutputAVFoundation.h | 4 ++++ Audio/Output/OutputAVFoundation.m | 8 +++++++- 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 69911e317..8ad42dc85 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -315,6 +315,8 @@ // if there's already one at the head of chainQueue... r-r-right? for(BufferChain *chain in chainQueue) { if([chain isRunning]) { + if(output) + [output setShouldPlayOutBuffer:YES]; atomic_fetch_sub(&refCount, 1); return YES; } @@ -338,6 +340,8 @@ while(duration >= 30.0 && shouldContinue) { [semaphore wait]; if(atomic_load_explicit(&resettingNow, memory_order_relaxed)) { + if(output) + [output setShouldPlayOutBuffer:YES]; atomic_fetch_sub(&refCount, 1); return YES; } @@ -357,6 +361,8 @@ [self requestNextStream:nextStreamUserInfo]; if(!nextStream) { + if(output) + [output setShouldPlayOutBuffer:YES]; atomic_fetch_sub(&refCount, 1); return YES; } @@ -407,6 +413,8 @@ while(shouldContinue && ![newChain open:url withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) { if(nextStream == nil) { newChain = nil; + if(output) + [output setShouldPlayOutBuffer:YES]; atomic_fetch_sub(&refCount, 1); return YES; } @@ -416,6 +424,8 @@ if([nextStream isEqualTo:url]) { newChain = nil; + if(output) + [output setShouldPlayOutBuffer:YES]; atomic_fetch_sub(&refCount, 1); return YES; } @@ -442,6 +452,9 @@ // - self.nextStreamUserInfo == next playlist entry // - head of chainQueue is the buffer chain for the next entry (which has launched its threads already) + if(output) + [output setShouldPlayOutBuffer:YES]; + atomic_fetch_sub(&refCount, 1); return YES; } diff --git a/Audio/Chain/OutputNode.h b/Audio/Chain/OutputNode.h index 5cb89b0b9..a1219fa79 100644 --- a/Audio/Chain/OutputNode.h +++ b/Audio/Chain/OutputNode.h @@ -63,6 +63,8 @@ - (void)setShouldContinue:(BOOL)s; +- (void)setShouldPlayOutBuffer:(BOOL)s; + - (void)pause; - (void)resume; diff --git a/Audio/Chain/OutputNode.m b/Audio/Chain/OutputNode.m index 6a9e07306..cb9801b5a 100644 --- a/Audio/Chain/OutputNode.m +++ b/Audio/Chain/OutputNode.m @@ -170,6 +170,10 @@ // [output stop]; } +- (void)setShouldPlayOutBuffer:(BOOL)s { + [output setShouldPlayOutBuffer:s]; +} + - (BOOL)isPaused { return paused; } diff --git a/Audio/Output/OutputAVFoundation.h b/Audio/Output/OutputAVFoundation.h index 9af631c55..a9f1bfad8 100644 --- a/Audio/Output/OutputAVFoundation.h +++ b/Audio/Output/OutputAVFoundation.h @@ -116,6 +116,8 @@ using std::atomic_long; FSurroundFilter *fsurround; BOOL resetStreamFormat; + + BOOL shouldPlayOutBuffer; float *samplePtr; float tempBuffer[512 * 32]; @@ -149,6 +151,8 @@ using std::atomic_long; - (void)setEqualizerEnabled:(BOOL)enabled; +- (void)setShouldPlayOutBuffer:(BOOL)enabled; + - (void)sustainHDCD; @end diff --git a/Audio/Output/OutputAVFoundation.m b/Audio/Output/OutputAVFoundation.m index 56837b3b9..83c9c7c77 100644 --- a/Audio/Output/OutputAVFoundation.m +++ b/Audio/Output/OutputAVFoundation.m @@ -342,6 +342,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons - (void)threadEntry:(id)arg { running = YES; started = NO; + shouldPlayOutBuffer = NO; secondsLatency = 1.0; while(!stopping) { @@ -940,6 +941,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons stopInvoked = NO; stopCompleted = NO; commandStop = NO; + shouldPlayOutBuffer = NO; audioFormatDescription = NULL; @@ -1208,7 +1210,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons } if(renderSynchronizer || audioRenderer) { if(renderSynchronizer) { - if(!commandStop) { + if(shouldPlayOutBuffer && !commandStop) { int compareVal = 0; double secondsLatency = self->secondsLatency >= 0 ? self->secondsLatency : 0; int compareMax = (((1000000 / 5000) * secondsLatency) + (10000 / 5000)); // latency plus 10ms, divide by sleep intervals @@ -1302,4 +1304,8 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons secondsHdcdSustained = 10.0; } +- (void)setShouldPlayOutBuffer:(BOOL)s { + shouldPlayOutBuffer = s; +} + @end