Skip to content

Instantly share code, notes, and snippets.

@albshin

albshin/kshon Secret

Last active February 2, 2019 01:25
Show Gist options
  • Save albshin/cf535afc3f94f7d7f7c7e3d1d9ff41cf to your computer and use it in GitHub Desktop.
Save albshin/cf535afc3f94f7d7f7c7e3d1d9ff41cf to your computer and use it in GitHub Desktop.
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