FILMITO commited on
Commit
6b3afc0
ยท
verified ยท
1 Parent(s): 280cba5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +264 -87
app.py CHANGED
@@ -6,38 +6,69 @@ import librosa
6
  import soundfile as sf
7
  import os
8
 
9
- class SimpleMP3Humanizer:
10
  def __init__(self):
 
11
  self.style_presets = {
12
- "pop": [0, 33, 25, 1], # Drums, Bass, Guitar, Piano
13
- "electronic": [0, 39, 81, 89], # Drums, Synth Bass, Lead, Pad
14
- "rock": [0, 33, 30, 27], # Drums, Bass, Distortion Guitar, Clean Guitar
15
- "cinematic": [0, 48, 61, 5] # Drums, Strings, Horn, Piano
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  def mp3_to_humanized_mp3(self, mp3_path, style="pop", intensity=0.7):
19
- """Convert MP3 to humanized MP3 in one step"""
20
  try:
21
- # Load the MP3
22
  y, sr = librosa.load(mp3_path, sr=22050, mono=True)
23
  duration = len(y) / sr
24
 
25
- # Create MIDI
26
  midi = pretty_midi.PrettyMIDI()
27
 
28
- # Add instruments
29
- for program in self.style_presets[style]:
30
- is_drum = (program == 0)
31
- instrument = pretty_midi.Instrument(program=program, is_drum=is_drum)
 
 
 
32
  midi.instruments.append(instrument)
33
 
34
- # Create simple music based on audio
35
- self.create_simple_music(midi, y, sr, duration, style, intensity)
36
 
37
- # Add human feel
38
- self.add_human_touch(midi, intensity)
39
 
40
- # Convert to audio
 
 
 
41
  audio_data = midi.synthesize()
42
 
43
  return audio_data, sr
@@ -45,44 +76,170 @@ class SimpleMP3Humanizer:
45
  except Exception as e:
46
  raise Exception(f"Conversion failed: {str(e)}")
47
 
48
- def create_simple_music(self, midi, y, sr, duration, style, intensity):
49
- """Create basic musical structure"""
50
- # Create beats
51
- num_beats = max(8, min(32, int(duration * 2))) # 2 beats per second
52
- beat_times = np.linspace(0, duration, num_beats)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- instruments = midi.instruments
 
 
 
 
55
 
56
- # Add drums
57
- drums = next((inst for inst in instruments if inst.is_drum), None)
58
- if drums:
59
- for i, time in enumerate(beat_times):
60
- # Kick on strong beats
61
- if i % 4 == 0:
62
- drums.notes.append(self.create_note(36, 90, time, 0.3))
63
- # Snare on off-beats
64
- if i % 4 == 2:
65
- drums.notes.append(self.create_note(38, 80, time, 0.2))
66
- # Hi-hats for electronic/pop
67
- if style in ["electronic", "pop"]:
68
- drums.notes.append(self.create_note(42, 70, time, 0.1))
69
 
70
- # Add bass
71
- bass = next((inst for inst in instruments if not inst.is_drum and 32 <= inst.program <= 39), None)
72
- if bass:
73
- bass_notes = [36, 38, 41, 43, 45, 48] # Simple bass line
74
- for i, time in enumerate(beat_times[::2]): # Every other beat
75
- if i < len(bass_notes):
76
- bass.notes.append(self.create_note(bass_notes[i], 85, time, 0.8))
77
 
78
- # Add melody
79
- melody_instruments = [inst for inst in instruments if not inst.is_drum and inst.program not in range(32, 40)]
80
  if melody_instruments:
81
- melody = melody_instruments[0]
82
- melody_notes = [60, 62, 64, 65, 67, 69, 71, 72] # C major scale
83
- for i, time in enumerate(beat_times[::4]): # Every 4 beats
84
- if i < len(melody_notes):
85
- melody.notes.append(self.create_note(melody_notes[i], 80, time, 1.0))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  def create_note(self, pitch, velocity, start, duration):
88
  """Helper to create a note"""
@@ -93,32 +250,40 @@ class SimpleMP3Humanizer:
93
  end=start + duration
94
  )
95
 
96
- def add_human_touch(self, midi, intensity):
97
- """Add humanization to the music"""
98
  for instrument in midi.instruments:
 
 
 
 
 
 
 
 
99
  for note in instrument.notes:
100
- # Random timing
101
- note.start += np.random.normal(0, 0.02 * intensity)
102
- note.start = max(0, note.start)
103
 
104
- # Random velocity
105
- note.velocity += int(np.random.normal(0, 10 * intensity))
106
- note.velocity = max(40, min(127, note.velocity))
107
 
108
- # Random duration for non-drums
109
  if not instrument.is_drum:
110
- note.end += np.random.normal(0, 0.05 * intensity)
111
- note.end = max(note.start + 0.1, note.end)
112
 
113
  def convert_mp3(input_mp3, style, intensity):
114
  """Main conversion function"""
115
  if input_mp3 is None:
116
  return None, "Please upload an MP3 file"
117
 
118
- converter = SimpleMP3Humanizer()
119
 
120
  try:
121
- # Convert to humanized MP3
122
  audio_data, sr = converter.mp3_to_humanized_mp3(input_mp3, style, intensity)
123
 
124
  # Save as temporary MP3 file
@@ -130,11 +295,13 @@ def convert_mp3(input_mp3, style, intensity):
130
  except Exception as e:
131
  return None, f"โŒ Error: {str(e)}"
132
 
133
- # Simple and compatible interface
134
- with gr.Blocks(theme=gr.themes.Soft(), title="MP3 Humanizer") as demo:
135
  gr.Markdown("""
136
- # ๐ŸŽต MP3 Humanizer
137
- **Upload AI Music โ†’ Get Human Version โ†’ Download MP3**
 
 
138
  """)
139
 
140
  with gr.Row():
@@ -146,28 +313,30 @@ with gr.Blocks(theme=gr.themes.Soft(), title="MP3 Humanizer") as demo:
146
  label="Upload MP3 File"
147
  )
148
 
149
- gr.Markdown("### 2. Choose Settings")
150
  style = gr.Radio(
151
  ["pop", "electronic", "rock", "cinematic"],
152
  value="pop",
153
- label="Music Style"
 
154
  )
155
 
156
  intensity = gr.Slider(
157
  0.1, 1.0, value=0.7,
158
- label="Human Feel Intensity"
 
159
  )
160
 
161
  convert_btn = gr.Button(
162
- "โœจ Convert to Human Version",
163
  variant="primary",
164
  size="lg"
165
  )
166
 
167
  with gr.Column(scale=1):
168
- gr.Markdown("### 3. Download Result")
169
  output_audio = gr.Audio(
170
- label="Your Humanized Song",
171
  type="filepath",
172
  interactive=False
173
  )
@@ -177,26 +346,34 @@ with gr.Blocks(theme=gr.themes.Soft(), title="MP3 Humanizer") as demo:
177
  interactive=False
178
  )
179
 
180
- # Simple instructions
181
- with gr.Accordion("๐Ÿ“– How to Use", open=True):
182
  gr.Markdown("""
183
- 1. **Upload** your AI-generated MP3 file
184
- 2. **Choose** your preferred music style
185
- 3. **Adjust** the human feel slider
186
- 4. **Click Convert** and wait a few seconds
187
- 5. **Play the preview** to hear your humanized song
188
- 6. **Click the download icon** in the audio player to save your MP3
189
 
190
- That's it! You'll get a complete MP3 file with drums, bass, melody, and human-sounding timing.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  """)
192
 
193
  # Conversion process
194
- def process_conversion(input_mp3, style, intensity):
195
- output_path, message = convert_mp3(input_mp3, style, intensity)
196
- return output_path, message
197
-
198
  convert_btn.click(
199
- fn=process_conversion,
200
  inputs=[input_audio, style, intensity],
201
  outputs=[output_audio, status]
202
  )
 
6
  import soundfile as sf
7
  import os
8
 
9
+ class AdvancedMP3Humanizer:
10
  def __init__(self):
11
+ # Enhanced instrument sets with better sound combinations
12
  self.style_presets = {
13
+ "pop": [
14
+ {"program": 0, "name": "Drums", "is_drum": True, "role": "rhythm"},
15
+ {"program": 33, "name": "Bass Guitar", "is_drum": False, "role": "bass"},
16
+ {"program": 25, "name": "Acoustic Guitar", "is_drum": False, "role": "chords"},
17
+ {"program": 1, "name": "Piano", "is_drum": False, "role": "melody"},
18
+ {"program": 54, "name": "Synth Voice", "is_drum": False, "role": "pad"}
19
+ ],
20
+ "electronic": [
21
+ {"program": 0, "name": "Electronic Drums", "is_drum": True, "role": "rhythm"},
22
+ {"program": 39, "name": "Synth Bass", "is_drum": False, "role": "bass"},
23
+ {"program": 81, "name": "Lead Synth", "is_drum": False, "role": "melody"},
24
+ {"program": 89, "name": "Warm Pad", "is_drum": False, "role": "pad"},
25
+ {"program": 55, "name": "Orchestral Hit", "is_drum": False, "role": "accent"}
26
+ ],
27
+ "rock": [
28
+ {"program": 0, "name": "Rock Drums", "is_drum": True, "role": "rhythm"},
29
+ {"program": 33, "name": "Electric Bass", "is_drum": False, "role": "bass"},
30
+ {"program": 30, "name": "Distortion Guitar", "is_drum": False, "role": "rhythm"},
31
+ {"program": 27, "name": "Clean Guitar", "is_drum": False, "role": "melody"},
32
+ {"program": 49, "name": "String Ensemble", "is_drum": False, "role": "pad"}
33
+ ],
34
+ "cinematic": [
35
+ {"program": 0, "name": "Orchestral Drums", "is_drum": True, "role": "rhythm"},
36
+ {"program": 48, "name": "String Ensemble", "is_drum": False, "role": "pad"},
37
+ {"program": 61, "name": "French Horn", "is_drum": False, "role": "melody"},
38
+ {"program": 5, "name": "Electric Piano", "is_drum": False, "role": "chords"},
39
+ {"program": 91, "name": "Atmosphere Pad", "is_drum": False, "role": "background"}
40
+ ]
41
  }
42
 
43
  def mp3_to_humanized_mp3(self, mp3_path, style="pop", intensity=0.7):
44
+ """Convert MP3 to humanized MP3 with better sounds"""
45
  try:
46
+ # Load the MP3 with better analysis
47
  y, sr = librosa.load(mp3_path, sr=22050, mono=True)
48
  duration = len(y) / sr
49
 
50
+ # Create MIDI with better timing
51
  midi = pretty_midi.PrettyMIDI()
52
 
53
+ # Add enhanced instruments
54
+ for inst_info in self.style_presets[style]:
55
+ instrument = pretty_midi.Instrument(
56
+ program=inst_info["program"],
57
+ is_drum=inst_info["is_drum"],
58
+ name=inst_info["name"]
59
+ )
60
  midi.instruments.append(instrument)
61
 
62
+ # Extract musical elements from the audio
63
+ tempo, beats, melody_info = self.analyze_audio(y, sr)
64
 
65
+ # Create enhanced musical arrangement
66
+ self.create_enhanced_music(midi, y, sr, duration, style, intensity, tempo, beats, melody_info)
67
 
68
+ # Add advanced humanization
69
+ self.advanced_humanization(midi, intensity)
70
+
71
+ # Synthesize with better sound quality
72
  audio_data = midi.synthesize()
73
 
74
  return audio_data, sr
 
76
  except Exception as e:
77
  raise Exception(f"Conversion failed: {str(e)}")
78
 
79
+ def analyze_audio(self, y, sr):
80
+ """Enhanced audio analysis"""
81
+ try:
82
+ # Get tempo and beats
83
+ tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr, units='time')
84
+
85
+ # Detect melody using multiple methods
86
+ onset_frames = librosa.onset.onset_detect(y=y, sr=sr, hop_length=512, delta=0.1)
87
+ onset_times = librosa.frames_to_time(onset_frames, sr=sr, hop_length=512)
88
+
89
+ # Simple pitch detection for melody
90
+ melody_contour = []
91
+ for onset_time in onset_times[:20]: # Analyze first 20 onsets
92
+ start_idx = int(onset_time * sr)
93
+ end_idx = min(start_idx + int(0.3 * sr), len(y))
94
+ if end_idx > start_idx:
95
+ segment = y[start_idx:end_idx]
96
+ freq = self.detect_strongest_frequency(segment, sr)
97
+ if 100 < freq < 800:
98
+ melody_contour.append(freq)
99
+
100
+ return tempo, beat_frames, melody_contour
101
+
102
+ except:
103
+ # Fallback values
104
+ return 120, np.linspace(0, 10, 20), [440, 523, 659, 784] # A, C, E, G frequencies
105
+
106
+ def detect_strongest_frequency(self, segment, sr):
107
+ """Detect the strongest frequency in a segment"""
108
+ try:
109
+ # Apply windowing
110
+ window = np.hanning(len(segment))
111
+ segment_windowed = segment * window
112
+
113
+ # FFT analysis
114
+ fft = np.fft.rfft(segment_windowed)
115
+ freqs = np.fft.rfftfreq(len(segment_windowed), 1/sr)
116
+ mags = np.abs(fft)
117
+
118
+ # Find strongest frequency in vocal range
119
+ mask = (freqs > 80) & (freqs < 1000)
120
+ if np.any(mask):
121
+ peak_idx = np.argmax(mags[mask])
122
+ return freqs[mask][peak_idx]
123
+ except:
124
+ pass
125
+ return 440 # Default to A4
126
+
127
+ def create_enhanced_music(self, midi, y, sr, duration, style, intensity, tempo, beats, melody_contour):
128
+ """Create realistic musical arrangement"""
129
+ instruments = {inst.name: inst for inst in midi.instruments}
130
 
131
+ # Create better beat structure
132
+ if len(beats) > 0:
133
+ beat_times = beats[:min(32, len(beats))]
134
+ else:
135
+ beat_times = np.linspace(0, min(duration, 16), 16)
136
 
137
+ # Enhanced drum patterns
138
+ if "Drums" in instruments:
139
+ self.create_advanced_drums(instruments["Drums"], beat_times, style)
 
 
 
 
 
 
 
 
 
 
140
 
141
+ # Better bass lines
142
+ bass_instruments = [inst for inst in midi.instruments if not inst.is_drum and inst.program in [33, 34, 35, 36, 37, 38, 39]]
143
+ if bass_instruments:
144
+ self.create_melodic_bass(bass_instruments[0], beat_times, melody_contour)
 
 
 
145
 
146
+ # Realistic melody extraction and creation
147
+ melody_instruments = [inst for inst in midi.instruments if not inst.is_drum and inst.program not in range(32, 40)]
148
  if melody_instruments:
149
+ self.create_adaptive_melody(melody_instruments[0], y, sr, duration, melody_contour, style)
150
+
151
+ # Chordal accompaniment
152
+ chord_instruments = [inst for inst in midi.instruments if not inst.is_drum and inst not in bass_instruments and inst not in melody_instruments]
153
+ for inst in chord_instruments:
154
+ self.create_harmonic_background(inst, beat_times, style)
155
+
156
+ def create_advanced_drums(self, drums, beat_times, style):
157
+ """Create style-appropriate drum patterns"""
158
+ for i, time in enumerate(beat_times):
159
+ # Always add kick on beat 1
160
+ if i % 4 == 0:
161
+ drums.notes.append(self.create_note(36, 95, time, 0.3)) # Kick
162
+
163
+ # Style-specific snare patterns
164
+ if style == "rock" and i % 4 == 2:
165
+ drums.notes.append(self.create_note(38, 90, time, 0.25)) # Snare
166
+ elif style == "pop" and i % 4 in [2, 3]:
167
+ drums.notes.append(self.create_note(38, 85, time + 0.05, 0.2)) # Snare with offset
168
+ elif style == "electronic" and i % 2 == 1:
169
+ drums.notes.append(self.create_note(38, 80, time, 0.15)) # Electronic snare
170
+
171
+ # Hi-hat patterns
172
+ if style in ["pop", "electronic"]:
173
+ if i % 2 == 0: # Every other beat
174
+ drums.notes.append(self.create_note(42, 70, time, 0.1)) # Closed hi-hat
175
+ if style == "electronic" and i % 4 == 0:
176
+ drums.notes.append(self.create_note(46, 75, time + 0.2, 0.3)) # Open hi-hat
177
+
178
+ # Additional percussion
179
+ if style == "cinematic" and i % 8 == 0:
180
+ drums.notes.append(self.create_note(49, 80, time, 0.5)) # Crash cymbal
181
+
182
+ def create_melodic_bass(self, bass, beat_times, melody_contour):
183
+ """Create melodic bass lines that follow the music"""
184
+ if len(melody_contour) > 0:
185
+ # Use detected melody to create bass line
186
+ base_note = self.freq_to_midi(np.median(melody_contour)) - 12
187
+ bass_scale = [base_note, base_note + 2, base_note + 4, base_note + 5, base_note + 7]
188
+ else:
189
+ # Fallback bass scale
190
+ bass_scale = [36, 38, 41, 43, 48]
191
+
192
+ for i, time in enumerate(beat_times[::2]): # Every other beat
193
+ if i < len(bass_scale):
194
+ note_pitch = bass_scale[i % len(bass_scale)]
195
+ # Vary velocity for expression
196
+ velocity = 80 + (i % 3) * 10
197
+ bass.notes.append(self.create_note(note_pitch, velocity, time, 0.9))
198
+
199
+ def create_adaptive_melody(self, melody, y, sr, duration, melody_contour, style):
200
+ """Create melody that adapts to the original audio"""
201
+ if len(melody_contour) > 0:
202
+ # Use detected frequencies to create melody
203
+ for i, freq in enumerate(melody_contour[:16]): # Use first 16 detected frequencies
204
+ midi_note = self.freq_to_midi(freq)
205
+ if 48 <= midi_note <= 84: # Reasonable melody range
206
+ time = (i / len(melody_contour)) * min(duration, 8) # Spread over 8 seconds max
207
+ duration_val = 0.3 + (i % 3) * 0.2 # Vary note durations
208
+ melody.notes.append(self.create_note(midi_note, 75 + (i % 4)*5, time, duration_val))
209
+ else:
210
+ # Create melodic pattern based on style
211
+ if style == "pop":
212
+ melody_notes = [60, 64, 67, 72, 67, 64, 60, 65] # C major arpeggio
213
+ elif style == "electronic":
214
+ melody_notes = [65, 69, 72, 77, 72, 69, 65, 70] # F major with tension
215
+ elif style == "rock":
216
+ melody_notes = [59, 62, 65, 67, 65, 62, 59, 64] # B minor pentatonic
217
+ else: # cinematic
218
+ melody_notes = [60, 63, 67, 70, 67, 63, 60, 65] # C minor arpeggio
219
+
220
+ for i, note_pitch in enumerate(melody_notes):
221
+ time = (i / len(melody_notes)) * min(duration, 8)
222
+ melody.notes.append(self.create_note(note_pitch, 80, time, 0.5))
223
+
224
+ def create_harmonic_background(self, instrument, beat_times, style):
225
+ """Create chordal harmony"""
226
+ if style == "pop":
227
+ chords = [[60, 64, 67], [65, 69, 72], [67, 71, 74], [62, 65, 69]] # C, F, G, Am
228
+ elif style == "electronic":
229
+ chords = [[65, 69, 72], [70, 74, 77], [72, 76, 79], [67, 70, 74]] # F, Bb, C, Gm
230
+ elif style == "rock":
231
+ chords = [[59, 62, 65], [64, 67, 71], [65, 69, 72], [62, 65, 69]] # Bm, Em, F, Am
232
+ else: # cinematic
233
+ chords = [[60, 63, 67], [65, 68, 72], [67, 70, 74], [62, 65, 69]] # Cm, Fm, Gm, Ab
234
+
235
+ for i, time in enumerate(beat_times[::4]): # Every 4 beats
236
+ chord = chords[i % len(chords)]
237
+ for note_pitch in chord:
238
+ instrument.notes.append(self.create_note(note_pitch, 60, time, 2.0))
239
+
240
+ def freq_to_midi(self, frequency):
241
+ """Convert frequency to MIDI note number"""
242
+ return int(69 + 12 * np.log2(frequency / 440.0))
243
 
244
  def create_note(self, pitch, velocity, start, duration):
245
  """Helper to create a note"""
 
250
  end=start + duration
251
  )
252
 
253
+ def advanced_humanization(self, midi, intensity):
254
+ """Advanced humanization with more natural variations"""
255
  for instrument in midi.instruments:
256
+ # Different humanization for different instrument types
257
+ if instrument.is_drum:
258
+ humanization_factor = 0.8 # Less humanization for drums
259
+ elif instrument.program in range(32, 40): # Bass instruments
260
+ humanization_factor = 0.6
261
+ else: # Melody/harmony instruments
262
+ humanization_factor = 1.2
263
+
264
  for note in instrument.notes:
265
+ # Timing variations (different for different instruments)
266
+ timing_variation = np.random.normal(0, 0.03 * intensity * humanization_factor)
267
+ note.start = max(0, note.start + timing_variation)
268
 
269
+ # Velocity variations (more expressive)
270
+ vel_variation = np.random.normal(0, 12 * intensity * humanization_factor)
271
+ note.velocity = max(40, min(127, note.velocity + int(vel_variation)))
272
 
273
+ # Duration variations (except drums)
274
  if not instrument.is_drum:
275
+ dur_variation = np.random.normal(0, 0.08 * intensity * humanization_factor)
276
+ note.end = max(note.start + 0.1, note.end + dur_variation)
277
 
278
  def convert_mp3(input_mp3, style, intensity):
279
  """Main conversion function"""
280
  if input_mp3 is None:
281
  return None, "Please upload an MP3 file"
282
 
283
+ converter = AdvancedMP3Humanizer()
284
 
285
  try:
286
+ # Convert to humanized MP3 with better sounds
287
  audio_data, sr = converter.mp3_to_humanized_mp3(input_mp3, style, intensity)
288
 
289
  # Save as temporary MP3 file
 
295
  except Exception as e:
296
  return None, f"โŒ Error: {str(e)}"
297
 
298
+ # Enhanced interface
299
+ with gr.Blocks(theme=gr.themes.Soft(), title="Advanced MP3 Humanizer") as demo:
300
  gr.Markdown("""
301
+ # ๐ŸŽต Advanced MP3 Humanizer
302
+ **Transform AI Music into Realistic Human Performances**
303
+
304
+ *Now with better instrument sounds and realistic musical arrangements!*
305
  """)
306
 
307
  with gr.Row():
 
313
  label="Upload MP3 File"
314
  )
315
 
316
+ gr.Markdown("### 2. Choose Music Style")
317
  style = gr.Radio(
318
  ["pop", "electronic", "rock", "cinematic"],
319
  value="pop",
320
+ label="Select Style",
321
+ info="Each style uses different instruments and patterns"
322
  )
323
 
324
  intensity = gr.Slider(
325
  0.1, 1.0, value=0.7,
326
+ label="Human Feel Intensity",
327
+ info="Higher = more natural human variations"
328
  )
329
 
330
  convert_btn = gr.Button(
331
+ "๐ŸŽน Create Human Version",
332
  variant="primary",
333
  size="lg"
334
  )
335
 
336
  with gr.Column(scale=1):
337
+ gr.Markdown("### 3. Your Humanized Song")
338
  output_audio = gr.Audio(
339
+ label="Enhanced Human Version",
340
  type="filepath",
341
  interactive=False
342
  )
 
346
  interactive=False
347
  )
348
 
349
+ # Enhanced instructions
350
+ with gr.Accordion("๐ŸŽธ What's New in This Version", open=True):
351
  gr.Markdown("""
352
+ **Major Improvements:**
 
 
 
 
 
353
 
354
+ ๐Ÿฅ **Better Drum Patterns**: Style-specific rhythms with kicks, snares, hi-hats
355
+ ๐ŸŽธ **Real Bass Lines**: Melodic bass that follows the music
356
+ ๐ŸŽน **Adaptive Melodies**: Extracts and enhances melodies from your audio
357
+ ๐ŸŽป **Rich Harmony**: Chord progressions and background pads
358
+ ๐ŸŽ›๏ธ **Advanced Humanization**: Different variations for each instrument type
359
+
360
+ **Each style now includes:**
361
+ - **Pop**: Drums, Bass Guitar, Acoustic Guitar, Piano, Synth Voice
362
+ - **Electronic**: Electronic Drums, Synth Bass, Lead Synth, Warm Pad, Orchestral Hits
363
+ - **Rock**: Rock Drums, Electric Bass, Distortion & Clean Guitars, Strings
364
+ - **Cinematic**: Orchestral Drums, String Ensemble, French Horn, Electric Piano, Atmosphere
365
+
366
+ **How to use:**
367
+ 1. Upload your AI-generated MP3
368
+ 2. Choose the style that matches your music
369
+ 3. Adjust human feel (0.7 is recommended)
370
+ 4. Click convert and wait ~10 seconds
371
+ 5. Play the preview and download your enhanced MP3!
372
  """)
373
 
374
  # Conversion process
 
 
 
 
375
  convert_btn.click(
376
+ fn=convert_mp3,
377
  inputs=[input_audio, style, intensity],
378
  outputs=[output_audio, status]
379
  )