namelessai commited on
Commit
ce6ed11
·
verified ·
1 Parent(s): 241df5e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -0
app.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import json
3
+ from pydub import AudioSegment
4
+ from pydub.effects import normalize, compress_dynamic_range, low_pass_filter, high_pass_filter
5
+ import numpy as np
6
+ import gradio as gr
7
+
8
+ # Default presets for common genres
9
+ PRESETS = {
10
+ "rock": {"gain": 6, "compress_threshold": -20, "compress_ratio": 4, "low_pass": 12000, "high_pass": 80},
11
+ "pop": {"gain": 4, "compress_threshold": -18, "compress_ratio": 3, "low_pass": 15000, "high_pass": 100},
12
+ "jazz": {"gain": 3, "compress_threshold": -22, "compress_ratio": 2, "low_pass": 14000, "high_pass": 60},
13
+ "electronic": {"gain": 8, "compress_threshold": -16, "compress_ratio": 5, "low_pass": 20000, "high_pass": 120},
14
+ }
15
+
16
+ # JSON export extension
17
+ EXPORT_EXT = ".master"
18
+
19
+ # Custom CSS for Gradio
20
+ CUSTOM_CSS = """
21
+ body { background-color: #1e1e1e; color: #f0f0f0; }
22
+ .gradio-container { border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); }
23
+ #title { font-size: 2rem; margin-bottom: 1rem; }
24
+ """
25
+
26
+ def apply_mastering(audio: AudioSegment, params: dict) -> AudioSegment:
27
+ # Gain
28
+ processed = audio + params["gain"]
29
+ # Compression
30
+ processed = compress_dynamic_range(processed,
31
+ threshold=params["compress_threshold"],
32
+ ratio=params["compress_ratio"])
33
+ # EQ filters
34
+ processed = high_pass_filter(processed, params["high_pass"])
35
+ processed = low_pass_filter(processed, params["low_pass"])
36
+ # Normalization
37
+ processed = normalize(processed)
38
+ return processed
39
+
40
+
41
+ def process_and_export(audio_file, preset_name, gain, threshold, ratio, lp, hp):
42
+ # Load
43
+ audio = AudioSegment.from_file(audio_file.name)
44
+ # Determine params
45
+ if preset_name != "custom":
46
+ params = PRESETS[preset_name]
47
+ else:
48
+ params = {"gain": gain, "compress_threshold": threshold, "compress_ratio": ratio,
49
+ "low_pass": lp, "high_pass": hp}
50
+ # Process
51
+ out = apply_mastering(audio, params)
52
+ # Export audio
53
+ buf = io.BytesIO()
54
+ out.export(buf, format="wav")
55
+ buf.seek(0)
56
+ # Create preset JSON
57
+ preset = {"preset": preset_name, "params": params}
58
+ preset_buf = io.BytesIO(json.dumps(preset, indent=2).encode())
59
+ preset_buf.name = "preset" + EXPORT_EXT
60
+ return (buf, "processed.wav"), (preset_buf, preset_buf.name)
61
+
62
+
63
+ def load_preset_json(file_obj):
64
+ data = json.load(file_obj)
65
+ name = data.get("preset", "custom")
66
+ params = data.get("params", {})
67
+ return name, params.get("gain", 0), params.get("compress_threshold", 0), \
68
+ params.get("compress_ratio", 1), params.get("low_pass", 20000), params.get("high_pass", 20)
69
+
70
+ with gr.Blocks(css=CUSTOM_CSS) as demo:
71
+ gr.Markdown("<div id='title'>Advanced Browser-based Audio Mastering Suite</div>")
72
+ with gr.Row():
73
+ with gr.Column():
74
+ audio_input = gr.Audio(label="Upload Audio", type="file")
75
+ preset_dropdown = gr.Dropdown(choices=list(PRESETS.keys()) + ["custom"], value="rock", label="Preset")
76
+ gain = gr.Slider(-10, 20, value=PRESETS["rock"]["gain"], label="Gain (dB)")
77
+ threshold = gr.Slider(-60, 0, value=PRESETS["rock"]["compress_threshold"], label="Compress Threshold (dB)")
78
+ ratio = gr.Slider(1, 10, value=PRESETS["rock"]["compress_ratio"], label="Compress Ratio")
79
+ lp = gr.Slider(1000, 20000, value=PRESETS["rock"]["low_pass"], label="Low-pass Frequency (Hz)")
80
+ hp = gr.Slider(20, 500, value=PRESETS["rock"]["high_pass"], label="High-pass Frequency (Hz)")
81
+ load_preset = gr.File(label="Load .master Preset", file_types=[".master"])
82
+ export_button = gr.Button("Process & Export")
83
+ with gr.Column():
84
+ output_audio = gr.Audio(label="Processed Audio")
85
+ export_preset_file = gr.File(label="Download Preset (.master)")
86
+
87
+ # Interactivity
88
+ def sync_sliders(preset):
89
+ if preset != "custom":
90
+ p = PRESETS[preset]
91
+ return gr.update(value=p["gain"]), gr.update(value=p["compress_threshold"]), \
92
+ gr.update(value=p["compress_ratio"]), gr.update(value=p["low_pass"]), \
93
+ gr.update(value=p["high_pass"])
94
+ return None
95
+
96
+ preset_dropdown.change(sync_sliders, inputs=[preset_dropdown], outputs=[gain, threshold, ratio, lp, hp])
97
+ load_preset.upload(load_preset_json, inputs=[load_preset],
98
+ outputs=[preset_dropdown, gain, threshold, ratio, lp, hp])
99
+ export_button.click(process_and_export,
100
+ inputs=[audio_input, preset_dropdown, gain, threshold, ratio, lp, hp],
101
+ outputs=[output_audio, export_preset_file])
102
+
103
+ if __name__ == "__main__":
104
+ demo.launch()