File size: 9,964 Bytes
0931910
d804881
 
6777887
0931910
9ab32d7
d51ffe7
3a8b45a
38f204d
 
 
 
 
3a8b45a
 
 
1470bc9
 
 
 
 
 
d51ffe7
 
183d840
5d533ea
9ab32d7
 
0931910
 
a9078f6
 
9ab32d7
 
 
d51ffe7
38f204d
d51ffe7
a9078f6
d51ffe7
 
 
 
 
 
 
 
38f204d
d51ffe7
 
38f204d
d51ffe7
9ab32d7
38f204d
9ab32d7
38f204d
9ab32d7
38f204d
9ab32d7
d51ffe7
38f204d
6957865
183d840
 
38f204d
6957865
9ab32d7
38f204d
 
9ab32d7
 
1470bc9
38f204d
9ab32d7
d51ffe7
8b62994
3a8b45a
9ab32d7
a9078f6
9ab32d7
 
 
 
a9078f6
38f204d
9ab32d7
a9078f6
38f204d
9ab32d7
3a8b45a
38f204d
 
 
 
 
 
 
 
 
 
 
 
3a8b45a
38f204d
3a8b45a
 
38f204d
3a8b45a
38f204d
3a8b45a
38f204d
d51ffe7
38f204d
 
6777887
 
 
 
 
 
 
 
 
38f204d
 
6777887
ca7e6be
 
8b62994
ca7e6be
8b62994
a9078f6
 
 
 
 
ca7e6be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ab32d7
ca7e6be
38f204d
9ab32d7
8b62994
a9078f6
 
 
 
 
ca7e6be
9ab32d7
 
38f204d
6957865
d51ffe7
38f204d
1470bc9
 
 
 
a9078f6
38f204d
1470bc9
 
 
 
38f204d
d51ffe7
9ab32d7
 
8b62994
9ab32d7
0931910
9ab32d7
5d533ea
 
 
 
 
 
 
 
 
d804881
 
 
6e31dbd
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
from pathlib import Path
import gradio as gr

from aip_trainer import PROJECT_ROOT_FOLDER, app_logger, sample_rate_start
from aip_trainer.lambdas import js, lambdaGetSample, lambdaSpeechToScore, lambdaTTS


css = """
.speech-output-label p {color: grey; margin-bottom: white;}
.background-white {background-color: white !important; }
.speech-output-group {padding: 12px;}
.speech-output-container {min-height: 60px;}
.speech-output-html {text-align: left; }
"""


def clear():
    return None


def clear2():
    return None, None


with gr.Blocks(css=css, head=js.head_driver_tour) as gradio_app:
    local_storage = gr.BrowserState([0.0, 0.0])
    app_logger.info("start gradio app building...")

    project_root_folder = Path(PROJECT_ROOT_FOLDER)
    with open(project_root_folder / "aip_trainer" / "lambdas" / "app_description.md", "r", encoding="utf-8") as app_description_src:
        md_app_description = app_description_src.read()
        gr.Markdown(md_app_description.format(sample_rate_start=sample_rate_start))
    with gr.Row():
        with gr.Column(scale=4, min_width=300):
            with gr.Row():
                with gr.Column(scale=2, min_width=80):
                    radio_language = gr.Radio(["de", "en"], label="Language", value="en", elem_id="radio-language-id-element")
                with gr.Column(scale=5, min_width=160):
                    radio_difficulty = gr.Radio(
                        label="Difficulty",
                        value=0,
                        choices=[
                            ("random", 0),
                            ("easy", 1),
                            ("medium", 2),
                            ("hard", 3),
                        ],
                        elem_id="radio-difficulty-id-element",
                    )
                with gr.Column(scale=1, min_width=100):
                    btn_random_phrase = gr.Button(value="Choose a random phrase", elem_id="btn-random-phrase-id-element")
            with gr.Row():
                with gr.Column(scale=7, min_width=300):
                    text_student_transcription = gr.Textbox(
                        lines=3,
                        label="Phrase to read for speech recognition",
                        value="Hi there, how are you?",
                        elem_id="text-student-transcription-id-element",
                    )
            with gr.Row():
                audio_tts = gr.Audio(label="Audio TTS", elem_id="audio-tts-id-element")
            with gr.Row():
                btn_run_tts = gr.Button(value="TTS in browser", elem_id="btn-run-tts-id-element")
                btn_run_tts_backend = gr.Button(value="TTS backend", elem_id="btn-run-tts-backend-id-element")
                btn_clear_tts = gr.Button(value="Clear TTS backend", elem_id="btn-clear-tts-backend-id-element")
                btn_clear_tts.click(clear, inputs=[], outputs=[audio_tts])
            with gr.Row():
                audio_student_recording_stt = gr.Audio(
                    label="Speech-toText audio output",
                    sources=["microphone", "upload"],
                    type="filepath",
                    show_download_button=True,
                    elem_id="audio-student-recording-stt-id-element",
                )
        with gr.Column(scale=4, min_width=320):
            text_transcribed_hidden = gr.Textbox(
                placeholder=None, label="Transcribed text", visible=False
            )
            text_letter_correctness = gr.Textbox(
                placeholder=None,
                label="Letters correctness",
                visible=False,
            )
            text_recording_ipa = gr.Textbox(
                placeholder=None, label="Student phonetic transcription", elem_id="text-student-recording-ipa-id-element"
            )
            text_ideal_ipa = gr.Textbox(
                placeholder=None, label="Ideal phonetic transcription", elem_id="text-ideal-ipa-id-element"
            )
            text_raw_json_output_hidden = gr.Textbox(placeholder=None, label="text_raw_json_output_hidden", visible=False)
            with gr.Group(elem_classes="speech-output-group background-white"):
                gr.Markdown("Speech accuracy output", elem_classes="speech-output-label background-white")
                with gr.Group(elem_classes="speech-output-container background-white"):
                    html_output = gr.HTML(
                        label="Speech accuracy output",
                        elem_id="speech-output",
                        show_label=False,
                        visible=True,
                        render=True,
                        value=" - ",
                        elem_classes="speech-output-html background-white",
                    )
            with gr.Row():
                gr.Markdown("### Speech accuracy score (%)", elem_classes="speech-accuracy-score-container row1", elem_id="speech-accuracy-score-container-id-element")
            with gr.Row():
                with gr.Column(min_width=100, elem_classes="speech-accuracy-score-container row2 col1"):
                    number_pronunciation_accuracy = gr.Number(label="Current score", elem_id="number-pronunciation-accuracy-id-element")
                with gr.Column(min_width=100, elem_classes="speech-accuracy-score-container row2 col2"):
                    number_score_de = gr.Number(label="Global score DE", value=0, interactive=False, elem_id="number-score-de-id-element")
                with gr.Column(min_width=100, elem_classes="speech-accuracy-score-container row2 col3"):
                    number_score_en = gr.Number(label="Global score EN", value=0, interactive=False, elem_id="number-score-en-id-element")
            with gr.Row():
                btn = gr.Button(value="Recognize speech accuracy", elem_id="btn-recognize-speech-accuracy-id-element")
            with gr.Accordion("Click here to expand the table examples", open=True, elem_id="accordion-examples-id-element"):
                examples_text = gr.Examples(
                    examples=[
                        ["Hallo, wie geht es dir?", "de", 1],
                        ["Hi there, how are you?", "en", 1],
                        ["Die König-Ludwig-Eiche ist ein Naturdenkmal im Staatsbad Brückenau.", "de", 2,],
                        ["Rome is home to some of the most beautiful monuments in the world.", "en", 2],
                        ["Die König-Ludwig-Eiche ist ein Naturdenkmal im Staatsbad Brückenau, einem Ortsteil des drei Kilometer nordöstlich gelegenen Bad Brückenau im Landkreis Bad Kissingen in Bayern.", "de", 3],
                        ["Some machine learning models are designed to understand and generate human-like text based on the input they receive.", "en", 3],
                    ],
                    inputs=[text_student_transcription, radio_language, radio_difficulty],
                    elem_id="examples-text-id-element",
                )

    def get_updated_score_by_language(text: str, audio_rec: str | Path, lang: str, score_de: float, score_en: float):
        _transcribed_text, _letter_correctness, _pronunciation_accuracy, _recording_ipa, _ideal_ipa, _res = lambdaSpeechToScore.get_speech_to_score_tuple(text, audio_rec, lang)
        output = {
            text_transcribed_hidden: _transcribed_text,
            text_letter_correctness: _letter_correctness,
            number_pronunciation_accuracy: _pronunciation_accuracy,
            text_recording_ipa: _recording_ipa,
            text_ideal_ipa: _ideal_ipa,
            text_raw_json_output_hidden: _res,
        }
        match lang:
            case "de":
                return {
                    number_score_de: float(score_de) + float(_pronunciation_accuracy),
                    number_score_en: float(score_en),
                    **output
                }
            case "en":
                return {
                    number_score_en: float(score_en) + float(_pronunciation_accuracy),
                    number_score_de: float(score_de),
                    **output
                }
            case _:
                raise NotImplementedError(f"Language {lang} not supported")

    btn.click(
        get_updated_score_by_language,
        inputs=[text_student_transcription, audio_student_recording_stt, radio_language, number_score_de, number_score_en],
        outputs=[
            text_transcribed_hidden,
            text_letter_correctness,
            number_pronunciation_accuracy,
            text_recording_ipa,
            text_ideal_ipa,
            text_raw_json_output_hidden,
            number_score_de, number_score_en
        ],
    )
    btn_run_tts.click(fn=None, inputs=[text_student_transcription, radio_language], outputs=audio_tts, js=js.js_play_audio)
    btn_run_tts_backend.click(
        fn=lambdaTTS.get_tts,
        inputs=[text_student_transcription, radio_language],
        outputs=audio_tts,
    )
    btn_random_phrase.click(
        lambdaGetSample.get_random_selection,
        inputs=[radio_language, radio_difficulty],
        outputs=[text_student_transcription],
    )
    btn_random_phrase.click(
        clear2,
        inputs=[],
        outputs=[audio_student_recording_stt, audio_tts]
    )
    html_output.change(
        None,
        inputs=[text_transcribed_hidden, text_letter_correctness],
        outputs=[html_output],
        js=js.js_update_ipa_output,
    )
    
    @gradio_app.load(inputs=[local_storage], outputs=[number_score_de, number_score_en])
    def load_from_local_storage(saved_values):
        print("loading from local storage", saved_values)
        return saved_values[0], saved_values[1]

    @gr.on([number_score_de.change, number_score_en.change], inputs=[number_score_de, number_score_en], outputs=[local_storage])
    def save_to_local_storage(score_de, score_en):
        return [score_de, score_en]


if __name__ == "__main__":
    gradio_app.launch()