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
84 changes: 84 additions & 0 deletions include/clap/ext/draft/midi-info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once

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

// This extension lets a plugin expose it's MIDI implementation.
// The primary goal is to allow a host to create a MIDI-CI Property Exchange "ChCtrlList" resource for the plugin,
// so keyboard controllers can assign their knobs to suitable controllers.

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This information is all in the param; and this extension won't work if you don't have param. So can you just glean it from there?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension isn't related to params at all I think. Why do you think so?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry I confused it with the param mapping conversation we had on discord.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically what's the relationship between this extension and

https://github.com/free-audio/clap/blob/main/include/clap/ext/draft/midi-mappings.h

the midi-mappings extension proposed here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

midi-mappings.h doesn't provide a way to say how important a param is. So a plugin would have to list any mapped params in midi-info.h again.

One could argue these two extensions could/should be rolled into one.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any reason to argue against that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the two extensions aren't really about the same thing: midi-mappings.h is about describing which param/MIDI controller pairs do the same thing. midi-info.h is about describing which MIDI messages work and what the important ones are.

//TODO : for completeness this should work per-input port. Is that worth it?
Bremmers marked this conversation as resolved.
Show resolved Hide resolved

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.
status: uint32_t;
Bremmers marked this conversation as resolved.
Show resolved Hide resolved

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

//Display name
//If name is empty the host can assume the standard MIDI name
Bremmers marked this conversation as resolved.
Show resolved Hide resolved
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,
uint32_t channel);

// Fills midiinfo. Returns true on success.
// Important: the most important controls (from a performing musician's point of view) should be listed first,
Bremmers marked this conversation as resolved.
Show resolved Hide resolved
// so the host can make sure these appear on a controller keyboard.
// [main-thread]
bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin,
uint32_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 *multitimbral)(const clap_plugin_t *plugin);
Bremmers marked this conversation as resolved.
Show resolved Hide resolved
} 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.
// [main-thread]
void(CLAP_ABI *rescan)(const clap_host_t *host);
} clap_host_midiinfo_t;

#ifdef __cplusplus
}
#endif