diff --git a/Package.swift b/Package.swift index d3da1272..acf6c677 100644 --- a/Package.swift +++ b/Package.swift @@ -29,7 +29,8 @@ let package = Package( ], path: "Sources/FluidAudio", resources: [ - .copy("TTS/LuxTts/G2p/Resources") + // Keep .process: .copy of a Resources-named directory breaks Apple code signing on iOS. + .process("TTS/LuxTts/G2p/Resources") ] ), // Byte-exact NeMo text normalization (FST engine, all 7 languages). @@ -66,7 +67,7 @@ let package = Package( "FluidAudioCLI", ], resources: [ - .copy("TTS/LuxTts/Resources") + .process("TTS/LuxTts/Resources") ] ), ], diff --git a/Sources/FluidAudio/TTS/LuxTts/G2p/LuxTtsG2p.swift b/Sources/FluidAudio/TTS/LuxTts/G2p/LuxTtsG2p.swift index 8d664e98..19e46c37 100644 --- a/Sources/FluidAudio/TTS/LuxTts/G2p/LuxTtsG2p.swift +++ b/Sources/FluidAudio/TTS/LuxTts/G2p/LuxTtsG2p.swift @@ -77,11 +77,9 @@ public struct LuxTtsG2p: Sendable { public init() throws { guard let lexiconURL = Bundle.module.url( - forResource: "luxtts_en_us_lexicon.tsv", withExtension: "zz", - subdirectory: "Resources"), + forResource: "luxtts_en_us_lexicon.tsv", withExtension: "zz"), let auxURL = Bundle.module.url( - forResource: "luxtts_en_us_g2p_aux", withExtension: "json", - subdirectory: "Resources") + forResource: "luxtts_en_us_g2p_aux", withExtension: "json") else { throw LuxTtsError.tokenizerFailed("bundled G2P resources missing") } diff --git a/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsFixtures.swift b/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsFixtures.swift index bcc0a96c..019c808f 100644 --- a/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsFixtures.swift +++ b/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsFixtures.swift @@ -120,10 +120,7 @@ struct LuxTtsFixtures: Decodable { // MARK: - Loading static func resourceURL(_ name: String) throws -> URL { - guard - let url = Bundle.module.url( - forResource: name, withExtension: nil, subdirectory: "Resources") - else { + guard let url = Bundle.module.url(forResource: name, withExtension: nil) else { throw XCTSkip("LuxTts fixture resource missing: \(name)") } return url diff --git a/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsG2pTests.swift b/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsG2pTests.swift index a942e7b6..a4f0782a 100644 --- a/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsG2pTests.swift +++ b/Tests/FluidAudioTests/TTS/LuxTts/LuxTtsG2pTests.swift @@ -12,6 +12,21 @@ import XCTest /// the mobius worktree; these tests pin representative behaviors. final class LuxTtsG2pTests: XCTestCase { + func testFixtureResourcesAreProcessedAtBundleRoot() { + XCTAssertFalse( + FileManager.default.fileExists( + atPath: Bundle.module.bundleURL + .appendingPathComponent("Resources", isDirectory: true).path + ), + "LuxTTS test resources must not create a reserved top-level Resources directory" + ) + XCTAssertTrue( + FileManager.default.fileExists( + atPath: Bundle.module.bundleURL.appendingPathComponent("luxtts_fixtures.json").path + ) + ) + } + private static let g2p: LuxTtsG2p = { do { return try LuxTtsG2p()