Compare commits
2 Commits
master
...
noisegate-
Author | SHA1 | Date |
---|---|---|
|
bf08c9e039 | 2 years ago |
|
dc99db8edf | 2 years ago |
38 changed files with 1428 additions and 102 deletions
@ -0,0 +1,13 @@
@@ -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. |
@ -0,0 +1,44 @@
@@ -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/ |
||||
|
||||
# --------------------------------------------------------------
|
||||
|
@ -0,0 +1,79 @@
@@ -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 |
||||
|
||||
# --------------------------------------------------------------
|
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
# Noise-Gate |
||||
|
||||
A simple noisegate with seperate gate and audio input |
@ -0,0 +1,165 @@
@@ -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]; |
||||
} |
@ -0,0 +1,52 @@
@@ -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__
|
@ -0,0 +1,137 @@
@@ -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; |
||||
} |
@ -0,0 +1,60 @@
@@ -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
|
@ -0,0 +1,74 @@
@@ -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) |
@ -0,0 +1,163 @@
@@ -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; |
||||
} |
||||
/**********************************************************************************************************************************************************/ |
@ -0,0 +1,9 @@
@@ -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 . |
@ -0,0 +1,104 @@
@@ -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 |
||||
]. |