- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| output | ||
| .gitignore | ||
| acid_hat_pattern.py | ||
| acid_kick_pattern.py | ||
| BassAcid.py | ||
| BassAcid_Aggressive.py | ||
| BassAcid_Artists.py | ||
| BassAcid_Blade.py | ||
| BassAcid_GiveMeAcid.py | ||
| BassAcid_Rush.py | ||
| bitwig_config.json | ||
| CHANGELOG.md | ||
| generate_all.py | ||
| gui_generator.py | ||
| lead_pattern.py | ||
| LICENSE | ||
| midi_core.py | ||
| pad_pattern.py | ||
| README.md | ||
| README_BITWIG.md | ||
Bitwig Studio — Generador de Secuencias MIDI Acid Techno
Scripts que generan clips .mid de bajo ácido, bombo y hi-hats para Bitwig Studio (SMF formato 0, 480 PPQ). Tempos y tónicas son configurables; cada estilo de artista trae los suyos por defecto.
Cada script escribe el clip en dos sitios:
output/(local, organizado en subcarpetas por artistaoutput/<Artista>/para kits y patrones de artista).- Biblioteca de Bitwig (
.../Library/Clips/Acid_Sequences/, organizado enAcid_Sequences/<Artista>/para cada artista), visible al instante en el navegador lateral (Clips → Acid_Sequences).
El nombre depende de cómo generes:
- Scripts individuales:
YYYYMMDDHHMM_<nombre>.mid. Un archivo por script; si repites dentro del mismo minuto, se sobrescribe (útil para regenerar una toma). - Kits (
generate_all.pyy GUI):YYYYMMDDHHMM_<Set>_<NN>_<nombre>.mid. La etiqueta<Set>y el correlativo<NN>hacen que dos kits del mismo minuto nunca compartan archivo, y se guardan dentro de la carpeta del artista (output/<Artista>/yAcid_Sequences/<Artista>/). Cada kit incluye por omisión 10 pistas: bajo, bombo específico del artista, hats, rush, patrón del artista, pad para ReplicantWave y lead para ReplicantWave (con su snippet.txtde 64 pasos para el secuenciador).
Scripts
| Script | Genera |
|---|---|
BassAcid_GiveMeAcid.py |
Give Me Acid (Marie Vaunt & A*S*Y*S @ 135 BPM): Peak-Time / Driving Acid Techno. 4 variaciones (driving_lead, call_response, squelch_roller, climax_drop), slides 303 legato, afinación en Si♭ (Bb2/46) y acentos con filtro abierto. |
BassAcid.py |
Rolling 303 clásico: pentatónica menor en Re, huecos en el beat para el kick, acentos y slides. Fill en el compás 4. |
BassAcid_Aggressive.py |
Hard Acid (Marie Vaunt / Verknipt): frigio y tritono, acentos extremos, screams de doble octava (+24) y fill ametralladora. |
BassAcid_Blade.py |
Blade (16 notas): un compás con 16 semicorcheas sin huecos, al estilo del acid techno de Blade (1998) / New Order – "Confusion" (Pump Panel Reconstruction Mix). Acentos en los 4 pulsos, stabs de octava y quinta con slide, espiral ascendente final. |
BassAcid_Rush.py |
KI/KI @ Elementenstraat: 4 variaciones (rolling, melodic_hook, octave_screamer, climax_drop), galopes de 16ths y rebotes de octava. |
BassAcid_Artists.py |
12 estilos de artistas Acid / Hard: Dax J, Chris Liebing, 999999999, Sara Landry, I Hate Models, Amelie Lens, Charlotte de Witte, Boston 168, Reinier Zonneveld, T78, Hardfloor y Klangkuenstler. Cada estilo trae BPM y tónica sugeridos y un motor rítmico propio. |
pad_pattern.py |
Pads para ReplicantWave: 7 texturas de acordes sostenidos (matrix_dark, synthetic_tears, neon_rain, corpo_cathedral, cryo_sleep, ghost_choir, braindance_memory) con voicings, extensiones y voz interna. |
lead_pattern.py |
Leads para ReplicantWave: 8 líneas monofónicas (neon_blade, sync_screamer, razor_lead, laser_katana, neon_samurai, combat_lead, void_screamer, extra_terra) con slides, y export al secuenciador interno de 64 pasos. |
acid_kick_pattern.py |
Kick Hard Techno de 4 compases: fraseo evolutivo, humanización, ghost/rumble y 6 estilos (ver abajo). |
acid_hat_pattern.py |
Hi-Hats Rave: offbeats abiertos, galope de semicorcheas con swing y redobles en compases 2 y 4. |
generate_all.py |
Generador maestro: el kit completo de 10 pistas por omisión (incluyendo Pad y Lead para ReplicantWave con snippet de 64 pasos), organizado en una carpeta por artista (output/<Artista> y Acid_Sequences/<Artista>). |
gui_generator.py |
GUI (tkinter): selectores de estilo de bajo, artista Acid/Hard, pad y lead con auto-ajuste de BPM/tónica, botones por patrón, kit completo y carpeta de Clips. |
Diagrama de flujo
Cómo se elige una ruta de generación y qué ocurre desde que lanzas un script hasta que el clip suena en Bitwig:
flowchart TD
start(["Ejecutas el generador"]) --> pick{"¿Qué quieres generar?"}
pick -->|"Un patrón"| single["Script individual<br/>BassAcid*.py<br/>kick · hats"]
pick -->|"El kit completo"| kit["generate_all.py"]
pick -->|"Con ratón"| gui["gui_generator.py"]
single --> artist{"¿Bajo de artista?"}
artist -->|"Sí"| artists["BassAcid_Artists.py<br/>12 estilos"]
artist -->|"No"| params
artists --> params
kit --> params
gui --> params
params["Parámetros<br/>--bpm · --root<br/>--bars · --seed"]
params --> grid["Rejilla de 16 semicorcheas<br/>nota · acento · slide · gate"]
grid --> engine["Firma rítmica del artista<br/>esqueleto A / B<br/>frase · acentos · gate"]
engine --> overlap["resolve_same_pitch_overlaps()<br/>acorta slides solapados"]
overlap --> writer["midi_core escribe<br/>SMF 0 · 480 PPQ"]
writer --> local[("output/ local")]
writer --> library[("Biblioteca de Bitwig<br/>Clips/Acid_Sequences")]
local --> drag["Arrastrar el .mid<br/>a una pista"]
library --> drag
drag --> synth["Sintetizador 303<br/>ABL3 · Phoscyon · Acid V"]
synth --> sound(["Suena el patrón"])
Arquitectura del código (qué módulo llama a cuál):
flowchart LR
subgraph entrada["Puntos de entrada"]
direction TB
cli["Scripts CLI"]
master["generate_all.py"]
app["gui_generator.py"]
end
subgraph motores["Generadores de patrón"]
direction TB
bajos["Bajos 303<br/>BassAcid · Rush<br/>GiveMeAcid<br/>Artists · Blade<br/>+ Aggressive"]
ritmo["Ritmo<br/>acid_kick_pattern<br/>acid_hat_pattern"]
synth["ReplicantWave<br/>pad_pattern<br/>lead_pattern"]
end
core["midi_core.py<br/>MidiSequence · MidiTrack<br/>resolve_same_pitch_overlaps"]
cli --> motores
master --> motores
app --> motores
bajos --> core
ritmo --> core
synth --> core
synth --> seq["Export 64 pasos<br/>(fragmento Rust)"]
core --> out[(".mid local +<br/>biblioteca Bitwig")]
Rutas de decisión rápidas:
- ¿Una sola idea? → script individual con
--style,--bpm,--rooty--seed. - ¿Buscas el sonido de un artista? →
BassAcid_Artists.py --style <clave>(o--list). - ¿Sesión completa para improvisar? →
generate_all.py(añade--artist-style allpara 19 clips). - ¿Prefieres no tocar la terminal? →
gui_generator.py.
Uso
GUI (recomendado)
python3 gui_generator.py
Kit completo
python3 generate_all.py
python3 generate_all.py --bpm 155 --root 50 --kick-style stutter --variations 3
python3 generate_all.py --artist-style all --bpm 150 --root 45 # añade los 12 artistas
python3 generate_all.py --pad-style all --lead-style all # añade 7 pads + 8 leads
python3 generate_all.py --pad-style matrix_dark --lead-style sync_screamer
python3 generate_all.py --no-artist # solo el kit base de 7 clips
python3 generate_all.py --artist-style dax_j --set-name DaxJ_145 # etiqueta de set a medida
Patrones individuales
python3 BassAcid_GiveMeAcid.py --style all --root Bb2 --bpm 135 # pack de 4 variaciones Give Me Acid
python3 BassAcid.py --bpm 155 --root 50
python3 BassAcid_Aggressive.py --bpm 155 --root 50
python3 BassAcid_Blade.py --bpm 155 --root 50
python3 BassAcid_Rush.py --style all --root F3 --bpm 153 # pack de 4 variaciones
python3 BassAcid_Artists.py --list # catálogo de artistas
python3 BassAcid_Artists.py --style dax_j # 145 BPM, C3
python3 BassAcid_Artists.py --style 999999999 --root G2 --bpm 150
python3 BassAcid_Artists.py --style all # pack de 12 estilos
python3 acid_kick_pattern.py --style hybrid --bars 4 --bpm 155
python3 acid_hat_pattern.py --bpm 155 --note 42 # 42 = F#1 closed hat
python3 pad_pattern.py --list # catálogo de pads
python3 pad_pattern.py --style cryo_sleep --bars 8
python3 pad_pattern.py --style all # pack de 7 pads
python3 lead_pattern.py --list # catálogo de leads
python3 lead_pattern.py --style sync_screamer --replicantwave
python3 lead_pattern.py --style all # pack de 8 leads
Estilos de artistas (BassAcid_Artists.py / midi_core.py)
Perfiles rítmicos investigados en YouTube a partir de temas clave y sets en vivo de cada
artista, centralizados en ARTIST_RHYTHM_PROFILES dentro de midi_core.py.
La diferencia entre estilos no es la tónica: cada artista tiene su subdivisión rítmica
propia (dónde golpea, qué pasos calla para el bombo, ligaduras de varios pasos _, ratchets
de fusa 1/32 r, duración de gate, swing y frase de 4 compases). Además, al generar un kit
completo asociado a un artista (generate_all.py --artist-style <clave> o desde la GUI),
midi_core.py imprime variantes complementarias del ritmo de ese artista sobre las pistas
compañeras del kit (01..07) para que dos sets de artistas distintos nunca compartan el
mismo patrón cambiando solo la nota raíz.
| Clave | Artista | Bajo compás A | Kick compás A | Frase | BPM | Raíz | Referencia YouTube |
|---|---|---|---|---|---|---|---|
dax_j |
Dax J | X·xX·xX·xX·xX·s· |
X··gX·g·X··gX·gx |
ABAB | 144 | C3 (48) | Speedball / Universal Future (Monnom Black) |
chris_liebing |
Chris Liebing | ·X··x·X··x·X··x· |
X···X··gX···X··x |
ABAB | 133 | A2 (45) | Aufbau / CLR Modular & Maschine Hybrid Live |
999999999 |
999999999 | Xr·x··r·X·r··x·r |
Xr·xX··rXr·xX··r |
AABB | 148 | G2 (43) | 300000003 / 000000005 / Awakenings Hardware Live |
sara_landry |
Sara Landry | ·gxX·gxX·gxX·gxX |
XggxXggxXggxXggx |
ABBA | 152 | A2 (45) | Legacy / Peer Pressure (Hekate / Verknipt) |
i_hate_models |
I Hate Models | X_·x_·s___·X_·x_ |
X_··X_··X·X_·x·· |
ABAB | 144 | E2 (40) | Daydream / Werewolf Disco Club |
amelie_lens |
Amelie Lens | ··X···X···X···X· |
X·g·X·g·X·g·X·g· |
AABB | 138 | A2 (45) | Exhale / Higher (Lenske) |
charlotte_de_witte |
Charlotte de Witte | Xx···xx·Xx··xx·· |
X_g·X_··X_g·X_·· |
ABAB | 138 | G2 (43) | Overdrive / Doppler / Sgadi Li Mi (KNTXT) |
boston_168 |
Boston 168 | X___···s___···x_ |
X__···g·X__····g |
ABBB | 126 | E2 (40) | Oblivion (Odd Even, 126 BPM, E Minor) |
reinier_zonneveld |
Reinier Zonneveld | xX·xxX·xxX·xxX·x |
Xx··Xx··Xx··Xx·g |
AABB | 146 | G2 (43) | Hard Gaan / Acid Octopus (Filth on Acid) |
t78 |
T78 | Xxx·x·······X·s· |
X··xX···X·····x· |
ABAB | 132 | A2 (45) | Acid Lick / Megator (Autektone) |
hardfloor |
Hardfloor | x·s_x·x·s_x·xXs· |
X··X··x·X·x·X··· |
AAAB | 136 | F#2 (42) | Acperience 1 (Harthouse 1992) |
klangkuenstler |
Klangkuenstler | ··x·r··X·r·X··r· |
X··r··x·X··r·x·r |
ABAB | 150 | F#2 (42) | Weltschmerz / Deine Angst (Outworld) |
Símbolos de la firma: X acento, x nota normal, g fantasma, s slide (acento + legato),
_ ligadura (prolonga la nota anterior +1 semicorchea), r ratchet 1/32 (doble golpe de
fusa dentro del paso) y · silencio. Cada artista tiene dos compases (A y B), motivos
melódicos deterministas (motif_a / motif_b) y un orden de frase (ABAB, AABB, ABBA,
AAAB, ABBB), más un turnaround propio en el último tiempo del compás 4.
Motor único en midi_core.py. Los 12 estilos y la adaptación rítmica de kits pasan por
render_skeleton_bar(), build_artist_rhythm_events() e imprint_artist_rhythm() en
midi_core.py. Las firmas se validan al importar el módulo con
validate_rhythm_signature().
Verificar que no se parecen. --report mide la similitud rítmica de los 12 estilos
entre sí sobre el loop de 4 compases (ataques 1/16 y 1/32, acentos y subdivisión/gate):
python3 BassAcid_Artists.py --report
Máxima similitud: 0.491 | Media: 0.274
Ningún par comparte el mismo ritmo.
Firmas rítmicas únicas: 12 de 12 estilos
Densidad del catálogo: 0.19 - 0.75 (10 niveles distintos)
La semilla cambia variaciones secundarias y micro-timing, no los ataques: la identidad
rítmica de cada artista es estable entre tomas (--seed reproduce una toma concreta).
En el pack independiente (--style all) y al invocar generate_all.py --artist-style <clave>
sin forzar --bpm/--root, cada artista usa su BPM, tónica y estilo de kick investigados.
Pads y leads para ReplicantWave
Los dos generadores están pensados para el sintetizador de PROCESOS/ReplicantWave
(16 voces, presets en src/presets/factory.rs). Cada estilo indica el preset con el
que se lleva mejor:
Pads (pad_pattern.py) — acordes sostenidos de 8 compases, gate 1.0 (legato), crescendo
opcional y una voz interna que entra a mitad de compás.
| Clave | Preset | Voicing | BPM | Raíz |
|---|---|---|---|---|
matrix_dark |
Arasaka Matrix Pad | wide | 90 | C3 (48) |
synthetic_tears |
Synthetic Tears Pad | close | 76 | A2 (45) |
neon_rain |
Neon Rain Pad | stacked | 84 | D3 (50) |
corpo_cathedral |
Corpo Cathedral | open_fifths | 60 | E3 (52) |
cryo_sleep |
Cryo Sleep Pad | bass_octave | 66 | G2 (43) |
ghost_choir |
Ghost Protocol Choir | stacked | 72 | F3 (53) |
braindance_memory |
Braindance Memory | wide | 80 | Bb2 (46) |
Voicings: close (fundamental + octava), wide (grave + resto una 8ª arriba), stacked
(coral), open_fifths (sin tercera), bass_octave (con sub). Todas las voces son
diatónicas de la menor natural: la voz interna se omite en los compases donde chocaría.
Leads (lead_pattern.py) — línea monofónica de 4 compases con slides (gate > 1.0)
y acentos por velocidad.
| Clave | Preset | BPM | Raíz |
|---|---|---|---|
neon_blade |
Neon Blade 2049 | 100 | C4 (60) |
sync_screamer |
Overclocked Sync Screamer | 140 | A3 (57) |
razor_lead |
Nightside Razor Lead | 128 | G3 (55) |
laser_katana |
Laser Katana | 150 | C4 (60) |
neon_samurai |
Neon Samurai Lead | 104 | D4 (62) |
combat_lead |
Cyberpunk 2077 Combat Lead | 132 | C4 (60) |
void_screamer |
Void Screamer Lead | 96 | A3 (57) |
extra_terra |
Extra Terra Cyber Lead | 128 | C4 (60) |
Export al secuenciador interno. Con --replicantwave, el lead se traduce a los 64
pasos del sintetizador y se escribe un fragmento Rust listo para pegar en
src/presets/factory.rs:
python3 lead_pattern.py --style sync_screamer --replicantwave
# -> output/...._Lead_ReplicantWave_Sync_screamer_ReplicantWaveSeq.txt
// Overclocked Sync Screamer - exportado por lead_pattern.py
// seq_length = 16, seq_rate = 3 (1/16), seq_swing = 0.0
let seq = create_default_steps(&[
( 0, 104, true , false, false),
( 12, 127, true , true , true ),
...
]);
El secuenciador es monofónico y su paso es un offset de −24..+24 semitonos, así que el export cuantiza a semicorcheas (o fusas si el motivo las usa), colapsa notas simultáneas y avisa de recortes. Los pads no se exportan: son acordes y el secuenciador toca una nota por paso, así que se usan como clip MIDI sobre los presets Pad.
Estilos de kick (--kick-style en el kit / --style individual)
hybrid(default) — evolución de 4 compases: base, síncopa, tensión máxima y redoble en fusas.rolling— sub-kick continuo en semicorcheas (rolling bassline).syncopated— bombos dobles en contratiempos con cross-accents.stutter— ráfagas de fusas (estilo Verknipt / Klangkuenstler).offbeat_push— bombos en las corcheas a contratiempo.predrop_break— compases 1-3 a tope y silencio en los 2 últimos tiempos del compás 4.
Nombres de archivo y sets
Los scripts individuales siguen con YYYYMMDDHHMM_<nombre>.mid. Los kits añaden
etiqueta de set y correlativo:
202611031607_DaxJ_01_BassAcid_GiveMeAcid_Driving_lead.mid
202611031607_DaxJ_02_BassAcid_Rolling_303.mid
...
202611031607_DaxJ_08_BassAcid_Artist_DaxJ.mid
202611031607_999999999_01_BassAcid_GiveMeAcid_Driving_lead.mid # otro artista, mismo minuto
202611031607_DaxJ_09_BassAcid_GiveMeAcid_Driving_lead.mid # mismo set otra vez: bloque 09-16
La etiqueta se deriva del artista (--artist-style dax_j → DaxJ), y se puede forzar con
--set-name. El correlativo es del set, no del archivo: se reserva un bloque contiguo
al vuelo y se salta cualquier índice ya ocupado, así que
- dos artistas distintos pueden generar en el mismo minuto sin pisarse (espacios de nombres separados por la etiqueta);
- el mismo set repetido en el mismo minuto abre un bloque nuevo en lugar de sobrescribir;
- si se agotan los 99 correlativos de ese minuto con esa etiqueta, el generador falla con un error explícito en vez de reutilizar nombres.
Raíz y nomenclatura de notas
--root (y --note) acepta número MIDI o nombre de nota, con C4 = 60 (Do central): 50 = D3 = D-3.
La raíz por defecto es MIDI 50 = D3, afinada con el kick en Re.
Carpeta de Clips (multiplataforma)
Se resuelve por SO desde bitwig_config.json, sin conflictos al sincronizar entre máquinas:
| SO | Ruta por defecto |
|---|---|
| macOS | ~/Documents/Bitwig Studio/Library/Clips/Acid_Sequences/ |
| Linux | ~/Bitwig Studio/Library/Clips/Acid_Sequences/ (o ~/Documents/... si existe) |
| Windows | ~/Documents/Bitwig Studio/Library/Clips/Acid_Sequences/ |
Para cambiarla: botón "Cambiar…" en la GUI, python3 generate_all.py --configure, o --clips-dir "/ruta".
Cómo usar los clips en Bitwig
- Navegador lateral → Clips / My Library → Acid_Sequences.
- Arrastra el
.mida una pista de instrumento (Arranger o Clip Launcher).
Slides y acentos 303
- Slides: se codifican como solapamiento legato (>100% del paso). En sintes como ABL3, Phoscyon 2, Arturia Acid V, Roland TB-303 o Polymer (mono + Glide) activan el portamento.
- Acentos: por velocidad MIDI (p. ej. 127 acento, ~80-100 normal, ~54-76 fantasma, según el patrón).
Notas técnicas
- Dependencias: solo la librería estándar de Python 3 (
midi_core.pyno importa nada externo); la GUI necesitatkinter. - Salida MIDI: SMF formato 0, una pista, 480 PPQ, canal 1 (índice 0).
- Config perezosa: importar
midi_coreno lee ni escribebitwig_config.json; la ruta se resuelve al usarla. - Aleatoriedad: los scripts de bajo (
BassAcid.py,BassAcid_Aggressive.py,BassAcid_Blade.py,BassAcid_Rush.py,BassAcid_GiveMeAcid.py,BassAcid_Artists.py) generan una variación distinta en cada ejecución. Usa--seed <n>para reproducir una toma concreta (enBassAcid_Artists.py, el pack--style allderiva una semilla por estilo). - Solapes de mismo pitch: todos los generadores pasan por
resolve_same_pitch_overlaps()demidi_core.py. Un gate de slide 303 (> 1.0) ya no puede hacer que el Note-Off de una nota silencie la siguiente del mismo tono. - Duración de notas:
MidiTrack.add_note()fuerza duración mínima de 1 tick; la humanización nunca desplaza una nota por debajo del tick 0. - Pads y leads:
pad_pattern.pyylead_pattern.pyson deterministas salvo la velocidad (±3) y el micro-timing del lead (±2 ticks, desactivable con--no-humanize). Pasa--seedpara congelar una toma. El export--replicantwavese calcula siempre sin humanización, sobre una sola frase, para que coincida con la rejilla del secuenciador.
Cambios recientes
El detalle completo está en CHANGELOG.md. Resumen de la última entrega:
- Nuevo
pad_pattern.pyylead_pattern.py: 7 pads y 8 leads alineados con los presets Pad y Lead de ReplicantWave, más export del lead al secuenciador interno de 64 pasos como fragmento Rust. - Integrado en
generate_all.py(--pad-style,--lead-style) y en la GUI (selectores con auto-ajuste de BPM/tónica y botones propios). El kit completo llega a 34 pistas. - Corregido el
add9mayor sobre tónica menor y la voz interna que chocaba con los acordes mayores: todas las voces de los pads son ahora diatómicas. - Corregido el export al secuenciador, que duplicaba pasos al incluir la humanización.
Entrega anterior:
- Nuevo
BassAcid_Artists.py: 12 estilos inspirados en Dax J, Chris Liebing, 999999999, Sara Landry, I Hate Models, Amelie Lens, Charlotte de Witte, Boston 168, Reinier Zonneveld, T78, Hardfloor y Klangkuenstler, con 7 motores rítmicos. - Integrado en
generate_all.py(--artist-style) y en la GUI (selector con auto-ajuste de BPM/tónica). - Corregido el solape de slides 303 del mismo pitch, que silenciaba la nota siguiente.
- Corregido el solape de hi-hats entre rolling y redobles.
- Añadido
midi_to_note_name()y raíces por nombre en la GUI (Bb2,F#2).