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;