Browse Source

Add Quad-Panner internal plugin, cleanup

Signed-off-by: falkTX <falktx@falktx.com>
pull/2011/head
falkTX 3 months ago
parent
commit
74c6c55fe6
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
6 changed files with 315 additions and 73 deletions
  1. +1
    -0
      source/native-plugins/Makefile
  2. +6
    -18
      source/native-plugins/_all.c
  3. +18
    -16
      source/native-plugins/_data.cpp
  4. +4
    -19
      source/native-plugins/audio-gain.c
  5. +6
    -20
      source/native-plugins/midi-to-cv.c
  6. +280
    -0
      source/native-plugins/quadpanner.c

+ 1
- 0
source/native-plugins/Makefile View File

@@ -40,6 +40,7 @@ OBJS = \
$(OBJDIR)/bypass.c.o \
$(OBJDIR)/cv-to-audio.c.o \
$(OBJDIR)/lfo.c.o \
$(OBJDIR)/quadpanner.c.o \
$(OBJDIR)/midi-channel-filter.c.o \
$(OBJDIR)/midi-channel-ab.c.o \
$(OBJDIR)/midi-channelize.c.o \


+ 6
- 18
source/native-plugins/_all.c View File

@@ -1,19 +1,5 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.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.
*/
// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#include "CarlaDefines.h"
#include "CarlaNative.h"
@@ -25,6 +11,7 @@ extern void carla_register_native_plugin_audiogain(void);
extern void carla_register_native_plugin_bypass(void);
extern void carla_register_native_plugin_cv2audio(void);
extern void carla_register_native_plugin_lfo(void);
extern void carla_register_native_plugin_quadpanner(void);
extern void carla_register_native_plugin_midi2cv(void);
extern void carla_register_native_plugin_midichanab(void);
extern void carla_register_native_plugin_midichanfilter(void);
@@ -38,15 +25,15 @@ extern void carla_register_native_plugin_miditranspose(void);
// Audio file
extern void carla_register_native_plugin_audiofile(void);

// MIDI file and sequencer
// MIDI file
extern void carla_register_native_plugin_midifile(void);
extern void carla_register_native_plugin_midipattern(void);

// Carla
extern void carla_register_native_plugin_carla(void);

// External-UI plugins
extern void carla_register_native_plugin_bigmeter(void);
extern void carla_register_native_plugin_midipattern(void);
extern void carla_register_native_plugin_notes(void);
extern void carla_register_native_plugin_xycontroller(void);

@@ -65,6 +52,7 @@ void carla_register_all_native_plugins(void)
carla_register_native_plugin_bypass();
carla_register_native_plugin_cv2audio();
carla_register_native_plugin_lfo();
carla_register_native_plugin_quadpanner();
carla_register_native_plugin_midi2cv();
carla_register_native_plugin_midichanab();
carla_register_native_plugin_midichannelize();


+ 18
- 16
source/native-plugins/_data.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.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.
*/
// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#include "CarlaNative.h"
#include "CarlaMIDI.h"
@@ -122,6 +108,22 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* copyright */ "GNU GPL v2+",
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
/* hints */ NATIVE_PLUGIN_IS_RTSAFE,
/* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING,
/* audioIns */ 4,
/* audioOuts */ 4,
/* midiIns */ 0,
/* midiOuts */ 0,
/* paramIns */ 2,
/* paramOuts */ 0,
/* name */ "Quad-Panner",
/* label */ "quadpanner",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
/* hints */ NATIVE_PLUGIN_IS_RTSAFE,


+ 4
- 19
source/native-plugins/audio-gain.c View File

@@ -1,22 +1,7 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.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.
*/
// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#include "CarlaNative.h"
#include "CarlaMIDI.h"

#include <math.h>
#include <stdbool.h>
@@ -203,8 +188,8 @@ void handle_audio_buffers(const float* inBuffer, float* outBuffer, Filter* const

// FIXME for v3.0, use const for the input buffer
static void audiogain_process(NativePluginHandle handle,
float** inBuffer, float** outBuffer, uint32_t frames,
const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
float** inBuffer, float** outBuffer, uint32_t frames,
const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
{
const float gain = handlePtr->gain;
const bool applyLeft = handlePtr->applyLeft;


+ 6
- 20
source/native-plugins/midi-to-cv.c View File

@@ -1,19 +1,5 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.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.
*/
// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later

/* This plugin code is based on MOD Devices' midi-to-cv-mono by Bram Giesen and Jarno Verheesen
*/
@@ -385,9 +371,6 @@ static const NativePluginDescriptor midi2cvDesc = {
.set_midi_program = NULL,
.set_custom_data = NULL,

.get_buffer_port_name = midi2cv_get_buffer_port_name,
.get_buffer_port_range = midi2cv_get_buffer_port_range,

.ui_show = NULL,
.ui_idle = NULL,

@@ -404,7 +387,10 @@ static const NativePluginDescriptor midi2cvDesc = {

.dispatcher = NULL,

.render_inline_display = NULL
.render_inline_display = NULL,

.get_buffer_port_name = midi2cv_get_buffer_port_name,
.get_buffer_port_range = midi2cv_get_buffer_port_range,
};

// -----------------------------------------------------------------------


+ 280
- 0
source/native-plugins/quadpanner.c View File

@@ -0,0 +1,280 @@
// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#include "CarlaNative.h"

#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

// -----------------------------------------------------------------------

typedef struct {
float a0, b1, z1;
} Filter;

static inline
void set_filter_sample_rate(Filter* const filter, const float sampleRate)
{
const float frequency = 30.0f / sampleRate;

filter->b1 = expf(-2.0f * (float)M_PI * frequency);
filter->a0 = 1.0f - filter->b1;
filter->z1 = 0.0f;
}

// -----------------------------------------------------------------------

typedef enum {
PARAM_LEFT_RIGHT = 0,
PARAM_FRONT_REAR,
PARAM_COUNT
} QuadPannerParams;

typedef struct {
Filter lowpass[PARAM_COUNT * 2];
float params[PARAM_COUNT];
} QuadPannerHandle;

// -----------------------------------------------------------------------

static NativePluginHandle quadpanner_instantiate(const NativeHostDescriptor* host)
{
QuadPannerHandle* const handle = calloc(1, sizeof(QuadPannerHandle));

if (handle == NULL)
return NULL;

const float sampleRate = host->get_sample_rate(host->handle);

for (unsigned i = 0; i < PARAM_COUNT * 2; ++i)
set_filter_sample_rate(&handle->lowpass[i], sampleRate);

return handle;
}

#define handlePtr ((QuadPannerHandle*)handle)

static void quadpanner_cleanup(NativePluginHandle handle)
{
free(handlePtr);
}

static uint32_t quadpanner_get_parameter_count(NativePluginHandle handle)
{
return PARAM_COUNT;

// unused
(void)handle;
}

static const NativeParameter* quadpanner_get_parameter_info(NativePluginHandle handle, uint32_t index)
{
if (index > PARAM_COUNT)
return NULL;

static NativeParameter param;

param.hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMATABLE;
param.unit = "%";
param.ranges.def = 0.0f;
param.ranges.min = -100.0f;
param.ranges.max = 100.0f;
param.ranges.step = 1;
param.ranges.stepSmall = 1;
param.ranges.stepLarge = 10;

switch (index)
{
case PARAM_LEFT_RIGHT:
param.name = "Left/Right";
break;
case PARAM_FRONT_REAR:
param.name = "Front/Rear";
break;
}

return &param;

// unused
(void)handle;
}

static float quadpanner_get_parameter_value(NativePluginHandle handle, uint32_t index)
{
return handlePtr->params[index];
}

static void quadpanner_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
{
handlePtr->params[index] = value;
}

static inline
void handle_audio_buffers(const float* inBuffer,
float* outBuffer,
Filter* const filter,
const float gain,
const uint32_t frames)
{
const float a0 = filter->a0;
const float b1 = filter->b1;
float z1 = filter->z1;

for (uint32_t i = 0; i < frames; ++i) {
z1 = gain * a0 + z1 * b1;
*outBuffer++ = *inBuffer++ * z1;
}

filter->z1 = z1;
}

// FIXME for v3.0, use const for the input buffer
static void quadpanner_process(NativePluginHandle handle,
float** inBuffer, float** outBuffer, uint32_t frames,
const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
{
float v1, v2, tmp;

// left/right
if ((tmp = handlePtr->params[PARAM_LEFT_RIGHT]) < 0.f)
{
v1 = 1.f;
v2 = 1.f - tmp * -0.01f;
}
else
{
v1 = 1.f - tmp * 0.01f;
v2 = 1.f;
}
handle_audio_buffers(inBuffer[0], outBuffer[0], &handlePtr->lowpass[0], v1, frames);
handle_audio_buffers(inBuffer[1], outBuffer[1], &handlePtr->lowpass[1], v2, frames);

// front/rear
if ((tmp = handlePtr->params[PARAM_FRONT_REAR]) < 0.f)
{
v1 = 1.f;
v2 = 1.f - tmp * -0.01f;
}
else
{
v1 = 1.f - tmp * 0.01f;
v2 = 1.f;
}
handle_audio_buffers(inBuffer[2], outBuffer[2], &handlePtr->lowpass[2], v1, frames);
handle_audio_buffers(inBuffer[3], outBuffer[3], &handlePtr->lowpass[3], v2, frames);

return;

// unused
(void)midiEvents;
(void)midiEventCount;
}

static intptr_t quadpanner_dispatcher(NativePluginHandle handle, NativePluginDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
switch (opcode)
{
case NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
for (unsigned i = 0; i < PARAM_COUNT * 2; ++i)
set_filter_sample_rate(&handlePtr->lowpass[i], opt);
break;
default:
break;
}

return 0;

// unused
(void)index;
(void)value;
(void)ptr;
}

static const char* quadpanner_get_buffer_port_name(NativePluginHandle handle, uint32_t index, bool isOutput)
{
static const char* const kInNames[4] = {
"In-Left",
"In-Right",
"In-Front",
"In-Rear",
};
static const char* const kOutNames[4] = {
"Out-Left",
"Out-Right",
"Out-Front",
"Out-Rear",
};

return isOutput ? kOutNames[index] : kInNames[index];

// unused
(void)handle;
}

// -----------------------------------------------------------------------

static const NativePluginDescriptor quadpannerDesc = {
.category = NATIVE_PLUGIN_CATEGORY_UTILITY,
.hints = NATIVE_PLUGIN_IS_RTSAFE,
.supports = NATIVE_PLUGIN_SUPPORTS_NOTHING,
.audioIns = 4,
.audioOuts = 4,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 0,
.midiOuts = 0,
.paramIns = PARAM_COUNT,
.paramOuts = 0,
.name = "Quad-Panner",
.label = "quadpanner",
.maker = "falkTX",
.copyright = "GNU GPL v2+",

.instantiate = quadpanner_instantiate,
.cleanup = quadpanner_cleanup,

.get_parameter_count = quadpanner_get_parameter_count,
.get_parameter_info = quadpanner_get_parameter_info,
.get_parameter_value = quadpanner_get_parameter_value,

.get_midi_program_count = NULL,
.get_midi_program_info = NULL,

.set_parameter_value = quadpanner_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 = quadpanner_process,

.get_state = NULL,
.set_state = NULL,

.dispatcher = quadpanner_dispatcher,

.render_inline_display = NULL,

.get_buffer_port_name = quadpanner_get_buffer_port_name,
.get_buffer_port_range = NULL,
};

// -----------------------------------------------------------------------

void carla_register_native_plugin_quadpanner(void);

void carla_register_native_plugin_quadpanner(void)
{
carla_register_native_plugin(&quadpannerDesc);
}

// -----------------------------------------------------------------------

Loading…
Cancel
Save