NØISEEN

Songs & sharing

The .noisesong file and the noise:// link

What a .noisesong file contains, how the noise:// deep link encodes it, and the limits both obey.

A song leaves NØISE in one of two machine-readable forms: a .noisesong file (JSON) or a noise:// link (the same JSON, encoded into a URL). Neither contains audio. Both carry exactly one song.

Warning

Schema 3, since NØISE 0.81 — with no backward compatibility. A song is ONE band with ONE kit, and a section sets its DRUMS and JAM lanes. The app reads nothing older than schema 3: a file with schemaVersion 2 or none opens as nothing, and an older library is set aside on first launch. This site refuses such a file at upload with the same words. Open the song in the app's editor and export it again.

The .noisesong file

EXPORT — in the SONGS plate and in the editor — writes a UTF-8 JSON document. The file type is registered by the app as nl.weap.noise.song ("NØISE Song", conforms to public.json, extension .noisesong), so double-clicking a file opens it in NØISE.

Envelope

{
  "version": 3,
  "song": { … }
}
FieldTypeMeaning
versionintegerFile format version; 3 since 0.81.
songobjectThe song.

Keys are written sorted and pretty-printed. Dates are ISO-8601 in UTC without fractional seconds (2026-05-01T12:00:00Z) — the app rejects fractional seconds.

The song object

{
  "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": { … }
}
FieldTypeRequiredMeaning
idUUID stringyesIdentity of the song. Importing a song whose id already exists in your library never merges with it — the import gets a fresh UUID and becomes a new, separate song, with the original id recorded in sourceId so the lineage isn't lost.
namestringyesSong name.
chartobjectyesThe chord chart (below).
stylestringnoThe JAM style of the whole song: pop, rock, blues, jazz, hiphop, funk, metal. Absent = rock. The drum genre follows from it (pop → POP, rock → ROCK, … hiphop → HIP-HOP) and is not a field. While the song plays the band plays the song's own band; your own DRUMS and JAM panels come back when the song is put down.
tempoHintnumbernoThe song's tempo; applied to the session when the song loads.
songDescriptionstringnoFree notes (notes: in the text format).
authorstringnoWho wrote it.
kitstringnoThe one JAM kit of the whole song, an id scoped to the style (pop.strings, rock.classic, metal.stock, …). Absent = the style's first kit. A kit of another style is ignored.
drumsobjectnoThe song's DRUMS lane — what every section starts from. See The lanes.
jamobjectnoThe song's JAM lane — the same.
tuningstringnoGuitarTuning.id: standard, dropD, halfStepDown, fullStepDown, dropC, openG, openD, dadgad. Applied to the session when the song loads, like the key and the tempo — not a hint. Absent means standard: a song that names no tuning is written in standard, and loading it sets that.
capointegernoThe fret the song's capo sits on, 0–9 (since 0.71). Applied on load like the tuning: absent or 0 means no capo, and loading the song takes one off. The chart stays in the shape key; the band and the detectors sound that many frets up.
grooveSeedintegernoThe author's groove seed. Every seeded choice the band makes — which of the authored bass and pad bars, the fills, the approach notes, the drum phrase, the walk-outs into the next chord — is drawn from it, so a shared song plays the same way on every Mac and iPad. Absent = a stable hash of the song's id. The app writes one when a new song is saved and stamps the effective seed on export, like the key. A whole number below 2^53, so every JSON reader - JavaScript included - reads it exactly.
sourceIdUUID stringnoThe song this one was imported or forked from (lineage of shared songs).
schemaVersionintegeryes3. Anything lower, or none, is not read — by the app or by this site.
createdAt, updatedAtdateyesTimestamps.

feel, drumStyle, drumEnergy, drumHumanize, jamIntensity, colorLayer and rhythmGuitar no longer exist at song level: they live inside drums and jam. A song from a newer app never fails on an extra key; unknown keys are kept on a round trip.

The lanes

The same two blocks sit on the song (what every section starts from) and on a section (what it says itself). Every field is optional and means "not set here" — see the resolution rule.

drums — what a section says to the kit:

FieldValuesMeaning
offtrue / falseThe kit is silent for this section (solo space).
feela GrooveFeel tag from the style's list (straight, halfTime, shuffle, swing, …)The groove — one feel for the drums AND the band. A feel the style does not offer resolves to the style's first.
fill.incrash, splash, none, chokeThe cymbal on the section's ONE. Absent = the arrangement decides from the transition. choke is carried, not yet played (plays as a crash).
fill.outauto, fill, none, break, or a fill's name (busy, tom roll, fill2, …)What the kit does on the section's way out, on the LAST bar of the last repeat. auto = the arrangement decides; fill = a fill whatever the transition; none = never; a name = that fill of the genre's bank (unknown → auto). break is carried, not yet played (plays as none).
variationa list of wordsThe style's overlays. Carried by the file; the app has no words for it yet.
preset.nameSTOCK, TIGHT, DRIVING, LAID BACK, LOOSE, SMOKY, QUIET, a player's own, or CUSTOMA LABEL for the four knobs below. The values travel; the name reads.
preset.energy0–1How hard the kit plays.
preset.swing0–1The grid, 0 straight … 1 full triplet. Absent = the feel's own swing.
preset.humanize0–1How much a hand wavers around the part.
preset.live0–1How much authored detail (ghosts, the bar-4 variant) is revealed.

jam — the band's flags:

FieldValuesMeaning
intensity0–1How busy the band plays.
colorLayertrue / falseThe band's fourth (colour) layer.
rhythmGuitartrue / falseThe band's strumming layer, where the style has one.

The resolution rule

Every lane field resolves in one order, per field:

SECTION → THE SECTION BEFORE IT → SONG
  • A section that sets a field decides it. A section that sets fill.in and nothing else decides the cymbal and follows for everything else.
  • A section that leaves a field open plays what the section before it played — say HALF TIME once and it carries on until something says otherwise. In the editor that reads FOLLOW PREV.
  • The first section has nothing before it, so it takes the song's lanes (FOLLOW SONG).
  • The style, the kit and the genre are the song's on every section. Nothing a section can say.
  • The preset name follows only when every knob does. A section that moved one knob under a named preset reads CUSTOM: the name is a label for exactly those four values. A section that names a preset and sets no knob carries the name AND the knobs of the section before it — the editor always writes a name with its values.
  • The listener is not in the list. A field the song leaves open is completed with a fixed default, part of the format, so the same document plays the same band everywhere:
FieldDefault
stylerock
kitthe style's first kit
drums.offfalse
drums.feelthe style's first feel
drums.fill.inabsent — the arrangement decides
drums.fill.outauto
drums.variation[]
drums.presetSTOCK: energy 0.5, the feel's own swing, humanize 0.15, live 0.25
jam.intensity0.5
jam.colorLayerfalse
jam.rhythmGuitarwhether the style has the layer at all

A section's swing and live land on the app's clock (GRID) while the song plays and are never saved as the player's own; the player's come back when the song is put down.

The chart object

{
  "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" }
      ]
    }
  ]
}
FieldMeaning
writtenKeyThe key the chart was written in, or absent. Degree cells resolve against it for display; while playing they follow the KEY module.
endBehavior"end" = play once, then a final downbeat hit held for a bar and the band stops. Absent = loop forever. Opaque string, so future behaviours never break older readers.
sections[]The editor adds up to 24; a file is read in full. Each has id, name, repeats (1–16), energy (base, lift, groove, hold, riff, sparse, stop — an unknown value plays as base), an optional color, and the two optional lanes drums and jam (above). A section carries no style, kit or drum genre, and no endFill — a fill on the way out is drums.fill.out: "fill". A lane field left out always means: what the section before it played, and for the first section the song's lane — never the listener's own setting.
items[]At most 32 per section. Each is { ref, duration, rawText }, plus an optional shape and an optional push.
refExactly one of degree, absolute, noChord, repeatPrevious. Swift encodes the payload under _0. A degree has degree 1–7, alteration (−1/0/+1), optional quality (chord type), alterations (b5 #5 b9 #9 #11 b13 add6 add9 add11 no3 no5) and secondaryOf (true = V/x), plus an optional bassIntervalSemitones (1–11): a slash bass as semitones above the chord's root, so it transposes with the key — { "degree": 1, "bassIntervalSemitones": 4 } is C/E in C and A/C♯ in A. On a chord tone it is an inversion, off it a pedal. An absolute chord has root (letter A–G + accidental), type, alterations and optional bass (a note name). Since 0.71 the band plays the bass; before, it was display only.
duration{ bars, ticks }. Bars are time-signature relative (a 2-bar chord is 2 bars in 4/4 and in 3/4), ticks are exact sub-bar time at 24 ticks per beat, so { "bars": 0, "ticks": 48 } is two beats. The editor writes any number of beats (a change on beat 4 is { "bars": 0, "ticks": 72 } then { "bars": 0, "ticks": 24 }), and a section need not add up to whole bars. Bars are clamped to 0–32.
rawTextWhat the user typed or what the cell showed when it was written. Display only — a chart can show I where the sounding chord is Em.
shapeThe guitar grip the player chose, as a self-describing tag: six frets low E to high e, x for muted, e.g. x32010. Frets of 10 or more need separators (8-10-10-9-8-8), and @n states a base fret that cannot be derived from the notes (x24442@2). Frets are 0–24. Absent means the app draws its own default grip. Rests and repeats never carry one. A grip is a free choice, not a property of the chord — players pick an Em7 voicing on an Em cell — so nothing validates it against the chord, and an unreadable tag simply means "no grip" rather than an invalid song.
push"eighth" or "sixteenth" when the chord is anticipated (since 0.71): the band strikes it that much before its written place and holds it over the beat. The place and the duration never move — bar counts, the playhead and winding know nothing of a push. Absent = on the beat; an unknown value reads as absent; the value is never written as "none". In the song text a push is a caret: ^G, ^^G.

Chord types are the 24 names of the app's ChordType: 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 the file such a name is the key of an empty object, { "minor7": {} }, under type as well as under quality.

What the app accepts on import

importSongs tries three shapes in order and takes the first that decodes:

  1. a .noisesong document { "version": …, "song": { … } },
  2. a bare song object,
  3. a whole library export { "version": …, "songs": [ … ] } — every song that this build can read is imported; unreadable ones are skipped, never the whole file.

In every shape a song with schemaVersion below 3 is skipped: the app logs why, and nothing is converted.

The website's Open in NØISE button, and the Copy link button beside it, produce this link. The app makes no links itself; it only reads them.

noise://song?d=<payload>
  • scheme noise, host song, one query parameter d;
  • <payload> is the .noisesong document encoded compactly (no whitespace, sorted keys, version: 3, schemaVersion: 3) as base64url (RFC 4648 §5, - and _ instead of + and /, no = padding).

When the app opens such a link it decodes the payload with the same rules as a file. It is tolerant: a payload that arrives padded or percent-encoded still decodes. Because the JSON is not compressed, a link is roughly 1.4 × the size of the compact JSON — a four-section song is a few kilobytes. Links longer than what your chat client accepts should be shared as a file instead.

Opening a link never adds anything silently: the app asks first. See Import.

Where your library lives

All songs are stored in one file, inside the app's container:

~/Library/Containers/com.noise-app.macos/Data/Library/Application Support/NØISE/jam-songs.json

It is written atomically; the previous version is kept as jam-songs.json.bak on every successful save, and a corrupt main file is silently restored from the backup (the corrupt copy is kept as jam-songs.json.corrupt). The library holds at most 100 songs; beyond that the least recently updated songs are dropped on save. A library written before schema 3 is set aside as jam-songs.v2.json on the first launch of 0.81 and the library starts empty — the songs are not converted, they are written again in the editor.

Warning

Do not edit jam-songs.json while NØISE is running — the app writes the whole file on every save and will overwrite your changes. Export a .noisesong, edit that, and import it back.