mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-22 07:10:28 +02:00
- domain/subtitle_processor.py: parse_subtitle_file, format_time_range, speed_up_audio, fit_audio_to_duration (moved from audio_buffer), process_subtitle_entries (core TTS loop with cancel/log/progress callbacks) - domain/audio_buffer.py: add fit_audio_to_duration, ffmpeg_time_stretch - domain/output_paths.py: add resolve_unique_path (collision-safe filename) - pyqt/conversion.py: _process_subtitle_file reduced from ~350 to ~100 lines by delegating to domain functions; removed 4 unused subtitle parser imports - +33 tests (8 resolve_unique_path, 14 subtitle_processor, 8 audio_buffer, 3 format_time_range) - 1153 tests pass
60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
"""Tests for domain/audio_buffer.py — fit_audio_to_duration, ffmpeg_time_stretch."""
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
from abogen.domain.audio_buffer import fit_audio_to_duration, ffmpeg_time_stretch, SAMPLE_RATE
|
|
|
|
|
|
class TestFitAudioToDuration:
|
|
def test_exact_length(self):
|
|
audio = np.ones(24000, dtype="float32")
|
|
result = fit_audio_to_duration(audio, 1.0, SAMPLE_RATE)
|
|
assert len(result) == 24000
|
|
|
|
def test_shorter_pads_with_zeros(self):
|
|
audio = np.ones(12000, dtype="float32")
|
|
result = fit_audio_to_duration(audio, 1.0, SAMPLE_RATE)
|
|
assert len(result) == 24000
|
|
assert result[0] == 1.0
|
|
assert result[12000] == 0.0
|
|
|
|
def test_longer_trims(self):
|
|
audio = np.ones(48000, dtype="float32")
|
|
result = fit_audio_to_duration(audio, 1.0, SAMPLE_RATE)
|
|
assert len(result) == 24000
|
|
assert result[-1] == 1.0
|
|
|
|
def test_empty_input(self):
|
|
result = fit_audio_to_duration(np.array([], dtype="float32"), 0.5, SAMPLE_RATE)
|
|
assert len(result) == 12000
|
|
assert np.all(result == 0.0)
|
|
|
|
def test_output_dtype(self):
|
|
audio = np.ones(100, dtype="float32")
|
|
result = fit_audio_to_duration(audio, 0.5, SAMPLE_RATE)
|
|
assert result.dtype == np.float32
|
|
|
|
|
|
class TestFfmpegTimeStretch:
|
|
def test_no_stretch_below_threshold(self):
|
|
audio = np.ones(24000, dtype="float32")
|
|
result = ffmpeg_time_stretch(audio, 0.8, SAMPLE_RATE)
|
|
np.testing.assert_array_equal(result, audio)
|
|
|
|
def test_no_stretch_at_exactly_one(self):
|
|
audio = np.ones(24000, dtype="float32")
|
|
result = ffmpeg_time_stretch(audio, 1.0, SAMPLE_RATE)
|
|
np.testing.assert_array_equal(result, audio)
|
|
|
|
def test_empty_audio(self):
|
|
result = ffmpeg_time_stretch(np.array([], dtype="float32"), 2.0, SAMPLE_RATE)
|
|
assert len(result) == 0
|
|
|
|
def test_stretch_reduces_duration(self):
|
|
audio = np.random.randn(48000).astype("float32")
|
|
result = ffmpeg_time_stretch(audio, 2.0, SAMPLE_RATE)
|
|
assert len(result) < len(audio)
|
|
assert len(result) > 0
|
|
assert result.dtype == np.float32
|