| |
| """Synthesise Egyptian Arabic with KemeTone. |
| |
| python example.py "النَّهَارْدَه الْجَوّ حِلْو أَوِي" out.wav |
| |
| Input should be diacritized. Undiacritized Arabic still synthesises, but short |
| vowels are then guessed by the phonemiser rather than read from the text, and |
| the guesses follow Modern Standard patterns — which is audibly wrong in |
| Egyptian. See the model card. |
| |
| If espeak-ng is not on the default library path, point KemeTone at it: |
| |
| export KEMETONE_ESPEAK_LIB=/path/to/libespeak-ng.so |
| export KEMETONE_ESPEAK_DATA=/path/to/espeak-ng-data |
| """ |
| import sys |
| import torch |
| import soundfile as sf |
| from kokoro import KModel |
| from kemetone import EgyptianG2P |
|
|
| SR = 24000 |
| REPO = "Rabe3/kemetone" |
|
|
|
|
| def main() -> int: |
| text = sys.argv[1] if len(sys.argv) > 1 else "النَّهَارْدَه الْجَوّ حِلْو أَوِي" |
| out = sys.argv[2] if len(sys.argv) > 2 else "out.wav" |
| device = "cuda" if torch.cuda.is_available() else "cpu" |
|
|
| model = KModel(repo_id=REPO, config="config.json", |
| model="kemetone.pth").to(device).eval() |
| voice = torch.load("voices/kemetone.pt", map_location=device) |
|
|
| ipa = EgyptianG2P()(text) |
| print("phonemes:", ipa) |
|
|
| with torch.no_grad(): |
| audio = model(ipa, voice[len(ipa) - 1]) |
|
|
| sf.write(out, audio.cpu().numpy(), SR) |
| print(f"wrote {out} {len(audio) / SR:.1f}s") |
| return 0 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |
|
|