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

midi controls extension #352

Open
wants to merge 11 commits into
base: next
Choose a base branch
from
94 changes: 94 additions & 0 deletions include/clap/ext/draft/midi-info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#pragma once

#include "../../plugin.h"

// This extension lets a plugin expose its MIDI implementation.
// The primary goal is to allow a host to create a MIDI-CI Property Exchange "ChCtrlList" resource for the plugin,
// which is presented to a keyboard / controller.
// A keyboard can then assign its knobs to suitable controllers, decide between sending poly or channel afertouch etc.
// Also, hosts can use this extension to indicate to users which controls actually work.

// TODO : clap_midiinfo could/should contain more (optional) info (min/max, stepcount, paramPath etc.)

static CLAP_CONSTEXPR const char CLAP_EXT_MIDIINFO[] = "clap.midi-info.draft/0";

#ifdef __cplusplus
extern "C" {
#endif

enum {
// MIDI 2.0 message status
CLAP_MIDIINFO_STATUS_REGISTERED_PER_NOTE_CONTROLLER = 0x00,
CLAP_MIDIINFO_STATUS_ASSIGNABLE_PER_NOTE_CONTROLLER = 0x10,
CLAP_MIDIINFO_STATUS_RPN = 0x20,
CLAP_MIDIINFO_STATUS_NRPN = 0x30,
CLAP_MIDIINFO_STATUS_PER_NOTE_PITCHBEND = 0x60,
CLAP_MIDIINFO_STATUS_POLY_AFTERTOUCH = 0xA0,
CLAP_MIDIINFO_STATUS_CONTROLLER = 0xB0,
CLAP_MIDIINFO_STATUS_CHANNEL_AFTERTOUCH = 0xD0,
CLAP_MIDIINFO_STATUS_PITCHBEND = 0xE0,

// CLAP note expressions.
// A host may map MIDI messages to note expressions, so it needs to know which note expressions are supported.
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_VOLUME = 0x100,
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_PAN = 0x101,
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_TUNING = 0x102,
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_VIBRATO = 0x103,
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_EXPRESSION = 0x104,
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_BRIGHTNESS = 0x105,
CLAP_MIDIINFO_STATUS_NOTE_EXPRESSION_PRESSURE = 0x106
Bremmers marked this conversation as resolved.
Show resolved Hide resolved
};

/* This describes a MIDI control/message */
typedef struct clap_midiinfo {
// CLAP_MIDIINFO_STATUS, describes what kind of control this struct is about.
uint32_t status;

// controller number, nrpn number etc.
// zero if not applicable the status value
uint32_t number;

// Priority of this control (from a performing musician's point of view)
// 1..5, a value of 1 is the most important, descending down to 5 as the least important.
// Multiple controls can have the same priority. In this case the control at the lowest index
// (see clap_plugin_midiinfo.get_info) is more important than the next ones.
uint32_t priority;

// Display name
// If name is empty the host can assume default MIDI controller names (cc7 is Volume etc.)
char name[CLAP_NAME_SIZE];
} clap_midiinfo_t;

typedef struct clap_plugin_midiinfo {
// Returns the number of clap_midiinfo structs for a channel.
// channel is 0..15
// [main-thread]
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin,
int16_t port_index,
uint16_t channel);

// Fills midiinfo. Returns true on success.
// [main-thread]
bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin,
int16_t port_index,
uint16_t channel,
uint32_t index,
clap_param_info_t *midiinfo);

//if false all channels are the same, so the host doesn't have to scan them all.
bool(CLAP_ABI *is_multitimbral)(const clap_plugin_t *plugin,
Bremmers marked this conversation as resolved.
Show resolved Hide resolved
int16_t port_index);
} clap_plugin_midiinfo_t;

typedef struct clap_host_midiinfo {
// Rescan the full list of structs.
// This can happen if an instrument switches to a different patch, for example.
// port_index = -1 means 'all ports'
// [main-thread]
void(CLAP_ABI *changed)(const clap_host_t *host,
int16_t port_index);
} clap_host_midiinfo_t;

#ifdef __cplusplus
}
#endif