diff --git a/apps/chanora_flutter/macos/Podfile.lock b/apps/chanora_flutter/macos/Podfile.lock index eab35a3..637f4db 100644 --- a/apps/chanora_flutter/macos/Podfile.lock +++ b/apps/chanora_flutter/macos/Podfile.lock @@ -7,33 +7,52 @@ PODS: - FlutterMacOS (1.0.0) - package_info_plus (0.0.1): - FlutterMacOS + - share_plus (0.0.1): + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS DEPENDENCIES: - audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`) - - chanora_bridge (from `/Users/edison/chanora/apps/chanora_flutter/macos`) + - chanora_bridge (from `/Users/edison/dev/chanora/apps/chanora_flutter/macos`) - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) EXTERNAL SOURCES: audio_session: :path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos chanora_bridge: - :path: "/Users/edison/chanora/apps/chanora_flutter/macos" + :path: "/Users/edison/dev/chanora/apps/chanora_flutter/macos" connectivity_plus: :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos FlutterMacOS: :path: Flutter/ephemeral package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + share_plus: + :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos SPEC CHECKSUMS: audio_session: eaca2512cf2b39212d724f35d11f46180ad3a33e - chanora_bridge: 1403e892a388d6bbb751d2d658e539d7a456fb1b + chanora_bridge: 4105993843b5421ee4ce72220a74c63f6fd99103 connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 package_info_plus: f0052d280d17aa382b932f399edf32507174e870 + share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd -PODFILE CHECKSUM: d2e26b3cd926b9e407faa321206548300d262a08 +PODFILE CHECKSUM: 99f0d126cab50f07c488b8550ebf033d2e8bcaeb COCOAPODS: 1.16.2 diff --git a/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj b/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj index 873ae4f..f76cca2 100644 --- a/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/apps/chanora_flutter/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 8C6000012DD0000000000001 /* SileroCoreMLBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C6000002DD0000000000001 /* SileroCoreMLBridge.swift */; }; + 8C6000042DD0000000000001 /* SileroCoreML in Frameworks */ = {isa = PBXBuildFile; productRef = 8C6000032DD0000000000001 /* SileroCoreML */; }; 45F255D1DE0134185DB5423D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 06E1AA7E1FB968C1D78DA8DE /* PrivacyInfo.xcprivacy */; }; 9B86175918197ECC64969956 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EFEADEEFAB54DFEAAD7A70E9 /* Pods_Runner.framework */; }; C2DC22E19FDCE26B9D79442E /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE04BBB936AA14C2B58FA0E /* Pods_RunnerTests.framework */; }; @@ -74,6 +76,7 @@ 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 8C6000002DD0000000000001 /* SileroCoreMLBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SileroCoreMLBridge.swift; sourceTree = ""; }; 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; @@ -105,6 +108,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8C6000042DD0000000000001 /* SileroCoreML in Frameworks */, 9B86175918197ECC64969956 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -179,6 +183,7 @@ children = ( 33CC10F02044A3C60003C045 /* AppDelegate.swift */, 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 8C6000002DD0000000000001 /* SileroCoreMLBridge.swift */, 33E51913231747F40026EE4D /* DebugProfile.entitlements */, 33E51914231749380026EE4D /* Release.entitlements */, 33CC11242044D66E0003C045 /* Resources */, @@ -250,6 +255,9 @@ 33CC11202044C79F0003C045 /* PBXTargetDependency */, ); name = Runner; + packageProductDependencies = ( + 8C6000032DD0000000000001 /* SileroCoreML */, + ); productName = Runner; productReference = 33CC10ED2044A3C60003C045 /* chanora_flutter.app */; productType = "com.apple.product-type.application"; @@ -293,6 +301,9 @@ Base, ); mainGroup = 33CC10E42044A3C60003C045; + packageReferences = ( + 8C6000022DD0000000000001 /* XCLocalSwiftPackageReference "silero-coreml" */, + ); productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -442,6 +453,7 @@ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + 8C6000012DD0000000000001 /* SileroCoreMLBridge.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -480,7 +492,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 0.2; PRODUCT_BUNDLE_IDENTIFIER = app.chanora.chanoraFlutter.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -496,7 +508,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 0.2; PRODUCT_BUNDLE_IDENTIFIER = app.chanora.chanoraFlutter.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -512,7 +524,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; MARKETING_VERSION = 0.2; PRODUCT_BUNDLE_IDENTIFIER = app.chanora.chanoraFlutter.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -562,7 +574,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -601,7 +613,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; }; @@ -611,7 +623,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Manual; - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Profile; @@ -663,7 +675,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -714,7 +726,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -753,7 +765,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -779,7 +791,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; }; @@ -789,7 +801,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Manual; - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -798,7 +810,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -847,6 +859,21 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 8C6000022DD0000000000001 /* XCLocalSwiftPackageReference "silero-coreml" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../../../../silero-coreml; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 8C6000032DD0000000000001 /* SileroCoreML */ = { + isa = XCSwiftPackageProductDependency; + package = 8C6000022DD0000000000001 /* XCLocalSwiftPackageReference "silero-coreml" */; + productName = SileroCoreML; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 33CC10E52044A3C60003C045 /* Project object */; } diff --git a/apps/chanora_flutter/macos/Runner/SileroCoreMLBridge.swift b/apps/chanora_flutter/macos/Runner/SileroCoreMLBridge.swift new file mode 100644 index 0000000..6ea3e9f --- /dev/null +++ b/apps/chanora_flutter/macos/Runner/SileroCoreMLBridge.swift @@ -0,0 +1,98 @@ +import CoreML +import Foundation +import SileroCoreML + +private final class ChanoraSileroVadBox { + let vad: SileroVAD + + init() throws { + let configuration = MLModelConfiguration() + vad = try SileroVAD(configuration: configuration) + } +} + +private let chanoraSileroErrorLock = NSLock() +private var chanoraSileroLastError = "" + +private func setChanoraSileroLastError(_ message: String) { + chanoraSileroErrorLock.lock() + chanoraSileroLastError = message + chanoraSileroErrorLock.unlock() +} + +@_cdecl("chanora_silero_vad_create") +public func chanoraSileroVadCreate() -> UnsafeMutableRawPointer? { + do { + let box = try ChanoraSileroVadBox() + return Unmanaged.passRetained(box).toOpaque() + } catch { + setChanoraSileroLastError(String(describing: error)) + return nil + } +} + +@_cdecl("chanora_silero_vad_destroy") +public func chanoraSileroVadDestroy(_ handle: UnsafeMutableRawPointer?) { + guard let handle else { return } + Unmanaged.fromOpaque(handle).release() +} + +@_cdecl("chanora_silero_vad_reset") +public func chanoraSileroVadReset(_ handle: UnsafeMutableRawPointer?) -> Int32 { + guard let handle else { + setChanoraSileroLastError("SileroVAD handle is null") + return -1 + } + let box = Unmanaged.fromOpaque(handle).takeUnretainedValue() + box.vad.reset() + return 0 +} + +@_cdecl("chanora_silero_vad_process") +public func chanoraSileroVadProcess( + _ handle: UnsafeMutableRawPointer?, + _ samples: UnsafePointer?, + _ sampleCount: Int, + _ probabilityOut: UnsafeMutablePointer? +) -> Int32 { + guard let handle else { + setChanoraSileroLastError("SileroVAD handle is null") + return -1 + } + guard let samples else { + setChanoraSileroLastError("SileroVAD samples pointer is null") + return -2 + } + guard let probabilityOut else { + setChanoraSileroLastError("SileroVAD probability output pointer is null") + return -3 + } + guard sampleCount == SileroVAD.chunkSize else { + setChanoraSileroLastError("SileroVAD expected \(SileroVAD.chunkSize) samples, got \(sampleCount)") + return -4 + } + + let box = Unmanaged.fromOpaque(handle).takeUnretainedValue() + do { + let chunk = Array(UnsafeBufferPointer(start: samples, count: sampleCount)) + probabilityOut.pointee = try box.vad.process(chunk) + return 0 + } catch { + setChanoraSileroLastError(String(describing: error)) + return -5 + } +} + +@_cdecl("chanora_silero_vad_last_error") +public func chanoraSileroVadLastError() -> UnsafeMutablePointer? { + chanoraSileroErrorLock.lock() + let message = chanoraSileroLastError + chanoraSileroErrorLock.unlock() + return strdup(message) +} + +@_cdecl("chanora_silero_vad_free_string") +public func chanoraSileroVadFreeString(_ string: UnsafeMutablePointer?) { + guard let string else { return } + free(string) +} diff --git a/apps/chanora_flutter/macos/macos_deployment_target.rb b/apps/chanora_flutter/macos/macos_deployment_target.rb index e1618c6..6ca72f2 100644 --- a/apps/chanora_flutter/macos/macos_deployment_target.rb +++ b/apps/chanora_flutter/macos/macos_deployment_target.rb @@ -4,9 +4,8 @@ # This value is the macOS SDK floor against which `libchanora_bridge.dylib` is # compiled — it is NOT the Flutter Runner app's deployment target (which lives # in Runner.xcodeproj/project.pbxproj at the PBXNativeTarget level and is -# currently `11.0`). The bridge floor is intentionally broader (`10.15`) so the -# cdylib symbols remain link-compatible with any consumer >= 10.15; the Runner -# app's own minimum is independently set at the Xcode-target layer. +# currently `13.0`). The bridge floor matches the Runner app and Apple/CoreML +# package requirement so the bundled SwiftPM dependency can link consistently. # # Consumers: # - apps/chanora_flutter/macos/Podfile (`platform :osx, ...`) @@ -18,4 +17,4 @@ # To bump the floor, edit ONLY this file. Do not introduce any other literal # occurrence of the floor string in this directory. -MACOS_BRIDGE_DEPLOYMENT_TARGET = '10.15'.freeze +MACOS_BRIDGE_DEPLOYMENT_TARGET = '13.0'.freeze