SVGC

From MMS Wiki
Jump to: navigation, search

SVGC, short for SVG Collection is the internal file format used in creating score visuals and synthesized audio tracks for exercises. It was originally developed to be exported from MuseScore and meant only for internal use.

SVGC files are accompanied with a partsfile that gives specific information on how the pieces provided in the SVGC are to be assembled into an exercise.

SVGC files have the .svc extension. In terms of structure, they are zip files, with the following structure:

  • One folder for each set of visuals used. The folder has the SVG-s, one per system, as well as a metainfo.json describing the mapping between the svg-s and the underlying audio
  • midi files to be synthesized into audio, as described in partsfile

Metainfo format

The format is JSON with the following structure:

{
"title": "...",
"subtitle": "...",
"composer": "...",
"instruments": ["Voice", "Piano"],

"ppm": 63,
"time_signature": [2,2],

"total_ticks": 26880,
"total_time": 266.6625,

"systems": [
{
    "width": 12960,
    "height": 3860,
    "img": "0/System_1.svg",
    "staves": [[0.02, 0.3471503], [0.5544041, 0.98]],

    "bticks": [0, 192, 384, 576, 768],
    "btimes": [0, 1.905, 3.81, 5.715, 7.62],
    "blines": [0.1975309, 0.3811728, 0.5632716, 0.7453704, 0.9259259],
    "bbeats": [2, 2, 2, 2],
    "birreg": [0, 0, 0, 0],

    "first_note_hz": 523.25,

    "ticks": [0, 72, 96, 144, 192, 264, 288, 336, 384, 456, 480, 528, 576, 648, 672, 720],
    "times": [0, 0.715, 0.9525, 1.4275, 1.905, 2.62, 2.8575, 3.3325, 3.81, 4.525, 4.7625, 5.2375, 5.715, 6.4275, 6.6675, 7.1425],
    "notes": [0.212963, 0.2638889, 0.2947531, 0.337963, 0.3950617, 0.4459876, 0.4768519, 0.5200617, 0.5771605, 0.6280864, 0.6589506, 0.7021605, 0.7592593, 0.8101852, 0.8410494, 0.8842593],
    "is_change": [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1],
    "is_rest": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    "pitches": [[72, 65, 53], [], [72, 65], [72, 65], [73, 65, 49], [], [73, 65], [73, 65], [72, 63, 44], [], [72, 63], [72, 63], [], [70, 63], [70, 63], [70, 63]],

    "jumps": [{"time": 30.89, "from_pos": 0.7314815, "to_pos": 0.9212963}]
},
...
],
"csystem": <same format as a single system>
}

  • time_signature and ppm refer to the beginning values. Having them change within the piece is not a problem.
  • total_ticks / total_time (o*) refer to the time where all audio stops, i.e. the last note-off
  • first_note_hz should give the first note, in hz. Useful if an alternative tuning is used in the actual recording
  • staves gives the vertical positions of the different staffs for voices, so a staff could be overlaid with a highlighting if needed. Currently unused.
  • Things prefixed with b refer to "bar". There needs to be one value per bar. blines also has one extra for the end line of the last bar.
- bticks is the starting ticks of the bars (o*)
- btimes is the start time of the bar (o*) 
- blines is the horiz. pos on svg
- bbeats is the beat count of each of the bars
- birreg should be 1 for irregular bars like pickup measures so that they would be "made full" when giving the count-in
  • Rest of the arrays need to have one value per note/rest
- ticks is the tick at which the event is (o*)
- times is the time at which it takes place (o*)
- notes is the horiz. pos of the event on the svg
- is_change is 1 unless nothing happens musically at this position i.e. the current event is slurred together with the previous, or both are rests in all voices
- is_rest marks if it is a full rest in all voices or not
- pitches should list all the pitches (in MIDI numbering) that should currently be sounding. For monophonic tracks, it can be a single level deep, with -1 for rests i.e. [72,-1,65,49,...]
  • csystem is a special system for horizontal scrolling view

(o*) - Either "times" or "ticks" value needs to be present. If "times" is provided, it takes precedence, but if not, it is calculated based on "ticks" and the onsets map in partsfile.

Partsfile

The format is JSON with the following structure:

{
"onsets": { "ticks": [...], "times": [...] },
"scale_tempo": 1.0,
"pad_midi": 0.0,

"audiotracks": {
 "midi_1,2":{
   "parts": ["1","2"],
   "monophonic": true,
   "voice": true,
   "synthesize": true
 },...
},
"excerpts": [
    {
        "name": "Full",
        "instrument": "Multiple",
        "excerpt": "0",
        "show_order": 0,
        "onsets": [<times in seconds of onsets>]
        "etalon": "midi_1,2",
        "audio": "midi_1,2",
        "backing": null
    },..
]
}

  • Excerpt should have the name of the folder in svgc the visual of which should be used
  • "onsets" inside the excerpt should be trimmed so that it starts at the beginning of the first actually audible note, and has the last onset at the close of the last audible note.

Refactor plan

The current format conflates data concerning visuals and data concerning audio tracks to a very large degree. This is because the format was initially intended for internal use and we are trying to retain backwards compatibility for now. There is a plan to make this decoupling a lot stronger in the future:

  • Add two json files to the root: audiotracks.json and general.json
  • general.json should contain
- title, subtitle, composer, exporter (and other such metainfo)
- the original, "ideal" ticks_to_times map (even if midis are synthesized with the one from partsfile)
- total_ticks, total_time 
  • audiotracks.json should contain, for all audio tracks that are used as a basis for feedback, be they synthesized from midi or done using real audio:
- bars with bticks, bbeats, birreg for the entirety
- ticks, is_change, is_rest, pitches
- first_note_hz, monophonic, voice, percussion
  • partsfile will not need "onsets" value on excerpts anymore - it would be calculated based on audiotracks.json
  • in UI, excerpt will load both a notes metafile and an audio metafile. Audio metafile is basically onset_map + the audiotrack entry for etalon.