File size: 3,614 Bytes
a44ca9d | 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 | /**
* Inflect-Nano-v2 OpenAI-compatible TTS Server
*
* Start: tts_server [--port 8000] [--host 0.0.0.0]
*
* API:
* GET /health
* GET /v1/models
* POST /v1/audio/speech (OpenAI TTS)
*
* Dependencies (production):
* - cpp-httplib (https://github.com/yhirose/cpp-httplib)
* - nlohmann/json (https://github.com/nlohmann/json)
*
* Build: cmake .. -DCPPHTTPLIB_DIR=... -DJSON_DIR=... && make tts_server
*/
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <stdexcept>
#include "inflect_tts.hpp"
// ---- placeholder: replace with cpp-httplib in production ----
static void print_startup(int host, int port) {
std::cout << "🎤 Inflect-Nano-v2 TTS Server\n";
std::cout << " Listening on 0.0.0.0:" << port << "\n";
std::cout << "\n";
std::cout << " POST /v1/audio/speech (OpenAI-compatible)\n";
std::cout << " GET /health\n";
std::cout << " GET /v1/models\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 << " ⚠ Production build requires cpp-httplib + nlohmann/json.\n";
std::cout << " git clone https://github.com/yhirose/cpp-httplib.git\n";
std::cout << " git clone https://github.com/nlohmann/json.git\n";
std::cout << " cmake .. -DCPPHTTPLIB_DIR=<path> -DJSON_DIR=<path>\n";
}
// ---- Production HTTP handler (uncomment with cpp-httplib) ----
/*
static std::string handle_speech(TTSEngine& engine, const std::string& body) {
auto j = nlohmann::json::parse(body);
std::string text = j.value("input", "");
float speed = j.value("speed", 1.0f);
float variation = j.value("variation", 0.667f);
auto waveform = engine.synthesize(text, speed, variation);
// Write WAV
std::ostringstream wav;
int sample_rate = 24000;
int data_size = waveform.size() * sizeof(float) * 8 / 16; // convert to int16
// ... WAV header + int16 samples ...
return wav.str();
}
*/
int main(int argc, char* argv[]) {
int port = 8000;
for (int i = 1; i < argc; ++i) {
if ((strcmp(argv[i], "--port") == 0 || strcmp(argv[i], "-p") == 0)
&& i + 1 < argc)
port = std::stoi(argv[++i]);
}
print_startup(0, port);
// TODO: Production HTTP loop with cpp-httplib
//
// httplib::Server svr;
//
// TTSEngine engine("../models/inflect_encoder.axmodel",
// "../models/inflect_decoder.axmodel");
//
// svr.Get("/health", [](const httplib::Request&, httplib::Response& res) {
// res.set_content("{\"status\":\"ok\",\"model\":\"inflect-nano-v2\"}",
// "application/json");
// });
//
// svr.Get("/v1/models", [](const httplib::Request&, httplib::Response& res) {
// res.set_content("{\"object\":\"list\",\"data\":[{\"id\":\"inflect-nano-v2\""
// ",\"object\":\"model\",\"owned_by\":\"owensong\"}]}",
// "application/json");
// });
//
// svr.Post("/v1/audio/speech", [&](const httplib::Request& req,
// httplib::Response& res) {
// auto wav = handle_speech(engine, req.body);
// res.set_content(wav, "audio/wav");
// });
//
// svr.listen("0.0.0.0", port);
return 0;
}
|