@@ -31,8 +31,5 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: uv sync --dev -p ${{ matrix.python-version }}
|
run: uv sync --dev -p ${{ matrix.python-version }}
|
||||||
- name: Run pytest
|
- name: Run pytest
|
||||||
env:
|
|
||||||
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
|
||||||
run: |
|
run: |
|
||||||
uvx hf auth login --token $HF_TOKEN
|
|
||||||
uv run -p ${{ matrix.python-version }} pytest -v ./tests
|
uv run -p ${{ matrix.python-version }} pytest -v ./tests
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
"""Integration tests for the CLI generate command using real implementation."""
|
"""Integration tests for the CLI generate command using real implementation."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
from pocket_tts.data.audio import audio_read
|
from pocket_tts.data.audio import audio_read
|
||||||
@@ -10,6 +13,9 @@ other_voice = "https://huggingface.co/kyutai/tts-voices/resolve/main/expresso/ex
|
|||||||
|
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
|
IS_CI = os.environ.get("CI") == "true"
|
||||||
|
CI_SKIP_REASON = "Voice cloning is not publicly available, skipping in the CI"
|
||||||
|
|
||||||
|
|
||||||
def test_generate_basic_usage(tmp_path):
|
def test_generate_basic_usage(tmp_path):
|
||||||
"""Test basic generate command with default parameters."""
|
"""Test basic generate command with default parameters."""
|
||||||
@@ -32,6 +38,7 @@ def test_generate_basic_usage(tmp_path):
|
|||||||
assert sample_rate == 24000 # Expected sample rate
|
assert sample_rate == 24000 # Expected sample rate
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(IS_CI, reason=CI_SKIP_REASON)
|
||||||
def test_generate_with_custom_voice(tmp_path):
|
def test_generate_with_custom_voice(tmp_path):
|
||||||
"""Test generate command with custom voice prompt."""
|
"""Test generate command with custom voice prompt."""
|
||||||
output_file = tmp_path / "custom_voice_test.wav"
|
output_file = tmp_path / "custom_voice_test.wav"
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ def test_readme_example():
|
|||||||
from pocket_tts import TTSModel
|
from pocket_tts import TTSModel
|
||||||
|
|
||||||
tts_model = TTSModel.load_model()
|
tts_model = TTSModel.load_model()
|
||||||
voice_state = tts_model.get_state_for_audio_prompt(
|
voice_state = tts_model.get_state_for_audio_prompt("cosette")
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
|
||||||
)
|
|
||||||
audio = tts_model.generate_audio(voice_state, "Hello world, this is a test.")
|
audio = tts_model.generate_audio(voice_state, "Hello world, this is a test.")
|
||||||
# Audio is a torch tensor containing PCM data.
|
# Audio is a torch tensor containing PCM data.
|
||||||
scipy.io.wavfile.write("output.wav", tts_model.sample_rate, audio.numpy())
|
scipy.io.wavfile.write("output.wav", tts_model.sample_rate, audio.numpy())
|
||||||
@@ -27,9 +25,7 @@ def test_quick_start():
|
|||||||
tts_model = TTSModel.load_model()
|
tts_model = TTSModel.load_model()
|
||||||
|
|
||||||
# Get voice state from an audio file
|
# Get voice state from an audio file
|
||||||
voice_state = tts_model.get_state_for_audio_prompt(
|
voice_state = tts_model.get_state_for_audio_prompt("marius")
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generate audio
|
# Generate audio
|
||||||
audio = tts_model.generate_audio(voice_state, "Hello world, this is a test.")
|
audio = tts_model.generate_audio(voice_state, "Hello world, this is a test.")
|
||||||
@@ -79,6 +75,9 @@ def test_get_state_for_audio_prompt():
|
|||||||
from pocket_tts import TTSModel
|
from pocket_tts import TTSModel
|
||||||
|
|
||||||
model = TTSModel.load_model()
|
model = TTSModel.load_model()
|
||||||
|
# hack to make it work without auth
|
||||||
|
model.has_voice_cloning = True
|
||||||
|
|
||||||
# From HuggingFace URL
|
# From HuggingFace URL
|
||||||
voice_state = model.get_state_for_audio_prompt(
|
voice_state = model.get_state_for_audio_prompt(
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
||||||
@@ -99,9 +98,7 @@ def test_generate_audio():
|
|||||||
|
|
||||||
model = TTSModel.load_model()
|
model = TTSModel.load_model()
|
||||||
|
|
||||||
voice_state = model.get_state_for_audio_prompt(
|
voice_state = model.get_state_for_audio_prompt("marius")
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generate audio
|
# Generate audio
|
||||||
audio = model.generate_audio(voice_state, "Hello world!", frames_after_eos=2, copy_state=True)
|
audio = model.generate_audio(voice_state, "Hello world!", frames_after_eos=2, copy_state=True)
|
||||||
@@ -115,9 +112,7 @@ def test_generate_audio_stream():
|
|||||||
|
|
||||||
model = TTSModel.load_model()
|
model = TTSModel.load_model()
|
||||||
|
|
||||||
voice_state = model.get_state_for_audio_prompt(
|
voice_state = model.get_state_for_audio_prompt("fantine")
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
|
||||||
)
|
|
||||||
# Stream generation
|
# Stream generation
|
||||||
for chunk in model.generate_audio_stream(voice_state, "Long text content..."):
|
for chunk in model.generate_audio_stream(voice_state, "Long text content..."):
|
||||||
# Process each chunk as it's generated
|
# Process each chunk as it's generated
|
||||||
@@ -131,17 +126,13 @@ def test_voice_management():
|
|||||||
model = TTSModel.load_model()
|
model = TTSModel.load_model()
|
||||||
# Preload multiple voices
|
# Preload multiple voices
|
||||||
voices = {
|
voices = {
|
||||||
"casual": model.get_state_for_audio_prompt(
|
"casual": model.get_state_for_audio_prompt("alba"),
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
"serious": model.get_state_for_audio_prompt("marius"),
|
||||||
),
|
|
||||||
"funny": model.get_state_for_audio_prompt(
|
|
||||||
"https://huggingface.co/kyutai/tts-voices/resolve/main/expresso/ex01-ex02_default_001_channel1_168s.wav"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate with different voices
|
# Generate with different voices
|
||||||
casual_audio = model.generate_audio(voices["casual"], "Hey there!")
|
casual_audio = model.generate_audio(voices["casual"], "Hey there!")
|
||||||
funny_audio = model.generate_audio(voices["funny"], "Good morning.")
|
funny_audio = model.generate_audio(voices["serious"], "Good morning.")
|
||||||
|
|
||||||
|
|
||||||
def test_batch_processing():
|
def test_batch_processing():
|
||||||
@@ -152,9 +143,7 @@ def test_batch_processing():
|
|||||||
|
|
||||||
model = TTSModel.load_model()
|
model = TTSModel.load_model()
|
||||||
|
|
||||||
voice_state = model.get_state_for_audio_prompt(
|
voice_state = model.get_state_for_audio_prompt("azelma")
|
||||||
"hf://kyutai/tts-voices/alba-mackenna/casual.wav"
|
|
||||||
)
|
|
||||||
# Process multiple texts efficiently by re-using the same voice state
|
# Process multiple texts efficiently by re-using the same voice state
|
||||||
texts = [
|
texts = [
|
||||||
"First sentence to generate.",
|
"First sentence to generate.",
|
||||||
|
|||||||
Reference in New Issue
Block a user