File size: 4,173 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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
 * Inflect-Micro-v2 OpenAI-compatible TTS Server
 *
 * Start:  tts_server [--port 8000] [--host 0.0.0.0]
 *
 * API:
 *   GET  /health          → {"status":"ok"}
 *   GET  /v1/models       → model list
 *   POST /v1/audio/speech → {"model":"tts-1","input":"Hello"} → audio/wav
 *
 * Dependencies: cpp-httplib (header-only), nlohmann/json (header-only)
 *   git clone https://github.com/yhirose/cpp-httplib.git
 *   git clone https://github.com/nlohmann/json.git
 *
 * Build: cmake .. -DCPPHTTPLIB_DIR=... -DJSON_DIR=... && make tts_server
 */
#include <iostream>
#include <sstream>
#include <string>
#include <thread>
#include <chrono>
// #include <httplib.h>      // cpp-httplib
// #include <nlohmann/json.hpp> // nlohmann/json
#include "inflect_tts.hpp"

// ---- Simple HTTP server without external deps (production: use cpp-httplib) ----

static void handle_request(const std::string& method, const std::string& path,
                           const std::string& body, std::string& response) {
    // Health check
    if (path == "/health") {
        response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"
                   "{\"status\":\"ok\",\"model\":\"inflect-micro-v2\"}";
        return;
    }

    // POST /v1/audio/speech
    if (method == "POST" && path == "/v1/audio/speech") {
        // Parse JSON body (simplified; production: use nlohmann/json)
        std::string text;
        float speed = 1.0f;

        // Extract "input" field
        size_t pos = body.find("\"input\":\"");
        if (pos != std::string::npos) {
            pos += 9;
            size_t end = body.find("\"", pos);
            if (end != std::string::npos) text = body.substr(pos, end - pos);
        }

        if (text.empty()) {
            response = "HTTP/1.1 400 Bad Request\r\n\r\n";
            return;
        }

        try {
            static TTSEngine engine("../models/inflect_encoder.axmodel", "../models/inflect_decoder.axmodel");
            auto waveform = engine.synthesize(text, speed);

            std::ostringstream wav_data;
            // Simplified: write raw float32 PCM; production: add WAV header
            wav_data.write(reinterpret_cast<const char*>(waveform.data()),
                           waveform.size() * sizeof(float));

            std::ostringstream resp;
            resp << "HTTP/1.1 200 OK\r\n"
                 << "Content-Type: audio/wav\r\n"
                 << "Content-Length: " << wav_data.str().size() << "\r\n"
                 << "X-Sample-Rate: 24000\r\n"
                 << "\r\n"
                 << wav_data.str();
            response = resp.str();
        } catch (const std::exception& e) {
            response = "HTTP/1.1 500 Internal Server Error\r\n\r\n";
        }
        return;
    }

    response = "HTTP/1.1 404 Not Found\r\n\r\n";
}

int main(int argc, char* argv[]) {
    int port = 8000;
    std::string host = "0.0.0.0";

    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--port") == 0 && i + 1 < argc)
            port = std::stoi(argv[++i]);
        else if (strcmp(argv[i], "--host") == 0 && i + 1 < argc)
            host = argv[++i];
    }

    std::cout << "🎤 Inflect-Micro-v2 TTS Server\n";
    std::cout << "   Listening on " << host << ":" << port << "\n";
    std::cout << "   POST /v1/audio/speech  (OpenAI-compatible)\n";
    std::cout << "   GET  /health\n";
    std::cout << "\n";
    std::cout << "   Example:\n";
    std::cout << "   curl -X POST http://localhost:" << port << "/v1/audio/speech \\\n";
    std::cout << "     -H 'Content-Type: application/json' \\\n";
    std::cout << "     -d '{\"model\":\"tts-1\",\"input\":\"Hello world\"}' \\\n";
    std::cout << "     --output speech.wav\n";
    std::cout << "\n";
    std::cout << "   Note: Production build requires cpp-httplib + nlohmann/json.\n";
    std::cout << "         See CMakeLists.txt for setup instructions.\n";

    // TODO: Production HTTP loop using cpp-httplib
    // httplib::Server svr;
    // svr.Post("/v1/audio/speech", [&](const httplib::Request& req, httplib::Response& res) {
    //     ...
    // });
    // svr.listen(host.c_str(), port);

    return 0;
}