M ext/meson.build => ext/meson.build +1 -0
@@ 17,6 17,7 @@
subdir ('midilib')
subdir ('nanovg')
+subdir ('noisegate-lv2')
subdir ('weakjack')
subdir ('whereami')
subdir ('zix')
A ext/noisegate-lv2/LICENSE => ext/noisegate-lv2/LICENSE +13 -0
@@ 0,0 1,13 @@
+VEJA NoiseGate
+Copyright (C) 2021 Jan Janssen <jan@moddevices.com>
+
+Permission to use, copy, modify, and/or distribute this software for any purpose with
+or without fee is hereby granted, provided that the above copyright notice and this
+permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
A ext/noisegate-lv2/Makefile => ext/noisegate-lv2/Makefile +44 -0
@@ 0,0 1,44 @@
+#!/usr/bin/make -f
+# Makefile for noisegate.lv2 #
+# --------------------------------- #
+
+include Makefile.mk
+
+NAME = noisegate
+
+# --------------------------------------------------------------
+# Installation path
+
+INSTALL_PATH = /usr/local/lib/lv2
+COMPLETE_INSTALL_PATH = $(DESTDIR)$(INSTALL_PATH)/$(NAME).lv2
+
+# --------------------------------------------------------------
+# Default target is to build all plugins
+
+all: build
+build: $(NAME)-build
+
+# --------------------------------------------------------------
+# Build rules
+
+$(NAME)-build: $(NAME).lv2/$(NAME)$(LIB_EXT)
+
+$(NAME).lv2/$(NAME)$(LIB_EXT): $(NAME).c gate_core.c circular_buffer.c
+ $(CC) $^ $(BUILD_C_FLAGS) $(LINK_FLAGS) -lm $(SHARED) -o $@
+
+# --------------------------------------------------------------
+
+clean:
+ rm -f $(NAME).lv2/$(NAME)$(LIB_EXT)
+
+# --------------------------------------------------------------
+
+install: build
+ install -d $(DESTDIR)$(PREFIX)/lib/lv2/$(NAME).lv2
+
+ install -m 644 $(NAME).lv2/*.so $(DESTDIR)$(PREFIX)/lib/lv2/$(NAME).lv2/
+ install -m 644 $(NAME).lv2/*.ttl $(DESTDIR)$(PREFIX)/lib/lv2/$(NAME).lv2/
+ cp -rv $(NAME).lv2/modgui $(DESTDIR)$(PREFIX)/lib/lv2/$(NAME).lv2/
+
+# --------------------------------------------------------------
+
A ext/noisegate-lv2/Makefile.mk => ext/noisegate-lv2/Makefile.mk +79 -0
@@ 0,0 1,79 @@
+#!/usr/bin/make -f
+# Makefile for noisegate.lv2 #
+# ----------------------- #
+#
+
+AR ?= ar
+CC ?= gcc
+CXX ?= g++
+
+# --------------------------------------------------------------
+# Fallback to Linux if no other OS defined
+
+ifneq ($(MACOS),true)
+ifneq ($(WIN32),true)
+LINUX=true
+endif
+endif
+
+# --------------------------------------------------------------
+# Set build and link flags
+
+BASE_FLAGS = -Wall -Wextra -pipe -Wno-unused-parameter
+BASE_OPTS = -O3 -ffast-math
+
+ifeq ($(MACOS),true)
+# MacOS linker flags
+LINK_OPTS = -Wl,-dead_strip -Wl,-dead_strip_dylibs
+else
+# Common linker flags
+LINK_OPTS = -Wl,-O1 -Wl,--as-needed -Wl,--strip-all
+endif
+
+ifneq ($(WIN32),true)
+# not needed for Windows
+BASE_FLAGS += -fPIC -DPIC
+endif
+
+ifeq ($(DEBUG),true)
+BASE_FLAGS += -O3 -g
+LINK_OPTS =
+else
+BASE_FLAGS += -DNDEBUG $(BASE_OPTS) -fvisibility=hidden -O3
+CXXFLAGS += -fvisibility-inlines-hidden
+endif
+
+BUILD_C_FLAGS = $(BASE_FLAGS) -std=c99 -std=gnu99 $(CFLAGS)
+BUILD_CXX_FLAGS = $(BASE_FLAGS) -std=c++11 $(CXXFLAGS) $(CPPFLAGS)
+
+ifeq ($(MACOS),true)
+# 'no-undefined' is always enabled on MacOS
+LINK_FLAGS = $(LINK_OPTS) $(LDFLAGS)
+else
+# add 'no-undefined'
+LINK_FLAGS = $(LINK_OPTS) -Wl,--no-undefined $(LDFLAGS)
+endif
+
+# --------------------------------------------------------------
+# Set shared lib extension
+
+LIB_EXT = .so
+
+ifeq ($(MACOS),true)
+LIB_EXT = .dylib
+endif
+
+ifeq ($(WIN32),true)
+LIB_EXT = .dll
+endif
+
+# --------------------------------------------------------------
+# Set shared library CLI arg
+
+SHARED = -shared
+
+ifeq ($(MACOS),true)
+SHARED = -dynamiclib
+endif
+
+# --------------------------------------------------------------
A ext/noisegate-lv2/README.md => ext/noisegate-lv2/README.md +3 -0
@@ 0,0 1,3 @@
+# Noise-Gate
+
+A simple noisegate with seperate gate and audio input
A ext/noisegate-lv2/circular_buffer.c => ext/noisegate-lv2/circular_buffer.c +165 -0
@@ 0,0 1,165 @@
+/*
+ ==============================================================================
+
+ * VEJA NoiseGate
+ * Copyright (C) 2021 Jan Janssen <jan@moddevices.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ==============================================================================
+*/
+
+#include "circular_buffer.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+void ringbuffer_clear(ringbuffer_t *buffer, uint32_t size)
+{
+ buffer->S=size;
+
+ uint32_t q = 0;
+ for ( q = 0; q < size; q++)
+ {
+ buffer->m_buffer[q] = 0.0f;
+ }
+
+ buffer->m_size = 0;
+ buffer->m_front = 0;
+ buffer->m_back = buffer->S - 1;
+ buffer->power = 0.0f;
+}
+
+void ringbuffer_push(ringbuffer_t *buffer)
+{
+ buffer->m_back = (buffer->m_back + 1) % buffer->S;
+
+ if(buffer->m_size == buffer->S)
+ {
+ buffer->m_front = (buffer->m_front + 1) % buffer->S;
+ }
+ else
+ {
+ buffer->m_size++;
+ }
+}
+
+void ringbuffer_push_sample(ringbuffer_t *buffer, const float x)
+{
+ ringbuffer_push(buffer);
+ buffer->m_buffer[buffer->m_back] = x;
+}
+
+void ringbuffer_pop(ringbuffer_t *buffer)
+{
+ if(buffer->m_size > 0 )
+ {
+ buffer->m_size--;
+ buffer->m_front = (buffer->m_front + 1) % buffer->S;
+ }
+}
+
+void ringbuffer_back_erase(ringbuffer_t *buffer, const uint32_t n)
+{
+ if(n >= buffer->m_size)
+ {
+ ringbuffer_clear(buffer, buffer->S);
+ }
+ else
+ {
+ buffer->m_size -= n;
+ buffer->m_back = (buffer->m_front + buffer->m_size - 1) % buffer->S;
+ }
+}
+
+void ringbuffer_front_erase(ringbuffer_t *buffer, const uint32_t n)
+{
+ if(n >= buffer->m_size)
+ {
+ ringbuffer_clear(buffer, buffer->S);
+ }
+ else
+ {
+ buffer->m_size -= n;
+ buffer->m_front = (buffer->m_front + n) % buffer->S;
+ }
+}
+
+int ringbuffer_peek_index(ringbuffer_t *buffer)
+{
+ uint32_t peek_index = 0;
+ float peek_value = 0;
+
+ uint32_t i = 0;
+ for (i = 0; i < buffer->S; i++)
+ {
+ if (peek_value < buffer->m_buffer[i])
+ {
+ peek_value = buffer->m_buffer[i];
+ peek_index = i;
+ }
+ }
+
+ return peek_index;
+}
+
+float ringbuffer_push_and_calculate_power(ringbuffer_t *buffer, const float input)
+{
+ float pow = sqrt(input * input) * (1.0f / buffer->S);
+
+ if (buffer->m_size < buffer->S)
+ {
+ //remove old sample and add new one to windowPower
+ buffer->power += pow;
+ ringbuffer_push_sample(buffer, pow);
+ }
+ else
+ {
+ //remove old sample and add new one to windowPower
+ buffer->power += pow - ringbuffer_front(buffer);
+ ringbuffer_pop(buffer);
+ ringbuffer_push_sample(buffer, pow);
+ }
+
+ return buffer->power;
+}
+
+float ringbuffer_front(ringbuffer_t *buffer)
+{
+ return buffer->m_buffer[buffer->m_front];
+}
+
+float ringbuffer_back(ringbuffer_t *buffer)
+{
+ return buffer->m_buffer[buffer->m_back];
+}
+
+float ringbuffer_get_val(ringbuffer_t *buffer, uint32_t index)
+{
+ return buffer->m_buffer[index];
+}
+
+int ringbuffer_empty(ringbuffer_t *buffer)
+{
+ return buffer->m_size == 0;
+}
+
+int ringbuffer_full(ringbuffer_t *buffer)
+{
+ return buffer->m_size == buffer->S;
+}
+
+float * ringbuffer_get_first_pointer(ringbuffer_t *buffer)
+{
+ return &buffer->m_buffer[buffer->m_back];
+}<
\ No newline at end of file
A ext/noisegate-lv2/circular_buffer.h => ext/noisegate-lv2/circular_buffer.h +52 -0
@@ 0,0 1,52 @@
+/*
+ ==============================================================================
+
+ * VEJA NoiseGate
+ * Copyright (C) 2021 Jan Janssen <jan@moddevices.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ==============================================================================
+*/
+
+#ifndef CIRCULAR_BUFFER_H
+#define CIRCULAR_BUFFER_H
+
+#include <stdint.h>
+
+#define MAX_BUFFER_SIZE 128
+
+typedef struct RINGBUFFER_T {
+ uint32_t S;
+ float m_buffer[MAX_BUFFER_SIZE];
+ uint32_t m_size;
+ uint32_t m_front;
+ uint32_t m_back;
+ float power;
+} ringbuffer_t;
+
+void ringbuffer_clear(ringbuffer_t *buffer, uint32_t size);
+void ringbuffer_push(ringbuffer_t *buffer);
+void ringbuffer_push_sample(ringbuffer_t *buffer, const float x);
+void ringbuffer_pop(ringbuffer_t *buffer);
+void ringbuffer_back_erase(ringbuffer_t *buffer, const uint32_t n);
+void ringbuffer_front_erase(ringbuffer_t *buffer, const uint32_t n);
+int ringbuffer_peek_index(ringbuffer_t *buffer);
+float ringbuffer_push_and_calculate_power(ringbuffer_t *buffer, const float input);
+float ringbuffer_front(ringbuffer_t *buffer);
+float ringbuffer_back(ringbuffer_t *buffer);
+float ringbuffer_get_val(ringbuffer_t *buffer, uint32_t index);
+int ringbuffer_empty(ringbuffer_t *buffer);
+int ringbuffer_full(ringbuffer_t *buffer);
+float * ringbuffer_get_first_pointer(ringbuffer_t *buffer);
+
+#endif // __RINGBUFFER_H__
A ext/noisegate-lv2/gate_core.c => ext/noisegate-lv2/gate_core.c +137 -0
@@ 0,0 1,137 @@
+/*
+ ==============================================================================
+
+ * VEJA NoiseGate
+ * Copyright (C) 2021 Jan Janssen <jan@moddevices.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ==============================================================================
+*/
+
+#include "gate_core.h"
+#include "circular_buffer.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+
+/*******************************************************************************
+ global functions
+*******************************************************************************/
+
+void Gate_Init(gate_t *gate)
+{
+ gate->_alpha = 1.0f;
+ gate->_rmsValue = 0.0f;
+ gate->_keyValue = 0.0f;
+ gate->_upperThreshold = 0.0f;
+ gate->_lowerThreshold = 0.0f;
+ gate->_attackTime = 0;
+ gate->_decayTime = 0;
+ gate->_holdTime = 0;
+ gate->_attackCounter = 0;
+ gate->_decayCounter = 0;
+ gate->_holdCounter = 0;
+ gate->_currentState = IDLE;
+ gate->_tau = 0;
+
+ ringbuffer_clear(&gate->window, MAX_BUFFER_SIZE);
+}
+
+void Gate_UpdateParameters(gate_t *gate, const uint32_t sampleRate, const uint32_t attack, const uint32_t hold,
+ const uint32_t decay, const uint32_t alpha, const float upperThreshold,
+ const float lowerThreshold)
+{
+ gate->_tau = sampleRate * 0.001f; //sample time in ms
+
+ gate->_upperThreshold = powf(10.0f, (upperThreshold / 20.0f)); // dB to level
+ gate->_lowerThreshold = powf(10.0f, (lowerThreshold / 20.0f));
+ gate->_attackTime = attack * gate->_tau;
+ gate->_decayTime = decay * gate->_tau;
+ gate->_holdTime = hold * gate->_tau;
+ gate->_alpha = alpha;
+}
+
+float Gate_ApplyGate(gate_t *gate, const float input, const float key)
+{
+ //get new keyValue
+ gate->_keyValue = ringbuffer_push_and_calculate_power(&gate->window, key);
+
+ switch (gate->_currentState)
+ {
+ case IDLE:
+ gate->_rmsValue = sqrt(gate->_keyValue * gate->_keyValue) * 0.707106781187;
+ if (gate->_rmsValue > gate->_upperThreshold)
+ {
+ if (gate->_attackCounter > gate->_attackTime)
+ {
+ gate->_currentState = HOLD;
+ gate->_holdCounter = 0;
+ gate->_attackCounter = 0;
+ return input;
+ }
+ else
+ {
+ gate->_attackCounter++;
+ if (gate->_attackCounter != 0)
+ return (input * powf((float)gate->_attackCounter, 2.0f) / powf((float)gate->_attackTime, 2.0f));
+ else
+ return 0.0f;
+ }
+ }
+ else
+ return 0.0f;
+ break;
+
+ case HOLD:
+ gate->_rmsValue = sqrt(gate->_keyValue * gate->_keyValue) * 0.707106781187;
+ if (gate->_rmsValue > gate->_lowerThreshold)
+ gate->_holdCounter = 0;
+ else if (gate->_holdCounter < gate->_holdTime)
+ gate->_holdCounter++;
+ else if (gate->_holdCounter >= gate->_holdTime)
+ {
+ gate->_currentState = DECAY;
+ gate->_decayCounter = 0;
+ }
+
+ return input;
+ break;
+
+ case DECAY:
+ if (gate->_decayCounter > gate->_decayTime)
+ {
+ gate->_currentState = IDLE;
+ return 0.0f;
+ }
+ else
+ {
+ float dif = (float)gate->_decayCounter - (float)gate->_decayTime;
+ if (gate->_decayCounter != 0)
+ {
+ gate->_decayCounter++;
+ return input * powf(dif, 2.0f) / powf((float)gate->_decayTime, 2.0f);
+ }
+ else
+ {
+ gate->_decayCounter++;
+ return input;
+ }
+ }
+ break;
+ }
+
+ //ERROR
+ return 0;
+}
A ext/noisegate-lv2/gate_core.h => ext/noisegate-lv2/gate_core.h +60 -0
@@ 0,0 1,60 @@
+/*
+ ==============================================================================
+
+ * VEJA NoiseGate
+ * Copyright (C) 2021 Jan Janssen <jan@moddevices.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ==============================================================================
+*/
+
+#ifndef GATE_CORE_H_INCLUDED
+#define GATE_CORE_H_INCLUDED
+
+#include <stdint.h>
+#include "circular_buffer.h"
+
+typedef enum {
+ IDLE,
+ HOLD,
+ DECAY
+} gate_state_t;
+
+typedef struct GATE_T {
+ float _alpha;
+ float _rmsValue, _keyValue, _upperThreshold, _lowerThreshold;
+ uint32_t _attackTime, _decayTime, _holdTime;
+ uint32_t _attackCounter, _decayCounter, _holdCounter;
+ uint32_t _currentState;
+ uint32_t _tau;
+
+ gate_state_t state;
+
+ ringbuffer_t window;
+} gate_t;
+
+/// <summary>This method called to initialize the Gate</summary>
+void Gate_Init(gate_t *gate);
+
+/// <summary>This method called to apply the Gate to the input sample</summary>
+/// <param name="input">Holds input sample</param>
+/// <param name="output">Holds the address where the output should be written to</param>
+float Gate_ApplyGate(gate_t *gate, const float input, const float key);
+
+/// <summary>This method called to set the length of the window</summary>
+/// <param name="length">Holds the value that determines the window length</param>
+void Gate_UpdateParameters(gate_t *gate, const uint32_t sampleRate, const uint32_t attack, const uint32_t hold,
+ const uint32_t decay, const uint32_t alpha, const float upperThreshold,
+ const float lowerThreshold);
+
+#endif //GATE_CORE_H_INCLUDED
A ext/noisegate-lv2/meson.build => ext/noisegate-lv2/meson.build +74 -0
@@ 0,0 1,74 @@
+# Copyright (C) 2021 Alexandros Theodotou <alex at zrythm dot org>
+#
+# This file is part of Zrythm
+#
+# Zrythm is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Zrythm 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
+
+noisegate_uri = 'https://lv2.zrythm.org/VeJaPlugins/NoiseGate'
+
+noisegate_cflags = [
+ '-Wall', '-Wextra', '-pipe',
+ '-Wno-unused-parameter', '-O3', '-g',
+ '-DPLUGIN_URI="' + noisegate_uri + '"',
+ '-DNDEBUG', '-ffast-math',
+ '-fvisibility=hidden',
+ '-fvisibility-inlines-hidden' ]
+
+if not os_windows
+ noisegate_cflags += [ '-fPIC', '-DPIC' ]
+endif
+
+noisegate_linkargs = []
+if os_darwin
+ noisegate_cflags += [ '-dynamiclib' ]
+ noisegate_linkargs += [
+ '-Wl,-dead_strip', '-Wl,-dead_strip_dylibs',
+ '-Wl,--no-undefined' ]
+else
+ noisegate_cflags += [ '-shared' ]
+ noisegate_linkargs += [
+ '-Wl,-O1', '-Wl,--as-needed', '-Wl,--strip-all' ]
+endif
+
+noisegate_lv2_install_dir = zrythmdatadir / 'lv2/noisegate.lv2'
+noisegate_so = shared_library (
+ 'noisegate',
+ 'circular_buffer.c',
+ 'noisegate.c',
+ 'gate_core.c',
+ dependencies: libm,
+ name_prefix: '',
+ gnu_symbol_visibility: 'hidden',
+ c_args: noisegate_cflags,
+ link_args: noisegate_linkargs,
+ install: true,
+ install_dir: noisegate_lv2_install_dir,
+ )
+
+noisegate_lv2_config = configuration_data ()
+noisegate_lv2_config.set (
+ 'PLUGIN_URI', noisegate_uri)
+
+noisegate_lv2_manifest_ttl = configure_file (
+ input: 'noisegate.lv2/manifest.ttl',
+ output: 'manifest.ttl',
+ configuration: noisegate_lv2_config,
+ install: true,
+ install_dir: noisegate_lv2_install_dir)
+noisegate_lv2_ttl = configure_file (
+ input: 'noisegate.lv2/noisegate.ttl',
+ output: 'noisegate.ttl',
+ configuration: noisegate_lv2_config,
+ install: true,
+ install_dir: noisegate_lv2_install_dir)
A ext/noisegate-lv2/noisegate.c => ext/noisegate-lv2/noisegate.c +163 -0
@@ 0,0 1,163 @@
+/*
+ * VEJA NoiseGate
+ * Copyright (C) 2021 Jan Janssen <jan@moddevices.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdbool.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#include "gate_core.h"
+
+/**********************************************************************************************************************************************************/
+
+typedef enum {
+ PLUGIN_INPUT,
+ PLUGIN_KEY,
+ PLUGIN_OUTPUT,
+ PLUGIN_THRESHOLD,
+ PLUGIN_ATTACK,
+ PLUGIN_HOLD,
+ PLUGIN_DECAY
+}PortIndex;
+
+/**********************************************************************************************************************************************************/
+
+typedef struct{
+
+ //ports
+ float* input;
+ float* key;
+ float* output;
+ float* threshold;
+ float* attack;
+ float* hold;
+ float* decay;
+
+ uint32_t sampleRate;
+
+ gate_t noisegate;
+
+} NoiseGate;
+
+/**********************************************************************************************************************************************************/
+// local functions //
+/**********************************************************************************************************************************************************/
+
+/**********************************************************************************************************************************************************/
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+double samplerate,
+const char* bundle_path,
+const LV2_Feature* const* features)
+{
+ NoiseGate* self = (NoiseGate*)malloc(sizeof(NoiseGate));
+
+ self->sampleRate = (uint32_t)samplerate;
+
+ Gate_Init(&self->noisegate);
+
+ return (LV2_Handle)self;
+}
+/**********************************************************************************************************************************************************/
+static void connect_port(LV2_Handle instance, uint32_t port, void *data)
+{
+ NoiseGate* self = (NoiseGate*)instance;
+
+ switch (port)
+ {
+ case PLUGIN_INPUT:
+ self->input = (float*) data;
+ break;
+ case PLUGIN_KEY:
+ self->key = (float*) data;
+ break;
+ case PLUGIN_OUTPUT:
+ self->output = (float*) data;
+ break;
+ case PLUGIN_THRESHOLD:
+ self->threshold = (float*) data;
+ break;
+ case PLUGIN_ATTACK:
+ self->attack = (float*) data;
+ break;
+ case PLUGIN_HOLD:
+ self->hold = (float*) data;
+ break;
+ case PLUGIN_DECAY:
+ self->decay = (float*) data;
+ break;
+ }
+}
+/**********************************************************************************************************************************************************/
+void activate(LV2_Handle instance)
+{
+ // TODO: include the activate function code here
+}
+
+/**********************************************************************************************************************************************************/
+void run(LV2_Handle instance, uint32_t n_samples)
+{
+ NoiseGate* self = (NoiseGate*)instance;
+
+ //update parameters
+ //lower threshold is 20dB lower
+ Gate_UpdateParameters(&self->noisegate, (uint32_t)self->sampleRate,
+ (uint32_t)*self->attack, (uint32_t)*self->hold,
+ (uint32_t)*self->decay, 1, *self->threshold, *self->threshold - 20.0f);
+
+
+ for (uint32_t i = 0; i < n_samples; ++i)
+ {
+ self->output[i] = Gate_ApplyGate(&self->noisegate, self->input[i], self->key[i]);
+ }
+}
+
+/**********************************************************************************************************************************************************/
+void deactivate(LV2_Handle instance)
+{
+ // TODO: include the deactivate function code here
+}
+/**********************************************************************************************************************************************************/
+void cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+/**********************************************************************************************************************************************************/
+const void* extension_data(const char* uri)
+{
+ return NULL;
+}
+/**********************************************************************************************************************************************************/
+static const LV2_Descriptor Descriptor = {
+ PLUGIN_URI,
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ extension_data
+};
+/**********************************************************************************************************************************************************/
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor* lv2_descriptor(uint32_t index)
+{
+ if (index == 0) return &Descriptor;
+ else return NULL;
+}
+/**********************************************************************************************************************************************************/
A ext/noisegate-lv2/noisegate.lv2/manifest.ttl => ext/noisegate-lv2/noisegate.lv2/manifest.ttl +9 -0
@@ 0,0 1,9 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix pset: <http://lv2plug.in/ns/ext/presets#> .
+
+<@PLUGIN_URI@>
+ a lv2:Plugin ;
+ lv2:binary <noisegate.so> ;
+ rdfs:seeAlso <noisegate.ttl> ;
+ lv2:optionalFeature lv2:hardRTCapable .
A ext/noisegate-lv2/noisegate.lv2/noisegate.ttl => ext/noisegate-lv2/noisegate.lv2/noisegate.ttl +104 -0
@@ 0,0 1,104 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#>.
+@prefix doap: <http://usefulinc.com/ns/doap#>.
+@prefix epp: <http://lv2plug.in/ns/ext/port-props#>.
+@prefix foaf: <http://xmlns.com/foaf/0.1/>.
+@prefix mod: <http://moddevices.com/ns/modgui#>.
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
+@prefix pset: <http://lv2plug.in/ns/ext/presets#>.
+@prefix units: <http://lv2plug.in/ns/extensions/units#>.
+
+<@PLUGIN_URI@>
+a lv2:Plugin, lv2:DynamicsPlugin;
+
+doap:name "[Z] NoiseGate";
+
+doap:developer [
+ foaf:name "VeJa plugins";
+ foaf:homepage <>;
+ foaf:mbox <mailto:jan@moddevices.com>;
+ ];
+
+doap:maintainer [
+ foaf:name "VeJa plugins";
+ foaf:homepage <http://moddevices.com>;
+ foaf:mbox <mailto:jan@moddevices.com>;
+ ];
+
+ lv2:minorVersion 1;
+ lv2:microVersion 0;
+
+rdfs:comment """
+
+Veja NoiseGate designed for MOD Devices
+
+Adapted for Zrythm by Alexandros Theodotou
+
+""";
+
+lv2:port
+[
+ a lv2:AudioPort, lv2:InputPort;
+ lv2:index 0;
+ lv2:symbol "Input";
+ lv2:name "Input";
+ lv2:shortname "Input";
+],
+[
+ a lv2:AudioPort, lv2:InputPort;
+ lv2:index 1;
+ lv2:symbol "Key";
+ lv2:name "Key";
+ lv2:shortname "Key";
+],
+[
+ a lv2:AudioPort, lv2:OutputPort;
+ lv2:index 2;
+ lv2:symbol "Output";
+ lv2:name "Output";
+ lv2:shortname "Output";
+],
+[
+ a lv2:ControlPort, lv2:InputPort;
+ lv2:index 3;
+ lv2:symbol "Threshold";
+ lv2:name "Threshold";
+ lv2:shortname "Threshold";
+ lv2:default -60;
+ lv2:minimum -80;
+ lv2:maximum -10;
+ units:unit units:db
+],
+[
+ a lv2:ControlPort, lv2:InputPort;
+ lv2:index 4;
+ lv2:symbol "Attack";
+ lv2:name "Attack";
+ lv2:shortname "Attack";
+ lv2:default 10;
+ lv2:minimum 1;
+ lv2:maximum 100;
+ units:unit units:ms
+],
+[
+ a lv2:ControlPort, lv2:InputPort;
+ lv2:index 5;
+ lv2:symbol "Hold";
+ lv2:name "Hold";
+ lv2:shortname "Hold";
+ lv2:default 10;
+ lv2:minimum 1;
+ lv2:maximum 200;
+ units:unit units:ms
+],
+[
+ a lv2:ControlPort, lv2:InputPort;
+ lv2:index 6;
+ lv2:symbol "Decay";
+ lv2:name "Decay";
+ lv2:shortname "Decay";
+ lv2:default 10;
+ lv2:minimum 1;
+ lv2:maximum 200;
+ units:unit units:ms
+].