Download app2.py from nightfury/MorseCode: direct link, hf CLI and curl.
- Browser
- Download file 9.51 kB
-
https://huggingface.co/spaces/nightfury/MorseCode/resolve/main/app2.py
- Command line
-
hf download hf://spaces/nightfury/MorseCode/app2.py
-
curl -L -o app2.py https://huggingface.co/spaces/nightfury/MorseCode/resolve/main/app2.py
9.51 kB
| import gradio as gr | |
| import numpy as np | |
| import tempfile | |
| from scipy.io import wavfile | |
| import speech_recognition as sr | |
| import soundfile as sf | |
| # Morse code dictionary | |
| MORSE_CODE_DICT = { | |
| 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', | |
| 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', | |
| 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', | |
| 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', | |
| 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', | |
| '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', | |
| '9': '----.', '0': '-----', ' ': '/' | |
| } | |
| MORSE_TO_CHAR = {v: k for k, v in MORSE_CODE_DICT.items()} | |
| # Timing constants | |
| DIT_DURATION = 0.1 | |
| DAH_DURATION = 3 * DIT_DURATION | |
| SPACE_DURATION = 7 * DIT_DURATION | |
| CHAR_SPACE = DIT_DURATION | |
| SAMPLE_RATE = 44100 | |
| # Decode Morse from audio beeps | |
| def decode_morse_from_audio(audio_data, is_file=False): | |
| if audio_data is None: | |
| return "", "" | |
| if is_file: | |
| sample_rate, data = wavfile.read(audio_data) | |
| else: | |
| sample_rate, data = audio_data | |
| if len(data.shape) > 1: | |
| data = data.mean(axis=1) | |
| data = data / np.max(np.abs(data)) | |
| threshold = 0.1 | |
| signal = data > threshold | |
| morse_code, decoded_text = "", "" | |
| i = 0 | |
| while i < len(signal) - int(SAMPLE_RATE * DIT_DURATION): | |
| if signal[i]: | |
| start = i | |
| while i < len(signal) and signal[i]: | |
| i += 1 | |
| duration = (i - start) / sample_rate | |
| morse_code += "-" if duration >= DAH_DURATION else "." | |
| else: | |
| start = i | |
| while i < len(signal) and not signal[i]: | |
| i += 1 | |
| pause = (i - start) / sample_rate | |
| if pause >= SPACE_DURATION and morse_code: | |
| decoded_text += " " | |
| morse_code = "" | |
| elif pause >= DIT_DURATION and morse_code: | |
| decoded_text += MORSE_TO_CHAR.get(morse_code, "?") | |
| morse_code = "" | |
| i += 1 | |
| if morse_code: | |
| decoded_text += MORSE_TO_CHAR.get(morse_code, "?") | |
| return morse_code, decoded_text.strip() | |
| # Decode Morse from text | |
| def decode_morse_from_text(morse_text): | |
| if not morse_text: | |
| return "" | |
| words = morse_text.split("/") | |
| decoded_text = "" | |
| for word in words: | |
| chars = word.strip().split() | |
| for char in chars: | |
| decoded_text += MORSE_TO_CHAR.get(char, "?") | |
| decoded_text += " " | |
| return decoded_text.strip() | |
| # Encode text to Morse | |
| def text_to_morse(text): | |
| text = text.upper() | |
| return " ".join(MORSE_CODE_DICT.get(char, "?") for char in text if char in MORSE_CODE_DICT) | |
| # Generate Morse audio | |
| def generate_morse_audio(morse): | |
| audio = [] | |
| frequency = 750 | |
| for symbol in morse.split(): | |
| if symbol == "/": | |
| audio.extend([0] * int(SAMPLE_RATE * SPACE_DURATION)) | |
| else: | |
| for char in symbol: | |
| duration = DAH_DURATION if char == "-" else DIT_DURATION | |
| t = np.linspace(0, duration, int(SAMPLE_RATE * duration), False) | |
| tone = 0.5 * np.sin(2 * np.pi * frequency * t) | |
| audio.extend(tone) | |
| audio.extend([0] * int(SAMPLE_RATE * DIT_DURATION)) | |
| audio.extend([0] * int(SAMPLE_RATE * CHAR_SPACE)) | |
| audio = np.array(audio, dtype=np.float32) | |
| with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_file: | |
| sf.write(temp_file.name, audio, SAMPLE_RATE, format="wav") | |
| return temp_file.name | |
| # Speech to text | |
| def speech_to_text(audio_path): | |
| recognizer = sr.Recognizer() | |
| with sr.AudioFile(audio_path) as source: | |
| audio_data = recognizer.record(source) | |
| try: | |
| return recognizer.recognize_google(audio_data) | |
| except: | |
| return "Speech recognition failed" | |
| # Highlight alphabet | |
| def generate_alphabet_html(text): | |
| html = "<div style='font-family: monospace; font-size: 16px;'>" | |
| for char in MORSE_CODE_DICT.keys(): | |
| color = "red" if char in text.upper() else "black" | |
| html += f"<span style='color: {color}; margin: 5px;'>{char}: {MORSE_CODE_DICT[char]}</span>" | |
| if char in "AEIMQUZ": | |
| html += "<br>" | |
| html += "</div>" | |
| return html | |
| # Encoding functions | |
| def encode_text_to_morse(text): | |
| morse = text_to_morse(text) | |
| audio = generate_morse_audio(morse) | |
| return morse, text, generate_alphabet_html(text), audio | |
| def encode_speech_to_morse(audio_path): | |
| text = speech_to_text(audio_path) | |
| morse = text_to_morse(text) | |
| audio = generate_morse_audio(morse) | |
| return morse, text, generate_alphabet_html(text), audio | |
| # Decoding functions | |
| def decode_morse_text(morse_text): | |
| text = decode_morse_from_text(morse_text) | |
| audio = generate_morse_audio(morse_text) | |
| return morse_text, text, generate_alphabet_html(text), audio | |
| def decode_morse_speech(audio_path): | |
| transcribed = speech_to_text(audio_path).replace("dit", ".").replace("dah", "-").replace("slash", "/") | |
| text = decode_morse_from_text(transcribed) | |
| audio = generate_morse_audio(transcribed) | |
| return transcribed, text, generate_alphabet_html(text), audio | |
| def decode_morse_audio(audio_path): | |
| morse, text = decode_morse_from_audio(audio_path, is_file=True) | |
| return morse, text, generate_alphabet_html(text), None | |
| def decode_live_morse(audio_data): | |
| morse, text = decode_morse_from_audio(audio_data, is_file=False) | |
| return morse, text, generate_alphabet_html(text), None | |
| # Gradio UI | |
| with gr.Blocks(title="Morse Code Converter") as demo: | |
| gr.Markdown("# Morse Code Converter") | |
| gr.Markdown("Encode to Morse or decode Morse from text, speech, or audio!") | |
| with gr.Tab("Encode Text to Morse"): | |
| text_input = gr.Textbox(label="Enter Text", placeholder="e.g., HELLO") | |
| text_btn = gr.Button("Convert to Morse") | |
| text_morse_out = gr.Textbox(label="Morse Code", interactive=False) | |
| text_text_out = gr.Textbox(label="Original Text", interactive=False) | |
| text_alphabet = gr.HTML(label="Alphabet (Highlighted)") | |
| text_audio = gr.Audio(label="Morse Audio", interactive=False) | |
| text_btn.click(fn=encode_text_to_morse, inputs=[text_input], outputs=[text_morse_out, text_text_out, text_alphabet, text_audio]) | |
| with gr.Tab("Encode Speech to Morse"): | |
| speech_input = gr.Audio(type="filepath", label="Record Speech (e.g., say 'HELLO')") | |
| speech_btn = gr.Button("Convert to Morse") | |
| speech_morse_out = gr.Textbox(label="Morse Code", interactive=False) | |
| speech_text_out = gr.Textbox(label="Transcribed Text", interactive=False) | |
| speech_alphabet = gr.HTML(label="Alphabet (Highlighted)") | |
| speech_audio = gr.Audio(label="Morse Audio", interactive=False) | |
| speech_btn.click(fn=encode_speech_to_morse, inputs=[speech_input], outputs=[speech_morse_out, speech_text_out, speech_alphabet, speech_audio]) | |
| with gr.Tab("Decode Morse Text"): | |
| morse_text_input = gr.Textbox(label="Enter Morse Text", placeholder="e.g., .... . .-.. .-.. ---") | |
| morse_text_btn = gr.Button("Decode Morse") | |
| morse_text_morse_out = gr.Textbox(label="Morse Code", interactive=False) | |
| morse_text_text_out = gr.Textbox(label="Decoded Text", interactive=False) | |
| morse_text_alphabet = gr.HTML(label="Alphabet (Highlighted)") | |
| morse_text_audio = gr.Audio(label="Morse Audio", interactive=False) | |
| morse_text_btn.click(fn=decode_morse_text, inputs=[morse_text_input], outputs=[morse_text_morse_out, morse_text_text_out, morse_text_alphabet, morse_text_audio]) | |
| with gr.Tab("Decode Morse Speech"): | |
| morse_speech_input = gr.Audio(type="filepath", label="Record Morse Speech (e.g., say 'dit dit dit dit dit')") | |
| morse_speech_btn = gr.Button("Decode Morse") | |
| morse_speech_morse_out = gr.Textbox(label="Transcribed Morse", interactive=False) | |
| morse_speech_text_out = gr.Textbox(label="Decoded Text", interactive=False) | |
| morse_speech_alphabet = gr.HTML(label="Alphabet (Highlighted)") | |
| morse_speech_audio = gr.Audio(label="Morse Audio", interactive=False) | |
| morse_speech_btn.click(fn=decode_morse_speech, inputs=[morse_speech_input], outputs=[morse_speech_morse_out, morse_speech_text_out, morse_speech_alphabet, morse_speech_audio]) | |
| with gr.Tab("Decode Morse Audio"): | |
| morse_audio_input = gr.Audio(type="filepath", label="Upload Morse Audio (WAV of beeps)") | |
| morse_audio_btn = gr.Button("Decode Morse") | |
| morse_audio_morse_out = gr.Textbox(label="Detected Morse", interactive=False) | |
| morse_audio_text_out = gr.Textbox(label="Decoded Text", interactive=False) | |
| morse_audio_alphabet = gr.HTML(label="Alphabet (Highlighted)") | |
| morse_audio_btn.click(fn=decode_morse_audio, inputs=[morse_audio_input], outputs=[morse_audio_morse_out, morse_audio_text_out, morse_audio_alphabet]) | |
| with gr.Tab("Decode Live Morse"): | |
| live_audio_input = gr.Audio(type="numpy", label="Live Morse Input (Use Microphone)", streaming=True) | |
| live_morse_out = gr.Textbox(label="Detected Morse", interactive=False) | |
| live_text_out = gr.Textbox(label="Decoded Text", interactive=False) | |
| live_alphabet = gr.HTML(label="Alphabet (Highlighted)") | |
| live_audio_input.stream(fn=decode_live_morse, inputs=[live_audio_input], outputs=[live_morse_out, live_text_out, live_alphabet]) | |
| demo.launch() |