Songs & Teilen
Die .noisesong-Datei und der noise://-Link
Was eine .noisesong-Datei enthält, wie der noise://-Link sie codiert, und welche Grenzen für beide gelten.
Ein Song verlässt NØISE in einer von zwei maschinenlesbaren Formen: als .noisesong-Datei (JSON) oder als noise://-Link (dasselbe JSON, in eine URL codiert). Keine von beiden enthält Audio. Beide tragen genau einen Song.
Achtung
Schema 3, seit NØISE 0.81 – ohne Rückwärtskompatibilität. Ein Song ist EINE Band mit EINEM Kit, und ein Teil setzt seine DRUMS- und JAM-Zeilen. Die App liest nichts, was älter ist als Schema 3: Eine Datei mit schemaVersion 2 oder ohne öffnet sich als nichts, und eine ältere Bibliothek wird beim ersten Start beiseitegelegt. Diese Website weist so eine Datei beim Hochladen mit denselben Worten ab. Öffne den Song im Editor der App und exportier ihn erneut.
Die .noisesong-Datei
EXPORT – im SONGS-Panel und im Editor – schreibt ein JSON-Dokument in UTF-8. Die App registriert den Dateityp als nl.weap.noise.song („NØISE Song“, entspricht public.json, Endung .noisesong), also öffnet ein Doppelklick auf die Datei sie in NØISE.
Der Umschlag
{
"version": 3,
"song": { … }
}| Feld | Typ | Bedeutung |
|---|---|---|
version | integer | Version des Dateiformats; 3 seit 0.81. |
song | object | Der Song. |
Die Schlüssel werden sortiert und lesbar eingerückt geschrieben. Datumsangaben sind ISO-8601 in UTC ohne Sekundenbruchteile (2026-05-01T12:00:00Z): Sekundenbruchteile weist die App ab.
Das Song-Objekt
{
"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": { … }
}| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
id | UUID string | ja | Identität des Songs. Ein Import, dessen id schon in deiner Bibliothek liegt, wird nie zusammengeführt: der Import bekommt eine neue UUID und wird ein eigener, getrennter Song, mit der ursprünglichen id in sourceId, damit die Herkunft nicht verloren geht. |
name | string | ja | Name des Songs. |
chart | object | ja | Das Akkordschema (unten). |
style | string | nein | Der JAM-Stil des ganzen Songs: pop, rock, blues, jazz, hiphop, funk, metal. Fehlt er, gilt rock. Das Drum-Genre folgt daraus (pop → POP, rock → ROCK, … hiphop → HIP-HOP) und ist kein eigenes Feld. Solange der Song läuft, spielt die Band die eigene Band des Songs; deine eigenen DRUMS- und JAM-Panels kommen zurück, wenn du den Song weglegst. |
tempoHint | number | nein | Das Tempo des Songs; wird beim Laden auf die Session angewendet. |
songDescription | string | nein | Freie Notizen (notes: im Textformat). |
author | string | nein | Wer ihn geschrieben hat. |
kit | string | nein | Das eine JAM-Kit des ganzen Songs, eine id gültig im Stil (pop.strings, rock.classic, metal.stock, …). Fehlt es, gilt das erste Kit des Stils. Ein Kit eines anderen Stils wird ignoriert. |
drums | object | nein | Die DRUMS-Zeile des Songs – wovon jeder Teil ausgeht. Siehe Die Zeilen. |
jam | object | nein | Die JAM-Zeile des Songs – dasselbe. |
tuning | string | nein | GuitarTuning.id: standard, dropD, halfStepDown, fullStepDown, dropC, openG, openD, dadgad. Wird beim Laden auf die Session angewendet, wie Tonart und Tempo – kein Hinweis. Fehlt es, gilt Standard: Ein Song, der keine Stimmung nennt, ist in Standard geschrieben, und Laden stellt die Session darauf. |
capo | Ganzzahl | nein | Der Bund, auf dem der Kapo des Songs sitzt, 0–9 (seit 0.71). Beim Laden angewendet wie die Stimmung: fehlt er oder steht 0, heißt das kein Kapo, und Laden nimmt ihn ab. Das Schema bleibt in der Grifftonart; Band und Erkennung klingen so viele Bünde höher. |
grooveSeed | Ganzzahl | nein | Der Groove-Seed des Autors. Jede Wahl, die die Band aus dem Seed zieht (welcher der geschriebenen Bass- und Pad-Takte, die Fills, der Anlauf im Bass, die Drum-Phrase, der Walking Bass in den nächsten Akkord), kommt daraus: ein geteilter Song spielt auf jedem Mac und iPad gleich. Fehlt er, gilt ein fester Hash der id des Songs. Die App schreibt einen, wenn ein neuer Song gesichert wird, und trägt beim Export den wirksamen Seed ein, wie die Tonart. Eine Ganzzahl unter 2^53, damit jeder JSON-Leser - auch JavaScript - sie exakt liest. |
sourceId | UUID string | nein | Der Song, aus dem dieser importiert oder abgeleitet wurde (Herkunft geteilter Songs). |
schemaVersion | integer | ja | 3. Alles Niedrigere, oder fehlend, wird nicht gelesen – weder von der App noch von dieser Website. |
createdAt, updatedAt | date | ja | Zeitstempel. |
feel, drumStyle, drumEnergy, drumHumanize, jamIntensity, colorLayer und rhythmGuitar gibt es auf Song-Ebene nicht mehr: Sie liegen jetzt in drums und jam. Ein Song aus einer neueren App scheitert nie an einem zusätzlichen Schlüssel; unbekannte Schlüssel bleiben bei einem Roundtrip erhalten.
Die Zeilen
Dieselben zwei Blöcke stehen am Song (wovon jeder Teil ausgeht) und an einem Teil (was er selbst sagt). Jedes Feld ist optional und heißt „hier nicht gesetzt" – siehe die Auflösungsregel.
drums – was ein Teil dem Kit sagt:
| Feld | Werte | Bedeutung |
|---|---|---|
off | true / false | Das Kit schweigt in diesem Teil (Solo-Raum). |
feel | ein GrooveFeel-Tag aus der Liste des Stils (straight, halfTime, shuffle, swing, …) | Der Groove – ein Feel für Drums UND Band. Ein Feel, das der Stil nicht anbietet, löst sich zum ersten Feel des Stils auf. |
fill.in | crash, splash, none, choke | Das Becken auf der Eins des Teils. Fehlt es, entscheidet das Arrangement aus dem Übergang. choke wird mitgeführt, aber noch nicht gespielt (klingt wie crash). |
fill.out | auto, fill, none, break, oder der Name eines Fills (busy, tom roll, fill2, …) | Was das Kit beim Ausgang aus dem Teil tut, im LETZTEN Takt der letzten Wiederholung. auto = das Arrangement entscheidet; fill = ein Fill, gleich welcher Übergang; none = nie; ein Name = dieser Fill aus der Bank des Genres (unbekannt → auto). break wird mitgeführt, aber noch nicht gespielt (klingt wie none). |
variation | eine Liste von Wörtern | Die Overlays des Stils. Die Datei trägt sie mit; die App hat noch keine Wörter dafür. |
preset.name | STOCK, TIGHT, DRIVING, LAID BACK, LOOSE, SMOKY, QUIET, ein eigenes des Spielers, oder CUSTOM | Ein LABEL für die vier Regler darunter. Die Werte reisen mit; der Name liest sich. |
preset.energy | 0–1 | Wie hart das Kit spielt. |
preset.swing | 0–1 | Das Raster, 0 straight … 1 volle Triole. Fehlt es, gilt der eigene Swing des Feels. |
preset.humanize | 0–1 | Wie stark eine Hand um den Part schwankt. |
preset.live | 0–1 | Wie viel geschriebenes Detail (Ghosts, die Bar-4-Variante) hörbar wird. |
jam – die Flags der Band:
| Feld | Werte | Bedeutung |
|---|---|---|
intensity | 0–1 | Wie dicht die Band spielt. |
colorLayer | true / false | Die vierte Ebene der Band (Farbe). |
rhythmGuitar | true / false | Die Rhythmusgitarre der Band, wo der Stil eine hat. |
Die Auflösungsregel
Jedes Feld einer Zeile löst sich in einer Reihenfolge auf, pro Feld:
TEIL → DER TEIL DAVOR → SONG- Ein Teil, der ein Feld setzt, entscheidet es. Ein Teil, der nur
fill.insetzt, entscheidet das Becken und folgt bei allem anderen. - Ein Teil, der ein Feld offen lässt, spielt, was der Teil davor gespielt hat – sag einmal HALF TIME, und es bleibt so, bis etwas anderes es setzt. Im Editor heißt das WIE DAVOR.
- Der erste Teil hat nichts davor, also übernimmt er die Zeilen des Songs (WIE DER SONG).
- Stil, Kit und Genre gehören dem Song, in jedem Teil. Nichts, was ein Teil sagen kann.
- Der Preset-Name folgt nur, wenn jeder Regler folgt. Ein Teil, der unter einem benannten Preset einen Regler bewegt, liest sich als
CUSTOM: der Name ist ein Label für genau diese vier Werte. Ein Teil, der ein Preset nennt und keinen Regler setzt, übernimmt den Namen UND die Regler des Teils davor – der Editor schreibt einen Namen immer mit seinen Werten. - Der Hörer steht nicht in der Liste. Ein Feld, das der Song offen lässt, wird mit einem festen Standard ergänzt, Teil des Formats, damit dasselbe Dokument überall dieselbe Band spielt:
| Feld | Standard |
|---|---|
style | rock |
kit | das erste Kit des Stils |
drums.off | false |
drums.feel | das erste Feel des Stils |
drums.fill.in | fehlt – das Arrangement entscheidet |
drums.fill.out | auto |
drums.variation | [] |
drums.preset | STOCK: energy 0.5, der eigene Swing des Feels, humanize 0.15, live 0.25 |
jam.intensity | 0.5 |
jam.colorLayer | false |
jam.rhythmGuitar | ob der Stil die Ebene überhaupt hat |
swing und live eines Teils landen, solange der Song läuft, auf der Clock der App (GRID) und werden nie als die eigenen des Spielers gesichert; die eigenen des Spielers kommen zurück, wenn du den Song weglegst.
Das Chart-Objekt
{
"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" }
]
}
]
}| Feld | Bedeutung |
|---|---|
writtenKey | Die Tonart, in der das Schema geschrieben wurde, oder fehlend. Stufen-Felder werden für die Anzeige gegen sie aufgelöst; beim Spielen folgen sie dem KEY-Modul. |
endBehavior | "end" = einmal spielen, dann ein letzter Schlag auf der Eins, einen Takt gehalten, und die Band stoppt. Fehlend = endlos loopen. Ein opaker String, damit künftige Verhalten ältere Leser nie brechen. |
sections[] | Der Editor fügt bis zu 24 hinzu; eine Datei wird vollständig gelesen. Jeder Teil hat id, name, repeats (1–16), energy (base, lift, groove, hold, riff, sparse, stop – ein unbekannter Wert spielt als base), ein optionales color, und die zwei optionalen Zeilen drums und jam (oben). Ein Teil trägt keinen Stil, kein Kit und kein Drum-Genre, und kein endFill – ein Fill beim Ausgang ist drums.fill.out: "fill". Ein Feld einer Zeile, das offenbleibt, heißt immer: was der Teil davor gespielt hat, und beim ersten Teil die Zeile des Songs – nie die eigene Einstellung des Hörers. |
items[] | Höchstens 32 pro Teil. Jedes ist { ref, duration, rawText }, plus ein optionales shape. (dazu ein optionales push) |
ref | Genau eines von degree, absolute, noChord, repeatPrevious. Swift legt den Inhalt unter _0 ab. Eine Stufe hat degree 1–7, alteration (−1/0/+1), optional quality (Akkordtyp), alterations (b5 #5 b9 #9 #11 b13 add6 add9 add11 no3 no5) und secondaryOf (true = V/x). Ein absoluter Akkord hat root (letter A–G + accidental), type, alterations und optional bass. Ein degree kann zudem bassIntervalSemitones (1–11) tragen: einen Slash-Bass als Halbtöne über dem Grundton des Akkords, so transponiert er mit der Tonart – { "degree": 1, "bassIntervalSemitones": 4 } ist C/E in C und A/C♯ in A. Auf einem Akkordton eine Umkehrung, daneben ein Orgelpunkt. Seit 0.71 spielt die Band den Bass; vorher wurde er nur angezeigt. |
duration | { bars, ticks }. Takte sind relativ zur Taktart (ein Akkord über 2 Takte ist 2 Takte im Vierviertel und im Dreiviertel), Ticks sind exakte Zeit innerhalb des Takts bei 24 Ticks pro Zählzeit, also ist { "bars": 0, "ticks": 48 } zwei Zählzeiten. Takte werden auf 0–32 begrenzt. Der Editor schreibt beliebig viele Zählzeiten (ein Wechsel auf der Vier ist { "bars": 0, "ticks": 72 }, dann { "bars": 0, "ticks": 24 }), und ein Teil muss nicht auf ganze Takte kommen. |
rawText | Was der Spieler getippt hat oder was das Feld beim Schreiben zeigte. Nur für die Anzeige: ein Schema kann I zeigen, wo der klingende Akkord Em ist. |
shape | Der Griff, den der Spieler gewählt hat, als selbsterklärendes Tag: sechs Bünde von der tiefen zur hohen Saite, x für gedämpft, z. B. x32010. Bünde ab 10 brauchen Trenner (8-10-10-9-8-8), und @n nennt einen Grundbund, der sich aus den Tönen nicht ableiten lässt (x24442@2). Bünde sind 0–24. Fehlt es, zeichnet die App ihren Standardgriff. Pausen und Wiederholungen tragen nie einen. Ein Griff ist freie Wahl, keine Eigenschaft des Akkords – Spieler legen ein Em7-Voicing auf ein Em-Feld –, also prüft nichts ihn gegen den Akkord, und ein unlesbares Tag heißt schlicht „kein Griff“, nicht „ungültiger Song“. |
push | "eighth" oder "sixteenth", wenn der Akkord antizipiert ist (seit 0.71): die Band schlägt ihn so viel vor seiner geschriebenen Stelle an und hält ihn über die Zählzeit. Stelle und Dauer rühren sich nie; Taktzählung, Abspielkopf und Spulen wissen nichts davon. Fehlt = auf der Zählzeit; ein unbekannter Wert liest sich als fehlend; "none" wird nie geschrieben. Im Songtext ist die Antizipation ein Zirkumflex: ^G, ^^G. |
Akkordtypen sind die 24 Namen des ChordType der 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. In der Datei ist so ein Name der Schlüssel eines leeren Objekts, { "minor7": {} }, unter type wie unter quality.
Was die App beim Import annimmt
importSongs probiert drei Formen der Reihe nach und nimmt die erste, die sich lesen lässt:
- ein
.noisesong-Dokument{ "version": …, "song": { … } }, - ein nacktes Song-Objekt,
- einen ganzen Bibliotheksexport
{ "version": …, "songs": [ … ] }: jeder Song, den dieser Build lesen kann, wird importiert; unlesbare werden übersprungen, nie die ganze Datei.
In jeder Form wird ein Song mit schemaVersion unter 3 übersprungen: die App protokolliert, warum, und nichts wird konvertiert.
Der noise://-Link
Die Taste In NØISE öffnen auf der Website, und Link kopieren daneben, erzeugen diesen Link. Die App macht selbst keine Links; sie liest sie nur.
noise://song?d=<payload>- Schema
noise, Hostsong, ein Query-Parameterd; <payload>ist das.noisesong-Dokument, kompakt codiert (keine Leerzeichen, sortierte Schlüssel,version: 3,schemaVersion: 3) als base64url (RFC 4648 §5,-und_statt+und/, kein=als Füllzeichen).
Öffnet die App so einen Link, decodiert sie den Inhalt nach denselben Regeln wie eine Datei. Sie ist nachsichtig: ein Inhalt, der mit Füllzeichen oder prozentcodiert ankommt, wird trotzdem gelesen. Weil das JSON nicht komprimiert ist, ist ein Link etwa 1,4-mal so groß wie das kompakte JSON: ein Song mit vier Teilen ist ein paar Kilobyte groß. Ist ein Link länger, als dein Chat-Programm annimmt, teil stattdessen die Datei.
Beim Öffnen eines Links landet nie still etwas in der Bibliothek: die App fragt erst. Siehe Import.
Wo deine Bibliothek liegt
Alle Songs liegen in einer Datei, im Container der App:
~/Library/Containers/com.noise-app.macos/Data/Library/Application Support/NØISE/jam-songs.jsonSie wird atomar geschrieben; bei jedem erfolgreichen Sichern bleibt die vorige Version als jam-songs.json.bak erhalten, und eine beschädigte Hauptdatei wird still aus dem Backup wiederhergestellt (die beschädigte Kopie bleibt als jam-songs.json.corrupt liegen). Die Bibliothek fasst höchstens 100 Songs; darüber fallen beim Sichern die am längsten nicht geänderten Songs weg. Eine Bibliothek, die vor Schema 3 geschrieben wurde, wird beim ersten Start von 0.81 als jam-songs.v2.json beiseitegelegt, und die Bibliothek startet leer – die Songs werden nicht konvertiert, sondern im Editor neu geschrieben.
Achtung
Ändere jam-songs.json nicht, während NØISE läuft: die App schreibt bei jedem Sichern die ganze Datei und überschreibt deine Änderungen. Exportier eine .noisesong-Datei, ändere die und importier sie wieder.