-
-
Save m4saka/a89594a17dc9422d75e01998bcfd2722 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
modified version of: https://bmson-spec.readthedocs.io/en/master/doc/index.html | |
// TODO List | |
// - lane swing | |
// - lane tilt | |
// - laser curves | |
// - BGA layer? | |
// top-level object | |
dictionary kson { | |
DOMString version; // kson version | |
KsonInfo info; // information, e.g. title, artist, ... | |
BarLine[]? lines; // location of bar-lines in pulses | |
BpmEvent[]? bpm_events; // bpm changes | |
StopEvent[]? stop_events; // stop events | |
CameraEventInfo? camera_events; // camera events | |
KeySound[]? key_sounds; // key sounds for chip FX & laser slams | |
NoteInfo[]? notes; // notes on each lane | |
AudioEffectDef[]? audio_effects; // audio effect definitions | |
AudioEffectEventInfo[]? audio_effect_events; // audio effect events on each lane | |
} | |
// header information | |
dictionary KsonInfo { | |
DOMString title; // self-explanatory | |
DOMString? title_translit; // transliterated title | |
DOMString? subtitle; // self-explanatory, can be a CD title or a music genre | |
DOMString artist; // self-explanatory | |
DOMString? artist_translit; // transliterated artist | |
DifficultyInfo difficulty; // self-explanatory | |
unsigned int level; // self-explanatory, 1-20 | |
DOMString bpm; // self-explanatory (is this needed?) | |
double init_bpm; // initial bpm (needed for specifying bpm before the first tick) | |
// All the other metadata fields | |
... | |
unsigned long resolution = 240; // pulses per quarter note | |
} | |
// chart difficulty (or custom chart name) | |
dictionary DifficultyInfo { | |
DOMString name; // e.g. "Challenge", "Infinity", "Gravity", "Maximum", "FOUR DIMENSIONS" | |
DOMString? short_name; // e.g. "CH", "IN", "GRV", "MXM", "FD" | |
// (if not specified, it inherits the client defaults based on "index". e.g. 1=>"CH") | |
unsigned char index; // 0-4 e.g. "CH"=>1, "IN"/"GRV"=>3, "MXM"/"FD"=>4 | |
} | |
// bar-lines | |
// this is for drawing bar lines, deducing time signature, | |
// and calculating duration of length parameters for audio effects | |
dictionary BarLine { | |
unsigned long y; // pulse number | |
} | |
// notes on each lane | |
dictionary NoteInfo { | |
BTNote[][]? bt; // bt notes (first key: lane index) | |
FXNote[][]? fx; // fx notes (first key: lane index) | |
LaserNote[][]? laser; // laser notes (first key: lane index (0: left knob, 1: right knob)) | |
} | |
// BT note | |
dictionary BTNote { | |
unsigned long y; // pulse number | |
unsigned long l; // length (0: normal note; greater than zero (length in pulses): long note) | |
} | |
// FX note | |
dictionary FXNote { | |
unsigned char x; // lane (0-1) | |
unsigned long y; // pulse number | |
unsigned long l; // length (0: normal note; greater than zero (length in pulses): long note) | |
AudioEffectInfo? audio_effect; // audio effects (and parameter changes if needed) | |
any? key_sound; // chip sound (valid only when l == 0) | |
// - DOMString: preset sound name | |
// - unsigned long: corresponds to KeySound.id | |
} | |
// laser note | |
dictionary LaserNote { | |
unsigned char x; // lane (0: left knob, 1: right knob) | |
unsigned long y; // pulse number | |
unsigned long l; // length (0: slam; greater than zero (length in pulses): long note) | |
int a; // laser x-axis position (-100 - 100) | |
AudioEffectInfo? audio_effect; // audio effects (and parameter changes if needed) | |
Spin? spin; // lane spin (valid only when l == 0) | |
any? key_sound; // slam sound (valid only when l == 0) | |
// - DOMString: preset sound name | |
// - unsigned long: corresponds to KeySound.id | |
// If not specified, the default slam sound will be used. | |
} | |
// Note: Two laser notes are connected if (y == prev.y + prev.l) is satisfied. | |
// If the next note is not connected to the current one, it is treated as a straightforward laser note. | |
// lane spin | |
dictionary Spin { | |
unsigned long y; // pulse number | |
unsigned long duration; // spin duration | |
long degree; // spin in degrees (negative is left and positive is right) | |
} | |
// audio effect parameter settings | |
dictionary AudioEffectParamInfo { | |
// Custom fields per FX | |
// | |
// ex1) "type=Flanger;delay=80samples;depth=30samples-60samples" in KSH | |
// type: "Flanger", | |
// delay: ["80samples"], | |
// depth: ["30samples", "30samples", "60samples"] | |
// | |
// ex2) "type=TapeStop;trigger=off>on;speed=20%" in KSH | |
// type: "TapeStop", | |
// trigger: ["off", "on"], | |
// depth: ["20%"] | |
} | |
// audio effect definition | |
dictionary AudioEffectDef { | |
DOMString name; // name of the audio effect (e.g. "LowFlanger") | |
DOMString type; // name of the audio effect to inherit (e.g. "Flanger") | |
AudioEffectParamInfo? params; | |
} | |
// Note: Preset audio effects ("Retrigger", "Gate", "Flanger"...) are implicitly defined in default. | |
// If an audio effect with the same name as a preset effect, implicitly defined presets will be overwritten. | |
// | |
// FX and laser share the audio effect definition itself, | |
// but the instances of audio effects are created for each, and they work in parallel. | |
// audio effect event | |
dictionary AudioEffectEvent { | |
DOMString name; // name of the audio effect (e.g. "LowFlanger") | |
AudioEffectParamInfo? params; // specified if you want to change values | |
// (e.g. FX note with Retrigger 8th: {"waveLength":["1/8"]}) | |
} | |
// audio effect events on each lane | |
dictionary AudioEffectEventInfo { | |
AudioEffectEvent[][]? fx; // audio effects for FX lanes (first key: lane index) | |
AudioEffectEvent[][]? laser; // audio effects for laser lanes (first key: lane index (0: left knob, 1: right knob)) | |
} | |
dictionary KeySound { | |
unsigned long id; // id | |
DOMString name; // key sound filename | |
} | |
/* NEED TO DISCUSS!! (this also can be implemented as a type of camera events which controls the offset of the lane background texture...) | |
// hide event | |
// for songs like "I" where the lane hides itself | |
dictionary HideEvent { | |
unsigned long y; // pulse number | |
unsigned long duration; // for smoothing | |
} | |
*/ | |
// camera events | |
dictionary CameraEventInfo { | |
CameraEvent[]? distance; // zoom_bottom | |
CameraEvent[]? shift_x; // zoom_side | |
CameraEvent[]? rotation_x; // zoom_top | |
} | |
// camera event | |
dictionary CameraEvent { | |
unsigned long y; // pulse number | |
unsigned long duration; // for smoothing | |
long value; // self-explanatory | |
} | |
// stop event | |
dictionary StopEvent { | |
unsigned long y; // pulse number | |
unsigned long duration; // stop duration (pulses to stop) | |
} | |
// bpm event | |
dictionary BpmEvent { | |
unsigned long y; // pulse number | |
double bpm; // bpm | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment