From cbba964e6b02aee2f0685adedafd605d098f651b Mon Sep 17 00:00:00 2001 From: PAB Date: Fri, 10 May 2024 14:03:00 +0200 Subject: [PATCH] example : bark.swiftui (#169) --- .github/workflows/build.yml | 12 + Package.swift | 44 ++ bark.cpp | 3 +- bark.h | 2 +- examples/bark.swiftui/.gitignore | 5 + examples/bark.swiftui/README.md | 13 + examples/bark.swiftui/bark-swiftui-Info.plist | 5 + .../bark.swiftui.xcodeproj/project.pbxproj | 414 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../UserInterfaceState.xcuserstate | Bin 0 -> 106311 bytes .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 13 + .../Assets.xcassets/Contents.json | 6 + .../bark.swiftui/Bindings/LibBark.swift | 49 +++ .../bark.swiftui/Models/AudioPlayer.swift | 53 +++ .../bark.swiftui/Models/BarkState.swift | 89 ++++ .../Preview Assets.xcassets/Contents.json | 6 + .../bark.swiftui/Views/ContentView.swift | 57 +++ .../bark.swiftui/bark_swiftuiApp.swift | 17 + .../bark_swift_package/Package.swift | 1 + .../bark.swiftui/bark_swift_package/bark.cpp | 1 + .../bark_swift_package/encodec.cpp | 1 + .../bark_swift_package/ggml-alloc.c | 1 + .../bark_swift_package/ggml-backend.c | 1 + .../bark.swiftui/bark_swift_package/ggml.c | 1 + .../bark_swift_package/include/bark.h | 1 + .../bark_swift_package/include/encodec.h | 1 + .../bark_swift_package/include/ggml-alloc.h | 1 + .../bark_swift_package/include/ggml-backend.h | 1 + .../bark_swift_package/include/ggml.h | 1 + spm-headers/bark.h | 1 + spm-headers/encodec.h | 1 + spm-headers/ggml-alloc.h | 1 + spm-headers/ggml-backend.h | 1 + spm-headers/ggml.h | 1 + 35 files changed, 820 insertions(+), 2 deletions(-) create mode 100644 Package.swift create mode 100644 examples/bark.swiftui/.gitignore create mode 100644 examples/bark.swiftui/README.md create mode 100644 examples/bark.swiftui/bark-swiftui-Info.plist create mode 100644 examples/bark.swiftui/bark.swiftui.xcodeproj/project.pbxproj create mode 100644 examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/xcuserdata/pbannier.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 examples/bark.swiftui/bark.swiftui/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 examples/bark.swiftui/bark.swiftui/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 examples/bark.swiftui/bark.swiftui/Assets.xcassets/Contents.json create mode 100644 examples/bark.swiftui/bark.swiftui/Bindings/LibBark.swift create mode 100644 examples/bark.swiftui/bark.swiftui/Models/AudioPlayer.swift create mode 100644 examples/bark.swiftui/bark.swiftui/Models/BarkState.swift create mode 100644 examples/bark.swiftui/bark.swiftui/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 examples/bark.swiftui/bark.swiftui/Views/ContentView.swift create mode 100644 examples/bark.swiftui/bark.swiftui/bark_swiftuiApp.swift create mode 120000 examples/bark.swiftui/bark_swift_package/Package.swift create mode 120000 examples/bark.swiftui/bark_swift_package/bark.cpp create mode 120000 examples/bark.swiftui/bark_swift_package/encodec.cpp create mode 120000 examples/bark.swiftui/bark_swift_package/ggml-alloc.c create mode 120000 examples/bark.swiftui/bark_swift_package/ggml-backend.c create mode 120000 examples/bark.swiftui/bark_swift_package/ggml.c create mode 120000 examples/bark.swiftui/bark_swift_package/include/bark.h create mode 120000 examples/bark.swiftui/bark_swift_package/include/encodec.h create mode 120000 examples/bark.swiftui/bark_swift_package/include/ggml-alloc.h create mode 120000 examples/bark.swiftui/bark_swift_package/include/ggml-backend.h create mode 120000 examples/bark.swiftui/bark_swift_package/include/ggml.h create mode 120000 spm-headers/bark.h create mode 120000 spm-headers/encodec.h create mode 120000 spm-headers/ggml-alloc.h create mode 120000 spm-headers/ggml-backend.h create mode 120000 spm-headers/ggml.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 756c8d5..7d3ad49 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -136,3 +136,15 @@ jobs: run: | emcmake cmake . -DCMAKE_BUILD_TYPE=${{ matrix.build }} make + + ios: + runs-on: macos-latest + + steps: + - name: Clone + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build swiftui example + run: xcodebuild -project examples/bark.swiftui/bark.swiftui.xcodeproj -scheme bark.swiftui -sdk iphonesimulator build diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..22c67f8 --- /dev/null +++ b/Package.swift @@ -0,0 +1,44 @@ +// swift-tools-version:5.5 + +import PackageDescription + +let package = Package( + name: "bark", + platforms: [ + .macOS(.v12), + .iOS(.v14), + .watchOS(.v4), + .tvOS(.v14) + ], + products: [ + .library(name: "bark", targets: ["bark"]), + ], + targets: [ + .target( + name: "bark", + path: ".", + sources: [ + "bark.cpp", + "encodec.cpp", + "ggml-alloc.c", + "ggml-backend.c", + "ggml.c", + ], + publicHeadersPath: "include", + cSettings: [ + .unsafeFlags(["-Wno-shorten-64-to-32", "-O3", "-DNDEBUG"]), + .define("GGML_USE_ACCELERATE"), + .unsafeFlags(["-fno-objc-arc"]), + // NOTE: NEW_LAPACK will required iOS version 16.4+ + // We should consider add this in the future when we drop support for iOS 14 + // (ref: ref: https://developer.apple.com/documentation/accelerate/1513264-cblas_sgemm?language=objc) + // .define("ACCELERATE_NEW_LAPACK"), + // .define("ACCELERATE_LAPACK_ILP64") + ], + linkerSettings: [ + .linkedFramework("Accelerate") + ] + ) + ], + cxxLanguageStandard: .cxx11 +) diff --git a/bark.cpp b/bark.cpp index 3cedd25..d581a8e 100644 --- a/bark.cpp +++ b/bark.cpp @@ -1189,6 +1189,8 @@ static bool bark_load_model_from_file( // codec model { + // not optimal: we close the file and reopen it using Encodec.cpp library with a + // specific offset const int offset = fin.tellg(); fin.close(); @@ -1201,7 +1203,6 @@ static bool bark_load_model_from_file( printf("\n"); - fin.close(); return true; } diff --git a/bark.h b/bark.h index c2b88aa..42cfabf 100644 --- a/bark.h +++ b/bark.h @@ -219,4 +219,4 @@ extern "C" { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/examples/bark.swiftui/.gitignore b/examples/bark.swiftui/.gitignore new file mode 100644 index 0000000..9657f3e --- /dev/null +++ b/examples/bark.swiftui/.gitignore @@ -0,0 +1,5 @@ +xcuserdata +xcshareddata + +!Models +!bark-swiftui-Info.plist \ No newline at end of file diff --git a/examples/bark.swiftui/README.md b/examples/bark.swiftui/README.md new file mode 100644 index 0000000..f64487a --- /dev/null +++ b/examples/bark.swiftui/README.md @@ -0,0 +1,13 @@ +A sample SwiftUI app using [bark.cpp](https://github.com/PABannier/bark.cpp/) to do audio generation locally. + +**Usage**: + +1. Select a model from the [bark.cpp repository](https://github.com/PABannier/bark.cpp/tree/master/models).[^1] +2. Add the model to `bark.swiftui/` **via Xcode**. If you drag and drop the model in the Xcode project outside of Xcode, the model weights won't be automatically added to the target. +3. Select the "Release" [^2] build configuration under "Run", then deploy and run to your device. + +**Note:** Pay attention to the folder path: `whisper.swiftui.demo/Resources/models` is the appropriate directory to place resources whilst `whisper.swiftui.demo/Models` is related to actual code. + +[^1]: I recommend the Bark small model for running on an iOS device. + +[^2]: The `Release` build can boost performance of audio generation. In this project, it also added `-O3 -DNDEBUG` to `Other C Flags`, but adding flags to app proj is not ideal in real world (applies to all C/C++ files), consider splitting xcodeproj in workspace in your own project. diff --git a/examples/bark.swiftui/bark-swiftui-Info.plist b/examples/bark.swiftui/bark-swiftui-Info.plist new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/examples/bark.swiftui/bark-swiftui-Info.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/bark.swiftui/bark.swiftui.xcodeproj/project.pbxproj b/examples/bark.swiftui/bark.swiftui.xcodeproj/project.pbxproj new file mode 100644 index 0000000..3147fd3 --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui.xcodeproj/project.pbxproj @@ -0,0 +1,414 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + E05A4F782BEE15150000CD31 /* bark_swiftuiApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E05A4F772BEE15150000CD31 /* bark_swiftuiApp.swift */; }; + E05A4F7A2BEE15150000CD31 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E05A4F792BEE15150000CD31 /* ContentView.swift */; }; + E05A4F7C2BEE15160000CD31 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E05A4F7B2BEE15160000CD31 /* Assets.xcassets */; }; + E05A4F7F2BEE15160000CD31 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E05A4F7E2BEE15160000CD31 /* Preview Assets.xcassets */; }; + E05A4F8A2BEE15BA0000CD31 /* LibBark.swift in Sources */ = {isa = PBXBuildFile; fileRef = E05A4F892BEE15BA0000CD31 /* LibBark.swift */; }; + E05A4F8C2BEE16590000CD31 /* BarkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E05A4F8B2BEE16590000CD31 /* BarkState.swift */; }; + E05A4F952BEE284C0000CD31 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E05A4F942BEE284C0000CD31 /* AudioPlayer.swift */; }; + E05A4F9A2BEE3DF60000CD31 /* bark in Frameworks */ = {isa = PBXBuildFile; productRef = E05A4F992BEE3DF60000CD31 /* bark */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E05A4F742BEE15150000CD31 /* bark.swiftui.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bark.swiftui.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E05A4F772BEE15150000CD31 /* bark_swiftuiApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = bark_swiftuiApp.swift; sourceTree = ""; }; + E05A4F792BEE15150000CD31 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + E05A4F7B2BEE15160000CD31 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E05A4F7E2BEE15160000CD31 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + E05A4F892BEE15BA0000CD31 /* LibBark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibBark.swift; sourceTree = ""; }; + E05A4F8B2BEE16590000CD31 /* BarkState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BarkState.swift; sourceTree = ""; }; + E05A4F942BEE284C0000CD31 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; + E05A4F972BEE3CB90000CD31 /* bark_swift_package */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = bark_swift_package; sourceTree = ""; }; + E05A4F982BEE3CCB0000CD31 /* bark-swiftui-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "bark-swiftui-Info.plist"; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E05A4F712BEE15150000CD31 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E05A4F9A2BEE3DF60000CD31 /* bark in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E05A4F6B2BEE15150000CD31 = { + isa = PBXGroup; + children = ( + E05A4F972BEE3CB90000CD31 /* bark_swift_package */, + E05A4F762BEE15150000CD31 /* bark.swiftui */, + E05A4F752BEE15150000CD31 /* Products */, + E05A4F862BEE156B0000CD31 /* Frameworks */, + ); + sourceTree = ""; + }; + E05A4F752BEE15150000CD31 /* Products */ = { + isa = PBXGroup; + children = ( + E05A4F742BEE15150000CD31 /* bark.swiftui.app */, + ); + name = Products; + sourceTree = ""; + }; + E05A4F762BEE15150000CD31 /* bark.swiftui */ = { + isa = PBXGroup; + children = ( + E05A4F982BEE3CCB0000CD31 /* bark-swiftui-Info.plist */, + E05A4F962BEE3A230000CD31 /* Bindings */, + E05A4F8E2BEE167A0000CD31 /* Views */, + E05A4F8D2BEE16640000CD31 /* Models */, + E05A4F772BEE15150000CD31 /* bark_swiftuiApp.swift */, + E05A4F7B2BEE15160000CD31 /* Assets.xcassets */, + E05A4F7D2BEE15160000CD31 /* Preview Content */, + ); + path = bark.swiftui; + sourceTree = ""; + }; + E05A4F7D2BEE15160000CD31 /* Preview Content */ = { + isa = PBXGroup; + children = ( + E05A4F7E2BEE15160000CD31 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + E05A4F862BEE156B0000CD31 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; + E05A4F8D2BEE16640000CD31 /* Models */ = { + isa = PBXGroup; + children = ( + E05A4F8B2BEE16590000CD31 /* BarkState.swift */, + E05A4F942BEE284C0000CD31 /* AudioPlayer.swift */, + ); + path = Models; + sourceTree = ""; + }; + E05A4F8E2BEE167A0000CD31 /* Views */ = { + isa = PBXGroup; + children = ( + E05A4F792BEE15150000CD31 /* ContentView.swift */, + ); + path = Views; + sourceTree = ""; + }; + E05A4F962BEE3A230000CD31 /* Bindings */ = { + isa = PBXGroup; + children = ( + E05A4F892BEE15BA0000CD31 /* LibBark.swift */, + ); + path = Bindings; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E05A4F732BEE15150000CD31 /* bark.swiftui */ = { + isa = PBXNativeTarget; + buildConfigurationList = E05A4F822BEE15160000CD31 /* Build configuration list for PBXNativeTarget "bark.swiftui" */; + buildPhases = ( + E05A4F702BEE15150000CD31 /* Sources */, + E05A4F712BEE15150000CD31 /* Frameworks */, + E05A4F722BEE15150000CD31 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = bark.swiftui; + packageProductDependencies = ( + E05A4F992BEE3DF60000CD31 /* bark */, + ); + productName = bark.swiftui; + productReference = E05A4F742BEE15150000CD31 /* bark.swiftui.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E05A4F6C2BEE15150000CD31 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1530; + LastUpgradeCheck = 1530; + TargetAttributes = { + E05A4F732BEE15150000CD31 = { + CreatedOnToolsVersion = 15.3; + }; + }; + }; + buildConfigurationList = E05A4F6F2BEE15150000CD31 /* Build configuration list for PBXProject "bark.swiftui" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E05A4F6B2BEE15150000CD31; + productRefGroup = E05A4F752BEE15150000CD31 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E05A4F732BEE15150000CD31 /* bark.swiftui */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E05A4F722BEE15150000CD31 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E05A4F7F2BEE15160000CD31 /* Preview Assets.xcassets in Resources */, + E05A4F7C2BEE15160000CD31 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E05A4F702BEE15150000CD31 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E05A4F7A2BEE15150000CD31 /* ContentView.swift in Sources */, + E05A4F782BEE15150000CD31 /* bark_swiftuiApp.swift in Sources */, + E05A4F952BEE284C0000CD31 /* AudioPlayer.swift in Sources */, + E05A4F8A2BEE15BA0000CD31 /* LibBark.swift in Sources */, + E05A4F8C2BEE16590000CD31 /* BarkState.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E05A4F802BEE15160000CD31 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + E05A4F812BEE15160000CD31 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E05A4F832BEE15160000CD31 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"bark.swiftui/Preview Content\""; + ENABLE_PREVIEWS = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "bark-swiftui-Info.plist"; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.PAB.bark-swiftui"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E05A4F842BEE15160000CD31 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"bark.swiftui/Preview Content\""; + ENABLE_PREVIEWS = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "bark-swiftui-Info.plist"; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + PRODUCT_BUNDLE_IDENTIFIER = "com.PAB.bark-swiftui"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E05A4F6F2BEE15150000CD31 /* Build configuration list for PBXProject "bark.swiftui" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E05A4F802BEE15160000CD31 /* Debug */, + E05A4F812BEE15160000CD31 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E05A4F822BEE15160000CD31 /* Build configuration list for PBXNativeTarget "bark.swiftui" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E05A4F832BEE15160000CD31 /* Debug */, + E05A4F842BEE15160000CD31 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + E05A4F992BEE3DF60000CD31 /* bark */ = { + isa = XCSwiftPackageProductDependency; + productName = bark; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = E05A4F6C2BEE15150000CD31 /* Project object */; +} diff --git a/examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/xcuserdata/pbannier.xcuserdatad/UserInterfaceState.xcuserstate b/examples/bark.swiftui/bark.swiftui.xcodeproj/project.xcworkspace/xcuserdata/pbannier.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..ec4aca1f917975d1e67d8387acfc02134432d20a GIT binary patch literal 106311 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 literal 0 HcmV?d00001 diff --git a/examples/bark.swiftui/bark.swiftui/Assets.xcassets/AccentColor.colorset/Contents.json b/examples/bark.swiftui/bark.swiftui/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/bark.swiftui/bark.swiftui/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/bark.swiftui/bark.swiftui/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/bark.swiftui/bark.swiftui/Assets.xcassets/Contents.json b/examples/bark.swiftui/bark.swiftui/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/bark.swiftui/bark.swiftui/Bindings/LibBark.swift b/examples/bark.swiftui/bark.swiftui/Bindings/LibBark.swift new file mode 100644 index 0000000..45e6e43 --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui/Bindings/LibBark.swift @@ -0,0 +1,49 @@ +import Foundation +import bark + +enum BarkError: Error { + case couldNotInitializeContext + case couldNotGenerateAudio +} + +actor BarkContext { + private var context: OpaquePointer + + init(context: OpaquePointer) { + self.context = context + } + + deinit { + bark_free(context) + } + + func generateAudio(text: String) throws -> [Float] { + // Leave 2 processors free (i.e. the high-efficiency cores). + let maxThreads = max(1, min(8, cpuCount() - 2)) + print("Using \(maxThreads) threads for audio generation") + let audioArray = try text.withCString { prompt in + if (bark_generate_audio(self.context, prompt, Int32(maxThreads))) { + let audio = bark_get_audio_data(self.context) + let audioLength = bark_get_audio_data_size(self.context) + return Array(UnsafeBufferPointer(start: audio, count: Int(audioLength))) + } else { + throw BarkError.couldNotGenerateAudio + } + } + return audioArray + } + + static func createContext(path: String, seed: Int) throws -> BarkContext { + let context = bark_load_model(path, bark_verbosity_level(0), UInt32(seed)) + if let context { + return BarkContext(context: context) + } else { + print("Couldn't load model at \(path)") + throw BarkError.couldNotInitializeContext + } + } +} + +fileprivate func cpuCount() -> Int { + ProcessInfo.processInfo.processorCount +} diff --git a/examples/bark.swiftui/bark.swiftui/Models/AudioPlayer.swift b/examples/bark.swiftui/bark.swiftui/Models/AudioPlayer.swift new file mode 100644 index 0000000..8d9a633 --- /dev/null +++ b/examples/bark.swiftui/bark.swiftui/Models/AudioPlayer.swift @@ -0,0 +1,53 @@ +// +// AudioPlayer.swift +// bark.swiftui +// +// Created by Pierre-Antoine BANNIER on 10/05/2024. +// + +import Foundation +import AVFoundation + +class AudioPlayer { + private var audioEngine: AVAudioEngine + private var playerNode: AVAudioPlayerNode + private var audioFormat: AVAudioFormat + + private var buffer: AVAudioPCMBuffer + + init(samples: [Float], sampleRate: Double = 24000.0) { + audioEngine = AVAudioEngine() + playerNode = AVAudioPlayerNode() + audioFormat = AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: 1)! + + // Setup the audio engine + audioEngine.attach(playerNode) + audioEngine.connect(playerNode, to: audioEngine.mainMixerNode, format: audioFormat) + + do { + try audioEngine.start() + } catch { + print("Error starting audio engine: \(error)") + } + + // Copy samples to the buffer + buffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: UInt32(samples.count))! + buffer.frameLength = buffer.frameCapacity + let channelData = buffer.floatChannelData![0] + + for i in 0..