File size: 2,683 Bytes
7cbe545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
afdce78
7cbe545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/**
 * Inflect-Micro-v2 TTS CLI
 *
 * Usage: tts_cli --text "Hello world" --output output.wav [--speed 1.0]
 *
 * Build: cmake .. && make tts_cli
 */
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <chrono>
#include "inflect_tts.hpp"

static void print_usage(const char* prog) {
    std::cerr << "Usage: " << prog << " --text <TEXT> [--output out.wav] [--speed 1.0]\n";
    std::cerr << "Options:\n";
    std::cerr << "  --text       Text to synthesize (required)\n";
    std::cerr << "  --output     Output file path (default: output.wav)\n";
    std::cerr << "  --speed      Playback speed 0.5-2.0 (default: 1.0)\n";
    std::cerr << "  --variation  Voice variation 0.0-1.0 (default: 0.667)\n";
}

int main(int argc, char* argv[]) {
    std::string text;
    std::string output = "output.wav";
    float speed = 1.0f;
    float variation = 0.667f;

    // Parse arguments
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--text") == 0 && i + 1 < argc)
            text = argv[++i];
        else if (strcmp(argv[i], "--output") == 0 && i + 1 < argc)
            output = argv[++i];
        else if (strcmp(argv[i], "--speed") == 0 && i + 1 < argc)
            speed = std::stof(argv[++i]);
        else if (strcmp(argv[i], "--variation") == 0 && i + 1 < argc)
            variation = std::stof(argv[++i]);
        else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
            print_usage(argv[0]); return 0;
        }
    }

    if (text.empty()) {
        std::cerr << "Error: --text is required\n";
        print_usage(argv[0]);
        return 1;
    }

    std::cout << "๐ŸŽค Text: " << text << "\n";
    std::cout << "๐Ÿ“ Output: " << output << "\n";

    try {
        TTSEngine engine("../models/inflect_encoder.axmodel", "../models/inflect_decoder.axmodel");

        auto t0 = std::chrono::steady_clock::now();
        auto waveform = engine.synthesize(text, speed, variation);
        auto t1 = std::chrono::steady_clock::now();

        double elapsed = std::chrono::duration<double>(t1 - t0).count();
        double duration = waveform.size() / 24000.0;
        std::cout << "โœ… Done! " << duration << "s audio, RTF=" << elapsed/duration << "x\n";

        // Write WAV (simplified: raw float32 for now, use libsndfile for proper WAV)
        std::ofstream out(output, std::ios::binary);
        out.write(reinterpret_cast<const char*>(waveform.data()),
                  waveform.size() * sizeof(float));
        std::cout << "๐Ÿ”Š " << output << "\n";

    } catch (const std::exception& e) {
        std::cerr << "โŒ Error: " << e.what() << "\n";
        return 1;
    }

    return 0;
}