| 688 | } |
| 689 | |
| 690 | runtime::TaskResult MioTTSSession::run(const runtime::TaskRequest & request) { |
| 691 | const auto wall_start = Clock::now(); |
| 692 | require_prepared("MioTTS run"); |
| 693 | if (!request.text_input.has_value() || request.text_input->text.empty()) { |
| 694 | throw std::runtime_error("MioTTS run() requires text_input"); |
| 695 | } |
| 696 | const auto text_length = static_cast<int64_t>( |
| 697 | engine::text::utf8_codepoint_count(request.text_input->text, "MioTTS text_input")); |
| 698 | const auto text_chunk_size_override = engine::text::parse_text_chunk_size_override(request.options); |
| 699 | engine::debug::trace_log_scalar("miotts.text_length", text_length); |
| 700 | if (!request.voice.has_value() || !request.voice->speaker.has_value() || |
| 701 | !request.voice->speaker->audio.has_value()) { |
| 702 | throw std::runtime_error("MioTTS run() requires voice speaker audio"); |
| 703 | } |
| 704 | auto timing_start = Clock::now(); |
| 705 | const auto reference_audio = miocodec::prepare_miocodec_mono_audio( |
| 706 | *request.voice->speaker->audio, |
| 707 | codec_assets_->config.sample_rate); |
| 708 | engine::debug::timing_log_scalar("miotts.audio.reference_prepare_ms", engine::debug::elapsed_ms(timing_start)); |
| 709 | const auto generation = generation_options_from_request(assets_->config, request); |
| 710 | engine::debug::trace_log_scalar("miotts.sampling.max_tokens", generation.max_tokens); |
| 711 | engine::debug::trace_log_scalar("miotts.sampling.temperature", generation.temperature); |
| 712 | engine::debug::trace_log_scalar("miotts.sampling.top_p", generation.top_p); |
| 713 | engine::debug::trace_log_scalar("miotts.sampling.repetition_penalty", generation.repetition_penalty); |
| 714 | engine::debug::trace_log_scalar("miotts.sampling.presence_penalty", generation.presence_penalty); |
| 715 | engine::debug::trace_log_scalar("miotts.sampling.frequency_penalty", generation.frequency_penalty); |
| 716 | const auto best_of_n = best_of_n_from_request( |
| 717 | request, |
| 718 | best_of_n_enabled_, |
| 719 | best_of_n_default_, |
| 720 | best_of_n_max_, |
| 721 | best_of_n_language_); |
| 722 | const auto text_chunks = text_chunk_size_override.has_value() |
| 723 | ? engine::text::split_text_chunks(request.text_input->text, *text_chunk_size_override) |
| 724 | : engine::text::split_text_chunks(request.text_input->text, text_chunk_size_); |
| 725 | engine::debug::trace_log_scalar("miotts.best_of_n.enabled", best_of_n.enabled); |
| 726 | engine::debug::trace_log_scalar("miotts.best_of_n.n", best_of_n.n); |
| 727 | engine::debug::trace_log_scalar( |
| 728 | "miotts.text_chunk_size", |
| 729 | text_chunk_size_override.value_or(text_chunk_size_)); |
| 730 | engine::debug::trace_log_scalar("miotts.text_chunk_count", static_cast<int64_t>(text_chunks.size())); |
| 731 | for (size_t chunk_index = 0; chunk_index < text_chunks.size(); ++chunk_index) { |
| 732 | const std::string prefix = "miotts.text_chunk_" + std::to_string(chunk_index); |
| 733 | engine::debug::trace_log_scalar(prefix + ".text", text_chunks[chunk_index]); |
| 734 | engine::debug::trace_log_scalar( |
| 735 | prefix + ".length", |
| 736 | static_cast<int64_t>(engine::text::utf8_codepoint_count(text_chunks[chunk_index], "MioTTS text chunk"))); |
| 737 | } |
| 738 | timing_start = Clock::now(); |
| 739 | const auto global = global_reference_->embedding_for_reference(reference_audio); |
| 740 | engine::debug::timing_log_scalar("miotts.global_reference_ms", engine::debug::elapsed_ms(timing_start)); |
| 741 | const engine::audio::STFTConfig stft_config{ |
| 742 | codec_assets_->config.n_fft, |
| 743 | codec_assets_->config.hop_length, |
| 744 | codec_assets_->config.n_fft, |
| 745 | true, |
| 746 | engine::audio::STFTPadMode::Reflect, |
| 747 | engine::audio::STFTFamily::Kokoro, |
nothing calls this directly
no test coverage detected