Skip to content

Instantly share code, notes, and snippets.

@m4saka
Forked from albshin/kshon
Last active May 5, 2022 14:06
Show Gist options
  • Save m4saka/a89594a17dc9422d75e01998bcfd2722 to your computer and use it in GitHub Desktop.
Save m4saka/a89594a17dc9422d75e01998bcfd2722 to your computer and use it in GitHub Desktop.
modified version of: https://bmson-spec.readthedocs.io/en/master/doc/index.html
Encoding: UTF-8 (without BOM), LF
// 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
BpmEvent[]? time_sig_events; // time signature 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
double init_bpm; // initial bpm (needed for specifying the bpm before the first tick)
TimeSignature init_time_sig; // initial time signature (needed for specifying the time signature before the first tick)
// (NOT optional, in order to avoid time signature events without KsonInfo.init_time_signature)
DOMString? disp_bpm; // displayed bpm (allowed characters: 0-9, "-", ".")
// If not specified, KsonInfo.init_bpm will be used.
// 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
}
// time signature change
// this is for drawing bar lines, deducing time signature,
// and calculating duration of length parameters for audio effects
dictionary TimeSignatureEvent {
unsigned long index; // Measure No. (not a tick value)
TimeSignature v; // time signature value
}
// time signature
dictionary TimeSignature {
unsigned long n; // numerator
unsigned long d; // denominator
}
// notes on each lane
dictionary NoteInfo {
BTNote[][]? bt; // bt notes (first index: lane)
FXNote[][]? fx; // fx notes (first index: lane)
LaserSection[][]? laser; // laser notes (first index: lane (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 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 section
dictionary LaserSection {
LaserPoint[] points;
unsigned char wide = 1; // 1-2, sets this section to be a 2x wide sections or not
}
// laser point
dictionary LaserPoint {
unsigned long y; // pulse number
int v; // laser x-axis position value (-100 - 100)
int? vf; // second x-axis value (specified if this is a laser slam)
AudioEffectInfo? audio_effect; // audio effects (and parameter changes if needed)
Spin? spin; // lane spin (valid only when vf is specified)
any? key_sound; // slam sound (valid only when vf is specified)
// - DOMString: preset sound name
// - unsigned long: corresponds to KeySound.id
// If not specified, the default slam sound will be used.
}
// lane spin
dictionary Spin {
unsigned long y; // pulse number
unsigned long l; // 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 index: lane)
AudioEffectEvent[][]? laser; // audio effects for laser lanes (first index: lane (0: left knob, 1: right knob))
}
// key sound (laser slam / chip fx)
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 l; // for smoothing
}
*/
// camera event list
dictionary CameraEventInfo {
CameraEvent[]? zoom; // zoom_bottom
CameraEvent[]? shift_x; // zoom_side
CameraEvent[]? rotation_x; // zoom_top
}
// camera event
dictionary CameraEvent {
unsigned long y; // pulse number
unsigned long l; // length (for linear transition)
long v; // value
long? vf; // second value (for an immediate change)
}
// stop event
dictionary StopEvent {
unsigned long y; // pulse number
unsigned long l; // stop duration (pulses to stop)
}
// bpm event
dictionary BpmEvent {
unsigned long y; // pulse number
double v; // bpm
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment