File size: 2,407 Bytes
1dfb01c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import Foundation

/// Loads a precomputed RoPE table from an .npy file.
/// Parses the numpy float16 binary format and returns Float32 values.
func loadRopeTable(_ name: String) throws -> [Float] {
    let url = PlapreConfig.repoRoot.appendingPathComponent(name)

    guard FileManager.default.fileExists(atPath: url.path) else {
        throw DataLoadingError.fileNotFound(url.path)
    }

    let data = try Data(contentsOf: url)

    // Find header end (newline after header)
    var headerEnd = 0
    for i in 0..<data.count {
        if data[i] == 0x0A {
            if i > 5 {
                headerEnd = i + 1
                let remaining = data.count - headerEnd
                if remaining % 2 == 0 {  // float16 = 2 bytes
                    break
                }
            }
        }
    }

    let rawData = data.subdata(in: headerEnd..<data.count)
    let count = rawData.count / 2
    var result = [Float](repeating: 0, count: count)

    rawData.withUnsafeBytes { ptr in
        let f16 = ptr.bindMemory(to: Float16.self)
        for i in 0..<count {
            result[i] = Float(f16[i])
        }
    }

    return result
}

/// Loads a speaker embedding from speakers.json.
func loadSpeaker(_ name: String) throws -> [Float] {
    let url = PlapreConfig.repoRoot.appendingPathComponent("speakers.json")

    guard FileManager.default.fileExists(atPath: url.path) else {
        throw DataLoadingError.fileNotFound(url.path)
    }

    let data = try Data(contentsOf: url)
    let json = try JSONSerialization.jsonObject(with: data) as? [String: [Double]]

    guard let speakers = json else {
        throw DataLoadingError.invalidFormat("speakers.json")
    }

    guard let embedding = speakers[name] else {
        throw DataLoadingError.speakerNotFound(name, speakers.keys.sorted())
    }

    return embedding.map { Float($0) }
}

enum DataLoadingError: LocalizedError {
    case fileNotFound(String)
    case invalidFormat(String)
    case speakerNotFound(String, [String])

    var errorDescription: String? {
        switch self {
        case .fileNotFound(let path):
            return "File not found: \(path)"
        case .invalidFormat(let file):
            return "Invalid format in: \(file)"
        case .speakerNotFound(let name, let available):
            return "Speaker '\(name)' not found. Available: \(available.joined(separator: ", "))"
        }
    }
}