Restructure as a UniFFI package

Regenerates the bindings against demucs-ffi, which renames the generated types with an Ffi prefix and the module to demucs_ffiFFI. Package.swift now uses a locally built DemucsFramework.xcframework when one is present and the release asset otherwise, and the Makefile builds that local framework from a sibling demucs-rs checkout. Also adds the Apache 2.0 license. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Seto committed Sep 26, 2026 at 14:42 UTC a3ebf240793c9afd38d0ebfabe95a580006d0998
5 files changed +706 -544
.gitignore
+6
@@ -1,2 +1,8 @@
1 .DS_Store
2 .build/
3 +.local/
4 +build/
5 +DerivedData/
6 +DemucsFramework.xcframework/
7 +Examples/DemucsExample/*.xcodeproj/
8 +*.xcresult
LICENSE new
+201
@@ -0,0 +1,201 @@
1 +
2 + Apache License
3 + Version 2.0, January 2004
4 + http://www.apache.org/licenses/
5 +
6 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 +
8 + 1. Definitions.
9 +
10 + "License" shall mean the terms and conditions for use, reproduction,
11 + and distribution as defined by Sections 1 through 9 of this document.
12 +
13 + "Licensor" shall mean the copyright owner or entity authorized by
14 + the copyright owner that is granting the License.
15 +
16 + "Legal Entity" shall mean the union of the acting entity and all
17 + other entities that control, are controlled by, or are under common
18 + control with that entity. For the purposes of this definition,
19 + "control" means (i) the power, direct or indirect, to cause the
20 + direction or management of such entity, whether by contract or
21 + otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 + outstanding shares, or (iii) beneficial ownership of such entity.
23 +
24 + "You" (or "Your") shall mean an individual or Legal Entity
25 + exercising permissions granted by this License.
26 +
27 + "Source" form shall mean the preferred form for making modifications,
28 + including but not limited to software source code, documentation
29 + source, and configuration files.
30 +
31 + "Object" form shall mean any form resulting from mechanical
32 + transformation or translation of a Source form, including but
33 + not limited to compiled object code, generated documentation,
34 + and conversions to other media types.
35 +
36 + "Work" shall mean the work of authorship, whether in Source or
37 + Object form, made available under the License, as indicated by a
38 + copyright notice that is included in or attached to the work
39 + (an example is provided in the Appendix below).
40 +
41 + "Derivative Works" shall mean any work, whether in Source or Object
42 + form, that is based on (or derived from) the Work and for which the
43 + editorial revisions, annotations, elaborations, or other modifications
44 + represent, as a whole, an original work of authorship. For the purposes
45 + of this License, Derivative Works shall not include works that remain
46 + separable from, or merely link (or bind by name) to the interfaces of,
47 + the Work and Derivative Works thereof.
48 +
49 + "Contribution" shall mean any work of authorship, including
50 + the original version of the Work and any modifications or additions
51 + to that Work or Derivative Works thereof, that is intentionally
52 + submitted to the Licensor for inclusion in the Work by the copyright owner
53 + or by an individual or Legal Entity authorized to submit on behalf of
54 + the copyright owner. For the purposes of this definition, "submitted"
55 + means any form of electronic, verbal, or written communication sent
56 + to the Licensor or its representatives, including but not limited to
57 + communication on electronic mailing lists, source code control systems,
58 + and issue tracking systems that are managed by, or on behalf of, the
59 + Licensor for the purpose of discussing and improving the Work, but
60 + excluding communication that is conspicuously marked or otherwise
61 + designated in writing by the copyright owner as "Not a Contribution."
62 +
63 + "Contributor" shall mean Licensor and any individual or Legal Entity
64 + on behalf of whom a Contribution has been received by the Licensor and
65 + subsequently incorporated within the Work.
66 +
67 + 2. Grant of Copyright License. Subject to the terms and conditions of
68 + this License, each Contributor hereby grants to You a perpetual,
69 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 + copyright license to reproduce, prepare Derivative Works of,
71 + publicly display, publicly perform, sublicense, and distribute the
72 + Work and such Derivative Works in Source or Object form.
73 +
74 + 3. Grant of Patent License. Subject to the terms and conditions of
75 + this License, each Contributor hereby grants to You a perpetual,
76 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 + (except as stated in this section) patent license to make, have made,
78 + use, offer to sell, sell, import, and otherwise transfer the Work,
79 + where such license applies only to those patent claims licensable
80 + by such Contributor that are necessarily infringed by their
81 + Contribution(s) alone or by combination of their Contribution(s)
82 + with the Work to which such Contribution(s) was submitted. If You
83 + institute patent litigation against any entity (including a
84 + cross-claim or counterclaim in a lawsuit) alleging that the Work
85 + or a Contribution incorporated within the Work constitutes direct
86 + or contributory patent infringement, then any patent licenses
87 + granted to You under this License for that Work shall terminate
88 + as of the date such litigation is filed.
89 +
90 + 4. Redistribution. You may reproduce and distribute copies of the
91 + Work or Derivative Works thereof in any medium, with or without
92 + modifications, and in Source or Object form, provided that You
93 + meet the following conditions:
94 +
95 + (a) You must give any other recipients of the Work or
96 + Derivative Works a copy of this License; and
97 +
98 + (b) You must cause any modified files to carry prominent notices
99 + stating that You changed the files; and
100 +
101 + (c) You must retain, in the Source form of any Derivative Works
102 + that You distribute, all copyright, patent, trademark, and
103 + attribution notices from the Source form of the Work,
104 + excluding those notices that do not pertain to any part of
105 + the Derivative Works; and
106 +
107 + (d) If the Work includes a "NOTICE" text file as part of its
108 + distribution, then any Derivative Works that You distribute must
109 + include a readable copy of the attribution notices contained
110 + within such NOTICE file, excluding any notices that do not
111 + pertain to any part of the Derivative Works, in at least one
112 + of the following places: within a NOTICE text file distributed
113 + as part of the Derivative Works; within the Source form or
114 + documentation, if provided along with the Derivative Works; or,
115 + within a display generated by the Derivative Works, if and
116 + wherever such third-party notices normally appear. The contents
117 + of the NOTICE file are for informational purposes only and
118 + do not modify the License. You may add Your own attribution
119 + notices within Derivative Works that You distribute, alongside
120 + or as an addendum to the NOTICE text from the Work, provided
121 + that such additional attribution notices cannot be construed
122 + as modifying the License.
123 +
124 + You may add Your own copyright statement to Your modifications and
125 + may provide additional or different license terms and conditions
126 + for use, reproduction, or distribution of Your modifications, or
127 + for any such Derivative Works as a whole, provided Your use,
128 + reproduction, and distribution of the Work otherwise complies with
129 + the conditions stated in this License.
130 +
131 + 5. Submission of Contributions. Unless You explicitly state otherwise,
132 + any Contribution intentionally submitted for inclusion in the Work
133 + by You to the Licensor shall be under the terms and conditions of
134 + this License, without any additional terms or conditions.
135 + Notwithstanding the above, nothing herein shall supersede or modify
136 + the terms of any separate license agreement you may have executed
137 + with Licensor regarding such Contributions.
138 +
139 + 6. Trademarks. This License does not grant permission to use the trade
140 + names, trademarks, service marks, or product names of the Licensor,
141 + except as required for reasonable and customary use in describing the
142 + origin of the Work and reproducing the content of the NOTICE file.
143 +
144 + 7. Disclaimer of Warranty. Unless required by applicable law or
145 + agreed to in writing, Licensor provides the Work (and each
146 + Contributor provides its Contributions) on an "AS IS" BASIS,
147 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 + implied, including, without limitation, any warranties or conditions
149 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 + PARTICULAR PURPOSE. You are solely responsible for determining the
151 + appropriateness of using or redistributing the Work and assume any
152 + risks associated with Your exercise of permissions under this License.
153 +
154 + 8. Limitation of Liability. In no event and under no legal theory,
155 + whether in tort (including negligence), contract, or otherwise,
156 + unless required by applicable law (such as deliberate and grossly
157 + negligent acts) or agreed to in writing, shall any Contributor be
158 + liable to You for damages, including any direct, indirect, special,
159 + incidental, or consequential damages of any character arising as a
160 + result of this License or out of the use or inability to use the
161 + Work (including but not limited to damages for loss of goodwill,
162 + work stoppage, computer failure or malfunction, or any and all
163 + other commercial damages or losses), even if such Contributor
164 + has been advised of the possibility of such damages.
165 +
166 + 9. Accepting Warranty or Additional Liability. While redistributing
167 + the Work or Derivative Works thereof, You may choose to offer,
168 + and charge a fee for, acceptance of support, warranty, indemnity,
169 + or other liability obligations and/or rights consistent with this
170 + License. However, in accepting such obligations, You may act only
171 + on Your own behalf and on Your sole responsibility, not on behalf
172 + of any other Contributor, and only if You agree to indemnify,
173 + defend, and hold each Contributor harmless for any liability
174 + incurred by, or claims asserted against, such Contributor by reason
175 + of your accepting any such warranty or additional liability.
176 +
177 + END OF TERMS AND CONDITIONS
178 +
179 + APPENDIX: How to apply the Apache License to your work.
180 +
181 + To apply the Apache License to your work, attach the following
182 + boilerplate notice, with the fields enclosed by brackets "[]"
183 + replaced with your own identifying information. (Don't include
184 + the brackets!) The text should be enclosed in the appropriate
185 + comment syntax for the file format. Please also get an OpenPGP
186 + key ID from https://keyserver.ubuntu.com and add it to the file,
187 + along with an "or later" clause for future license compatibility.
188 +
189 + Copyright [yyyy] [name of copyright owner]
190 +
191 + Licensed under the Apache License, Version 2.0 (the "License");
192 + you may not use this file except in compliance with the License.
193 + You may obtain a copy of the License at
194 +
195 + http://www.apache.org/licenses/LICENSE-2.0
196 +
197 + Unless required by applicable law or agreed to in writing, software
198 + distributed under the License is distributed on an "AS IS" BASIS,
199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 + See the License for the specific language governing permissions and
201 + limitations under the License.
Makefile new
+92
@@ -0,0 +1,92 @@
1 +SHELL := /bin/sh
2 +
3 +SWIFT_REPO := $(CURDIR)
4 +DEMUCS_REPO ?= $(abspath ../demucs-rs)
5 +MANIFEST := $(DEMUCS_REPO)/demucs-ffi/Cargo.toml
6 +BINDGEN_MANIFEST := $(DEMUCS_REPO)/uniffi-bindgen/Cargo.toml
7 +BINDGEN := $(DEMUCS_REPO)/target/release/uniffi-bindgen
8 +APPLE_TARGET_DIR := $(DEMUCS_REPO)/target/apple
9 +LIB_NAME := libdemucs_ffi.a
10 +
11 +IOS_DEPLOYMENT_TARGET ?= 16.0
12 +MACOS_DEPLOYMENT_TARGET ?= 14.0
13 +TVOS_DEPLOYMENT_TARGET ?= 16.0
14 +VISIONOS_DEPLOYMENT_TARGET ?= 1.0
15 +
16 +LOCAL_DIR := $(SWIFT_REPO)/.local
17 +GENERATED_DIR := $(LOCAL_DIR)/generated/Demucs
18 +HEADERS_DIR := $(LOCAL_DIR)/Headers
19 +FRAMEWORK_DIR := $(SWIFT_REPO)/DemucsFramework.xcframework
20 +SWIFT_GLUE := $(SWIFT_REPO)/Sources/Demucs/demucs_ffi.swift
21 +
22 +# demucs-rs's .cargo/config.toml builds macOS with `-C target-cpu=native`;
23 +# clear it so a local framework behaves like the released one.
24 +export CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS :=
25 +
26 +# $(call rustc,<target>,<deployment env>,<extra cargo args>)
27 +rustc = $(2) cargo $(3) rustc --target-dir "$(APPLE_TARGET_DIR)" --manifest-path "$(MANIFEST)" --target $(1) --release --lib --crate-type staticlib
28 +lib = $(APPLE_TARGET_DIR)/$(1)/release/$(LIB_NAME)
29 +
30 +.PHONY: help validate ios macos tvos visionos build-bindgen prepare generate-swift clean
31 +
32 +help:
33 + @printf '%s\n' \
34 + 'Demucs Swift local builds' \
35 + '' \
36 + 'make ios | macos | tvos | visionos' \
37 + 'Set DEMUCS_REPO=/path/to/demucs-rs when the repositories are not siblings.'
38 +
39 +validate:
40 + @test -f "$(MANIFEST)" || { echo "Could not find demucs-rs at $(DEMUCS_REPO)"; exit 1; }
41 +
42 +build-bindgen: validate
43 + cargo build --manifest-path "$(BINDGEN_MANIFEST)" --release
44 +
45 +prepare:
46 + @rm -rf "$(FRAMEWORK_DIR)" "$(GENERATED_DIR)" "$(HEADERS_DIR)"
47 + @mkdir -p "$(GENERATED_DIR)" "$(HEADERS_DIR)"
48 +
49 +generate-swift:
50 + @test -n "$(BINDGEN_INPUT)" || { echo "BINDGEN_INPUT is required"; exit 1; }
51 + cd "$(DEMUCS_REPO)" && "$(BINDGEN)" generate "$(BINDGEN_INPUT)" --crate demucs_ffi --language swift --out-dir "$(GENERATED_DIR)"
52 + cp "$(GENERATED_DIR)/demucs_ffi.swift" "$(SWIFT_GLUE)"
53 + cp "$(GENERATED_DIR)/demucs_ffiFFI.h" "$(HEADERS_DIR)/demucs_ffiFFI.h"
54 + cp "$(GENERATED_DIR)/demucs_ffiFFI.modulemap" "$(HEADERS_DIR)/module.modulemap"
55 +
56 +ios: build-bindgen prepare
57 + $(call rustc,aarch64-apple-ios,IPHONEOS_DEPLOYMENT_TARGET=$(IOS_DEPLOYMENT_TARGET))
58 + $(call rustc,aarch64-apple-ios-sim,IPHONEOS_DEPLOYMENT_TARGET=$(IOS_DEPLOYMENT_TARGET))
59 + $(MAKE) generate-swift BINDGEN_INPUT="$(call lib,aarch64-apple-ios)"
60 + xcodebuild -create-xcframework \
61 + -library "$(call lib,aarch64-apple-ios)" -headers "$(HEADERS_DIR)" \
62 + -library "$(call lib,aarch64-apple-ios-sim)" -headers "$(HEADERS_DIR)" \
63 + -output "$(FRAMEWORK_DIR)"
64 +
65 +macos: build-bindgen prepare
66 + $(call rustc,aarch64-apple-darwin,MACOSX_DEPLOYMENT_TARGET=$(MACOS_DEPLOYMENT_TARGET))
67 + $(MAKE) generate-swift BINDGEN_INPUT="$(call lib,aarch64-apple-darwin)"
68 + xcodebuild -create-xcframework \
69 + -library "$(call lib,aarch64-apple-darwin)" -headers "$(HEADERS_DIR)" \
70 + -output "$(FRAMEWORK_DIR)"
71 +
72 +# tvOS and visionOS are tier 3 targets: no prebuilt std, so nightly + build-std.
73 +tvos: build-bindgen prepare
74 + $(call rustc,aarch64-apple-tvos,TVOS_DEPLOYMENT_TARGET=$(TVOS_DEPLOYMENT_TARGET),+nightly -Z build-std)
75 + $(call rustc,aarch64-apple-tvos-sim,TVOS_DEPLOYMENT_TARGET=$(TVOS_DEPLOYMENT_TARGET),+nightly -Z build-std)
76 + $(MAKE) generate-swift BINDGEN_INPUT="$(call lib,aarch64-apple-tvos)"
77 + xcodebuild -create-xcframework \
78 + -library "$(call lib,aarch64-apple-tvos)" -headers "$(HEADERS_DIR)" \
79 + -library "$(call lib,aarch64-apple-tvos-sim)" -headers "$(HEADERS_DIR)" \
80 + -output "$(FRAMEWORK_DIR)"
81 +
82 +visionos: build-bindgen prepare
83 + $(call rustc,aarch64-apple-visionos,XROS_DEPLOYMENT_TARGET=$(VISIONOS_DEPLOYMENT_TARGET),+nightly -Z build-std)
84 + $(call rustc,aarch64-apple-visionos-sim,XROS_DEPLOYMENT_TARGET=$(VISIONOS_DEPLOYMENT_TARGET),+nightly -Z build-std)
85 + $(MAKE) generate-swift BINDGEN_INPUT="$(call lib,aarch64-apple-visionos)"
86 + xcodebuild -create-xcframework \
87 + -library "$(call lib,aarch64-apple-visionos)" -headers "$(HEADERS_DIR)" \
88 + -library "$(call lib,aarch64-apple-visionos-sim)" -headers "$(HEADERS_DIR)" \
89 + -output "$(FRAMEWORK_DIR)"
90 +
91 +clean:
92 + rm -rf "$(FRAMEWORK_DIR)" "$(LOCAL_DIR)"
Package.swift
+45 -20
@@ -1,20 +1,34 @@
1 -// swift-tools-version:5.9
1 +// swift-tools-version:6.2
2 +import Foundation
3 import PackageDescription
4
4 -// These two constants are rewritten automatically by the demucs-rs
5 -// "Release SDK Swift" workflow on every release. Do not reformat them —
6 -// the rewrite regex depends on this exact layout.
7 -//
8 -// For local development against a locally built framework, comment out the
9 -// url/checksum binaryTarget below and use the path form instead:
10 -// .binaryTarget(name: "DemucsFramework", path: "../demucs-rs/dist/swift/DemucsFramework.xcframework"),
11 -// (run .github/scripts/build-swift-xcframework.sh in demucs-rs first).
12 -// Never commit the path form — CI overwrites this file on every release.
5 +let packageRoot = URL(fileURLWithPath: #filePath).deletingLastPathComponent()
6 +let localFrameworkPath = "DemucsFramework.xcframework"
7 +let localFrameworkAbsolutePath = packageRoot.appendingPathComponent(localFrameworkPath).path
8 +
9 +// Updated automatically by demucs-rs's release-sdk-swift workflow. Keep the
10 +// layout: the workflow rewrites the quoted string on the line after each `let`.
11 let releaseFrameworkURL =
14 - "https://github.com/ondeinference/demucs-rs/releases/download/swift-0.1.0/DemucsFramework.xcframework.zip"
12 + "https://github.com/SplitFireAI/demucs-rs/releases/download/swift-v0.1.0/DemucsFramework.xcframework.zip"
13 let releaseFrameworkChecksum =
14 "0000000000000000000000000000000000000000000000000000000000000000"
15
16 +// `make macos` (or ios, tvos, visionos) drops a locally built framework next to
17 +// this file; SwiftPM uses it when present and the release asset otherwise.
18 +let demucsFrameworkTarget: Target
19 +if FileManager.default.fileExists(atPath: localFrameworkAbsolutePath) {
20 + demucsFrameworkTarget = .binaryTarget(
21 + name: "DemucsFramework",
22 + path: localFrameworkPath
23 + )
24 +} else {
25 + demucsFrameworkTarget = .binaryTarget(
26 + name: "DemucsFramework",
27 + url: releaseFrameworkURL,
28 + checksum: releaseFrameworkChecksum
29 + )
30 +}
31 +
32 let package = Package(
33 name: "Demucs",
34 platforms: [
@@ -24,18 +38,29 @@ let package = Package(
38 .visionOS(.v1),
39 ],
40 products: [
27 - .library(name: "Demucs", targets: ["Demucs"])
41 + .library(name: "Demucs", targets: ["Demucs"]),
42 ],
43 targets: [
30 - .binaryTarget(
31 - name: "DemucsFramework",
32 - url: releaseFrameworkURL,
33 - checksum: releaseFrameworkChecksum
34 - ),
44 + demucsFrameworkTarget,
45 .target(
46 name: "Demucs",
37 - dependencies: ["DemucsFramework"],
38 - path: "Sources/Demucs"
47 + dependencies: [.target(name: "DemucsFramework")],
48 + path: "Sources/Demucs",
49 + linkerSettings: [
50 + // wgpu's Metal backend.
51 + .linkedFramework("Metal"),
52 + .linkedFramework("QuartzCore"),
53 + .linkedFramework("CoreGraphics"),
54 + .linkedFramework("IOKit", .when(platforms: [.macOS])),
55 + // native-tls (weight downloads) and the Rust standard library.
56 + .linkedFramework("CoreFoundation"),
57 + .linkedFramework("Foundation"),
58 + .linkedFramework("Security"),
59 + ]
60 ),
40 - ]
61 + ],
62 + // UniFFI 0.31's generated bindings predate Swift 6's region isolation
63 + // checks. The hand-written Demucs API is concurrency-safe; the generated
64 + // bridge compiles in Swift 5 language mode until UniFFI updates.
65 + swiftLanguageModes: [.v5]
66 )
Sources/Demucs/demucs_ffi.swift renamed
+362 -524
@@ -7,8 +7,8 @@ import Foundation
7 // Depending on the consumer's build setup, the low-level FFI code
8 // might be in a separate module, or it might be compiled inline into
9 // this module. This is a bit of light hackery to work with both.
10 -#if canImport(demucsFFI)
11 -import demucsFFI
10 +#if canImport(demucs_ffiFFI)
11 +import demucs_ffiFFI
12 #endif
13
14 fileprivate extension RustBuffer {
@@ -25,13 +25,13 @@ fileprivate extension RustBuffer {
25 }
26
27 static func from(_ ptr: UnsafeBufferPointer<UInt8>) -> RustBuffer {
28 - try! rustCall { ffi_demucs_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
28 + try! rustCall { ffi_demucs_ffi_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
29 }
30
31 // Frees the buffer in place.
32 // The buffer must not be used after this is called.
33 func deallocate() {
34 - try! rustCall { ffi_demucs_rustbuffer_free(self, $0) }
34 + try! rustCall { ffi_demucs_ffi_rustbuffer_free(self, $0) }
35 }
36 }
37
@@ -281,7 +281,7 @@ private func makeRustCall<T, E: Swift.Error>(
281 _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T,
282 errorHandler: ((RustBuffer) throws -> E)?
283 ) throws -> T {
284 - uniffiEnsureDemucsInitialized()
284 + uniffiEnsureDemucsFfiInitialized()
285 var callStatus = RustCallStatus.init()
286 let returnedVal = callback(&callStatus)
287 try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler)
@@ -555,74 +555,55 @@ fileprivate struct FfiConverterString: FfiConverter {
555
556
557 /**
558 - * Thread-safe HTDemucs source-separation engine.
558 + * Holds at most one loaded model.
559 *
560 - * Typical lifecycle from Swift:
561 - * ```swift
562 - * configureCacheDir(path: appSupportDir) // sandboxed platforms
563 - * try await downloadModel(model: .fourStem, listener: dl)
564 - * let engine = DemucsEngine()
565 - * let secs = try await engine.loadModel(model: .fourStem)
566 - * try await engine.warmup()
567 - * let stems = try await engine.separate(left: l, right: r, sampleRate: 44100)
568 - * ```
560 + * burn modules are `Send` but not `Sync` (parameters sit in a `OnceCell`), so
561 + * the model lives behind a `Mutex` and each operation holds it for its whole
562 + * run: loads, warmups and separations on one engine happen one at a time.
563 + * The loaded model's identity is kept apart so status queries never wait on
564 + * a separation.
565 */
570 -public protocol DemucsEngineProtocol: AnyObject, Sendable {
566 +public protocol FfiDemucsEngineProtocol: AnyObject, Sendable {
567
572 - func isLoaded() async -> Bool
568 + func isLoaded() -> Bool
569
570 /**
575 - * Load a model's weights from the local cache into memory (and onto the
576 - * GPU device). Errors with `NotCached` if `downloadModel` has not been
577 - * run for this model. Returns the wall-clock load time in seconds.
571 + * Loads a downloaded model, replacing any model already loaded. Returns
572 + * the load time in seconds. Fails with `NotCached` if the weights have
573 + * not been downloaded yet.
574 */
579 - func loadModel(model: DemucsModel) async throws -> Double
575 + func loadModel(model: FfiDemucsModel) async throws -> Double
576
581 - /**
582 - * The model currently loaded, if any.
583 - */
584 - func loadedModel() async -> DemucsModel?
577 + func loadedModel() -> FfiDemucsModel?
578
579 /**
587 - * Separate a stereo track into stems.
588 - *
589 - * `left` and `right` are per-channel PCM samples (any sample rate;
590 - * resampled to 44100 Hz internally). Mono input: pass the same samples
591 - * for both channels. Output stems are stereo PCM at 44100 Hz.
592 - *
593 - * Holds the engine lock for the whole separation, so concurrent calls
594 - * on one engine serialize.
580 + * Separates stereo PCM at any sample rate. Both channels must have the
581 + * same, non-zero length; pass the same buffer twice for mono.
582 */
596 - func separate(left: [Float], right: [Float], sampleRate: UInt32) async throws -> [StemResult]
583 + func separate(left: [Float], right: [Float], sampleRate: UInt32, listener: FfiSeparationListener) async throws -> [FfiStem]
584
585 /**
599 - * Drop the loaded model, freeing CPU and GPU memory. Returns true if a
600 - * model was loaded.
586 + * Frees the loaded model. Returns `false` if nothing was loaded.
587 */
588 func unloadModel() async -> Bool
589
590 /**
605 - * Run the full pipeline once on synthetic audio to pre-compile GPU
606 - * shaders and resolve autotune. Optional but recommended before the
607 - * first `separate` call; takes a few seconds on first run.
591 + * Runs a dummy separation so the first real one does not pay for shader
592 + * compilation.
593 */
594 func warmup() async throws
595
596 }
597 /**
613 - * Thread-safe HTDemucs source-separation engine.
598 + * Holds at most one loaded model.
599 *
615 - * Typical lifecycle from Swift:
616 - * ```swift
617 - * configureCacheDir(path: appSupportDir) // sandboxed platforms
618 - * try await downloadModel(model: .fourStem, listener: dl)
619 - * let engine = DemucsEngine()
620 - * let secs = try await engine.loadModel(model: .fourStem)
621 - * try await engine.warmup()
622 - * let stems = try await engine.separate(left: l, right: r, sampleRate: 44100)
623 - * ```
600 + * burn modules are `Send` but not `Sync` (parameters sit in a `OnceCell`), so
601 + * the model lives behind a `Mutex` and each operation holds it for its whole
602 + * run: loads, warmups and separations on one engine happen one at a time.
603 + * The loaded model's identity is kept apart so status queries never wait on
604 + * a separation.
605 */
625 -open class DemucsEngine: DemucsEngineProtocol, @unchecked Sendable {
606 +open class FfiDemucsEngine: FfiDemucsEngineProtocol, @unchecked Sendable {
607 fileprivate let handle: UInt64
608
609 /// Used to instantiate a [FFIObject] without an actual handle, for fakes in tests, mostly.
@@ -659,12 +640,12 @@ open class DemucsEngine: DemucsEngineProtocol, @unchecked Sendable {
640 @_documentation(visibility: private)
641 #endif
642 public func uniffiCloneHandle() -> UInt64 {
662 - return try! rustCall { uniffi_demucs_fn_clone_demucsengine(self.handle, $0) }
643 + return try! rustCall { uniffi_demucs_ffi_fn_clone_ffidemucsengine(self.handle, $0) }
644 }
645 public convenience init() {
646 let handle =
647 try! rustCall() {
667 - uniffi_demucs_fn_constructor_demucsengine_new($0
648 + uniffi_demucs_ffi_fn_constructor_ffidemucsengine_new($0
649 )
650 }
651 self.init(unsafeFromHandle: handle)
@@ -676,116 +657,86 @@ public convenience init() {
657 return
658 }
659
679 - try! rustCall { uniffi_demucs_fn_free_demucsengine(handle, $0) }
660 + try! rustCall { uniffi_demucs_ffi_fn_free_ffidemucsengine(handle, $0) }
661 }
662
663
664
665
685 -open func isLoaded()async -> Bool {
686 - return
687 - try! await uniffiRustCallAsync(
688 - rustFutureFunc: {
689 - uniffi_demucs_fn_method_demucsengine_is_loaded(
690 - self.uniffiCloneHandle()
691 -
692 - )
693 - },
694 - pollFunc: ffi_demucs_rust_future_poll_i8,
695 - completeFunc: ffi_demucs_rust_future_complete_i8,
696 - freeFunc: ffi_demucs_rust_future_free_i8,
697 - liftFunc: FfiConverterBool.lift,
698 - errorHandler: nil
699 -
700 - )
666 +open func isLoaded() -> Bool {
667 + return try! FfiConverterBool.lift(try! rustCall() {
668 + uniffi_demucs_ffi_fn_method_ffidemucsengine_is_loaded(
669 + self.uniffiCloneHandle(),$0
670 + )
671 +})
672 }
673
674 /**
704 - * Load a model's weights from the local cache into memory (and onto the
705 - * GPU device). Errors with `NotCached` if `downloadModel` has not been
706 - * run for this model. Returns the wall-clock load time in seconds.
675 + * Loads a downloaded model, replacing any model already loaded. Returns
676 + * the load time in seconds. Fails with `NotCached` if the weights have
677 + * not been downloaded yet.
678 */
708 -open func loadModel(model: DemucsModel)async throws -> Double {
679 +open func loadModel(model: FfiDemucsModel)async throws -> Double {
680 return
681 try await uniffiRustCallAsync(
682 rustFutureFunc: {
712 - uniffi_demucs_fn_method_demucsengine_load_model(
683 + uniffi_demucs_ffi_fn_method_ffidemucsengine_load_model(
684 self.uniffiCloneHandle(),
714 - FfiConverterTypeDemucsModel_lower(model)
685 + FfiConverterTypeFfiDemucsModel_lower(model)
686 )
687 },
717 - pollFunc: ffi_demucs_rust_future_poll_f64,
718 - completeFunc: ffi_demucs_rust_future_complete_f64,
719 - freeFunc: ffi_demucs_rust_future_free_f64,
688 + pollFunc: ffi_demucs_ffi_rust_future_poll_f64,
689 + completeFunc: ffi_demucs_ffi_rust_future_complete_f64,
690 + freeFunc: ffi_demucs_ffi_rust_future_free_f64,
691 liftFunc: FfiConverterDouble.lift,
721 - errorHandler: FfiConverterTypeDemucsFfiError_lift
692 + errorHandler: FfiConverterTypeFfiDemucsError_lift
693 )
694 }
695
725 - /**
726 - * The model currently loaded, if any.
727 - */
728 -open func loadedModel()async -> DemucsModel? {
729 - return
730 - try! await uniffiRustCallAsync(
731 - rustFutureFunc: {
732 - uniffi_demucs_fn_method_demucsengine_loaded_model(
733 - self.uniffiCloneHandle()
734 -
735 - )
736 - },
737 - pollFunc: ffi_demucs_rust_future_poll_rust_buffer,
738 - completeFunc: ffi_demucs_rust_future_complete_rust_buffer,
739 - freeFunc: ffi_demucs_rust_future_free_rust_buffer,
740 - liftFunc: FfiConverterOptionTypeDemucsModel.lift,
741 - errorHandler: nil
742 -
743 - )
696 +open func loadedModel() -> FfiDemucsModel? {
697 + return try! FfiConverterOptionTypeFfiDemucsModel.lift(try! rustCall() {
698 + uniffi_demucs_ffi_fn_method_ffidemucsengine_loaded_model(
699 + self.uniffiCloneHandle(),$0
700 + )
701 +})
702 }
703
704 /**
747 - * Separate a stereo track into stems.
748 - *
749 - * `left` and `right` are per-channel PCM samples (any sample rate;
750 - * resampled to 44100 Hz internally). Mono input: pass the same samples
751 - * for both channels. Output stems are stereo PCM at 44100 Hz.
752 - *
753 - * Holds the engine lock for the whole separation, so concurrent calls
754 - * on one engine serialize.
705 + * Separates stereo PCM at any sample rate. Both channels must have the
706 + * same, non-zero length; pass the same buffer twice for mono.
707 */
756 -open func separate(left: [Float], right: [Float], sampleRate: UInt32)async throws -> [StemResult] {
708 +open func separate(left: [Float], right: [Float], sampleRate: UInt32, listener: FfiSeparationListener)async throws -> [FfiStem] {
709 return
710 try await uniffiRustCallAsync(
711 rustFutureFunc: {
760 - uniffi_demucs_fn_method_demucsengine_separate(
712 + uniffi_demucs_ffi_fn_method_ffidemucsengine_separate(
713 self.uniffiCloneHandle(),
762 - FfiConverterSequenceFloat.lower(left),FfiConverterSequenceFloat.lower(right),FfiConverterUInt32.lower(sampleRate)
714 + FfiConverterSequenceFloat.lower(left),FfiConverterSequenceFloat.lower(right),FfiConverterUInt32.lower(sampleRate),FfiConverterCallbackInterfaceFfiSeparationListener_lower(listener)
715 )
716 },
765 - pollFunc: ffi_demucs_rust_future_poll_rust_buffer,
766 - completeFunc: ffi_demucs_rust_future_complete_rust_buffer,
767 - freeFunc: ffi_demucs_rust_future_free_rust_buffer,
768 - liftFunc: FfiConverterSequenceTypeStemResult.lift,
769 - errorHandler: FfiConverterTypeDemucsFfiError_lift
717 + pollFunc: ffi_demucs_ffi_rust_future_poll_rust_buffer,
718 + completeFunc: ffi_demucs_ffi_rust_future_complete_rust_buffer,
719 + freeFunc: ffi_demucs_ffi_rust_future_free_rust_buffer,
720 + liftFunc: FfiConverterSequenceTypeFfiStem.lift,
721 + errorHandler: FfiConverterTypeFfiDemucsError_lift
722 )
723 }
724
725 /**
774 - * Drop the loaded model, freeing CPU and GPU memory. Returns true if a
775 - * model was loaded.
726 + * Frees the loaded model. Returns `false` if nothing was loaded.
727 */
728 open func unloadModel()async -> Bool {
729 return
730 try! await uniffiRustCallAsync(
731 rustFutureFunc: {
781 - uniffi_demucs_fn_method_demucsengine_unload_model(
732 + uniffi_demucs_ffi_fn_method_ffidemucsengine_unload_model(
733 self.uniffiCloneHandle()
734
735 )
736 },
786 - pollFunc: ffi_demucs_rust_future_poll_i8,
787 - completeFunc: ffi_demucs_rust_future_complete_i8,
788 - freeFunc: ffi_demucs_rust_future_free_i8,
737 + pollFunc: ffi_demucs_ffi_rust_future_poll_i8,
738 + completeFunc: ffi_demucs_ffi_rust_future_complete_i8,
739 + freeFunc: ffi_demucs_ffi_rust_future_free_i8,
740 liftFunc: FfiConverterBool.lift,
741 errorHandler: nil
742
@@ -793,24 +744,23 @@ open func unloadModel()async -> Bool {
744 }
745
746 /**
796 - * Run the full pipeline once on synthetic audio to pre-compile GPU
797 - * shaders and resolve autotune. Optional but recommended before the
798 - * first `separate` call; takes a few seconds on first run.
747 + * Runs a dummy separation so the first real one does not pay for shader
748 + * compilation.
749 */
750 open func warmup()async throws {
751 return
752 try await uniffiRustCallAsync(
753 rustFutureFunc: {
804 - uniffi_demucs_fn_method_demucsengine_warmup(
754 + uniffi_demucs_ffi_fn_method_ffidemucsengine_warmup(
755 self.uniffiCloneHandle()
756
757 )
758 },
809 - pollFunc: ffi_demucs_rust_future_poll_void,
810 - completeFunc: ffi_demucs_rust_future_complete_void,
811 - freeFunc: ffi_demucs_rust_future_free_void,
759 + pollFunc: ffi_demucs_ffi_rust_future_poll_void,
760 + completeFunc: ffi_demucs_ffi_rust_future_complete_void,
761 + freeFunc: ffi_demucs_ffi_rust_future_free_void,
762 liftFunc: { $0 },
813 - errorHandler: FfiConverterTypeDemucsFfiError_lift
763 + errorHandler: FfiConverterTypeFfiDemucsError_lift
764 )
765 }
766
@@ -822,24 +772,24 @@ open func warmup()async throws {
772 #if swift(>=5.8)
773 @_documentation(visibility: private)
774 #endif
825 -public struct FfiConverterTypeDemucsEngine: FfiConverter {
775 +public struct FfiConverterTypeFfiDemucsEngine: FfiConverter {
776 typealias FfiType = UInt64
827 - typealias SwiftType = DemucsEngine
777 + typealias SwiftType = FfiDemucsEngine
778
829 - public static func lift(_ handle: UInt64) throws -> DemucsEngine {
830 - return DemucsEngine(unsafeFromHandle: handle)
779 + public static func lift(_ handle: UInt64) throws -> FfiDemucsEngine {
780 + return FfiDemucsEngine(unsafeFromHandle: handle)
781 }
782
833 - public static func lower(_ value: DemucsEngine) -> UInt64 {
783 + public static func lower(_ value: FfiDemucsEngine) -> UInt64 {
784 return value.uniffiCloneHandle()
785 }
786
837 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DemucsEngine {
787 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiDemucsEngine {
788 let handle: UInt64 = try readInt(&buf)
789 return try lift(handle)
790 }
791
842 - public static func write(_ value: DemucsEngine, into buf: inout [UInt8]) {
792 + public static func write(_ value: FfiDemucsEngine, into buf: inout [UInt8]) {
793 writeInt(&buf, lower(value))
794 }
795 }
@@ -848,48 +798,39 @@ public struct FfiConverterTypeDemucsEngine: FfiConverter {
798 #if swift(>=5.8)
799 @_documentation(visibility: private)
800 #endif
851 -public func FfiConverterTypeDemucsEngine_lift(_ handle: UInt64) throws -> DemucsEngine {
852 - return try FfiConverterTypeDemucsEngine.lift(handle)
801 +public func FfiConverterTypeFfiDemucsEngine_lift(_ handle: UInt64) throws -> FfiDemucsEngine {
802 + return try FfiConverterTypeFfiDemucsEngine.lift(handle)
803 }
804
805 #if swift(>=5.8)
806 @_documentation(visibility: private)
807 #endif
858 -public func FfiConverterTypeDemucsEngine_lower(_ value: DemucsEngine) -> UInt64 {
859 - return FfiConverterTypeDemucsEngine.lower(value)
808 +public func FfiConverterTypeFfiDemucsEngine_lower(_ value: FfiDemucsEngine) -> UInt64 {
809 + return FfiConverterTypeFfiDemucsEngine.lower(value)
810 }
811
812
813
814
865 -/**
866 - * Progress payload for weight downloads.
867 - */
868 -public struct DownloadProgress: Equatable, Hashable {
815 +public struct FfiDownloadProgress: Equatable, Hashable {
816 public var downloadedBytes: UInt64
817 /**
871 - * 0 when the server did not report a Content-Length.
818 + * From `Content-Length`, or the model's nominal size when the server
819 + * does not send one.
820 */
821 public var totalBytes: UInt64
874 - /**
875 - * 0.0–1.0, or 0.0 when the total is unknown.
876 - */
822 public var fraction: Double
878 - public var done: Bool
823
824 // Default memberwise initializers are never public by default, so we
825 // declare one manually.
826 public init(downloadedBytes: UInt64,
827 /**
884 - * 0 when the server did not report a Content-Length.
885 - */totalBytes: UInt64,
886 - /**
887 - * 0.0–1.0, or 0.0 when the total is unknown.
888 - */fraction: Double, done: Bool) {
828 + * From `Content-Length`, or the model's nominal size when the server
829 + * does not send one.
830 + */totalBytes: UInt64, fraction: Double) {
831 self.downloadedBytes = downloadedBytes
832 self.totalBytes = totalBytes
833 self.fraction = fraction
892 - self.done = done
834 }
835
836
@@ -898,28 +839,26 @@ public struct DownloadProgress: Equatable, Hashable {
839 }
840
841 #if compiler(>=6)
901 -extension DownloadProgress: Sendable {}
842 +extension FfiDownloadProgress: Sendable {}
843 #endif
844
845 #if swift(>=5.8)
846 @_documentation(visibility: private)
847 #endif
907 -public struct FfiConverterTypeDownloadProgress: FfiConverterRustBuffer {
908 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DownloadProgress {
848 +public struct FfiConverterTypeFfiDownloadProgress: FfiConverterRustBuffer {
849 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiDownloadProgress {
850 return
910 - try DownloadProgress(
851 + try FfiDownloadProgress(
852 downloadedBytes: FfiConverterUInt64.read(from: &buf),
853 totalBytes: FfiConverterUInt64.read(from: &buf),
913 - fraction: FfiConverterDouble.read(from: &buf),
914 - done: FfiConverterBool.read(from: &buf)
854 + fraction: FfiConverterDouble.read(from: &buf)
855 )
856 }
857
918 - public static func write(_ value: DownloadProgress, into buf: inout [UInt8]) {
858 + public static func write(_ value: FfiDownloadProgress, into buf: inout [UInt8]) {
859 FfiConverterUInt64.write(value.downloadedBytes, into: &buf)
860 FfiConverterUInt64.write(value.totalBytes, into: &buf)
861 FfiConverterDouble.write(value.fraction, into: &buf)
922 - FfiConverterBool.write(value.done, into: &buf)
862 }
863 }
864
@@ -927,46 +866,35 @@ public struct FfiConverterTypeDownloadProgress: FfiConverterRustBuffer {
866 #if swift(>=5.8)
867 @_documentation(visibility: private)
868 #endif
930 -public func FfiConverterTypeDownloadProgress_lift(_ buf: RustBuffer) throws -> DownloadProgress {
931 - return try FfiConverterTypeDownloadProgress.lift(buf)
869 +public func FfiConverterTypeFfiDownloadProgress_lift(_ buf: RustBuffer) throws -> FfiDownloadProgress {
870 + return try FfiConverterTypeFfiDownloadProgress.lift(buf)
871 }
872
873 #if swift(>=5.8)
874 @_documentation(visibility: private)
875 #endif
937 -public func FfiConverterTypeDownloadProgress_lower(_ value: DownloadProgress) -> RustBuffer {
938 - return FfiConverterTypeDownloadProgress.lower(value)
876 +public func FfiConverterTypeFfiDownloadProgress_lower(_ value: FfiDownloadProgress) -> RustBuffer {
877 + return FfiConverterTypeFfiDownloadProgress.lower(value)
878 }
879
880
942 -/**
943 - * Descriptive metadata for a model variant.
944 - */
945 -public struct ModelMetadata: Equatable, Hashable {
881 +public struct FfiModelMetadata: Equatable, Hashable {
882 + public var model: FfiDemucsModel
883 public var id: String
884 public var label: String
885 public var description: String
949 - /**
950 - * Safetensors weight file name, e.g. "htdemucs.safetensors".
951 - */
952 - public var filename: String
886 public var sizeMb: UInt32
954 - public var stems: [StemKind]
955 - public var downloadUrl: String
887 + public var stems: [FfiStemKind]
888
889 // Default memberwise initializers are never public by default, so we
890 // declare one manually.
959 - public init(id: String, label: String, description: String,
960 - /**
961 - * Safetensors weight file name, e.g. "htdemucs.safetensors".
962 - */filename: String, sizeMb: UInt32, stems: [StemKind], downloadUrl: String) {
891 + public init(model: FfiDemucsModel, id: String, label: String, description: String, sizeMb: UInt32, stems: [FfiStemKind]) {
892 + self.model = model
893 self.id = id
894 self.label = label
895 self.description = description
966 - self.filename = filename
896 self.sizeMb = sizeMb
897 self.stems = stems
969 - self.downloadUrl = downloadUrl
898 }
899
900
@@ -975,34 +903,32 @@ public struct ModelMetadata: Equatable, Hashable {
903 }
904
905 #if compiler(>=6)
978 -extension ModelMetadata: Sendable {}
906 +extension FfiModelMetadata: Sendable {}
907 #endif
908
909 #if swift(>=5.8)
910 @_documentation(visibility: private)
911 #endif
984 -public struct FfiConverterTypeModelMetadata: FfiConverterRustBuffer {
985 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ModelMetadata {
912 +public struct FfiConverterTypeFfiModelMetadata: FfiConverterRustBuffer {
913 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiModelMetadata {
914 return
987 - try ModelMetadata(
915 + try FfiModelMetadata(
916 + model: FfiConverterTypeFfiDemucsModel.read(from: &buf),
917 id: FfiConverterString.read(from: &buf),
918 label: FfiConverterString.read(from: &buf),
919 description: FfiConverterString.read(from: &buf),
991 - filename: FfiConverterString.read(from: &buf),
920 sizeMb: FfiConverterUInt32.read(from: &buf),
993 - stems: FfiConverterSequenceTypeStemKind.read(from: &buf),
994 - downloadUrl: FfiConverterString.read(from: &buf)
921 + stems: FfiConverterSequenceTypeFfiStemKind.read(from: &buf)
922 )
923 }
924
998 - public static func write(_ value: ModelMetadata, into buf: inout [UInt8]) {
925 + public static func write(_ value: FfiModelMetadata, into buf: inout [UInt8]) {
926 + FfiConverterTypeFfiDemucsModel.write(value.model, into: &buf)
927 FfiConverterString.write(value.id, into: &buf)
928 FfiConverterString.write(value.label, into: &buf)
929 FfiConverterString.write(value.description, into: &buf)
1002 - FfiConverterString.write(value.filename, into: &buf)
930 FfiConverterUInt32.write(value.sizeMb, into: &buf)
1004 - FfiConverterSequenceTypeStemKind.write(value.stems, into: &buf)
1005 - FfiConverterString.write(value.downloadUrl, into: &buf)
931 + FfiConverterSequenceTypeFfiStemKind.write(value.stems, into: &buf)
932 }
933 }
934
@@ -1010,43 +936,28 @@ public struct FfiConverterTypeModelMetadata: FfiConverterRustBuffer {
936 #if swift(>=5.8)
937 @_documentation(visibility: private)
938 #endif
1013 -public func FfiConverterTypeModelMetadata_lift(_ buf: RustBuffer) throws -> ModelMetadata {
1014 - return try FfiConverterTypeModelMetadata.lift(buf)
939 +public func FfiConverterTypeFfiModelMetadata_lift(_ buf: RustBuffer) throws -> FfiModelMetadata {
940 + return try FfiConverterTypeFfiModelMetadata.lift(buf)
941 }
942
943 #if swift(>=5.8)
944 @_documentation(visibility: private)
945 #endif
1020 -public func FfiConverterTypeModelMetadata_lower(_ value: ModelMetadata) -> RustBuffer {
1021 - return FfiConverterTypeModelMetadata.lower(value)
946 +public func FfiConverterTypeFfiModelMetadata_lower(_ value: FfiModelMetadata) -> RustBuffer {
947 + return FfiConverterTypeFfiModelMetadata.lower(value)
948 }
949
950
1025 -/**
1026 - * Coarse separation progress derived from chunk/stem counters.
1027 - */
1028 -public struct SeparationProgress: Equatable, Hashable {
1029 - /**
1030 - * 0.0–1.0 overall fraction.
1031 - */
951 +public struct FfiSeparationProgress: Equatable, Hashable {
952 public var fraction: Double
1033 - /**
1034 - * 0-based index of the chunk currently in flight.
1035 - */
1036 - public var currentChunk: UInt64
953 + public var chunkIndex: UInt64
954 public var totalChunks: UInt64
955
956 // Default memberwise initializers are never public by default, so we
957 // declare one manually.
1041 - public init(
1042 - /**
1043 - * 0.0–1.0 overall fraction.
1044 - */fraction: Double,
1045 - /**
1046 - * 0-based index of the chunk currently in flight.
1047 - */currentChunk: UInt64, totalChunks: UInt64) {
958 + public init(fraction: Double, chunkIndex: UInt64, totalChunks: UInt64) {
959 self.fraction = fraction
1049 - self.currentChunk = currentChunk
960 + self.chunkIndex = chunkIndex
961 self.totalChunks = totalChunks
962 }
963
@@ -1056,25 +967,25 @@ public struct SeparationProgress: Equatable, Hashable {
967 }
968
969 #if compiler(>=6)
1059 -extension SeparationProgress: Sendable {}
970 +extension FfiSeparationProgress: Sendable {}
971 #endif
972
973 #if swift(>=5.8)
974 @_documentation(visibility: private)
975 #endif
1065 -public struct FfiConverterTypeSeparationProgress: FfiConverterRustBuffer {
1066 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SeparationProgress {
976 +public struct FfiConverterTypeFfiSeparationProgress: FfiConverterRustBuffer {
977 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiSeparationProgress {
978 return
1068 - try SeparationProgress(
979 + try FfiSeparationProgress(
980 fraction: FfiConverterDouble.read(from: &buf),
1070 - currentChunk: FfiConverterUInt64.read(from: &buf),
981 + chunkIndex: FfiConverterUInt64.read(from: &buf),
982 totalChunks: FfiConverterUInt64.read(from: &buf)
983 )
984 }
985
1075 - public static func write(_ value: SeparationProgress, into buf: inout [UInt8]) {
986 + public static func write(_ value: FfiSeparationProgress, into buf: inout [UInt8]) {
987 FfiConverterDouble.write(value.fraction, into: &buf)
1077 - FfiConverterUInt64.write(value.currentChunk, into: &buf)
988 + FfiConverterUInt64.write(value.chunkIndex, into: &buf)
989 FfiConverterUInt64.write(value.totalChunks, into: &buf)
990 }
991 }
@@ -1083,29 +994,30 @@ public struct FfiConverterTypeSeparationProgress: FfiConverterRustBuffer {
994 #if swift(>=5.8)
995 @_documentation(visibility: private)
996 #endif
1086 -public func FfiConverterTypeSeparationProgress_lift(_ buf: RustBuffer) throws -> SeparationProgress {
1087 - return try FfiConverterTypeSeparationProgress.lift(buf)
997 +public func FfiConverterTypeFfiSeparationProgress_lift(_ buf: RustBuffer) throws -> FfiSeparationProgress {
998 + return try FfiConverterTypeFfiSeparationProgress.lift(buf)
999 }
1000
1001 #if swift(>=5.8)
1002 @_documentation(visibility: private)
1003 #endif
1093 -public func FfiConverterTypeSeparationProgress_lower(_ value: SeparationProgress) -> RustBuffer {
1094 - return FfiConverterTypeSeparationProgress.lower(value)
1004 +public func FfiConverterTypeFfiSeparationProgress_lower(_ value: FfiSeparationProgress) -> RustBuffer {
1005 + return FfiConverterTypeFfiSeparationProgress.lower(value)
1006 }
1007
1008
1009 /**
1099 - * One separated stem: interleaved-free stereo PCM at 44100 Hz.
1010 + * One separated source. `left` and `right` are at the input sample rate and
1011 + * have the same length as the input channels.
1012 */
1101 -public struct StemResult: Equatable, Hashable {
1102 - public var kind: StemKind
1013 +public struct FfiStem: Equatable, Hashable {
1014 + public var kind: FfiStemKind
1015 public var left: [Float]
1016 public var right: [Float]
1017
1018 // Default memberwise initializers are never public by default, so we
1019 // declare one manually.
1108 - public init(kind: StemKind, left: [Float], right: [Float]) {
1020 + public init(kind: FfiStemKind, left: [Float], right: [Float]) {
1021 self.kind = kind
1022 self.left = left
1023 self.right = right
@@ -1117,24 +1029,24 @@ public struct StemResult: Equatable, Hashable {
1029 }
1030
1031 #if compiler(>=6)
1120 -extension StemResult: Sendable {}
1032 +extension FfiStem: Sendable {}
1033 #endif
1034
1035 #if swift(>=5.8)
1036 @_documentation(visibility: private)
1037 #endif
1126 -public struct FfiConverterTypeStemResult: FfiConverterRustBuffer {
1127 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> StemResult {
1038 +public struct FfiConverterTypeFfiStem: FfiConverterRustBuffer {
1039 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiStem {
1040 return
1129 - try StemResult(
1130 - kind: FfiConverterTypeStemKind.read(from: &buf),
1041 + try FfiStem(
1042 + kind: FfiConverterTypeFfiStemKind.read(from: &buf),
1043 left: FfiConverterSequenceFloat.read(from: &buf),
1044 right: FfiConverterSequenceFloat.read(from: &buf)
1045 )
1046 }
1047
1136 - public static func write(_ value: StemResult, into buf: inout [UInt8]) {
1137 - FfiConverterTypeStemKind.write(value.kind, into: &buf)
1048 + public static func write(_ value: FfiStem, into buf: inout [UInt8]) {
1049 + FfiConverterTypeFfiStemKind.write(value.kind, into: &buf)
1050 FfiConverterSequenceFloat.write(value.left, into: &buf)
1051 FfiConverterSequenceFloat.write(value.right, into: &buf)
1052 }
@@ -1144,43 +1056,33 @@ public struct FfiConverterTypeStemResult: FfiConverterRustBuffer {
1056 #if swift(>=5.8)
1057 @_documentation(visibility: private)
1058 #endif
1147 -public func FfiConverterTypeStemResult_lift(_ buf: RustBuffer) throws -> StemResult {
1148 - return try FfiConverterTypeStemResult.lift(buf)
1059 +public func FfiConverterTypeFfiStem_lift(_ buf: RustBuffer) throws -> FfiStem {
1060 + return try FfiConverterTypeFfiStem.lift(buf)
1061 }
1062
1063 #if swift(>=5.8)
1064 @_documentation(visibility: private)
1065 #endif
1154 -public func FfiConverterTypeStemResult_lower(_ value: StemResult) -> RustBuffer {
1155 - return FfiConverterTypeStemResult.lower(value)
1066 +public func FfiConverterTypeFfiStem_lower(_ value: FfiStem) -> RustBuffer {
1067 + return FfiConverterTypeFfiStem.lower(value)
1068 }
1069
1070
1159 -/**
1160 - * Errors surfaced across the FFI boundary.
1161 - */
1162 -public enum DemucsFfiError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError {
1071 +public enum FfiDemucsError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError {
1072
1073
1074
1166 - case NoModelLoaded
1167 - case AlreadyLoaded(modelId: String
1168 - )
1169 - case Weights(reason: String
1170 - )
1171 - case Dsp(reason: String
1172 - )
1173 - case Tensor(reason: String
1075 + case Cancelled
1076 + case NotLoaded
1077 + case NotCached(modelId: String
1078 )
1175 - case Internal(reason: String
1079 + case InvalidInput(reason: String
1080 )
1177 - case Cancelled
1178 - case NotCached(reason: String
1081 + case Download(reason: String
1082 )
1083 case Io(reason: String
1084 )
1182 - case NoCacheDir
1183 - case Download(reason: String
1085 + case Inference(reason: String
1086 )
1087
1088
@@ -1195,47 +1097,37 @@ public enum DemucsFfiError: Swift.Error, Equatable, Hashable, Foundation.Localiz
1097 }
1098
1099 #if compiler(>=6)
1198 -extension DemucsFfiError: Sendable {}
1100 +extension FfiDemucsError: Sendable {}
1101 #endif
1102
1103 #if swift(>=5.8)
1104 @_documentation(visibility: private)
1105 #endif
1204 -public struct FfiConverterTypeDemucsFfiError: FfiConverterRustBuffer {
1205 - typealias SwiftType = DemucsFfiError
1106 +public struct FfiConverterTypeFfiDemucsError: FfiConverterRustBuffer {
1107 + typealias SwiftType = FfiDemucsError
1108
1207 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DemucsFfiError {
1109 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiDemucsError {
1110 let variant: Int32 = try readInt(&buf)
1111 switch variant {
1112
1113
1114
1115
1214 - case 1: return .NoModelLoaded
1215 - case 2: return .AlreadyLoaded(
1116 + case 1: return .Cancelled
1117 + case 2: return .NotLoaded
1118 + case 3: return .NotCached(
1119 modelId: try FfiConverterString.read(from: &buf)
1120 )
1218 - case 3: return .Weights(
1219 - reason: try FfiConverterString.read(from: &buf)
1220 - )
1221 - case 4: return .Dsp(
1121 + case 4: return .InvalidInput(
1122 reason: try FfiConverterString.read(from: &buf)
1123 )
1224 - case 5: return .Tensor(
1124 + case 5: return .Download(
1125 reason: try FfiConverterString.read(from: &buf)
1126 )
1227 - case 6: return .Internal(
1127 + case 6: return .Io(
1128 reason: try FfiConverterString.read(from: &buf)
1129 )
1230 - case 7: return .Cancelled
1231 - case 8: return .NotCached(
1232 - reason: try FfiConverterString.read(from: &buf)
1233 - )
1234 - case 9: return .Io(
1235 - reason: try FfiConverterString.read(from: &buf)
1236 - )
1237 - case 10: return .NoCacheDir
1238 - case 11: return .Download(
1130 + case 7: return .Inference(
1131 reason: try FfiConverterString.read(from: &buf)
1132 )
1133
@@ -1243,62 +1135,43 @@ public struct FfiConverterTypeDemucsFfiError: FfiConverterRustBuffer {
1135 }
1136 }
1137
1246 - public static func write(_ value: DemucsFfiError, into buf: inout [UInt8]) {
1138 + public static func write(_ value: FfiDemucsError, into buf: inout [UInt8]) {
1139 switch value {
1140
1141
1142
1143
1144
1253 - case .NoModelLoaded:
1145 + case .Cancelled:
1146 writeInt(&buf, Int32(1))
1147
1148
1257 - case let .AlreadyLoaded(modelId):
1149 + case .NotLoaded:
1150 writeInt(&buf, Int32(2))
1259 - FfiConverterString.write(modelId, into: &buf)
1260 -
1151
1262 - case let .Weights(reason):
1152 +
1153 + case let .NotCached(modelId):
1154 writeInt(&buf, Int32(3))
1264 - FfiConverterString.write(reason, into: &buf)
1155 + FfiConverterString.write(modelId, into: &buf)
1156
1157
1267 - case let .Dsp(reason):
1158 + case let .InvalidInput(reason):
1159 writeInt(&buf, Int32(4))
1160 FfiConverterString.write(reason, into: &buf)
1161
1162
1272 - case let .Tensor(reason):
1163 + case let .Download(reason):
1164 writeInt(&buf, Int32(5))
1165 FfiConverterString.write(reason, into: &buf)
1166
1167
1277 - case let .Internal(reason):
1168 + case let .Io(reason):
1169 writeInt(&buf, Int32(6))
1170 FfiConverterString.write(reason, into: &buf)
1171
1172
1282 - case .Cancelled:
1173 + case let .Inference(reason):
1174 writeInt(&buf, Int32(7))
1284 -
1285 -
1286 - case let .NotCached(reason):
1287 - writeInt(&buf, Int32(8))
1288 - FfiConverterString.write(reason, into: &buf)
1289 -
1290 -
1291 - case let .Io(reason):
1292 - writeInt(&buf, Int32(9))
1293 - FfiConverterString.write(reason, into: &buf)
1294 -
1295 -
1296 - case .NoCacheDir:
1297 - writeInt(&buf, Int32(10))
1298 -
1299 -
1300 - case let .Download(reason):
1301 - writeInt(&buf, Int32(11))
1175 FfiConverterString.write(reason, into: &buf)
1176
1177 }
@@ -1309,38 +1182,32 @@ public struct FfiConverterTypeDemucsFfiError: FfiConverterRustBuffer {
1182 #if swift(>=5.8)
1183 @_documentation(visibility: private)
1184 #endif
1312 -public func FfiConverterTypeDemucsFfiError_lift(_ buf: RustBuffer) throws -> DemucsFfiError {
1313 - return try FfiConverterTypeDemucsFfiError.lift(buf)
1185 +public func FfiConverterTypeFfiDemucsError_lift(_ buf: RustBuffer) throws -> FfiDemucsError {
1186 + return try FfiConverterTypeFfiDemucsError.lift(buf)
1187 }
1188
1189 #if swift(>=5.8)
1190 @_documentation(visibility: private)
1191 #endif
1319 -public func FfiConverterTypeDemucsFfiError_lower(_ value: DemucsFfiError) -> RustBuffer {
1320 - return FfiConverterTypeDemucsFfiError.lower(value)
1192 +public func FfiConverterTypeFfiDemucsError_lower(_ value: FfiDemucsError) -> RustBuffer {
1193 + return FfiConverterTypeFfiDemucsError.lower(value)
1194 }
1195
1196 // Note that we don't yet support `indirect` for enums.
1197 // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
1198 /**
1326 - * Which HTDemucs variant to load.
1199 + * Which model variant to download or load.
1200 + *
1201 + * `FineTuned` runs one sub-model per requested stem, so asking for fewer
1202 + * stems is proportionally faster. It only knows drums, bass, other and
1203 + * vocals; an empty list or any other stem is rejected at load time.
1204 */
1205
1329 -public enum DemucsModel: Equatable, Hashable {
1206 +public enum FfiDemucsModel: Equatable, Hashable {
1207
1331 - /**
1332 - * htdemucs — 4 stems, balanced speed and quality (~84 MB).
1333 - */
1208 case fourStem
1335 - /**
1336 - * htdemucs_6s — 6 stems, adds guitar and piano (~84 MB).
1337 - */
1209 case sixStem
1339 - /**
1340 - * htdemucs_ft — fine-tuned, best quality, one sub-model per requested
1341 - * stem so inference time scales with `stems.len()` (~333 MB).
1342 - */
1343 - case fineTuned(stems: [StemKind]
1210 + case fineTuned(stems: [FfiStemKind]
1211 )
1212
1213
@@ -1350,16 +1217,16 @@ public enum DemucsModel: Equatable, Hashable {
1217 }
1218
1219 #if compiler(>=6)
1353 -extension DemucsModel: Sendable {}
1220 +extension FfiDemucsModel: Sendable {}
1221 #endif
1222
1223 #if swift(>=5.8)
1224 @_documentation(visibility: private)
1225 #endif
1359 -public struct FfiConverterTypeDemucsModel: FfiConverterRustBuffer {
1360 - typealias SwiftType = DemucsModel
1226 +public struct FfiConverterTypeFfiDemucsModel: FfiConverterRustBuffer {
1227 + typealias SwiftType = FfiDemucsModel
1228
1362 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DemucsModel {
1229 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiDemucsModel {
1230 let variant: Int32 = try readInt(&buf)
1231 switch variant {
1232
@@ -1367,14 +1234,14 @@ public struct FfiConverterTypeDemucsModel: FfiConverterRustBuffer {
1234
1235 case 2: return .sixStem
1236
1370 - case 3: return .fineTuned(stems: try FfiConverterSequenceTypeStemKind.read(from: &buf)
1237 + case 3: return .fineTuned(stems: try FfiConverterSequenceTypeFfiStemKind.read(from: &buf)
1238 )
1239
1240 default: throw UniffiInternalError.unexpectedEnumCase
1241 }
1242 }
1243
1377 - public static func write(_ value: DemucsModel, into buf: inout [UInt8]) {
1244 + public static func write(_ value: FfiDemucsModel, into buf: inout [UInt8]) {
1245 switch value {
1246
1247
@@ -1388,7 +1255,7 @@ public struct FfiConverterTypeDemucsModel: FfiConverterRustBuffer {
1255
1256 case let .fineTuned(stems):
1257 writeInt(&buf, Int32(3))
1391 - FfiConverterSequenceTypeStemKind.write(stems, into: &buf)
1258 + FfiConverterSequenceTypeFfiStemKind.write(stems, into: &buf)
1259
1260 }
1261 }
@@ -1398,25 +1265,22 @@ public struct FfiConverterTypeDemucsModel: FfiConverterRustBuffer {
1265 #if swift(>=5.8)
1266 @_documentation(visibility: private)
1267 #endif
1401 -public func FfiConverterTypeDemucsModel_lift(_ buf: RustBuffer) throws -> DemucsModel {
1402 - return try FfiConverterTypeDemucsModel.lift(buf)
1268 +public func FfiConverterTypeFfiDemucsModel_lift(_ buf: RustBuffer) throws -> FfiDemucsModel {
1269 + return try FfiConverterTypeFfiDemucsModel.lift(buf)
1270 }
1271
1272 #if swift(>=5.8)
1273 @_documentation(visibility: private)
1274 #endif
1408 -public func FfiConverterTypeDemucsModel_lower(_ value: DemucsModel) -> RustBuffer {
1409 - return FfiConverterTypeDemucsModel.lower(value)
1275 +public func FfiConverterTypeFfiDemucsModel_lower(_ value: FfiDemucsModel) -> RustBuffer {
1276 + return FfiConverterTypeFfiDemucsModel.lower(value)
1277 }
1278
1279
1280 // Note that we don't yet support `indirect` for enums.
1281 // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
1415 -/**
1416 - * A single separable audio source.
1417 - */
1282
1419 -public enum StemKind: Equatable, Hashable {
1283 +public enum FfiStemKind: Equatable, Hashable {
1284
1285 case drums
1286 case bass
@@ -1432,16 +1296,16 @@ public enum StemKind: Equatable, Hashable {
1296 }
1297
1298 #if compiler(>=6)
1435 -extension StemKind: Sendable {}
1299 +extension FfiStemKind: Sendable {}
1300 #endif
1301
1302 #if swift(>=5.8)
1303 @_documentation(visibility: private)
1304 #endif
1441 -public struct FfiConverterTypeStemKind: FfiConverterRustBuffer {
1442 - typealias SwiftType = StemKind
1305 +public struct FfiConverterTypeFfiStemKind: FfiConverterRustBuffer {
1306 + typealias SwiftType = FfiStemKind
1307
1444 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> StemKind {
1308 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FfiStemKind {
1309 let variant: Int32 = try readInt(&buf)
1310 switch variant {
1311
@@ -1461,7 +1325,7 @@ public struct FfiConverterTypeStemKind: FfiConverterRustBuffer {
1325 }
1326 }
1327
1464 - public static func write(_ value: StemKind, into buf: inout [UInt8]) {
1328 + public static func write(_ value: FfiStemKind, into buf: inout [UInt8]) {
1329 switch value {
1330
1331
@@ -1496,15 +1360,15 @@ public struct FfiConverterTypeStemKind: FfiConverterRustBuffer {
1360 #if swift(>=5.8)
1361 @_documentation(visibility: private)
1362 #endif
1499 -public func FfiConverterTypeStemKind_lift(_ buf: RustBuffer) throws -> StemKind {
1500 - return try FfiConverterTypeStemKind.lift(buf)
1363 +public func FfiConverterTypeFfiStemKind_lift(_ buf: RustBuffer) throws -> FfiStemKind {
1364 + return try FfiConverterTypeFfiStemKind.lift(buf)
1365 }
1366
1367 #if swift(>=5.8)
1368 @_documentation(visibility: private)
1369 #endif
1506 -public func FfiConverterTypeStemKind_lower(_ value: StemKind) -> RustBuffer {
1507 - return FfiConverterTypeStemKind.lower(value)
1370 +public func FfiConverterTypeFfiStemKind_lower(_ value: FfiStemKind) -> RustBuffer {
1371 + return FfiConverterTypeFfiStemKind.lower(value)
1372 }
1373
1374
@@ -1512,37 +1376,36 @@ public func FfiConverterTypeStemKind_lower(_ value: StemKind) -> RustBuffer {
1376
1377
1378 /**
1515 - * Receives download progress. Return true to continue, false to cancel —
1516 - * the partial file is deleted and `download_model` returns `Cancelled`.
1379 + * Called from a background thread. Return `false` to cancel the download.
1380 */
1518 -public protocol DownloadProgressListener: AnyObject, Sendable {
1381 +public protocol FfiDownloadListener: AnyObject, Sendable {
1382
1520 - func onProgress(progress: DownloadProgress) -> Bool
1383 + func onProgress(progress: FfiDownloadProgress) -> Bool
1384
1385 }
1386
1387
1388 // Put the implementation in a struct so we don't pollute the top-level namespace
1526 -fileprivate struct UniffiCallbackInterfaceDownloadProgressListener {
1389 +fileprivate struct UniffiCallbackInterfaceFfiDownloadListener {
1390
1391 // Create the VTable using a series of closures.
1392 // Swift automatically converts these into C callback functions.
1393 //
1394 // This creates 1-element array, since this seems to be the only way to construct a const
1395 // pointer that we can pass to the Rust code.
1533 - static let vtable: [UniffiVTableCallbackInterfaceDownloadProgressListener] = [UniffiVTableCallbackInterfaceDownloadProgressListener(
1396 + static let vtable: [UniffiVTableCallbackInterfaceFfiDownloadListener] = [UniffiVTableCallbackInterfaceFfiDownloadListener(
1397 uniffiFree: { (uniffiHandle: UInt64) -> () in
1398 do {
1536 - try FfiConverterCallbackInterfaceDownloadProgressListener.handleMap.remove(handle: uniffiHandle)
1399 + try FfiConverterCallbackInterfaceFfiDownloadListener.handleMap.remove(handle: uniffiHandle)
1400 } catch {
1538 - print("Uniffi callback interface DownloadProgressListener: handle missing in uniffiFree")
1401 + print("Uniffi callback interface FfiDownloadListener: handle missing in uniffiFree")
1402 }
1403 },
1404 uniffiClone: { (uniffiHandle: UInt64) -> UInt64 in
1405 do {
1543 - return try FfiConverterCallbackInterfaceDownloadProgressListener.handleMap.clone(handle: uniffiHandle)
1406 + return try FfiConverterCallbackInterfaceFfiDownloadListener.handleMap.clone(handle: uniffiHandle)
1407 } catch {
1545 - fatalError("Uniffi callback interface DownloadProgressListener: handle missing in uniffiClone")
1408 + fatalError("Uniffi callback interface FfiDownloadListener: handle missing in uniffiClone")
1409 }
1410 },
1411 onProgress: { (
@@ -1553,11 +1416,11 @@ fileprivate struct UniffiCallbackInterfaceDownloadProgressListener {
1416 ) in
1417 let makeCall = {
1418 () throws -> Bool in
1556 - guard let uniffiObj = try? FfiConverterCallbackInterfaceDownloadProgressListener.handleMap.get(handle: uniffiHandle) else {
1419 + guard let uniffiObj = try? FfiConverterCallbackInterfaceFfiDownloadListener.handleMap.get(handle: uniffiHandle) else {
1420 throw UniffiInternalError.unexpectedStaleHandle
1421 }
1422 return uniffiObj.onProgress(
1560 - progress: try FfiConverterTypeDownloadProgress_lift(progress)
1423 + progress: try FfiConverterTypeFfiDownloadProgress_lift(progress)
1424 )
1425 }
1426
@@ -1572,23 +1435,23 @@ fileprivate struct UniffiCallbackInterfaceDownloadProgressListener {
1435 )]
1436 }
1437
1575 -private func uniffiCallbackInitDownloadProgressListener() {
1576 - uniffi_demucs_fn_init_callback_vtable_downloadprogresslistener(UniffiCallbackInterfaceDownloadProgressListener.vtable)
1438 +private func uniffiCallbackInitFfiDownloadListener() {
1439 + uniffi_demucs_ffi_fn_init_callback_vtable_ffidownloadlistener(UniffiCallbackInterfaceFfiDownloadListener.vtable)
1440 }
1441
1442 // FfiConverter protocol for callback interfaces
1443 #if swift(>=5.8)
1444 @_documentation(visibility: private)
1445 #endif
1583 -fileprivate struct FfiConverterCallbackInterfaceDownloadProgressListener {
1584 - fileprivate static let handleMap = UniffiHandleMap<DownloadProgressListener>()
1446 +fileprivate struct FfiConverterCallbackInterfaceFfiDownloadListener {
1447 + fileprivate static let handleMap = UniffiHandleMap<FfiDownloadListener>()
1448 }
1449
1450 #if swift(>=5.8)
1451 @_documentation(visibility: private)
1452 #endif
1590 -extension FfiConverterCallbackInterfaceDownloadProgressListener : FfiConverter {
1591 - typealias SwiftType = DownloadProgressListener
1453 +extension FfiConverterCallbackInterfaceFfiDownloadListener : FfiConverter {
1454 + typealias SwiftType = FfiDownloadListener
1455 typealias FfiType = UInt64
1456
1457 #if swift(>=5.8)
@@ -1625,54 +1488,53 @@ extension FfiConverterCallbackInterfaceDownloadProgressListener : FfiConverter {
1488 #if swift(>=5.8)
1489 @_documentation(visibility: private)
1490 #endif
1628 -public func FfiConverterCallbackInterfaceDownloadProgressListener_lift(_ handle: UInt64) throws -> DownloadProgressListener {
1629 - return try FfiConverterCallbackInterfaceDownloadProgressListener.lift(handle)
1491 +public func FfiConverterCallbackInterfaceFfiDownloadListener_lift(_ handle: UInt64) throws -> FfiDownloadListener {
1492 + return try FfiConverterCallbackInterfaceFfiDownloadListener.lift(handle)
1493 }
1494
1495 #if swift(>=5.8)
1496 @_documentation(visibility: private)
1497 #endif
1635 -public func FfiConverterCallbackInterfaceDownloadProgressListener_lower(_ v: DownloadProgressListener) -> UInt64 {
1636 - return FfiConverterCallbackInterfaceDownloadProgressListener.lower(v)
1498 +public func FfiConverterCallbackInterfaceFfiDownloadListener_lower(_ v: FfiDownloadListener) -> UInt64 {
1499 + return FfiConverterCallbackInterfaceFfiDownloadListener.lower(v)
1500 }
1501
1502
1503
1504
1505 /**
1643 - * Receives coarse progress during separation.
1644 - *
1645 - * Called from the inference task; keep the callback fast. Return true to
1646 - * continue, false to cancel — the engine then returns `Cancelled`.
1506 + * Called from a background thread. Return `false` to cancel; cancellation
1507 + * takes effect at the next chunk boundary (every ~7.8 s of audio), so audio
1508 + * short enough to fit in one chunk always runs to completion.
1509 */
1648 -public protocol SeparationProgressListener: AnyObject, Sendable {
1510 +public protocol FfiSeparationListener: AnyObject, Sendable {
1511
1650 - func onProgress(progress: SeparationProgress) -> Bool
1512 + func onProgress(progress: FfiSeparationProgress) -> Bool
1513
1514 }
1515
1516
1517 // Put the implementation in a struct so we don't pollute the top-level namespace
1656 -fileprivate struct UniffiCallbackInterfaceSeparationProgressListener {
1518 +fileprivate struct UniffiCallbackInterfaceFfiSeparationListener {
1519
1520 // Create the VTable using a series of closures.
1521 // Swift automatically converts these into C callback functions.
1522 //
1523 // This creates 1-element array, since this seems to be the only way to construct a const
1524 // pointer that we can pass to the Rust code.
1663 - static let vtable: [UniffiVTableCallbackInterfaceSeparationProgressListener] = [UniffiVTableCallbackInterfaceSeparationProgressListener(
1525 + static let vtable: [UniffiVTableCallbackInterfaceFfiSeparationListener] = [UniffiVTableCallbackInterfaceFfiSeparationListener(
1526 uniffiFree: { (uniffiHandle: UInt64) -> () in
1527 do {
1666 - try FfiConverterCallbackInterfaceSeparationProgressListener.handleMap.remove(handle: uniffiHandle)
1528 + try FfiConverterCallbackInterfaceFfiSeparationListener.handleMap.remove(handle: uniffiHandle)
1529 } catch {
1668 - print("Uniffi callback interface SeparationProgressListener: handle missing in uniffiFree")
1530 + print("Uniffi callback interface FfiSeparationListener: handle missing in uniffiFree")
1531 }
1532 },
1533 uniffiClone: { (uniffiHandle: UInt64) -> UInt64 in
1534 do {
1673 - return try FfiConverterCallbackInterfaceSeparationProgressListener.handleMap.clone(handle: uniffiHandle)
1535 + return try FfiConverterCallbackInterfaceFfiSeparationListener.handleMap.clone(handle: uniffiHandle)
1536 } catch {
1675 - fatalError("Uniffi callback interface SeparationProgressListener: handle missing in uniffiClone")
1537 + fatalError("Uniffi callback interface FfiSeparationListener: handle missing in uniffiClone")
1538 }
1539 },
1540 onProgress: { (
@@ -1683,11 +1545,11 @@ fileprivate struct UniffiCallbackInterfaceSeparationProgressListener {
1545 ) in
1546 let makeCall = {
1547 () throws -> Bool in
1686 - guard let uniffiObj = try? FfiConverterCallbackInterfaceSeparationProgressListener.handleMap.get(handle: uniffiHandle) else {
1548 + guard let uniffiObj = try? FfiConverterCallbackInterfaceFfiSeparationListener.handleMap.get(handle: uniffiHandle) else {
1549 throw UniffiInternalError.unexpectedStaleHandle
1550 }
1551 return uniffiObj.onProgress(
1690 - progress: try FfiConverterTypeSeparationProgress_lift(progress)
1552 + progress: try FfiConverterTypeFfiSeparationProgress_lift(progress)
1553 )
1554 }
1555
@@ -1702,23 +1564,23 @@ fileprivate struct UniffiCallbackInterfaceSeparationProgressListener {
1564 )]
1565 }
1566
1705 -private func uniffiCallbackInitSeparationProgressListener() {
1706 - uniffi_demucs_fn_init_callback_vtable_separationprogresslistener(UniffiCallbackInterfaceSeparationProgressListener.vtable)
1567 +private func uniffiCallbackInitFfiSeparationListener() {
1568 + uniffi_demucs_ffi_fn_init_callback_vtable_ffiseparationlistener(UniffiCallbackInterfaceFfiSeparationListener.vtable)
1569 }
1570
1571 // FfiConverter protocol for callback interfaces
1572 #if swift(>=5.8)
1573 @_documentation(visibility: private)
1574 #endif
1713 -fileprivate struct FfiConverterCallbackInterfaceSeparationProgressListener {
1714 - fileprivate static let handleMap = UniffiHandleMap<SeparationProgressListener>()
1575 +fileprivate struct FfiConverterCallbackInterfaceFfiSeparationListener {
1576 + fileprivate static let handleMap = UniffiHandleMap<FfiSeparationListener>()
1577 }
1578
1579 #if swift(>=5.8)
1580 @_documentation(visibility: private)
1581 #endif
1720 -extension FfiConverterCallbackInterfaceSeparationProgressListener : FfiConverter {
1721 - typealias SwiftType = SeparationProgressListener
1582 +extension FfiConverterCallbackInterfaceFfiSeparationListener : FfiConverter {
1583 + typealias SwiftType = FfiSeparationListener
1584 typealias FfiType = UInt64
1585
1586 #if swift(>=5.8)
@@ -1755,15 +1617,15 @@ extension FfiConverterCallbackInterfaceSeparationProgressListener : FfiConverter
1617 #if swift(>=5.8)
1618 @_documentation(visibility: private)
1619 #endif
1758 -public func FfiConverterCallbackInterfaceSeparationProgressListener_lift(_ handle: UInt64) throws -> SeparationProgressListener {
1759 - return try FfiConverterCallbackInterfaceSeparationProgressListener.lift(handle)
1620 +public func FfiConverterCallbackInterfaceFfiSeparationListener_lift(_ handle: UInt64) throws -> FfiSeparationListener {
1621 + return try FfiConverterCallbackInterfaceFfiSeparationListener.lift(handle)
1622 }
1623
1624 #if swift(>=5.8)
1625 @_documentation(visibility: private)
1626 #endif
1765 -public func FfiConverterCallbackInterfaceSeparationProgressListener_lower(_ v: SeparationProgressListener) -> UInt64 {
1766 - return FfiConverterCallbackInterfaceSeparationProgressListener.lower(v)
1627 +public func FfiConverterCallbackInterfaceFfiSeparationListener_lower(_ v: FfiSeparationListener) -> UInt64 {
1628 + return FfiConverterCallbackInterfaceFfiSeparationListener.lower(v)
1629 }
1630
1631 #if swift(>=5.8)
@@ -1793,8 +1655,8 @@ fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer {
1655 #if swift(>=5.8)
1656 @_documentation(visibility: private)
1657 #endif
1796 -fileprivate struct FfiConverterOptionTypeDemucsModel: FfiConverterRustBuffer {
1797 - typealias SwiftType = DemucsModel?
1658 +fileprivate struct FfiConverterOptionTypeFfiDemucsModel: FfiConverterRustBuffer {
1659 + typealias SwiftType = FfiDemucsModel?
1660
1661 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
1662 guard let value = value else {
@@ -1802,13 +1664,13 @@ fileprivate struct FfiConverterOptionTypeDemucsModel: FfiConverterRustBuffer {
1664 return
1665 }
1666 writeInt(&buf, Int8(1))
1805 - FfiConverterTypeDemucsModel.write(value, into: &buf)
1667 + FfiConverterTypeFfiDemucsModel.write(value, into: &buf)
1668 }
1669
1670 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
1671 switch try readInt(&buf) as Int8 {
1672 case 0: return nil
1811 - case 1: return try FfiConverterTypeDemucsModel.read(from: &buf)
1673 + case 1: return try FfiConverterTypeFfiDemucsModel.read(from: &buf)
1674 default: throw UniffiInternalError.unexpectedOptionalTag
1675 }
1676 }
@@ -1842,23 +1704,23 @@ fileprivate struct FfiConverterSequenceFloat: FfiConverterRustBuffer {
1704 #if swift(>=5.8)
1705 @_documentation(visibility: private)
1706 #endif
1845 -fileprivate struct FfiConverterSequenceTypeModelMetadata: FfiConverterRustBuffer {
1846 - typealias SwiftType = [ModelMetadata]
1707 +fileprivate struct FfiConverterSequenceTypeFfiModelMetadata: FfiConverterRustBuffer {
1708 + typealias SwiftType = [FfiModelMetadata]
1709
1848 - public static func write(_ value: [ModelMetadata], into buf: inout [UInt8]) {
1710 + public static func write(_ value: [FfiModelMetadata], into buf: inout [UInt8]) {
1711 let len = Int32(value.count)
1712 writeInt(&buf, len)
1713 for item in value {
1852 - FfiConverterTypeModelMetadata.write(item, into: &buf)
1714 + FfiConverterTypeFfiModelMetadata.write(item, into: &buf)
1715 }
1716 }
1717
1856 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ModelMetadata] {
1718 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [FfiModelMetadata] {
1719 let len: Int32 = try readInt(&buf)
1858 - var seq = [ModelMetadata]()
1720 + var seq = [FfiModelMetadata]()
1721 seq.reserveCapacity(Int(len))
1722 for _ in 0 ..< len {
1861 - seq.append(try FfiConverterTypeModelMetadata.read(from: &buf))
1723 + seq.append(try FfiConverterTypeFfiModelMetadata.read(from: &buf))
1724 }
1725 return seq
1726 }
@@ -1867,23 +1729,23 @@ fileprivate struct FfiConverterSequenceTypeModelMetadata: FfiConverterRustBuffer
1729 #if swift(>=5.8)
1730 @_documentation(visibility: private)
1731 #endif
1870 -fileprivate struct FfiConverterSequenceTypeStemResult: FfiConverterRustBuffer {
1871 - typealias SwiftType = [StemResult]
1732 +fileprivate struct FfiConverterSequenceTypeFfiStem: FfiConverterRustBuffer {
1733 + typealias SwiftType = [FfiStem]
1734
1873 - public static func write(_ value: [StemResult], into buf: inout [UInt8]) {
1735 + public static func write(_ value: [FfiStem], into buf: inout [UInt8]) {
1736 let len = Int32(value.count)
1737 writeInt(&buf, len)
1738 for item in value {
1877 - FfiConverterTypeStemResult.write(item, into: &buf)
1739 + FfiConverterTypeFfiStem.write(item, into: &buf)
1740 }
1741 }
1742
1881 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [StemResult] {
1743 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [FfiStem] {
1744 let len: Int32 = try readInt(&buf)
1883 - var seq = [StemResult]()
1745 + var seq = [FfiStem]()
1746 seq.reserveCapacity(Int(len))
1747 for _ in 0 ..< len {
1886 - seq.append(try FfiConverterTypeStemResult.read(from: &buf))
1748 + seq.append(try FfiConverterTypeFfiStem.read(from: &buf))
1749 }
1750 return seq
1751 }
@@ -1892,23 +1754,23 @@ fileprivate struct FfiConverterSequenceTypeStemResult: FfiConverterRustBuffer {
1754 #if swift(>=5.8)
1755 @_documentation(visibility: private)
1756 #endif
1895 -fileprivate struct FfiConverterSequenceTypeStemKind: FfiConverterRustBuffer {
1896 - typealias SwiftType = [StemKind]
1757 +fileprivate struct FfiConverterSequenceTypeFfiStemKind: FfiConverterRustBuffer {
1758 + typealias SwiftType = [FfiStemKind]
1759
1898 - public static func write(_ value: [StemKind], into buf: inout [UInt8]) {
1760 + public static func write(_ value: [FfiStemKind], into buf: inout [UInt8]) {
1761 let len = Int32(value.count)
1762 writeInt(&buf, len)
1763 for item in value {
1902 - FfiConverterTypeStemKind.write(item, into: &buf)
1764 + FfiConverterTypeFfiStemKind.write(item, into: &buf)
1765 }
1766 }
1767
1906 - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [StemKind] {
1768 + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [FfiStemKind] {
1769 let len: Int32 = try readInt(&buf)
1908 - var seq = [StemKind]()
1770 + var seq = [FfiStemKind]()
1771 seq.reserveCapacity(Int(len))
1772 for _ in 0 ..< len {
1911 - seq.append(try FfiConverterTypeStemKind.read(from: &buf))
1773 + seq.append(try FfiConverterTypeFfiStemKind.read(from: &buf))
1774 }
1775 return seq
1776 }
@@ -1928,7 +1790,7 @@ fileprivate func uniffiRustCallAsync<F, T>(
1790 ) async throws -> T {
1791 // Make sure to call the ensure init function since future creation doesn't have a
1792 // RustCallStatus param, so doesn't use makeRustCall()
1931 - uniffiEnsureDemucsInitialized()
1793 + uniffiEnsureDemucsFfiInitialized()
1794 let rustFuture = rustFutureFunc()
1795 defer {
1796 freeFunc(rustFuture)
@@ -1961,122 +1823,98 @@ fileprivate func uniffiFutureContinuationCallback(handle: UInt64, pollResult: In
1823 print("uniffiFutureContinuationCallback invalid handle")
1824 }
1825 }
1964 -/**
1965 - * Metadata for every supported model variant.
1966 - */
1967 -public func allModels() -> [ModelMetadata] {
1968 - return try! FfiConverterSequenceTypeModelMetadata.lift(try! rustCall() {
1969 - uniffi_demucs_fn_func_all_models($0
1826 +public func allModels() -> [FfiModelMetadata] {
1827 + return try! FfiConverterSequenceTypeFfiModelMetadata.lift(try! rustCall() {
1828 + uniffi_demucs_ffi_fn_func_all_models($0
1829 + )
1830 +})
1831 +}
1832 +public func cachedModelPath(model: FfiDemucsModel) -> String? {
1833 + return try! FfiConverterOptionString.lift(try! rustCall() {
1834 + uniffi_demucs_ffi_fn_func_cached_model_path(
1835 + FfiConverterTypeFfiDemucsModel_lower(model),$0
1836 )
1837 })
1838 }
1839 /**
1974 - * Filesystem path the model's weights live at once downloaded, or None if
1975 - * not cached yet.
1840 + * Samples per chunk at 44.1 kHz.
1841 */
1977 -public func cachedModelPath(model: DemucsModel) -> String? {
1978 - return try! FfiConverterOptionString.lift(try! rustCall() {
1979 - uniffi_demucs_fn_func_cached_model_path(
1980 - FfiConverterTypeDemucsModel_lower(model),$0
1842 +public func chunkLength() -> UInt64 {
1843 + return try! FfiConverterUInt64.lift(try! rustCall() {
1844 + uniffi_demucs_ffi_fn_func_chunk_length($0
1845 )
1846 })
1847 }
1848 /**
1985 - * Override the model cache directory.
1986 - *
1987 - * On iOS/tvOS/visionOS call this once at app launch — before
1988 - * `downloadModel` or `DemucsEngine.loadModel` — with a directory inside the
1989 - * app sandbox, e.g. the app's Application Support or Caches directory.
1990 - * The directory is created if missing.
1849 + * Sets where model weights are stored. Sandboxed apps should call this once
1850 + * at launch with a directory inside their container. Without it, weights go
1851 + * to the platform cache directory under `demucs-rs/`.
1852 */
1853 public func configureCacheDir(path: String) {try! rustCall() {
1993 - uniffi_demucs_fn_func_configure_cache_dir(
1854 + uniffi_demucs_ffi_fn_func_configure_cache_dir(
1855 FfiConverterString.lower(path),$0
1856 )
1857 }
1858 }
1859 /**
1999 - * Delete a model's weights from the local cache. Returns true if a file was
2000 - * removed.
1860 + * Returns `true` if a file was removed.
1861 */
2002 -public func deleteCachedModel(model: DemucsModel) -> Bool {
1862 +public func deleteCachedModel(model: FfiDemucsModel) -> Bool {
1863 return try! FfiConverterBool.lift(try! rustCall() {
2004 - uniffi_demucs_fn_func_delete_cached_model(
2005 - FfiConverterTypeDemucsModel_lower(model),$0
1864 + uniffi_demucs_ffi_fn_func_delete_cached_model(
1865 + FfiConverterTypeFfiDemucsModel_lower(model),$0
1866 )
1867 })
1868 }
1869 /**
2010 - * Whether the model's weights are already in the local cache.
1870 + * Downloads the model's weights from HuggingFace into the cache directory.
1871 + * Returns immediately if they are already there.
1872 */
2012 -public func isModelCached(model: DemucsModel) -> Bool {
1873 +public func downloadModel(model: FfiDemucsModel, listener: FfiDownloadListener)async throws {
1874 + return
1875 + try await uniffiRustCallAsync(
1876 + rustFutureFunc: {
1877 + uniffi_demucs_ffi_fn_func_download_model(FfiConverterTypeFfiDemucsModel_lower(model),FfiConverterCallbackInterfaceFfiDownloadListener_lower(listener)
1878 + )
1879 + },
1880 + pollFunc: ffi_demucs_ffi_rust_future_poll_void,
1881 + completeFunc: ffi_demucs_ffi_rust_future_complete_void,
1882 + freeFunc: ffi_demucs_ffi_rust_future_free_void,
1883 + liftFunc: { $0 },
1884 + errorHandler: FfiConverterTypeFfiDemucsError_lift
1885 + )
1886 +}
1887 +/**
1888 + * All fine-tuned stem selections share one weights file, so this answers the
1889 + * same for every `FineTuned` value.
1890 + */
1891 +public func isModelCached(model: FfiDemucsModel) -> Bool {
1892 return try! FfiConverterBool.lift(try! rustCall() {
2014 - uniffi_demucs_fn_func_is_model_cached(
2015 - FfiConverterTypeDemucsModel_lower(model),$0
1893 + uniffi_demucs_ffi_fn_func_is_model_cached(
1894 + FfiConverterTypeFfiDemucsModel_lower(model),$0
1895 )
1896 })
1897 }
2019 -/**
2020 - * Metadata (name, size, stems, download URL) for a model variant.
2021 - */
2022 -public func modelMetadata(model: DemucsModel) -> ModelMetadata {
2023 - return try! FfiConverterTypeModelMetadata_lift(try! rustCall() {
2024 - uniffi_demucs_fn_func_model_metadata(
2025 - FfiConverterTypeDemucsModel_lower(model),$0
1898 +public func modelMetadata(model: FfiDemucsModel) -> FfiModelMetadata {
1899 + return try! FfiConverterTypeFfiModelMetadata_lift(try! rustCall() {
1900 + uniffi_demucs_ffi_fn_func_model_metadata(
1901 + FfiConverterTypeFfiDemucsModel_lower(model),$0
1902 )
1903 })
1904 }
1905 /**
2030 - * Number of inference chunks a track of `n_samples` (per channel, at
2031 - * 44100 Hz) is split into. Useful for sizing progress UIs.
1906 + * How many chunks `separate` will split this many input samples into, for
1907 + * sizing progress UI up front. `sample_rate` is the input rate; audio is
1908 + * chunked after resampling to 44.1 kHz.
1909 */
2033 -public func numChunks(nSamples: UInt64) -> UInt64 {
1910 +public func numChunks(nSamples: UInt64, sampleRate: UInt32) -> UInt64 {
1911 return try! FfiConverterUInt64.lift(try! rustCall() {
2035 - uniffi_demucs_fn_func_num_chunks(
2036 - FfiConverterUInt64.lower(nSamples),$0
1912 + uniffi_demucs_ffi_fn_func_num_chunks(
1913 + FfiConverterUInt64.lower(nSamples),
1914 + FfiConverterUInt32.lower(sampleRate),$0
1915 )
1916 })
1917 }
2040 -/**
2041 - * Download a model's weights into the local cache.
2042 - *
2043 - * No-op (immediately reports `done`) if the model is already cached. Call
2044 - * `configureCacheDir` first on sandboxed platforms.
2045 - */
2046 -public func downloadModel(model: DemucsModel, listener: DownloadProgressListener)async throws {
2047 - return
2048 - try await uniffiRustCallAsync(
2049 - rustFutureFunc: {
2050 - uniffi_demucs_fn_func_download_model(FfiConverterTypeDemucsModel_lower(model),FfiConverterCallbackInterfaceDownloadProgressListener_lower(listener)
2051 - )
2052 - },
2053 - pollFunc: ffi_demucs_rust_future_poll_void,
2054 - completeFunc: ffi_demucs_rust_future_complete_void,
2055 - freeFunc: ffi_demucs_rust_future_free_void,
2056 - liftFunc: { $0 },
2057 - errorHandler: FfiConverterTypeDemucsFfiError_lift
2058 - )
2059 -}
2060 -/**
2061 - * `DemucsEngine.separate` with progress reporting and cancellation.
2062 - *
2063 - * A free function because UniFFI 0.31 only supports callback interfaces as
2064 - * free-function parameters.
2065 - */
2066 -public func separateWithProgress(engine: DemucsEngine, left: [Float], right: [Float], sampleRate: UInt32, listener: SeparationProgressListener)async throws -> [StemResult] {
2067 - return
2068 - try await uniffiRustCallAsync(
2069 - rustFutureFunc: {
2070 - uniffi_demucs_fn_func_separate_with_progress(FfiConverterTypeDemucsEngine_lower(engine),FfiConverterSequenceFloat.lower(left),FfiConverterSequenceFloat.lower(right),FfiConverterUInt32.lower(sampleRate),FfiConverterCallbackInterfaceSeparationProgressListener_lower(listener)
2071 - )
2072 - },
2073 - pollFunc: ffi_demucs_rust_future_poll_rust_buffer,
2074 - completeFunc: ffi_demucs_rust_future_complete_rust_buffer,
2075 - freeFunc: ffi_demucs_rust_future_free_rust_buffer,
2076 - liftFunc: FfiConverterSequenceTypeStemResult.lift,
2077 - errorHandler: FfiConverterTypeDemucsFfiError_lift
2078 - )
2079 -}
1918
1919 private enum InitializationResult {
1920 case ok
@@ -2089,73 +1927,73 @@ private let initializationResult: InitializationResult = {
1927 // Get the bindings contract version from our ComponentInterface
1928 let bindings_contract_version = 30
1929 // Get the scaffolding contract version by calling the into the dylib
2092 - let scaffolding_contract_version = ffi_demucs_uniffi_contract_version()
1930 + let scaffolding_contract_version = ffi_demucs_ffi_uniffi_contract_version()
1931 if bindings_contract_version != scaffolding_contract_version {
1932 return InitializationResult.contractVersionMismatch
1933 }
2096 - if (uniffi_demucs_checksum_func_all_models() != 40632) {
1934 + if (uniffi_demucs_ffi_checksum_func_all_models() != 35841) {
1935 return InitializationResult.apiChecksumMismatch
1936 }
2099 - if (uniffi_demucs_checksum_func_cached_model_path() != 59385) {
1937 + if (uniffi_demucs_ffi_checksum_func_cached_model_path() != 60660) {
1938 return InitializationResult.apiChecksumMismatch
1939 }
2102 - if (uniffi_demucs_checksum_func_configure_cache_dir() != 33315) {
1940 + if (uniffi_demucs_ffi_checksum_func_chunk_length() != 30511) {
1941 return InitializationResult.apiChecksumMismatch
1942 }
2105 - if (uniffi_demucs_checksum_func_delete_cached_model() != 23501) {
1943 + if (uniffi_demucs_ffi_checksum_func_configure_cache_dir() != 17121) {
1944 return InitializationResult.apiChecksumMismatch
1945 }
2108 - if (uniffi_demucs_checksum_func_is_model_cached() != 9391) {
1946 + if (uniffi_demucs_ffi_checksum_func_delete_cached_model() != 32733) {
1947 return InitializationResult.apiChecksumMismatch
1948 }
2111 - if (uniffi_demucs_checksum_func_model_metadata() != 64919) {
1949 + if (uniffi_demucs_ffi_checksum_func_download_model() != 18057) {
1950 return InitializationResult.apiChecksumMismatch
1951 }
2114 - if (uniffi_demucs_checksum_func_num_chunks() != 27500) {
1952 + if (uniffi_demucs_ffi_checksum_func_is_model_cached() != 62970) {
1953 return InitializationResult.apiChecksumMismatch
1954 }
2117 - if (uniffi_demucs_checksum_func_download_model() != 37675) {
1955 + if (uniffi_demucs_ffi_checksum_func_model_metadata() != 60733) {
1956 return InitializationResult.apiChecksumMismatch
1957 }
2120 - if (uniffi_demucs_checksum_func_separate_with_progress() != 6510) {
1958 + if (uniffi_demucs_ffi_checksum_func_num_chunks() != 4306) {
1959 return InitializationResult.apiChecksumMismatch
1960 }
2123 - if (uniffi_demucs_checksum_method_demucsengine_is_loaded() != 28086) {
1961 + if (uniffi_demucs_ffi_checksum_method_ffidemucsengine_is_loaded() != 13782) {
1962 return InitializationResult.apiChecksumMismatch
1963 }
2126 - if (uniffi_demucs_checksum_method_demucsengine_load_model() != 54613) {
1964 + if (uniffi_demucs_ffi_checksum_method_ffidemucsengine_load_model() != 18700) {
1965 return InitializationResult.apiChecksumMismatch
1966 }
2129 - if (uniffi_demucs_checksum_method_demucsengine_loaded_model() != 45821) {
1967 + if (uniffi_demucs_ffi_checksum_method_ffidemucsengine_loaded_model() != 27072) {
1968 return InitializationResult.apiChecksumMismatch
1969 }
2132 - if (uniffi_demucs_checksum_method_demucsengine_separate() != 52086) {
1970 + if (uniffi_demucs_ffi_checksum_method_ffidemucsengine_separate() != 27889) {
1971 return InitializationResult.apiChecksumMismatch
1972 }
2135 - if (uniffi_demucs_checksum_method_demucsengine_unload_model() != 24792) {
1973 + if (uniffi_demucs_ffi_checksum_method_ffidemucsengine_unload_model() != 21923) {
1974 return InitializationResult.apiChecksumMismatch
1975 }
2138 - if (uniffi_demucs_checksum_method_demucsengine_warmup() != 20811) {
1976 + if (uniffi_demucs_ffi_checksum_method_ffidemucsengine_warmup() != 4128) {
1977 return InitializationResult.apiChecksumMismatch
1978 }
2141 - if (uniffi_demucs_checksum_constructor_demucsengine_new() != 51674) {
1979 + if (uniffi_demucs_ffi_checksum_constructor_ffidemucsengine_new() != 48414) {
1980 return InitializationResult.apiChecksumMismatch
1981 }
2144 - if (uniffi_demucs_checksum_method_downloadprogresslistener_on_progress() != 44819) {
1982 + if (uniffi_demucs_ffi_checksum_method_ffidownloadlistener_on_progress() != 42698) {
1983 return InitializationResult.apiChecksumMismatch
1984 }
2147 - if (uniffi_demucs_checksum_method_separationprogresslistener_on_progress() != 56005) {
1985 + if (uniffi_demucs_ffi_checksum_method_ffiseparationlistener_on_progress() != 32252) {
1986 return InitializationResult.apiChecksumMismatch
1987 }
1988
2151 - uniffiCallbackInitDownloadProgressListener()
2152 - uniffiCallbackInitSeparationProgressListener()
1989 + uniffiCallbackInitFfiDownloadListener()
1990 + uniffiCallbackInitFfiSeparationListener()
1991 return InitializationResult.ok
1992 }()
1993
1994 // Make the ensure init function public so that other modules which have external type references to
1995 // our types can call it.
2158 -public func uniffiEnsureDemucsInitialized() {
1996 +public func uniffiEnsureDemucsFfiInitialized() {
1997 switch initializationResult {
1998 case .ok:
1999 break