diff --git a/apps/chanora_flutter/ios/Podfile b/apps/chanora_flutter/ios/Podfile index 2085ef7..e44216a 100644 --- a/apps/chanora_flutter/ios/Podfile +++ b/apps/chanora_flutter/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '15.1' +platform :ios, '16.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/apps/chanora_flutter/ios/Podfile.lock b/apps/chanora_flutter/ios/Podfile.lock index 982fd00..8f9c544 100644 --- a/apps/chanora_flutter/ios/Podfile.lock +++ b/apps/chanora_flutter/ios/Podfile.lock @@ -55,7 +55,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0 - chanora_bridge: e1c7a6f9135400efec036d9df706b2b4b29b2cd5 + chanora_bridge: 2ed7c2ba427fab135dd9eab66c507b09cfee113a connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_foreground_task: a159d2c2173b33699ddb3e6c2a067045d7cebb89 @@ -65,6 +65,6 @@ SPEC CHECKSUMS: shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b -PODFILE CHECKSUM: 50c5b575d74b9daff4bf33213abfd2c15d7f2e41 +PODFILE CHECKSUM: e2123068539aeb66d53dc1612b383d13f489ede2 COCOAPODS: 1.16.2 diff --git a/apps/chanora_flutter/ios/Runner.xcodeproj/project.pbxproj b/apps/chanora_flutter/ios/Runner.xcodeproj/project.pbxproj index 3ac9d44..93bcf4a 100644 --- a/apps/chanora_flutter/ios/Runner.xcodeproj/project.pbxproj +++ b/apps/chanora_flutter/ios/Runner.xcodeproj/project.pbxproj @@ -14,6 +14,8 @@ 3EF79A791760D95CE0F41CFF /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63497078A621E2A73B102C46 /* Pods_RunnerTests.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; + 8C5000012DD0000000000001 /* SileroCoreMLBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C5000002DD0000000000001 /* SileroCoreMLBridge.swift */; }; + 8C5000042DD0000000000001 /* SileroCoreML in Frameworks */ = {isa = PBXBuildFile; productRef = 8C5000032DD0000000000001 /* SileroCoreML */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -57,6 +59,7 @@ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 8C5000002DD0000000000001 /* SileroCoreMLBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SileroCoreMLBridge.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7E043103010958FC2C6CA47F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 89E01DD0E6B92DA93A02E9D6 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; @@ -76,6 +79,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8C5000042DD0000000000001 /* SileroCoreML in Frameworks */, 1E3B5BCCA481234F14E64D44 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -164,6 +168,7 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, + 8C5000002DD0000000000001 /* SileroCoreMLBridge.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 1937FD83C5CC909094CDC137 /* PrivacyInfo.xcprivacy */, ); @@ -210,6 +215,9 @@ dependencies = ( ); name = Runner; + packageProductDependencies = ( + 8C5000032DD0000000000001 /* SileroCoreML */, + ); productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; @@ -243,6 +251,9 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 8C5000022DD0000000000001 /* XCLocalSwiftPackageReference "silero-coreml" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -386,6 +397,7 @@ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */, + 8C5000012DD0000000000001 /* SileroCoreMLBridge.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -462,7 +474,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.1; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -595,7 +607,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.1; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -646,7 +658,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.1; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -742,6 +754,21 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 8C5000022DD0000000000001 /* XCLocalSwiftPackageReference "silero-coreml" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../../../../silero-coreml; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 8C5000032DD0000000000001 /* SileroCoreML */ = { + isa = XCSwiftPackageProductDependency; + package = 8C5000022DD0000000000001 /* XCLocalSwiftPackageReference "silero-coreml" */; + productName = SileroCoreML; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/apps/chanora_flutter/ios/Runner/SileroCoreMLBridge.swift b/apps/chanora_flutter/ios/Runner/SileroCoreMLBridge.swift new file mode 100644 index 0000000..6ea3e9f --- /dev/null +++ b/apps/chanora_flutter/ios/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/ios/chanora_bridge.podspec b/apps/chanora_flutter/ios/chanora_bridge.podspec index d204783..93ca741 100644 --- a/apps/chanora_flutter/ios/chanora_bridge.podspec +++ b/apps/chanora_flutter/ios/chanora_bridge.podspec @@ -40,7 +40,7 @@ Pod::Spec.new do |s| s.license = { :type => 'Apache-2.0 OR MIT', :text => 'See LICENSE-APACHE / LICENSE-MIT at the repo root' } s.author = { 'EdisonJwa' => 'me@edison.network' } s.source = { :path => '.' } - s.platform = :ios, '15.1' + s.platform = :ios, '16.0' # Build the Rust bridge on `pod install`. The script runs under # bash; we use `set -e` so any failure (cargo missing, target not @@ -92,9 +92,9 @@ Pod::Spec.new do |s| RUSTUP_HOME="$USER_HOME/.rustup" \\ RUSTUP_TOOLCHAIN="stable-aarch64-apple-darwin" \\ RUSTC="$RUSTC_BIN" \\ - IPHONEOS_DEPLOYMENT_TARGET=15.1 \\ + IPHONEOS_DEPLOYMENT_TARGET=16.0 \\ CMAKE_POLICY_VERSION_MINIMUM=3.5 \\ - CMAKE_OSX_DEPLOYMENT_TARGET=15.1 \\ + CMAKE_OSX_DEPLOYMENT_TARGET=16.0 \\ "$CARGO_BIN" build --release --target aarch64-apple-ios -p chanora_bridge if [ ! -f "$BRIDGE" ]; then @@ -122,7 +122,7 @@ Pod::Spec.new do |s| CFBundleShortVersionString1.0.0 CFBundleVersion1 CFBundleSupportedPlatformsiPhoneOS - MinimumOSVersion15.1 + MinimumOSVersion16.0 PLIST @@ -200,9 +200,9 @@ PLIST RUSTUP_HOME="$USER_HOME/.rustup" \\ RUSTUP_TOOLCHAIN="stable-aarch64-apple-darwin" \\ RUSTC="$RUSTC_BIN" \\ - IPHONEOS_DEPLOYMENT_TARGET=15.1 \\ + IPHONEOS_DEPLOYMENT_TARGET=16.0 \\ CMAKE_POLICY_VERSION_MINIMUM=3.5 \\ - CMAKE_OSX_DEPLOYMENT_TARGET=15.1 \\ + CMAKE_OSX_DEPLOYMENT_TARGET=16.0 \\ "$CARGO_BIN" build --release --target "$RUST_TARGET" -p chanora_bridge cd "$REPO_ROOT/apps/chanora_flutter/ios" @@ -230,7 +230,7 @@ PLIST CFBundleShortVersionString1.0.0 CFBundleVersion1 CFBundleSupportedPlatforms$SUPPORTED_PLATFORM - MinimumOSVersion15.1 + MinimumOSVersion16.0 PLIST