CornetAI / src /generadores /generador_maestro_midis.py
jmp684's picture
Upload 12 files
4f8d622 verified
import pretty_midi
import random
import os
# --- CONFIGURACIÓN ---
OUTPUT_FOLDER = "dataset_midis"
CANTIDAD_RITMICOS = 250
CANTIDAD_LEGATOS = 250
ALLOWED_PITCHES = [67, 68, 72, 73, 76]
def get_dynamic_level():
niveles = [
(45, 60), # Piano (Suave)
(65, 85), # Mezzoforte (Normal)
(90, 127), # Fortissimo (Fuerte)
]
# Se da más peso al Mezzoforte y Fortissimo, pero incluimos Piano
return random.choices(niveles, weights=[0.2, 0.5, 0.3])[0]
def get_next_stepwise(current_pitch):
idx = ALLOWED_PITCHES.index(current_pitch)
moves = []
if idx > 0: moves.append(idx - 1)
if idx < len(ALLOWED_PITCHES) - 1: moves.append(idx + 1)
return ALLOWED_PITCHES[random.choice(moves)]
def generar_ritmico(index):
pm = pretty_midi.PrettyMIDI()
inst = pretty_midi.Instrument(program=0, name="Corneta Ritmica")
current = 0.5
while current < 15.0:
# Cambio de dinámica cada cierto tiempo
min_v, max_v = get_dynamic_level()
# Frase de 4 a 8 notas con esa dinámica
notas_frase = random.randint(4, 8)
for _ in range(notas_frase):
pitch = random.choice(ALLOWED_PITCHES)
dur = random.choice([0.2, 0.4, 0.6]) # Staccato rápido
# Velocidad dentro del rango dinámico actual
vel = random.randint(min_v, max_v)
note = pretty_midi.Note(velocity=vel, pitch=pitch, start=current, end=current+dur)
inst.notes.append(note)
gap = random.uniform(0.1, 0.3)
current += dur + gap
if current > 15.0: break
# Silencio entre frases de distinta dinámica
current += random.uniform(0.5, 1.5)
pm.instruments.append(inst)
return pm
def generar_legato(index):
pm = pretty_midi.PrettyMIDI()
inst = pretty_midi.Instrument(program=0, name="Corneta Legato")
current = 0.5
while current < 14.0:
num_notas = random.randint(3, 6)
pitch = random.choice(ALLOWED_PITCHES)
# Elegir dinámica para toda la frase (ej. un solo piano)
min_v, max_v = get_dynamic_level()
for n in range(num_notas):
dur = random.uniform(1.2, 3.0) # Notas muy largas
start = current
end = current + dur + 0.05 # Solapamiento generoso para legato
# Pequeña variación humana dentro de la frase
vel = random.randint(min_v, max_v)
note = pretty_midi.Note(velocity=vel, pitch=pitch, start=start, end=end)
inst.notes.append(note)
current += dur
if n < num_notas - 1:
pitch = get_next_stepwise(pitch)
current += random.uniform(1.5, 2.5)
pm.instruments.append(inst)
return pm
if __name__ == "__main__":
if not os.path.exists(OUTPUT_FOLDER): os.makedirs(OUTPUT_FOLDER)
# Limpieza previa opcional (descomentar si quieres borrar los viejos)
# for f in os.listdir(OUTPUT_FOLDER): os.remove(os.path.join(OUTPUT_FOLDER, f))
print(f"--- Generando {CANTIDAD_RITMICOS + CANTIDAD_LEGATOS} archivos con Dinámicas ---")
for i in range(CANTIDAD_RITMICOS):
midi = generar_ritmico(i)
midi.write(os.path.join(OUTPUT_FOLDER, f"dinamico_ritmico_{i:03d}.mid"))
for i in range(CANTIDAD_LEGATOS):
midi = generar_legato(i)
midi.write(os.path.join(OUTPUT_FOLDER, f"dinamico_legato_{i:03d}.mid"))
print("Dataset generado.")