8. Virtual Interface Layer

Hardware peripherals don't directly access the DSP kernel. Instead, they interact with a virtual interface layer. This is largely done to allow software emulators to easily spoof input messages when the hardware isn't there.

There are two main hardware periphals: the Monome and the Griffin Knob.

8.1. Monome Interface

8.1.1. Monome Interface Top-level Declaration

The monome interface struct is declared inside of the Monolith struct.

<<struct_contents>>=
monolith_monome_d vmonome;
<<init>>=
monolith_monome_init(m, &m->vmonome);

8.1.2. Monome Interface Struct

The monome interface layer is encapsulated in a struct called monolith_monome_d.

<<typedefs>>=
typedef struct monolith_monome_d monolith_monome_d;
<<structs>>=
struct monolith_monome_d {
<<monome_struct_contents>>
};

8.1.3. Monome Initialization

The monome virtual interface data is initialized with the function monolith_monome_init. This should be called before it is "hooked up" to a monome device, real or virtual.

<<function_declarations>>=
void monolith_monome_init(monolith_d *md, monolith_monome_d *m);
<<functions>>=
void monolith_monome_init(monolith_d *md, monolith_monome_d *m)
{
<<monolith_monome_init>>
}

8.1.4. Top-level monolith data reference

Because the interface will call page callbacks, a reference to the monolith data is required inside here.

<<monome_struct_contents>>=
monolith_d *md;
<<monolith_monome_init>>=
m->md = md;

8.1.5. Monome User Data

Data used to control the monome is stored in a void struct.

<<monome_struct_contents>>=
void *ud;
<<monolith_monome_init>>=
m->ud = NULL;

User data can be set using the function monolith_monome_data_set.

<<function_declarations>>=
void monolith_monome_data_set(monolith_monome_d *m, void *ud);
<<functions>>=
void monolith_monome_data_set(monolith_monome_d *m, void *ud)
{
    m->ud = ud;
}

8.1.6. LED press

Any time a monome key is pressed, it prossessed with the LED press callback.

<<monome_struct_contents>>=
void (*press)(monolith_monome_d *, int, int, int);
<<monolith_monome_init>>=
m->press = NULL;

This callback is called with the function monolith_monome_press.

<<function_declarations>>=
void monolith_monome_press(monolith_monome_d *m, int x, int y, int s);
<<functions>>=
void monolith_monome_press(monolith_monome_d *m, int x, int y, int s)
{
    if(m->press != NULL) {
        m->press(m, x, y, s);
    }
}

The callback is set with the function monolith_monome_press_set.

<<function_declarations>>=
void monolith_monome_press_set(monolith_monome_d *m,
                               void (*press)
                               (monolith_monome_d *, int, int, int));
<<functions>>=
void monolith_monome_press_set(monolith_monome_d *m,
                               void (*press)
                               (monolith_monome_d *, int, int, int))
{
    m->press = press;
}

8.1.7. LED set

A single LED is set with the LED lite callback.

8.1.7.1. LED set callback

<<monome_struct_contents>>=
void (*led_set)(monolith_monome_d *, int, int, int);
<<monolith_monome_init>>=
m->led_set = NULL;

The callback is called with the function monolith_monome_led_set

<<function_declarations>>=
void monolith_monome_led_set(monolith_monome_d *m, int x, int y, int s);
<<functions>>=
void monolith_monome_led_set(monolith_monome_d *m, int x, int y, int s)
{
    if(m->led_set != NULL) {
        m->led_set(m, x, y, s);
    }
}
8.1.7.2. LED set setter

The callback is set with the function monolith_monome_led_set_set.

<<function_declarations>>=
void monolith_monome_led_set_set(monolith_monome_d *m,
                               void (*led_set)
                               (monolith_monome_d *, int, int, int));
<<functions>>=
void monolith_monome_led_set_set(monolith_monome_d *m,
                               void (*led_set)
                               (monolith_monome_d *, int, int, int))
{
    m->led_set = led_set;
}
8.1.7.3. LED set in scheme

The monolith_monome_led_set callback can be called from scheme using the function monolith:monome-led-set.

<<primitive_entries>>=
{"monolith:monome-led-set", pp_led_set, 3, 3, {INT,INT,INT}},
<<scheme_functions>>=
static cell pp_led_set(cell p) {
    monolith_d *m;
    int x, y, s;
    char name[] = "monolith:monome-led-set";
    x = integer_value(name, car(p));
    p = cdr(p);
    y = integer_value(name, car(p));
    p = cdr(p);
    s = integer_value(name, car(p));
    m = monolith_data_get();
    if(m != NULL) monolith_monome_led_set(&m->vmonome, x, y, s);
    return UNSPECIFIC;
}

8.1.8. LED row

A row is illuminated with the LED row callback

8.1.8.1. LED row callback

<<monome_struct_contents>>=
void (*led_row)(monolith_monome_d *, int, int, int);

The callback is called with the function monolith_monome_led_row.

<<function_declarations>>=
void monolith_monome_led_row(monolith_monome_d *m, int x, int y, int s);
<<functions>>=
void monolith_monome_led_row(monolith_monome_d *m, int x, int y, int s)
{
    if(m->led_row != NULL) {
        m->led_row(m, x, y, s);
    }
}
8.1.8.2. LED row setter

The LED row callback is set with the function monolith_monome_led_row_set.

<<function_declarations>>=
void monolith_monome_led_row_set(monolith_monome_d *m,
                               void (*led_set)
                               (monolith_monome_d *, int, int, int));
<<functions>>=
void monolith_monome_led_row_set(monolith_monome_d *m,
                               void (*led_row)
                               (monolith_monome_d *, int, int, int))
{
    m->led_row = led_row;
}
8.1.8.3. LED row in scheme

The monolith_monome_led_row callback can be called from scheme using the function monolith:monome-led-row.

<<primitive_entries>>=
{"monolith:monome-led-row", pp_led_row, 3, 3, {INT,INT,INT}},
<<scheme_functions>>=
static cell pp_led_row(cell p) {
    monolith_d *m;
    int x, y, s;
    char name[] = "monolith:monome-led-set";
    x = integer_value(name, car(p));
    p = cdr(p);
    y = integer_value(name, car(p));
    p = cdr(p);
    s = integer_value(name, car(p));
    m = monolith_data_get();
    if(m != NULL) monolith_monome_led_row(&m->vmonome, x, y, s);
    return UNSPECIFIC;
}
8.1.8.4. LED row (16-bit)

The core LED row function only is able to enable rows one byte at a time, but this is tedious for cases where you wish to set all 16 values at one time. The function monolith_monome_led_row16 allows you to set an entire 16-bit row using an unsigned short value.

<<function_declarations>>=
void monolith_monome_led_row16(monolith_monome_d *m, int row, unsigned short s);
<<functions>>=
void monolith_monome_led_row16(monolith_monome_d *m, int row, unsigned short s)
{

    monolith_monome_led_row(m, 0, row, s & 255);
    monolith_monome_led_row(m, 255, row, (s >> 8) & 255);
}

It can be called with the scheme function monolith:monome-led-row16.

<<primitive_entries>>=
{"monolith:monome-led-row16", pp_monome_led_row16, 2, 2, {INT,INT,___}},
<<scheme_functions>>=
static cell pp_monome_led_row16(cell p)
{
    unsigned short x;
    int row;
    char name[] = "monolith:monome-led-row16";
    monolith_d *m;
    m = monolith_data_get();
    row = integer_value(name, car(p));
    p = cdr(p);
    x = (unsigned short) integer_value(name, car(p));
    monolith_monome_led_row16(&m->vmonome, row, x);
    return UNSPECIFIC;
}

8.1.9. LED all

All leds can be turned on (1) or off (0) with the Led all command

8.1.9.1. LED all callback

<<monome_struct_contents>>=
void (*led_all)(monolith_monome_d *, int);
<<monolith_monome_init>>=
m->led_set = NULL;

The callback is called with the function monolith_monome_led_all

<<function_declarations>>=
void monolith_monome_led_all(monolith_monome_d *m, int s);
<<functions>>=
void monolith_monome_led_all(monolith_monome_d *m, int s)
{
    if(m->led_all != NULL) {
        m->led_all(m, s);
    }
}
8.1.9.2. LED all setter

The callback is set with the function monolith_monome_led_all_set.

<<function_declarations>>=
void monolith_monome_led_all_set(monolith_monome_d *m,
                               void (*led_all)
                               (monolith_monome_d *, int));
<<functions>>=
void monolith_monome_led_all_set(monolith_monome_d *m,
                               void (*led_all)
                               (monolith_monome_d *, int))
{
    m->led_all = led_all;
}
8.1.9.3. LED all in scheme

The monolith_monome_led_all callback can be called from scheme using the function monolith:monome-led-all.

<<primitive_entries>>=
{"monolith:monome-led-all", pp_led_all, 1, 1, {INT,___,___}},
<<scheme_functions>>=
static cell pp_led_all(cell p) {
    monolith_d *m;
    int s;
    char name[] = "monolith:monome-led-set";
    s = integer_value(name, car(p));
    m = monolith_data_get();
    if(m != NULL) monolith_monome_led_all(&m->vmonome, s);
    return UNSPECIFIC;
}

8.1.10. DONE LED Column

CLOSED: [2019-12-05 Thu 19:31] Sets a column on the monome.

8.1.10.1. DONE LED column callback

CLOSED: [2019-12-05 Thu 19:16]

<<monome_struct_contents>>=
void (*led_col)(monolith_monome_d *, int, int, int);

The callback is called with the function monolith_monome_led_col.

<<function_declarations>>=
void monolith_monome_led_col(monolith_monome_d *m,
                             int x, int y, int s);
<<functions>>=
void monolith_monome_led_col(monolith_monome_d *m,
                             int x, int y, int s)
{
    if(m->led_col != NULL) {
        m->led_col(m, x, y, s);
    }
}
8.1.10.2. DONE LED column setter

CLOSED: [2019-12-05 Thu 19:24]

<<function_declarations>>=
void monolith_monome_led_col_set(monolith_monome_d *m,
                               void (*f)
                               (monolith_monome_d *, int, int, int));
<<functions>>=
void monolith_monome_led_col_set(monolith_monome_d *m,
                               void (*f)
                               (monolith_monome_d *, int, int, int))
{
    m->led_col = f;
}
8.1.10.3. DONE LED column in scheme

CLOSED: [2019-12-05 Thu 19:25]

<<primitive_entries>>=
{"monolith:monome-led-col", pp_led_col, 3, 3, {INT,INT,INT}},
<<scheme_functions>>=
static cell pp_led_col(cell p) {
    monolith_d *m;
    int x, y, s;
    char name[] = "monolith:monome-led-set";
    x = integer_value(name, car(p));
    p = cdr(p);
    y = integer_value(name, car(p));
    p = cdr(p);
    s = integer_value(name, car(p));
    m = monolith_data_get();
    if(m != NULL) monolith_monome_led_col(&m->vmonome, x, y, s);
    return UNSPECIFIC;
}

8.2. Griffin Knob Interface

8.2.1. Griffin Top-Level Declaration

The virtual struct interface is declared inside of the topmost monolith struct as a variable called vgriffin.

<<struct_contents>>=
monolith_griffin_d vgriffin;

It is initialized in the top-level init callback.

<<init>>=
monolith_griffin_init(m, &m->vgriffin);

8.2.2. Griffin Struct

The griffin virtual interface is stored in a struct called monolith_griffin_d.

<<typedefs>>=
typedef struct monolith_griffin_d monolith_griffin_d;
<<structs>>=
struct monolith_griffin_d {
<<griffin_struct_contents>>
};

8.2.3. Griffin Top-level struct reference

<<griffin_struct_contents>>=
monolith_d *md;
<<griffin_init>>=
g->md = md;

8.2.4. Griffin Initialization

The griffin is initialized with the function monolith_griffin_init.

<<function_declarations>>=
void monolith_griffin_init(monolith_d *md, monolith_griffin_d *g);
<<functions>>=
void monolith_griffin_init(monolith_d *md, monolith_griffin_d *g)
{
<<griffin_init>>
}

8.2.5. Griffin User Data

User data is stored as a generic void pointer called ud.

<<griffin_struct_contents>>=
void *ud;
<<griffin_init>>=
g->ud = NULL;

8.2.6. Griffin Knob Turn

Any time a griffin turns, it is processed with a callback called turn.

<<griffin_struct_contents>>=
void (*turn)(monolith_griffin_d *, int);
<<griffin_init>>=
g->turn = NULL;

The turn callback is called with the function monolith_griffin_turn.

<<function_declarations>>=
void monolith_griffin_turn(monolith_griffin_d *g, int state);
<<functions>>=
void monolith_griffin_turn(monolith_griffin_d *g, int state)
{
    if(g->turn != NULL) g->turn(g, state);
}

The turn callback is set with the function monolith_griffin_turn_set.

<<function_declarations>>=
void monolith_griffin_turn_set(monolith_griffin_d *g,
                               void (*turn)(monolith_griffin_d *, int));
<<functions>>=
void monolith_griffin_turn_set(monolith_griffin_d *g,
                               void (*turn)(monolith_griffin_d *, int))
{
    g->turn = turn;
}

8.2.7. Griffin Push

8.2.7.1. Griffin Push in C

Any time the griffin is pushed, it is processed with a callback called push.

<<griffin_struct_contents>>=
void (*push)(monolith_griffin_d *, int);
<<griffin_init>>=
g->push = NULL;

The press callback is called with the function monolith_griffin_press.

<<function_declarations>>=
void monolith_griffin_push(monolith_griffin_d *g, int state);
<<functions>>=
void monolith_griffin_push(monolith_griffin_d *g, int state)
{
    if(g->push != NULL) g->push(g, state);
}

The push callback is set with the function monolith_griffin_push_set.

<<function_declarations>>=
void monolith_griffin_push_set(monolith_griffin_d *g,
                                void (*push)(monolith_griffin_d *, int));
<<functions>>=
void monolith_griffin_push_set(monolith_griffin_d *g,
                                void (*push)(monolith_griffin_d *, int))
{
    g->push = push;
}
8.2.7.2. Griffin Press in Scheme

In scheme, a griffin press can be simulated using the function monolith:griffin-press. It takes in a single integer argument indicating the press state. a "1" is a push down, and a "0" is push up.

<<primitive_entries>>=
{"monolith:griffin-push", pp_griffin_push, 1, 1, {INT,___,___}},
<<scheme_functions>>=
static cell pp_griffin_push(cell p) {
    monolith_d *m;
    int s;
    char name[] = "monolith:griffin-push";
    s = integer_value(name, car(p));
    m = monolith_data_get();
    if(m != NULL) monolith_griffin_push(&m->vgriffin, s);
    return UNSPECIFIC;
}

8.3. Arc Interface

This will eventually describe the virtual interface layer for the Monome Arc, a high resolution encoder with visual feedback.

Most of this is copied from the monome interface.

8.3.1. Arc Interface Top-Level Declaration

<<struct_contents>>=
monolith_arc_d varc;
<<init>>=
monolith_arc_init(m, &m->varc);

Can be retrieved with monolith_arc_get.

<<function_declarations>>=
monolith_arc_d * monolith_arc_get(monolith_d *m);
<<functions>>=
monolith_arc_d * monolith_arc_get(monolith_d *m)
{
    return &m->varc;
}

8.3.2. Arc Interface Struct

<<typedefs>>=
typedef struct monolith_arc_d monolith_arc_d;
<<structs>>=
struct monolith_arc_d {
<<arc_struct_contents>>
};

8.3.3. Arc Initialization

<<function_declarations>>=
void monolith_arc_init(monolith_d *md, monolith_arc_d *a);
<<functions>>=
void monolith_arc_init(monolith_d *md, monolith_arc_d *a)
{
<<monolith_arc_init>>
}

8.3.4. Top-level Arc Data Reference

<<arc_struct_contents>>=
monolith_d *md;
<<monolith_arc_init>>=
a->md = md;

8.3.5. Arc User Data

<<arc_struct_contents>>=
void *ud;
<<monolith_arc_init>>=
a->ud = NULL;
<<function_declarations>>=
void monolith_arc_data_set(monolith_arc_d *a, void *ud);
<<functions>>=
void monolith_arc_data_set(monolith_arc_d *a, void *ud)
{
    a->ud = ud;
}

8.3.6. Arc Delta

Any time an encoder is turned, this callback happens.

<<arc_struct_contents>>=
void (*delta)(monolith_arc_d *, int, int);
<<monolith_arc_init>>=
a->delta = NULL;
<<function_declarations>>=
void monolith_arc_delta(monolith_arc_d *a, int n, int d);
<<functions>>=
void monolith_arc_delta(monolith_arc_d *a, int n, int d)
{
    if(a->delta != NULL) {
        a->delta(a, n, d);
    }
}
<<function_declarations>>=
void monolith_arc_delta_set(monolith_arc_d *a,
                            void (*delta)
                            (monolith_arc_d *, int, int));
<<functions>>=
void monolith_arc_delta_set(monolith_arc_d *a,
                            void (*delta)
                            (monolith_arc_d *, int, int))
{
    a->delta = delta;
}

8.3.7. Arc Map

Maps an array of size 64 to the device.

<<arc_struct_contents>>=
void (*map)(monolith_arc_d *, int, unsigned char *);
<<monolith_arc_init>>=
a->map = NULL;
<<function_declarations>>=
void monolith_arc_map(monolith_arc_d *a, int n, unsigned char *l);
<<functions>>=
void monolith_arc_map(monolith_arc_d *a, int n, unsigned char *l)
{
    if(a->map != NULL) {
        a->map(a, n, l);
    }
}
<<function_declarations>>=
void monolith_arc_map_set(monolith_arc_d *a,
                          void (*map)
                          (monolith_arc_d *, int, unsigned char *));
<<functions>>=
void monolith_arc_map_set(monolith_arc_d *a,
                          void (*map)
                          (monolith_arc_d *, int, unsigned char *))
{
    a->map = map;
}

8.3.8. Arc All

Sets knob n to be either all on or off.

<<arc_struct_contents>>=
void (*all)(monolith_arc_d *, int, int);
<<monolith_arc_init>>=
a->all= NULL;
<<function_declarations>>=
void monolith_arc_all(monolith_arc_d *a, int n, int l);
<<functions>>=
void monolith_arc_all(monolith_arc_d *a, int n, int l)
{
    if(a->all != NULL) {
        a->all(a, n, l);
    }
}
<<function_declarations>>=
void monolith_arc_all_set(monolith_arc_d *a,
                          void (*all)
                          (monolith_arc_d *, int, int));
<<functions>>=
void monolith_arc_all_set(monolith_arc_d *a,
                          void (*all)
                          (monolith_arc_d *, int, int))
{
    a->all = all;
}



prev | home | next