AudioGen: Auto-Trim Stille für besseres Looping
Neue Option 'trim_silence' (Ja/Nein) im AudioGen Node. Schneidet automatisch Stille am Anfang und Ende ab (Threshold -40dB, 10ms Padding). Default: Ja. Besseres Loop-Verhalten da keine Pause mehr am Anfang. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8768edc16c
commit
b90b816063
2 changed files with 30 additions and 6 deletions
|
|
@ -144,6 +144,22 @@ class MusicGenLongNode:
|
|||
return (out_path + ".wav",)
|
||||
|
||||
|
||||
def _trim_silence(wav, sample_rate, threshold_db=-40.0, pad_ms=10):
|
||||
"""Schneidet Stille am Anfang und Ende ab"""
|
||||
threshold = 10 ** (threshold_db / 20.0)
|
||||
# Mono oder Stereo: max über alle Kanäle
|
||||
amplitude = wav.abs().max(dim=0).values
|
||||
above = (amplitude > threshold).nonzero(as_tuple=True)[0]
|
||||
if len(above) == 0:
|
||||
return wav
|
||||
start = max(0, above[0].item() - int(pad_ms * sample_rate / 1000))
|
||||
end = min(wav.shape[1], above[-1].item() + int(pad_ms * sample_rate / 1000))
|
||||
trimmed = wav[:, start:end]
|
||||
if trimmed.shape[1] != wav.shape[1]:
|
||||
print(f"[Trim] {wav.shape[1]/sample_rate:.2f}s → {trimmed.shape[1]/sample_rate:.2f}s (Stille entfernt)")
|
||||
return trimmed
|
||||
|
||||
|
||||
def _next_number(output_dir, base_name):
|
||||
"""Findet die nächste fortlaufende Nummer für einen Dateinamen"""
|
||||
pattern = os.path.join(output_dir, f"{base_name}_*.wav")
|
||||
|
|
@ -168,6 +184,7 @@ class AudioGenNode:
|
|||
"temperature": ("FLOAT", {"default": 1.0, "min": 0.1, "max": 2.0, "step": 0.05}),
|
||||
"cfg_coef": ("FLOAT", {"default": 3.0, "min": 0.5, "max": 10.0, "step": 0.5}),
|
||||
"top_k": ("INT", {"default": 250, "min": 1, "max": 1000}),
|
||||
"trim_silence": (["Ja", "Nein"], {"default": "Ja"}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +194,7 @@ class AudioGenNode:
|
|||
CATEGORY = "AudioCraft"
|
||||
OUTPUT_NODE = True
|
||||
|
||||
def generate(self, prompt, name, duration, seed, temperature, cfg_coef, top_k):
|
||||
def generate(self, prompt, name, duration, seed, temperature, cfg_coef, top_k, trim_silence):
|
||||
from audiocraft.models import AudioGen
|
||||
from audiocraft.data.audio import audio_write
|
||||
|
||||
|
|
@ -195,6 +212,10 @@ class AudioGenNode:
|
|||
|
||||
print(f"[AudioGen] Generating: {prompt}")
|
||||
wav = ag.generate([prompt])
|
||||
result = wav[0].cpu()
|
||||
|
||||
if trim_silence == "Ja":
|
||||
result = _trim_silence(result, ag.sample_rate)
|
||||
|
||||
output_dir = "/app/ComfyUI/output/audio"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
|
@ -202,8 +223,8 @@ class AudioGenNode:
|
|||
num = _next_number(output_dir, base_name)
|
||||
filename = f"{base_name}_{num:03d}"
|
||||
out_path = os.path.join(output_dir, filename)
|
||||
audio_write(out_path, wav[0].cpu(), ag.sample_rate, strategy="loudness")
|
||||
print(f"[AudioGen] Saved: {filename}.wav")
|
||||
audio_write(out_path, result, ag.sample_rate, strategy="loudness")
|
||||
print(f"[AudioGen] Saved: {filename}.wav ({result.shape[1]/ag.sample_rate:.2f}s)")
|
||||
|
||||
return (out_path + ".wav",)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@
|
|||
"fixed",
|
||||
0.8,
|
||||
4.5,
|
||||
200
|
||||
200,
|
||||
"Ja"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -79,7 +80,8 @@
|
|||
"fixed",
|
||||
1.0,
|
||||
3.5,
|
||||
250
|
||||
250,
|
||||
"Ja"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -135,7 +137,8 @@
|
|||
"fixed",
|
||||
1.0,
|
||||
3.0,
|
||||
250
|
||||
250,
|
||||
"Ja"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue