diff --git a/Makefile b/Makefile index 496ee82fb..ea692c2a1 100644 --- a/Makefile +++ b/Makefile @@ -411,7 +411,6 @@ ifeq ($(EXPERIMENTAL_PLUGINS),true) install -d $(DESTDIR)$(PREFIX)/share/carla/resources/bls1/ install -d $(DESTDIR)$(PREFIX)/share/carla/resources/rev1/ endif - install -d $(DESTDIR)$(PREFIX)/share/carla/resources/nekofilter/ ifeq ($(HAVE_ZYN_DEPS),true) ifeq ($(HAVE_ZYN_UI_DEPS),true) install -d $(DESTDIR)$(PREFIX)/share/carla/resources/zynaddsubfx/ @@ -541,10 +540,6 @@ ifeq ($(EXPERIMENTAL_PLUGINS),true) $(DESTDIR)$(PREFIX)/share/carla/resources/ endif - install -m 644 \ - bin/resources/nekofilter/*.png \ - $(DESTDIR)$(PREFIX)/share/carla/resources/nekofilter/ - ifeq ($(HAVE_ZYN_DEPS),true) ifeq ($(HAVE_ZYN_UI_DEPS),true) install -m 644 \ diff --git a/source/native-plugins/Makefile b/source/native-plugins/Makefile index 7f0b02a82..ca6990100 100644 --- a/source/native-plugins/Makefile +++ b/source/native-plugins/Makefile @@ -77,8 +77,7 @@ OBJS += \ $(OBJDIR)/midi-join.c.o \ $(OBJDIR)/midi-split.c.o \ $(OBJDIR)/midi-through.c.o \ - $(OBJDIR)/midi-transpose.c.o \ - $(OBJDIR)/nekofilter.c.o + $(OBJDIR)/midi-transpose.c.o OBJS += \ $(OBJDIR)/audio-file.cpp.o \ diff --git a/source/native-plugins/_all.c b/source/native-plugins/_all.c index 5d5f7c86f..2f13d26f9 100644 --- a/source/native-plugins/_all.c +++ b/source/native-plugins/_all.c @@ -29,7 +29,6 @@ extern void carla_register_native_plugin_midijoin(void); extern void carla_register_native_plugin_midisplit(void); extern void carla_register_native_plugin_midithrough(void); extern void carla_register_native_plugin_miditranspose(void); -extern void carla_register_native_plugin_nekofilter(void); // Audio file extern void carla_register_native_plugin_audiofile(void); @@ -79,7 +78,6 @@ void carla_register_all_native_plugins(void) carla_register_native_plugin_midisplit(); carla_register_native_plugin_midithrough(); carla_register_native_plugin_miditranspose(); - carla_register_native_plugin_nekofilter(); // Audio file carla_register_native_plugin_audiofile(); diff --git a/source/native-plugins/_data.cpp b/source/native-plugins/_data.cpp index 072280e3f..c60890703 100644 --- a/source/native-plugins/_data.cpp +++ b/source/native-plugins/_data.cpp @@ -159,27 +159,6 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* copyright */ "GNU GPL v2+", DESCFUNCS }, -{ - /* category */ NATIVE_PLUGIN_CATEGORY_FILTER, -#if defined(__linux__) || defined(__linux) - /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE - |NATIVE_PLUGIN_HAS_UI), -#else - /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE), -#endif - /* supports */ static_cast(0x0), - /* audioIns */ 1, - /* audioOuts */ 1, - /* midiIns */ 0, - /* midiOuts */ 0, - /* paramIns */ 2 + 4*4, - /* paramOuts */ 0, - /* name */ "NekoFilter", - /* label */ "nekofilter", - /* maker */ "falkTX, Nedko, Fons Adriaensen", - /* copyright */ "GNU GPL v2+", - DESCFUNCS -}, // ----------------------------------------------------------------------- @@ -763,8 +742,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE |NATIVE_PLUGIN_HAS_UI |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS - |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD - |NATIVE_PLUGIN_USES_PARENT_ID), + |NATIVE_PLUGIN_USES_STATE), /* supports */ static_cast(0x0), /* audioIns */ 1, /* audioOuts */ 1, @@ -782,9 +760,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* category */ NATIVE_PLUGIN_CATEGORY_FILTER, /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE |NATIVE_PLUGIN_HAS_UI - |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS - |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD - |NATIVE_PLUGIN_USES_PARENT_ID), + |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS), /* supports */ static_cast(0x0), /* audioIns */ 2, /* audioOuts */ 2, @@ -802,9 +778,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* category */ NATIVE_PLUGIN_CATEGORY_DELAY, /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE |NATIVE_PLUGIN_HAS_UI - |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS - |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD - |NATIVE_PLUGIN_USES_PARENT_ID), + |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS), /* supports */ static_cast(0x0), /* audioIns */ 2, /* audioOuts */ 4, @@ -822,9 +796,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { /* category */ NATIVE_PLUGIN_CATEGORY_DELAY, /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE |NATIVE_PLUGIN_HAS_UI - |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS - |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD - |NATIVE_PLUGIN_USES_PARENT_ID), + |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS), /* supports */ static_cast(0x0), /* audioIns */ 2, /* audioOuts */ 2, diff --git a/source/native-plugins/nekofilter.c b/source/native-plugins/nekofilter.c deleted file mode 100644 index 02c7386f6..000000000 --- a/source/native-plugins/nekofilter.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Carla Native Plugins - * Copyright (C) 2012-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "CarlaNative.h" - -// ----------------------------------------------------------------------- -// Plugin Code - -#include "nekofilter/nekofilter.c" -#include "nekofilter/filter.c" -#include "nekofilter/log.c" - -// ----------------------------------------------------------------------- - -static const NativePluginDescriptor nekofilterDesc = { - .category = NATIVE_PLUGIN_CATEGORY_FILTER, -#ifdef WANT_UI - .hints = NATIVE_PLUGIN_IS_RTSAFE|NATIVE_PLUGIN_HAS_UI, -#else - .hints = NATIVE_PLUGIN_IS_RTSAFE, -#endif - .supports = 0x0, - .audioIns = 1, - .audioOuts = 1, - .midiIns = 0, - .midiOuts = 0, - .paramIns = GLOBAL_PARAMETERS_COUNT + BAND_PARAMETERS_COUNT*BANDS_COUNT, - .paramOuts = 0, - .name = "NekoFilter", - .label = "nekofilter", - .maker = "falkTX, Nedko, Fons Adriaensen", - .copyright = "GNU GPL v2+", - - .instantiate = nekofilter_instantiate, - .cleanup = nekofilter_cleanup, - - .get_parameter_count = nekofilter_get_parameter_count, - .get_parameter_info = nekofilter_get_parameter_info, - .get_parameter_value = nekofilter_get_parameter_value, - .get_parameter_text = NULL, - - .get_midi_program_count = NULL, - .get_midi_program_info = NULL, - - .set_parameter_value = nekofilter_set_parameter_value, - .set_midi_program = NULL, - .set_custom_data = NULL, - -#ifdef WANT_UI - .ui_show = nekofilter_ui_show, - .ui_idle = nekofilter_ui_idle, - - .ui_set_parameter_value = nekofilter_ui_set_parameter_value, - .ui_set_midi_program = NULL, - .ui_set_custom_data = NULL, -#else - .ui_show = NULL, - .ui_idle = NULL, - - .ui_set_parameter_value = NULL, - .ui_set_midi_program = NULL, - .ui_set_custom_data = NULL, -#endif - - .activate = NULL, - .deactivate = NULL, - .process = nekofilter_process, - - .get_state = NULL, - .set_state = NULL, - - .dispatcher = NULL -}; - -// ----------------------------------------------------------------------- - -void carla_register_native_plugin_nekofilter(void); - -void carla_register_native_plugin_nekofilter(void) -{ - carla_register_native_plugin(&nekofilterDesc); -} - -// ----------------------------------------------------------------------- diff --git a/source/native-plugins/nekofilter/filter.c b/source/native-plugins/nekofilter/filter.c deleted file mode 100644 index 22aa809b9..000000000 --- a/source/native-plugins/nekofilter/filter.c +++ /dev/null @@ -1,363 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - Copyright (C) 2008 Nedko Arnaudov - The DSP code is based on ladspa:1970 by Fons Adriaensen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* if NDEBUG is defined, assert checks are disabled */ -//#define NDEBUG - -#include -#include -#include -#include -#include -#include - -#include "filter.h" - -static -float -exp2ap(float x) -{ - int i; - - i = (int)(floorf(x)); - x -= (float)i; - return ldexpf(1.0f + x * (0.6930f + x * (0.2416f + x * (0.0517f + x * 0.0137f))), i); -} - -static -bool -compare_floats( - const float v1, - const float v2) -{ - return fabs(v1-v2) < FLT_EPSILON; -} - -struct param_sect -{ - float f, b, g; - float s1, s2, a; - float z1, z2; -}; - -static -void -param_sect_init( - struct param_sect * sect_ptr) -{ - sect_ptr->f = 0.25f; - sect_ptr->b = sect_ptr->g = 1.0f; - sect_ptr->a = sect_ptr->s1 = sect_ptr->s2 = sect_ptr->z1 = sect_ptr->z2 = 0.0f; -} - -static -void -param_sect_proc( - struct param_sect * sect_ptr, - unsigned long k, - float * sig, - float f, - float b, - float g) -{ - float s1, s2, d1, d2, a, da, x, y; - bool u2 = false; - - s1 = sect_ptr->s1; - s2 = sect_ptr->s2; - a = sect_ptr->a; - d1 = 0; - d2 = 0; - da = 0; - - if (! compare_floats(f, sect_ptr->f)) - { - if (f < 0.5f * sect_ptr->f) f = 0.5f * sect_ptr->f; - else if (f > 2.0f * sect_ptr->f) f = 2.0f * sect_ptr->f; - sect_ptr->f = f; - sect_ptr->s1 = -cosf(6.283185f * f); - d1 = (sect_ptr->s1 - s1) / (float)k; - u2 = true; - } - - if (! compare_floats(g, sect_ptr->g)) - { - if (g < 0.5f * sect_ptr->g) g = 0.5f * sect_ptr->g; - else if (g > 2.0f * sect_ptr->g) g = 2.0f * sect_ptr->g; - sect_ptr->g = g; - sect_ptr->a = 0.5f * (g - 1.0f); - da = (sect_ptr->a - a) / (float)k; - u2 = true; - } - - if (! compare_floats(b, sect_ptr->b)) - { - if (b < 0.5f * sect_ptr->b) b = 0.5f * sect_ptr->b; - else if (b > 2.0f * sect_ptr->b) b = 2.0f * sect_ptr->b; - sect_ptr->b = b; - u2 = true; - } - - if (u2) - { - b *= 7 * f / sqrtf(g); - sect_ptr->s2 = (1 - b) / (1 + b); - d2 = (sect_ptr->s2 - s2) / (float)k; - } - - while (k--) - { - s1 += d1; - s2 += d2; - a += da; - x = *sig; - y = x - s2 * sect_ptr->z2; - *sig++ -= a * (sect_ptr->z2 + s2 * y - x); - y -= s1 * sect_ptr->z1; - sect_ptr->z2 = sect_ptr->z1 + s1 * y; - sect_ptr->z1 = y + 1e-10f; - } -} - -struct filter -{ - float sample_rate; - - const float * global_parameters[GLOBAL_PARAMETERS_COUNT]; - - unsigned int bands_count; - const float ** band_parameters; /* [band_index * BAND_PARAMETERS_COUNT + parameter_index] */ - - float gain; - unsigned long fade; - struct param_sect * sect; /* [band_index] */ -}; - -bool -filter_create( - float sample_rate, - unsigned int bands_count, - filter_handle * handle_ptr) -{ - struct filter * filter_ptr; - unsigned int j; - - assert(bands_count > 0); - - filter_ptr = calloc(1, sizeof(struct filter)); - if (filter_ptr == NULL) - { - goto fail; - } - - filter_ptr->band_parameters = calloc(bands_count, sizeof(float *) * BAND_PARAMETERS_COUNT); - if (filter_ptr->band_parameters == NULL) - { - goto free_filter; - } - - filter_ptr->sect = malloc(sizeof(struct param_sect) * bands_count); - if (filter_ptr->sect == NULL) - { - goto free_band_params; - } - - filter_ptr->sample_rate = sample_rate; - filter_ptr->bands_count = bands_count; - filter_ptr->fade = 0; - filter_ptr->gain = 1.0; - - for (j = 0; j < bands_count; ++j) - { - param_sect_init(filter_ptr->sect + j); - } - - *handle_ptr = (filter_handle)filter_ptr; - - return true; - -free_band_params: - free(filter_ptr->band_parameters); - -free_filter: - free(filter_ptr); - -fail: - return false; -} - -#define filter_ptr ((struct filter *)handle) - -void -filter_destroy( - filter_handle handle) -{ - free(filter_ptr->sect); - free(filter_ptr->band_parameters); - free(filter_ptr); -} - -void -filter_connect_global_parameter( - filter_handle handle, - unsigned int global_parameter, - const float * value_ptr) -{ - assert(global_parameter < GLOBAL_PARAMETERS_COUNT); - - filter_ptr->global_parameters[global_parameter] = value_ptr; -} - -void -filter_connect_band_parameter( - filter_handle handle, - unsigned int band_index, - unsigned int band_parameter, - const float * value_ptr) -{ - assert(band_index < filter_ptr->bands_count); - assert(band_parameter < BAND_PARAMETERS_COUNT); - - filter_ptr->band_parameters[band_index * BAND_PARAMETERS_COUNT + band_parameter] = value_ptr; -} - -void -filter_run( - filter_handle handle, - const float * input_buffer, - float * output_buffer, - unsigned long samples_count) -{ - unsigned long i, j, k; - unsigned long bands_count; - const float * p; - float sig[48]; - float t, g, d; - float fgain; - float sfreq[filter_ptr->bands_count]; - float sband[filter_ptr->bands_count]; - float sgain[filter_ptr->bands_count]; - - bands_count = filter_ptr->bands_count; - - fgain = exp2ap(0.1661f * *filter_ptr->global_parameters[GLOBAL_PARAMETER_GAIN]); - - for (j = 0; j < bands_count; ++j) - { - t = *filter_ptr->band_parameters[BAND_PARAMETERS_COUNT * j + BAND_PARAMETER_FREQUENCY] / filter_ptr->sample_rate; - if (t < 0.0002f) - { - t = 0.0002f; - } - else if (t > 0.4998f) - { - t = 0.4998f; - } - sfreq[j] = t; - - sband[j] = *filter_ptr->band_parameters[BAND_PARAMETERS_COUNT * j + BAND_PARAMETER_BANDWIDTH]; - - if (*filter_ptr->band_parameters[BAND_PARAMETERS_COUNT * j + BAND_PARAMETER_ACTIVE] > 0.0) - { - sgain[j] = exp2ap(0.1661f * *filter_ptr->band_parameters[BAND_PARAMETERS_COUNT * j + BAND_PARAMETER_GAIN]); - } - else - { - sgain[j] = 1.0f; - } - } - - while (samples_count) - { - k = (samples_count > 48) ? 32 : samples_count; - - t = fgain; - g = filter_ptr->gain; - - if (t > 1.25f * g) - { - t = 1.25f * g; - } - else if (t < 0.80f * g) - { - t = 0.80f * g; - } - - filter_ptr->gain = t; - d = (t - g) / (float)k; - for (i = 0; i < k; ++i) - { - g += d; - sig[i] = g * input_buffer[i]; - } - - for (j = 0; j < bands_count; ++j) - { - param_sect_proc(filter_ptr->sect + j, k, sig, sfreq[j], sband[j], sgain[j]); - } - - j = filter_ptr->fade; - g = (float)j / 16.0f; - p = 0; - - if (*filter_ptr->global_parameters[GLOBAL_PARAMETER_ACTIVE] > 0.0f) - { - if (j == 16) - { - p = sig; - } - else - { - ++j; - } - } - else - { - if (j == 0) - { - p = input_buffer; - } - else - { - --j; - } - } - - filter_ptr->fade = j; - - if (p) - { - memcpy(output_buffer, p, k * sizeof(float)); - } - else - { - d = ((float)j / 16.0f - g) / (float)k; - for (i = 0; i < k; ++i) - { - g += d; - output_buffer[i] = g * sig[i] + (1.0f - g) * input_buffer[i]; - } - } - - input_buffer += k; - output_buffer += k; - samples_count -= k; - } -} diff --git a/source/native-plugins/nekofilter/filter.h b/source/native-plugins/nekofilter/filter.h deleted file mode 100644 index a0810ffb6..000000000 --- a/source/native-plugins/nekofilter/filter.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - Copyright (C) 2008 Nedko Arnaudov - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef FILTER_H__D5DC5ADF_211A_48F6_93A5_68CD3B73D6C5__INCLUDED -#define FILTER_H__D5DC5ADF_211A_48F6_93A5_68CD3B73D6C5__INCLUDED - -typedef struct {int unused; } * filter_handle; - -#define GLOBAL_PARAMETER_ACTIVE 0 -#define GLOBAL_PARAMETER_GAIN 1 -#define GLOBAL_PARAMETERS_COUNT 2 - -#define BAND_PARAMETER_ACTIVE 0 -#define BAND_PARAMETER_FREQUENCY 1 -#define BAND_PARAMETER_BANDWIDTH 2 -#define BAND_PARAMETER_GAIN 3 -#define BAND_PARAMETERS_COUNT 4 - -bool -filter_create( - float sample_rate, - unsigned int bands_count, - filter_handle * handle_ptr); - -void -filter_connect_global_parameter( - filter_handle handle, - unsigned int global_parameter, - const float * value_ptr); - -void -filter_connect_band_parameter( - filter_handle handle, - unsigned int band_index, - unsigned int band_parameter, - const float * value_ptr); - -void -filter_run( - filter_handle handle, - const float * input_buffer, - float * output_buffer, - unsigned long samples_count); - -void -filter_destroy( - filter_handle handle); - -#endif /* #ifndef FILTER_H__D5DC5ADF_211A_48F6_93A5_68CD3B73D6C5__INCLUDED */ diff --git a/source/native-plugins/nekofilter/log.c b/source/native-plugins/nekofilter/log.c deleted file mode 100644 index f7acf32fb..000000000 --- a/source/native-plugins/nekofilter/log.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - *****************************************************************************/ - -#include -#include -#include -#include - -#include "log.h" - -void nekolog(int level, const char * format, ...) -{ - va_list arglist; - - va_start(arglist, format); - vprintf(format, arglist); - va_end(arglist); - - return; - - //unused - (void)level; -} diff --git a/source/native-plugins/nekofilter/log.h b/source/native-plugins/nekofilter/log.h deleted file mode 100644 index a3eaf7c8b..000000000 --- a/source/native-plugins/nekofilter/log.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - *****************************************************************************/ - -#ifndef LOG_H__7097F6FE_4FEE_4962_9542_60375961F567__INCLUDED -#define LOG_H__7097F6FE_4FEE_4962_9542_60375961F567__INCLUDED - -void nekolog(int level, const char * format, ...); - -#define LOG_LEVEL_DEBUG 0 -#define LOG_LEVEL_INFO 1 -#define LOG_LEVEL_WARNING 2 -#define LOG_LEVEL_NOTICE 3 -#define LOG_LEVEL_ERROR 4 -#define LOG_LEVEL_FATAL 5 -#define LOG_LEVEL_BLACK_HOLE 6 - -#if !defined(LOG_LEVEL) -#define LOG_LEVEL LOG_LEVEL_WARNING -#endif - -#if LOG_LEVEL <= LOG_LEVEL_DEBUG -# define LOG_DEBUG(format, arg...) \ - nekolog(LOG_LEVEL_DEBUG, \ - format "\n", ## arg) -#else -# define LOG_DEBUG(format, arg...) -#endif - -#if LOG_LEVEL <= LOG_LEVEL_INFO -# define LOG_INFO(format, arg...) \ - nekolog(LOG_LEVEL_INFO, \ - format "\n", ## arg) -#else -# define LOG_INFO(format, arg...) -#endif - -#if LOG_LEVEL <= LOG_LEVEL_WARNING -# define LOG_WARNING(format, arg...) \ - nekolog(LOG_LEVEL_WARNING, \ - format "\n", ## arg) -#else -# define LOG_WARNING(format, arg...) -#endif - -#if LOG_LEVEL <= LOG_LEVEL_NOTICE -# define LOG_NOTICE(format, arg...) \ - nekolog(LOG_LEVEL_NOTICE, \ - format "\n", ## arg) -#else -# define LOG_NOTICE(format, arg...) -#endif - -#if LOG_LEVEL <= LOG_LEVEL_ERROR -# define LOG_ERROR(format, arg...) \ - nekolog(LOG_LEVEL_ERROR, \ - format "\n", ## arg) -#else -# define LOG_ERROR(format, arg...) -#endif - -#if LOG_LEVEL <= LOG_LEVEL_FATAL -# define LOG_FATAL(format, arg...) \ - nekolog(LOG_LEVEL_FATAL, \ - format "\n", ## arg) -#else -# define LOG_FATAL(format, arg...) -#endif - -#endif /* #ifndef LOG_H__7097F6FE_4FEE_4962_9542_60375961F567__INCLUDED */ diff --git a/source/native-plugins/nekofilter/nekofilter.c b/source/native-plugins/nekofilter/nekofilter.c deleted file mode 100644 index 0d9bad862..000000000 --- a/source/native-plugins/nekofilter/nekofilter.c +++ /dev/null @@ -1,411 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov - * Copyright (C) 2013-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - *****************************************************************************/ - -#if defined(__linux__) || defined(__linux) -# define WANT_UI -#endif - -#define LOG_LEVEL LOG_LEVEL_ERROR - -#include "CarlaNative.h" - -#include -#include -#include -#include -#include - -#include "filter.h" -#include "log.h" - -#ifdef WANT_UI -# include "ui.c" -#endif - -#define BANDS_COUNT 4 - -struct nekofilter -{ - filter_handle filter; - float params_global[GLOBAL_PARAMETERS_COUNT]; - float params_bands[BAND_PARAMETERS_COUNT*BANDS_COUNT]; - const NativeHostDescriptor* host; -#ifdef WANT_UI - struct control* ui; -#endif -}; - -static -NativePluginHandle -nekofilter_instantiate( - const NativeHostDescriptor* host) -{ - struct nekofilter * nekofilter_ptr; - unsigned int i; - - LOG_DEBUG("nekofilter_create_plugin_instance() called."); - - nekofilter_ptr = malloc(sizeof(struct nekofilter)); - if (nekofilter_ptr == NULL) - { - return NULL; - } - - nekofilter_ptr->host = host; -#ifdef WANT_UI - nekofilter_ptr->ui = NULL; -#endif - - if (! filter_create((float)host->get_sample_rate(host->handle), BANDS_COUNT, &nekofilter_ptr->filter)) - { - free(nekofilter_ptr); - return NULL; - } - - nekofilter_ptr->params_global[GLOBAL_PARAMETER_ACTIVE] = 1.0f; - nekofilter_ptr->params_global[GLOBAL_PARAMETER_GAIN] = 0.0f; - - filter_connect_global_parameter(nekofilter_ptr->filter, - GLOBAL_PARAMETER_ACTIVE, - &nekofilter_ptr->params_global[GLOBAL_PARAMETER_ACTIVE]); - - filter_connect_global_parameter(nekofilter_ptr->filter, - GLOBAL_PARAMETER_GAIN, - &nekofilter_ptr->params_global[GLOBAL_PARAMETER_GAIN]); - - for (i=0; i < BANDS_COUNT; ++i) - { - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_ACTIVE] = 0.0f; - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_FREQUENCY] = 0.0f; - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_BANDWIDTH] = 1.0f; - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_GAIN] = 0.0f; - - switch (i) - { - case 0: - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_FREQUENCY] = 200.0f; - break; - case 1: - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_FREQUENCY] = 400.0f; - break; - case 2: - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_FREQUENCY] = 1000.0f; - break; - case 3: - nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_FREQUENCY] = 2000.0f; - break; - } - - filter_connect_band_parameter(nekofilter_ptr->filter, - i, - BAND_PARAMETER_ACTIVE, - &nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_ACTIVE]); - - filter_connect_band_parameter(nekofilter_ptr->filter, - i, - BAND_PARAMETER_FREQUENCY, - &nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_FREQUENCY]); - - filter_connect_band_parameter(nekofilter_ptr->filter, - i, - BAND_PARAMETER_BANDWIDTH, - &nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_BANDWIDTH]); - - filter_connect_band_parameter(nekofilter_ptr->filter, - i, - BAND_PARAMETER_GAIN, - &nekofilter_ptr->params_bands[i*BAND_PARAMETERS_COUNT + BAND_PARAMETER_GAIN]); - } - - return (NativePluginHandle)nekofilter_ptr; -} - -#define nekofilter_ptr ((struct nekofilter *)handle) - -static -uint32_t -nekofilter_get_parameter_count( - NativePluginHandle handle) -{ - return GLOBAL_PARAMETERS_COUNT + BAND_PARAMETERS_COUNT*BANDS_COUNT; - - // unused - (void)handle; -} - -static -const NativeParameter* -nekofilter_get_parameter_info( - NativePluginHandle handle, - uint32_t index) -{ - static NativeParameter param; - static char* name = NULL; - static char* unit = NULL; - uint32_t band; - char strBuf[32]; - - if (name != NULL) - { - free(name); - name = NULL; - } - if (unit != NULL) - { - free(unit); - unit = NULL; - } - - if (handle == NULL && index == 0xf00baa) - // internal cleanup call - return NULL; - - param.hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE; - param.ranges.def = 0.0f; - param.ranges.min = 0.0f; - param.ranges.max = 0.0f; - param.scalePointCount = 0; - param.scalePoints = NULL; - - switch (index) - { - case GLOBAL_PARAMETER_ACTIVE: - name = strdup("Active"); - param.hints |= NATIVE_PARAMETER_IS_BOOLEAN; - param.ranges.max = 1.0f; - goto ready; - break; - - case GLOBAL_PARAMETER_GAIN: - name = strdup("Gain"); - unit = strdup("dB"); - param.ranges.min = -20.0f; - param.ranges.max = 20.0f; - goto ready; - break; - } - - index -= GLOBAL_PARAMETERS_COUNT; - - band = index / BANDS_COUNT; - index %= BANDS_COUNT; - - sprintf(strBuf, "%i:", band); - - switch (index) - { - case BAND_PARAMETER_ACTIVE: - strcat(strBuf, "Active"); - name = strdup(strBuf); - param.hints |= NATIVE_PARAMETER_IS_BOOLEAN; - param.ranges.max = 1.0f; - break; - - case BAND_PARAMETER_FREQUENCY: - strcat(strBuf, "Frequency"); - name = strdup(strBuf); - unit = strdup("Hz"); - param.hints |= NATIVE_PARAMETER_IS_LOGARITHMIC; - - switch (band) - { - case 0: - param.ranges.min = 20.0f; - param.ranges.max = 2000.0f; - break; - case 1: - param.ranges.min = 40.0f; - param.ranges.max = 4000.0f; - break; - case 2: - param.ranges.min = 100.0f; - param.ranges.max = 10000.0f; - break; - case 3: - param.ranges.min = 200.0f; - param.ranges.max = 20000.0f; - break; - } - break; - - case BAND_PARAMETER_BANDWIDTH: - strcat(strBuf, "Bandwidth"); - name = strdup(strBuf); - param.hints |= NATIVE_PARAMETER_IS_LOGARITHMIC; - param.ranges.min = 0.125f; - param.ranges.max = 8.0f; - break; - - case BAND_PARAMETER_GAIN: - strcat(strBuf, "Gain"); - name = strdup(strBuf); - unit = strdup("dB"); - param.ranges.min = -20.0f; - param.ranges.max = 20.0f; - break; - } - -ready: - if (param.hints & NATIVE_PARAMETER_IS_BOOLEAN) - { - param.ranges.step = 1.0f; - param.ranges.stepSmall = 1.0f; - param.ranges.stepLarge = 1.0f; - } - else - { - float range = param.ranges.max - param.ranges.min; - param.ranges.step = range/100.0f; - param.ranges.stepSmall = range/1000.0f; - param.ranges.stepLarge = range/10.0f; - } - - param.name = name; - param.unit = unit; - - return ¶m; -} - -static -float -nekofilter_get_parameter_value( - NativePluginHandle handle, - uint32_t index) -{ - if (index < GLOBAL_PARAMETERS_COUNT) - { - return nekofilter_ptr->params_global[index]; - } - else - { - assert(index >= GLOBAL_PARAMETERS_COUNT); - index -= GLOBAL_PARAMETERS_COUNT; - - return nekofilter_ptr->params_bands[index]; - } -} - -static -void -nekofilter_set_parameter_value( - NativePluginHandle handle, - uint32_t index, - float value) -{ - if (index < GLOBAL_PARAMETERS_COUNT) - { - nekofilter_ptr->params_global[index] = value; - } - else - { - assert(index >= GLOBAL_PARAMETERS_COUNT); - index -= GLOBAL_PARAMETERS_COUNT; - - nekofilter_ptr->params_bands[index] = value; - } -} - -static -void -nekofilter_process( - NativePluginHandle handle, - float** inBuffer, - float** outBuffer, - uint32_t frames, - const NativeMidiEvent* midiEvents, - uint32_t midiEventCount) -{ - LOG_DEBUG("nekofilter_run"); - filter_run( - nekofilter_ptr->filter, - inBuffer[0], - outBuffer[0], - frames); - - return; - - // unused - (void)midiEventCount; - (void)midiEvents; -} - -#ifdef WANT_UI -static -void -nekofilter_ui_show( - NativePluginHandle handle, - bool show) -{ - if (show) - { - if (nekofilter_ptr->ui == NULL) - nekofilter_ptr->ui = nekoui_instantiate(nekofilter_ptr->host); - if (nekofilter_ptr->ui != NULL) - nekoui_show(nekofilter_ptr->ui); - else - nekofilter_ptr->host->dispatcher(nekofilter_ptr->host->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, NULL, 0.0f); - } - else if (nekofilter_ptr->ui != NULL) - nekoui_hide(nekofilter_ptr->ui); -} - -static -void -nekofilter_ui_idle( - NativePluginHandle handle) -{ - if (nekofilter_ptr->ui != NULL) - nekoui_run(nekofilter_ptr->ui); -} - -static -void -nekofilter_ui_set_parameter_value( - NativePluginHandle handle, - uint32_t index, - float value) -{ - if (nekofilter_ptr->ui != NULL) - nekoui_set_parameter_value(nekofilter_ptr->ui, index, value); -} -#endif - -static -void -nekofilter_cleanup( - NativePluginHandle handle) -{ -#ifdef WANT_UI - if (nekofilter_ptr->ui != NULL) - { - nekoui_quit(nekofilter_ptr->ui); - nekoui_cleanup(nekofilter_ptr->ui); - } -#endif - - filter_destroy(nekofilter_ptr->filter); - free(nekofilter_ptr); - - // cleanup static data - nekofilter_get_parameter_info(NULL, 0xf00baa); -} - -#undef nekofilter_ptr diff --git a/source/native-plugins/nekofilter/ui.c b/source/native-plugins/nekofilter/ui.c deleted file mode 100644 index c0e520e9a..000000000 --- a/source/native-plugins/nekofilter/ui.c +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * Copyright (C) 2009 Nedko Arnaudov - * Copyright (C) 2013-2014 Filipe Coelho - * - * LV2 UI bundle shared library for communicating with a DSSI UI - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307, USA. - * - *****************************************************************************/ - -#define UI_EXECUTABLE "/nekofilter-ui" - -#define WAIT_START_TIMEOUT 3000 /* ms */ -#define WAIT_ZOMBIE_TIMEOUT 3000 /* ms */ -#define WAIT_STEP 100 /* ms */ - -//#define FORK_TIME_MEASURE - -#define USE_VFORK -//#define USE_CLONE -//#define USE_CLONE2 - -#if defined(USE_VFORK) -# define FORK vfork -# define FORK_STR "vfork" -#elif defined(USE_CLONE) -# define FORK_STR "clone" -#elif defined(USE_CLONE2) -# define FORK_STR "clone2" -#else -# define FORK fork -# define FORK_STR "fork" -#endif - -#include "CarlaNative.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(FORK_TIME_MEASURE) -# include -#endif - -#if defined(USE_CLONE) || defined(USE_CLONE2) -# include -#endif - -struct control -{ - const NativeHostDescriptor* host; - - bool running; /* true if UI launched and 'exiting' not received */ - bool visible; /* true if 'show' sent */ - - int send_pipe; /* the pipe end that is used for sending messages to UI */ - int recv_pipe; /* the pipe end that is used for receiving messages from UI */ - - pid_t pid; -}; - -static -char * -read_line( - struct control * control_ptr) -{ - ssize_t ret; - char ch; - char buf[100]; - char * ptr; - - ptr = buf; - -loop: - ret = read(control_ptr->recv_pipe, &ch, 1); - if (ret == 1 && ch != '\n') - { - *ptr++ = ch; - goto loop; - } - - if (ptr != buf) - { - *ptr = 0; - //printf("recv: \"%s\"\n", buf); - return strdup(buf); - } - - return NULL; -} - -static -bool -wait_child( - pid_t pid) -{ - pid_t ret; - int i; - - if (pid == -1) - { - fprintf(stderr, "Can't wait for pid -1\n"); - return false; - } - - for (i = 0; i < WAIT_ZOMBIE_TIMEOUT / WAIT_STEP; ++i) - { - //printf("waitpid(%d): %d\n", (int)pid, i); - - ret = waitpid(pid, NULL, WNOHANG); - if (ret != 0) - { - if (ret == pid) - { - //printf("child zombie with pid %d was consumed.\n", (int)pid); - return true; - } - - if (ret == -1) - { - fprintf(stderr, "waitpid(%d) failed: %s\n", (int)pid, strerror(errno)); - return false; - } - - fprintf(stderr, "we have waited for child pid %d to exit but we got pid %d instead\n", (int)pid, (int)ret); - - return false; - } - - //printf("zombie wait %d ms ...\n", WAIT_STEP); - usleep(WAIT_STEP * 1000); /* wait 100 ms */ - } - - fprintf( - stderr, - "we have waited for child with pid %d to exit for %.1f seconds and we are giving up\n", - (int)pid, - (float)WAIT_START_TIMEOUT / 1000.0f); - - return false; -} - -static -void -nekoui_run( - struct control * control_ptr) -{ - char * msg; - char * port_index_str; - char * port_value_str; - int index; - float value; - char * locale; - - msg = read_line(control_ptr); - if (msg == NULL) - { - return; - } - - locale = strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "POSIX"); - - if (!strcmp(msg, "port_value")) - { - port_index_str = read_line(control_ptr); - port_value_str = read_line(control_ptr); - - index = atoi(port_index_str); - if (sscanf(port_value_str, "%f", &value) == 1) - { - //printf("port %d = %f\n", port, value); - control_ptr->host->ui_parameter_changed(control_ptr->host->handle, (uint32_t)index, value); - } - else - { - fprintf(stderr, "failed to convert \"%s\" to float\n", port_value_str); - } - - free(port_index_str); - free(port_value_str); - } - else if (!strcmp(msg, "close")) - { - control_ptr->visible = false; - control_ptr->host->ui_closed(control_ptr->host->handle); - } - else if (!strcmp(msg, "exiting")) - { - /* for a while wait child to exit, we dont like zombie processes */ - if (!wait_child(control_ptr->pid)) - { - fprintf(stderr, "force killing misbehaved child %d (exit)\n", (int)control_ptr->pid); - if (kill(control_ptr->pid, SIGKILL) == -1) - { - fprintf(stderr, "kill() failed: %s (exit)\n", strerror(errno)); - } - else - { - wait_child(control_ptr->pid); - } - } - - control_ptr->running = false; - control_ptr->visible = false; - control_ptr->host->ui_closed(control_ptr->host->handle); - } - else - { - printf("unknown message: \"%s\"\n", msg); - } - - setlocale(LC_NUMERIC, locale); - free(locale); - - free(msg); -} - -static -void -nekoui_show( - struct control * control_ptr) -{ - if (control_ptr->visible) - { - return; - } - - ssize_t ign = write(control_ptr->send_pipe, "show\n", 5); - control_ptr->visible = true; - return; - - // ignored - (void)ign; -} - -static -void -nekoui_hide( - struct control * control_ptr) -{ - if (!control_ptr->visible) - { - return; - } - - ssize_t ign = write(control_ptr->send_pipe, "hide\n", 5); - control_ptr->visible = false; - return; - - // ignored - (void)ign; -} - -static -void -nekoui_quit( - struct control * control_ptr) -{ - ssize_t ign = write(control_ptr->send_pipe, "quit\n", 5); - control_ptr->visible = false; - - /* for a while wait child to exit, we dont like zombie processes */ - if (!wait_child(control_ptr->pid)) - { - fprintf(stderr, "force killing misbehaved child %d (exit)\n", (int)control_ptr->pid); - if (kill(control_ptr->pid, SIGKILL) == -1) - { - fprintf(stderr, "kill() failed: %s (exit)\n", strerror(errno)); - } - else - { - wait_child(control_ptr->pid); - } - } - return; - - // ignored - (void)ign; -} - -#if defined(FORK_TIME_MEASURE) -static -uint64_t -get_current_time() -{ - struct timeval time; - - if (gettimeofday(&time, NULL) != 0) - return 0; - - return (uint64_t)time.tv_sec * 1000000 + (uint64_t)time.tv_usec; -} - -#define FORK_TIME_MEASURE_VAR_NAME ____t - -#define FORK_TIME_MEASURE_VAR uint64_t FORK_TIME_MEASURE_VAR_NAME -#define FORK_TIME_MEASURE_BEGIN FORK_TIME_MEASURE_VAR_NAME = get_current_time() -#define FORK_TIME_MEASURE_END(msg) \ - { \ - FORK_TIME_MEASURE_VAR_NAME = get_current_time() - FORK_TIME_MEASURE_VAR_NAME; \ - fprintf(stderr, msg ": %llu us\n", (unsigned long long)FORK_TIME_MEASURE_VAR_NAME); \ - } - -#else - -#define FORK_TIME_MEASURE_VAR -#define FORK_TIME_MEASURE_BEGIN -#define FORK_TIME_MEASURE_END(msg) - -#endif - -#if defined(USE_CLONE) || defined(USE_CLONE2) - -static int clone_fn(void * context) -{ - execvp(*(const char **)context, (char **)context); - return -1; -} - -#endif - -static bool do_fork(char* const argv[6], int* ret /*, int pipe1[2], int pipe2[2]*/) -{ - int ret2 = *ret = FORK(); - - switch (ret2) - { - case 0: /* child process */ - /* fork duplicated the handles, close pipe ends that are used by parent process */ -#if !defined(USE_VFORK) - /* it looks we cant do this for vfork() */ - close(pipe1[1]); - close(pipe2[0]); -#endif - - execvp(argv[0], argv); - fprintf(stderr, "exec of UI failed: %s\n", strerror(errno)); - _exit(0); - return false; - case -1: - fprintf(stderr, "fork() failed to create new process for plugin UI\n"); - _exit(0); - return false; - } - - return true; -} - -static -struct control* -nekoui_instantiate( - const NativeHostDescriptor* host) -{ - struct control * control_ptr; - char * filename; - int pipe1[2]; /* written by host process, read by plugin UI process */ - int pipe2[2]; /* written by plugin UI process, read by host process */ - char ui_recv_pipe[100]; - char ui_send_pipe[100]; - int oldflags; - FORK_TIME_MEASURE_VAR; - char * argv[6]; - int ret; - int i; - char ch; - char ap2[24], ap26[24], ap27[24]; - strcpy(ap2, "/usr/bin/python2"); - strcpy(ap26, "/usr/bin/python2.6"); - strcpy(ap27, "/usr/bin/python2,7"); - - if (access(ap2, F_OK) != -1) - argv[0] = ap2; - else if (access(ap27, F_OK) != -1) - argv[0] = ap27; - else if (access(ap26, F_OK) != -1) - argv[0] = ap26; - else - goto fail; - - control_ptr = malloc(sizeof(struct control)); - if (control_ptr == NULL) - { - goto fail; - } - - control_ptr->host = host; - control_ptr->running = false; - control_ptr->visible = false; - control_ptr->send_pipe = -1; - control_ptr->recv_pipe = -1; - control_ptr->pid = -1; - - if (pipe(pipe1) != 0) - { - fprintf(stderr, "pipe1 creation failed.\n"); - goto fail_free_control; - } - - if (pipe(pipe2) != 0) - { - fprintf(stderr, "pipe2 creation failed.\n"); - goto fail_free_control; - } - - snprintf(ui_recv_pipe, sizeof(ui_recv_pipe), "%d", pipe1[0]); /* [0] means reading end */ - snprintf(ui_send_pipe, sizeof(ui_send_pipe), "%d", pipe2[1]); /* [1] means writting end */ - - filename = malloc(strlen(host->resourceDir) + strlen(UI_EXECUTABLE) + 1); - if (filename == NULL) - { - goto fail_free_control; - } - - strcpy(filename, host->resourceDir); - strcat(filename, UI_EXECUTABLE); - - char sample_rate_str[12] = { 0 }; - snprintf(sample_rate_str, 12, "%g", host->get_sample_rate(host->handle)); - - argv[1] = filename; - argv[2] = sample_rate_str; - argv[3] = ui_recv_pipe; /* reading end */ - argv[4] = ui_send_pipe; /* writting end */ - argv[5] = NULL; - - FORK_TIME_MEASURE_BEGIN; - -#if defined(USE_CLONE) - { - int stack[8000]; - - ret = clone(clone_fn, stack + 4000, CLONE_VFORK, argv); - if (ret == -1) - { - fprintf(stderr, "clone() failed: %s\n", strerror(errno)); - goto fail_free_control; - } - } -#elif defined(USE_CLONE2) - fprintf(stderr, "clone2() exec not implemented yet\n"); - goto fail_free_control; -#else - if (! do_fork(argv, &ret /*, pipe1, pipe2*/)) - goto fail_free_control; -#endif - - FORK_TIME_MEASURE_END(FORK_STR "() time"); - - //fprintf(stderr, FORK_STR "()-ed child process: %d\n", ret); - control_ptr->pid = ret; - - /* fork duplicated the handles, close pipe ends that are used by the child process */ - close(pipe1[0]); - close(pipe2[1]); - - control_ptr->send_pipe = pipe1[1]; /* [1] means writting end */ - control_ptr->recv_pipe = pipe2[0]; /* [0] means reading end */ - - oldflags = fcntl(control_ptr->recv_pipe, F_GETFL); - fcntl(control_ptr->recv_pipe, F_SETFL, oldflags | O_NONBLOCK); - - /* wait a while for child process to confirm it is alive */ - //printf("waiting UI start\n"); - i = 0; -loop: - ret = (int)read(control_ptr->recv_pipe, &ch, 1); - switch (ret) - { - case -1: - if (errno == EAGAIN) - { - if (i < WAIT_START_TIMEOUT / WAIT_STEP) - { - //printf("start wait %d ms ...\n", WAIT_STEP); - usleep(WAIT_STEP * 1000); - i++; - goto loop; - } - - fprintf( - stderr, - "we have waited for child with pid %d to appear for %.1f seconds and we are giving up\n", - (int)control_ptr->pid, - (float)((float)WAIT_START_TIMEOUT / 1000)); - } - else - { - fprintf(stderr, "read() failed: %s\n", strerror(errno)); - } - break; - case 1: - if (ch == '\n') - { - return control_ptr; - } - - fprintf(stderr, "read() wrong first char '%c'\n", ch); - - break; - default: - fprintf(stderr, "read() returned %d\n", ret); - } - - fprintf(stderr, "force killing misbehaved child %d (start)\n", (int)control_ptr->pid); - - if (kill(control_ptr->pid, SIGKILL) == -1) - { - fprintf(stderr, "kill() failed: %s (start)\n", strerror(errno)); - } - - /* wait a while child to exit, we dont like zombie processes */ - wait_child(control_ptr->pid); - -fail_free_control: - free(control_ptr); - -fail: - fprintf(stderr, "nekofilter UI launch failed\n"); - return NULL; -} - -static -void -nekoui_cleanup( - struct control * control_ptr) -{ - //printf("cleanup() called\n"); - free(control_ptr); -} - -static -void -nekoui_set_parameter_value( - struct control * control_ptr, - uint32_t index, - float value) -{ - char buf[100]; - int len; - char * locale; - ssize_t ign; - - //printf("port_event(%u, %f) called\n", (unsigned int)port_index, *(float *)buffer); - - locale = strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "POSIX"); - - ign = write(control_ptr->send_pipe, "port_value\n", 11); - len = sprintf(buf, "%u\n", (unsigned int)index); - ign = write(control_ptr->send_pipe, buf, (size_t)len); - len = sprintf(buf, "%.10f\n", value); - ign = write(control_ptr->send_pipe, buf, (size_t)len); - fsync(control_ptr->send_pipe); - - setlocale(LC_NUMERIC, locale); - free(locale); - return; - - // ignored - (void)ign; -} - -#undef control_ptr diff --git a/source/native-plugins/resources/nekofilter-ui b/source/native-plugins/resources/nekofilter-ui deleted file mode 100755 index ba73d5d0c..000000000 --- a/source/native-plugins/resources/nekofilter-ui +++ /dev/null @@ -1,1243 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2008,2009 Nedko Arnaudov -# Copyright (C) 2006 Leonard Ritter -# Filter response code by Fons Adriaensen -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - -import sys -import os -import fcntl -import gtk -import gobject -import cairo -from math import pi, sin, cos, atan2, log, sqrt, hypot, log10 -from colorsys import hls_to_rgb, rgb_to_hls - -def map_coords_linear(x,y): - return x,1.0-y - -def map_coords_spheric(x,y): - nx = cos(x * 2 * pi) * y - ny = -sin(x * 2 * pi) * y - return nx, ny - -def get_peaks(f, tolerance=0.01, maxd=0.01, mapfunc=map_coords_linear): - corners = 360 - yc = 1.0/corners - peaks = [] - x0,y0 = 0.0,0.0 - t0 = -9999.0 - i0 = 0 - for i in xrange(int(corners)): - p = i*yc - a = f(p) - x,y = mapfunc(p, a) - if i == 0: - x0,y0 = x,y - t = atan2((y0 - y), (x0 - x)) / (2*pi) - td = t - t0 - if (abs(td) >= tolerance): - t0 = t - peaks.append((x,y)) - x0,y0 = x,y - return peaks - -def make_knobshape(gaps, gapdepth): - def knobshape_func(x): - x = (x*gaps)%1.0 - w = 0.5 - g1 = 0.5 - w*0.5 - g2 = 0.5 + w*0.5 - if (x >= g1) and (x < 0.5): - x = (x-g1)/(w*0.5) - return 0.5 - gapdepth * x * 0.9 - elif (x >= 0.5) and (x < g2): - x = (x-0.5)/(w*0.5) - return 0.5 - gapdepth * (1-x) * 0.9 - else: - return 0.5 - return get_peaks(knobshape_func, 0.03, 0.05, map_coords_spheric) - -def hls_to_color(h,l,s): - r,g,b = hls_to_rgb(h,l,s) - return gtk.gdk.color_parse('#%04X%04X%04X' % (int(r*65535),int(g*65535),int(b*65535))) - -def color_to_hls(color): - string = color.to_string() - r = int(string[1:5], 16) / 65535.0 - g = int(string[5:9], 16) / 65535.0 - b = int(string[9:13], 16) / 65535.0 - return rgb_to_hls(r, g, b) - -MARKER_NONE = '' -MARKER_LINE = 'line' -MARKER_ARROW = 'arrow' -MARKER_DOT = 'dot' - -LEGEND_NONE = '' -LEGEND_DOTS = 'dots' # painted dots -LEGEND_LINES = 'lines' # painted ray-like lines -LEGEND_RULER = 'ruler' # painted ray-like lines + a circular one -LEGEND_RULER_INWARDS = 'ruler-inwards' # same as ruler, but the circle is on the outside -LEGEND_LED_SCALE = 'led-scale' # an LCD scale -LEGEND_LED_DOTS = 'led-dots' # leds around the knob - -class KnobTooltip: - def __init__(self): - self.tooltip_window = gtk.Window(gtk.WINDOW_POPUP) - self.tooltip = gtk.Label() - #self.tooltip.modify_fg(gtk.STATE_NORMAL, hls_to_color(0.0, 1.0, 0.0)) - self.tooltip_timeout = None - vbox = gtk.VBox() - vbox2 = gtk.VBox() - vbox2.add(self.tooltip) - vbox2.set_border_width(2) - vbox.add(vbox2) - self.tooltip_window.add(vbox) - vbox.connect('expose-event', self.on_tooltip_expose) - - def show_tooltip(self, knob): - text = knob.format_value() - rc = knob.get_allocation() - x,y = knob.window.get_origin() - self.tooltip_window.show_all() - w,h = self.tooltip_window.get_size() - wx,wy = x+rc.x-w, y+rc.y+rc.height/2-h/2 - self.tooltip_window.move(wx,wy) - rc = self.tooltip_window.get_allocation() - self.tooltip_window.window.invalidate_rect((0,0,rc.width,rc.height), False) - self.tooltip.set_text(text) - if self.tooltip_timeout: - gobject.source_remove(self.tooltip_timeout) - self.tooltip_timeout = gobject.timeout_add(500, self.hide_tooltip) - - def hide_tooltip(self): - self.tooltip_window.hide_all() - - def on_tooltip_expose(self, widget, event): - ctx = widget.window.cairo_create() - rc = widget.get_allocation() - #ctx.set_source_rgb(*hls_to_rgb(0.0, 0.0, 0.5)) - #ctx.paint() - ctx.set_source_rgb(*hls_to_rgb(0.0, 0.0, 0.5)) - ctx.translate(0.5, 0.5) - ctx.set_line_width(1) - ctx.rectangle(rc.x, rc.y,rc.width-1,rc.height-1) - ctx.stroke() - return False - - - -knob_tooltip = None -def get_knob_tooltip(): - global knob_tooltip - if not knob_tooltip: - knob_tooltip = KnobTooltip() - return knob_tooltip - -class SmartAdjustment(gtk.Adjustment): - def __init__(self, log=False, value=0, lower=0, upper=0, step_incr=0, page_incr=0, page_size=0): - self.log = log - gtk.Adjustment.__init__(self, value, lower, upper, step_incr, page_incr, page_size) - self.normalized_value = self.real2norm(self.value) - - def real2norm(self, value): - if self.log: - return log(value / self.lower, self.upper / self.lower) - else: - return (value - self.lower) / (self.upper - self.lower) - - def norm2real(self, value): - if self.log: - return self.lower * pow(self.upper / self.lower, value) - else: - return value * (self.upper - self.lower) + self.lower - - def set_value(self, value): - self.normalized_value = self.real2norm(value) - gtk.Adjustment.set_value(self, value) - - def get_normalized_value(self): - return self.normalized_value - - def set_normalized_value(self, value): - self.normalized_value = value - - if self.normalized_value < 0.0: - self.normalized_value = 0.0 - elif self.normalized_value > 1.0: - self.normalized_value = 1.0 - - self.set_value(self.norm2real(self.normalized_value)) - -class Knob(gtk.VBox): - def __init__(self): - gtk.VBox.__init__(self) - self.gapdepth = 4 - self.gaps = 10 - self.value = 0.0 - self.min_value = 0.0 - self.max_value = 127.0 - self.fg_hls = 0.0, 0.7, 0.0 - self.legend_hls = None - self.dragging = False - self.start = 0.0 - self.digits = 2 - self.segments = 13 - self.label = '' - self.marker = MARKER_LINE - self.angle = (3.0/4.0) * 2 * pi - self.knobshape = None - self.legend = LEGEND_DOTS - self.lsize = 2 - self.lscale = False - self.set_double_buffered(True) - self.connect('realize', self.on_realize) - self.connect("size_allocate", self.on_size_allocate) - self.connect('expose-event', self.on_expose) - self.set_border_width(6) - self.set_size_request(50, 50) - self.tooltip_enabled = False - self.adj = None - - def set_adjustment(self, adj): - self.min_value = 0.0 - self.max_value = 1.0 - self.value = adj.get_normalized_value() - if self.adj: - self.adj.disconnect(self.adj_id) - self.adj = adj - self.adj_id = adj.connect("value-changed", self.on_adj_value_changed) - - def is_sensitive(self): - return self.get_property("sensitive") - - def format_value(self): - if self.adj: - value = self.adj.value - else: - value = self.value - return ("%%.%if" % self.digits) % value - - def show_tooltip(self): - if self.tooltip_enabled: - get_knob_tooltip().show_tooltip(self) - - def on_realize(self, widget): - self.root = self.get_toplevel() - self.root.add_events(gtk.gdk.ALL_EVENTS_MASK) - self.root.connect('scroll-event', self.on_mousewheel) - self.root.connect('button-press-event', self.on_left_down) - self.root.connect('button-release-event', self.on_left_up) - self.root.connect('motion-notify-event', self.on_motion) - self.update_knobshape() - - def update_knobshape(self): - rc = self.get_allocation() - b = self.get_border_width() - size = min(rc.width, rc.height) - 2*b - gd = float(self.gapdepth*0.5) / size - self.gd = gd - self.knobshape = make_knobshape(self.gaps, gd) - - def set_legend_scale(self, scale): - self.lscale = scale - self.refresh() - - def set_legend_line_width(self, width): - self.lsize = width - self.refresh() - - def set_segments(self, segments): - self.segments = segments - self.refresh() - - def set_marker(self, marker): - self.marker = marker - self.refresh() - - def set_range(self, minvalue, maxvalue): - self.min_value = minvalue - self.max_value = maxvalue - self.set_value(self.value) - - def quantize_value(self, value): - scaler = 10**self.digits - value = int((value*scaler)+0.5) / float(scaler) - return value - - def on_adj_value_changed(self, adj): - new_value = adj.get_normalized_value() - if self.value != new_value: - self.value = new_value - self.refresh() - - def set_value(self, value): - oldval = self.value - self.value = min(max(self.quantize_value(value), self.min_value), self.max_value) - if self.value != oldval: - if self.adj: - self.adj.set_normalized_value(value) - self.refresh() - - def get_value(self): - return self.value - - def set_top_color(self, h, l, s): - self.fg_hls = h,l,s - self.refresh() - - def set_legend_color(self, h, l, s): - self.legend_hls = h,l,s - self.refresh() - - def get_top_color(self): - return self.fg_hls - - def set_gaps(self, gaps): - self.gaps = gaps - self.knobshape = None - self.refresh() - - def get_gaps(self): - return self.gaps - - def set_gap_depth(self, gapdepth): - self.gapdepth = gapdepth - self.knobshape = None - self.refresh() - - def get_gap_depth(self): - return self.gapdepth - - def set_angle(self, angle): - self.angle = angle - self.refresh() - - def get_angle(self): - return self.angle - - def set_legend(self, legend): - self.legend = legend - self.refresh() - - def get_legend(self): - return self.legend - - def on_left_down(self, widget, event): - #print("on_left_down") - - # dont drag insensitive widgets - if not self.is_sensitive(): - return False - - if not sum(self.get_allocation().intersect((int(event.x), int(event.y), 1, 1))): - return False - if event.button == 1: - #print("start draggin") - self.startvalue = self.value - self.start = event.y - self.dragging = True - self.show_tooltip() - self.grab_add() - return True - return False - - def on_left_up(self, widget, event): - #print("on_left_up") - if not self.dragging: - return False - if event.button == 1: - #print("stop draggin") - self.dragging = False - self.grab_remove() - return True - return False - - def on_motion(self, widget, event): - #print("on_motion") - - # dont drag insensitive widgets - if not self.is_sensitive(): - return False - - if self.dragging: - x,y,state = self.window.get_pointer() - rc = self.get_allocation() - range = self.max_value - self.min_value - scale = rc.height - if event.state & gtk.gdk.SHIFT_MASK: - scale = rc.height*8 - value = self.startvalue - ((y - self.start)*range)/scale - oldval = self.value - self.set_value(value) - self.show_tooltip() - if oldval != self.value: - self.start = y - self.startvalue = self.value - return True - return False - - def on_mousewheel(self, widget, event): - - # dont move insensitive widgets - if not self.is_sensitive(): - return False - - if not sum(self.get_allocation().intersect((int(event.x), int(event.y), 1, 1))): - return - range = self.max_value - self.min_value - minstep = 1.0 / (10**self.digits) - if event.state & (gtk.gdk.SHIFT_MASK | gtk.gdk.BUTTON1_MASK): - step = minstep - else: - step = max(self.quantize_value(range/25.0), minstep) - value = self.value - if event.direction == gtk.gdk.SCROLL_UP: - value += step - elif event.direction == gtk.gdk.SCROLL_DOWN: - value -= step - self.set_value(value) - self.show_tooltip() - - def on_size_allocate(self, widget, allocation): - #print(allocation.x, allocation.y, allocation.width, allocation.height) - self.update_knobshape() - - def draw_points(self, ctx, peaks): - ctx.move_to(*peaks[0]) - for peak in peaks[1:]: - ctx.line_to(*peak) - - def draw(self, ctx): - if not self.legend_hls: - self.legend_hls = color_to_hls(self.style.fg[gtk.STATE_NORMAL]) - - if not self.knobshape: - self.update_knobshape() - startangle = pi*1.5 - self.angle*0.5 - angle = ((self.value - self.min_value) / (self.max_value - self.min_value)) * self.angle + startangle - rc = self.get_allocation() - size = min(rc.width, rc.height) - - kh = self.get_border_width() # knob height - - ps = 1.0/size # pixel size - ps2 = 1.0 / (size-(2*kh)-1) # pixel size inside knob - ss = ps * kh # shadow size - lsize = ps2 * self.lsize # legend line width - # draw spherical - ctx.translate(rc.x, rc.y) - ctx.translate(0.5,0.5) - ctx.translate(size*0.5, size*0.5) - ctx.scale(size-(2*kh)-1, size-(2*kh)-1) - if self.legend == LEGEND_DOTS: - ctx.save() - ctx.set_source_rgb(*hls_to_rgb(*self.legend_hls)) - dots = self.segments - for i in xrange(dots): - s = float(i)/(dots-1) - a = startangle + self.angle*s - ctx.save() - ctx.rotate(a) - r = lsize*0.5 - if self.lscale: - r = max(r*s,ps2) - ctx.arc(0.5+lsize, 0.0, r, 0.0, 2*pi) - ctx.fill() - ctx.restore() - ctx.restore() - elif self.legend in (LEGEND_LINES, LEGEND_RULER, LEGEND_RULER_INWARDS): - ctx.save() - ctx.set_source_rgb(*hls_to_rgb(*self.legend_hls)) - dots = self.segments - n = ps2*(kh-1) - for i in xrange(dots): - s = float(i)/(dots-1) - a = startangle + self.angle*s - ctx.save() - ctx.rotate(a) - r = n*0.9 - if self.lscale: - r = max(r*s,ps2) - ctx.move_to(0.5+ps2+n*0.1, 0.0) - ctx.line_to(0.5+ps2+n*0.1+r, 0.0) - ctx.set_line_width(lsize) - ctx.stroke() - ctx.restore() - ctx.restore() - if self.legend == LEGEND_RULER: - ctx.save() - ctx.set_source_rgb(*hls_to_rgb(*self.legend_hls)) - ctx.set_line_width(lsize) - ctx.arc(0.0, 0.0, 0.5+ps2+n*0.1, startangle, startangle+self.angle) - ctx.stroke() - ctx.restore() - elif self.legend == LEGEND_RULER_INWARDS: - ctx.save() - ctx.set_source_rgb(*hls_to_rgb(*self.legend_hls)) - ctx.set_line_width(lsize) - ctx.arc(0.0, 0.0, 0.5+ps2+n, startangle, startangle+self.angle) - ctx.stroke() - - # draw shadow only for sensitive widgets that have height - if self.is_sensitive() and kh: - ctx.save() - ctx.translate(ss, ss) - ctx.rotate(angle) - self.draw_points(ctx, self.knobshape) - ctx.close_path() - ctx.restore() - ctx.set_source_rgba(0,0,0,0.3) - ctx.fill() - - if self.legend in (LEGEND_LED_SCALE, LEGEND_LED_DOTS): - ch,cl,cs = self.legend_hls - n = ps2*(kh-1) - ctx.save() - ctx.set_line_cap(cairo.LINE_CAP_ROUND) - ctx.set_source_rgb(*hls_to_rgb(ch,cl*0.2,cs)) - ctx.set_line_width(lsize) - ctx.arc(0.0, 0.0, 0.5+ps2+n*0.5, startangle, startangle+self.angle) - ctx.stroke() - ctx.set_source_rgb(*hls_to_rgb(ch,cl,cs)) - if self.legend == LEGEND_LED_SCALE: - ctx.set_line_width(lsize-ps2*2) - ctx.arc(0.0, 0.0, 0.5+ps2+n*0.5, startangle, angle) - ctx.stroke() - elif self.legend == LEGEND_LED_DOTS: - dots = self.segments - dsize = lsize-ps2*2 - seg = self.angle/dots - endangle = startangle + self.angle - for i in xrange(dots): - s = float(i)/(dots-1) - a = startangle + self.angle*s - if ((a-seg*0.5) > angle) or (angle == startangle): - break - ctx.save() - ctx.rotate(a) - r = dsize*0.5 - if self.lscale: - r = max(r*s,ps2) - ctx.arc(0.5+ps2+n*0.5, 0.0, r, 0.0, 2*pi) - ctx.fill() - ctx.restore() - ctx.restore() - pat = cairo.LinearGradient(-0.5, -0.5, 0.5, 0.5) - pat.add_color_stop_rgb(1.0, 0.2,0.2,0.2) - pat.add_color_stop_rgb(0.0, 0.3,0.3,0.3) - ctx.set_source(pat) - ctx.rotate(angle) - self.draw_points(ctx, self.knobshape) - ctx.close_path() - ctx.fill_preserve() - ctx.set_source_rgba(0.1,0.1,0.1,1) - ctx.save() - ctx.identity_matrix() - ctx.set_line_width(1.0) - ctx.stroke() - ctx.restore() - - ctx.arc(0.0, 0.0, 0.5-self.gd, 0.0, pi*2.0) - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], max(self.fg_hls[1]*0.4,0.0), self.fg_hls[2])) - ctx.fill() - ctx.arc(0.0, 0.0, 0.5-self.gd-ps, 0.0, pi*2.0) - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], min(self.fg_hls[1]*1.2,1.0), self.fg_hls[2])) - ctx.fill() - ctx.arc(0.0, 0.0, 0.5-self.gd-(2*ps), 0.0, pi*2.0) - ctx.set_source_rgb(*hls_to_rgb(*self.fg_hls)) - ctx.fill() - - # dont draw cap for insensitive widgets - if not self.is_sensitive(): - return - - #~ ctx.set_line_cap(cairo.LINE_CAP_ROUND) - #~ ctx.move_to(0.5-0.3-self.gd-ps, 0.0) - #~ ctx.line_to(0.5-self.gd-ps*5, 0.0) - - if self.marker == MARKER_LINE: - ctx.set_line_cap(cairo.LINE_CAP_BUTT) - ctx.move_to(0.5-0.3-self.gd-ps, 0.0) - ctx.line_to(0.5-self.gd-ps, 0.0) - ctx.save() - ctx.identity_matrix() - ctx.translate(0.5,0.5) - ctx.set_line_width(5) - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], min(self.fg_hls[1]*1.2,1.0), self.fg_hls[2])) - ctx.stroke_preserve() - ctx.set_line_width(3) - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], max(self.fg_hls[1]*0.4,0.0), self.fg_hls[2])) - ctx.stroke() - ctx.restore() - elif self.marker == MARKER_DOT: - ctx.arc(0.5-0.05-self.gd-ps*5, 0.0, 0.05, 0.0, 2*pi) - ctx.save() - ctx.identity_matrix() - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], min(self.fg_hls[1]*1.2,1.0), self.fg_hls[2])) - ctx.stroke_preserve() - ctx.set_line_width(1) - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], max(self.fg_hls[1]*0.4,0.0), self.fg_hls[2])) - ctx.fill() - ctx.restore() - elif self.marker == MARKER_ARROW: - ctx.set_line_cap(cairo.LINE_CAP_BUTT) - ctx.move_to(0.5-0.3-self.gd-ps, 0.1) - ctx.line_to(0.5-0.1-self.gd-ps, 0.0) - ctx.line_to(0.5-0.3-self.gd-ps, -0.1) - ctx.close_path() - ctx.save() - ctx.identity_matrix() - #~ ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], min(self.fg_hls[1]*1.2,1.0), self.fg_hls[2])) - #~ ctx.stroke_preserve() - ctx.set_line_width(1) - ctx.set_source_rgb(*hls_to_rgb(self.fg_hls[0], max(self.fg_hls[1]*0.4,0.0), self.fg_hls[2])) - ctx.fill() - ctx.restore() - - def refresh(self): - rect = self.get_allocation() - if self.window: - self.window.invalidate_rect(rect, False) - return True - - def on_expose(self, widget, event): - self.context = self.window.cairo_create() - self.draw(self.context) - return False - -class filter_band: - def __init__(self, sample_rate): - self.fsamp = sample_rate - - def set_params(self, freq, bandw, gain): - freq_ratio = freq / self.fsamp - gain2 = pow(10.0, 0.05 * gain) - b = 7 * bandw * freq_ratio / sqrt(gain2) - self.gn = 0.5 * (gain2 - 1) - self.v1 = -cos(2 * pi * freq_ratio) - self.v2 = (1 - b) / (1 + b) - self.v1 *= (1 + self.v2) - self.gn *= (1 - self.v2) - - def get_response(self, freq): - w = 2 * pi * (freq / self.fsamp) - c1 = cos(w) - s1 = sin(w) - c2 = cos(2 * w) - s2 = sin(2 * w) - - x = c2 + self.v1 * c1 + self.v2 - y = s2 + self.v1 * s1 - t1 = hypot(x, y) - x += self.gn * (c2 - 1) - y += self.gn * s2 - t2 = hypot(x, y) - - #return t2 / t1 - return 20 * log10(t2 / t1) - -class frequency_response(gtk.DrawingArea): - def __init__(self): - gtk.DrawingArea.__init__(self) - - self.connect("expose-event", self.on_expose) - self.connect("size-request", self.on_size_request) - self.connect("size_allocate", self.on_size_allocate) - - self.color_bg = gtk.gdk.Color(0,0,0) - self.color_value = gtk.gdk.Color(int(65535 * 0.8), int(65535 * 0.7), 0) - self.color_mark = gtk.gdk.Color(int(65535 * 0.3), int(65535 * 0.3), int(65535 * 0.3)) - self.color_sum = gtk.gdk.Color(int(65535 * 1.0), int(65535 * 1.0), int(65535 * 1.0)) - self.width = 0 - self.height = 0 - self.margin = 10 - self.db_range = 30 - self.master_gain = 0.0 - self.master_enabled = False - - self.filters = {} - - def on_expose(self, widget, event): - cairo_ctx = widget.window.cairo_create() - - # set a clip region for the expose event - cairo_ctx.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) - cairo_ctx.clip() - - self.draw(cairo_ctx) - - return False - - def on_size_allocate(self, widget, allocation): - #print(allocation.x, allocation.y, allocation.width, allocation.height) - self.width = float(allocation.width) - self.height = float(allocation.height) - self.font_size = 10 - - def on_size_request(self, widget, requisition): - #print("size-request, %u x %u" % (requisition.width, requisition.height)) - requisition.width = 150 - requisition.height = 150 - return - - def invalidate_all(self): - self.queue_draw_area(0, 0, int(self.width), int(self.height)) - - def get_x(self, hz): - width = self.width - 3.5 * self.margin - #x = self.margin + width * (hz - 20) / (20000 - 20) - x = 2.5 * self.margin + width * log(hz / 20.0, 1000.0) - #print(x) - return x - - def get_freq(self, x): - width = self.width - 3.5 * self.margin - return 20 * pow(1000, (x - 2.5 * self.margin) / width) - - def get_y(self, db): - height = self.height - 2.5 * self.margin - y = self.margin + height * (self.db_range - db) / (self.db_range * 2) - #print(y) - return y - - def draw_db_grid(self, cairo_ctx, db): - x = self.get_x(20) - y = self.get_y(db) - cairo_ctx.move_to(x, y) - cairo_ctx.line_to(self.get_x(20000), y) - - if db % 10 == 0: - x -= 20 - y += 3 - cairo_ctx.move_to(x, y) - label = "%+d" % db - if db == 0: - label = " " + label - cairo_ctx.show_text(label) - - cairo_ctx.stroke() - - def invalidate_all(self): - self.queue_draw_area(0, 0, int(self.width), int(self.height)) - - def draw(self, cairo_ctx): - cairo_ctx.select_font_face("Fixed") - - cairo_ctx.set_source_color(self.color_bg) - cairo_ctx.rectangle(0, 0, self.width, self.height) - cairo_ctx.fill() - - cairo_ctx.set_source_color(self.color_mark) - cairo_ctx.set_line_width(1); - - for hz in range(20, 101, 10) + range(100, 1001, 100) + range(1000, 10001, 1000) + range(10000, 20001, 10000): - if hz >= 10000: - label = "%dk" % int(hz / 1000) - elif hz >= 1000: - label = "%dk" % int(hz / 1000) - else: - label = "%d" % int(hz) - first_digit = int(label[0]) - if first_digit > 5 or (first_digit > 3 and (len(label) == 3)): - label = None - - x = self.get_x(hz) - cairo_ctx.move_to(x, self.get_y(self.db_range)) - y = self.get_y(-self.db_range) - cairo_ctx.line_to(x, y) - if label: - y += 10 - if hz == 20000: - x -= 15 - elif hz != 20: - x -= 3 - cairo_ctx.move_to(x, y) - cairo_ctx.show_text(label) - cairo_ctx.stroke() - - for db in range(0, self.db_range + 1, 5): - self.draw_db_grid(cairo_ctx, db) - - if db != 0: - self.draw_db_grid(cairo_ctx, -db) - - curves = [[x, {}, self.master_gain, self.get_freq(x)] for x in range(int(self.get_x(20)), int(self.get_x(20e3)))] - #print(repr(curves)) - - # calculate filter responses - for label, filter in self.filters.items(): - if not filter.enabled: - continue - - for point in curves: - db = filter.get_response(point[3]) - point[1][label] = [self.get_y(db), db] - - # calculate sum curve - for point in curves: - for label, filter_point in point[1].items(): - point[2] += filter_point[1] - #print(point) - - # draw filter curves - for label, filter in self.filters.items(): - if not filter.enabled: - continue - - cairo_ctx.set_source_color(filter.color) - cairo_ctx.move_to(curves[0][0], curves[0][1][label][0]) - for point in curves: - cairo_ctx.line_to(point[0], point[1][label][0]) - cairo_ctx.stroke() - - if self.master_enabled: - # draw sum curve - cairo_ctx.set_source_color(self.color_sum) - cairo_ctx.set_line_width(2); - cairo_ctx.move_to(curves[0][0], self.get_y(curves[0][2])) - for point in curves: - cairo_ctx.line_to(point[0], self.get_y(point[2])) - cairo_ctx.stroke() - - # draw base point markers - for label, filter in self.filters.items(): - if not filter.enabled: - continue - - cairo_ctx.set_source_color(self.color_value) - x = self.get_x(filter.adj_hz.value) - y = self.get_y(filter.adj_db.value) - - cairo_ctx.move_to(x, y) - cairo_ctx.show_text(label) - cairo_ctx.stroke() - - def add_filter(self, label, sample_rate, adj_hz, adj_db, adj_bw, color): - #print("filter %s added (%.2f Hz, %.2f dB, %.2f bw)" % (label, adj_hz.value, adj_db.value, adj_bw.value)) - filter = filter_band(sample_rate) - filter.enabled = False - filter.label = label - filter.color = color - filter.set_params(adj_hz.value, adj_bw.value, adj_db.value) - adj_hz.filter = filter - adj_db.filter = filter - adj_bw.filter = filter - filter.adj_hz = adj_hz - filter.adj_db = adj_db - filter.adj_bw = adj_bw - adj_hz.connect("value-changed", self.on_value_change_request) - adj_db.connect("value-changed", self.on_value_change_request) - adj_bw.connect("value-changed", self.on_value_change_request) - self.filters[label] = filter - - def enable_filter(self, label): - filter = self.filters[label] - #print("filter %s enabled (%.2f Hz, %.2f dB, %.2f bw)" % (label, filter.adj_hz.value, filter.adj_db.value, filter.adj_bw.value)) - filter.enabled = True - self.invalidate_all() - - def disable_filter(self, label): - filter = self.filters[label] - #print("filter %s disabled (%.2f Hz, %.2f dB, %.2f bw)" % (label, filter.adj_hz.value, filter.adj_db.value, filter.adj_bw.value)) - filter.enabled = False - self.invalidate_all() - - def on_value_change_request(self, adj): - #print("adj changed") - adj.filter.set_params(adj.filter.adj_hz.value, adj.filter.adj_bw.value, adj.filter.adj_db.value) - self.invalidate_all() - - def master_enable(self): - self.master_enabled = True; - self.invalidate_all() - - def master_disable(self): - self.master_enabled = False; - self.invalidate_all() - - def set_master_gain(self, gain): - self.master_gain = gain; - self.invalidate_all() - -class filter_ui: - def __init__(self, argv): - self.fake = len(argv) == 1 - - if self.fake: - self.shown = False - self.sample_rate = 48e3 - else: - self.sample_rate = float(argv[1]) - self.recv_pipe_fd = int(argv[2]) - self.send_pipe_fd = int(argv[3]) - - oldflags = fcntl.fcntl(self.recv_pipe_fd, fcntl.F_GETFL) - fcntl.fcntl(self.recv_pipe_fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) - - self.recv_pipe = os.fdopen(self.recv_pipe_fd, 'r') - self.send_pipe = os.fdopen(self.send_pipe_fd, 'w') - - self.port_base = 0 - #self.nekologo = gtk.gdk.pixbuf_new_from_file(os.path.join(sys.path[0], "nekofilter", "lv2logo.png")) - - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - #self.window.set_size_request(600, 400) - self.window.set_title("NekoFilter (GUI)") - self.window.set_role("plugin_ui") - - self.top_vbox = gtk.VBox() - self.top_vbox.set_spacing(10) - - align = gtk.Alignment(0.5, 0.5, 1.0, 1.0) - align.set_padding(10, 10, 10, 10) - align.add(self.top_vbox) - - self.window.add(align) - - self.fr = frequency_response() - self.fr.set_size_request(400, 200) - - frame = gtk.Frame() - frame.set_shadow_type(gtk.SHADOW_ETCHED_OUT) - frame.add(self.fr) - - self.top_vbox.pack_start(frame, True, True) - - self.param_hbox = gtk.HBox() - self.top_vbox.pack_start(self.param_hbox) - - self.param_hbox.set_spacing(10) - - self.initator = False - - self.ports = [] - - misc_box = gtk.VBox() - misc_box.set_spacing(5) - - master_frame = gtk.Frame("Master") - master_frame.set_label_align(0.5, 0.5) - - master_box = gtk.VBox() - master_box.set_spacing(5) - - port = {'index': 0, 'name': 'Active', 'type': 'toggle'} - self.ports.append(port) - self.add_param_box(master_box, self.create_toggle_box(port)) - - port = {'index': 1, 'name': 'Gain', 'type': 'knob', 'min': -20.0, 'max': 20.0, 'unit': 'dB', 'log': False} - self.ports.append(port) - self.add_param_box(master_box, self.create_knob_box(port)) - - master_frame.add(master_box) - misc_box.pack_start(master_frame, False, False) - - #logo = gtk.Image() - #logo.set_from_pixbuf(self.nekologo) - #misc_box.pack_start(logo, True, True) - - button_box = gtk.VBox() - - button = gtk.Button(stock=gtk.STOCK_ABOUT) - button.connect("clicked", self.on_about) - button_box.pack_start(button) - - button = gtk.Button(stock=gtk.STOCK_CLOSE) - button.connect("clicked", self.on_window_closed) - button_box.pack_start(button) - - align = gtk.Alignment(0.5, 1.0, 1.0, 0.0) - align.add(button_box) - misc_box.pack_start(align, True, True) - - band_parameters = [ - {'name': 'Active', 'type': 'toggle'}, - {'name': 'Frequency', 'type': 'knob', 'unit': 'Hz', 'log': True}, - {'name': 'Bandwidth', 'type': 'knob', 'min': 0.125, 'max': 8.0, 'unit': '', 'log': True}, - {'name': 'Gain', 'type': 'knob', 'min': -20.0, 'max': 20.0, 'unit': 'dB', 'log': False}] - - freq_min = [ 20.0, 40.0, 100.0, 200.0] - freq_max = [2000.0, 4000.0, 10000.0, 20000.0] - - port_index = 2 - - filter_colors = [gtk.gdk.Color(int(65535 * 1.0), int(65535 * 0.6), int(65535 * 0.0)), - gtk.gdk.Color(int(65535 * 0.6), int(65535 * 1.0), int(65535 * 0.6)), - gtk.gdk.Color(int(65535 * 0.0), int(65535 * 0.6), int(65535 * 1.0)), - gtk.gdk.Color(int(65535 * 0.9), int(65535 * 0.0), int(65535 * 0.5))] - - for i in [0, 1, 2, 3]: - band_frame = gtk.Frame("Band %d" % (i + 1)) - band_frame.set_label_align(0.5, 0.5) - - band_box = gtk.VBox() - band_box.set_spacing(5) - - for parameter in band_parameters: - - port = parameter.copy() - port['index'] = port_index - port_index += 1 - - if port['name'] == 'Frequency': - port['min'] = freq_min[i] - port['max'] = freq_max[i] - - self.ports.append(port) - - #param_box.set_spacing(5) - if port['type'] == 'knob': - self.add_param_box(band_box, self.create_knob_box(port)) - elif port['type'] == 'toggle': - self.add_param_box(band_box, self.create_toggle_box(port)) - - self.fr.add_filter( - str(i + 1), - self.sample_rate, - self.ports[port_index - 3]['adj'], # frequency - self.ports[port_index - 1]['adj'], # gain - self.ports[port_index - 2]['adj'], # bandwidth - filter_colors[i]) - - band_frame.add(band_box) - - self.param_hbox.pack_start(band_frame, True, True) - - self.param_hbox.pack_start(misc_box, True, True) - - self.initator = True - - def on_about(self, widget): - about = gtk.AboutDialog() - about.set_transient_for(self.window) - about.set_name("4-band parametric filter") - #about.set_website(program_data['website']) - about.set_authors(["Filipe Coelho - Carla port", - "Nedko Arnaudov - Original LV2 plugin and GUI", - "Fons Adriaensen - DSP code"]) - #about.set_artists(["LV2 logo has been designed by Thorsten Wilms, based on a concept from Peter Shorthose."]) - #about.set_logo(self.nekologo) - about.show() - about.run() - about.hide() - - def create_knob_box(self, port): - param_box = gtk.VBox() - step = (port['max'] - port['min']) / 100 - adj = SmartAdjustment(port['log'], port['min'], port['min'], port['max'], step, step * 20) - adj.port = port - port['adj'] = adj - - adj.connect("value-changed", self.on_adj_value_changed) - - knob = Knob() - knob.set_adjustment(adj) - align = gtk.Alignment(0.5, 0.5, 0, 0) - align.set_padding(0, 0, 20, 20) - align.add(knob) - param_box.pack_start(align, False) - - adj.label = gtk.Label(self.get_adj_value_text(adj)[0]) - param_box.pack_start(adj.label, False) - #spin = gtk.SpinButton(adj, 0.0, 2) - #param_box.pack_start(spin, False) - - label = gtk.Label(port['name']) - param_box.pack_start(label, False) - return param_box - - def create_toggle_box(self, port): - param_box = gtk.VBox() - button = gtk.CheckButton(port['name']) - button.port = port - port['widget'] = button - - button.connect("toggled", self.on_button_toggled) - - align = gtk.Alignment(0.5, 0.5, 0, 0) - align.add(button) - param_box.pack_start(align, False) - return param_box - - def add_param_box(self, container, param_box): - align = gtk.Alignment(0.5, 0.5, 1.0, 1.0) - align.set_padding(10, 10, 10, 10) - align.add(param_box) - - container.pack_start(align, True) - - def get_adj_value_text(self, adj): - value = adj.get_value() - if value >= 10000: - format = "%.0f" - elif value >= 1000: - format = "%.1f" - else: - format = "%.2f" - text = format % value - unit = adj.port['unit'] - if unit: - text += " " + unit - - return value, text - - def on_adj_value_changed(self, adj): - value, text = self.get_adj_value_text(adj) - adj.label.set_text(text) - - if adj.port['index'] == 1: - #print("Master gain = %.2f dB" % adj.get_value()) - self.fr.set_master_gain(adj.get_value()) - - if self.initator: - #print(adj.port, adj.get_value()) - self.send_port_value(adj.port['index'] + self.port_base, value) - - def on_button_toggled(self, widget): - port_index = widget.port['index'] - band_no = (port_index - 2) / 4 + 1 - if widget.get_active(): - value = 1.0 - if band_no > 0: - self.fr.enable_filter(str(band_no)) - else: - self.fr.master_enable() - else: - value = 0.0 - if band_no > 0: - self.fr.disable_filter(str(band_no)) - else: - self.fr.master_disable() - - if self.initator: - self.send_port_value(port_index + self.port_base, value) - - def send(self, lines): - if self.fake: - return - - for line in lines: - #print('send: "' + line + '"') - self.send_pipe.write(line + "\n") - self.send_pipe.flush() - - def send_close(self): - self.send(["close"]) - - def send_exiting(self): - self.send(["exiting"]) - - def send_port_value(self, port_index, value): - self.send(["port_value", str(port_index), "%.10f" % value]) - - def send_hi(self): - self.send([""]) # send empty line (just newline char) - - def recv_line(self): - return self.recv_pipe.readline().strip() - - def recv_command(self): - try: - msg = self.recv_line() - - if msg == "port_value": - port_index = int(self.recv_line()) - port_value = float(self.recv_line()) - #print("port_value_change recevied: %d %f" % (port_index, port_value)) - self.on_port_value_changed(port_index, port_value) - elif msg == "show": - self.on_show() - elif msg == "hide": - self.on_hide() - elif msg == "quit": - self.on_quit() - else: - print("unknown message: \"" + msg + "\"") - - return True - except IOError: - return False - - def on_recv(self, fd, cond): - #print("on_recv") - if cond == gobject.IO_HUP: - gtk.main_quit() - return False - - while True: - if not self.recv_command(): - break - - return True - - def run(self): - self.window.connect("destroy", self.on_window_closed) - - if self.fake: - if not self.shown: - self.shown = True - self.on_show() - else: - self.send_hi() - gobject.io_add_watch(self.recv_pipe_fd, gobject.IO_IN | gobject.IO_HUP, self.on_recv) - - gtk.main() - - def on_port_value_changed(self, port_index, port_value): - #print("port %d set to %f" % (port_index, port_value)) - port_index -= self.port_base - port = self.ports[port_index] - #print(repr(port)) - port_type = port['type'] - if port_type == 'knob': - self.initator = False - port['adj'].set_value(port_value) - self.initator = True - elif port_type == 'toggle': - if port_value > 0.0: - toggled = True - else: - toggled = False - - self.initator = False - port['widget'].set_active(toggled) - self.initator = True - - def on_show(self): - self.window.show_all() - - def on_hide(self): - self.window.hide_all() - - def on_quit(self): - gtk.main_quit() - - def on_window_closed(self, arg): - self.window.hide_all() - self.send_close() - #self.send_exiting() - - if self.fake: - gtk.main_quit() - -def main(): - filter_ui(sys.argv).run() - #print("main done") - -if __name__ == '__main__': - main() diff --git a/source/native-plugins/resources/nekofilter/lv2logo.png b/source/native-plugins/resources/nekofilter/lv2logo.png deleted file mode 100644 index fc2a1e1e8..000000000 Binary files a/source/native-plugins/resources/nekofilter/lv2logo.png and /dev/null differ diff --git a/source/native-plugins/zita-at1-ui.cpp b/source/native-plugins/zita-at1-ui.cpp index 4f521e101..b0b9ac916 100644 --- a/source/native-plugins/zita-at1-ui.cpp +++ b/source/native-plugins/zita-at1-ui.cpp @@ -208,6 +208,9 @@ int main(int argc, const char* argv[]) handler->next_event(); XFlush(display->dpy()); + if (argc == 1) + mainwin->x_map(); + do { ev = mainwin->process(); diff --git a/source/native-plugins/zita-bls1-ui.cpp b/source/native-plugins/zita-bls1-ui.cpp index eab63a57d..18ffb0dc8 100644 --- a/source/native-plugins/zita-bls1-ui.cpp +++ b/source/native-plugins/zita-bls1-ui.cpp @@ -163,6 +163,9 @@ int main(int argc, const char* argv[]) handler->next_event(); XFlush(display->dpy()); + if (argc == 1) + mainwin->x_map(); + do { ev = mainwin->process(); diff --git a/source/native-plugins/zita-rev1-ui.cpp b/source/native-plugins/zita-rev1-ui.cpp index cb476f2f8..6b42dd98a 100644 --- a/source/native-plugins/zita-rev1-ui.cpp +++ b/source/native-plugins/zita-rev1-ui.cpp @@ -171,6 +171,9 @@ int main(int argc, const char* argv[]) handler->next_event(); XFlush(display->dpy()); + if (argc == 1) + mainwin->x_map(); + do { ev = mainwin->process();