Unidad 6
Introducción 📜
Sección titulada «Introducción 📜»En esta unidad vas a continuar el trabajo arquitectónico de las unidades 4 y 5, pero esta vez la fuente de datos ya no será un dispositivo físico conectado por serial. En lugar de eso, vas a integrar una segunda aplicación web que genera eventos musicales en tiempo real usando Strudel.
El reto ya no consiste solamente en lograr que “dos cosas se comuniquen”. El
reto real es mantener una arquitectura desacoplada, clara y explicable, en la
que cada capa conserve su responsabilidad: una aplicación genera eventos, un
adapter los traduce a un contrato estable, bridgeServer.js los transporta, y
el frontend los interpreta y los convierte en una respuesta visual sincronizada
en el tiempo.
Rúbrica de evaluación de la unidad 📝
Sección titulada «Rúbrica de evaluación de la unidad 📝»Requisito de salida (condición necesaria)
Sección titulada «Requisito de salida (condición necesaria)»Rúbrica analítica
Sección titulada «Rúbrica analítica»| Criterio (peso) | Cumple plenamente (5.0) | Se cumple medianamente (4.0) | Problemas importantes (3.0) | Falta comprensión básica (2.0) | No hay evidencia (0.0) |
|---|---|---|---|---|---|
| 1. Aplicación + bitácora (40%) | La app se ejecuta sin fallos en el entorno acordado. La sincronización es consistente y la bitácora permite reconstruir el flujo completo del sistema. Todo es consistente con lo mostrado en la demo. | La app funciona y logra la comunicación básica entre Strudel y la visual. La bitácora permite verificar lo esencial, aunque hay 1–2 vacíos menores. | La app funciona parcialmente, la sincronización es inestable o la arquitectura no está claramente documentada. La bitácora tiene vacíos importantes. | La app no corre o no demuestra lo requerido. La bitácora no permite verificar cómo se implementó la solución. | No se entregaron evidencias o no se puede acceder a ellas |
| Evaluación | |||||
| 2. Sustentación (60%) | Responde con precisión conectando: (a) los eventos musicales que se generan, (b) cómo viajan por el sistema, y (c) cómo se convierten en imagen sincronizada. Justifica decisiones y reconoce límites. | Responde correctamente pero con imprecisiones menores o con una justificación superficial de algunas decisiones. | Explica parcialmente qué sucede, pero le cuesta describir con claridad la arquitectura, el uso del tiempo o la separación de responsabilidades entre capas. | No logra explicar de forma coherente el flujo de datos o mezcla conceptos sin relación clara con lo implementado. | No se entregaron evidencias o no se puede acceder a ellas |
| Evaluación |
Seek: Investigación 💡
Sección titulada «Seek: Investigación 💡»Actividad 01
Sección titulada «Actividad 01»En esta actividad vamos a estudiar un caso de integración entre dos aplicaciones que viven en el navegador y cuyo repositorio es este:
- Una app musical que genera eventos con Strudel.
- Una app visual que recibe esos eventos y los transforma en animación.
La meta no es copiar un experimento existente, sino analizarlo para entender qué problema arquitectónico resuelve y cómo se relaciona con lo que ya has trabajado en las unidades 4 y 5.
El experimento de referencia ya resuelve una parte importante del problema: la
sincronización temporal. En ese caso de estudio, los eventos musicales no se
ejecutan apenas llegan por WebSocket, sino cuando el reloj local alcanza el
timestamp indicado por el mensaje.
Esto introduce una idea nueva para el curso:
- En las unidades 4 y 5 el reto principal era parsear y validar datos.
- En las unidades 4 y 5 esto se resolvía creando nuevos adapters sin romper el resto del sistema.
- En esta unidad también debes programar cuándo ocurre la respuesta visual.
Paso 1: ¿Qué tipo de datos puede emitir Strudel?
Sección titulada «Paso 1: ¿Qué tipo de datos puede emitir Strudel?»Para esta unidad vamos a usar Strudel como una aplicación generadora de eventos musicales. Un patrón como este:
setcps(0.5)
const pat = s("[bd*2 sd hh oh]").bank("tr909")
$: stack( pat.gain('0.05'), pat.osc())puede producir mensajes con información como:
- Qué sonido ocurrió;
- Cuándo debería ocurrir;
- Cuánto dura su ciclo rítmico;
- Otros parámetros asociados al evento.
En vez de pensar en Strudel como “un sintetizador”, para esta unidad debes pensarlo como una fuente de eventos.
Paso 2: Transporte vs sincronización
Sección titulada «Paso 2: Transporte vs sincronización»Supón que el bridge recibe este mensaje:
{ address: '/dirt/play', args: [ 'cps', 0.5, 'cycle', 15.25, 'delta', 0.5, 's', 'tr909sd', 'bank', 'tr909' ], timestamp: 1774966984435.2805}Si la aplicación visual dispara la animación apenas llega el mensaje, el sistema queda amarrado a la latencia de red, al navegador y a la carga del computador.
Si en cambio la aplicación:
- recibe el mensaje;
- lo guarda en una cola;
- espera a que
Date.now()alcance sutimestamp; - recién ahí activa la respuesta visual;
entonces la sincronización mejora y la arquitectura se vuelve más explícita.
Esto es importante porque permite distinguir dos capas conceptuales:
- Transporte: mover el mensaje de una app a la otra;
- Scheduling: ejecutar el evento en el instante correcto.
Paso 3: Continuidad con las unidades 4 y 5
Sección titulada «Paso 3: Continuidad con las unidades 4 y 5»Aunque ahora no hay puerto serial ni micro:bit, la lógica de diseño sigue siendo la misma:
- Existe una fuente externa de datos;
- Esos datos deben traducirse a una forma comprensible por el sistema;
- Esa traducción debe encapsularse en un adapter;
- Hay una capa de transporte;
- Hay una capa de frontend que convierte eventos en estado y luego en imagen.
En otras palabras:
- En la unidad 4 cambió el formato ASCII.
- En la unidad 5 cambió el protocolo binario y apareció el framing.
- En esta unidad cambia la naturaleza misma del evento: ahora es un evento musical con tiempo programado.
Apply: Aplicación 🛠
Sección titulada «Apply: Aplicación 🛠»Actividad 02
Sección titulada «Actividad 02»Un equipo de diseño sonoro ha creado una aplicación en Strudel que genera música en el navegador. Tu tarea es integrar esa aplicación a un sistema visual ya existente, pero debes hacerlo sin romper la arquitectura desacoplada que vienes desarrollando desde las unidades anteriores.
La documentación funcional del sistema es esta:
- La aplicación de Strudel corre en el navegador.
- Strudel envía eventos por WebSocket al puerto
8080. - Cada evento contiene información musical y una marca temporal
timestamp. - Un Adapter debe recibir estos mensajes, normalizarlos y entregarlos a
bridgeServer.js. - El bridge debe reenviarlos a la aplicación visual.
- La aplicación visual debe responder de forma sincronizada con el tiempo indicado por el evento.
Ejemplo de mensaje de entrada al bridge:
{ address: '/dirt/play', args: [ 'cps', 0.5, 'cycle', 15.25, 'delta', 0.5, 's', 'tr909sd', 'bank', 'tr909' ], timestamp: 1774966984435.2805}Qué debes implementar:
-
Integrar una configuración de Strudel que emita eventos musicales por WebSocket hacia el puerto
8080. -
Crear un nuevo Adapter para Strudel, por ejemplo
StrudelAdapter.js, que:- Reciba los eventos entrantes desde Strudel;
- Los normalice a un formato claro para el sistema;
- Los entregue a
bridgeServer.jssin decidir cómo se dibujan.
-
Registrar ese Adapter en
bridgeServer.jssin convertir el bridge en el lugar donde vive la lógica de dominio. -
Adaptar
bridgeClient.jspara que:- Reciba los eventos reenviados;
- Dispare el evento correspondiente hacia la capa de frontend.
-
Implementar en el frontend una lógica que:
- Reciba eventos musicales;
- Los almacene en una cola;
- Los active cuando llegue su
timestamp; - Traduzca esos eventos en una respuesta visual coherente.
Arquitectura del frontend: guía de integración
Sección titulada «Arquitectura del frontend: guía de integración»En esta unidad no basta con “hacer que algo se vea”. Debes respetar la arquitectura del frontend que ya vienes trabajando.
-
bridgeClient.js- Recibe el mensaje normalizado reenviado por
bridgeServer.js; - Inspecciona
msg.type; - Dispara el evento correspondiente hacia la FSM.
- Recibe el mensaje normalizado reenviado por
-
FSMTask- Recibe eventos ya normalizados;
- No debe parsear mensajes crudos de Strudel;
- Coordina la actualización de estado y la ejecución del render.
-
updateLogic- Aquí aterrizan los datos del evento musical;
- Aquí debes actualizar la cola de eventos temporizados;
- Aquí debes traducir el mensaje a variables de estado visual.
-
drawRunning- Aquí no debes parsear mensajes de red;
- Aquí no debes decidir cómo interpretar
msg.type; - Aquí solo debes leer el estado ya calculado y dibujar.
En otras palabras: bridgeClient.js recibe, FSMTask organiza,
updateLogic actualiza estado y drawRunning dibuja.
Contrato mínimo sugerido para el evento normalizado:
{ type: "strudel", timestamp: 1710000000000, payload: { eventType: "noteEvent", s: "tr909bd", delta: 0.25 }}No es obligatorio usar exactamente este contrato, pero tu sistema debe tener un formato estable, explícito y fácil de explicar en la sustentación.
Requisito mínimo funcional
Tu sistema debe soportar al menos estos sonidos:
bdsdocphh
y debe usar al menos estos parámetros:
- tipo de sonido;
timestamp;deltao alguna duración equivalente.
Exploración opcional
Si quieres llevar tu propuesta más lejos, puedes integrar:
- Líneas de bajo;
- Melodías;
- Escalas;
- Color por familia sonora;
- Duración visual dependiente de
delta; - Múltiples capas visuales simultáneas.
Pista de implementación
En las unidades 4 y 5 aprendiste que no conviene mezclar la lectura del protocolo con la lógica visual. Aquí ocurre lo mismo:
- El Adapter debe traducir y normalizar el mensaje de Strudel;
bridgeServer.jsno debe decidir colores, formas o composiciones;- El frontend no debería interpretar mensajes WebSocket desordenados o ambiguos;
- La capa de estado debe convertir el evento musical en variables visuales y luego el render debe limitarse a dibujar.