{"id":13652655,"url":"https://github.com/soundio/sequence-json","last_synced_at":"2025-04-23T03:31:07.922Z","repository":{"id":23905398,"uuid":"27285406","full_name":"soundio/sequence-json","owner":"soundio","description":"A way of creating music sequence data in JSON","archived":false,"fork":true,"pushed_at":"2024-05-09T23:04:29.000Z","size":148,"stargazers_count":132,"open_issues_count":5,"forks_count":5,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-05-22T08:06:05.297Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"cruncher/music-json-spec","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/soundio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-28T23:22:47.000Z","updated_at":"2024-05-16T06:52:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/soundio/sequence-json","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundio%2Fsequence-json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundio%2Fsequence-json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundio%2Fsequence-json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soundio%2Fsequence-json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soundio","download_url":"https://codeload.github.com/soundio/sequence-json/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250365420,"owners_count":21418686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T02:01:01.338Z","updated_at":"2025-04-23T03:31:03.183Z","avatar_url":"https://github.com/soundio.png","language":null,"funding_links":[],"categories":["Format Extensions","Others"],"sub_categories":[],"readme":"# Sequence JSON\n\nA simple format for representing sequences of timed events in JSON.\n\nThis format defines a minimal set of events that get music working, with the objective of supporting applications \nof the WebAudio and WebMIDI APIs. However, it is designed to be extensible. Consumers of Sequence JSON are expected \nto silently ignore unsupported event types so that users may also sequence their own data.\n\n\n## Concepts\n\nThe Sequence format defines two data structures, a Sequence object and an Event array.\n\nSequenceJSON describes all times and durations in beats. Beat values are arbitrary, and depend on the rate of playback \nof a sequence. A sequence playing back at a rate of `1` is running at 1 beat per second, so it is following absolute time.\n\n## Example JSON\n\nHere are the first two bars of Dolphin Dance represented as a sequence in JSON:\n\n```json\n{\n    \"name\": \"Dolphin Dance\",\n    \"events\": [\n        [0,   \"meter\", 4, 1],\n        [0,   \"rate\", 2, \"step\"],\n        [2,   \"note\", 76, 0.8, 0.5],\n        [2.5, \"note\", 77, 0.6, 0.5],\n        [3,   \"note\", 79, 1, 0.5],\n        [3.5, \"note\", 74, 1, 3.5],\n        [10,  \"note\", 76, 1, 0.5],\n        [0,   \"chord\", \"C\", \"∆\", 4],\n        [4,   \"chord\", \"G\", \"-\", 4]\n    ]\n}\n```\n\n\n## Sequence\n\n```json\n{\n    \"events\": [...]\n}\n```\n\n`events` – ARRAY\u003cbr/\u003e\nAn array of events.\n\nAn `events` property is the only requirement for a top-level sequence. Sequences may also have the properties:\n\n```json\n{\n    \"id\": \"0\",\n    \"name\": \"My Sequence\",\n    \"author\": {...},\n    \"url\":  \"https://...\",\n    \"sequences\": [...]\n}\n```\n\n`id` – STRING\u003cbr/\u003e\nin any array of sequences it must be unique, and is used to identify the sequence for playback.\nA top level sequence does not require an `id`.\n\n`name` – STRING, optional\u003cbr/\u003e\nAn arbitrary string.\n\n`author` – OBJECT, optional\u003cbr/\u003e\nAn object containing details of the author.\n\n`url` – URL STRING, optional\u003cbr/\u003e\nPoints to a resource where this sequence can be fetched as JSON.\n\n`sequences`  – ARRAY, optional\u003cbr/\u003e\nAn array of sequence objects.\nSequences are played back by `\"sequence\"` events in the `events` array.\nIf there are no `\"sequence\"` events  in the `events` array, the property `sequences` is not required.\n\n---\n\n## Event\n\n```js\n[beat, type, ...]\n```\n\n`beat` – FLOAT\u003cbr/\u003e\nDescribes a point in time from the start of the sequence in beats.\n\n`type` – STRING\u003cbr/\u003e\nThe event type, determines the length of the event array and the structure of the rest of its values:\n\n| beat   | type         | 2 | 3 | 4 | 5 |\n| :----- | :----------- | :--- | :--- | :--- | :--- |\n| `beat` | `\"note\"`     | `pitch` | `dynamic` | `duration` |  |\n| `beat` | `\"param\"`    | `name` | `value` | `curve` | `duration` |\n| `beat` | `\"rate\"`     | `number` |  |  |  |\n| `beat` | `\"meter\"`    | `duration` | `divisor` |  |  |\n| `beat` | `\"chord\"`    | `root` | `mode` | `duration` |  |\n| `beat` | `\"key\"`      | `name` |  |  |  |\n| `beat` | `\"sequence\"` | `id` | `target` | `duration` |  |\n| `beat` | `\"start\"`    | reserved |  |  |  |\n| `beat` | `\"stop\"`     | reserved |  |  |  |\n\n\n\n\n---\n\n### `\"note\"`\n\n```js\n[beat, \"note\", name, dynamic, duration]\n```\n\n`name` – FLOAT [0-127] or STRING\u003cbr/\u003e\nRepresents the pitch of a note.\nIf `name` is a number, it is a MIDI note number, but may be a float and so can represent any frequency. MIDI note number `69` is `440Hz`.\nIf `name` is a string it is an arbitrary pitch name. Implementations must accept at least the 128 pitch names `'C0'` - `'G9'`, and \nthe use of both the hash `#` and the unicode sharp `♯`, and both the small letter `b` and the unicode flat `♭` in their spellings, but\noutput only the unicode spellings in any Sequence data output.\n\n`dynamic` – FLOAT [0-1]\u003cbr/\u003e\nRepresents the force of the note's attack.\nA `dynamic` larger than `1` is permissible, but negative `dynamic` is invalid.\n\n`duration` – FLOAT [0-n]\u003cbr/\u003e\nRepresents the duration of the note in beats.\n\n---\n\n### `\"param\"`\n\n```js\n[beat, \"param\", name, value]\n[beat, \"param\", name, value, curve]\n[beat, \"param\", name, value, \"target\", duration]\n```\n\n`name` – STRING\u003cbr/\u003e\nThe name of the param to control.\nIn a WebAudio context this would typically map to an AudioParam on the instrument being targetted.\n\n`value` – FLOAT\u003cbr/\u003e\nThe destination value of the param.\n\n`curve` – STRING `\"step\"`, `\"linear\"`, `\"exponential\"` or `\"target\"`\u003cbr/\u003e\nThe ramp to use for transition to `value`.\nThis parameter is optional. If it is not present the event describes a `\"step\"` curve.\nIf `curve` is `\"target\"` the event has a fifth parameter:\n\n`duration` – FLOAT\u003cbr/\u003e\nThe decay time of the `\"target\"` curve.\n\n---\n\n### `\"rate\"`\n\n```js\n[beat, \"rate\", rate]\n[beat, \"rate\", rate, curve]\n[beat, \"rate\", rate, \"target\", duration]\n```\n\n`rate`  – FLOAT\u003cbr/\u003e\nRate of playback of a sequence. Nominally in beats per second, but sequences may be played\nfrom other sequences, and rates are accumulative. If sequence A is playing at rate `2` and \ncontains sequence B playing at rate `1.5`, sequence B is playing at an absolute rate of `3`,\nor 3 beats per second, a tempo of 90bpm.\n\n`curve` – STRING, optional\u003cbr/\u003e\nOne of `\"step\"`, `\"linear\"`, `\"exponential\"` or `\"target\"`. \nRepresents the type of ramp to use to transition to the new rate. Where `curve` is `\"target\"` a duration is required:\n\n`duration` – STRING, optional\u003cbr/\u003e\nWhere `curve` is `\"target\"`, represents the target duration of the target curve.\n\nWhere there is no `\"rate\"` event at beat `0`, consumers should assume a playback rate of `2`,\nas if there were an initial `[0, \"rate\", 2]` event in the data. A rate of `2` is a tempo of 120bpm.\n\n\n---\n\n### `\"meter\"`\n\n```js\n[beat, \"meter\", duration, division]\n```\n\n`duration` – INT\u003cbr/\u003e\nThe duration of a bar, in beats.\n\n`division` – INT\u003cbr/\u003e\nThe duration of a division, in beats.\n\nHere are some common time signatures as meter events:\n\n| time | event |\n| :--- | :---- |\n| 4/4  | `[0, \"meter\", 4, 1]` |\n| 3/4  | `[0, \"meter\", 3, 1]` |\n| 6/8  | `[0, \"meter\", 3, 0.5]` |\n| 2/4  | `[0, \"meter\", 2, 1]` |\n| 7/8  | `[0, \"meter\", 3.5, 0.5]` |\n\nA meter event MUST occur at a beat that is a full bar from a previous meter event. The second event here is valid:\n\n```json\n[0, \"meter\", 4, 1]\n[4, \"meter\", 3, 1]\n```\n\nWhere here it is invalid:\n\n```json\n[0, \"meter\", 4, 1]\n[2, \"meter\", 3, 1]\n```\n\nConsumers may choose to recover from invalid `\"meter\"` events by pushing them to the start of the following bar,\nor choose to throw an error.\n\nMeter events have no effect on the rate of the beat clock (although they may have an effect on a metronome or \nrhythm generator). Where no `\"meter\"` event is defined at beat `0` consumers should assume a default meter of \n4/4 - ie, `[0, \"meter\", 4, 1]`.\n\n---\n\n### `\"chord\"`\n\n```js\n[beat, \"chord\", root, mode, duration]\n```\n\n`root` – INT [0-11] or STRING, represents the root of a chord.\nWhere `root` is a number it represents root note as a MIDI number `0-11`.\nWhere `root` is a string it must be a root note name, ie. `C`, `C♯`, `D` ... `A`, `B♭`, `B`.\n\n`mode` – STRING, represents the mode of a chord.\nThe mode identifier may be arbitrary, but these mode names have fixed meanings:\n\n| Symbol     | Meaning |\n| :--------- | :----------------------------------- |\n| `\"∆♯11\"`   | 4th mode of the major scale (lydian) |\n| `\"∆\"`      | 1st mode of the major scale (ionian) |\n| `\"7\"`      | 5th mode of the major scale (myxolydian) |\n| `\"-7\"`     | 2nd mode of the major scale (dorian) |\n| `\"-♭6\"`    | 6th mode of the major scale (aoelian) |\n| `\"7sus♭9\"` | 3rd mode of the major scale (phrygian) |\n| `\"ø\"`      | 7th mode of the major scale (locrian) |\n| `\"7♯11\"`   | 4th mode of melodic minor |\n| `\"-∆\"`     | 1st mode of melodic minor |\n| `\"∆♭6\"`    | 5th mode of melodic minor |\n| `\"-♭9\"`    | 2nd mode of melodic minor |\n| `\"ø7\"`     | 6th mode of melodic minor |\n| `\"∆♯5\"`    | 3rd mode of melodic minor |\n| `\"7alt\"`   | 7th mode of melodic minor |\n| `\"°\"`      | Diminished whole tone / half tone |\n| `\"7♭9\"`    | Diminished half tone / whole tone |\n| `\"+7\"`     | Whole tone |\n\n`duration` – FLOAT, the duration of the chord in beats.\n\nA chord event provides information about the root and mode of the music. A chord event can \nbe interpreted by a music generator, or used by a notation renderer to display chord symbols.\n\n---\n\n### `\"key\"`\n\n```js\n[beat, \"key\", name]\n```\n\n`name` – STRING\u003cbr/\u003e\nThe name of a major key, a capital letter followed optionally by an accidental, as in `\"A♭\"`, `\"A\"`, `\"A♯\"`, `\"B♭\"`, `\"B\"`, `\"C\"`, and so on up to `\"G♯\"`.\n\nRepresents a visual key change in written notation only. Does not affect how a performance sounds.\n\u003cblockquote\u003eHarmonic generators should use `\"chord\"` events to generate sound based on modes.\u003c/blockquote\u003e\n\n---\n\n### `\"sequence\"`\n\n```js\n[beat, \"sequence\", sequenceId, targetId, duration]\n```\n\n`sequenceId` – STRING\u003cbr/\u003e\nThe id of a sequence found in the `sequences` array\n\n`targetId`   – STRING\u003cbr/\u003e\nThe id of an instrument to play the sequence through.\n\n`duration`   – FLOAT\u003cbr/\u003e\nThe duration in beats to play the sequence.\n\nRenders a sequence from the `sequences` array. For example, this event plays the sequence \"my-sequence\" at beat `0.5` for `3` beats:\n\n```json\n[0.5, \"sequence\", \"my-sequence\", 3]\n```\n\n\u003cblockquote\u003eTBD. It is not clear exactly how to spec targetId to select a target instrument in an interoperable manner. In Soundstage, it refers to the id of a node in the `nodes` array, where nodes are WebAudio nodes in the Soundstage graph.\u003c/blockquote\u003e\n\n---\n\n### `\"start\"`\n\n```js\n[beat, \"start\", identifier, value]\n```\n\nReserved event name. Basically, both `\"note\"` and `\"sequence\"` events, which have duration, may be decomposed into matching `\"start\"` and `\"stop\"` events without duration in internal implementations.\nNeither should appear in exported SequenceJSON.\n\n---\n\n### `\"stop\"`\n\n```js\n[beat, \"stop\", identifier, value]\n```\n\nReserved event name. See `\"start\"`.\n\n---\n\n## Implementations\n\n- \u003ca href=\"http://github.com/soundio/soundstage\"\u003eSoundstage\u003c/a\u003e is a WebAudio wrapper and playback sequencer that consumes and outputs Sequence JSON.\n- \u003ca href=\"http://github.com/stephband/scribe/\"\u003eScribe\u003c/a\u003e is a music notation interpreter and HTML renderer that consumes and outputs Sequence JSON. It also parses ABC notation to Sequence JSON, as well as a sequence text format that is basically Sequence JSON without any of the JSON syntax or quote marks, just spaces between values.\n\n## References\n\n- OSC spec: \u003ca href=\"http://opensoundcontrol.org/spec-1_0\"\u003ehttp://opensseqoundcontrol.org/spec-1_0\u003c/a\u003e\n- OSC example messages: \u003ca href=\"http://opensoundcontrol.org/files/OSC-Demo.pdf\"\u003ehttp://opensoundcontrol.org/files/OSC-Demo.pdf\u003c/a\u003e\n- Music XML: \u003ca href=\"http://www.musicxml.com/for-developers/\"\u003ehttp://www.musicxml.com/for-developers/\u003c/a\u003e\n- VexFlow: \u003ca href=\"http://www.vexflow.com/\"\u003ehttp://www.vexflow.com/\u003c/a\u003e\n\n\u003c!--\n## Contributions\n\nStephen Band, Stelio Tzonis, Al Johri and Jason Sigal.\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoundio%2Fsequence-json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoundio%2Fsequence-json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoundio%2Fsequence-json/lists"}