System Configuration#
Outside of the image configuration data, which is more "how does one build a linux distribution" type stuff, and which can all be found in the zynthbox-sys repository, we have a number of files which define a variety of things for us: In particular, the files here, found in the config
folder of main repository, describe which instrumentation plugins the system knows about, how they should be displayed in the user interface, and what categories are available for your sounds. Specifically, the following files are used to do this:
For all objects in each of these files, it is worth making a note that the object contents (that is, which keys exist in each object) is normalised across the types in the same file. This means that while for some objects, certain keys don't make sense, they will still exist. A simple example of this being the defaultDryWetMixAmount
key in categories.json, which only makes sense for audio effects, but all objects in the file contain the key, and set to null which strictly identifies the key as unused.
snd_categories.json#
This file is used to describe which categories are available for use by the Sound files. As usual, this is intended to be both strictly stable, and extensible for future use. This example currently contains the entire file (as it is quite small for the time being), but with the intent that it should be extensible, you should still treat this as an example of the layout. The current state can be found here in the repository.
You will notice that each of these objects contain only a single key at the moment. The intent is to allow for future additions to this (for example an image, a description, or the like), and so to ensure the stability of the format, we make each entry an object instead of simply a string.
{
// The key for all entries in the root object are each a category which a
// Sound can be assigned. This key will be unique, and stable in perpetuity
// This is the global category, intended to display all sounds (as suggested
// by the * wildcard style key)
"*": {
// The human-readable name of the category, as displayed in the UI. This
// value is not guaranteed stable, and should not be used in persistence
"displayName": "All"
},
// The following several entries (up to a total of 99) are our defined
// categories usable for sounds. Again, the key will remain stable in
// perpetuity, while the name is not guaranteed stable, and might potentially
// change
"1": {
"displayName": "Drums"
},
"2": {
"displayName": "Bass"
},
"3": {
"displayName": "Leads"
},
"4": {
"displayName": "Synth/Keys"
},
"5": {
"displayName": "Strings/Pads"
},
"6": {
"displayName": "Guitar/Plucks"
},
// The final entry is a catch-all type overflow category, hence being at
// the end
"99": {
"displayName": "FX/Other"
},
// The best-of categories begin with the global best-of, with the key 100
// This is used internally to allow users to mark a number of their sounds
// as a kind of global favourite
"100": {
"displayName": "Best Of"
}
}
categories.json#
This file is used in combination with plugins.json to define how to display our software instruments. You will notice that the soundfont and synth categories each currently only contain a single entry. This is because currently, these are not displayed in categories in the UI. However, to ensure a reasonable level of normalisation in the data, the fields exist, and can be amended with more data in the future as required, without causing data format changes.
The objects in each type of category are very similar, and while not all fields make sense for all types, we still include such fields in the objects. For example, the defaultDryWetMixAmount
field only makes sense for audio effect plugins, and as such is set to null, marking it explicitly as not used.
The complete file in its current state can be found here in the repository.
{
// Categories can be a number of different types. Currently we have audioFx,
// synths, and soundfonts. This may expand in the future (for example midi
// effects).
// This object contains all the audio effect categories
"audioFx": {
// Each category object is unique in its type container object, and
// together with the type, this fully and uniquely qualifies each object
// (to allow for stable references to it from plugins.json)
"0000": {
// The human-readable display name used to show this category in the
// user interface
"displayName": "Chorus",
// An image used to display the category in our effect picker popup
// (if null, empty or the image is not found, a default image will
// be used)
"image": "categories/chorus.png",
// A short, human-readable description of the category
"description": null,
// The default dry/wet mix amount for all audio effects in this
// category.
// This will usually be 1, and is a value from 0 through 2
// - 0 being 100% dry and 0% wet
// - 1 being 100% dry and 100% wet
// - and 2 being 0% dry and 100% wet
// Some categories (especially and in particular Filter and EQ) will
// need this to be 2, to avoid signal doubling
"defaultDryWetMixAmount": "1"
},
"0001": {
"displayName": "Compressor",
"image": "categories/compressor.png",
"description": null,
"defaultDryWetMixAmount": "1"
}
// Any number of further entries here
},
"synths": {
"0000": {
"displayName": "Synth",
"image": null,
"description": "Sound generation tools which take midi input and create audio based on the instructions contained within those events",
// Setting this value to null will mark it as unused (it only really
// makes sense for audio effects)
"defaultDryWetMixAmount": null
}
},
"soundfonts": {
"0000": {
"displayName": "Soundfont",
"image": null,
"description": null,
// Setting this value to null will mark it as unused (it only really
// makes sense for audio effects)
"defaultDryWetMixAmount": null
}
}
}
plugins.json#
This file is used by the core system to decide which software instrument plugins are available for use (meaning both sound generators and effects, as well as included soundfonts). It is done this way to ensure we can provide reasonable assurances that your musical creations are still going to load when, sometime in the distant future, you find your old sketchpad from when you first got yourself something running Zynthbox OS, and wonder what that one might sound like to your new cybernetic ears. If we instead for example, just generated a list of things when you start the thing up, not only would it take considerably longer to start (which isn't great), but you would easily end up in a situation where we would be unable to ensure the future compatibility of the system with older Sketchpads, which we consider to be an unacceptable situation.
Ensure correctness
As this was written during the implementation of the consolidated plugins.json logic, it is entirely possible that some things here are incorrect. While this is true for all the logic, it is more true here: It will need checking over once the code has been finalised, to ensure the documentation is, in fact, correct.
Absolute paths...
Should we perhaps be using a relative path from a known location to identify things that are in our data location. For example, all SF2 files are already known to be in a central location, so maybe our listing here could "just" contain the path relative to that location?
The following example listing only contains a single entry for each type of item, but the one shipped with Zynthbox OS contains a great many in each. To see a complete version of this file, you can check out the current development version here.
{
// The category for all the synth engines
"synth": {
// The plugin's unique ID
"ZBP_SYNTH_00008": {
// The human-readable name displayed in the Synth picking popup
"displayName": "synthv1",
// A short-form description of the engine, displayed in the Synth picking
// popup
"description": "An old-school 4-oscillator subtractive polyphonic synthesizer with stereo fx",
// A long-form description of the engine, for displaying to the user (can
// be null or empty, in which case the description above is used)
"longDescription": null,
// The filename of the image file used for this instrument's tiles in the
// UI, relative to the img folder (if empty or the image is not found, a
// default image will be used)
"image": "synths/synthv1.png",
// A list of the categories this plugin should be found in. Usually there
// will be only one entry, but some plugins will feature in multiple
"categories": [
// The type and id of a category uniquely identifies it (in database
// parlance, a composite key)
{
// The type of category (this engine is a synth, so we use a category
// from the relevant list)
"type": "synth",
// The (currently only) synth category
"id": "0000"
}
],
// The current (usually the most recent, and if there is only one version,
// always 0000) version of the plugin
"currentVersion": "0000",
// A list of all unique information for each version of the plugin.
// Usually this will have a single entry (with the same key as the value
// of currentVersion above), but should there in the future be a need for
// multiple versions of the same plugin to be installed, this can be used
// to define the details for those.
"versions": {
// The details for version 0000 (notice this is the same as the
// currentVersion value)
"0000": {
// A field used to decide whether to show this version in the Synth
// picking popup (defaults to true, useful for development)
"visible": true,
// The internal name of the plugin as used by the engine type
// implementation to load the plugin
"pluginName": "synthv1",
// The plugin format
"format": "LV2",
// The file system location for this engine
"path": "/usr/lib/lv2/synthv1.lv2/",
// The type of plugin (in this case jalv, which loads lv2 plugins)
"engineType": "jalv",
// sha256 doesn't make sense for the binary plugins (like lv2)
"sha256sum": null,
// The version of Zynthbox in which this plugin was added
"zynthboxVersionAdded": "1",
// The plugin's URI, used by the engine to load this plugin (in case
// of e.g. lv2 plugins)
"url": "http://synthv1.sourceforge.net/lv2",
// The names of the controllers used to control volume for this
// plugin, if there is one (otherwise it's null)
"volumeControls": [
"OUT1_VOLUME",
"OUT2_VOLUME"
],
// The control name for the plugin's filter cutoff controller, if
// there is one (otherwise it's null)
"cutoffControl": "DCF1_CUTOFF",
// The control name for the plugin's filter resonance controller, if
// there is one (otherwise it's null)
"resonanceControl": "DCF1_RESO"
},
"0001": {
// A field used to decide whether to show this version in the Synth
// picking popup (defaults to true, useful for development)
"visible": false,
"pluginName": "synthv1-1.3.2",
"format": "LV2",
"path": "/usr/lib/lv2/synthv1-1.3.2.lv2/",
"engineType": "jalv",
"sha256sum": null,
"zynthboxVersionAdded": "1",
"url": "http://synthv1.sourceforge.net/lv2/1.3.2",
"volumeControls": [
"OUT1_VOLUME",
"OUT2_VOLUME"
],
"cutoffControl": "DCF1_CUTOFF",
"resonanceControl": "DCF1_RESO"
}
}
},
// Many more entries here, one for each of our engines
},
// The category containing all the included soundfonts
"soundfont": {
// The sound font's unique ID
"ZBP_SF_00001": {
// The human-readable name used in the Banks list for soundfont
// based engines
"displayName": "BuenosBassSlides",
// A short-form description of the soundfont, for displaying to the user
// (if null or empty, the ui will display a message to say this, instead
// of displaying no text)
"description": null,
// A long-form description of the soundfont, for displaying to the user
// (can be null or empty, in which case the description is used)
"longDescription": null,
// The filename of the image file used for this instrument's tiles in the
// UI, relative to the img folder (if null, empty or the image is not
// found, a default image will be used)
"image": null,
// A list of the categories this plugin should be found in. Usually there
// will be only one entry, but some plugins will feature in multiple
"categories": [
{
// The type of category (this engine is a soundfont, so we use a
// category from the relevant list)
"type": "soundfont",
// The (currently singular) soundfont category
"id": "0000"
}
],
// The current (usually the most recent, and if there is only one version,
// always 0000) version of the soundfont
"currentVersion": "0000",
// A list of all unique information for each version of the soundfont.
// Usually this will have a single entry (with the same key as the value
// of currentVersion above), but should there in the future be a need for
// multiple versions of the same soundfont to be installed, this can be
// used to define the details for those.
"versions": {
// The details for version 0000 (notice this is the same as the
// currentVersion field's value
"0000": {
// A field used to decide whether to show this version in the Synth
// picking popup (defaults to true,
// useful for development)
"visible": true,
// The internal name of the soundfont
"pluginName": "BuenosBassSlides",
// The format of the soundfont (either SFZ, SF2, or SF3)
"format": "SF2",
// The file system location for this soundfont
"path": "/zynthian/zynthian-data/soundfonts/sf2/BuenosBassSlides.sf2",
// The type of engine (this is unused for soundfonts, which can be loaded
// by any number of engines)
"engineType": null,
// A sha256 sum which can be used to ensure the soundfont found on
// disk is in fact correct, and also potentially for identifying an
// unknown one
"sha256sum": "e5ba83f6ad2226db02db2fa64703bf0642185fdf7f9545cc57abe16fd9198dd7",
// The version of Zynthbox in which this soundfont was added
"zynthboxVersionAdded": "1",
// The plugin's URI, used by the engine to load this plugin, if
// relevant (otherwise it's null, like here)
"url": null,
// The names of the controllers used to control volume for this plugin,
// if there is one (otherwise it's null, like here)
"volumeControls": null,
// The control name for the plugin's filter cutoff controller, if
// there is one (otherwise it's nulllike here)
"cutoffControl": null,
// The control name for the plugin's filter resonance controller,
// if there is one (otherwise it's null, like here)
"resonanceControl": null
}
}
},
// Many more entries here, one for each of our included soundfonts
},
// The category containing all the included audio effect engines
"audioFx": {
// The plugin's unique ID
"ZBP_FX_00021": {
// The human-readable name for this plugin (shown in the Pick FX popup's
// category display)
"displayName": "GxVoodooFuzz",
// A short-form description of the engine, displayed in the Synth
// picking popup
"description": "Simulation impressed by the Voodoo Lab SuperFuzz pedal",
// A long-form description of the engine, for displaying to the user (can
// be null or empty, in which case the description above is used)
// As visible here, this description can be either in raw text (which will
// be treated formatted as such in the UI), or it can be Qt's RichText
// format - see the following link for details:
// https://doc.qt.io/archives/qt-5.15/qml-qtquick-text.html#textFormat-prop
"longDescription": "Simulation impressed by the Voodoo Lab (*) SuperFuzz pedal.
It's basically a Bosstone circuite, followed by the tone control
of the FoxToneMachine in parralel with a DarkBooster,
finaly ended in a Volume control.
(*) Other product names modeled in this software are trademarks
of their respective companies that do not endorse and are not associated
or affiliated with this simulation.
Voodoo Lab is trademark or trade name of other manufacturer
and was used merely to identify the product whose sound was reviewed
in the creation of this product.
All other trademarks are the property of their respective holders.",
// The filename of the image file used for this instrument's tiles in the
// UI, relative to the img folder (if empty or the image is not found, a
// default image will be used)
"image": "audioFx/gxvoodoofuzz.png",
// A list of the categories this plugin should be found in. Usually there
// will be only one entry, but some plugins will feature in multiple
// As an example, we put this usually distortion-only effect into two
// categories
"categories": [
{
// The type of category (this engine is an audio effect, so we use a
// category from the relevant list)
"type": "audioFx",
// The Distortion category
"id": "0003"
},
{
// The type of category (this engine is an audio effect, so we use a
// category from the relevant list)
"type": "audioFx",
// The Simulator category (which GxVoodooFuzz is not, really, but we
// add it here to show what having more than one category looks like)
"id": "0012"
}
],
// The current (usually the most recent, and if there is only one version,
// always 0000) version of the plugin
"currentVersion": "0000",
// A list of all unique information for each version of the plugin.
// Usually this will have a single entry (with the same key as the value
// of currentVersion above), but should there in the future be a need for
// multiple versions of the same plugin to be installed, this can be used
// to define the details for those.
"versions": {
// The details for version 0000 (notice this is the same as the
// currentVersion field's value)
"0000": {
// A field used to decide whether to show this version in the Synth
// picking popup (defaults to true, useful for development)
"visible": true,
// The internal name of the plugin as used by the engine type
// implementation to load the plugin
"pluginName": "GxVoodooFuzz",
// The format of the plugin
"format": "LV2",
// The file system location for this plugin
"path": "/usr/lib/lv2/gx_voodoo.lv2/",
// The type of engine (in this case jalv, which loads lv2 plugins)
"engineType": "jalv",
// sha256 doesn't make sense for the binary plugins (like lv2)
"sha256sum": null,
// The version of Zynthbox in which this plugin was added
"zynthboxVersionAdded": "1",
// The plugin's URI, used by the engine to load this plugin (in case
// of e.g. lv2 plugins)
"url": "http://guitarix.sourceforge.net/plugins/gx_voodoo_#_voodoo_",
// The names of the controllers used to control oscillator volume for
// this plugin, if there is one (otherwise it's null, like here)
"volumeControls": null,
// The control name for the plugin's filter cutoff controller, if
// there is one (otherwise it's null, like here)
"cutoffControl": null,
// The control name for the plugin's filter resonance controller, if
// there is one (otherwise it's null, like here)
"resonanceControl": null
}
}
},
// Many more entries here, one for each of our included audio effect engines
}
}