diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index bfa5d299..40d4b31e 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -1360,16 +1360,16 @@ - + - + @@ -1450,6 +1450,30 @@ + + + + + + + + + + + + + + + + + + + @@ -1459,6 +1483,8 @@ + + diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index db84830e..a1419f41 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -2214,16 +2214,16 @@ - + - + @@ -2233,6 +2233,30 @@ + + + + + + + + + + + + + + + + + + + @@ -2242,6 +2266,8 @@ + + diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h index 5774bd79..2b636aeb 100644 --- a/VoidLink/Database/DataManager.h +++ b/VoidLink/Database/DataManager.h @@ -21,6 +21,11 @@ typedef NS_ENUM(NSUInteger, UINavigationBarHeight) { UINavigationBarHeightIPhone = 44 }; +typedef NS_ENUM(NSInteger, AudioEngine) { + SystemAudioEngine, + SDLAudioEngine +}; + typedef NS_ENUM(NSInteger, TouchMode) { RelativeTouch, NativeTouch, @@ -120,6 +125,7 @@ typedef NS_ENUM(NSInteger, WidgetSizeTransition) { singleTapSensitivy:(CGFloat)singleTapSensitivy hapticEngine:(NSInteger)hapticEngine edgeSlidingSensitivity:(CGFloat)edgeSlidingSensitivity + audioEngine:(NSInteger)audioEngine backgroundSessionTimer:(NSInteger)backgroundSessionTimer; - (NSArray*) getHosts; diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m index 5c757fac..8d3c8711 100644 --- a/VoidLink/Database/DataManager.m +++ b/VoidLink/Database/DataManager.m @@ -108,6 +108,7 @@ singleTapSensitivy:(CGFloat)singleTapSensitivy hapticEngine:(NSInteger)hapticEngine edgeSlidingSensitivity:(CGFloat)edgeSlidingSensitivity + audioEngine:(NSInteger)audioEngine backgroundSessionTimer:(NSInteger)backgroundSessionTimer{ [_managedObjectContext performBlockAndWait:^{ @@ -166,6 +167,7 @@ settingsToSave.singleTapSensitivity = [NSNumber numberWithDouble:singleTapSensitivy]; settingsToSave.hapticEngine = [NSNumber numberWithInteger:hapticEngine]; settingsToSave.edgeSlidingSensitivity = [NSNumber numberWithFloat:edgeSlidingSensitivity]; + settingsToSave.audioEngine = [NSNumber numberWithInteger:audioEngine]; settingsToSave.rememberFoldState = rememberFoldState; [self saveData]; }]; diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h index b189ceed..eff564bd 100644 --- a/VoidLink/Database/TemporarySettings.h +++ b/VoidLink/Database/TemporarySettings.h @@ -82,6 +82,7 @@ @property (nonatomic, retain) NSNumber * hapticEngine; @property (nonatomic, retain) NSNumber * appTheme; @property (nonatomic, retain) NSNumber * edgeSlidingSensitivity; +@property (nonatomic, retain) NSNumber * audioEngine; @property (nonatomic, retain) NSNumber * framePacingMode; - (id) initFromSettings:(Settings*)settings; diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m index 76e8b796..900813f7 100644 --- a/VoidLink/Database/TemporarySettings.m +++ b/VoidLink/Database/TemporarySettings.m @@ -138,8 +138,9 @@ self.edgeSlidingSensitivity = settings.edgeSlidingSensitivity; self.appTheme = settings.appTheme; self.hapticEngine = settings.hapticEngine; -#endif self.uniqueId = settings.uniqueId; + self.audioEngine = settings.audioEngine; +#endif return self; } diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index 68ea9d0c..64243cf7 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -24,6 +24,7 @@ + diff --git a/VoidLink/Stream/Connection.m b/VoidLink/Stream/Connection.m index 32a6b4a5..598c55ab 100644 --- a/VoidLink/Stream/Connection.m +++ b/VoidLink/Stream/Connection.m @@ -403,8 +403,7 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength) float* fbuf = (float*)audioBuffer; - // if(useSystemAudioEngine && false) { - if(true){ + if(useSystemAudioEngine) { // 创建 AVAudioPCMBuffer AVAudioFrameCount frameCount = decodeLen; AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFormat frameCapacity:frameCount]; @@ -581,9 +580,7 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t _streamConfig.supportedVideoFormats = config.supportedVideoFormats; _streamConfig.audioConfiguration = config.audioConfiguration; _streamConfig.redirectMic = config.redirectMic && [MicHandler permissionGranted]; - NSLog(@"config.localVolume %f", config.localVolume); [Connection setVolume:config.localVolume]; - // Since we require iOS 12 or above, we're guaranteed to be running // on a 64-bit device with ARMv8 crypto instructions, so we don't // need to check for that here. diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h index 710c478e..b11fafe7 100644 --- a/VoidLink/ViewControllers/SettingsViewController.h +++ b/VoidLink/ViewControllers/SettingsViewController.h @@ -178,6 +178,10 @@ @property (strong, nonatomic) IBOutlet UIStackView *appThemeStack; @property (strong, nonatomic) IBOutlet UISegmentedControl *appThemeSelector; +@property (strong, nonatomic) IBOutlet UIStackView *audioEngineStack; +@property (strong, nonatomic) IBOutlet UISegmentedControl *audioEngineSelector; + + @property (strong, nonatomic) IBOutlet UIStackView *testStack; @property (nonatomic, strong) MicHandler *micHandler; diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index 23a46883..074e62a9 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -35,6 +35,7 @@ NSInteger _bitrate; NSInteger _lastSelectedResolutionIndex; bool settingsViewJustLoaded; + bool settingsViewJustExpanded; uint16_t oswLayoutFingers; CustomEdgeSlideGestureRecognizer *slideToCloseSettingsViewRecognizer; NSMutableDictionary *_settingStackDict; @@ -399,6 +400,8 @@ BOOL isCustomResolution(int resolutionSelected) { - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:NO]; + settingsViewJustExpanded = true; + /* [self checkAndRequestMicPermission]; self.micHandler = [MicHandler new]; @@ -458,6 +461,8 @@ BOOL isCustomResolution(int resolutionSelected) { [self.customResolutionSwitch setOn: isCustomResolution(self->tempSettings.resolutionSelected.intValue)]; [self.resolutionSelector setEnabled:!self.customResolutionSwitch.isOn]; [self touchModeChanged:self.touchModeSelector]; // a special fix for iOS 14 to set hidden for the "enableOswStack" + + settingsViewJustExpanded = false; } - (void)viewWillDisappear:(BOOL)animated{ @@ -785,6 +790,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self addSetting:self.redirectMicStack ofId:@"redirectMicStack" withInfoTag:YES withDynamicLabel:NO to:audioSection]; [self addSetting:self.useBuiltinMicStack ofId:@"useBuiltinMicStack" withInfoTag:YES withDynamicLabel:NO to:audioSection]; [self addSetting:self.micVolumeStack ofId:@"micVolumeStack" withInfoTag:NO withDynamicLabel:YES to:audioSection]; + [self addSetting:self.audioEngineStack ofId:@"audioEngineStack" withInfoTag:YES withDynamicLabel:NO to:audioSection]; [self addSetting:self.audioConfigStack ofId:@"audioConfigStack" withInfoTag:NO withDynamicLabel:NO to:audioSection]; [audioSection addToParentStack:_parentStack]; // [audioSection setExpanded:NO]; @@ -1534,6 +1540,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self.view addGestureRecognizer:self->slideToCloseSettingsViewRecognizer]; self->settingsViewJustLoaded = true; + self->settingsViewJustExpanded = true; // Always run settings in dark mode because we want the light fonts if (@available(iOS 13.0, tvOS 13.0, *)) { @@ -1739,7 +1746,9 @@ BOOL isCustomResolution(int resolutionSelected) { [self.graphOpacityStepper setValue:(int)self->tempSettings.graphOpacity.intValue]; [self.graphOpacityStepper addTarget:self action:@selector(graphOpacityStepperTapped:) forControlEvents:UIControlEventValueChanged]; [self graphOpacityStepperTapped:self.graphOpacityStepper]; - + + self.audioEngineSelector.selectedSegmentIndex = self->tempSettings.audioEngine.intValue; + if (@available(iOS 18.0, tvOS 18.0, *)) {}else{ [self.audioConfigSelector removeSegmentAtIndex:1 animated:false]; [self.audioConfigSelector removeSegmentAtIndex:1 animated:false]; // segment 2 goes away when you remove index 2 @@ -1865,7 +1874,7 @@ BOOL isCustomResolution(int resolutionSelected) { self->motionControlSection.expandable = [self isCustomOswEnabled]; - [self->motionControlSection setExpanded:[self isCustomOswEnabled]]; + // [self->motionControlSection setExpanded:[self isCustomOswEnabled]]; __weak typeof(self) weakSelf = self; self->motionControlSection.lockedSectionHandler = ^{ [CountdownAlertController showAlertIn:weakSelf @@ -1958,8 +1967,7 @@ BOOL isCustomResolution(int resolutionSelected) { - (bool)isCustomOswEnabled{ bool customOswEnabled = [self isOswEnabled] && self.onScreenWidgetSelector.selectedSegmentIndex == OnScreenControlsLevelCustom; motionControlSection.expandable = customOswEnabled; - if(!settingsViewJustLoaded) [motionControlSection setExpanded:customOswEnabled]; - NSLog(@"isCustomOswEnabled %d, %f",customOswEnabled, CACurrentMediaTime()); + if(!(settingsViewJustExpanded || settingsViewJustLoaded)) [motionControlSection setExpanded:customOswEnabled]; return customOswEnabled; } @@ -2079,12 +2087,12 @@ BOOL isCustomResolution(int resolutionSelected) { } bool customOscEnabled = [self isCustomOswEnabled]; - NSLog(@"customOscEnabled %d", customOscEnabled); + // NSLog(@"customOscEnabled %d", customOscEnabled); UILabel* oswDynamicLabel = [self findDynamicLabelFromStack:self.onScreenWidgetStack]; NSString* labelText = customOscEnabled ? [LocalizationHelper localizedStringForKey:@"%d finger tap", self->oswLayoutFingers] : @""; oswDynamicLabel.text = [NSString stringWithFormat:@" %@ ", labelText]; oswDynamicLabel.hidden = !customOscEnabled; - NSLog(@"oswDynamicLabel.hidden %d", oswDynamicLabel.hidden); + // NSLog(@"oswDynamicLabel.hidden %d", oswDynamicLabel.hidden); [self handleOswGestureChange]; if(customOscEnabled && !settingsViewJustLoaded && !self.mainFrameViewController.settingsExpandedInStreamView) { // [self.keyboardToggleFingerNumSlider setValue:3.0]; @@ -2851,6 +2859,7 @@ BOOL isCustomResolution(int resolutionSelected) { CGFloat singleTapSensitivity = self.singleTapSensitivitySlider.value; NSInteger hapticEngine = self.hapticEngineSelector.selectedSegmentIndex; CGFloat edgeSlidingSensitivity = self.edgeSlidingSensitivitySlider.value; + NSInteger audioEngine = self.audioEngineSelector.selectedSegmentIndex; NSInteger backgroundSessionTimer = self.backgroundSessionTimerSlider.value == self.backgroundSessionTimerSlider.maximumValue ? (uint32_t) INT16_MAX : (uint32_t)self.backgroundSessionTimerSlider.value; [dataMan saveSettingsWithBitrate:_bitrate @@ -2905,6 +2914,7 @@ BOOL isCustomResolution(int resolutionSelected) { singleTapSensitivy:singleTapSensitivity hapticEngine:hapticEngine edgeSlidingSensitivity:edgeSlidingSensitivity + audioEngine:audioEngine backgroundSessionTimer:backgroundSessionTimer]; } diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 5c24d22a..0f722a2b 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -374,6 +374,8 @@ } else [micHandler stopTappingWithStopEngine:false]; + [Connection setUseSystemAudioEngine:_settings.audioEngine.intValue == SystemAudioEngine]; + if(!viewJustLoaded) [_controllerSupport updateControllerSupport:self.streamConfig delegate:self]; // reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC [_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig streamFrameTopLayerView:self.view]; //reinitiate setupStreamView process. diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index ab4cf4dc..98f0b360 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -619,6 +619,48 @@ } } }, + "85A-d5-pLE.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 85A-d5-pLE.segmentTitles[0] = \"System\"; ObjectID = \"85A-d5-pLE\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "System" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "系统" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "系統" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "系統" + } + } + } + }, + "85A-d5-pLE.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 85A-d5-pLE.segmentTitles[1] = \"SDL\"; ObjectID = \"85A-d5-pLE\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "SDL" + } + } + } + }, "aa5-3y-I4d.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; aa5-3y-I4d.segmentTitles[0] = \"Off\"; ObjectID = \"aa5-3y-I4d\";", "extractionState" : "extracted_with_value", @@ -1987,6 +2029,36 @@ } } }, + "fY9-M2-tiS.text" : { + "comment" : "Class = \"UILabel\"; text = \"Audio Engine\"; ObjectID = \"fY9-M2-tiS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Audio Engine" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "音频引擎" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "音訊引擎" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "音訊引擎" + } + } + } + }, "Gmb-bu-KCv.text" : { "comment" : "Class = \"UILabel\"; text = \"Button Visual Feedback\"; ObjectID = \"Gmb-bu-KCv\";", "extractionState" : "extracted_with_value", diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index e5376279..8865b2f6 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -1657,6 +1657,36 @@ } } }, + "dO2-cf-Ovg.text" : { + "comment" : "Class = \"UILabel\"; text = \"Audio Engine\"; ObjectID = \"dO2-cf-Ovg\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Audio Engine" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "音频引擎" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "音訊引擎" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "音訊引擎" + } + } + } + }, "dUM-r9-0Bo.text" : { "comment" : "Class = \"UILabel\"; text = \"Emulated Controller Type\"; ObjectID = \"dUM-r9-0Bo\";", "extractionState" : "extracted_with_value", @@ -3325,6 +3355,48 @@ } } }, + "pVq-EW-Dta.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; pVq-EW-Dta.segmentTitles[0] = \"System\"; ObjectID = \"pVq-EW-Dta\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "System" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "系统" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "系統" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "系統" + } + } + } + }, + "pVq-EW-Dta.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; pVq-EW-Dta.segmentTitles[1] = \"SDL\"; ObjectID = \"pVq-EW-Dta\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "SDL" + } + } + } + }, "q6v-Jb-ysy.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; q6v-Jb-ysy.segmentTitles[0] = \"Xbox 360\"; ObjectID = \"q6v-Jb-ysy\";", "extractionState" : "extracted_with_value",