* Create midi-channel-ab.c midi-channel-filter.c + bits of midi-split.c = an attempt at a per channel output A/B routing * Update Makefile for ab plugin * Update midi-channel-ab.c fixed incorrect copy/paste * add A/B plugin * Add A/B plugin * Add A/B plugin * Add A/B plugin * Add A/B plugin * Rename and reorder binary options * Fix output order * Fix order(?) * Fix order * More efficient code, floats to booleans, comparison fixes * Revert mistake * Fix midi output port numbers * Fix maker name * Add copyright header linetags/v1.9.9
@@ -28,6 +28,7 @@ OBJS = \ | |||||
$(OBJDIR)/bypass.c.o \ | $(OBJDIR)/bypass.c.o \ | ||||
$(OBJDIR)/lfo.c.o \ | $(OBJDIR)/lfo.c.o \ | ||||
$(OBJDIR)/midi-channel-filter.c.o \ | $(OBJDIR)/midi-channel-filter.c.o \ | ||||
$(OBJDIR)/midi-channel-ab.c.o \ | |||||
$(OBJDIR)/midi-gain.c.o \ | $(OBJDIR)/midi-gain.c.o \ | ||||
$(OBJDIR)/midi-join.c.o \ | $(OBJDIR)/midi-join.c.o \ | ||||
$(OBJDIR)/midi-split.c.o \ | $(OBJDIR)/midi-split.c.o \ | ||||
@@ -28,6 +28,7 @@ | |||||
extern void carla_register_native_plugin_bypass(void); | extern void carla_register_native_plugin_bypass(void); | ||||
extern void carla_register_native_plugin_lfo(void); | extern void carla_register_native_plugin_lfo(void); | ||||
extern void carla_register_native_plugin_midichanfilter(void); | extern void carla_register_native_plugin_midichanfilter(void); | ||||
extern void carla_register_native_plugin_midichanab(void); | |||||
extern void carla_register_native_plugin_midigain(void); | extern void carla_register_native_plugin_midigain(void); | ||||
extern void carla_register_native_plugin_midijoin(void); | extern void carla_register_native_plugin_midijoin(void); | ||||
extern void carla_register_native_plugin_midisplit(void); | extern void carla_register_native_plugin_midisplit(void); | ||||
@@ -61,6 +62,7 @@ void carla_register_all_native_plugins(void) | |||||
carla_register_native_plugin_bypass(); | carla_register_native_plugin_bypass(); | ||||
carla_register_native_plugin_lfo(); | carla_register_native_plugin_lfo(); | ||||
carla_register_native_plugin_midichanfilter(); | carla_register_native_plugin_midichanfilter(); | ||||
carla_register_native_plugin_midichanab(); | |||||
carla_register_native_plugin_midigain(); | carla_register_native_plugin_midigain(); | ||||
carla_register_native_plugin_midijoin(); | carla_register_native_plugin_midijoin(); | ||||
carla_register_native_plugin_midisplit(); | carla_register_native_plugin_midisplit(); | ||||
@@ -28,6 +28,7 @@ | |||||
extern void carla_register_native_plugin_bypass(void); | extern void carla_register_native_plugin_bypass(void); | ||||
extern void carla_register_native_plugin_lfo(void); | extern void carla_register_native_plugin_lfo(void); | ||||
extern void carla_register_native_plugin_midichanfilter(void); | extern void carla_register_native_plugin_midichanfilter(void); | ||||
extern void carla_register_native_plugin_midichanab(void); | |||||
extern void carla_register_native_plugin_midigain(void); | extern void carla_register_native_plugin_midigain(void); | ||||
extern void carla_register_native_plugin_midijoin(void); | extern void carla_register_native_plugin_midijoin(void); | ||||
extern void carla_register_native_plugin_midisplit(void); | extern void carla_register_native_plugin_midisplit(void); | ||||
@@ -52,6 +53,7 @@ void carla_register_all_native_plugins(void) | |||||
carla_register_native_plugin_bypass(); | carla_register_native_plugin_bypass(); | ||||
carla_register_native_plugin_lfo(); | carla_register_native_plugin_lfo(); | ||||
carla_register_native_plugin_midichanfilter(); | carla_register_native_plugin_midichanfilter(); | ||||
carla_register_native_plugin_midichanab(); | |||||
carla_register_native_plugin_midigain(); | carla_register_native_plugin_midigain(); | ||||
carla_register_native_plugin_midijoin(); | carla_register_native_plugin_midijoin(); | ||||
carla_register_native_plugin_midisplit(); | carla_register_native_plugin_midisplit(); | ||||
@@ -83,6 +83,22 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | DESCFUNCS | ||||
}, | }, | ||||
{ | |||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | |||||
/* hints */ NATIVE_PLUGIN_IS_RTSAFE, | |||||
/* supports */ NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | |||||
/* audioIns */ 0, | |||||
/* audioOuts */ 0, | |||||
/* midiIns */ 1, | |||||
/* midiOuts */ 2, | |||||
/* paramIns */ 0, | |||||
/* paramOuts */ 0, | |||||
/* name */ "MIDI Channel A/B", | |||||
/* label */ "midichanab", | |||||
/* maker */ "Milk Brewster", | |||||
/* copyright */ "GNU GPL v2+", | |||||
DESCFUNCS | |||||
}, | |||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
/* hints */ NATIVE_PLUGIN_IS_RTSAFE, | /* hints */ NATIVE_PLUGIN_IS_RTSAFE, | ||||
@@ -67,6 +67,22 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | DESCFUNCS | ||||
}, | }, | ||||
{ | |||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | |||||
/* hints */ NATIVE_PLUGIN_IS_RTSAFE, | |||||
/* supports */ NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | |||||
/* audioIns */ 0, | |||||
/* audioOuts */ 0, | |||||
/* midiIns */ 1, | |||||
/* midiOuts */ 2, | |||||
/* paramIns */ 0, | |||||
/* paramOuts */ 0, | |||||
/* name */ "MIDI Channel A/B", | |||||
/* label */ "midichanab", | |||||
/* maker */ "Milk Brewster", | |||||
/* copyright */ "GNU GPL v2+", | |||||
DESCFUNCS | |||||
}, | |||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
/* hints */ NATIVE_PLUGIN_IS_RTSAFE, | /* hints */ NATIVE_PLUGIN_IS_RTSAFE, | ||||
@@ -0,0 +1,211 @@ | |||||
/* | |||||
* Carla Native Plugins | |||||
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2018 Milk Brewster <code@milkmiruku.com> | |||||
* | |||||
* This program is free software; you can redistribute it and/or | |||||
* modify it under the terms of the GNU General Public License as | |||||
* published by the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
*/ | |||||
#include "CarlaNative.h" | |||||
#include "CarlaMIDI.h" | |||||
#include <stdlib.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
// ----------------------------------------------------------------------- | |||||
typedef struct { | |||||
const NativeHostDescriptor* host; | |||||
bool channels[MAX_MIDI_CHANNELS]; | |||||
} MidiGainHandle; | |||||
// ----------------------------------------------------------------------- | |||||
static NativePluginHandle midichanab_instantiate(const NativeHostDescriptor* host) | |||||
{ | |||||
MidiGainHandle* const handle = (MidiGainHandle*)malloc(sizeof(MidiGainHandle)); | |||||
if (handle == NULL) | |||||
return NULL; | |||||
handle->host = host; | |||||
memset(handle->channels, 0, MAX_MIDI_CHANNELS); | |||||
return handle; | |||||
} | |||||
#define handlePtr ((MidiGainHandle*)handle) | |||||
static void midichanab_cleanup(NativePluginHandle handle) | |||||
{ | |||||
free(handlePtr); | |||||
} | |||||
static uint32_t midichanab_get_parameter_count(NativePluginHandle handle) | |||||
{ | |||||
return MAX_MIDI_CHANNELS; | |||||
// unused | |||||
(void)handle; | |||||
} | |||||
static const NativeParameter* midichanab_get_parameter_info(NativePluginHandle handle, uint32_t index) | |||||
{ | |||||
if (index >= MAX_MIDI_CHANNELS) | |||||
return NULL; | |||||
static NativeParameter param; | |||||
static const NativeParameterScalePoint scalePoints[2] = { { "Output A", 0 }, { "Output B", 1 } }; | |||||
static char paramName[24]; | |||||
param.hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE|NATIVE_PARAMETER_IS_BOOLEAN|NATIVE_PARAMETER_USES_SCALEPOINTS; | |||||
param.name = paramName; | |||||
param.unit = NULL; | |||||
param.ranges.def = 0; | |||||
param.ranges.min = 0; | |||||
param.ranges.max = 1; | |||||
param.ranges.step = 1; | |||||
param.ranges.stepSmall = 1; | |||||
param.ranges.stepLarge = 1; | |||||
param.scalePointCount = 2; | |||||
param.scalePoints = scalePoints; | |||||
snprintf(paramName, 24, "%u", index+1); | |||||
return ¶m; | |||||
// unused | |||||
(void)handle; | |||||
} | |||||
static float midichanab_get_parameter_value(NativePluginHandle handle, uint32_t index) | |||||
{ | |||||
if (index >= MAX_MIDI_CHANNELS) | |||||
return 0; | |||||
return handlePtr->channels[index] ? 1 : 0; | |||||
} | |||||
static void midichanab_set_parameter_value(NativePluginHandle handle, uint32_t index, float value) | |||||
{ | |||||
if (index >= MAX_MIDI_CHANNELS) | |||||
return; | |||||
handlePtr->channels[index] = (value >= 0.5f); | |||||
} | |||||
static void midichanab_process(NativePluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount) | |||||
{ | |||||
const NativeHostDescriptor* const host = handlePtr->host; | |||||
const bool* const channels = handlePtr->channels; | |||||
NativeMidiEvent tmpEvent; | |||||
for (uint32_t i=0; i < midiEventCount; ++i) | |||||
{ | |||||
const NativeMidiEvent* const midiEvent = &midiEvents[i]; | |||||
const uint8_t status = (uint8_t)MIDI_GET_STATUS_FROM_DATA(midiEvent->data); | |||||
if (MIDI_IS_CHANNEL_MESSAGE(status)) | |||||
{ | |||||
const uint8_t channel = (uint8_t)MIDI_GET_CHANNEL_FROM_DATA(midiEvent->data); | |||||
if (channel >= MAX_MIDI_CHANNELS) | |||||
continue; | |||||
if (channels[channel]) | |||||
{ | |||||
memcpy(&tmpEvent, midiEvent, sizeof(NativeMidiEvent)); | |||||
++tmpEvent.port; | |||||
host->write_midi_event(host->handle, &tmpEvent); | |||||
} | |||||
else | |||||
{ | |||||
host->write_midi_event(host->handle, midiEvent); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
// pass through all non-message events | |||||
host->write_midi_event(host->handle, midiEvent); | |||||
} | |||||
} | |||||
return; | |||||
// unused | |||||
(void)inBuffer; | |||||
(void)outBuffer; | |||||
(void)frames; | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
static const NativePluginDescriptor midichanabDesc = { | |||||
.category = NATIVE_PLUGIN_CATEGORY_UTILITY, | |||||
.hints = NATIVE_PLUGIN_IS_RTSAFE, | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | |||||
.audioIns = 0, | |||||
.audioOuts = 0, | |||||
.midiIns = 1, | |||||
.midiOuts = 2, | |||||
.paramIns = 0, | |||||
.paramOuts = 0, | |||||
.name = "MIDI Channel A/B", | |||||
.label = "midichanab", | |||||
.maker = "Milk Brewster", | |||||
.copyright = "GNU GPL v2+", | |||||
.instantiate = midichanab_instantiate, | |||||
.cleanup = midichanab_cleanup, | |||||
.get_parameter_count = midichanab_get_parameter_count, | |||||
.get_parameter_info = midichanab_get_parameter_info, | |||||
.get_parameter_value = midichanab_get_parameter_value, | |||||
.get_midi_program_count = NULL, | |||||
.get_midi_program_info = NULL, | |||||
.set_parameter_value = midichanab_set_parameter_value, | |||||
.set_midi_program = NULL, | |||||
.set_custom_data = NULL, | |||||
.ui_show = NULL, | |||||
.ui_idle = NULL, | |||||
.ui_set_parameter_value = NULL, | |||||
.ui_set_midi_program = NULL, | |||||
.ui_set_custom_data = NULL, | |||||
.activate = NULL, | |||||
.deactivate = NULL, | |||||
.process = midichanab_process, | |||||
.get_state = NULL, | |||||
.set_state = NULL, | |||||
.dispatcher = NULL | |||||
}; | |||||
// ----------------------------------------------------------------------- | |||||
void carla_register_native_plugin_midichanab(void); | |||||
void carla_register_native_plugin_midichanab(void) | |||||
{ | |||||
carla_register_native_plugin(&midichanabDesc); | |||||
} | |||||
// ----------------------------------------------------------------------- |
@@ -63,6 +63,7 @@ struct PluginListManager { | |||||
if (std::strcmp(desc->label, "lfo" ) == 0 || | if (std::strcmp(desc->label, "lfo" ) == 0 || | ||||
std::strcmp(desc->label, "midichanfilter" ) == 0 || | std::strcmp(desc->label, "midichanfilter" ) == 0 || | ||||
std::strcmp(desc->label, "midichanab" ) == 0 || | |||||
std::strcmp(desc->label, "midigain" ) == 0 || | std::strcmp(desc->label, "midigain" ) == 0 || | ||||
std::strcmp(desc->label, "midijoin" ) == 0 || | std::strcmp(desc->label, "midijoin" ) == 0 || | ||||
std::strcmp(desc->label, "midisplit" ) == 0 || | std::strcmp(desc->label, "midisplit" ) == 0 || | ||||