77 lines
2.5 KiB
Python
77 lines
2.5 KiB
Python
"""
|
|
Windows-friendly regeneration of the voice spike, extended to all 5
|
|
Pokemon the app currently knows about. Ports generate_samples.sh's
|
|
"fixed" (cadence-corrected) + robot_filter_v2.py (intensity 0.45) stages
|
|
to Python, using piper's Python API directly instead of the `piper` CLI
|
|
and skipping the ffmpeg mp3 step (WAV plays fine on Android, and ffmpeg
|
|
isn't installed on this machine).
|
|
|
|
Usage: .venv\\Scripts\\python.exe generate_all.py
|
|
"""
|
|
|
|
import wave
|
|
from pathlib import Path
|
|
|
|
from piper import PiperVoice
|
|
from piper.config import SynthesisConfig
|
|
|
|
import robot_filter_v2
|
|
|
|
HERE = Path(__file__).parent
|
|
VOICE_MODEL = HERE / "voices" / "en_US-joe-medium.onnx"
|
|
OUT_DIR = HERE / "output"
|
|
|
|
ENTRIES = {
|
|
"bulbasaur": (
|
|
"Bulbasaur, the seed Pokémon. It can be seen napping in bright "
|
|
"sunlight. There is a seed on its back. By soaking up the sun's "
|
|
"rays, the seed grows progressively larger."
|
|
),
|
|
"charizard": (
|
|
"Charizard, the flame Pokémon. Charizard flies around the sky in "
|
|
"search of powerful opponents. It breathes fire of such great "
|
|
"heat that it melts anything."
|
|
),
|
|
"pikachu": (
|
|
"Pikachu, the mouse Pokémon. When several of these Pokémon "
|
|
"gather, their electricity could build and cause lightning "
|
|
"storms."
|
|
),
|
|
"eevee": (
|
|
"Eevee, the evolution Pokémon. Its genetic code is irregular. It "
|
|
"may mutate if it is exposed to radiation from element stones."
|
|
),
|
|
"squirtle": (
|
|
"Squirtle, the tiny turtle Pokémon. After birth, its back swells "
|
|
"and hardens into a shell. It powerfully sprays foam from its "
|
|
"mouth."
|
|
),
|
|
}
|
|
|
|
ROBOT_INTENSITY = 0.45
|
|
|
|
|
|
SYN_CONFIG = SynthesisConfig(noise_scale=0.5, noise_w_scale=0.3, length_scale=0.98)
|
|
|
|
|
|
def main():
|
|
OUT_DIR.mkdir(exist_ok=True)
|
|
print(f"Loading voice model {VOICE_MODEL.name}...")
|
|
voice = PiperVoice.load(str(VOICE_MODEL))
|
|
|
|
for name, text in ENTRIES.items():
|
|
fixed_path = OUT_DIR / f"{name}_fixed.wav"
|
|
robot_path = OUT_DIR / f"{name}_fixed_robot.wav"
|
|
print(f"Synthesizing {name}...")
|
|
with wave.open(str(fixed_path), "wb") as wav_file:
|
|
voice.synthesize_wav(text, wav_file, syn_config=SYN_CONFIG)
|
|
sr, x = robot_filter_v2.load(str(fixed_path))
|
|
y = robot_filter_v2.robotize(x, sr, intensity=ROBOT_INTENSITY)
|
|
robot_filter_v2.save(str(robot_path), sr, y)
|
|
print(f" -> {robot_path.name}")
|
|
|
|
print("\nDone. See output/*_fixed_robot.wav")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|