-
-
Save albshin/cf535afc3f94f7d7f7c7e3d1d9ff41cf 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 | |
// top-level object | |
dictionary kshon { | |
DOMString version; // kshon version | |
KshonInfo info; // information, e.g. title, artist, … | |
BarLine[]? lines; // location of bar-lines in pulses | |
BpmEvent[]? bpm_events; // bpm changes | |
StopEvent[]? stop_events; // stop events | |
HideEvent[]? hide_events; // hide events | |
ZoomEvent[]? zoom_events; // zoom events | |
SpinEvent[]? spin_events; // spin events | |
Note[]? notes; // note data | |
FXNote[]? fx_notes; // fx note data | |
Laser[]? lasers; // laser data | |
} | |
// header information | |
dictionary KshonInfo { | |
DOMString title; // self-explanatory | |
DOMString artist; // self-explanatory | |
DOMString chart_name; // e.g. "HYPER", "FOUR DIMENSIONS" | |
DOMString difficulty; // enum e.g. "EXH", "ADV" | |
unsigned long level; // self-explanatory | |
DOMString bpm; // self-explanatory | |
// All the other metadata fields | |
... | |
unsigned long resolution = 240; // pulses per quarter note | |
} | |
// bar-lines | |
// this is purely for drawing bar lines and deducing time signature | |
dictionary BarLine { | |
unsigned long y; // pulse number | |
} | |
// sound note | |
dictionary Note { | |
any x; // lane (this could be something like A,B,C,D) | |
unsigned long y; // pulse number | |
unsigned long l; // length (0: normal note; greater than zero (length in pulses): long note) | |
} | |
// fx note | |
dictionary ButtonFX { | |
any type; // the type of FX (bitcrusher,flanger,none,etc) | |
// Custom fields per FX | |
// ex) | |
// type: "Flanger", | |
// delay: 80, | |
// depth: "60samples" | |
} | |
// laserfx event | |
dictionary LaserFX { | |
any type; // e.g. peaking,hipass | |
// add custom parameters here | |
} | |
// slamfx event | |
dictionary SlamFX { | |
any type; // e.g. up,down,swing,mute | |
unsigned int vol; // volume of slam | |
// add custom parameters here | |
} | |
// sound note | |
dictionary FXNote { | |
any x; // lane (this could be something like A,B) | |
unsigned long y; // pulse number | |
unsigned long l; // length (0: normal note; greater than zero (length in pulses): long note) | |
ButtonFX fx; // The FX related to the FXNote | |
} | |
dictionary LaserPoint { | |
unsigned long y; // pulse number | |
long axis; // probably something like -100.0 to 100.0 | |
boolean slam; // whether or not the point is a slam | |
// If not set, the point will inherit the FX attributes from the previous point in the array | |
LaserFX? laser_fx; // FX that should play during this laser | |
SlamFX? slam_fx; // FX that should play during this slam | |
} | |
// If you wanted to create a slam, you would add two consecutive points to the "points" array on a laser | |
// both having "slam=true" and two separate axis values. | |
// lasers | |
dictionary Laser { | |
any side; // determine laser left or laser right | |
LaserPoint[] points; // points | |
} | |
// hide event | |
// for songs like "I" where the lane hides itself | |
dictionary HideEvent { | |
unsigned long y; // pulse number | |
unsigned long duration; // for smoothing | |
} | |
// zoom event | |
dictionary ZoomEvent { | |
unsigned long y; // pulse number | |
unsigned long duration; // for smoothing | |
DOMString side; // top/bottom/side | |
long zoom; // value of the zoom | |
} | |
// spin event | |
dictionary SpinEvent { | |
unsigned long y; // pulse number | |
unsigned long duration; // for smoothing | |
long degrees; // spin in degrees (negative is left and positive is right) | |
} | |
// 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 | |
} | |
==================Let's say that we want to add a Mine (DDR) into the spec================== | |
dictionary Mine { | |
unsigned long y; // pulse number | |
} | |
dictionary kshon { | |
DOMString version; // kshon version | |
KshonInfo info; // information, e.g. title, artist, … | |
BarLine[]? lines; // location of bar-lines in pulses | |
BpmEvent[]? bpm_events; // bpm changes | |
StopEvent[]? stop_events; // stop events | |
HideEvent[]? hide_events; // hide events | |
ZoomEvent[]? zoom_events; // zoom events | |
SpinEvent[]? spin_events; // spin events | |
Note[]? notes; // note data | |
FXNote[]? fx_notes; // fx note data | |
Laser[]? lasers; // laser data | |
// Add mine array here | |
Mine[]? mines; // mine data | |
} | |
With this spec, we can easily add new object types and event types without touching pre-existing ones. | |
Older versions of KSH will never try to interpret mines. | |
==================First measure of Azul (remix)================== | |
1/32th | |
Time signature: 2/4 | |
240 Pulses = 1 Beat | |
480 Pulses per measure | |
-- | |
beat=2/4 | |
t=97.5 | |
1010|00|-- PULSE: (0/32 * 480) = 0 | |
0000|00|-- | |
1001|00|-- PULSE: (2/32 * 480) = 30 | |
0000|00|-- | |
1010|00|-- PULSE: (4/32 * 480) = 60 | |
0000|00|-- | |
0100|00|-- | |
0000|00|-- | |
1010|00|-- PULSE: (8/32 * 480) = 120 | |
0000|00|-- | |
0000|00|-- | |
0000|00|-- | |
0101|00|-- PULSE: (12/32 * 480) = 180 | |
0000|00|-- | |
0000|00|-- | |
0000|00|-- | |
0000|0F|0- PULSE: (16/32 * 480) = 240 | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0001|0F|:- | |
0000|0F|:- | |
0000|0F|:- | |
0000|0F|:- PULSE: (31/32 * 480) = 465 | |
-- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment