#include "zipvoice_c_api.h" #include "zipvoice_resident_server.hpp" #include #include struct ZipVoiceHandle { std::unique_ptr impl; std::string last_error; std::string last_path; }; extern "C" { ZipVoiceHandle *zipvoice_create(const ZipVoiceConfig *cfg) { if (!cfg) return nullptr; auto *h = new ZipVoiceHandle(); h->impl = std::make_unique(); bool ok = h->impl->Init( cfg->root_dir ? cfg->root_dir : "", cfg->model_dir ? cfg->model_dir : "", cfg->token_file ? cfg->token_file : "", cfg->vocoder_model ? cfg->vocoder_model : "", cfg->max_tokens > 0 ? cfg->max_tokens : 384, cfg->max_feat_len > 0 ? cfg->max_feat_len : 1024, cfg->num_step > 0 ? cfg->num_step : 4, cfg->default_speed > 0.0f ? cfg->default_speed : 1.0f, cfg->seed > 0 ? cfg->seed : 42); if (!ok) { delete h; return nullptr; } return h; } void zipvoice_destroy(ZipVoiceHandle *h) { delete h; } int zipvoice_cache_prompt(ZipVoiceHandle *h, const char *key, const char *wav_path, const char *prompt_text) { if (!h || !h->impl || !key || !wav_path || !prompt_text) return 0; bool ok = h->impl->CachePrompt(key, wav_path, prompt_text); if (!ok) h->last_error = "cache_prompt failed"; return ok ? 1 : 0; } ZipVoiceResponseC zipvoice_infer(ZipVoiceHandle *h, const ZipVoiceRequestC *req) { ZipVoiceResponseC out{}; if (!h || !h->impl || !req || !req->text || !req->output_wav) { out.ok = 0; out.error = "invalid arguments"; return out; } ZipVoiceRequest cpp_req; cpp_req.text = req->text; cpp_req.prompt = req->prompt ? req->prompt : "zh"; cpp_req.speed = req->speed; cpp_req.output_wav = req->output_wav; auto resp = h->impl->Infer(cpp_req); out.ok = resp.ok ? 1 : 0; h->last_path = resp.path; h->last_error = resp.error; out.path = h->last_path.c_str(); out.error = h->last_error.empty() ? nullptr : h->last_error.c_str(); out.wall_sec = resp.wall_sec; out.model_sec = resp.model_sec; out.rtf = resp.rtf; return out; } } // extern "C"