# The configuration file * 1. [Concept](#Concept) * 2. [Configuration object](#Configurationobject) * 2.1. [`device`](#device) * 2.2. [`thresholds`](#thresholds) * 3. [Controls](#Controls) * 4. [Command](#Command) * 4.1. [Command definition object](#Commanddefinitionobject) * 4.2. [`Encoder` kind](#Encoderkind) * 4.3. [`Switch` kind](#Switchkind) * 4.4. [`Trigger` kind](#Triggerkind) * 5. [The full tree](#Thefulltree) * 5.1. [Config entry tree](#Configentrytree) * 5.2. [Thresholds tree](#Thresholdstree) * 5.3. [Controls tree](#Controlstree) * 6. [Even more detail](#Evenmoredetail) This is a `JSON` file, named `midiboard.json`, that by default is expected to be located at `$HOME/midiboard.json`. This documentation will define the data model and how to understand and write this file. It is heavily recommended to use the integrated tool to generate a skeleton, because it has a JSON Schema definition with descriptions for every key and some basic type/bounds checking. ## 1. Concept The idea of having a complex configuration for this program is to let the user define actions as code, having free reign into what one can do on actuation of a key, button or knob in the selected controller or controllers. The program is designed to allow multiple devices with their own rules and definitions, keeping a runtime for each device on a separated thread. This means that if you want to have different configurations for completely different devices, all of it can live on a single file, keeping simple the daemonization process. Tho achieve this goals, the `JSON` is structured to contain the schema location and a single key that contains an array with all the whole config entries: | Property | Type | Description | |----------|---------------|-----------------------------------------------------| | `$Schema` | String (enum) | Schema URI of the `JSON` file. | | `config` | Array (Object) | List of all the config definitions, one per device. | ## 2. Configuration object Each config entry in the `config` array is an object, representing the whole config per each device. There can only be one device per object in the array. The individual configuration is separated in three parts; `device`, `thresholds`, and `controls`: | Property | Type | Description | |-----------|--------|-------------------------------------------------------------------| | `device` | String | Name of the device. | | `thresholds` | Object | Set of time thresholds for activating different kind of controls. | | `controls` | Object | Set of controls and its actions on activation. | ### 2.1. `device` Simply the name of the device as reported by ALSA. This value must be exact. To get the name you can either use the included tool `midiboard devices --list`, or use `aseqdump -l`. ### 2.2. `thresholds` List of thresholds. for every type of event. For more information on available events, thresholds, and how they differentiate, check the [events docs](https://github.com/aordano/midiboard/docs/events.md). | Property | Type | Description | |----------|--------|------------------------------------------| | `encoder` | Object | Threshold data for any `Encoder` event. | | `trigger` | Object | Threshold data for any `Trigger` event. | | `switch` | Object | Threshold data for any `Switch` event. | Each threshold data object contains two keys, `detection`, and `activation`: | Property | Type | Description | |------------|--------|----------------------------------------------------------------------------------------------------------| | `detection` | Number | Minimum time, annotated in `ms`, for considering a detection event as successful. | | `activation` | Number | Minimum time, annotated in `ms`, for considering an activation for any control that has this event type. | ## 3. Controls The `controls` key is where the meat of the config file is located. Each child property (_you can name them as you want, as long as you only use a single word, in lowercase and/or digits, starting with a letter (not a digit), low dashes are ok too._) will be a chosen name for a given control. | Property | Type | Description | |------------------|--------|---------------------------------------------| | control name | Object | Object defining the given control behavior. | Each control has three properties; `key`, `kind`, and `command`: | Property | Type | Description | |-----------|---------------|---------------------------------------------------------------------------------------------------| | `key` | Number | Numeric value representing the key associated with this control, on the corresponding device. | | `command` | Object | Object defining the command(s) to execute on a successful activation of the control. | You can get the value of the `key` (the activated controller on the midi device) using the included tool `midiboard devices --input ` or with `aseqdump -p `. ## 4. Command This entry has three sets of possible children. What children does it have depends on the kind of event associated to the command. It always has a `kind` property that defines what type of event is associated with, and the correct keys for the command data. | Property | Type | Description | |--------------|---------------|---------------------------------------------------------------------------------------------------------------| | `kind` | String (enum) | Event type to understand the control behavior as. Options are ` Encoder ` , ` Switch ` , and ` Trigger ` . | | valid keys | Object | Valid key depends on selected `kind` of event. | For more information on the event types check the [events docs](https://github.com/aordano/midiboard/blob/master/docs/events.md#Eventtypes). ### 4.1. Command definition object Every one of the keys described as "Command definition object" contain this common object describing what command to execute: | Property | Type | Description | |----------|----------------|------------------------------------------------------------------------| | `cmd` | String | Main command to execute. Must be in `$PATH` or a script file location. | | `args` | Array (String) | List of arguments to add to the given command. | ### 4.2. `Encoder` kind Encoders execute different commands on rising values (turning a knob or sliding a fader incrementing the detected value) or falling values (turning a knob or sliding a fader decreasing the detected value). | Property | Type | Description | |----------|---------------|-----------------------------------------------------------------------------| | `kind` | String (enum) | Event type to understand the control behavior as. Selected as ` Encoder ` . | | `increase` | Object | Command definition object for executing on detection of a rising value. | | `decrease` | Object | Command definition object for executing on detection of a falling value. | ### 4.3. `Switch` kind Switchs hold a binary state and alternate between both states, executing a different command on every state change. | Property | Type | Description | |-----------------|---------------|---------------------------------------------------------------------------------| | `kind` | String (enum) | Event type to understand the control behavior as. Selected as `Switch`. | | `on` | Object | Command definition object for executing on setting the state as `ON`. | | `off` | Object | Command definition object for executing on setting the state as `OFF`. | | `initial_state` | String (enum) | Initial state to consider the control as being in, at the start of the program. | ### 4.4. `Trigger` kind Triggers just execute a single command on a successful activation. | Property | Type | Description | |-----------|---------------|----------------------------------------------------------------------------------| | `kind` | String (enum) | Event type to understand the control behavior as. Selected as `Trigger`. | | `execute` | Object | Command definition object for executing on successful activation of the control. | ## 5. The full tree To make it clearer and to more easily understand the big picture, i added some diagrams that encapsulate the config hierarchy tree: ### 5.1. Config entry tree ```mermaid graph TD root(("{ }")) schema("$Schema") --> A((String)) a.config("config") --->|" entries "| config("{ ... } ...") device("device") --> B((String)) thresholds(["thresholds"]) controls(["controls"]) root --> schema root --> a.config config --> device config --> thresholds config --> controls ``` ### 5.2. Thresholds tree ```mermaid graph TD thresholds(["thresholds"]) thresh.encoder("encoder ") thresh.switch("switch ") thresh.trigger("trigger ") thresh.sub[["THRESHOLD"]] thresh.sub.det("detection") --> A((Number)) thresh.sub.act("activation") --> B((Number)) thresh.sub --> thresh.sub.det thresh.sub --> thresh.sub.act thresholds --> thresh.encoder thresholds --> thresh.switch thresholds --> thresh.trigger thresh.encoder --> thresh.encoder.1[["THRESHOLD"]] thresh.switch --> thresh.switch.1[["THRESHOLD"]] thresh.trigger --> thresh.trigger.1[["THRESHOLD"]] ``` ### 5.3. Controls tree ```mermaid graph TD controls(["controls"]) controls.name("{ ... }") controls.key("key") --> A((String)) command("command ") controls --->|properties| controls.name controls.name --> command controls.name --> controls.key command --> choose{" "} choose1("{ ... }") choose2("{ ... }") choose3("{ ... }") choose ----->|Encoder| choose1 choose -------->|Switch| choose2 choose -->|Trigger| choose3 choose1 --> kind1("kind") --> B1(("String: 'Encoder'")) choose1 --> enc1("increase") --> B2[["COMMAND"]] choose1 --> enc2("decrease") --> B3[["COMMAND"]] choose2 --> kind2("kind") --> C1(("String: 'Switch'")) choose2 --> sw1("on") --> C2[["COMMAND"]] choose2 --> sw2("off") --> C3[["COMMAND"]] choose2 --> sw3("initial_state") --> C4((String)) choose3 --> kind3("kind") --> D1(("String: 'Trigger'")) choose3 --> tr1("execute") --> D2[["COMMAND"]] COMMAND[[COMMAND]] --> cmd1("cmd") --> cmd11((String)) COMMAND --> cmd2("args") --> cmd21(("Array(String)")) ``` ## 6. Even more detail For more details you should directly check the [schema and its annotations](https://github.com/aordano/midiboard/blob/master/schema/midiboard.schema.json). It is recommended to use a `JSON` visualization tool to make more sense of it.