HumanizeBot / app.py
FILMITO's picture
Update app.py
280cba5 verified
raw
history blame
7.58 kB
import gradio as gr
import pretty_midi
import numpy as np
import tempfile
import librosa
import soundfile as sf
import os
class SimpleMP3Humanizer:
def __init__(self):
self.style_presets = {
"pop": [0, 33, 25, 1], # Drums, Bass, Guitar, Piano
"electronic": [0, 39, 81, 89], # Drums, Synth Bass, Lead, Pad
"rock": [0, 33, 30, 27], # Drums, Bass, Distortion Guitar, Clean Guitar
"cinematic": [0, 48, 61, 5] # Drums, Strings, Horn, Piano
}
def mp3_to_humanized_mp3(self, mp3_path, style="pop", intensity=0.7):
"""Convert MP3 to humanized MP3 in one step"""
try:
# Load the MP3
y, sr = librosa.load(mp3_path, sr=22050, mono=True)
duration = len(y) / sr
# Create MIDI
midi = pretty_midi.PrettyMIDI()
# Add instruments
for program in self.style_presets[style]:
is_drum = (program == 0)
instrument = pretty_midi.Instrument(program=program, is_drum=is_drum)
midi.instruments.append(instrument)
# Create simple music based on audio
self.create_simple_music(midi, y, sr, duration, style, intensity)
# Add human feel
self.add_human_touch(midi, intensity)
# Convert to audio
audio_data = midi.synthesize()
return audio_data, sr
except Exception as e:
raise Exception(f"Conversion failed: {str(e)}")
def create_simple_music(self, midi, y, sr, duration, style, intensity):
"""Create basic musical structure"""
# Create beats
num_beats = max(8, min(32, int(duration * 2))) # 2 beats per second
beat_times = np.linspace(0, duration, num_beats)
instruments = midi.instruments
# Add drums
drums = next((inst for inst in instruments if inst.is_drum), None)
if drums:
for i, time in enumerate(beat_times):
# Kick on strong beats
if i % 4 == 0:
drums.notes.append(self.create_note(36, 90, time, 0.3))
# Snare on off-beats
if i % 4 == 2:
drums.notes.append(self.create_note(38, 80, time, 0.2))
# Hi-hats for electronic/pop
if style in ["electronic", "pop"]:
drums.notes.append(self.create_note(42, 70, time, 0.1))
# Add bass
bass = next((inst for inst in instruments if not inst.is_drum and 32 <= inst.program <= 39), None)
if bass:
bass_notes = [36, 38, 41, 43, 45, 48] # Simple bass line
for i, time in enumerate(beat_times[::2]): # Every other beat
if i < len(bass_notes):
bass.notes.append(self.create_note(bass_notes[i], 85, time, 0.8))
# Add melody
melody_instruments = [inst for inst in instruments if not inst.is_drum and inst.program not in range(32, 40)]
if melody_instruments:
melody = melody_instruments[0]
melody_notes = [60, 62, 64, 65, 67, 69, 71, 72] # C major scale
for i, time in enumerate(beat_times[::4]): # Every 4 beats
if i < len(melody_notes):
melody.notes.append(self.create_note(melody_notes[i], 80, time, 1.0))
def create_note(self, pitch, velocity, start, duration):
"""Helper to create a note"""
return pretty_midi.Note(
velocity=velocity,
pitch=pitch,
start=start,
end=start + duration
)
def add_human_touch(self, midi, intensity):
"""Add humanization to the music"""
for instrument in midi.instruments:
for note in instrument.notes:
# Random timing
note.start += np.random.normal(0, 0.02 * intensity)
note.start = max(0, note.start)
# Random velocity
note.velocity += int(np.random.normal(0, 10 * intensity))
note.velocity = max(40, min(127, note.velocity))
# Random duration for non-drums
if not instrument.is_drum:
note.end += np.random.normal(0, 0.05 * intensity)
note.end = max(note.start + 0.1, note.end)
def convert_mp3(input_mp3, style, intensity):
"""Main conversion function"""
if input_mp3 is None:
return None, "Please upload an MP3 file"
converter = SimpleMP3Humanizer()
try:
# Convert to humanized MP3
audio_data, sr = converter.mp3_to_humanized_mp3(input_mp3, style, intensity)
# Save as temporary MP3 file
output_path = tempfile.mktemp(suffix='_humanized.mp3')
sf.write(output_path, audio_data, sr)
return output_path, "βœ… Conversion successful! Your humanized song is ready below."
except Exception as e:
return None, f"❌ Error: {str(e)}"
# Simple and compatible interface
with gr.Blocks(theme=gr.themes.Soft(), title="MP3 Humanizer") as demo:
gr.Markdown("""
# 🎡 MP3 Humanizer
**Upload AI Music β†’ Get Human Version β†’ Download MP3**
""")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 1. Upload Your AI Song")
input_audio = gr.Audio(
sources=["upload"],
type="filepath",
label="Upload MP3 File"
)
gr.Markdown("### 2. Choose Settings")
style = gr.Radio(
["pop", "electronic", "rock", "cinematic"],
value="pop",
label="Music Style"
)
intensity = gr.Slider(
0.1, 1.0, value=0.7,
label="Human Feel Intensity"
)
convert_btn = gr.Button(
"✨ Convert to Human Version",
variant="primary",
size="lg"
)
with gr.Column(scale=1):
gr.Markdown("### 3. Download Result")
output_audio = gr.Audio(
label="Your Humanized Song",
type="filepath",
interactive=False
)
status = gr.Textbox(
label="Status",
interactive=False
)
# Simple instructions
with gr.Accordion("πŸ“– How to Use", open=True):
gr.Markdown("""
1. **Upload** your AI-generated MP3 file
2. **Choose** your preferred music style
3. **Adjust** the human feel slider
4. **Click Convert** and wait a few seconds
5. **Play the preview** to hear your humanized song
6. **Click the download icon** in the audio player to save your MP3
That's it! You'll get a complete MP3 file with drums, bass, melody, and human-sounding timing.
""")
# Conversion process
def process_conversion(input_mp3, style, intensity):
output_path, message = convert_mp3(input_mp3, style, intensity)
return output_path, message
convert_btn.click(
fn=process_conversion,
inputs=[input_audio, style, intensity],
outputs=[output_audio, status]
)
if __name__ == "__main__":
demo.launch()