diff options
| author | historia <historiavg@proton.me> | 2026-08-20 18:06:22 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-08-20 18:06:22 -0400 |
| commit | 5ca77f86b70718b4ef1a07299efbd6431268d546 (patch) | |
| tree | e50a439ea7a92bd628f78240fdbc2d4093df6928 /tests/test_tts.py | |
| parent | b873844f7eb681119542661ef588c5b452f88763 (diff) | |
| download | tts-audiobook-generator-5ca77f86b70718b4ef1a07299efbd6431268d546.tar.gz | |
fix: do not chunk with audio.cpp backend (double chunking)
Diffstat (limited to 'tests/test_tts.py')
| -rw-r--r-- | tests/test_tts.py | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/tests/test_tts.py b/tests/test_tts.py index 9ca6f0d..ec357c1 100644 --- a/tests/test_tts.py +++ b/tests/test_tts.py @@ -703,7 +703,8 @@ class AudioCppTTSClientRequestTests(unittest.TestCase): self._tmp.cleanup() @staticmethod - def _make_client(preset_mode=False, voice="Vivian", language="English", seed=-1): + def _make_client(preset_mode=False, voice="Vivian", language="English", seed=-1, + chunk_text=True): client = AudioCppTTSClient.__new__(AudioCppTTSClient) client.api_url = "http://127.0.0.1:8080" client.model_id = config.AUDIOCPP_MODEL_ID @@ -711,6 +712,7 @@ class AudioCppTTSClientRequestTests(unittest.TestCase): client.voice = voice client.language = language client._seed = seed + client.chunk_text = chunk_text return client @staticmethod @@ -746,6 +748,45 @@ class AudioCppTTSClientRequestTests(unittest.TestCase): self.assertEqual(payload["seed"], 1234) self.assertNotIn("instructions", payload) + def test_negative_seed_omitted_from_payload(self): + client = self._make_client(preset_mode=True, voice="narrator", seed=-1) + with patch("converter.tts.urllib.request.urlopen", + return_value=self._post_response(self._wav_bytes())) as mock_urlopen: + client._request_wav("Hello world.") + payload = json.loads(mock_urlopen.call_args[0][0].data.decode("utf-8")) + self.assertNotIn("seed", payload) + + def test_whole_text_sent_as_one_request_without_client_chunking(self): + client = self._make_client(chunk_text=False) + # 9 words with CHUNK_SIZE=5 would split in two if client chunking + # were on; kept under the 10-word truncation-check threshold. + text = " ".join(f"word{i}" for i in range(9)) + with patch.object(config, "CHUNK_SIZE", 5), \ + patch.object(client, "_request_wav", + return_value=self._wav_bytes()) as mock_request: + result = client.generate_chunk(text, 1) + self.assertIsNotNone(result) + self.assertEqual(mock_request.call_count, 1) + self.assertEqual(mock_request.call_args[0][0], text) + + def test_single_request_timeout_scales_with_text_length(self): + client = self._make_client(chunk_text=False) + long_text = " ".join(f"word{i}" for i in range(1500)) # ~10 min of audio + with patch("converter.tts.urllib.request.urlopen", + return_value=self._post_response(self._wav_bytes())) as mock_urlopen: + client._request_wav(long_text) + timeout = mock_urlopen.call_args[1]["timeout"] + self.assertGreater(timeout, config.API_TIMEOUT) + + def test_client_chunking_keeps_configured_timeout(self): + client = self._make_client(chunk_text=True) + long_text = " ".join(f"word{i}" for i in range(1500)) + with patch("converter.tts.urllib.request.urlopen", + return_value=self._post_response(self._wav_bytes())) as mock_urlopen: + client._request_wav(long_text) + timeout = mock_urlopen.call_args[1]["timeout"] + self.assertEqual(timeout, config.API_TIMEOUT) + def test_speaker_mode_sends_instruct(self): client = self._make_client(preset_mode=False) with patch("converter.tts.urllib.request.urlopen", @@ -857,6 +898,7 @@ class AudioCppTTSClientTruncationTests(unittest.TestCase): client.voice = "narrator" client.language = "English" client._seed = -1 + client.chunk_text = True return client @staticmethod @@ -909,7 +951,8 @@ class BackendWiringTests(unittest.TestCase): AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE, backend=tts.BACKEND_AUDIOCPP, voice="narrator", language="ja") - mock_audiocpp.assert_called_once_with(voice="narrator", language="Japanese") + mock_audiocpp.assert_called_once_with(voice="narrator", language="Japanese", + chunk_text=False) mock_faster.assert_not_called() mock_qwen.assert_not_called() @@ -917,7 +960,18 @@ class BackendWiringTests(unittest.TestCase): with patch("converter.converter.AudioCppTTSClient") as mock_audiocpp: AudiobookConverter(voice_mode=tts.VOICE_MODE_CUSTOM, backend=tts.BACKEND_AUDIOCPP) - mock_audiocpp.assert_called_once_with(voice=None, language=config.LANGUAGE) + mock_audiocpp.assert_called_once_with(voice=None, language=config.LANGUAGE, + chunk_text=False) + + def test_audiocpp_backend_chunk_flag_forces_client_chunking(self): + with patch("converter.converter.AudioCppTTSClient") as mock_audiocpp: + converter = AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE, + backend=tts.BACKEND_AUDIOCPP, + voice="narrator", chunk=True) + mock_audiocpp.assert_called_once_with(voice="narrator", + language=config.LANGUAGE, + chunk_text=True) + self.assertTrue(converter.client_chunks) def test_gradio_backend_uses_qwen_client(self): with patch("converter.converter.FasterTTSClient") as mock_faster, \ @@ -942,6 +996,31 @@ class BackendWiringTests(unittest.TestCase): voice="narrator") self.assertIsNone(converter.voice_clone_ref_audio) + def test_chapter_chunks_audiocpp_default_is_one_request(self): + converter = self._audiocpp_converter(voice="narrator") + text = " ".join(f"word{i}" for i in range(50)) + with patch.object(config, "CHUNK_SIZE", 10): + self.assertEqual(converter._chapter_chunks(text), [text]) + + def test_chapter_chunks_audiocpp_chunk_flag_splits(self): + with patch("converter.converter.AudioCppTTSClient"): + converter = AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE, + backend=tts.BACKEND_AUDIOCPP, + voice="narrator", chunk=True) + text = " ".join(f"word{i}" for i in range(50)) + with patch.object(config, "CHUNK_SIZE", 10): + chunks = converter._chapter_chunks(text) + self.assertGreater(len(chunks), 1) + self.assertTrue(all(len(chunk.split()) <= 10 for chunk in chunks)) + + def test_chapter_chunks_gradio_always_splits(self): + with patch("converter.converter.QwenTTSClient"): + converter = AudiobookConverter(voice_mode=tts.VOICE_MODE_CUSTOM) + text = " ".join(f"word{i}" for i in range(50)) + with patch.object(config, "CHUNK_SIZE", 10): + chunks = converter._chapter_chunks(text) + self.assertGreater(len(chunks), 1) + def test_faster_backend_still_validates_other_settings(self): with patch("converter.converter.FasterTTSClient"): with self.assertRaises(ValueError): |
