import gradio as gr import numpy as np import io from scipy.io import wavfile import speech_recognition as sr import soundfile as sf # Morse code dictionary (ITU standard) 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()} # Morse code timing (in seconds) DIT_DURATION = 0.1 # 100ms for dit DAH_DURATION = 3 * DIT_DURATION # 300ms for dah SPACE_DURATION = 7 * DIT_DURATION # 700ms for word space CHAR_SPACE = DIT_DURATION # Space between characters SAMPLE_RATE = 44100 # Standard audio sample rate # Decode Morse from audio (simplified) def decode_morse_from_audio(audio_data): if audio_data is None: return "", "" 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() # Convert text to Morse code def text_to_morse(text): text = text.upper() morse = " ".join(MORSE_CODE_DICT.get(char, "?") for char in text if char in MORSE_CODE_DICT) return morse # Generate Morse code audio from text def generate_morse_audio(morse): audio = [] frequency = 750 # Hz for Morse tone 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)) # Space between dits/dahs audio.extend([0] * int(SAMPLE_RATE * CHAR_SPACE)) # Space between characters audio = np.array(audio, dtype=np.float32) buffer = io.BytesIO() sf.write(buffer, audio, SAMPLE_RATE, format="wav") buffer.seek(0) return buffer # Speech to text def speech_to_text(audio): recognizer = sr.Recognizer() with sr.AudioFile(audio) as source: audio_data = recognizer.record(source) try: return recognizer.recognize_google(audio_data) except sr.UnknownValueError: return "Could not understand audio" except sr.RequestError: return "Speech recognition service unavailable" # Highlight alphabet in UI def generate_alphabet_html(decoded_text): html = "