diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..6ba6ae8 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "cake.tool": { + "version": "0.35.0", + "commands": [ + "dotnet-cake" + ] + }, + "dotnet-format": { + "version": "3.1.37601", + "commands": [ + "dotnet-format" + ] + } + } +} \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 1026f42..e094946 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -19,9 +19,9 @@ - + - + $(MSBuildThisFileDirectory)CodeAnalysis\osu-framework-microphone.ruleset diff --git a/global.json b/global.json new file mode 100644 index 0000000..99c68cf --- /dev/null +++ b/global.json @@ -0,0 +1,11 @@ +{ + "sdk": { + "allowPrerelease": false, + "rollForward": "minor", + "version": "3.1.100" + }, + "msbuild-sdks": { + "MSBuild.Sdk.Extras": "2.0.54", + "Microsoft.Build.Traversal": "2.0.52" + } +} \ No newline at end of file diff --git a/osu-framework-microphone.sln b/osu-framework-microphone.sln index 0f9f672..af090a2 100644 --- a/osu-framework-microphone.sln +++ b/osu-framework-microphone.sln @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.Microphone.Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.Microphone.Tests.Android", "osu.Framework.Microphone.Tests.Android\osu.Framework.Microphone.Tests.Android.csproj", "{320089C6-A141-4D3E-BD5F-C4A6CE9E567B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.Microphone.iOS", "osu.Framework.Microphone.iOS\osu.Framework.Microphone.iOS.csproj", "{431614F4-D662-4CBD-B6C2-3E0D79CA968B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -85,6 +87,18 @@ Global {320089C6-A141-4D3E-BD5F-C4A6CE9E567B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {320089C6-A141-4D3E-BD5F-C4A6CE9E567B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {320089C6-A141-4D3E-BD5F-C4A6CE9E567B}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Debug|iPhone.Build.0 = Debug|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Release|Any CPU.Build.0 = Release|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Release|iPhone.ActiveCfg = Release|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Release|iPhone.Build.0 = Release|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {431614F4-D662-4CBD-B6C2-3E0D79CA968B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/osu.Framework.Microphone.Tests.iOS/AppDelegate.cs b/osu.Framework.Microphone.Tests.iOS/AppDelegate.cs index 474d39c..43695a6 100644 --- a/osu.Framework.Microphone.Tests.iOS/AppDelegate.cs +++ b/osu.Framework.Microphone.Tests.iOS/AppDelegate.cs @@ -2,13 +2,26 @@ // See the LICENCE file in the repository root for full licence text. using Foundation; +using osu.Framework.Input.Handlers.Microphone; using osu.Framework.iOS; +using osu.Framework.iOS.Input; namespace osu.Framework.Tests { [Register("AppDelegate")] public class AppDelegate : GameAppDelegate { - protected override Game CreateGame() => new VisualTestGame(); + protected override Game CreateGame() => new TestingVisualTestGame(); + + internal class TestingVisualTestGame : VisualTestGame + { + protected override void LoadComplete() + { + base.LoadComplete(); + + // Need to cache IOSMicrophoneHandler in here to let MicrophoneInputManager knows. + Host.Dependencies.CacheAs(typeof(OsuTKMicrophoneHandler), new IOSMicrophoneHandler()); + } + } } } diff --git a/osu.Framework.Microphone.Tests.iOS/Info.plist b/osu.Framework.Microphone.Tests.iOS/Info.plist index c73d92a..d3603c7 100644 --- a/osu.Framework.Microphone.Tests.iOS/Info.plist +++ b/osu.Framework.Microphone.Tests.iOS/Info.plist @@ -2,10 +2,10 @@ + CFBundleIdentifier + ppy.osu-Framework-Microphone-Tests-iOS CFBundleName osu.Framework.Tests.iOS - CFBundleIdentifier - ppy.osu-Framework-Tests-iOS CFBundleShortVersionString 1.0 CFBundleVersion @@ -14,6 +14,10 @@ MinimumOSVersion 11.0 + NSMicrophoneUsageDescription + Ask for microphone permission + UIApplicationSupportsIndirectInputEvents + UIDeviceFamily 1 @@ -25,6 +29,10 @@ armv7 + UIRequiresFullScreen + + UIStatusBarHidden + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait @@ -34,11 +42,5 @@ XSAppIconAssets Assets.xcassets/AppIcon.appiconset - UIStatusBarHidden - - UIRequiresFullScreen - - UIApplicationSupportsIndirectInputEvents - diff --git a/osu.Framework.Microphone.Tests.iOS/Linker.xml b/osu.Framework.Microphone.Tests.iOS/Linker.xml index 51e6f60..be5441a 100644 --- a/osu.Framework.Microphone.Tests.iOS/Linker.xml +++ b/osu.Framework.Microphone.Tests.iOS/Linker.xml @@ -6,6 +6,12 @@ + + + + + + diff --git a/osu.Framework.Microphone.Tests.iOS/osu.Framework.Microphone.Tests.iOS.csproj b/osu.Framework.Microphone.Tests.iOS/osu.Framework.Microphone.Tests.iOS.csproj index 882d355..2d327f5 100644 --- a/osu.Framework.Microphone.Tests.iOS/osu.Framework.Microphone.Tests.iOS.csproj +++ b/osu.Framework.Microphone.Tests.iOS/osu.Framework.Microphone.Tests.iOS.csproj @@ -40,6 +40,10 @@ + + {431614f4-d662-4cbd-b6c2-3e0d79ca968b} + osu.Framework.Microphone.iOS + {D0F85C61-800A-4645-8633-AC59208FA732} osu.Framework.Microphone diff --git a/osu.Framework.Microphone.iOS/Input/IOSMicrophoneHandler.cs b/osu.Framework.Microphone.iOS/Input/IOSMicrophoneHandler.cs new file mode 100644 index 0000000..fce5285 --- /dev/null +++ b/osu.Framework.Microphone.iOS/Input/IOSMicrophoneHandler.cs @@ -0,0 +1,59 @@ +using AVFoundation; +using Foundation; +using osu.Framework.Input.Handlers.Microphone; +using osu.Framework.Logging; +using osu.Framework.Platform; + +namespace osu.Framework.iOS.Input +{ + public class IOSMicrophoneHandler : OsuTKMicrophoneHandler + { + public override bool IsActive => throw new System.NotImplementedException(); + + public IOSMicrophoneHandler() : base(-1) + { + } + + public override bool Initialize(GameHost host) + { + var session = AVAudioSession.SharedInstance(); + var success = false; + + Logger.Log("Begin Recording", LoggingTarget.Information, LogLevel.Verbose); + + session.RequestRecordPermission((granted) => + { + Logger.Log($"Audio Permission: {granted}", LoggingTarget.Information); + + if (granted) + { + session.SetCategory(AVAudioSession.CategoryRecord, out NSError error); + if (error == null) + { + session.SetActive(true, out error); + if (error != null) + { + Logger.Log(error.LocalizedDescription, LoggingTarget.Information, LogLevel.Error); + } + else + { + success = base.Initialize(host); + Logger.Log($"Microphone get permission status : {success}", LoggingTarget.Information); + } + } + else + { + Logger.Log(error.LocalizedDescription, LoggingTarget.Information, LogLevel.Error); + } + } + else + { + Logger.Log("YOU MUST ENABLE MICROPHONE PERMISSION", LoggingTarget.Information, LogLevel.Error); + } + }); + + Logger.Log($"Checking : {success}", LoggingTarget.Information, LogLevel.Error); + return success; + } + } +} diff --git a/osu.Framework.Microphone.iOS/osu.Framework.Microphone.iOS.csproj b/osu.Framework.Microphone.iOS/osu.Framework.Microphone.iOS.csproj new file mode 100644 index 0000000..bd7365b --- /dev/null +++ b/osu.Framework.Microphone.iOS/osu.Framework.Microphone.iOS.csproj @@ -0,0 +1,46 @@ + + + xamarinios10 + Library + true + osu.Framework.Microphone.iOS + osu.Framework.iOS + Resources + Unofficial osu!framework extension for using microphon as input device. + + + false + true + true + false + 1.0.10 + Git + osu-framework microphone andy840119 + andy840119 + osu!Karaoke + osu!Karaoke + + osu.Framework.Microphone.iOS + en + + + + + + + + + + + + + + + + + true + true + PreserveNewest + + + diff --git a/osu.Framework.Microphone/Input/MicrophoneInputManager.cs b/osu.Framework.Microphone/Input/MicrophoneInputManager.cs index d97aed1..443f259 100644 --- a/osu.Framework.Microphone/Input/MicrophoneInputManager.cs +++ b/osu.Framework.Microphone/Input/MicrophoneInputManager.cs @@ -5,18 +5,30 @@ using osu.Framework.Input.Handlers.Microphone; using osu.Framework.Input.StateChanges.Events; using osu.Framework.Input.States; +using System; namespace osu.Framework.Input { public class MicrophoneInputManager : CustomInputManager { - private readonly OsuTKMicrophoneHandler handler; - protected override InputState CreateInitialState() => new MicrophoneInputState(new MicrophoneState()); + private readonly int deviceId; + public MicrophoneInputManager(int device = -1) { - AddHandler(handler = new OsuTKMicrophoneHandler(device)); + deviceId = device; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + // Use handler like iOS microphone handler if there's exist handler in dependencies. + if (Host.Dependencies.Get(typeof(OsuTKMicrophoneHandler)) is OsuTKMicrophoneHandler handler) + AddHandler(Activator.CreateInstance(handler.GetType()) as OsuTKMicrophoneHandler); + else + AddHandler(new OsuTKMicrophoneHandler(deviceId)); } public override void HandleInputStateChange(InputStateChangeEvent inputStateChange)