Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
ea800e4
feat: vertical without Twitch, and Enhanced Broadcasting on the GPU
Soulhackzlol Sep 24, 2026
2a4eed6
release: 0.1.15
Soulhackzlol Sep 24, 2026
82bae0e
docs: the test count is 408
Soulhackzlol Sep 24, 2026
b88bf6a
wip: crash protection groundwork
Soulhackzlol Sep 24, 2026
086c20b
Merge fix/vertical-without-twitch into feature/crash-protection
Soulhackzlol Sep 24, 2026
1f65fc0
feat: crash protection, and H.264 tracks from Twitch when multistreaming
Soulhackzlol Sep 25, 2026
3d1fbde
fix: Twitch Dual Format's vertical track reaches vertical destination…
Soulhackzlol Sep 25, 2026
9cdf7e8
fix: find the vertical track from the EB config, and leave Twitch's c…
Soulhackzlol Sep 25, 2026
30cd2e6
feat: three more reconnect screen styles and a clearer settings card
Soulhackzlol Sep 25, 2026
2b0cb03
perf: crash protection preview in one request, animated by CSS
Soulhackzlol Sep 25, 2026
8a371d3
chore: remove dead dashboard code and a per-tag format with tracing off
Soulhackzlol Sep 25, 2026
9f8b4dd
feat: System organized by topic, with setting search and a save bar
Soulhackzlol Sep 25, 2026
4e52d86
fix: style thumbnails after a reload, a smooth 24-frame preview, ligh…
Soulhackzlol Sep 25, 2026
0503b6e
feat: motion that guides the eye, and destination cards that explain …
Soulhackzlol Sep 25, 2026
1c77833
feat: command palette, a readable event log, and a friendly empty Des…
Soulhackzlol Sep 25, 2026
bbd1e0d
revert: drop the command palette
Soulhackzlol Sep 25, 2026
423643c
feat: platform logos, the signal path, sharper type, and idle screens
Soulhackzlol Sep 25, 2026
8dc495b
feat: a richer aurora that follows the stream state, and lit surfaces
Soulhackzlol Sep 25, 2026
9f15c29
feat: a roomier, responsive destination editor
Soulhackzlol Sep 25, 2026
d4b5b70
feat: animated fields, dropdowns and hovers that follow the aurora
Soulhackzlol Sep 25, 2026
b93c734
docs: accurate changelog wording for the tint
Soulhackzlol Sep 25, 2026
1c01b50
fix: keep a fresh EB session OBS asks for during a crash-protection hold
Soulhackzlol Sep 25, 2026
a028273
fix: reserve the pane scrollbar's room so tabs don't shift
Soulhackzlol Sep 25, 2026
07e16c1
fix: clicking the open tab no longer replays its animation
Soulhackzlol Sep 25, 2026
17a5a04
perf: incremental log view; merge duplicated CSS; drop dead code
Soulhackzlol Sep 25, 2026
7396cfc
fix: bug-hunt round across crash protection, EB, the slate and the da…
Soulhackzlol Sep 26, 2026
e28ce7a
fix: delay engine, EB fallback and hardening for 0.1.15
Soulhackzlol Sep 27, 2026
c1c0c13
feat(dashboard): delay panel and readout motion, flowing aurora
Soulhackzlol Sep 27, 2026
159d57e
docs: 0.1.15 changelog and README updates
Soulhackzlol Sep 27, 2026
fe36d89
fix: engine review for 0.1.15
Soulhackzlol Sep 28, 2026
a78df84
feat(dock): mid-stream pass; fix stuck bitrate and hover tint
Soulhackzlol Sep 28, 2026
d0a360e
fix(vod-script): VOD track dropped when Enhanced Broadcasting is off
Soulhackzlol Sep 29, 2026
fb1f36b
chore: 0.1.15-rc.1
Soulhackzlol Sep 29, 2026
98df4ed
ci(release): install ffmpeg for the Linux test job
Soulhackzlol Sep 29, 2026
8e3b8ab
docs(changelog): point the VOD script re-download at its new System tab
Soulhackzlol Sep 29, 2026
e7174fa
docs(changelog): credit adTexaz for the VOD script report
Soulhackzlol Sep 29, 2026
7e09a75
feat(integrations): engine, Twitch chat, catalog and API
Soulhackzlol Sep 30, 2026
14fb12c
feat(integrations): the Integrations tab, and working Discord TLS
Soulhackzlol Sep 30, 2026
6f123fd
fix(integrations): scan for bugs, edge cases and rough UX
Soulhackzlol Sep 30, 2026
473d63b
feat(integrations): smooth, polished UI and leak fixes
Soulhackzlol Oct 1, 2026
d76504d
feat(integrations): use your own Twitch app from System
Soulhackzlol Oct 1, 2026
b14c32b
feat(integrations): try API requests in the builder, undo, back, hidd…
Soulhackzlol Oct 1, 2026
cfb3f97
feat(integrations): pick how an integration starts, visually
Soulhackzlol Oct 1, 2026
0597416
feat(integrations): premium motion details
Soulhackzlol Oct 1, 2026
3164170
feat(integrations): "Command from a website", with bot command import
Soulhackzlol Oct 1, 2026
f58db94
feat(integrations): hotkeys, on-stream alerts, live Discord messages
Soulhackzlol Oct 1, 2026
23cce20
fix(integrations): deep scan, security, crash and phone layout fixes
Soulhackzlol Oct 1, 2026
b1e2346
fix(integrations): Twitch refusals, late flap alerts, MIDI pads on an…
Soulhackzlol Oct 1, 2026
fe6cbf2
fix(integrations): catalog tiles no longer clip, quieter Add buttons
Soulhackzlol Oct 2, 2026
91fda60
feat(integrations): delay arming events, clearer builder, experimenta…
Soulhackzlol Oct 2, 2026
8470ee3
release: 0.1.15 - integrations ready to ship, delay tail, release rev…
Soulhackzlol Oct 4, 2026
3e77921
feat(integrations): import preview shows every step and the raw settings
Soulhackzlol Oct 4, 2026
d2472b2
polish(integrations): import preview as cards with smooth folds
Soulhackzlol Oct 4, 2026
5f0dec2
fix: release review round 2 (freeze floor, program lock, overlay sand…
Soulhackzlol Oct 4, 2026
2e17b75
fix: release review round 3 (self-requests, Studio, long freezes)
Soulhackzlol Oct 4, 2026
0529eaa
fix(dashboard): switched-off cards stay dim while their tab eases in
Soulhackzlol Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/ISSUE_TEMPLATE/integrations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Integrations (experimental)
description: A bug, a rough edge or an idea for the Integrations tab.
title: "[integrations] "
labels: ["integrations"]
body:
- type: markdown
attributes:
value: |
Integrations are new and experimental, so every report helps shape them. Thanks for testing.

- type: input
id: version
attributes:
label: InstantClone version
description: Top-right of the dashboard, or the `v0.1.15` in the .exe name.
placeholder: "v0.1.15"
validations:
required: true

- type: dropdown
id: kind
attributes:
label: What is it?
options:
- Something doesn't work
- Something is confusing
- An idea or a missing feature
validations:
required: true

- type: input
id: integration
attributes:
label: Which integration
description: Its name on the card, like "Smart platform alerts" or one you built.
placeholder: "Highlight button"

- type: textarea
id: what-happened
attributes:
label: What happened, or what you'd like
description: In your words. Screenshots help a lot.
validations:
required: true

- type: textarea
id: run
attributes:
label: The run log (if something failed)
description: Open the integration and look at its last runs. Paste the steps and what each one answered. Check it first for links, keys or tokens and remove them.
render: text

- type: textarea
id: recipe
attributes:
label: The integration as a recipe (optional)
description: On the card, use Share and paste it here. Recipes never contain your webhooks, keys or tokens.
render: text
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,10 @@ jobs:
- uses: Swatinem/rust-cache@v2

# native-tls links system OpenSSL on Linux (schannel on Windows), so the
# headers must be present for the build to link.
# headers must be present for the build to link. ffmpeg lets the
# reconnect screen's lossless round-trip test run instead of skipping.
- name: install build deps
run: sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev
run: sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev ffmpeg

- name: clippy
run: cargo clippy --all-targets -- -D warnings
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ on:
permissions:
contents: write # needed to create releases

# The Twitch app id the Integrations tab logs in with (Device Code flow, a
# public client: the id is not a secret). Baked in at compile time through
# option_env!; set it as a repository variable named TWITCH_CLIENT_ID.
env:
INSTANTCLONE_TWITCH_CLIENT_ID: ${{ vars.TWITCH_CLIENT_ID }}

jobs:
# Gate 1: tests must pass on the exact tagged commit before we ship.
# This guards against the "tag a commit that was never on main" case
Expand Down Expand Up @@ -48,8 +54,10 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: false
# ffmpeg: the reconnect screen's decode tests fail on Linux CI without it
# (same deps as ci.yml's test-linux).
- name: install build deps
run: sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev
run: sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev ffmpeg
- name: clippy
run: cargo clippy --all-targets -- -D warnings
- name: test
Expand Down
790 changes: 788 additions & 2 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "instantclone"
version = "0.1.14"
version = "0.1.15"
edition = "2021"
authors = ["s1moscs"]
license = "GPL-3.0-only"
Expand Down Expand Up @@ -61,6 +61,7 @@ windows-sys = { version = "0.61", features = [
"Win32_System_LibraryLoader",
"Win32_Security_Cryptography",
"Win32_System_Threading",
"Win32_System_SystemInformation",
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_DataExchange",
"Win32_System_Memory",
Expand Down
33 changes: 25 additions & 8 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Haz simulcast de una señal de OBS a Twitch, YouTube, Kick y RTMP personalizado
<td valign="top">

**📱 Vertical (9:16) gratis**
Activa **Formato Dual** de Twitch (Enhanced Broadcasting) y pon el formato de cualquier destino no-Twitch en **Vertical**. InstantClone reutiliza el lienzo 9:16 que OBS ya crea para Twitch y lo envía a YouTube Shorts, Kick móvil o TikTok, sin codificación extra.
En OBS, activa **Enhanced Broadcasting** y elige tu lienzo vertical (por ejemplo Aitum Vertical) en **Lienzo adicional**, y pon el formato de cualquier destino no-Twitch en **Vertical**. InstantClone envía ese lienzo 9:16 a TikTok, YouTube Shorts o Kick móvil, con o sin un destino de Twitch. Activa el destino Vertical antes de empezar a emitir: sin Twitch, la pista vertical solo se codifica mientras haya uno activo. ¿También en Twitch? El **Formato Dual** de Twitch aporta el mismo lienzo.

</td>
<td valign="top">
Expand Down Expand Up @@ -191,13 +191,29 @@ Rearma o ajusta el delay arriba/abajo sin desarmar primero, expuesto como un con
<td valign="top">

**⌨ Atajos de teclado globales**
Asigna delay on/off, armar, activar, cortar y **cortar cuando esto salga** a una combinación que funciona con un juego en pantalla completa por delante. Toda combinación necesita un modificador para que nada se dispare a media partida, una que otra app ya ocupa se marca en su fila en vez de fallar en silencio, y una acción rechazada te llega como globo en la bandeja.
Asigna delay on/off, armar, activar, cortar, **cortar cuando esto salga** y terminar la protección contra crasheos a una combinación que funciona con un juego en pantalla completa por delante. Toda combinación necesita un modificador para que nada se dispare a media partida, una que otra app ya ocupa se marca en su fila en vez de fallar en silencio, y una acción rechazada te llega como globo en la bandeja.

</td>
<td valign="top">

**🎹 Pads y controladoras MIDI**
Mapea las mismas cinco acciones a un pad o un knob, aprendidos pulsando el control en vez de escribir un número de nota. Cada mapeo recuerda de qué dispositivo vino, así dos controladoras pueden mover acciones distintas aunque manden la misma nota, y puedes acotar a qué dispositivo escucha InstantClone.
Mapea las mismas acciones a un pad o un knob, aprendidos pulsando el control en vez de escribir un número de nota. Cada mapeo recuerda de qué dispositivo vino, así dos controladoras pueden mover acciones distintas aunque manden la misma nota, y puedes acotar a qué dispositivo escucha InstantClone.

</td>
</tr>
<tr>
<td valign="top" colspan="2">

**🛡 Protección contra crasheos**
Si OBS se cuelga o se congela, todos los destinos siguen en directo con una pantalla de reconexión (cinco estilos, con tus colores y tu texto) y audio en silencio, hasta 5 minutos. Cuando OBS vuelve, retoma en la misma conexión desde su primer keyframe, Enhanced Broadcasting incluido: cada pista recibe su propia pantalla y OBS recibe la misma sesión de Twitch. Las pistas HEVC y AV1 mantienen su último fotograma. Termínala antes desde el panel, el dock de OBS, la bandeja, un atajo o un pad MIDI.

</td>
</tr>
<tr>
<td valign="top" colspan="2">

**🧩 Integraciones (experimental)**
InstantClone habla con Discord, el chat de Twitch, tu móvil y tus propias herramientas. Con un clic añades un aviso de crasheo, un comando `!delay`, controles para mods, un botón de highlight que clipea lo que los espectadores vieron de verdad, una tarjeta de Discord que escribe la línea de tiempo de tu stream, capítulos de YouTube, una luz de "en directo" y más, y un editor por pasos cubre el resto. Son nuevas y aún pueden cambiar: cuéntanos lo que falle o confunda con el enlace **Report it** de la pestaña.

</td>
</tr>
Expand All @@ -216,7 +232,7 @@ Mapea las mismas cinco acciones a un pad o un knob, aprendidos pulsando el contr
<tr>
<td valign="top" width="50%">

**Dos fases por diseño.** **Armas** un buffer (un tamaño objetivo en segundos). InstantClone lo prellena desde la señal de OBS sin tocar lo que sale. Cuando se llena pulsas **Activar**, y el cambio a diferido es instantáneo en pantalla: el reproductor solo salta del borde en directo a un punto N segundos atrás.
**Dos fases por diseño.** **Armas** un buffer (un tamaño objetivo en segundos). InstantClone lo prellena desde la señal de OBS sin tocar lo que sale. Cuando se llena pulsas **Activar**, y el cambio a diferido es instantáneo en pantalla: el reproductor solo salta del borde en directo al fotograma clave de al menos N segundos atrás, así que el público nunca queda más cerca del directo de lo que pusiste.

</td>
<td valign="top" width="50%">
Expand Down Expand Up @@ -249,6 +265,7 @@ Mapea las mismas cinco acciones a un pad o un knob, aprendidos pulsando el contr
| <kbd>POST</kbd> | `/cut-after` | | Marca el borde en directo; autocorta cuando sale en todos. |
| <kbd>POST</kbd> | `/cut-after/cancel` | | Descarta un corte programado pendiente. |
| <kbd>POST</kbd> | `/delay` | `ms=NNN` | De un tiro: arma y autoactiva en cuanto esté listo. |
| <kbd>POST</kbd> | `/crash-protection/end` | | Termina ya la pantalla de reconexión: todos los destinos terminan. |
| <kbd>GET</kbd> | `/state` | | Instantánea JSON puntual. |
| <kbd>GET</kbd> | `/events` | | Flujo de estado JSON por server-sent events. Solo push. |

Expand Down Expand Up @@ -306,7 +323,7 @@ Armado de un botón. Añade `/activate` y `/stop` a otros dos botones para contr

- **Handshake RTMP con paridad total con OBS.** `connect` lleva la misma bolsa de capacidades de códec que envía librtmp (`audioCodecs=3191`, `videoCodecs=252`, `videoFunction=1`), el `fourCcList` de Enhanced-RTMP (AVC / HEVC / AV1 / VP9 / Opus / AC-3 / FLAC), `Set Chunk Size` antes de connect, `FCUnpublish → deleteStream` al cerrar, y RTMP Acknowledgement (BYTES_READ_REPORT) al umbral ventana/10 declarado por el par, en entrada y salida.
- **Passthrough de Enhanced Broadcasting a Twitch.** Cuando OBS pasa a multipista "Auto" hacemos de proxy de `GetClientConfiguration` de Twitch, ruteamos la salida al endpoint IVS asignado a la sesión y reenviamos cada SPS/PPS por pista fielmente para que se encienda la escalera de transcodificado sin importar el nivel de cuenta. Los destinos no-Twitch reciben la pista primaria horizontal por defecto; las etiquetas de escalera con `TrackId != 0` se descartan para evitar la tormenta de varios frames por PTS que hace caer el decodificador de YouTube. Los cortes de EB caen en el IDR de la pista primaria (no en el keyframe del peldaño que gane el `partition_point`) para que el decodificador del destino siempre tenga su ancla.
- **Selección del lienzo vertical (9:16).** El lienzo vertical se identifica decodificando el SPS de cada pista por orientación (retrato, mayor área) en vez de confiar en el JSON privado de sesión de Twitch, y se autocorrige según se activa/desactiva Formato Dual.
- **Selección del lienzo vertical (9:16).** El lienzo vertical se identifica decodificando el SPS de cada pista por orientación (retrato, mayor área) en vez de confiar en el JSON privado de sesión de Twitch, y se autocorrige según aparece o desaparece el lienzo vertical.
- **Audio de VOD de Twitch, desbloqueado en el servicio InstantClone.** OBS ata su pista de VOD al servicio llamado literalmente "Twitch" (`ServiceSupportsVodTrack == {"Twitch"}`), así que está bloqueada en el servicio InstantClone. Un pequeño script de OBS incluido (`optional-vod-unlocker.lua`, descargado desde el panel) engancha el mismo segundo codificador de audio que usaría la propia pista de VOD de OBS, sin la restricción. Su lector de formato coincide byte a byte con el `flv_packet_audio_ex` de OBS (`AudioPacketType` en el byte 0, `TrackId` en el byte 6). OBS 32.2+ necesita el script; OBS anterior puede usar la casilla de VOD Track integrada (escribimos `EnableCustomServerVodTrack` en el `user.ini` de OBS 32, con `global.ini` como respaldo).
- **Ruteo de audio por destino.** Las pistas no seleccionadas se descartan y la elegida se aplana a una etiqueta de una sola pista estándar (AAC reescrito al `0xAF` legado), espejando el `flatten_multitrack_video` del lado de vídeo. Si la pista elegida no se está enviando, cae a la pista en directo en vez de quedarse en silencio.

Expand Down Expand Up @@ -336,7 +353,7 @@ El HTML del panel se minifica + gzipea en tiempo de compilación con `build.rs`

**E/S de disco síncrona en la ruta caliente de escritura al anillo, por elección.** La escritura con buffer aterriza en la caché de páginas del SO en microsegundos y el kernel vacía en segundo plano, así que la caché de páginas ya es el buffer asíncrono; el índice y los bytes avanzan bajo un solo lock para que un lector nunca vea una etiqueta cuyos bytes aún no están en disco.

**Tests.** `cargo test --release` cubre la máquina de estados (`arm → preparing → ready → active → cut`), detección de IDR de AVC + Enhanced-RTMP, AMF0 (incluido Strict Array + guardia de recursión), round-trip de settings, expulsión del buffer en anillo con protección de lecturas en vuelo, parseo HTTP, política CSRF, pre-flight de puerto, negociación de contenido, caché de cabeceras de secuencia por pista de Enhanced Broadcasting + selección de etiquetas por TrackId, audio multipista + ruteo por destino, parseo de orientación SPS para la selección vertical, el parcheador de `services.json`, el parser del check de actualizaciones, el SHA-256 hecho a mano (vectores NIST), el lector/escritor de chunk-stream RTMP, la máquina del corte programado, las tablas de atajos y de mapeos MIDI (incluido el dispositivo que distingue dos controladoras), y la descarga de autoactualización + verificación de checksum + intercambio del exe. **392 tests, todos en verde.**
**Tests.** `cargo test --release` cubre la máquina de estados (`arm → preparing → ready → active → cut`), detección de IDR de AVC + Enhanced-RTMP, AMF0 (incluido Strict Array + guardia de recursión), round-trip de settings, expulsión del buffer en anillo con protección de lecturas en vuelo, parseo HTTP, política CSRF, pre-flight de puerto, negociación de contenido, caché de cabeceras de secuencia por pista de Enhanced Broadcasting + selección de etiquetas por TrackId, audio multipista + ruteo por destino, parseo de orientación SPS para la selección vertical, la configuración de Enhanced Broadcasting construida a partir de los lienzos y codificadores GPU de OBS, el parcheador de `services.json`, el parser del check de actualizaciones, el SHA-256 hecho a mano (vectores NIST), el lector/escritor de chunk-stream RTMP, la máquina del corte programado, las tablas de atajos y de mapeos MIDI (incluido el dispositivo que distingue dos controladoras), la protección contra crasheos (distinguir crasheo, parada y congelado, el codificador sin pérdidas de la pantalla de reconexión comprobado con ffmpeg, el empaquetado por pista de Enhanced Broadcasting, el AAC en silencio), el motor de integraciones (pasos, plantillas, recetas, chat, tarjetas de Discord, la línea de tiempo del stream), y la descarga de autoactualización + verificación de checksum + intercambio del exe. **843 tests, todos en verde.**

</details>

Expand All @@ -346,7 +363,7 @@ El HTML del panel se minifica + gzipea en tiempo de compilación con `build.rs`

## Estado

**Listo para uso diario en Windows.** Lo uso en mis propios streams, y un grupo creciente de streamers lo corre a diario también. CI ejecuta fmt + clippy (`-D warnings`) + 392 tests en cada push, y un commit etiquetado compila y publica una release con un `SHA256SUMS.txt` al lado (todavía sin certificado de firma de código, así que el SO puede avisar al primer arranque).
**Listo para uso diario en Windows.** Lo uso en mis propios streams, y un grupo creciente de streamers lo corre a diario también. CI ejecuta fmt + clippy (`-D warnings`) + 843 tests en cada push, y un commit etiquetado compila y publica una release con un `SHA256SUMS.txt` al lado (todavía sin certificado de firma de código, así que el SO puede avisar al primer arranque).

**Lo áspero, con honestidad**

Expand Down Expand Up @@ -415,7 +432,7 @@ En la pestaña **Destinos** de InstantClone, nunca en OBS. OBS solo apunta a Ins

<br/>

Sí, ambas cosas. Cinco acciones - delay on/off, armar, activar, cortar a directo y **cortar cuando esto salga** - se asignan a un atajo de teclado global, a un pad o knob MIDI, o a los dos a la vez, en **Ajustes**. Los atajos funcionan con un juego en pantalla completa por delante, así no haces alt-tab a media partida, y toda combinación necesita un modificador (Ctrl, Alt, Shift o Win) para que una tecla suelta no dispare una acción de delay. Los mapeos MIDI se aprenden pulsando el control en vez de escribir un número de nota, y cada uno recuerda de qué dispositivo vino, así dos controladoras pueden mover acciones distintas. Por ahora solo en Windows.
Sí, ambas cosas. Seis acciones - delay on/off, armar, activar, cortar a directo, **cortar cuando esto salga** y terminar la protección contra crasheos - se asignan a un atajo de teclado global, a un pad o knob MIDI, o a los dos a la vez, en **Ajustes**. Los atajos funcionan con un juego en pantalla completa por delante, así no haces alt-tab a media partida, y toda combinación necesita un modificador (Ctrl, Alt, Shift o Win) para que una tecla suelta no dispare una acción de delay. Los mapeos MIDI se aprenden pulsando el control en vez de escribir un número de nota, y cada uno recuerda de qué dispositivo vino, así dos controladoras pueden mover acciones distintas. Por ahora solo en Windows.

</details>

Expand Down
Loading
Loading