Spaces:
Running on Zero
Running on Zero
File size: 4,448 Bytes
ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 ef8bde4 495ab46 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #!/usr/bin/env python3
"""Trap Style MIDI Transformer"""
import pretty_midi as pm
import numpy as np
import random
from pathlib import Path
class TrapTransformer:
def __init__(self, bpm=140):
self.bpm = bpm
self.beat_duration = 60.0 / bpm
def extract_bass_notes(self, midi_data):
"""Pull low notes that can become 808s"""
bass_notes = []
for track in midi_data.instruments:
if track.is_drum:
continue
for note in track.notes:
if note.pitch < 48: # Below C3
bass_notes.append(note)
return bass_notes
def create_808_bass(self, bass_notes, duration_seconds):
"""Longer sustain + louder = 808 feel"""
enhanced = []
for note in bass_notes:
new_note = pm.Note(
velocity=min(note.velocity + 20, 127),
pitch=note.pitch,
start=note.start,
end=min(note.end + 0.3, duration_seconds),
)
enhanced.append(new_note)
return enhanced
def add_hi_hats(self, duration_seconds):
"""Fast hi-hat rolls (trap signature)"""
hat_track = pm.Instrument(program=0, is_drum=True, name="HiHats")
t = 0.0
while t < duration_seconds:
step = self.beat_duration / 4 # 1/16 notes
if random.random() < 0.3: # 30% chance → roll
rolls = random.choice([4, 8])
for i in range(rolls):
hat_track.notes.append(
pm.Note(
velocity=random.randint(80, 120),
pitch=42,
start=t + (i * step / rolls),
end=t + ((i + 1) * step / rolls),
)
)
else:
hat_track.notes.append(
pm.Note(
velocity=random.randint(90, 115),
pitch=42,
start=t,
end=t + step * 0.5,
)
)
t += step
return hat_track
def add_trap_drums(self, duration_seconds):
"""Half-time kicks + snares"""
drum_track = pm.Instrument(program=0, is_drum=True, name="TrapDrums")
bar = self.beat_duration * 2 # Half-time bar
num_bars = int(duration_seconds / bar)
for b in range(num_bars):
kick_t = b * bar
snare_t = b * bar + self.beat_duration # Snare on beat 3 (half-time)
drum_track.notes.append(
pm.Note(velocity=120, pitch=36, start=kick_t, end=kick_t + 0.1)
)
drum_track.notes.append(
pm.Note(velocity=110, pitch=38, start=snare_t, end=snare_t + 0.08)
)
return drum_track
def apply_sidechain(self, midi_data, kick_times):
"""Simulate sidechain pump — duck melody before kicks"""
for instrument in midi_data.instruments:
if instrument.is_drum:
continue
for note in instrument.notes:
for kt in kick_times:
if note.start <= kt <= note.end:
note.velocity = max(1, note.velocity - 10)
return midi_data
def transform_to_trap(self, input_midi_path, output_midi_path=None):
"""Main: transform any MIDI → Trap"""
midi_data = pm.PrettyMIDI(str(input_midi_path))
duration = midi_data.get_end_time()
# Enhance existing bass
bass_notes = self.extract_bass_notes(midi_data)
enhanced_bass = self.create_808_bass(bass_notes, duration)
# Add new drum + hat tracks
hat_track = self.add_hi_hats(duration)
drum_track = self.add_trap_drums(duration)
# Sidechain
kick_times = [n.start for n in drum_track.notes if n.pitch == 36]
midi_data = self.apply_sidechain(midi_data, kick_times)
# Append trap layers
midi_data.instruments.append(hat_track)
midi_data.instruments.append(drum_track)
# Set tempo
try:
for tempo_change in midi_data._tempo_changes:
tempo_change.tempo = self.bpm
except Exception:
pass
if output_midi_path:
midi_data.write(str(output_midi_path))
return midi_data |