File size: 6,521 Bytes
37cf751
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f311696
 
 
 
 
 
37cf751
 
f311696
 
 
 
37cf751
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f311696
 
69081d6
f311696
37cf751
 
f311696
37cf751
 
 
08d7994
f311696
37cf751
 
 
19c7016
2db586b
f311696
19c7016
f311696
 
 
 
 
19c7016
2db586b
 
f311696
37cf751
 
f311696
 
37cf751
 
 
 
 
 
 
 
f311696
 
37cf751
f311696
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
import gradio as gr
import requests
from gtts import gTTS
from pydub import AudioSegment
from pydub.generators import Sine
import os

# Cloze questions
cloze_questions = [
    {
        "question": "Alex [BLANK] for his daring spirit and his love for exploring the rugged landscapes around Echo Ridge.",
        "answer": "was known",
        "hint": "know"
    },
    {
        "question": "One day, while exploring the local library, Alex [BLANK] upon an ancient map tucked inside a forgotten book on village lore.",
        "answer": "stumbled",
        "hint": "stumble"
    },
    {
        "question": "The map [BLANK] at the location of a lost treasure, hidden deep within a cave known as Whispering Hollow.",
        "answer": "hinted",
        "hint": "hint"
    },
    {
        "question": "Excited by the prospect of a real adventure, Alex [BLANK] to seek out the treasure.",
        "answer": "decided",
        "hint": "decide"
    },
    {
        "question": "Knowing the journey would be risky, he [BLANK] the help of his best friends, Mia and Sam.",
        "answer": "enlisted",
        "hint": "enlist"
    },
    {
        "question": "Together, they [BLANK] for the expedition, gathering supplies and studying the map extensively.",
        "answer": "prepared",
        "hint": "prepare"
    },
    {
        "question": "They [BLANK] their route, took note of landmarks, and readied themselves for any challenges they might face.",
        "answer": "planned",
        "hint": "plan"
    }
]

# Function to create a bell sound
def create_bell_sound(filename="bell.wav"):
    # Generate a bell sound (1000 Hz tone for 200 ms)
    tone = Sine(1000).to_audio_segment(duration=200).apply_gain(-10).fade_in(50).fade_out(50)
    tone.export(filename, format="wav")

# Create the bell sound file
create_bell_sound()

# Function to convert text to speech and add bell sound
def text_to_speech_with_bell(text, filename):
    tts = gTTS(text.replace("[BLANK]", ""))
    tts.save("temp.mp3")

    # Load the generated speech and bell sound
    speech = AudioSegment.from_mp3("temp.mp3")
    bell = AudioSegment.from_wav("bell.wav")

    # Find the position of the blank and insert the bell sound
    blank_position = text.find("[BLANK]")
    part1 = text[:blank_position]
    part2 = text[blank_position + len("[BLANK]"):]
    tts_part1 = gTTS(part1).save("part1.mp3")
    tts_part2 = gTTS(part2).save("part2.mp3")
    speech_part1 = AudioSegment.from_mp3("part1.mp3")
    speech_part2 = AudioSegment.from_mp3("part2.mp3")

    # Create a silent segment (2 seconds)
    silent_segment = AudioSegment.silent(duration=2000)

    combined = speech_part1 + bell + silent_segment + speech_part2

    # Save the final audio with the bell sound inserted
    combined.export(filename, format="mp3")
    os.remove("temp.mp3")
    os.remove("part1.mp3")
    os.remove("part2.mp3")
    return filename

# Function to convert text to speech without any modifications
def text_to_speech(text, filename):
    tts = gTTS(text)
    tts.save(filename)
    return filename

# Generate audio files for questions
for i, question in enumerate(cloze_questions):
    full_audio_filename = f"full_question_{i+1}.mp3"
    cloze_audio_filename = f"cloze_question_{i+1}.mp3"
    question["full_audio"] = text_to_speech(question["question"].replace("[BLANK]", question["answer"]), full_audio_filename)
    question["cloze_audio"] = text_to_speech_with_bell(question["question"], cloze_audio_filename)

# Function to handle the cloze quiz
def cloze_quiz(state, answer):
    name, question_index, score, results = state
    question = cloze_questions[question_index]

    correct = answer.strip().lower() == question["answer"].lower()

    if correct:
        score += 1
        results.append(f"Question {question_index + 1}: Correct\n")
    else:
        results.append(f"Question {question_index + 1}: Incorrect, the correct answer is: {question['answer']}\n")

    question_index += 1

    if question_index < len(cloze_questions):
        next_full_audio = cloze_questions[question_index]["full_audio"]
        next_cloze_audio = cloze_questions[question_index]["cloze_audio"]
        next_hint = f"Hint: {cloze_questions[question_index]['hint']} ◁◁◁ Check out this verb!"
        return (name, question_index, score, results), next_full_audio, next_cloze_audio, next_hint, gr.update(visible=False), gr.update(value="", interactive=True, visible=True)
    else:
        result_text = f"* Name: {name}\n* Score: {score} out of {len(cloze_questions)}\n" + "\n".join(results)
        return (name, question_index, score, results), None, None, "", gr.update(visible=True, value=result_text), gr.update(visible=False)

# Function to start the quiz
def start_quiz(name):
    hint = f"Hint: {cloze_questions[0]['hint']} ◁◁◁ Check out this verb!"
    return (name, 0, 0, []), cloze_questions[0]["full_audio"], cloze_questions[0]["cloze_audio"], hint, gr.update(visible=False), gr.update(visible=True)

# Create the Gradio interface
with gr.Blocks() as iface:
    gr.Markdown("# Listening Cloze Test Instructions")
    gr.Markdown("""
    **Instructions:**

    1. Listen to the full sentence.
    2. Listen to the cloze question with the beep sound.
    3. Write the correct form of the verb you hear in the blank space. Remember, you do not need to write the entire sentence, just the verb.

    **For example, if you hear "Yesterday, Alex went to the store," and then you hear "Yesterday, Alex ___ to the store" with a beep sound, you should write "went" if that is the verb you heard.**

    **Are you ready? Let's begin!**
    """)

    name_input = gr.Textbox(label="Enter your name")
    start_button = gr.Button("Start Quiz")
    full_question_audio = gr.Audio(interactive=True, autoplay=False, label="Full Sentence Listening")
    cloze_question_audio = gr.Audio(interactive=True, autoplay=False, label="Cloze Question")
    hint_output = gr.Markdown()
    answer_input = gr.Textbox(label="Your Answer")
    next_button = gr.Button("Next")
    result_output = gr.Textbox(label="Results", interactive=False, visible=False)

    # Initialize the state
    state = gr.State()

    start_button.click(start_quiz, inputs=name_input, outputs=[state, full_question_audio, cloze_question_audio, hint_output, result_output, answer_input])
    next_button.click(cloze_quiz, inputs=[state, answer_input], outputs=[state, full_question_audio, cloze_question_audio, hint_output, result_output, answer_input])

iface.launch(share=True)