nightfury commited on
Commit
c8a4052
·
verified ·
1 Parent(s): bb8e127

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -0
app.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import time
4
+ from scipy.io import wavfile
5
+ import io
6
+
7
+ # Morse code dictionary (ITU standard)
8
+ MORSE_CODE_DICT = {
9
+ 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.',
10
+ 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..',
11
+ 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.',
12
+ 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
13
+ 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--',
14
+ '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..',
15
+ '9': '----.', '0': '-----', ' ': ' '
16
+ }
17
+
18
+ # Reverse dictionary for decoding
19
+ MORSE_TO_CHAR = {v: k for k, v in MORSE_CODE_DICT.items()}
20
+
21
+ # Function to process audio and detect Morse code (simplified)
22
+ def decode_morse_from_audio(audio_data):
23
+ if audio_data is None:
24
+ return "", ""
25
+
26
+ # Audio comes as (sample_rate, data) from Gradio
27
+ sample_rate, data = audio_data
28
+ if len(data.shape) > 1: # Convert stereo to mono if needed
29
+ data = data.mean(axis=1)
30
+
31
+ # Normalize audio data
32
+ data = data / np.max(np.abs(data))
33
+
34
+ # Threshold for detecting signal (tweak as needed)
35
+ threshold = 0.1
36
+ signal = data > threshold
37
+
38
+ # Timing parameters (in samples, adjust based on sample_rate)
39
+ dit_length = int(sample_rate * 0.1) # 100ms for a dit
40
+ dah_length = dit_length * 3 # 300ms for a dah
41
+ space_length = dit_length * 7 # 700ms for word space
42
+
43
+ morse_code = ""
44
+ decoded_text = ""
45
+ i = 0
46
+
47
+ while i < len(signal) - dit_length:
48
+ if signal[i]:
49
+ # Measure signal duration
50
+ start = i
51
+ while i < len(signal) and signal[i]:
52
+ i += 1
53
+ duration = i - start
54
+
55
+ # Classify as dit or dah
56
+ if duration >= dah_length:
57
+ morse_code += "-"
58
+ elif duration >= dit_length:
59
+ morse_code += "."
60
+
61
+ # Check for spaces (pauses)
62
+ else:
63
+ start = i
64
+ while i < len(signal) and not signal[i]:
65
+ i += 1
66
+ pause = i - start
67
+
68
+ if pause >= space_length:
69
+ if morse_code:
70
+ decoded_text += MORSE_TO_CHAR.get(morse_code, "?")
71
+ decoded_text += " "
72
+ morse_code = ""
73
+ elif pause >= dit_length and morse_code:
74
+ decoded_text += MORSE_TO_CHAR.get(morse_code, "?")
75
+ morse_code = ""
76
+
77
+ i += 1
78
+
79
+ # Handle any remaining code
80
+ if morse_code:
81
+ decoded_text += MORSE_TO_CHAR.get(morse_code, "?")
82
+
83
+ return morse_code, decoded_text.strip()
84
+
85
+ # Function to generate highlighted alphabet UI
86
+ def generate_alphabet_html(decoded_text):
87
+ html = "<div style='font-family: monospace; font-size: 16px;'>"
88
+ for char in MORSE_CODE_DICT.keys():
89
+ color = "red" if char in decoded_text.upper() else "black"
90
+ html += f"<span style='color: {color}; margin: 5px;'>{char}: {MORSE_CODE_DICT[char]}</span>"
91
+ if char in "AEIMQUZ":
92
+ html += "<br>"
93
+ html += "</div>"
94
+ return html
95
+
96
+ # Gradio streaming function
97
+ def stream_morse_decoder(audio):
98
+ morse, text = decode_morse_from_audio(audio)
99
+ alphabet_html = generate_alphabet_html(text)
100
+ return morse, text, alphabet_html
101
+
102
+ # Gradio UI with Blocks
103
+ with gr.Blocks(title="Morse Code Decoder") as demo:
104
+ gr.Markdown("# Morse Code Decoder")
105
+ gr.Markdown("Speak or play Morse code into your microphone to decode it live!")
106
+
107
+ with gr.Row():
108
+ audio_input = gr.Audio(source="microphone", type="numpy", streaming=True, label="Live Audio Input")
109
+
110
+ with gr.Row():
111
+ with gr.Column():
112
+ morse_output = gr.Textbox(label="Detected Morse Code", interactive=False)
113
+ text_output = gr.Textbox(label="Decoded Text", interactive=False)
114
+ with gr.Column():
115
+ alphabet_display = gr.HTML(label="Morse Alphabet (Highlighted)")
116
+
117
+ # Event listener for streaming audio
118
+ audio_input.stream(
119
+ fn=stream_morse_decoder,
120
+ inputs=[audio_input],
121
+ outputs=[morse_output, text_output, alphabet_display],
122
+ _js="() => { return [navigator.mediaDevices.getUserMedia({ audio: true })];"
123
+ )
124
+
125
+ # Launch the app
126
+ demo.launch()