Compare commits

...

2 Commits

  1. 1
      ext/meson.build
  2. 13
      ext/noisegate-lv2/LICENSE
  3. 44
      ext/noisegate-lv2/Makefile
  4. 79
      ext/noisegate-lv2/Makefile.mk
  5. 3
      ext/noisegate-lv2/README.md
  6. 165
      ext/noisegate-lv2/circular_buffer.c
  7. 52
      ext/noisegate-lv2/circular_buffer.h
  8. 137
      ext/noisegate-lv2/gate_core.c
  9. 60
      ext/noisegate-lv2/gate_core.h
  10. 74
      ext/noisegate-lv2/meson.build
  11. 163
      ext/noisegate-lv2/noisegate.c
  12. 9
      ext/noisegate-lv2/noisegate.lv2/manifest.ttl
  13. 104
      ext/noisegate-lv2/noisegate.lv2/noisegate.ttl
  14. 1
      inc/actions/actions.h
  15. 3
      inc/actions/arranger_selections.h
  16. 25
      inc/audio/audio_function.h
  17. 2
      inc/audio/encoder.h
  18. 4
      inc/gui/widgets/editor_toolbar.h
  19. 2
      inc/plugins/carla_native_plugin.h
  20. 3
      inc/plugins/plugin.h
  21. 2
      inc/plugins/plugin_descriptor.h
  22. 12
      inc/plugins/plugin_gtk.h
  23. 2
      inc/settings/plugin_settings.h
  24. 3
      inc/zrythm.h
  25. 54
      src/actions/actions.c
  26. 11
      src/actions/arranger_selections.c
  27. 297
      src/audio/audio_function.c
  28. 16
      src/gui/backend/event_manager.c
  29. 66
      src/gui/widgets/editor_toolbar.c
  30. 2
      src/gui/widgets/main_window.c
  31. 2
      src/plugins/carla_native_plugin.c
  32. 26
      src/plugins/plugin.c
  33. 2
      src/plugins/plugin_descriptor.c
  34. 61
      src/plugins/plugin_gtk.c
  35. 21
      src/plugins/plugin_manager.c
  36. 2
      src/settings/plugin_settings.c
  37. 1
      src/utils/meson.build
  38. 6
      src/zrythm.c

1
ext/meson.build vendored

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
subdir ('midilib')
subdir ('nanovg')
subdir ('noisegate-lv2')
subdir ('weakjack')
subdir ('whereami')
subdir ('zix')

13
ext/noisegate-lv2/LICENSE vendored

@ -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.

44
ext/noisegate-lv2/Makefile vendored

@ -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/
# --------------------------------------------------------------

79
ext/noisegate-lv2/Makefile.mk vendored

@ -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
# --------------------------------------------------------------

3
ext/noisegate-lv2/README.md vendored

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
# Noise-Gate
A simple noisegate with seperate gate and audio input

165
ext/noisegate-lv2/circular_buffer.c vendored

@ -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];
}

52
ext/noisegate-lv2/circular_buffer.h vendored

@ -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__

137
ext/noisegate-lv2/gate_core.c vendored

@ -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;
}

60
ext/noisegate-lv2/gate_core.h vendored

@ -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

74
ext/noisegate-lv2/meson.build vendored

@ -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)

163
ext/noisegate-lv2/noisegate.c vendored

@ -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;
}
/**********************************************************************************************************************************************************/

9
ext/noisegate-lv2/noisegate.lv2/manifest.ttl vendored

@ -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 .

104
ext/noisegate-lv2/noisegate.lv2/noisegate.ttl vendored

@ -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
].

1
inc/actions/actions.h

@ -426,6 +426,7 @@ DECLARE_SIMPLE ( @@ -426,6 +426,7 @@ DECLARE_SIMPLE (
/* Editor functions. */
DECLARE_SIMPLE (activate_editor_function);
DECLARE_SIMPLE (activate_editor_function_lv2);
COLD DECLARE_SIMPLE (
activate_midi_editor_highlighting);

3
inc/actions/arranger_selections.h

@ -585,7 +585,8 @@ arranger_selections_action_new_edit_automation_function ( @@ -585,7 +585,8 @@ arranger_selections_action_new_edit_automation_function (
UndoableAction *
arranger_selections_action_new_edit_audio_function (
ArrangerSelections * sel_before,
AudioFunctionType audio_func_type);
AudioFunctionType audio_func_type,
const char * uri);
/**
* Creates a new action for automation autofill.

25
inc/audio/audio_function.h

@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
#include "utils/yaml.h"
typedef struct ArrangerSelections ArrangerSelections;
typedef struct Plugin Plugin;
/**
* @addtogroup audio
@ -44,6 +45,9 @@ typedef enum AudioFunctionType @@ -44,6 +45,9 @@ typedef enum AudioFunctionType
AUDIO_FUNCTION_NORMALIZE,
AUDIO_FUNCTION_REVERSE,
/** Custom plugin. */
AUDIO_FUNCTION_CUSTOM_PLUGIN,
/* reserved */
AUDIO_FUNCTION_INVALID,
} AudioFunctionType;
@ -54,6 +58,7 @@ static const cyaml_strval_t @@ -54,6 +58,7 @@ static const cyaml_strval_t
{ __("Invert"), AUDIO_FUNCTION_INVERT },
{ __("Normalize"), AUDIO_FUNCTION_NORMALIZE },
{ __("Reverse"), AUDIO_FUNCTION_REVERSE },
{ __("Custom Plugin"), AUDIO_FUNCTION_CUSTOM_PLUGIN },
{ __("Invalid"), AUDIO_FUNCTION_INVALID },
};
@ -64,6 +69,23 @@ audio_function_type_to_string ( @@ -64,6 +69,23 @@ audio_function_type_to_string (
return audio_function_type_strings[type].str;
}
/**
* Returns the URI of the plugin responsible for
* handling the type, if any.
*/
static inline const char *
audio_function_get_plugin_uri_for_type (
AudioFunctionType type)
{
switch (type)
{
default:
break;
}
return NULL;
}
/**
* Applies the given action to the given selections.
*
@ -73,7 +95,8 @@ audio_function_type_to_string ( @@ -73,7 +95,8 @@ audio_function_type_to_string (
int
audio_function_apply (
ArrangerSelections * sel,
AudioFunctionType type);
AudioFunctionType type,
const char * uri);
/**
* @}

2
inc/audio/encoder.h

@ -82,6 +82,7 @@ audio_encoder_new_from_file ( @@ -82,6 +82,7 @@ audio_encoder_new_from_file (
*
* @param show_progress Display a progress dialog.
*/
NONNULL
void
audio_encoder_decode (
AudioEncoder * self,
@ -91,6 +92,7 @@ audio_encoder_decode ( @@ -91,6 +92,7 @@ audio_encoder_decode (
/**
* Free's the AudioEncoder and its members.
*/
NONNULL
void
audio_encoder_free (
AudioEncoder * self);

4
inc/gui/widgets/editor_toolbar.h

@ -67,6 +67,10 @@ typedef struct _EditorToolbarWidget @@ -67,6 +67,10 @@ typedef struct _EditorToolbarWidget
GMenuModel * midi_functions_menu;
GMenuModel * automation_functions_menu;
GMenuModel * audio_functions_menu;
/** Whether audio functions were already added
* to the menu. */
bool added_audio_funcs;
} EditorToolbarWidget;
/**

2
inc/plugins/carla_native_plugin.h

@ -242,7 +242,7 @@ carla_native_plugin_close ( @@ -242,7 +242,7 @@ carla_native_plugin_close (
bool
carla_native_plugin_has_custom_ui (
PluginDescriptor * descr);
const PluginDescriptor * descr);
/**
* Deactivates, cleanups and frees the instance.

3
inc/plugins/plugin.h

@ -275,6 +275,9 @@ typedef struct Plugin @@ -275,6 +275,9 @@ typedef struct Plugin
/** Whether the plugin is used for MIDI
* auditioning in SampleProcessor. */
bool is_auditioner;
/** Whether the plugin is used for functions. */
bool is_function;
} Plugin;
static const cyaml_schema_field_t

2
inc/plugins/plugin_descriptor.h

@ -411,7 +411,7 @@ plugin_descriptor_is_same_plugin ( @@ -411,7 +411,7 @@ plugin_descriptor_is_same_plugin (
NONNULL
bool
plugin_descriptor_has_custom_ui (
PluginDescriptor * self);
const PluginDescriptor * self);
/**
* Returns the minimum bridge mode required for this

12
inc/plugins/plugin_gtk.h

@ -46,6 +46,9 @@ typedef struct PluginGtkController @@ -46,6 +46,9 @@ typedef struct PluginGtkController
/** Port this control is for. */
Port * port;
/** Pointer back to plugin. */
Plugin * plugin;
} PluginGtkController;
typedef struct PluginGtkPresetMenu
@ -82,7 +85,8 @@ plugin_gtk_create_window ( @@ -82,7 +85,8 @@ plugin_gtk_create_window (
*/
void
plugin_gtk_open_generic_ui (
Plugin * plugin);
Plugin * plugin,
bool fire_events);
/**
* Called on each GUI frame to update the GTK UI.
@ -195,6 +199,12 @@ plugin_gtk_generic_set_widget_value ( @@ -195,6 +199,12 @@ plugin_gtk_generic_set_widget_value (
LV2_URID type,
const void * body);
void
plugin_gtk_build_menu (
Plugin * plugin,
GtkWidget * window,
GtkWidget * vbox);
/**
* @}
*/

2
inc/settings/plugin_settings.h

@ -132,7 +132,7 @@ plugin_settings_schema = @@ -132,7 +132,7 @@ plugin_settings_schema =
PluginSetting *
NONNULL
plugin_setting_new_default (
PluginDescriptor * descr);
const PluginDescriptor * descr);
PluginSetting *
NONNULL

3
inc/zrythm.h

@ -126,6 +126,9 @@ typedef enum ZrythmDirType @@ -126,6 +126,9 @@ typedef enum ZrythmDirType
/** CSS themes. */
ZRYTHM_DIR_SYSTEM_THEMES_CSS_DIR,
/** Built-in plugins path. */
ZRYTHM_DIR_SYSTEM_LV2_PLUGINS_DIR,
/* ************************************ */
/*

54
src/actions/actions.c

@ -91,6 +91,7 @@ @@ -91,6 +91,7 @@
#include "gui/widgets/timeline_ruler.h"
#include "gui/widgets/toolbox.h"
#include "gui/widgets/tracklist.h"
#include "plugins/plugin_manager.h"
#include "project.h"
#include "settings/settings.h"
#include "utils/dialogs.h"
@ -2359,10 +2360,13 @@ do_automation_func ( @@ -2359,10 +2360,13 @@ do_automation_func (
/**
* Common routine for applying undoable audio
* functions.
*
* @param uri Plugin URI, if applying plugin.
*/
static void
do_audio_func (
AudioFunctionType type)
const AudioFunctionType type,
const char * uri)
{
g_return_if_fail (
region_find (&CLIP_EDITOR->region_id));
@ -2376,9 +2380,11 @@ do_audio_func ( @@ -2376,9 +2380,11 @@ do_audio_func (
return;
}
UndoableAction * ua =
UndoableAction * ua = NULL;
ua =
arranger_selections_action_new_edit_audio_function (
sel, type);
sel, type, uri);
if (ua)
{
undo_manager_perform (UNDO_MANAGER, ua);
@ -2476,22 +2482,22 @@ DEFINE_SIMPLE (activate_editor_function) @@ -2476,22 +2482,22 @@ DEFINE_SIMPLE (activate_editor_function)
{
do_audio_func (
g_settings_get_int (
S_UI, "audio-function"));
S_UI, "audio-function"), NULL);
}
else if (string_is_equal (str, "invert"))
{
do_audio_func (
AUDIO_FUNCTION_INVERT);
AUDIO_FUNCTION_INVERT, NULL);
}
else if (string_is_equal (str, "normalize"))
{
do_audio_func (
AUDIO_FUNCTION_NORMALIZE);
AUDIO_FUNCTION_NORMALIZE, NULL);
}
else if (string_is_equal (str, "reverse"))
{
do_audio_func (
AUDIO_FUNCTION_REVERSE);
AUDIO_FUNCTION_REVERSE, NULL);
}
else
{
@ -2504,6 +2510,40 @@ DEFINE_SIMPLE (activate_editor_function) @@ -2504,6 +2510,40 @@ DEFINE_SIMPLE (activate_editor_function)
}
}
DEFINE_SIMPLE (activate_editor_function_lv2)
{
size_t size;
const char * str =
g_variant_get_string (variant, &size);
ZRegion * region =
clip_editor_get_region (CLIP_EDITOR);
if (!region)
return;
PluginDescriptor * descr =
plugin_manager_find_plugin_from_uri (
PLUGIN_MANAGER, str);
g_return_if_fail (descr);
switch (region->id.type)
{
case REGION_TYPE_MIDI:
{
}
break;
case REGION_TYPE_AUDIO:
{
do_audio_func (
AUDIO_FUNCTION_CUSTOM_PLUGIN, str);
}
break;
default:
g_return_if_reached ();
break;
}
}
DEFINE_SIMPLE (
activate_midi_editor_highlighting)
{

11
src/actions/arranger_selections.c

@ -577,14 +577,16 @@ arranger_selections_action_new_edit_automation_function ( @@ -577,14 +577,16 @@ arranger_selections_action_new_edit_automation_function (
UndoableAction *
arranger_selections_action_new_edit_audio_function (
ArrangerSelections * sel_before,
AudioFunctionType audio_func_type)
AudioFunctionType audio_func_type,
const char * uri)
{
/* prepare selections before */
ArrangerSelections * sel_before_clone =
arranger_selections_clone (sel_before);
int res =
audio_function_apply (
sel_before_clone, AUDIO_FUNCTION_INVALID);
sel_before_clone, AUDIO_FUNCTION_INVALID,
NULL);
if (res != 0)
{
arranger_selections_free_full (
@ -596,7 +598,7 @@ arranger_selections_action_new_edit_audio_function ( @@ -596,7 +598,7 @@ arranger_selections_action_new_edit_audio_function (
arranger_selections_clone (sel_before);
res =
audio_function_apply (
sel_after, audio_func_type);
sel_after, audio_func_type, uri);
if (res != 0)
{
arranger_selections_free_full (sel_after);
@ -1954,7 +1956,8 @@ do_or_undo_edit ( @@ -1954,7 +1956,8 @@ do_or_undo_edit (
if (!self->first_run)
{
if (self->edit_type ==
ARRANGER_SELECTIONS_ACTION_EDIT_EDITOR_FUNCTION &&
ARRANGER_SELECTIONS_ACTION_EDIT_EDITOR_FUNCTION
&&
self->sel->type ==
ARRANGER_SELECTIONS_TYPE_AUDIO)
{

297
src/audio/audio_function.c

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2020-2021 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm