Canciones y compartir
El archivo .noisesong y el enlace noise://
Qué contiene un archivo .noisesong, cómo lo codifica el enlace noise:// y los límites que cumplen los dos.
Una canción sale de NØISE en una de dos formas legibles por máquina: un archivo .noisesong (JSON) o un enlace noise:// (el mismo JSON, codificado en una URL). Ninguna contiene audio. Las dos llevan exactamente una canción.
Aviso
Esquema 3, desde NØISE 0.81: sin compatibilidad hacia atrás. Una canción es UNA banda con UN kit, y una sección fija sus carriles DRUMS y JAM. La app no lee nada anterior al esquema 3: un archivo con schemaVersion 2 o sin ese campo no abre nada, y una biblioteca antigua se aparta en el primer arranque. Esta web rechaza ese archivo al subirlo con las mismas palabras. Abre la canción en el editor de la app y expórtala de nuevo.
El archivo .noisesong
EXPORTAR, en la placa CANCIONES y en el editor, escribe un documento JSON en UTF-8. La app registra el tipo de archivo como nl.weap.noise.song (“NØISE Song”, conforme a public.json, extensión .noisesong), así que un doble clic en un archivo lo abre en NØISE.
El sobre
{
"version": 3,
"song": { … }
}| Campo | Tipo | Significado |
|---|---|---|
version | integer | Versión del formato de archivo; 3 desde 0.81. |
song | object | La canción. |
Las claves se escriben ordenadas y con sangría. Las fechas son ISO-8601 en UTC sin fracciones de segundo (2026-05-01T12:00:00Z): la app rechaza las fracciones de segundo.
El objeto song
{
"id": "6F1A0E9C-3D4E-4B11-9A0B-1C2D3E4F5A6B",
"name": "Amber Skyline",
"author": "NØISE",
"songDescription": "Demo song for the website",
"style": "rock",
"kit": "rock.classic",
"drums": { "feel": "straight", "preset": { "name": "LAID BACK", "energy": 0.45, "swing": 0.2, "humanize": 0.25, "live": 0.35 } },
"jam": { "intensity": 0.5, "colorLayer": false, "rhythmGuitar": true },
"tempoHint": 112,
"grooveSeed": 4422912175377245,
"schemaVersion": 3,
"createdAt": "2026-05-01T12:00:00Z",
"updatedAt": "2026-05-01T12:00:00Z",
"chart": { … }
}| Campo | Tipo | Obligatorio | Significado |
|---|---|---|---|
id | UUID string | sí | Identidad de la canción. Importar una canción cuyo id ya existe en tu biblioteca nunca la fusiona con ella: la importada recibe un UUID nuevo y pasa a ser una canción nueva y aparte, con el id original anotado en sourceId para que no se pierda el linaje. |
name | string | sí | Nombre de la canción. |
chart | object | sí | El cifrado (más abajo). |
style | string | no | El estilo de JAM de toda la canción: pop, rock, blues, jazz, hiphop, funk, metal. Ausente = rock. El género de batería sale de él (pop → POP, rock → ROCK, … hiphop → HIP-HOP) y no es un campo aparte. Mientras suena la canción, la banda toca la banda propia de la canción; tus propios paneles DRUMS y JAM vuelven cuando sueltas la canción. |
tempoHint | number | no | El tempo de la canción; se aplica a la sesión cuando la canción se carga. |
songDescription | string | no | Notas libres (notes: en el formato de texto). |
author | string | no | Quién la escribió. |
kit | string | no | El único kit de JAM de toda la canción, un id que pertenece al estilo (pop.strings, rock.classic, metal.stock, …). Ausente = el primer kit del estilo. Un kit de otro estilo se ignora. |
drums | object | no | El carril DRUMS de la canción: de donde parte cada sección. Mira Los carriles. |
jam | object | no | El carril JAM de la canción: lo mismo. |
tuning | string | no | GuitarTuning.id: standard, dropD, halfStepDown, fullStepDown, dropC, openG, openD, dadgad. Se aplica a la sesión cuando la canción se carga, como la tonalidad y el tempo: no es una pista. Ausente significa Standard: una canción que no nombra afinación está escrita en Standard, y al cargarla la sesión pasa a Standard. |
capo | entero | no | El traste donde va la cejilla de la canción, 0–9 (desde 0.71). Se aplica al cargar como la afinación: ausente o 0 significa sin cejilla, y cargar la canción la quita. El cifrado se queda en la tonalidad de las formas; la banda y los detectores suenan esos trastes más arriba. |
grooveSeed | entero | no | La semilla de groove del autor. Todo lo que la banda decide por sorteo (cuáles de los compases escritos de bajo y pad, los fills, las notas de aproximación, la frase de la batería, el walking bass hacia el acorde siguiente) sale de ella: una canción compartida suena igual en cada Mac y cada iPad. Ausente: un hash fijo del id de la canción. La app escribe una al guardar una canción nueva y anota la semilla efectiva al exportar, como la tonalidad. Un entero por debajo de 2^53, para que cualquier lector JSON, JavaScript incluido, lo lea exacto. |
sourceId | UUID string | no | La canción de la que esta se importó o derivó (linaje de las canciones compartidas). |
schemaVersion | integer | sí | 3. Cualquier valor menor, o su ausencia, no se lee: ni la app ni esta web. |
createdAt, updatedAt | date | sí | Marcas de tiempo. |
feel, drumStyle, drumEnergy, drumHumanize, jamIntensity, colorLayer y rhythmGuitar ya no existen a nivel de canción: viven dentro de drums y jam. Una canción de una app más nueva nunca falla por una clave de más; las claves desconocidas se conservan al leer y volver a escribir el archivo.
Los carriles
Los mismos dos bloques están en la canción (de donde parte cada sección) y en una sección (lo que ella misma fija). Todo campo es opcional y significa "no fijado aquí": mira la regla de resolución.
drums, lo que una sección le dice al kit:
| Campo | Valores | Significado |
|---|---|---|
off | true / false | El kit se calla en esta sección (espacio para un solo). |
feel | una etiqueta GrooveFeel de la lista del estilo (straight, halfTime, shuffle, swing, …) | El groove: un feel para la batería Y la banda. Un feel que el estilo no ofrece se resuelve al primero del estilo. |
fill.in | crash, splash, none, choke | El platillo en el UNO de la sección. Ausente = lo decide el arreglo según la transición. choke se lleva pero no suena aún (suena como un crash). |
fill.out | auto, fill, none, break, o el nombre de un fill (busy, tom roll, fill2, …) | Lo que hace el kit a la salida de la sección, en el ÚLTIMO compás de la última repetición. auto = lo decide el arreglo; fill = mete un fill sea cual sea la transición; none = nunca; un nombre = ese fill del banco del género (desconocido → auto). break se lleva pero no suena aún (suena como none). |
variation | una lista de palabras | Las capas del estilo. La lleva el archivo; la app aún no tiene palabras para ella. |
preset.name | STOCK, TIGHT, DRIVING, LAID BACK, LOOSE, SMOKY, QUIET, uno tuyo, o CUSTOM | Una ETIQUETA para los cuatro mandos de abajo. Los valores viajan; el nombre se lee. |
preset.energy | 0–1 | Lo fuerte que toca el kit. |
preset.swing | 0–1 | La rejilla, 0 recto … 1 tresillo completo. Ausente = el swing propio del feel. |
preset.humanize | 0–1 | Cuánto se desvía una mano alrededor de la parte. |
preset.live | 0–1 | Cuánto detalle escrito (ghosts, la variante del compás 4) se revela. |
jam, los indicadores de la banda:
| Campo | Valores | Significado |
|---|---|---|
intensity | 0–1 | Cuánto toca la banda. |
colorLayer | true / false | La cuarta capa (de color) de la banda. |
rhythmGuitar | true / false | La capa de guitarra rítmica de la banda, en los estilos que la tienen. |
La regla de resolución
Todo campo de un carril se resuelve en un orden, campo a campo:
SECCIÓN → LA SECCIÓN ANTERIOR → CANCIÓN- Una sección que fija un campo lo decide. Una sección que fija
fill.iny nada más decide el platillo y sigue en todo lo demás. - Una sección que deja un campo abierto toca lo que tocó la sección anterior: di HALF TIME una vez y sigue así hasta que algo diga lo contrario. En el editor eso se lee COMO ANTERIOR.
- La primera sección no tiene nada antes, así que toma los carriles de la canción (COMO CANCIÓN).
- El estilo, el kit y el género son los de la canción en cada sección. Nada que una sección pueda fijar.
- El nombre del preset solo sigue cuando lo hacen los cuatro mandos. Una sección que mueve un mando bajo un preset con nombre pasa a leer
CUSTOM: el nombre es una etiqueta para exactamente esos cuatro valores. Una sección que nombra un preset y no fija ningún mando lleva el nombre Y los mandos de la sección anterior: el editor siempre escribe un nombre junto con sus valores. - Quien escucha no está en la lista. Un campo que la canción deja abierto se completa con un valor por defecto fijo, parte del formato, así que el mismo documento toca la misma banda en cualquier sitio:
| Campo | Por defecto |
|---|---|
style | rock |
kit | el primer kit del estilo |
drums.off | false |
drums.feel | el primer feel del estilo |
drums.fill.in | ausente: lo decide el arreglo |
drums.fill.out | auto |
drums.variation | [] |
drums.preset | STOCK: energía 0.5, el swing propio del feel, humanize 0.15, live 0.25 |
jam.intensity | 0.5 |
jam.colorLayer | false |
jam.rhythmGuitar | según si el estilo tiene esa capa |
El swing y el live de una sección aterrizan en el reloj de la app (GRID) mientras suena la canción, y nunca se guardan como propios tuyos; los tuyos vuelven cuando sueltas la canción.
El objeto chart
{
"writtenKey": { "tonic": 9, "mode": "minor" },
"endBehavior": "end",
"sections": [
{
"id": "…",
"name": "INTRO",
"repeats": 2,
"energy": "sparse",
"color": "cyan",
"drums": { "feel": "straight", "fill": { "in": "none" } },
"items": [
{ "ref": { "degree": { "_0": { "degree": 1, "alteration": 0, "quality": { "minor": {} }, "alterations": [], "secondaryOf": false } } },
"duration": { "bars": 2, "ticks": 0 }, "rawText": "Am" },
{ "ref": { "absolute": { "_0": { "root": { "letter": "F", "accidental": 0 }, "type": { "major": {} }, "alterations": [] } } },
"duration": { "bars": 1, "ticks": 0 }, "rawText": "F" }
]
}
]
}| Campo | Significado |
|---|---|
writtenKey | La tonalidad en la que se escribió el cifrado, o ausente. Las casillas de grado se resuelven contra ella para mostrarse; al tocar siguen el módulo TONALIDAD. |
endBehavior | "end" = suena una vez, luego un último golpe en el uno sostenido un compás y la banda para. Ausente = en loop para siempre. Cadena opaca, para que un comportamiento futuro nunca rompa a los lectores antiguos. |
sections[] | El editor añade hasta 24; un archivo se lee entero. Cada una tiene id, name, repeats (1–16), energy (base, lift, groove, hold, riff, sparse, stop: un valor desconocido suena como base), un color opcional, y los dos carriles opcionales drums y jam (arriba). Una sección no lleva estilo, kit ni género de batería, ni endFill: un fill a la salida es drums.fill.out: "fill". Un campo de carril que se deja fuera siempre significa: lo que tocó la sección anterior, y en la primera sección, el carril de la canción; nunca el ajuste de quien la escucha. |
items[] | Como mucho 32 por sección. Cada uno es { ref, duration, rawText }, más un shape opcional. (más un push opcional) |
ref | Exactamente uno de degree, absolute, noChord, repeatPrevious. Swift codifica la carga bajo _0. Un grado tiene degree 1–7, alteration (−1/0/+1), quality opcional (tipo de acorde), alterations (b5 #5 b9 #9 #11 b13 add6 add9 add11 no3 no5) y secondaryOf (true = V/x). Un acorde absoluto tiene root (letter A–G + accidental), type, alterations y un bass opcional. Un degree también puede llevar bassIntervalSemitones (1–11): un bajo con barra en semitonos por encima de la fundamental del acorde, así que transpone con la tonalidad; { "degree": 1, "bassIntervalSemitones": 4 } es C/E en C y A/C♯ en A. En una nota del acorde es una inversión; fuera, un pedal. Desde 0.71 la banda toca el bajo; antes solo se mostraba. |
duration | { bars, ticks }. Los compases son relativos al tipo de compás (un acorde de 2 compases dura 2 compases en cuatro por cuatro y en tres por cuatro), los ticks son tiempo exacto dentro del compás a 24 ticks por tiempo, así que { "bars": 0, "ticks": 48 } son dos tiempos. Los compases se limitan a 0–32. El editor escribe cualquier número de tiempos (un cambio en el tiempo 4 es { "bars": 0, "ticks": 72 } y luego { "bars": 0, "ticks": 24 }), y una sección no tiene por qué sumar compases enteros. |
rawText | Lo que escribió el guitarrista o lo que mostraba la casilla al escribirse. Solo para mostrar: un cifrado puede enseñar I donde el acorde que suena es Em. |
shape | La forma de guitarra que eligió el guitarrista, como etiqueta autodescriptiva: seis trastes de la sexta a la primera cuerda, x para cuerda apagada, p. ej. x32010. Los trastes de 10 o más necesitan separadores (8-10-10-9-8-8), y @n indica un traste base que no se puede deducir de las notas (x24442@2). Los trastes van de 0 a 24. Ausente significa que la app dibuja su propia forma por defecto. Los silencios y las repeticiones nunca llevan una. Una forma es una elección libre, no una propiedad del acorde (un guitarrista elige un voicing de Em7 en una casilla de Em), así que nada la valida contra el acorde, y una etiqueta ilegible significa “sin forma”, no una canción inválida. |
push | "eighth" o "sixteenth" cuando el acorde está anticipado (desde 0.71): la banda lo ataca ese tanto antes de su sitio escrito y lo mantiene sobre el tiempo. El sitio y la duración nunca se mueven; el conteo de compases, el cabezal y el rebobinado no saben nada de la anticipación. Ausente = en el tiempo; un valor desconocido se lee como ausente; nunca se escribe "none". En el texto de la canción la anticipación es un acento circunflejo: ^G, ^^G. |
Los tipos de acorde son los 24 nombres del ChordType de la app: major minor diminished augmented sus2 sus4 major7 minor7 dominant7 diminished7 halfDiminished7 minorMajor7 augmented7 add9 major9 minor9 dominant9 major11 minor11 dominant11 major13 minor13 dominant13 power. En el archivo, ese nombre es la clave de un objeto vacío, { "minor7": {} }, tanto bajo type como bajo quality.
Lo que la app acepta al importar
importSongs prueba tres formas en orden y se queda con la primera que descodifica:
- un documento
.noisesong{ "version": …, "song": { … } }, - un objeto song suelto,
- una exportación de biblioteca entera
{ "version": …, "songs": [ … ] }: se importa cada canción que esta versión sabe leer; las ilegibles se omiten, nunca el archivo entero.
En cualquier forma, una canción con schemaVersion menor que 3 se omite: la app anota por qué, y no se convierte nada.
El enlace noise://
El botón Abrir en NØISE de la web, y el botón Copiar enlace a su lado, producen este enlace. La app no hace enlaces; solo los lee.
noise://song?d=<payload>- esquema
noise, hostsong, un parámetro de consultad; <payload>es el documento.noisesongcodificado en compacto (sin espacios, claves ordenadas,version: 3,schemaVersion: 3) como base64url (RFC 4648 §5,-y_en vez de+y/, sin relleno=).
Cuando la app abre un enlace así, descodifica la carga con las mismas reglas que un archivo. Es tolerante: una carga que llega con relleno o en percent-encoding también se descodifica. Como el JSON no va comprimido, un enlace ocupa más o menos 1,4 veces el JSON compacto: una canción de cuatro secciones son unos pocos kilobytes. Un enlace más largo de lo que acepta tu chat se comparte mejor como archivo.
Abrir un enlace nunca añade nada en silencio: la app pregunta antes. Mira Importar.
Dónde está tu biblioteca
Todas las canciones están en un solo archivo, dentro del contenedor de la app:
~/Library/Containers/com.noise-app.macos/Data/Library/Application Support/NØISE/jam-songs.jsonSe escribe de forma atómica; en cada guardado correcto la versión anterior se conserva como jam-songs.json.bak, y un archivo principal corrupto se restaura en silencio desde la copia (la copia corrupta se conserva como jam-songs.json.corrupt). La biblioteca guarda como mucho 100 canciones; a partir de ahí, al guardar se descartan las canciones actualizadas hace más tiempo. Una biblioteca escrita antes del esquema 3 se aparta como jam-songs.v2.json en el primer arranque de 0.81 y la biblioteca empieza vacía: las canciones no se convierten, se escriben de nuevo en el editor.
Aviso
No edites jam-songs.json con NØISE abierto: la app escribe el archivo entero en cada guardado y pisará tus cambios. Exporta un .noisesong, edita ese, e impórtalo de vuelta.