Module Description

Wikis > Analog3 > Module Description

Outline

Here is an example of schema and generated table for MIDI Gateway module:

{
    "name": "midigw",
    "type": "Module",
    "member": [
        {
            "name": "MIDI channel",
            "type": "NumberSelector",
            "min": 1,
            "max": 16
        },
        {
            "name": "Voices",
            "type": "Selector",
            "choices": ["mono", "duo", "poly 4", "poly 5", "poly 6", "poly 8", "poly 10", "poly 16"]
        },
        {
            "name": "Retrigger",
            "type": "Switch",
            "default": True
        }
    ]
}

#define P_N1_MIDI_CHANNEL_OFFSET 0
#define P_L_VOICES_OFFSET        1
#define P_B_RETRIGGER_OFFSET     2
#define P_BUFFER_SIZE            3

static uint8_t p_buffer[P_BUFFER_SIZE];

#define P_N1_MIDI_CHANNEL (*(uint8_t*)&p_buffer[P_N1_MIDI_CHANNEL_OFFSET])
#define P_N1_MIDI_CHANNEL_VALUE_OFFSET 1

#define P_L_VOICES       (*(uint8_t*)&p_buffer[P_L_VOICES_OFFSET])
#define P_L_VOICES__MONO     0
#define P_L_VOICES__DUO      1
#define P_L_VOICES__POLY_4   2
#define P_L_VOICES__POLY_5   3
#define P_L_VOICES__POLY_6   4
#define P_L_VOICES__POLY_8   5
#define P_L_VOICES__POLY_10  6
#define P_L_VOICES__POLY_16  7

int id_offset = 1;

There are two ways to modify a component parameter. They are:

  • Direct control using a component address
  • Indirect control through a unit

Component Address

Every component has its unique address in order to exchange its parameter via data bus. A component address is a 4 byte integer like IP address. Thus, you have two ways of address management — static and dynamic.

Unit

*** TODO: rename unit to union

Analog 3 will have many parameters that may cause difficulty in control them. Unit helps simplifying synth manipulation.

A unit is a virtual component that consists of zero or more components or units. It has its own control parameter. A unit is a component on data bus. Thus it has a component address. Updating the unit parameter causes changes in its sub-components at once.

An example usage of units is building polyphonic perspective. When you build a four-voice polyphonic synthesizer, you make a unit for each synth parameter (such as VCF cutoff frequency) and recruits corresponding physical components of the four voices. Its representation looks following:

{
    "name": "cutoff frequency",
    "type": "KnobUnit",
    "members": [
        "voice1.vcf.cutoff_frequency",
        "voice2.vcf.cutoff_frequency",
        "voice3.vcf.cutoff_frequency",
        "voice4.vcf.cutoff_frequency"
    ]
}

Another example is bundling multiple parameters to simplify manipulation.

{
    "name": "sharpness",
    "type": "KnobUnit",
    "members": [
        "envelope_generator.hit.intensity",
        "envelope_generator.attack.time",
        "envelope_generator.1st_decay.time"
    ]
}