From 28edb46955522865b869974444b25b47d67bc3b6 Mon Sep 17 00:00:00 2001 From: ydharavath Date: Mon, 22 Jun 2026 08:03:46 +0000 Subject: [PATCH 1/2] feat(tts): add --word_time_offsets flag and print word timings Point nvriva_common at the fork carrying the new TTS proto fields. Co-Authored-By: Claude Opus 4.8 (1M context) --- WORKSPACE | 6 ++++-- riva/clients/tts/riva_tts_client.cc | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 470ba0c..c3bf7ed 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -76,8 +76,10 @@ grpc_extra_deps() git_repository( name = "nvriva_common", - remote = "https://github.com/nvidia-riva/common.git", - commit = "71df98266725320a6b6b3a9f32a6da832dc93691" + # Fork of nvidia-riva/common@71df982 (current upstream main) plus the TTS + # word-timestamp proto fields (enable_word_time_offsets / WordTiming). + remote = "https://github.com/ydharavath/common.git", + commit = "560795e" ) http_archive( diff --git a/riva/clients/tts/riva_tts_client.cc b/riva/clients/tts/riva_tts_client.cc index b7501f2..94811de 100644 --- a/riva/clients/tts/riva_tts_client.cc +++ b/riva/clients/tts/riva_tts_client.cc @@ -55,6 +55,9 @@ DEFINE_string( "Input audio prompt file for Zero Shot Model. Audio length should be between 3-10 seconds."); DEFINE_int32(zero_shot_quality, 20, "Required quality of output audio, ranges between 1-40."); DEFINE_string(custom_dictionary, "", " User dictionary containing graph-to-phone custom words"); +DEFINE_bool( + word_time_offsets, false, + "If true, request per-word start/end timestamps (returned in response metadata)."); DEFINE_string(zero_shot_transcript, "", "Transcript corresponding to Zero shot audio prompt."); DEFINE_uint64(timeout_ms, 10000, "Timeout for GRPC channel creation"); DEFINE_uint64(max_grpc_message_size, MAX_GRPC_MESSAGE_SIZE, "Max GRPC message size"); @@ -239,6 +242,7 @@ main(int argc, char** argv) request.set_sample_rate_hz(rate); request.set_voice_name(FLAGS_voice_name); + request.set_enable_word_time_offsets(FLAGS_word_time_offsets); if (not FLAGS_zero_shot_audio_prompt.empty()) { auto zero_shot_data = request.mutable_zero_shot_data(); std::vector> audio_prompt; @@ -301,6 +305,12 @@ main(int argc, char** argv) auto audio = response.audio(); LOG(INFO) << "Got " << audio.length() << " bytes back from server" << std::endl; + if (FLAGS_word_time_offsets) { + for (const auto& word : response.meta().words()) { + LOG(INFO) << "word: \"" << word.word() << "\" start: " << word.start_time() + << " ms end: " << word.end_time() << " ms" << std::endl; + } + } // Write to WAV file if (FLAGS_audio_encoding.empty() || FLAGS_audio_encoding == "pcm") { ::riva::utils::wav::Write( From 2c28399f1f44ad0929825ffb9371608ef75f34da Mon Sep 17 00:00:00 2001 From: ydharavath Date: Tue, 23 Jun 2026 10:49:11 +0000 Subject: [PATCH 2/2] feat(tts): print word timestamps in streaming client + perf-client --word_time_offsets --- riva/clients/tts/riva_tts_client.cc | 7 +++++++ riva/clients/tts/riva_tts_perf_client.cc | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/riva/clients/tts/riva_tts_client.cc b/riva/clients/tts/riva_tts_client.cc index 94811de..b7746eb 100644 --- a/riva/clients/tts/riva_tts_client.cc +++ b/riva/clients/tts/riva_tts_client.cc @@ -363,6 +363,13 @@ main(int argc, char** argv) std::copy(opus_data, opus_data + len, std::back_inserter(opus_buffer)); audio_len += len; } + // Word timestamps arrive in the final chunk's metadata. + if (FLAGS_word_time_offsets) { + for (const auto& word : chunk.meta().words()) { + LOG(INFO) << "word: \"" << word.word() << "\" start: " << word.start_time() + << " ms end: " << word.end_time() << " ms" << std::endl; + } + } } grpc::Status rpc_status = reader->Finish(); auto end = std::chrono::steady_clock::now(); diff --git a/riva/clients/tts/riva_tts_perf_client.cc b/riva/clients/tts/riva_tts_perf_client.cc index 20bad2f..916e9bd 100644 --- a/riva/clients/tts/riva_tts_perf_client.cc +++ b/riva/clients/tts/riva_tts_perf_client.cc @@ -46,6 +46,9 @@ DEFINE_string( language, "en-US", "Language code as per [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag."); DEFINE_string(voice_name, "", "Desired voice name"); +DEFINE_bool( + word_time_offsets, false, + "If true, request per-word start/end timestamps (returned in response metadata)."); DEFINE_int32(num_iterations, 1, "Number of times to loop over audio files"); DEFINE_int32(num_parallel_requests, 1, "Number of parallel requests to keep in flight"); DEFINE_int32(num_sentences, 1, "Number of sentences to send"); @@ -153,6 +156,7 @@ synthesizeBatch( request.set_language_code(language); request.set_sample_rate_hz(rate); request.set_voice_name(voice_name); + request.set_enable_word_time_offsets(FLAGS_word_time_offsets); if (FLAGS_audio_encoding.empty() || FLAGS_audio_encoding == "pcm") { request.set_encoding(nr::LINEAR_PCM); } else if (FLAGS_audio_encoding == "opus") { @@ -251,6 +255,7 @@ synthesizeOnline( request.set_language_code(language); request.set_sample_rate_hz(rate); request.set_voice_name(voice_name); + request.set_enable_word_time_offsets(FLAGS_word_time_offsets); auto ae = nr::AudioEncoding::ENCODING_UNSPECIFIED; if (FLAGS_audio_encoding.empty() || FLAGS_audio_encoding == "pcm") { ae = nr::LINEAR_PCM;