From ed8e2d78f73209be14da232ec9ab7e4ecbbb1e67 Mon Sep 17 00:00:00 2001 From: Stuart Carnie Date: Fri, 14 Aug 2020 18:51:49 -0700 Subject: [PATCH] Copied Audio fixes --- OpenEmuKit.xcodeproj/project.pbxproj | 2 +- OpenEmuKit/OpenEmuKit.h | 1 + Source/OEGameAudio.h | 2 +- Source/OEGameAudio.m | 96 ++++++++++++++-------------- Source/OELogging.h | 2 +- Source/OELogging.m | 3 +- 6 files changed, 53 insertions(+), 53 deletions(-) diff --git a/OpenEmuKit.xcodeproj/project.pbxproj b/OpenEmuKit.xcodeproj/project.pbxproj index 1a3792b..35913b7 100644 --- a/OpenEmuKit.xcodeproj/project.pbxproj +++ b/OpenEmuKit.xcodeproj/project.pbxproj @@ -42,7 +42,7 @@ 05E6BA2A24CCD75900ACFB35 /* OEAudioUnit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 05E6BA2624CCD75800ACFB35 /* OEAudioUnit.mm */; }; 05E6BA2B24CCD75900ACFB35 /* OEGameAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 05E6BA2724CCD75900ACFB35 /* OEGameAudio.h */; }; 05E6BA3024CCD77600ACFB35 /* OEGameLayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E6BA2D24CCD77300ACFB35 /* OEGameLayerView.m */; }; - 05E6BA3124CCD77600ACFB35 /* OEGameLayerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 05E6BA2E24CCD77400ACFB35 /* OEGameLayerView.h */; }; + 05E6BA3124CCD77600ACFB35 /* OEGameLayerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 05E6BA2E24CCD77400ACFB35 /* OEGameLayerView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 05E6BA3C24CCD79600ACFB35 /* OEThreadProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 05E6BA3624CCD79200ACFB35 /* OEThreadProxy.h */; }; 05E6BA3D24CCD79600ACFB35 /* OELogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E6BA3724CCD79300ACFB35 /* OELogging.m */; }; 05E6BA3E24CCD79600ACFB35 /* OEThreadProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E6BA3824CCD79500ACFB35 /* OEThreadProxy.m */; }; diff --git a/OpenEmuKit/OpenEmuKit.h b/OpenEmuKit/OpenEmuKit.h index 9e9b27f..a73b2d1 100644 --- a/OpenEmuKit/OpenEmuKit.h +++ b/OpenEmuKit/OpenEmuKit.h @@ -42,3 +42,4 @@ FOUNDATION_EXPORT const unsigned char OpenEmuKitVersionString[]; #import #import #import +#import diff --git a/Source/OEGameAudio.h b/Source/OEGameAudio.h index f8f4361..3aefce3 100644 --- a/Source/OEGameAudio.h +++ b/Source/OEGameAudio.h @@ -32,7 +32,7 @@ @interface OEGameAudio : NSObject @property(nonatomic) CGFloat volume; -@property AudioDeviceID outputDeviceID; +@property(nonatomic) AudioDeviceID outputDeviceID; - (id)initWithCore:(OEGameCore *)core; diff --git a/Source/OEGameAudio.m b/Source/OEGameAudio.m index 0ff336d..41b17da 100644 --- a/Source/OEGameAudio.m +++ b/Source/OEGameAudio.m @@ -36,7 +36,7 @@ id _token; AVAudioUnitGenerator *_gen; __weak OEGameCore *_gameCore; - AudioDeviceID _outputDeviceID; + BOOL _outputDeviceIsDefault; BOOL _running; // specifies the expected state of OEGameAudio } @@ -52,25 +52,13 @@ _volume = 1.0; _running = NO; _engine = [AVAudioEngine new]; - - __weak typeof(self) weakSelf = self; - _token = [NSNotificationCenter.defaultCenter addObserverForName:AVAudioEngineConfigurationChangeNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull note) { - os_log_info(OE_LOG_AUDIO, "AVAudioEngine configuration change"); - if (weakSelf) { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf->_outputDeviceID = [strongSelf defaultAudioOutputDeviceID]; - [strongSelf setDeviceAndConnections]; - [strongSelf resumeAudio]; - } - }]; + _outputDeviceIsDefault = YES; return self; } - (void)dealloc { - if (_token) { - [NSNotificationCenter.defaultCenter removeObserver:_token]; - } + [self stopMonitoringEngineConfiguration]; } - (void)audioSampleRateDidChange { @@ -88,12 +76,13 @@ [self createNodes]; [self configureNodes]; [self attachNodes]; - [self setDeviceAndConnections]; + [self setOutputDeviceID:self.outputDeviceID]; [_engine prepare]; // per the following, we need to wait before resuming to allow devices to start 🤦🏻‍♂️ // https://github.com/AudioKit/AudioKit/blob/f2a404ff6cf7492b93759d2cd954c8a5387c8b75/Examples/macOS/OutputSplitter/OutputSplitter/Audio/Output.swift#L88-L95 [self performSelector:@selector(resumeAudio) withObject:nil afterDelay:0.020]; + [self startMonitoringEngineConfiguration]; } - (void)stopAudio { @@ -119,6 +108,26 @@ } } +- (void)startMonitoringEngineConfiguration +{ + __weak typeof(self) weakSelf = self; + _token = [NSNotificationCenter.defaultCenter addObserverForName:AVAudioEngineConfigurationChangeNotification object:_engine queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull note) { + __strong typeof(weakSelf) strongSelf = weakSelf; + if (!strongSelf) + return; + + os_log_info(OE_LOG_AUDIO, "AVAudioEngine configuration change"); + [self setOutputDeviceID:self.outputDeviceID]; + }]; +} + +- (void)stopMonitoringEngineConfiguration +{ + if (_token) { + [NSNotificationCenter.defaultCenter removeObserver:_token]; + } +} + - (OEAudioBufferReadBlock)readBlockForBuffer:(id)buffer { if ([buffer respondsToSelector:@selector(readBlock)]) { return [buffer readBlock]; @@ -209,20 +218,7 @@ _gen = nil; } -- (void)setDeviceAndConnections { - if (_outputDeviceID == 0) { - _outputDeviceID = [self defaultAudioOutputDeviceID]; - os_log_info(OE_LOG_AUDIO, "using default audio device %d", _outputDeviceID); - } - - NSError *err; - if (![_engine.outputNode.AUAudioUnit setDeviceID:_outputDeviceID error:&err]) { - os_log_error(OE_LOG_AUDIO, "unable to set output device ID %d: %{public}s", - _outputDeviceID, - err.localizedDescription.UTF8String); - return; - } - +- (void)connectNodes { [_engine connect:_gen to:_engine.mainMixerNode format:nil]; _engine.mainMixerNode.outputVolume = _volume; } @@ -237,28 +233,32 @@ - (AudioDeviceID)outputDeviceID { - return _outputDeviceID; + return _outputDeviceIsDefault ? 0 : _engine.outputNode.AUAudioUnit.deviceID; } - (void)setOutputDeviceID:(AudioDeviceID)outputDeviceID { - if(outputDeviceID != _outputDeviceID) - { - // 0 indicates use the current system default output - if (outputDeviceID == 0) { - outputDeviceID = [self defaultAudioOutputDeviceID]; - os_log_info(OE_LOG_AUDIO, "using default audio device %d", _outputDeviceID); - } - - _outputDeviceID = outputDeviceID; - - [_engine stop]; - [self setDeviceAndConnections]; - - if (_running && !_engine.isRunning) { - [_engine prepare]; - [self performSelector:@selector(resumeAudio) withObject:nil afterDelay:0.020]; - } + if (outputDeviceID == 0) { + outputDeviceID = [self defaultAudioOutputDeviceID]; + os_log_info(OE_LOG_AUDIO, "using default audio device %d", outputDeviceID); + _outputDeviceIsDefault = YES; + } else { + _outputDeviceIsDefault = NO; + } + + [_engine stop]; + NSError *err; + if (![_engine.outputNode.AUAudioUnit setDeviceID:outputDeviceID error:&err]) { + os_log_error(OE_LOG_AUDIO, "unable to set output device ID %d: %{public}s", + outputDeviceID, + err.localizedDescription.UTF8String); + return; + } + [self connectNodes]; + + if (_running && !_engine.isRunning) { + [_engine prepare]; + [self performSelector:@selector(resumeAudio) withObject:nil afterDelay:0.020]; } } diff --git a/Source/OELogging.h b/Source/OELogging.h index 6091cf4..cd8fbf7 100644 --- a/Source/OELogging.h +++ b/Source/OELogging.h @@ -24,4 +24,4 @@ #import -extern os_log_t OE_LOG_AUDIO, OE_LOG_IMPORT; +extern os_log_t OE_LOG_AUDIO; diff --git a/Source/OELogging.m b/Source/OELogging.m index d1dc856..a36be80 100644 --- a/Source/OELogging.m +++ b/Source/OELogging.m @@ -24,11 +24,10 @@ #import "OELogging.h" -os_log_t OE_LOG_AUDIO, OE_LOG_IMPORT; +os_log_t OE_LOG_AUDIO; __attribute__((constructor)) static void InitializeLogging() { OE_LOG_AUDIO = os_log_create("org.openemu.OpenEmuKit", "OEGameAudio"); - OE_LOG_IMPORT = os_log_create("org.openemu.OpenEmu", "import"); }