patchbanks commited on
Commit
7e5e13f
·
verified ·
1 Parent(s): 0309c1c

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -35
app.py CHANGED
@@ -129,44 +129,53 @@ def generate_midi(temperature, top_k):
129
 
130
  midi_events = round_bars
131
 
 
 
 
 
 
 
 
 
 
 
 
132
  return midi_events
133
 
134
 
135
- def write_midi(midi_events, bpm):
136
  midi_data = pretty_midi.PrettyMIDI(initial_tempo=bpm, resolution=96)
137
  midi_data.time_signature_changes.append(pretty_midi.containers.TimeSignature(4, 4, 0))
138
  instrument = pretty_midi.Instrument(0)
139
  midi_data.instruments.append(instrument)
140
 
141
- for sequence in midi_events:
142
- for event in sequence:
143
- pitch = event['pitch']
144
- velocity = event['velocity']
145
- start = midi_data.tick_to_time(event['start'])
146
- end = midi_data.tick_to_time(event['end'])
147
- note = pretty_midi.Note(pitch=pitch, velocity=velocity, start=start, end=end)
148
- instrument.notes.append(note)
149
 
150
  midi_path = os.path.join(temp_dir, 'output.mid')
151
  midi_data.write(midi_path)
152
  print(f"Generated: {midi_path}")
153
 
154
 
155
- def render_wav(midi_file, uploaded_sf2=None):
156
  sf2_dir = 'sf2_kits'
157
  audio_format = 's16'
158
  sample_rate = '44100'
159
- gain = '2.0'
160
 
161
  if uploaded_sf2:
162
  sf2_file = uploaded_sf2
163
  else:
164
- sf2_files = [f for f in os.listdir(sf2_dir) if f.endswith('.sf2')]
165
  if not sf2_files:
166
  raise ValueError("No SoundFont (.sf2) file found in directory.")
167
  sf2_file = os.path.join(sf2_dir, random.choice(sf2_files))
168
 
169
- print(f"Using SoundFont: {sf2_file}")
170
  output_wav = os.path.join(temp_dir, 'output.wav')
171
 
172
  with open(os.devnull, 'w') as devnull:
@@ -179,15 +188,15 @@ def render_wav(midi_file, uploaded_sf2=None):
179
  return output_wav
180
 
181
 
182
- def generate_and_return_files(bpm, temperature, top_k, uploaded_sf2=None):
183
  midi_events = generate_midi(temperature, top_k)
184
  if not midi_events:
185
  return "Error generating MIDI.", None, None
186
 
187
- write_midi(midi_events, bpm)
188
 
189
  midi_file = os.path.join(temp_dir, 'output.mid')
190
- wav_raw = render_wav(midi_file, uploaded_sf2)
191
  wav_fx = os.path.join(temp_dir, 'output_fx.wav')
192
 
193
  sfx_settings = [
@@ -213,40 +222,60 @@ def generate_and_return_files(bpm, temperature, top_k, uploaded_sf2=None):
213
 
214
 
215
  custom_css = """
 
 
 
 
 
 
 
 
 
216
  #generate-btn {
217
- background-color: #6366f1 !important;
218
- color: white !important;
219
- border: none !important;
220
- font-size: 16px;
221
- padding: 10px 20px;
222
- border-radius: 5px;
223
- cursor: pointer;
224
  }
 
225
  #generate-btn:hover {
226
- background-color: #4f51c5 !important;
 
 
 
 
227
  }
228
  """
229
 
230
- with gr.Blocks(css=custom_css, theme="soft") as iface:
231
- gr.Markdown("<h1 style='font-weight: bold; text-align: center;'>nanoMPC - AI Midi Drum Sequencer</h1>")
232
- gr.Markdown("<p style='text-align:center;'>nanoMPC is a tiny transformer model that generates MIDI drum beats inspired by Lo-Fi, Boom Bap and other styles of Hip Hop.</p>")
 
 
 
 
 
 
233
 
234
  with gr.Row():
235
  with gr.Column(scale=1):
236
- bpm = gr.Slider(minimum=50, maximum=200, step=1, value=90, label="BPM")
237
  temperature = gr.Slider(minimum=0.1, maximum=2.0, step=0.1, value=1.0, label="Temperature")
238
- top_k = gr.Slider(minimum=4, maximum=128, step=1, value=64, label="Top-k")
239
- soundfont = gr.File(label="Optional: Upload SoundFont (preset=0, bank=0)")
240
-
241
- with gr.Column(scale=1):
242
- midi_file = gr.File(label="MIDI File Output")
243
- audio_file = gr.Audio(label="Generated Audio Output", type="filepath")
244
  generate_button = gr.Button("Generate", elem_id="generate-btn")
 
245
 
246
  generate_button.click(
247
  fn=generate_and_return_files,
248
- inputs=[bpm, temperature, top_k, soundfont],
249
  outputs=[midi_file, audio_file]
250
  )
251
 
 
 
252
  iface.launch(share=True)
 
129
 
130
  midi_events = round_bars
131
 
132
+ # remove duplciates
133
+ for track in midi_events:
134
+ track.sort(key=lambda x: x['start'])
135
+ unique_notes = []
136
+
137
+ for note in track:
138
+ if not any(abs(note['start'] - n['start']) < 12 and note['pitch'] == n['pitch'] for n in unique_notes):
139
+ unique_notes.append(note)
140
+
141
+ track[:] = unique_notes
142
+
143
  return midi_events
144
 
145
 
146
+ def write_single_midi(midi_events, bpm):
147
  midi_data = pretty_midi.PrettyMIDI(initial_tempo=bpm, resolution=96)
148
  midi_data.time_signature_changes.append(pretty_midi.containers.TimeSignature(4, 4, 0))
149
  instrument = pretty_midi.Instrument(0)
150
  midi_data.instruments.append(instrument)
151
 
152
+ for event in midi_events[0]:
153
+ pitch = event['pitch']
154
+ velocity = event['velocity']
155
+ start = midi_data.tick_to_time(event['start'])
156
+ end = midi_data.tick_to_time(event['end'])
157
+ note = pretty_midi.Note(pitch=pitch, velocity=velocity, start=start, end=end)
158
+ instrument.notes.append(note)
 
159
 
160
  midi_path = os.path.join(temp_dir, 'output.mid')
161
  midi_data.write(midi_path)
162
  print(f"Generated: {midi_path}")
163
 
164
 
165
+ def render_wav(midi_file, uploaded_sf2=None, output_level='2.0'):
166
  sf2_dir = 'sf2_kits'
167
  audio_format = 's16'
168
  sample_rate = '44100'
169
+ gain = str(output_level)
170
 
171
  if uploaded_sf2:
172
  sf2_file = uploaded_sf2
173
  else:
174
+ sf2_files = [f for f in os.listdir(os.path.join(sf2_dir)) if f.endswith('.sf2')]
175
  if not sf2_files:
176
  raise ValueError("No SoundFont (.sf2) file found in directory.")
177
  sf2_file = os.path.join(sf2_dir, random.choice(sf2_files))
178
 
 
179
  output_wav = os.path.join(temp_dir, 'output.wav')
180
 
181
  with open(os.devnull, 'w') as devnull:
 
188
  return output_wav
189
 
190
 
191
+ def generate_and_return_files(bpm, temperature, top_k, uploaded_sf2=None, output_level='2.0'):
192
  midi_events = generate_midi(temperature, top_k)
193
  if not midi_events:
194
  return "Error generating MIDI.", None, None
195
 
196
+ write_single_midi(midi_events, bpm)
197
 
198
  midi_file = os.path.join(temp_dir, 'output.mid')
199
+ wav_raw = render_wav(midi_file, uploaded_sf2, output_level)
200
  wav_fx = os.path.join(temp_dir, 'output_fx.wav')
201
 
202
  sfx_settings = [
 
222
 
223
 
224
  custom_css = """
225
+ .gradio-container {
226
+ max-width: 1200px !important;
227
+ margin: 0 auto;
228
+ }
229
+
230
+ input[type="range"] {
231
+ background-image: linear-gradient(#7c4dff, #7c4dff);
232
+ }
233
+
234
  #generate-btn {
235
+ font-size: 18px;
236
+ padding: 10px 20px;
237
+ border-radius: 5px;
238
+ cursor: pointer;
239
+ background: linear-gradient(90deg, hsla(268, 90%, 68%, 1) 0%, hsla(260, 72%, 70%, 1) 50%, hsla(247, 73%, 65%, 1) 100%);
240
+ transition: background 1s ease;
 
241
  }
242
+
243
  #generate-btn:hover {
244
+ background: linear-gradient(90deg, hsla(268, 90%, 78%, 1) 0%, hsla(260, 72%, 80%, 1) 50%, hsla(247, 73%, 75%, 1) 100%);
245
+ }
246
+
247
+ #component-11 .download a {
248
+ font-size: 16px;
249
  }
250
  """
251
 
252
+ waveform_opts = gr.WaveformOptions(
253
+ waveform_color="#888888",
254
+ waveform_progress_color="#7c4dff",
255
+ trim_region_color="#7c4dff"
256
+ )
257
+
258
+ with gr.Blocks(css=custom_css, theme=gr.themes.Monochrome(font=gr.themes.GoogleFont("Roboto"))) as iface:
259
+ gr.Markdown("<h1 style='font-weight: bold; text-align: center; font-size: 40px; margin: 0px;'>nanoMPC</h1>")
260
+ gr.Markdown("<p style='text-align: center; font-size: 18px;'>nanoMPC is a MIDI transformer model that generates lo-fi and boom bap beats.</p>")
261
 
262
  with gr.Row():
263
  with gr.Column(scale=1):
264
+ bpm = gr.Slider(minimum=50, maximum=200, step=1, value=100, label="BPM")
265
  temperature = gr.Slider(minimum=0.1, maximum=2.0, step=0.1, value=1.0, label="Temperature")
266
+ top_k = gr.Slider(minimum=4, maximum=16, step=1, value=8, label="Top-k")
267
+ output_level = gr.Slider(minimum=0, maximum=3, step=0.10, value=2.0, label="Output Gain")
268
+ midi_file = gr.File(label="MIDI Output")
269
+ audio_file = gr.Audio(label="Audio Output", type="filepath", waveform_options=waveform_opts)
 
 
270
  generate_button = gr.Button("Generate", elem_id="generate-btn")
271
+ soundfont = gr.File(label="Optional: Upload SoundFont (preset=0, bank=0)")
272
 
273
  generate_button.click(
274
  fn=generate_and_return_files,
275
+ inputs=[bpm, temperature, top_k, soundfont, output_level],
276
  outputs=[midi_file, audio_file]
277
  )
278
 
279
+ gr.Markdown("<p style='text-align: center; font-size: 14px;'>Developed by <a href='https://www.patchbanks.com/' target='_blank'><strong>Patchbanks</strong></a></p>")
280
+
281
  iface.launch(share=True)