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
// - laser curves
// - lane swing (with a camera macro with curves?)
// - BGA layer?
// top-level object
dictionary kson {
DOMString version; // kson version
MetaInfo meta; // meta data, e.g. title, artist, ...
BeatInfo beat; // beat-related data, e.g. bpm, time signature, ...
NoteInfo? note; // notes on each lane
AudioInfo? audio; // audio-related data
CameraInfo? camera; // camera-related data
}
/* ------------------------------------------------------------------ */
/* ------------------------------ META ------------------------------ */
/* ------------------------------------------------------------------ */
// meta data
dictionary MetaInfo {
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? disp_bpm; // displayed bpm (allowed characters: 0-9, "-", ".")
// If not specified, KsonInfo.init_bpm will be used.
// All the other metadata fields
...
}
// 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
}
/* ------------------------------------------------------------------ */
/* ------------------------------ BEAT ------------------------------ */
/* ------------------------------------------------------------------ */
// beat-related data
dictionary BeatInfo {
BpmEvent[]? bpm; // bpm changes
TimeSignatureEvent[]? time_sig; // time signature changes
StopEvent[]? stop; // stop events
unsigned long resolution = 240; // pulses per quarter note
}
// bpm event
dictionary BpmEvent {
unsigned long y; // pulse number
double v; // bpm
}
// 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 pulse value)
TimeSignature v; // time signature value
}
// time signature
dictionary TimeSignature {
unsigned long n; // numerator
unsigned long d; // denominator
}
// stop event
dictionary StopEvent {
unsigned long y; // pulse number
unsigned long l; // stop duration (pulses to stop)
}
/* ------------------------------------------------------------------ */
/* ------------------------------ NOTE ------------------------------ */
/* ------------------------------------------------------------------ */
// 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)
any? key_sound; // chip sound (valid only when l == 0)
// - DOMString: preset sound name
// - unsigned long: corresponds to KeySound.id
}
// laser section
dictionary LaserSection {
unsigned long y; // pulse number
LaserPoint[] point; // laser points
unsigned char wide = 1; // 1-2, sets this section to be a 2x wide sections or not
}
// laser point
dictionary LaserPoint {
unsigned long ry; // pulse number relative to LaserSection.y
int v; // laser x-axis position value (-100 - 100)
int? vf; // second x-axis value (specified if this is a laser slam)
CameraMacroEvent? camera_macro; // lane spin etc. (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.
}
/* ------------------------------------------------------------------- */
/* ------------------------------ AUDIO ------------------------------ */
/* ------------------------------------------------------------------- */
// audio-related data
dictionary AudioInfo {
KeySoundDef[]? key_sound_def; // key sounds for chip FX & laser slams
AudioEffectDef[]? audio_effect_def; // audio effect definitions
AudioEffectEventInfo? audio_effect; // audio effect events on each lane
}
// key sound definition (laser slam / chip fx)
dictionary KeySoundDef {
unsigned long id; // id
DOMString filename; // key sound filename
}
// 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? param;
}
// 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 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 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))
}
// audio effect event
dictionary AudioEffectEvent {
DOMString name; // corresponds to AudioEffectDef.name
AudioEffectParamInfo? param; // specified if you want to change values
// (e.g. FX note with Retrigger 8th: {"waveLength":["1/8"]})
}
/* -------------------------------------------------------------------- */
/* ------------------------------ CAMERA ------------------------------ */
/* -------------------------------------------------------------------- */
// camera-related data
dictionary CameraInfo {
CameraEventInfo[]? event; // camera events
//CameraMacroDef[]? macro_def; // camera macro definitions (for future use)
TiltEventInfo[]? tilt; // tilt-related events
}
// tilt-related events
dictionary TiltEventInfo {
TiltManualSection[]? manual; // manual tilt
TiltKeepEvent[]? keep; // tilt keep
CameraEventInfo? camera_assign; // tilt=>camera value translation (for NORMAL/BIGGER/BIGGEST tilt scales)
}
// Note: the default value of "camera_assign" is
// {"lane_rotation_z":[{"y":0, "v":7}], "jdgline_shift_x":[{"y":0, "v":?? (depends on clients) }], "jdgline_rotation_z":[{"y":0, "v":7}]}
// manual tilt section
dictionary TiltManualSection {
unsigned long y; // pulse number
TiltPoint[] point; // camera value points
}
// manual tilt point
dictionary TiltManualPoint {
unsigned long ry; // pulse number relative to TiltManualSection.y
long v; // value (normal tilt: -100 - 100)
long? vf; // second value (for an immediate change)
}
// tilt keep
dictionary TiltKeepEvent {
unsigned long y; // pulse number
unsigned long l; // duration (pulses to keep)
}
// camera macro definition (for future use)
dictionary CameraMacroDef {
DOMString name; // name of the camera macro (e.g. "spin")
/* something */
}
// Note: "spin" & "half_spin" & "swing" are predefined by kson clients.
// camera macro event (spin etc., currently used in laser slams)
dictionary CameraMacroEvent {
DOMString name; // corresponds to CameraMacroDef.name
unsigned long l; // duration
long scale; // scale(%), e.g. left spin: -100, right spin: 100
}
// camera event list
dictionary CameraEventInfo {
CameraValuePoint[]? lane_zoom; // zoom_bottom
CameraValuePoint[]? lane_shift_x; // zoom_side
CameraValuePoint[]? lane_rotation_x; // zoom_top
CameraValuePoint[]? lane_rotation_z; // lane rotation (degree)
CameraValuePoint[]? jdgline_shift_x; // judgment line x
CameraValuePoint[]? jdgline_rotation_z; // judgment line rotation (degree)
}
// camera value point
dictionary CameraValuePoint {
unsigned long y; // pulse number
long v; // value
long? vf; // second value (for an immediate change)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment