Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,44 +1,85 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from pydub import AudioSegment
|
| 3 |
-
import noisereduce as nr
|
| 4 |
import numpy as np
|
| 5 |
import tempfile
|
| 6 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
#
|
| 13 |
def apply_normalize(audio):
|
| 14 |
return audio.normalize()
|
| 15 |
|
| 16 |
def apply_noise_reduction(audio):
|
| 17 |
samples, frame_rate = audiosegment_to_array(audio)
|
| 18 |
-
|
| 19 |
-
return
|
| 20 |
-
reduced_noise.tobytes(),
|
| 21 |
-
frame_rate=frame_rate,
|
| 22 |
-
sample_width=reduced_noise.dtype.itemsize,
|
| 23 |
-
channels=audio.channels
|
| 24 |
-
)
|
| 25 |
|
| 26 |
def apply_compression(audio):
|
| 27 |
return audio.compress_dynamic_range()
|
| 28 |
|
| 29 |
def apply_reverb(audio):
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
return audio.overlay(reverb_audio, position=1000)
|
| 33 |
|
| 34 |
def apply_pitch_shift(audio, semitones=-2):
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
# Main processing function
|
| 44 |
def process_audio(audio_file, effect):
|
|
@@ -53,9 +94,22 @@ def process_audio(audio_file, effect):
|
|
| 53 |
elif effect == "Add Reverb":
|
| 54 |
result = apply_reverb(audio)
|
| 55 |
elif effect == "Pitch Shift":
|
| 56 |
-
result = apply_pitch_shift(audio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
else:
|
| 58 |
-
result = audio
|
| 59 |
|
| 60 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as f:
|
| 61 |
result.export(f.name, format="wav")
|
|
@@ -72,14 +126,19 @@ interface = gr.Interface(
|
|
| 72 |
"Noise Reduction",
|
| 73 |
"Compress Dynamic Range",
|
| 74 |
"Add Reverb",
|
| 75 |
-
"Pitch Shift"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
],
|
| 77 |
label="Select Effect"
|
| 78 |
)
|
| 79 |
],
|
| 80 |
outputs=gr.Audio(label="Processed Audio", type="filepath"),
|
| 81 |
-
title="Fix My Recording -
|
| 82 |
-
description="
|
| 83 |
)
|
| 84 |
|
| 85 |
interface.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from pydub import AudioSegment
|
|
|
|
| 3 |
import numpy as np
|
| 4 |
import tempfile
|
| 5 |
import os
|
| 6 |
+
import noisereduce as nr
|
| 7 |
+
from scipy.io import wavfile
|
| 8 |
+
import subprocess
|
| 9 |
+
import shutil
|
| 10 |
+
|
| 11 |
+
# Helper functions
|
| 12 |
+
def audiosegment_to_array(audio):
|
| 13 |
+
return np.array(audio.get_array_of_samples()), audio.frame_rate
|
| 14 |
|
| 15 |
+
def array_to_audiosegment(samples, frame_rate, sample_width=2, channels=1):
|
| 16 |
+
return AudioSegment(
|
| 17 |
+
samples.tobytes(),
|
| 18 |
+
frame_rate=frame_rate,
|
| 19 |
+
sample_width=sample_width,
|
| 20 |
+
channels=channels
|
| 21 |
+
)
|
| 22 |
|
| 23 |
+
# Effect Functions
|
| 24 |
def apply_normalize(audio):
|
| 25 |
return audio.normalize()
|
| 26 |
|
| 27 |
def apply_noise_reduction(audio):
|
| 28 |
samples, frame_rate = audiosegment_to_array(audio)
|
| 29 |
+
reduced = nr.reduce_noise(y=samples, sr=frame_rate)
|
| 30 |
+
return array_to_audiosegment(reduced, frame_rate, channels=audio.channels)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
def apply_compression(audio):
|
| 33 |
return audio.compress_dynamic_range()
|
| 34 |
|
| 35 |
def apply_reverb(audio):
|
| 36 |
+
reverb = audio - 10
|
| 37 |
+
return audio.overlay(reverb, position=1000)
|
|
|
|
| 38 |
|
| 39 |
def apply_pitch_shift(audio, semitones=-2):
|
| 40 |
+
new_frame_rate = int(audio.frame_rate * (2 ** (semitones / 12)))
|
| 41 |
+
samples = np.array(audio.get_array_of_samples())
|
| 42 |
+
resampled = np.interp(
|
| 43 |
+
np.arange(0, len(samples), 2 ** (semitones / 12)),
|
| 44 |
+
np.arange(len(samples)),
|
| 45 |
+
samples
|
| 46 |
+
).astype(np.int16)
|
| 47 |
+
return AudioSegment(
|
| 48 |
+
resampled.tobytes(),
|
| 49 |
+
frame_rate=new_frame_rate,
|
| 50 |
+
sample_width=audio.sample_width,
|
| 51 |
+
channels=audio.channels
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
def apply_echo(audio, delay_ms=500, decay=0.5):
|
| 55 |
+
echo = audio - 10
|
| 56 |
+
return audio.overlay(echo, position=delay_ms)
|
| 57 |
+
|
| 58 |
+
def apply_stereo_widen(audio, pan_amount=0.3):
|
| 59 |
+
left = audio.pan(-pan_amount)
|
| 60 |
+
right = audio.pan(pan_amount)
|
| 61 |
+
return AudioSegment.from_mono_audiosegments(left, right)
|
| 62 |
+
|
| 63 |
+
def apply_bass_boost(audio, gain=10):
|
| 64 |
+
return audio.low_pass_filter(100).apply_gain(gain)
|
| 65 |
+
|
| 66 |
+
def apply_treble_boost(audio, gain=10):
|
| 67 |
+
return audio.high_pass_filter(4000).apply_gain(gain)
|
| 68 |
+
|
| 69 |
+
# Save temp WAV file for spleeter
|
| 70 |
+
def save_temp_wav(audio, path):
|
| 71 |
+
audio.export(path, format="wav")
|
| 72 |
+
|
| 73 |
+
# Vocal Isolation using spleeter
|
| 74 |
+
def apply_vocal_isolation(audio_path):
|
| 75 |
+
output_dir = tempfile.mkdtemp()
|
| 76 |
+
cmd = ["spleeter", "separate", "-o", output_dir, audio_path]
|
| 77 |
+
subprocess.run(cmd)
|
| 78 |
+
vocal_path = os.path.join(output_dir, os.path.basename(audio_path).replace(".wav", ""), "vocals.wav")
|
| 79 |
+
if os.path.exists(vocal_path):
|
| 80 |
+
return vocal_path
|
| 81 |
+
else:
|
| 82 |
+
raise Exception("Vocal isolation failed.")
|
| 83 |
|
| 84 |
# Main processing function
|
| 85 |
def process_audio(audio_file, effect):
|
|
|
|
| 94 |
elif effect == "Add Reverb":
|
| 95 |
result = apply_reverb(audio)
|
| 96 |
elif effect == "Pitch Shift":
|
| 97 |
+
result = apply_pitch_shift(audio)
|
| 98 |
+
elif effect == "Echo":
|
| 99 |
+
result = apply_echo(audio)
|
| 100 |
+
elif effect == "Stereo Widening":
|
| 101 |
+
result = apply_stereo_widen(audio)
|
| 102 |
+
elif effect == "Bass Boost":
|
| 103 |
+
result = apply_bass_boost(audio)
|
| 104 |
+
elif effect == "Treble Boost":
|
| 105 |
+
result = apply_treble_boost(audio)
|
| 106 |
+
elif effect == "Isolate Vocals":
|
| 107 |
+
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
|
| 108 |
+
save_temp_wav(audio, f.name)
|
| 109 |
+
vocal_path = apply_vocal_isolation(f.name)
|
| 110 |
+
result = AudioSegment.from_wav(vocal_path)
|
| 111 |
else:
|
| 112 |
+
result = audio
|
| 113 |
|
| 114 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as f:
|
| 115 |
result.export(f.name, format="wav")
|
|
|
|
| 126 |
"Noise Reduction",
|
| 127 |
"Compress Dynamic Range",
|
| 128 |
"Add Reverb",
|
| 129 |
+
"Pitch Shift",
|
| 130 |
+
"Echo",
|
| 131 |
+
"Stereo Widening",
|
| 132 |
+
"Bass Boost",
|
| 133 |
+
"Treble Boost",
|
| 134 |
+
"Isolate Vocals"
|
| 135 |
],
|
| 136 |
label="Select Effect"
|
| 137 |
)
|
| 138 |
],
|
| 139 |
outputs=gr.Audio(label="Processed Audio", type="filepath"),
|
| 140 |
+
title="Fix My Recording - Pro Edition",
|
| 141 |
+
description="Apply noise reduction, mastering, creative effects, or isolate vocals from your track!"
|
| 142 |
)
|
| 143 |
|
| 144 |
interface.launch()
|