From f4f4f80f64f03778246777157f4068de98baccd7 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Mon, 7 Feb 2022 22:44:56 -0800 Subject: [PATCH] Restart playback on device or output format change Now the output is restarted on the current file at the current position if the output format has changed. This should resolve the issue finally. Signed-off-by: Christopher Snowhill --- Application/PlaybackController.m | 6 ++++++ Audio/AudioPlayer.h | 4 +++- Audio/AudioPlayer.m | 4 ++++ Audio/Chain/BufferChain.h | 2 ++ Audio/Chain/BufferChain.m | 4 ++++ Audio/Chain/OutputNode.h | 2 ++ Audio/Chain/OutputNode.m | 4 ++++ Audio/Output/OutputCoreAudio.h | 1 + Audio/Output/OutputCoreAudio.m | 17 +++++++++++++++++ 9 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Application/PlaybackController.m b/Application/PlaybackController.m index e2c4e188e..8dffb7f19 100644 --- a/Application/PlaybackController.m +++ b/Application/PlaybackController.m @@ -756,6 +756,12 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) { [miniWindow showHDCDLogo:YES]; } +- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo { + PlaylistEntry *pe = [playlistController currentEntry]; + BOOL paused = playbackStatus == CogStatusPaused; + [player play:[pe URL] withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused andSeekTo:[pe currentPosition]]; +} + - (void)removeHDCD:(id)sender { MainWindow *mainWindow = (MainWindow *)appController.mainWindow; [mainWindow showHDCDLogo:NO]; diff --git a/Audio/AudioPlayer.h b/Audio/AudioPlayer.h index 51e2581f2..97c89f183 100644 --- a/Audio/AudioPlayer.h +++ b/Audio/AudioPlayer.h @@ -76,6 +76,8 @@ - (void)setNextStream:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi; - (void)resetNextStreams; +- (void)restartPlaybackAtCurrentPosition; + + (NSArray *)fileTypes; + (NSArray *)schemes; + (NSArray *)containerTypes; @@ -121,5 +123,5 @@ - (void)audioPlayer:(AudioPlayer *)player refreshEqualizer:(AudioUnit)eq; - (void)audioPlayer:(AudioPlayer *)player removeEqualizer:(AudioUnit)eq; - (void)audioPlayer:(AudioPlayer *)player sustainHDCD:(id)userInfo; - +- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo; @end diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 41637ea10..651f84a05 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -220,6 +220,10 @@ } } +- (void)restartPlaybackAtCurrentPosition { + [self sendDelegateMethod:@selector(audioPlayer:restartPlaybackAtCurrentPosition:) withObject:[bufferChain userInfo] waitUntilDone:NO]; +} + - (void)setShouldContinue:(BOOL)s { shouldContinue = s; diff --git a/Audio/Chain/BufferChain.h b/Audio/Chain/BufferChain.h index b99c26271..d989f0ad4 100644 --- a/Audio/Chain/BufferChain.h +++ b/Audio/Chain/BufferChain.h @@ -75,4 +75,6 @@ - (void)sustainHDCD; +- (void)restartPlaybackAtCurrentPosition; + @end diff --git a/Audio/Chain/BufferChain.m b/Audio/Chain/BufferChain.m index e5125487d..83e724e86 100644 --- a/Audio/Chain/BufferChain.m +++ b/Audio/Chain/BufferChain.m @@ -260,4 +260,8 @@ [controller sustainHDCD]; } +- (void)restartPlaybackAtCurrentPosition { + [controller restartPlaybackAtCurrentPosition]; +} + @end diff --git a/Audio/Chain/OutputNode.h b/Audio/Chain/OutputNode.h index db7312055..e414d6c44 100644 --- a/Audio/Chain/OutputNode.h +++ b/Audio/Chain/OutputNode.h @@ -63,4 +63,6 @@ - (void)sustainHDCD; +- (void)restartPlaybackAtCurrentPosition; + @end diff --git a/Audio/Chain/OutputNode.m b/Audio/Chain/OutputNode.m index f2cf016fe..9f4c280d8 100644 --- a/Audio/Chain/OutputNode.m +++ b/Audio/Chain/OutputNode.m @@ -159,4 +159,8 @@ [output sustainHDCD]; } +- (void)restartPlaybackAtCurrentPosition { + [controller restartPlaybackAtCurrentPosition]; +} + @end diff --git a/Audio/Output/OutputCoreAudio.h b/Audio/Output/OutputCoreAudio.h index d66353ec8..cc4f44961 100644 --- a/Audio/Output/OutputCoreAudio.h +++ b/Audio/Output/OutputCoreAudio.h @@ -41,6 +41,7 @@ BOOL started; BOOL paused; BOOL stopNext; + BOOL restarted; BOOL eqEnabled; diff --git a/Audio/Output/OutputCoreAudio.m b/Audio/Output/OutputCoreAudio.m index a3e56e1ef..d8e7a4c75 100644 --- a/Audio/Output/OutputCoreAudio.m +++ b/Audio/Output/OutputCoreAudio.m @@ -167,6 +167,7 @@ static OSStatus renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioAct running = NO; started = NO; stopNext = NO; + restarted = NO; streamFormatStarted = NO; @@ -211,10 +212,16 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const running = YES; started = NO; stopNext = NO; + size_t eventCount = 0; atomic_store(&bytesRendered, 0); NSMutableArray *delayedEvents = [[NSMutableArray alloc] init]; BOOL delayedEventsPopped = YES; while(!stopping) { + if(++eventCount == 48) { + [self resetIfOutputChanged]; + if(restarted) break; + eventCount = 0; + } if([outputController shouldReset]) { @autoreleasepool { [[outputController buffer] reset]; @@ -459,6 +466,15 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const free(devids); } +- (void)resetIfOutputChanged { + AVAudioFormat *format = _au.outputBusses[0].format; + + if(!restarted && !_deviceFormat || ![_deviceFormat isEqual:format]) { + [outputController restartPlaybackAtCurrentPosition]; + restarted = YES; + } +} + - (BOOL)updateDeviceFormat { AVAudioFormat *format = _au.outputBusses[0].format; @@ -560,6 +576,7 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const paused = NO; stopNext = NO; outputDeviceID = -1; + restarted = NO; downmixer = nil;