yangrongzhao
Inflect-Nano-v2 for AX650 NPU3
a44ca9d
Raw
History Blame Contribute Delete
3.18 kB
/**
* Inflect-Nano-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 <stdexcept>
#include "inflect_tts.hpp"
static const char* kUsage = R"(Usage: tts_cli --text <TEXT> [OPTIONS]
Options:
--text <TEXT> Text to synthesize (required)
--output <PATH> Output WAV file (default: output.wav)
--encoder <PATH> Encoder AXMODEL path (default: ../models/inflect_encoder.axmodel)
--decoder <PATH> Decoder AXMODEL path (default: ../models/inflect_decoder.axmodel)
--speed <FLOAT> Playback speed 0.5-2.0 (default: 1.0)
--variation <FLOAT> Voice variation 0.0-1.0 (default: 0.667)
-h, --help Show this help
)";
int main(int argc, char* argv[]) {
std::string text;
std::string output = "output.wav";
std::string encoder_path = "../models/inflect_encoder.axmodel";
std::string decoder_path = "../models/inflect_decoder.axmodel";
float speed = 1.0f;
float variation = 0.667f;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if ((arg == "--text" || arg == "-t") && i + 1 < argc)
text = argv[++i];
else if (arg == "--output" && i + 1 < argc)
output = argv[++i];
else if (arg == "--encoder" && i + 1 < argc)
encoder_path = argv[++i];
else if (arg == "--decoder" && i + 1 < argc)
decoder_path = argv[++i];
else if (arg == "--speed" && i + 1 < argc)
speed = std::stof(argv[++i]);
else if (arg == "--variation" && i + 1 < argc)
variation = std::stof(argv[++i]);
else if (arg == "--help" || arg == "-h") {
std::cout << kUsage; return 0;
}
}
if (text.empty()) {
std::cerr << "Error: --text is required\n" << kUsage;
return 1;
}
std::cout << "🎀 Text: " << text << "\n";
std::cout << "πŸ“ Output: " << output << "\n";
try {
TTSEngine engine(encoder_path, decoder_path);
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 << "⏱ " << elapsed << "s wall, "
<< duration << "s audio, RTF="
<< (duration > 0 ? elapsed / duration : 0) << "x\n";
// Write raw float32 PCM (add WAV header with libsndfile in production)
std::ofstream out(output, std::ios::binary);
if (!out) {
std::cerr << "Error: cannot open " << output << "\n";
return 1;
}
out.write(reinterpret_cast<const char*>(waveform.data()),
waveform.size() * sizeof(float));
std::cout << "βœ… Done β†’ " << output << "\n";
} catch (const std::exception& e) {
std::cerr << "❌ Error: " << e.what() << "\n";
return 1;
}
return 0;
}