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