File size: 3,617 Bytes
0d2eaf0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3982804
0d2eaf0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
652203a
 
c552b6f
 
0d2eaf0
 
 
 
 
 
 
 
 
40392fe
0d2eaf0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import os
from typing import Text
import gradio as gr
import soundfile as sf
from transformers import pipeline
import numpy as np
import torch
import re
from speechbrain.pretrained import EncoderClassifier


def create_speaker_embedding(speaker_model, waveform: np.ndarray) -> np.ndarray:
    with torch.no_grad():
        speaker_embeddings = speaker_model.encode_batch(torch.tensor(waveform))
        speaker_embeddings = torch.nn.functional.normalize(speaker_embeddings, dim=2)
        if device.type != 'cuda':
            speaker_embeddings = speaker_embeddings.squeeze().numpy()
        else:
            speaker_embeddings = speaker_embeddings.squeeze().cpu().numpy()
    speaker_embeddings = torch.tensor(speaker_embeddings, dtype=dtype).unsqueeze(0).to(device)
    return speaker_embeddings


def remove_special_characters_s(text: Text) -> Text:
    chars_to_remove_regex = '[\-\…\–\"\“\%\‘\”\�\»\«\„\`\'́]'
    # remove special characters
    text = re.sub(chars_to_remove_regex, '', text)
    text = re.sub("՚", "'", text)
    text = re.sub("’", "'", text)
    text = re.sub(r'ы', 'и', text)
    text = text.lower()
    return text


def cyrillic_to_latin(text: Text) -> Text:
    replacements = [
        ('а', 'a'),
        ('б', 'b'),
        ('в', 'v'),
        ('г', 'h'),
        ('д', 'd'),
        ('е', 'e'),
        ('ж', 'zh'),
        ('з', 'z'),
        ('и', 'y'),
        ('й', 'j'),
        ('к', 'k'),
        ('л', 'l'),
        ('м', 'm'),
        ('н', 'n'),
        ('о', 'o'),
        ('п', 'p'),
        ('р', 'r'),
        ('с', 's'),
        ('т', 't'),
        ('у', 'u'),
        ('ф', 'f'),
        ('х', 'h'),
        ('ц', 'ts'),
        ('ч', 'ch'),
        ('ш', 'sh'),
        ('щ', 'sch'),
        ('ь', "'"),
        ('ю', 'ju'),
        ('я', 'ja'),
        ('є', 'je'),
        ('і', 'i'),
        ('ї', 'ji'),
        ('ґ', 'g')
    ]

    for src, dst in replacements:
        text = text.replace(src, dst)
    return text


device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
if torch.cuda.is_available():
    dtype = torch.bfloat16 if torch.cuda.get_device_capability()[0] == 8 else torch.float16
else:
    dtype = torch.float32

spk_model_name = "speechbrain/spkrec-xvect-voxceleb"

speaker_model = EncoderClassifier.from_hparams(
            source=spk_model_name, 
            run_opts={"device": device}, 
            savedir=os.path.join("/tmp", spk_model_name)
            )

waveform, samplerate = sf.read("files/speaker.wav")

speaker_embeddings = create_speaker_embedding(speaker_model, waveform)

transcriber = pipeline("text-to-speech", model="Oysiyl/speecht5_tts_common_voice_uk")

def transcribe(text: Text) -> tuple((int, np.ndarray)):
    text = remove_special_characters_s(text)
    text = cyrillic_to_latin(text)
    out = transcriber(text, forward_params={"speaker_embeddings": speaker_embeddings})
    audio, sr = out["audio"], out["sampling_rate"]
    return sr, audio


demo = gr.Interface(
    transcribe,
    gr.Textbox(),
    outputs="audio",
    title="Text to Speech for Ukrainian language demo",
    description="Click on the example below or type text!",
    examples=[["Держава-агресор Росія закуповує комунікаційне обладнання, зокрема супутникові інтернет-термінали Starlink, для використання у війні в арабських країнах"], 
              ["Доброго вечора, ми з України!"]],
    cache_examples=True
)

demo.launch()