| @@ -8,7 +8,18 @@ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| // ----------------------------------------------------------------------- | |||
| /** | |||
| * FrontLeft, FrontRight, RearLeft, and RearRight speakers: room corners or car doors-like located. | |||
| * Here is each of L-R, F-R controls attenuates two channels but not one. | |||
| * | |||
| * If L-R is +0.1 and F-R is -0.2 then: | |||
| * FrontLeft channel is *= (0.9 * 1.0), | |||
| * FrontRight *= (1.0 * 1.0), | |||
| * RearLeft *= (0.9 * 0.8), | |||
| * and RearRight *= (1.0 * 0.8). | |||
| */ | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| typedef struct { | |||
| float a0, b1, z1; | |||
| @@ -24,7 +35,7 @@ void set_filter_sample_rate(Filter* const filter, const float sampleRate) | |||
| filter->z1 = 0.0f; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| typedef enum { | |||
| PARAM_LEFT_RIGHT = 0, | |||
| @@ -37,7 +48,7 @@ typedef struct { | |||
| float params[PARAM_COUNT]; | |||
| } QuadPannerHandle; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static NativePluginHandle quadpanner_instantiate(const NativeHostDescriptor* host) | |||
| { | |||
| @@ -135,35 +146,36 @@ static void quadpanner_process(NativePluginHandle handle, | |||
| float** inBuffer, float** outBuffer, uint32_t frames, | |||
| const NativeMidiEvent* midiEvents, uint32_t midiEventCount) | |||
| { | |||
| float v1, v2, tmp; | |||
| float v1, v2, v3, v4, tmp; // FrontLeft, FrontRight, RearLeft, and RearRight | |||
| // left/right | |||
| if ((tmp = handlePtr->params[PARAM_LEFT_RIGHT]) < 0.f) | |||
| { | |||
| v1 = 1.f; | |||
| v2 = 1.f - tmp * -0.01f; | |||
| v1 = v3 = 1.f; | |||
| v2 = v4 = 1.f - tmp * -0.01f; | |||
| } | |||
| else | |||
| { | |||
| v1 = 1.f - tmp * 0.01f; | |||
| v2 = 1.f; | |||
| v1 = v3 = 1.f - tmp * 0.01f; | |||
| v2 = v4 = 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) | |||
| if ((tmp = handlePtr->params[PARAM_FRONT_REAR] * 0.01f) < 0.f) | |||
| { | |||
| v1 = 1.f; | |||
| v2 = 1.f - tmp * -0.01f; | |||
| v3 *= 1.f - -tmp; | |||
| v4 *= 1.f - -tmp; | |||
| } | |||
| else | |||
| { | |||
| v1 = 1.f - tmp * 0.01f; | |||
| v2 = 1.f; | |||
| v1 *= 1.f - tmp; | |||
| v2 *= 1.f - tmp; | |||
| } | |||
| handle_audio_buffers(inBuffer[2], outBuffer[2], &handlePtr->lowpass[2], v1, frames); | |||
| handle_audio_buffers(inBuffer[3], outBuffer[3], &handlePtr->lowpass[3], v2, frames); | |||
| handle_audio_buffers(inBuffer[0], outBuffer[0], &handlePtr->lowpass[0], v1, frames); | |||
| handle_audio_buffers(inBuffer[1], outBuffer[1], &handlePtr->lowpass[1], v2, frames); | |||
| handle_audio_buffers(inBuffer[2], outBuffer[2], &handlePtr->lowpass[2], v3, frames); | |||
| handle_audio_buffers(inBuffer[3], outBuffer[3], &handlePtr->lowpass[3], v4, frames); | |||
| return; | |||
| @@ -176,12 +188,12 @@ static intptr_t quadpanner_dispatcher(NativePluginHandle handle, NativePluginDis | |||
| { | |||
| 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: | |||
| 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; | |||
| @@ -195,16 +207,16 @@ static intptr_t quadpanner_dispatcher(NativePluginHandle handle, NativePluginDis | |||
| 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", | |||
| "In-FrontLeft", | |||
| "In-FrontRight", | |||
| "In-RearLeft", | |||
| "In-RearRight", | |||
| }; | |||
| static const char* const kOutNames[4] = { | |||
| "Out-Left", | |||
| "Out-Right", | |||
| "Out-Front", | |||
| "Out-Rear", | |||
| "Out-FrontLeft", | |||
| "Out-FrontRight", | |||
| "Out-RearLeft", | |||
| "Out-RearRight", | |||
| }; | |||
| return isOutput ? kOutNames[index] : kInNames[index]; | |||
| @@ -213,7 +225,7 @@ static const char* quadpanner_get_buffer_port_name(NativePluginHandle handle, ui | |||
| (void)handle; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static const NativePluginDescriptor quadpannerDesc = { | |||
| .category = NATIVE_PLUGIN_CATEGORY_UTILITY, | |||
| @@ -268,7 +280,7 @@ static const NativePluginDescriptor quadpannerDesc = { | |||
| .get_buffer_port_range = NULL, | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void carla_register_native_plugin_quadpanner(void); | |||
| @@ -277,4 +289,4 @@ void carla_register_native_plugin_quadpanner(void) | |||
| carla_register_native_plugin(&quadpannerDesc); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||