You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/static/sounds/ui-inline.json

1 line
113 KiB

feat(sema,sound): un pack se entrega como quieras — y un `data:` no se pide, se descodifica La entrega deja de ser parte del contrato. Un pack de ficheros puede llegar como quince URLs o como UN JSON de base64 (`packFromBase64`): mismo tipo, mismo intercambio en caliente, misma reserva sintética por entrada, y un nombre que no existe sigue sin compilar. Medido sobre `static/sounds/ui-inline.json`: una petición en vez de quince, y 69.082 B con brotli frente a 79.332 B de los ficheros sueltos — el +33 % del base64 lo deshace la compresión, y el JSON gana además porque nadie comprime `audio/mpeg` y todos comprimen `application/json`. ## `step` no se oía Era a la vez el MÁS CORTO (18 ms) y el MÁS FLOJO (gain 0.025), y esas dos cosas se multiplican: el oído integra energía durante ~100-200 ms, así que un tono corto necesita MÁS amplitud, no menos. Medido, rendía a −29,8 dBFS con la novena parte de la energía de `touch`. Ahora 0.06 a los mismos 18 ms. Lo que no había era el guard: la distinguibilidad es una RELACIÓN, y dos sonidos pueden ser perfectamente distintos entre sí y ser los dos inaudibles. `sound-names.test.ts` gana un suelo absoluto sobre `gain² × duración`. ## El precalentamiento no precalentaba - `preload` pedía el contexto con `getOrCreateContext()`, que hace `await resume()` — y antes del primer gesto esa promesa se queda PENDIENTE en Chrome, no se rechaza. No descargaba nada hasta que el usuario ya había pulsado, que es justo la latencia que el preload existe para quitar. `decodeAudioData` funciona en un contexto suspendido. - Aplicar un pack en caliente no calentaba la caché: cada nombre pagaba su viaje la primera vez que sonaba. Ahora `rebuildMap()` llama a `warmSamples()`. - Con `preferences.sound === 'off'` no se descarga NADA — un pack que no se puede oír son bytes gastados en silencio. Pero la petición se RECUERDA en vez de tirarse: el nivel se lee en el dispatch, así que la primera reproducción audible vacía la cola y encender el sonido no devuelve una caché fría. ## Un `data:` se descodifica en el sitio `connect-src 'self'` BLOQUEA `fetch('data:…')` — la directiva casa por ESQUEMA y `'self'` no cubre `data:` — mientras deja pasar una ruta del mismo origen. Un pack inline enrutado por `fetch` caía a síntesis EN SILENCIO justo en el entorno que llevó a alguien a hacerlo inline. Y es ~6x más lento. `bytesFor()` lo resuelve con `atob`. ## De la revisión adversarial - Las claves del JSON se validan: una que no sea `SoundName` LANZA, igual que una ruta mala en `assertMapPaths` y por la misma razón — tragarse la errata da el síntoma «parte de mi pack no se aplicó» sin nada a lo que apuntar. - `isSoundName` preguntaba `name in SEMA_MAP.sounds`, y `in` recorre el prototipo: `isSoundName('toString')` devolvía `true`. Inofensivo mientras todos los llamantes tecleaban el nombre; nada inofensivo al validar red. - `warmSamples` sólo tenía una de las dos ramas que sí tiene el constructor, así que una app con canal de sonido propio se calentaba al arrancar y nunca más; y esa rama leía la preferencia UNA vez, en construcción. Las dos se caían por lo mismo: ahora comparten `warmUrls()` en vez de duplicarse. - El demo del catálogo cancela su fetch: elegir `inline` y saltar a `synth` antes de que llegara reinstalaba el pack sobre un `clearMap()` ya hecho. - `fallbackFor(name)` borra los dos casts que copiaba todo el que autorase un pack de ficheros. ## Documentación `architecture/sema.md` gana la sección de las dos formas de entrega y el párrafo de `preloadSamples` reescrito — describía un precalentamiento que ya no es el que ocurre. El README del arte conoce la ruta `data:`. La página de packs gana su sección equivalente y deja de señalar unos `.wav` sueltos como «el ejemplo». Y un fantasma: `soft` no existe — es un nombre del catálogo viejo que quedaba como ejemplo en ocho sitios, incluido el docstring de `applySounds`, cuyo ejemplo copiado literalmente LANZABA. `static/sounds/ui-inline.json` se genera desde `packs/ui-mp3.ts`; el comando está documentado ahí y reproduce el fichero byte a byte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
{"touch":"SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYxLjcuMTAwAAAAAAAAAAAAAAD/+3DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAMAAATlAH9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f8DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwP///////////////////////////////////////////wAAAABMYXZjNjEuMTkAAAAAAAAAAAAAAAAkBlsAAAAAAAAE5ZdvqCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//twxAAADpkDORQTAAJ6q663MPADQgAAAIxjHmMAEYxjYCZO//7sgQAAAAAQQjt/d3d/+IjHPJgAABBAgQgwgFk78GECBABgMmnphAghdkyZMmTv3d3d3v72TBwGAyacREQQQyyBDHu7uyBBAEAxfwcBAEAQBAHwfB8HwcBDnNYOAgGIgB8H/0hiyWyyRtksmEsBksiIVJ12QQ8lVewbRrhiG4VzSxHEfUufbZSXCILOW5SobpsYXBWEzw+nUaPpHPYfxtIWw1hTuGXCa0dkYzpUWcbtmlITJ4UzjGiOLv4+PnW9bf7wZDIzqyBm8LG8fec1tumb0vBcmSkOmL4+f//+56vimZ9Xzdim3qPTF8Wm/////+HuImtXzD3PuPiCHgdQgMh0O/+KiWenmWVnEkZXSluc1vsgAf/7csQIABJtEU/5h4AKJrRk0x8gAIW6Lts7iVWGtO0+mGmmmJr/NL1fDaJEkWOKqGJcltxddSMEMgyFvRXSSopwV5YgmRMBV7YVaT1GarK+rO3xN5V76Wp+pqWZE2zdPKmrCoUeYZpX3asF7NqalMJdWuN4bLsnzTFjbx84c9bpTd8Q1DIyv46n1IxVkjfPtiF39Sf29B6foARCIAAAAERT4/4mBiwrfkLAs5hfihAbHkl46BlAbFGSS+AZIfiFlIISUtjLwCFDZAyozYAAqcxRb4dKYizRoB6IpDq/w6YmxlBRhCwrYbS0VLXX/FbEXEBTMdpfJ4gJrrXX//QIFSM3JknTEnf///LqRdMjEmTQmSgQ8ZYniy6H/X///k8mRUsLTEFNRTMuMTAwqqqqqqqqqqqqqqqqqqqq//twxAwDwAABpBwAACAAADSAAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg==","step":"SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYxLjcuMTAwAAAAAAAAAAAAAAD/+3DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAMAAATlAH9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f8DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwP///////////////////////////////////////////wAAAABMYXZjNjEuMTkAAAAAAAAAAAAAAAAkBNMAAAAAAAAE5YuMUXIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//twxAAADhRdLBT0gAqQH6r3N5ACCQDgVCnLePWPWTs61ArHjx4rE4higBMExWTo0aNGjQIECBAgQIECNG3Oc5zmwAAAAAB4eHh4YAAAAAB4eHh4YAAAAAB4eHh4YAAAAAB4eHh4YAAAAAB4eHh4YAAAAIDw8PD0gAAAGg8PD/1AAP9sPHwlgMBk+Leav2XUWiQABwqJNBjzUcgwAQVFAJU7JTKAgzsvT9aqoElYZGJg4LSFV6uihOIhBSMLuLXu4qYDYA5tsCD0y/sawh2MgKht13sQXTWlT/Vo1NWZnJ2IQudIerGYZrU0CWoPnqGUrPQAKCOo68xTXH+a1S0vP73/9xFju+/b8Rikazcy1Wl3f/////7dPnSWLF//5qt+ss90v8HzWDR7YgAAAACI5/9fpCkAAAADKP/7csQHgBFkmzG5vAACL7NiB7ZgAXkcITsRYmBzSQJ2TKgcQB7UYVPWTLA1E6EQXroBAxaU2e+Ygw64OFS5M5e/M/NOTAkpk1WIxKHqOXyPUVf679NG68NP1Lq0qi0aoGesRdGzap7tNapt5ZVTp1gqJCKBYSuBVED0BjxaRKhH+3LTykf9H+TWme//3//9W7XIBlNIbmDBxUMApa1riUi6rTQX4g+63eHakskgobAYiFnoGC3QMGJpi3Pe2iEXufbWyoZTYaH1iDelGanuo3/mVt7t81o3/MUntIo78O6W+q/yKYu/dOc0F7UH7+g8n6W1z7wggxV2x0bWZ/sbPuLRSkijGnEtSGuaLIMnEpF5puRNObS6lsExFqLNQ2KALRwoKbrpXKrmILmWNOO070urv7DtiGozhlKo//twxA6D0YGXBCyYc8AAADSAAAAE1blMZIlgEjBIlppGnIhKJwMk5JLeaRw4GxjknNRypnDiWyRl5n1VPNeZlqr9q01Fqr9q2XnHmexyRoLpqrhhSkGNVWM1Y7/SDCYBCqAiWZYzVc9quf7Q/1hrSak3V1WMfQGiVIMBeSEXlv0yU6rtTEFNRTMuMTAwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg==","tick":"SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYxLjcuMTAwAAAAAAAAAAAAAAD/+3DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAQAAAYfAGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM/////////////////////////////////wAAAABMYXZjNjEuMTkAAAAAAAAAAAAAAAAkAk4AAAAAAAAGH6CSA3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//twxAAADhUTLxQUAAqPMim7GMAAr5VAAAAAAAIIxjGMb/hP4R3e9EkXAUBYDQyne4Fxc93///hEQXPuCBQUSSBQUFDJLFwbgsBoHiS72QDcG4uLu7u6IiIiJX/+4

Powered by TurnKey Linux.