NØISEDE

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": { … }
}
FeldTypBedeutung
versionintegerVersion des Dateiformats; 3 seit 0.81.
songobjectDer 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": { … }
}
FeldTypPflichtBedeutung
idUUID stringjaIdentitä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.
namestringjaName des Songs.
chartobjectjaDas Akkordschema (unten).
stylestringneinDer 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.
tempoHintnumberneinDas Tempo des Songs; wird beim Laden auf die Session angewendet.
songDescriptionstringneinFreie Notizen (notes: im Textformat).
authorstringneinWer ihn geschrieben hat.
kitstringneinDas 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.
drumsobjectneinDie DRUMS-Zeile des Songs – wovon jeder Teil ausgeht. Siehe Die Zeilen.
jamobjectneinDie JAM-Zeile des Songs – dasselbe.
tuningstringneinGuitarTuning.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.
capoGanzzahlneinDer 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.
grooveSeedGanzzahlneinDer 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.
sourceIdUUID stringneinDer Song, aus dem dieser importiert oder abgeleitet wurde (Herkunft geteilter Songs).
schemaVersionintegerja3. Alles Niedrigere, oder fehlend, wird nicht gelesen – weder von der App noch von dieser Website.
createdAt, updatedAtdatejaZeitstempel.

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:

FeldWerteBedeutung
offtrue / falseDas Kit schweigt in diesem Teil (Solo-Raum).
feelein 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.incrash, splash, none, chokeDas 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.outauto, 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).
variationeine Liste von WörternDie Overlays des Stils. Die Datei trägt sie mit; die App hat noch keine Wörter dafür.
preset.nameSTOCK, TIGHT, DRIVING, LAID BACK, LOOSE, SMOKY, QUIET, ein eigenes des Spielers, oder CUSTOMEin LABEL für die vier Regler darunter. Die Werte reisen mit; der Name liest sich.
preset.energy0–1Wie hart das Kit spielt.
preset.swing0–1Das Raster, 0 straight … 1 volle Triole. Fehlt es, gilt der eigene Swing des Feels.
preset.humanize0–1Wie stark eine Hand um den Part schwankt.
preset.live0–1Wie viel geschriebenes Detail (Ghosts, die Bar-4-Variante) hörbar wird.

jam – die Flags der Band:

FeldWerteBedeutung
intensity0–1Wie dicht die Band spielt.
colorLayertrue / falseDie vierte Ebene der Band (Farbe).
rhythmGuitartrue / falseDie 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.in setzt, 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:
FeldStandard
stylerock
kitdas erste Kit des Stils
drums.offfalse
drums.feeldas erste Feel des Stils
drums.fill.infehlt – das Arrangement entscheidet
drums.fill.outauto
drums.variation[]
drums.presetSTOCK: energy 0.5, der eigene Swing des Feels, humanize 0.15, live 0.25
jam.intensity0.5
jam.colorLayerfalse
jam.rhythmGuitarob 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" }
      ]
    }
  ]
}
FeldBedeutung
writtenKeyDie 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)
refGenau 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.
rawTextWas 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.
shapeDer 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:

  1. ein .noisesong-Dokument { "version": …, "song": { … } },
  2. ein nacktes Song-Objekt,
  3. 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.

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, Host song, ein Query-Parameter d;
  • <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.json

Sie 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.