Download enhancer.py from aboalaa1472/recitation-segmenter-app: direct link, hf CLI and curl.
- Browser
- Download file 8.85 kB
-
https://huggingface.co/spaces/aboalaa1472/recitation-segmenter-app/resolve/main/enhancer.py
- Command line
-
hf download hf://spaces/aboalaa1472/recitation-segmenter-app/enhancer.py
-
curl -L -o enhancer.py https://huggingface.co/spaces/aboalaa1472/recitation-segmenter-app/resolve/main/enhancer.py
8.85 kB
| """ | |
| Quran Audio Enhancer - Hugging Face Gradio Space | |
| ================================================= | |
| GUI ูุงู ู ูุชุญุณูู ุฌูุฏุฉ ุชูุงูุฉ ุงููุฑุขู ุงููุฑูู | |
| """ | |
| import numpy as np | |
| import scipy.signal as signal | |
| import librosa | |
| import soundfile as sf | |
| import noisereduce as nr | |
| import gradio as gr | |
| import tempfile | |
| import os | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ุฏูุงู ุงูู ุนุงูุฌุฉ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def load_audio(file_path: str, sr: int = 22050): | |
| audio, sample_rate = librosa.load(file_path, sr=sr, mono=True) | |
| return audio, sample_rate | |
| def remove_dc_offset(audio): | |
| return (audio - np.mean(audio)).astype(np.float32) | |
| def reduce_noise(audio, sr, strength): | |
| noise_clip = audio[:int(sr * 0.5)] if len(audio) > sr else audio | |
| return nr.reduce_noise( | |
| y=audio, sr=sr, y_noise=noise_clip, | |
| prop_decrease=strength, stationary=False, | |
| n_fft=2048, win_length=2048, hop_length=512, | |
| n_std_thresh_stationary=1.5, chunk_size=60000, use_torch=False | |
| ) | |
| def apply_bandpass_filter(audio, sr, low_hz=80, high_hz=8000): | |
| nyquist = sr / 2 | |
| low = low_hz / nyquist | |
| high = min(high_hz / nyquist, 0.99) | |
| b, a = signal.butter(6, [low, high], btype='band') | |
| return signal.filtfilt(b, a, audio).astype(np.float32) | |
| def enhance_clarity(audio): | |
| harmonic, _ = librosa.effects.hpss(audio, margin=3.0) | |
| return (0.8 * harmonic + 0.2 * audio).astype(np.float32) | |
| def apply_de_essing(audio, sr, threshold=0.4): | |
| nyquist = sr / 2 | |
| low = 5000 / nyquist | |
| high = min(10000 / nyquist, 0.99) | |
| b, a = signal.butter(4, [low, high], btype='band') | |
| sibilant = signal.filtfilt(b, a, audio) | |
| sib_rms = np.sqrt(np.convolve(sibilant**2, np.ones(512)/512, mode='same')) | |
| max_rms = np.max(sib_rms) + 1e-8 | |
| mask = np.where(sib_rms / max_rms > threshold, | |
| threshold / (sib_rms / max_rms + 1e-8), 1.0) | |
| return (audio - sibilant + sibilant * mask).astype(np.float32) | |
| def normalize_loudness(audio, target_db): | |
| rms = np.sqrt(np.mean(audio ** 2)) | |
| if rms < 1e-8: | |
| return audio | |
| target_rms = 10 ** (target_db / 20) | |
| return np.clip(audio * (target_rms / rms), -1.0, 1.0).astype(np.float32) | |
| def analyze_quality(audio, sr): | |
| rms_db = float(20 * np.log10(np.sqrt(np.mean(audio**2)) + 1e-8)) | |
| peak_db = float(20 * np.log10(np.max(np.abs(audio)) + 1e-8)) | |
| frames = librosa.util.frame(audio, frame_length=512, hop_length=512) | |
| frame_rms = np.sqrt(np.mean(frames**2, axis=0)) | |
| noise_floor_db = float(20 * np.log10(np.percentile(frame_rms, 10) + 1e-8)) | |
| noise_label = "๐ข ู ูุฎูุถุฉ" if noise_floor_db < -50 else "๐ก ู ุชูุณุทุฉ" if noise_floor_db < -35 else "๐ด ู ุฑุชูุนุฉ" | |
| return rms_db, peak_db, noise_floor_db, noise_label | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ุงูุฏุงูุฉ ุงูุฑุฆูุณูุฉ ููู ุนุงูุฌุฉ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def process_audio(audio_file, noise_strength, apply_bandpass, | |
| apply_enhancement, apply_deessing, target_db, output_format): | |
| if audio_file is None: | |
| return None, "โ ๏ธ ุงูุฑุฌุงุก ุฑูุน ู ูู ุตูุชู ุฃููุงู." | |
| # ุชุญู ูู | |
| audio, sr = load_audio(audio_file, sr=22050) | |
| duration = len(audio) / sr | |
| # ุชุญููู ูุจู | |
| rms_b, peak_b, noise_b, noise_label_b = analyze_quality(audio, sr) | |
| # ู ุนุงูุฌุฉ | |
| audio = remove_dc_offset(audio) | |
| audio = reduce_noise(audio, sr, noise_strength) | |
| if apply_bandpass: | |
| audio = apply_bandpass_filter(audio, sr) | |
| if apply_enhancement: | |
| audio = enhance_clarity(audio) | |
| if apply_deessing: | |
| audio = apply_de_essing(audio, sr) | |
| audio = normalize_loudness(audio, target_db) | |
| # ุชุญููู ุจุนุฏ | |
| rms_a, peak_a, noise_a, noise_label_a = analyze_quality(audio, sr) | |
| # ุญูุธ | |
| ext = "wav" if output_format == "WAV" else "flac" | |
| out_path = tempfile.mktemp(suffix=f"_enhanced.{ext}") | |
| sf.write(out_path, audio, sr, | |
| format=ext.upper(), | |
| subtype='PCM_16' if ext == 'wav' else None) | |
| # ุชูุฑูุฑ | |
| report = f""" | |
| ## ๐ ุชูุฑูุฑ ุงูู ุนุงูุฌุฉ | |
| | | ูุจู | ุจุนุฏ | | |
| |---|---|---| | |
| | ู ุณุชูู ุงูุตูุช (RMS) | {rms_b:.1f} dBFS | {rms_a:.1f} dBFS | | |
| | ุงูุฐุฑูุฉ | {peak_b:.1f} dBFS | {peak_a:.1f} dBFS | | |
| | ู ุณุชูู ุงูุถูุถุงุก | {noise_b:.1f} dBFS | {noise_a:.1f} dBFS | | |
| | ุชูุฏูุฑ ุงูุถูุถุงุก | {noise_label_b} | {noise_label_a} | | |
| **โฑ๏ธ ู ุฏุฉ ุงูู ูู:** {duration:.1f} ุซุงููุฉ | |
| **๐ต ู ุนุฏู ุงูุนููุงุช:** {sr} Hz | |
| **๐ ุงูุตูุบุฉ:** {output_format} | |
| ### ุงูุฎุทูุงุช ุงูู ุทุจููุฉ: | |
| {"โ " if True else "โ"} ุฅุฒุงูุฉ DC Offset | |
| โ ุฅุฒุงูุฉ ุงูุถูุถุงุก (ููุฉ: {noise_strength}) | |
| {"โ " if apply_bandpass else "โ"} ููุชุฑ ุงูุชุฑุฏุฏุงุช ุงูุตูุชูุฉ | |
| {"โ " if apply_enhancement else "โ"} ุชุญุณูู ุงููุถูุญ | |
| {"โ " if apply_deessing else "โ"} De-essing | |
| โ ุชุนุฏูู ู ุณุชูู ุงูุตูุช โ {target_db} dBFS | |
| """.strip() | |
| return out_path, report | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ูุงุฌูุฉ Gradio | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Blocks( | |
| title="๐ Quran Audio Enhancer", | |
| ) as demo: | |
| gr.HTML(""" | |
| <div class='title-text'> | |
| <h1>๐ Quran Audio Enhancer</h1> | |
| </div> | |
| <div class='subtitle-text'> | |
| <p>ุฃุฏุงุฉ ูุชุญุณูู ุฌูุฏุฉ ุชูุงูุฉ ุงููุฑุขู ุงููุฑูู โ ุฅุฒุงูุฉ ุงูุถูุถุงุก ูุชุญุณูู ุงูุตูุช</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| # ุงูุนู ูุฏ ุงูุฃูุณุฑ: ุงูุฅุฏุฎุงู ูุงูุฅุนุฏุงุฏุงุช | |
| with gr.Column(scale=1): | |
| gr.Markdown("### ๐ ุฑูุน ุงูู ูู ุงูุตูุชู") | |
| audio_input = gr.Audio( | |
| label="ุงุฑูุน ุงูู ูู ููุง (WAV, MP3, FLAC, OGG, M4A)", | |
| type="filepath", | |
| ) | |
| gr.Markdown("### โ๏ธ ุฅุนุฏุงุฏุงุช ุงูู ุนุงูุฌุฉ") | |
| noise_strength = gr.Slider( | |
| minimum=0.0, maximum=1.0, value=0.75, step=0.05, | |
| label="ููุฉ ุฅุฒุงูุฉ ุงูุถูุถุงุก", | |
| info="0 = ุฎููู ุฌุฏุงู | 1 = ููู ุฌุฏุงู" | |
| ) | |
| target_db = gr.Slider( | |
| minimum=-40.0, maximum=-6.0, value=-18.0, step=1.0, | |
| label="ู ุณุชูู ุงูุตูุช ุงูููุงุฆู (dBFS)", | |
| info="ุงูููู ุฉ ุงูู ูุตู ุจูุง: -18" | |
| ) | |
| with gr.Row(): | |
| apply_bandpass = gr.Checkbox(value=True, label="ููุชุฑ ุงูุชุฑุฏุฏุงุช ุงูุตูุชูุฉ") | |
| apply_enhancement = gr.Checkbox(value=True, label="ุชุญุณูู ุงููุถูุญ") | |
| apply_deessing = gr.Checkbox(value=True, label="De-essing") | |
| output_format = gr.Radio( | |
| choices=["WAV", "FLAC"], | |
| value="WAV", | |
| label="ุตูุบุฉ ุงูุฅุฎุฑุงุฌ" | |
| ) | |
| process_btn = gr.Button( | |
| "๐ ุงุจุฏุฃ ุงูู ุนุงูุฌุฉ", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| # ุงูุนู ูุฏ ุงูุฃูู ู: ุงููุชูุฌุฉ | |
| with gr.Column(scale=1): | |
| gr.Markdown("### ๐ต ุงูู ูู ุงูู ุญุณูู") | |
| audio_output = gr.Audio( | |
| label="ุงุณุชู ุน ูุญู ูู ุงูู ูู ุงูู ุญุณูู", | |
| type="filepath", | |
| ) | |
| gr.Markdown("### ๐ ุงูุชูุฑูุฑ") | |
| report_output = gr.Markdown( | |
| value="*ุณูุธูุฑ ุงูุชูุฑูุฑ ุจุนุฏ ุงูู ุนุงูุฌุฉ...*" | |
| ) | |
| # ุฑุจุท ุงูุฒุฑ | |
| process_btn.click( | |
| fn=process_audio, | |
| inputs=[ | |
| audio_input, noise_strength, apply_bandpass, | |
| apply_enhancement, apply_deessing, target_db, output_format | |
| ], | |
| outputs=[audio_output, report_output], | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| **ูุตุงุฆุญ ููุญุตูู ุนูู ุฃูุถู ูุชูุฌุฉ:** | |
| - ุงุณุชุฎุฏู `ููุฉ ุฅุฒุงูุฉ ุงูุถูุถุงุก` ุจูู 0.6 ู0.85 ููุชูุงูุงุช | |
| - ุฅุฐุง ูุงู ุงูุตูุช ูุจุฏู ุงุตุทูุงุนูุงูุ ููู ุงูููุฉ | |
| - ุตูุบุฉ FLAC ุฃูุถู ููุฃุฑุดูุฉ | WAV ููุงุณุชุฎุฏุงู ุงูุนุงุฏู | |
| """) | |
| if __name__ == "__main__": | |
| demo.launch() | |