add speed parameter
This commit is contained in:
@@ -4,6 +4,8 @@ High-performance text-to-speech inference using ONNX Runtime.
|
||||
|
||||
## 📰 Update News
|
||||
|
||||
**2025.11.19** - Added `--speed` parameter to control speech synthesis speed (default: 1.05, recommended range: 0.9-1.5).
|
||||
|
||||
**2025.11.19** - Added automatic text chunking for long-form inference. Long texts are split into chunks and synthesized with natural pauses.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace fs = std::filesystem;
|
||||
struct Args {
|
||||
std::string onnx_dir = "../assets/onnx";
|
||||
int total_step = 5;
|
||||
float speed = 1.05f;
|
||||
int n_test = 4;
|
||||
std::vector<std::string> voice_style = {"../assets/voice_styles/M1.json"};
|
||||
std::vector<std::string> text = {
|
||||
@@ -36,6 +37,7 @@ Args parseArgs(int argc, char* argv[]) {
|
||||
std::string arg = argv[i];
|
||||
if (arg == "--onnx-dir" && i + 1 < argc) args.onnx_dir = argv[++i];
|
||||
else if (arg == "--total-step" && i + 1 < argc) args.total_step = std::stoi(argv[++i]);
|
||||
else if (arg == "--speed" && i + 1 < argc) args.speed = std::stof(argv[++i]);
|
||||
else if (arg == "--n-test" && i + 1 < argc) args.n_test = std::stoi(argv[++i]);
|
||||
else if (arg == "--voice-style" && i + 1 < argc) args.voice_style = splitString(argv[++i], ',');
|
||||
else if (arg == "--text" && i + 1 < argc) args.text = splitString(argv[++i], '|');
|
||||
@@ -51,6 +53,7 @@ int main(int argc, char* argv[]) {
|
||||
// --- 1. Parse arguments --- //
|
||||
Args args = parseArgs(argc, argv);
|
||||
int total_step = args.total_step;
|
||||
float speed = args.speed;
|
||||
int n_test = args.n_test;
|
||||
std::string save_dir = args.save_dir;
|
||||
std::vector<std::string> voice_style_paths = args.voice_style;
|
||||
@@ -84,9 +87,9 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
auto result = timer("Generating speech from text", [&]() {
|
||||
if (batch) {
|
||||
return text_to_speech->batch(memory_info, text_list, style, total_step);
|
||||
return text_to_speech->batch(memory_info, text_list, style, total_step, speed);
|
||||
} else {
|
||||
return text_to_speech->call(memory_info, text_list[0], style, total_step);
|
||||
return text_to_speech->call(memory_info, text_list[0], style, total_step, speed);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -160,7 +160,8 @@ TextToSpeech::SynthesisResult TextToSpeech::_infer(
|
||||
Ort::MemoryInfo& memory_info,
|
||||
const std::vector<std::string>& text_list,
|
||||
const Style& style,
|
||||
int total_step
|
||||
int total_step,
|
||||
float speed
|
||||
) {
|
||||
int bsz = text_list.size();
|
||||
|
||||
@@ -213,6 +214,11 @@ TextToSpeech::SynthesisResult TextToSpeech::_infer(
|
||||
auto* dur_data = dp_outputs[0].GetTensorMutableData<float>();
|
||||
std::vector<float> duration(dur_data, dur_data + bsz);
|
||||
|
||||
// Apply speed factor to duration
|
||||
for (auto& dur : duration) {
|
||||
dur /= speed;
|
||||
}
|
||||
|
||||
// Create new tensors for text encoder (previous ones were moved)
|
||||
text_ids_tensor = intArrayToTensor(memory_info, text_ids, text_ids_shape);
|
||||
text_mask_tensor = arrayToTensor(memory_info, text_mask, text_mask_shape);
|
||||
@@ -370,6 +376,7 @@ TextToSpeech::SynthesisResult TextToSpeech::call(
|
||||
const std::string& text,
|
||||
const Style& style,
|
||||
int total_step,
|
||||
float speed,
|
||||
float silence_duration
|
||||
) {
|
||||
if (style.getTtlShape()[0] != 1) {
|
||||
@@ -381,7 +388,7 @@ TextToSpeech::SynthesisResult TextToSpeech::call(
|
||||
float dur_cat = 0.0f;
|
||||
|
||||
for (const auto& chunk : text_list) {
|
||||
auto result = _infer(memory_info, {chunk}, style, total_step);
|
||||
auto result = _infer(memory_info, {chunk}, style, total_step, speed);
|
||||
|
||||
if (wav_cat.empty()) {
|
||||
wav_cat = result.wav;
|
||||
@@ -406,9 +413,10 @@ TextToSpeech::SynthesisResult TextToSpeech::batch(
|
||||
Ort::MemoryInfo& memory_info,
|
||||
const std::vector<std::string>& text_list,
|
||||
const Style& style,
|
||||
int total_step
|
||||
int total_step,
|
||||
float speed
|
||||
) {
|
||||
return _infer(memory_info, text_list, style, total_step);
|
||||
return _infer(memory_info, text_list, style, total_step, speed);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
const std::string& text,
|
||||
const Style& style,
|
||||
int total_step,
|
||||
float speed = 1.05f,
|
||||
float silence_duration = 0.3f
|
||||
);
|
||||
|
||||
@@ -98,7 +99,8 @@ public:
|
||||
Ort::MemoryInfo& memory_info,
|
||||
const std::vector<std::string>& text_list,
|
||||
const Style& style,
|
||||
int total_step
|
||||
int total_step,
|
||||
float speed = 1.05f
|
||||
);
|
||||
|
||||
int getSampleRate() const { return sample_rate_; }
|
||||
@@ -108,7 +110,8 @@ private:
|
||||
Ort::MemoryInfo& memory_info,
|
||||
const std::vector<std::string>& text_list,
|
||||
const Style& style,
|
||||
int total_step
|
||||
int total_step,
|
||||
float speed = 1.05f
|
||||
);
|
||||
Config cfgs_;
|
||||
UnicodeProcessor* text_processor_;
|
||||
|
||||
Reference in New Issue
Block a user