mirror of
https://github.com/SWivid/F5-TTS.git
synced 2026-07-28 13:26:59 -07:00
Merge pull request #1309 from Wing900/fix/fix-duration-chunk-allocation
fix: allocate fix_duration across chunks to avoid N× duration blow-up
This commit is contained in:
@@ -474,7 +474,19 @@ def infer_batch_process(
|
||||
if len(ref_text[-1].encode("utf-8")) == 1:
|
||||
ref_text = ref_text + " "
|
||||
|
||||
def _infer_basic(gen_text):
|
||||
# Allocate fix_duration across chunks to avoid each chunk using the full-sentence duration (N× blow-up)
|
||||
if fix_duration is not None and len(gen_text_batches) > 1:
|
||||
ref_audio_len_frames = audio.shape[-1] // hop_length
|
||||
ref_sec = ref_audio_len_frames * hop_length / target_sample_rate
|
||||
target_total = fix_duration - ref_sec
|
||||
weights = [len(c.encode("utf-8")) for c in gen_text_batches]
|
||||
total_w = sum(weights)
|
||||
allocatable = target_total + cross_fade_duration * (len(gen_text_batches) - 1)
|
||||
fix_durations = [ref_sec + allocatable * w / total_w for w in weights]
|
||||
else:
|
||||
fix_durations = [fix_duration] * len(gen_text_batches)
|
||||
|
||||
def _infer_basic(gen_text, fix_dur):
|
||||
local_speed = speed
|
||||
if len(gen_text.encode("utf-8")) < 10:
|
||||
local_speed = 0.3
|
||||
@@ -484,8 +496,8 @@ def infer_batch_process(
|
||||
final_text_list = convert_char_to_pinyin(text_list)
|
||||
|
||||
ref_audio_len = audio.shape[-1] // hop_length
|
||||
if fix_duration is not None:
|
||||
duration = int(fix_duration * target_sample_rate / hop_length)
|
||||
if fix_dur is not None:
|
||||
duration = int(fix_dur * target_sample_rate / hop_length)
|
||||
else:
|
||||
# Calculate duration
|
||||
ref_text_len = len(ref_text.encode("utf-8"))
|
||||
@@ -519,26 +531,27 @@ def infer_batch_process(
|
||||
|
||||
return generated_wave, generated
|
||||
|
||||
def infer_single_process(gen_text):
|
||||
generated_wave, generated = _infer_basic(gen_text)
|
||||
def infer_single_process(gen_text, fix_dur):
|
||||
generated_wave, generated = _infer_basic(gen_text, fix_dur)
|
||||
generated_cpu = generated[0].cpu().numpy()
|
||||
del generated
|
||||
return generated_wave, generated_cpu
|
||||
|
||||
def infer_single_process_streaming(gen_text):
|
||||
def infer_single_process_streaming(gen_text, fix_dur):
|
||||
# for src/f5_tts/socket_server.py
|
||||
generated_wave, generated = _infer_basic(gen_text)
|
||||
generated_wave, generated = _infer_basic(gen_text, fix_dur)
|
||||
del generated
|
||||
for j in range(0, len(generated_wave), chunk_size):
|
||||
yield generated_wave[j : j + chunk_size], target_sample_rate
|
||||
|
||||
if streaming:
|
||||
for gen_text in progress.tqdm(gen_text_batches) if progress is not None else gen_text_batches:
|
||||
for chunk in infer_single_process_streaming(gen_text):
|
||||
batches_iter = progress.tqdm(gen_text_batches) if progress is not None else gen_text_batches
|
||||
for gen_text, fix_dur in zip(batches_iter, fix_durations):
|
||||
for chunk in infer_single_process_streaming(gen_text, fix_dur):
|
||||
yield chunk
|
||||
else:
|
||||
with ThreadPoolExecutor() as executor:
|
||||
futures = [executor.submit(infer_single_process, gen_text) for gen_text in gen_text_batches]
|
||||
futures = [executor.submit(infer_single_process, gt, fd) for gt, fd in zip(gen_text_batches, fix_durations)]
|
||||
for future in progress.tqdm(futures) if progress is not None else futures:
|
||||
result = future.result()
|
||||
if result:
|
||||
|
||||
Reference in New Issue
Block a user