Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ctlra v1 #203

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 216 additions & 0 deletions gcc/ctlra_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#include "luppp_script_api.h"

#include "pstdint.h"

#include "event.h"


#define MODE_SCENE 0
#define MODE_PATTERN 1
#define MODE_PAD 2
#define MODE_VOLUME 3

static int mode;
static int shift;
static float volumes[4];

int test_ctlra(int num, struct ctlra_event_t **events)
{
//printf("test_ctlra\n");
for(uint32_t i = 0; i < num; i++) {
const char *pressed = 0;
struct ctlra_event_t *e = events[i];
const char *name = 0;
switch(e->type) {
case CTLRA_EVENT_BUTTON: {
int id = e->button.id;
printf("button id = %d\n", id);
switch(id) {
case 7: shift = e->button.pressed; break;
case 21: mode = MODE_SCENE; break;
case 22: mode = MODE_PATTERN; break;
case 23: mode = MODE_PAD; break;
case 24: if(shift) mode = MODE_VOLUME; break;

case 63: printf("ecndoer press\n");
struct event_grid_launch_scene ev = {
4
};
luppp_do(EVENT_GRID_LAUNCH_SCENE, &ev);
break;

default: printf("button %d\n", id); break;
}
break;
}

case CTLRA_EVENT_GRID: {
int pos = e->grid.pos;
//printf("grid id = %d, pos %d, pressed %d\n", e->grid.id, e->grid.pos, e->grid.pressed);
if(mode == MODE_VOLUME) {
static float vols[] = {1, 0.5, 0.3, 0.15};
int t = e->grid.pos % 4;
float v = vols[e->grid.pos / 4];
struct event_track_volume ev = {t, v};
volumes[t] = v;
luppp_do(EVENT_TRACK_VOLUME, &ev);
}
if(mode == MODE_SCENE) {
struct event_grid_launch_scene ev =
{e->grid.pos / 4};
luppp_do(EVENT_GRID_LAUNCH_SCENE, &ev);
}
if(mode == MODE_PATTERN) {
int t = e->grid.pos % 4;
int s = e->grid.pos / 4;
struct event_grid_press_release ev =
{t, s, e->grid.pressed};
luppp_do(EVENT_GRID_PRESS_RELEASE, &ev);
}
break;
}

case CTLRA_EVENT_SLIDER: {
int id = e->slider.id;
//printf("slider %d\n", id);
if(id < 4) {
struct event_track_volume ev = {
.track = id,
.value = e->slider.value,
};
luppp_do(EVENT_TRACK_VOLUME, &ev);
} else {
struct event_track_send ev = {
.track = id - 4,
.send = 0,
.value = e->slider.value,
};
luppp_do(EVENT_TRACK_SEND, &ev);
}
break;
}
} /* switch */
}
}

int test_poll(unsigned char* midi)
{
if(midi[1] == 0x42) {
printf("play pressed\n");
}
if(midi[1] == 0x3c) {
printf("cue pressed\n");
}
if(midi[1] == 0x3b) {
printf("demo pressed\n");
}
if(midi[1] == 0x33) {
printf("33 pressed\n");
}
if(midi[1] == 0x47) {
printf("47 pressed\n");
}
if(midi[1] == 0x66) {
printf("66 pressed - sending track active\n");
struct event_track_send_active e = {
.track = 3,
.send = 0,
.active = midi[0] == 0x90,
};
luppp_do(EVENT_TRACK_SEND_ACTIVE, &e);
}

static int lookup[0x17];
lookup[0x8 ] = 0;
lookup[0x17] = 1;
lookup[0xb ] = 2;
lookup[0x9 ] = 3;

if(midi[0] == 0xb0) {
if(midi[1] == 0x17 ||
midi[1] == 0x8 ||
midi[1] == 0xb ||
midi[1] == 0x9) {
struct event_track_send e = {
.track = lookup[midi[1]],
.send = 0,
.value = midi[2] / 127.f,
};
luppp_do(EVENT_TRACK_SEND, &e);
}

if(midi[1] == 0xd || midi[1] == 0xe) {
struct event_track_volume e = {
.track = (midi[1] == 0xe),
.value = midi[2] / 127.f,
};
luppp_do(EVENT_TRACK_VOLUME, &e);
}
}

return 0;
}

void test_handle(void *ctlr, enum EVENT_ID id, void *event)
{
switch(id) {
case EVENT_TRACK_SEND_ACTIVE: {
struct event_track_send_active *e =
(struct event_track_send_active *)event;
//printf("Script t %d, s %d, active %d\n", e->track, e->send, e->active);
unsigned char led_on [3] = {0x90, 0x42, 0x7F};
unsigned char led_off[3] = {0x80, 0x42, 0};
#if 0
if(e->active)
//luppp_write_midi(ctlr, led_on);
else
//luppp_write_midi(ctlr, led_off);
#endif
} break;
case EVENT_GRID_PRESS_RELEASE: {
struct event_grid_press_release *e =
(struct event_grid_press_release *)event;
//printf("pressed = %d\n", e->pressed);
uint32_t col[] = {
0xff000000,
0x0000ff00,
0x000041ff,
0x00ff5100,
0x000041ff,
0x00ff0000,
0x0000ffff,
};
if(e->track > 3 || e->scene > 3)
break;
int light = (e->scene * 4) + e->track + 28;
//printf("light = %d\n", light);
luppp_write_ctlra_light(ctlr, light, col[e->pressed]);
} break;
case EVENT_TIME_BAR_BEAT: {
struct event_time_bar_beat *e =
(struct event_time_bar_beat *)event;
//printf("Script bar %d, beat %d\n", e->bar, e->beat);
int on = e->beat % 4;
int off = (e->beat+3) % 4;
uint32_t ids[] = {16, 13, 14, 19};
luppp_write_ctlra_light(ctlr, ids[on], UINT32_MAX);
int i;
for(i = on; i < 3; i++)
luppp_write_ctlra_light(ctlr, ids[off-i], 0x4000000);
} break;
};

/* TODO: port this to the feedback API: handle "other" stuff */
luppp_write_ctlra_light(ctlr, 20, (mode == MODE_SCENE) * UINT32_MAX);
luppp_write_ctlra_light(ctlr, 21, (mode == MODE_PATTERN) * UINT32_MAX);
luppp_write_ctlra_light(ctlr, 22, (mode == MODE_PAD) * UINT32_MAX);

luppp_write_ctlra_light(ctlr, 23, (mode == MODE_VOLUME) * UINT32_MAX);
if(mode == MODE_VOLUME) {
const float levels[] = {1, 0.5, 0.3, 0.15};
for(int j = 0; j < 4; j++)
for(int i = 0; i < 4; i++)
luppp_write_ctlra_light(ctlr, 28 + j + i * 4,
(volumes[j] >= levels[i]) * UINT32_MAX);
}
}
157 changes: 157 additions & 0 deletions gcc/event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright (c) 2016, OpenAV Productions,
* Harry van Haaren <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef OPENAV_CTLRA_EVENT
#define OPENAV_CTLRA_EVENT

/** @file
* Event header of the Ctlra library. These events provide a generic
* interface which is used to send events from hardware devices to the
* software application. These events describe any action - if a device
* has an action that cannot be currently described, please contact OpenAV
* or send a patch to propose a solution. Thanks!
*/

/** Types of events */
enum ctlra_event_type_t {
/* The order of these events must not be modified */
CTLRA_EVENT_BUTTON = 0,
CTLRA_EVENT_ENCODER,
CTLRA_EVENT_SLIDER,
CTLRA_EVENT_GRID,
/* Feedback items represent items like LEDs */
CTLRA_FEEDBACK_ITEM,
/* The number of event types there are */
CTLRA_EVENT_T_COUNT,
};

/* defined in event.c */
extern const char *ctlra_event_type_names[];

struct ctlra_dev_t;

/** Represents a button. */
struct ctlra_event_button_t {
/** The id of the button */
uint32_t id;
/** The state of the button */
uint8_t pressed : 1;
uint8_t has_pressure : 1;
uint8_t unused : 6;
/** Pressure or velocity of the button press/release */
float pressure;
};

#define CTLRA_EVENT_ENCODER_FLAG_INT (1<<0)
#define CTLRA_EVENT_ENCODER_FLAG_FLOAT (1<<1)

/** Represents an endless stepped controller. */
struct ctlra_event_encoder_t {
/** The id of the encoder */
uint32_t id;
/** This flag indicates if the encoder is sending an integer or
* floating point delta increment.
*
* "Stepped" rotary encoders (such as those used to navigate
* song libraries etc) will use the integer delta, with a single
* step being the smallest delta.
*
* Endless encoders (without notches) use the floating point delta
* and the application may interpret the range of the delta as
* 1.0f : one full clockwise rotation (360 deg)
* -1.0f : one full anti-clockwise rotation (-360 deg)
*
* When explicitly scripting support for a controller, the actual
* encoder ID itself will already know which type it is - but for
* generic handling of any controller, this int/float metadata is
* required for correct handling of the values.
*/
uint8_t flags;
union {
/** Positive values indicate clockwise rotation, and vice-versa */
int32_t delta;
float delta_float;
};
};

/** Represents a fader or dial with a fixed range of movement. */
struct ctlra_event_slider_t {
/** The id of the slider */
uint32_t id;
/** Absolute position of the control */
float value;
};

#define CTLRA_EVENT_GRID_FLAG_BUTTON (1<<0)
#define CTLRA_EVENT_GRID_FLAG_PRESSURE (1<<1)

/** Represents a grid of buttons */
struct ctlra_event_grid_t {
/** The ID of the grid */
uint32_t id;
/** Flags: set if pressure or button, see defines above */
uint16_t flags;
/** The position of the square in the grid */
uint16_t pos;
/** The pressure component of the grid, range from 0.f to 1.f */
float pressure;
/** The state of the button component of the square. Pressed
* should only be set once when the state is considered changed.
* This makes handling note-events from a grid easier */
uint32_t pressed;
};

/** The event passed around in the API */
struct ctlra_event_t {
/** The type of this event */
enum ctlra_event_type_t type;

/** The event data: see examples/ dir for examples of usage */
union {
struct ctlra_event_button_t button;
struct ctlra_event_encoder_t encoder;
struct ctlra_event_slider_t slider;
struct ctlra_event_grid_t grid;
};
};

/** Callback function that is called for event(s) */
typedef void (*ctlra_event_func)(struct ctlra_dev_t* dev,
uint32_t num_events,
struct ctlra_event_t** event,
void *userdata);

/** Callback function that is called to update the feedback on the device,
* eg for leds, buttons and screens */
typedef void (*ctlra_feedback_func)(struct ctlra_dev_t *dev,
void *userdata);

#endif /* OPENAV_CTLRA_EVENT */
Loading