diff -Nru x42-plugins-20170428/balance.lv2/balance.ttl.in x42-plugins-20190714/balance.lv2/balance.ttl.in --- x42-plugins-20170428/balance.lv2/balance.ttl.in 2016-08-23 12:15:04.000000000 +0000 +++ x42-plugins-20190714/balance.lv2/balance.ttl.in 2019-01-23 22:16:51.000000000 +0000 @@ -48,7 +48,7 @@ lv2:default 0 ; lv2:minimum 0 ; lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; + lv2:portProperty lv2:toggled; ] , [ a lv2:InputPort , lv2:ControlPort ; @@ -58,7 +58,7 @@ lv2:default 0 ; lv2:minimum 0 ; lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; + lv2:portProperty lv2:toggled; ] , [ a lv2:InputPort , lv2:ControlPort ; Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/balance.lv2/img/x42-balance.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/balance.lv2/img/x42-balance.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/balance.lv2/img/x42-balance.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/balance.lv2/img/x42-balance.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/balance.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/balance.lv2/img/x42.ico differ diff -Nru x42-plugins-20170428/balance.lv2/Makefile x42-plugins-20190714/balance.lv2/Makefile --- x42-plugins-20170428/balance.lv2/Makefile 2016-08-23 12:15:04.000000000 +0000 +++ x42-plugins-20190714/balance.lv2/Makefile 2019-01-23 22:16:51.000000000 +0000 @@ -4,11 +4,11 @@ # make CXXFLAGS=-O2 # make install DESTDIR=$(CURDIR)/debian/balance_lv2 PREFIX=/usr # -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CXXFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS=-s UISTRIPFLAGS=-s @@ -16,7 +16,7 @@ balance_VERSION?=$(shell git describe --tags HEAD 2>/dev/null | sed 's/-g.*$$//;s/^v//' || echo "LV2") ############################################################################### -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm LV2NAME=balance LV2GUI=balanceUI @@ -24,9 +24,12 @@ BUILDDIR=build/ targets= -override CXXFLAGS+=-fPIC TX=textures/ +ifeq ($(XWIN),) + override CXXFLAGS += -fPIC -fvisibility=hidden +endif + IS_OSX= PKG_GL_LIBS= UNAME=$(shell uname) @@ -62,10 +65,10 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") else - override CXXFLAGS+=`pkg-config --cflags lv2` + override CXXFLAGS+=`$(PKG_CONFIG) --cflags lv2` endif # optional UI @@ -95,18 +98,18 @@ endif endif -HAVE_UI=$(shell pkg-config --exists $(PKG_GL_LIBS) ftgl && echo $(FONT_FOUND)) +HAVE_UI=$(shell $(PKG_CONFIG) --exists $(PKG_GL_LIBS) ftgl && echo $(FONT_FOUND)) LV2UIREQ= # check for LV2 idle thread -- requires 'lv2', atleast_version='1.4.6 -ifeq ($(shell pkg-config --atleast-version=1.4.6 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.4.6 lv2 || echo no), no) UICFLAGS+=-DOLD_SUIL else LV2UIREQ=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CXXFLAGS += -DHAVE_LV2_1_8 endif @@ -120,34 +123,34 @@ UIDEPS+=pugl/pugl_osx.m UILIBS=pugl/pugl_osx.m -framework Cocoa -framework OpenGL UI_TYPE=CocoaUI - UILIBS+=`pkg-config --variable=libdir ftgl`/libftgl.a `pkg-config --variable=libdir ftgl`/libfreetype.a -lm -mmacosx-version-min=10.5 - UILIBS+=`pkg-config --libs zlib` + UILIBS+=`$(PKG_CONFIG) --variable=libdir ftgl`/libftgl.a `$(PKG_CONFIG) --variable=libdir ftgl`/libfreetype.a -lm -mmacosx-version-min=10.5 + UILIBS+=`$(PKG_CONFIG) --libs zlib` else ifneq ($(XWIN),) UIDEPS+=pugl/pugl_win.cpp UICFLAGS+=-DPTW32_STATIC_LIB UILIBS=pugl/pugl_win.cpp - UILIBS+=`pkg-config --variable=libdir ftgl`/libftgl.a `pkg-config --variable=libdir ftgl`/libfreetype.a - UILIBS+=`pkg-config --libs zlib` + UILIBS+=`$(PKG_CONFIG) --variable=libdir ftgl`/libftgl.a `$(PKG_CONFIG) --variable=libdir ftgl`/libfreetype.a + UILIBS+=`$(PKG_CONFIG) --libs zlib` UILIBS+=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread UI_TYPE=WindowsUI else UIDEPS+=pugl/pugl_x11.c - UICFLAGS+=`pkg-config --cflags glu gl` + UICFLAGS+=`$(PKG_CONFIG) --cflags glu gl` UILIBS=pugl/pugl_x11.c -lX11 UI_TYPE=X11UI ifeq ($(STATICBUILD), yes) - UILIBS+=`pkg-config --libs glu` - UILIBS+=`pkg-config --variable=libdir ftgl`/libftgl.a `pkg-config --variable=libdir ftgl`/libfreetype.a - UILIBS+=`pkg-config --libs zlib` + UILIBS+=`$(PKG_CONFIG) --libs glu` + UILIBS+=`$(PKG_CONFIG) --variable=libdir ftgl`/libftgl.a `$(PKG_CONFIG) --variable=libdir ftgl`/libfreetype.a + UILIBS+=`$(PKG_CONFIG) --libs zlib` else - UILIBS+=`pkg-config --libs glu ftgl` + UILIBS+=`$(PKG_CONFIG) --libs glu ftgl` endif UICFLAGS+=-DFONTFILE=\"$(FONTFILE)\" endif endif - UILIBS+=`pkg-config --libs ftgl` - UICFLAGS+=`pkg-config --cflags freetype2` `pkg-config --cflags ftgl` -DHAVE_FTGL -DUINQHACK=Blc + UILIBS+=`$(PKG_CONFIG) --libs ftgl` + UICFLAGS+=`$(PKG_CONFIG) --cflags freetype2` `$(PKG_CONFIG) --cflags ftgl` -DHAVE_FTGL -DUINQHACK=Blc UICFLAGS+=-DFONTSIZE=$(FONTSIZE) targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) diff -Nru x42-plugins-20170428/controlfilter.lv2/filters/exp.c x42-plugins-20190714/controlfilter.lv2/filters/exp.c --- x42-plugins-20170428/controlfilter.lv2/filters/exp.c 2016-06-19 12:12:28.000000000 +0000 +++ x42-plugins-20190714/controlfilter.lv2/filters/exp.c 2019-05-07 14:57:14.000000000 +0000 @@ -3,7 +3,7 @@ #ifdef CSC_TTF controlfilter:CSC_NAME - TTL_DEFAULTDEF("Control Port Exponental") + TTL_DEFAULTDEF("Control Port Exponential") , TTL_IPORTFLOAT(0, "base", "base", -10, 10, 2.718281828) ; rdfs:comment "Control Parameter Exponential out = base ^ in" . diff -Nru x42-plugins-20170428/controlfilter.lv2/filters/invert.c x42-plugins-20190714/controlfilter.lv2/filters/invert.c --- x42-plugins-20170428/controlfilter.lv2/filters/invert.c 2016-06-19 12:12:28.000000000 +0000 +++ x42-plugins-20190714/controlfilter.lv2/filters/invert.c 2019-05-07 14:57:14.000000000 +0000 @@ -3,7 +3,7 @@ #ifdef CSC_TTF controlfilter:CSC_NAME - TTL_DEFAULTDEF("Control Linear Scale") + TTL_DEFAULTDEF("Control Invert") ; rdfs:comment "Control Parameter Inverter out = 1 / in" . diff -Nru x42-plugins-20170428/controlfilter.lv2/Makefile x42-plugins-20190714/controlfilter.lv2/Makefile --- x42-plugins-20170428/controlfilter.lv2/Makefile 2016-06-19 12:12:28.000000000 +0000 +++ x42-plugins-20190714/controlfilter.lv2/Makefile 2019-05-07 14:57:14.000000000 +0000 @@ -4,6 +4,7 @@ PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s @@ -47,12 +48,14 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +ifeq ($(XWIN),) +override CFLAGS += -fPIC -fvisibility=hidden +endif +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` -DVERSION="\"$(controlfilter_VERSION)\"" ############################################################################### # build target definitions diff -Nru x42-plugins-20170428/controlfilter.lv2/src/controlfilter.c x42-plugins-20190714/controlfilter.lv2/src/controlfilter.c --- x42-plugins-20170428/controlfilter.lv2/src/controlfilter.c 2016-06-19 12:12:28.000000000 +0000 +++ x42-plugins-20190714/controlfilter.lv2/src/controlfilter.c 2019-05-07 14:57:14.000000000 +0000 @@ -135,7 +135,7 @@ free(instance); } -const void* +static const void* extension_data(const char* uri) { return NULL; diff -Nru x42-plugins-20170428/controlfilter.lv2/src/ttl.h x42-plugins-20190714/controlfilter.lv2/src/ttl.h --- x42-plugins-20170428/controlfilter.lv2/src/ttl.h 2016-06-19 12:12:28.000000000 +0000 +++ x42-plugins-20190714/controlfilter.lv2/src/ttl.h 2019-05-07 14:57:14.000000000 +0000 @@ -28,7 +28,7 @@ lv2:ControlPort ; \ lv2:index 0 ; \ lv2:symbol "in" ; \ - lv2:name "Control Input" \ + lv2:name "Control Input"; \ lv2:default 0.0 ; \ lv2:minimum -1.0 ; \ lv2:maximum 1.0 ; \ diff -Nru x42-plugins-20170428/convoLV2/convolution.cc x42-plugins-20190714/convoLV2/convolution.cc --- x42-plugins-20170428/convoLV2/convolution.cc 2016-09-18 17:36:23.000000000 +0000 +++ x42-plugins-20190714/convoLV2/convolution.cc 2019-05-04 23:26:24.000000000 +0000 @@ -47,8 +47,8 @@ #include #include "convolution.h" -#if ZITA_CONVOLVER_MAJOR_VERSION != 3 -# error "This programs requires zita-convolver 3.x.x" +#if ZITA_CONVOLVER_MAJOR_VERSION != 3 && ZITA_CONVOLVER_MAJOR_VERSION != 4 +# error "This programs requires zita-convolver 3 or 4" #endif #ifndef SRC_QUALITY // alternatives: SRC_SINC_FASTEST, SRC_SINC_MEDIUM_QUALITY, (SRC_ZERO_ORDER_HOLD, SRC_LINEAR) @@ -156,6 +156,7 @@ if (n_sp) *n_sp = (unsigned int) src_data.output_frames_gen; free(rdb); + src_delete (src_state); } } @@ -319,11 +320,6 @@ clv->fragment_size = buffersize; - if (zita_convolver_major_version () != ZITA_CONVOLVER_MAJOR_VERSION) { - fprintf (stderr, "convoLV2: Zita-convolver version does not match.\n"); - return -1; - } - if (clv->convproc) { fprintf (stderr, "convoLV2: already initialized.\n"); return (-1); @@ -343,7 +339,9 @@ clv->convproc = new Convproc; clv->convproc->set_options (options); +#if ZITA_CONVOLVER_MAJOR_VERSION == 3 clv->convproc->set_density (clv->density); +#endif if (audiofile_read (clv->ir_fn, sample_rate, &p, &n_chan, &n_frames)) { fprintf(stderr, "convoLV2: failed to read IR.\n"); @@ -378,6 +376,9 @@ /*quantum*/ buffersize, /*min-part*/ buffersize /* must be >= fragm */, /*max-part*/ buffersize /* Convproc::MAXPART -> stich output every period */ +#if ZITA_CONVOLVER_MAJOR_VERSION == 4 + , clv->density +#endif )) { fprintf (stderr, "convoLV2: Cannot initialize convolution engine.\n"); goto errout; Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/convoLV2/img/x42-convolv.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/convoLV2/img/x42-convolv.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/convoLV2/img/x42-convolv.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/convoLV2/img/x42-convolv.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/convoLV2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/convoLV2/img/x42.ico differ diff -Nru x42-plugins-20170428/convoLV2/lv2.c x42-plugins-20190714/convoLV2/lv2.c --- x42-plugins-20170428/convoLV2/lv2.c 2016-09-18 17:36:23.000000000 +0000 +++ x42-plugins-20190714/convoLV2/lv2.c 2019-05-04 23:26:24.000000000 +0000 @@ -460,7 +460,9 @@ } } - if (map_path) { + if (!map_path) { + return LV2_STATE_ERR_NO_FEATURE; + } else { char fn[1024]; // PATH_MAX if (clv_query_setting(self->clv_online, "convolution.ir.file", fn, 1024) > 0 ) { char* apath = map_path->abstract_path(map_path->handle, fn); @@ -468,7 +470,9 @@ apath, strlen(apath) + 1, self->uris.atom_Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); +#ifndef _WIN32 // https://github.com/drobilla/lilv/issues/14 free(apath); +#endif } } return LV2_STATE_SUCCESS; @@ -490,11 +494,18 @@ support), but fall back to instantiate() schedules (spec-violating workaround for broken hosts). */ LV2_Worker_Schedule* schedule = self->schedule; + LV2_State_Map_Path* map_path = NULL; for (int i = 0; features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_WORKER__schedule)) { DEBUG_printf("State: using thread-safe restore scheduler\n"); schedule = (LV2_Worker_Schedule*)features[i]->data; } + if (!strcmp(features[i]->URI, LV2_STATE__mapPath)) { + map_path = (LV2_State_Map_Path*)features[i]->data; + } + } + if (!map_path) { + return LV2_STATE_ERR_NO_FEATURE; } if (schedule == self->schedule) { DEBUG_printf("State: warning: using run() scheduler to restore\n"); @@ -545,10 +556,14 @@ value = retrieve(handle, self->uris.clv2_impulse, &size, &type, &valflags); + if (value) { - const char* path = (const char*)value; + char* path = map_path->absolute_path (map_path->handle, (const char*) value); DEBUG_printf("PTH: convolution.ir.file=%s\n", path); clv_configure(self->clv_offline, "convolution.ir.file", path); +#ifndef _WIN32 // https://github.com/drobilla/lilv/issues/14 + free (path); +#endif } else { ok = false; } diff -Nru x42-plugins-20170428/convoLV2/lv2ttl/convoLV2.ttl.in x42-plugins-20190714/convoLV2/lv2ttl/convoLV2.ttl.in --- x42-plugins-20170428/convoLV2/lv2ttl/convoLV2.ttl.in 2016-09-18 17:36:23.000000000 +0000 +++ x42-plugins-20190714/convoLV2/lv2ttl/convoLV2.ttl.in 2019-05-04 23:26:24.000000000 +0000 @@ -4,6 +4,7 @@ @prefix doap: . @prefix foaf: . @prefix lv2: . +@prefix opts: . @prefix patch: . @prefix pg: . @prefix rdfs: . @@ -36,8 +37,7 @@ lv2:microVersion 0 ; lv2:minorVersion 4 ; lv2:project ; - lv2:requiredFeature urid:map , - work:schedule ; + lv2:requiredFeature bufsz:boundedBlockLength, urid:map, opts:options, work:schedule; bufsz:minBlockLength 64 ; bufsz:maxBlockLength 8192 ; lv2:extensionData work:interface , @@ -96,11 +96,12 @@ lv2:microVersion 0 ; lv2:minorVersion 4 ; lv2:project ; - lv2:requiredFeature urid:map , - work:schedule ; + lv2:requiredFeature bufsz:boundedBlockLength, urid:map, opts:options, work:schedule; + bufsz:minBlockLength 64 ; + bufsz:maxBlockLength 8192 ; lv2:extensionData work:interface , state:interface ; - lv2:optionalFeature lv2:hardRTCapable ; + lv2:optionalFeature lv2:hardRTCapable, state:threadSafeRestore, bufsz:coarseBlockLength; @CLV2UI@ patch:writable clv2:impulse ; lv2:port [ @@ -170,11 +171,12 @@ lv2:microVersion 0 ; lv2:minorVersion 4 ; lv2:project ; - lv2:requiredFeature urid:map , - work:schedule ; + lv2:requiredFeature bufsz:boundedBlockLength, urid:map, opts:options, work:schedule; + bufsz:minBlockLength 64 ; + bufsz:maxBlockLength 8192 ; lv2:extensionData work:interface , state:interface ; - lv2:optionalFeature lv2:hardRTCapable ; + lv2:optionalFeature lv2:hardRTCapable, state:threadSafeRestore, bufsz:coarseBlockLength; @CLV2UI@ patch:writable clv2:impulse ; lv2:port [ diff -Nru x42-plugins-20170428/convoLV2/Makefile x42-plugins-20190714/convoLV2/Makefile --- x42-plugins-20170428/convoLV2/Makefile 2016-09-18 17:36:23.000000000 +0000 +++ x42-plugins-20190714/convoLV2/Makefile 2019-05-04 23:26:24.000000000 +0000 @@ -4,56 +4,70 @@ # make CXXFLAGS=-O2 # make install DESTDIR=$(CURDIR)/debian/convoLV2 PREFIX=/usr # -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only PREFIX ?= /usr/local +LV2DIR ?= $(PREFIX)/lib/lv2 + +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CXXFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib + +PKG_CONFIG?=pkg-config +STRIP ?= strip + BUILDGTK ?= no ############################################################################### BUILDDIR=build/ -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 LV2NAME=convoLV2 LV2GUI=convoLV2UI BUNDLE=convo.lv2 +targets= + UNAME=$(shell uname) ifeq ($(UNAME),Darwin) LV2LDFLAGS=-dynamiclib LIB_EXT=.dylib + STRIPFLAGS=-u -r -arch all -s lv2syms + UISTRIPFLAGS=-u -r -arch all -s lv2uisyms + targets+=lv2syms lv2uisyms else LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic LIB_EXT=.so + STRIPFLAGS=-s + UISTRIPFLAGS=-s endif ifneq ($(XWIN),) CC=$(XWIN)-gcc CXX=$(XWIN)-g++ + STRIP=$(XWIN)-strip LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed -lpthread LIB_EXT=.dll BUILDGTK=no override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CXXFLAGS += -fPIC -fvisibility=hidden endif # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --atleast-version=1.4 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.4 lv2 || echo no), no) $(error "LV2 SDK needs to be version 1.4 or later") endif -ifneq ($(shell pkg-config --exists sndfile samplerate\ +ifneq ($(shell $(PKG_CONFIG) --exists sndfile samplerate\ && echo yes), yes) $(error "libsndfile and libsamplerate are required") endif CLV2UI= ifneq ($(BUILDGTK), no) - ifeq ($(shell pkg-config --exists glib-2.0 gtk+-2.0 || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists glib-2.0 gtk+-2.0 || echo no), no) $(warning "The optional plugin GUI requires glib-2.0 and gtk+-2.0") $(warning "call make BUILDGTK=no to disable the GUI.") $(error "Aborting build.") @@ -63,26 +77,25 @@ ifeq ($(LIBZITACONVOLVER),) ifeq ($(shell test -f /usr/include/zita-convolver.h -o -f /usr/local/include/zita-convolver.h || echo no ), no) - $(error "libzita-convolver3, is required") + $(error "libzita-convolver3 or 4, is required") endif LOADLIBES += -lzita-convolver endif # add library dependent flags and libs -override CXXFLAGS +=-fPIC -override CXXFLAGS +=`pkg-config --cflags glib-2.0 lv2 sndfile samplerate` -override LOADLIBES +=`pkg-config --libs sndfile samplerate` -lm +override CXXFLAGS +=`$(PKG_CONFIG) --cflags glib-2.0 lv2 sndfile samplerate` +override LOADLIBES +=`$(PKG_CONFIG) --libs sndfile samplerate` -lm -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CXXFLAGS += -DHAVE_LV2_1_8 endif -GTKCFLAGS = `pkg-config --cflags gtk+-2.0` -GTKLIBS = `pkg-config --libs gtk+-2.0` +GTKCFLAGS = `$(PKG_CONFIG) --cflags gtk+-2.0` +GTKLIBS = `$(PKG_CONFIG) --libs gtk+-2.0` -targets= $(BUILDDIR)$(LV2NAME)$(LIB_EXT) +targets+= $(BUILDDIR)$(LV2NAME)$(LIB_EXT) ifneq ($(BUILDGTK), no) targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) @@ -94,6 +107,12 @@ all: $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets) +lv2syms: + echo "_lv2_descriptor" > lv2syms + +lv2uisyms: + echo "_lv2ui_descriptor" > lv2uisyms + $(BUILDDIR)manifest.ttl: lv2ttl/manifest.ttl.in lv2ttl/manifest.gui.ttl.in @mkdir -p $(BUILDDIR) sed "s/@LV2NAME@/$(LV2NAME)/;s/@LV2GUI@/$(LV2GUI)/;s/@LIB_EXT@/$(LIB_EXT)/" \ @@ -112,15 +131,18 @@ endif $(BUILDDIR)$(LV2NAME)$(LIB_EXT): lv2.c convolution.cc uris.h + @mkdir -p $(BUILDDIR) $(CXX) $(CPPFLAGS) $(CXXFLAGS) \ -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) lv2.c convolution.cc \ $(LIBZITACONVOLVER) \ -shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES) + $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(BUILDDIR)$(LV2GUI)$(LIB_EXT): ui.c uris.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(GTKCFLAGS) \ -o $(BUILDDIR)$(LV2GUI)$(LIB_EXT) ui.c \ -shared $(LV2LDFLAGS) $(LDFLAGS) $(GTKLIBS) + $(STRIP) $(UISTRIPFLAGS) $(BUILDDIR)$(LV2GUI)$(LIB_EXT) # install/uninstall/clean target definitions @@ -139,7 +161,8 @@ clean: rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl \ - $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(BUILDDIR)$(LV2GUI)$(LIB_EXT) + $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(BUILDDIR)$(LV2GUI)$(LIB_EXT) \ + lv2syms lv2uisyms rm -rf $(BUILDDIR)*.dSYM -test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true diff -Nru x42-plugins-20170428/convoLV2/README.md x42-plugins-20190714/convoLV2/README.md --- x42-plugins-20170428/convoLV2/README.md 2016-09-18 17:36:23.000000000 +0000 +++ x42-plugins-20190714/convoLV2/README.md 2019-05-04 23:26:24.000000000 +0000 @@ -18,7 +18,7 @@ convoLV2's main use-case is cabinet-emulation and generic signal processing where latency matters. -For fancy reverb applications, see also [IR.lv2](http://factorial.hu/plugins/lv2/ir). +For fancy reverb applications, see also [IR.lv2](https://tomszilagyi.github.io/plugins/ir.lv2/) Install ------- diff -Nru x42-plugins-20170428/darc.lv2/COPYING x42-plugins-20190714/darc.lv2/COPYING --- x42-plugins-20170428/darc.lv2/COPYING 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/COPYING 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff -Nru x42-plugins-20170428/darc.lv2/git2lv2.mk x42-plugins-20190714/darc.lv2/git2lv2.mk --- x42-plugins-20170428/darc.lv2/git2lv2.mk 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/git2lv2.mk 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,43 @@ + +############################################################################### +# extract versions +GIT_REV_REGEXP="([0-9][0-9]*)\.([0-9][0-9]*)(\.([0-9][0-9]*))?(-([0-9][0-9]*))?(-g([a-f0-9]+))?" + +override MAJOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\1/) +override MINOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\2/) +override MICRO=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\4/) +override GITREV=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\6/) + +ifeq ($(MAJOR),) + override MAJOR=0 +endif +ifeq ($(MINOR),) + override MINOR=0 +endif +ifeq ($(MICRO),) + override MICRO=0 +endif + +$(info Version: $(LV2VERSION) -> $(MAJOR) $(MINOR) $(MICRO) $(GITREV)) + +# version requirements, see +# http://lv2plug.in/ns/lv2core/#minorVersion +# http://lv2plug.in/ns/lv2core/#microVersion +ifeq ($(GITREV),) +# even numbers for tagged releases + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 ) + override LV2MIC = 0 +else +# odd-numbers for all non tagged git versions + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 + 1 ) + override LV2MIC = $(shell expr $(GITREV) \* 2 + 1) +endif + +ifeq ($(LV2MIN),) + $(error "Cannot extract required LV2 minor-version parameter") +endif +ifeq ($(LV2MIC),) + $(error "Cannot extract required LV2 micro-version parameter") +endif + +$(info LV2 Version: $(LV2MIN) $(LV2MIC)) diff -Nru x42-plugins-20170428/darc.lv2/gui/darc.c x42-plugins-20190714/darc.lv2/gui/darc.c --- x42-plugins-20170428/darc.lv2/gui/darc.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/gui/darc.c 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,1327 @@ +/* robtk dyncomp gui + * + * Copyright 2019 Robin Gareus + * + * 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, 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/options/options.h" + +#include "../src/darc.h" + +#define RTK_URI DARC_URI +#define RTK_GUI "ui" + +#ifndef MAX +#define MAX(A, B) ((A) > (B)) ? (A) : (B) +#endif + +#ifndef MIN +#define MIN(A, B) ((A) < (B)) ? (A) : (B) +#endif + +typedef struct { + LV2UI_Write_Function write; + LV2UI_Controller controller; + LV2UI_Touch* touch; + + PangoFontDescription* font[2]; + + RobWidget* rw; // top-level container + RobWidget* ctbl; // control element table + + /* Level + reduction drawing area */ + RobWidget* m0; + int m0_width; + int m0_height; + + /* Gain Mapping */ + RobWidget* m1; + + /* current gain */ + float _gmin; + float _gmax; + float _rms; + + /* control knobs */ + RobTkDial* spn_ctrl[5]; + RobTkLbl* lbl_ctrl[5]; + RobTkCBtn* btn_hold; + + cairo_surface_t* dial_bg[5]; + + /* gain meter */ + cairo_pattern_t* m_fg; + cairo_pattern_t* m_bg; + cairo_surface_t* m0bg; + + /* gain curve/mapping */ + cairo_surface_t* m1_grid; + cairo_surface_t* m1_ctrl; + cairo_surface_t* m1_mask; + + bool ctrl_dirty; // update m1_ctrl, m1_mask + + /* tooltips */ + int tt_id; + int tt_timeout; + cairo_rectangle_t* tt_pos; + cairo_rectangle_t* tt_box; + + bool disable_signals; + + RobWidget* m2; + const char* nfo; +} darcUI; + +/* **************************************************************************** + * Control knob ranges and value mapping + */ + +struct CtrlRange { + float min; + float max; + float dflt; + float step; + float mult; + bool log; + const char* name; +}; + +const struct CtrlRange ctrl_range[] = { + /* clang-format off */ + { -10, 30, 0, 0.2, 5, false, "Input Gain" }, + { -50, -10, -30, 0.1, 5, false, "Threshold" }, + { 0, 1, 0, 72, 2, true, "Ratio" }, + { .001, .1, 0.01, 100, 5, true, "Attack" }, + { .03, 3, 0.3, 100, 5, true, "Release" }, + /* clang-format on */ +}; + +static const char* tooltips[] = { + "Input Gain. Gain applied before level detection\nor any other processing.\n(not visualized as x-axis offset in curve)", + "Threshold. Signal level (RMS) at which\nthe compression effect is engaged.", + "Ratio. The amount of gain or attenuation to be\napplied (dB/dB above threshold).\nUnity is retained at -10dBFS/RMS\n(auto makeup-gain).", + "Attack time. Time it takes for the signal\nto become fully compressed after\nexceeding the threshold.", + "Release time. Minimum recovery time\nto uncompressed signal-level\nafter falling below threshold.", + "Hold. Retain current attenuation when the signal\nsubceeds the threshold.\nThis prevents modulation of the noise-floor\nand can counter-act 'pumping'.", +}; + +static float +ctrl_to_gui (const uint32_t c, const float v) +{ + if (!ctrl_range[c].log) { + return v; + } + if (ctrl_range[c].min == 0) { + return v * v * ctrl_range[c].step; + } + const float r = logf (ctrl_range[c].max / ctrl_range[c].min); + return rintf (ctrl_range[c].step / r * (logf (v / ctrl_range[c].min))); +} + +static float +gui_to_ctrl (const uint32_t c, const float v) +{ + if (!ctrl_range[c].log) { + return v; + } + if (ctrl_range[c].min == 0) { + return sqrt (v / ctrl_range[c].step); + } + const float r = log (ctrl_range[c].max / ctrl_range[c].min); + return expf (logf (ctrl_range[c].min) + v * r / ctrl_range[c].step); +} + +static float +k_min (const uint32_t c) +{ + if (!ctrl_range[c].log) { + return ctrl_range[c].min; + } + return 0; +} + +static float +k_max (const uint32_t c) +{ + if (!ctrl_range[c].log) { + return ctrl_range[c].max; + } + return ctrl_range[c].step; +} + +static float +k_step (const uint32_t c) +{ + if (!ctrl_range[c].log) { + return ctrl_range[c].step; + } + return 1; +} + +/* ****************************************************************************/ + +static const float c_dlf[4] = { 0.8, 0.8, 0.8, 1.0 }; // custom foreground color + +/* ***************************************************************************** + * Knob faceplates + */ + +static void +prepare_faceplates (darcUI* ui) +{ + cairo_t* cr; + float xlp, ylp; + +/* clang-format off */ +#define INIT_DIAL_SF(VAR, W, H) \ + VAR = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 2 * (W), 2 * (H)); \ + cr = cairo_create (VAR); \ + cairo_scale (cr, 2.0, 2.0); \ + CairoSetSouerceRGBA (c_trs); \ + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); \ + cairo_rectangle (cr, 0, 0, W, H); \ + cairo_fill (cr); \ + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + +#define DIALDOTS(V, XADD, YADD) \ + float ang = (-.75 * M_PI) + (1.5 * M_PI) * (V); \ + xlp = GED_CX + XADD + sinf (ang) * (GED_RADIUS + 3.0); \ + ylp = GED_CY + YADD - cosf (ang) * (GED_RADIUS + 3.0); \ + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); \ + CairoSetSouerceRGBA (c_dlf); \ + cairo_set_line_width (cr, 2.5); \ + cairo_move_to (cr, rint (xlp) - .5, rint (ylp) - .5); \ + cairo_close_path (cr); \ + cairo_stroke (cr); + +#define RESPLABLEL(V) \ + { \ + DIALDOTS (V, 4.5, 15.5) \ + xlp = rint (GED_CX + 4.5 + sinf (ang) * (GED_RADIUS + 9.5)); \ + ylp = rint (GED_CY + 15.5 - cosf (ang) * (GED_RADIUS + 9.5)); \ + } + /* clang-format on */ + + INIT_DIAL_SF (ui->dial_bg[0], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "-10", ui->font[0], xlp + 6, ylp, 0, 1, c_dlf); + RESPLABLEL (0.25); + RESPLABLEL (0.5); + write_text_full (cr, "+10", ui->font[0], xlp - 2, ylp, 0, 2, c_dlf); + RESPLABLEL (.75); + RESPLABLEL (1.0); + write_text_full (cr, "+30", ui->font[0], xlp - 6, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + + INIT_DIAL_SF (ui->dial_bg[1], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "-50", ui->font[0], xlp + 6, ylp, 0, 1, c_dlf); + RESPLABLEL (0.25); + RESPLABLEL (0.5); + write_text_full (cr, "-30", ui->font[0], xlp - 2, ylp, 0, 2, c_dlf); + RESPLABLEL (.75); + RESPLABLEL (1.0); + write_text_full (cr, "-10", ui->font[0], xlp - 6, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + + INIT_DIAL_SF (ui->dial_bg[2], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "1", ui->font[0], xlp + 4, ylp, 0, 1, c_dlf); + RESPLABLEL (.25); + write_text_full (cr, "2", ui->font[0], xlp + 3, ylp, 0, 1, c_dlf); + RESPLABLEL (.44); + write_text_full (cr, "3", ui->font[0], xlp + 1, ylp, 0, 1, c_dlf); + RESPLABLEL (.64) + write_text_full (cr, "5", ui->font[0], xlp + 4, ylp, 0, 1, c_dlf); + RESPLABLEL (.81) + write_text_full (cr, "10", ui->font[0], xlp + 6, ylp, 0, 1, c_dlf); + RESPLABLEL (1.0); + write_text_full (cr, "Lim", ui->font[0], xlp - 9, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + + INIT_DIAL_SF (ui->dial_bg[3], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "1ms", ui->font[0], xlp + 9, ylp, 0, 1, c_dlf); + RESPLABLEL (.16); + RESPLABLEL (.33); + write_text_full (cr, "5", ui->font[0], xlp - 1, ylp, 0, 2, c_dlf); + RESPLABLEL (0.5); + RESPLABLEL (.66); + write_text_full (cr, "20", ui->font[0], xlp + 3, ylp, 0, 2, c_dlf); + RESPLABLEL (.83); + RESPLABLEL (1.0); + write_text_full (cr, "100", ui->font[0], xlp - 9, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + + INIT_DIAL_SF (ui->dial_bg[4], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "30ms", ui->font[0], xlp + 9, ylp, 0, 1, c_dlf); + RESPLABLEL (.16); + RESPLABLEL (.33); + write_text_full (cr, "150", ui->font[0], xlp - 5, ylp, 0, 2, c_dlf); + RESPLABLEL (0.5); + RESPLABLEL (.66); + write_text_full (cr, "600", ui->font[0], xlp + 5, ylp, 0, 2, c_dlf); + RESPLABLEL (.83); + RESPLABLEL (1.0); + write_text_full (cr, "3s", ui->font[0], xlp - 6, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + +#undef DIALDOTS +#undef INIT_DIAL_SF +#undef RESPLABLEL +} + +/* ***************************************************************************** + * Numeric value display - knob tooltips + */ + +static void +display_annotation (darcUI* ui, RobTkDial* d, cairo_t* cr, const char* txt) +{ + int tw, th; + cairo_save (cr); + PangoLayout* pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, ui->font[0]); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_translate (cr, d->w_width / 2, d->w_height - 2); + cairo_translate (cr, -tw / 2.0, -th); + cairo_set_source_rgba (cr, .0, .0, .0, .7); + rounded_rectangle (cr, -1, -1, tw + 3, th + 1, 3); + cairo_fill (cr); + CairoSetSouerceRGBA (c_wht); + pango_cairo_show_layout (cr, pl); + g_object_unref (pl); + cairo_restore (cr); + cairo_new_path (cr); +} + +static void +dial_annotation_db (RobTkDial* d, cairo_t* cr, void* data) +{ + darcUI* ui = (darcUI*)(data); + char txt[16]; + snprintf (txt, 16, "%5.1f dB", d->cur); + display_annotation (ui, d, cr, txt); +} + +static void +format_msec (char* txt, const float val) +{ + if (val < 0.03) { + snprintf (txt, 16, "%.1f ms", val * 1000.f); + } else if (val < 0.3) { + snprintf (txt, 16, "%.0f ms", val * 1000.f); + } else { + snprintf (txt, 16, "%.2f s", val); + } +} + +static void +dial_annotation_tm (RobTkDial* d, cairo_t* cr, void* data) +{ + darcUI* ui = (darcUI*)(data); + char txt[16]; + assert (d == ui->spn_ctrl[3] || d == ui->spn_ctrl[4]); + const float val = gui_to_ctrl ((d == ui->spn_ctrl[3]) ? 3 : 4, d->cur); + format_msec (txt, val); + display_annotation (ui, d, cr, txt); +} + +static void +dial_annotation_rr (RobTkDial* d, cairo_t* cr, void* data) +{ + darcUI* ui = (darcUI*)(data); + char txt[16]; + const float val = gui_to_ctrl (2, d->cur); + if (val >= 1) { + snprintf (txt, 16, "\u221E : 1"); + } else if (val >= .9) { + snprintf (txt, 16, "%.0f : 1", 1 / (1.f - val)); + } else { + snprintf (txt, 16, "%.1f : 1", 1 / (1.f - val)); + } + display_annotation (ui, d, cr, txt); +} + +/* ***************************************************************************** + * knob & button callbacks + */ + +static bool +cb_spn_ctrl (RobWidget* w, void* handle) +{ + darcUI* ui = (darcUI*)handle; + if (w == ui->spn_ctrl[1]->rw || w == ui->spn_ctrl[2]->rw) { + ui->ctrl_dirty = true; + queue_draw (ui->m1); + } + + if (ui->disable_signals) { + return TRUE; + } + + for (uint32_t i = 0; i < 5; ++i) { + if (w != ui->spn_ctrl[i]->rw) { + continue; + } + const float val = gui_to_ctrl (i, robtk_dial_get_value (ui->spn_ctrl[i])); + ui->write (ui->controller, DARC_INPUTGAIN + i, sizeof (float), 0, (const void*)&val); + break; + } + return TRUE; +} + +static bool +cb_btn_hold (RobWidget* w, void* handle) +{ + darcUI* ui = (darcUI*)handle; + + ui->ctrl_dirty = true; + queue_draw (ui->m1); + + if (ui->disable_signals) { + return TRUE; + } + + const float val = robtk_cbtn_get_active (ui->btn_hold) ? 1.f : 0.f; + ui->write (ui->controller, DARC_HOLD, sizeof (float), 0, (const void*)&val); + return TRUE; +} + +/* ***************************************************************************** + * Tooltip & Help Overlay + */ + +static bool +tooltip_overlay (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) +{ + darcUI* ui = (darcUI*)rw->top; + assert (ui->tt_id >= 0 && ui->tt_id < 5); + + cairo_save (cr); + cairo_rectangle_t event = { 0, 0, rw->area.width, rw->area.height }; + rcontainer_clear_bg (rw, cr, &event); + rcontainer_expose_event (rw, cr, &event); + cairo_restore (cr); + + const float top = ui->tt_box->y; + rounded_rectangle (cr, 0, top, rw->area.width, ui->tt_pos->y - top, 3); + cairo_set_source_rgba (cr, 0, 0, 0, .7); + cairo_fill (cr); + + if (ui->tt_id < 4) { + rounded_rectangle (cr, ui->tt_pos->x, ui->tt_pos->y, + ui->tt_pos->width + 2, ui->tt_pos->height + 1, 3); + cairo_set_source_rgba (cr, 1, 1, 1, .5); + cairo_fill (cr); + } + + const float* color = c_wht; + PangoFontDescription* font = pango_font_description_from_string ("Sans 11px"); + + const float xp = .5 * rw->area.width; + const float yp = .5 * (ui->tt_pos->y - top); + + cairo_save (cr); + cairo_scale (cr, rw->widget_scale, rw->widget_scale); + write_text_full (cr, tooltips[ui->tt_id], font, + xp / rw->widget_scale, yp / rw->widget_scale, + 0, 2, color); + cairo_restore (cr); + + pango_font_description_free (font); + + return TRUE; +} + +static bool +tooltip_cnt (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) +{ + darcUI* ui = (darcUI*)rw->top; + if (++ui->tt_timeout < 12) { + rcontainer_expose_event (rw, cr, ev); + queue_draw (rw); + } else { + rw->expose_event = tooltip_overlay; + tooltip_overlay (rw, cr, ev); + } + return TRUE; +} + +static void +ttip_handler (RobWidget* rw, bool on, void* handle) +{ + darcUI* ui = (darcUI*)handle; + ui->tt_id = -1; + ui->tt_timeout = 0; + + for (int i = 0; i < 5; ++i) { + if (rw == ui->lbl_ctrl[i]->rw) { + ui->tt_id = i; + break; + } + } + if (rw == ui->btn_hold->rw) { + ui->tt_id = 4; + } + + if (on && ui->tt_id >= 0) { + ui->tt_pos = &rw->area; + ui->tt_box = &ui->spn_ctrl[0]->rw->area; + ui->ctbl->expose_event = tooltip_cnt; + queue_draw (ui->ctbl); + } else { + ui->ctbl->expose_event = rcontainer_expose_event; + ui->ctbl->parent->resized = TRUE; // full re-expose + queue_draw (ui->rw); + } +} + +/* ***************************************************************************** + * Gain Meter Display + */ + +#define M0HEIGHT 36 + +static void +m0_size_request (RobWidget* handle, int* w, int* h) +{ + darcUI* ui = (darcUI*)GET_HANDLE (handle); + + *w = 300; + *h = M0HEIGHT * ui->rw->widget_scale; +} + +static void +m0_size_allocate (RobWidget* handle, int w, int h) +{ + darcUI* ui = (darcUI*)GET_HANDLE (handle); + + h = M0HEIGHT * ui->rw->widget_scale; + + ui->m0_width = w; + ui->m0_height = h; + + robwidget_set_size (ui->m0, w, h); + + if (ui->m_fg) { + cairo_pattern_destroy (ui->m_fg); + } + if (ui->m_bg) { + cairo_pattern_destroy (ui->m_bg); + } + if (ui->m0bg) { + cairo_surface_destroy (ui->m0bg); + } + ui->m_fg = NULL; + ui->m_bg = NULL; + ui->m0bg = NULL; + + if (1) { + pango_font_description_free (ui->font[1]); + char fnt[32]; + snprintf (fnt, 32, "Mono %.0fpx\n", 10 * sqrtf (h / (float)M0HEIGHT)); + ui->font[1] = pango_font_description_from_string (fnt); + } + + queue_draw (ui->m0); +} + +static void +m0_render_faceplate (darcUI* ui, cairo_t* cr) +{ + const uint32_t yscale = ui->m0_height / M0HEIGHT; + const uint32_t top = (ui->m0_height - M0HEIGHT * yscale) * .5; + const uint32_t disp_w = ui->m0_width - 20; // deafult: 300 + +#define YPOS(y) (top + yscale * (y)) +#define HGHT(y) (yscale * (y)) + +#define DEF(x) MAX (0, MIN (1., ((20. + (x)) / 60.))) +#define DEFLECT(x) (rint (disp_w * DEF (x)) - .5) + + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + + CairoSetSouerceRGBA (c_blk); + rounded_rectangle (cr, 0, top, ui->m0_width, HGHT (M0HEIGHT), 6); + cairo_fill_preserve (cr); + cairo_clip (cr); + + /* meter background */ + cairo_set_source (cr, ui->m_bg); + cairo_rectangle (cr, 5, YPOS (4), disp_w + 10, HGHT (12)); + cairo_fill (cr); + + /* meter ticks */ + cairo_set_line_width (cr, yscale); + CairoSetSouerceRGBA (c_wht); + for (int i = 0; i < 7; ++i) { + float dbx = DEFLECT (-20 + i * 10); + cairo_move_to (cr, 10 + dbx, YPOS (2)); + cairo_line_to (cr, 10 + dbx, YPOS (18)); + cairo_stroke (cr); + + int tw, th; + PangoLayout* pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, ui->font[1]); + + if (i == 0) { + pango_layout_set_text (pl, "Gain:", -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, 5 + dbx, YPOS (20)); + pango_cairo_show_layout (cr, pl); + g_object_unref (pl); + continue; + } + char txt[16]; + snprintf (txt, 16, "%+2d ", (i - 2) * 10); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, 10 + dbx - tw * .5, YPOS (20)); + pango_cairo_show_layout (cr, pl); + g_object_unref (pl); + } +} + +static bool +m0_expose_event (RobWidget* handle, cairo_t* cr, cairo_rectangle_t* ev) +{ + darcUI* ui = (darcUI*)GET_HANDLE (handle); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); + cairo_clip_preserve (cr); + + float c[4]; + get_color_from_theme (1, c); + cairo_set_source_rgb (cr, c[0], c[1], c[2]); + cairo_fill (cr); + + const uint32_t yscale = ui->m0_height / M0HEIGHT; + const uint32_t top = (ui->m0_height - M0HEIGHT * yscale) * .5; + const uint32_t disp_w = ui->m0_width - 20; // deafult: 300 + +#define YPOS(y) (top + yscale * (y)) +#define HGHT(y) (yscale * (y)) + +#define DEF(x) MAX (0, MIN (1., ((20. + (x)) / 60.))) +#define DEFLECT(x) (rint (disp_w * DEF (x)) - .5) + + if (!ui->m_fg) { + cairo_pattern_t* pat = cairo_pattern_create_linear (10, 0.0, disp_w, 0.0); + /* clang-format off */ + cairo_pattern_add_color_stop_rgb (pat, DEF (40), .1, .9, .1); + cairo_pattern_add_color_stop_rgb (pat, DEF (5), .1, .9, .1); + cairo_pattern_add_color_stop_rgb (pat, DEF (-5), .9, .9, .1); + cairo_pattern_add_color_stop_rgb (pat, DEF (-20), .9, .9, .1); + /* clang-format on */ + ui->m_fg = pat; + } + + if (!ui->m_bg) { + const float alpha = 0.5; + cairo_pattern_t* pat = cairo_pattern_create_linear (10, 0.0, disp_w, 0.0); + /* clang-format off */ + cairo_pattern_add_color_stop_rgba (pat, DEF (40), .0, .5, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (5), .0, .5, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (-5), .5, .0, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (-20), .5, .0, .0, alpha); + /* clang-format on */ + ui->m_bg = pat; + } + + if (!ui->m0bg) { + ui->m0bg = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ui->m0_width, ui->m0_height); + cairo_t* icr = cairo_create (ui->m0bg); + m0_render_faceplate (ui, icr); + cairo_destroy (icr); + } + + cairo_set_source_surface (cr, ui->m0bg, 0, 0); + cairo_paint (cr); + + /* current reduction */ + float v0 = DEFLECT (ui->_gmin); + float v1 = DEFLECT (ui->_gmax); + cairo_rectangle (cr, 7.5 + v0, YPOS (4), 5 + v1 - v0, HGHT (12)); + cairo_set_source (cr, ui->m_fg); + cairo_fill (cr); + + return TRUE; +} + +/* ****************************************************************************/ + +static float +comp_curve (float in, float threshold, float ratio, bool hold) +{ + float key = in; + if (hold && in < threshold) { + key = threshold; + } +#ifdef __USE_GNU + float g = logf (exp10f (1.f + .1f * threshold) + exp10f (1.f + .1f * key)); +#else + float g = logf (powf (10.f, 1.f + .1f * threshold) + powf (10.f, 1.f + .1f * key)); +#endif + return /*-10/log(10)*/ -4.342944819f * ratio * g + in; +} + +/* ****************************************************************************/ + +#define M1RECT 350 + +static void +m1_size_request (RobWidget* handle, int* w, int* h) +{ + darcUI* ui = (darcUI*)GET_HANDLE (handle); + + *w = M1RECT * ui->rw->widget_scale; + *h = M1RECT * ui->rw->widget_scale; +} + +static void +m1_size_allocate (RobWidget* handle, int w, int h) +{ + darcUI* ui = (darcUI*)GET_HANDLE (handle); + + if (ui->m1_grid) { + cairo_surface_destroy (ui->m1_grid); + } + if (ui->m1_ctrl) { + cairo_surface_destroy (ui->m1_ctrl); + } + if (ui->m1_mask) { + cairo_surface_destroy (ui->m1_mask); + } + ui->m1_grid = NULL; + ui->m1_ctrl = NULL; + ui->m1_mask = NULL; + + queue_draw (ui->m1); +} + +static void +m1_render_grid (darcUI* ui, cairo_t* cr) +{ + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + + cairo_scale (cr, ui->rw->widget_scale, ui->rw->widget_scale); + + CairoSetSouerceRGBA (c_blk); + rounded_rectangle (cr, 0, 0, M1RECT, M1RECT, 8); + cairo_fill_preserve (cr); + cairo_clip (cr); + + /* draw grid 10dB steps */ + cairo_set_line_width (cr, 1.0); + + const double dash1[] = { 1, 2 }; + const double dash2[] = { 1, 3 }; + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_dash (cr, dash2, 2, 2); + + for (uint32_t d = 1; d < 7; ++d) { + const float x = -.5 + floor (M1RECT * d * 10.f / 70.f); + const float y = -.5 + floor (M1RECT * (70 - d * 10.f) / 70.f); + + cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.5); + + cairo_move_to (cr, x, 0); + cairo_line_to (cr, x, M1RECT); + cairo_stroke (cr); + + cairo_move_to (cr, 0, y); + cairo_line_to (cr, M1RECT, y); + cairo_stroke (cr); + + char txt[16]; + snprintf (txt, 16, "%+2d", -60 + d * 10); + write_text_full (cr, txt, ui->font[1], x, M1RECT * (10.f / 70.f) - 2, 0, 5, c_dlf); + if (d != 6) { + write_text_full (cr, txt, ui->font[1], M1RECT * (60.f / 70.f) + 2, y, M_PI * .5, 5, c_dlf); + } + } + + /* diagonal unity */ + cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 1.0); + cairo_set_dash (cr, dash1, 2, 2); + cairo_move_to (cr, 0, M1RECT); + cairo_line_to (cr, M1RECT, 0); + cairo_stroke (cr); + + cairo_set_dash (cr, 0, 0, 0); + + write_text_full (cr, "Output", ui->font[0], M1RECT * (65.f / 70.f), M1RECT * .5, M_PI * .5, 5, c_dlf); + write_text_full (cr, "Input [dBFS/RMS]", ui->font[0], M1RECT * .5, M1RECT * (5.f / 70.f), 0, 5, c_dlf); + + /* 0dBFS limit indicator */ + cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.5); + const float x = -.5 + floor (M1RECT * 60.f / 70.f); + const float y = -.5 + floor (M1RECT * 10.f / 70.f); + cairo_move_to (cr, x, 0); + cairo_line_to (cr, x, M1RECT); + cairo_stroke (cr); + cairo_move_to (cr, 0, y); + cairo_line_to (cr, M1RECT, y); + cairo_stroke (cr); +} + +static void +m1_render_mask (darcUI* ui) +{ + if (ui->m1_ctrl) { + cairo_surface_destroy (ui->m1_ctrl); + } + if (ui->m1_mask) { + cairo_surface_destroy (ui->m1_mask); + } + + int sq = M1RECT * ui->rw->widget_scale; + ui->m1_ctrl = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, sq, sq); + ui->m1_mask = cairo_image_surface_create (CAIRO_FORMAT_A8, M1RECT, M1RECT); + + cairo_t* cr = cairo_create (ui->m1_ctrl); + cairo_t* cm = cairo_create (ui->m1_mask); + + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_operator (cm, CAIRO_OPERATOR_CLEAR); + cairo_paint (cm); + cairo_set_operator (cm, CAIRO_OPERATOR_OVER); + + cairo_scale (cr, ui->rw->widget_scale, ui->rw->widget_scale); + + rounded_rectangle (cr, 0, 0, M1RECT, M1RECT, 8); + cairo_clip (cr); + + rounded_rectangle (cm, 0, 0, M1RECT, M1RECT, 8); + cairo_clip (cm); + + const float thrsh = gui_to_ctrl (1, robtk_dial_get_value (ui->spn_ctrl[1])); + const float ratio = gui_to_ctrl (2, robtk_dial_get_value (ui->spn_ctrl[2])); + const bool hold = robtk_cbtn_get_active (ui->btn_hold); + + cairo_set_source_rgba (cr, .8, .8, .8, 1.0); + cairo_set_line_width (cr, 1.0); + + if (hold) { + cairo_move_to (cr, 0, M1RECT * ((comp_curve (-60, thrsh, ratio, true) - 10) / -70.f)); + + uint32_t x = 1; + for (; x <= M1RECT; ++x) { + const float x_db = 70.f * (-1.f + x / (float)M1RECT) + 10.f; + const float y_db = comp_curve (x_db, thrsh, ratio, true) - 10; + const float y = M1RECT * (y_db / -70.f); + cairo_line_to (cr, x, y); + if (x_db > thrsh) { + break; + } + } + + const double dash1[] = { 1, 2, 4, 2 }; + cairo_set_dash (cr, dash1, 4, 0); + cairo_stroke_preserve (cr); + cairo_set_dash (cr, NULL, 0, 0); + + for (; x > 0; --x) { + const float x_db = 70.f * (-1.f + x / (float)M1RECT) + 10.f; + const float y_db = comp_curve (x_db, thrsh, ratio, false) - 10; + const float y = M1RECT * (y_db / -70.f); + cairo_line_to (cr, x, y); + } + + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 0, 0, .5, .5); + cairo_fill (cr); + } + + cairo_move_to (cr, 0, M1RECT * ((comp_curve (-60, thrsh, ratio, false) - 10) / -70.f)); + cairo_move_to (cm, 0, M1RECT * ((comp_curve (-60, thrsh, ratio, hold) - 10) / -70.f)); + + cairo_set_source_rgba (cr, .8, .8, .8, 1.0); + + for (uint32_t x = 1; x <= M1RECT; ++x) { + const float x_db = 70.f * (-1.f + x / (float)M1RECT) + 10.f; + const float y_db = comp_curve (x_db, thrsh, ratio, false) - 10; + const float h_db = comp_curve (x_db, thrsh, ratio, hold) - 10; + cairo_line_to (cr, x, M1RECT * (y_db / -70.f)); + cairo_line_to (cm, x, M1RECT * (h_db / -70.f)); + } + cairo_stroke_preserve (cr); + + cairo_line_to (cr, M1RECT, M1RECT); + cairo_line_to (cr, 0, M1RECT); + cairo_close_path (cr); + + cairo_line_to (cm, M1RECT, M1RECT); + cairo_line_to (cm, 0, M1RECT); + cairo_close_path (cm); + + cairo_set_source_rgba (cr, 1, 1, 1, .1); + cairo_fill (cr); + + cairo_set_source_rgba (cm, 1, 1, 1, 1); + cairo_fill (cm); + + cairo_destroy (cr); + cairo_destroy (cm); +} + +static bool +m1_expose_event (RobWidget* handle, cairo_t* cr, cairo_rectangle_t* ev) +{ + darcUI* ui = (darcUI*)GET_HANDLE (handle); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); + cairo_clip_preserve (cr); + + float c[4]; + get_color_from_theme (1, c); + cairo_set_source_rgb (cr, c[0], c[1], c[2]); + cairo_fill (cr); + + if (!ui->m1_grid) { + int sq = M1RECT * ui->rw->widget_scale; + ui->m1_grid = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, sq, sq); + cairo_t* icr = cairo_create (ui->m1_grid); + m1_render_grid (ui, icr); + cairo_destroy (icr); + } + + if (!ui->m1_ctrl || !ui->m1_mask || ui->ctrl_dirty) { + ui->ctrl_dirty = false; + m1_render_mask (ui); + } + + cairo_set_source_surface (cr, ui->m1_grid, 0, 0); + cairo_paint (cr); + + cairo_set_source_surface (cr, ui->m1_ctrl, 0, 0); + cairo_paint (cr); + + cairo_scale (cr, ui->rw->widget_scale, ui->rw->widget_scale); + + const float thrsh = gui_to_ctrl (1, robtk_dial_get_value (ui->spn_ctrl[1])); + const bool hold = robtk_cbtn_get_active (ui->btn_hold); + + float thx = (thrsh + 60.f) * M1RECT / 70.f; + if (hold) { + /* shade area where hold is active */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, thx, M1RECT); + cairo_clip (cr); + cairo_set_source_rgba (cr, 0.0, 0.0, .7, .1); + cairo_mask_surface (cr, ui->m1_mask, 0, 0); + cairo_fill (cr); + cairo_restore (cr); + } + + cairo_set_line_width (cr, 1); + cairo_move_to (cr, floor (thx) - .5, M1RECT * 9.f / 70.f); + cairo_line_to (cr, floor (thx) - .5, M1RECT); + cairo_set_source_rgba (cr, .8, .7, .1, .9); + const double dash1[] = { 1, 1 }; + cairo_set_dash (cr, dash1, 2, 0); + cairo_stroke (cr); + cairo_set_dash (cr, NULL, 0, 0); + + float pkx = (ui->_rms + 60.f) * M1RECT / 70.f; + if (pkx > 0) { + cairo_save (cr); + cairo_rectangle (cr, 0, 0, pkx, M1RECT); + cairo_clip (cr); + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, 0.5); + cairo_mask_surface (cr, ui->m1_mask, 0, 0); + cairo_fill (cr); + cairo_restore (cr); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + + float pky0 = (ui->_rms + ui->_gmax - 10.f) * M1RECT / -70.f; + float pky1 = (ui->_rms + ui->_gmin - 10.f) * M1RECT / -70.f; + cairo_move_to (cr, pkx, pky0); + cairo_line_to (cr, pkx, pky1); + cairo_set_line_width (cr, 5); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + cairo_stroke (cr); + } + + return TRUE; +} + +/* ****************************************************************************/ + +static void +m2_size_request (RobWidget* handle, int* w, int* h) +{ + *w = 12; + *h = 10; +} + +static void +m2_size_allocate (RobWidget* rw, int w, int h) +{ + robwidget_set_size (rw, w, h); +} + +static bool +m2_expose_event (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) +{ + darcUI* ui = (darcUI*)GET_HANDLE (rw); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); + cairo_clip (cr); + cairo_rectangle (cr, 0, 0, rw->area.width, rw->area.height); + cairo_clip_preserve (cr); + + float c[4]; + get_color_from_theme (1, c); + cairo_set_source_rgb (cr, c[0], c[1], c[2]); + cairo_fill (cr); + + cairo_scale (cr, ui->rw->widget_scale, ui->rw->widget_scale); + if (ui->nfo) { + write_text_full (cr, ui->nfo, ui->font[0], 0, .5 * rw->area.height / ui->rw->widget_scale, 0, 3, c_gry); + } + return TRUE; +} + +/* ****************************************************************************/ + +static RobWidget* +toplevel (darcUI* ui, void* const top) +{ + /* main widget: layout */ + ui->rw = rob_vbox_new (FALSE, 2); + robwidget_make_toplevel (ui->rw, top); + robwidget_toplevel_enable_scaling (ui->rw); + + ui->font[0] = pango_font_description_from_string ("Mono 9px"); + ui->font[1] = pango_font_description_from_string ("Mono 10px"); + + prepare_faceplates (ui); + + /* level display */ + ui->m0 = robwidget_new (ui); + robwidget_set_alignment (ui->m0, .5, .5); + robwidget_set_expose_event (ui->m0, m0_expose_event); + robwidget_set_size_request (ui->m0, m0_size_request); + robwidget_set_size_allocate (ui->m0, m0_size_allocate); + + /* graph display */ + ui->m1 = robwidget_new (ui); + robwidget_set_alignment (ui->m1, .5, .5); + robwidget_set_expose_event (ui->m1, m1_expose_event); + robwidget_set_size_request (ui->m1, m1_size_request); + robwidget_set_size_allocate (ui->m1, m1_size_allocate); + + /* control knob table */ + ui->ctbl = rob_table_new (/*rows*/ 3, /*cols*/ 5, FALSE); + ui->ctbl->top = (void*)ui; + +#define GSP_W(PTR) robtk_dial_widget (PTR) +#define GLB_W(PTR) robtk_lbl_widget (PTR) +#define GBT_W(PTR) robtk_cbtn_widget (PTR) + + for (uint32_t i = 0; i < 5; ++i) { + ui->lbl_ctrl[i] = robtk_lbl_new (ctrl_range[i].name); + ui->spn_ctrl[i] = robtk_dial_new_with_size ( + k_min (i), k_max (i), k_step (i), + GED_WIDTH + 8, GED_HEIGHT + 20, GED_CX + 4, GED_CY + 15, GED_RADIUS); + ui->spn_ctrl[i]->with_scroll_accel = false; + + robtk_dial_set_value (ui->spn_ctrl[i], ctrl_to_gui (i, ctrl_range[i].dflt)); + robtk_dial_set_callback (ui->spn_ctrl[i], cb_spn_ctrl, ui); + robtk_dial_set_default (ui->spn_ctrl[i], ctrl_to_gui (i, ctrl_range[i].dflt)); + robtk_dial_set_scroll_mult (ui->spn_ctrl[i], ctrl_range[i].mult); + + if (ui->touch) { + robtk_dial_set_touch (ui->spn_ctrl[i], ui->touch->touch, ui->touch->handle, DARC_INPUTGAIN + i); + } + + robtk_dial_set_scaled_surface_scale (ui->spn_ctrl[i], ui->dial_bg[i], 2.0); + robtk_lbl_annotation_callback (ui->lbl_ctrl[i], ttip_handler, ui); + + rob_table_attach (ui->ctbl, GSP_W (ui->spn_ctrl[i]), i, i + 1, 0, 1, 4, 0, RTK_EXANDF, RTK_SHRINK); + rob_table_attach (ui->ctbl, GLB_W (ui->lbl_ctrl[i]), i, i + 1, 1, 2, 4, 0, RTK_EXANDF, RTK_SHRINK); + } + + /* snap at 0dB gain */ + robtk_dial_set_detent_default (ui->spn_ctrl[0], true); + + /* use 'dot' for time knobs */ + ui->spn_ctrl[3]->displaymode = 3; + ui->spn_ctrl[4]->displaymode = 3; // use dot + + /* these numerics are meaningful */ + robtk_dial_annotation_callback (ui->spn_ctrl[0], dial_annotation_db, ui); + robtk_dial_annotation_callback (ui->spn_ctrl[1], dial_annotation_db, ui); + robtk_dial_annotation_callback (ui->spn_ctrl[2], dial_annotation_rr, ui); + robtk_dial_annotation_callback (ui->spn_ctrl[3], dial_annotation_tm, ui); + robtk_dial_annotation_callback (ui->spn_ctrl[4], dial_annotation_tm, ui); + + /* custom knob colors */ + { + const float c_bg[4] = { .7, .7, .1, 1.0 }; + create_dial_pattern (ui->spn_ctrl[0], c_bg); + ui->spn_ctrl[0]->dcol[0][0] = + ui->spn_ctrl[0]->dcol[0][1] = + ui->spn_ctrl[0]->dcol[0][2] = .05; + } + { + const float c_bg[4] = { .8, .3, .0, 1.0 }; + create_dial_pattern (ui->spn_ctrl[1], c_bg); + ui->spn_ctrl[1]->dcol[0][0] = + ui->spn_ctrl[1]->dcol[0][1] = + ui->spn_ctrl[1]->dcol[0][2] = .05; + } + { + const float c_bg[4] = { .9, .2, .2, 1.0 }; + create_dial_pattern (ui->spn_ctrl[2], c_bg); + ui->spn_ctrl[2]->dcol[0][0] = + ui->spn_ctrl[2]->dcol[0][1] = + ui->spn_ctrl[2]->dcol[0][2] = .05; + } + { + const float c_bg[4] = { .3, .3, .7, 1.0 }; + create_dial_pattern (ui->spn_ctrl[3], c_bg); + ui->spn_ctrl[3]->dcol[0][0] = + ui->spn_ctrl[3]->dcol[0][1] = + ui->spn_ctrl[3]->dcol[0][2] = .05; + create_dial_pattern (ui->spn_ctrl[4], c_bg); + ui->spn_ctrl[4]->dcol[0][0] = + ui->spn_ctrl[4]->dcol[0][1] = + ui->spn_ctrl[4]->dcol[0][2] = .05; + } + + /* explicit hold button */ + ui->btn_hold = robtk_cbtn_new ("Hold", GBT_LED_RIGHT, false); + robtk_cbtn_set_callback (ui->btn_hold, cb_btn_hold, ui); + rob_table_attach (ui->ctbl, GBT_W (ui->btn_hold), 4, 5, 3, 4, 8, 2, RTK_EXANDF, RTK_SHRINK); + + robtk_cbtn_set_temporary_mode (ui->btn_hold, 1); + robtk_cbtn_set_color_on (ui->btn_hold, 0.1, 0.3, 0.8); + robtk_cbtn_set_color_off (ui->btn_hold, .1, .1, .3); + robtk_cbtn_annotation_callback (ui->btn_hold, ttip_handler, ui); + + /* version info */ + + ui->m2 = robwidget_new (ui); + robwidget_set_alignment (ui->m2, 0, 0); + robwidget_set_expose_event (ui->m2, m2_expose_event); + robwidget_set_size_request (ui->m2, m2_size_request); + robwidget_set_size_allocate (ui->m2, m2_size_allocate); + + rob_table_attach (ui->ctbl, ui->m2, 0, 2, 3, 4, 8, 2, RTK_FILL, RTK_FILL); + + /* top-level packing */ + rob_vbox_child_pack (ui->rw, ui->m1, FALSE, TRUE); + rob_vbox_child_pack (ui->rw, ui->ctbl, FALSE, TRUE); + rob_vbox_child_pack (ui->rw, ui->m0, TRUE, TRUE); + return ui->rw; +} + +static void +gui_cleanup (darcUI* ui) +{ + for (int i = 0; i < 5; ++i) { + robtk_dial_destroy (ui->spn_ctrl[i]); + robtk_lbl_destroy (ui->lbl_ctrl[i]); + cairo_surface_destroy (ui->dial_bg[i]); + } + + pango_font_description_free (ui->font[0]); + pango_font_description_free (ui->font[1]); + + if (ui->m_fg) { + cairo_pattern_destroy (ui->m_fg); + } + if (ui->m_bg) { + cairo_pattern_destroy (ui->m_bg); + } + if (ui->m0bg) { + cairo_surface_destroy (ui->m0bg); + } + if (ui->m1_grid) { + cairo_surface_destroy (ui->m1_grid); + } + if (ui->m1_ctrl) { + cairo_surface_destroy (ui->m1_ctrl); + } + if (ui->m1_mask) { + cairo_surface_destroy (ui->m1_mask); + } + + robtk_cbtn_destroy (ui->btn_hold); + robwidget_destroy (ui->m0); + robwidget_destroy (ui->m1); + robwidget_destroy (ui->m2); + rob_table_destroy (ui->ctbl); + rob_box_destroy (ui->rw); +} + +/* ***************************************************************************** + * RobTk + LV2 + */ + +#define LVGL_RESIZEABLE + +static void +ui_enable (LV2UI_Handle handle) +{ +} + +static void +ui_disable (LV2UI_Handle handle) +{ +} + +static enum LVGLResize +plugin_scale_mode (LV2UI_Handle handle) +{ + return LVGL_LAYOUT_TO_FIT; +} + +static LV2UI_Handle +instantiate ( + void* const ui_toplevel, + const LV2UI_Descriptor* descriptor, + const char* plugin_uri, + const char* bundle_path, + LV2UI_Write_Function write_function, + LV2UI_Controller controller, + RobWidget** widget, + const LV2_Feature* const* features) +{ + darcUI* ui = (darcUI*)calloc (1, sizeof (darcUI)); + if (!ui) { + return NULL; + } + + if (strcmp (plugin_uri, RTK_URI "mono") && strcmp (plugin_uri, RTK_URI "stereo")) { + free (ui); + return NULL; + } + + const LV2_Options_Option* options = NULL; + const LV2_URID_Map* map = NULL; + + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_UI__touch)) { + ui->touch = (LV2UI_Touch*)features[i]->data; + } else if (!strcmp (features[i]->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp (features[i]->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)features[i]->data; + } + } + + ui->nfo = robtk_info (ui_toplevel); + ui->write = write_function; + ui->controller = controller; + ui->ctrl_dirty = false; + ui->disable_signals = true; + *widget = toplevel (ui, ui_toplevel); + ui->disable_signals = false; + + if (options && map) { + LV2_URID atom_Float = map->map (map->handle, LV2_ATOM__Float); + LV2_URID ui_scale = map->map (map->handle, "http://lv2plug.in/ns/extensions/ui#scaleFactor"); + for (const LV2_Options_Option* o = options; o->key; ++o) { + if (o->context == LV2_OPTIONS_INSTANCE && o->key == ui_scale && o->type == atom_Float) { + float ui_scale = *(const float*)o->value; + if (ui_scale < 1.0) { + ui_scale = 1.0; + } + if (ui_scale > 2.0) { + ui_scale = 2.0; + } + robtk_queue_scale_change (ui->rw, ui_scale); + } + } + } + return ui; +} + +static void +cleanup (LV2UI_Handle handle) +{ + darcUI* ui = (darcUI*)handle; + gui_cleanup (ui); + free (ui); +} + +/* receive information from DSP */ +static void +port_event (LV2UI_Handle handle, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer) +{ + darcUI* ui = (darcUI*)handle; + + if (format != 0) { + return; + } + + if (port_index == DARC_GMIN) { + ui->_gmin = *(float*)buffer; + /* TODO: partial exposure, only redraw changed gain area */ + queue_draw (ui->m0); + queue_draw (ui->m1); + } else if (port_index == DARC_GMAX) { + ui->_gmax = *(float*)buffer; + queue_draw (ui->m0); + queue_draw (ui->m1); + } else if (port_index == DARC_RMS) { + ui->_rms = *(float*)buffer; + queue_draw (ui->m1); + } else if (port_index == DARC_HOLD) { + ui->disable_signals = true; + robtk_cbtn_set_active (ui->btn_hold, (*(float*)buffer) > 0); + ui->disable_signals = false; + } else if (port_index >= DARC_INPUTGAIN && port_index <= DARC_RELEASE) { + const float v = *(float*)buffer; + ui->disable_signals = true; + uint32_t ctrl = port_index - DARC_INPUTGAIN; + robtk_dial_set_value (ui->spn_ctrl[ctrl], ctrl_to_gui (ctrl, v)); + ui->disable_signals = false; + } +} + +static const void* +extension_data (const char* uri) +{ + return NULL; +} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/darc.lv2/img/darc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/darc.lv2/img/darc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/darc.lv2/img/x42-darc.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/darc.lv2/img/x42-darc.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/darc.lv2/img/x42-darc.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/darc.lv2/img/x42-darc.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/darc.lv2/img/x42-darc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/darc.lv2/img/x42-darc.png differ diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc.gui.in x42-plugins-20190714/darc.lv2/lv2ttl/darc.gui.in --- x42-plugins-20170428/darc.lv2/lv2ttl/darc.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc.gui.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,9 @@ + +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + opts:supportedOption ; + lv2:optionalFeature opts:options ; + @UI_REQ@ + lv2:requiredFeature urid:map ; + . + diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc_mono.h x42-plugins-20190714/darc.lv2/lv2ttl/darc_mono.h --- x42-plugins-20170428/darc.lv2/lv2ttl/darc_mono.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc_mono.h 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,41 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/darc#mono + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _plugin_mono = { + &lv2_descriptor, + &lv2ui_descriptor + , 0 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "x42-comp - Dynamic Compressor Mono" // const char *plugin_human_id + , (const struct LV2Port[12]) + { + { "enable", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Enable"}, + { "hold", CONTROL_IN, 0.000000, 0.000000, 1.000000, "Hold"}, + { "inputgain", CONTROL_IN, 0.000000, -10.000000, 30.000000, "Input Gain"}, + { "threshold", CONTROL_IN, -30.000000, -50.000000, -10.000000, "Threshold"}, + { "Ratio", CONTROL_IN, 0.000000, 0.000000, 1.000000, "Ratio"}, + { "attack", CONTROL_IN, 0.010000, 0.001000, 0.100000, "Attack Time"}, + { "release", CONTROL_IN, 0.300000, 0.030000, 3.000000, "Release Time"}, + { "gain_min", CONTROL_OUT, nan, -20.000000, 40.000000, "Gain Min"}, + { "gain_max", CONTROL_OUT, nan, -20.000000, 40.000000, "Gain Max"}, + { "rms", CONTROL_OUT, nan, -80.000000, 10.000000, "Signal Level"}, + { "in", AUDIO_IN, nan, nan, nan, "In"}, + { "out", AUDIO_OUT, nan, nan, nan, "Out"}, + } + , 12 // uint32_t nports_total + , 1 // uint32_t nports_audio_in + , 1 // uint32_t nports_audio_out + , 0 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 0 // uint32_t nports_atom_in + , 0 // uint32_t nports_atom_out + , 10 // uint32_t nports_ctrl + , 7 // uint32_t nports_ctrl_in + , 3 // uint32_t nports_ctrl_out + , 8192 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , UINT32_MAX // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc.mono.ttl.in x42-plugins-20190714/darc.lv2/lv2ttl/darc.mono.ttl.in --- x42-plugins-20170428/darc.lv2/lv2ttl/darc.mono.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc.mono.ttl.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,13 @@ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 10 ; + lv2:symbol "in" ; + lv2:name "In" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 11 ; + lv2:symbol "out" ; + lv2:name "Out" + ] + . diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc.ports.ttl.in x42-plugins-20190714/darc.lv2/lv2ttl/darc.ports.ttl.in --- x42-plugins-20170428/darc.lv2/lv2ttl/darc.ports.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc.ports.ttl.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,117 @@ + +@LV2NAME@:@URISUFFIX@ + a lv2:Plugin, doap:Project, lv2:CompressorPlugin; + doap:license ; + doap:maintainer ; + @VERSION@ + doap:name "x42-comp - Dynamic Compressor@NAMESUFFIX@"; + lv2:extensionData idpy:interface @SIGNATURE@; + lv2:optionalFeature lv2:hardRTCapable, idpy:queue_draw; + @UITTL@ + lv2:port [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 0 ; + lv2:symbol "enable" ; + lv2:name "Enable"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + lv2:designation lv2:enabled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 1 ; + lv2:symbol "hold" ; + lv2:name "Hold"; + lv2:default 0 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + lv2:designation lv2:enabled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 2 ; + lv2:symbol "inputgain" ; + lv2:name "Input Gain" ; + lv2:default 0.0 ; + lv2:minimum -10.0 ; + lv2:maximum 30.0; + pprop:rangeSteps 81; + units:unit units:db ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 3 ; + lv2:symbol "threshold" ; + lv2:name "Threshold" ; + lv2:default -30.0 ; + lv2:minimum -50.0 ; + lv2:maximum -10.0; + pprop:rangeSteps 81; + units:unit units:db ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 4 ; + lv2:symbol "Ratio" ; + lv2:name "Ratio" ; + lv2:default 0.0 ; + lv2:minimum 0.0 ; + lv2:maximum 1.0; + lv2:scalePoint [ rdfs:label "Lim"; rdf:value 1 ; ] ; + pprop:rangeSteps 37; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 5 ; + lv2:symbol "attack" ; + lv2:name "Attack Time"; + lv2:default 0.01 ; + lv2:minimum 0.001 ; + lv2:maximum 0.1 ; + lv2:portProperty pprop:logarithmic; + pprop:rangeSteps 101; + units:unit units:s ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 6 ; + lv2:symbol "release" ; + lv2:name "Release Time"; + lv2:default 0.3 ; + lv2:minimum 0.03 ; + lv2:maximum 3.0 ; + lv2:portProperty pprop:logarithmic; + pprop:rangeSteps 101; + units:unit units:s ; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 7 ; + lv2:symbol "gain_min" ; + lv2:name "Gain Min" ; + lv2:minimum -20.0 ; + lv2:maximum 40.0; + units:unit units:db ; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 8 ; + lv2:symbol "gain_max" ; + lv2:name "Gain Max" ; + lv2:minimum -20.0 ; + lv2:maximum 40.0; + units:unit units:db ; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 9 ; + lv2:symbol "rms" ; + lv2:name "Signal Level" ; + lv2:minimum -80.0 ; + lv2:maximum 10.0; + units:unit units:db ; + ] , [ diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc_stereo.h x42-plugins-20190714/darc.lv2/lv2ttl/darc_stereo.h --- x42-plugins-20170428/darc.lv2/lv2ttl/darc_stereo.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc_stereo.h 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,43 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/darc#stereo + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _plugin_stereo = { + &lv2_descriptor, + &lv2ui_descriptor + , 1 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "x42-comp - Dynamic Compressor Stereo" // const char *plugin_human_id + , (const struct LV2Port[14]) + { + { "enable", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Enable"}, + { "hold", CONTROL_IN, 0.000000, 0.000000, 1.000000, "Hold"}, + { "inputgain", CONTROL_IN, 0.000000, -10.000000, 30.000000, "Input Gain"}, + { "threshold", CONTROL_IN, -30.000000, -50.000000, -10.000000, "Threshold"}, + { "Ratio", CONTROL_IN, 0.000000, 0.000000, 1.000000, "Ratio"}, + { "attack", CONTROL_IN, 0.010000, 0.001000, 0.100000, "Attack Time"}, + { "release", CONTROL_IN, 0.300000, 0.030000, 3.000000, "Release Time"}, + { "gain_min", CONTROL_OUT, nan, -20.000000, 40.000000, "Gain Min"}, + { "gain_max", CONTROL_OUT, nan, -20.000000, 40.000000, "Gain Max"}, + { "rms", CONTROL_OUT, nan, -80.000000, 10.000000, "Signal Level"}, + { "inL", AUDIO_IN, nan, nan, nan, "In Left"}, + { "outL", AUDIO_OUT, nan, nan, nan, "Out Left"}, + { "inR", AUDIO_IN, nan, nan, nan, "In Right"}, + { "outR", AUDIO_OUT, nan, nan, nan, "Out Right"}, + } + , 14 // uint32_t nports_total + , 2 // uint32_t nports_audio_in + , 2 // uint32_t nports_audio_out + , 0 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 0 // uint32_t nports_atom_in + , 0 // uint32_t nports_atom_out + , 10 // uint32_t nports_ctrl + , 7 // uint32_t nports_ctrl_in + , 3 // uint32_t nports_ctrl_out + , 8192 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , UINT32_MAX // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc.stereo.ttl.in x42-plugins-20190714/darc.lv2/lv2ttl/darc.stereo.ttl.in --- x42-plugins-20170428/darc.lv2/lv2ttl/darc.stereo.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc.stereo.ttl.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,25 @@ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 10 ; + lv2:symbol "inL" ; + lv2:name "In Left" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 11 ; + lv2:symbol "outL" ; + lv2:name "Out Left" + ] , [ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 12 ; + lv2:symbol "inR" ; + lv2:name "In Right" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 13 ; + lv2:symbol "outR" ; + lv2:name "Out Right" + ] ; + . diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/darc.ttl.in x42-plugins-20190714/darc.lv2/lv2ttl/darc.ttl.in --- x42-plugins-20170428/darc.lv2/lv2ttl/darc.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/darc.ttl.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,28 @@ +@prefix atom: . +@prefix doap: . +@prefix foaf: . +@prefix idpy: . +@prefix kx: . +@prefix lv2: . +@prefix mod: . +@prefix opts: . +@prefix pprop: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsz: . +@prefix state: . +@prefix ui: . +@prefix units: . +@prefix urid: . + +idpy:queue_draw a lv2:Feature . +idpy:interface a lv2:ExtensionData . +ui:scaleFactor a opts:Option . + +@prefix @LV2NAME@: . + + + a foaf:Person ; + foaf:name "Robin Gareus" ; + foaf:mbox ; + foaf:homepage . diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/manifest.gui.in x42-plugins-20190714/darc.lv2/lv2ttl/manifest.gui.in --- x42-plugins-20170428/darc.lv2/lv2ttl/manifest.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/manifest.gui.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,6 @@ + +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + ui:binary <@LV2GUI@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . + diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/manifest.ttl.in x42-plugins-20190714/darc.lv2/lv2ttl/manifest.ttl.in --- x42-plugins-20170428/darc.lv2/lv2ttl/manifest.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/manifest.ttl.in 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,17 @@ +@prefix kx: . +@prefix lv2: . +@prefix modgui: . +@prefix rdfs: . +@prefix ui: . + +@prefix @LV2NAME@: . + +@LV2NAME@:mono + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . + +@LV2NAME@:stereo + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/darc.lv2/lv2ttl/plugins.h x42-plugins-20190714/darc.lv2/lv2ttl/plugins.h --- x42-plugins-20170428/darc.lv2/lv2ttl/plugins.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/lv2ttl/plugins.h 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,11 @@ +#define MULTIPLUGIN 1 +#define X42_MULTIPLUGIN_NAME "Dynamic Compressor" +#define X42_MULTIPLUGIN_URI "http://gareus.org/oss/lv2/darc" + +#include "lv2ttl/darc_mono.h" +#include "lv2ttl/darc_stereo.h" + +static const RtkLv2Description _plugins[] = { + _plugin_mono, + _plugin_stereo, +}; diff -Nru x42-plugins-20170428/darc.lv2/Makefile x42-plugins-20190714/darc.lv2/Makefile --- x42-plugins-20170428/darc.lv2/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/Makefile 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,324 @@ +#!/usr/bin/make -f + +# these can be overridden using make variables. e.g. +# make CFLAGS=-O2 +# make install DESTDIR=$(CURDIR)/debian/darc.lv2 PREFIX=/usr +# +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +MANDIR ?= $(PREFIX)/share/man/man1 +# see http://lv2plug.in/pages/filesystem-hierarchy-standard.html, don't use libdir +LV2DIR ?= $(PREFIX)/lib/lv2 + +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG +CFLAGS ?= -Wall -g -Wno-unused-function + +PKG_CONFIG?=pkg-config +STRIP?= strip + +BUILDOPENGL?=yes +BUILDJACKAPP?=yes +INLINEDISPLAY?=yes + +darc_VERSION ?= $(shell (git describe --tags HEAD || echo "0") | sed 's/-g.*$$//;s/^v//') +RW ?= robtk/ + +############################################################################### + +BUILDDIR = build/ +APPBLD = x42/ + +############################################################################### + +LV2NAME=darc +LV2GUI=darcUI_gl +BUNDLE=darc.lv2 +targets= + +LOADLIBES=-lm +LV2UIREQ= +GLUICFLAGS=-I. + +UNAME=$(shell uname) +ifeq ($(UNAME),Darwin) + LV2LDFLAGS=-dynamiclib + LIB_EXT=.dylib + EXE_EXT= + UI_TYPE=ui:CocoaUI + PUGL_SRC=$(RW)pugl/pugl_osx.m + PKG_GL_LIBS= + GLUILIBS=-framework Cocoa -framework OpenGL -framework CoreFoundation + STRIPFLAGS=-u -r -arch all -s $(RW)lv2syms + EXTENDED_RE=-E +else + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.so + EXE_EXT= + UI_TYPE=ui:X11UI + PUGL_SRC=$(RW)pugl/pugl_x11.c + PKG_GL_LIBS=glu gl + GLUILIBS=-lX11 + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` + STRIPFLAGS= -s + EXTENDED_RE=-r +endif + +ifneq ($(XWIN),) + CC=$(XWIN)-gcc + CXX=$(XWIN)-g++ + STRIP=$(XWIN)-strip + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.dll + EXE_EXT=.exe + PUGL_SRC=$(RW)pugl/pugl_win.cpp + PKG_GL_LIBS= + UI_TYPE=ui:WindowsUI + GLUILIBS=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread + GLUICFLAGS=-I. + override LDFLAGS += -static-libgcc -static-libstdc++ +endif + +ifeq ($(EXTERNALUI), yes) + UI_TYPE= +endif + +ifeq ($(UI_TYPE),) + UI_TYPE=kx:Widget + LV2UIREQ+=lv2:requiredFeature kx:Widget; + override CFLAGS += -DXTERNAL_UI +endif + +targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +UITTL= +ifneq ($(BUILDOPENGL), no) + targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) + UITTL=ui:ui $(LV2NAME):ui_gl ; +endif + +############################################################################### +# extract versions +LV2VERSION=$(darc_VERSION) +include git2lv2.mk + +############################################################################### +# check for build-dependencies + +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) + $(error "LV2 SDK was not found") +endif + +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) + $(error "LV2 SDK needs to be version 1.6.0 or later") +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") + endif +endif + +ifneq ($(BUILDJACKAPP), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) + $(warning *** libjack from http://jackaudio.org is required) + $(error Please install libjack-dev or libjack-jackd2-dev) + endif + JACKAPP=$(APPBLD)x42-darc$(EXE_EXT) +endif + +# check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) + override CFLAGS += -DHAVE_LV2_1_8 +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifneq ($(MAKECMDGOALS), submodules) + ifeq ($(wildcard $(RW)robtk.mk),) + $(warning "**********************************************************") + $(warning This plugin needs https://github.com/x42/robtk) + $(warning "**********************************************************") + $(info ) + $(info set the RW environment variale to the location of the robtk headers) + ifeq ($(wildcard .git),.git) + $(info or run 'make submodules' to initialize robtk as git submodule) + endif + $(info ) + $(warning "**********************************************************") + $(error robtk not found) + endif + endif +endif + +# LV2 idle >= lv2-1.6.0 +GLUICFLAGS+=-DHAVE_IDLE_IFACE +LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; + +# add library dependent flags and libs +override CFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(darc_VERSION)\"" +override CFLAGS += `$(PKG_CONFIG) --cflags lv2` +ifeq ($(XWIN),) +override CFLAGS += -fPIC -fvisibility=hidden +else +override CFLAGS += -DPTW32_STATIC_LIB +endif + +ifneq ($(INLINEDISPLAY),no) + override CFLAGS += `$(PKG_CONFIG) --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE + override LOADLIBES += `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango` + ifneq ($(XWIN),) + override LOADLIBES += -lpthread -lusp10 + endif +endif + +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` $(CFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` + +ifneq ($(XWIN),) +GLUILIBS+=-lpthread -lusp10 +endif + +GLUICFLAGS+=$(LIC_CFLAGS) +GLUILIBS+=$(LIC_LOADLIBES) + +#GLUICFLAGS+=-DUSE_GUI_THREAD +ifeq ($(GLTHREADSYNC), yes) + GLUICFLAGS+=-DTHREADSYNC +endif + +ifneq ($(LIC_CFLAGS),) + LV2SIGN=, + override CFLAGS += -I$(RW) +endif + +ROBGL+= Makefile + +JACKCFLAGS=-I. $(CFLAGS) $(LIC_CFLAGS) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) + + +############################################################################### +# build target definitions +default: all + +submodule_pull: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_pull + +submodule_update: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_update + +submodule_check: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_check + +submodules: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodules + +all: submodule_check $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets) $(JACKAPP) + +$(BUILDDIR)manifest.ttl: lv2ttl/manifest.ttl.in lv2ttl/manifest.gui.in Makefile + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/" \ + lv2ttl/manifest.ttl.in > $(BUILDDIR)manifest.ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/;s/@UI_TYPE@/$(UI_TYPE)/;s/@LV2GUI@/$(LV2GUI)/g" \ + lv2ttl/manifest.gui.in >> $(BUILDDIR)manifest.ttl +endif + +$(BUILDDIR)$(LV2NAME).ttl: Makefile lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).gui.in \ + lv2ttl/$(LV2NAME).ports.ttl.in lv2ttl/$(LV2NAME).mono.ttl.in lv2ttl/$(LV2NAME).stereo.ttl.in + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g" \ + lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ + lv2ttl/$(LV2NAME).gui.in >> $(BUILDDIR)$(LV2NAME).ttl +endif + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/mono/;s/@NAMESUFFIX@/ Mono/;s/@CTLSIZE@/1024/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/" \ + lv2ttl/$(LV2NAME).ports.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + cat lv2ttl/$(LV2NAME).mono.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/stereo/;s/@NAMESUFFIX@/ Stereo/;s/@CTLSIZE@/1024/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/" \ + lv2ttl/$(LV2NAME).ports.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + cat lv2ttl/$(LV2NAME).stereo.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + +DSP_SRC = src/lv2.c +DSP_DEPS = $(DSP_SRC) src/darc.h +GUI_DEPS = gui/darc.c src/darc.h + +$(BUILDDIR)$(LV2NAME)$(LIB_EXT): $(DSP_DEPS) Makefile + @mkdir -p $(BUILDDIR) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LIC_CFLAGS) -std=c99 \ + -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DSP_SRC) \ + -shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES) $(LIC_LOADLIBES) + $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +jackapps: $(JACKAPP) + +$(eval x42_darc_JACKSRC = -DX42_MULTIPLUGIN src/lv2.c) +x42_darc_JACKGUI = gui/darc.c +x42_darc_LV2HTTL = lv2ttl/plugins.h +x42_darc_JACKDESC = lv2ui_descriptor +$(APPBLD)x42-darc$(EXE_EXT): $(DSP_DEPS) $(GUI_DEPS) \ + $(x42_darc_JACKGUI) $(x42_darc_LV2HTTL) + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + -include $(RW)robtk.mk +endif + +$(BUILDDIR)$(LV2GUI)$(LIB_EXT): gui/$(LV2NAME).c + +############################################################################### +# install/uninstall/clean target definitions + +install: install-bin install-man + +uninstall: uninstall-bin uninstall-man + +install-bin: all + install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m644 $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m755 $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +ifneq ($(BUILDOPENGL), no) + install -m755 $(BUILDDIR)$(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +endif +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(BINDIR) + install -m755 $(APPBLD)x42-darc$(EXE_EXT) $(DESTDIR)$(BINDIR) +endif + +uninstall-bin: + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/manifest.ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME).ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME)$(LIB_EXT) + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2GUI)$(LIB_EXT) + rm -f $(DESTDIR)$(BINDIR)/x42-darc$(EXE_EXT) + -rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE) + -rmdir $(DESTDIR)$(BINDIR) + +install-man: +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(MANDIR) + install -m644 x42-darc.1 $(DESTDIR)$(MANDIR) +endif + +uninstall-man: + rm -f $(DESTDIR)$(MANDIR)/x42-darc.1 + -rmdir $(DESTDIR)$(MANDIR) + +man: $(APPBLD)x42-darc + help2man -N -o x42-darc.1 -n "x42-darc JACK Dynamic Audio Compressor" $(APPBLD)x42-darc + +clean: + rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl \ + $(BUILDDIR)$(LV2NAME)$(LIB_EXT) \ + $(BUILDDIR)$(LV2GUI)$(LIB_EXT) + rm -rf $(BUILDDIR)*.dSYM + rm -rf $(APPBLD)x42-* + -test -d $(APPBLD) && rmdir $(APPBLD) || true + -test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true + +distclean: clean + rm -f cscope.out cscope.files tags + +.PHONY: clean all install uninstall distclean jackapps man \ + install-bin uninstall-bin install-man uninstall-man \ + submodule_check submodules submodule_update submodule_pull diff -Nru x42-plugins-20170428/darc.lv2/README.md x42-plugins-20190714/darc.lv2/README.md --- x42-plugins-20170428/darc.lv2/README.md 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/README.md 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,51 @@ +darc.lv2 - Dynamic Audio Range Compressor +========================================= + +darc.lv2 is a general purpose audio signal compressor. + +The compression gain is controlled by threshold and ratio only: +Makeup gain is automatically set to retain equal loudness at -10 dBFS/RMS with a soft knee. +This maintains perceived loudness over a wide range of thresholds and ratio settings. + +It is available as [LV2 plugin](http://lv2plug.in/) and standalone [JACK](http://jackaudio.org/)-application. + +Usage +----- + +The Plugin has five controls which can be operated by mouse-drag and the scroll-wheel. +Holding the _Ctrl_ key allows for fine-grained control when dragging or using the mouse-wheel on a knob. + +Furthermore the UI offers +* Shift + click: reset to default +* Right-click on knob: toggle current value with default, 2nd click restore. + +For an elaborate descripton and manual, please see https://x42-plugins.com/x42/x42-compressor + +Install +------- + +Compiling darc.lv2 requires the LV2 SDK, jack-headers, gnu-make, a c++-compiler, +liblo, libpango, libcairo and openGL (sometimes called: glu, glx, mesa). + +```bash + git clone git://github.com/x42/darc.lv2.git + cd darc.lv2 + make submodules + make + sudo make install PREFIX=/usr +``` + +Note to packagers: the Makefile honors `PREFIX` and `DESTDIR` variables as well +as `CXXLAGS`, `LDFLAGS` and `OPTIMIZATIONS` (additions to `CXXFLAGS`), also +see the first 10 lines of the Makefile. +You really want to package the superset of [x42-plugins](https://github.com/x42/x42-plugins). + +Screenshots +----------- + +![screenshot](https://raw.github.com/x42/darc.lv2/master/img/darc.png "DARC LV2 GUI") + +Credits +------- + +darc.lv2 was inspired by Fons Adriaensen's zita-dc1-0.3.3. diff -Nru x42-plugins-20170428/darc.lv2/src/darc.h x42-plugins-20190714/darc.lv2/src/darc.h --- x42-plugins-20170428/darc.lv2/src/darc.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/src/darc.h 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,23 @@ +/* common definitions UI and DSP */ + +#define DARC_URI "http://gareus.org/oss/lv2/darc#" + +typedef enum { + DARC_ENABLE, + DARC_HOLD, + DARC_INPUTGAIN, + DARC_THRESHOLD, + DARC_RATIO, + DARC_ATTACK, + DARC_RELEASE, + + DARC_GMIN, + DARC_GMAX, + DARC_RMS, + + DARC_INPUT0, + DARC_OUTPUT0, + DARC_INPUT1, + DARC_OUTPUT1, + DARC_LAST +} PortIndex; diff -Nru x42-plugins-20170428/darc.lv2/src/lv2.c x42-plugins-20190714/darc.lv2/src/lv2.c --- x42-plugins-20170428/darc.lv2/src/lv2.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/src/lv2.c 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,681 @@ +/* darc.lv2 + * + * Copyright (C) 2018,2019 Robin Gareus + * inspired by Fons Adriaensen's zita-dc1 + * + * 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, 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, see . + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include + +#include "darc.h" + +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#ifdef DISPLAY_INTERFACE +#include "lv2_rgext.h" +#include +#include +#endif + +#ifndef MAX +#define MAX(A, B) ((A) > (B)) ? (A) : (B) +#endif + +#ifndef MIN +#define MIN(A, B) ((A) < (B)) ? (A) : (B) +#endif + +/* ****************************************************************************/ + +typedef struct { + float sample_rate; + + uint32_t n_channels; + float norm_input; + + float ratio; + float p_rat; + + bool hold; + + float igain; + float p_ign; + float l_ign; + + float p_thr; + float l_thr; + + float w_att; + float w_rel; + float t_att; + float t_rel; + + float za1; + float zr1; + float zr2; + + bool newg; + float gmax; + float gmin; + + float rms; + float w_rms; + float w_lpf; + +} Dyncomp; + +static inline void +Dyncomp_reset (Dyncomp* self) +{ + self->za1 = 0.f; + self->zr1 = 0.f; + self->zr2 = 0.f; + self->rms = 0.f; + self->gmin = 0.f; + self->gmax = 0.f; + self->newg = true; +} + +static inline void +Dyncomp_set_ratio (Dyncomp* self, float r) +{ + self->p_rat = 0.5f * r; +} + +static inline void +Dyncomp_set_inputgain (Dyncomp* self, float g) +{ + if (g == self->l_ign) { + return; + } + self->l_ign = g; +#ifdef __USE_GNU + self->p_ign = exp10f (0.05f * g); +#else + self->p_ign = powf (10.0f, 0.05f * g); +#endif +} + +static inline void +Dyncomp_set_threshold (Dyncomp* self, float t) +{ + if (t == self->l_thr) { + return; + } + self->l_thr = t; + /* Note that this is signal-power, hence .5 * 10^(x/10) */ +#ifdef __USE_GNU + self->p_thr = 0.5f * exp10f (0.1f * t); +#else + self->p_thr = 0.5f * powf (10.0f, 0.1f * t); +#endif +} + +static inline void +Dyncomp_set_hold (Dyncomp* self, bool hold) +{ + self->hold = hold; +} + +static inline void +Dyncomp_set_attack (Dyncomp* self, float a) +{ + if (a == self->t_att) { + return; + } + self->t_att = a; + self->w_att = 0.5f / (self->sample_rate * a); +} + +static inline void +Dyncomp_set_release (Dyncomp* self, float r) +{ + if (r == self->t_rel) { + return; + } + self->t_rel = r; + self->w_rel = 3.5f / (self->sample_rate * r); +} + +static inline void +Dyncomp_get_gain (Dyncomp* self, float* gmin, float* gmax, float* rms) +{ + *gmin = self->gmin * 8.68589f; /* 20 / log(10) */ + *gmax = self->gmax * 8.68589f; + if (self->rms > 1e-8f) { + *rms = 10.f * log10f (2.f * self->rms * self->norm_input); + } else { + *rms = -80; + } + self->newg = true; +} + +static inline void +Dyncomp_init (Dyncomp* self, float sample_rate, uint32_t n_channels) +{ + self->sample_rate = sample_rate; + self->n_channels = n_channels; + self->norm_input = 1.f / n_channels; + + self->ratio = 0.f; + self->p_rat = 0.f; + + self->igain = 1.f; + self->p_ign = 1.f; + self->l_ign = 0.f; + + self->p_thr = 0.05f; + self->l_thr = -10.f; + + self->hold = false; + + self->t_att = 0.f; + self->t_rel = 0.f; + + self->w_rms = 5.f / sample_rate; + self->w_lpf = 160.f / sample_rate; + + Dyncomp_set_attack (self, 0.01f); + Dyncomp_set_release (self, 0.03f); + Dyncomp_reset (self); +} + +static inline void +Dyncomp_process (Dyncomp* self, uint32_t n_samples, float* inp[], float* out[]) +{ + float gmin, gmax; + + /* reset min/max gain report */ + if (self->newg) { + gmax = -100.0f; + gmin = 100.0f; + self->newg = false; + } else { + gmax = self->gmax; + gmin = self->gmin; + } + + /* interpolate input gain */ + float g = self->igain; + const float g1 = self->p_ign; + float dg = g1 - g; + if (fabsf (dg) < 1e-5f || (g > 1.f && fabsf (dg) < 1e-3f)) { + g = g1; + dg = 0; + } + + /* interpolate ratio */ + float r = self->ratio; + const float r1 = self->p_rat; + float dr = r1 - r; + if (fabsf (dr) < 1e-5f) { + r = r1; + dr = 0; + } + + /* localize variables */ + float za1 = self->za1; + float zr1 = self->zr1; + float zr2 = self->zr2; + + float rms = self->rms; + + const float w_rms = self->w_rms; + const float w_lpf = self->w_lpf; + const float w_att = self->w_att; + const float w_rel = self->w_rel; + const float p_thr = self->p_thr; + + const float p_hold = self->hold ? 2.f * p_thr : 0.f; + + const uint32_t nc = self->n_channels; + const float n_1 = self->norm_input; + + for (uint32_t j = 0; j < n_samples; ++j) { + /* update input gain */ + if (dg != 0) { + g += w_lpf * (g1 - g); + } + + /* Input/Key RMS */ + float v = 0; + for (uint32_t i = 0; i < nc; ++i) { + const float x = g * inp[i][j]; + v += x * x; + } + + v *= n_1; // normalize *= 1 / (number of channels) + + /* slow moving RMS, used for GUI level meter display */ + rms += w_rms * (v - rms); // TODO: consider reporting range; 5ms integrate, 50ms min/max readout + + /* calculate signal power relative to threshold, LPF using attack time constant */ + za1 += w_att * (p_thr + v - za1); + + /* hold release */ + const bool hold = (za1 < p_hold); + + /* Note: za1 >= p_thr; so zr1, zr2 can't become denormal */ + if (zr1 < za1) { + zr1 = za1; + } else if (!hold) { + zr1 -= w_rel * zr1; + } + + if (zr2 < za1) { + zr2 = za1; + } else if (!hold) { + zr2 += w_rel * (zr1 - zr2); + } + + /* update ratio */ + if (dr != 0) { + r += w_lpf * (r1 - r); + } + + /* Note: expf (a * logf (b)) == powf (b, a); + * however powf() is significantly slower + * + * Effective gain is (zr2) ^ (-ratio). + * + * with 0 <= ratio <= 0.5 and + * zr2 being low-pass (attack/release) filtered square of the key-signal. + */ + + float pg = -r * logf (20.0f * zr2); + + /* store min/max gain in dB, report to UI */ + gmax = fmaxf (gmax, pg); + gmin = fminf (gmin, pg); + + pg = g * expf (pg); + + /* apply gain factor to all channels */ + for (uint32_t i = 0; i < nc; ++i) { + out[i][j] = pg * inp[i][j]; + } + } + + /* copy back variables */ + self->za1 = za1; + self->zr1 = zr1; + self->zr2 = zr2; + self->igain = g; + self->ratio = r; + self->gmax = gmax; + self->gmin = gmin; + self->rms = rms + 1e-12; // + denormal protection +} + +/* ****************************************************************************/ + +typedef struct { + float* _port[DARC_LAST]; + + Dyncomp dyncomp; + + float _gmin; + float _gmax; + float _rms; + + uint32_t samplecnt; + uint32_t sampletme; // 50ms + +#ifdef DISPLAY_INTERFACE + LV2_Inline_Display_Image_Surface surf; + cairo_surface_t* display; + LV2_Inline_Display* queue_draw; + cairo_pattern_t* mpat; + cairo_pattern_t* cpat; + uint32_t w, h; + float ui_gmin; + float ui_gmax; +#endif + +} Darc; + +static LV2_Handle +instantiate (const LV2_Descriptor* descriptor, + double rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Darc* self = (Darc*)calloc (1, sizeof (Darc)); + + uint32_t n_channels; + + if (!strcmp (descriptor->URI, DARC_URI "mono")) { + n_channels = 1; + } else if (!strcmp (descriptor->URI, DARC_URI "stereo")) { + n_channels = 2; + } else { + free (self); + return NULL; + } + +#ifdef DISPLAY_INTERFACE + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_INLINEDISPLAY__queue_draw)) { + self->queue_draw = (LV2_Inline_Display*)features[i]->data; + } + } +#endif + + Dyncomp_init (&self->dyncomp, rate, n_channels); + self->sampletme = ceilf (rate * 0.05); // 50ms + self->samplecnt = self->sampletme; + + return (LV2_Handle)self; +} + +static void +connect_port (LV2_Handle instance, + uint32_t port, + void* data) +{ + Darc* self = (Darc*)instance; + if (port < DARC_LAST) { + self->_port[port] = (float*)data; + } +} + +static void +activate (LV2_Handle instance) +{ + Darc* self = (Darc*)instance; + Dyncomp_reset (&self->dyncomp); + self->samplecnt = self->sampletme; +} + +static void +run (LV2_Handle instance, uint32_t n_samples) +{ + Darc* self = (Darc*)instance; + + /* bypass/enable */ + const bool enable = *self->_port[DARC_ENABLE] > 0; + + if (enable) { + Dyncomp_set_inputgain (&self->dyncomp, *self->_port[DARC_INPUTGAIN]); + Dyncomp_set_threshold (&self->dyncomp, *self->_port[DARC_THRESHOLD]); + Dyncomp_set_ratio (&self->dyncomp, *self->_port[DARC_RATIO]); + Dyncomp_set_hold (&self->dyncomp, *self->_port[DARC_HOLD] > 0); + } else { + Dyncomp_set_inputgain (&self->dyncomp, 0); + Dyncomp_set_threshold (&self->dyncomp, -10.f); + Dyncomp_set_ratio (&self->dyncomp, 0); + Dyncomp_set_hold (&self->dyncomp, false); + } + + Dyncomp_set_attack (&self->dyncomp, *self->_port[DARC_ATTACK]); + Dyncomp_set_release (&self->dyncomp, *self->_port[DARC_RELEASE]); + + float* ins[2] = { self->_port[DARC_INPUT0], self->_port[DARC_INPUT1] }; + float* outs[2] = { self->_port[DARC_OUTPUT0], self->_port[DARC_OUTPUT1] }; + + Dyncomp_process (&self->dyncomp, n_samples, ins, outs); + + self->samplecnt += n_samples; + while (self->samplecnt >= self->sampletme) { + self->samplecnt -= self->sampletme; + Dyncomp_get_gain (&self->dyncomp, &self->_gmin, &self->_gmax, &self->_rms); + + self->_gmin = fminf (40.f, fmaxf (-20.f, self->_gmin)); + self->_gmax = fminf (40.f, fmaxf (-20.f, self->_gmax)); + self->_rms = fminf (10.f, fmaxf (-80.f, self->_rms)); + +#ifdef DISPLAY_INTERFACE + if (self->queue_draw && (self->ui_gmin != self->_gmin || self->ui_gmax != self->_gmax)) { + self->ui_gmin = self->_gmin; + self->ui_gmax = self->_gmax; + self->queue_draw->queue_draw (self->queue_draw->handle); + } +#endif + } + + *self->_port[DARC_GMIN] = self->_gmin; + *self->_port[DARC_GMAX] = self->_gmax; + *self->_port[DARC_RMS] = self->_rms; +} + +static void +cleanup (LV2_Handle instance) +{ + Darc* self = (Darc*)instance; +#ifdef DISPLAY_INTERFACE + if (self->mpat) { + cairo_pattern_destroy (self->mpat); + } + if (self->cpat) { + cairo_pattern_destroy (self->cpat); + } + if (self->display) { + cairo_surface_destroy (self->display); + } +#endif + free (instance); +} + +/* ****************************************************************************/ + +#ifdef WITH_SIGNATURE +#define RTK_URI DARC_URI +#include "gpg_init.c" +#include WITH_SIGNATURE +struct license_info license_infos = { + "x42-Compressor", + "http://x42-plugins.com/x42/x42-compressor" +}; +#include "gpg_lv2ext.c" +#endif + +#ifdef DISPLAY_INTERFACE +static void +create_pattern (Darc* self, const double w) +{ + const int x0 = floor (w * 0.05); + const int x1 = ceil (w * 0.95); + const int wd = x1 - x0; + +#define DEF(x) ((x0 + wd * ((x) + 20.) / 60.) / w) + + cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, w, 0); + /* clang-format off */ + cairo_pattern_add_color_stop_rgba (pat, 1.0, .0, .5, .0, 0); + cairo_pattern_add_color_stop_rgba (pat, DEF (40), .0, .5, .0, 0.5); + cairo_pattern_add_color_stop_rgba (pat, DEF (5), .0, .5, .0, 0.5); + cairo_pattern_add_color_stop_rgba (pat, DEF (-5), .5, .0, .0, 0.5); + cairo_pattern_add_color_stop_rgba (pat, DEF (-20), .5, .0, .0, 0.5); + cairo_pattern_add_color_stop_rgba (pat, 0.0, .5, .0, .0, 0); + /* clang-format on */ + self->mpat = pat; + + pat = cairo_pattern_create_linear (0.0, 0.0, w, 0); + /* clang-format off */ + cairo_pattern_add_color_stop_rgba (pat, 1.0, .1, .9, .1, 0); + cairo_pattern_add_color_stop_rgba (pat, DEF (40), .1, .9, .1, 1); + cairo_pattern_add_color_stop_rgba (pat, DEF (5), .1, .9, .1, 1); + cairo_pattern_add_color_stop_rgba (pat, DEF (-5), .9, .9, .1, 1); + cairo_pattern_add_color_stop_rgba (pat, DEF (-20), .9, .9, .1, 1); + cairo_pattern_add_color_stop_rgba (pat, 0.0, .9, .9, .1, 0); + /* clang-format on */ + self->cpat = pat; + +#undef DEF +} + +static LV2_Inline_Display_Image_Surface* +dpl_render (LV2_Handle handle, uint32_t w, uint32_t max_h) +{ +#ifdef WITH_SIGNATURE + if (!is_licensed (handle)) { + return NULL; + } +#endif + uint32_t h = MAX (11, MIN (1 | (uint32_t)ceilf (w / 10.f), max_h)); + + Darc* self = (Darc*)handle; + + if (!self->display || self->w != w || self->h != h) { + if (self->display) + cairo_surface_destroy (self->display); + self->display = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + self->w = w; + self->h = h; + if (self->mpat) { + cairo_pattern_destroy (self->mpat); + self->mpat = NULL; + } + if (self->cpat) { + cairo_pattern_destroy (self->cpat); + self->cpat = NULL; + } + } + + if (!self->mpat || !self->cpat) { + create_pattern (self, w); + } + + cairo_t* cr = cairo_create (self->display); + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba (cr, .2, .2, .2, 1.0); + cairo_fill (cr); + + const int x0 = floor (w * 0.05); + const int x1 = ceil (w * 0.95); + const int wd = x1 - x0; + + cairo_set_line_width (cr, 1); + cairo_set_source_rgba (cr, 0.8, 0.8, 0.8, 1.0); + +#define DEF(x) (rint (x0 + wd * ((x) + 20.) / 60.) - .5) +#define GRID(x) \ + cairo_move_to (cr, DEF (x), 0); \ + cairo_rel_line_to (cr, 0, h); \ + cairo_stroke (cr) + + GRID (-20); + GRID (-10); + GRID (0); + GRID (10); + GRID (20); + GRID (30); + GRID (40); + +#undef GRID + + cairo_rectangle (cr, x0, 2, wd, h - 5); + cairo_set_source (cr, self->mpat); + cairo_fill (cr); + + if (1) { + float v0 = DEF (self->ui_gmin); + float v1 = DEF (self->ui_gmax); + cairo_rectangle (cr, v0 - 1, 2, 2. + v1 - v0, h - 5); + cairo_set_source (cr, self->cpat); + cairo_fill (cr); + } else { /* bypassed */ + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba (cr, .2, .2, .2, 0.8); + cairo_fill (cr); + } + +#undef DEF + + /* finish surface */ + cairo_destroy (cr); + cairo_surface_flush (self->display); + self->surf.width = cairo_image_surface_get_width (self->display); + self->surf.height = cairo_image_surface_get_height (self->display); + self->surf.stride = cairo_image_surface_get_stride (self->display); + self->surf.data = cairo_image_surface_get_data (self->display); + + return &self->surf; +} +#endif + +const void* +extension_data (const char* uri) +{ +#ifdef DISPLAY_INTERFACE + static const LV2_Inline_Display_Interface display = { dpl_render }; + if (!strcmp (uri, LV2_INLINEDISPLAY__interface)) { +#if (defined _WIN32 && defined RTK_STATIC_INIT) + static int once = 0; + if (!once) { + once = 1; + gobject_init_ctor (); + } +#endif + return &display; + } +#endif +#ifdef WITH_SIGNATURE + LV2_LICENSE_EXT_C +#endif + return NULL; +} + +static const LV2_Descriptor descriptor_mono = { + DARC_URI "mono", + instantiate, + connect_port, + activate, + run, + NULL, + cleanup, + extension_data +}; + +static const LV2_Descriptor descriptor_stereo = { + DARC_URI "stereo", + instantiate, + connect_port, + activate, + run, + NULL, + cleanup, + extension_data +}; + +/* clang-format off */ +#undef LV2_SYMBOL_EXPORT +#ifdef _WIN32 +# define LV2_SYMBOL_EXPORT __declspec(dllexport) +#else +# define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default"))) +#endif +/* clang-format on */ +LV2_SYMBOL_EXPORT +const LV2_Descriptor* +lv2_descriptor (uint32_t index) +{ + switch (index) { + case 0: + return &descriptor_mono; + case 1: + return &descriptor_stereo; + default: + return NULL; + } +} diff -Nru x42-plugins-20170428/darc.lv2/x42-darc.1 x42-plugins-20190714/darc.lv2/x42-darc.1 --- x42-plugins-20170428/darc.lv2/x42-darc.1 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/darc.lv2/x42-darc.1 2019-07-14 19:45:50.000000000 +0000 @@ -0,0 +1,72 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH X42-DARC "1" "July 2019" "x42-darc version 0.4.2" "User Commands" +.SH NAME +x42-darc \- x42-darc JACK Dynamic Audio Compressor +.SH SYNOPSIS +.B x42-darc +[ \fI\,OPTIONS \/\fR] [ \fI\,Plugin-ID or URI \/\fR] +.SH DESCRIPTION +x42\-darc \- JACK Dynamic Compressor +.PP +This is a standalone JACK application of a collection of LV2 plugins. +Use ID \fB\-1\fR, \fB\-l\fR or \fB\-\-list\fR for a dedicated list of included plugins. +By default the first listed plugin (ID 0) is used. +.PP +List of available plugins: (ID "Name" URI) +.TP +0 +"x42\-comp \- Dynamic Compressor Mono" http://gareus.org/oss/lv2/darc#mono +.TP +1 +"x42\-comp \- Dynamic Compressor Stereo" http://gareus.org/oss/lv2/darc#stereo +.PP +Usage: +All control elements are operated in using the mouse: +.TP +Click+Drag +left/down: decrease, right/up: increase value. Hold the Ctrl key to increase sensitivity. +.TP +Shift+Click +reset to default value +.TP +Scroll\-wheel +up/down by 1 step (smallest possible adjustment for given setting). Rapid continuous scrolling increases the step\-size. +.PP +The application can be closed by sending a SIGTERM (CTRL+C) on the command\-line of by closing the window. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Display this help and exit +.TP +\fB\-j\fR, \fB\-\-jack\-name\fR +Set the JACK client name +(defaults to plugin\-name) +.TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP +\fB\-l\fR, \fB\-\-list\fR +Print list of available plugins and exit +.TP +\fB\-O\fR , \fB\-\-osc\fR +Listen for OSC messages on the given UDP port +.TP +\fB\-p\fR :, \fB\-\-port\fR : +Set initial value for given control port +.TP +\fB\-P\fR, \fB\-\-portlist\fR +Print control port list on startup +.TP +\fB\-\-osc\-doc\fR +Print available OSC commands and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version information and exit +.PP +See also: +Website: +.SH COPYRIGHT +Copyright \(co GPL 2013\-2019 Robin Gareus +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/debian/changelog x42-plugins-20190714/debian/changelog --- x42-plugins-20170428/debian/changelog 2017-06-25 21:32:24.000000000 +0000 +++ x42-plugins-20190714/debian/changelog 2019-11-05 20:16:08.000000000 +0000 @@ -1,3 +1,66 @@ +x42-plugins (20190714-1~18.04) bionic; urgency=medium + + * Backport + * Add libjack-jackd2-dev to Build-Depends + + -- DNS Tue, 05 Nov 2019 21:16:08 +0100 + +x42-plugins (20190714-1) unstable; urgency=medium + + [ Olivier Humbert ] + * Update control to add adescription for the new dpl.lv2 + + [ Ondřej Nový ] + * d/control: Remove trailing whitespaces + * Use debhelper-compat instead of debian/compat + + [ Ross Gammon ] + * New upstream version 20190714 + - Fixes cross building failure, Helmut Grohne's patches + applied upstream (Closes: #900705) + * Update debian/copyright file + * Add description of new plugins to debian/control + * Add myself to uploaders + * Bump standards version, no changes required + * Add a simple autopkgtest + * Add an upstream metadata file + * Add a Salsa CI pipeline config + + -- Ross Gammon Wed, 07 Aug 2019 15:37:05 +0200 + +x42-plugins (20180803-1) unstable; urgency=medium + + * Team upload. + + [ Ondřej Nový ] + * d/copyright: Use https protocol in Format field + * d/control: Set Vcs-* to salsa.debian.org + * d/changelog: Remove trailing whitespaces + + [ Felipe Sateler ] + * Change maintainer address to debian-multimedia@lists.debian.org + + [ Sebastian Ramacher ] + * New upstream release. + - Fix FTBFS with GCC 8. (Closes: #897889) + * debian/patches: Remove, fixed upstream. + * debian/: Bump debhelper compat to 11. + * debian/rules: + - Simplify + - Disable strip. + - Enable all hardening options + * debian/copyright: Update copyright info. + + -- Sebastian Ramacher Sat, 04 Aug 2018 10:04:43 +0200 + +x42-plugins (20170428-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Add patch from Aurelien Jarno to fix FTBFS with glibc 2.27. + (Closes: #890672) + + -- Adrian Bunk Tue, 20 Mar 2018 20:30:37 +0200 + x42-plugins (20170428-1) unstable; urgency=medium * New upstream version 20170428 @@ -173,7 +236,7 @@ x42-plugins (20131021-1) unstable; urgency=low [ Jaromír Mikeš ] - * New upstream release. + * New upstream release. * Depedencies tighten. * Description updated. * Update version. @@ -185,6 +248,6 @@ x42-plugins (20130915-1) unstable; urgency=low - * Initial release (Closes: #712043) + * Initial release (Closes: #712043) -- Jaromír Mikeš Sun, 15 Sep 2013 21:38:29 +0200 diff -Nru x42-plugins-20170428/debian/compat x42-plugins-20190714/debian/compat --- x42-plugins-20170428/debian/compat 2016-12-23 00:22:36.000000000 +0000 +++ x42-plugins-20190714/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru x42-plugins-20170428/debian/control x42-plugins-20190714/debian/control --- x42-plugins-20170428/debian/control 2017-06-25 21:24:42.000000000 +0000 +++ x42-plugins-20190714/debian/control 2019-11-05 20:13:35.000000000 +0000 @@ -1,14 +1,15 @@ Source: x42-plugins Section: sound Priority: optional -Maintainer: Debian Multimedia Maintainers +Maintainer: Debian Multimedia Maintainers Uploaders: Jaromír Mikeš , - Robin Gareus + Robin Gareus , + Ross Gammon Build-Depends: - debhelper (>= 10), + debhelper-compat (= 11), pkg-config, - libjack-dev, + libjack-jackd2-dev | libjack-dev, libftgl-dev, lv2-dev (>=1.4.2~), libzita-convolver-dev, @@ -21,9 +22,9 @@ libpugl-dev, libltc-dev, liblo-dev -Standards-Version: 4.0.0 -Vcs-Git: https://anonscm.debian.org/git/pkg-multimedia/x42-plugins.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-multimedia/x42-plugins.git +Standards-Version: 4.4.0 +Vcs-Git: https://salsa.debian.org/multimedia-team/x42-plugins.git +Vcs-Browser: https://salsa.debian.org/multimedia-team/x42-plugins Homepage: https://github.com/x42/x42-plugins Package: x42-plugins @@ -40,13 +41,22 @@ synthesizers, in particular ingen * convoLV2 - a convolution plugin + * darc.lv2 + - a general purpose audio signal compressor + * dpl.lv2 + - a look-ahead digital peak limiter intended but not limited to the final + step of mastering or mixing * fat1.lv2 - auto-tuner based on Fons Adriaensen's zita-at1 * fil4.lv2 - a 4-band parametric EQ with graphical display - additional High/Low shelfs and Hi/Lo Pass filters + * matrixmixer.lv2 + - a matrix mixer * meters.lv2 - a collection of plugins for audio-level metering + * mididebug.lv2 + - an instrumention tool to generate arbitrary MIDI messages * midifilter.lv2 - a collection of MIDI filters * midigen.lv2 @@ -63,6 +73,8 @@ - a simple audio oscilloscope with variable time scale * stepseq.lv2 - simple step sequencer + * spectra.lv2 + - a lollipop graph spectrum analyzer * stereoroute.lv2 - stereo routing plugin * testsignal.lv2 diff -Nru x42-plugins-20170428/debian/copyright x42-plugins-20190714/debian/copyright --- x42-plugins-20170428/debian/copyright 2016-08-25 12:16:53.000000000 +0000 +++ x42-plugins-20190714/debian/copyright 2019-08-07 13:37:05.000000000 +0000 @@ -1,17 +1,17 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: X42-plugins Upstream-Contact: Robin Gareus Source: https://github.com/x42/x42-plugins Files: * -Copyright: 2013 Robin Gareus +Copyright: 2013-2019 Robin Gareus License: GPL-2+ Files: convoLV2/uris.h convoLV2/ui.c Copyright: 2011-2012 David Robillard - 2012 Robin Gareus + 2012-2019 Robin Gareus License: GPL-2+ Files: @@ -28,6 +28,10 @@ 2011-2012 Ben Loftis, Harrison Consoles License: ISC +Files: dpl.lv2/src/peaklim.* +Copyright: 2010-2018 Fons Adriensen +License: GPL-3+ + Files: debian/* Copyright: 2013-2016 Jaromír Mikeš License: GPL-2+ @@ -61,3 +65,20 @@ . You should have received a copy of the GNU General Public License along with this program. If not, see . + +License: GPL-3+ + This file 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 3 of the License, or + (at your option) any later version. + . + It 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 it. If not, see . + . + On Debian systems, the full text of the GNU General Public License version 3 + can be found in the file `/usr/share/common-licenses/GPL-3'. diff -Nru x42-plugins-20170428/debian/gitlab-ci.yml x42-plugins-20190714/debian/gitlab-ci.yml --- x42-plugins-20170428/debian/gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/debian/gitlab-ci.yml 2019-08-07 13:37:05.000000000 +0000 @@ -0,0 +1,4 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml diff -Nru x42-plugins-20170428/debian/rules x42-plugins-20190714/debian/rules --- x42-plugins-20170428/debian/rules 2017-06-25 21:31:12.000000000 +0000 +++ x42-plugins-20190714/debian/rules 2019-08-07 13:37:05.000000000 +0000 @@ -1,26 +1,13 @@ #!/usr/bin/make -f -export DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow, -pie - -export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - +export DEB_BUILD_MAINT_OPTIONS=hardening=+all +export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed export OPTIMIZATIONS= -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG +export PREFIX=/usr +export STRIP=/bin/true %: dh $@ override_dh_auto_clean: - - -override_dh_auto_configure: - dh_auto_configure -- \ - --prefix=/usr - -override_dh_auto_build: - $(MAKE) \ - PREFIX=/usr - -override_dh_auto_install: - $(MAKE) install \ - DESTDIR=$(CURDIR)/debian/x42-plugins \ - PREFIX=/usr + $(MAKE) clean || true diff -Nru x42-plugins-20170428/debian/tests/control x42-plugins-20190714/debian/tests/control --- x42-plugins-20170428/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/debian/tests/control 2019-08-07 13:37:05.000000000 +0000 @@ -0,0 +1,2 @@ +Tests: version +Depends: @ diff -Nru x42-plugins-20170428/debian/tests/version x42-plugins-20190714/debian/tests/version --- x42-plugins-20170428/debian/tests/version 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/debian/tests/version 2019-08-07 13:37:05.000000000 +0000 @@ -0,0 +1,13 @@ +#!/bin/sh + +set -eu + +x42-darc -G -V +x42-dpl -G -V +x42-fat1 -G -V +x42-fil4 -G -V +x42-matrixmixer8x8 -G -V +x42-mixtri -G -V +x42-spectr -G -V +x42-stepseq -G -V +x42-tuna -G -V diff -Nru x42-plugins-20170428/debian/upstream/metadata x42-plugins-20190714/debian/upstream/metadata --- x42-plugins-20170428/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/debian/upstream/metadata 2019-08-07 13:37:05.000000000 +0000 @@ -0,0 +1,4 @@ +--- +Name: x42-plugins +Repository: https://github.com/x42/x42-plugins.git +Repository-Browse: https://github.com/x42/x42-plugins diff -Nru x42-plugins-20170428/dpl.lv2/.clang-format x42-plugins-20190714/dpl.lv2/.clang-format --- x42-plugins-20170428/dpl.lv2/.clang-format 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/.clang-format 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,35 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlinesLeft: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine : false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: AllDefinitions +BreakBeforeBraces: Linux +ColumnLimit: 0 +IndentCaseLabels: true +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +ReflowComments: true +PointerAlignment: Left +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: Always +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Cpp11BracedListStyle: false +AccessModifierOffset: -8 +IndentWidth: 8 +TabWidth: 8 +UseTab: ForIndentation diff -Nru x42-plugins-20170428/dpl.lv2/COPYING x42-plugins-20190714/dpl.lv2/COPYING --- x42-plugins-20170428/dpl.lv2/COPYING 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/COPYING 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff -Nru x42-plugins-20170428/dpl.lv2/git2lv2.mk x42-plugins-20190714/dpl.lv2/git2lv2.mk --- x42-plugins-20170428/dpl.lv2/git2lv2.mk 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/git2lv2.mk 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,43 @@ + +############################################################################### +# extract versions +GIT_REV_REGEXP="([0-9][0-9]*)\.([0-9][0-9]*)(\.([0-9][0-9]*))?(-([0-9][0-9]*))?(-g([a-f0-9]+))?" + +override MAJOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\1/) +override MINOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\2/) +override MICRO=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\4/) +override GITREV=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\6/) + +ifeq ($(MAJOR),) + override MAJOR=0 +endif +ifeq ($(MINOR),) + override MINOR=0 +endif +ifeq ($(MICRO),) + override MICRO=0 +endif + +$(info Version: $(LV2VERSION) -> $(MAJOR) $(MINOR) $(MICRO) $(GITREV)) + +# version requirements, see +# http://lv2plug.in/ns/lv2core/#minorVersion +# http://lv2plug.in/ns/lv2core/#microVersion +ifeq ($(GITREV),) +# even numbers for tagged releases + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 ) + override LV2MIC = 0 +else +# odd-numbers for all non tagged git versions + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 + 1 ) + override LV2MIC = $(shell expr $(GITREV) \* 2 + 1) +endif + +ifeq ($(LV2MIN),) + $(error "Cannot extract required LV2 minor-version parameter") +endif +ifeq ($(LV2MIC),) + $(error "Cannot extract required LV2 micro-version parameter") +endif + +$(info LV2 Version: $(LV2MIN) $(LV2MIC)) diff -Nru x42-plugins-20170428/dpl.lv2/gui/dpl.c x42-plugins-20190714/dpl.lv2/gui/dpl.c --- x42-plugins-20170428/dpl.lv2/gui/dpl.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/gui/dpl.c 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,883 @@ +/* robtk plim gui + * + * Copyright 2016 Robin Gareus + * + * 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, 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +#include "../src/uris.h" + +#define RTK_URI PLIM_URI +#define RTK_GUI "ui" + +#ifndef MAX +#define MAX(A, B) ((A) > (B)) ? (A) : (B) +#endif + +#ifndef MIN +#define MIN(A, B) ((A) < (B)) ? (A) : (B) +#endif + +struct CtrlRange { + float min; + float max; + float dflt; + float step; + float mult; + bool log; + const char* name; +}; + +typedef struct { + LV2UI_Write_Function write; + LV2UI_Controller controller; + LV2_Atom_Forge forge; + LV2_URID_Map* map; + LV2UI_Touch* touch; + PlimLV2URIs uris; + + PangoFontDescription* font[3]; + + RobWidget* rw; // top-level container + RobWidget* ctbl; // control element table + + /* Level + reduction drawing area */ + RobWidget* m0; + int m0_width; + int m0_height; + + /* history */ + float _peak; + float _min[HISTLEN]; + float _max[HISTLEN]; + uint32_t _hist; + + RobTkDial* spn_ctrl[3]; + RobTkLbl* lbl_ctrl[3]; + + cairo_pattern_t* m_fg; + cairo_pattern_t* m_bg; + cairo_surface_t* dial_bg[3]; + + bool disable_signals; + + int tt_id; + int tt_timeout; + cairo_rectangle_t* tt_pos; + cairo_rectangle_t* tt_box; + + const char* nfo; +} PLimUI; + +const struct CtrlRange ctrl_range[] = { + { -10, 30, 0, 0.2, 5, false, "Input Gain" }, + { -10, 0, 0, 0.1, 1, false, "Threshold" }, + { .001, 1, 0.01, 150, 5, true, "Release" }, +}; + +static const char* tooltips[] = { + "Input Gain. Gain applied\nbefore peak detection or any\nother processing.\n", + + "Threshold. The maximum sample\nvalue at the output.\n", + + "Release time. Minimum recovery\ntime. Low frequency content\nmay extend this.\n", + /* + "Note that DPL1 allows short release times even on signals that\n" + "contain high level low frequency signals. Any gain reduction caused by\n" + "those will have an automatically extended hold time in order to avoid\n" + "the limiter following the shape of the waveform and create excessive distortion.\n" + "Short superimposed peaks will still have the release time as set by this control.\n", + */ +}; + +static float +ctrl_to_gui (const uint32_t c, const float v) +{ + if (!ctrl_range[c].log) { + return v; + } + const float r = logf (ctrl_range[c].max / ctrl_range[c].min); + return rintf (ctrl_range[c].step / r * (logf (v / ctrl_range[c].min))); +} + +static float +gui_to_ctrl (const uint32_t c, const float v) +{ + if (!ctrl_range[c].log) { + return v; + } + const float r = log (ctrl_range[c].max / ctrl_range[c].min); + return expf (logf (ctrl_range[c].min) + v * r / ctrl_range[c].step); +} + +static float +k_min (const uint32_t c) +{ + if (!ctrl_range[c].log) { + return ctrl_range[c].min; + } + return 0; +} + +static float +k_max (const uint32_t c) +{ + if (!ctrl_range[c].log) { + return ctrl_range[c].max; + } + return ctrl_range[c].step; +} + +static float +k_step (const uint32_t c) +{ + if (!ctrl_range[c].log) { + return ctrl_range[c].step; + } + return 1; +} + +/////////////////////////////////////////////////////////////////////////////// + +static const float c_dlf[4] = { 0.8, 0.8, 0.8, 1.0 }; // dial faceplate fg + +/////////////////////////////////////////////////////////////////////////////// + +/*** knob faceplates ***/ +static void +prepare_faceplates (PLimUI* ui) +{ + cairo_t* cr; + float xlp, ylp; + +/* clang-format off */ +#define INIT_DIAL_SF(VAR, W, H) \ + VAR = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 2 * (W), 2 * (H)); \ + cr = cairo_create (VAR); \ + cairo_scale (cr, 2.0, 2.0); \ + CairoSetSouerceRGBA (c_trs); \ + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); \ + cairo_rectangle (cr, 0, 0, W, H); \ + cairo_fill (cr); \ + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + +#define DIALDOTS(V, XADD, YADD) \ + float ang = (-.75 * M_PI) + (1.5 * M_PI) * (V); \ + xlp = GED_CX + XADD + sinf (ang) * (GED_RADIUS + 3.0); \ + ylp = GED_CY + YADD - cosf (ang) * (GED_RADIUS + 3.0); \ + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); \ + CairoSetSouerceRGBA (c_dlf); \ + cairo_set_line_width (cr, 2.5); \ + cairo_move_to (cr, rint (xlp) - .5, rint (ylp) - .5); \ + cairo_close_path (cr); \ + cairo_stroke (cr); + +#define RESPLABLEL(V) \ + { \ + DIALDOTS (V, 4.5, 15.5) \ + xlp = rint (GED_CX + 4.5 + sinf (ang) * (GED_RADIUS + 9.5)); \ + ylp = rint (GED_CY + 15.5 - cosf (ang) * (GED_RADIUS + 9.5)); \ + } + /* clang-format on */ + + INIT_DIAL_SF (ui->dial_bg[0], GED_WIDTH + 8, GED_HEIGHT + 20); + + RESPLABLEL (0.00); + write_text_full (cr, "-10", ui->font[0], xlp + 6, ylp, 0, 1, c_dlf); + RESPLABLEL (0.25); + RESPLABLEL (0.5); + write_text_full (cr, "10", ui->font[0], xlp, ylp, 0, 2, c_dlf); + RESPLABLEL (.75); + RESPLABLEL (1.0); + write_text_full (cr, "30", ui->font[0], xlp - 6, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + + INIT_DIAL_SF (ui->dial_bg[1], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "-10", ui->font[0], xlp + 6, ylp, 0, 1, c_dlf); + RESPLABLEL (.2); + RESPLABLEL (.4); + RESPLABLEL (.6); + RESPLABLEL (.8); + RESPLABLEL (1.0); + write_text_full (cr, "0", ui->font[0], xlp - 6, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + + INIT_DIAL_SF (ui->dial_bg[2], GED_WIDTH + 8, GED_HEIGHT + 20); + RESPLABLEL (0.00); + write_text_full (cr, "1ms", ui->font[0], xlp + 2, ylp, 0, 1, c_dlf); + RESPLABLEL (.16); + RESPLABLEL (.33); + write_text_full (cr, "10 ", ui->font[0], xlp, ylp, 0, 2, c_dlf); + RESPLABLEL (0.5); + RESPLABLEL (.66); + write_text_full (cr, " 0.1", ui->font[0], xlp, ylp, 0, 2, c_dlf); + RESPLABLEL (.83); + RESPLABLEL (1.0); + write_text_full (cr, "1s", ui->font[0], xlp - 2, ylp, 0, 3, c_dlf); + cairo_destroy (cr); + +#undef DIALDOTS +#undef INIT_DIAL_SF +#undef RESPLABLEL +} + +static void +display_annotation (PLimUI* ui, RobTkDial* d, cairo_t* cr, const char* txt) +{ + int tw, th; + cairo_save (cr); + PangoLayout* pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, ui->font[0]); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_translate (cr, d->w_width / 2, d->w_height - 2); + cairo_translate (cr, -tw / 2.0, -th); + cairo_set_source_rgba (cr, .0, .0, .0, .7); + rounded_rectangle (cr, -1, -1, tw + 3, th + 1, 3); + cairo_fill (cr); + CairoSetSouerceRGBA (c_wht); + pango_cairo_show_layout (cr, pl); + g_object_unref (pl); + cairo_restore (cr); + cairo_new_path (cr); +} + +static void +dial_annotation_db (RobTkDial* d, cairo_t* cr, void* data) +{ + PLimUI* ui = (PLimUI*)(data); + char txt[16]; + snprintf (txt, 16, "%5.1f dB", d->cur); + display_annotation (ui, d, cr, txt); +} + +static void +format_msec (char* txt, const float val) +{ + if (val < 0.03) { + snprintf (txt, 16, "%.1f ms", val * 1000.f); + } else if (val < 0.3) { + snprintf (txt, 16, "%.0f ms", val * 1000.f); + } else { + snprintf (txt, 16, "%.2f s", val); + } +} + +static void +dial_annotation_tm (RobTkDial* d, cairo_t* cr, void* data) +{ + PLimUI* ui = (PLimUI*)(data); + char txt[16]; + const float val = gui_to_ctrl (2, d->cur); + format_msec (txt, val); + display_annotation (ui, d, cr, txt); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*** global tooltip overlay ****/ + +static bool +tooltip_overlay (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) +{ + PLimUI* ui = (PLimUI*)rw->top; + assert (ui->tt_id >= 0 && ui->tt_id < 3); + + cairo_save (cr); + rw->resized = TRUE; + rcontainer_expose_event (rw, cr, ev); + cairo_restore (cr); + + const float top = ui->tt_box->y; + rounded_rectangle (cr, 0, top, rw->area.width, ui->tt_pos->y + 1 - top, 3); + cairo_set_source_rgba (cr, 0, 0, 0, .7); + cairo_fill (cr); + + rounded_rectangle (cr, ui->tt_pos->x + 1, ui->tt_pos->y + 1, + ui->tt_pos->width + 3, ui->tt_pos->height + 1, 3); + cairo_set_source_rgba (cr, 1, 1, 1, .5); + cairo_fill (cr); + + const float* color = c_wht; + PangoFontDescription* font = pango_font_description_from_string ("Sans 11px"); + + const float xp = rw->area.width * .5; + const float yp = rw->area.height * .5; + + cairo_save (cr); + cairo_scale (cr, rw->widget_scale, rw->widget_scale); + write_text_full (cr, tooltips[ui->tt_id], font, + xp / rw->widget_scale, yp / rw->widget_scale, + 0, 2, color); + cairo_restore (cr); + + pango_font_description_free (font); + return TRUE; +} + +static bool +tooltip_cnt (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) +{ + PLimUI* ui = (PLimUI*)rw->top; + if (++ui->tt_timeout < 8) { + rcontainer_expose_event (rw, cr, ev); + queue_draw (rw); + } else { + rw->expose_event = tooltip_overlay; + rw->resized = TRUE; + tooltip_overlay (rw, cr, ev); + } + return TRUE; +} + +static void +ttip_handler (RobWidget* rw, bool on, void* handle) +{ + PLimUI* ui = (PLimUI*)handle; + ui->tt_id = -1; + ui->tt_timeout = 0; + + for (int i = 0; i < 3; ++i) { + if (rw == ui->lbl_ctrl[i]->rw) { + ui->tt_id = i; + break; + } + } + + if (on && ui->tt_id >= 0) { + ui->tt_pos = &rw->area; + ui->tt_box = &ui->spn_ctrl[0]->rw->area; + ui->ctbl->expose_event = tooltip_cnt; + ui->ctbl->resized = TRUE; + queue_draw (ui->ctbl); + } else { + ui->ctbl->expose_event = rcontainer_expose_event; + ui->ctbl->parent->resized = TRUE; //full re-expose + queue_draw (ui->rw); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +/*** knob & button callbacks ****/ + +static bool +cb_spn_ctrl (RobWidget* w, void* handle) +{ + PLimUI* ui = (PLimUI*)handle; + if (ui->disable_signals) + return TRUE; + + for (uint32_t i = 0; i < 3; ++i) { + if (w != ui->spn_ctrl[i]->rw) { + continue; + } + const float val = gui_to_ctrl (i, robtk_dial_get_value (ui->spn_ctrl[i])); + ui->write (ui->controller, PLIM_GAIN + i, sizeof (float), 0, (const void*)&val); + break; + } + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// + +static void +m0_size_request (RobWidget* handle, int* w, int* h) +{ + *w = 320; + *h = 80; +} + +static void +m0_size_allocate (RobWidget* handle, int w, int h) +{ + PLimUI* ui = (PLimUI*)GET_HANDLE (handle); + ui->m0_width = w; + ui->m0_height = h; + robwidget_set_size (ui->m0, w, h); + + if (ui->m_fg) { + cairo_pattern_destroy (ui->m_fg); + } + if (ui->m_bg) { + cairo_pattern_destroy (ui->m_bg); + } + ui->m_fg = ui->m_bg = NULL; + + if (1) { + int scale = MIN (w / 180, h / 80); + pango_font_description_free (ui->font[1]); + pango_font_description_free (ui->font[2]); + char fnt[32]; + snprintf (fnt, 32, "Mono %.0fpx\n", 10 * sqrtf (scale)); + ui->font[1] = pango_font_description_from_string (fnt); + snprintf (fnt, 32, "Mono Bold %.0fpx\n", 12 * sqrtf (scale)); + ui->font[2] = pango_font_description_from_string (fnt); + } + + queue_draw (ui->m0); +} + +static bool +m0_expose_event (RobWidget* handle, cairo_t* cr, cairo_rectangle_t* ev) +{ + PLimUI* ui = (PLimUI*)GET_HANDLE (handle); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); + cairo_clip_preserve (cr); + + float c[4]; + get_color_from_theme (1, c); + cairo_set_source_rgb (cr, c[0], c[1], c[2]); + cairo_fill (cr); + + const uint32_t yscale = ui->m0_height / 80; + const uint32_t top = (ui->m0_height - 80 * yscale) * .5; + const uint32_t disp_w = ui->m0_width - 20; // deafult: 300 +#define YPOS(y) (top + yscale * (y)) +#define HGHT(y) (yscale * (y)) + + CairoSetSouerceRGBA (c_blk); + rounded_rectangle (cr, 0, top, ui->m0_width, HGHT (80), 6); + cairo_fill_preserve (cr); + cairo_clip (cr); + +#define DEF(x) MAX (0, MIN (1., ((10. + (x)) / 30.))) +#define DEFLECT(x) (disp_w * DEF (x)) +#define PX (1.0 / (disp_w - 10.)) + + if (!ui->m_fg) { + cairo_pattern_t* pat = cairo_pattern_create_linear (10, 0.0, disp_w, 0.0); + cairo_pattern_add_color_stop_rgb (pat, DEF (-10), .0, .8, .0); + cairo_pattern_add_color_stop_rgb (pat, DEF (0), .0, .8, .0); + cairo_pattern_add_color_stop_rgb (pat, DEF (0) + PX, .7, .7, .0); + cairo_pattern_add_color_stop_rgb (pat, DEF (5), .7, .7, .0); + cairo_pattern_add_color_stop_rgb (pat, DEF (20), .9, .0, .0); + ui->m_fg = pat; + } + + if (!ui->m_bg) { + const float alpha = 0.5; + cairo_pattern_t* pat = cairo_pattern_create_linear (10, 0.0, disp_w, 0.0); + cairo_pattern_add_color_stop_rgba (pat, DEF (-10), .0, .8, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (0), .0, .8, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (0) + PX, .7, .7, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (5), .7, .7, .0, alpha); + cairo_pattern_add_color_stop_rgba (pat, DEF (20), .9, .0, .0, alpha); + ui->m_bg = pat; + } + + /* meter background */ + cairo_set_source (cr, ui->m_bg); + cairo_rectangle (cr, 5, YPOS (68), disp_w + 10, HGHT (8)); + cairo_fill (cr); + + cairo_set_line_width (cr, yscale); + cairo_set_source (cr, ui->m_fg); + + /* reduction history */ + for (int i = 0; i < HISTLEN; ++i) { + int p = (i + ui->_hist) % HISTLEN; + + const int x0 = DEFLECT (-20.0f * log10f (ui->_max[p])); + const int x1 = DEFLECT (-20.0f * log10f (ui->_min[p])); + + cairo_move_to (cr, 9 + x0, YPOS (i + .5)); + cairo_line_to (cr, 10 + x1, YPOS (i + .5)); + + cairo_stroke (cr); + } + + /* current reduction */ + if (ui->_peak > -10) { + cairo_rectangle (cr, 5, YPOS (68), 5 + DEFLECT (ui->_peak), HGHT (8)); + cairo_fill (cr); + } + + // TODO: cache this background + + /* meter ticks */ + cairo_set_line_width (cr, 1); + CairoSetSouerceRGBA (c_wht); + for (int i = 0; i < 7; ++i) { + int dbx = DEFLECT (-10 + i * 5); + cairo_move_to (cr, 9.5 + dbx, YPOS (68)); + cairo_line_to (cr, 9.5 + dbx, YPOS (76)); + cairo_stroke (cr); + + if (i > 0) { + int tw, th; + PangoLayout* pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, ui->font[1]); + if (i > 1) { + char txt[16]; + snprintf (txt, 16, "-%d ", (i - 2) * 5); + pango_layout_set_text (pl, txt, -1); + } else { + pango_layout_set_text (pl, "Gain Reduction:", -1); + } + CairoSetSouerceRGBA (c_dlf); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, 9.5 + dbx - tw * .5, YPOS (68) - th); + pango_cairo_show_layout (cr, pl); + g_object_unref (pl); + } + } + + /* numeric display */ + if (1) { + int tw, th; + char txt[16]; + int y0 = top; + PangoLayout* pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, ui->font[2]); + + snprintf (txt, 16, "%5.1f dB", robtk_dial_get_value (ui->spn_ctrl[0])); + cairo_set_source_rgb (cr, .6, .6, .1); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, DEFLECT (-1) - tw, y0 + th * .5); + pango_cairo_show_layout (cr, pl); + y0 += th; + + snprintf (txt, 16, "%5.1f dB", robtk_dial_get_value (ui->spn_ctrl[1])); + cairo_set_source_rgb (cr, .7, .2, .2); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, DEFLECT (-1) - tw, y0 + th * .5); + pango_cairo_show_layout (cr, pl); + y0 += th; + + const float val = gui_to_ctrl (2, robtk_dial_get_value (ui->spn_ctrl[2])); + format_msec (txt, val); + + cairo_set_source_rgb (cr, .2, .2, .7); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, DEFLECT (-1) - tw, y0 + th * .5); + pango_cairo_show_layout (cr, pl); + + g_object_unref (pl); + } + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// + +static RobWidget* +toplevel (PLimUI* ui, void* const top) +{ + /* main widget: layout */ + ui->rw = rob_hbox_new (FALSE, 2); + robwidget_make_toplevel (ui->rw, top); + robwidget_toplevel_enable_scaling (ui->rw); + + ui->font[0] = pango_font_description_from_string ("Mono 9px"); + ui->font[1] = pango_font_description_from_string ("Mono 10px"); + ui->font[2] = pango_font_description_from_string ("Mono Bold 12px"); + + prepare_faceplates (ui); + + /* graph display */ + ui->m0 = robwidget_new (ui); + robwidget_set_alignment (ui->m0, .5, .5); + robwidget_set_expose_event (ui->m0, m0_expose_event); + robwidget_set_size_request (ui->m0, m0_size_request); + robwidget_set_size_allocate (ui->m0, m0_size_allocate); + + ui->ctbl = rob_table_new (/*rows*/ 2, /*cols*/ 3, FALSE); + ui->ctbl->top = (void*)ui; + +#define GSP_W(PTR) robtk_dial_widget (PTR) +#define GLB_W(PTR) robtk_lbl_widget (PTR) +#define GSL_W(PTR) robtk_select_widget (PTR) + + for (uint32_t i = 0; i < 3; ++i) { + ui->lbl_ctrl[i] = robtk_lbl_new (ctrl_range[i].name); + ui->spn_ctrl[i] = robtk_dial_new_with_size ( + k_min (i), k_max (i), k_step (i), + GED_WIDTH + 8, GED_HEIGHT + 20, GED_CX + 4, GED_CY + 15, GED_RADIUS); + ui->spn_ctrl[i]->with_scroll_accel = false; + + robtk_dial_set_callback (ui->spn_ctrl[i], cb_spn_ctrl, ui); + robtk_dial_set_value (ui->spn_ctrl[i], ctrl_to_gui (i, ctrl_range[i].dflt)); + robtk_dial_set_default (ui->spn_ctrl[i], ctrl_to_gui (i, ctrl_range[i].dflt)); + robtk_dial_set_scroll_mult (ui->spn_ctrl[i], ctrl_range[i].mult); + + if (ui->touch) { + robtk_dial_set_touch (ui->spn_ctrl[i], ui->touch->touch, ui->touch->handle, PLIM_GAIN + i); + } + + robtk_dial_set_scaled_surface_scale (ui->spn_ctrl[i], ui->dial_bg[i], 2.0); + + robtk_lbl_annotation_callback (ui->lbl_ctrl[i], ttip_handler, ui); + + rob_table_attach (ui->ctbl, GSP_W (ui->spn_ctrl[i]), i, i + 1, 0, 1, 4, 0, RTK_EXANDF, RTK_SHRINK); + rob_table_attach (ui->ctbl, GLB_W (ui->lbl_ctrl[i]), i, i + 1, 1, 2, 4, 0, RTK_EXANDF, RTK_SHRINK); + } + + ui->spn_ctrl[2]->displaymode = 3; // use dot + robtk_dial_set_detent_default (ui->spn_ctrl[0], true); + + /* these numerics are meaningful */ + robtk_dial_annotation_callback (ui->spn_ctrl[0], dial_annotation_db, ui); + robtk_dial_annotation_callback (ui->spn_ctrl[1], dial_annotation_db, ui); + robtk_dial_annotation_callback (ui->spn_ctrl[2], dial_annotation_tm, ui); + + /* some custom colors */ + { + const float c_bg[4] = { .6, .6, .1, 1.0 }; + create_dial_pattern (ui->spn_ctrl[0], c_bg); + ui->spn_ctrl[0]->dcol[0][0] = + ui->spn_ctrl[0]->dcol[0][1] = + ui->spn_ctrl[0]->dcol[0][2] = .05; + } + { + const float c_bg[4] = { .7, .2, .2, 1.0 }; + create_dial_pattern (ui->spn_ctrl[1], c_bg); + ui->spn_ctrl[1]->dcol[0][0] = + ui->spn_ctrl[1]->dcol[0][1] = + ui->spn_ctrl[1]->dcol[0][2] = .05; + } + { + const float c_bg[4] = { .2, .2, .7, 1.0 }; + create_dial_pattern (ui->spn_ctrl[2], c_bg); + ui->spn_ctrl[2]->dcol[0][0] = + ui->spn_ctrl[2]->dcol[0][1] = + ui->spn_ctrl[2]->dcol[0][2] = .05; + } + + /* top-level packing */ + rob_hbox_child_pack (ui->rw, ui->ctbl, FALSE, TRUE); + rob_hbox_child_pack (ui->rw, ui->m0, TRUE, TRUE); + return ui->rw; +} + +static void +gui_cleanup (PLimUI* ui) +{ + for (int i = 0; i < 3; ++i) { + robtk_dial_destroy (ui->spn_ctrl[i]); + robtk_lbl_destroy (ui->lbl_ctrl[i]); + cairo_surface_destroy (ui->dial_bg[i]); + } + + pango_font_description_free (ui->font[0]); + pango_font_description_free (ui->font[1]); + pango_font_description_free (ui->font[2]); + + if (ui->m_fg) { + cairo_pattern_destroy (ui->m_fg); + } + if (ui->m_bg) { + cairo_pattern_destroy (ui->m_bg); + } + + robwidget_destroy (ui->m0); + rob_table_destroy (ui->ctbl); + rob_box_destroy (ui->rw); +} + +/****************************************************************************** + * RobTk + LV2 + */ + +static void +tx_state (PLimUI* ui) +{ + uint8_t obj_buf[1024]; + lv2_atom_forge_set_buffer (&ui->forge, obj_buf, 1024); + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&ui->forge, 0); + LV2_Atom* msg = (LV2_Atom*)x_forge_object (&ui->forge, &frame, 1, ui->uris.state); + + lv2_atom_forge_property_head (&ui->forge, ui->uris.s_uiscale, 0); + lv2_atom_forge_float (&ui->forge, ui->rw->widget_scale); + + lv2_atom_forge_pop (&ui->forge, &frame); + ui->write (ui->controller, PLIM_ATOM_CONTROL, lv2_atom_total_size (msg), ui->uris.atom_eventTransfer, msg); +} + +#define LVGL_RESIZEABLE + +static void +ui_enable (LV2UI_Handle handle) +{ + PLimUI* ui = (PLimUI*)handle; + + uint8_t obj_buf[64]; + lv2_atom_forge_set_buffer (&ui->forge, obj_buf, 64); + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&ui->forge, 0); + LV2_Atom* msg = (LV2_Atom*)x_forge_object (&ui->forge, &frame, 1, ui->uris.ui_on); + lv2_atom_forge_pop (&ui->forge, &frame); + ui->write (ui->controller, PLIM_ATOM_CONTROL, lv2_atom_total_size (msg), ui->uris.atom_eventTransfer, msg); +} + +static void +ui_disable (LV2UI_Handle handle) +{ + PLimUI* ui = (PLimUI*)handle; + + tx_state (ui); // too late? + + uint8_t obj_buf[64]; + lv2_atom_forge_set_buffer (&ui->forge, obj_buf, 64); + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&ui->forge, 0); + LV2_Atom* msg = (LV2_Atom*)x_forge_object (&ui->forge, &frame, 1, ui->uris.ui_off); + lv2_atom_forge_pop (&ui->forge, &frame); + ui->write (ui->controller, PLIM_ATOM_CONTROL, lv2_atom_total_size (msg), ui->uris.atom_eventTransfer, msg); +} + +static enum LVGLResize +plugin_scale_mode (LV2UI_Handle handle) +{ + return LVGL_LAYOUT_TO_FIT; +} + +static LV2UI_Handle +instantiate ( + void* const ui_toplevel, + const LV2UI_Descriptor* descriptor, + const char* plugin_uri, + const char* bundle_path, + LV2UI_Write_Function write_function, + LV2UI_Controller controller, + RobWidget** widget, + const LV2_Feature* const* features) +{ + PLimUI* ui = (PLimUI*)calloc (1, sizeof (PLimUI)); + if (!ui) { + return NULL; + } + + if (strcmp (plugin_uri, RTK_URI "mono") && strcmp (plugin_uri, RTK_URI "stereo")) { + free (ui); + return NULL; + } + + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_URID_URI "#map")) { + ui->map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_UI__touch)) { + ui->touch = (LV2UI_Touch*)features[i]->data; + } + } + + if (!ui->map) { + fprintf (stderr, "dpl.lv2 UI: Host does not support urid:map\n"); + free (ui); + return NULL; + } + + ui->nfo = robtk_info (ui_toplevel); + ui->write = write_function; + ui->controller = controller; + ui->disable_signals = true; + + map_plim_uris (ui->map, &ui->uris); + lv2_atom_forge_init (&ui->forge, ui->map); + + *widget = toplevel (ui, ui_toplevel); + ui->disable_signals = false; + return ui; +} + +static void +cleanup (LV2UI_Handle handle) +{ + PLimUI* ui = (PLimUI*)handle; + gui_cleanup (ui); + free (ui); +} + +/* receive information from DSP */ +static void +port_event (LV2UI_Handle handle, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer) +{ + PLimUI* ui = (PLimUI*)handle; + + if (format == ui->uris.atom_eventTransfer && port_index == PLIM_ATOM_NOTIFY) { + LV2_Atom* atom = (LV2_Atom*)buffer; + if (atom->type != ui->uris.atom_Blank && atom->type != ui->uris.atom_Object) { + return; + } + LV2_Atom_Object* obj = (LV2_Atom_Object*)atom; + + if (obj->body.otype == ui->uris.state) { + const LV2_Atom* a0 = NULL; + if (1 == lv2_atom_object_get (obj, ui->uris.s_uiscale, &a0, NULL) && a0) { + const float sc = ((LV2_Atom_Float*)a0)->body; + if (sc != ui->rw->widget_scale && sc >= 1.0 && sc <= 2.0) { + robtk_queue_scale_change (ui->rw, sc); + } + } + } else if (obj->body.otype == ui->uris.history) { + const LV2_Atom* a0 = NULL; + const LV2_Atom* a1 = NULL; + const LV2_Atom* a2 = NULL; + if (3 == lv2_atom_object_get (obj, ui->uris.position, &a0, ui->uris.minvals, &a1, ui->uris.maxvals, &a2, NULL) && a0 && a1 && a2 && a0->type == ui->uris.atom_Int && a1->type == ui->uris.atom_Vector && a2->type == ui->uris.atom_Vector) { + ui->_hist = ((LV2_Atom_Int*)a0)->body; + + LV2_Atom_Vector* mins = (LV2_Atom_Vector*)LV2_ATOM_BODY (a1); + assert (mins->atom.type == ui->uris.atom_Float); + assert (HISTLEN == (a2->size - sizeof (LV2_Atom_Vector_Body)) / mins->atom.size); + + LV2_Atom_Vector* maxs = (LV2_Atom_Vector*)LV2_ATOM_BODY (a2); + assert (maxs->atom.type == ui->uris.atom_Float); + assert (HISTLEN == (a2->size - sizeof (LV2_Atom_Vector_Body)) / maxs->atom.size); + + memcpy (ui->_min, (float*)LV2_ATOM_BODY (&mins->atom), sizeof (float) * HISTLEN); + memcpy (ui->_max, (float*)LV2_ATOM_BODY (&maxs->atom), sizeof (float) * HISTLEN); + queue_draw (ui->m0); + } + } + return; + } + + if (format != 0) { + return; + } + + if (port_index == PLIM_LEVEL) { + ui->_peak = *(float*)buffer; + queue_draw (ui->m0); + } else if (port_index >= PLIM_GAIN && port_index <= PLIM_RELEASE) { + const float v = *(float*)buffer; + ui->disable_signals = true; + uint32_t ctrl = port_index - PLIM_GAIN; + robtk_dial_set_value (ui->spn_ctrl[ctrl], ctrl_to_gui (ctrl, v)); + ui->disable_signals = false; + } +} + +static const void* +extension_data (const char* uri) +{ + return NULL; +} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/dpl.lv2/img/dpl1.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/dpl.lv2/img/dpl1.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/dpl.lv2/img/x42-dpl.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/dpl.lv2/img/x42-dpl.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/dpl.lv2/img/x42-dpl.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/dpl.lv2/img/x42-dpl.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/dpl.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/dpl.lv2/img/x42.ico differ diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.gui.in x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.gui.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.gui.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,7 @@ + +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + @UI_REQ@ + lv2:requiredFeature urid:map ; + . + diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl_mono.h x42-plugins-20190714/dpl.lv2/lv2ttl/dpl_mono.h --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl_mono.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl_mono.h 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,39 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/dpl#mono + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _plugin_mono = { + &lv2_descriptor, + &lv2ui_descriptor + , 0 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "x42-dpl - Digital Peak Limiter Mono" // const char *plugin_human_id + , (const struct LV2Port[10]) + { + { "control", ATOM_IN, nan, nan, nan, "UI to plugin communication"}, + { "notify", ATOM_OUT, nan, nan, nan, "Plugin to GUI communication"}, + { "enable", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Enable"}, + { "gain", CONTROL_IN, 0.000000, -10.000000, 30.000000, "Input Gain"}, + { "threshold", CONTROL_IN, 0.000000, -10.000000, 0.000000, "Threshold"}, + { "release", CONTROL_IN, 0.010000, 0.001000, 1.000000, "Release Time"}, + { "level", CONTROL_OUT, nan, -10.000000, 20.000000, "Signal Level"}, + { "latency", CONTROL_OUT, nan, 0.000000, 1024.000000, "Signal Latency"}, + { "in", AUDIO_IN, nan, nan, nan, "In"}, + { "out", AUDIO_OUT, nan, nan, nan, "Out"}, + } + , 10 // uint32_t nports_total + , 1 // uint32_t nports_audio_in + , 1 // uint32_t nports_audio_out + , 0 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 1 // uint32_t nports_atom_in + , 1 // uint32_t nports_atom_out + , 6 // uint32_t nports_ctrl + , 4 // uint32_t nports_ctrl_in + , 2 // uint32_t nports_ctrl_out + , 65888 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , 7 // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.mono.ttl.in x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.mono.ttl.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.mono.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.mono.ttl.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,14 @@ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 8 ; + lv2:symbol "in" ; + lv2:name "In" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 9 ; + lv2:symbol "out" ; + lv2:name "Out" + ] ; + rdfs:comment "Mono look-ahead digital peak limiter" + . diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.ports.ttl.in x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.ports.ttl.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.ports.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.ports.ttl.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,95 @@ + +@LV2NAME@:@URISUFFIX@ + a lv2:Plugin, doap:Project, lv2:LimiterPlugin; + doap:license ; + doap:maintainer ; + @VERSION@ + doap:name "x42-dpl - Digital Peak Limiter@NAMESUFFIX@"; + lv2:requiredFeature urid:map ; + lv2:extensionData idpy:interface, state:interface @SIGNATURE@; + lv2:optionalFeature lv2:hardRTCapable, idpy:queue_draw, opts:options ; + opts:supportedOption ; + @UITTL@ + lv2:port [ + a atom:AtomPort , + lv2:InputPort ; + atom:bufferType atom:Sequence ; + lv2:designation lv2:control ; + lv2:index 0 ; + lv2:symbol "control" ; + lv2:name "control" ; + rdfs:comment "UI to plugin communication" + ] , [ + a atom:AtomPort , + lv2:OutputPort ; + atom:bufferType atom:Sequence ; + lv2:designation lv2:control ; + lv2:index 1 ; + lv2:symbol "notify" ; + lv2:name "Notify" ; + rsz:minimumSize @CTLSIZE@; + rdfs:comment "Plugin to GUI communication" + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 2 ; + lv2:symbol "enable" ; + lv2:name "Enable"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + lv2:designation lv2:enabled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 3 ; + lv2:symbol "gain" ; + lv2:name "Input Gain" ; + lv2:default 0.0 ; + lv2:minimum -10.0 ; + lv2:maximum 30.0; + pprop:rangeSteps 201; + units:unit units:db ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 4 ; + lv2:symbol "threshold" ; + lv2:name "Threshold" ; + lv2:default 0.0 ; + lv2:minimum -10.0 ; + lv2:maximum 0.0; + pprop:rangeSteps 101; + units:unit units:db ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 5 ; + lv2:symbol "release" ; + lv2:name "Release Time"; + lv2:default 0.01 ; + lv2:minimum 0.001 ; + lv2:maximum 1.0 ; + lv2:portProperty pprop:logarithmic; + pprop:rangeSteps 151; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 6 ; + lv2:symbol "level" ; + lv2:name "Signal Level" ; + lv2:minimum -10.0 ; + lv2:maximum 20.0; + units:unit units:db ; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 7 ; + lv2:symbol "latency" ; + lv2:name "Signal Latency" ; + lv2:minimum 0 ; + lv2:maximum 1024; + lv2:portProperty lv2:reportsLatency, lv2:integer; + units:unit units:frame; + ] , [ diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl_stereo.h x42-plugins-20190714/dpl.lv2/lv2ttl/dpl_stereo.h --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl_stereo.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl_stereo.h 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,41 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/dpl#stereo + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _plugin_stereo = { + &lv2_descriptor, + &lv2ui_descriptor + , 1 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "x42-dpl - Digital Peak Limiter Stereo" // const char *plugin_human_id + , (const struct LV2Port[12]) + { + { "control", ATOM_IN, nan, nan, nan, "UI to plugin communication"}, + { "notify", ATOM_OUT, nan, nan, nan, "Plugin to GUI communication"}, + { "enable", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Enable"}, + { "gain", CONTROL_IN, 0.000000, -10.000000, 30.000000, "Input Gain"}, + { "threshold", CONTROL_IN, 0.000000, -10.000000, 0.000000, "Threshold"}, + { "release", CONTROL_IN, 0.010000, 0.001000, 1.000000, "Release Time"}, + { "level", CONTROL_OUT, nan, -10.000000, 20.000000, "Signal Level"}, + { "latency", CONTROL_OUT, nan, 0.000000, 1024.000000, "Signal Latency"}, + { "inL", AUDIO_IN, nan, nan, nan, "In Left"}, + { "outL", AUDIO_OUT, nan, nan, nan, "Out Left"}, + { "inR", AUDIO_IN, nan, nan, nan, "In Right"}, + { "outR", AUDIO_OUT, nan, nan, nan, "Out Right"}, + } + , 12 // uint32_t nports_total + , 2 // uint32_t nports_audio_in + , 2 // uint32_t nports_audio_out + , 0 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 1 // uint32_t nports_atom_in + , 1 // uint32_t nports_atom_out + , 6 // uint32_t nports_ctrl + , 4 // uint32_t nports_ctrl_in + , 2 // uint32_t nports_ctrl_out + , 131424 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , 7 // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.stereo.ttl.in x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.stereo.ttl.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.stereo.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.stereo.ttl.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,26 @@ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 8 ; + lv2:symbol "inL" ; + lv2:name "In Left" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 9 ; + lv2:symbol "outL" ; + lv2:name "Out Left" + ] , [ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 10 ; + lv2:symbol "inR" ; + lv2:name "In Right" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 11 ; + lv2:symbol "outR" ; + lv2:name "Out Right" + ] ; + rdfs:comment "Stereo look-ahead digital peak limiter" + . diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.ttl.in x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.ttl.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/dpl.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/dpl.ttl.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,27 @@ +@prefix atom: . +@prefix doap: . +@prefix foaf: . +@prefix idpy: . +@prefix kx: . +@prefix lv2: . +@prefix mod: . +@prefix opts: . +@prefix pprop: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsz: . +@prefix state: . +@prefix ui: . +@prefix units: . +@prefix urid: . + +idpy:queue_draw a lv2:Feature . +idpy:interface a lv2:ExtensionData . + +@prefix @LV2NAME@: . + + + a foaf:Person ; + foaf:name "Robin Gareus" ; + foaf:mbox ; + foaf:homepage . diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/manifest.gui.in x42-plugins-20190714/dpl.lv2/lv2ttl/manifest.gui.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/manifest.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/manifest.gui.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,6 @@ + +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + ui:binary <@LV2GUI@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . + diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/manifest.ttl.in x42-plugins-20190714/dpl.lv2/lv2ttl/manifest.ttl.in --- x42-plugins-20170428/dpl.lv2/lv2ttl/manifest.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/manifest.ttl.in 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,17 @@ +@prefix kx: . +@prefix lv2: . +@prefix modgui: . +@prefix rdfs: . +@prefix ui: . + +@prefix @LV2NAME@: . + +@LV2NAME@:mono + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . + +@LV2NAME@:stereo + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/dpl.lv2/lv2ttl/plugins.h x42-plugins-20190714/dpl.lv2/lv2ttl/plugins.h --- x42-plugins-20170428/dpl.lv2/lv2ttl/plugins.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/lv2ttl/plugins.h 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,12 @@ +#define MULTIPLUGIN 1 +#define X42_MULTIPLUGIN_NAME "Peak Limiter" +#define X42_MULTIPLUGIN_URI "http://gareus.org/oss/lv2/dpl" + +#include "lv2ttl/dpl_mono.h" +#include "lv2ttl/dpl_stereo.h" + +static const RtkLv2Description _plugins[] = { + _plugin_stereo, + _plugin_mono, +}; + diff -Nru x42-plugins-20170428/dpl.lv2/Makefile x42-plugins-20190714/dpl.lv2/Makefile --- x42-plugins-20170428/dpl.lv2/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/Makefile 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,323 @@ +#!/usr/bin/make -f + +# these can be overridden using make variables. e.g. +# make CFLAGS=-O2 +# make install DESTDIR=$(CURDIR)/debian/dpl.lv2 PREFIX=/usr +# +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +MANDIR ?= $(PREFIX)/share/man/man1 +# see http://lv2plug.in/pages/filesystem-hierarchy-standard.html, don't use libdir +LV2DIR ?= $(PREFIX)/lib/lv2 + +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG +CXXFLAGS ?= -Wall -g -Wno-unused-function + +PKG_CONFIG?=pkg-config +STRIP?= strip + +BUILDOPENGL?=yes +BUILDJACKAPP?=yes + +dpl_VERSION ?= $(shell (git describe --tags HEAD || echo "0") | sed 's/-g.*$$//;s/^v//') +RW ?= robtk/ + +############################################################################### + +BUILDDIR = build/ +APPBLD = x42/ + +############################################################################### + +LV2NAME=dpl +LV2GUI=dplUI_gl +BUNDLE=dpl.lv2 +targets= + +LOADLIBES=-lm +LV2UIREQ= +GLUICFLAGS=-I. + +UNAME=$(shell uname) +ifeq ($(UNAME),Darwin) + LV2LDFLAGS=-dynamiclib + LIB_EXT=.dylib + EXE_EXT= + UI_TYPE=ui:CocoaUI + PUGL_SRC=$(RW)pugl/pugl_osx.m + PKG_GL_LIBS= + GLUILIBS=-framework Cocoa -framework OpenGL -framework CoreFoundation + STRIPFLAGS=-u -r -arch all -s $(RW)lv2syms + EXTENDED_RE=-E +else + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.so + EXE_EXT= + UI_TYPE=ui:X11UI + PUGL_SRC=$(RW)pugl/pugl_x11.c + PKG_GL_LIBS=glu gl + GLUILIBS=-lX11 + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` + STRIPFLAGS= -s + EXTENDED_RE=-r +endif + +ifneq ($(XWIN),) + CC=$(XWIN)-gcc + CXX=$(XWIN)-g++ + STRIP=$(XWIN)-strip + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.dll + EXE_EXT=.exe + PUGL_SRC=$(RW)pugl/pugl_win.cpp + PKG_GL_LIBS= + UI_TYPE=ui:WindowsUI + GLUILIBS=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread + GLUICFLAGS=-I. + override LDFLAGS += -static-libgcc -static-libstdc++ +endif + +ifeq ($(EXTERNALUI), yes) + UI_TYPE= +endif + +ifeq ($(UI_TYPE),) + UI_TYPE=kx:Widget + LV2UIREQ+=lv2:requiredFeature kx:Widget; + override CXXFLAGS += -DXTERNAL_UI +endif + +targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +UITTL= +ifneq ($(BUILDOPENGL), no) + targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) + UITTL=ui:ui $(LV2NAME):ui_gl ; +endif + +############################################################################### +# extract versions +LV2VERSION=$(dpl_VERSION) +include git2lv2.mk + +############################################################################### +# check for build-dependencies + +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) + $(error "LV2 SDK was not found") +endif + +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) + $(error "LV2 SDK needs to be version 1.6.0 or later") +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") + endif +endif + +ifneq ($(BUILDJACKAPP), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) + $(warning *** libjack from http://jackaudio.org is required) + $(error Please install libjack-dev or libjack-jackd2-dev) + endif + JACKAPP=$(APPBLD)x42-dpl$(EXE_EXT) +endif + +# check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) + override CXXFLAGS += -DHAVE_LV2_1_8 +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifneq ($(MAKECMDGOALS), submodules) + ifeq ($(wildcard $(RW)robtk.mk),) + $(warning "**********************************************************") + $(warning This plugin needs https://github.com/x42/robtk) + $(warning "**********************************************************") + $(info ) + $(info set the RW environment variale to the location of the robtk headers) + ifeq ($(wildcard .git),.git) + $(info or run 'make submodules' to initialize robtk as git submodule) + endif + $(info ) + $(warning "**********************************************************") + $(error robtk not found) + endif + endif +endif + +# LV2 idle >= lv2-1.6.0 +GLUICFLAGS+=-DHAVE_IDLE_IFACE +LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; + +# add library dependent flags and libs +override CXXFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(dpl_VERSION)\"" +override CXXFLAGS += `$(PKG_CONFIG) --cflags lv2` +ifeq ($(XWIN),) +override CXXFLAGS += -fPIC -fvisibility=hidden +else +override CXXFLAGS += -DPTW32_STATIC_LIB +endif + +ifneq ($(INLINEDISPLAY),no) + override CXXFLAGS += `$(PKG_CONFIG) --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE + override LOADLIBES += `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango` + ifneq ($(XWIN),) + override LOADLIBES += -lpthread -lusp10 + endif +endif + +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` $(CXXFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` + +ifneq ($(XWIN),) +GLUILIBS+=-lpthread -lusp10 +endif + +GLUICFLAGS+=$(LIC_CFLAGS) +GLUILIBS+=$(LIC_LOADLIBES) + +#GLUICFLAGS+=-DUSE_GUI_THREAD +ifeq ($(GLTHREADSYNC), yes) + GLUICFLAGS+=-DTHREADSYNC +endif + +ifneq ($(LIC_CFLAGS),) + LV2SIGN=, + override CXXFLAGS += -I$(RW) +endif + +ROBGL+= Makefile + +JACKCFLAGS=-I. $(CXXFLAGS) $(LIC_CFLAGS) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) + + +############################################################################### +# build target definitions +default: all + +submodule_pull: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_pull + +submodule_update: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_update + +submodule_check: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_check + +submodules: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodules + +all: submodule_check $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets) $(JACKAPP) + +$(BUILDDIR)manifest.ttl: lv2ttl/manifest.ttl.in lv2ttl/manifest.gui.in Makefile + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/" \ + lv2ttl/manifest.ttl.in > $(BUILDDIR)manifest.ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/;s/@UI_TYPE@/$(UI_TYPE)/;s/@LV2GUI@/$(LV2GUI)/g" \ + lv2ttl/manifest.gui.in >> $(BUILDDIR)manifest.ttl +endif + +$(BUILDDIR)$(LV2NAME).ttl: Makefile lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).gui.in \ + lv2ttl/$(LV2NAME).ports.ttl.in lv2ttl/$(LV2NAME).mono.ttl.in lv2ttl/$(LV2NAME).stereo.ttl.in + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g" \ + lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ + lv2ttl/$(LV2NAME).gui.in >> $(BUILDDIR)$(LV2NAME).ttl +endif + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/mono/;s/@NAMESUFFIX@/ Mono/;s/@CTLSIZE@/1024/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/" \ + lv2ttl/$(LV2NAME).ports.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + cat lv2ttl/$(LV2NAME).mono.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/stereo/;s/@NAMESUFFIX@/ Stereo/;s/@CTLSIZE@/1024/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/" \ + lv2ttl/$(LV2NAME).ports.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + cat lv2ttl/$(LV2NAME).stereo.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + +DSP_SRC = src/lv2.cc src/peaklim.cc +DSP_DEPS = $(DSP_SRC) src/uris.h src/peaklim.h +GUI_DEPS = gui/dpl.c src/uris.h + +$(BUILDDIR)$(LV2NAME)$(LIB_EXT): $(DSP_DEPS) Makefile + @mkdir -p $(BUILDDIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LIC_CFLAGS)\ + -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DSP_SRC) \ + -shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES) $(LIC_LOADLIBES) + $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +jackapps: $(JACKAPP) + +$(eval x42_dpl_JACKSRC = -DX42_MULTIPLUGIN src/lv2.cc src/peaklim.cc) +x42_dpl_JACKGUI = gui/dpl.c +x42_dpl_LV2HTTL = lv2ttl/plugins.h +x42_dpl_JACKDESC = lv2ui_descriptor +$(APPBLD)x42-dpl$(EXE_EXT): $(DSP_DEPS) $(GUI_DEPS) \ + $(x42_dpl_JACKGUI) $(x42_dpl_LV2HTTL) + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + -include $(RW)robtk.mk +endif + +$(BUILDDIR)$(LV2GUI)$(LIB_EXT): gui/$(LV2NAME).c + +############################################################################### +# install/uninstall/clean target definitions + +install: install-bin install-man + +uninstall: uninstall-bin uninstall-man + +install-bin: all + install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m644 $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m755 $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +ifneq ($(BUILDOPENGL), no) + install -m755 $(BUILDDIR)$(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +endif +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(BINDIR) + install -m755 $(APPBLD)x42-dpl$(EXE_EXT) $(DESTDIR)$(BINDIR) +endif + +uninstall-bin: + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/manifest.ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME).ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME)$(LIB_EXT) + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2GUI)$(LIB_EXT) + rm -f $(DESTDIR)$(BINDIR)/x42-dpl$(EXE_EXT) + -rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE) + -rmdir $(DESTDIR)$(BINDIR) + +install-man: +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(MANDIR) + install -m644 x42-dpl.1 $(DESTDIR)$(MANDIR) +endif + +uninstall-man: + rm -f $(DESTDIR)$(MANDIR)/x42-dpl.1 + -rmdir $(DESTDIR)$(MANDIR) + +man: $(APPBLD)x42-dpl + help2man -N -o x42-dpl.1 -n "x42-dpl JACK Peak Limiter" $(APPBLD)x42-dpl + +clean: + rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl \ + $(BUILDDIR)$(LV2NAME)$(LIB_EXT) \ + $(BUILDDIR)$(LV2GUI)$(LIB_EXT) + rm -rf $(BUILDDIR)*.dSYM + rm -rf $(APPBLD)x42-* + -test -d $(APPBLD) && rmdir $(APPBLD) || true + -test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true + +distclean: clean + rm -f cscope.out cscope.files tags + +.PHONY: clean all install uninstall distclean jackapps man \ + install-bin uninstall-bin install-man uninstall-man \ + submodule_check submodules submodule_update submodule_pull diff -Nru x42-plugins-20170428/dpl.lv2/README.md x42-plugins-20190714/dpl.lv2/README.md --- x42-plugins-20170428/dpl.lv2/README.md 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/README.md 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,55 @@ +dpl.lv2 - Digital Peak Limiter +============================== + +dpl.lv2 is a look-ahead digital peak limiter intended but not limited to the final step of mastering or mixing. + +It is available as [LV2 plugin](http://lv2plug.in/) and standalone [JACK](http://jackaudio.org/)-application. + +Usage +----- + +The Plugin has three controls which can be operated by mouse-drag and the scroll-wheel. +Holding the _Ctrl_ key allows for fine-grained control when dragging or using the mouse-wheel on a knob. + +Furthermore the UI offers +* Shift + click: reset to default +* Right-click on knob: toggle current value with default, 2nd click restore. + +The rotary knobs from left to right allow to set + +* Input gain. This sets the gain applied before peak detection or any other processing. Range is -10 to +30 dB in steps of 0.2 dB. + +* Threshold. The maximum sample value at the output. -10 to 0 dB in steps of 0.1 dB. dpl.lv2 will not allow a single sample above this level. + +* Release time. This can be set from 1 ms to 1 second. Note that dpl.lv2 allows short release times even on signals that contain high level low frequency signals. Any gain reduction caused by those will have an automatically extended hold time in order to avoid the limiter following the shape of the waveform and create excessive distortion. Short superimposed peaks will still have the release time as set by this control. + + +Install +------- + +Compiling dpl.lv2 requires the LV2 SDK, jack-headers, gnu-make, a c++-compiler, +libpango, libcairo and openGL (sometimes called: glu, glx, mesa). + +```bash + git clone git://github.com/x42/dpl.lv2.git + cd dpl.lv2 + make submodules + make + sudo make install PREFIX=/usr +``` + +Note to packagers: the Makefile honors `PREFIX` and `DESTDIR` variables as well +as `CXXLAGS`, `LDFLAGS` and `OPTIMIZATIONS` (additions to `CXXFLAGS`), also +see the first 10 lines of the Makefile. +You really want to package the superset of [x42-plugins](https://github.com/x42/x42-plugins). + + +Screenshots +----------- + +![screenshot](https://raw.github.com/x42/dpl.lv2/master/img/dpl1.png "DPL LV2 GUI") + +Credits +------- + +dpl.lv2 is based on zita-jacktools-1.0.0 by Fons Adriaensen. diff -Nru x42-plugins-20170428/dpl.lv2/src/lv2.cc x42-plugins-20190714/dpl.lv2/src/lv2.cc --- x42-plugins-20170428/dpl.lv2/src/lv2.cc 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/src/lv2.cc 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,565 @@ +/* plim.lv2 + * + * Copyright (C) 2018 Robin Gareus + * + * 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, 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, see . + */ + +#include +#include +#include +#include + +#include "peaklim.h" +#include "uris.h" + +#include "lv2/lv2plug.in/ns/ext/state/state.h" +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "lv2/lv2plug.in/ns/ext/options/options.h" + +#ifdef DISPLAY_INTERFACE +#include "lv2_rgext.h" +#include +#include +#endif + +#ifndef MAX +#define MAX(A, B) ((A) > (B)) ? (A) : (B) +#endif + +#ifndef MIN +#define MIN(A, B) ((A) < (B)) ? (A) : (B) +#endif + +typedef struct { + float* _port[PLIM_LAST]; + + DPLLV2::Peaklim* peaklim; + + /* history */ + float _peak; + float _min[HISTLEN]; + float _max[HISTLEN]; + uint32_t _hist; + + uint32_t samplecnt; + uint32_t sampletme; // 50ms + + /* atom-forge, UI communication */ + const LV2_Atom_Sequence* control; + LV2_Atom_Sequence* notify; + LV2_URID_Map* map; + PlimLV2URIs uris; + LV2_Atom_Forge forge; + LV2_Atom_Forge_Frame frame; + + /* GUI state */ + bool ui_active; + bool send_state_to_ui; + float ui_scale; + +#ifdef DISPLAY_INTERFACE + LV2_Inline_Display_Image_Surface surf; + cairo_surface_t* display; + LV2_Inline_Display* queue_draw; + cairo_pattern_t* mpat; + uint32_t w, h; + float ui_reduction; +#endif + +} Plim; + +static LV2_Handle +instantiate (const LV2_Descriptor* descriptor, + double rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Plim* self = (Plim*)calloc (1, sizeof (Plim)); + + uint32_t n_channels; + + if (!strcmp (descriptor->URI, PLIM_URI "mono")) { + n_channels = 1; + } else if (!strcmp (descriptor->URI, PLIM_URI "stereo")) { + n_channels = 2; + } else { + free (self); + return NULL; + } + + const LV2_Options_Option* options = NULL; + + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_URID__map)) { + self->map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)features[i]->data; + } +#ifdef DISPLAY_INTERFACE + else if (!strcmp (features[i]->URI, LV2_INLINEDISPLAY__queue_draw)) { + self->queue_draw = (LV2_Inline_Display*)features[i]->data; + } +#endif + } + + if (!self->map) { + fprintf (stderr, "dpl.lv2 error: Host does not support urid:map\n"); + free (self); + return NULL; + } + + lv2_atom_forge_init (&self->forge, self->map); + map_plim_uris (self->map, &self->uris); + + self->ui_active = false; + self->ui_scale = 1.0; + self->_peak = -20; + + for (int i = 0; i < HISTLEN; ++i) { + self->_min[i] = self->_max[i] = 1.0; + } + + self->peaklim = new DPLLV2::Peaklim (); + self->peaklim->init (rate, n_channels); + + self->sampletme = ceilf (rate * 0.05); // 50ms + + if (options) { + LV2_URID atom_Float = self->map->map (self->map->handle, LV2_ATOM__Float); + LV2_URID ui_scale = self->map->map (self->map->handle, "http://lv2plug.in/ns/extensions/ui#scaleFactor"); + for (const LV2_Options_Option* o = options; o->key; ++o) { + if (o->context == LV2_OPTIONS_INSTANCE && o->key == ui_scale && o->type == atom_Float) { + float ui_scale = *(const float*)o->value; + if (ui_scale < 1.0) { ui_scale = 1.0; } + if (ui_scale > 2.0) { ui_scale = 2.0; } + self->ui_scale = ui_scale; + } + } + } + + return (LV2_Handle)self; +} + +static void +connect_port (LV2_Handle instance, + uint32_t port, + void* data) +{ + Plim* self = (Plim*)instance; + if (port == PLIM_ATOM_CONTROL) { + self->control = (const LV2_Atom_Sequence*)data; + } else if (port == PLIM_ATOM_NOTIFY) { + self->notify = (LV2_Atom_Sequence*)data; + } else if (port < PLIM_LAST) { + self->_port[port] = (float*)data; + } +} + +/** forge atom-vector of raw data */ +static void +tx_history (Plim* self) +{ + LV2_Atom_Forge_Frame frame; + /* forge container object of type 'rawaudio' */ + lv2_atom_forge_frame_time (&self->forge, 0); + x_forge_object (&self->forge, &frame, 1, self->uris.history); + + /* add integer attribute 'channelid' */ + lv2_atom_forge_property_head (&self->forge, self->uris.position, 0); + lv2_atom_forge_int (&self->forge, self->_hist); + + /* add vector of floats raw */ + lv2_atom_forge_property_head (&self->forge, self->uris.minvals, 0); + lv2_atom_forge_vector (&self->forge, sizeof (float), self->uris.atom_Float, HISTLEN, self->_min); + + lv2_atom_forge_property_head (&self->forge, self->uris.maxvals, 0); + lv2_atom_forge_vector (&self->forge, sizeof (float), self->uris.atom_Float, HISTLEN, self->_max); + + /* close off atom-object */ + lv2_atom_forge_pop (&self->forge, &frame); +} + +static void +tx_state (Plim* self) +{ + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&self->forge, 0); + x_forge_object (&self->forge, &frame, 1, self->uris.state); + + lv2_atom_forge_property_head (&self->forge, self->uris.s_uiscale, 0); + lv2_atom_forge_float (&self->forge, self->ui_scale); + + lv2_atom_forge_pop (&self->forge, &frame); +} + +static void +run (LV2_Handle instance, uint32_t n_samples) +{ + Plim* self = (Plim*)instance; + + if (!self->control || !self->notify) { + *self->_port[PLIM_LEVEL] = -10; + *self->_port[PLIM_LATENCY] = self->peaklim->get_latency (); + if (self->_port[PLIM_INPUT0] != self->_port[PLIM_OUTPUT0]) { + memcpy (self->_port[PLIM_OUTPUT0], self->_port[PLIM_INPUT0], n_samples * sizeof (float)); + } + if (self->_port[PLIM_INPUT1] != self->_port[PLIM_OUTPUT1]) { + memcpy (self->_port[PLIM_OUTPUT1], self->_port[PLIM_INPUT1], n_samples * sizeof (float)); + } + return; + } + + /* prepare forge buffer and initialize atom-sequence */ + const uint32_t capacity = self->notify->atom.size; + lv2_atom_forge_set_buffer (&self->forge, (uint8_t*)self->notify, capacity); + lv2_atom_forge_sequence_head (&self->forge, &self->frame, 0); + + /* process messages from GUI; */ + if (self->control) { + LV2_Atom_Event* ev = lv2_atom_sequence_begin (&(self->control)->body); + while (!lv2_atom_sequence_is_end (&(self->control)->body, (self->control)->atom.size, ev)) { + if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) { + const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; + if (obj->body.otype == self->uris.ui_off) { + self->ui_active = false; + } else if (obj->body.otype == self->uris.ui_on) { + self->ui_active = true; + self->send_state_to_ui = true; + } else if (obj->body.otype == self->uris.state) { + const LV2_Atom* v = NULL; + lv2_atom_object_get (obj, self->uris.s_uiscale, &v, 0); + if (v) { + self->ui_scale = ((LV2_Atom_Float*)v)->body; + } + } + } + ev = lv2_atom_sequence_next (ev); + } + } + +#define BYPASS_THRESH 40 // dBFS + + /* bypass/enable */ + const bool enable = *self->_port[PLIM_ENABLE] > 0; + + if (enable) { + self->peaklim->set_inpgain (*self->_port[PLIM_GAIN]); + self->peaklim->set_threshold (*self->_port[PLIM_THRESHOLD]); + self->peaklim->set_release (*self->_port[PLIM_RELEASE]); + } else { + self->peaklim->set_inpgain (0); + self->peaklim->set_threshold (BYPASS_THRESH); + self->peaklim->set_release (.05); + } + + float* ins[2] = { self->_port[PLIM_INPUT0], self->_port[PLIM_INPUT1] }; + float* outs[2] = { self->_port[PLIM_OUTPUT0], self->_port[PLIM_OUTPUT1] }; + + self->peaklim->process (n_samples, ins, outs); + + bool tx = false; + + self->samplecnt += n_samples; + while (self->samplecnt >= self->sampletme) { + self->samplecnt -= self->sampletme; + float pk; + self->peaklim->get_stats (&pk, &self->_max[self->_hist], &self->_min[self->_hist]); + + pk = pk < 0.1 ? -20 : (20. * log10f (pk)); + + if (self->_peak > -20) { + self->_peak -= .3; // 6dB/sec + } + if (pk > self->_peak) { + self->_peak = pk; + } + +#ifdef DISPLAY_INTERFACE + const float display_lvl = enable ? fmaxf (-10.f, self->_peak) : -100.f; + if (self->queue_draw && self->ui_reduction != display_lvl) { + self->ui_reduction = display_lvl; + self->queue_draw->queue_draw (self->queue_draw->handle); + } +#endif + + self->_hist = (self->_hist + 1) % HISTLEN; + tx = true; + } + + *self->_port[PLIM_LEVEL] = enable ? fmaxf (-10.f, self->_peak) : -10; + *self->_port[PLIM_LATENCY] = self->peaklim->get_latency (); + + if (self->ui_active && self->send_state_to_ui) { + self->send_state_to_ui = false; + tx_state (self); + tx_history (self); + } else if (self->ui_active && tx) { + tx_history (self); + } + + /* close off atom-sequence */ + lv2_atom_forge_pop (&self->forge, &self->frame); +} + +#define STATESTORE(URI, TYPE, VALUE) \ + store (handle, self->uris.URI, \ + (void*)&(VALUE), sizeof (uint32_t), \ + self->uris.atom_##TYPE, \ + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + +static LV2_State_Status +plim_save (LV2_Handle instance, + LV2_State_Store_Function store, + LV2_State_Handle handle, + uint32_t flags, + const LV2_Feature* const* features) +{ + Plim* self = (Plim*)instance; + + STATESTORE (s_uiscale, Float, self->ui_scale) + + return LV2_STATE_SUCCESS; +} + +/* clang-format off */ +#define STATEREAD(URI, TYPE, CAST, PARAM) \ + value = retrieve (handle, self->uris.URI, &size, &type, &valflags); \ + if (value && size == sizeof (uint32_t) && type == self->uris.atom_##TYPE) { \ + PARAM = *((const CAST*)value); \ + } +/* clang-format on */ + +static LV2_State_Status +plim_restore (LV2_Handle instance, + LV2_State_Retrieve_Function retrieve, + LV2_State_Handle handle, + uint32_t flags, + const LV2_Feature* const* features) +{ + Plim* self = (Plim*)instance; + const void* value; + size_t size; + uint32_t type; + uint32_t valflags; + + STATEREAD (s_uiscale, Float, float, self->ui_scale) + + self->send_state_to_ui = true; + return LV2_STATE_SUCCESS; +} + +static void +cleanup (LV2_Handle instance) +{ + Plim* self = (Plim*)instance; + delete self->peaklim; +#ifdef DISPLAY_INTERFACE + if (self->mpat) { + cairo_pattern_destroy (self->mpat); + } + if (self->display) { + cairo_surface_destroy (self->display); + } +#endif + free (instance); +} + +#ifdef WITH_SIGNATURE +#define RTK_URI PLIM_URI +#include "gpg_init.c" +#include WITH_SIGNATURE +struct license_info license_infos = { + "x42-Digital Peak Limiter", + "http://x42-plugins.com/x42/x42-limiter" +}; +#include "gpg_lv2ext.c" +#endif + +#ifdef DISPLAY_INTERFACE +static void +create_pattern (Plim* self, const double w) +{ + cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, w, 0); + + const int x0 = floor (w * 0.05); + const int x1 = ceil (w * 0.95); + const int wd = x1 - x0; + +#define DEF(x) ((x1 - wd * (x) / 20.) / w) + cairo_pattern_add_color_stop_rgba (pat, 1.0, .7, .7, .0, 0); + cairo_pattern_add_color_stop_rgba (pat, DEF (0), .7, .7, .0, 1); + cairo_pattern_add_color_stop_rgba (pat, DEF (5), .7, .7, .0, 1); + cairo_pattern_add_color_stop_rgba (pat, DEF (20), .9, .0, .0, 1); + cairo_pattern_add_color_stop_rgba (pat, 0.0, .9, .0, .0, 0); +#undef DEF + + self->mpat = pat; +} + +static LV2_Inline_Display_Image_Surface* +dpl_render (LV2_Handle handle, uint32_t w, uint32_t max_h) +{ +#ifdef WITH_SIGNATURE + if (!is_licensed (handle)) { + return NULL; + } +#endif + uint32_t h = MAX (11, MIN (1 | (uint32_t)ceilf (w / 10.f), max_h)); + + Plim* self = (Plim*)handle; + + if (!self->display || self->w != w || self->h != h) { + if (self->display) + cairo_surface_destroy (self->display); + self->display = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + self->w = w; + self->h = h; + if (self->mpat) { + cairo_pattern_destroy (self->mpat); + self->mpat = NULL; + } + } + + if (!self->mpat) { + create_pattern (self, w); + } + + cairo_t* cr = cairo_create (self->display); + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba (cr, .2, .2, .2, 1.0); + cairo_fill (cr); + + const int x0 = floor (w * 0.05); + const int x1 = ceil (w * 0.95); + const int wd = x1 - x0; + + cairo_set_line_width (cr, 1); + cairo_set_source_rgba (cr, 0.8, 0.8, 0.8, 1.0); + +#define DEF(x) (rint (x1 - wd * (x) / 20.) - .5) + cairo_move_to (cr, DEF (0), 0); + cairo_rel_line_to (cr, 0, h); + cairo_stroke (cr); + cairo_move_to (cr, DEF (5), 0); + cairo_rel_line_to (cr, 0, h); + cairo_stroke (cr); + cairo_move_to (cr, DEF (10), 0); + cairo_rel_line_to (cr, 0, h); + cairo_stroke (cr); + cairo_move_to (cr, DEF (15), 0); + cairo_rel_line_to (cr, 0, h); + cairo_stroke (cr); + cairo_move_to (cr, DEF (20), 0); + cairo_rel_line_to (cr, 0, h); + cairo_stroke (cr); +#undef DEF + + cairo_rectangle (cr, x0, 2, wd, h - 5); + cairo_set_source_rgba (cr, .5, .5, .5, 0.6); + cairo_fill (cr); + +#define CLAMP01(x) (((x) > 1.f) ? 1.f : (((x) < 0.f) ? 0.f : (x))) + if (self->ui_reduction >= -10.f) { + const int xw = wd * CLAMP01 (self->ui_reduction / 20.f); + cairo_rectangle (cr, x1 - xw, 2, xw, h - 5); + cairo_set_source (cr, self->mpat); + cairo_fill (cr); + } else { + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba (cr, .2, .2, .2, 0.8); + cairo_fill (cr); + } + + /* finish surface */ + cairo_destroy (cr); + cairo_surface_flush (self->display); + self->surf.width = cairo_image_surface_get_width (self->display); + self->surf.height = cairo_image_surface_get_height (self->display); + self->surf.stride = cairo_image_surface_get_stride (self->display); + self->surf.data = cairo_image_surface_get_data (self->display); + + return &self->surf; +} +#endif + +const void* +extension_data (const char* uri) +{ + static const LV2_State_Interface state = { plim_save, plim_restore }; + if (!strcmp (uri, LV2_STATE__interface)) { + return &state; + } +#ifdef DISPLAY_INTERFACE + static const LV2_Inline_Display_Interface display = { dpl_render }; + if (!strcmp (uri, LV2_INLINEDISPLAY__interface)) { +#if (defined _WIN32 && defined RTK_STATIC_INIT) + static int once = 0; + if (!once) { + once = 1; + gobject_init_ctor (); + } +#endif + return &display; + } +#endif +#ifdef WITH_SIGNATURE + LV2_LICENSE_EXT_C +#endif + return NULL; +} + +static const LV2_Descriptor descriptor_mono = { + PLIM_URI "mono", + instantiate, + connect_port, + NULL, + run, + NULL, + cleanup, + extension_data +}; + +static const LV2_Descriptor descriptor_stereo = { + PLIM_URI "stereo", + instantiate, + connect_port, + NULL, + run, + NULL, + cleanup, + extension_data +}; + +/* clang-format off */ +#undef LV2_SYMBOL_EXPORT +#ifdef _WIN32 +# define LV2_SYMBOL_EXPORT __declspec(dllexport) +#else +# define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default"))) +#endif +/* clang-format on */ +LV2_SYMBOL_EXPORT +const LV2_Descriptor* +lv2_descriptor (uint32_t index) +{ + switch (index) { + case 0: + return &descriptor_mono; + case 1: + return &descriptor_stereo; + default: + return NULL; + } +} diff -Nru x42-plugins-20170428/dpl.lv2/src/peaklim.cc x42-plugins-20190714/dpl.lv2/src/peaklim.cc --- x42-plugins-20170428/dpl.lv2/src/peaklim.cc 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/src/peaklim.cc 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2010-2018 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 3 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, see . + */ + +#include +#include +#include + +#include "peaklim.h" + +using namespace DPLLV2; + +void +Histmin::init (int hlen) +{ + int i; + + assert (hlen <= SIZE); + _hlen = hlen; + _hold = hlen; + _wind = 0; + _vmin = 1; + for (i = 0; i < SIZE; i++) + _hist[i] = _vmin; +} + +float +Histmin::write (float v) +{ + int i, j; + + i = _wind; + _hist[i] = v; + if (v <= _vmin) { + _vmin = v; + _hold = _hlen; + } else if (--_hold == 0) { + _vmin = v; + _hold = _hlen; + for (j = 1 - _hlen; j < 0; j++) { + v = _hist[(i + j) & MASK]; + if (v < _vmin) { + _vmin = v; + _hold = _hlen + j; + } + } + } + _wind = ++i & MASK; + return _vmin; +} + +Peaklim::Peaklim (void) + : _fsamp (0), + _nchan (0), + _rstat (false), + _peak (0), + _gmax (1), + _gmin (1) +{ + for (int i = 0; i < MAXCHAN; i++) + _dbuff[i] = 0; +} + +Peaklim::~Peaklim (void) +{ + fini (); +} + +void +Peaklim::set_inpgain (float v) +{ + _g1 = powf (10.0f, 0.05f * v); +} + +void +Peaklim::set_threshold (float v) +{ + _gt = powf (10.0f, -0.05f * v); +} + +void +Peaklim::set_release (float v) +{ + if (v > 1.0f) { + v = 1.0f; + } + if (v < 1e-3f) { + v = 1e-3f; + } + _w3 = 1.0f / (v * _fsamp); +} + +void +Peaklim::init (float fsamp, int nchan) +{ + int i, k1, k2; + + fini (); + if (nchan > MAXCHAN) { + nchan = MAXCHAN; + } + _fsamp = fsamp; + _nchan = nchan; + if (fsamp > 130000) + _div1 = 32; + else if (fsamp > 65000) { + _div1 = 16; + } else + _div1 = 8; + _div2 = 8; + k1 = (int)(ceilf (1.2e-3f * _fsamp / _div1)); + k2 = 12; + _delay = k1 * _div1; + for (_dsize = 64; _dsize < _delay + _div1; _dsize *= 2) + ; + _dmask = _dsize - 1; + _delri = 0; + for (i = 0; i < _nchan; i++) { + _dbuff[i] = new float[_dsize]; + memset (_dbuff[i], 0, _dsize * sizeof (float)); + } + _hist1.init (k1 + 1); + _hist2.init (k2); + _c1 = _div1; + _c2 = _div2; + _m1 = 0.0f; + _m2 = 0.0f; + _wlf = 6.28f * 500.0f / fsamp; + _w1 = 10.0f / _delay; + _w2 = _w1 / _div2; + _w3 = 1.0f / (0.01f * fsamp); + for (i = 0; i < _nchan; i++) + _zlf[i] = 0.0f; + _z1 = 1.0f; + _z2 = 1.0f; + _z3 = 1.0f; + _gt = 1.0f; + _g0 = 1.0f; + _g1 = 1.0f; + _dg = 0.0f; + _gmax = 1.0f; + _gmin = 1.0f; +} + +void +Peaklim::fini (void) +{ + int i; + + for (i = 0; i < MAXCHAN; i++) { + delete[] _dbuff[i]; + _dbuff[i] = 0; + } + _nchan = 0; +} + +void +Peaklim::process (int nframes, float* inp[], float* out[]) +{ + int i, j, k, n, ri, wi; + float g, d, h1, h2, m1, m2, x, z, z1, z2, z3, pk, t0, t1, *p; + + ri = _delri; + wi = (ri + _delay) & _dmask; + h1 = _hist1.vmin (); + h2 = _hist2.vmin (); + m1 = _m1; + m2 = _m2; + z1 = _z1; + z2 = _z2; + z3 = _z3; + + if (_rstat) { + _rstat = false; + pk = 0; + t0 = _gmax; + t1 = _gmin; + } else { + pk = _peak; + t0 = _gmin; + t1 = _gmax; + } + + k = 0; + while (nframes) { + n = (_c1 < nframes) ? _c1 : nframes; + + g = _g0; + for (j = 0; j < _nchan; j++) { + p = inp[j] + k; + z = _zlf[j]; + g = _g0; + d = _dg; + for (i = 0; i < n; i++) { + x = g * *p++; + g += d; + _dbuff[j][wi + i] = x; + z += _wlf * (x - z) + 1e-20f; + x = fabsf (x); + if (x > m1) { + m1 = x; + } + x = fabsf (z); + if (x > m2) { + m2 = x; + } + } + _zlf[j] = z; + } + _g0 = g; + + _c1 -= n; + if (_c1 == 0) { + m1 *= _gt; + if (m1 > pk) { + pk = m1; + } + h1 = (m1 > 1.0f) ? 1.0f / m1 : 1.0f; + h1 = _hist1.write (h1); + m1 = 0; + _c1 = _div1; + if (--_c2 == 0) { + m2 *= _gt; + h2 = (m2 > 1.0f) ? 1.0f / m2 : 1.0f; + h2 = _hist2.write (h2); + m2 = 0; + _c2 = _div2; + _dg = _g1 - _g0; + if (fabsf (_dg) < 1e-9f) { + _g0 = _g1; + _dg = 0; + } else { + _dg /= _div1 * _div2; + } + } + } + + for (i = 0; i < n; i++) { + z1 += _w1 * (h1 - z1); + z2 += _w2 * (h2 - z2); + z = (z2 < z1) ? z2 : z1; + if (z < z3) { + z3 += _w1 * (z - z3); + } else { + z3 += _w3 * (z - z3); + } + if (z3 > t1) { + t1 = z3; + } + if (z3 < t0) { + t0 = z3; + } + for (j = 0; j < _nchan; j++) { + out[j][k + i] = z3 * _dbuff[j][ri + i]; + } + } + + wi = (wi + n) & _dmask; + ri = (ri + n) & _dmask; + k += n; + nframes -= n; + } + + _delri = ri; + _m1 = m1; + _m2 = m2; + _z1 = z1; + _z2 = z2; + _z3 = z3; + _peak = pk; + _gmin = t0; + _gmax = t1; +} diff -Nru x42-plugins-20170428/dpl.lv2/src/peaklim.h x42-plugins-20190714/dpl.lv2/src/peaklim.h --- x42-plugins-20170428/dpl.lv2/src/peaklim.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/src/peaklim.h 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2010-2018 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 3 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, see . + */ + +#ifndef _PEAKLIM_H +#define _PEAKLIM_H + +#include + +namespace DPLLV2 +{ +class Histmin +{ +public: + Histmin (void) + { + } + ~Histmin (void) + { + } + + void init (int hlen); + float write (float v); + float + vmin (void) + { + return _vmin; + } + +private: + enum { SIZE = 32, + MASK = SIZE - 1 }; + + int _hlen; + int _hold; + int _wind; + float _vmin; + float _hist[SIZE]; +}; + +class Peaklim +{ +public: + enum { MAXCHAN = 64 }; + + Peaklim (void); + ~Peaklim (void); + + void init (float fsamp, int nchan); + void fini (void); + + void set_inpgain (float v); + void set_threshold (float v); + void set_release (float v); + + int + get_latency () const + { + return _delay; + } + + void + get_stats (float* peak, float* gmax, float* gmin) + { + *peak = _peak; + *gmax = _gmax; + *gmin = _gmin; + _rstat = true; + } + + void process (int nsamp, float* inp[], float* out[]); + +private: + float _fsamp; + int _nchan; + int _div1; + int _div2; + int _delay; + int _dsize; + int _dmask; + int _delri; + float* _dbuff[MAXCHAN]; + int _c1, _c2; + float _g0, _g1, _dg; + float _gt, _m1, _m2; + float _w1, _w2, _w3, _wlf; + float _z1, _z2, _z3; + float _zlf[MAXCHAN]; + volatile bool _rstat; + volatile float _peak; + volatile float _gmax; + volatile float _gmin; + Histmin _hist1; + Histmin _hist2; +}; + +} // namespace + +#endif diff -Nru x42-plugins-20170428/dpl.lv2/src/uris.h x42-plugins-20190714/dpl.lv2/src/uris.h --- x42-plugins-20170428/dpl.lv2/src/uris.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/src/uris.h 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013.2018 Robin Gareus + * + * 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, 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, see . + */ + +#ifndef PLIM_URIS_H +#define PLIM_URIS_H + +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/atom/forge.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" + +#define PLIM_URI "http://gareus.org/oss/lv2/dpl#" + +#define HISTLEN 60 + +#ifdef HAVE_LV2_1_8 +#define x_forge_object lv2_atom_forge_object +#else +#define x_forge_object lv2_atom_forge_blank +#endif + +typedef struct { + LV2_URID atom_Blank; + LV2_URID atom_Object; + LV2_URID atom_Vector; + LV2_URID atom_Float; + LV2_URID atom_Int; + LV2_URID atom_eventTransfer; + LV2_URID history; + LV2_URID position; + LV2_URID minvals; + LV2_URID maxvals; + LV2_URID ui_on; + LV2_URID ui_off; + LV2_URID state; + LV2_URID s_uiscale; +} PlimLV2URIs; + +static inline void +map_plim_uris (LV2_URID_Map* map, PlimLV2URIs* uris) +{ + uris->atom_Blank = map->map (map->handle, LV2_ATOM__Blank); + uris->atom_Object = map->map (map->handle, LV2_ATOM__Object); + uris->atom_Vector = map->map (map->handle, LV2_ATOM__Vector); + uris->atom_Float = map->map (map->handle, LV2_ATOM__Float); + uris->atom_Int = map->map (map->handle, LV2_ATOM__Int); + uris->atom_eventTransfer = map->map (map->handle, LV2_ATOM__eventTransfer); + uris->history = map->map (map->handle, PLIM_URI "history"); + uris->position = map->map (map->handle, PLIM_URI "position"); + uris->minvals = map->map (map->handle, PLIM_URI "minvals"); + uris->maxvals = map->map (map->handle, PLIM_URI "maxvals"); + uris->ui_on = map->map (map->handle, PLIM_URI "ui_on"); + uris->ui_off = map->map (map->handle, PLIM_URI "ui_off"); + uris->state = map->map (map->handle, PLIM_URI "state"); + uris->s_uiscale = map->map (map->handle, PLIM_URI "uiscale"); +} + +/* common definitions UI and DSP */ + +typedef enum { + PLIM_ATOM_CONTROL = 0, + PLIM_ATOM_NOTIFY, + + PLIM_ENABLE, + PLIM_GAIN, + PLIM_THRESHOLD, + PLIM_RELEASE, + + PLIM_LEVEL, + PLIM_LATENCY, + + PLIM_INPUT0, + PLIM_OUTPUT0, + PLIM_INPUT1, + PLIM_OUTPUT1, + PLIM_LAST +} PortIndex; + +#endif diff -Nru x42-plugins-20170428/dpl.lv2/x42-dpl.1 x42-plugins-20190714/dpl.lv2/x42-dpl.1 --- x42-plugins-20170428/dpl.lv2/x42-dpl.1 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/dpl.lv2/x42-dpl.1 2019-07-14 19:38:38.000000000 +0000 @@ -0,0 +1,72 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH X42-DPL "1" "July 2019" "x42-dpl version 0.3.3" "User Commands" +.SH NAME +x42-dpl \- x42-dpl JACK Peak Limiter +.SH SYNOPSIS +.B x42-dpl +[ \fI\,OPTIONS \/\fR] [ \fI\,Plugin-ID or URI \/\fR] +.SH DESCRIPTION +x42\-dpl \- JACK Peak Limiter +.PP +This is a standalone JACK application of a collection of LV2 plugins. +Use ID \fB\-1\fR, \fB\-l\fR or \fB\-\-list\fR for a dedicated list of included plugins. +By default the first listed plugin (ID 0) is used. +.PP +List of available plugins: (ID "Name" URI) +.TP +0 +"x42\-dpl \- Digital Peak Limiter Stereo" http://gareus.org/oss/lv2/dpl#stereo +.TP +1 +"x42\-dpl \- Digital Peak Limiter Mono" http://gareus.org/oss/lv2/dpl#mono +.PP +Usage: +All control elements are operated in using the mouse: +.TP +Click+Drag +left/down: decrease, right/up: increase value. Hold the Ctrl key to increase sensitivity. +.TP +Shift+Click +reset to default value +.TP +Scroll\-wheel +up/down by 1 step (smallest possible adjustment for given setting). Rapid continuous scrolling increases the step\-size. +.PP +The application can be closed by sending a SIGTERM (CTRL+C) on the command\-line of by closing the window. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Display this help and exit +.TP +\fB\-j\fR, \fB\-\-jack\-name\fR +Set the JACK client name +(defaults to plugin\-name) +.TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP +\fB\-l\fR, \fB\-\-list\fR +Print list of available plugins and exit +.TP +\fB\-O\fR , \fB\-\-osc\fR +Listen for OSC messages on the given UDP port +.TP +\fB\-p\fR :, \fB\-\-port\fR : +Set initial value for given control port +.TP +\fB\-P\fR, \fB\-\-portlist\fR +Print control port list on startup +.TP +\fB\-\-osc\-doc\fR +Print available OSC commands and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version information and exit +.PP +See also: +Website: +.SH COPYRIGHT +Copyright \(co GPL 2013\-2019 Robin Gareus +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/fat1.lv2/gui/fat1.c x42-plugins-20190714/fat1.lv2/gui/fat1.c --- x42-plugins-20170428/fat1.lv2/gui/fat1.c 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/gui/fat1.c 2019-07-14 19:38:55.000000000 +0000 @@ -23,6 +23,9 @@ #include #include +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/options/options.h" + #include "../src/fat1.h" #define RTK_URI FAT1_URI @@ -54,6 +57,7 @@ typedef struct { LV2UI_Write_Function write; LV2UI_Controller controller; + LV2UI_Touch* touch; PangoFontDescription* font[2]; @@ -92,8 +96,10 @@ int key_majmin; int tt_id; + int tt_timeout; cairo_rectangle_t* tt_pos; + bool microtonal; const char* nfo; } Fat1UI; @@ -135,23 +141,23 @@ return rintf (ctrl_range[c].step / r * (logf (v / ctrl_range[c].min))); } -float gui_to_ctrl (const uint32_t c, const float v) { +static float gui_to_ctrl (const uint32_t c, const float v) { if (!ctrl_range[c].log) { return v; } const float r = log (ctrl_range[c].max / ctrl_range[c].min); return expf (logf (ctrl_range[c].min) + v * r / ctrl_range[c].step); } -float k_min (const uint32_t c) { +static float k_min (const uint32_t c) { if (!ctrl_range[c].log) { return ctrl_range[c].min; } return 0; } -float k_max (const uint32_t c) { +static float k_max (const uint32_t c) { if (!ctrl_range[c].log) { return ctrl_range[c].max; } return ctrl_range[c].step; } -float k_step (const uint32_t c) { +static float k_step (const uint32_t c) { if (!ctrl_range[c].log) { return ctrl_range[c].step; } return 1; } @@ -333,18 +339,34 @@ pango_font_description_free (font); return TRUE; +} +static bool +tooltip_cnt (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) +{ + Fat1UI* ui = (Fat1UI*)rw->top; + if (++ui->tt_timeout < 8) { + rcontainer_expose_event (rw, cr, ev); + queue_draw (rw); + } else { + rw->expose_event = tooltip_overlay; + rw->resized = TRUE; + tooltip_overlay (rw, cr, ev); + } + return TRUE; } -static void ttip_handler (RobTkLbl* d, bool on, void *handle) { + +static void ttip_handler (RobWidget* rw, bool on, void *handle) { Fat1UI* ui = (Fat1UI*)handle; ui->tt_id = -1; + ui->tt_timeout = 0; for (int i = 0; i < 5; ++i) { - if (d == ui->lbl_ctrl[i]) { ui->tt_id = i; break;} + if (rw == ui->lbl_ctrl[i]->rw) { ui->tt_id = i; break;} } if (on && ui->tt_id >= 0) { - ui->tt_pos = &d->rw->area; - ui->ctbl->expose_event = tooltip_overlay; + ui->tt_pos = &rw->area; + ui->ctbl->expose_event = tooltip_cnt; ui->ctbl->resized = TRUE; queue_draw (ui->ctbl); } else { @@ -404,6 +426,12 @@ /*** scale overlay display ****/ static void keysel_apply (Fat1UI* ui) { + if (ui->touch) { + for (uint32_t n = 0; n < 12; ++n) { + ui->touch->touch (ui->touch->handle, FAT_NOTE + n, true); + } + } + int k = 0; switch (ui->key_note) { case 0: k = 12; break; @@ -418,6 +446,11 @@ float val = 1.0; ui->write (ui->controller, FAT_NOTE + n, sizeof (float), 0, (const void*) &val); } + if (ui->touch) { + for (uint32_t n = 0; n < 12; ++n) { + ui->touch->touch (ui->touch->handle, FAT_NOTE + n, false); + } + } return; default: return; @@ -433,6 +466,11 @@ float val = western [ (n + k) % 12 ]; ui->write (ui->controller, FAT_NOTE + n, sizeof (float), 0, (const void*) &val); } + if (ui->touch) { + for (uint32_t n = 0; n < 12; ++n) { + ui->touch->touch (ui->touch->handle, FAT_NOTE + n, false); + } + } } static bool keysel_overlay (RobWidget* rw, cairo_t* cr, cairo_rectangle_t* ev) { @@ -721,6 +759,11 @@ ui->notes |= (1 << n); } ui->write (ui->controller, FAT_NOTE + n, sizeof (float), 0, (const void*) &val); + + if (ui->touch) { + ui->touch->touch (ui->touch->handle, FAT_NOTE + n, false); + } + queue_draw (ui->m0); if (ui->ctbl->block_events) { ui->key_note = -1; @@ -741,6 +784,10 @@ static RobWidget* m0_mouse_down (RobWidget* handle, RobTkBtnEvent* ev) { Fat1UI* ui = (Fat1UI*)GET_HANDLE (handle); if (ev->button == 1) { + const int n = ui->hover; + if (n >= 0 && n < 12 && ui->touch) { + ui->touch->touch (ui->touch->handle, FAT_NOTE + n, true); + } return handle; } if (ev->button == 3 && robtk_select_get_value (ui->sel_mode) != 1) { @@ -905,6 +952,10 @@ robtk_dial_set_detent_default (ui->spn_ctrl[i], true); robtk_dial_set_scroll_mult (ui->spn_ctrl[i], ctrl_range[i].mult); + if (ui->touch) { + robtk_dial_set_touch (ui->spn_ctrl[i], ui->touch->touch, ui->touch->handle, FAT_TUNE + i); + } + robtk_dial_set_scaled_surface_scale (ui->spn_ctrl[i], ui->dial_bg[i], 2.0); robtk_lbl_annotation_callback(ui->lbl_ctrl[i], ttip_handler, ui); @@ -974,6 +1025,11 @@ robtk_select_set_value (ui->sel_mode, 0); robtk_select_set_callback (ui->sel_mode, cb_mode, ui); + if (ui->touch) { + robtk_select_set_touch (ui->sel_mchn, ui->touch->touch, ui->touch->handle, FAT_MCHN); + robtk_select_set_touch (ui->sel_mode, ui->touch->touch, ui->touch->handle, FAT_MODE); + } + ui->lbl_mode = robtk_lbl_new ("Mode"); ui->lbl_mchn = robtk_lbl_new ("MIDI Chn."); ui->btn_panic = robtk_pbtn_new ("MIDI Panic"); @@ -1048,9 +1104,26 @@ return NULL; } - if (strcmp (plugin_uri, RTK_URI)) { + if (0 == strcmp(plugin_uri, FAT1_URI)) { + ui->microtonal = false; + } else if (0 == strcmp(plugin_uri, FAT1_URI "#microtonal")) { + ui->microtonal = true; + } else { free (ui); - return NULL; + return 0; + } + + const LV2_Options_Option* options = NULL; + const LV2_URID_Map* map = NULL; + + for (int i = 0; features[i]; ++i) { + if (!strcmp(features[i]->URI, LV2_UI__touch)) { + ui->touch = (LV2UI_Touch*)features[i]->data; + } else if (!strcmp (features[i]->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)features[i]->data; + } } ui->nfo = robtk_info (ui_toplevel); @@ -1060,6 +1133,20 @@ ui->disable_signals = true; *widget = toplevel (ui, ui_toplevel); ui->disable_signals = false; + + if (options && map) { + LV2_URID atom_Float = map->map (map->handle, LV2_ATOM__Float); + LV2_URID ui_scale = map->map (map->handle, "http://lv2plug.in/ns/extensions/ui#scaleFactor"); + for (const LV2_Options_Option* o = options; o->key; ++o) { + if (o->context == LV2_OPTIONS_INSTANCE && o->key == ui_scale && o->type == atom_Float) { + float ui_scale = *(const float*)o->value; + if (ui_scale < 1.0) { ui_scale = 1.0; } + if (ui_scale > 2.0) { ui_scale = 2.0; } + robtk_queue_scale_change (ui->rw, ui_scale); + } + } + } + return ui; } @@ -1128,6 +1215,10 @@ queue_draw (ui->m0); } } + else if (port_index >= FAT_SCALE && port_index < FAT_LAST && ui->microtonal) { + //uint32_t k = port_index - FAT_SCALE; + // TODO microtonal scale + } ui->disable_signals = false; } diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.base.ttl.in x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.base.ttl.in --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.base.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.base.ttl.in 2019-07-14 19:38:55.000000000 +0000 @@ -0,0 +1,301 @@ + + + a lv2:Plugin, doap:Project, lv2:PitchPlugin; + doap:license ; + doap:maintainer ; + doap:name "Autotune@NAMESUFFIX@"; + @VERSION@ + @UITTL@ + lv2:optionalFeature lv2:hardRTCapable; + lv2:requiredFeature urid:map; + @MODBRAND@ + @MODLABEL@ + @SIGNATURE@ + lv2:port [ + a atom:AtomPort, lv2:InputPort; + atom:bufferType atom:Sequence; + atom:supports midi:MidiEvent; + lv2:index 0; + lv2:symbol "midiin"; + lv2:name "MIDI In"; + lv2:portProperty lv2:isSideChain; + ] , [ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 1 ; + lv2:symbol "in" ; + lv2:name "Input" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 2 ; + lv2:symbol "out" ; + lv2:name "Output" + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 3 ; + lv2:symbol "mode" ; + lv2:name "Mode"; + lv2:default 0 ; + lv2:minimum 0 ; + lv2:maximum 2 ; + lv2:portProperty lv2:integer, lv2:enumeration; + lv2:scalePoint [ rdfs:label "Auto"; rdf:value 0 ; ] ; + lv2:scalePoint [ rdfs:label "MIDI"; rdf:value 1 ; ] ; + lv2:scalePoint [ rdfs:label "Manual"; rdf:value 2 ; ] ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 4 ; + lv2:symbol "channelf" ; + lv2:name "Filter Channel"; + lv2:minimum 0 ; + lv2:maximum 16 ; + lv2:default 0; + lv2:scalePoint [ rdfs:label "Any"; rdf:value 0 ]; + lv2:scalePoint [ rdfs:label "01" ; rdf:value 1 ]; + lv2:scalePoint [ rdfs:label "02" ; rdf:value 2 ]; + lv2:scalePoint [ rdfs:label "03" ; rdf:value 3 ]; + lv2:scalePoint [ rdfs:label "04" ; rdf:value 4 ]; + lv2:scalePoint [ rdfs:label "05" ; rdf:value 5 ]; + lv2:scalePoint [ rdfs:label "06" ; rdf:value 6 ]; + lv2:scalePoint [ rdfs:label "07" ; rdf:value 7 ]; + lv2:scalePoint [ rdfs:label "08" ; rdf:value 8 ]; + lv2:scalePoint [ rdfs:label "09" ; rdf:value 9 ]; + lv2:scalePoint [ rdfs:label "10" ; rdf:value 10 ]; + lv2:scalePoint [ rdfs:label "11" ; rdf:value 11 ]; + lv2:scalePoint [ rdfs:label "12" ; rdf:value 12 ]; + lv2:scalePoint [ rdfs:label "13" ; rdf:value 13 ]; + lv2:scalePoint [ rdfs:label "14" ; rdf:value 14 ]; + lv2:scalePoint [ rdfs:label "15" ; rdf:value 15 ]; + lv2:scalePoint [ rdfs:label "16" ; rdf:value 16 ]; + lv2:portProperty lv2:integer, lv2:enumeration; + rdfs:comment "MIDI Channel (1..16) on which the filter is active; 0: any)." ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 5 ; + lv2:symbol "tuning" ; + lv2:name "Tuning"; + lv2:default 440.0 ; + lv2:minimum 400.0 ; + lv2:maximum 480.0 ; + units:unit units:hz; + pprop:rangeSteps 401; + rdfs:comment "This sets the frequency corresponding to 'A' pitch, in other words the required tuning. This will be the default 440 Hz in most cases."; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 6 ; + lv2:symbol "bias" ; + lv2:name "Bias"; + lv2:default 0.5 ; + lv2:minimum 0.0 ; + lv2:maximum 1.0 ; + pprop:rangeSteps 271; + rdfs:comment "Normally the pitch estimator will select the enabled note closest to the measured pitch. The Bias control adds some preference for the current note - this allows it to go off-tune more than would be the case otherwise."; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 7 ; + lv2:symbol "filter" ; + lv2:name "Filter"; + lv2:default 0.1 ; + lv2:minimum 0.02 ; + lv2:maximum 0.5 ; + lv2:scalePoint [ rdfs:label "Slow"; rdf:value 0.5 ; ] ; + lv2:scalePoint [ rdfs:label "Med"; rdf:value 0.1 ; ] ; + lv2:scalePoint [ rdfs:label "Fast"; rdf:value 0.02 ; ] ; + lv2:portProperty pprop:logarithmic; + pprop:rangeSteps 201; + rdfs:comment "This sets the amount of smoothing on the pitch correction while the current note does not change. If it does change the filter is bypassed and the correction jumps immediately to the new value."; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 8 ; + lv2:symbol "corr" ; + lv2:name "Correction"; + lv2:default 1.0 ; + lv2:minimum 0.0 ; + lv2:maximum 1.0 ; + pprop:rangeSteps 271; + rdfs:comment "Determines how much of the estimated pitch error gets corrected. Full correction may remove expression or vibrato."; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 9 ; + lv2:symbol "offset" ; + lv2:name "Offset"; + lv2:default 0.0 ; + lv2:minimum -2.0 ; + lv2:maximum 2.0 ; + pprop:rangeSteps 401; + units:unit units:semitone12TET; + rdfs:comment "Adds an offset in the range of +/- two semitones to the pitch correction. With the Correction control set to zero the result is a constant pitch change."; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 10 ; + lv2:symbol "m00" ; + lv2:name "C"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 11 ; + lv2:symbol "m01" ; + lv2:name "C#"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 12 ; + lv2:symbol "m02" ; + lv2:name "D"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 13 ; + lv2:symbol "m03" ; + lv2:name "D#"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 14 ; + lv2:symbol "m04" ; + lv2:name "E"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 15 ; + lv2:symbol "m05" ; + lv2:name "F"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 16 ; + lv2:symbol "m06" ; + lv2:name "F#"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 17 ; + lv2:symbol "m07" ; + lv2:name "G"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 18 ; + lv2:symbol "m08" ; + lv2:name "G#"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 19 ; + lv2:symbol "m09" ; + lv2:name "A"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 20 ; + lv2:symbol "m10" ; + lv2:name "A#"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 21 ; + lv2:symbol "m11" ; + lv2:name "B"; + lv2:default 1 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 22 ; + lv2:symbol "panic" ; + lv2:name "MIDI Panic"; + lv2:default 0 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:portProperty lv2:integer, lv2:toggled, pprop:trigger; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 23 ; + lv2:symbol "nmask" ; + lv2:name "Note Mask"; + lv2:minimum 0 ; + lv2:maximum 4096 ; + lv2:portProperty lv2:integer; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 24 ; + lv2:symbol "nset" ; + lv2:name "Note Set"; + lv2:minimum 0 ; + lv2:maximum 4096 ; + lv2:portProperty lv2:integer; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 25 ; + lv2:symbol "error" ; + lv2:name "Pitch Error"; + lv2:minimum -1.0 ; + lv2:maximum 1.0 ; + ] , [ + a lv2:OutputPort , + lv2:ControlPort ; + lv2:index 26 ; + lv2:symbol "latency" ; + lv2:name "latency"; + lv2:minimum 0 ; + lv2:maximum 4096; + lv2:portProperty lv2:reportsLatency, lv2:integer; + units:unit units:frame; diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1_chroma.h x42-plugins-20190714/fat1.lv2/lv2ttl/fat1_chroma.h --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1_chroma.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1_chroma.h 2019-07-14 19:38:55.000000000 +0000 @@ -0,0 +1,56 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/fat1 + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _fat1_chroma = { + &lv2_descriptor, + &lv2ui_descriptor + , 0 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "Autotune" // const char *plugin_human_id + , (const struct LV2Port[27]) + { + { "midiin", MIDI_IN, nan, nan, nan, "MIDI In"}, + { "in", AUDIO_IN, nan, nan, nan, "Input"}, + { "out", AUDIO_OUT, nan, nan, nan, "Output"}, + { "mode", CONTROL_IN, 0.000000, 0.000000, 2.000000, "Mode"}, + { "channelf", CONTROL_IN, 0.000000, 0.000000, 16.000000, "MIDI Channel (1..16) on which the filter is active; 0: any)."}, + { "tuning", CONTROL_IN, 440.000000, 400.000000, 480.000000, "This sets the frequency corresponding to 'A' pitch, in other words the required tuning. This will be the default 440 Hz in most cases."}, + { "bias", CONTROL_IN, 0.500000, 0.000000, 1.000000, "Normally the pitch estimator will select the enabled note closest to the measured pitch. The Bias control adds some preference for the current note - this allows it to go off-tune more than would be the case otherwise."}, + { "filter", CONTROL_IN, 0.100000, 0.020000, 0.500000, "This sets the amount of smoothing on the pitch correction while the current note does not change. If it does change the filter is bypassed and the correction jumps immediately to the new value."}, + { "corr", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Determines how much of the estimated pitch error gets corrected. Full correction may remove expression or vibrato."}, + { "offset", CONTROL_IN, 0.000000, -2.000000, 2.000000, "Adds an offset in the range of +/- two semitones to the pitch correction. With the Correction control set to zero the result is a constant pitch change."}, + { "m00", CONTROL_IN, 1.000000, 0.000000, 1.000000, "C"}, + { "m01", CONTROL_IN, 1.000000, 0.000000, 1.000000, "C#"}, + { "m02", CONTROL_IN, 1.000000, 0.000000, 1.000000, "D"}, + { "m03", CONTROL_IN, 1.000000, 0.000000, 1.000000, "D#"}, + { "m04", CONTROL_IN, 1.000000, 0.000000, 1.000000, "E"}, + { "m05", CONTROL_IN, 1.000000, 0.000000, 1.000000, "F"}, + { "m06", CONTROL_IN, 1.000000, 0.000000, 1.000000, "F#"}, + { "m07", CONTROL_IN, 1.000000, 0.000000, 1.000000, "G"}, + { "m08", CONTROL_IN, 1.000000, 0.000000, 1.000000, "G#"}, + { "m09", CONTROL_IN, 1.000000, 0.000000, 1.000000, "A"}, + { "m10", CONTROL_IN, 1.000000, 0.000000, 1.000000, "A#"}, + { "m11", CONTROL_IN, 1.000000, 0.000000, 1.000000, "B"}, + { "panic", CONTROL_IN, 0.000000, 0.000000, 1.000000, "MIDI Panic"}, + { "nmask", CONTROL_OUT, nan, 0.000000, 4096.000000, "Note Mask"}, + { "nset", CONTROL_OUT, nan, 0.000000, 4096.000000, "Note Set"}, + { "error", CONTROL_OUT, nan, -1.000000, 1.000000, "Pitch Error"}, + { "latency", CONTROL_OUT, nan, 0.000000, 4096.000000, "latency"}, + } + , 27 // uint32_t nports_total + , 1 // uint32_t nports_audio_in + , 1 // uint32_t nports_audio_out + , 1 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 0 // uint32_t nports_atom_in + , 0 // uint32_t nports_atom_out + , 24 // uint32_t nports_ctrl + , 20 // uint32_t nports_ctrl_in + , 4 // uint32_t nports_ctrl_out + , 8192 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , 26 // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.chroma.ttl.in x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.chroma.ttl.in --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.chroma.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.chroma.ttl.in 2019-07-14 19:38:55.000000000 +0000 @@ -0,0 +1,3 @@ + ]; + rdfs:comment "AT1 is an 'autotuner', normally used to correct the pitch of a voice singing (slightly) out of tune. The 'expected' pitch can be controlled by MIDI, or be a fixed set of notes. AT1 can probably be used on some instruments as well, but is primarily designed to cover the vocal range."; + . diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.gui.in x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.gui.in --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.gui.in 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.gui.in 2019-07-14 19:38:55.000000000 +0000 @@ -1,6 +1,8 @@ @LV2NAME@:ui_gl a @UI_TYPE@ ; + opts:supportedOption ; + lv2:optionalFeature opts:options ; @UI_REQ@ . diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.h x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.h --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.h 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -// generated by lv2ttl2c from -// http://gareus.org/oss/lv2/fat1 - -extern const LV2_Descriptor* lv2_descriptor(uint32_t index); -extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); - -static const RtkLv2Description _plugin = { - &lv2_descriptor, - &lv2ui_descriptor - , 0 // uint32_t dsp_descriptor_id - , 0 // uint32_t gui_descriptor_id - , "Autotune" // const char *plugin_human_id - , (const struct LV2Port[27]) - { - { "midiin", MIDI_IN, nan, nan, nan, "MIDI In"}, - { "in", AUDIO_IN, nan, nan, nan, "Input"}, - { "out", AUDIO_OUT, nan, nan, nan, "Output"}, - { "mode", CONTROL_IN, 0.000000, 0.000000, 2.000000, "Mode"}, - { "channelf", CONTROL_IN, 0.000000, 0.000000, 16.000000, "MIDI Channel (1..16) on which the filter is active; 0: any)."}, - { "tuning", CONTROL_IN, 440.000000, 400.000000, 480.000000, "Tuning"}, - { "bias", CONTROL_IN, 0.500000, 0.000000, 1.000000, "Bias"}, - { "filter", CONTROL_IN, 0.100000, 0.020000, 0.500000, "Filter"}, - { "corr", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Correlation"}, - { "offset", CONTROL_IN, 0.000000, -2.000000, 2.000000, "Offset"}, - { "m00", CONTROL_IN, 1.000000, 0.000000, 1.000000, "C"}, - { "m01", CONTROL_IN, 1.000000, 0.000000, 1.000000, "C#"}, - { "m02", CONTROL_IN, 1.000000, 0.000000, 1.000000, "D"}, - { "m03", CONTROL_IN, 1.000000, 0.000000, 1.000000, "D#"}, - { "m04", CONTROL_IN, 1.000000, 0.000000, 1.000000, "E"}, - { "m05", CONTROL_IN, 1.000000, 0.000000, 1.000000, "F"}, - { "m06", CONTROL_IN, 1.000000, 0.000000, 1.000000, "F#"}, - { "m07", CONTROL_IN, 1.000000, 0.000000, 1.000000, "G"}, - { "m08", CONTROL_IN, 1.000000, 0.000000, 1.000000, "G#"}, - { "m09", CONTROL_IN, 1.000000, 0.000000, 1.000000, "A"}, - { "m10", CONTROL_IN, 1.000000, 0.000000, 1.000000, "A#"}, - { "m11", CONTROL_IN, 1.000000, 0.000000, 1.000000, "B"}, - { "panic", CONTROL_IN, 0.000000, 0.000000, 1.000000, "MIDI Panic"}, - { "nmask", CONTROL_OUT, nan, 0.000000, 4096.000000, "Note Mask"}, - { "nset", CONTROL_OUT, nan, 0.000000, 4096.000000, "Note Set"}, - { "error", CONTROL_OUT, nan, -1.000000, 1.000000, "Pitch Error"}, - { "latency", CONTROL_OUT, nan, 0.000000, 4096.000000, "latency"}, - } - , 27 // uint32_t nports_total - , 1 // uint32_t nports_audio_in - , 1 // uint32_t nports_audio_out - , 1 // uint32_t nports_midi_in - , 0 // uint32_t nports_midi_out - , 0 // uint32_t nports_atom_in - , 0 // uint32_t nports_atom_out - , 24 // uint32_t nports_ctrl - , 20 // uint32_t nports_ctrl_in - , 4 // uint32_t nports_ctrl_out - , 8192 // uint32_t min_atom_bufsiz - , false // bool send_time_info - , 26 // uint32_t latency_ctrl_port -}; diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1_micro.h x42-plugins-20190714/fat1.lv2/lv2ttl/fat1_micro.h --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1_micro.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1_micro.h 2019-07-14 19:38:55.000000000 +0000 @@ -0,0 +1,68 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/fat1#microtonal + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _fat1_micro = { + &lv2_descriptor, + &lv2ui_descriptor + , 1 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "Autotune (microtonal)" // const char *plugin_human_id + , (const struct LV2Port[39]) + { + { "midiin", MIDI_IN, nan, nan, nan, "MIDI In"}, + { "in", AUDIO_IN, nan, nan, nan, "Input"}, + { "out", AUDIO_OUT, nan, nan, nan, "Output"}, + { "mode", CONTROL_IN, 0.000000, 0.000000, 2.000000, "Mode"}, + { "channelf", CONTROL_IN, 0.000000, 0.000000, 16.000000, "MIDI Channel (1..16) on which the filter is active; 0: any)."}, + { "tuning", CONTROL_IN, 440.000000, 400.000000, 480.000000, "This sets the frequency corresponding to 'A' pitch, in other words the required tuning. This will be the default 440 Hz in most cases."}, + { "bias", CONTROL_IN, 0.500000, 0.000000, 1.000000, "Normally the pitch estimator will select the enabled note closest to the measured pitch. The Bias control adds some preference for the current note - this allows it to go off-tune more than would be the case otherwise."}, + { "filter", CONTROL_IN, 0.100000, 0.020000, 0.500000, "This sets the amount of smoothing on the pitch correction while the current note does not change. If it does change the filter is bypassed and the correction jumps immediately to the new value."}, + { "corr", CONTROL_IN, 1.000000, 0.000000, 1.000000, "Determines how much of the estimated pitch error gets corrected. Full correction may remove expression or vibrato."}, + { "offset", CONTROL_IN, 0.000000, -2.000000, 2.000000, "Adds an offset in the range of +/- two semitones to the pitch correction. With the Correction control set to zero the result is a constant pitch change."}, + { "m00", CONTROL_IN, 1.000000, 0.000000, 1.000000, "C"}, + { "m01", CONTROL_IN, 1.000000, 0.000000, 1.000000, "C#"}, + { "m02", CONTROL_IN, 1.000000, 0.000000, 1.000000, "D"}, + { "m03", CONTROL_IN, 1.000000, 0.000000, 1.000000, "D#"}, + { "m04", CONTROL_IN, 1.000000, 0.000000, 1.000000, "E"}, + { "m05", CONTROL_IN, 1.000000, 0.000000, 1.000000, "F"}, + { "m06", CONTROL_IN, 1.000000, 0.000000, 1.000000, "F#"}, + { "m07", CONTROL_IN, 1.000000, 0.000000, 1.000000, "G"}, + { "m08", CONTROL_IN, 1.000000, 0.000000, 1.000000, "G#"}, + { "m09", CONTROL_IN, 1.000000, 0.000000, 1.000000, "A"}, + { "m10", CONTROL_IN, 1.000000, 0.000000, 1.000000, "A#"}, + { "m11", CONTROL_IN, 1.000000, 0.000000, 1.000000, "B"}, + { "panic", CONTROL_IN, 0.000000, 0.000000, 1.000000, "MIDI Panic"}, + { "nmask", CONTROL_OUT, nan, 0.000000, 4096.000000, "Note Mask"}, + { "nset", CONTROL_OUT, nan, 0.000000, 4096.000000, "Note Set"}, + { "error", CONTROL_OUT, nan, -1.000000, 1.000000, "Pitch Error"}, + { "latency", CONTROL_OUT, nan, 0.000000, 4096.000000, "latency"}, + { "scale00", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (C)"}, + { "scale01", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (C#)"}, + { "scale02", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (D)"}, + { "scale03", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (D#)"}, + { "scale04", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (E)"}, + { "scale05", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (F)"}, + { "scale06", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (F#)"}, + { "scale07", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (G)"}, + { "scale08", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (G#)"}, + { "scale09", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (A)"}, + { "scale10", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (A#)"}, + { "scale11", CONTROL_IN, 0.000000, -1.000000, 1.000000, "Note Tuning (B)"}, + } + , 39 // uint32_t nports_total + , 1 // uint32_t nports_audio_in + , 1 // uint32_t nports_audio_out + , 1 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 0 // uint32_t nports_atom_in + , 0 // uint32_t nports_atom_out + , 36 // uint32_t nports_ctrl + , 32 // uint32_t nports_ctrl_in + , 4 // uint32_t nports_ctrl_out + , 8192 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , 26 // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.micro.ttl.in x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.micro.ttl.in --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.micro.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.micro.ttl.in 2019-07-14 19:38:55.000000000 +0000 @@ -0,0 +1,111 @@ + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 27 ; + lv2:symbol "scale00" ; + lv2:name "Note Tuning (C)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 28 ; + lv2:symbol "scale01" ; + lv2:name "Note Tuning (C#)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 29 ; + lv2:symbol "scale02" ; + lv2:name "Note Tuning (D)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 30 ; + lv2:symbol "scale03" ; + lv2:name "Note Tuning (D#)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 31 ; + lv2:symbol "scale04" ; + lv2:name "Note Tuning (E)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 32 ; + lv2:symbol "scale05" ; + lv2:name "Note Tuning (F)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 33 ; + lv2:symbol "scale06" ; + lv2:name "Note Tuning (F#)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 34 ; + lv2:symbol "scale07" ; + lv2:name "Note Tuning (G)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 35 ; + lv2:symbol "scale08" ; + lv2:name "Note Tuning (G#)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 36 ; + lv2:symbol "scale09" ; + lv2:name "Note Tuning (A)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 37 ; + lv2:symbol "scale10" ; + lv2:name "Note Tuning (A#)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ] , [ + a lv2:InputPort , + lv2:ControlPort ; + lv2:index 38 ; + lv2:symbol "scale11" ; + lv2:name "Note Tuning (B)"; + lv2:default 0 ; + lv2:minimum -1 ; + lv2:maximum 1 ; + ]; + rdfs:comment "AT1 is an 'autotuner', normally used to correct the pitch of a voice singing (slightly) out of tune. The 'expected' pitch can be controlled by MIDI, or be a fixed set of notes. AT1 can probably be used on some instruments as well, but is primarily designed to cover the vocal range. This variant allows to apply microtonal adjustments per note."; + . diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.ttl.in x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.ttl.in --- x42-plugins-20170428/fat1.lv2/lv2ttl/fat1.ttl.in 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/fat1.ttl.in 2019-07-14 19:38:55.000000000 +0000 @@ -5,6 +5,7 @@ @prefix lv2: . @prefix midi: . @prefix mod: . +@prefix opts: . @prefix pprop: . @prefix rdf: . @prefix rdfs: . @@ -19,308 +20,3 @@ foaf:name "Robin Gareus"; foaf:mbox ; foaf:homepage . - - - a lv2:Plugin, doap:Project, lv2:WaveshaperPlugin; - doap:license ; - doap:maintainer ; - doap:name "Autotune"; - rdfs:comment "AT1 is an 'autotuner', normally used to correct the pitch of a voice singing (slightly) out of tune. The 'expected' pitch can be controlled by MIDI, or be a fixed set of notes. AT1 can probably be used on some instruments as well, but is primarily designed to cover the vocal range."; - @VERSION@ - @UITTL@ - lv2:optionalFeature lv2:hardRTCapable; - lv2:requiredFeature urid:map; - @MODBRAND@ - @MODLABEL@ - @SIGNATURE@ - - lv2:port [ - a atom:AtomPort, lv2:InputPort; - atom:bufferType atom:Sequence; - atom:supports midi:MidiEvent; - lv2:index 0; - lv2:symbol "midiin"; - lv2:name "MIDI In"; - lv2:portProperty lv2:isSideChain; - ] , [ - a lv2:AudioPort , - lv2:InputPort ; - lv2:index 1 ; - lv2:symbol "in" ; - lv2:name "Input" - ] , [ - a lv2:AudioPort , - lv2:OutputPort ; - lv2:index 2 ; - lv2:symbol "out" ; - lv2:name "Output" - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 3 ; - lv2:symbol "mode" ; - lv2:name "Mode"; - lv2:default 0 ; - lv2:minimum 0 ; - lv2:maximum 2 ; - lv2:portProperty lv2:integer, lv2:enumeration; - lv2:scalePoint [ rdfs:label "Auto"; rdf:value 0 ; ] ; - lv2:scalePoint [ rdfs:label "MIDI"; rdf:value 1 ; ] ; - lv2:scalePoint [ rdfs:label "Manual"; rdf:value 2 ; ] ; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 4 ; - lv2:symbol "channelf" ; - lv2:name "Filter Channel"; - lv2:minimum 0 ; - lv2:maximum 16 ; - lv2:default 0; - lv2:scalePoint [ rdfs:label "Any"; rdf:value 0 ]; - lv2:scalePoint [ rdfs:label "01" ; rdf:value 1 ]; - lv2:scalePoint [ rdfs:label "02" ; rdf:value 2 ]; - lv2:scalePoint [ rdfs:label "03" ; rdf:value 3 ]; - lv2:scalePoint [ rdfs:label "04" ; rdf:value 4 ]; - lv2:scalePoint [ rdfs:label "05" ; rdf:value 5 ]; - lv2:scalePoint [ rdfs:label "06" ; rdf:value 6 ]; - lv2:scalePoint [ rdfs:label "07" ; rdf:value 7 ]; - lv2:scalePoint [ rdfs:label "08" ; rdf:value 8 ]; - lv2:scalePoint [ rdfs:label "09" ; rdf:value 9 ]; - lv2:scalePoint [ rdfs:label "10" ; rdf:value 10 ]; - lv2:scalePoint [ rdfs:label "11" ; rdf:value 11 ]; - lv2:scalePoint [ rdfs:label "12" ; rdf:value 12 ]; - lv2:scalePoint [ rdfs:label "13" ; rdf:value 13 ]; - lv2:scalePoint [ rdfs:label "14" ; rdf:value 14 ]; - lv2:scalePoint [ rdfs:label "15" ; rdf:value 15 ]; - lv2:scalePoint [ rdfs:label "16" ; rdf:value 16 ]; - lv2:portProperty lv2:integer, lv2:enumeration; - rdfs:comment "MIDI Channel (1..16) on which the filter is active; 0: any)." ; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 5 ; - lv2:symbol "tuning" ; - lv2:name "Tuning"; - lv2:default 440.0 ; - lv2:minimum 400.0 ; - lv2:maximum 480.0 ; - units:unit units:hz; - pprop:rangeSteps 400; - rdfs:comment "This sets the frequency corresponding to 'A' pitch, in other words the required tuning. This will be the default 440 Hz in most cases."; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 6 ; - lv2:symbol "bias" ; - lv2:name "Bias"; - lv2:default 0.5 ; - lv2:minimum 0.0 ; - lv2:maximum 1.0 ; - pprop:rangeSteps 270; - rdfs:comment "Normally the pitch estimator will select the enabled note closest to the measured pitch. The Bias control adds some preference for the current note - this allows it to go off-tune more than would be the case otherwise."; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 7 ; - lv2:symbol "filter" ; - lv2:name "Filter"; - lv2:default 0.1 ; - lv2:minimum 0.02 ; - lv2:maximum 0.5 ; - lv2:scalePoint [ rdfs:label "Slow"; rdf:value 0.5 ; ] ; - lv2:scalePoint [ rdfs:label "Med"; rdf:value 0.1 ; ] ; - lv2:scalePoint [ rdfs:label "Fast"; rdf:value 0.02 ; ] ; - lv2:portProperty pprop:logarithmic; - pprop:rangeSteps 200; - rdfs:comment "This sets the amount of smoothing on the pitch correction while the current note does not change. If it does change the filter is bypassed and the correction jumps immediately to the new value."; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 8 ; - lv2:symbol "corr" ; - lv2:name "Correction"; - lv2:default 1.0 ; - lv2:minimum 0.0 ; - lv2:maximum 1.0 ; - pprop:rangeSteps 270; - rdfs:comment "Determines how much of the estimated pitch error gets corrected. Full correction may remove expression or vibrato."; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 9 ; - lv2:symbol "offset" ; - lv2:name "Offset"; - lv2:default 0.0 ; - lv2:minimum -2.0 ; - lv2:maximum 2.0 ; - pprop:rangeSteps 400; - units:unit units:semitone12TET; - rdfs:comment "Adds an offset in the range of +/- two semitones to the pitch correction. With the Correction control set to zero the result is a constant pitch change."; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 10 ; - lv2:symbol "m00" ; - lv2:name "C"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 11 ; - lv2:symbol "m01" ; - lv2:name "C#"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 12 ; - lv2:symbol "m02" ; - lv2:name "D"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 13 ; - lv2:symbol "m03" ; - lv2:name "D#"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 14 ; - lv2:symbol "m04" ; - lv2:name "E"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 15 ; - lv2:symbol "m05" ; - lv2:name "F"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 16 ; - lv2:symbol "m06" ; - lv2:name "F#"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 17 ; - lv2:symbol "m07" ; - lv2:name "G"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 18 ; - lv2:symbol "m08" ; - lv2:name "G#"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 19 ; - lv2:symbol "m09" ; - lv2:name "A"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 20 ; - lv2:symbol "m10" ; - lv2:name "A#"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 21 ; - lv2:symbol "m11" ; - lv2:name "B"; - lv2:default 1 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled; - ] , [ - a lv2:InputPort , - lv2:ControlPort ; - lv2:index 22 ; - lv2:symbol "panic" ; - lv2:name "MIDI Panic"; - lv2:default 0 ; - lv2:minimum 0 ; - lv2:maximum 1 ; - lv2:portProperty lv2:integer, lv2:toggled, pprop:trigger; - ] , [ - a lv2:OutputPort , - lv2:ControlPort ; - lv2:index 23 ; - lv2:symbol "nmask" ; - lv2:name "Note Mask"; - lv2:minimum 0 ; - lv2:maximum 4096 ; - lv2:portProperty lv2:integer; - ] , [ - a lv2:OutputPort , - lv2:ControlPort ; - lv2:index 24 ; - lv2:symbol "nset" ; - lv2:name "Note Set"; - lv2:minimum 0 ; - lv2:maximum 4096 ; - lv2:portProperty lv2:integer; - ] , [ - a lv2:OutputPort , - lv2:ControlPort ; - lv2:index 25 ; - lv2:symbol "error" ; - lv2:name "Pitch Error"; - lv2:minimum -1.0 ; - lv2:maximum 1.0 ; - ] , [ - a lv2:OutputPort , - lv2:ControlPort ; - lv2:index 26 ; - lv2:symbol "latency" ; - lv2:name "latency"; - lv2:minimum 0 ; - lv2:maximum 4096; - lv2:portProperty lv2:reportsLatency, lv2:integer; - units:unit units:frame; - ]; - . diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/manifest.ttl.in x42-plugins-20190714/fat1.lv2/lv2ttl/manifest.ttl.in --- x42-plugins-20170428/fat1.lv2/lv2ttl/manifest.ttl.in 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/manifest.ttl.in 2019-07-14 19:38:55.000000000 +0000 @@ -9,3 +9,8 @@ a lv2:Plugin ; lv2:binary ; rdfs:seeAlso . + + + a lv2:Plugin ; + lv2:binary ; + rdfs:seeAlso . diff -Nru x42-plugins-20170428/fat1.lv2/lv2ttl/plugins.h x42-plugins-20190714/fat1.lv2/lv2ttl/plugins.h --- x42-plugins-20170428/fat1.lv2/lv2ttl/plugins.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/lv2ttl/plugins.h 2019-07-14 19:38:55.000000000 +0000 @@ -0,0 +1,10 @@ +#define X42_MULTIPLUGIN_NAME "Autotune" +#define X42_MULTIPLUGIN_URI "http://gareus.org/oss/lv2/fat1" + +#include "lv2ttl/fat1_chroma.h" +#include "lv2ttl/fat1_micro.h" + +static const RtkLv2Description _plugins[] = { + _fat1_micro, + _fat1_chroma +}; diff -Nru x42-plugins-20170428/fat1.lv2/Makefile x42-plugins-20190714/fat1.lv2/Makefile --- x42-plugins-20170428/fat1.lv2/Makefile 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/Makefile 2019-07-14 19:38:55.000000000 +0000 @@ -12,6 +12,8 @@ OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CXXFLAGS ?= -Wall -g -Wno-unused-function + +PKG_CONFIG?=pkg-config STRIP ?= strip BUILDOPENGL?=yes @@ -65,7 +67,7 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_GL_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` STRIPFLAGS= -s EXTENDED_RE=-r endif @@ -104,6 +106,7 @@ endif ifneq ($(MOD),) targets+=$(BUILDDIR)modgui + override CXXFLAGS += -DMOD endif ############################################################################### @@ -113,26 +116,26 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --exists fftw3f || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f || echo no), no) $(error "fftw3f library was not found") endif -ifeq ($(shell pkg-config --atleast-version=1.6.0 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) $(error "LV2 SDK needs to be version 1.6.0 or later") endif ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) - ifeq ($(shell pkg-config --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") endif endif ifneq ($(BUILDJACKAPP), no) - ifeq ($(shell pkg-config --exists jack || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif @@ -140,7 +143,7 @@ endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CXXFLAGS += -DHAVE_LV2_1_8 endif @@ -168,17 +171,17 @@ # add library dependent flags and libs override CXXFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(fat1_VERSION)\"" -override CXXFLAGS += `pkg-config --cflags lv2 fftw3f` +override CXXFLAGS += `$(PKG_CONFIG) --cflags lv2 fftw3f` ifeq ($(XWIN),) override CXXFLAGS += -fPIC -fvisibility=hidden else override CXXFLAGS += -DPTW32_STATIC_LIB endif -override LOADLIBES += `pkg-config --libs lv2 fftw3f` +override LOADLIBES += `$(PKG_CONFIG) --libs lv2 fftw3f` -GLUICFLAGS+=`pkg-config --cflags cairo pango` $(CXXFLAGS) -GLUILIBS+=`pkg-config $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` $(CXXFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 @@ -189,15 +192,15 @@ ifneq ($(LIC_CFLAGS),) - SIGNATURE=lv2:extensionData \\; + LV2SIGN=lv2:extensionData \\; override CXXFLAGS += -I$(RW) endif ROBGL+= Makefile JACKCFLAGS=-I. $(CXXFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` -JACKLIBS=-lm $(GLUILIBS) $(LIC_LOADLIBES) $(LOADLIBES) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) ############################################################################### @@ -231,10 +234,16 @@ lv2ttl/manifest.modgui.in >> $(BUILDDIR)manifest.ttl endif -$(BUILDDIR)$(LV2NAME).ttl: Makefile lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).gui.in +$(BUILDDIR)$(LV2NAME).ttl: Makefile lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).base.ttl.in lv2ttl/$(LV2NAME).chroma.ttl.in lv2ttl/$(LV2NAME).micro.ttl.in lv2ttl/$(LV2NAME).gui.in @mkdir -p $(BUILDDIR) - sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(SIGNATURE)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/" \ + sed "s/@LV2NAME@/$(LV2NAME)/g" \ lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@URISUFFIX@//;s/@NAMESUFFIX@//" \ + lv2ttl/$(LV2NAME).base.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + cat lv2ttl/$(LV2NAME).chroma.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@URISUFFIX@/#microtonal/;s/@NAMESUFFIX@/ (microtonal)/" \ + lv2ttl/$(LV2NAME).base.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl + cat lv2ttl/$(LV2NAME).micro.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl ifneq ($(BUILDOPENGL), no) sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ lv2ttl/$(LV2NAME).gui.in >> $(BUILDDIR)$(LV2NAME).ttl @@ -254,12 +263,12 @@ jackapps: $(JACKAPP) -$(eval x42_fat1_JACKSRC = src/fat1.cc src/retuner.cc src/resampler.cc src/resampler-table.cc) +$(eval x42_fat1_JACKSRC = -DX42_MULTIPLUGIN src/fat1.cc src/retuner.cc src/resampler.cc src/resampler-table.cc) x42_fat1_JACKGUI = gui/fat1.c -x42_fat1_LV2HTTL = lv2ttl/fat1.h +x42_fat1_LV2HTTL = lv2ttl/plugins.h x42_fat1_JACKDESC = lv2ui_descriptor $(APPBLD)x42-fat1$(EXE_EXT): $(DSP_DEPS) $(GUI_DEPS) \ - $(x42_fat1_JACKGUI) $(x42_fat1_LV2HTTL) + $(x42_fat1_LV2HTTL) lv2ttl/fat1_chroma.h lv2ttl/fat1_micro.h ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) -include $(RW)robtk.mk diff -Nru x42-plugins-20170428/fat1.lv2/Makefile.git x42-plugins-20190714/fat1.lv2/Makefile.git --- x42-plugins-20170428/fat1.lv2/Makefile.git 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/Makefile.git 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -#!/usr/bin/make - -submodules: - git submodule init - git submodule update - -submodule_update: - git submodule update - -submodule_pull: - git submodule foreach "git pull" - -submodule_check: - @-test -d .git -a .gitmodules && \ - git submodule status \ - | grep -q "^-" \ - && $(MAKE) submodules || true - @-test -d .git -a .gitmodules && \ - git submodule status \ - | grep -q "^+" \ - && $(MAKE) submodule_update || true - -.PHONY: submodule_check submodules submodule_update submodule_pull Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/active_note.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/active_note.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/aluminium.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/aluminium.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/dropdown-arrow-black.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/dropdown-arrow-black.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/footswitch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/footswitch.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/pitcherror.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/pitcherror.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/screenshot-x42-autotune.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/screenshot-x42-autotune.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/thumbnail-x42-autotune.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/thumbnail-x42-autotune.png differ diff -Nru x42-plugins-20170428/fat1.lv2/modgui/x42-autotune.css x42-plugins-20190714/fat1.lv2/modgui/x42-autotune.css --- x42-plugins-20170428/fat1.lv2/modgui/x42-autotune.css 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/modgui/x42-autotune.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,341 +0,0 @@ -@import url(/fonts/nexa/stylesheet.css); -@import url(/fonts/questrial/stylesheet.css); - - -/* = CONTAINER -================================================ */ -.x42-autotune{{{cns}}} { - background-image:url(/resources/x42-fat1.png{{{ns}}}); - background-position:center center; - background-repeat:no-repeat; - background-size:421px 431px; - border-radius: 21px; - height:431px; - position:absolute; - width:421px; -} - -/* = Labels -================================================ */ -.x42-autotune{{{cns}}} .x42-brand { - bottom: 50px; - cursor:default; - left: 40px; - position:absolute; - text-align:center; - width: 25px; -} - -.x42-autotune{{{cns}}} .x42-brand h1 { - color:#aaa; - font-family:"Nexa"; - font-size:28px; - margin:0; - padding:0; - text-shadow: -2px 2px 2px #444; - transform: rotate(270deg); - -webkit-transform: rotate(270deg); -} - -.x42-autotune{{{cns}}} .x42-plugin-name { - bottom:48px; - overflow:hidden; - position:absolute; - right:38px; - text-align:center; - text-shadow: 0 0 1px #ccc; -} - -.x42-autotune{{{cns}}} .x42-plugin-name h1 { - font-family:"Questrial"; - font-size:21px; - line-height:1; -} - -/* = LIGHT ON/OFF -================================================ */ -.x42-autotune{{{cns}}} .mod-light { - background-position:center center; - background-repeat:no-repeat; - bottom:95px; - height:32px; - left:20px; - position:absolute; - right:20px; -} - -/* = FOOTSWITCH -================================================ */ -.x42-autotune{{{cns}}} .mod-footswitch { - background-image:url(/resources/footswitch.png{{{ns}}}); - background-position:bottom center; - background-repeat:no-repeat; - background-size:auto 132px; - bottom: 39px; - cursor:pointer; - height:66px; - left: 20px; - margin: auto; - position:absolute; - right: 20px; - width: 66px; -} - -.x42-autotune{{{cns}}} .mod-footswitch.on { - background-position: top center !important; -} - - -/* = KNOBS -================================================ */ -.x42-autotune{{{cns}}} .mod-control-group { - margin:20px 20px 5px 20px !important; - position:relative; - text-align:center; - z-index:30; -} -.x42-autotune{{{cns}}} .top { - margin-top:0px !important; -} - -.x42-autotune{{{cns}}} .mod-control-group .mod-knob { - overflow:hidden; - position:relative; -} - -.x42-autotune{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - bottom:12px; - cursor:default; - display:block; - font-size:11px; - font-weight:bold; - height:12px; - left:0; - line-height:1; - margin:0; - overflow:hidden; - padding:0; - position:absolute; - right:0; - text-transform:uppercase; -} - -.x42-autotune{{{cns}}} .mod-control-group .mod-knob .mod-knob-value { - bottom:0px; - font-size:11px; - left:0; - line-height:1; - position:absolute; - right:0; - z-index:60; -} - -.x42-autotune{{{cns}}} .mod-control-group .mod-knob .mod-knob-image { - background-image:url(/resources/aluminium.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 60px; - height:60px; - width:60px; - margin:0 auto; -} - -.x42-autotune{{{cns}}} .mod-control-group .mod-knob { - display:inline-block; - height:88px; - margin: 1px 5px; -} - -/* = TOP-Row (enum + pitch-error bars) -================================================ */ -.x42-autotune{{{cns}}} .at-toprow { - height:31px; - margin:20px auto 5px auto !important; - width:300px; - z-index:35; -} - -.x42-autotune{{{cns}}} .pitcherror, -.x42-autotune{{{cns}}} .mod-enumerated-group { - height:31px; - margin:0 10px 0 10px; - position:relative; - width:130px; - float:left; -} - -.x42-autotune{{{cns}}} .pitcherror, -.x42-autotune{{{cns}}} .mod-enumerated .mod-enumerated-selected { - background-color:rgba(0,0,0,.3); - box-shadow:inset 0 0 4px rgba(0,0,0,.3); - border-radius:4px; -} - -/* = Pitch Error display -================================================ */ -.x42-autotune{{{cns}}} .pitcherror { - background-image:url(/resources/pitcherror.png{{{ns}}}); - background-position:center; - background-repeat:no-repeat; - overflow:hidden; -} - -.x42-autotune{{{cns}}} .pitcherror .bar { - background:#00ff00; - box-shadow: 0px 0px 0px 1px #000; - position:absolute; - width:3px; - margin:0; - padding:0; - height:31px; - top:0px; - left:63px; -} - -.x42-autotune{{{cns}}} .pitcherror .bar.bad { - background:#ff0000; -} - -/* = ENUMERATED LIST -================================================ */ - -.x42-autotune{{{cns}}} .mod-enumerated { - background-image:url(/resources/dropdown-arrow-black.png{{{ns}}}); - background-position:right center; - background-repeat:no-repeat; - font-size:11px; - font-weight:bold; - left:0; - line-height:2; - overflow:hidden; - position:absolute; - right:0; - text-align:center; -} - -.x42-autotune{{{cns}}} .mod-enumerated .mod-enumerated-selected { - padding:3px 9px; -} - -.x42-autotune{{{cns}}} .mod-enumerated .mod-enumerated-list { - background-color:rgba(0,0,0,.9); - color:#fff; - display:none; - height:115px; - overflow:auto; - position:relative; -} - -.x42-autotune{{{cns}}} .mod-enumerated .mod-enumerated-list > div { - padding:3px 9px; -} - -.x42-autotune{{{cns}}} .mod-enumerated .mod-enumerated-list > div:hover { - background-color:rgba(255,255,255,.2); - cursor:pointer; -} - -/* = Piano -================================================ */ -.x42-autotune{{{cns}}} .pianokeyboard { - background-color:black; - margin: 5px auto; - position:relative; - overflow:hidden; - padding:0 0 2px 3px; - width:368px; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key { - float: left; - box-shadow: 0 2px 2px 1px #999 inset; -} - -.x42-autotune{{{cns}}} .pianokeyboard .active, -.x42-autotune{{{cns}}} .pianokeyboard .active:after { - background-image:url(/resources/active_note.png{{{ns}}}); - background-position:center bottom 10px; - background-repeat:no-repeat; -} - -.x42-autotune{{{cns}}} .pianokeyboard .active:after { - background-size:20px 20px; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-black.off.midion::after, -.x42-autotune{{{cns}}} .pianokeyboard .active.on:after { - background-position:center bottom 7px; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-black.on.midioff::after { - background-position:center bottom 10px !important; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-white { - background-color:#fff; - border-radius: 0 0 4px 4px; - height: 140px; - margin: 0 2px 2px 0; - position: relative; - width: 50px; - z-index:50; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-white.on.midioff { - background-color:#fff; - box-shadow: 0 2px 2px 1px #999 inset; - top: 0px; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-white.midion, -.x42-autotune{{{cns}}} .pianokeyboard .key-white.on { - background-color: #efedee; - box-shadow: 2px 2px 3px 1px #999 inset, -3px 2px 3px 1px #999 inset; - top: -1px; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-black { - width: 0; - margin: 0; -} - - -.x42-autotune{{{cns}}} .pianokeyboard .key-black.off.midion:after, -.x42-autotune{{{cns}}} .pianokeyboard .key-black.on::after { - background-color:#3c3c3c; - border-radius: 0 0 4px 4px; - box-shadow: -1px 0 1px 0 #666, 1px 0px 3px 0 #888, 0 5px 0 3px #000, 0px 3px 3px 1px #000 inset; - content: ""; - display: block; - height: 84px; - position: relative; - width: 30px; - left: -16px; - top: -2px; - z-index:51; -} - -.x42-autotune{{{cns}}} .pianokeyboard .key-black.on.midioff:after, -.x42-autotune{{{cns}}} .pianokeyboard .key-black.off::after { - background-color:#444; - border-radius: 0 0 4px 4px; - box-shadow: -2px 1px 2px 0px #ddd, 1px 1px 0px 1px #444, 0 3px 0 3px #000, 2px 0px 3px 0px #999 inset, -3px 0px 3px 0px #333 inset; - content: ""; - display: block; - height: 86px; - position: relative; - width: 30px; - left: -16px; - top: -2px; - z-index:51; -} - -/* = COLORS -================================================ */ -.x42-autotune{{{cns}}} h1, -.x42-autotune{{{cns}}} .mod-enumerated, -.x42-autotune{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - color:black; -} -.x42-autotune{{{cns}}} h1 { - border-color:black; -} diff -Nru x42-plugins-20170428/fat1.lv2/modgui/x42-autotune.html x42-plugins-20190714/fat1.lv2/modgui/x42-autotune.html --- x42-plugins-20170428/fat1.lv2/modgui/x42-autotune.html 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/modgui/x42-autotune.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -
-
-

x42

-

fAT1

- -
-
-
-
-
-
Auto
-
MIDI
-
Manual
-
-
-
-
-
-
-
- -
-
-
- Tuning -
-
-
-
- Bias -
-
-
- Filter -
-
-
- Corr. -
-
-
- Offset -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
- {{#effect.ports.audio.input}} -
-
-
- {{/effect.ports.audio.input}} - {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} - {{#effect.ports.cv.input}} -
-
-
- {{/effect.ports.cv.input}} -
-
- {{#effect.ports.audio.output}} -
-
-
- {{/effect.ports.audio.output}} - {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} - {{#effect.ports.cv.output}} -
-
-
- {{/effect.ports.cv.output}} -
-
diff -Nru x42-plugins-20170428/fat1.lv2/modgui/x42-autotune.js x42-plugins-20190714/fat1.lv2/modgui/x42-autotune.js --- x42-plugins-20170428/fat1.lv2/modgui/x42-autotune.js 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/modgui/x42-autotune.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -function (event) { - - /* mask midi selected notes */ - function mask_key (id, midimode) { - var sym = id; - if (id < 10) { sym = "0" + id; } - var key = event.icon.find ('[mod-port-symbol=m' + sym +']'); - if (midimode > 0) { - key.removeClass ('midioff'); - key.addClass ('midion'); - } else if (midimode < 0) { - key.removeClass ('midion'); - key.addClass ('midioff'); - } else { - /* note is under user control */ - key.removeClass ('midion'); - key.removeClass ('midioff'); - } - } - - /* highlight detected note(s) */ - function set_key (id, on) { - var sym = id; - if (id < 10) { sym = "0" + id; } - var key = event.icon.find ('[mod-port-symbol=m' + sym +']'); - if (on) { - key.addClass ('active'); - } else { - key.removeClass ('active'); - } - } - - function update_midi_mask (data) { - if (data.mode == 2 || (data.mode == 0 && data.nmask == 0)) { - /* manual mode -- control input applies */ - /* auto mode -- control applies IFF no midi notes are set */ - for (k = 0; k < 12; ++k) { - mask_key (k, 0); - } - return; - } - /* midi rulez */ - for (k = 0; k < 12; ++k) { - mask_key (k, (Math.floor (data.nmask) & (1 << k)) == 0 ? -1 : 1); - } - } - - function update_note_set (data) { - for (k = 0; k < 12; ++k) { - set_key (k, Math.floor (data.nset) & (1 << k)); - } - } - - function update_pitcherror (err) { - var bar = event.icon.find ('[mod-role=pitch-error]'); - if (Math.abs (err) > 0.33) { - bar.addClass ('bad'); - } else { - bar.removeClass ('bad'); - } - var pos = 63 + 64 * err; - bar.css ('left', pos + 'px'); /* CSS or style? XXX */ - } - - /* top-level entry, called from mod-ui */ - if (event.type == 'start') { - var ports = event.ports; - var data = {}; - data.mode = 0; - data.nmask = 0; - data.nset = 0; - for (var p in ports) { - if (event.symbol == 'error') { - update_pitcherror (event.value); - } - else if (ports[p].symbol == 'mode') { - data.mode = event.value; - } - else if (ports[p].symbol == 'nmask') { - data.nmask = event.value; - } - else if (ports[p].symbol == 'nset') { - data.nset = event.value; - } - } - update_midi_mask (data); - update_note_set (data); - var ds = event.icon.find ('[mod-role=drag-handle]'); - ds.data ('persist', data); - } - else if (event.type == 'change') { - var ds = event.icon.find ('[mod-role=drag-handle]'); - var data = ds.data ('persist'); - if (event.symbol == 'error') { - update_pitcherror (event.value); - return; - } - else if (event.symbol == 'mode') { - data.mode = event.value; - update_midi_mask (data); - } - else if (event.symbol == 'nmask') { - data.nmask = event.value; - update_midi_mask (data); - } - else if (event.symbol == 'nset') { - data.nset = event.value; - update_note_set (data); - } - ds.data ('persist', data); - } -} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fat1.lv2/modgui/x42-fat1.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fat1.lv2/modgui/x42-fat1.png differ diff -Nru x42-plugins-20170428/fat1.lv2/src/fat1.cc x42-plugins-20190714/fat1.lv2/src/fat1.cc --- x42-plugins-20170428/fat1.lv2/src/fat1.cc 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/src/fat1.cc 2019-07-14 19:38:55.000000000 +0000 @@ -32,6 +32,7 @@ #include "retuner.h" static pthread_mutex_t fftw_planner_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int instance_count = 0; typedef struct { LV2_URID atom_Sequence; @@ -59,6 +60,8 @@ int midichan; float latency; + bool microtonal; + uint32_t noteset_update_interval; uint32_t noteset_update_counter; int noteset; @@ -111,8 +114,10 @@ } // no break -- fallthrough, note-on velocity 0 case 0x80: - self->notes [n % 12] -= 1; - return 1; + if (self->notes [n % 12]) { + self->notes [n % 12] -= 1; + return 1; + } default: break; } @@ -133,6 +138,15 @@ Fat1* self = (Fat1*)calloc (1, sizeof (Fat1)); LV2_URID_Map* map = NULL; + if (0 == strcmp(descriptor->URI, FAT1_URI)) { + self->microtonal = false; + } else if (0 == strcmp(descriptor->URI, FAT1_URI "#microtonal")) { + self->microtonal = true; + } else { + free (self); + return 0; + } + int i; for (i=0; features[i]; ++i) { if (!strcmp (features[i]->URI, LV2_URID__map)) { @@ -152,6 +166,7 @@ pthread_mutex_lock(&fftw_planner_lock); self->retuner = new LV2AT::Retuner (rate); + ++instance_count; pthread_mutex_unlock(&fftw_planner_lock); self->notemask = 0xfff; @@ -258,6 +273,12 @@ self->retuner->set_corroffs (*self->port [FAT_OFFS]); self->retuner->set_notemask (notes); + if (self->microtonal) { + for (int i = 0; i < 12; ++i) { + self->retuner->set_notescale (i, *self->port [FAT_SCALE + i]); + } + } + /* process */ self->retuner->process (n_samples, self->port [FAT_INPUT], self->port [FAT_OUTPUT]); @@ -280,6 +301,23 @@ Fat1* self = (Fat1*)instance; pthread_mutex_lock(&fftw_planner_lock); delete self->retuner; + if (instance_count > 0) { + --instance_count; + } +#ifdef WITH_STATIC_FFTW_CLEANUP + /* use this only when statically linking to a local fftw! + * + * "After calling fftw_cleanup, all existing plans become undefined, + * and you should not attempt to execute them nor to destroy them." + * [http://www.fftw.org/fftw3_doc/Using-Plans.html] + * + * If libfftwf is shared with other plugins or the host this can + * cause undefined behavior. + */ + if (instance_count == 0) { + fftwf_cleanup (); + } +#endif pthread_mutex_unlock(&fftw_planner_lock); free (instance); } @@ -309,6 +347,18 @@ extension_data }; +static const LV2_Descriptor descriptor_microtonal = { + FAT1_URI "#microtonal", + instantiate, + connect_port, + activate, + run, + NULL, + cleanup, + extension_data +}; + + #undef LV2_SYMBOL_EXPORT #ifdef _WIN32 # define LV2_SYMBOL_EXPORT __declspec(dllexport) @@ -322,6 +372,8 @@ switch (index) { case 0: return &descriptor; + case 1: + return &descriptor_microtonal; default: return NULL; } diff -Nru x42-plugins-20170428/fat1.lv2/src/fat1.h x42-plugins-20190714/fat1.lv2/src/fat1.h --- x42-plugins-20170428/fat1.lv2/src/fat1.h 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/src/fat1.h 2019-07-14 19:38:55.000000000 +0000 @@ -17,5 +17,6 @@ FAT_NSET, FAT_ERRR, FAT_LTNC, - FAT_LAST + FAT_SCALE, // +12 notes (microtonal only) + FAT_LAST = 39 } PortIndex; diff -Nru x42-plugins-20170428/fat1.lv2/src/retuner.cc x42-plugins-20190714/fat1.lv2/src/retuner.cc --- x42-plugins-20170428/fat1.lv2/src/retuner.cc 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/src/retuner.cc 2019-07-14 19:38:55.000000000 +0000 @@ -134,6 +134,10 @@ _frcount = 0; _rindex1 = _ipsize / 2; _rindex2 = 0; + + for (int i = 0; i < 12; ++i) { + _notescale[i] = i; + } } @@ -323,6 +327,9 @@ { int d, h, i, j, k; float f, m, t, x, y, z; +#ifdef MOD + float rms = 0; +#endif d = _upsamp ? 2 : 1; h = _fftlen / 2; @@ -330,9 +337,19 @@ k = _ipsize - 1; for (i = 0; i < _fftlen; i++) { - _fftTdata [i] = _fftTwind [i] * _ipbuff [j & k]; + int jk = j & k; + _fftTdata [i] = _fftTwind [i] * _ipbuff [jk]; +#ifdef MOD + rms += _ipbuff [jk] * _ipbuff [jk]; +#endif j += d; } +#ifdef MOD // ignore noise-floor + if (rms < _fftlen * 0.000031623f) { // signal < -45dBFS/RMS + _cycle = 0; + return; + } +#endif fftwf_execute_dft_r2c (_fwdplan, _fftTdata, _fftFdata); f = _fsamp / (_fftlen * 3e3f); for (i = 0; i < h; i++) @@ -405,7 +422,7 @@ { if (_notemask & m) { - d = f - (i - 9) / 12.0f; + d = f - (_notescale[i] - 9) / 12.0f; d -= floorf (d + 0.5f); a = fabsf (d); if (i == _lastnote) a -= _notebias; diff -Nru x42-plugins-20170428/fat1.lv2/src/retuner.h x42-plugins-20190714/fat1.lv2/src/retuner.h --- x42-plugins-20170428/fat1.lv2/src/retuner.h 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/src/retuner.h 2019-07-14 19:38:55.000000000 +0000 @@ -66,7 +66,12 @@ { _notemask = k; } - + + void set_notescale (int i, float v) + { + _notescale[i] = i + v; + } + int get_noteset (void) { int k; @@ -123,6 +128,9 @@ fftwf_plan _fwdplan; fftwf_plan _invplan; LV2AT::Resampler _resampler; + + float _notescale[12]; + }; }; diff -Nru x42-plugins-20170428/fat1.lv2/x42-fat1.1 x42-plugins-20190714/fat1.lv2/x42-fat1.1 --- x42-plugins-20170428/fat1.lv2/x42-fat1.1 2017-04-27 23:57:08.000000000 +0000 +++ x42-plugins-20190714/fat1.lv2/x42-fat1.1 2019-07-14 19:38:55.000000000 +0000 @@ -1,15 +1,24 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH X42-FAT1 "1" "April 2017" "x42-fat1 version 0.3.3" "User Commands" +.TH X42-FAT1 "1" "July 2019" "x42-fat1 version 0.5.4" "User Commands" .SH NAME x42-fat1 \- x42 JACK Auto Tune .SH SYNOPSIS .B x42-fat1 -[ \fI\,OPTIONS \/\fR] +[ \fI\,OPTIONS \/\fR] [ \fI\,Plugin-ID or URI \/\fR] .SH DESCRIPTION x42\-fat1 \- JACK Autotune .PP -This is a standalone JACK application of the LV2 plugin: -"Autotune". +This is a standalone JACK application of a collection of LV2 plugins. +Use ID \fB\-1\fR, \fB\-l\fR or \fB\-\-list\fR for a dedicated list of included plugins. +By default the first listed plugin (ID 0) is used. +.PP +List of available plugins: (ID "Name" URI) +.TP +0 +"Autotune (microtonal)" http://gareus.org/oss/lv2/fat1#microtonal +.TP +1 +"Autotune" http://gareus.org/oss/lv2/fat1 .PP Usage: All control elements are operated in using the mouse: @@ -33,6 +42,12 @@ Set the JACK client name (defaults to plugin\-name) .TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP +\fB\-l\fR, \fB\-\-list\fR +Print list of available plugins and exit +.TP \fB\-O\fR , \fB\-\-osc\fR Listen for OSC messages on the given UDP port .TP @@ -51,7 +66,7 @@ See also: Website: .SH COPYRIGHT -Copyright \(co GPL 2013\-2015 Robin Gareus +Copyright \(co GPL 2013\-2019 Robin Gareus .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/fil4.lv2/gui/analyser.cc x42-plugins-20190714/fil4.lv2/gui/analyser.cc --- x42-plugins-20170428/fil4.lv2/gui/analyser.cc 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/gui/analyser.cc 2019-07-14 19:39:06.000000000 +0000 @@ -63,6 +63,14 @@ #endif if (_fftplan) fftwf_destroy_plan (_fftplan); #ifdef WITH_FFTW_LOCK + if (instance_count > 0) { + --instance_count; + } +# ifdef WITH_STATIC_FFTW_CLEANUP + if (instance_count == 0) { + fftwf_cleanup (); + } +# endif pthread_mutex_unlock(&fftw_planner_lock); #endif delete _power; @@ -81,7 +89,14 @@ #ifdef WITH_FFTW_LOCK pthread_mutex_lock(&fftw_planner_lock); #endif - if (_fftplan) fftwf_destroy_plan (_fftplan); + if (_fftplan) { + fftwf_destroy_plan (_fftplan); + } +#ifdef WITH_FFTW_LOCK + else { + ++instance_count; + } +#endif _fftlen = fftlen; _fftplan = fftwf_plan_dft_r2c_1d (_fftlen, _warped, _trdata + 4, FFTW_ESTIMATE); #ifdef WITH_FFTW_LOCK diff -Nru x42-plugins-20170428/fil4.lv2/gui/fft.c x42-plugins-20190714/fil4.lv2/gui/fft.c --- x42-plugins-20170428/fil4.lv2/gui/fft.c 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/gui/fft.c 2019-07-14 19:39:06.000000000 +0000 @@ -1,5 +1,5 @@ /* FFT analysis - spectrogram - * Copyright (C) 2013 Robin Gareus + * Copyright (C) 2013, 2019 Robin Gareus * * 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 @@ -16,88 +16,169 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include #include #include -#include -#include #ifndef MIN -#define MIN(A,B) ( (A) < (B) ? (A) : (B) ) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) #endif static pthread_mutex_t fftw_planner_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int instance_count = 0; + +typedef enum { + W_HANN = 0, + W_HAMMMIN, + W_NUTTALL, + W_BLACKMAN_NUTTALL, + W_BLACKMAN_HARRIS, + W_FLAT_TOP +} window_t; /****************************************************************************** * internal FFT abstraction */ struct FFTAnalysis { - uint32_t window_size; - uint32_t data_size; - double rate; - double freq_per_bin; - double phasediff_step; - float *hann_window; - float *fft_in; - float *fft_out; - float *power; - float *phase; - float *phase_h; + uint32_t window_size; + window_t window_type; + uint32_t data_size; + double rate; + double freq_per_bin; + double phasediff_step; + float* window; + float* fft_in; + float* fft_out; + float* power; + float* phase; + float* phase_h; fftwf_plan fftplan; - float *ringbuf; + float* ringbuf; uint32_t rboff; uint32_t smps; uint32_t sps; uint32_t step; - double phasediff_bin; + double phasediff_bin; }; -/****************************************************************************** - * internal private functions +/* **************************************************************************** + * windows */ -static float * ft_hann_window(struct FFTAnalysis *ft) { - if (ft->hann_window) return ft->hann_window; - ft->hann_window = (float *) malloc(sizeof(float) * ft->window_size); +static double +ft_hannhamm (float* window, uint32_t n, double a, double b) +{ double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + for (uint32_t i = 0; i < n; ++i) { + window[i] = a - b * cos (c * i); + sum += window[i]; + } + return sum; +} - for (uint32_t i=0; i < ft->window_size; i++) { - ft->hann_window[i] = 0.5f - (0.5f * (float) cos(2.0f * M_PI * (float)i / (float)(ft->window_size))); - sum += ft->hann_window[i]; +static double +ft_bnh (float* window, uint32_t n, double a0, double a1, double a2, double a3) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i); + sum += window[i]; } + return sum; +} + +static double +ft_flattop (float* window, uint32_t n) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + const double c4 = 4.0 * c; + + const double a0 = 1.0; + const double a1 = 1.93; + const double a2 = 1.29; + const double a3 = 0.388; + const double a4 = 0.028; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i) + a4 * cos(c4 * i); + sum += window[i]; + } + return sum; +} + + +/* **************************************************************************** + * internal private functions + */ +static float* +ft_gen_window (struct FFTAnalysis* ft) +{ + if (ft->window) { + return ft->window; + } + + ft->window = (float*)malloc (sizeof (float) * ft->window_size); + double sum = .0; + + /* https://en.wikipedia.org/wiki/Window_function */ + switch (ft->window_type) { + default: + case W_HANN: + sum = ft_hannhamm (ft->window, ft->window_size, .5, .5); + break; + case W_HAMMMIN: + sum = ft_hannhamm (ft->window, ft->window_size, .54, .46); + break; + case W_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .355768, .487396, .144232, .012604); + break; + case W_BLACKMAN_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .3635819, .4891775, .1365995, .0106411); + break; + case W_BLACKMAN_HARRIS: + sum = ft_bnh (ft->window, ft->window_size, .35875, .48829, .14128, .01168); + break; + case W_FLAT_TOP: + sum = ft_flattop (ft->window, ft->window_size); + break; + } + const double isum = 2.0 / sum; - for (uint32_t i=0; i < ft->window_size; i++) { - ft->hann_window[i] *= isum; + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->window[i] *= isum; } - return ft->hann_window; + return ft->window; } -static void ft_analyze(struct FFTAnalysis *ft) { - fftwf_execute(ft->fftplan); +static void +ft_analyze (struct FFTAnalysis* ft) +{ + fftwf_execute (ft->fftplan); - memcpy(ft->phase_h, ft->phase, sizeof(float) * ft->data_size); + memcpy (ft->phase_h, ft->phase, sizeof (float) * ft->data_size); ft->power[0] = ft->fft_out[0] * ft->fft_out[0]; ft->phase[0] = 0; #define FRe (ft->fft_out[i]) -#define FIm (ft->fft_out[ft->window_size-i]) +#define FIm (ft->fft_out[ft->window_size - i]) for (uint32_t i = 1; i < ft->data_size - 1; ++i) { ft->power[i] = (FRe * FRe) + (FIm * FIm); - ft->phase[i] = atan2f(FIm, FRe); + ft->phase[i] = atan2f (FIm, FRe); } #undef FRe #undef FIm } -static void ft_analyze_hann(struct FFTAnalysis *ft) { - float *window = ft_hann_window(ft); - for (uint32_t i = 0; i < ft->window_size; i++) { - ft->fft_in[i] *= window[i]; - } - ft_analyze(ft); -} - - /****************************************************************************** * public API (static for direct source inclusion) */ @@ -106,10 +187,12 @@ #endif FFTX_FN_PREFIX -void fftx_reset(struct FFTAnalysis *ft) { +void +fftx_reset (struct FFTAnalysis* ft) +{ for (uint32_t i = 0; i < ft->data_size; ++i) { - ft->power[i] = 0; - ft->phase[i] = 0; + ft->power[i] = 0; + ft->phase[i] = 0; ft->phase_h[i] = 0; } for (uint32_t i = 0; i < ft->window_size; ++i) { @@ -117,73 +200,107 @@ ft->fft_out[i] = 0; } ft->rboff = 0; - ft->smps = 0; - ft->step = 0; + ft->smps = 0; + ft->step = 0; } FFTX_FN_PREFIX -void fftx_init(struct FFTAnalysis *ft, uint32_t window_size, double rate, double fps) { - ft->rate = rate; - ft->window_size = window_size; - ft->data_size = window_size / 2; - ft->hann_window = NULL; - ft->rboff = 0; - ft->smps = 0; - ft->step = 0; - ft->sps = (fps > 0) ? ceil(rate / fps) : 0; - ft->freq_per_bin = ft->rate / ft->data_size / 2.f; +void +fftx_init (struct FFTAnalysis* ft, uint32_t window_size, double rate, double fps) +{ + ft->rate = rate; + ft->window_size = window_size; + ft->window_type = W_HANN; + ft->data_size = window_size / 2; + ft->window = NULL; + ft->rboff = 0; + ft->smps = 0; + ft->step = 0; + ft->sps = (fps > 0) ? ceil (rate / fps) : 0; + ft->freq_per_bin = ft->rate / ft->data_size / 2.f; ft->phasediff_step = M_PI / ft->data_size; - ft->phasediff_bin = 0; + ft->phasediff_bin = 0; + + ft->ringbuf = (float*)malloc (window_size * sizeof (float)); + ft->fft_in = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->fft_out = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->power = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase_h = (float*)malloc (ft->data_size * sizeof (float)); - ft->ringbuf = (float *) malloc(window_size * sizeof(float)); - ft->fft_in = (float *) fftwf_malloc(sizeof(float) * window_size); - ft->fft_out = (float *) fftwf_malloc(sizeof(float) * window_size); - ft->power = (float *) malloc(ft->data_size * sizeof(float)); - ft->phase = (float *) malloc(ft->data_size * sizeof(float)); - ft->phase_h = (float *) malloc(ft->data_size * sizeof(float)); - - fftx_reset(ft); - - pthread_mutex_lock(&fftw_planner_lock); - ft->fftplan = fftwf_plan_r2r_1d(window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); - pthread_mutex_unlock(&fftw_planner_lock); + fftx_reset (ft); + + pthread_mutex_lock (&fftw_planner_lock); + ft->fftplan = fftwf_plan_r2r_1d (window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); + ++instance_count; + pthread_mutex_unlock (&fftw_planner_lock); } FFTX_FN_PREFIX -void fftx_free(struct FFTAnalysis *ft) { - if (!ft) return; - pthread_mutex_lock(&fftw_planner_lock); - fftwf_destroy_plan(ft->fftplan); - pthread_mutex_unlock(&fftw_planner_lock); - free(ft->hann_window); - free(ft->ringbuf); - fftwf_free(ft->fft_in); - fftwf_free(ft->fft_out); - free(ft->power); - free(ft->phase); - free(ft->phase_h); - free(ft); -} - -static -int _fftx_run(struct FFTAnalysis *ft, - const uint32_t n_samples, float const * const data) +void +fftx_set_window (struct FFTAnalysis* ft, window_t type) { - assert(n_samples <= ft->window_size); + if (ft->window_type == type) { + return; + } + ft->window_type = type; + free (ft->window); + ft->window = NULL; +} - float * const f_buf = ft->fft_in; - float * const r_buf = ft->ringbuf; +FFTX_FN_PREFIX +void +fftx_free (struct FFTAnalysis* ft) +{ + if (!ft) { + return; + } + pthread_mutex_lock (&fftw_planner_lock); + fftwf_destroy_plan (ft->fftplan); + if (instance_count > 0) { + --instance_count; + } +#ifdef WITH_STATIC_FFTW_CLEANUP + /* use this only when statically linking to a local fftw! + * + * "After calling fftw_cleanup, all existing plans become undefined, + * and you should not attempt to execute them nor to destroy them." + * [http://www.fftw.org/fftw3_doc/Using-Plans.html] + * + * If libfftwf is shared with other plugins or the host this can + * cause undefined behavior. + */ + if (instance_count == 0) { + fftwf_cleanup (); + } +#endif + pthread_mutex_unlock (&fftw_planner_lock); + free (ft->window); + free (ft->ringbuf); + fftwf_free (ft->fft_in); + fftwf_free (ft->fft_out); + free (ft->power); + free (ft->phase); + free (ft->phase_h); + free (ft); +} + +static int +_fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) +{ + assert (n_samples <= ft->window_size); + + float* const f_buf = ft->fft_in; + float* const r_buf = ft->ringbuf; const uint32_t n_off = ft->rboff; const uint32_t n_siz = ft->window_size; const uint32_t n_old = n_siz - n_samples; - /* copy new data into ringbuffer and fft-buffer - * TODO: use memcpy - */ for (uint32_t i = 0; i < n_samples; ++i) { - r_buf[ (i + n_off) % n_siz ] = data[i]; - f_buf[n_old + i] = data[i]; + r_buf[(i + n_off) % n_siz] = data[i]; + f_buf[n_old + i] = data[i]; } ft->rboff = (ft->rboff + n_samples) % n_siz; @@ -203,117 +320,142 @@ if (p0s + n_old >= n_siz) { const uint32_t n_p1 = n_siz - p0s; const uint32_t n_p2 = n_old - n_p1; - memcpy(f_buf, &r_buf[p0s], sizeof(float) * n_p1); - memcpy(&f_buf[n_p1], &r_buf[0], sizeof(float) * n_p2); + memcpy (f_buf, &r_buf[p0s], sizeof (float) * n_p1); + memcpy (&f_buf[n_p1], &r_buf[0], sizeof (float) * n_p2); } else { - memcpy(&f_buf[0], &r_buf[p0s], sizeof(float) * n_old); + memcpy (&f_buf[0], &r_buf[p0s], sizeof (float) * n_old); + } + + /* apply window function */ + float const* const window = ft_gen_window (ft); + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->fft_in[i] *= window[i]; } /* ..and analyze */ - ft_analyze_hann(ft); + ft_analyze (ft); + ft->phasediff_bin = ft->phasediff_step * (double)ft->step; return 0; } FFTX_FN_PREFIX -int fftx_run(struct FFTAnalysis *ft, - const uint32_t n_samples, float const * const data) +int +fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) { if (n_samples <= ft->window_size) { - return _fftx_run(ft, n_samples, data); + return _fftx_run (ft, n_samples, data); } - int rv = -1; - uint32_t n = 0; + int rv = -1; + uint32_t n = 0; while (n < n_samples) { - uint32_t step = MIN(ft->window_size, n_samples - n); - if (!_fftx_run(ft, step, &data[n])) rv = 0; + uint32_t step = MIN (ft->window_size, n_samples - n); + if (!_fftx_run (ft, step, &data[n])) { + rv = 0; + } n += step; } return rv; } - FFTX_FN_PREFIX -void fa_analyze_dsp(struct FFTAnalysis *ft, - void (*run)(void *, uint32_t, float*), void *handle) +void +fa_analyze_dsp (struct FFTAnalysis* ft, + void (*run) (void*, uint32_t, float*), void* handle) { - float *buf = ft->fft_in; + float* buf = ft->fft_in; /* pre-run 8K samples... (re-init/flush effect) */ uint32_t prerun_n_samples = 8192; while (prerun_n_samples > 0) { uint32_t n_samples = MIN (prerun_n_samples, ft->window_size); - memset(buf, 0, sizeof(float) * n_samples); + memset (buf, 0, sizeof (float) * n_samples); run (handle, n_samples, buf); prerun_n_samples -= n_samples; } /* delta impulse */ - memset(buf, 0, sizeof(float) * ft->window_size); + memset (buf, 0, sizeof (float) * ft->window_size); *buf = 1.0; /* call plugin's run() function -- in-place processing */ run (handle, ft->window_size, buf); ft->step = ft->window_size; - /* ..and analyze */ - ft_analyze(ft); + ft_analyze (ft); } - -/***************************************************************************** +/* *************************************************************************** * convenient access functions */ FFTX_FN_PREFIX -uint32_t fftx_bins(struct FFTAnalysis *ft) { - return ft->data_size; +uint32_t +fftx_bins (struct FFTAnalysis* ft) +{ + return ft->data_size; } FFTX_FN_PREFIX -inline float fast_log2 (float val) { - union {float f; int i;} t; - t.f = val; - int * const exp_ptr = &t.i; - int x = *exp_ptr; - const int log_2 = ((x >> 23) & 255) - 128; +inline float +fast_log2 (float val) +{ + union { + float f; + int i; + } t; + t.f = val; + int* const exp_ptr = &t.i; + int x = *exp_ptr; + const int log_2 = ((x >> 23) & 255) - 128; x &= ~(255 << 23); x += 127 << 23; *exp_ptr = x; - val = ((-1.0f/3) * t.f + 2) * t.f - 2.0f/3; + val = ((-1.0f / 3) * t.f + 2) * t.f - 2.0f / 3; return (val + log_2); } FFTX_FN_PREFIX -inline float fast_log (const float val) { - return (fast_log2 (val) * 0.69314718f); +inline float +fast_log (const float val) +{ + return (fast_log2 (val) * 0.69314718f); } FFTX_FN_PREFIX -inline float fast_log10 (const float val) { - return fast_log2(val) / 3.312500f; +inline float +fast_log10 (const float val) +{ + return fast_log2 (val) / 3.312500f; } FFTX_FN_PREFIX -inline float fftx_power_to_dB(float a) { +inline float +fftx_power_to_dB (float a) +{ /* 10 instead of 20 because of squared signal -- no sqrt(powerp[]) */ - return a > 1e-12 ? 10.0 * fast_log10(a) : -INFINITY; + return a > 1e-12 ? 10.0 * fast_log10 (a) : -INFINITY; } FFTX_FN_PREFIX -float fftx_power_at_bin(struct FFTAnalysis *ft, const int b) { - return (fftx_power_to_dB(ft->power[b])); +float +fftx_power_at_bin (struct FFTAnalysis* ft, const int b) +{ + return (fftx_power_to_dB (ft->power[b])); } FFTX_FN_PREFIX -float fftx_freq_at_bin(struct FFTAnalysis *ft, const int b) { +float +fftx_freq_at_bin (struct FFTAnalysis* ft, const int b) +{ /* calc phase: difference minus expected difference */ - float phase = ft->phase[b] - ft->phase_h[b] - (float) b * ft->phasediff_bin; + float phase = ft->phase[b] - ft->phase_h[b] - (float)b * ft->phasediff_bin; /* clamp to -M_PI .. M_PI */ int over = phase / M_PI; - over += (over >= 0) ? (over&1) : -(over&1); - phase -= M_PI*(float)over; + over += (over >= 0) ? (over & 1) : -(over & 1); + phase -= M_PI * (float)over; /* scale according to overlap */ phase *= (ft->data_size / ft->step) / M_PI; - return ft->freq_per_bin * ((float) b + phase); + return ft->freq_per_bin * ((float)b + phase); } diff -Nru x42-plugins-20170428/fil4.lv2/gui/fil4.c x42-plugins-20190714/fil4.lv2/gui/fil4.c --- x42-plugins-20170428/fil4.lv2/gui/fil4.c 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/gui/fil4.c 2019-07-14 19:39:06.000000000 +0000 @@ -97,6 +97,7 @@ LV2_Atom_Forge forge; LV2_URID_Map* map; Fil4LV2URIs uris; + LV2UI_Touch* touch; PangoFontDescription *font[2]; @@ -331,11 +332,7 @@ robtk_pbtn_set_text (p, buf); } -static void dial_annotation_db (RobTkDial * d, cairo_t *cr, void *data) { - Fil4UI* ui = (Fil4UI*) (data); - char txt[16]; - snprintf(txt, 16, "%+5.1fdB", d->cur); - +static void tooltip_text (Fil4UI* ui, RobTkDial* d, cairo_t *cr, const char* txt) { int tw, th; cairo_save(cr); PangoLayout * pl = pango_cairo_create_layout(cr); @@ -354,6 +351,13 @@ cairo_new_path(cr); } +static void dial_annotation_db (RobTkDial * d, cairo_t *cr, void *data) { + Fil4UI* ui = (Fil4UI*) (data); + char txt[16]; + snprintf(txt, 16, "%+5.1fdB", d->cur); + tooltip_text (ui, d, cr, txt); +} + static void dial_annotation_hz (RobTkCBtn *l, const int which, const float hz) { char txt[24]; if (hz > 5000) { @@ -380,6 +384,25 @@ //printf("-> %f -> %s\n", hz, t); } +static void dial_annotation_bw (RobTkDial *d, cairo_t *cr, void *data) { + Fil4UI* ui = (Fil4UI*) (data); + char txt[16]; + const int bw = rintf (1000.f * dial_to_bw (d->cur)); + switch (bw) { + case 62: snprintf(txt, 16, "1/16 Oct"); break; + case 125: snprintf(txt, 16, "1/8 Oct"); break; + case 250: snprintf(txt, 16, "1/4 Oct"); break; + case 500: snprintf(txt, 16, "1/2 Oct"); break; + case 1000: snprintf(txt, 16, "1 Oct"); break; + case 2000: snprintf(txt, 16, "2 Oct"); break; + case 4000: snprintf(txt, 16, "4 Oct"); break; + default: + snprintf(txt, 16, "%.2f Oct", dial_to_bw (d->cur)); + break; + } + tooltip_text (ui, d, cr, txt); +} + /*** knob faceplates ***/ static void prepare_faceplates(Fil4UI* ui) { cairo_t *cr; @@ -1856,6 +1879,16 @@ static RobWidget* m0_mouse_up (RobWidget* handle, RobTkBtnEvent *ev) { Fil4UI* ui = (Fil4UI*)GET_HANDLE(handle); end_solo (ui); + + if (ui->dragging >= 0 && ui->dragging < NCTRL && ui->touch) { + ui->touch->touch (ui->touch->handle, IIR_LS_FREQ + ui->dragging * 4, false); + ui->touch->touch (ui->touch->handle, IIR_LS_GAIN + ui->dragging * 4, false); + } else if (ui->dragging == Ctrl_LPF && ui->touch) { + ui->touch->touch (ui->touch->handle, FIL_LOFREQ, false); + } else if (ui->dragging == Ctrl_HPF && ui->touch) { + ui->touch->touch (ui->touch->handle, FIL_HIFREQ, false); + } + ui->dragging = -1; update_filter_display (ui); return NULL; @@ -1868,6 +1901,7 @@ int cp = find_control_point (ui, ev->x, ev->y); + int port_index = -1; switch (cp) { case -1: return NULL; @@ -1884,13 +1918,16 @@ break; case Ctrl_HPF: bwctl = ui->spn_g_hiq; + port_index = FIL_HIQ; break; case Ctrl_LPF: bwctl = ui->spn_g_loq; + port_index = FIL_LOQ; break; default: assert (cp >= 0 && cp < NCTRL); bwctl = ui->spn_bw[cp]; + port_index = IIR_LS_Q + cp * 4; break; } @@ -1901,6 +1938,10 @@ float v = robtk_dial_get_value (bwctl); const float delta = (ev->state & ROBTK_MOD_CTRL) ? bwctl->acc : bwctl->scroll_mult * bwctl->acc; + if (port_index >= 0 && ui->touch) { + ui->touch->touch (ui->touch->handle, port_index, true); + } + switch (ev->direction) { case ROBTK_SCROLL_RIGHT: case ROBTK_SCROLL_UP: @@ -1915,6 +1956,11 @@ default: break; } + + if (port_index >= 0 && ui->touch) { + ui->touch->touch (ui->touch->handle, port_index, false); + } + return NULL; } @@ -2000,6 +2046,15 @@ return NULL; } + if (ui->dragging >= 0 && ui->dragging < NCTRL && ui->touch) { + ui->touch->touch (ui->touch->handle, IIR_LS_FREQ + ui->dragging * 4, true); + ui->touch->touch (ui->touch->handle, IIR_LS_GAIN + ui->dragging * 4, true); + } else if (ui->dragging == Ctrl_LPF && ui->touch) { + ui->touch->touch (ui->touch->handle, FIL_LOFREQ, true); + } else if (ui->dragging == Ctrl_HPF && ui->touch) { + ui->touch->touch (ui->touch->handle, FIL_HIFREQ, true); + } + assert (ui->dragging >= 0); return handle; } @@ -2478,6 +2533,10 @@ robtk_dial_set_callback (ui->spn_g_gain, cb_spn_g_gain, ui); robtk_pbtn_set_callback (ui->btn_peak, cb_peak_rest, ui); + if (ui->touch) { + robtk_dial_set_touch (ui->spn_g_gain, ui->touch->touch, ui->touch->handle, FIL_GAIN); + } + robtk_cbtn_set_temporary_mode (ui->btn_g_enable, 1); robtk_cbtn_set_color_on(ui->btn_g_enable, 1.0, 1.0, 1.0); robtk_cbtn_set_color_off(ui->btn_g_enable, .2, .2, .2); @@ -2538,6 +2597,13 @@ robtk_dial_set_callback (ui->spn_g_hiq, cb_spn_g_hiq, ui); robtk_dial_set_callback (ui->spn_g_loq, cb_spn_g_loq, ui); + if (ui->touch) { + robtk_dial_set_touch (ui->spn_g_hifreq, ui->touch->touch, ui->touch->handle, FIL_HIFREQ); + robtk_dial_set_touch (ui->spn_g_lofreq, ui->touch->touch, ui->touch->handle, FIL_LOFREQ); + robtk_dial_set_touch (ui->spn_g_hiq, ui->touch->touch, ui->touch->handle, FIL_HIQ); + robtk_dial_set_touch (ui->spn_g_loq, ui->touch->touch, ui->touch->handle, FIL_LOQ); + } + /* trigger update of hi/lo labels */ ui->disable_signals = true; robtk_dial_set_value (ui->spn_g_hifreq, freq_to_dial (&lphp[0], lphp[0].dflt)); @@ -2597,6 +2663,10 @@ rob_table_attach (ui->ctbl, GSP_W(ui->spn_freq[i]), col, col+1, 5, 7, 0, 0, RTK_EXANDF, RTK_SHRINK); robtk_dial_annotation_callback(ui->spn_gain[i], dial_annotation_db, ui); + if (i > 0 && i < NCTRL - 1) { + /* band's bandwidth */ + robtk_dial_annotation_callback(ui->spn_bw[i], dial_annotation_bw, ui); + } robtk_dial_set_constained (ui->spn_freq[i], false); robtk_dial_set_default(ui->spn_freq[i], freq_to_dial (&freqs[i], freqs[i].dflt)); robtk_dial_set_default(ui->spn_gain[i], 0.0); @@ -2607,6 +2677,13 @@ robtk_dial_set_callback (ui->spn_bw[i], cb_spn_bw, ui); robtk_dial_set_callback (ui->spn_gain[i], cb_spn_gain, ui); + if (ui->touch) { + robtk_cbtn_set_touch (ui->btn_enable[i], ui->touch->touch, ui->touch->handle, IIR_LS_EN + i * 4); + robtk_dial_set_touch (ui->spn_freq[i], ui->touch->touch, ui->touch->handle, IIR_LS_FREQ + i * 4); + robtk_dial_set_touch (ui->spn_gain[i], ui->touch->touch, ui->touch->handle, IIR_LS_GAIN + i * 4); + robtk_dial_set_touch (ui->spn_bw[i], ui->touch->touch, ui->touch->handle, IIR_LS_Q + i * 4); + } + robtk_dial_set_alignment (ui->spn_freq[i], 0.0, .5); robtk_dial_set_alignment (ui->spn_bw[i], 1.0, .5); robtk_dial_set_alignment (ui->spn_gain[i], 0.0, .5); @@ -2872,6 +2949,9 @@ if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) { ui->map = (LV2_URID_Map*)features[i]->data; } + if (!strcmp(features[i]->URI, LV2_UI__touch)) { + ui->touch = (LV2UI_Touch*)features[i]->data; + } } if (!ui->map) { diff -Nru x42-plugins-20170428/fil4.lv2/lv2ttl/fil4.ports.ttl.in x42-plugins-20190714/fil4.lv2/lv2ttl/fil4.ports.ttl.in --- x42-plugins-20170428/fil4.lv2/lv2ttl/fil4.ports.ttl.in 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/lv2ttl/fil4.ports.ttl.in 2019-07-14 19:39:06.000000000 +0000 @@ -6,8 +6,9 @@ @VERSION@ doap:name "x42-eq - Parametric Equalizer@NAMESUFFIX@"; lv2:requiredFeature urid:map ; - lv2:extensionData state:interface @SIGNATURE@; - lv2:optionalFeature lv2:hardRTCapable ; + lv2:extensionData idpy:interface, state:interface @SIGNATURE@; + lv2:optionalFeature lv2:hardRTCapable, idpy:queue_draw, opts:options ; + opts:supportedOption ; @UITTL@ @MODBRAND@ @MODLABEL@ diff -Nru x42-plugins-20170428/fil4.lv2/lv2ttl/fil4.ttl.in x42-plugins-20190714/fil4.lv2/lv2ttl/fil4.ttl.in --- x42-plugins-20170428/fil4.lv2/lv2ttl/fil4.ttl.in 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/lv2ttl/fil4.ttl.in 2019-07-14 19:39:06.000000000 +0000 @@ -1,9 +1,11 @@ @prefix atom: . @prefix doap: . @prefix foaf: . +@prefix idpy: . @prefix kx: . @prefix lv2: . @prefix mod: . +@prefix opts: . @prefix pprop: . @prefix rdf: . @prefix rdfs: . @@ -13,6 +15,10 @@ @prefix units: . @prefix urid: . +idpy:queue_draw a lv2:Feature . +idpy:interface a lv2:ExtensionData . +ui:scaleFactor a opts:Option . + @prefix @LV2NAME@: . diff -Nru x42-plugins-20170428/fil4.lv2/Makefile x42-plugins-20190714/fil4.lv2/Makefile --- x42-plugins-20170428/fil4.lv2/Makefile 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/Makefile 2019-07-14 19:39:06.000000000 +0000 @@ -12,7 +12,9 @@ OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CXXFLAGS ?= -Wall -g -Wno-unused-function -STRIP ?= strip + +PKG_CONFIG?=pkg-config +STRIP?= strip BUILDOPENGL?=yes BUILDJACKAPP?=yes @@ -68,7 +70,7 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_GL_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` STRIPFLAGS= -s EXTENDED_RE=-r endif @@ -116,26 +118,26 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --exists fftw3f || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f || echo no), no) $(error "fftw3f library was not found") endif -ifeq ($(shell pkg-config --atleast-version=1.6.0 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) $(error "LV2 SDK needs to be version 1.6.0 or later") endif ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) - ifeq ($(shell pkg-config --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") endif endif ifneq ($(BUILDJACKAPP), no) - ifeq ($(shell pkg-config --exists jack || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif @@ -143,7 +145,7 @@ endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CXXFLAGS += -DHAVE_LV2_1_8 endif @@ -171,7 +173,7 @@ # add library dependent flags and libs override CXXFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(fil4_VERSION)\"" -override CXXFLAGS += `pkg-config --cflags lv2` +override CXXFLAGS += `$(PKG_CONFIG) --cflags lv2` ifeq ($(XWIN),) override CXXFLAGS += -fPIC -fvisibility=hidden else @@ -179,15 +181,15 @@ endif ifneq ($(INLINEDISPLAY),no) -override CXXFLAGS += `pkg-config --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE -override LOADLIBES += `pkg-config $(PKG_UI_FLAGS) --libs cairo pangocairo pango` +override CXXFLAGS += `$(PKG_CONFIG) --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE +override LOADLIBES += `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango` ifneq ($(XWIN),) override LOADLIBES += -lpthread -lusp10 endif endif -GLUICFLAGS+=`pkg-config --cflags cairo pango fftw3f` $(CXXFLAGS) -GLUILIBS+=`pkg-config $(PKG_UI_FLAGS) --libs cairo pango pangocairo fftw3f $(PKG_GL_LIBS)` +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango fftw3f` $(CXXFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo fftw3f $(PKG_GL_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 @@ -202,15 +204,15 @@ endif ifneq ($(LIC_CFLAGS),) - SIGNATURE=, + LV2SIGN=, override CXXFLAGS += -I$(RW) endif ROBGL+= Makefile JACKCFLAGS=-I. $(CXXFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` -JACKLIBS=-lm $(GLUILIBS) $(LIC_LOADLIBES) $(LOADLIBES) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) ############################################################################### @@ -255,10 +257,10 @@ sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ lv2ttl/$(LV2NAME).gui.in >> $(BUILDDIR)$(LV2NAME).ttl endif - sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/mono/;s/@NAMESUFFIX@/ Mono/;s/@CTLSIZE@/65888/;s/@SIGNATURE@/$(SIGNATURE)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL1)/" \ + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/mono/;s/@NAMESUFFIX@/ Mono/;s/@CTLSIZE@/65888/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL1)/" \ lv2ttl/$(LV2NAME).ports.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl cat lv2ttl/$(LV2NAME).mono.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl - sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/stereo/;s/@NAMESUFFIX@/ Stereo/;s/@CTLSIZE@/131424/;s/@SIGNATURE@/$(SIGNATURE)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL2)/" \ + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/stereo/;s/@NAMESUFFIX@/ Stereo/;s/@CTLSIZE@/131424/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL2)/" \ lv2ttl/$(LV2NAME).ports.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl cat lv2ttl/$(LV2NAME).stereo.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/donate.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/donate.png differ diff -Nru x42-plugins-20170428/fil4.lv2/modgui/icon-x42-eq.html x42-plugins-20190714/fil4.lv2/modgui/icon-x42-eq.html --- x42-plugins-20170428/fil4.lv2/modgui/icon-x42-eq.html 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/modgui/icon-x42-eq.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

HighPass

-
-
-
-
-
-
-
-
-

Enable

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

LowPass

-
-

x42

- -
- -
- {{#effect.ports.audio.input}} -
-
-
- {{/effect.ports.audio.input}} - {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} - {{#effect.ports.cv.input}} -
-
-
- {{/effect.ports.cv.input}} -
-
- {{#effect.ports.audio.output}} -
-
-
- {{/effect.ports.audio.output}} - {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} - {{#effect.ports.cv.output}} -
-
-
- {{/effect.ports.cv.output}} -
-
- Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/led-bypassed.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/led-bypassed.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/screenshot-x42-eq-mono.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/screenshot-x42-eq-mono.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/screenshot-x42-eq-stereo.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/screenshot-x42-eq-stereo.png differ diff -Nru x42-plugins-20170428/fil4.lv2/modgui/stylesheet-x42-eq.css x42-plugins-20190714/fil4.lv2/modgui/stylesheet-x42-eq.css --- x42-plugins-20170428/fil4.lv2/modgui/stylesheet-x42-eq.css 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/modgui/stylesheet-x42-eq.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,304 +0,0 @@ -/* STYLES FOR THE BOXY PEDAL */ - -@import url(/fonts/nexa/stylesheet.css); -@import url(/fonts/questrial/stylesheet.css); - - -/* = CONTAINER -================================================ */ -.mod-pedal-boxy{{{cns}}} { - background-position:center center; - background-repeat:no-repeat; - position:absolute; - border-radius: 21px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq { - width:780px; - height:480px; -} - -/* = Labels -================================================ */ -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .x42-brand { - right: 12px; - position:absolute; - text-align:center; - bottom: 42px; - width: 25px; - cursor:default; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .x42-brand h1 { - font-family:"Nexa"; - font-size:28px; - padding:0; - margin:0; - color:#aaa; - transform: rotate(270deg); - -webkit-transform: rotate(270deg); - text-shadow: 0 2px 2px #111; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .x42-donate { - left: 12px; - position:absolute; - text-align:center; - bottom: 42px; - width: 25px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq a { - text-decoration:none; - border: 0px; - color: #aaa; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .x42-donate a { - background-image:url(/resources/donate.png{{{ns}}}); - display:inline-block; - width: 32px; - height: 32px; -} - -.mod-pedal-boxy{{{cns}}} .x42-label { - left:30px; - right:30px; - bottom:28px; - overflow:hidden; - position:absolute; - text-align:center; - cursor:default; -} - -.mod-pedal-boxy{{{cns}}} .x42-label h1 { - font-family:"Questrial"; - font-size:16px; - line-height:1; - color:#aaa; -} - -/* = KNOBS -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-control-group { - margin:16px !important; - position:relative; - text-align:center; - z-index:30; -} -.mod-pedal-boxy{{{cns}}} .top { - margin-top:0px !important; -} - -.mod-pedal-boxy{{{cns}}} .mod-control-group .mod-knob { - overflow:hidden; - position:relative; -} - -.mod-pedal-boxy{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - bottom:0px; - display:block; - font-size:11px; - font-weight:bold; - height:12px; - left:0; - line-height:1; - margin:0; - overflow:hidden; - padding:0; - position:absolute; - right:0; - text-transform:uppercase; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-knob .mod-knob-image { - background-image:url(/resources/x42-eq-knob.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 60px; - height:60px; - width:60px; - margin:12px auto 0 auto; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-right .mod-knob-image { - margin-top:2px !important; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-toggle .mod-toggle-image { - background-image:url(/resources/x42-eq-switch.png{{{ns}}}); - background-position:left center ; - background-repeat:no-repeat; - background-size:180px 35px; - height:35px; - width:90px; - margin:0px auto 0 auto; - cursor:pointer !important; - position:relative; - overflow:hidden; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-toggle .mod-toggle-image.on { - background-position: 0px 0px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-toggle .mod-toggle-image.off { - background-position: -90px 0px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-led .mod-led-image { - background-image:url(/resources/x42-led.png{{{ns}}}); - background-position:left center ; - background-repeat:no-repeat; - background-size:48px 24px; - height:24px; - width:24px; - margin:0px auto 0 auto; - cursor:pointer !important; - position:relative; - overflow:hidden; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-led { - position:absolute; - right:0px; - bottom:0px; - width:24px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-toggle { - display:inline-block; - width:90px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .mod-knob { - display:inline-block; - height:85px; - width:95px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band { - position:relative; - display:inline-block; - width:120px; - border: 1px solid #666; - border-radius: 7px; - padding: 5px 0 0 2px; - margin-bottom: 3px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-hpf, -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-lpf { - position:relative; - display:inline-block; - text-align:center; - width:198px; - border: 1px solid #666; - border-radius: 7px; - padding-top: 5px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-global { - position:relative; - display:inline-block; - border: 1px solid #666; - border-radius: 7px; - display:inline-block; - width:120px; - padding-top: 5px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-tf { - position:relative; - display:inline-block; - border: 1px solid #666; - border-radius: 7px; - display:inline-block; - width:120px; - background-color:#111; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-svg { - position:relative; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-svg svg { - position:relative; - top:1px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-left { - margin-right: 20px; - background-position:left center ; - background-repeat:no-repeat; - background-size:93px 85px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-right { - margin-left: 30px; - background-position:left center ; - background-repeat:no-repeat; - background-size:93px 75px; - height:75px; -} - -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-global .mod-knob, -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-lpf .mod-knob, -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-hpf .mod-knob { - background-position:left center ; - background-repeat:no-repeat; - background-size:93px 85px; -} - -/* = Knob faceplates -================================================ */ -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-global .x42-eq-gain, -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-gain { - background-image:url(/resources/x42-eq-gain.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-bw { - background-image:url(/resources/x42-eq-bw.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-bwhs { - background-image:url(/resources/x42-eq-bwhs.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-bwls { - background-image:url(/resources/x42-eq-bwls.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-freq0 { - background-image:url(/resources/x42-eq-f0.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-freq1 { - background-image:url(/resources/x42-eq-f1.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-freq2 { - background-image:url(/resources/x42-eq-f2.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-freq3 { - background-image:url(/resources/x42-eq-f3.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-freq4 { - background-image:url(/resources/x42-eq-f4.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-band .x42-eq-freq5 { - background-image:url(/resources/x42-eq-f5.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-lpf .x42-eq-freql { - background-image:url(/resources/x42-eq-fl.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-lpf .x42-eq-bwlp { - background-image:url(/resources/x42-eq-bwlp.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-hpf .x42-eq-freqh { - background-image:url(/resources/x42-eq-fh.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-x42-eq .mod-control-group .x42-eq-hpf .x42-eq-bwhp { - background-image:url(/resources/x42-eq-bwhp.png{{{ns}}}); -} - -/* = BACKGROUND IMAGES - Color of the pedal -================================================ */ -.mod-pedal-boxy{{{cns}}}.mod-x42-eq { - background-image:url(/resources/x42-eq-background.png{{{ns}}}); -} - -/* vim: set sw=4 et: */ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/thumbnail-x42-eq-mono.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/thumbnail-x42-eq-mono.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/thumbnail-x42-eq-stereo.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/thumbnail-x42-eq-stereo.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-background.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-background.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-bwhp.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-bwhp.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-bwhs.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-bwhs.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-bwlp.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-bwlp.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-bwls.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-bwls.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-bw.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-bw.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-f0.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-f0.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-f1.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-f1.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-f2.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-f2.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-f3.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-f3.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-f4.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-f4.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-f5.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-f5.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-fh.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-fh.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-fl.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-fl.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-gain.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-gain.png differ diff -Nru x42-plugins-20170428/fil4.lv2/modgui/x42-eq.js x42-plugins-20190714/fil4.lv2/modgui/x42-eq.js --- x42-plugins-20170428/fil4.lv2/modgui/x42-eq.js 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/modgui/x42-eq.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,458 +0,0 @@ -function (event) { - - /* constants */ - - var log1k = Math.log (1000.0); - var rate = 48000; - - /* some helper functions */ - - function freq_at_x (x, width) { - /* log-scale 20..20K */ - return 20 * Math.pow (1000, x / width); - } - - function x_at_freq (f, width) { - return width * Math.log (f / 20.0) / log1k; - } - - function y_at_db (db) { - return 50 - 50 * db / 20; - } - - /** calculate combined transfer function for all filters - * - * @param f frequency in Hz - * @returns dB (gain,attenuation) at given frequency - */ - function response (dsp, f) { - var db = 0; - /* calc omega and sin/cos once */ - var w = 2 * Math.PI * f / dsp[0].rate; - var c = Math.cos (w); - var s = Math.sin (w); - for (var i = 0; i < Object.keys (dsp).length; i++) { - db += dsp[i].dBAtFreq (f, w, c, s); - } - return db; - } - - /* the actual SVG drawing function */ - function x42_draw_tf (tf) { - var ds = tf.data ('xModPorts'); - var dsp = tf.data ('xModDSP'); - var svg = tf.svg ('get'); - if (!dsp || !svg) { - return; - } - if (Object.keys (dsp).length < 8) { - return; - } - - var width = 119; - svg.clear (); - - /* grid */ - var g = svg.group ({stroke: 'gray', strokeWidth: 0.5, fill: 'none'}); - var yg = y_at_db (0); - svg.line (g, 0, yg, width, yg); - - g = svg.group ({stroke: 'gray', strokeWidth: 0.25, fill: 'none'}); - yg = .5 + Math.round (y_at_db ( 6)); svg.line (g, 0, yg, width, yg); - yg = .5 + Math.round (y_at_db ( -6)); svg.line (g, 0, yg, width, yg); - yg = .5 + Math.round (y_at_db ( 12)); svg.line (g, 0, yg, width, yg); - yg = .5 + Math.round (y_at_db (-12)); svg.line (g, 0, yg, width, yg); - yg = .5 + Math.round (y_at_db ( 18)); svg.line (g, 0, yg, width, yg); - yg = .5 + Math.round (y_at_db (-18)); svg.line (g, 0, yg, width, yg); - - var xg; - g = svg.group ({stroke: 'darkgray', strokeWidth: 0.25, strokeDashArray: '1, 3', fill: 'none'}); - xg = Math.round (x_at_freq ( 50, width)); svg.line (g, xg, 0, xg, 100); - xg = Math.round (x_at_freq ( 200, width)); svg.line (g, xg, 0, xg, 100); - xg = Math.round (x_at_freq ( 500, width)); svg.line (g, xg, 0, xg, 100); - xg = Math.round (x_at_freq ( 2000, width)); svg.line (g, xg, 0, xg, 100); - xg = Math.round (x_at_freq ( 5000, width)); svg.line (g, xg, 0, xg, 100); - xg = Math.round (x_at_freq (15000, width)); svg.line (g, xg, 0, xg, 100); - - var tg = svg.group ({stroke: 'gray', fontSize: '8px', textAnchor: 'end', fontFamily: 'Monospace', strokeWidth: 0.5}); - var to; var tr; - g = svg.group ({stroke: 'gray', strokeWidth: 0.25, strokeDashArray: '3, 2'}); - xg = Math.round (x_at_freq ( 100, width)); svg.line (g, xg, 0, xg, 105); - to = svg.group (tg, {transform: 'translate ('+xg+', 103)'}); - tr = svg.group (to, {transform: 'rotate (-90, 3, 0)'}); - svg.text (tr, 0, 0, "100"); - - xg = Math.round (x_at_freq ( 1000, width)); svg.line (g, xg, 0, xg, 105); - to = svg.group (tg, {transform: 'translate ('+xg+', 103)'}); - tr = svg.group (to, {transform: 'rotate (-90, 3, 0)'}); - svg.text (tr, 0, 0, "1K"); - - xg = Math.round (x_at_freq (10000, width)); svg.line (g, xg, 0, xg, 105); - to = svg.group (tg, {transform: 'translate ('+xg+', 103)'}); - tr = svg.group (to, {transform: 'rotate (-90, 3, 0)'}); - svg.text (tr, 0, 0, "10K"); - - /* transfer function */ - var clp = svg.clipPath (null, 'tfClip'); - svg.rect (clp, -1, 0, width + 3, 100); - - var color = 'white'; - if (!ds['enable'] || 1 == ds[':bypass']) { - color = '#444444'; - } - - var path = []; - g = svg.group ({stroke: color, strokeWidth: 1.0, fill: 'none'}); - for (var x = 0; x < width; x++) { - path.push ([x, y_at_db (response (dsp, freq_at_x (x, width)))]); - } - svg.polyline (g, path, {clipPath: 'url(#tfClip)'}); - path.push ([width + 1, 50]); - path.push ([0, 50]); - g = svg.group ({stroke: 'none', fill: color, fillOpacity: '0.35'}); - svg.polyline (g, path, {clipPath: 'url(#tfClip)'}); - } - - /* test if all transfer-function relevant - * port-parameters are known. Cache the result. - */ - function check_information (tf) { - var ok = tf.data ('xModOK'); - if (ok) { - return true; - } - var ds = tf.data ('xModPorts'); - /* 33 plugin control inputs + MOD bypass */ - if (34 > Object.keys (ds).length) { - return false; - } - - var pname = [ - 'sec1', 'gain1', 'freq1', 'q1', - 'sec2', 'gain2', 'freq2', 'q2', - 'sec3', 'gain3', 'freq3', 'q3', - 'sec4', 'gain4', 'freq4', 'q4', - 'HSsec', 'HSgain', 'HSfreq', 'HSq', - 'LSsec', 'LSgain', 'LSfreq', 'LSq', - 'HighPass', 'HPfreq', 'HPQ', - 'LowPass', 'LPfreq', 'LPQ', - 'enable', ':bypass' // 32 - // gain, reset-peak - ]; - - ok = true; - for (var p in pname) { - if (typeof ds[pname[p]] === 'undefined') { - ok = false; - break; - } - } - tf.data ('xModOK', ok); - return ok; - } - - /* Call when an input parameter changes, update the - * corresponding filter - * - * @return 0 when successful and a re-expose of the Transfer function - * is needed, -1 otherwise - */ - function set_filter (tf, symbol) { - var ds = tf.data ('xModPorts'); - var dsp = tf.data ('xModDSP'); - switch (symbol) { - case 'sec1': - case 'gain1': - case 'freq1': - case 'q1': - dsp[0] = new X42EQBandPass (ds['sec1'], ds['gain1'], ds['freq1'], ds['q1'], rate); - break; - case 'sec2': - case 'gain2': - case 'freq2': - case 'q2': - dsp[1] = new X42EQBandPass (ds['sec2'], ds['gain2'], ds['freq2'], ds['q2'], rate); - break; - case 'sec3': - case 'gain3': - case 'freq3': - case 'q3': - dsp[2] = new X42EQBandPass (ds['sec3'], ds['gain3'], ds['freq3'], ds['q3'], rate); - break; - case 'sec4': - case 'gain4': - case 'freq4': - case 'q4': - dsp[3] = new X42EQBandPass (ds['sec4'], ds['gain4'], ds['freq4'], ds['q4'], rate); - break; - case 'LSsec': - case 'LSgain': - case 'LSfreq': - case 'LSq': - dsp[4] = new X42EQShelf (ds['LSsec'], ds['LSgain'], ds['LSfreq'], ds['LSq'], 0, rate); - break; - case 'HSsec': - case 'HSgain': - case 'HSfreq': - case 'HSq': - dsp[5] = new X42EQShelf (ds['HSsec'], ds['HSgain'], ds['HSfreq'], ds['HSq'], 1, rate); - break; - case 'HighPass': - case 'HPfreq': - case 'HPQ': - dsp[6] = new X42EQHighPass (ds['HighPass'], ds['HPfreq'], ds['HPQ'], rate); - break; - case 'LowPass': - case 'LPfreq': - case 'LPQ': - dsp[7] = new X42EQLowPass (ds['LowPass'], ds['LPfreq'], ds['LPQ'], rate); - break; - case 'enable': - case ':bypass': - return 0; - default: - return -1; - break; - } - tf.data ('xModDSP', dsp); - return 0; - } - - /* wrapper around the above, set parameter, - * test that all parameters are known before updating - */ - function set_x42_eq_param (tf, symbol, value) { - var ds = tf.data ('xModPorts'); - ds[symbol] = value; - tf.data ('xModPorts', ds); - - if (check_information (tf)) { - if (0 == set_filter (tf, symbol)) { - x42_draw_tf (tf); - } - } - } - - - /* top-level entry, called from mod-ui */ - if (event.type == 'start') { - /* initialize */ - var tf = event.icon.find ('[mod-role=transfer-function]'); - tf.svg (); - - var svg = tf.svg ('get'); - svg.configure ({width: '118px'}, false); - svg.configure ({height: '130px'}, false); - svg.clear (); - var tg = svg.group ({stroke: '#cccccc', fontSize: '11px', textAnchor: 'middle', strokeWidth: 0.5}); - svg.text (tg, 59, 65, "Transfer function", {dy: '-1.5em'}); - svg.text (tg, 59, 65, "display needs"); - svg.text (tg, 59, 65, "MOD v0.15.0 or later.", {dy: '1.5em'}); - - var ds = {}; - var ports = event.ports; - - for (var p in ports) { - ds[ports[p].symbol] = ports[p].value; - } - - tf.data ('xModDSP', []); - tf.data ('xModPorts', ds); - tf.data ('xModOK', false); - - if (!check_information (tf)) { - /* MOD < v0.15.0 does not set initial values */ - return; - } - - set_filter (tf, 'sec1'); - set_filter (tf, 'sec2'); - set_filter (tf, 'sec3'); - set_filter (tf, 'sec4'); - set_filter (tf, 'LSsec'); - set_filter (tf, 'HSsec'); - set_filter (tf, 'HighPass'); - set_filter (tf, 'LowPass'); - x42_draw_tf (tf); - } - else if (event.type == 'change') { - /* update parameters, redraw transfer function if needed */ - var tf = event.icon.find ('[mod-role=transfer-function]'); - set_x42_eq_param (tf, event.symbol, event.value); - } -} - -/* GLOBAL fn & classes */ - -function x42_hypot (x, y) { - return Math.sqrt (x * x + y * y); -} - -function x42_square (x) { - return x * x -} - -var X42EQShelf = function (en, gain, freq, bandw, type, rate) { - this.en = en; - this.rate = rate; - if (!this.en) { return; } - - var freq_ratio = freq / rate; - var q = .2129 + bandw / 2.25; - if (freq_ratio < 0.0004) { freq_ratio = 0.0004; } - if (freq_ratio > 0.4700) { freq_ratio = 0.4700; } - if (q < .25) { q = .25; } - if (q > 2.0) { q = 2.0; } - - var w0 = 2. * Math.PI * freq_ratio; - var _cosW = Math.cos (w0); - - var A = Math.pow (10, .025 * gain); // sqrt(gain_as_coeff) - var As = Math.sqrt (A); - var a = Math.sin (w0) / 2 * (1 / q); - - if (type) { // high shelf - var b0 = A * ((A + 1) + (A - 1) * _cosW + 2 * As * a); - var b1 = -2 * A * ((A - 1) + (A + 1) * _cosW); - var b2 = A * ((A + 1) + (A - 1) * _cosW - 2 * As * a); - var a0 = (A + 1) - (A - 1) * _cosW + 2 * As * a; - var a1 = 2 * ((A - 1) - (A + 1) * _cosW); - var a2 = (A + 1) - (A - 1) * _cosW - 2 * As * a; - - var _b0 = b0 / a0; - var _b2 = b2 / a0; - var _a2 = a2 / a0; - - this.A = _b0 + _b2; - this.B = _b0 - _b2; - this.C = 1.0 + _a2; - this.D = 1.0 - _a2; - this.A1 = a1 / a0; - this.B1 = b1 / a0; - } else { // low shelf - var b0 = A * ((A + 1) - (A - 1) * _cosW + 2 * As * a); - var b1 = 2 * A * ((A - 1) - (A + 1) * _cosW); - var b2 = A * ((A + 1) - (A - 1) * _cosW - 2 * As * a); - var a0 = (A + 1) + (A - 1) * _cosW + 2 * As * a; - var a1 = -2 * ((A - 1) + (A + 1) * _cosW); - var a2 = (A + 1) + (A - 1) * _cosW - 2 * As * a; - - var _b0 = b0 / a0; - var _b2 = b2 / a0; - var _a2 = a2 / a0; - - this.A = _b0 + _b2; - this.B = _b0 - _b2; - this.C = 1.0 + _a2; - this.D = 1.0 - _a2; - this.A1 = a1 / a0; - this.B1 = b1 / a0; - } -} - -X42EQShelf.prototype.dBAtFreq = function (f, w, c1, s1) { - if (!this.en) { return 0; } - /* - var w = 2 * Math.PI * f / this.rate; - var c1 = Math.cos (w); - var s1 = Math.sin (w); - */ - - var A = this.A * c1 + this.B1; - var B = this.B * s1; - var C = this.C * c1 + this.A1; - var D = this.D * s1; - return 20 * Math.log10 (Math.sqrt ((x42_square (A) + x42_square (B)) * (x42_square (C) + x42_square (D))) / (x42_square (C) + x42_square (D))); -} - -var X42EQBandPass = function (en, gain, freq, bandw, rate) { - this.en = en; - this.rate = rate; - if (!this.en) { return; } - - var freq_ratio = freq / rate; - if (freq_ratio < 0.0002) { freq_ratio = 0.0002; } - if (freq_ratio > 0.4998) { freq_ratio = 0.4998; } - var g = Math.pow (10, 0.05 * gain); - var b = 7 * bandw * freq_ratio / Math.sqrt (g); - - this.s2 = (1 - b) / (1 + b); - this.s1 = -1 * Math.cos (2 * Math.PI * freq_ratio); - this.s1 *= (1 + this.s2); - this.gain_db = 0.5 * (g - 1) * (1 - this.s2); -}; - -X42EQBandPass.prototype.dBAtFreq = function (f, w, c1, s1) { - if (!this.en) { return 0; } - /* - var w = 2 * Math.PI * f / this.rate; - var c1 = Math.cos (w); - var s1 = Math.sin (w); - */ - var c2 = Math.cos (2 * w); - var s2 = Math.sin (2 * w); - - var x = c2 + this.s1 * c1 + this.s2; - var y = s2 + this.s1 * s1; - - var t1 = x42_hypot (x, y); - - x += this.gain_db * (c2 - 1); - y += this.gain_db * s2; - - var t2 = x42_hypot (x, y); - - return 20 * Math.log10 (t2 / t1); -} - -var X42EQHighPass = function (en, freq, q, rate) { - this.en = en; - this.rate = rate; - if (!this.en) { return; } - - this.freq = freq; - this.q = q; -} - -X42EQHighPass.prototype.dBAtFreq = function (f) { - if (!this.en) { return 0; } - if (f < 5) { f = 5; } - else if (f > this.rate / 12) { f = this.rate / 12; } - // this is only an approx. - var wr = this.freq / f; - var q; - var r = (0.7 + 0.78 * Math.tanh (1.82 * (this.q - .8))); // RESHP - if (r < 1.3) { - q = 3.01 * Math.sqrt (r / (r + 2)); - } else { - q = Math.sqrt (4 - 0.09 / (r - 1.09)); - } - return -10 * Math.log10 (x42_square (1 + x42_square (wr)) - x42_square (q * wr)); -} - -var X42EQLowPass = function (en, freq, q, rate) { - this.en = en; - this.rate = rate; - if (!this.en) { return; } - if (freq < rate * 0.0002) { - freq = rate * 0.0002; - } - else if (freq > rate * 0.4998) { - freq = rate * 0.4998; - } - this.fb = 3. * Math.pow (q, 3.20772); - if (this.fb < 0) { this.fb = 0; } - if (this.fb > 9) { this.fb = 9; } - - this.wc = Math.sin (Math.PI * freq / rate); - this.q = Math.sqrt (4 * this.fb / (1 + this.fb)); -} - -X42EQLowPass.prototype.dBAtFreq = function (f) { - if (!this.en) { return 0; } - // this is only an approx. w/o additional shelf - var w = Math.sin (Math.PI * f / this.rate); - return -10 * Math.log10 (x42_square (1 + x42_square (w / this.wc)) - x42_square (this.q * w / this.wc)); -} - -/* vim: set sw=2 ts=2: */ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-knob.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-knob.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-eq-switch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-eq-switch.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/fil4.lv2/modgui/x42-led.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/fil4.lv2/modgui/x42-led.png differ diff -Nru x42-plugins-20170428/fil4.lv2/README.md x42-plugins-20190714/fil4.lv2/README.md --- x42-plugins-20170428/fil4.lv2/README.md 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/README.md 2019-07-14 19:39:06.000000000 +0000 @@ -69,7 +69,7 @@ Fil4 is based on fil-plugins LADSPA by Fons Adriaensen. -Fil4 consists of four 2nd order resonant filters using a Mitra-Regalia +Fil4 consists of four 2nd order resonant filters using a Regalia-Mitra style lattice filter, which has the nice property of being stable even while parameters are being changed. diff -Nru x42-plugins-20170428/fil4.lv2/src/idpy.c x42-plugins-20190714/fil4.lv2/src/idpy.c --- x42-plugins-20170428/fil4.lv2/src/idpy.c 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/src/idpy.c 2019-07-14 19:39:06.000000000 +0000 @@ -125,6 +125,7 @@ const float xw = w - 1; const float a = self->enabled ? 1.0 : .2; + const float ny = x_at_freq (.5 * self->rate, xw); /* zero line */ cairo_set_operator (cr, CAIRO_OPERATOR_OVER); @@ -165,7 +166,12 @@ FilterChannel const * const fc = &self->fc[0]; - for (uint32_t i = 0; i < xw; ++i) { + if (ny < xw) { + cairo_rectangle (cr, 0, 0, ny, h); + cairo_clip (cr); + } + + for (uint32_t i = 0; i < xw && i < ny; ++i) { const float freq = freq_at_x (i, xw); const float w = 2.f * M_PI * freq / self->rate; struct omega _w; diff -Nru x42-plugins-20170428/fil4.lv2/src/lv2.c x42-plugins-20190714/fil4.lv2/src/lv2.c --- x42-plugins-20170428/fil4.lv2/src/lv2.c 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/src/lv2.c 2019-07-14 19:39:06.000000000 +0000 @@ -28,6 +28,7 @@ #include "lv2/lv2plug.in/ns/lv2core/lv2.h" #include "lv2/lv2plug.in/ns/ext/state/state.h" +#include "lv2/lv2plug.in/ns/ext/options/options.h" #ifdef DISPLAY_INTERFACE #include @@ -127,9 +128,13 @@ return NULL; } + const LV2_Options_Option* options = NULL; + for (int i=0; features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_URID__map)) { self->map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)features[i]->data; } #ifdef DISPLAY_INTERFACE else if (!strcmp(features[i]->URI, LV2_INLINEDISPLAY__queue_draw)) { @@ -161,6 +166,19 @@ self->db_scale = DEFAULT_YZOOM; self->ui_scale = 1.0; + if (options) { + LV2_URID atom_Float = self->map->map (self->map->handle, LV2_ATOM__Float); + LV2_URID ui_scale = self->map->map (self->map->handle, "http://lv2plug.in/ns/extensions/ui#scaleFactor"); + for (const LV2_Options_Option* o = options; o->key; ++o) { + if (o->context == LV2_OPTIONS_INSTANCE && o->key == ui_scale && o->type == atom_Float) { + float ui_scale = *(const float*)o->value; + if (ui_scale < 1.0) { ui_scale = 1.0; } + if (ui_scale > 2.0) { ui_scale = 2.0; } + self->ui_scale = ui_scale; + } + } + } + return (LV2_Handle)self; } diff -Nru x42-plugins-20170428/fil4.lv2/x42-fil4.1 x42-plugins-20190714/fil4.lv2/x42-fil4.1 --- x42-plugins-20170428/fil4.lv2/x42-fil4.1 2017-04-27 23:57:17.000000000 +0000 +++ x42-plugins-20190714/fil4.lv2/x42-fil4.1 2019-07-14 19:39:06.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH X42-FIL4 "1" "April 2017" "x42-fil4 version 0.5.5" "User Commands" +.TH X42-FIL4 "1" "July 2019" "x42-fil4 version 0.6.6" "User Commands" .SH NAME x42-fil4 \- x42 JACK Parametric Equalizer .SH SYNOPSIS @@ -12,7 +12,7 @@ Use ID \fB\-1\fR, \fB\-l\fR or \fB\-\-list\fR for a dedicated list of included plugins. By default the first listed plugin (ID 0) is used. .PP -List if available plugins: (ID "Name" URI) +List of available plugins: (ID "Name" URI) .TP 0 "x42\-eq \- Parametric Equalizer Stereo" http://gareus.org/oss/lv2/fil4#stereo @@ -42,6 +42,9 @@ Set the JACK client name (defaults to plugin\-name) .TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP \fB\-l\fR, \fB\-\-list\fR Print list of available plugins and exit .TP @@ -63,7 +66,7 @@ See also: Website: .SH COPYRIGHT -Copyright \(co GPL 2013\-2015 Robin Gareus +Copyright \(co GPL 2013\-2019 Robin Gareus .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/gitversion.mak x42-plugins-20190714/gitversion.mak --- x42-plugins-20170428/gitversion.mak 2017-04-28 00:05:02.000000000 +0000 +++ x42-plugins-20190714/gitversion.mak 2019-07-14 19:54:01.000000000 +0000 @@ -1,19 +1,24 @@ -export balance_VERSION=0.6.5 -export controlfilter_VERSION=0.3.1 -export convoLV2_VERSION=0.5.3 -export fat1_VERSION=0.3.3 -export fil4_VERSION=0.5.5 -export meters_VERSION=0.9.4 -export midifilter_VERSION=0.4.7 -export midigen_VERSION=0.2.2 -export midimap_VERSION=0.3.0 -export mixtri_VERSION=0.2.8 -export nodelay_VERSION=0.3.0 -export onsettrigger_VERSION=0.2.4 -export robtk_VERSION=0.5.3 -export sisco_VERSION=0.7.2 -export stepseq_VERSION=0.4.1 -export stereoroute_VERSION=0.1.1 -export testsignal_VERSION=0.4.0 -export tuna_VERSION=0.4.3 -export xfade_VERSION=0.2.4 +export balance_VERSION=0.6.7 +export controlfilter_VERSION=0.4.0 +export convoLV2_VERSION=0.6.4 +export darc_VERSION=0.4.2 +export dpl_VERSION=0.3.3 +export fat1_VERSION=0.5.4 +export fil4_VERSION=0.6.6 +export matrixmixer_VERSION=0.2.4 +export meters_VERSION=0.9.12 +export mididebug_VERSION=0.3.0 +export midifilter_VERSION=0.5.4 +export midigen_VERSION=0.2.5 +export midimap_VERSION=0.3.3 +export mixtri_VERSION=0.3.3 +export nodelay_VERSION=0.4.0 +export onsettrigger_VERSION=0.4.0 +export robtk_VERSION=0.6.5 +export sisco_VERSION=0.8.3 +export spectra_VERSION=0.4.1 +export stepseq_VERSION=0.5.5 +export stereoroute_VERSION=0.2.0 +export testsignal_VERSION=0.5.3 +export tuna_VERSION=0.4.14 +export xfade_VERSION=0.3.0 diff -Nru x42-plugins-20170428/Makefile x42-plugins-20190714/Makefile --- x42-plugins-20170428/Makefile 2016-08-21 19:04:19.000000000 +0000 +++ x42-plugins-20190714/Makefile 2019-07-14 19:53:50.000000000 +0000 @@ -6,10 +6,31 @@ ############################################################################### VERSION ?=$(shell date +%Y%m%d) -SUBDIRS = balance.lv2 convoLV2 fat1.lv2 fil4.lv2 meters.lv2 \ - midifilter.lv2 midigen.lv2 midimap.lv2 mixtri.lv2 \ - nodelay.lv2 onsettrigger.lv2 sisco.lv2 stepseq.lv2 \ - stereoroute.lv2 testsignal.lv2 tuna.lv2 xfade.lv2 +SUBDIRS = \ + balance.lv2 \ + controlfilter.lv2 \ + darc.lv2 \ + dpl.lv2 \ + convoLV2 \ + fat1.lv2 \ + fil4.lv2 \ + matrixmixer.lv2 \ + meters.lv2 \ + mididebug.lv2 \ + midifilter.lv2 \ + midigen.lv2 \ + midimap.lv2 \ + mixtri.lv2 \ + nodelay.lv2 \ + onsettrigger.lv2 \ + sisco.lv2 \ + spectra.lv2 \ + stepseq.lv2 \ + stereoroute.lv2 \ + testsignal.lv2 \ + tuna.lv2 \ + xfade.lv2 + all clean install uninstall: submodule_check $(SUBDIRS) diff -Nru x42-plugins-20170428/matrixmixer.lv2/COPYING x42-plugins-20190714/matrixmixer.lv2/COPYING --- x42-plugins-20170428/matrixmixer.lv2/COPYING 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/COPYING 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -Nru x42-plugins-20170428/matrixmixer.lv2/genhead.sh x42-plugins-20190714/matrixmixer.lv2/genhead.sh --- x42-plugins-20170428/matrixmixer.lv2/genhead.sh 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/genhead.sh 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,57 @@ +#!/bin/bash +N_INPUTS=$1 +N_OUTPUTS=$2 + +NCTRL=$(( $N_INPUTS * $N_OUTPUTS )) +NPORTS=$(( $N_INPUTS + $N_OUTPUTS + $NCTRL )) + +cat << EOF +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _plugin = { + &lv2_descriptor, &lv2ui_descriptor + , 0 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "Matrix Mixer ${N_INPUTS}x${N_OUTPUTS}" + , (const struct LV2Port[${NPORTS}]) + { +EOF + +i=1; while test $i -le $N_INPUTS; do + echo " { \"in$i\", AUDIO_IN, nan, nan, nan, \"Audio Input $i\"}," + i=$[$i + 1] +done +i=1; while test $i -le $N_OUTPUTS; do + echo " { \"out$i\", AUDIO_OUT, nan, nan, nan, \"Audio Output $i\"}," + i=$[$i + 1] +done + +i=1; while test $i -le $N_INPUTS; do + j=1; while test $j -le $N_OUTPUTS; do + AMP="0.f" + if test $j -eq $i; then AMP="1.f"; fi + echo " { \"mix_${i}_${j}\", CONTROL_IN, ${AMP}, -6.f, 6.f,\"Mix ${i} ${j}\"}," + j=$[$j + 1] + done + i=$[$i + 1] +done + +cat << EOF + } + , ${NPORTS} // uint32_t nports_total + , ${N_INPUTS} // uint32_t nports_audio_in + , ${N_OUTPUTS} // uint32_t nports_audio_out + , 0 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 0 // uint32_t nports_atom_in + , 0 // uint32_t nports_atom_out + , ${NCTRL} // uint32_t nports_ctrl + , ${NCTRL} // uint32_t nports_ctrl_in + , 0 // uint32_t nports_ctrl_out + , 8192 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , UINT32_MAX // uint32_t latency_ctrl_port +}; + +EOF diff -Nru x42-plugins-20170428/matrixmixer.lv2/genttl.sh x42-plugins-20190714/matrixmixer.lv2/genttl.sh --- x42-plugins-20170428/matrixmixer.lv2/genttl.sh 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/genttl.sh 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,57 @@ +#!/bin/bash +N_INPUTS=$1 +N_OUTPUTS=$2 + +IDX=0 + +i=1; while test $i -le $N_INPUTS; do +if test $IDX -gt 0; then + echo " ] , [" +fi +cat << EOF + a lv2:AudioPort , + lv2:InputPort ; + lv2:index ${IDX} ; + lv2:symbol "in${i}" ; + lv2:name "Audio Input ${i}" ; +EOF + i=$[$i + 1] + IDX=$[$IDX + 1] +done + +i=1; while test $i -le $N_OUTPUTS; do +cat << EOF + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index ${IDX} ; + lv2:symbol "out${i}" ; + lv2:name "Audio Output ${i}" ; +EOF + i=$[$i + 1] + IDX=$[$IDX + 1] +done + +i=1; while test $i -le $N_INPUTS; do + j=1; while test $j -le $N_OUTPUTS; do + AMP=0.0 + if test $j -eq $i; then AMP=1.0; fi +cat << EOF + ] , [ + a lv2:ControlPort , + lv2:InputPort ; + lv2:index ${IDX} ; + lv2:symbol "mix_${i}_${j}" ; + lv2:name "Mix ${i} ${j}" ; + lv2:minimum -6.0; + lv2:maximum 6.0; + lv2:default ${AMP}; + lv2:scalePoint [ rdfs:label "invert"; rdf:value -1.0 ; ] ; + lv2:scalePoint [ rdfs:label "off"; rdf:value 0.0 ; ] ; + lv2:scalePoint [ rdfs:label "on"; rdf:value 1.0 ; ] ; +EOF + j=$[$j + 1] + IDX=$[$IDX + 1] + done + i=$[$i + 1] +done diff -Nru x42-plugins-20170428/matrixmixer.lv2/git2lv2.mk x42-plugins-20190714/matrixmixer.lv2/git2lv2.mk --- x42-plugins-20170428/matrixmixer.lv2/git2lv2.mk 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/git2lv2.mk 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,43 @@ + +############################################################################### +# extract versions +GIT_REV_REGEXP="([0-9][0-9]*)\.([0-9][0-9]*)(\.([0-9][0-9]*))?(-([0-9][0-9]*))?(-g([a-f0-9]+))?" + +override MAJOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\1/) +override MINOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\2/) +override MICRO=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\4/) +override GITREV=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\6/) + +ifeq ($(MAJOR),) + override MAJOR=0 +endif +ifeq ($(MINOR),) + override MINOR=0 +endif +ifeq ($(MICRO),) + override MICRO=0 +endif + +$(info Version: $(LV2VERSION) -> $(MAJOR) $(MINOR) $(MICRO) $(GITREV)) + +# version requirements, see +# http://lv2plug.in/ns/lv2core/#minorVersion +# http://lv2plug.in/ns/lv2core/#microVersion +ifeq ($(GITREV),) +# even numbers for tagged releases + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 ) + override LV2MIC = 0 +else +# odd-numbers for all non tagged git versions + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 + 1 ) + override LV2MIC = $(shell expr $(GITREV) \* 2 + 1) +endif + +ifeq ($(LV2MIN),) + $(error "Cannot extract required LV2 minor-version parameter") +endif +ifeq ($(LV2MIC),) + $(error "Cannot extract required LV2 micro-version parameter") +endif + +$(info LV2 Version: $(LV2MIN) $(LV2MIC)) diff -Nru x42-plugins-20170428/matrixmixer.lv2/.gitmodules x42-plugins-20190714/matrixmixer.lv2/.gitmodules --- x42-plugins-20170428/matrixmixer.lv2/.gitmodules 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/.gitmodules 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,3 @@ +[submodule "robtk"] + path = robtk + url = git://github.com/x42/robtk.git diff -Nru x42-plugins-20170428/matrixmixer.lv2/gui/matrixmixer.c x42-plugins-20190714/matrixmixer.lv2/gui/matrixmixer.c --- x42-plugins-20170428/matrixmixer.lv2/gui/matrixmixer.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/gui/matrixmixer.c 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,511 @@ +/* Matrix Mixer + * + * Copyright (C) 2019 Robin Gareus + * + * 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, 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, see . + */ + +#include +#include +#include + +#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" + +#include "../src/matrixmixer.h" + +#define RTK_URI MATMIX_URI +#define RTK_GUI "ui" + +#define GD_W 35 +#define GD_H 34 +#define GD_RAD 10 +#define GD_CX 17.5 +#define GD_CY 17.5 + +#define M_OFFSET (N_INPUTS + N_OUTPUTS) +#define M_SIZE (N_INPUTS * N_OUTPUTS) + +typedef struct { + LV2UI_Write_Function write; + LV2UI_Controller controller; + LV2UI_Touch* touch; + + RobWidget* rw; + RobWidget* matrix; + + RobTkDial* mtx_gain[M_SIZE]; + RobTkLbl* mtx_lbl_i[N_INPUTS]; + RobTkLbl* mtx_lbl_o[N_OUTPUTS]; + RobTkLbl* mtx_lbl; + + cairo_surface_t* mtx_sf[6]; + PangoFontDescription* font; + + bool disable_signals; + + const char* nfo; +} MatMixUI; + +static void +create_faceplate (MatMixUI* ui) +{ + cairo_t* cr; + float c_bg[4]; + get_color_from_theme (1, c_bg); + +#define MTX_SF(SF) \ + SF = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 2 * GD_W, 2 * GD_H); \ + cr = cairo_create (SF); \ + cairo_scale (cr, 2.0, 2.0); \ + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); \ + cairo_rectangle (cr, 0, 0, GD_W, GD_H); \ + CairoSetSouerceRGBA (c_bg); \ + cairo_fill (cr); \ + CairoSetSouerceRGBA (c_g60); \ + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); \ + cairo_set_line_width (cr, 1.0); + +#define MTX_ARROW_H \ + cairo_move_to (cr, 5, GD_CY); \ + cairo_rel_line_to (cr, -5, -4); \ + cairo_rel_line_to (cr, 0, 8); \ + cairo_close_path (cr); \ + cairo_fill (cr); + +#define MTX_ARROW_V \ + cairo_move_to (cr, GD_CX, GD_H); \ + cairo_rel_line_to (cr, -4, -5); \ + cairo_rel_line_to (cr, 8, 0); \ + cairo_close_path (cr); \ + cairo_fill (cr); + + MTX_SF (ui->mtx_sf[0]); + MTX_ARROW_H; + MTX_ARROW_V; + + cairo_move_to (cr, 0, GD_CY); + cairo_line_to (cr, GD_W, GD_CY); + cairo_stroke (cr); + cairo_move_to (cr, GD_CX, 0); + cairo_line_to (cr, GD_CX, GD_H); + cairo_stroke (cr); + cairo_destroy (cr); + + // top-row + MTX_SF (ui->mtx_sf[1]); + MTX_ARROW_H; + MTX_ARROW_V; + + cairo_move_to (cr, 0, GD_CY); + cairo_line_to (cr, GD_W, GD_CY); + cairo_stroke (cr); + cairo_move_to (cr, GD_CX, GD_CY); + cairo_line_to (cr, GD_CX, GD_H); + cairo_stroke (cr); + cairo_destroy (cr); + + // left column + MTX_SF (ui->mtx_sf[2]); + MTX_ARROW_V; + + cairo_move_to (cr, 0, GD_CY); + cairo_line_to (cr, GD_W, GD_CY); + cairo_stroke (cr); + cairo_move_to (cr, GD_CX, 0); + cairo_line_to (cr, GD_CX, GD_H); + cairo_stroke (cr); + cairo_destroy (cr); + + // right column + MTX_SF (ui->mtx_sf[3]); + MTX_ARROW_H; + MTX_ARROW_V; + + cairo_move_to (cr, 0, GD_CY); + cairo_line_to (cr, GD_CX, GD_CY); + cairo_stroke (cr); + cairo_move_to (cr, GD_CX, 0); + cairo_line_to (cr, GD_CX, GD_H); + cairo_stroke (cr); + cairo_destroy (cr); + + // top-left + MTX_SF (ui->mtx_sf[4]); + MTX_ARROW_V; + + cairo_move_to (cr, 0, GD_CY); + cairo_line_to (cr, GD_W, GD_CY); + cairo_stroke (cr); + cairo_move_to (cr, GD_CX, GD_CY); + cairo_line_to (cr, GD_CX, GD_H); + cairo_stroke (cr); + cairo_destroy (cr); + + // top-right + MTX_SF (ui->mtx_sf[5]); + MTX_ARROW_H; + MTX_ARROW_V; + + cairo_move_to (cr, 0, GD_CY); + cairo_line_to (cr, GD_CX, GD_CY); + cairo_stroke (cr); + cairo_move_to (cr, GD_CX, GD_CY); + cairo_line_to (cr, GD_CX, GD_H); + cairo_stroke (cr); + cairo_destroy (cr); +} + +static float +knob_pos_to_gain (float v) +{ + if (v == 0.f) { + return 0; + } + return exp (((pow (fabs (v), 0.125) * 150.) - 144.) * log (2.) / 6.); +} + +static float +knob_gain_to_pos (float v) +{ + if (v == 0.f) { + return 0; + } + return pow ((6. * log (fabs (v)) / log (2.) + 144.) / 150., 8.); +} + +static float +knob_to_db (float v) +{ + return 20.f * log10f (knob_pos_to_gain (v)); +} + +static void +dial_annotation_db (RobTkDial* d, cairo_t* cr, void* data) +{ + MatMixUI* ui = (MatMixUI*)(data); + char txt[16]; + switch (d->click_state) { + case 1: + snprintf (txt, 16, "\u00D8%+4.1fdB", knob_to_db (d->cur)); + break; + default: + snprintf (txt, 16, "%+4.1fdB", knob_to_db (d->cur)); + break; + } + + int tw, th; + cairo_save (cr); + PangoLayout* pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, ui->font); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_translate (cr, d->w_width / 2, d->w_height - 0); + cairo_translate (cr, -tw / 2.0, -th); + cairo_set_source_rgba (cr, .0, .0, .0, .5); + rounded_rectangle (cr, -1, -1, tw + 3, th + 1, 3); + cairo_fill (cr); + CairoSetSouerceRGBA (c_wht); + pango_cairo_show_layout (cr, pl); + g_object_unref (pl); + cairo_restore (cr); + cairo_new_path (cr); +} + +/* **************************************************************************** + * UI callbacks + */ + +static void +set_dot_color (RobTkDial* dial, float gain) +{ + if (gain == 0.f) { + dial->dcol[0][0] = .05; + dial->dcol[0][1] = .05; + dial->dcol[0][2] = .05; + } else if (gain == 1.f) { + dial->dcol[0][0] = .20; + dial->dcol[0][1] = 1.0; + dial->dcol[0][2] = .20; + } else { + dial->dcol[0][0] = .95; + dial->dcol[0][1] = .95; + dial->dcol[0][2] = .95; + } +} + +static bool +cb_mtx_gain (RobWidget* w, void* handle) +{ + MatMixUI* ui = (MatMixUI*)handle; + + unsigned int n; + memcpy (&n, w->name, sizeof (unsigned int)); + float val = knob_pos_to_gain (robtk_dial_get_value (ui->mtx_gain[n])); + set_dot_color (ui->mtx_gain[n], val); + + if (ui->disable_signals) { + return TRUE; + } + + if (robtk_dial_get_state (ui->mtx_gain[n]) == 1) { + val *= -1; + } + ui->write (ui->controller, M_OFFSET + n, sizeof (float), 0, (const void*)&val); + return TRUE; +} + + +static RobWidget* +robtk_dial_mouse_intercept (RobWidget* handle, RobTkBtnEvent* ev) +{ + RobTkDial* d = (RobTkDial*)GET_HANDLE (handle); + MatMixUI* ui = (MatMixUI*)d->handle; + + if (!d->sensitive) { + return NULL; + } + + if (ev->button == 2) { + /* middle-click exclusively assigns output */ + unsigned int n; + memcpy (&n, d->rw->name, sizeof (unsigned int)); + + unsigned c = n % N_OUTPUTS; + unsigned r = n / N_OUTPUTS; + for (uint32_t i = 0; i < N_OUTPUTS; ++i) { + unsigned int nn = r * N_OUTPUTS + i; + if (i == c) { + if (d->cur == 0) { + robtk_dial_set_value (ui->mtx_gain[nn], knob_gain_to_pos (1.f)); + } else { + robtk_dial_set_value (ui->mtx_gain[nn], knob_gain_to_pos (0.f)); + } + } else { + robtk_dial_set_value (ui->mtx_gain[nn], knob_gain_to_pos (0.f)); + } + } + return handle; + } + return robtk_dial_mousedown (handle, ev); +} + +/****************************************************************************** + * RobWidget + */ + +static RobWidget* +toplevel (MatMixUI* ui, void* const top) +{ + ui->rw = rob_vbox_new (FALSE, 2); + robwidget_make_toplevel (ui->rw, top); + robwidget_toplevel_enable_scaling (ui->rw); + + ui->font = pango_font_description_from_string ("Mono 9px"); + + create_faceplate (ui); + + ui->matrix = rob_table_new (/*rows*/ 2 + N_INPUTS, /*cols*/ 1 + N_OUTPUTS, FALSE); + + ui->mtx_lbl = robtk_lbl_new ("Matrix Mixer"); + rob_table_attach (ui->matrix, robtk_lbl_widget (ui->mtx_lbl), + 1, N_OUTPUTS + 1, + 0, 1, + 2, 2, RTK_SHRINK, RTK_SHRINK); + + /* matrix */ + for (unsigned int r = 0; r < N_INPUTS; ++r) { + char txt[16]; + sprintf (txt, "In %d", r + 1); + ui->mtx_lbl_i[r] = robtk_lbl_new (txt); + rob_table_attach (ui->matrix, robtk_lbl_widget (ui->mtx_lbl_i[r]), + 0, 1, + r + 1, r + 2, + 2, 2, RTK_SHRINK, RTK_SHRINK); + + for (unsigned int c = 0; c < N_OUTPUTS; ++c) { + unsigned int n = r * N_OUTPUTS + c; + + // TODO log-scale mapping -inf || -60 .. +6dB + + ui->mtx_gain[n] = robtk_dial_new_with_size ( + 0, 1, knob_gain_to_pos(1.0) / 192.f, + GD_W, GD_H, GD_CX, GD_CY, GD_RAD); + + robtk_dial_set_default (ui->mtx_gain[n], knob_gain_to_pos (c == r ? 1 : 0)); + robtk_dial_set_callback (ui->mtx_gain[n], cb_mtx_gain, ui); + robtk_dial_annotation_callback (ui->mtx_gain[n], dial_annotation_db, ui); + float detent = knob_gain_to_pos (1.f); + robtk_dial_set_detents (ui->mtx_gain[n], 1 , &detent); + + robtk_dial_enable_states (ui->mtx_gain[n], 1); + robtk_dial_set_state_color (ui->mtx_gain[n], 1, 1.0, .0, .0, .3); + robtk_dial_set_default_state (ui->mtx_gain[n], 0); + + robwidget_set_mousedown (ui->mtx_gain[n]->rw, robtk_dial_mouse_intercept); + set_dot_color (ui->mtx_gain[n], (c == r ? 1 : 0)); + ui->mtx_gain[n]->displaymode = 3; + + if (ui->touch) { + robtk_dial_set_touch (ui->mtx_gain[n], ui->touch->touch, ui->touch->handle, M_OFFSET + n); + } + + /* set faceplate */ + if (c == N_OUTPUTS - 1 && r == 0) { + robtk_dial_set_scaled_surface_scale (ui->mtx_gain[n], ui->mtx_sf[5], 2.0); + } else if (c == 0 && r == 0) { + robtk_dial_set_scaled_surface_scale (ui->mtx_gain[n], ui->mtx_sf[4], 2.0); + } else if (c == N_OUTPUTS - 1) { + robtk_dial_set_scaled_surface_scale (ui->mtx_gain[n], ui->mtx_sf[3], 2.0); + } else if (c == 0) { + robtk_dial_set_scaled_surface_scale (ui->mtx_gain[n], ui->mtx_sf[2], 2.0); + } else if (r == 0) { + robtk_dial_set_scaled_surface_scale (ui->mtx_gain[n], ui->mtx_sf[1], 2.0); + } else { + robtk_dial_set_scaled_surface_scale (ui->mtx_gain[n], ui->mtx_sf[0], 2.0); + } + + rob_table_attach (ui->matrix, robtk_dial_widget (ui->mtx_gain[n]), + c + 1, c + 2, + r + 1, r + 2, + 0, 0, RTK_SHRINK, RTK_SHRINK); + + memcpy (ui->mtx_gain[n]->rw->name, &n, sizeof (unsigned int)); + } + } + + /* matrix out labels */ + for (unsigned int c = 0; c < N_OUTPUTS; ++c) { + char txt[16]; + sprintf (txt, "Out\n%d", c + 1); + ui->mtx_lbl_o[c] = robtk_lbl_new (txt); + rob_table_attach (ui->matrix, robtk_lbl_widget (ui->mtx_lbl_o[c]), + c + 1, c + 2, + N_INPUTS + 1, N_INPUTS + 2, + 2, 2, RTK_SHRINK, RTK_SHRINK); + } + + /* top-level packing */ + rob_vbox_child_pack (ui->rw, ui->matrix, TRUE, TRUE); + return ui->rw; +} + +/****************************************************************************** + * LV2 + */ + +static void +gui_cleanup (MatMixUI* ui) +{ + for (unsigned int r = 0; r < N_INPUTS; ++r) { + robtk_lbl_destroy (ui->mtx_lbl_i[r]); + for (unsigned int c = 0; c < N_OUTPUTS; ++c) { + unsigned int n = r * N_OUTPUTS + c; + robtk_dial_destroy (ui->mtx_gain[n]); + } + } + + for (int i = 0; i < N_OUTPUTS; ++i) { + robtk_lbl_destroy (ui->mtx_lbl_o[i]); + } + + robtk_lbl_destroy (ui->mtx_lbl); + + for (int i = 0; i < 6; ++i) { + cairo_surface_destroy (ui->mtx_sf[i]); + } + pango_font_description_free (ui->font); + + rob_table_destroy (ui->matrix); + rob_box_destroy (ui->rw); +} + +#define LVGL_RESIZEABLE + +static void ui_disable(LV2UI_Handle handle) { } +static void ui_enable(LV2UI_Handle handle) { } + +static LV2UI_Handle +instantiate ( + void* const ui_toplevel, + const LV2UI_Descriptor* descriptor, + const char* plugin_uri, + const char* bundle_path, + LV2UI_Write_Function write_function, + LV2UI_Controller controller, + RobWidget** widget, + const LV2_Feature* const* features) +{ + MatMixUI* ui = (MatMixUI*)calloc (1, sizeof (MatMixUI)); + if (!ui) { + return NULL; + } + + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_UI__touch)) { + ui->touch = (LV2UI_Touch*)features[i]->data; + } + } + + ui->nfo = robtk_info (ui_toplevel); + ui->write = write_function; + ui->controller = controller; + ui->disable_signals = true; + + *widget = toplevel (ui, ui_toplevel); + ui->disable_signals = false; + return ui; +} + +static enum LVGLResize +plugin_scale_mode (LV2UI_Handle handle) +{ + return LVGL_LAYOUT_TO_FIT; +} + +static void +cleanup (LV2UI_Handle handle) +{ + MatMixUI* ui = (MatMixUI*)handle; + gui_cleanup (ui); + free (ui); +} + +static const void* +extension_data (const char* uri) +{ + return NULL; +} + +static void +port_event ( + LV2UI_Handle handle, + uint32_t port, + uint32_t buffer_size, + uint32_t format, + const void* buffer) +{ + MatMixUI* ui = (MatMixUI*)handle; + + if (format != 0) { + return; + } + const float v = *(float*)buffer; + + if (port >= M_OFFSET && port < M_OFFSET + M_SIZE) { + ui->disable_signals = true; + robtk_dial_set_value (ui->mtx_gain[port - M_OFFSET], knob_gain_to_pos (v)); + robtk_dial_set_state (ui->mtx_gain[port - M_OFFSET], v < 0 ? 1 : 0); + ui->disable_signals = false; + } +} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/matrixmixer.lv2/img/matrix16x20.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/matrixmixer.lv2/img/matrix16x20.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/matrixmixer.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/matrixmixer.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/matrixmixer.lv2/img/x42-matrixmixer.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/matrixmixer.lv2/img/x42-matrixmixer.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/matrixmixer.lv2/img/x42-matrixmixer.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/matrixmixer.lv2/img/x42-matrixmixer.png differ diff -Nru x42-plugins-20170428/matrixmixer.lv2/lv2ttl/manifest.gui.in x42-plugins-20190714/matrixmixer.lv2/lv2ttl/manifest.gui.in --- x42-plugins-20170428/matrixmixer.lv2/lv2ttl/manifest.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/lv2ttl/manifest.gui.in 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,5 @@ + + + a @UI_TYPE@ ; + ui:binary <@LV2GUI@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/matrixmixer.lv2/lv2ttl/manifest.ttl.in x42-plugins-20190714/matrixmixer.lv2/lv2ttl/manifest.ttl.in --- x42-plugins-20170428/matrixmixer.lv2/lv2ttl/manifest.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/lv2ttl/manifest.ttl.in 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,10 @@ +@prefix kx: . +@prefix lv2: . +@prefix modgui: . +@prefix rdfs: . +@prefix ui: . + + + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/matrixmixer.lv2/lv2ttl/matrixmixer.gui.in x42-plugins-20190714/matrixmixer.lv2/lv2ttl/matrixmixer.gui.in --- x42-plugins-20170428/matrixmixer.lv2/lv2ttl/matrixmixer.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/lv2ttl/matrixmixer.gui.in 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,5 @@ + +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + @UI_REQ@ + . diff -Nru x42-plugins-20170428/matrixmixer.lv2/lv2ttl/matrixmixer.ttl.in x42-plugins-20190714/matrixmixer.lv2/lv2ttl/matrixmixer.ttl.in --- x42-plugins-20170428/matrixmixer.lv2/lv2ttl/matrixmixer.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/lv2ttl/matrixmixer.ttl.in 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,32 @@ +@prefix atom: . +@prefix doap: . +@prefix foaf: . +@prefix lv2: . +@prefix units: . +@prefix rdfs: . +@prefix ui: . +@prefix urid: . +@prefix pprop: . +@prefix rdf: . +@prefix rsz: . +@prefix kx: . + +@prefix @LV2NAME@: . + + + a foaf:Person ; + foaf:name "Robin Gareus" ; + foaf:mbox ; + foaf:homepage . + + + a lv2:Plugin, doap:Project, lv2:UtilityPlugin; + doap:license ; + doap:maintainer ; + doap:name "Matrix Mixer @NAMESUFFIX@"; + @VERSION@ + @UITTL@ + lv2:optionalFeature lv2:hardRTCapable; + @SIGNATURE@ + lv2:port [ + diff -Nru x42-plugins-20170428/matrixmixer.lv2/Makefile x42-plugins-20190714/matrixmixer.lv2/Makefile --- x42-plugins-20170428/matrixmixer.lv2/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/Makefile 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,325 @@ +#!/usr/bin/make -f + +# these can be overridden using make variables. e.g. +# make CFLAGS=-O2 +# make install DESTDIR=$(CURDIR)/debian/matrixmixer.lv2 PREFIX=/usr +# +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +MANDIR ?= $(PREFIX)/share/man/man1 +# see http://lv2plug.in/pages/filesystem-hierarchy-standard.html, don't use libdir +LV2DIR ?= $(PREFIX)/lib/lv2 + +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG # -fopt-info-vec-optimized +CFLAGS ?= -Wall -g -Wno-unused-function + +PKG_CONFIG?=pkg-config +STRIP?= strip + +# grid-size (should be at least 4x4 for the MOD-GUI) +N_INPUTS ?= 8 +N_OUTPUTS ?= 8 + +BUILDOPENGL?=yes +BUILDJACKAPP?=yes + +matrixmixer_VERSION ?= $(shell git describe --tags HEAD | sed 's/-g.*$$//;s/^v//' || echo "LV2") +RW ?= robtk/ + +############################################################################### + +BUILDDIR = build/ +APPBLD = x42/ + +############################################################################### + +LV2NAME=matrixmixer +LV2GUI=matrixmixerUI_gl +BUNDLE=matrixmixer.lv2 + +URISUFFIX=i$(N_INPUTS)o$(N_OUTPUTS) +NAMESUFFIX=$(N_INPUTS)x$(N_OUTPUTS) + +targets= + +LOADLIBES=-lm +LV2UIREQ= +GLUICFLAGS=-I. + +UNAME=$(shell uname) +ifeq ($(UNAME),Darwin) + LV2LDFLAGS=-dynamiclib + LIB_EXT=.dylib + EXE_EXT= + UI_TYPE=ui:CocoaUI + PUGL_SRC=$(RW)pugl/pugl_osx.m + PKG_GL_LIBS= + GLUILIBS=-framework Cocoa -framework OpenGL -framework CoreFoundation + STRIPFLAGS=-u -r -arch all -s $(RW)lv2syms + EXTENDED_RE=-E +else + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.so + EXE_EXT= + UI_TYPE=ui:X11UI + PUGL_SRC=$(RW)pugl/pugl_x11.c + PKG_GL_LIBS=glu gl + GLUILIBS=-lX11 + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` + STRIPFLAGS= -s + EXTENDED_RE=-r +endif + +ifneq ($(XWIN),) + CC=$(XWIN)-gcc + CXX=$(XWIN)-g++ + STRIP=$(XWIN)-strip + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.dll + EXE_EXT=.exe + PUGL_SRC=$(RW)pugl/pugl_win.cpp + PKG_GL_LIBS= + UI_TYPE=ui:WindowsUI + GLUILIBS=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread + GLUICFLAGS=-I. + override LDFLAGS += -static-libgcc -static-libstdc++ +endif + +ifeq ($(EXTERNALUI), yes) + UI_TYPE= +endif + +ifeq ($(UI_TYPE),) + UI_TYPE=kx:Widget + LV2UIREQ+=lv2:requiredFeature kx:Widget; + override CFLAGS += -DXTERNAL_UI +endif + +targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +UITTL= +ifneq ($(BUILDOPENGL), no) + targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) + UITTL=ui:ui $(LV2NAME):ui_gl ; +endif + +############################################################################### +# extract versions +LV2VERSION=$(matrixmixer_VERSION) +include git2lv2.mk + +############################################################################### +# check for build-dependencies + +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) + $(error "LV2 SDK was not found") +endif + +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) + $(error "LV2 SDK needs to be version 1.6.0 or later") +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") + endif +endif + +ifneq ($(BUILDJACKAPP), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) + $(warning *** libjack from http://jackaudio.org is required) + $(error Please install libjack-dev or libjack-jackd2-dev) + endif + JACKAPP=$(APPBLD)x42-matrixmixer$(NAMESUFFIX)$(EXE_EXT) + targets+=$(APPBLD)matrixmixer.h +endif + +# check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) + override CFLAGS += -DHAVE_LV2_1_8 +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifneq ($(MAKECMDGOALS), submodules) + ifeq ($(wildcard $(RW)robtk.mk),) + $(warning "**********************************************************") + $(warning This plugin needs https://github.com/x42/robtk) + $(warning "**********************************************************") + $(info ) + $(info set the RW environment variale to the location of the robtk headers) + ifeq ($(wildcard .git),.git) + $(info or run 'make submodules' to initialize robtk as git submodule) + endif + $(info ) + $(warning "**********************************************************") + $(error robtk not found) + endif + endif +endif + +# LV2 idle >= lv2-1.6.0 +GLUICFLAGS+=-DHAVE_IDLE_IFACE +LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; + +# add library dependent flags and libs +override CFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(matrixmixer_VERSION)\"" +override CFLAGS += `$(PKG_CONFIG) --cflags lv2` + +ifeq ($(XWIN),) +override CFLAGS += -fPIC -fvisibility=hidden +else +override CFLAGS += -DPTW32_STATIC_LIB +endif +override LOADLIBES += `$(PKG_CONFIG) --libs lv2` + + +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` $(CFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` + +ifneq ($(XWIN),) +GLUILIBS+=-lpthread -lusp10 +endif + +GLUICFLAGS+=$(LIC_CFLAGS) +GLUILIBS+=$(LIC_LOADLIBES) + +ifneq ($(LIC_CFLAGS),) + LV2SIGN=, + override CFLAGS += -I$(RW) +endif + +ROBGL+= Makefile + +JACKCFLAGS=-I. $(CFLAGS) $(LIC_CFLAGS) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) + +############################################################################### +# build target definitions +default: all + +submodule_pull: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_pull + +submodule_update: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_update + +submodule_check: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_check + +submodules: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodules + +all: submodule_check $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets) $(JACKAPP) + +$(BUILDDIR)manifest.ttl: lv2ttl/manifest.ttl.in lv2ttl/manifest.gui.in Makefile + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/$(URISUFFIX)/;s/@LIB_EXT@/$(LIB_EXT)/" \ + lv2ttl/manifest.ttl.in > $(BUILDDIR)manifest.ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/$(URISUFFIX)/;s/@LIB_EXT@/$(LIB_EXT)/;s/@UI_TYPE@/$(UI_TYPE)/;s/@LV2GUI@/$(LV2GUI)/g" \ + lv2ttl/manifest.gui.in >> $(BUILDDIR)manifest.ttl +endif + +$(BUILDDIR)$(LV2NAME).ttl: lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).gui.in Makefile + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(LV2SIGN)/;s/@NAMESUFFIX@/$(NAMESUFFIX)/;s/@URISUFFIX@/$(URISUFFIX)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/" \ + lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl + ./genttl.sh $(N_INPUTS) $(N_OUTPUTS) >> $(BUILDDIR)$(LV2NAME).ttl + echo "]; ." >> $(BUILDDIR)$(LV2NAME).ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@URISUFFIX@/$(URISUFFIX)/;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ + lv2ttl/$(LV2NAME).gui.in >> $(BUILDDIR)$(LV2NAME).ttl +endif + +override CFLAGS+= -DN_INPUTS=$(N_INPUTS) -DN_OUTPUTS=$(N_OUTPUTS) + +DSP_SRC = src/$(LV2NAME).c +DSP_DEPS = $(DSP_SRC) src/$(LV2NAME).h +GUI_DEPS = gui/$(LV2NAME).c src/$(LV2NAME).h + +$(BUILDDIR)$(LV2NAME)$(LIB_EXT): $(DSP_DEPS) Makefile + @mkdir -p $(BUILDDIR) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LIC_CFLAGS) -std=c99 \ + -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DSP_SRC) \ + -shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES) $(LIC_LOADLIBES) + $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +$(APPBLD)matrixmixer.h: Makefile + @mkdir -p $(APPBLD) + ./genhead.sh $(N_INPUTS) $(N_OUTPUTS) > $(APPBLD)matrixmixer.h + +jackapps: $(JACKAPP) + +$(eval x42_matrixmixer$(NAMESUFFIX)_JACKSRC = src/matrixmixer.c) +$(eval x42_matrixmixer$(NAMESUFFIX)_JACKGUI = gui/matrixmixer.c) +$(eval x42_matrixmixer$(NAMESUFFIX)_LV2HTTL = $(APPBLD)matrixmixer.h) +$(eval x42_matrixmixer$(NAMESUFFIX)_JACKDESC = lv2ui_descriptor) + +$(APPBLD)x42-matrixmixer$(NAMESUFFIX)$(EXE_EXT): $(DSP_DEPS) $(GUI_DEPS) \ + $(APPBLD)matrixmixer.h \ + $(x42_matrixmixer_JACKGUI) $(x42_matrixmixer_LV2HTTL) + + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + -include $(RW)robtk.mk +endif + +$(BUILDDIR)$(LV2GUI)$(LIB_EXT): $(GUI_DEPS) + +############################################################################### +# install/uninstall/clean target definitions + +install: install-bin install-man + +uninstall: uninstall-bin uninstall-man + +install-bin: all + install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m644 $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m755 $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +ifneq ($(BUILDOPENGL), no) + install -m755 $(BUILDDIR)$(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +endif +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(BINDIR) + install -m755 $(APPBLD)x42-matrixmixer$(NAMESUFFIX)$(EXE_EXT) $(DESTDIR)$(BINDIR) +endif + +uninstall-bin: + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/manifest.ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME).ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME)$(LIB_EXT) + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2GUI)$(LIB_EXT) + rm -f $(DESTDIR)$(BINDIR)/x42-matrixmixer$(NAMESUFFIX)$(EXE_EXT) + -rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE) + -rmdir $(DESTDIR)$(BINDIR) + +install-man: +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(MANDIR) + install -m644 x42-matrixmixer.1 $(DESTDIR)$(MANDIR) +endif + +uninstall-man: + rm -f $(DESTDIR)$(MANDIR)/x42-matrixmixer.1 + -rmdir $(DESTDIR)$(MANDIR) + +man: $(APPBLD)x42-matrixmixer$(NAMESUFFIX) + help2man -N -o x42-matrixmixer.1 -n "JACK Matrix Mixer" $(APPBLD)x42-matrixmixer$(NAMESUFFIX) + +clean: + rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl \ + $(BUILDDIR)$(LV2NAME)$(LIB_EXT) \ + $(BUILDDIR)$(LV2GUI)$(LIB_EXT) + rm -rf $(BUILDDIR)*.dSYM + rm -rf $(APPBLD)x42-* $(APPBLD)matrixmixer.h + -test -d $(APPBLD) && rmdir $(APPBLD) || true + -test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true + +distclean: clean + rm -f cscope.out cscope.files tags + +.PHONY: clean all install uninstall distclean jackapps man \ + install-bin uninstall-bin install-man uninstall-man \ + submodule_check submodules submodule_update submodule_pull diff -Nru x42-plugins-20170428/matrixmixer.lv2/README.md x42-plugins-20190714/matrixmixer.lv2/README.md --- x42-plugins-20170428/matrixmixer.lv2/README.md 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/README.md 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,44 @@ +Matrix-Mixer +============ + +matrixmixer.lv2 is a matrix mixer :) + +It is available as [LV2 plugin](http://lv2plug.in/) and standalone [JACK](http://jackaudio.org/)-application. +The jack application can run headless and be remote controlled via [OSC](http://opensoundcontrol.org/). + +Install +------- + +Compilation requires the LV2 SDK, jack-headers, gnu-make, a c-compiler, +libpango, libcairo, openGL (sometimes called: glu, glx, mesa), and +optionally libjack and liblo (for jack-app with remote-control) + +```bash +git clone git://github.com/x42/matrixmixer.lv2 +cd matrixmixer.lv2 +make submodules +make +#sudo make install PREFIX=/usr +``` + +Note to packagers: The Makefile honors `PREFIX` and `DESTDIR` variables as well +as `CFLAGS`, `LDFLAGS` and `OPTIMIZATIONS` (additions to `CFLAGS`), also +see the first 10 lines of the Makefile. +You really want to package the superset of [x42-plugins](https://github.com/x42/x42-plugins). + +The number of I/O can be set at compile time using `N_INPUTS` and `N_OUTPUTS` make variables. +The default is 8x8. Note that to change the size, a `make clean` is needed. + +Usage +----- +* Click+drag or scroll-wheel on a knob to change gain +* Left-click a control to invert polarity (knob turns red) +* Middle-click on a knob to exclusively un/assigns it in the current row +* Right-click on a knob to toggle current/default value (by default matching I/O on the diagonal is set to 0dB) + +Screenshots +----------- + +![screenshot](https://raw.github.com/x42/matrixmixer.lv2/master/img/matrix16x20.png "MatrixMixer 16x20 GUI") + +Compiled with `make N_INPUTS=16 N_OUTPUTS=20` diff -Nru x42-plugins-20170428/matrixmixer.lv2/src/matrixmixer.c x42-plugins-20190714/matrixmixer.lv2/src/matrixmixer.c --- x42-plugins-20170428/matrixmixer.lv2/src/matrixmixer.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/src/matrixmixer.c 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,204 @@ +/* Matrix Mixer LV2 + * + * Copyright (C) 2019 Robin Gareus + * + * 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, 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. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include + +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#include "matrixmixer.h" + +#define MAX_NPROC 32 + +typedef struct { + float const* a_in[N_INPUTS]; + float* a_out[N_OUTPUTS]; + float* p_gain[N_INPUTS * N_OUTPUTS]; + + float gain[N_INPUTS * N_OUTPUTS]; + float lpf; +} MixMat; + +static LV2_Handle +instantiate ( + const LV2_Descriptor* descriptor, + double rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + MixMat* self = (MixMat*)calloc (1, sizeof (MixMat)); + if (!self) { + return NULL; + } + + self->lpf = 920.f / rate; + memset (self->gain, 0, sizeof (float) * N_INPUTS * N_OUTPUTS); + + return (LV2_Handle)self; +} + +static void +connect_port ( + LV2_Handle handle, + uint32_t port, + void* data) +{ + MixMat* self = (MixMat*)handle; + if (port < N_INPUTS) { + self->a_in[port] = (float const*)data; + } else if (port < N_INPUTS + N_OUTPUTS) { + self->a_out[port - N_INPUTS] = (float*)data; + } else if (port < N_INPUTS + N_OUTPUTS + N_INPUTS * N_OUTPUTS) { + self->p_gain[port - N_INPUTS - N_OUTPUTS] = (float*)data; + } +} + +static void +process_inplace (float const* const* ins, float* const* outs, float const* const gain, uint32_t n_samples) +{ + /* LV2 allows in-place processing ins == outs. + * we need to buffer outputs to avoid overwriting data + */ + float buf[N_OUTPUTS][MAX_NPROC]; + + /* 1st row, set outputs */ + float const* in = ins[0]; + for (uint32_t c = 0; c < N_OUTPUTS; ++c) { + for (uint32_t i = 0; i < n_samples; ++i) { + buf[c][i] = in[i] * gain[c]; + } + } + + /* remaining rows, add to output */ + for (uint32_t r = 1; r < N_INPUTS; ++r) { + in = ins[r]; + for (uint32_t c = 0; c < N_OUTPUTS; ++c) { + for (uint32_t i = 0; i < n_samples; ++i) { + buf[c][i] += in[i] * gain[c + r * N_OUTPUTS]; + } + } + } + + /* copy back buffer */ + for (uint32_t c = 0; c < N_OUTPUTS; ++c) { + memcpy (outs[c], buf[c], n_samples * sizeof (float)); + } +} + +static void +run (LV2_Handle handle, uint32_t n_samples) +{ + MixMat* self = (MixMat*)handle; + + /* cache on stack */ + float const* const* const ins = self->a_in; + float* const* const outs = self->a_out; + + float gain_target[N_INPUTS * N_OUTPUTS]; + float gain[N_INPUTS * N_OUTPUTS]; + + const float lpf = self->lpf; + + for (int i = 0; i < N_INPUTS * N_OUTPUTS; ++i) { + gain_target[i] = *self->p_gain[i]; + gain[i] = self->gain[i]; + } + + /* process in chunks of MAX_NPROC samples */ + uint32_t offset = 0; + uint32_t remain = n_samples; + while (remain > 0) { + uint32_t n_proc = remain > MAX_NPROC ? MAX_NPROC : remain; + + float const* inp[N_INPUTS]; + float* outp[N_OUTPUTS]; + + /* prepare buffer-pointers for this sub-cycle */ + for (uint32_t r = 0; r < N_INPUTS; ++r) { + inp[r] = &ins[r][offset]; + } + for (uint32_t c = 0; c < N_OUTPUTS; ++c) { + outp[c] = &outs[c][offset]; + } + + process_inplace (inp, outp, gain, n_proc); + + /* low-pass filter gain coefficient */ + for (int i = 0; i < N_INPUTS * N_OUTPUTS; ++i) { + if (fabsf (gain[i] - gain_target[i]) < 1e-6) { + gain[i] = gain_target[i]; + } else { + gain[i] += lpf * (gain_target[i] - gain[i]) + 1e-10; + } + } + + remain -= n_proc; + offset += n_proc; + } + + memcpy (self->gain, gain, N_INPUTS * N_OUTPUTS * sizeof (float)); +} + +static void +cleanup (LV2_Handle handle) +{ + free (handle); +} + +static const void* +extension_data (const char* uri) +{ + return NULL; +} + +static const LV2_Descriptor descriptor = { + MATMIX_URI, + instantiate, + connect_port, + NULL, + run, + NULL, + cleanup, + extension_data +}; + +#undef LV2_SYMBOL_EXPORT +#ifdef _WIN32 +# define LV2_SYMBOL_EXPORT __declspec(dllexport) +#else +# define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default"))) +#endif +LV2_SYMBOL_EXPORT +const LV2_Descriptor* +lv2_descriptor (uint32_t index) +{ + switch (index) { + case 0: + return &descriptor; + default: + return NULL; + } +} diff -Nru x42-plugins-20170428/matrixmixer.lv2/src/matrixmixer.h x42-plugins-20190714/matrixmixer.lv2/src/matrixmixer.h --- x42-plugins-20170428/matrixmixer.lv2/src/matrixmixer.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/src/matrixmixer.h 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,3 @@ +#define xstr(s) str(s) +#define str(s) #s +#define MATMIX_URI "http://gareus.org/oss/lv2/matrixmixer#i" xstr(N_INPUTS) "o" xstr(N_OUTPUTS) diff -Nru x42-plugins-20170428/matrixmixer.lv2/x42-matrixmixer.1 x42-plugins-20190714/matrixmixer.lv2/x42-matrixmixer.1 --- x42-plugins-20170428/matrixmixer.lv2/x42-matrixmixer.1 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/matrixmixer.lv2/x42-matrixmixer.1 2019-07-14 19:39:16.000000000 +0000 @@ -0,0 +1,60 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH X42-MATRIXMIXER8X8 "1" "July 2019" "x42-matrixmixer8x8 version 0.2.4" "User Commands" +.SH NAME +x42-matrixmixer8x8 \- JACK Matrix Mixer +.SH SYNOPSIS +.B x42-matrixmixer8x8 +[ \fI\,OPTIONS \/\fR] +.SH DESCRIPTION +x42\-matrixmixer8x8 \- JACK Matrix Mixer 8x8 +.PP +This is a standalone JACK application of the LV2 plugin: +"Matrix Mixer 8x8". +.PP +Usage: +All control elements are operated in using the mouse: +.TP +Click+Drag +left/down: decrease, right/up: increase value. Hold the Ctrl key to increase sensitivity. +.TP +Shift+Click +reset to default value +.TP +Scroll\-wheel +up/down by 1 step (smallest possible adjustment for given setting). Rapid continuous scrolling increases the step\-size. +.PP +The application can be closed by sending a SIGTERM (CTRL+C) on the command\-line of by closing the window. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Display this help and exit +.TP +\fB\-j\fR, \fB\-\-jack\-name\fR +Set the JACK client name +(defaults to plugin\-name) +.TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP +\fB\-O\fR , \fB\-\-osc\fR +Listen for OSC messages on the given UDP port +.TP +\fB\-p\fR :, \fB\-\-port\fR : +Set initial value for given control port +.TP +\fB\-P\fR, \fB\-\-portlist\fR +Print control port list on startup +.TP +\fB\-\-osc\-doc\fR +Print available OSC commands and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version information and exit +.PP +See also: +Website: +.SH COPYRIGHT +Copyright \(co GPL 2013\-2019 Robin Gareus +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/meters.lv2/doc/x42-meter.1 x42-plugins-20190714/meters.lv2/doc/x42-meter.1 --- x42-plugins-20170428/meters.lv2/doc/x42-meter.1 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/doc/x42-meter.1 2019-05-07 15:16:13.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH X42-METER "1" "April 2017" "x42-meter version 0.9.4" "User Commands" +.TH X42-METER "1" "May 2019" "x42-meter version 0.9.12" "User Commands" .SH NAME x42-meter \- JACK Audio Meter Collection .SH SYNOPSIS @@ -12,7 +12,7 @@ Use ID \fB\-1\fR, \fB\-l\fR or \fB\-\-list\fR for a dedicated list of included plugins. By default the first listed plugin (ID 0) is used. .PP -List if available plugins: (ID "Name" URI) +List of available plugins: (ID "Name" URI) .TP 0 "EBU R128 Meter" http://gareus.org/oss/lv2/meters#EBUr128 @@ -48,7 +48,7 @@ "True\-Peak and RMS Meter (Stereo)" http://gareus.org/oss/lv2/meters#TPnRMSstereo .TP 11 -"DR14 \- Dynamic Range Meter" http://gareus.org/oss/lv2/meters#dr14stereo +"DR\-14 \- Crest Factor Loudness Range Meter" http://gareus.org/oss/lv2/meters#dr14stereo .TP 12 "Stereo Phase\-Correlation Meter" http://gareus.org/oss/lv2/meters#COR @@ -96,6 +96,9 @@ Set the JACK client name (defaults to plugin\-name) .TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP \fB\-l\fR, \fB\-\-list\fR Print list of available plugins and exit .TP @@ -117,7 +120,7 @@ See also: Website: .SH COPYRIGHT -Copyright \(co GPL 2013\-2015 Robin Gareus +Copyright \(co GPL 2013\-2019 Robin Gareus .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/meters.lv2/gui/fft.c x42-plugins-20190714/meters.lv2/gui/fft.c --- x42-plugins-20170428/meters.lv2/gui/fft.c 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/gui/fft.c 2019-05-07 15:16:13.000000000 +0000 @@ -1,5 +1,5 @@ /* FFT analysis - spectrogram - * Copyright (C) 2013 Robin Gareus + * Copyright (C) 2013, 2019 Robin Gareus * * 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 @@ -16,88 +16,169 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include #include #include -#include -#include #ifndef MIN -#define MIN(A,B) ( (A) < (B) ? (A) : (B) ) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) #endif static pthread_mutex_t fftw_planner_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int instance_count = 0; + +typedef enum { + W_HANN = 0, + W_HAMMMIN, + W_NUTTALL, + W_BLACKMAN_NUTTALL, + W_BLACKMAN_HARRIS, + W_FLAT_TOP +} window_t; /****************************************************************************** * internal FFT abstraction */ struct FFTAnalysis { - uint32_t window_size; - uint32_t data_size; - double rate; - double freq_per_bin; - double phasediff_step; - float *hann_window; - float *fft_in; - float *fft_out; - float *power; - float *phase; - float *phase_h; + uint32_t window_size; + window_t window_type; + uint32_t data_size; + double rate; + double freq_per_bin; + double phasediff_step; + float* window; + float* fft_in; + float* fft_out; + float* power; + float* phase; + float* phase_h; fftwf_plan fftplan; - float *ringbuf; + float* ringbuf; uint32_t rboff; uint32_t smps; uint32_t sps; uint32_t step; - double phasediff_bin; + double phasediff_bin; }; -/****************************************************************************** - * internal private functions +/* **************************************************************************** + * windows */ -static float * ft_hann_window(struct FFTAnalysis *ft) { - if (ft->hann_window) return ft->hann_window; - ft->hann_window = (float *) malloc(sizeof(float) * ft->window_size); +static double +ft_hannhamm (float* window, uint32_t n, double a, double b) +{ double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + for (uint32_t i = 0; i < n; ++i) { + window[i] = a - b * cos (c * i); + sum += window[i]; + } + return sum; +} - for (uint32_t i=0; i < ft->window_size; i++) { - ft->hann_window[i] = 0.5f - (0.5f * (float) cos(2.0f * M_PI * (float)i / (float)(ft->window_size))); - sum += ft->hann_window[i]; +static double +ft_bnh (float* window, uint32_t n, double a0, double a1, double a2, double a3) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i); + sum += window[i]; } + return sum; +} + +static double +ft_flattop (float* window, uint32_t n) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + const double c4 = 4.0 * c; + + const double a0 = 1.0; + const double a1 = 1.93; + const double a2 = 1.29; + const double a3 = 0.388; + const double a4 = 0.028; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i) + a4 * cos(c4 * i); + sum += window[i]; + } + return sum; +} + + +/* **************************************************************************** + * internal private functions + */ +static float* +ft_gen_window (struct FFTAnalysis* ft) +{ + if (ft->window) { + return ft->window; + } + + ft->window = (float*)malloc (sizeof (float) * ft->window_size); + double sum = .0; + + /* https://en.wikipedia.org/wiki/Window_function */ + switch (ft->window_type) { + default: + case W_HANN: + sum = ft_hannhamm (ft->window, ft->window_size, .5, .5); + break; + case W_HAMMMIN: + sum = ft_hannhamm (ft->window, ft->window_size, .54, .46); + break; + case W_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .355768, .487396, .144232, .012604); + break; + case W_BLACKMAN_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .3635819, .4891775, .1365995, .0106411); + break; + case W_BLACKMAN_HARRIS: + sum = ft_bnh (ft->window, ft->window_size, .35875, .48829, .14128, .01168); + break; + case W_FLAT_TOP: + sum = ft_flattop (ft->window, ft->window_size); + break; + } + const double isum = 2.0 / sum; - for (uint32_t i=0; i < ft->window_size; i++) { - ft->hann_window[i] *= isum; + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->window[i] *= isum; } - return ft->hann_window; + return ft->window; } -static void ft_analyze(struct FFTAnalysis *ft) { - fftwf_execute(ft->fftplan); +static void +ft_analyze (struct FFTAnalysis* ft) +{ + fftwf_execute (ft->fftplan); - memcpy(ft->phase_h, ft->phase, sizeof(float) * ft->data_size); + memcpy (ft->phase_h, ft->phase, sizeof (float) * ft->data_size); ft->power[0] = ft->fft_out[0] * ft->fft_out[0]; ft->phase[0] = 0; #define FRe (ft->fft_out[i]) -#define FIm (ft->fft_out[ft->window_size-i]) +#define FIm (ft->fft_out[ft->window_size - i]) for (uint32_t i = 1; i < ft->data_size - 1; ++i) { ft->power[i] = (FRe * FRe) + (FIm * FIm); - ft->phase[i] = atan2f(FIm, FRe); + ft->phase[i] = atan2f (FIm, FRe); } #undef FRe #undef FIm } -static void ft_analyze_hann(struct FFTAnalysis *ft) { - float *window = ft_hann_window(ft); - for (uint32_t i = 0; i < ft->window_size; i++) { - ft->fft_in[i] *= window[i]; - } - ft_analyze(ft); -} - - /****************************************************************************** * public API (static for direct source inclusion) */ @@ -106,10 +187,12 @@ #endif FFTX_FN_PREFIX -void fftx_reset(struct FFTAnalysis *ft) { +void +fftx_reset (struct FFTAnalysis* ft) +{ for (uint32_t i = 0; i < ft->data_size; ++i) { - ft->power[i] = 0; - ft->phase[i] = 0; + ft->power[i] = 0; + ft->phase[i] = 0; ft->phase_h[i] = 0; } for (uint32_t i = 0; i < ft->window_size; ++i) { @@ -117,73 +200,107 @@ ft->fft_out[i] = 0; } ft->rboff = 0; - ft->smps = 0; - ft->step = 0; + ft->smps = 0; + ft->step = 0; } FFTX_FN_PREFIX -void fftx_init(struct FFTAnalysis *ft, uint32_t window_size, double rate, double fps) { - ft->rate = rate; - ft->window_size = window_size; - ft->data_size = window_size / 2; - ft->hann_window = NULL; - ft->rboff = 0; - ft->smps = 0; - ft->step = 0; - ft->sps = (fps > 0) ? ceil(rate / fps) : 0; - ft->freq_per_bin = ft->rate / ft->data_size / 2.f; +void +fftx_init (struct FFTAnalysis* ft, uint32_t window_size, double rate, double fps) +{ + ft->rate = rate; + ft->window_size = window_size; + ft->window_type = W_HANN; + ft->data_size = window_size / 2; + ft->window = NULL; + ft->rboff = 0; + ft->smps = 0; + ft->step = 0; + ft->sps = (fps > 0) ? ceil (rate / fps) : 0; + ft->freq_per_bin = ft->rate / ft->data_size / 2.f; ft->phasediff_step = M_PI / ft->data_size; - ft->phasediff_bin = 0; + ft->phasediff_bin = 0; + + ft->ringbuf = (float*)malloc (window_size * sizeof (float)); + ft->fft_in = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->fft_out = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->power = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase_h = (float*)malloc (ft->data_size * sizeof (float)); - ft->ringbuf = (float *) malloc(window_size * sizeof(float)); - ft->fft_in = (float *) fftwf_malloc(sizeof(float) * window_size); - ft->fft_out = (float *) fftwf_malloc(sizeof(float) * window_size); - ft->power = (float *) malloc(ft->data_size * sizeof(float)); - ft->phase = (float *) malloc(ft->data_size * sizeof(float)); - ft->phase_h = (float *) malloc(ft->data_size * sizeof(float)); - - fftx_reset(ft); - - pthread_mutex_lock(&fftw_planner_lock); - ft->fftplan = fftwf_plan_r2r_1d(window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); - pthread_mutex_unlock(&fftw_planner_lock); + fftx_reset (ft); + + pthread_mutex_lock (&fftw_planner_lock); + ft->fftplan = fftwf_plan_r2r_1d (window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); + ++instance_count; + pthread_mutex_unlock (&fftw_planner_lock); } FFTX_FN_PREFIX -void fftx_free(struct FFTAnalysis *ft) { - if (!ft) return; - pthread_mutex_lock(&fftw_planner_lock); - fftwf_destroy_plan(ft->fftplan); - pthread_mutex_unlock(&fftw_planner_lock); - free(ft->hann_window); - free(ft->ringbuf); - fftwf_free(ft->fft_in); - fftwf_free(ft->fft_out); - free(ft->power); - free(ft->phase); - free(ft->phase_h); - free(ft); -} - -static -int _fftx_run(struct FFTAnalysis *ft, - const uint32_t n_samples, float const * const data) +void +fftx_set_window (struct FFTAnalysis* ft, window_t type) { - assert(n_samples <= ft->window_size); + if (ft->window_type == type) { + return; + } + ft->window_type = type; + free (ft->window); + ft->window = NULL; +} - float * const f_buf = ft->fft_in; - float * const r_buf = ft->ringbuf; +FFTX_FN_PREFIX +void +fftx_free (struct FFTAnalysis* ft) +{ + if (!ft) { + return; + } + pthread_mutex_lock (&fftw_planner_lock); + fftwf_destroy_plan (ft->fftplan); + if (instance_count > 0) { + --instance_count; + } +#ifdef WITH_STATIC_FFTW_CLEANUP + /* use this only when statically linking to a local fftw! + * + * "After calling fftw_cleanup, all existing plans become undefined, + * and you should not attempt to execute them nor to destroy them." + * [http://www.fftw.org/fftw3_doc/Using-Plans.html] + * + * If libfftwf is shared with other plugins or the host this can + * cause undefined behavior. + */ + if (instance_count == 0) { + fftwf_cleanup (); + } +#endif + pthread_mutex_unlock (&fftw_planner_lock); + free (ft->window); + free (ft->ringbuf); + fftwf_free (ft->fft_in); + fftwf_free (ft->fft_out); + free (ft->power); + free (ft->phase); + free (ft->phase_h); + free (ft); +} + +static int +_fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) +{ + assert (n_samples <= ft->window_size); + + float* const f_buf = ft->fft_in; + float* const r_buf = ft->ringbuf; const uint32_t n_off = ft->rboff; const uint32_t n_siz = ft->window_size; const uint32_t n_old = n_siz - n_samples; - /* copy new data into ringbuffer and fft-buffer - * TODO: use memcpy - */ for (uint32_t i = 0; i < n_samples; ++i) { - r_buf[ (i + n_off) % n_siz ] = data[i]; - f_buf[n_old + i] = data[i]; + r_buf[(i + n_off) % n_siz] = data[i]; + f_buf[n_old + i] = data[i]; } ft->rboff = (ft->rboff + n_samples) % n_siz; @@ -203,117 +320,142 @@ if (p0s + n_old >= n_siz) { const uint32_t n_p1 = n_siz - p0s; const uint32_t n_p2 = n_old - n_p1; - memcpy(f_buf, &r_buf[p0s], sizeof(float) * n_p1); - memcpy(&f_buf[n_p1], &r_buf[0], sizeof(float) * n_p2); + memcpy (f_buf, &r_buf[p0s], sizeof (float) * n_p1); + memcpy (&f_buf[n_p1], &r_buf[0], sizeof (float) * n_p2); } else { - memcpy(&f_buf[0], &r_buf[p0s], sizeof(float) * n_old); + memcpy (&f_buf[0], &r_buf[p0s], sizeof (float) * n_old); + } + + /* apply window function */ + float const* const window = ft_gen_window (ft); + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->fft_in[i] *= window[i]; } /* ..and analyze */ - ft_analyze_hann(ft); + ft_analyze (ft); + ft->phasediff_bin = ft->phasediff_step * (double)ft->step; return 0; } FFTX_FN_PREFIX -int fftx_run(struct FFTAnalysis *ft, - const uint32_t n_samples, float const * const data) +int +fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) { if (n_samples <= ft->window_size) { - return _fftx_run(ft, n_samples, data); + return _fftx_run (ft, n_samples, data); } - int rv = -1; - uint32_t n = 0; + int rv = -1; + uint32_t n = 0; while (n < n_samples) { - uint32_t step = MIN(ft->window_size, n_samples - n); - if (!_fftx_run(ft, step, &data[n])) rv = 0; + uint32_t step = MIN (ft->window_size, n_samples - n); + if (!_fftx_run (ft, step, &data[n])) { + rv = 0; + } n += step; } return rv; } - FFTX_FN_PREFIX -void fa_analyze_dsp(struct FFTAnalysis *ft, - void (*run)(void *, uint32_t, float*), void *handle) +void +fa_analyze_dsp (struct FFTAnalysis* ft, + void (*run) (void*, uint32_t, float*), void* handle) { - float *buf = ft->fft_in; + float* buf = ft->fft_in; /* pre-run 8K samples... (re-init/flush effect) */ uint32_t prerun_n_samples = 8192; while (prerun_n_samples > 0) { uint32_t n_samples = MIN (prerun_n_samples, ft->window_size); - memset(buf, 0, sizeof(float) * n_samples); + memset (buf, 0, sizeof (float) * n_samples); run (handle, n_samples, buf); prerun_n_samples -= n_samples; } /* delta impulse */ - memset(buf, 0, sizeof(float) * ft->window_size); + memset (buf, 0, sizeof (float) * ft->window_size); *buf = 1.0; /* call plugin's run() function -- in-place processing */ run (handle, ft->window_size, buf); ft->step = ft->window_size; - /* ..and analyze */ - ft_analyze(ft); + ft_analyze (ft); } - -/***************************************************************************** +/* *************************************************************************** * convenient access functions */ FFTX_FN_PREFIX -uint32_t fftx_bins(struct FFTAnalysis *ft) { - return ft->data_size; +uint32_t +fftx_bins (struct FFTAnalysis* ft) +{ + return ft->data_size; } FFTX_FN_PREFIX -inline float fast_log2 (float val) { - union {float f; int i;} t; - t.f = val; - int * const exp_ptr = &t.i; - int x = *exp_ptr; - const int log_2 = ((x >> 23) & 255) - 128; +inline float +fast_log2 (float val) +{ + union { + float f; + int i; + } t; + t.f = val; + int* const exp_ptr = &t.i; + int x = *exp_ptr; + const int log_2 = ((x >> 23) & 255) - 128; x &= ~(255 << 23); x += 127 << 23; *exp_ptr = x; - val = ((-1.0f/3) * t.f + 2) * t.f - 2.0f/3; + val = ((-1.0f / 3) * t.f + 2) * t.f - 2.0f / 3; return (val + log_2); } FFTX_FN_PREFIX -inline float fast_log (const float val) { - return (fast_log2 (val) * 0.69314718f); +inline float +fast_log (const float val) +{ + return (fast_log2 (val) * 0.69314718f); } FFTX_FN_PREFIX -inline float fast_log10 (const float val) { - return fast_log2(val) / 3.312500f; +inline float +fast_log10 (const float val) +{ + return fast_log2 (val) / 3.312500f; } FFTX_FN_PREFIX -inline float fftx_power_to_dB(float a) { +inline float +fftx_power_to_dB (float a) +{ /* 10 instead of 20 because of squared signal -- no sqrt(powerp[]) */ - return a > 1e-12 ? 10.0 * fast_log10(a) : -INFINITY; + return a > 1e-12 ? 10.0 * fast_log10 (a) : -INFINITY; } FFTX_FN_PREFIX -float fftx_power_at_bin(struct FFTAnalysis *ft, const int b) { - return (fftx_power_to_dB(ft->power[b])); +float +fftx_power_at_bin (struct FFTAnalysis* ft, const int b) +{ + return (fftx_power_to_dB (ft->power[b])); } FFTX_FN_PREFIX -float fftx_freq_at_bin(struct FFTAnalysis *ft, const int b) { +float +fftx_freq_at_bin (struct FFTAnalysis* ft, const int b) +{ /* calc phase: difference minus expected difference */ - float phase = ft->phase[b] - ft->phase_h[b] - (float) b * ft->phasediff_bin; + float phase = ft->phase[b] - ft->phase_h[b] - (float)b * ft->phasediff_bin; /* clamp to -M_PI .. M_PI */ int over = phase / M_PI; - over += (over >= 0) ? (over&1) : -(over&1); - phase -= M_PI*(float)over; + over += (over >= 0) ? (over & 1) : -(over & 1); + phase -= M_PI * (float)over; /* scale according to overlap */ phase *= (ft->data_size / ft->step) / M_PI; - return ft->freq_per_bin * ((float) b + phase); + return ft->freq_per_bin * ((float)b + phase); } diff -Nru x42-plugins-20170428/meters.lv2/gui/meterimage.c x42-plugins-20190714/meters.lv2/gui/meterimage.c --- x42-plugins-20170428/meters.lv2/gui/meterimage.c 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/gui/meterimage.c 2019-05-07 15:16:13.000000000 +0000 @@ -125,15 +125,14 @@ PangoLayout * pl = pango_cairo_create_layout(cr); PangoFontDescription *desc = pango_font_description_from_string(font); pango_layout_set_font_description(pl, desc); - pango_font_description_free(desc); pango_layout_set_text(pl, txt, -1); pango_layout_get_pixel_size(pl, &tw, &th); cairo_translate (cr, x, y); cairo_rotate (cr, ang); cairo_translate (cr, -tw/2.0, -th/2.0); - pango_cairo_layout_path(cr, pl); - cairo_fill(cr); + pango_cairo_show_layout(cr, pl); g_object_unref(pl); + pango_font_description_free(desc); cairo_restore(cr); cairo_new_path (cr); } @@ -436,7 +435,7 @@ if ((pc%2) == 0) { char buf[8]; if (pc==10) - sprintf(buf, " 100%%"); + sprintf(buf, " 100%%"); else sprintf(buf, "%d", pc*10); img_needle_label_col(cr, buf, percZ + pc * percS, _rx, c_blk); diff -Nru x42-plugins-20170428/meters.lv2/gui/phasewheel.c x42-plugins-20190714/meters.lv2/gui/phasewheel.c --- x42-plugins-20170428/meters.lv2/gui/phasewheel.c 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/gui/phasewheel.c 2019-05-07 15:16:13.000000000 +0000 @@ -45,7 +45,7 @@ #define PC_BLOCKSIZE (PC_HEIGHT - PC_BLOCK) static const float c_ann[4] = {0.5, 0.5, 0.5, 1.0}; // text annotation color -static const float c_ahz[4] = {0.6, 0.6, 0.6, 0.5}; // frequency annotation +static const float c_ahz[4] = {0.6, 0.6, 0.6, 0.6}; // frequency annotation static const float c_grd[4] = {0.4, 0.4, 0.4, 1.0}; // grid color #ifdef _WIN32 @@ -285,7 +285,7 @@ /** prepare drawing surfaces, render fixed background */ static void m0_create_surfaces(MF2UI* ui) { cairo_t* cr; - const double ccc = ui->width / 2.0 + .5; + const double ccc = floor (ui->width / 2.0) + .5; const double rad = (ui->width - XOFF) * .5; if (ui->sf_ann) cairo_surface_destroy(ui->sf_ann); @@ -369,7 +369,7 @@ * and on screen annotations - sample-rate dependent */ static void update_grid(MF2UI* ui) { - const double ccc = ui->width / 2.0 + .5; + const double ccc = floor (ui->width / 2.0) + .5; const double rad = (ui->width - XOFF) * .5; cairo_t *cr = cairo_create (ui->sf_ann); @@ -378,25 +378,35 @@ cairo_fill (cr); cairo_set_line_width (cr, 1.0); - cairo_arc (cr, ccc, ccc, rad, 0, 2.0 * M_PI); cairo_set_source_rgba(cr, 0, 0, 0, 1.0); cairo_fill_preserve(cr); CairoSetSouerceRGBA(c_g90); cairo_stroke(cr); - const double dash1[] = {1.0, 2.0}; + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + + double lw = round (10. * rad / (double)PH_RAD) / 10.; + cairo_set_line_width (cr, lw); + double dash1[2]; + dash1[0] = 1; + dash1[1] = 2 * lw; + cairo_set_dash(cr, dash1, 2, 0); CairoSetSouerceRGBA(c_grd); + char fn[32]; + sprintf (fn, "Mono %.0fpx", round (9.f * rad / (double)PH_RAD)); + PangoFontDescription *fd = pango_font_description_from_string(fn); + float freq = 62.5; while (freq < ui->rate / 2) { char txt[16]; if (freq < 1000) { snprintf(txt, 16, "%d Hz", (int)ceil(freq)); } else { - snprintf(txt, 16, "%d KHz", (int)ceil(freq/1000.f)); + snprintf(txt, 16, "%d kHz", (int)ceil(freq/1000.f)); } { @@ -405,36 +415,43 @@ cairo_stroke(cr); const float px = ccc + dr * sinf(M_PI * -.75); const float py = ccc - dr * cosf(M_PI * -.75); - write_text_full(cr, txt, ui->font[0], px, py, M_PI * -.75, -2, c_ahz); + write_text_full(cr, txt, fd, px, py, M_PI * -.75, -2, c_ahz); } freq *= 2.0; } - const double dash2[] = {1.0, 3.0}; - cairo_set_line_width(cr, 3.5); - cairo_set_dash(cr, dash2, 2, 2); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); - cairo_set_line_width(cr, 1.5); - cairo_move_to(cr, ccc - rad, ccc); + /* horiz line */ + cairo_set_line_width(cr, lw * 1.5); + cairo_move_to(cr, ccc, ccc); + cairo_line_to(cr, ccc - rad, ccc); + cairo_move_to(cr, ccc, ccc); cairo_line_to(cr, ccc + rad, ccc); cairo_stroke(cr); - cairo_set_line_width(cr, 3.5); - cairo_move_to(cr, ccc, ccc - rad); + /* vert thicker line */ + cairo_set_line_width(cr, lw * 2.5); + cairo_move_to(cr, ccc, ccc); + cairo_line_to(cr, ccc, ccc - rad); + cairo_move_to(cr, ccc, ccc); cairo_line_to(cr, ccc, ccc + rad); cairo_stroke(cr); + cairo_set_dash(cr, NULL, 0, 0); - write_text_full(cr, "+L", ui->font[0], ccc, ccc - rad * .92, 0, -2, c_ann); - write_text_full(cr, "-L", ui->font[0], ccc, ccc + rad * .92, 0, -2, c_ann); - write_text_full(cr, "0\u00B0", ui->font[0], ccc, ccc - rad * .80, 0, -2, c_ann); - write_text_full(cr, "180\u00B0", ui->font[0], ccc, ccc + rad * .80, 0, -2, c_ann); - - write_text_full(cr, "-R", ui->font[0], ccc - rad * .92, ccc, 0, -2, c_ann); - write_text_full(cr, "+R", ui->font[0], ccc + rad * .92, ccc, 0, -2, c_ann); - write_text_full(cr, "-90\u00B0", ui->font[0], ccc - rad * .80, ccc, 0, -2, c_ann); - write_text_full(cr, "+90\u00B0", ui->font[0], ccc + rad * .80, ccc, 0, -2, c_ann); + write_text_full(cr, "+L", fd, ccc, ccc - rad * .92, 0, -2, c_ann); + write_text_full(cr, "-L", fd, ccc, ccc + rad * .92, 0, -2, c_ann); + write_text_full(cr, "0\u00B0", fd, ccc, ccc - rad * .80, 0, -2, c_ann); + write_text_full(cr, "180\u00B0", fd, ccc, ccc + rad * .80, 0, -2, c_ann); + + write_text_full(cr, "-R", fd, ccc - rad * .92, ccc, 0, -2, c_ann); + write_text_full(cr, "+R", fd, ccc + rad * .92, ccc, 0, -2, c_ann); + write_text_full(cr, "-90\u00B0", fd, ccc - rad * .80, ccc, 0, -2, c_ann); + write_text_full(cr, "+90\u00B0", fd, ccc + rad * .80, ccc, 0, -2, c_ann); + + pango_font_description_free(fd); cairo_destroy (cr); } @@ -553,7 +570,7 @@ /* linear FFT data display */ static void plot_data_fft(MF2UI* ui) { cairo_t* cr; - const double ccc = ui->width / 2.0 + .5; + const double ccc = floor (ui->width / 2.0) + .5; const double rad = (ui->width - XOFF) * .5; const float gain = robtk_dial_get_value(ui->gain); const float persistence = robtk_dial_get_value(ui->screen); @@ -591,7 +608,7 @@ /* 1/Octave data display */ static void plot_data_oct(MF2UI* ui) { cairo_t* cr; - const double ccc = ui->width / 2.0 + .5; + const double ccc = floor (ui->width / 2.0) + .5; const double rad = (ui->width - XOFF) * .5; const float gain = robtk_dial_get_value(ui->gain); const float persistence = robtk_dial_get_value(ui->screen); @@ -668,8 +685,8 @@ } cairo_translate(cr, - rint((ui->m0_width - ui->width) * .5), - rint((ui->m0_height - ui->height) * .5)); + floor((ui->m0_width - ui->width) * .5), + floor((ui->m0_height - ui->height) * .5)); if (pthread_mutex_trylock (&ui->fft_lock) == 0 ) { if (robtk_cbtn_get_active(ui->btn_oct)) { @@ -812,7 +829,7 @@ queue_draw(ui->m2); } #ifdef __USE_GNU - const float thresh = pow10f(.05 * (MIN_CUTOFF - val)); + const float thresh = exp10f(.05 * (MIN_CUTOFF - val)); #else const float thresh = powf(10, .05 * (MIN_CUTOFF - val)); #endif diff -Nru x42-plugins-20170428/meters.lv2/lv2ttl/dr14stereo.h x42-plugins-20190714/meters.lv2/lv2ttl/dr14stereo.h --- x42-plugins-20170428/meters.lv2/lv2ttl/dr14stereo.h 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/lv2ttl/dr14stereo.h 2019-05-07 15:16:13.000000000 +0000 @@ -9,7 +9,7 @@ &lv2ui_dr14 , 26 // uint32_t dsp_descriptor_id , 0 // uint32_t gui_descriptor_id - , "DR14 - Dynamic Range Meter" // const char *plugin_human_id + , "DR-14 - Crest Factor Loudness Range Meter" // const char *plugin_human_id , (const struct LV2Port[19]) { { "control", ATOM_IN, nan, nan, nan, "Control"}, diff -Nru x42-plugins-20170428/meters.lv2/lv2ttl/meters.lv2.ttl.in x42-plugins-20190714/meters.lv2/lv2ttl/meters.lv2.ttl.in --- x42-plugins-20170428/meters.lv2/lv2ttl/meters.lv2.ttl.in 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/lv2ttl/meters.lv2.ttl.in 2019-05-07 15:16:13.000000000 +0000 @@ -7,6 +7,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -50,6 +51,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -114,6 +116,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -157,6 +160,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -221,6 +225,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -264,6 +269,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -328,6 +334,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -371,6 +378,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -435,6 +443,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -478,6 +487,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -541,6 +551,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ @@ -1972,6 +1983,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @KMRGUI@ ; lv2:port [ @@ -2033,6 +2045,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @KMRGUI@ ; lv2:port [ @@ -2124,6 +2137,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @KMRGUI@ ; lv2:port [ @@ -2185,6 +2199,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @KMRGUI@ ; lv2:port [ @@ -2276,6 +2291,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @KMRGUI@ ; lv2:port [ @@ -2337,6 +2353,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @KMRGUI@ ; lv2:port [ @@ -2426,6 +2443,7 @@ doap:name "Phase/Frequency Wheel@NAME_SUFFIX@"; @VERSION@ lv2:project ; + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; @SIGNATURE@ ui:ui @MPWGUI@ ; @@ -2568,6 +2586,7 @@ doap:name "Stereo/Frequency Scope@NAME_SUFFIX@"; @VERSION@ lv2:project ; + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; @SIGNATURE@ ui:ui @SFSGUI@ ; @@ -2666,9 +2685,10 @@ mtr:dr14mono@URI_SUFFIX@ a lv2:Plugin, lv2:AnalyserPlugin, doap:Project ; doap:license ; - doap:name "DR14 - Dynamic Range Meter (Mono)@NAME_SUFFIX@"; + doap:name "DR-14 - Crest Factor Loudness Range Meter (Mono)@NAME_SUFFIX@"; @VERSION@ lv2:project ; + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; @SIGNATURE@ ui:ui @DRMGUI@ ; @@ -2772,16 +2792,17 @@ lv2:maximum 20; rdfs:comment "" ; ] ; - rdfs:comment "Pleasurize Music Foundation Dynamic Range Meter" + rdfs:comment "This meter establishes a single loudness value by measuring the crest factor of a chunked subset of the input signal." . mtr:dr14stereo@URI_SUFFIX@ a lv2:Plugin, lv2:AnalyserPlugin, doap:Project ; doap:license ; - doap:name "DR14 - Dynamic Range Meter (Stereo)@NAME_SUFFIX@"; + doap:name "DR-14 - Crest Factor Loudness Range Meter (Stereo)@NAME_SUFFIX@"; @VERSION@ lv2:project ; + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; @SIGNATURE@ ui:ui @DRMGUI@ ; @@ -2957,7 +2978,7 @@ lv2:maximum 20; rdfs:comment "" ; ] ; - rdfs:comment "Pleasurize Music Foundation Dynamic Range Meter" + rdfs:comment "This meter establishes a single loudness value by measuring the crest factor of a chunked subset of the input signal." . mtr:TPnRMSmono@URI_SUFFIX@ @@ -2966,6 +2987,7 @@ doap:name "True-Peak and RMS Meter (Mono)@NAME_SUFFIX@"; @VERSION@ lv2:project ; + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; @SIGNATURE@ ui:ui @DRMGUI@ ; @@ -2987,7 +3009,7 @@ lv2:maximum 1.0 ; lv2:default 1.0 ; lv2:portProperty pprop:notOnGUI ; - rdfs:comment "compat w/DR14" ; + rdfs:comment "unused - port compatibility" ; ] , [ a lv2:ControlPort, lv2:InputPort ; lv2:index 2 ; @@ -3007,7 +3029,7 @@ lv2:minimum 0.0; lv2:maximum 1.0; lv2:portProperty pprop:notOnGUI ; - rdfs:comment "compat w/DR14, reinit GUI" ; + rdfs:comment "unused - port compatibility, reinit GUI" ; ] , [ a lv2:AudioPort , lv2:InputPort ; @@ -3069,6 +3091,7 @@ doap:name "True-Peak and RMS Meter (Stereo)@NAME_SUFFIX@"; @VERSION@ lv2:project ; + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; @SIGNATURE@ ui:ui @DRMGUI@ ; @@ -3090,7 +3113,7 @@ lv2:maximum 1.0 ; lv2:default 1.0 ; lv2:portProperty pprop:notOnGUI ; - rdfs:comment "compat w/DR14" ; + rdfs:comment "unused - port compatibility" ; ] , [ a lv2:ControlPort, lv2:InputPort ; lv2:index 2 ; @@ -3172,7 +3195,7 @@ lv2:minimum 0 ; lv2:maximum 1; lv2:portProperty pprop:notOnGUI ; - rdfs:comment "compat w/DR14" ; + rdfs:comment "unused - port compatibility" ; ] , [ a lv2:AudioPort , lv2:InputPort ; @@ -3282,6 +3305,7 @@ @VERSION@ lv2:project ; lv2:optionalFeature lv2:hardRTCapable ; + @INLINEDISPLAYTLL@ @SIGNATURE@ ui:ui @MTRGUI@ ; lv2:port [ diff -Nru x42-plugins-20170428/meters.lv2/lv2ttl/meters.ttl.in x42-plugins-20190714/meters.lv2/lv2ttl/meters.ttl.in --- x42-plugins-20170428/meters.lv2/lv2ttl/meters.ttl.in 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/lv2ttl/meters.ttl.in 2019-05-07 15:16:13.000000000 +0000 @@ -1,19 +1,24 @@ @prefix atom: . @prefix doap: . @prefix foaf: . +@prefix idpy: . +@prefix kx: . @prefix lv2: . -@prefix units: . +@prefix pprop: . +@prefix pg: . @prefix rdf: . @prefix rdfs: . -@prefix ui: . -@prefix urid: . -@prefix pg: . @prefix rsz: . -@prefix time: . @prefix state: . -@prefix pprop: . +@prefix time: . +@prefix ui: . +@prefix units: . +@prefix urid: . + +idpy:queue_draw a lv2:Feature . +idpy:interface a lv2:ExtensionData . + @prefix mtr: . -@prefix kx: . a foaf:Person ; diff -Nru x42-plugins-20170428/meters.lv2/lv2ttl/tp_rms_stereo.h x42-plugins-20190714/meters.lv2/lv2ttl/tp_rms_stereo.h --- x42-plugins-20170428/meters.lv2/lv2ttl/tp_rms_stereo.h 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/lv2ttl/tp_rms_stereo.h 2019-05-07 15:16:13.000000000 +0000 @@ -13,7 +13,7 @@ , (const struct LV2Port[17]) { { "control", ATOM_IN, nan, nan, nan, "Control"}, - { "unused1", CONTROL_IN, 1.000000, 0.000000, 1.000000, "compat w/DR14"}, + { "unused1", CONTROL_IN, 1.000000, 0.000000, 1.000000, ""}, { "reset", CONTROL_IN, 0.000000, 0.000000, 1.000000, ""}, { "blkcnt", CONTROL_OUT, nan, 0.000000, 3600.000000, ""}, { "in1", AUDIO_IN, nan, nan, nan, "Audio input"}, @@ -22,7 +22,7 @@ { "dBTP_p1", CONTROL_OUT, nan, -80.000000, 6.000000, ""}, { "dBRMS_m1", CONTROL_OUT, nan, -80.000000, 0.000000, ""}, { "dBRMS_p1", CONTROL_OUT, nan, -80.000000, 0.000000, ""}, - { "unused2", CONTROL_OUT, nan, 0.000000, 1.000000, "compat w/DR14"}, + { "unused2", CONTROL_OUT, nan, 0.000000, 1.000000, ""}, { "in2", AUDIO_IN, nan, nan, nan, "Audio input"}, { "out2", AUDIO_OUT, nan, nan, nan, "signal pass-thru"}, { "dBTP_m2", CONTROL_OUT, nan, -80.000000, 6.000000, ""}, diff -Nru x42-plugins-20170428/meters.lv2/Makefile x42-plugins-20190714/meters.lv2/Makefile --- x42-plugins-20170428/meters.lv2/Makefile 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/Makefile 2019-05-07 15:16:13.000000000 +0000 @@ -12,6 +12,8 @@ OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CFLAGS ?= -Wall -Wno-unused-function + +PKG_CONFIG ?= pkg-config STRIP ?= strip EXTERNALUI?=yes @@ -21,7 +23,7 @@ RW?=robtk/ ############################################################################### -override CFLAGS += -g -fvisibility=hidden $(OPTIMIZATIONS) +override CFLAGS += -g $(OPTIMIZATIONS) BUILDDIR=build/ APPBLD=x42/ @@ -83,7 +85,7 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` -pthread + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` -pthread STRIPFLAGS=-s EXTENDED_RE=-r endif @@ -129,28 +131,28 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --atleast-version=1.6.0 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) $(error "LV2 SDK needs to be at least version 1.6.0 (idle interface)") endif -ifeq ($(shell pkg-config --exists glib-2.0 pango cairo $(PKG_LIBS) || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists glib-2.0 pango cairo $(PKG_LIBS) || echo no), no) $(error "These plugins requires $(PKG_LIBS) cairo pango glib-2.0") endif -ifeq ($(shell pkg-config --exists jack || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif -ifeq ($(shell pkg-config --exists fftw3f || echo no), no) - $(error "fftw3f library was not found") +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f || echo no), no) + $(error "fftw3f library was not found") endif -FFTW=`pkg-config --cflags --libs fftw3f` -lm +FFTW=`$(PKG_CONFIG) --cflags --libs fftw3f` -lm export FFTW # lv2 >= 1.6.0 @@ -158,7 +160,7 @@ LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif @@ -179,12 +181,13 @@ override CFLAGS += -DPTW32_STATIC_LIB override CXXFLAGS += -DPTW32_STATIC_LIB endif -override CFLAGS += `pkg-config --cflags lv2` -DVERSION="\"$(meters_VERSION)\"" +override CFLAGS += `$(PKG_CONFIG) --cflags lv2` -DVERSION="\"$(meters_VERSION)\"" override CXXFLAGS += -DVERSION="\"$(meters_VERSION)\"" ifneq ($(INLINEDISPLAY),no) -override CXXFLAGS += `pkg-config --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE -I. -override LOADLIBES += `pkg-config $(PKG_UI_FLAGS) --libs cairo pangocairo pango` + override CXXFLAGS += `$(PKG_CONFIG) --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE -I. + override LOADLIBES += `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango` + INLINEDISPLAYTLL=lv2:optionalFeature idpy:queue_draw; lv2:extensionData idpy:interface; ifneq ($(XWIN),) override LOADLIBES += -lusp10 endif @@ -196,8 +199,8 @@ UIIMGS=$(IM)meter-bright.c $(IM)meter-dark.c $(IM)screw.c -GLUICFLAGS+=`pkg-config --cflags cairo pango` -GLUILIBS+=`pkg-config --libs $(PKG_UI_FLAGS) cairo pangocairo pango $(PKG_LIBS)` +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` +GLUILIBS+=`$(PKG_CONFIG) --libs $(PKG_UI_FLAGS) cairo pangocairo pango $(PKG_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 endif @@ -211,7 +214,7 @@ endif ifneq ($(LIC_CFLAGS),) - SIGNATURE=lv2:extensionData ; + LV2SIGN=lv2:extensionData ; override CXXFLAGS += -I$(RW) endif @@ -230,10 +233,10 @@ goniometer_UIDEP=zita-resampler/resampler.cc zita-resampler/resampler-table.cc goniometer_UISRC=zita-resampler/resampler.cc zita-resampler/resampler-table.cc -$(eval phasewheel_UISRC=$(value FFTW)) -$(eval stereoscope_UISRC=$(value FFTW)) +$(eval phasewheel_UISRC=$(FFTW)) +$(eval stereoscope_UISRC=$(FFTW)) -$(eval meters_UISRC=$(value FFTW)) +$(eval meters_UISRC=$(FFTW)) meters_UISRC+=zita-resampler/resampler.cc zita-resampler/resampler-table.cc ############################################################################### @@ -285,10 +288,10 @@ lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl sed "s/@UI_URI_SUFFIX@/_gl/;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ lv2ttl/$(LV2NAME).gui.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl - sed "s/@URI_SUFFIX@//g;s/@NAME_SUFFIX@//g;s/@DPMGUI@/$(DPMGUI)_gl/g;s/@EBUGUI@/$(EBUGUI)_gl/g;s/@GONGUI@/$(GONGUI)_gl/g;s/@MTRGUI@/$(MTRGUI)_gl/g;s/@KMRGUI@/$(KMRGUI)_gl/g;s/@MPWGUI@/$(MPWGUI)_gl/g;s/@SFSGUI@/$(SFSGUI)_gl/g;s/@DRMGUI@/$(DRMGUI)_gl/g;s/@SDHGUI@/$(SDHGUI)_gl/g;s/@BITGUI@/$(BITGUI)_gl/g;s/@SURGUI@/$(SURGUI)_gl/g;s/@SIGNATURE@/$(SIGNATURE)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ + sed "s/@URI_SUFFIX@//g;s/@NAME_SUFFIX@//g;s/@DPMGUI@/$(DPMGUI)_gl/g;s/@EBUGUI@/$(EBUGUI)_gl/g;s/@GONGUI@/$(GONGUI)_gl/g;s/@MTRGUI@/$(MTRGUI)_gl/g;s/@KMRGUI@/$(KMRGUI)_gl/g;s/@MPWGUI@/$(MPWGUI)_gl/g;s/@SFSGUI@/$(SFSGUI)_gl/g;s/@DRMGUI@/$(DRMGUI)_gl/g;s/@SDHGUI@/$(SDHGUI)_gl/g;s/@BITGUI@/$(BITGUI)_gl/g;s/@SURGUI@/$(SURGUI)_gl/g;s/@INLINEDISPLAYTLL@/$(INLINEDISPLAYTLL)/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ lv2ttl/$(LV2NAME).lv2.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl -$(BUILDDIR)$(LV2NAME)$(LIB_EXT): src/meters.cc $(DSPDEPS) src/ebulv2.cc src/uris.h src/goniometerlv2.c src/goniometer.h src/spectrumlv2.c src/spectr.c src/xfer.c src/dr14.c src/sigdistlv2.c src/bitmeter.c src/surmeter.c src/dpy_needle.c gui/meterimage.c Makefile +$(BUILDDIR)$(LV2NAME)$(LIB_EXT): src/meters.cc $(DSPDEPS) src/ebulv2.cc src/uris.h src/goniometerlv2.c src/goniometer.h src/spectrumlv2.c src/spectr.c src/xfer.c src/dr14.c src/sigdistlv2.c src/bitmeter.c src/surmeter.c src/dpy_needle.c src/dpy_bargraph.c gui/meterimage.c Makefile @mkdir -p $(BUILDDIR) $(CXX) $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) $(LIC_CFLAGS) \ -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) src/$(LV2NAME).cc $(DSPSRC) \ @@ -297,8 +300,8 @@ JACKCFLAGS=-I. $(CFLAGS) $(CXXFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` -JACKLIBS=-lm $(GLUILIBS) $(LIC_LOADLIBES) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) ## JACK applications @@ -337,7 +340,7 @@ $(APPBLD)x42-goniometer$(EXE_EXT): src/meters.cc $(DSPSRC) $(DSPDEPS) \ $(x42_goniometer_JACKGUI) $(x42_goniometer_LV2HTTL) -$(eval x42_phasewheel_JACKSRC = src/meters.cc $(DSPSRC) $(value FFTW)) +$(eval x42_phasewheel_JACKSRC = src/meters.cc $(DSPSRC) $(FFTW)) x42_phasewheel_JACKGUI = gui/phasewheel.c x42_phasewheel_LV2HTTL = lv2ttl/phasewheel.h x42_phasewheel_JACKDESC = lv2ui_phasewheel @@ -358,7 +361,7 @@ $(APPBLD)x42-spectrum30$(EXE_EXT): src/meters.cc $(DSPSRC) $(DSPDEPS) \ $(x42_spectrum30_JACKGUI) $(x42_spectrum30_LV2HTTL) -$(eval x42_stereoscope_JACKSRC = src/meters.cc $(DSPSRC) $(value FFTW)) +$(eval x42_stereoscope_JACKSRC = src/meters.cc $(DSPSRC) $(FFTW)) x42_stereoscope_JACKGUI = gui/stereoscope.c x42_stereoscope_LV2HTTL = lv2ttl/stereoscope.h x42_stereoscope_JACKDESC = lv2ui_stereoscope @@ -413,7 +416,7 @@ $(APPBLD)x42-stereoscope.o \ $(APPBLD)x42-truepeakrms.o -$(eval x42_meter_collection_JACKSRC = -DX42_MULTIPLUGIN src/meters.cc $(DSPSRC) $(COLLECTION_OBJS) $(value FFTW)) +$(eval x42_meter_collection_JACKSRC = -DX42_MULTIPLUGIN src/meters.cc $(DSPSRC) $(COLLECTION_OBJS) $(FFTW)) x42_meter_collection_LV2HTTL = lv2ttl/plugins.h $(APPBLD)x42-meter-collection$(EXE_EXT): src/meters.cc $(DSPSRC) $(DSPDEPS) $(COLLECTION_OBJS) \ lv2ttl/cor.h lv2ttl/dr14stereo.h lv2ttl/ebur128.h lv2ttl/goniometer.h \ diff -Nru x42-plugins-20170428/meters.lv2/README.md x42-plugins-20190714/meters.lv2/README.md --- x42-plugins-20170428/meters.lv2/README.md 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/README.md 2019-05-07 15:16:13.000000000 +0000 @@ -17,7 +17,7 @@ * Digital True-Peak Meter (4x Oversampling), Type II rise-time, 13.3dB/s falloff. * True-Peak (4x Oversampling) + RMS (600ms integration time) combined with numeric readout * K-12, K-14, K-20 / RMS type K-Meters according to the K-system introduced by Bob Katz -* DR14 (pleasurizemusic.com, specs by tischmeyer/algorithmix) +* DR-14 (crest factor / loudness range measurement method) and the following stereo plugins: @@ -90,7 +90,7 @@ ![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/LV2meters.png "Various Needle Meters in Ardour") ![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/spectr_and_goni.png "Spectrum Analyzer and Stereo Phase Scope") ![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/phasewheel.png "Phase/Frequency Wheel") -![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/dr14meter.png "DR14 Dynamic Range Meter (Pleasurize Music Foundation)") +![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/dr14meter.png "DR-14 Crest Factor Meter") ![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/stereoscope.png "Stereo/Frequency Scope") ![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/sigdisthist.png "Signal Distribution Histogram") ![screenshot](https://raw.github.com/x42/meters.lv2/master/doc/bitmeter.png "Bit Meter") diff -Nru x42-plugins-20170428/meters.lv2/src/dpy_bargraph.c x42-plugins-20190714/meters.lv2/src/dpy_bargraph.c --- x42-plugins-20170428/meters.lv2/src/dpy_bargraph.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/src/dpy_bargraph.c 2019-05-07 15:16:13.000000000 +0000 @@ -0,0 +1,151 @@ +#ifdef DISPLAY_INTERFACE + +#ifndef MIN +#define MIN(A,B) ((A) < (B)) ? (A) : (B) +#endif + +#ifndef MAX +#define MAX(A,B) ((A) > (B)) ? (A) : (B) +#endif + +#include "rtk/common.h" +//#include "rtk/style.h" + +static inline float kmeter_deflect (float db, float krange) { + db += krange; + if (db < -40.0f) { + return (db > -90.0f ? pow (10.0f, db * 0.05f) : 0.0f) * 500.0f / (krange + 45.0f); + } else { + const float rv = (db + 45.0f) / (krange + 45.0f); + return MIN (rv, 1.0); + } +} + + +#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; } +#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; } + +static void create_pattern (LV2meter* self, double w) { + + int clr[12]; + float stp[5]; + + stp[4] = kmeter_deflect ( 4 - self->kstandard, self->kstandard); + stp[3] = kmeter_deflect ( 3 - self->kstandard, self->kstandard); + stp[2] = kmeter_deflect ( 0 - self->kstandard, self->kstandard); + stp[1] = kmeter_deflect (-20 - self->kstandard, self->kstandard); + stp[0] = kmeter_deflect (-40 - self->kstandard, self->kstandard); + + clr[ 0]=0x003399ff; clr[ 1]=0x009933ff; + clr[ 2]=0x00aa00ff; clr[ 3]=0x00bb00ff; + clr[ 4]=0x00ff00ff; clr[ 5]=0x00ff00ff; + clr[ 6]=0xfff000ff; clr[ 7]=0xfff000ff; + clr[ 8]=0xff8000ff; clr[ 9]=0xff8000ff; + clr[10]=0xff0000ff; clr[11]=0xff0000ff; + + guint8 r,g,b,a; + const double onep = 1.0 / w; + + cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, w, 0); + + cairo_pattern_add_color_stop_rgb (pat, 1.0, .0, .0, .0); + + // top/clip + UINT_TO_RGBA (clr[11], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, 1.0 - onep, r/255.0, g/255.0, b/255.0); + + // -0dB + UINT_TO_RGBA (clr[10], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[4] + onep, r/255.0, g/255.0, b/255.0); + UINT_TO_RGBA (clr[9], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[4] - onep, r/255.0, g/255.0, b/255.0); + + // -3dB || -2dB + UINT_TO_RGBA (clr[8], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[3] + onep, r/255.0, g/255.0, b/255.0); + UINT_TO_RGBA (clr[7], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[3] - onep, r/255.0, g/255.0, b/255.0); + + // -9dB + UINT_TO_RGBA (clr[6], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[2] + onep, r/255.0, g/255.0, b/255.0); + UINT_TO_RGBA (clr[5], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[2] - onep, r/255.0, g/255.0, b/255.0); + + // -18dB + UINT_TO_RGBA (clr[4], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[1] + onep, r/255.0, g/255.0, b/255.0); + UINT_TO_RGBA (clr[3], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[1] - onep, r/255.0, g/255.0, b/255.0); + + // -40dB + UINT_TO_RGBA (clr[2], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[0] + onep, r/255.0, g/255.0, b/255.0); + UINT_TO_RGBA (clr[1], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, stp[0] - onep, r/255.0, g/255.0, b/255.0); + + // -inf + UINT_TO_RGBA (clr[0], &r, &g, &b, &a); + cairo_pattern_add_color_stop_rgb (pat, onep, r/255.0, g/255.0, b/255.0); + + //Bottom + cairo_pattern_add_color_stop_rgb (pat, 0.0, .0 , .0, .0); + + self->mpat= pat; +} + +static LV2_Inline_Display_Image_Surface * +bargraph_render (LV2_Handle instance, uint32_t w, uint32_t max_h) +{ +#ifdef WITH_SIGNATURE + if (!is_licensed (instance)) { return NULL; } +#endif + + LV2meter* self = (LV2meter*)instance; + + uint32_t h = MIN (MAX (8, ceilf (w * self->chn / 16.f)), max_h); + h &= ~1; + + if (!self->display || self->w != w || self->h != h) { + if (self->display) cairo_surface_destroy(self->display); + self->display = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + self->w = w; + self->h = h; + if (self->mpat) { + cairo_pattern_destroy (self->mpat); + self->mpat = NULL; + } + } + + if (!self->mpat) { + create_pattern (self, w); + } + + cairo_t* cr = cairo_create (self->display); + + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba (cr, .2, .2, .2, 1.0); + cairo_fill (cr); + + int ypc = h / self->chn; + + for (uint32_t c = 0; c < self->chn; ++c) { + float v = self->mval[c]; + v = v > .000031623f ? 20.0 * log10f(v) : -90.0; + v = w * kmeter_deflect (v, self->kstandard); + cairo_rectangle (cr, 1, c * ypc, v, ypc - 1); + cairo_set_source(cr, self->mpat); + cairo_fill (cr); + } + + cairo_destroy (cr); + + cairo_surface_flush (self->display); + self->surf.width = cairo_image_surface_get_width (self->display); + self->surf.height = cairo_image_surface_get_height (self->display); + self->surf.stride = cairo_image_surface_get_stride (self->display); + self->surf.data = cairo_image_surface_get_data (self->display); + + return &self->surf; +} +#endif diff -Nru x42-plugins-20170428/meters.lv2/src/meters.cc x42-plugins-20190714/meters.lv2/src/meters.cc --- x42-plugins-20170428/meters.lv2/src/meters.cc 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/src/meters.cc 2019-05-07 15:16:13.000000000 +0000 @@ -103,6 +103,7 @@ float* mprev; uint32_t chn; + int kstandard; float peak_max[2]; float peak_hold; @@ -155,6 +156,7 @@ LV2_Inline_Display_Image_Surface surf; cairo_surface_t* display; cairo_surface_t* face; + cairo_pattern_t* mpat; LV2_Inline_Display* queue_draw; uint32_t w, h; #endif @@ -162,9 +164,10 @@ } LV2meter; -#define MTRDEF(NAME, CLASS, TYPE) \ +#define MTRDEF(NAME, CLASS, TYPE, KM) \ else if (!strcmp(descriptor->URI, MTR_URI NAME "mono")) { \ self->chn = 1; \ + self->kstandard = KM; \ self->type = TYPE; \ self->mtr = (JmeterDSP **)malloc (self->chn * sizeof (JmeterDSP *)); \ self->mtr[0] = new CLASS(); \ @@ -172,6 +175,7 @@ } \ else if (!strcmp(descriptor->URI, MTR_URI NAME "stereo")) { \ self->chn = 2; \ + self->kstandard = KM; \ self->type = TYPE; \ self->mtr = (JmeterDSP **)malloc (self->chn * sizeof (JmeterDSP *)); \ self->mtr[0] = new CLASS(); \ @@ -203,15 +207,15 @@ self->bms[1] = new Msppmdsp(-6); self->bms[0]->init(rate); } - MTRDEF("VU", Vumeterdsp, MT_VU) - MTRDEF("BBC", Iec2ppmdsp, MT_BBC) - MTRDEF("EBU", Iec2ppmdsp, MT_EBU) - MTRDEF("DIN", Iec1ppmdsp, MT_DIN) - MTRDEF("NOR", Iec1ppmdsp, MT_NOR) - MTRDEF("dBTP", TruePeakdsp, MT_NONE) - MTRDEF("K12", Kmeterdsp, MT_NONE) - MTRDEF("K14", Kmeterdsp, MT_NONE) - MTRDEF("K20", Kmeterdsp, MT_NONE) + MTRDEF("VU", Vumeterdsp, MT_VU, 0) + MTRDEF("BBC", Iec2ppmdsp, MT_BBC, 0) + MTRDEF("EBU", Iec2ppmdsp, MT_EBU, 0) + MTRDEF("DIN", Iec1ppmdsp, MT_DIN, 0) + MTRDEF("NOR", Iec1ppmdsp, MT_NOR, 0) + MTRDEF("dBTP", TruePeakdsp, MT_NONE, 0) + MTRDEF("K12", Kmeterdsp, MT_NONE, 12) + MTRDEF("K14", Kmeterdsp, MT_NONE, 14) + MTRDEF("K20", Kmeterdsp, MT_NONE, 20) else { free(self); return NULL; @@ -390,6 +394,22 @@ *self->hold = self->peak_hold; } + +#ifdef DISPLAY_INTERFACE + for (uint32_t c = 0; c < self->chn; ++c) { + self->mval[c] = *self->level[c]; + // TODO: IFF difference >= 1/2 px at given self->w + if (self->mval[c] != self->mprev[c]) { + self->need_expose = true; + self->mprev[c] = self->mval[c]; + } + } + + if (self->need_expose && self->queue_draw) { + self->need_expose = false; + self->queue_draw->queue_draw (self->queue_draw->handle); + } +#endif } @@ -404,6 +424,7 @@ #ifdef DISPLAY_INTERFACE if (self->display) cairo_surface_destroy(self->display); if (self->face) cairo_surface_destroy(self->face); + if (self->mpat) cairo_pattern_destroy(self->mpat); #endif free (self->mtr); free(instance); @@ -518,6 +539,7 @@ #ifdef DISPLAY_INTERFACE if (self->display) cairo_surface_destroy(self->display); if (self->face) cairo_surface_destroy(self->face); + if (self->mpat) cairo_pattern_destroy(self->mpat); #endif free(instance); } @@ -568,6 +590,7 @@ #ifdef DISPLAY_INTERFACE if (self->display) cairo_surface_destroy(self->display); if (self->face) cairo_surface_destroy(self->face); + if (self->mpat) cairo_pattern_destroy(self->mpat); #endif free(instance); } @@ -594,7 +617,11 @@ return NULL; } +#ifdef DISPLAY_INTERFACE #include "dpy_needle.c" +#include "dpy_bargraph.c" +#endif + const void* extension_data_needle(const char* uri) { @@ -611,6 +638,23 @@ return extension_data (uri); } +const void* +extension_data_kmeter(const char* uri) +{ +#ifdef DISPLAY_INTERFACE + static const LV2_Inline_Display_Interface display = { bargraph_render }; + if (!strcmp(uri, LV2_INLINEDISPLAY__interface)) { +#if (defined _WIN32 && defined RTK_STATIC_INIT) + static int once = 0; + if (!once) {once = 1; gobject_init_ctor();} +#endif + return &display; + } +#endif + return extension_data (uri); +} + + //#ifdef DEBUG_SPECTR #include "spectr.c" @@ -649,12 +693,12 @@ mkdesc(14,"dBTPmono", dbtp_run, extension_data) mkdesc(15,"dBTPstereo", dbtp_run, extension_data) -mkdesc(K12M,"K12mono", kmeter_run, extension_data) -mkdesc(K14M,"K14mono", kmeter_run, extension_data) -mkdesc(K20M,"K20mono", kmeter_run, extension_data) -mkdesc(K12S,"K12stereo", kmeter_run, extension_data) -mkdesc(K14S,"K14stereo", kmeter_run, extension_data) -mkdesc(K20S,"K20stereo", kmeter_run, extension_data) +mkdesc(K12M,"K12mono", kmeter_run, extension_data_kmeter) +mkdesc(K14M,"K14mono", kmeter_run, extension_data_kmeter) +mkdesc(K20M,"K20mono", kmeter_run, extension_data_kmeter) +mkdesc(K12S,"K12stereo", kmeter_run, extension_data_kmeter) +mkdesc(K14S,"K14stereo", kmeter_run, extension_data_kmeter) +mkdesc(K20S,"K20stereo", kmeter_run, extension_data_kmeter) static const LV2_Descriptor descriptorCor = { MTR_URI "COR", diff -Nru x42-plugins-20170428/meters.lv2/src/spectr.c x42-plugins-20190714/meters.lv2/src/spectr.c --- x42-plugins-20170428/meters.lv2/src/spectr.c 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/src/spectr.c 2019-05-07 15:16:13.000000000 +0000 @@ -25,13 +25,22 @@ #include #include -#if __cplusplus >= 201103L || defined __APPLE__ +#if __cplusplus >= 201103L || ((defined __APPLE__ || defined __FreeBSD__) && defined __cplusplus) # include # define csqrt(XX) std::sqrt(XX) # define creal(XX) std::real(XX) # define cimag(XX) std::imag(XX) -//# define _I ((complex_t)(1i)) // broken with Apple LLVM version 6.1.0 (clang-602.0.53) -# define _I sqrt((complex_t)(-1)) // ridiculous ... whatever works + +# ifdef __cpp_lib_complex_udls + using namespace std::literals::complex_literals; +# endif + +# if defined __clang_major__ && __clang_major__ > 4 +# define _I (std::complex(0.0,1.0)) +# else +# define _I ((complex_t)(1i)) +# endif + typedef std::complex complex_t; #else # include @@ -112,7 +121,6 @@ rate * wu * .5 / M_PI); } if (wl < 1e-9) { - /* this is just for completeness, it cannot happen with spectr.lv2 */ wl = 1e-9; fprintf(stderr, "spectr.lv2: band f:%9.2fHz (%.2fHz -> %.2fHz) contains sub-bass frequencies\n", freq, freq-band/2, freq+band/2); diff -Nru x42-plugins-20170428/meters.lv2/src/surmeter.c x42-plugins-20190714/meters.lv2/src/surmeter.c --- x42-plugins-20170428/meters.lv2/src/surmeter.c 2017-04-27 23:57:51.000000000 +0000 +++ x42-plugins-20190714/meters.lv2/src/surmeter.c 2019-05-07 15:16:13.000000000 +0000 @@ -121,8 +121,6 @@ for (uint32_t c = 0; c < cors; ++c) { uint32_t in_a = rintf (*self->surc_a[c]); uint32_t in_b = rintf (*self->surc_b[c]); - if (in_a < 0) in_a = 0; - if (in_b < 0) in_b = 0; if (in_a >= self->chn) in_a = self->chn - 1; if (in_b >= self->chn) in_b = self->chn - 1; self->cor4[c]->process (self->input[in_a], self->input[in_b], n_samples); diff -Nru x42-plugins-20170428/mididebug.lv2/COPYING x42-plugins-20190714/mididebug.lv2/COPYING --- x42-plugins-20170428/mididebug.lv2/COPYING 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/COPYING 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -Nru x42-plugins-20170428/mididebug.lv2/git2lv2.mk x42-plugins-20190714/mididebug.lv2/git2lv2.mk --- x42-plugins-20170428/mididebug.lv2/git2lv2.mk 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/git2lv2.mk 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,43 @@ + +############################################################################### +# extract versions +GIT_REV_REGEXP="([0-9][0-9]*)\.([0-9][0-9]*)(\.([0-9][0-9]*))?(-([0-9][0-9]*))?(-g([a-f0-9]+))?" + +override MAJOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\1/) +override MINOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\2/) +override MICRO=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\4/) +override GITREV=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\6/) + +ifeq ($(MAJOR),) + override MAJOR=0 +endif +ifeq ($(MINOR),) + override MINOR=0 +endif +ifeq ($(MICRO),) + override MICRO=0 +endif + +$(info Version: $(LV2VERSION) -> $(MAJOR) $(MINOR) $(MICRO) $(GITREV)) + +# version requirements, see +# http://lv2plug.in/ns/lv2core/#minorVersion +# http://lv2plug.in/ns/lv2core/#microVersion +ifeq ($(GITREV),) +# even numbers for tagged releases + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 ) + override LV2MIC = 0 +else +# odd-numbers for all non tagged git versions + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 + 1 ) + override LV2MIC = $(shell expr $(GITREV) \* 2 + 1) +endif + +ifeq ($(LV2MIN),) + $(error "Cannot extract required LV2 minor-version parameter") +endif +ifeq ($(LV2MIC),) + $(error "Cannot extract required LV2 micro-version parameter") +endif + +$(info LV2 Version: $(LV2MIN) $(LV2MIC)) diff -Nru x42-plugins-20170428/mididebug.lv2/lv2ttl/manifest.modgui.in x42-plugins-20190714/mididebug.lv2/lv2ttl/manifest.modgui.in --- x42-plugins-20170428/mididebug.lv2/lv2ttl/manifest.modgui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/lv2ttl/manifest.modgui.in 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,17 @@ + + + modgui:gui [ + modgui:resourcesDirectory ; + modgui:iconTemplate ; + modgui:stylesheet ; + modgui:screenshot ; + modgui:thumbnail ; + modgui:javascript ; + modgui:brand "x42" ; + modgui:label "MIDI Debug" ; + modgui:port [ + lv2:index 0 ; + lv2:symbol "bytes" ; + lv2:name "Length" ; + ] ; + ] . diff -Nru x42-plugins-20170428/mididebug.lv2/lv2ttl/manifest.ttl.in x42-plugins-20190714/mididebug.lv2/lv2ttl/manifest.ttl.in --- x42-plugins-20170428/mididebug.lv2/lv2ttl/manifest.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/lv2ttl/manifest.ttl.in 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,8 @@ +@prefix lv2: . +@prefix modgui: . +@prefix rdfs: . + + + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/mididebug.lv2/lv2ttl/mididebug.ttl.in x42-plugins-20190714/mididebug.lv2/lv2ttl/mididebug.ttl.in --- x42-plugins-20170428/mididebug.lv2/lv2ttl/mididebug.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/lv2ttl/mididebug.ttl.in 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,218 @@ +@prefix atom: . +@prefix doap: . +@prefix foaf: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pprop: . +@prefix rdf: . +@prefix rdfs: . +@prefix units: . +@prefix urid: . + + + a foaf:Person; + foaf:name "Robin Gareus"; + foaf:mbox ; + foaf:homepage . + + + a lv2:Plugin, doap:Project, lv2:UtilityPlugin; + doap:license ; + doap:maintainer ; + doap:name "MIDI Event Generator"; + @VERSION@ + lv2:optionalFeature lv2:hardRTCapable; + lv2:requiredFeature urid:map; + rdfs:comment "A MIDI debug utility to generate arbitrary messages."; + + @MODBRAND@ + @MODLABEL@ + @SIGNATURE@ + + lv2:port [ + a atom:AtomPort, lv2:OutputPort; + atom:bufferType atom:Sequence; + atom:supports midi:MidiEvent; + lv2:index 0; + lv2:symbol "midiout"; + lv2:name "MIDI Out"; + ] , [ + a lv2:InputPort, lv2:ControlPort; + lv2:index 1; + lv2:symbol "bytes"; + lv2:name "Bytes to Send"; + lv2:minimum 0; + lv2:default 0; + lv2:maximum 3; + lv2:portProperty lv2:integer, lv2:enumeration; + lv2:scalePoint [ rdf:value 0 ; rdfs:label "Automatic"; ] ; + lv2:scalePoint [ rdf:value 1 ; rdfs:label "1 byte"; ] ; + lv2:scalePoint [ rdf:value 2 ; rdfs:label "2 bytes"; ] ; + lv2:scalePoint [ rdf:value 3 ; rdfs:label "3 bytes"; ] ; + ] , [ + a lv2:InputPort, lv2:ControlPort; + lv2:index 2; + lv2:symbol "b1"; + lv2:name "Byte 1"; + lv2:minimum 128; + lv2:default 176; + lv2:maximum 255; + lv2:portProperty lv2:integer, lv2:enumeration; + lv2:scalePoint [ rdf:value 128 ; rdfs:label "(0x80) Note Off C01"; ] ; + lv2:scalePoint [ rdf:value 129 ; rdfs:label "(0x81) Note Off C02"; ] ; + lv2:scalePoint [ rdf:value 130 ; rdfs:label "(0x82) Note Off C03"; ] ; + lv2:scalePoint [ rdf:value 131 ; rdfs:label "(0x83) Note Off C04"; ] ; + lv2:scalePoint [ rdf:value 132 ; rdfs:label "(0x84) Note Off C04"; ] ; + lv2:scalePoint [ rdf:value 133 ; rdfs:label "(0x85) Note Off C06"; ] ; + lv2:scalePoint [ rdf:value 134 ; rdfs:label "(0x86) Note Off C07"; ] ; + lv2:scalePoint [ rdf:value 135 ; rdfs:label "(0x87) Note Off C08"; ] ; + lv2:scalePoint [ rdf:value 136 ; rdfs:label "(0x88) Note Off C09"; ] ; + lv2:scalePoint [ rdf:value 137 ; rdfs:label "(0x89) Note Off C10"; ] ; + lv2:scalePoint [ rdf:value 138 ; rdfs:label "(0x8A) Note Off C11"; ] ; + lv2:scalePoint [ rdf:value 139 ; rdfs:label "(0x8B) Note Off C12"; ] ; + lv2:scalePoint [ rdf:value 140 ; rdfs:label "(0x8C) Note Off C13"; ] ; + lv2:scalePoint [ rdf:value 141 ; rdfs:label "(0x8D) Note Off C14"; ] ; + lv2:scalePoint [ rdf:value 142 ; rdfs:label "(0x8E) Note Off C15"; ] ; + lv2:scalePoint [ rdf:value 143 ; rdfs:label "(0x8F) Note Off C16"; ] ; + lv2:scalePoint [ rdf:value 144 ; rdfs:label "(0x90) Note On C01"; ] ; + lv2:scalePoint [ rdf:value 145 ; rdfs:label "(0x91) Note On C02"; ] ; + lv2:scalePoint [ rdf:value 146 ; rdfs:label "(0x92) Note On C03"; ] ; + lv2:scalePoint [ rdf:value 147 ; rdfs:label "(0x93) Note On C04"; ] ; + lv2:scalePoint [ rdf:value 148 ; rdfs:label "(0x94) Note On C04"; ] ; + lv2:scalePoint [ rdf:value 149 ; rdfs:label "(0x95) Note On C06"; ] ; + lv2:scalePoint [ rdf:value 150 ; rdfs:label "(0x96) Note On C07"; ] ; + lv2:scalePoint [ rdf:value 151 ; rdfs:label "(0x97) Note On C08"; ] ; + lv2:scalePoint [ rdf:value 152 ; rdfs:label "(0x98) Note On C09"; ] ; + lv2:scalePoint [ rdf:value 153 ; rdfs:label "(0x99) Note On C10"; ] ; + lv2:scalePoint [ rdf:value 154 ; rdfs:label "(0x9A) Note On C11"; ] ; + lv2:scalePoint [ rdf:value 155 ; rdfs:label "(0x9B) Note On C12"; ] ; + lv2:scalePoint [ rdf:value 156 ; rdfs:label "(0x9C) Note On C13"; ] ; + lv2:scalePoint [ rdf:value 157 ; rdfs:label "(0x9D) Note On C14"; ] ; + lv2:scalePoint [ rdf:value 158 ; rdfs:label "(0x9E) Note On C15"; ] ; + lv2:scalePoint [ rdf:value 159 ; rdfs:label "(0x9F) Note On C16"; ] ; + lv2:scalePoint [ rdf:value 160 ; rdfs:label "(0xA0) Poly. Aftertouch C01"; ] ; + lv2:scalePoint [ rdf:value 161 ; rdfs:label "(0xA1) Poly. Aftertouch C02"; ] ; + lv2:scalePoint [ rdf:value 162 ; rdfs:label "(0xA2) Poly. Aftertouch C03"; ] ; + lv2:scalePoint [ rdf:value 163 ; rdfs:label "(0xA3) Poly. Aftertouch C04"; ] ; + lv2:scalePoint [ rdf:value 164 ; rdfs:label "(0xA4) Poly. Aftertouch C04"; ] ; + lv2:scalePoint [ rdf:value 165 ; rdfs:label "(0xA5) Poly. Aftertouch C06"; ] ; + lv2:scalePoint [ rdf:value 166 ; rdfs:label "(0xA6) Poly. Aftertouch C07"; ] ; + lv2:scalePoint [ rdf:value 167 ; rdfs:label "(0xA7) Poly. Aftertouch C08"; ] ; + lv2:scalePoint [ rdf:value 168 ; rdfs:label "(0xA8) Poly. Aftertouch C09"; ] ; + lv2:scalePoint [ rdf:value 169 ; rdfs:label "(0xA9) Poly. Aftertouch C10"; ] ; + lv2:scalePoint [ rdf:value 170 ; rdfs:label "(0xAA) Poly. Aftertouch C11"; ] ; + lv2:scalePoint [ rdf:value 171 ; rdfs:label "(0xAB) Poly. Aftertouch C12"; ] ; + lv2:scalePoint [ rdf:value 172 ; rdfs:label "(0xAC) Poly. Aftertouch C13"; ] ; + lv2:scalePoint [ rdf:value 173 ; rdfs:label "(0xAD) Poly. Aftertouch C14"; ] ; + lv2:scalePoint [ rdf:value 174 ; rdfs:label "(0xAE) Poly. Aftertouch C15"; ] ; + lv2:scalePoint [ rdf:value 175 ; rdfs:label "(0xAF) Poly. Aftertouch C16"; ] ; + lv2:scalePoint [ rdf:value 176 ; rdfs:label "(0xB0) Control Change C01"; ] ; + lv2:scalePoint [ rdf:value 177 ; rdfs:label "(0xB1) Control Change C02"; ] ; + lv2:scalePoint [ rdf:value 178 ; rdfs:label "(0xB2) Control Change C03"; ] ; + lv2:scalePoint [ rdf:value 179 ; rdfs:label "(0xB3) Control Change C04"; ] ; + lv2:scalePoint [ rdf:value 180 ; rdfs:label "(0xB4) Control Change C04"; ] ; + lv2:scalePoint [ rdf:value 181 ; rdfs:label "(0xB5) Control Change C06"; ] ; + lv2:scalePoint [ rdf:value 182 ; rdfs:label "(0xB6) Control Change C07"; ] ; + lv2:scalePoint [ rdf:value 183 ; rdfs:label "(0xB7) Control Change C08"; ] ; + lv2:scalePoint [ rdf:value 184 ; rdfs:label "(0xB8) Control Change C09"; ] ; + lv2:scalePoint [ rdf:value 185 ; rdfs:label "(0xB9) Control Change C10"; ] ; + lv2:scalePoint [ rdf:value 186 ; rdfs:label "(0xBA) Control Change C11"; ] ; + lv2:scalePoint [ rdf:value 187 ; rdfs:label "(0xBB) Control Change C12"; ] ; + lv2:scalePoint [ rdf:value 188 ; rdfs:label "(0xBC) Control Change C13"; ] ; + lv2:scalePoint [ rdf:value 189 ; rdfs:label "(0xBD) Control Change C14"; ] ; + lv2:scalePoint [ rdf:value 190 ; rdfs:label "(0xBE) Control Change C15"; ] ; + lv2:scalePoint [ rdf:value 191 ; rdfs:label "(0xBF) Control Change C16"; ] ; + lv2:scalePoint [ rdf:value 192 ; rdfs:label "(0xC0) Program Change C01"; ] ; + lv2:scalePoint [ rdf:value 193 ; rdfs:label "(0xC1) Program Change C02"; ] ; + lv2:scalePoint [ rdf:value 194 ; rdfs:label "(0xC2) Program Change C03"; ] ; + lv2:scalePoint [ rdf:value 195 ; rdfs:label "(0xC3) Program Change C04"; ] ; + lv2:scalePoint [ rdf:value 196 ; rdfs:label "(0xC4) Program Change C04"; ] ; + lv2:scalePoint [ rdf:value 197 ; rdfs:label "(0xC5) Program Change C06"; ] ; + lv2:scalePoint [ rdf:value 198 ; rdfs:label "(0xC6) Program Change C07"; ] ; + lv2:scalePoint [ rdf:value 199 ; rdfs:label "(0xC7) Program Change C08"; ] ; + lv2:scalePoint [ rdf:value 200 ; rdfs:label "(0xC8) Program Change C09"; ] ; + lv2:scalePoint [ rdf:value 201 ; rdfs:label "(0xC9) Program Change C10"; ] ; + lv2:scalePoint [ rdf:value 202 ; rdfs:label "(0xCA) Program Change C11"; ] ; + lv2:scalePoint [ rdf:value 203 ; rdfs:label "(0xCB) Program Change C12"; ] ; + lv2:scalePoint [ rdf:value 204 ; rdfs:label "(0xCC) Program Change C13"; ] ; + lv2:scalePoint [ rdf:value 205 ; rdfs:label "(0xCD) Program Change C14"; ] ; + lv2:scalePoint [ rdf:value 206 ; rdfs:label "(0xCE) Program Change C15"; ] ; + lv2:scalePoint [ rdf:value 207 ; rdfs:label "(0xCF) Program Change C16"; ] ; + lv2:scalePoint [ rdf:value 208 ; rdfs:label "(0xD0) Chn. Aftertouch C01"; ] ; + lv2:scalePoint [ rdf:value 209 ; rdfs:label "(0xD1) Chn. Aftertouch C02"; ] ; + lv2:scalePoint [ rdf:value 210 ; rdfs:label "(0xD2) Chn. Aftertouch C03"; ] ; + lv2:scalePoint [ rdf:value 211 ; rdfs:label "(0xD3) Chn. Aftertouch C04"; ] ; + lv2:scalePoint [ rdf:value 212 ; rdfs:label "(0xD4) Chn. Aftertouch C04"; ] ; + lv2:scalePoint [ rdf:value 213 ; rdfs:label "(0xD5) Chn. Aftertouch C06"; ] ; + lv2:scalePoint [ rdf:value 214 ; rdfs:label "(0xD6) Chn. Aftertouch C07"; ] ; + lv2:scalePoint [ rdf:value 215 ; rdfs:label "(0xD7) Chn. Aftertouch C08"; ] ; + lv2:scalePoint [ rdf:value 216 ; rdfs:label "(0xD8) Chn. Aftertouch C09"; ] ; + lv2:scalePoint [ rdf:value 217 ; rdfs:label "(0xD9) Chn. Aftertouch C10"; ] ; + lv2:scalePoint [ rdf:value 218 ; rdfs:label "(0xDA) Chn. Aftertouch C11"; ] ; + lv2:scalePoint [ rdf:value 219 ; rdfs:label "(0xDB) Chn. Aftertouch C12"; ] ; + lv2:scalePoint [ rdf:value 220 ; rdfs:label "(0xDC) Chn. Aftertouch C13"; ] ; + lv2:scalePoint [ rdf:value 221 ; rdfs:label "(0xDD) Chn. Aftertouch C14"; ] ; + lv2:scalePoint [ rdf:value 222 ; rdfs:label "(0xDE) Chn. Aftertouch C15"; ] ; + lv2:scalePoint [ rdf:value 223 ; rdfs:label "(0xDF) Chn. Aftertouch C16"; ] ; + lv2:scalePoint [ rdf:value 224 ; rdfs:label "(0xE0) PitchBend C01"; ] ; + lv2:scalePoint [ rdf:value 225 ; rdfs:label "(0xE1) PitchBend C02"; ] ; + lv2:scalePoint [ rdf:value 226 ; rdfs:label "(0xE2) PitchBend C03"; ] ; + lv2:scalePoint [ rdf:value 227 ; rdfs:label "(0xE3) PitchBend C04"; ] ; + lv2:scalePoint [ rdf:value 228 ; rdfs:label "(0xE4) PitchBend C04"; ] ; + lv2:scalePoint [ rdf:value 229 ; rdfs:label "(0xE5) PitchBend C06"; ] ; + lv2:scalePoint [ rdf:value 230 ; rdfs:label "(0xE6) PitchBend C07"; ] ; + lv2:scalePoint [ rdf:value 231 ; rdfs:label "(0xE7) PitchBend C08"; ] ; + lv2:scalePoint [ rdf:value 232 ; rdfs:label "(0xE8) PitchBend C09"; ] ; + lv2:scalePoint [ rdf:value 233 ; rdfs:label "(0xE9) PitchBend C10"; ] ; + lv2:scalePoint [ rdf:value 234 ; rdfs:label "(0xEA) PitchBend C11"; ] ; + lv2:scalePoint [ rdf:value 235 ; rdfs:label "(0xEB) PitchBend C12"; ] ; + lv2:scalePoint [ rdf:value 236 ; rdfs:label "(0xEC) PitchBend C13"; ] ; + lv2:scalePoint [ rdf:value 237 ; rdfs:label "(0xED) PitchBend C14"; ] ; + lv2:scalePoint [ rdf:value 238 ; rdfs:label "(0xEE) PitchBend C15"; ] ; + lv2:scalePoint [ rdf:value 239 ; rdfs:label "(0xEF) PitchBend C16"; ] ; + lv2:scalePoint [ rdf:value 240 ; rdfs:label "(0xF0) N/A - SysEx"; ] ; + lv2:scalePoint [ rdf:value 241 ; rdfs:label "(0xF1) N/A - MTC QFrame"; ] ; + lv2:scalePoint [ rdf:value 242 ; rdfs:label "(0xF2) Song Position"; ] ; + lv2:scalePoint [ rdf:value 243 ; rdfs:label "(0xF3) Song Select"; ] ; + lv2:scalePoint [ rdf:value 244 ; rdfs:label "(0xF4) Undefined - Reserved"; ] ; + lv2:scalePoint [ rdf:value 245 ; rdfs:label "(0xF5) Undefined - Reserved"; ] ; + lv2:scalePoint [ rdf:value 246 ; rdfs:label "(0xF6) Tune request"; ] ; + lv2:scalePoint [ rdf:value 247 ; rdfs:label "(0xF7) End of SysEx [EOX]"; ] ; + lv2:scalePoint [ rdf:value 248 ; rdfs:label "(0xF8) Timing clock"; ] ; + lv2:scalePoint [ rdf:value 249 ; rdfs:label "(0xF9) Undefined - Reserved"; ] ; + lv2:scalePoint [ rdf:value 250 ; rdfs:label "(0xFA) MClk Start"; ] ; + lv2:scalePoint [ rdf:value 251 ; rdfs:label "(0xFB) MClk Stop"; ] ; + lv2:scalePoint [ rdf:value 252 ; rdfs:label "(0xFC) MClk Continue"; ] ; + lv2:scalePoint [ rdf:value 253 ; rdfs:label "(0xFD) Undefined - Reserved"; ] ; + lv2:scalePoint [ rdf:value 254 ; rdfs:label "(0xFE) Active Sensing"; ] ; + lv2:scalePoint [ rdf:value 255 ; rdfs:label "(0xFF) System Reset"; ] ; + ] , [ + a lv2:InputPort, lv2:ControlPort; + lv2:index 3; + lv2:symbol "b2"; + lv2:name "Byte 2"; + lv2:minimum 0; + lv2:default 0; + lv2:maximum 127; + lv2:portProperty lv2:integer; + ] , [ + a lv2:InputPort, lv2:ControlPort; + lv2:index 4; + lv2:symbol "b3"; + lv2:name "Byte 3"; + lv2:minimum 0; + lv2:default 0; + lv2:maximum 127; + lv2:portProperty lv2:integer; + ] , [ + a lv2:InputPort, lv2:ControlPort; + lv2:index 5; + lv2:symbol "trigger"; + lv2:name "Send"; + lv2:minimum 0; + lv2:default 0; + lv2:maximum 1; + lv2:portProperty lv2:integer, lv2:toggled, pprop:trigger; + ] + . diff -Nru x42-plugins-20170428/mididebug.lv2/Makefile x42-plugins-20190714/mididebug.lv2/Makefile --- x42-plugins-20170428/mididebug.lv2/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/Makefile 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,135 @@ +#!/usr/bin/make -f + +# these can be overridden using make variables. e.g. +# make CFLAGS=-O2 +# make install DESTDIR=$(CURDIR)/debian/mididebug.lv2 PREFIX=/usr +# +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +PREFIX ?= /usr/local +CFLAGS ?= $(OPTIMIZATIONS) -Wall +LIBDIR ?= lib + +STRIP?=strip +STRIPFLAGS?=-s + +mididebug_VERSION?=$(shell git describe --tags HEAD 2>/dev/null | sed 's/-g.*$$//;s/^v//' || echo "LV2") +############################################################################### +LIB_EXT=.so + +LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LOADLIBES=-lm +LV2NAME=mididebug +BUNDLE=mididebug.lv2 +BUILDDIR=build/ +targets= + +UNAME=$(shell uname) +ifeq ($(UNAME),Darwin) + LV2LDFLAGS=-dynamiclib + LIB_EXT=.dylib + EXTENDED_RE=-E + STRIPFLAGS=-u -r -arch all -s lv2syms + targets+=lv2syms +else + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic + LIB_EXT=.so + EXTENDED_RE=-r +endif + +ifneq ($(XWIN),) + CC=$(XWIN)-gcc + STRIP=$(XWIN)-strip + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.dll + override LDFLAGS += -static-libgcc -static-libstdc++ +endif + +targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +ifneq ($(MOD),) + targets+=$(BUILDDIR)modgui + MODLABEL=mod:label \"MIDI Debug\"; + MODBRAND=mod:brand \"x42\"; +else + MODLABEL= + MODBRAND= +endif + +############################################################################### +# extract versions +LV2VERSION=$(mididebug_VERSION) +include git2lv2.mk + +# check for build-dependencies +ifeq ($(shell pkg-config --exists lv2 || echo no), no) + $(error "LV2 SDK was not found") +endif + +# check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank +ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) + override CFLAGS += -DHAVE_LV2_1_8 +endif + +override CFLAGS += -fPIC -std=c99 +override CFLAGS += `pkg-config --cflags lv2` + +# build target definitions +default: all + +all: $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets) + +lv2syms: + echo "_lv2_descriptor" > lv2syms + +$(BUILDDIR)manifest.ttl: lv2ttl/manifest.ttl.in + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/;s/@LIB_EXT@/$(LIB_EXT)/" \ + lv2ttl/manifest.ttl.in > $(BUILDDIR)manifest.ttl +ifneq ($(MOD),) + sed "s/@LV2NAME@/$(LV2NAME)/" \ + lv2ttl/manifest.modgui.in >> $(BUILDDIR)manifest.ttl +endif + +$(BUILDDIR)$(LV2NAME).ttl: lv2ttl/$(LV2NAME).ttl.in + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/;s/@SIGNATURE@//;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/" \ + lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl + +$(BUILDDIR)$(LV2NAME)$(LIB_EXT): src/$(LV2NAME).c + @mkdir -p $(BUILDDIR) + $(CC) $(CPPFLAGS) $(CFLAGS) \ + -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) src/$(LV2NAME).c \ + -shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES) + $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +$(BUILDDIR)modgui: modgui/ + @mkdir -p $(BUILDDIR)/modgui + cp -r modgui/* $(BUILDDIR)modgui/ + +# install/uninstall/clean target definitions + +install: all + install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m755 $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m644 $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE) +ifneq ($(MOD),) + install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE)/modgui + install -t $(DESTDIR)$(LV2DIR)/$(BUNDLE)/modgui $(BUILDDIR)modgui/* +endif + +uninstall: + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/manifest.ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME).ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME)$(LIB_EXT) + rm -rf $(DESTDIR)$(LV2DIR)/$(BUNDLE)/modgui + -rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE) + +clean: + rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(BUILDDIR)$(LV2NAME)$(LIB_EXT) lv2syms + rm -rf $(BUILDDIR)modgui + -test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true + +distclean: clean + rm -f cscope.out cscope.files tags + +.PHONY: clean all install uninstall distclean Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/box.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/box.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/dropdown-arrow-white.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/dropdown-arrow-white.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/footswitch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/footswitch.png differ diff -Nru x42-plugins-20170428/mididebug.lv2/modgui/icon-mididebug.html x42-plugins-20190714/mididebug.lv2/modgui/icon-mididebug.html --- x42-plugins-20170428/mididebug.lv2/modgui/icon-mididebug.html 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/modgui/icon-mididebug.html 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,58 @@ +
+
+ +

x42

+

MIDI Debug

+ +
+ {{#controls.0}} +
+
+
+ {{#scalePoints}} +
{{label}}
+ {{/scalePoints}} +
+
+ {{/controls.0}} +
+ +
+
+ Status Byte +
+
+
+
+
+ Data 1 +
+
+
+ Data 2 +
+
+
+ +
+
+
+ Send +
+
+ +
+ {{#effect.ports.midi.input}} +
+
+
+ {{/effect.ports.midi.input}} +
+
+ {{#effect.ports.midi.output}} +
+
+
+ {{/effect.ports.midi.output}} +
+
Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/midi_7f.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/midi_7f.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/midi_ff.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/midi_ff.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/screenshot-mididebug.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/screenshot-mididebug.png differ diff -Nru x42-plugins-20170428/mididebug.lv2/modgui/script-mididebug.js x42-plugins-20190714/mididebug.lv2/modgui/script-mididebug.js --- x42-plugins-20170428/mididebug.lv2/modgui/script-mididebug.js 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/modgui/script-mididebug.js 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,31 @@ +function (event) { + + function hideshowbytes (bytes) { + var b2 = event.icon.find ('[mod-gui-role=byte2]'); + var b3 = event.icon.find ('[mod-gui-role=byte3]'); + if (bytes == 1) { + b2.css('display', 'none'); + b3.css('display', 'none'); + } else if (bytes == 2) { + b2.css('display', 'inline-block'); + b3.css('display', 'none'); + } else { + b2.css('display', 'inline-block'); + b3.css('display', 'inline-block'); + } + } + + if (event.type == 'start') { + var ports = event.ports; + for (var p in ports) { + if (ports[p].symbol == 'bytes') { + hideshowbytes (event.value); + } + } + } + else if (event.type == 'change') { + if (event.symbol == 'bytes') { + hideshowbytes (event.value); + } + } +} diff -Nru x42-plugins-20170428/mididebug.lv2/modgui/stylesheet-mididebug.css x42-plugins-20190714/mididebug.lv2/modgui/stylesheet-mididebug.css --- x42-plugins-20170428/mididebug.lv2/modgui/stylesheet-mididebug.css 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/modgui/stylesheet-mididebug.css 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,202 @@ +@import url(/fonts/nexa/stylesheet.css); +@import url(/fonts/questrial/stylesheet.css); + +/* = CONTAINER +================================================ */ +.x42-mdbg{{{cns}}} { + background-image:url(/resources/box.png{{{ns}}}); + background-position:center center; + background-repeat:no-repeat; + background-size:230px 431px; + height:431px; + position:absolute; + width:230px; + border-radius: 21px; + + line-height:1.429; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + + border-color:white; + color:white; +} + +/* = Labels +================================================ */ +.x42-mdbg{{{cns}}} .x42-brand { + left:0; + position:absolute; + right:0; + text-align:center; + top:212px; +} + +.x42-mdbg{{{cns}}} .x42-brand h1 { + border-radius:12px; + border-style:solid; + border-width:4px; + display:inline-block; + font-family:"Nexa"; + font-size:32px; + padding:3px 9px 0; +} + +.x42-mdbg{{{cns}}} .x42-plugin-name { + left:30px; + overflow:hidden; + position:absolute; + right:30px; + text-align:center; + bottom:35px; +} + +.x42-mdbg{{{cns}}} .x42-plugin-name h1 { + font-family:"Questrial"; + font-size:21px; + line-height:1; +} + +/* = LIGHT ON/OFF +================================================ */ +.x42-mdbg{{{cns}}} .mod-light { + background-position:center center; + background-repeat:no-repeat; + height:32px; + left:10px; + position:absolute; + right:10px; + top:235px; +} + +/* = KNOBS +================================================ */ +.x42-mdbg{{{cns}}} .mod-control-group { + margin:10px !important; + position:relative; + text-align:center; + z-index:30; +} + +.x42-mdbg{{{cns}}} .mod-control-group .mod-knob { + overflow:hidden; + position:relative; + display:inline-block; + height:64px; + margin: 0 14px; +} + +.x42-mdbg{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { + bottom:0px; + display:block; + font-size:11px; + font-weight:bold; + height:12px; + left:0; + line-height:1; + margin:0; + overflow:hidden; + padding:0; + position:absolute; + right:0; + text-transform:uppercase; +} + +.x42-mdbg{{{cns}}} .mod-control-group .mod-knob .mod-knob-ff-image { + background-image:url(/resources/midi_ff.png{{{ns}}}); + background-repeat:no-repeat; + background-size:auto 42px; + background-color:#222; + box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; + height:42px; + width:48px; + margin:0 auto; +} + +.x42-mdbg{{{cns}}} .mod-control-group .mod-knob .mod-knob-7f-image { + background-image:url(/resources/midi_7f.png{{{ns}}}); + background-repeat:no-repeat; + background-size:auto 42px; + background-color:#222; + box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; + height:42px; + width:48px; + margin:0 auto; +} + +.x42-mdbg{{{cns}}} .bottom-group { + margin:10px auto 0 auto; + left:10px; + right:10px; + position:absolute; + bottom:70px; +} + +/* = Push Buttons +================================================ */ +.x42-mdbg{{{cns}}} .mod-pushbutton { + background-image:url(/resources/footswitch.png{{{ns}}}); + background-position:top center; + background-repeat:no-repeat; + background-size:auto 88px; + cursor:pointer; + height:44px; + margin: 4px auto 0 auto; + width: 44px; +} + +.x42-mdbg{{{cns}}} .mod-pushbutton.on { + background-position: bottom center !important; +} + + +/* = ENUMERATED LIST +================================================ */ +.x42-mdbg{{{cns}}} .mod-enumerated-group { + height:31px; + margin:20px auto 0 !important; + position:relative; + width:190px; + z-index:35; +} + +.x42-mdbg{{{cns}}} .mod-enumerated { + background-image:url(/resources/dropdown-arrow-white.png{{{ns}}}); + background-position:right center; + background-repeat:no-repeat; + font-size:11px; + font-weight:bold; + left:0; + line-height:2; + overflow:hidden; + position:absolute; + right:0; + text-align:center; +} + +.x42-mdbg{{{cns}}} .mod-enumerated .mod-enumerated-selected { + background-color:rgba(0,0,0,.3); + box-shadow:inset 0 0 4px rgba(0,0,0,.3); + border-radius:4px; + padding:3px 9px; + border-radius:4px 4px 0 0; +} + +.x42-mdbg{{{cns}}} .mod-enumerated .mod-enumerated-list { + background-color:rgba(0,0,0,.9); + color:#fff; + display:none; + height:115px; + overflow:auto; + position:relative; +} + +.x42-mdbg{{{cns}}} .mod-enumerated .mod-enumerated-list > div { + padding:3px 9px; +} + +.x42-mdbg{{{cns}}} .mod-enumerated .mod-enumerated-list > div:hover { + background-color:rgba(255,255,255,.2); + cursor:pointer; +} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/mididebug.lv2/modgui/thumbnail-mididebug.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/mididebug.lv2/modgui/thumbnail-mididebug.png differ diff -Nru x42-plugins-20170428/mididebug.lv2/README.md x42-plugins-20190714/mididebug.lv2/README.md --- x42-plugins-20170428/mididebug.lv2/README.md 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/README.md 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,20 @@ +mididebug.lv2 - MIDI Message Generator +====================================== + +mididebug.lv2 is an instrumention tool to generate arbitrary MIDI +messages up to 3 bytes in length. It's mainly intented for +http://moddevices.com/ but works in any LV2 plugin-host. + +Install +------- + +Compiling mididebug.lv2 requires the LV2 SDK, gnu-make, and a c-compiler. + +```bash + git clone git://github.com/x42/mididebug.lv2.git + cd mididebug.lv2 + make + sudo make install PREFIX=/usr +``` + +To build the the MOD GUI use `make MOD=1` diff -Nru x42-plugins-20170428/mididebug.lv2/src/mididebug.c x42-plugins-20190714/mididebug.lv2/src/mididebug.c --- x42-plugins-20170428/mididebug.lv2/src/mididebug.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/mididebug.lv2/src/mididebug.c 2019-07-11 19:35:45.000000000 +0000 @@ -0,0 +1,261 @@ +/* midi event generator + * + * Copyright (C) 2016 Robin Gareus + * + * 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, 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, see . + */ + +#define _GNU_SOURCE + +#define MDEBUG_URI "http://gareus.org/oss/lv2/mididebug" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "lv2/lv2plug.in/ns/ext/time/time.h" +#include + +typedef struct { + /* ports */ + LV2_Atom_Sequence* midiout; + float* p_nbytes; + float* p_b[3]; + float* p_trigger; + + /* Cached Ports */ + bool c_trigger; + + /* atom-forge and URI mapping */ + LV2_Atom_Forge forge; + LV2_Atom_Forge_Frame frame; + LV2_URID midi_MidiEvent; + + /* LV2 Output */ + LV2_Log_Log* log; + LV2_Log_Logger logger; + +} MDebug; + +/** + * add a midi message to the output port + */ +static void +forge_midimessage (MDebug* self, + uint32_t tme, + const uint8_t* const buffer, + uint32_t size) +{ + LV2_Atom midiatom; + midiatom.type = self->midi_MidiEvent; + midiatom.size = size; + + if (0 == lv2_atom_forge_frame_time (&self->forge, tme)) return; + if (0 == lv2_atom_forge_raw (&self->forge, &midiatom, sizeof (LV2_Atom))) return; + if (0 == lv2_atom_forge_raw (&self->forge, buffer, size)) return; + lv2_atom_forge_pad (&self->forge, sizeof (LV2_Atom) + size); +} + +/* ***************************************************************************** + * LV2 Plugin + */ + +static LV2_Handle +instantiate (const LV2_Descriptor* descriptor, + double rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + MDebug* self = (MDebug*)calloc (1, sizeof (MDebug)); + LV2_URID_Map* map = NULL; + + int i; + for (i=0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp (features[i]->URI, LV2_LOG__log)) { + self->log = (LV2_Log_Log*)features[i]->data; + } + } + + lv2_log_logger_init (&self->logger, map, self->log); + + if (!map) { + lv2_log_error (&self->logger, "MDebug.lv2 error: Host does not support urid:map\n"); + free (self); + return NULL; + } + + lv2_atom_forge_init (&self->forge, map); + self->midi_MidiEvent = map->map (map->handle, LV2_MIDI__MidiEvent); + + return (LV2_Handle)self; +} + +static void +connect_port (LV2_Handle instance, + uint32_t port, + void* data) +{ + MDebug* self = (MDebug*)instance; + + switch (port) { + case 0: + self->midiout = (LV2_Atom_Sequence*)data; + break; + case 1: + self->p_nbytes = (float*)data; + break; + case 2: + self->p_b[0] = (float*)data; + break; + case 3: + self->p_b[1] = (float*)data; + break; + case 4: + self->p_b[2] = (float*)data; + break; + case 5: + self->p_trigger = (float*)data; + break; + default: + break; + } +} + + +static void +run (LV2_Handle instance, uint32_t n_samples) +{ + MDebug* self = (MDebug*)instance; + if (!self->midiout) { + return; + } + + /* initialize output port */ + const uint32_t capacity = self->midiout->atom.size; + lv2_atom_forge_set_buffer (&self->forge, (uint8_t*)self->midiout, capacity); + lv2_atom_forge_sequence_head (&self->forge, &self->frame, 0); + + if (*self->p_trigger > 0 && !self->c_trigger) { + uint32_t nb = *self->p_nbytes; + uint8_t b[3]; + b[0] = (int)rint (*self->p_b[0]) & 0xff; + b[1] = (int)rint (*self->p_b[1]) & 0x7f; + b[2] = (int)rint (*self->p_b[2]) & 0x7f; + b[0] |= 0x80; + if (nb > 3) nb = 3; + if (nb < 1) { + switch (b[0] >> 4) { + case 0x8: // Note Off + case 0x9: // Note On + case 0xa: // Key Aftertouch + case 0xb: // CC + case 0xe: // PitchBend + nb = 3; + break; + case 0xc: // PGM + case 0xd: // Chan Aftertouch + nb = 2; + break; + case 0xf: // System + switch (b[0] & 0xf) { + case 0x0: // SysEx Start + case 0x1: // MTC QFrame + case 0x4: // Reserved + case 0x5: // Reserved + case 0x9: // Reserved + case 0xd: // Reserved + nb = 0; //< N/A + break; + case 0x6: // Tune request + case 0x7: // End of SysEx (EOX) + case 0xa: // MClk: Start + case 0xb: // MClk: Stop + case 0xc: // MClk: Continue + case 0xe: // Active Sensing + case 0xf: // System Reset + nb = 1; + break; + case 0x3: // Song Select + nb = 2; + break; + case 0x2: // Song Position Pointer + nb = 3; + break; + default: /* cannot happen */ + nb = 0; + break; + } + break; + default: /* cannot happen */ + nb = 0; + break; + } + } + + if (nb > 0) { + forge_midimessage (self, 0, b, nb); + } + } + self->c_trigger = *self->p_trigger > 0; +} + +static void +cleanup (LV2_Handle instance) +{ + free (instance); +} + +static const void* +extension_data (const char* uri) +{ + return NULL; +} + +static const LV2_Descriptor descriptor = { + MDEBUG_URI, + instantiate, + connect_port, + NULL, + run, + NULL, + cleanup, + extension_data +}; + +#undef LV2_SYMBOL_EXPORT +#ifdef _WIN32 +# define LV2_SYMBOL_EXPORT __declspec(dllexport) +#else +# define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default"))) +#endif +LV2_SYMBOL_EXPORT +const LV2_Descriptor* +lv2_descriptor (uint32_t index) +{ + switch (index) { + case 0: + return &descriptor; + default: + return NULL; + } +} diff -Nru x42-plugins-20170428/midifilter.lv2/filters/keysplit.c x42-plugins-20190714/midifilter.lv2/filters/keysplit.c --- x42-plugins-20170428/midifilter.lv2/filters/keysplit.c 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/filters/keysplit.c 2019-06-23 14:34:51.000000000 +0000 @@ -40,7 +40,7 @@ uint8_t mst = buffer[0] & 0xf0; if (size != 3 - || !(mst == MIDI_NOTEON || mst == MIDI_NOTEOFF || mst == MIDI_POLYKEYPRESSURE) + || !(mst == MIDI_NOTEON || mst == MIDI_NOTEOFF || mst == MIDI_POLYKEYPRESSURE || mst == MIDI_CONTROLCHANGE) || !(floor(*self->cfg[0]) == 0 || chs == chn) ) { @@ -96,6 +96,14 @@ buf[1] = midi_limit_val(key + transp1); } break; + case MIDI_CONTROLCHANGE: + buf[1] = buffer[1]; + if (ch0 != ch1) { + buf[0] = mst | ch0; + forge_midimessage(self, tme, buf, size); + } + buf[0] = mst | ch1; + break; } forge_midimessage(self, tme, buf, size); } diff -Nru x42-plugins-20170428/midifilter.lv2/filters/midistrum.c x42-plugins-20190714/midifilter.lv2/filters/midistrum.c --- x42-plugins-20170428/midifilter.lv2/filters/midistrum.c 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/filters/midistrum.c 2019-06-23 14:34:51.000000000 +0000 @@ -54,6 +54,37 @@ } static void +filter_midistrum_enqueue(MidiFilter* self, uint8_t const* buf, int size, int tme) +{ + const int max_delay = self->memI[0]; + const int roff = self->memI[1]; + const int woff = self->memI[2]; + + if ((woff + 1) % max_delay == roff) { + return; // queue full + } + + MidiEventQueue* qm = &(self->memQ[roff]); + + for (int idx = woff; idx != roff;) { + /* move existing (later) events forward in the queue */ + const int pidx = (idx > 0) ? (idx - 1) : (max_delay - 1); + memcpy (&(self->memQ[idx]), &(self->memQ[pidx]), sizeof (MidiEventQueue)); + + if (self->memQ[idx].size != 0 && self->memQ[idx].reltime <= tme) { + qm = &(self->memQ[idx]); + break; + } + idx = pidx; + } + + memcpy(qm->buf, buf, size); + qm->size = size; + qm->reltime = tme; + self->memI[2] = (self->memI[2] + 1) % max_delay; +} + +static void filter_midistrum_process(MidiFilter* self, int tme) { int i; @@ -68,7 +99,6 @@ } } - float bpm = (*self->cfg[1]); if (*self->cfg[0] && (self->available_info & NFO_BPM)) { bpm = self->bpm; @@ -109,7 +139,6 @@ int reltime = MSC_DIFF(self->memI[4], self->memI[3]); int tdiff = strum_time / self->memI[5]; - float spdcfg = -(*self->cfg[5]); float velcfg = (*self->cfg[6]) / -112.0; @@ -156,11 +185,9 @@ sfact = sfact ==0 ? 0 : 1.0 / sqrt(sfact); } - MidiEventQueue *qm = &(self->memQ[self->memI[2]]); - memcpy(qm->buf, self->memS[nextup].buf, self->memS[nextup].size); - qm->size = self->memS[nextup].size; - qm->reltime = reltime + rint((float)(tdiff * i) * sfact); - self->memI[2] = (self->memI[2] + 1) % self->memI[0]; + filter_midistrum_enqueue (self, self->memS[nextup].buf, self->memS[nextup].size, + reltime + rint((float)(tdiff * i) * sfact)); + self->memS[nextup].size = 0; // mark as processed } @@ -202,6 +229,12 @@ uint8_t mst = buffer[0] & 0xf0; if (size > 3) { + /* This may result in out-of-order messages (!) + * + * However messages > 3 bytes (sysex) are not commonly sent to softsynths. + * Furthermore, LV2 requires normalized MIDI (no running status), + * so this should be safe. + */ forge_midimessage(self, tme, buffer, size); return; } @@ -211,14 +244,7 @@ } if (size != 3 || !(mst == MIDI_NOTEON || mst == MIDI_NOTEOFF)) { - if ((self->memI[2] + 1) % self->memI[0] == self->memI[1]) { - return; // queue full - } - MidiEventQueue *qm = &(self->memQ[self->memI[2]]); - memcpy(qm->buf, buffer, size); - qm->size = size; - qm->reltime = tme; - self->memI[2] = (self->memI[2] + 1) % self->memI[0]; + filter_midistrum_enqueue (self, buffer, size, tme); return; } @@ -282,11 +308,7 @@ const int delay = strum_time + max_collect; #endif // TODO filter out ignored dups from (ignored note-on) above - MidiEventQueue *qm = &(self->memQ[self->memI[2]]); - memcpy(qm->buf, buffer, size); - qm->size = size; - qm->reltime = tme + delay; - self->memI[2] = (self->memI[2] + 1) % self->memI[0]; + filter_midistrum_enqueue(self, buffer, size, tme + delay); } } @@ -299,7 +321,6 @@ static void filter_postproc_midistrum(MidiFilter* self) { - int i; const int max_delay = self->memI[0]; const int roff = self->memI[1]; const int woff = self->memI[2]; @@ -308,45 +329,54 @@ filter_midistrum_process(self, n_samples); - for (i=0; i < max_delay; ++i) { + for (int i = 0; i < max_delay; ++i) { const int off = (i + roff) % max_delay; - if (self->memQ[off].size > 0) { - if (self->memQ[off].reltime < n_samples) { - if (self->memQ[off].size == 3 && (self->memQ[off].buf[0] & 0xf0) == MIDI_NOTEON) { - const uint8_t chn = self->memQ[off].buf[0] & 0x0f; - const uint8_t key = self->memQ[off].buf[1] & 0x7f; - self->memCS[chn][key]++; - if (self->memCS[chn][key] > 1) { // send a note-off first - uint8_t buf[3]; - buf[0] = MIDI_NOTEOFF | chn; - buf[1] = key; buf[2] = 0; - forge_midimessage(self, self->memQ[off].reltime, buf, 3); - } - forge_midimessage(self, self->memQ[off].reltime, self->memQ[off].buf, self->memQ[off].size); - } - else if (self->memQ[off].size == 3 && (self->memQ[off].buf[0] & 0xf0) == MIDI_NOTEOFF) { - const uint8_t chn = self->memQ[off].buf[0] & 0x0f; - const uint8_t key = self->memQ[off].buf[1] & 0x7f; - if (self->memCS[chn][key] > 0) { - self->memCS[chn][key]--; - if (self->memCS[chn][key] == 0) { - forge_midimessage(self, self->memQ[off].reltime, self->memQ[off].buf, self->memQ[off].size); - } - } - } else { + if (off == woff) { + if (!skipped) { self->memI[1] = off; } + break; + } + + if (self->memQ[off].size == 0) { + if (!skipped) { self->memI[1] = off; } + continue; + } + + if (self->memQ[off].reltime >= n_samples) { + self->memQ[off].reltime -= n_samples; + skipped = 1; + continue; + } + + assert (!skipped); + + if (self->memQ[off].size == 3 && (self->memQ[off].buf[0] & 0xf0) == MIDI_NOTEON) { + const uint8_t chn = self->memQ[off].buf[0] & 0x0f; + const uint8_t key = self->memQ[off].buf[1] & 0x7f; + self->memCS[chn][key]++; + if (self->memCS[chn][key] > 1) { // send a note-off first + uint8_t buf[3]; + buf[0] = MIDI_NOTEOFF | chn; + buf[1] = key; buf[2] = 0; + forge_midimessage(self, self->memQ[off].reltime, buf, 3); + } + forge_midimessage(self, self->memQ[off].reltime, self->memQ[off].buf, self->memQ[off].size); + } + else if (self->memQ[off].size == 3 && (self->memQ[off].buf[0] & 0xf0) == MIDI_NOTEOFF) { + const uint8_t chn = self->memQ[off].buf[0] & 0x0f; + const uint8_t key = self->memQ[off].buf[1] & 0x7f; + if (self->memCS[chn][key] > 0) { + self->memCS[chn][key]--; + if (self->memCS[chn][key] == 0) { forge_midimessage(self, self->memQ[off].reltime, self->memQ[off].buf, self->memQ[off].size); } - - self->memQ[off].size = 0; - if (!skipped) self->memI[1] = (self->memI[1] + 1) % max_delay; - } else { - self->memQ[off].reltime -= n_samples; - skipped = 1; } - } else if (!skipped) self->memI[1] = off; + } else { + forge_midimessage(self, self->memQ[off].reltime, self->memQ[off].buf, self->memQ[off].size); + } - if (off == woff) break; + self->memQ[off].size = 0; + self->memI[1] = off; } self->memI[3] = (self->memI[3] + n_samples)%MSC_MAX; diff -Nru x42-plugins-20170428/midifilter.lv2/filters/sostenuto.c x42-plugins-20190714/midifilter.lv2/filters/sostenuto.c --- x42-plugins-20170428/midifilter.lv2/filters/sostenuto.c 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/filters/sostenuto.c 2019-06-23 14:34:51.000000000 +0000 @@ -13,8 +13,9 @@ lv2:scalePoint [ rdfs:label "off" ; rdf:value 0 ] ; lv2:scalePoint [ rdfs:label "on" ; rdf:value 1 ] ; lv2:scalePoint [ rdfs:label "CC64" ; rdf:value 2 ] ; + lv2:scalePoint [ rdfs:label "CC66" ; rdf:value 3 ] ; lv2:portProperty lv2:integer; lv2:portProperty lv2:enumeration; - rdfs:comment "Mode of the sustain pedal. Fixed on/off (control parameter automation) or depending on MIDI CC 64.") + rdfs:comment "Mode of the sustain pedal. Fixed on (pedal pressed) or off (pedal released) for notes of all MIDI channels. The on/off state can alternatively be set by CC, in which case it's per MIDI-channel.") ; rdfs:comment "This filter delays note-off messages by a given time, emulating a piano sostenuto pedal. When the pedal is released, note-off messages that are queued will be sent immediately. The delay-time can be changed dynamically, changes do affects note-off messages that are still queued." . @@ -108,8 +109,10 @@ const uint8_t vel = buffer[2] & 0x7f; uint8_t mst = buffer[0] & 0xf0; - /* pedal CC 64 -- TODO make CC (and theshold) configurable !? */ - if (size == 3 && mst == MIDI_CONTROLCHANGE && (buffer[1]) == 64) { + if (size == 3 && mst == MIDI_CONTROLCHANGE && (buffer[1]) == 64 && pedal == 2) { + self->memI[16 + chn] = vel > 63 ? 1 : 0; + } + if (size == 3 && mst == MIDI_CONTROLCHANGE && (buffer[1]) == 66 && pedal == 3) { self->memI[16 + chn] = vel > 63 ? 1 : 0; } @@ -126,7 +129,8 @@ default: case 0: state = 0; break; case 1: state = 1; break; - case 2: state = self->memI[16 + chn]; break; + case 2: // no break, fallthrough + case 3: state = self->memI[16 + chn]; break; } if (mst == MIDI_NOTEON && vel ==0 ) { diff -Nru x42-plugins-20170428/midifilter.lv2/Makefile x42-plugins-20190714/midifilter.lv2/Makefile --- x42-plugins-20170428/midifilter.lv2/Makefile 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/Makefile 2019-06-23 14:34:51.000000000 +0000 @@ -1,9 +1,9 @@ #!/usr/bin/make -f - -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s @@ -30,9 +30,9 @@ ifeq ($(UNAME),Darwin) LV2LDFLAGS=-dynamiclib LIB_EXT=.dylib + EXTENDED_RE=-E STRIPFLAGS=-u -r -arch all -s lv2syms targets+=lv2syms - EXTENDED_RE=-E else LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic LIB_EXT=.so @@ -45,6 +45,8 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) @@ -58,12 +60,11 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/midifilter.lv2/midifilter.h x42-plugins-20190714/midifilter.lv2/midifilter.h --- x42-plugins-20170428/midifilter.lv2/midifilter.h 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/midifilter.h 2019-06-23 14:34:51.000000000 +0000 @@ -26,11 +26,15 @@ #define SQUARE(a) ( (a) * (a) ) #endif +#ifndef ABSDIFF +#define ABSDIFF(a,b) ( (a) > (b) ? ((a) - (b)) : ((b) - (a)) ) +#endif + #define ROUND_PARTIAL_BEATS(X,Y) ( rint( (Y) * (X)) / (Y) - floor(rint( (Y) * (X)) / (Y)) ) -/* /monotonic/ sample count */ +/* /monotonic/sample count */ #define MSC_MAX (1<<29) -#define MSC_DIFF(NOW, THEN) ( abs((NOW) - (THEN)) < (MSC_MAX>>1) \ +#define MSC_DIFF(NOW, THEN) ( ABSDIFF(NOW, THEN) < (MSC_MAX>>1) \ ? ( (NOW) - (THEN) ) \ : ( (NOW) > (THEN) ? ((NOW) - (THEN) - MSC_MAX) : (MSC_MAX - (THEN) + (NOW)) ) \ ) @@ -101,7 +105,7 @@ double bar_beats; double beat_beats; uint32_t pos_bbt; - long int pos_frame; + int64_t pos_frame; float frames_per_second; MidiEventQueue *memQ; Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/dropdown-arrow-black.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/dropdown-arrow-black.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/footswitch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/footswitch.png differ diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-cctonote.html x42-plugins-20190714/midifilter.lv2/modgui/icon-cctonote.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-cctonote.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-cctonote.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -
-
-

x42

-

MIDI CC to Note

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Mode -
-
-
-
Fixed key, velocity = CC-value
-
key = CC-value, fixed velocity (64)
-
All keys, key = parameter, velocity = CC-value
-
-
-
-
- -
-
- CC Parameter -
-
-
- Key (Note) -
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-channelfilter.html x42-plugins-20190714/midifilter.lv2/modgui/icon-channelfilter.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-channelfilter.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-channelfilter.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -
-
-

x42

-

MIDI Channel Filter

- -
-
- -
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-channelmap.html x42-plugins-20190714/midifilter.lv2/modgui/icon-channelmap.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-channelmap.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-channelmap.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -
-
-

x42

-

MIDI Channelmap

- -
-
- -
-
- Chn 1 -
-
-
- Chn 2 -
-
-
- Chn 3 -
-
-
- Chn 4 -
-
-
- Chn 5 -
-
-
- Chn 6 -
-
-
- Chn 7 -
-
-
- Chn 8 -
-
-
- Chn 9 -
-
-
- Chn 12 -
-
-
- Chn 11 -
-
-
- Chn 12 -
-
-
- Chn 13 -
-
-
- Chn 14 -
-
-
- Chn 15 -
-
-
- Chn 16 -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-enforcescale.html x42-plugins-20190714/midifilter.lv2/modgui/icon-enforcescale.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-enforcescale.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-enforcescale.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -
-
-

x42

-

MIDI Enforce Scale

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Scale -
-
-
-
C Major
-
C# Major
-
D Major
-
D# Major
-
E Major
-
F Major
-
F# Major
-
G Major
-
G# Major
-
A Major
-
A# Major
-
B Major
-
-
-
- -
- Out of Key -
-
-
-
Discard
-
Always down
-
Always up
-
-
-
- -
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-eventblocker.html x42-plugins-20190714/midifilter.lv2/modgui/icon-eventblocker.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-eventblocker.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-eventblocker.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -
-
-

x42

-

MIDI Event Filter

- -
-
- -
-
-
CC
-
Notes
-
PC
-
KP
-
CP
-
PB
-
SX
-
Cstm
-
- -
-
Custom Filter Settings
-
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Scale -
-
-
-
Note Off (0x8x)
-
Note On (0x9x)
-
Polykey Pressure (0xAx)
-
Control Change (0xBx)
-
Program Change (0xCx)
-
Channel Pressure (0xDx)
-
Pitchbend (0xEx)
-
-
-
-
- -
-
- Data 1 -
-
-
- Data 2 -
-
-
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-keyrange.html x42-plugins-20190714/midifilter.lv2/modgui/icon-keyrange.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-keyrange.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-keyrange.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -
-
-

x42

-

MIDI Note Range Filter

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Mode -
-
-
-
Off/Bypass
-
Include Range
-
Exclude Range
-
-
-
-
- -
-
- Lowest Note -
-
-
- Highest Note -
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-keysplit.html x42-plugins-20190714/midifilter.lv2/modgui/icon-keysplit.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-keysplit.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-keysplit.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -
-
-

x42

-

MIDI Splitter

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
-
-
- SplitPoint -
-
-
- -
-
- Upper Channel -
-
-
- Transpose Upr -
-
-
- Lower Channel -
-
-
- Transpose Lwr -
-
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-mapcc.html x42-plugins-20190714/midifilter.lv2/modgui/icon-mapcc.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-mapcc.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-mapcc.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -
-
-

x42

-

MIDI CC Map

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- - -
-
- From Param -
-
-
- To Param -
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-mapkeychannel.html x42-plugins-20190714/midifilter.lv2/modgui/icon-mapkeychannel.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-mapkeychannel.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-mapkeychannel.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -
-
-

x42

-

MIDI 12-tone Channel Map

- -
-
- -
-
- C -
-
-
- C# -
-
-
- D -
-
-
- D# -
-
-
- E -
-
-
- F -
-
-
- F# -
-
-
- G -
-
-
- G# -
-
-
- A -
-
-
- A# -
-
-
- B -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-mapkeyscale.html x42-plugins-20190714/midifilter.lv2/modgui/icon-mapkeyscale.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-mapkeyscale.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-mapkeyscale.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -
-
-

x42

-

MIDI Key Transpose

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
-
- C -
-
-
- C# -
-
-
- D -
-
-
- D# -
-
-
- E -
-
-
- F -
-
-
- F# -
-
-
- G -
-
-
- G# -
-
-
- A -
-
-
- A# -
-
-
- B -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-midichord.html x42-plugins-20190714/midifilter.lv2/modgui/icon-midichord.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-midichord.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-midichord.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -
-
-

x42

-

MIDI Chord Builder

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Scale -
-
-
-
C Major
-
C# Major
-
D Major
-
D# Major
-
E Major
-
F Major
-
F# Major
-
G Major
-
G# Major
-
A Major
-
A# Major
-
B Major
-
-
-
-
- -
-
Prime
-
Third
-
5th
-
6th
-
7th
-
8va
-
9th
-
11th
-
13th
-
Bass
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-mididelay.html x42-plugins-20190714/midifilter.lv2/modgui/icon-mididelay.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-mididelay.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-mididelay.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -
-
-

x42

-

MIDI Delay

- -
-
- -
- Delay Beats 4/4 -
-
-
-
No Delay
-
Eighth
-
Quarter
-
Half Note
-
Whole Note
-
Two Bars
-
Four Bars
-
-
-
- -
-
-
- Delaytime -
-
-
-
- Randomize -
-
-
- - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-mididup.html x42-plugins-20190714/midifilter.lv2/modgui/icon-mididup.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-mididup.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-mididup.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -
-
-

x42

-

MIDI Channel Unisono

- -
-
- -
-
- Source Channel -
-
-
- Duplicate to Channel -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-midistrum.html x42-plugins-20190714/midifilter.lv2/modgui/icon-midistrum.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-midistrum.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-midistrum.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -
-
-

x42

-

MIDI Strum

- -
-
- -
-
- - Strum Duration -
-
-
-
Immediate
-
32th
-
16th
-
Eighth
-
Quarter Note
-
Half Note
-
Whole Note
-
-
-
- -
- Strum Mode -
-
-
-
Always Down (low notes first)
-
Always Up (high notes first)
-
Alternate
-
Up/Down Beat
-
Up/Down 8th
-
-
-
-
- -
-
-
- Speed -
-
-
-
- Timeout -
-
-
-
-
-
- Strum Acc. -
-
- -
-
- Rnd. Accel. -
-
- -
-
- Rnd. Vel. -
-
- -
-
- Δ Vel. -
-
-
- - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-miditranspose.html x42-plugins-20190714/midifilter.lv2/modgui/icon-miditranspose.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-miditranspose.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-miditranspose.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -
-
-

x42

-

Chromatic Transpose

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- - -
-
- Transpose -
-
-
- Inversion Point -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-monolegato.html x42-plugins-20190714/midifilter.lv2/modgui/icon-monolegato.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-monolegato.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-monolegato.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -
-
-

x42

-

MIDI Monophonic Legato

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-noactivesensing.html x42-plugins-20190714/midifilter.lv2/modgui/icon-noactivesensing.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-noactivesensing.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-noactivesensing.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -
-
-

x42

-

MIDI Remove Active Sensing

- -
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-nodup.html x42-plugins-20190714/midifilter.lv2/modgui/icon-nodup.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-nodup.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-nodup.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -
-
-

x42

-

MIDI Duplicate Blocker

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-notetocc.html x42-plugins-20190714/midifilter.lv2/modgui/icon-notetocc.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-notetocc.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-notetocc.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -
-
-

x42

-

MIDI Note to CC

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Mode -
-
-
-
Fixed parameter, CC-value = velocity
-
Fixed parameter, CC-value = key
-
All keys, parameter = key, CC-value = velocity
-
-
-
-
- -
-
- CC Parameter -
-
-
- Key (Note) -
-
-
- - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-notetoggle.html x42-plugins-20190714/midifilter.lv2/modgui/icon-notetoggle.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-notetoggle.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-notetoggle.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -
-
-

x42

-

MIDI Note Toggle

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-ntapdelay.html x42-plugins-20190714/midifilter.lv2/modgui/icon-ntapdelay.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-ntapdelay.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-ntapdelay.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -
-
-

x42

-

MIDI N-Tap Delay

- -
-
- - -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- - -
- Repeat-time -
-
-
-
32th
-
16th
-
Eighth
-
Quarter
-
Half Note
-
Whole Note
-
Two Bars
-
Four Bars
-
-
-
-
- -
-
- Repeats -
-
-
-
- Delaytime -
-
-
- Ramp -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-onechannelfilter.html x42-plugins-20190714/midifilter.lv2/modgui/icon-onechannelfilter.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-onechannelfilter.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-onechannelfilter.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -
-
-

x42

-

MIDI Channel Filter

- -
-
- -
-
- Midi Channel -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-passthru.html x42-plugins-20190714/midifilter.lv2/modgui/icon-passthru.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-passthru.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-passthru.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -
-
-

x42

-

MIDI Thru

- -
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-quantize.html x42-plugins-20190714/midifilter.lv2/modgui/icon-quantize.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-quantize.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-quantize.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -
-
-

x42

-

MIDI Quantization

- -
-
- - -
- Repeat-time -
-
-
-
32th
-
16th
-
Eighth
-
Quarter
-
Half Note
-
Whole Note
-
Two Bars
-
Four Bars
-
-
-
- -
-
-
Min.D
-
-
-
- Time Base -
-
-
- -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-randvelocity.html x42-plugins-20190714/midifilter.lv2/modgui/icon-randvelocity.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-randvelocity.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-randvelocity.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -
-
-

x42

-

MIDI Velocity Randomizer

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Random Mode -
-
-
-
Absolute (equal distribution)
-
Normalized (standard deviation)
-
-
-
-
- - -
-
- Rand. Factor -
-
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-scalecc.html x42-plugins-20190714/midifilter.lv2/modgui/icon-scalecc.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-scalecc.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-scalecc.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -
-
-

x42

-

MIDI Scale CC Value

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Parameter Mode -
-
-
-
Off/Bypass
-
Include Range
-
Exclude Range
-
-
-
- -
- Value Mode -
-
-
-
Clamp to 0..127
-
Reflect Overflow (-1 to 1, 128 to 127)
-
Truncate Overflow (-1 to 127, 128 to 0)
-
-
-
-
- -
-
- CC Start -
-
-
- CC End -
-
- -
- Scale Factor -
-
-
-
- Offset -
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-sostenuto.html x42-plugins-20190714/midifilter.lv2/modgui/icon-sostenuto.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-sostenuto.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-sostenuto.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -
-
-

x42

-

MIDI Sustain

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Pedal Mode -
-
-
-
Off
-
On
-
CC64
-
-
-
-
- -
-
-
- Sostenuto [sec] -
-
-
- - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-velocityrange.html x42-plugins-20190714/midifilter.lv2/modgui/icon-velocityrange.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-velocityrange.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-velocityrange.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -
-
-

x42

-

MIDI Velocity Range Filter

- -
-
- -
-
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- -
- Mode -
-
-
-
Off/Bypass
-
Include Range
-
Exclude Range
-
-
-
-
- -
-
- Min Volume -
-
-
- Max Volume -
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/icon-velocityscale.html x42-plugins-20190714/midifilter.lv2/modgui/icon-velocityscale.html --- x42-plugins-20170428/midifilter.lv2/modgui/icon-velocityscale.html 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/icon-velocityscale.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -
-
-

x42

-

MIDI Velocity Adjust

- -
-
- -
- Midi Channel -
-
-
-
Any
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
-
-
- - -
-
- Note-on Min -
-
-
- Note-on Max -
-
-
- Note-on Offset -
-
-
- -
-
- Note-off Min -
-
-
- Note-off Max -
-
-
- Note-off Offset -
-
-
- - - -
- {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} -
-
- {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} -
-
Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob127.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob127.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob129.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob129.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob13_12.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob13_12.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob16.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob16.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob17.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob17.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob48_48.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob48_48.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob63_64.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob63_64.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob64_64.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob64_64.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob65.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob65.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/knob.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/knob.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/led-blu-off.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/led-blu-off.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/led-blu-on.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/led-blu-on.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/led-grn-off.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/led-grn-off.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/led-grn-on.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/led-grn-on.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/midi127.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/midi127.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/midi128.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/midi128.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-cctonote.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-cctonote.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-channelfilter.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-channelfilter.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-channelmap.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-channelmap.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-enforcescale.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-enforcescale.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-eventblocker.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-eventblocker.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-keyrange.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-keyrange.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-keysplit.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-keysplit.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-mapcc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-mapcc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-mapkeychannel.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-mapkeychannel.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-mapkeyscale.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-mapkeyscale.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-midichord.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-midichord.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-mididelay.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-mididelay.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-mididup.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-mididup.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-midistrum.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-midistrum.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-miditranspose.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-miditranspose.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-monolegato.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-monolegato.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-noactivesensing.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-noactivesensing.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-nodup.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-nodup.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-notetocc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-notetocc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-notetoggle.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-notetoggle.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-ntapdelay.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-ntapdelay.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-onechannelfilter.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-onechannelfilter.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-passthru.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-passthru.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-quantize.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-quantize.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-randvelocity.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-randvelocity.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-scalecc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-scalecc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-sostenuto.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-sostenuto.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-velocityrange.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-velocityrange.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/screenshot-velocityscale.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/screenshot-velocityscale.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/small-box.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/small-box.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-cctonote.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-cctonote.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-channelfilter.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-channelfilter.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-channelmap.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-channelmap.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-enforcescale.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-enforcescale.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-eventblocker.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-eventblocker.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-keyrange.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-keyrange.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-keysplit.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-keysplit.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-mapcc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-mapcc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-mapkeychannel.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-mapkeychannel.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-mapkeyscale.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-mapkeyscale.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-midichord.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-midichord.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-mididelay.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-mididelay.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-mididup.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-mididup.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-midistrum.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-midistrum.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-miditranspose.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-miditranspose.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-monolegato.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-monolegato.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-noactivesensing.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-noactivesensing.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-nodup.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-nodup.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-notetocc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-notetocc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-notetoggle.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-notetoggle.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-ntapdelay.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-ntapdelay.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-onechannelfilter.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-onechannelfilter.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-passthru.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-passthru.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-quantize.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-quantize.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-randvelocity.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-randvelocity.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-scalecc.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-scalecc.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-sostenuto.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-sostenuto.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-velocityrange.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-velocityrange.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midifilter.lv2/modgui/thumbnail-velocityscale.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midifilter.lv2/modgui/thumbnail-velocityscale.png differ diff -Nru x42-plugins-20170428/midifilter.lv2/modgui/x42-style.css x42-plugins-20190714/midifilter.lv2/modgui/x42-style.css --- x42-plugins-20170428/midifilter.lv2/modgui/x42-style.css 2017-03-21 21:24:42.000000000 +0000 +++ x42-plugins-20190714/midifilter.lv2/modgui/x42-style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,789 +0,0 @@ -@import url(/fonts/nexa/stylesheet.css); -@import url(/fonts/questrial/stylesheet.css); - -/* = CONTAINER -================================================ */ -.x42-midifilter{{{cns}}} { - background-image:url(/resources/small-box.png{{{ns}}}); - background-position:center center; - background-repeat:no-repeat; - border-radius: 21px; - position:absolute; -} - -/* = Labels -================================================ */ -.x42-midifilter{{{cns}}} .center { - text-align:center; -} - -.x42-midifilter{{{cns}}} .x42-brand { - bottom: 12%; - cursor:default; - left: 6.5%; - position:absolute; - text-align:center; - width: 25px; -} - -.x42-midifilter{{{cns}}} .x42-brand h1 { - font-family:"Nexa"; - font-size:28px; - padding:0; - margin:0; - color:#eee; - transform: rotate(270deg); - -webkit-transform: rotate(270deg); - text-shadow: -2px 2px 2px #444; -} - -.x42-midifilter{{{cns}}} .x42-plugin-name { - overflow:hidden; - position:absolute; - right:7%; - text-align:center; - bottom:6.5%; -} - -.x42-midifilter{{{cns}}} .x42-plugin-name h1 { - font-family:"Questrial"; - font-size:19px; - line-height:1; - color:#222; - text-shadow: -1px -1px 0 #bbb; -} - -/* = LIGHT ON/OFF -================================================ */ -.x42-midifilter{{{cns}}} .mod-light { - background-position:center center; - background-repeat:no-repeat; - height:32px; - position:absolute; -} - - -/* = FOOTSWITCH -================================================ */ -.x42-midifilter{{{cns}}} .mod-footswitch { - background-image:url(/resources/footswitch.png{{{ns}}}); - background-position:bottom center; - background-repeat:no-repeat; - background-size:auto 88px; - cursor:pointer; - height:44px; - margin: auto; - position:absolute; - width: 44px; -} - -.x42-midifilter{{{cns}}} .mod-footswitch.on { - background-position: top center !important; -} - - -/* = KNOBS -================================================ */ -.x42-midifilter{{{cns}}} .mod-control-group { - margin:20px 20px 5px 20px; - position:relative; - text-align:center; - z-index:30; -} - -.x42-midifilter{{{cns}}} .top { - margin-top:0px; -} - -.x42-midifilter{{{cns}}} .one-knob { - margin-left:auto; - margin-right:auto; - width:100px; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob { - overflow:hidden; - position:relative; - display:inline-block; - height:88px; - margin: 3px 10px; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob.midi { - height:74px; - margin-bottom:0; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob.wide { - width:64px; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob.wider { - width:88px; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob.grid16 { - height:42px; - margin: 3px 5px 3px 15px; - overflow:visible; -} - -.x42-midifilter{{{cns}}} .mod-control-group span.mod-knob-title { - color:#333; - font-size:11px; - font-weight:bold; - line-height:1; - text-transform:uppercase; - cursor:default; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - color:#333; - bottom:12px; - display:block; - height:12px; - left:0; - margin:0; - overflow:hidden; - padding:0; - position:absolute; - right:0; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob.midi > span.mod-knob-title { - color:#333; - bottom:0px; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob.grid16 > span.mod-knob-title { - display:block; - width:10px; - margin:0; - overflow:hidden; - padding:0; - position:absolute; - text-align:center; - top:15px; - left:-30px; - width:48px; - transform: rotate(270deg); - -webkit-transform: rotate(270deg); -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-value { - color:#333; - bottom:0px; - font-size:11px; - position:absolute; - line-height:1; - left:0; - right:0; - z-index:60; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-image { - background-image:url(/resources/knob.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 60px; - height:60px; - width:60px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m16-image { - background-image:url(/resources/knob16.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:64px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m65-image { - background-image:url(/resources/knob65.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m4848-image { - background-image:url(/resources/knob48_48.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m6464-image { - background-image:url(/resources/knob64_64.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m6364-image { - background-image:url(/resources/knob63_64.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m127-image { - background-image:url(/resources/knob127.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-n127-image { - background-image:url(/resources/midi127.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-n128-image { - background-image:url(/resources/midi128.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m129-image { - background-image:url(/resources/knob129.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 56px; - background-color:#222; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 2px 1px #fff inset; - height:56px; - width:96px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-mc17-image { - background-image:url(/resources/knob17.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 42px; - background-color:#222; - box-shadow: 1px 1px 2px 0px #000 inset, -1px -1px 2px 0px #fff inset; - height:42px; - width:48px; - margin:0 auto; -} - -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob .mod-knob-m1312-image { - background-image:url(/resources/knob13_12.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 42px; - background-color:#222; - box-shadow: 1px 1px 2px 0px #000 inset, -1px -1px 2px 0px #fff inset; - height:42px; - width:72px; - margin:0 auto; -} - -/* = ENUMERATED LIST -================================================ */ -.x42-midifilter{{{cns}}} .mod-enum-top-group { - cursor:default; - margin:15px 20px 5px 20px; -} - -.x42-midifilter{{{cns}}} .mod-enum-top-group-2items { - cursor:default; - margin:15px auto 5px; - width:240px; -} - -.x42-midifilter{{{cns}}} .mod-enum-float-group { - cursor:default; - margin:5px 0px 5px; -} - -.x42-midifilter{{{cns}}} .mod-enumerated-group { - cursor:default; - height:31px; - margin:20px auto 20px auto !important; - position:relative; - width:100px; - z-index:35; -} - -.x42-midifilter{{{cns}}} .mod-enumerated-group.float { - margin: 0 10px 20px 10px !important; - float:left; -} - -.x42-midifilter{{{cns}}} .mod-enumerated { - background-image:url(/resources/dropdown-arrow-black.png{{{ns}}}); - background-position:right center; - background-repeat:no-repeat; - font-size:11px; - font-weight:bold; - left:0; - line-height:2; - overflow:hidden; - position:absolute; - right:0; - text-align:center; - z-index:35; -} - -.x42-midifilter{{{cns}}} .mod-enumerated .mod-enumerated-selected { - background-color:rgba(0,0,0,.3); - box-shadow:inset 0 0 4px rgba(0,0,0,.3); - border-radius:4px; - padding:3px 9px; - z-index: 35; -} - -.x42-midifilter{{{cns}}} .mod-enumerated .mod-enumerated-list { - cursor:pointer; - background-color:rgba(0,0,0,.9); - color:#fff; - display:none; - height:115px; - overflow:auto; - position:relative; - z-index: 50; -} - -.x42-midifilter{{{cns}}} .mod-enumerated .mod-enumerated-list > div { - padding:3px 9px; - z-index: 50; -} - -.x42-midifilter{{{cns}}} .mod-enumerated .mod-enumerated-list > div:hover { - background-color:rgba(255,255,255,.2); - z-index: 50; -} - -/* = Toggle Buttons -================================================ */ -.x42-midifilter{{{cns}}} .buttongrid { - overflow:hidden; - margin: 20px auto; - position:relative; - z-index: 30; -} - -.x42-midifilter{{{cns}}} .buttongrid .togglebtn { - background-color:#444; - border-radius: 5px; - cursor:default; - float:left; - height: 50px; - margin: 5px; - width: 50px; - overflow: hidden; - padding: 28px 0 0 6px; - color:white; - z-index: 35; - background-size:20px 20px; - background-repeat:no-repeat; - background-position: 29px 1px; -} - -.x42-midifilter{{{cns}}} .buttongrid .togglebtn.on { - background-image:url(/resources/led-grn-on.png{{{ns}}}); - background-color:#333; - box-shadow: 0 -2px 2px 1px #222 inset, -1px -2px 1px 1px #888 inset; - padding: 29px 0 0 6px; - background-position: 29px 2px; -} - -.x42-midifilter{{{cns}}} .buttongrid .togglebtn.off { - background-image:url(/resources/led-grn-off.png{{{ns}}}); - box-shadow: 2px 2px 2px 0px #000 inset, -2px -2px 2px 1px #666 inset; -} - -/* = COLORS -================================================ */ -.x42-midifilter{{{cns}}} h1, -.x42-midifilter{{{cns}}} .mod-enumerated, -.x42-midifilter{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - color:black; -} -.x42-midifilter{{{cns}}} h1 { - border-color:black; -} - -/* = Plugin Specifics -- TODO unify a bit more -================================================ */ -.x42-midifilter{{{cns}}}.x42-midi-nodup .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-mididup .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-monolegato .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-transpose .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-notetoggle .mod-light { - bottom:90px; - left:20px; - right:20px; -} - -.x42-midifilter{{{cns}}}.x42-midi-velocityscale .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-strum .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-onechannelfilter .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-ntapdelay .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-randvelocity .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-mapcc .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-velocityrange .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-keyrange .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-cctonote .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-notetocc .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-delay .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-sostenuto .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-keysplit .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-quantize .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-midichord .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-mapkeyscale .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-enforcescale .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-mapkeychannel .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-channelmap .mod-light, -.x42-midifilter{{{cns}}}.x42-midi-channelfilter .mod-light { - bottom:43px; - right:20px; - width:32px; -} - -.x42-midifilter{{{cns}}}.x42-midi-scalecc .mod-light { - bottom:43px; - right:0px; - left:60px; -} - -.x42-midifilter{{{cns}}}.x42-midi-stub .mod-light { - bottom:75px; - left:20px; - right:20px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-stub .mod-footswitch { - bottom: 25px; - left: 20px; - right: 20px; -} - -.x42-midifilter{{{cns}}}.x42-midi-randvelocity .mod-footswitch { - bottom: 25px; - left: 62px; -} - -.x42-midifilter{{{cns}}}.x42-midi-quantize .mod-footswitch { - bottom: 25px; - left: 72px; -} - -.x42-midifilter{{{cns}}}.x42-midi-ntapdelay .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-channelmap .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-notetocc .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-cctonote .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-delay .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-sostenuto .mod-footswitch { - bottom: 35px; - left: 10px; - right: 10px; -} - -.x42-midifilter{{{cns}}}.x42-midi-keysplit .mod-footswitch { - bottom: 37px; - left: 60px; -} - -.x42-midifilter{{{cns}}}.x42-midi-scalecc .mod-footswitch { - bottom: 37px; - right: 60px; - left: 0px; -} - -.x42-midifilter{{{cns}}}.x42-midi-enforcescale .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .mod-footswitch { - bottom: 37px; - left: 10px; - right: 10px; -} - -.x42-midifilter{{{cns}}}.x42-midi-mapkeychannel .mod-footswitch { - bottom: 42px; - left: 10px; - right: 10px; -} - - -.x42-midifilter{{{cns}}}.x42-midi-nodup .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-mididup .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-monolegato .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-transpose .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-onechannelfilter .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-notetoggle .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-velocityrange .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-keyrange .mod-footswitch { - bottom: 45px; - left: 10px; - right: 10px; - z-index: 45; -} - -.x42-midifilter{{{cns}}}.x42-midi-velocityscale .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-strum .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-midichord .mod-footswitch { - bottom: 47px; - left: 10px; - right: 10px; -} - -.x42-midifilter{{{cns}}}.x42-midi-mapcc .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-mapkeyscale .mod-footswitch, -.x42-midifilter{{{cns}}}.x42-midi-channelmap .mod-footswitch { - bottom: 55px; - left: 10px; - right: 10px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-mapkeyscale { - background-size:430px 330px; - height:330px; - width:430px; -} - -.x42-midifilter{{{cns}}}.x42-midi-channelmap, -.x42-midifilter{{{cns}}}.x42-midi-channelfilter { - background-size:330px 330px; - height:330px; - width:330px; -} - -.x42-midifilter{{{cns}}}.x42-midi-channelfilter .buttongrid { - width: 240px; - height: 240px; - top: 15px; -} - -.x42-midifilter{{{cns}}}.x42-midi-channelfilter .mod-footswitch { - bottom: 35px; - left: 82px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-nodup, -.x42-midifilter{{{cns}}}.x42-midi-mididup, -.x42-midifilter{{{cns}}}.x42-midi-monolegato, -.x42-midifilter{{{cns}}}.x42-midi-onechannelfilter, -.x42-midifilter{{{cns}}}.x42-midi-notetoggle { - background-size:300px 200px; - height:200px; - width:300px; -} - - -.x42-midifilter{{{cns}}}.x42-midi-mapcc, -.x42-midifilter{{{cns}}}.x42-midi-delay, -.x42-midifilter{{{cns}}}.x42-midi-sostenuto { - background-size:280px 240px; - height:240px; - width:280px; -} - -.x42-midifilter{{{cns}}}.x42-midi-notetocc, -.x42-midifilter{{{cns}}}.x42-midi-cctonote { - background-size:444px 225px; - height:225px; - width:444px; -} - - -.x42-midifilter{{{cns}}}.x42-midi-velocityrange, -.x42-midifilter{{{cns}}}.x42-midi-keyrange { - background-size:332px 220px; - height:220px; - width:332px; -} - -.x42-midifilter{{{cns}}}.x42-midi-velocityscale, -.x42-midifilter{{{cns}}}.x42-midi-strum { - background-size:420px 360px; - height:360px; - width:420px; -} - -.x42-midifilter{{{cns}}}.x42-midi-transpose { - background-size:300px 230px; - height:230px; - width:300px; -} - -.x42-midifilter{{{cns}}}.x42-midi-ntapdelay { - background-size:360px 240px; - height:240px; - width:360px; -} - -.x42-midifilter{{{cns}}}.x42-midi-randvelocity { - background-size:360px 220px; - height:220px; - width:360px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-stub { - background-size:170px 170px; - height:170px; - width:170px; -} - - -.x42-midifilter{{{cns}}}.x42-midi-stub .x42-plugin-name { - top:0px; - left:7%; -} - - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-midichord { - background-size:330px 280px; - height:280px; - width:330px; -} - -.x42-midifilter{{{cns}}}.x42-midi-midichord .buttongrid { - width: 300px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-enforcescale { - background-size:400px 170px; - height:170px; - width:400px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-eventblocker { - background-size:480px 280px; - height:280px; - width:480px; -} - -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .top-float { - margin: 10px 20px; -} - -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .top-float > div { - float:left; -} - -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .group-pane { - border: 1px solid black; - border-radius: 11px; - margin:5px; -} -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .group-pane > span { - display:block; - text-align:center; -} - -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .buttongrid { - width: 120px; -} - -.x42-midifilter{{{cns}}}.x42-midi-eventblocker .x42-brand { - left: 150px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-mapkeychannel { - background-size:330px 260px; - height:260px; - width:330px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-mididup .mod-knob.m16 { - margin:0px 10px; - width:100px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-quantize { - background-size:300px 220px; - height:220px; - width:300px; -} - -.x42-midifilter{{{cns}}}.x42-midi-quantize .buttongrid { - width: 60px; - height: 66px; - display:inline-block; - text-align:left; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-keysplit { - background-size:400px 320px; - height:320px; - width:400px; -} - -.x42-midifilter{{{cns}}}.x42-midi-keysplit .top-float { - margin: 10px 20px; -} - -.x42-midifilter{{{cns}}}.x42-midi-keysplit .top-float > div { - float:left; - margin:0; - max-width:240px; -} - -/* --- */ - -.x42-midifilter{{{cns}}}.x42-midi-scalecc { - background-size:510px 240px; - height:240px; - width:510px; -} - -/* --- */ -.x42-midifilter{{{cns}}}.x42-midi-keyrange .mod-footswitch { - z-index:40; -} diff -Nru x42-plugins-20170428/midigen.lv2/Makefile x42-plugins-20190714/midigen.lv2/Makefile --- x42-plugins-20170428/midigen.lv2/Makefile 2016-08-22 14:26:29.000000000 +0000 +++ x42-plugins-20190714/midigen.lv2/Makefile 2019-04-13 11:59:18.000000000 +0000 @@ -1,14 +1,9 @@ #!/usr/bin/make -f - -# these can be overridden using make variables. e.g. -# make CFLAGS=-O2 -# make install DESTDIR=$(CURDIR)/debian/midigen.lv2 PREFIX=/usr -# -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s @@ -16,7 +11,7 @@ ############################################################################### LIB_EXT=.so -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm LV2NAME=midigen BUNDLE=midigen.lv2 @@ -61,17 +56,17 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/boxy-gray.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/boxy-gray.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/dropdown-arrow-black.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/dropdown-arrow-black.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/dropdown-arrow-white.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/dropdown-arrow-white.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/footswitch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/footswitch.png differ diff -Nru x42-plugins-20170428/midigen.lv2/modgui/icon-midi-generator.html x42-plugins-20190714/midigen.lv2/modgui/icon-midi-generator.html --- x42-plugins-20170428/midigen.lv2/modgui/icon-midi-generator.html 2016-08-22 14:26:29.000000000 +0000 +++ x42-plugins-20190714/midigen.lv2/modgui/icon-midi-generator.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -
-
-

{{brand}}

-

{{label}}

-
-
- {{#controls.0}} -
-
-
- {{#scalePoints}} -
{{label}}
- {{/scalePoints}} -
-
- {{/controls.0}} -
-
- {{#controls.1}} -
-
- {{name}} -
- {{/controls.1}} - {{#controls.2}} -
-
- {{name}} -
- {{/controls.2}} - {{#controls.3}} -
-
- {{name}} -
- {{/controls.3}} -
-
-
- {{#effect.ports.audio.input}} -
-
-
- {{/effect.ports.audio.input}} - {{#effect.ports.midi.input}} -
-
-
- {{/effect.ports.midi.input}} - {{#effect.ports.cv.input}} -
-
-
- {{/effect.ports.cv.input}} -
-
- {{#effect.ports.audio.output}} -
-
-
- {{/effect.ports.audio.output}} - {{#effect.ports.midi.output}} -
-
-
- {{/effect.ports.midi.output}} - {{#effect.ports.cv.output}} -
-
-
- {{/effect.ports.cv.output}} -
-
\ No newline at end of file Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/knob-steel.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/knob-steel.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/screenshot-midi-generator.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/screenshot-midi-generator.png differ diff -Nru x42-plugins-20170428/midigen.lv2/modgui/stylesheet-midi-generator.css x42-plugins-20190714/midigen.lv2/modgui/stylesheet-midi-generator.css --- x42-plugins-20170428/midigen.lv2/modgui/stylesheet-midi-generator.css 2016-08-22 14:26:29.000000000 +0000 +++ x42-plugins-20190714/midigen.lv2/modgui/stylesheet-midi-generator.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -/* STYLES FOR THE BOXY PEDAL */ - -@import url(/fonts/nexa/stylesheet.css); -@import url(/fonts/questrial/stylesheet.css); - - -/* = CONTAINER -================================================ */ -.mod-pedal-boxy{{{cns}}} { - background-position:center center; - background-repeat:no-repeat; - background-size:230px 431px; - height:431px; - position:absolute; - width:230px; - border-radius: 21px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy50 { - background-size:301px 315px; - height:315px; - width:301px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy75 { - background-size:326px 431px; - width:326px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy85 { - background-size:364px 431px; - width:364px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy100 { - background-size:421px 431px; - width:421px; -} - -/* = PLUGIN'S AUTHOR -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-plugin-brand { - left:0; - position:absolute; - right:0; - text-align:center; - text-transform:uppercase; - top:160px; -} - -.mod-pedal-boxy{{{cns}}} .mod-plugin-brand h1 { - border-color:#000; - border-radius:12px; - border-style:solid; - border-width:4px; - display:inline-block; - font-family:"Nexa"; - font-size:32px; - padding:3px 9px 0; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy50 .mod-plugin-brand { - top:16px; -} - -.mod-pedal-boxy{{{cns}}}.mod-one-footswitch-presets .mod-plugin-brand { - top:12px; -} - - -/* = PLUGIN'S NAME -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-plugin-name { - left:30px; - overflow:hidden; - position:absolute; - right:30px; - text-align:center; - top:340px; -} - -.mod-pedal-boxy{{{cns}}} .mod-plugin-name h1 { - font-family:"Questrial"; - font-size:21px; - line-height:1; -} - -.mod-pedal-boxy{{{cns}}}.mod-five-knobs .mod-plugin-name, -.mod-pedal-boxy{{{cns}}}.mod-six-knobs .mod-plugin-name, -.mod-pedal-boxy{{{cns}}}.mod-seven-knobs .mod-plugin-name, -.mod-pedal-boxy{{{cns}}}.mod-eight-knobs .mod-plugin-name { - top:350px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy50 .mod-plugin-name { - top:230px; -} - - -/* = LIGHT ON/OFF -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-light { - background-position:center center; - background-repeat:no-repeat; - height:32px; - left:10px; - position:absolute; - right:10px; - top:235px; -} - -.mod-pedal-boxy{{{cns}}}.mod-five-knobs .mod-light, -.mod-pedal-boxy{{{cns}}}.mod-six-knobs .mod-light, -.mod-pedal-boxy{{{cns}}}.mod-seven-knobs .mod-light, -.mod-pedal-boxy{{{cns}}}.mod-eight-knobs .mod-light { - top:253px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy50 .mod-light { - top:105px; -} - -.mod-pedal-boxy{{{cns}}}.mod-one-footswitch-presets .mod-light { - top:120px; -} - - -/* = FOOTSWITCH -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-footswitch { - background-image:url(/resources/footswitch.png{{{ns}}}); - background-position:bottom center; - background-repeat:no-repeat; - background-size:auto 132px; - bottom: 95px; - left: 13px; - right: 13px; - cursor:pointer; - height:66px; - width: 66px; - margin: auto; - position:absolute !important; -} -.mod-pedal-boxy{{{cns}}} .mod-footswitch.on { - background-position-y: top !important -} - -.mod-pedal-boxy{{{cns}}}.mod-five-knobs .mod-footswitch, -.mod-pedal-boxy{{{cns}}}.mod-six-knobs .mod-footswitch, -.mod-pedal-boxy{{{cns}}}.mod-seven-knobs .mod-footswitch, -.mod-pedal-boxy{{{cns}}}.mod-eight-knobs .mod-footswitch { - top:285px; -} - -.mod-pedal-boxy{{{cns}}}.mod-boxy50 .mod-footswitch { - top:140px; -} - -.mod-pedal-boxy{{{cns}}}.mod-one-footswitch-presets .mod-footswitch { - top:170px; -} - - -/* = KNOBS -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-control-group { - margin:20px !important; - position:relative; - text-align:center; - z-index:30; -} -.mod-pedal-boxy{{{cns}}} .top { - margin-top:0px !important; -} - -.mod-pedal-boxy{{{cns}}}.mod-one-footswitch-presets .mod-control-group { - margin:10px !important; - top:75px; -} - -.mod-pedal-boxy{{{cns}}}.mod-one-footswitch-presets .mod-control-group > select { - width:100%; -} - -.mod-pedal-boxy{{{cns}}} .mod-control-group .mod-knob { - overflow:hidden; - position:relative; -} - -.mod-pedal-boxy{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - bottom:0px; - display:block; - font-size:11px; - font-weight:bold; - height:12px; - left:0; - line-height:1; - margin:0; - overflow:hidden; - padding:0; - position:absolute; - right:0; - text-transform:uppercase; -} - -/* THREE AND HIGHER KNOBS */ -.mod-pedal-boxy{{{cns}}}.mod-three-knobs .mod-control-group .mod-knob .mod-knob-image { - background-image:url(/resources/knobs/lata/lata.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 60px; - height:60px; - width:60px; - margin:0 auto; -} -.mod-pedal-boxy{{{cns}}}.mod-three-knobs .mod-control-group .mod-knob, - display:inline-block; - height:73px; -} - -/* EIGTH KNOBS */ -.mod-pedal-boxy{{{cns}}}.mod-eight-knobs .mod-knob { - width:70px; -} - -/* = ENUMERATED LIST -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-enumerated-group { - height:31px; - margin:20px auto 0 !important; - position:relative; - width:190px; - z-index:35; -} - -.mod-pedal-boxy{{{cns}}}.mod-three-knobs .mod-enumerated-group, -.mod-pedal-boxy{{{cns}}}.mod-four-knobs .mod-enumerated-group { - margin-bottom:5px !important; -} - -.mod-pedal-boxy{{{cns}}}.mod-four-knobs .mod-enumerated-group { - width:250px; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated { - background-position:right center; - background-repeat:no-repeat; - font-size:11px; - font-weight:bold; - left:0; - line-height:2; - overflow:hidden; - position:absolute; - right:0; - text-align:left; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated .mod-enumerated-selected { - background-color:rgba(0,0,0,.3); - box-shadow:inset 0 0 4px rgba(0,0,0,.3); - border-radius:4px; - padding:3px 9px; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated .mod-enumerated-selected { - border-radius:4px 4px 0 0; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated .mod-enumerated-list { - display:none; - color:#fff; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated .mod-enumerated-list { - background-color:rgba(0,0,0,.9); - display:none; - height:115px; - overflow:auto; - position:relative; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated .mod-enumerated-list > div { - padding:3px 9px; -} - -.mod-pedal-boxy{{{cns}}} .mod-enumerated .mod-enumerated-list > div:hover { - background-color:rgba(255,255,255,.2); - cursor:pointer; -} - -/* SLIDER -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-slider:first-child { - margin-left:8px; -} - -.mod-pedal-boxy{{{cns}}} .mod-slider { - color:black; - float:left; - font-size:11px; - height:140px; - margin-bottom:2px; - margin-right:2px; - overflow:hidden; - position:relative; - text-align:center; - width:33px; -} - - -.mod-pedal-boxy{{{cns}}} .mod-slider .mod-slider-title { - display:block; - font-size:11px; - font-weight:bold; - height:7px; - line-height:1; - margin-bottom:3px; - overflow:hidden; - padding:7px 0 5px; - position:relative; -} - -.mod-pedal-boxy{{{cns}}} .mod-slider .mod-slider-image { - background-image:url(/resources/pedals/slider.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 110px; - height:110px; - margin:0 auto; - width:44px; -} - -.mod-pedal-boxy{{{cns}}} .mod-slider .mod-slider-image:hover { - cursor:pointer; -} - -.mod-pedal-boxy{{{cns}}}.mod-three-sliders .mod-slider { - margin:0; - width:33%; -} - -.mod-pedal-boxy{{{cns}}}.mod-four-sliders .mod-slider { - margin:0; - width:25%; -} - -.mod-pedal-boxy{{{cns}}}.mod-five-sliders .mod-slider { - margin:0; - width:20%; -} - -.mod-pedal-boxy{{{cns}}}.mod-six-sliders .mod-slider { - margin:0; - width:16.5%; -} - -.mod-pedal-boxy{{{cns}}}.mod-seven-sliders .mod-slider { - margin:0; - width:14.2%; -} - -.mod-pedal-boxy{{{cns}}}.mod-eight-sliders .mod-slider { - margin:0; - width:12.5%; -} - -.mod-pedal-boxy{{{cns}}}.mod-nine-sliders .mod-slider { - margin:0; - width:11.11%; -} - -.mod-pedal-boxy{{{cns}}}.mod-ten-sliders .mod-slider { - margin:0; - width:10%; -} - -.mod-pedal-boxy{{{cns}}}.mod-ten-sliders .mod-slider .mod-slider-image { - margin-left:-5px; -} - -.mod-pedal-boxy{{{cns}}}.mod-twelve-sliders .mod-slider { - margin:0; - width:8.333333%; -} - -.mod-pedal-boxy{{{cns}}}.mod-twelve-sliders .mod-slider .mod-slider-image { - margin-left:-5px; -} - - -/* = BACKGROUND IMAGES - Color of the pedal -================================================ */ -.mod-pedal-boxy{{{cns}}}.mod-gray { - background-image:url(/resources/boxy-gray.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-boxy50.mod-gray { - background-image:url(/resources/pedals/boxy-small/gray.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-boxy75.mod-gray { - background-image:url(/resources/pedals/boxy75/gray.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-boxy85.mod-gray { - background-image:url(/resources/pedals/boxy85/gray.png{{{ns}}}); -} -.mod-pedal-boxy{{{cns}}}.mod-boxy100.mod-gray { - background-image:url(/resources/pedals/boxy100/gray.png{{{ns}}}); -} - - -/* = COLORS - Color of the pedals labels -================================================ */ -.mod-pedal-boxy{{{cns}}}.mod-gray .mod-enumerated -{ - background-image:url(/resources/dropdown-arrow-white.png{{{ns}}}); -} -} -.mod-pedal-boxy{{{cns}}}.mod-gray h1, -.mod-pedal-boxy{{{cns}}}.mod-gray .mod-enumerated, -.mod-pedal-boxy{{{cns}}}.mod-gray .mod-control-group .mod-knob > span.mod-knob-title, -.mod-pedal-boxy{{{cns}}}.mod-none h1 -{ - color:white; -} -.mod-pedal-boxy{{{cns}}}.mod-gray h1, -{ - border-color:white; -} -/* STYLES FOR THE BOXY KNOB */ - - -/* = KNOBS -================================================ */ -.mod-pedal-boxy{{{cns}}} .mod-control-group.mod-steel .mod-knob .mod-knob-image { - background-image:url(/resources/knob-steel.png{{{ns}}}); -} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midigen.lv2/modgui/thumbnail-midi-generator.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midigen.lv2/modgui/thumbnail-midi-generator.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midimap.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midimap.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midimap.lv2/img/x42-midimap.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midimap.lv2/img/x42-midimap.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/midimap.lv2/img/x42-midimap.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/midimap.lv2/img/x42-midimap.png differ diff -Nru x42-plugins-20170428/midimap.lv2/Makefile x42-plugins-20190714/midimap.lv2/Makefile --- x42-plugins-20170428/midimap.lv2/Makefile 2016-11-07 20:23:14.000000000 +0000 +++ x42-plugins-20190714/midimap.lv2/Makefile 2019-01-23 22:24:48.000000000 +0000 @@ -1,14 +1,9 @@ #!/usr/bin/make -f - -# these can be overridden using make variables. e.g. -# make CFLAGS=-O2 -# make install DESTDIR=$(CURDIR)/debian/midimap.lv2 PREFIX=/usr -# -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s @@ -16,7 +11,7 @@ ############################################################################### LIB_EXT=.so -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm LV2NAME=midimap BUNDLE=midimap.lv2 @@ -42,6 +37,8 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) @@ -52,17 +49,16 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/midimap.lv2/src/midimap.c x42-plugins-20190714/midimap.lv2/src/midimap.c --- x42-plugins-20170428/midimap.lv2/src/midimap.c 2016-11-07 20:23:14.000000000 +0000 +++ x42-plugins-20190714/midimap.lv2/src/midimap.c 2019-01-23 22:24:48.000000000 +0000 @@ -120,9 +120,9 @@ LV2_Log_Logger logger; /* host transport */ - float transport_speed; - long transport_frame; - bool transport_rolling; + float transport_speed; + int64_t transport_frame; + bool transport_rolling; bool bpm_avail; float bpm; @@ -1014,13 +1014,23 @@ } } + LV2_State_Map_Path* map_path = NULL; + + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_STATE__mapPath)) { + map_path = (LV2_State_Map_Path*) features[i]->data; + } + } - if (!loaded) { + if (!loaded && map_path) { // try re-loading saved file (v0.1.0) value = retrieve (handle, self->uris.mem_cfgfile, &size, &type, &valflags); if (value) { - const char* fn = (const char*)value; - parse_config_file (self, fn); + char* path = map_path->absolute_path (map_path->handle, (const char*)value); + parse_config_file (self, path); +#ifndef _WIN32 // https://github.com/drobilla/lilv/issues/14 + free (path); +#endif } } diff -Nru x42-plugins-20170428/mixtri.lv2/gui/mixtri.c x42-plugins-20190714/mixtri.lv2/gui/mixtri.c --- x42-plugins-20170428/mixtri.lv2/gui/mixtri.c 2017-04-27 23:58:19.000000000 +0000 +++ x42-plugins-20190714/mixtri.lv2/gui/mixtri.c 2019-07-14 19:39:22.000000000 +0000 @@ -159,7 +159,7 @@ cairo_move_to(cr, 0, MIX_CY); cairo_line_to(cr, 60, MIX_CY); cairo_stroke(cr); -#ifndef GTK_BACKEND + cairo_move_to(cr, 6.5, MIX_CY-3.5); cairo_line_to(cr, 6.5, MIX_CY+3.5); cairo_line_to(cr, 12.5, MIX_CY); @@ -169,7 +169,7 @@ cairo_line_to(cr, 60-1.5, MIX_CY); cairo_close_path(cr); cairo_fill(cr); -#endif + AMPLABEL( 0, 60., 80., 30.5); write_text_full(cr, " 0dB", font, xlp, ylp, 0, 2, c_wht); AMPLABEL( 20, 60., 80., 30.5); write_text_full(cr, "+20", font, xlp, ylp, 0, 2, c_wht); AMPLABEL(-60, 60., 80., 30.5); write_text_full(cr, "-60", font, xlp, ylp, 0, 2, c_wht); @@ -262,7 +262,6 @@ annotation_txt(ui, d, cr, tmp); } -#ifndef GTK_BACKEND static bool box_expose_event(RobWidget* rw, cairo_t* cr, cairo_rectangle_t *ev) { if (rw->resized) { cairo_rectangle_t event; @@ -332,7 +331,6 @@ } return rcontainer_expose_event_no_clear(rw, cr, ev); } -#endif static void draw_arrow (cairo_t *cr, float x, float y, bool down) { cairo_save(cr); @@ -1087,9 +1085,7 @@ robtk_lbl_set_color(ui->label[7], .6, .6, .6, 1.0); ui->ctable = rob_table_new(/*rows*/7, /*cols*/ 9, FALSE); -#ifndef GTK_BACKEND ui->ctable->expose_event = box_expose_event; -#endif rob_table_attach(ui->ctable, robtk_lbl_widget(ui->label[0]), 1, 2, 0, 1, 0, 0, RTK_EXANDF, RTK_SHRINK); @@ -1172,16 +1168,17 @@ ui->spb_delay_in[i] = robtk_spin_new(0, MAXDELAY-1, 1); ui->spb_delay_in[i]->dial->displaymode = 3; + robtk_lbl_set_text(ui->spb_delay_in[i]->lbl_r, "000000"); robtk_spin_set_default(ui->spb_delay_in[i], 0); robtk_spin_set_value(ui->spb_delay_in[i], 0); robtk_spin_set_callback(ui->spb_delay_in[i], cb_set_delay, ui); robtk_spin_label_width(ui->spb_delay_in[i], -1, MIX_WIDTH - GSP_WIDTH - 8); -#ifndef GTK_BACKEND + robtk_dial_set_surface(ui->spb_delay_in[i]->dial,ui->delayI); robtk_lbl_set_alignment(ui->spb_delay_in[i]->lbl_r, 0, 0.3); robtk_dial_set_alignment(ui->spb_delay_in[i]->dial, .5, 1.0); ui->spb_delay_in[i]->rw->yalign = .45; -#endif + rob_table_attach(ui->ctable, robtk_spin_widget(ui->spb_delay_in[i]), 1, 2, i+1, i+2, 0, 0, RTK_EXANDF, RTK_SHRINK); } @@ -1199,10 +1196,8 @@ robtk_spin_set_callback(ui->spb_delay_out[i], cb_set_delay, ui); robtk_spin_set_default(ui->spb_delay_out[i], 0); robtk_spin_set_value(ui->spb_delay_out[i], 0); -#ifndef GTK_BACKEND robtk_dial_set_surface(ui->spb_delay_out[i]->dial,ui->delayO); robtk_lbl_set_alignment(ui->spb_delay_out[i]->lbl_r, 0, 0.3); -#endif robtk_spin_label_width(ui->spb_delay_out[i], -1, MIX_WIDTH - GSP_WIDTH - 8); rob_table_attach(ui->ctable, robtk_spin_widget(ui->spb_delay_out[i]), i+5, i+6, 5, 6, 0, 0, RTK_EXANDF, RTK_SHRINK); diff -Nru x42-plugins-20170428/mixtri.lv2/Makefile x42-plugins-20190714/mixtri.lv2/Makefile --- x42-plugins-20170428/mixtri.lv2/Makefile 2017-04-27 23:58:19.000000000 +0000 +++ x42-plugins-20190714/mixtri.lv2/Makefile 2019-07-14 19:39:22.000000000 +0000 @@ -12,10 +12,11 @@ OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CFLAGS ?= -Wall -Wno-unused-function + +PKG_CONFIG?=pkg-config STRIP ?= strip EXTERNALUI?=yes -BUILDGTK?=no KXURI?=yes mixtri_VERSION?=$(shell git describe --tags HEAD | sed 's/-g.*$$//;s/^v//' || echo "LV2") @@ -29,7 +30,6 @@ LV2NAME=mixtri LV2GUI=mixtriUI_gl -LV2GTK=mixtriUI_gtk ######### @@ -37,7 +37,6 @@ LV2CFLAGS=$(CFLAGS) -I. -DMIXTRILV2 JACKCFLAGS=$(CFLAGS) -I. GLUICFLAGS=-I. -GTKUICFLAGS=-I. UNAME=$(shell uname) ifeq ($(UNAME),Darwin) @@ -48,7 +47,6 @@ PUGL_SRC=$(RW)pugl/pugl_osx.m PKG_GL_LIBS= GLUILIBS=-framework Cocoa -framework OpenGL -framework CoreFoundation - BUILDGTK=no STRIPFLAGS=-u -r -arch all -s $(RW)lv2syms EXTENDED_RE=-E else @@ -59,7 +57,7 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_GL_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` -pthread + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` -pthread STRIPFLAGS=-s EXTENDED_RE=-r endif @@ -74,7 +72,6 @@ PKG_GL_LIBS= UI_TYPE=ui:WindowsUI GLUILIBS=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread - BUILDGTK=no GLUICFLAGS=-I. override LDFLAGS += -static-libgcc -static-libstdc++ endif @@ -91,23 +88,12 @@ endif endif -#ifeq ($(BUILDOPENGL)$(BUILDGTK), nono) -# $(error at least one of gtk or openGL needs to be enabled) -#endif - targets=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) ifneq ($(BUILDOPENGL), no) targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) endif -ifneq ($(BUILDGTK), no) -targets+=$(BUILDDIR)$(LV2GTK)$(LIB_EXT) -PKG_GTK_LIBS=glib-2.0 gtk+-2.0 -else -PKG_GTK_LIBS= -endif - ############################################################################### # extract versions LV2VERSION=$(mixtri_VERSION) @@ -116,28 +102,28 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --exists ltc || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists ltc || echo no), no) $(error "libltc was not found - https://x42.github.io/libltc/") endif -ifeq ($(shell pkg-config --atleast-version=1.6.0 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) $(error "LV2 SDK needs to be version 1.6.0 or later") endif -ifeq ($(shell pkg-config --exists pango cairo $(PKG_GTK_LIBS) $(PKG_GL_LIBS) || echo no), no) - $(error "This plugin requires cairo pango $(PKG_GTK_LIBS) $(PKG_GL_LIBS)") +ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif -ifeq ($(shell pkg-config --exists jack || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif @@ -155,11 +141,10 @@ # lv2 >= 1.6.0 GLUICFLAGS+=-DHAVE_IDLE_IFACE -GTKUICFLAGS+=-DHAVE_IDLE_IFACE LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; # add library dependent flags and libs -LV2CFLAGS += `pkg-config --cflags lv2 ltc` +LV2CFLAGS += `$(PKG_CONFIG) --cflags lv2 ltc` LV2CFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(mixtri_VERSION)\"" ifeq ($(XWIN),) LV2CFLAGS += -fPIC -fvisibility=hidden @@ -167,13 +152,10 @@ LV2CFLAGS += -DPTW32_STATIC_LIB endif -LOADLIBES=`pkg-config $(PKG_UI_FLAGS) --libs ltc` -lm - -GTKUICFLAGS+= $(LV2CFLAGS) `pkg-config --cflags gtk+-2.0 cairo pango` -GTKUILIBS+=`pkg-config --libs gtk+-2.0 cairo pango` +LOADLIBES=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs ltc` -lm -GLUICFLAGS+= $(LV2CFLAGS) `pkg-config --cflags cairo pango` -GLUILIBS+=`pkg-config $(PKG_UI_FLAGS) --libs cairo pangocairo pango $(PKG_GL_LIBS)` +GLUICFLAGS+= $(LV2CFLAGS) `$(PKG_CONFIG) --cflags cairo pango` +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango $(PKG_GL_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 endif @@ -187,8 +169,6 @@ endif ROBGL+= Makefile -ROBGTK += Makefile - ############################################################################### # build target definitions @@ -217,22 +197,12 @@ @mkdir -p $(BUILDDIR) sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/g" \ lv2ttl/manifest.ttl.in > $(BUILDDIR)manifest.ttl -ifneq ($(BUILDOPENGL), no) sed "s/@INSTANCE@/lv2/g;s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/g;s/@URI_SUFFIX@//g" \ lv2ttl/manifest.lv2.ttl.in >> $(BUILDDIR)manifest.ttl +ifneq ($(BUILDOPENGL), no) sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@LV2GUI@/$(LV2GUI)/g" \ lv2ttl/manifest.gl.ttl.in >> $(BUILDDIR)manifest.ttl endif -ifneq ($(BUILDGTK), no) - sed "s/@INSTANCE@/lv2/g;s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/g;s/@URI_SUFFIX@/_gtk/g" \ - lv2ttl/manifest.lv2.ttl.in >> $(BUILDDIR)manifest.ttl - sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/g;s/@LV2GTK@/$(LV2GTK)/g" \ - lv2ttl/manifest.gtk.ttl.in >> $(BUILDDIR)manifest.ttl -endif -ifeq ($(BUILDOPENGL)$(BUILDGTK), nono) - sed "s/@INSTANCE@/lv2/g;s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/g;s/@URI_SUFFIX@//g" \ - lv2ttl/manifest.lv2.ttl.in >> $(BUILDDIR)manifest.ttl -endif $(BUILDDIR)$(LV2NAME).ttl: lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).lv2.ttl.in lv2ttl/$(LV2NAME).gui.ttl.in Makefile @@ -244,19 +214,11 @@ lv2ttl/$(LV2NAME).gui.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl sed "s/@INSTANCE@/lv2/g;s/@LV2NAME@/$(LV2NAME)/g;s/@URI_SUFFIX@//g;s/@NAME_SUFFIX@//g;s/@UIDEF@/ui:ui/;s/@UI@/ui_gl/g;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ lv2ttl/$(LV2NAME).lv2.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl -endif -ifneq ($(BUILDGTK), no) - sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_URI_SUFFIX@/_gtk/;s/@UI_TYPE@/ui:GtkUI/;s/@UI_REQ@//;s/@URI_SUFFIX@/_gtk/g" \ - lv2ttl/$(LV2NAME).gui.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl - sed "s/@INSTANCE@/lv2/g;s/@LV2NAME@/$(LV2NAME)/g;s/@URI_SUFFIX@/_gtk/g;s/@NAME_SUFFIX@/ GTK/g;s/@UIDEF@/ui:ui/;s/@UI@/ui_gtk/g;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ - lv2ttl/$(LV2NAME).lv2.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl -endif -ifeq ($(BUILDOPENGL)$(BUILDGTK), nono) +else sed "s/@INSTANCE@/lv2/g;s/@LV2NAME@/$(LV2NAME)/g;s/@URI_SUFFIX@//g;s/@NAME_SUFFIX@//g;s/@UIDEF@/#/;s/@UI@//g;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ lv2ttl/$(LV2NAME).lv2.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl endif - $(BUILDDIR)$(LV2NAME)$(LIB_EXT): src/mixtri.c src/mixtri.h @mkdir -p $(BUILDDIR) $(CC) $(CPPFLAGS) $(LV2CFLAGS) -std=c99 \ @@ -265,8 +227,8 @@ $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) JACKCFLAGS=-I. $(LV2CFLAGS) $(CFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo ltc $(PKG_GL_LIBS)` -JACKLIBS=-lm $(GLUILIBS) $(LIC_LOADLIBES) `pkg-config $(PKG_UI_FLAGS) --libs ltc` +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo ltc $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs ltc` $(eval x42_mixtri_JACKSRC = src/mixtri.c) x42_mixtri_JACKGUI = gui/mixtri.c @@ -278,7 +240,6 @@ -include $(RW)robtk.mk -$(BUILDDIR)$(LV2GTK)$(LIB_EXT): gui/mixtri.c src/mixtri.h $(BUILDDIR)$(LV2GUI)$(LIB_EXT): gui/mixtri.c src/mixtri.h ############################################################################### @@ -295,9 +256,6 @@ ifneq ($(BUILDOPENGL), no) install -m755 $(BUILDDIR)$(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) endif -ifneq ($(BUILDGTK), no) - install -m755 $(BUILDDIR)$(LV2GTK)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) -endif install -d $(DESTDIR)$(BINDIR) install -m755 $(APPBLD)x42-mixtri$(EXE_EXT) $(DESTDIR)$(BINDIR) @@ -306,7 +264,6 @@ rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME).ttl rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME)$(LIB_EXT) rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2GUI)$(LIB_EXT) - rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2GTK)$(LIB_EXT) rm -f $(DESTDIR)$(BINDIR)/x42-mixtri$(EXE_EXT) -rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE) -rmdir $(DESTDIR)$(BINDIR) @@ -326,7 +283,6 @@ rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl \ $(BUILDDIR)$(LV2NAME)$(LIB_EXT) \ $(BUILDDIR)$(LV2GUI)$(LIB_EXT) \ - $(BUILDDIR)$(LV2GTK)$(LIB_EXT) rm -rf $(BUILDDIR)*.dSYM rm -rf $(APPBLD)x42-* -test -d $(APPBLD) && rmdir $(APPBLD) || true diff -Nru x42-plugins-20170428/mixtri.lv2/x42-mixtri.1 x42-plugins-20190714/mixtri.lv2/x42-mixtri.1 --- x42-plugins-20170428/mixtri.lv2/x42-mixtri.1 2017-04-27 23:58:19.000000000 +0000 +++ x42-plugins-20190714/mixtri.lv2/x42-mixtri.1 2019-07-14 19:39:22.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH X42-MIXTRI "1" "April 2017" "x42-mixtri version 0.2.8" "User Commands" +.TH X42-MIXTRI "1" "July 2019" "x42-mixtri version 0.3.3" "User Commands" .SH NAME x42-mixtri \- JACK Mixer'n'Trigger .SH SYNOPSIS @@ -33,6 +33,9 @@ Set the JACK client name (defaults to plugin\-name) .TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP \fB\-O\fR , \fB\-\-osc\fR Listen for OSC messages on the given UDP port .TP @@ -51,7 +54,7 @@ See also: Website: .SH COPYRIGHT -Copyright \(co GPL 2013\-2015 Robin Gareus +Copyright \(co GPL 2013\-2019 Robin Gareus .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/nodelay.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/nodelay.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/nodelay.lv2/img/x42-nodelay.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/nodelay.lv2/img/x42-nodelay.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/nodelay.lv2/img/x42-nodelay.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/nodelay.lv2/img/x42-nodelay.png differ diff -Nru x42-plugins-20170428/nodelay.lv2/Makefile x42-plugins-20190714/nodelay.lv2/Makefile --- x42-plugins-20170428/nodelay.lv2/Makefile 2016-09-29 22:40:43.000000000 +0000 +++ x42-plugins-20190714/nodelay.lv2/Makefile 2019-05-04 22:58:37.000000000 +0000 @@ -1,14 +1,9 @@ #!/usr/bin/make -f - -# these can be overridden using make variables. e.g. -# make CFLAGS=-O2 -# make install DESTDIR=$(CURDIR)/debian/nodelay.lv2 PREFIX=/usr -# -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s @@ -16,7 +11,7 @@ ############################################################################### LIB_EXT=.so -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm LV2NAME=nodelay BUNDLE=nodelay.lv2 @@ -42,6 +37,8 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) @@ -52,12 +49,11 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/nodelay.lv2/nodelay.c x42-plugins-20190714/nodelay.lv2/nodelay.c --- x42-plugins-20170428/nodelay.lv2/nodelay.c 2016-09-29 22:40:43.000000000 +0000 +++ x42-plugins-20190714/nodelay.lv2/nodelay.c 2019-05-04 22:58:37.000000000 +0000 @@ -105,11 +105,14 @@ NoDelay* self = (NoDelay*)instance; uint32_t pos = 0; - float delay = MAX(0, MIN((MAXDELAY - 1), *(self->delay))); + const float delay_ctrl = MAX(0, MIN((MAXDELAY - 1), *(self->delay))); + int mode = rint (*self->report_latency); + + float delay = delay_ctrl; const float* const input = self->input; float* const output = self->output; - if (*self->report_latency > 1.5) { + if (mode >= 2) { delay = 0; } @@ -140,10 +143,17 @@ INCREMENT_PTRS; } } - if (*self->report_latency > 0.5) { - *(self->latency) = (float)self->c_dly; - } else { - *(self->latency) = 0; + + switch (mode) { + case 0: + *(self->latency) = 0.f; + break; + case 2: + *(self->latency) = delay_ctrl; + break; + default: + *(self->latency) = (float)self->c_dly; + break; } for (; pos < n_samples; pos++) { @@ -159,7 +169,7 @@ free(instance); } -const void* +static const void* extension_data(const char* uri) { return NULL; diff -Nru x42-plugins-20170428/nodelay.lv2/nodelay.ttl.in x42-plugins-20190714/nodelay.lv2/nodelay.ttl.in --- x42-plugins-20170428/nodelay.lv2/nodelay.ttl.in 2016-09-29 22:40:43.000000000 +0000 +++ x42-plugins-20190714/nodelay.lv2/nodelay.ttl.in 2019-05-04 22:58:37.000000000 +0000 @@ -12,7 +12,7 @@ foaf:homepage . - a lv2:Plugin, doap:Project; + a lv2:Plugin, doap:Project, lv2:UtilityPlugin; doap:license ; doap:maintainer ; doap:name "No Delay Line"; diff -Nru x42-plugins-20170428/onsettrigger.lv2/lv2ttl/onsettrigger.lv2.in x42-plugins-20190714/onsettrigger.lv2/lv2ttl/onsettrigger.lv2.in --- x42-plugins-20170428/onsettrigger.lv2/lv2ttl/onsettrigger.lv2.in 2016-09-29 20:33:55.000000000 +0000 +++ x42-plugins-20190714/onsettrigger.lv2/lv2ttl/onsettrigger.lv2.in 2019-05-04 23:01:39.000000000 +0000 @@ -5,9 +5,8 @@ doap:maintainer ; doap:name "Onset Trigger - Bassdrum Detection Mono@NAME_SUFFIX@"; @VERSION@ + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; - lv2:microVersion 0 ; - lv2:minorVersion 5 ; lv2:port [ a atom:AtomPort , @@ -142,9 +141,8 @@ doap:maintainer ; doap:name "Onset Trigger - Bassdrum Detection Stereo@NAME_SUFFIX@"; @VERSION@ + lv2:requiredFeature urid:map ; lv2:optionalFeature lv2:hardRTCapable ; - lv2:microVersion 0 ; - lv2:minorVersion 5 ; lv2:port [ a atom:AtomPort , diff -Nru x42-plugins-20170428/onsettrigger.lv2/Makefile x42-plugins-20190714/onsettrigger.lv2/Makefile --- x42-plugins-20170428/onsettrigger.lv2/Makefile 2016-09-29 20:33:55.000000000 +0000 +++ x42-plugins-20190714/onsettrigger.lv2/Makefile 2019-05-04 23:01:39.000000000 +0000 @@ -1,24 +1,21 @@ #!/usr/bin/make -f - -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local -CFLAGS ?= -Wall -Wno-unused-function -LIBDIR ?= lib +CFLAGS ?= $(OPTIMIZATIONS) -Wall -Wno-unused-function +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s -override CFLAGS += -g $(OPTIMIZATIONS) -BUILDDIR=build/ onsettrigger_VERSION?=$(shell git describe --tags HEAD 2>/dev/null | sed 's/-g.*$$//;s/^v//' || echo "LV2") ############################################################################### LIB_EXT=.so -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm - LV2NAME=onsettrigger BUNDLE=onsettrigger.lv2 +BUILDDIR=build/ targets= ######### @@ -46,9 +43,10 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif - targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) ############################################################################### @@ -57,12 +55,11 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS +=-fPIC -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/onsettrigger.lv2/src/spectr.c x42-plugins-20190714/onsettrigger.lv2/src/spectr.c --- x42-plugins-20170428/onsettrigger.lv2/src/spectr.c 2016-09-29 20:33:55.000000000 +0000 +++ x42-plugins-20190714/onsettrigger.lv2/src/spectr.c 2019-05-04 23:01:39.000000000 +0000 @@ -25,12 +25,22 @@ #include #include -#if __cplusplus >= 201103L || (defined __cplusplus && defined __APPLE__) +#if __cplusplus >= 201103L || ((defined __APPLE__ || defined __FreeBSD__) && defined __cplusplus) # include # define csqrt(XX) std::sqrt(XX) # define creal(XX) std::real(XX) # define cimag(XX) std::imag(XX) -# define _I ((complex_t)(1i)) + +# ifdef __cpp_lib_complex_udls + using namespace std::literals::complex_literals; +# endif + +# if defined __clang_major__ && __clang_major__ > 4 +# define _I (std::complex(0.0,1.0)) +# else +# define _I ((complex_t)(1i)) +# endif + typedef std::complex complex_t; #else # include @@ -58,11 +68,11 @@ static inline double proc_one(struct Filter * const f, const double in) { - const double w = in - f->W[a1]*f->z[z1] - f->W[a2]*f->z[z2]; - const double out = f->W[b0]*w + f->W[b1]*f->z[z1] + f->W[b2]*f->z[z2]; - f->z[z2] = f->z[z1]; - f->z[z1] = w; - return out; + + const double y = f->W[b0] * in + f->z[z1]; + f->z[z1] = f->W[b1] * in - f->W[a1] * y + f->z[z2]; + f->z[z2] = f->W[b2] * in - f->W[a2] * y; + return y; } static inline float @@ -111,7 +121,6 @@ rate * wu * .5 / M_PI); } if (wl < 1e-9) { - /* this is just for completeness, it cannot happen with spectr.lv2 */ wl = 1e-9; fprintf(stderr, "onsettrigger.lv2: band f:%9.2fHz (%.2fHz -> %.2fHz) contains sub-bass frequencies\n", freq, freq-band/2, freq+band/2); @@ -185,6 +194,7 @@ fb->f[0].W[b2] *= creal(scale); #ifdef DEBUG_SPECTR + printf("CFG SR:%f FQ:%f BW:%f O:%d\n", rate, freq, band, order); printf("SCALE (%g, %g)\n", creal(scale), cimag(scale)); for (uint32_t i = 0; i < fb->filter_stages; ++i) { struct Filter *flt = &fb->f[i]; diff -Nru x42-plugins-20170428/plugin.list x42-plugins-20190714/plugin.list --- x42-plugins-20170428/plugin.list 2016-08-21 19:04:19.000000000 +0000 +++ x42-plugins-20190714/plugin.list 2019-07-14 19:53:50.000000000 +0000 @@ -1,8 +1,13 @@ git://github.com/x42/balance.lv2 +git://github.com/x42/controlfilter.lv2 git://github.com/x42/convoLV2 +git://github.com/x42/darc.lv2 +git://github.com/x42/dpl.lv2 git://github.com/x42/fat1.lv2 git://github.com/x42/fil4.lv2 +git://github.com/x42/matrixmixer.lv2 git://github.com/x42/meters.lv2 +git://github.com/x42/mididebug.lv2 git://github.com/x42/midifilter.lv2 git://github.com/x42/midigen.lv2 git://github.com/x42/midimap.lv2 @@ -11,6 +16,7 @@ git://github.com/x42/onsettrigger.lv2 git://github.com/x42/robtk git://github.com/x42/sisco.lv2 +git://github.com/x42/spectra.lv2 git://github.com/x42/stepseq.lv2 git://github.com/x42/stereoroute.lv2 git://github.com/x42/testsignal.lv2 diff -Nru x42-plugins-20170428/plugin.versions x42-plugins-20190714/plugin.versions --- x42-plugins-20170428/plugin.versions 2017-04-28 00:05:02.000000000 +0000 +++ x42-plugins-20190714/plugin.versions 2019-07-14 19:54:00.000000000 +0000 @@ -1,19 +1,24 @@ -balance.lv2 v0.6.5 -controlfilter.lv2 v0.3.1 -convoLV2 v0.5.3 -fat1.lv2 v0.3.3 -fil4.lv2 v0.5.5 -meters.lv2 v0.9.4 -midifilter.lv2 v0.4.7 -midigen.lv2 v0.2.2 -midimap.lv2 v0.3.0 -mixtri.lv2 v0.2.8 -nodelay.lv2 v0.3.0 -onsettrigger.lv2 v0.2.4 -robtk v0.5.3 -sisco.lv2 v0.7.2 -stepseq.lv2 v0.4.1 -stereoroute.lv2 v0.1.1 -testsignal.lv2 v0.4.0 -tuna.lv2 v0.4.3 -xfade.lv2 v0.2.4 +balance.lv2 v0.6.7 +controlfilter.lv2 v0.4.0 +convoLV2 v0.6.4 +darc.lv2 v0.4.2 +dpl.lv2 v0.3.3 +fat1.lv2 v0.5.4 +fil4.lv2 v0.6.6 +matrixmixer.lv2 v0.2.4 +meters.lv2 v0.9.12 +mididebug.lv2 v0.3.0 +midifilter.lv2 v0.5.4 +midigen.lv2 v0.2.5 +midimap.lv2 v0.3.3 +mixtri.lv2 v0.3.3 +nodelay.lv2 v0.4.0 +onsettrigger.lv2 v0.4.0 +robtk v0.6.5 +sisco.lv2 v0.8.3 +spectra.lv2 v0.4.1 +stepseq.lv2 v0.5.5 +stereoroute.lv2 v0.2.0 +testsignal.lv2 v0.5.3 +tuna.lv2 v0.4.14 +xfade.lv2 v0.3.0 diff -Nru x42-plugins-20170428/robtk/gl/layout.h x42-plugins-20190714/robtk/gl/layout.h --- x42-plugins-20170428/robtk/gl/layout.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/gl/layout.h 2019-07-14 19:08:03.000000000 +0000 @@ -257,14 +257,25 @@ static bool rcontainer_expose_event(RobWidget* rw, cairo_t* cr, cairo_rectangle_t *ev) { if (rw->resized) { +#if 0 cairo_rectangle_t event; event.x = MAX(0, ev->x - rw->area.x); event.y = MAX(0, ev->y - rw->area.y); - event.width = MIN(rw->area.x + rw->area.width , ev->x + ev->width) - MAX(ev->x, rw->area.x); + event.width = MIN(rw->area.x + rw->area.width , ev->x + ev->width) - MAX(ev->x, rw->area.x); event.height = MIN(rw->area.y + rw->area.height, ev->y + ev->height) - MAX(ev->y, rw->area.y); cairo_save(cr); rcontainer_clear_bg(rw, cr, &event); cairo_restore(cr); +#else + cairo_save(cr); + cairo_rectangle_t event; + event.x = 0; + event.y = 0; + event.width = rw->area.width; + event.height = rw->area.height; + rcontainer_clear_bg(rw, cr, &event); + cairo_restore(cr); +#endif } return rcontainer_expose_event_no_clear(rw, cr, ev); } diff -Nru x42-plugins-20170428/robtk/jackwrap.c x42-plugins-20190714/robtk/jackwrap.c --- x42-plugins-20170428/robtk/jackwrap.c 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/jackwrap.c 2019-07-14 19:08:03.000000000 +0000 @@ -1,6 +1,6 @@ /* x42 jack wrapper / minimal LV2 host * - * Copyright (C) 2012-2014 Robin Gareus + * Copyright (C) 2012-2019 Robin Gareus * * 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 @@ -16,7 +16,6 @@ * along with this program. If not, see . */ - #ifndef UPDATE_FREQ_RATIO #define UPDATE_FREQ_RATIO 60 // MAX # of audio-cycles per GUI-refresh #endif @@ -44,29 +43,29 @@ #endif #ifdef WIN32 -#include #include +#include #define pthread_t //< override jack.h def #endif #ifdef __APPLE__ #include -extern void rtk_osx_api_init(void); -extern void rtk_osx_api_terminate(void); -extern void rtk_osx_api_run(void); -extern void rtk_osx_api_err(const char *msg); +extern void rtk_osx_api_init (void); +extern void rtk_osx_api_terminate (void); +extern void rtk_osx_api_run (void); +extern void rtk_osx_api_err (const char* msg); #endif -#include +#include #include -#include +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include +#include #if (defined _WIN32 && defined RTK_STATIC_INIT) #include @@ -82,58 +81,58 @@ #include "weakjack/weak_libjack.h" #else #include -#include #include +#include #endif #undef pthread_t -#include "lv2/lv2plug.in/ns/lv2core/lv2.h" -#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" -#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h" -#include "lv2/lv2plug.in/ns/ext/urid/urid.h" #include "lv2/lv2plug.in/ns/ext/atom/atom.h" #include "lv2/lv2plug.in/ns/ext/atom/forge.h" #include "lv2/lv2plug.in/ns/ext/midi/midi.h" #include "lv2/lv2plug.in/ns/ext/time/time.h" +#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" #include "lv2/lv2plug.in/ns/ext/worker/worker.h" +#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" #include "./gl/xternalui.h" #ifndef WIN32 -#include #include +#include #endif -#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr) -#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr) -#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr) +#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run (ptr) +#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show (ptr) +#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide (ptr) #define nan NAN #ifndef UINT32_MAX -# define UINT32_MAX (4294967295U) +#define UINT32_MAX (4294967295U) #endif -static const LV2_Descriptor* plugin_dsp; -static const LV2UI_Descriptor *plugin_gui; +static const LV2_Descriptor* plugin_dsp; +static const LV2UI_Descriptor* plugin_gui; -static LV2_Handle plugin_instance = NULL; -static LV2UI_Handle gui_instance = NULL; +static LV2_Handle plugin_instance = NULL; +static LV2UI_Handle gui_instance = NULL; -static float *plugin_ports_pre = NULL; -static float *plugin_ports_post = NULL; +static float* plugin_ports_pre = NULL; +static float* plugin_ports_post = NULL; -static LV2_Atom_Sequence *atom_in = NULL; -static LV2_Atom_Sequence *atom_out = NULL; +static LV2_Atom_Sequence* atom_in = NULL; +static LV2_Atom_Sequence* atom_out = NULL; -static jack_port_t **input_port = NULL; -static jack_port_t **output_port = NULL; +static jack_port_t** input_port = NULL; +static jack_port_t** output_port = NULL; -static jack_port_t *midi_in = NULL; -static jack_port_t *midi_out = NULL; +static jack_port_t* midi_in = NULL; +static jack_port_t* midi_out = NULL; -static jack_client_t *j_client = NULL; -static uint32_t j_samplerate = 48000; +static jack_client_t* j_client = NULL; +static uint32_t j_samplerate = 48000; static int _freewheeling = 0; @@ -141,20 +140,20 @@ jack_nframes_t position; float bpm; bool rolling; -} j_transport = {0, 0, false}; +} j_transport = { 0, 0, false }; -static jack_ringbuffer_t *rb_ctrl_to_ui = NULL; -static jack_ringbuffer_t *rb_ctrl_from_ui = NULL; -static jack_ringbuffer_t *rb_atom_to_ui = NULL; -static jack_ringbuffer_t *rb_atom_from_ui = NULL; +static jack_ringbuffer_t* rb_ctrl_to_ui = NULL; +static jack_ringbuffer_t* rb_ctrl_from_ui = NULL; +static jack_ringbuffer_t* rb_atom_to_ui = NULL; +static jack_ringbuffer_t* rb_atom_from_ui = NULL; #ifdef HAVE_LIBLO #include -lo_server_thread osc_server = NULL; -static jack_ringbuffer_t *rb_osc_to_ui = NULL; +lo_server_thread osc_server = NULL; +static jack_ringbuffer_t* rb_osc_to_ui = NULL; typedef struct _osc_midi_event { - size_t size; + size_t size; uint8_t buffer[3]; } osc_midi_event_t; @@ -163,27 +162,28 @@ #endif static osc_midi_event_t event_queue[OSC_MIDI_QUEUE_SIZE]; + static int queued_events_start = 0; -static int queued_events_end = 0; +static int queued_events_end = 0; #endif static pthread_mutex_t gui_thread_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER; +static pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER; -static uint32_t uri_midi_MidiEvent = 0; -static uint32_t uri_atom_Sequence = 0; +static uint32_t uri_midi_MidiEvent = 0; +static uint32_t uri_atom_Sequence = 0; static uint32_t uri_atom_EventTransfer = 0; -static uint32_t uri_time_Position = 0; -static uint32_t uri_time_frame = 0; -static uint32_t uri_time_speed = 0; -static uint32_t uri_time_bar = 0; -static uint32_t uri_time_barBeat = 0; -static uint32_t uri_time_beatUnit = 0; -static uint32_t uri_time_beatsPerBar = 0; +static uint32_t uri_time_Position = 0; +static uint32_t uri_time_frame = 0; +static uint32_t uri_time_speed = 0; +static uint32_t uri_time_bar = 0; +static uint32_t uri_time_barBeat = 0; +static uint32_t uri_time_beatUnit = 0; +static uint32_t uri_time_beatsPerBar = 0; static uint32_t uri_time_beatsPerMinute = 0; -static char **urimap = NULL; +static char** urimap = NULL; static uint32_t urimap_len = 0; enum PortType { @@ -199,10 +199,10 @@ struct DelayBuffer { jack_latency_range_t port_latency; - int wanted_delay; - int c_dly; // current delay - int w_ptr; - int r_ptr; + int wanted_delay; + int c_dly; // current delay + int w_ptr; + int r_ptr; float out_buffer[MAXPERIOD]; float delay_buffer[MAXDELAY]; }; @@ -213,23 +213,23 @@ }; struct LV2Port { - const char *name; + const char* name; enum PortType porttype; - float val_default; - float val_min; - float val_max; - const char *doc; + float val_default; + float val_min; + float val_max; + const char* doc; }; typedef struct _RtkLv2Description { - const LV2_Descriptor* (*lv2_descriptor)(uint32_t index); - const LV2UI_Descriptor* (*lv2ui_descriptor)(uint32_t index); + const LV2_Descriptor* (*lv2_descriptor) (uint32_t index); + const LV2UI_Descriptor* (*lv2ui_descriptor) (uint32_t index); const uint32_t dsp_descriptor_id; const uint32_t gui_descriptor_id; - const char *plugin_human_id; + const char* plugin_human_id; - const struct LV2Port *ports; + const struct LV2Port* ports; const uint32_t nports_total; const uint32_t nports_audio_in; @@ -246,7 +246,7 @@ const uint32_t latency_ctrl_port; } RtkLv2Description; -static RtkLv2Description const *inst; +static RtkLv2Description const* inst; /* a simple state machine for this client */ static volatile enum { @@ -255,55 +255,55 @@ } client_state = Run; static struct lv2_external_ui_host extui_host; -static struct lv2_external_ui *extui = NULL; +static struct lv2_external_ui* extui = NULL; static LV2UI_Controller controller = NULL; static LV2_Atom_Forge lv2_forge; -static uint32_t *portmap_a_in; -static uint32_t *portmap_a_out; -static uint32_t *portmap_rctl; -static uint32_t *portmap_ctrl; -static uint32_t portmap_atom_to_ui = -1; -static uint32_t portmap_atom_from_ui = -1; -static uint32_t uri_to_id(LV2_URI_Map_Callback_Data callback_data, const char* uri); +static uint32_t* portmap_a_in; +static uint32_t* portmap_a_out; +static uint32_t* portmap_rctl; +static uint32_t* portmap_ctrl; +static uint32_t portmap_atom_to_ui = -1; +static uint32_t portmap_atom_from_ui = -1; +static uint32_t uri_to_id (LV2_URI_Map_Callback_Data callback_data, const char* uri); -static jack_ringbuffer_t* worker_requests = NULL; +static jack_ringbuffer_t* worker_requests = NULL; static jack_ringbuffer_t* worker_responses = NULL; static pthread_t worker_thread; -static pthread_mutex_t worker_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t worker_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t worker_ready = PTHREAD_COND_INITIALIZER; static LV2_Worker_Interface* worker_iface = NULL; -static pthread_mutex_t port_write_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t port_write_lock = PTHREAD_MUTEX_INITIALIZER; -static struct DelayBuffer **delayline = NULL; -static uint32_t worst_capture_latency = 0; -static uint32_t plugin_latency = 0; +static struct DelayBuffer** delayline = NULL; +static uint32_t worst_capture_latency = 0; +static uint32_t plugin_latency = 0; /****************************************************************************** * Delayline for latency compensation */ #define FADE_LEN (16) -#define INCREMENT_PTRS \ - dly->r_ptr = (dly->r_ptr + 1) % MAXDELAY; \ - dly->w_ptr = (dly->w_ptr + 1) % MAXDELAY; - -static float * -delay_port (struct DelayBuffer *dly, uint32_t n_samples, float *in) -{ - uint32_t pos = 0; - const int delay = dly->wanted_delay; - const float * const input = in; - float* const output = dly->out_buffer; +#define INCREMENT_PTRS \ + dly->r_ptr = (dly->r_ptr + 1) % MAXDELAY; \ + dly->w_ptr = (dly->w_ptr + 1) % MAXDELAY; + +static float* +delay_port (struct DelayBuffer* dly, uint32_t n_samples, float* in) +{ + uint32_t pos = 0; + const int delay = dly->wanted_delay; + const float* const input = in; + float* const output = dly->out_buffer; if (dly->c_dly == delay && delay == 0) { // only copy data into buffer in case delay time changes for (; pos < n_samples; pos++) { - dly->delay_buffer[ dly->w_ptr ] = input[pos]; + dly->delay_buffer[dly->w_ptr] = input[pos]; INCREMENT_PTRS; } return in; @@ -315,41 +315,39 @@ // fade out for (; pos < fade_len; pos++) { - const float gain = (float)(fade_len - pos) / (float)fade_len; - dly->delay_buffer[ dly->w_ptr ] = input[pos]; - output[pos] = dly->delay_buffer[ dly->r_ptr ] * gain; + const float gain = (float)(fade_len - pos) / (float)fade_len; + dly->delay_buffer[dly->w_ptr] = input[pos]; + output[pos] = dly->delay_buffer[dly->r_ptr] * gain; INCREMENT_PTRS; } // update read pointer dly->r_ptr += dly->c_dly - delay; if (dly->r_ptr < 0) { - dly->r_ptr -= MAXDELAY * floor(dly->r_ptr / (float)MAXDELAY); + dly->r_ptr -= MAXDELAY * floor (dly->r_ptr / (float)MAXDELAY); } - //printf("Delay changed %d -> %d\n", dly->c_dly, delay); // DEBUG dly->r_ptr = dly->r_ptr % MAXDELAY; dly->c_dly = delay; // fade in for (; pos < 2 * fade_len; pos++) { - const float gain = (float)(pos - fade_len) / (float)fade_len; - dly->delay_buffer[ dly->w_ptr ] = input[pos]; - output[pos] = dly->delay_buffer[ dly->r_ptr ] * gain; + const float gain = (float)(pos - fade_len) / (float)fade_len; + dly->delay_buffer[dly->w_ptr] = input[pos]; + output[pos] = dly->delay_buffer[dly->r_ptr] * gain; INCREMENT_PTRS; } } for (; pos < n_samples; pos++) { - dly->delay_buffer[ dly->w_ptr ] = input[pos]; - output[pos] = dly->delay_buffer[ dly->r_ptr ]; + dly->delay_buffer[dly->w_ptr] = input[pos]; + output[pos] = dly->delay_buffer[dly->r_ptr]; INCREMENT_PTRS; } return dly->out_buffer; } - /////////////////////////// // GET INFO FROM LV2 TTL // // see lv2ttl2c // @@ -358,108 +356,106 @@ #include JACK_DESCRIPT //// /////////////////////////// - /****************************************************************************** * JACK */ -static int process (jack_nframes_t nframes, void *arg) { +static int +process (jack_nframes_t nframes, void* arg) +{ if (nframes > MAXPERIOD) { static bool warned_max_period = false; if (!warned_max_period) { warned_max_period = true; - fprintf (stderr, "Jack Period Size > %d is not supported (current %d)\n", MAXPERIOD , nframes); + fprintf (stderr, "Jack Period Size > %d is not supported (current %d)\n", MAXPERIOD, nframes); } if (inst->nports_midi_out > 0) { - void* buf = jack_port_get_buffer(midi_out, nframes); - jack_midi_clear_buffer(buf); + void* buf = jack_port_get_buffer (midi_out, nframes); + jack_midi_clear_buffer (buf); } - for (uint32_t i=0 ; i < inst->nports_audio_out; ++i) { - float * bp = (float*) jack_port_get_buffer (output_port[i], nframes); + for (uint32_t i = 0; i < inst->nports_audio_out; ++i) { + float* bp = (float*)jack_port_get_buffer (output_port[i], nframes); memset (bp, 0, nframes * sizeof (float)); } return 0; } - while (jack_ringbuffer_read_space(rb_ctrl_from_ui) >= sizeof(uint32_t) + sizeof(float)) { + while (jack_ringbuffer_read_space (rb_ctrl_from_ui) >= sizeof (uint32_t) + sizeof (float)) { uint32_t idx; - jack_ringbuffer_read(rb_ctrl_from_ui, (char*) &idx, sizeof(uint32_t)); - jack_ringbuffer_read(rb_ctrl_from_ui, (char*) &(plugin_ports_pre[idx]), sizeof(float)); + jack_ringbuffer_read (rb_ctrl_from_ui, (char*)&idx, sizeof (uint32_t)); + jack_ringbuffer_read (rb_ctrl_from_ui, (char*)&(plugin_ports_pre[idx]), sizeof (float)); } /* Get Jack transport position */ jack_position_t pos; - const bool rolling = (jack_transport_query(j_client, &pos) == JackTransportRolling); - const bool transport_changed = (rolling != j_transport.rolling - || pos.frame != j_transport.position - || ((pos.valid & JackPositionBBT) && (pos.beats_per_minute != j_transport.bpm))); + const bool rolling = (jack_transport_query (j_client, &pos) == JackTransportRolling); + const bool transport_changed = (rolling != j_transport.rolling || pos.frame != j_transport.position || ((pos.valid & JackPositionBBT) && (pos.beats_per_minute != j_transport.bpm))); /* atom buffers */ if (inst->nports_atom_in > 0 || inst->nports_midi_in > 0) { /* start Atom sequence */ - atom_in->atom.type = uri_atom_Sequence; - atom_in->atom.size = 8; - LV2_Atom_Sequence_Body *body = &atom_in->body; - body->unit = 0; // URID of unit of event time stamp LV2_ATOM__timeUnit ?? - body->pad = 0; // unused - uint8_t * seq = (uint8_t*) (body + 1); + atom_in->atom.type = uri_atom_Sequence; + atom_in->atom.size = 8; + LV2_Atom_Sequence_Body* body = &atom_in->body; + body->unit = 0; // URID of unit of event time stamp LV2_ATOM__timeUnit ?? + body->pad = 0; // unused + uint8_t* seq = (uint8_t*)(body + 1); if (transport_changed && inst->send_time_info) { uint8_t pos_buf[256]; LV2_Atom* lv2_pos = (LV2_Atom*)pos_buf; - lv2_atom_forge_set_buffer(&lv2_forge, pos_buf, sizeof(pos_buf)); - LV2_Atom_Forge* forge = &lv2_forge; + lv2_atom_forge_set_buffer (&lv2_forge, pos_buf, sizeof (pos_buf)); + LV2_Atom_Forge* forge = &lv2_forge; LV2_Atom_Forge_Frame frame; #ifdef HAVE_LV2_1_8 - lv2_atom_forge_object(&lv2_forge, &frame, 1, uri_time_Position); + lv2_atom_forge_object (&lv2_forge, &frame, 1, uri_time_Position); #else - lv2_atom_forge_blank(&lv2_forge, &frame, 1, uri_time_Position); + lv2_atom_forge_blank (&lv2_forge, &frame, 1, uri_time_Position); #endif - lv2_atom_forge_property_head(forge, uri_time_frame, 0); - lv2_atom_forge_long(forge, pos.frame); - lv2_atom_forge_property_head(forge, uri_time_speed, 0); - lv2_atom_forge_float(forge, rolling ? 1.0 : 0.0); + lv2_atom_forge_property_head (forge, uri_time_frame, 0); + lv2_atom_forge_long (forge, pos.frame); + lv2_atom_forge_property_head (forge, uri_time_speed, 0); + lv2_atom_forge_float (forge, rolling ? 1.0 : 0.0); if (pos.valid & JackPositionBBT) { - lv2_atom_forge_property_head(forge, uri_time_barBeat, 0); - lv2_atom_forge_float( - forge, pos.beat - 1 + (pos.tick / pos.ticks_per_beat)); - lv2_atom_forge_property_head(forge, uri_time_bar, 0); - lv2_atom_forge_long(forge, pos.bar - 1); - lv2_atom_forge_property_head(forge, uri_time_beatUnit, 0); - lv2_atom_forge_int(forge, pos.beat_type); - lv2_atom_forge_property_head(forge, uri_time_beatsPerBar, 0); - lv2_atom_forge_float(forge, pos.beats_per_bar); - lv2_atom_forge_property_head(forge, uri_time_beatsPerMinute, 0); - lv2_atom_forge_float(forge, pos.beats_per_minute); + lv2_atom_forge_property_head (forge, uri_time_barBeat, 0); + lv2_atom_forge_float (forge, pos.beat - 1 + (pos.tick / pos.ticks_per_beat)); + lv2_atom_forge_property_head (forge, uri_time_bar, 0); + lv2_atom_forge_long (forge, pos.bar - 1); + lv2_atom_forge_property_head (forge, uri_time_beatUnit, 0); + lv2_atom_forge_int (forge, pos.beat_type); + lv2_atom_forge_property_head (forge, uri_time_beatsPerBar, 0); + lv2_atom_forge_float (forge, pos.beats_per_bar); + lv2_atom_forge_property_head (forge, uri_time_beatsPerMinute, 0); + lv2_atom_forge_float (forge, pos.beats_per_minute); } - uint32_t size = lv2_pos->size; - uint32_t padded_size = ((sizeof(LV2_Atom_Event) + size) + 7) & (~7); + uint32_t size = lv2_pos->size; + uint32_t padded_size = ((sizeof (LV2_Atom_Event) + size) + 7) & (~7); if (inst->min_atom_bufsiz > padded_size) { //printf("send time..\n"); - LV2_Atom_Event *aev = (LV2_Atom_Event *)seq; - aev->time.frames = 0; - aev->body.size = size; - aev->body.type = lv2_pos->type; - memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(lv2_pos), size); + LV2_Atom_Event* aev = (LV2_Atom_Event*)seq; + aev->time.frames = 0; + aev->body.size = size; + aev->body.type = lv2_pos->type; + memcpy (LV2_ATOM_BODY (&aev->body), LV2_ATOM_BODY (lv2_pos), size); atom_in->atom.size += padded_size; - seq += padded_size; + seq += padded_size; } } if (gui_instance) { - while (jack_ringbuffer_read_space(rb_atom_from_ui) > sizeof(LV2_Atom)) { + while (jack_ringbuffer_read_space (rb_atom_from_ui) > sizeof (LV2_Atom)) { LV2_Atom a; - jack_ringbuffer_read(rb_atom_from_ui, (char *) &a, sizeof(LV2_Atom)); - uint32_t padded_size = atom_in->atom.size + a.size + sizeof(int64_t); + jack_ringbuffer_read (rb_atom_from_ui, (char*)&a, sizeof (LV2_Atom)); + uint32_t padded_size = atom_in->atom.size + a.size + sizeof (int64_t); if (inst->min_atom_bufsiz > padded_size) { - memset(seq, 0, sizeof(int64_t)); // LV2_Atom_Event->time - seq += sizeof(int64_t); - jack_ringbuffer_read(rb_atom_from_ui, (char *) seq, a.size); + memset (seq, 0, sizeof (int64_t)); // LV2_Atom_Event->time + seq += sizeof (int64_t); + jack_ringbuffer_read (rb_atom_from_ui, (char*)seq, a.size); seq += a.size; - atom_in->atom.size += a.size + sizeof(int64_t); + atom_in->atom.size += a.size + sizeof (int64_t); } } } @@ -468,15 +464,15 @@ #ifdef HAVE_LIBLO /*inject OSC midi events, use time 0 */ while (queued_events_end != queued_events_start) { - uint32_t size = event_queue[queued_events_end].size; - uint32_t padded_size = ((sizeof(LV2_Atom_Event) + size) + 7) & (~7); + uint32_t size = event_queue[queued_events_end].size; + uint32_t padded_size = ((sizeof (LV2_Atom_Event) + size) + 7) & (~7); if (inst->min_atom_bufsiz > padded_size) { - LV2_Atom_Event *aev = (LV2_Atom_Event *)seq; - aev->time.frames = 0; // time - aev->body.size = size; - aev->body.type = uri_midi_MidiEvent; - memcpy(LV2_ATOM_BODY(&aev->body), event_queue[queued_events_end].buffer, size); + LV2_Atom_Event* aev = (LV2_Atom_Event*)seq; + aev->time.frames = 0; // time + aev->body.size = size; + aev->body.type = uri_midi_MidiEvent; + memcpy (LV2_ATOM_BODY (&aev->body), event_queue[queued_events_end].buffer, size); atom_in->atom.size += padded_size; seq += padded_size; } @@ -486,20 +482,20 @@ #endif /* inject jack midi events */ - void* buf = jack_port_get_buffer(midi_in, nframes); - for (uint32_t i = 0; i < jack_midi_get_event_count(buf); ++i) { + void* buf = jack_port_get_buffer (midi_in, nframes); + for (uint32_t i = 0; i < jack_midi_get_event_count (buf); ++i) { jack_midi_event_t ev; - jack_midi_event_get(&ev, buf, i); + jack_midi_event_get (&ev, buf, i); - uint32_t size = ev.size; - uint32_t padded_size = ((sizeof(LV2_Atom_Event) + size) + 7) & (~7); + uint32_t size = ev.size; + uint32_t padded_size = ((sizeof (LV2_Atom_Event) + size) + 7) & (~7); if (inst->min_atom_bufsiz > padded_size) { - LV2_Atom_Event *aev = (LV2_Atom_Event *)seq; - aev->time.frames = ev.time; - aev->body.size = size; - aev->body.type = uri_midi_MidiEvent; - memcpy(LV2_ATOM_BODY(&aev->body), ev.buffer, size); + LV2_Atom_Event* aev = (LV2_Atom_Event*)seq; + aev->time.frames = ev.time; + aev->body.size = size; + aev->body.type = uri_midi_MidiEvent; + memcpy (LV2_ATOM_BODY (&aev->body), ev.buffer, size); atom_in->atom.size += padded_size; seq += padded_size; } @@ -513,7 +509,7 @@ } /* make a backup copy, to see what was changed */ - memcpy(plugin_ports_post, plugin_ports_pre, inst->nports_ctrl * sizeof(float)); + memcpy (plugin_ports_post, plugin_ports_pre, inst->nports_ctrl * sizeof (float)); /* expected transport state in next cycle */ j_transport.position = rolling ? pos.frame + nframes : pos.frame; @@ -521,31 +517,30 @@ j_transport.rolling = rolling; /* [re] connect jack audio buffers */ - for (uint32_t i=0 ; i < inst->nports_audio_out; i++) { - plugin_dsp->connect_port(plugin_instance, portmap_a_out[i], jack_port_get_buffer (output_port[i], nframes)); + for (uint32_t i = 0; i < inst->nports_audio_out; i++) { + plugin_dsp->connect_port (plugin_instance, portmap_a_out[i], jack_port_get_buffer (output_port[i], nframes)); } - for (uint32_t i=0; i < inst->nports_audio_in; i++) { + for (uint32_t i = 0; i < inst->nports_audio_in; i++) { delayline[i]->wanted_delay = worst_capture_latency - delayline[i]->port_latency.max; - plugin_dsp->connect_port( - plugin_instance, portmap_a_in[i], - delay_port(delayline[i], nframes, (float*) jack_port_get_buffer (input_port[i], nframes)) - ); + plugin_dsp->connect_port ( + plugin_instance, portmap_a_in[i], + delay_port (delayline[i], nframes, (float*)jack_port_get_buffer (input_port[i], nframes))); } /* run the plugin */ - plugin_dsp->run(plugin_instance, nframes); + plugin_dsp->run (plugin_instance, nframes); /* handle worker emit response - may amend Atom seq... */ if (worker_responses) { - uint32_t read_space = jack_ringbuffer_read_space(worker_responses); + uint32_t read_space = jack_ringbuffer_read_space (worker_responses); while (read_space) { uint32_t size = 0; - char worker_response[4096]; - jack_ringbuffer_read(worker_responses, (char*)&size, sizeof(size)); - jack_ringbuffer_read(worker_responses, worker_response, size); - worker_iface->work_response(plugin_instance, size, worker_response); - read_space -= sizeof(size) + size; + char worker_response[4096]; + jack_ringbuffer_read (worker_responses, (char*)&size, sizeof (size)); + jack_ringbuffer_read (worker_responses, worker_response, size); + worker_iface->work_response (plugin_instance, size, worker_response); + read_space -= sizeof (size) + size; } } @@ -553,62 +548,62 @@ if (gui_instance) { for (uint32_t p = 0; p < inst->nports_ctrl; p++) { - if (inst->ports[portmap_rctl[p]].porttype != CONTROL_OUT) continue; + if (inst->ports[portmap_rctl[p]].porttype != CONTROL_OUT) + continue; if (plugin_ports_pre[p] != plugin_ports_post[p]) { - if (inst->latency_ctrl_port != UINT32_MAX - && p == portmap_ctrl[inst->latency_ctrl_port]) { - plugin_latency = rintf(plugin_ports_pre[p]); + if (inst->latency_ctrl_port != UINT32_MAX && p == portmap_ctrl[inst->latency_ctrl_port]) { + plugin_latency = rintf (plugin_ports_pre[p]); // TODO handle case if there's no GUI thread to call // jack_recompute_total_latencies() } - if (jack_ringbuffer_write_space(rb_ctrl_to_ui) >= sizeof(uint32_t) + sizeof(float)) { - jack_ringbuffer_write(rb_ctrl_to_ui, (char *) &portmap_rctl[p], sizeof(uint32_t)); - jack_ringbuffer_write(rb_ctrl_to_ui, (char *) &plugin_ports_pre[p], sizeof(float)); + if (jack_ringbuffer_write_space (rb_ctrl_to_ui) >= sizeof (uint32_t) + sizeof (float)) { + jack_ringbuffer_write (rb_ctrl_to_ui, (char*)&portmap_rctl[p], sizeof (uint32_t)); + jack_ringbuffer_write (rb_ctrl_to_ui, (char*)&plugin_ports_pre[p], sizeof (float)); } } } } if (inst->nports_midi_out > 0) { - void* buf = jack_port_get_buffer(midi_out, nframes); - jack_midi_clear_buffer(buf); + void* buf = jack_port_get_buffer (midi_out, nframes); + jack_midi_clear_buffer (buf); } /* Atom sequence port-events */ - if (inst->nports_atom_out + inst->nports_midi_out > 0 && atom_out->atom.size > sizeof(LV2_Atom)) { - if (gui_instance && jack_ringbuffer_write_space(rb_atom_to_ui) >= atom_out->atom.size + 2 * sizeof(LV2_Atom)) { - LV2_Atom a = {atom_out->atom.size + (uint32_t) sizeof(LV2_Atom), 0}; - jack_ringbuffer_write(rb_atom_to_ui, (char *) &a, sizeof(LV2_Atom)); - jack_ringbuffer_write(rb_atom_to_ui, (char *) atom_out, a.size); + if (inst->nports_atom_out + inst->nports_midi_out > 0 && atom_out->atom.size > sizeof (LV2_Atom)) { + if (gui_instance && jack_ringbuffer_write_space (rb_atom_to_ui) >= atom_out->atom.size + 2 * sizeof (LV2_Atom)) { + LV2_Atom a = { atom_out->atom.size + (uint32_t)sizeof (LV2_Atom), 0 }; + jack_ringbuffer_write (rb_atom_to_ui, (char*)&a, sizeof (LV2_Atom)); + jack_ringbuffer_write (rb_atom_to_ui, (char*)atom_out, a.size); } if (inst->nports_midi_out) { - void* buf = jack_port_get_buffer(midi_out, nframes); - LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((&(atom_out)->body) + 1); // lv2_atom_sequence_begin - while((const uint8_t*)ev < ((const uint8_t*) &(atom_out)->body + (atom_out)->atom.size)) { + void* buf = jack_port_get_buffer (midi_out, nframes); + LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((&(atom_out)->body) + 1); // lv2_atom_sequence_begin + while ((const uint8_t*)ev < ((const uint8_t*)&(atom_out)->body + (atom_out)->atom.size)) { if (ev->body.type == uri_midi_MidiEvent) { - jack_midi_event_write(buf, ev->time.frames, (const uint8_t*)(ev+1), ev->body.size); + jack_midi_event_write (buf, ev->time.frames, (const uint8_t*)(ev + 1), ev->body.size); } - ev = (LV2_Atom_Event const*) /* lv2_atom_sequence_next() */ - ((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7)); + ev = (LV2_Atom_Event const*)/* lv2_atom_sequence_next() */ + ((const uint8_t*)ev + sizeof (LV2_Atom_Event) + ((ev->body.size + 7) & ~7)); } } } /* signal worker end of process run */ if (worker_iface && worker_iface->end_run) { - worker_iface->end_run(plugin_instance); + worker_iface->end_run (plugin_instance); } /* wake up UI */ if (gui_instance && ( - jack_ringbuffer_read_space(rb_ctrl_to_ui) >= sizeof(uint32_t) + sizeof(float) - || jack_ringbuffer_read_space(rb_atom_to_ui) > sizeof(LV2_Atom) + jack_ringbuffer_read_space (rb_ctrl_to_ui) >= sizeof (uint32_t) + sizeof (float) + || jack_ringbuffer_read_space (rb_atom_to_ui) > sizeof (LV2_Atom) #ifdef HAVE_LIBLO - || jack_ringbuffer_read_space(rb_osc_to_ui) >= sizeof(uint32_t) + sizeof(float) + || jack_ringbuffer_read_space (rb_osc_to_ui) >= sizeof (uint32_t) + sizeof (float) #endif - ) + ) ) { if (pthread_mutex_trylock (&gui_thread_lock) == 0) { pthread_cond_signal (&data_ready); @@ -618,17 +613,20 @@ return 0; } - -static void jack_shutdown (void *arg) { - fprintf(stderr,"recv. shutdown request from jackd.\n"); - client_state=Exit; +static void +jack_shutdown (void* arg) +{ + fprintf (stderr, "recv. shutdown request from jackd.\n"); + client_state = Exit; pthread_cond_signal (&data_ready); } -static int jack_graph_order_cb (void *arg) { +static int +jack_graph_order_cb (void* arg) +{ worst_capture_latency = 0; for (uint32_t i = 0; i < inst->nports_audio_in; i++) { - jack_port_get_latency_range(input_port[i], JackCaptureLatency, &(delayline[i]->port_latency)); + jack_port_get_latency_range (input_port[i], JackCaptureLatency, &(delayline[i]->port_latency)); if (delayline[i]->port_latency.max > worst_capture_latency) { worst_capture_latency = delayline[i]->port_latency.max; } @@ -636,16 +634,17 @@ return 0; } -static void jack_latency_cb (jack_latency_callback_mode_t mode, void *arg) { +static void +jack_latency_cb (jack_latency_callback_mode_t mode, void* arg) +{ // assume 1 -> 1 map - // TODO add systemic latency of plugin (currently no robtk plugins add latency) - jack_graph_order_cb(NULL); // update worst-case latency, delayline alignment + jack_graph_order_cb (NULL); // update worst-case latency, delayline alignment if (mode == JackCaptureLatency) { for (uint32_t i = 0; i < inst->nports_audio_out; i++) { jack_latency_range_t r; if (i < inst->nports_audio_in) { const uint32_t port_delay = worst_capture_latency - delayline[i]->port_latency.max; - jack_port_get_latency_range(input_port[i], JackCaptureLatency, &r); + jack_port_get_latency_range (input_port[i], JackCaptureLatency, &r); r.min += port_delay; r.max += port_delay; } else { @@ -653,33 +652,37 @@ } r.min += plugin_latency; r.max += plugin_latency; - jack_port_set_latency_range(output_port[i], JackCaptureLatency, &r); + jack_port_set_latency_range (output_port[i], JackCaptureLatency, &r); } } else { // JackPlaybackLatency for (uint32_t i = 0; i < inst->nports_audio_in; i++) { - const uint32_t port_delay = worst_capture_latency - delayline[i]->port_latency.max; + const uint32_t port_delay = worst_capture_latency - delayline[i]->port_latency.max; jack_latency_range_t r; if (i < inst->nports_audio_out) { - jack_port_get_latency_range(output_port[i], JackPlaybackLatency, &r); + jack_port_get_latency_range (output_port[i], JackPlaybackLatency, &r); } else { r.min = r.max = 0; } r.min += port_delay + plugin_latency; r.max += port_delay + plugin_latency; - jack_port_set_latency_range(input_port[i], JackPlaybackLatency, &r); + jack_port_set_latency_range (input_port[i], JackPlaybackLatency, &r); } } } -static void jack_freewheel_cb (int onoff, void *arg) { +static void +jack_freewheel_cb (int onoff, void* arg) +{ _freewheeling = onoff; } -static int init_jack(const char *client_name) { +static int +init_jack (const char* client_name) +{ jack_status_t status; - char* cn = strdup (client_name); + char* cn = strdup (client_name); if (strlen (cn) >= (unsigned int)jack_client_name_size () - 1) { - cn [jack_client_name_size () - 1] = '\0'; + cn[jack_client_name_size () - 1] = '\0'; } j_client = jack_client_open (cn, JackNoStartServer, &status); free (cn); @@ -694,173 +697,189 @@ fprintf (stderr, "JACK server started\n"); } if (status & JackNameNotUnique) { - client_name = jack_get_client_name(j_client); + client_name = jack_get_client_name (j_client); fprintf (stderr, "jack-client name: `%s'\n", client_name); } jack_set_process_callback (j_client, process, 0); jack_set_graph_order_callback (j_client, jack_graph_order_cb, 0); - jack_set_latency_callback(j_client, jack_latency_cb, 0); - jack_set_freewheel_callback(j_client, jack_freewheel_cb, 0); + jack_set_latency_callback (j_client, jack_latency_cb, 0); + jack_set_freewheel_callback (j_client, jack_freewheel_cb, 0); #ifndef WIN32 jack_on_shutdown (j_client, jack_shutdown, NULL); #endif - j_samplerate=jack_get_sample_rate (j_client); + j_samplerate = jack_get_sample_rate (j_client); return (0); } -static int jack_portsetup(void) { +static int +jack_portsetup (void) +{ /* Allocate data structures that depend on the number of ports. */ if (inst->nports_audio_in > 0) { - input_port = (jack_port_t **) malloc (sizeof (jack_port_t *) * inst->nports_audio_in); - delayline = (struct DelayBuffer **) calloc (inst->nports_audio_in, sizeof (struct DelayBuffer *)); + input_port = (jack_port_t**)malloc (sizeof (jack_port_t*) * inst->nports_audio_in); + delayline = (struct DelayBuffer**)calloc (inst->nports_audio_in, sizeof (struct DelayBuffer*)); } for (uint32_t i = 0; i < inst->nports_audio_in; i++) { if ((input_port[i] = jack_port_register (j_client, - inst->ports[portmap_a_in[i]].name, - JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) { + inst->ports[portmap_a_in[i]].name, + JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) { fprintf (stderr, "cannot register input port \"%s\"!\n", inst->ports[portmap_a_in[i]].name); return (-1); } - delayline[i] = (struct DelayBuffer *) calloc (1, sizeof (struct DelayBuffer)); + delayline[i] = (struct DelayBuffer*)calloc (1, sizeof (struct DelayBuffer)); } if (inst->nports_audio_out > 0) { - output_port = (jack_port_t **) malloc (sizeof (jack_port_t *) * inst->nports_audio_out); + output_port = (jack_port_t**)malloc (sizeof (jack_port_t*) * inst->nports_audio_out); } for (uint32_t i = 0; i < inst->nports_audio_out; i++) { if ((output_port[i] = jack_port_register (j_client, - inst->ports[portmap_a_out[i]].name, - JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) { + inst->ports[portmap_a_out[i]].name, + JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) { fprintf (stderr, "cannot register output port \"%s\"!\n", inst->ports[portmap_a_out[i]].name); return (-1); } } - if (inst->nports_midi_in){ + if (inst->nports_midi_in) { if ((midi_in = jack_port_register (j_client, - inst->ports[portmap_atom_from_ui].name, - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0)) == 0) { + inst->ports[portmap_atom_from_ui].name, + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0)) == 0) { fprintf (stderr, "cannot register midi input port \"%s\"!\n", inst->ports[portmap_atom_from_ui].name); return (-1); } } - if (inst->nports_midi_out){ + if (inst->nports_midi_out) { if ((midi_out = jack_port_register (j_client, - inst->ports[portmap_atom_to_ui].name, - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0)) == 0) { + inst->ports[portmap_atom_to_ui].name, + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0)) == 0) { fprintf (stderr, "cannot register midi output port \"%s\"!\n", inst->ports[portmap_atom_to_ui].name); return (-1); } } jack_graph_order_cb (NULL); // query port latencies - jack_recompute_total_latencies(j_client); + jack_recompute_total_latencies (j_client); return (0); } -static void jack_portconnect(int which) { - +static void +jack_portconnect (int which) +{ if (which & 1) { // connect audio input(s) - const char **ports = jack_get_ports(j_client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsPhysical); + const char** ports = jack_get_ports (j_client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsPhysical); for (uint32_t i = 0; i < inst->nports_audio_in && ports && ports[i]; i++) { - if (jack_connect (j_client, jack_port_name (input_port[i]), ports[i])) + if (jack_connect (j_client, ports[i], jack_port_name (input_port[i]))) break; } - if (ports) { jack_free(ports); } + if (ports) { + jack_free (ports); + } } if (which & 2) { // connect audio outputs(s) - const char **ports = jack_get_ports(j_client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput|JackPortIsPhysical); + const char** ports = jack_get_ports (j_client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsPhysical); for (uint32_t i = 0; i < inst->nports_audio_out && ports && ports[i]; i++) { if (jack_connect (j_client, jack_port_name (output_port[i]), ports[i])) break; } - if (ports) { jack_free(ports); } + if (ports) { + jack_free (ports); + } } if ((which & 4) && midi_in) { // midi in - const char **ports = jack_get_ports(j_client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput|JackPortIsPhysical); + const char** ports = jack_get_ports (j_client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsPhysical); if (ports && ports[0]) { - jack_connect (j_client, jack_port_name (midi_in), ports[0]); + jack_connect (j_client, ports[0], jack_port_name (midi_in)); + } + if (ports) { + jack_free (ports); } - if (ports) { jack_free(ports); } } if ((which & 8) && midi_out) { // midi out - const char **ports = jack_get_ports(j_client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput|JackPortIsPhysical); + const char** ports = jack_get_ports (j_client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsPhysical); if (ports && ports[0]) { jack_connect (j_client, jack_port_name (midi_out), ports[0]); } - if (ports) { jack_free(ports); } + if (ports) { + jack_free (ports); + } } - } /****************************************************************************** * LV2 */ -static uint32_t uri_to_id(LV2_URI_Map_Callback_Data callback_data, const char* uri) { - for (uint32_t i=0; i < urimap_len; ++i) { - if (!strcmp(urimap[i], uri)) { +static uint32_t +uri_to_id (LV2_URI_Map_Callback_Data callback_data, const char* uri) +{ + for (uint32_t i = 0; i < urimap_len; ++i) { + if (!strcmp (urimap[i], uri)) { //printf("Found mapped URI '%s' -> %d\n", uri, i + 1); return i + 1; } } //printf("map URI '%s' -> %d\n", uri, urimap_len + 1); - urimap = (char**) realloc(urimap, (urimap_len + 1) * sizeof(char*)); - urimap[urimap_len] = strdup(uri); + urimap = (char**)realloc (urimap, (urimap_len + 1) * sizeof (char*)); + urimap[urimap_len] = strdup (uri); return ++urimap_len; } -static void free_uri_map() { - for (uint32_t i=0; i < urimap_len; ++i) { - free(urimap[i]); +static void +free_uri_map () +{ + for (uint32_t i = 0; i < urimap_len; ++i) { + free (urimap[i]); } - free(urimap); + free (urimap); } -static void write_function( - LV2UI_Controller controller, - uint32_t port_index, - uint32_t buffer_size, - uint32_t port_protocol, - const void* buffer) { - - if (buffer_size == 0) return; +static void +write_function ( + LV2UI_Controller controller, + uint32_t port_index, + uint32_t buffer_size, + uint32_t port_protocol, + const void* buffer) +{ + if (buffer_size == 0) + return; if (port_protocol != 0) { - if (jack_ringbuffer_write_space(rb_atom_from_ui) >= buffer_size + sizeof(LV2_Atom)) { - LV2_Atom a = {buffer_size, 0}; - jack_ringbuffer_write(rb_atom_from_ui, (char *) &a, sizeof(LV2_Atom)); - jack_ringbuffer_write(rb_atom_from_ui, (char *) buffer, buffer_size); + if (jack_ringbuffer_write_space (rb_atom_from_ui) >= buffer_size + sizeof (LV2_Atom)) { + LV2_Atom a = { buffer_size, 0 }; + jack_ringbuffer_write (rb_atom_from_ui, (char*)&a, sizeof (LV2_Atom)); + jack_ringbuffer_write (rb_atom_from_ui, (char*)buffer, buffer_size); } return; } - if (buffer_size != sizeof(float)) { - fprintf(stderr, "LV2Host: write_function() unsupported buffer\n"); + if (buffer_size != sizeof (float)) { + fprintf (stderr, "LV2Host: write_function() unsupported buffer\n"); return; } if (port_index >= inst->nports_total) { - fprintf(stderr, "LV2Host: write_function() invalid port\n"); + fprintf (stderr, "LV2Host: write_function() invalid port\n"); return; } if (portmap_ctrl[port_index] == UINT32_MAX) { - fprintf(stderr, "LV2Host: write_function() unmapped port\n"); + fprintf (stderr, "LV2Host: write_function() unmapped port\n"); return; } if (inst->ports[port_index].porttype != CONTROL_IN) { - fprintf(stderr, "LV2Host: write_function() not a control input\n"); + fprintf (stderr, "LV2Host: write_function() not a control input\n"); return; } - if (jack_ringbuffer_write_space(rb_ctrl_from_ui) >= sizeof(uint32_t) + sizeof(float)) { + if (jack_ringbuffer_write_space (rb_ctrl_from_ui) >= sizeof (uint32_t) + sizeof (float)) { pthread_mutex_lock (&port_write_lock); - jack_ringbuffer_write(rb_ctrl_from_ui, (char *) &portmap_ctrl[port_index], sizeof(uint32_t)); - jack_ringbuffer_write(rb_ctrl_from_ui, (char *) buffer, sizeof(float)); + jack_ringbuffer_write (rb_ctrl_from_ui, (char*)&portmap_ctrl[port_index], sizeof (uint32_t)); + jack_ringbuffer_write (rb_ctrl_from_ui, (char*)buffer, sizeof (float)); pthread_mutex_unlock (&port_write_lock); } } @@ -868,62 +887,66 @@ // LV2 Worker static LV2_Worker_Status -lv2_worker_respond(LV2_Worker_Respond_Handle unused, - uint32_t size, - const void* data) +lv2_worker_respond (LV2_Worker_Respond_Handle unused, + uint32_t size, + const void* data) { - jack_ringbuffer_write(worker_responses, (const char*)&size, sizeof(size)); - jack_ringbuffer_write(worker_responses, (const char*)data, size); + jack_ringbuffer_write (worker_responses, (const char*)&size, sizeof (size)); + jack_ringbuffer_write (worker_responses, (const char*)data, size); return LV2_WORKER_SUCCESS; } - -static void* worker_func(void* data) { +static void* +worker_func (void* data) +{ pthread_mutex_lock (&worker_lock); while (1) { - char buf[4096]; + char buf[4096]; uint32_t size = 0; - if (jack_ringbuffer_read_space(worker_requests) <= sizeof(size)) { - pthread_cond_wait(&worker_ready, &worker_lock); + if (jack_ringbuffer_read_space (worker_requests) <= sizeof (size)) { + pthread_cond_wait (&worker_ready, &worker_lock); } - if (client_state == Exit) break; + if (client_state == Exit) + break; - jack_ringbuffer_read(worker_requests, (char*)&size, sizeof(size)); + jack_ringbuffer_read (worker_requests, (char*)&size, sizeof (size)); if (size > 4096) { - fprintf(stderr, "Worker information is too large. Abort.\n"); + fprintf (stderr, "Worker information is too large. Abort.\n"); break; } - jack_ringbuffer_read(worker_requests, buf, size); - worker_iface->work(plugin_instance, lv2_worker_respond, NULL, size, buf); + jack_ringbuffer_read (worker_requests, buf, size); + worker_iface->work (plugin_instance, lv2_worker_respond, NULL, size, buf); } pthread_mutex_unlock (&worker_lock); return NULL; } -static void worker_init() { - worker_requests = jack_ringbuffer_create(4096); - worker_responses = jack_ringbuffer_create(4096); - jack_ringbuffer_mlock(worker_requests); - jack_ringbuffer_mlock(worker_responses); - pthread_create(&worker_thread, NULL, worker_func, NULL); +static void +worker_init () +{ + worker_requests = jack_ringbuffer_create (4096); + worker_responses = jack_ringbuffer_create (4096); + jack_ringbuffer_mlock (worker_requests); + jack_ringbuffer_mlock (worker_responses); + pthread_create (&worker_thread, NULL, worker_func, NULL); } static LV2_Worker_Status -lv2_worker_schedule(LV2_Worker_Schedule_Handle unused, - uint32_t size, - const void* data) +lv2_worker_schedule (LV2_Worker_Schedule_Handle unused, + uint32_t size, + const void* data) { if (_freewheeling) { - worker_iface->work(plugin_instance, lv2_worker_respond, NULL, size, data); + worker_iface->work (plugin_instance, lv2_worker_respond, NULL, size, data); return LV2_WORKER_SUCCESS; } - assert(worker_requests); - jack_ringbuffer_write(worker_requests, (const char*)&size, sizeof(size)); - jack_ringbuffer_write(worker_requests, (const char*)data, size); + assert (worker_requests); + jack_ringbuffer_write (worker_requests, (const char*)&size, sizeof (size)); + jack_ringbuffer_write (worker_requests, (const char*)data, size); if (pthread_mutex_trylock (&worker_lock) == 0) { pthread_cond_signal (&worker_ready); pthread_mutex_unlock (&worker_lock); @@ -936,44 +959,56 @@ */ #ifdef HAVE_LIBLO -static void osc_queue_midi_event (osc_midi_event_t *ev) { +static void +osc_queue_midi_event (osc_midi_event_t* ev) +{ if (((queued_events_start + 1) % OSC_MIDI_QUEUE_SIZE) == queued_events_end) { return; } - memcpy (&event_queue[queued_events_start], ev, sizeof(osc_midi_event_t)); + memcpy (&event_queue[queued_events_start], ev, sizeof (osc_midi_event_t)); queued_events_start = (queued_events_start + 1) % OSC_MIDI_QUEUE_SIZE; } -static void oscb_error (int num, const char *m, const char *path) { - fprintf(stderr, "liblo server error %d in path %s: %s\n", num, path, m); +static void +oscb_error (int num, const char* m, const char* path) +{ + fprintf (stderr, "liblo server error %d in path %s: %s\n", num, path, m); } -#define MIDI_Q3(STATUS) \ - osc_midi_event_t ev; \ - ev.size = 3; \ - ev.buffer[0] = STATUS | (argv[0]->i & 0x0f); \ - ev.buffer[1] = argv[1]->i & 0x7f; \ - ev.buffer[2] = argv[2]->i & 0x7f; \ - osc_queue_midi_event (&ev); +#define MIDI_Q3(STATUS) \ + osc_midi_event_t ev; \ + ev.size = 3; \ + ev.buffer[0] = STATUS | (argv[0]->i & 0x0f); \ + ev.buffer[1] = argv[1]->i & 0x7f; \ + ev.buffer[2] = argv[2]->i & 0x7f; \ + osc_queue_midi_event (&ev); -static int oscb_noteon (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { - MIDI_Q3(0x90); +static int +oscb_noteon (const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) +{ + MIDI_Q3 (0x90); return 0; } -static int oscb_noteoff (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { - MIDI_Q3(0x80); +static int +oscb_noteoff (const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) +{ + MIDI_Q3 (0x80); return 0; } -static int oscb_cc (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { - MIDI_Q3(0xb0); +static int +oscb_cc (const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) +{ + MIDI_Q3 (0xb0); return 0; } -static int oscb_pc (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { +static int +oscb_pc (const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) +{ osc_midi_event_t ev; - ev.size = 2; + ev.size = 2; ev.buffer[0] = 0xc0 | (argv[0]->i & 0x0f); ev.buffer[1] = argv[1]->i & 0x7f; ev.buffer[2] = 0x00; @@ -981,9 +1016,11 @@ return 0; } -static int oscb_rawmidi (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { +static int +oscb_rawmidi (const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) +{ osc_midi_event_t ev; - ev.size = 3; + ev.size = 3; ev.buffer[0] = argv[0]->m[1]; ev.buffer[1] = argv[0]->m[2] & 0x7f; ev.buffer[2] = argv[0]->m[3] & 0x7f; @@ -991,11 +1028,13 @@ return 0; } -static int oscb_parameter (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { +static int +oscb_parameter (const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) +{ assert (argc == 2 && !strcmp (types, "if")); const uint32_t port = argv[0]->i; - const float val = argv[1]->f; + const float val = argv[1]->f; if (inst->nports_ctrl <= port) { fprintf (stderr, "OSC: Invalid Parameter 0 <= %d < %d\n", port, inst->nports_ctrl); @@ -1012,95 +1051,103 @@ if (inst->ports[port_index].val_min < inst->ports[port_index].val_max) { if (val < inst->ports[port_index].val_min || val > inst->ports[port_index].val_max) { fprintf (stderr, "OSC: Value out of bounds %f <= %f <= %f\n", - inst->ports[port_index].val_min, val, inst->ports[port_index].val_max); + inst->ports[port_index].val_min, val, inst->ports[port_index].val_max); return 0; } } //fprintf (stdout, "OSC: %d, %d -> %f\n", port, port_index, val); - write_function (NULL, port_index, sizeof (float), 0, (const void*) &val); + write_function (NULL, port_index, sizeof (float), 0, (const void*)&val); - if (jack_ringbuffer_write_space (rb_osc_to_ui) >= sizeof(uint32_t) + sizeof(float)) { - jack_ringbuffer_write (rb_osc_to_ui, (char *) &port_index, sizeof(uint32_t)); - jack_ringbuffer_write (rb_osc_to_ui, (char *) &val, sizeof(float)); + if (jack_ringbuffer_write_space (rb_osc_to_ui) >= sizeof (uint32_t) + sizeof (float)) { + jack_ringbuffer_write (rb_osc_to_ui, (char*)&port_index, sizeof (uint32_t)); + jack_ringbuffer_write (rb_osc_to_ui, (char*)&val, sizeof (float)); } return 0; } struct osc_command { - const char *path; - const char *typespec; + const char* path; + const char* typespec; lo_method_handler handler; - const char *documentation; + const char* documentation; }; static struct osc_command OSCC[] = { - {"/x42/parameter", "if", &oscb_parameter, "Set Control Input value. control-port, value"}, - {"/x42/midi/raw", "m", &oscb_rawmidi, "Send raw midi message to plugin"}, - {"/x42/midi/cc", "iii", &oscb_cc, "Send midi control-change: channel, parameter, value"}, - {"/x42/midi/pc", "ii", &oscb_pc, "Send midi program-change: channel, program"}, - {"/x42/midi/noteon", "iii", &oscb_noteon, "Send midi note on: channel, key, velocity"}, - {"/x42/midi/noteoff", "iii", &oscb_noteoff, "Send midi note off: channel, key, velocity"}, + { "/x42/parameter", "if", &oscb_parameter, "Set Control Input value. control-port, value" }, + { "/x42/midi/raw", "m", &oscb_rawmidi, "Send raw midi message to plugin" }, + { "/x42/midi/cc", "iii", &oscb_cc, "Send midi control-change: channel, parameter, value" }, + { "/x42/midi/pc", "ii", &oscb_pc, "Send midi program-change: channel, program" }, + { "/x42/midi/noteon", "iii", &oscb_noteon, "Send midi note on: channel, key, velocity" }, + { "/x42/midi/noteoff", "iii", &oscb_noteoff, "Send midi note off: channel, key, velocity" }, }; -static void print_oscdoc (void) { - printf("# X42 OSC methods. Format:\n"); - printf("# Path Typespec Documentation \n"); - printf("#######################################################\n"); - for (size_t i = 0; i < sizeof(OSCC) / sizeof(struct osc_command); ++i) { - printf("%s %s %s\n", OSCC[i].path, OSCC[i].typespec, OSCC[i].documentation); +static void +print_oscdoc (void) +{ + printf ("# X42 OSC methods. Format:\n"); + printf ("# Path Typespec Documentation \n"); + printf ("#######################################################\n"); + for (size_t i = 0; i < sizeof (OSCC) / sizeof (struct osc_command); ++i) { + printf ("%s %s %s\n", OSCC[i].path, OSCC[i].typespec, OSCC[i].documentation); } } -static int start_osc_server (int osc_port) { - char tmp[8]; +static int +start_osc_server (int osc_port) +{ + char tmp[8]; uint32_t port = (osc_port > 100 && osc_port < 60000) ? osc_port : 9988; #ifdef _WIN32 - sprintf(tmp, "%d", port); + sprintf (tmp, "%d", port); #else - snprintf(tmp, sizeof(tmp), "%d", port); + snprintf (tmp, sizeof (tmp), "%d", port); #endif osc_server = lo_server_thread_new (tmp, oscb_error); if (!osc_server) { - fprintf(stderr, "OSC failed to listen on port %s", tmp); + fprintf (stderr, "OSC failed to listen on port %s", tmp); return -1; } else { - char *urlstr = lo_server_thread_get_url (osc_server); - fprintf(stderr, "OSC server: %s\n", urlstr); + char* urlstr = lo_server_thread_get_url (osc_server); + fprintf (stderr, "OSC server: %s\n", urlstr); free (urlstr); } - for (size_t i = 0; i < sizeof(OSCC) / sizeof(struct osc_command); ++i) { + for (size_t i = 0; i < sizeof (OSCC) / sizeof (struct osc_command); ++i) { lo_server_thread_add_method (osc_server, OSCC[i].path, OSCC[i].typespec, OSCC[i].handler, NULL); } - lo_server_thread_start(osc_server); + lo_server_thread_start (osc_server); return 0; } -static void stop_osc_server () { - if (!osc_server) return; +static void +stop_osc_server () +{ + if (!osc_server) + return; lo_server_thread_stop (osc_server); lo_server_thread_free (osc_server); - fprintf(stderr, "OSC server shut down.\n"); + fprintf (stderr, "OSC server shut down.\n"); osc_server = NULL; } #endif - /****************************************************************************** * MAIN */ -static void cleanup(int sig) { +static void +cleanup (int sig) +{ if (j_client) { jack_client_close (j_client); - j_client=NULL; + j_client = NULL; } if (worker_requests) { @@ -1108,10 +1155,10 @@ pthread_cond_signal (&worker_ready); pthread_mutex_unlock (&worker_lock); - pthread_join(worker_thread, NULL); + pthread_join (worker_thread, NULL); - jack_ringbuffer_free(worker_requests); - jack_ringbuffer_free(worker_responses); + jack_ringbuffer_free (worker_requests); + jack_ringbuffer_free (worker_responses); } #ifdef HAVE_LIBLO @@ -1119,193 +1166,216 @@ #endif if (plugin_dsp && plugin_instance && plugin_dsp->deactivate) { - plugin_dsp->deactivate(plugin_instance); + plugin_dsp->deactivate (plugin_instance); } if (plugin_gui && gui_instance && plugin_gui->cleanup) { - plugin_gui->cleanup(gui_instance); + plugin_gui->cleanup (gui_instance); } if (plugin_dsp && plugin_instance && plugin_dsp->cleanup) { - plugin_dsp->cleanup(plugin_instance); + plugin_dsp->cleanup (plugin_instance); } - jack_ringbuffer_free(rb_ctrl_to_ui); - jack_ringbuffer_free(rb_ctrl_from_ui); + jack_ringbuffer_free (rb_ctrl_to_ui); + jack_ringbuffer_free (rb_ctrl_from_ui); - jack_ringbuffer_free(rb_atom_to_ui); - jack_ringbuffer_free(rb_atom_from_ui); + jack_ringbuffer_free (rb_atom_to_ui); + jack_ringbuffer_free (rb_atom_from_ui); #ifdef HAVE_LIBLO - jack_ringbuffer_free(rb_osc_to_ui); + jack_ringbuffer_free (rb_osc_to_ui); #endif - free(input_port); - free(output_port); + free (input_port); + free (output_port); if (delayline) { for (uint32_t i = 0; i < inst->nports_audio_in; i++) { - free(delayline[i]); + free (delayline[i]); } } - free(delayline); + free (delayline); - free(plugin_ports_pre); - free(plugin_ports_post); - free(portmap_a_in); - free(portmap_a_out); - free(portmap_ctrl); - free(portmap_rctl); - free(atom_in); - free(atom_out); - free_uri_map(); - fprintf(stderr, "bye.\n"); + free (plugin_ports_pre); + free (plugin_ports_post); + free (portmap_a_in); + free (portmap_a_out); + free (portmap_ctrl); + free (portmap_rctl); + free (atom_in); + free (atom_out); + free_uri_map (); + fprintf (stderr, "bye.\n"); } -static void run_one(LV2_Atom_Sequence *data) { - +static void +run_one (LV2_Atom_Sequence* data) +{ #ifdef HAVE_LIBLO - while (jack_ringbuffer_read_space(rb_osc_to_ui) >= sizeof(uint32_t) + sizeof(float)) { + while (jack_ringbuffer_read_space (rb_osc_to_ui) >= sizeof (uint32_t) + sizeof (float)) { uint32_t idx; - float val; - jack_ringbuffer_read(rb_osc_to_ui, (char*) &idx, sizeof(uint32_t)); - jack_ringbuffer_read(rb_osc_to_ui, (char*) &val, sizeof(float)); - plugin_gui->port_event(gui_instance, idx, sizeof(float), 0, &val); + float val; + jack_ringbuffer_read (rb_osc_to_ui, (char*)&idx, sizeof (uint32_t)); + jack_ringbuffer_read (rb_osc_to_ui, (char*)&val, sizeof (float)); + plugin_gui->port_event (gui_instance, idx, sizeof (float), 0, &val); } #endif - while (jack_ringbuffer_read_space(rb_ctrl_to_ui) >= sizeof(uint32_t) + sizeof(float)) { + while (jack_ringbuffer_read_space (rb_ctrl_to_ui) >= sizeof (uint32_t) + sizeof (float)) { uint32_t idx; - float val; - jack_ringbuffer_read(rb_ctrl_to_ui, (char*) &idx, sizeof(uint32_t)); - jack_ringbuffer_read(rb_ctrl_to_ui, (char*) &val, sizeof(float)); - plugin_gui->port_event(gui_instance, idx, sizeof(float), 0, &val); + float val; + jack_ringbuffer_read (rb_ctrl_to_ui, (char*)&idx, sizeof (uint32_t)); + jack_ringbuffer_read (rb_ctrl_to_ui, (char*)&val, sizeof (float)); + plugin_gui->port_event (gui_instance, idx, sizeof (float), 0, &val); if (idx == inst->latency_ctrl_port) { // jack client calls cannot be done in the DSP thread with jack1 - jack_recompute_total_latencies(j_client); + jack_recompute_total_latencies (j_client); } } - while (jack_ringbuffer_read_space(rb_atom_to_ui) > sizeof(LV2_Atom)) { + while (jack_ringbuffer_read_space (rb_atom_to_ui) > sizeof (LV2_Atom)) { LV2_Atom a; - jack_ringbuffer_read(rb_atom_to_ui, (char *) &a, sizeof(LV2_Atom)); - assert(a.size < inst->min_atom_bufsiz); - jack_ringbuffer_read(rb_atom_to_ui, (char *) data, a.size); + jack_ringbuffer_read (rb_atom_to_ui, (char*)&a, sizeof (LV2_Atom)); + assert (a.size < inst->min_atom_bufsiz); + jack_ringbuffer_read (rb_atom_to_ui, (char*)data, a.size); LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((&(data)->body) + 1); // lv2_atom_sequence_begin - while((const uint8_t*)ev < ((const uint8_t*) &(data)->body + (data)->atom.size)) { - plugin_gui->port_event(gui_instance, portmap_atom_to_ui, - ev->body.size, uri_atom_EventTransfer, &ev->body); - ev = (LV2_Atom_Event const*) /* lv2_atom_sequence_next() */ - ((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7)); + while ((const uint8_t*)ev < ((const uint8_t*)&(data)->body + (data)->atom.size)) { + plugin_gui->port_event (gui_instance, portmap_atom_to_ui, + ev->body.size, uri_atom_EventTransfer, &ev->body); + ev = (LV2_Atom_Event const*)/* lv2_atom_sequence_next() */ + ((const uint8_t*)ev + sizeof (LV2_Atom_Event) + ((ev->body.size + 7) & ~7)); } } - LV2_EXTERNAL_UI_RUN(extui); + LV2_EXTERNAL_UI_RUN (extui); } #ifdef __APPLE__ -static void osx_loop (CFRunLoopTimerRef timer, void *info) { +static void +osx_loop (CFRunLoopTimerRef timer, void* info) +{ if (client_state == Run) { - run_one((LV2_Atom_Sequence*)info); + run_one ((LV2_Atom_Sequence*)info); } if (client_state == Exit) { - rtk_osx_api_terminate(); + rtk_osx_api_terminate (); } } #else - -static void main_loop(void) { - struct timespec timeout; - LV2_Atom_Sequence *data = (LV2_Atom_Sequence*) malloc(inst->min_atom_bufsiz * sizeof(uint8_t)); +static void +main_loop (void) +{ + struct timespec timeout; + LV2_Atom_Sequence* data = (LV2_Atom_Sequence*)malloc (inst->min_atom_bufsiz * sizeof (uint8_t)); pthread_mutex_lock (&gui_thread_lock); while (client_state != Exit) { - run_one(data); + run_one (data); - if (client_state == Exit) break; + if (client_state == Exit) + break; #ifdef _WIN32 - //Sleep(1000/UI_UPDATE_FPS); +//Sleep(1000/UI_UPDATE_FPS); #if (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 struct __timeb64 timebuffer; - _ftime64(&timebuffer); + _ftime64 (&timebuffer); #else struct __timeb32 timebuffer; - _ftime(&timebuffer); + _ftime (&timebuffer); #endif timeout.tv_nsec = timebuffer.millitm * 1000000; - timeout.tv_sec = timebuffer.time; + timeout.tv_sec = timebuffer.time; #else // POSIX - clock_gettime(CLOCK_REALTIME, &timeout); + clock_gettime (CLOCK_REALTIME, &timeout); #endif timeout.tv_nsec += 1000000000 / (UI_UPDATE_FPS); - if (timeout.tv_nsec >= 1000000000) {timeout.tv_nsec -= 1000000000; timeout.tv_sec+=1;} + if (timeout.tv_nsec >= 1000000000) { + timeout.tv_nsec -= 1000000000; + timeout.tv_sec += 1; + } pthread_cond_timedwait (&data_ready, &gui_thread_lock, &timeout); } /* while running */ - free(data); + free (data); pthread_mutex_unlock (&gui_thread_lock); } #endif // APPLE RUNLOOP -static void catchsig (int sig) { - fprintf(stderr,"caught signal - shutting down.\n"); - client_state=Exit; +static void +catchsig (int sig) +{ + fprintf (stderr, "caught signal - shutting down.\n"); + client_state = Exit; pthread_cond_signal (&data_ready); } -static void on_external_ui_closed(void* controller) { - catchsig(0); +static void +on_external_ui_closed (void* controller) +{ + catchsig (0); } #ifdef X42_MULTIPLUGIN -static void list_plugins (void) { +static void +list_plugins (void) +{ unsigned int i; - for (i = 0; i < sizeof(_plugins) / sizeof(RtkLv2Description); ++i) { - const LV2_Descriptor* d = _plugins[i].lv2_descriptor(_plugins[i].dsp_descriptor_id); - printf(" %2d \"%s\" %s\n", i, _plugins[i].plugin_human_id, d->URI); + for (i = 0; i < sizeof (_plugins) / sizeof (RtkLv2Description); ++i) { + const LV2_Descriptor* d = _plugins[i].lv2_descriptor (_plugins[i].dsp_descriptor_id); + printf (" %2d \"%s\" %s\n", i, _plugins[i].plugin_human_id, d->URI); } } #endif -static void print_usage (void) { +static void +print_usage (void) +{ #ifdef X42_MULTIPLUGIN printf ("x42-%s - JACK %s\n\n", APPNAME, X42_MULTIPLUGIN_NAME); printf ("Usage: x42-%s [ OPTIONS ] [ Plugin-ID or URI ]\n\n", APPNAME); printf ("This is a standalone JACK application of a collection of LV2 plugins.\n" - "Use ID -1, -l or --list for a dedicated list of included plugins.\n" - "By default the first listed plugin (ID 0) is used.\n\n"); - printf ("List if available plugins: (ID \"Name\" URI)\n"); - list_plugins(); + "Use ID -1, -l or --list for a dedicated list of included plugins.\n" + "By default the first listed plugin (ID 0) is used.\n\n"); + printf ("List of available plugins: (ID \"Name\" URI)\n"); + list_plugins (); #else #if defined X42_PLUGIN_STRUCT - inst = & X42_PLUGIN_STRUCT; + inst = &X42_PLUGIN_STRUCT; #else inst = &_plugin; #endif - const LV2_Descriptor* d = inst->lv2_descriptor(inst->dsp_descriptor_id); + const LV2_Descriptor* d = inst->lv2_descriptor (inst->dsp_descriptor_id); printf ("x42-%s - JACK %s\n\n", APPNAME, inst->plugin_human_id); printf ("Usage: x42-%s [ OPTIONS ]\n\n", APPNAME); + printf ("This is a standalone JACK application of the LV2 plugin:\n" - "\"%s\".\n", inst->plugin_human_id); + "\"%s\".\n", + inst->plugin_human_id); #endif printf ("\nUsage:\n" + "All control elements are operated in using the mouse:\n" " Click+Drag left/down: decrease, right/up: increase value. Hold the Ctrl key to increase sensitivity.\n" " Shift+Click reset to default value\n" " Scroll-wheel up/down by 1 step (smallest possible adjustment for given setting). Rapid continuous scrolling increases the step-size.\n" "The application can be closed by sending a SIGTERM (CTRL+C) on the command-line of by closing the window.\n" - ); + ); printf ("\nOptions:\n" + " -h, --help Display this help and exit\n" " -j, --jack-name Set the JACK client name\n" " (defaults to plugin-name)\n" +#ifndef REQUIRE_UI +" -G, --nogui run headless, useful for OSC remote ctrl.\n" +#endif #ifdef X42_MULTIPLUGIN " -l, --list Print list of available plugins and exit\n" #endif @@ -1315,7 +1385,7 @@ " -P, --portlist Print control port list on startup\n" " --osc-doc Print available OSC commands and exit\n" " -V, --version Print version information and exit\n" - ); + ); #ifdef X42_MULTIPLUGIN_URI printf ("\nSee also: <%s>\n", X42_MULTIPLUGIN_URI); @@ -1325,15 +1395,19 @@ printf ("Website: \n"); } -static void print_version (void) { +static void +print_version (void) +{ printf ("x42-%s version %s\n\n", APPNAME, VERSION); printf ("\n" - "Copyright (C) GPL 2013-2015 Robin Gareus \n" - "This is free software; see the source for copying conditions. There is NO\n" - "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); + "Copyright (C) GPL 2013-2019 Robin Gareus \n" + "This is free software; see the source for copying conditions. There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); } -static void dump_control_ports (void) { +static void +dump_control_ports (void) +{ printf ("# Input Control Port List (%d ports)\n", inst->nports_ctrl); for (uint32_t i = 0; i < inst->nports_ctrl; ++i) { const uint32_t pi = portmap_rctl[i]; @@ -1358,47 +1432,58 @@ printf ("### End Port List\n"); } -int main (int argc, char **argv) { - int c; - int rv = 0; - int osc_port = 0; - bool dump_ports = false; - uint32_t c_ain = 0; - uint32_t c_aout = 0; - uint32_t c_ctrl = 0; - uint32_t n_pval = 0; - struct PValue *pval = NULL; - char* jack_client_name = NULL; +int +main (int argc, char** argv) +{ + int c; + int rv = 0; + int osc_port = 0; + bool dump_ports = false; + bool headless = false; + uint32_t c_ain = 0; + uint32_t c_aout = 0; + uint32_t c_ctrl = 0; + uint32_t n_pval = 0; + struct PValue* pval = NULL; + char* jack_client_name = NULL; const struct option long_options[] = { - { "help", no_argument, 0, 'h' }, - { "jack-name", required_argument, 0, 'j' }, - { "list", no_argument, 0, 'l' }, - { "osc", required_argument, 0, 'O' }, - { "osc-doc", no_argument, 0, 0x100 }, - { "port", required_argument, 0, 'p' }, - { "portlist", no_argument, 0, 'P' }, - { "version", no_argument, 0, 'V' }, + { "help", no_argument, 0, 'h' }, + { "jack-name", required_argument, 0, 'j' }, + { "list", no_argument, 0, 'l' }, + { "nogui", no_argument, 0, 'G' }, + { "osc", required_argument, 0, 'O' }, + { "osc-doc", no_argument, 0, 0x100 }, + { "port", required_argument, 0, 'p' }, + { "portlist", no_argument, 0, 'P' }, + { "version", no_argument, 0, 'V' }, }; - const char *optstring = "hj:lO:p:PV1"; + const char* optstring = "Ghj:lO:p:PV1"; - if (optind < argc && !strncmp (argv[optind], "-psn_0", 6)) {++optind;} + if (optind < argc && !strncmp (argv[optind], "-psn_0", 6)) { + ++optind; + } - while ((c = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { - char *tmp; + while ((c = getopt_long (argc, argv, optstring, long_options, NULL)) != -1) { + char* tmp; switch (c) { case 'h': - print_usage(); + print_usage (); return 0; break; + case 'G': +#ifndef REQUIRE_UI + headless = true; +#endif + break; case 'j': jack_client_name = optarg; break; case '1': // catch -1, backward compat case 'l': #ifdef X42_MULTIPLUGIN - list_plugins(); + list_plugins (); #endif return 0; break; @@ -1410,9 +1495,9 @@ break; case 'p': if ((tmp = strchr (optarg, ':')) != NULL && *(++tmp)) { - pval = (struct PValue*) realloc (pval, (n_pval + 1) * sizeof (struct PValue)); + pval = (struct PValue*)realloc (pval, (n_pval + 1) * sizeof (struct PValue)); pval[n_pval].port_idx = atoi (optarg); - pval[n_pval].value = atof (tmp); + pval[n_pval].value = atof (tmp); ++n_pval; } break; @@ -1420,7 +1505,7 @@ dump_ports = true; break; case 'V': - print_version(); + print_version (); return 0; break; @@ -1428,7 +1513,7 @@ #ifndef HAVE_LIBLO fprintf (stderr, "This version was compiled without OSC support.\n"); #else - print_oscdoc(); + print_oscdoc (); #endif return 0; break; @@ -1436,28 +1521,26 @@ // silently ignore additional session options on OSX #ifndef __APPLE__ fprintf (stderr, "invalid argument.\n"); - print_usage(); - return(1); + print_usage (); + return (1); #endif break; } } // TODO autoconnect option. - // TODO allow to set initial params #ifdef X42_MULTIPLUGIN inst = NULL; if (optind < argc && atoi (argv[optind]) < 0) { - list_plugins(); + list_plugins (); return 0; - } - if (optind < argc && strlen(argv[optind]) > 2 && atoi (argv[optind]) == 0) { + if (optind < argc && strlen (argv[optind]) > 2 && atoi (argv[optind]) == 0) { unsigned int i; - for (i = 0; i < sizeof(_plugins) / sizeof(RtkLv2Description); ++i) { - const LV2_Descriptor* d = _plugins[i].lv2_descriptor(_plugins[i].dsp_descriptor_id); - if (strstr(d->URI, argv[optind]) || strstr(_plugins[i].plugin_human_id, argv[optind])) { + for (i = 0; i < sizeof (_plugins) / sizeof (RtkLv2Description); ++i) { + const LV2_Descriptor* d = _plugins[i].lv2_descriptor (_plugins[i].dsp_descriptor_id); + if (strstr (d->URI, argv[optind]) || strstr (_plugins[i].plugin_human_id, argv[optind])) { inst = &_plugins[i]; break; } @@ -1465,7 +1548,7 @@ } if (optind < argc && !inst && atoi (argv[optind]) >= 0) { unsigned int plugid = atoi (argv[optind]); - if (plugid < (sizeof(_plugins) / sizeof(RtkLv2Description))) { + if (plugid < (sizeof (_plugins) / sizeof (RtkLv2Description))) { inst = &_plugins[plugid]; } } @@ -1473,57 +1556,57 @@ inst = &_plugins[0]; } #elif defined X42_PLUGIN_STRUCT - inst = & X42_PLUGIN_STRUCT; + inst = &X42_PLUGIN_STRUCT; #else inst = &_plugin; #endif #ifdef __APPLE__ - rtk_osx_api_init(); + rtk_osx_api_init (); #endif #ifdef USE_WEAK_JACK - if (have_libjack()) { + if (have_libjack ()) { fprintf (stderr, "JACK is not available. http://jackaudio.org/\n"); #ifdef _WIN32 - MessageBox(NULL, TEXT( - "JACK is not available.\n" - "You must have the JACK Audio Connection Kit installed to use the tools. " - "Please see http://jackaudio.org/ and http://jackaudio.org/faq/jack_on_windows.html" - ), TEXT("Error"), MB_ICONERROR | MB_OK); + MessageBox (NULL, + TEXT ( + "JACK is not available.\n" + "You must have the JACK Audio Connection Kit installed to use the tools. " + "Please see http://jackaudio.org/ and http://jackaudio.org/faq/jack_on_windows.html"), + TEXT ("Error"), MB_ICONERROR | MB_OK); #elif __APPLE__ rtk_osx_api_err ( - "JACK is not available.\n" - "You must have the JACK Audio Connection Kit installed to use the tools. " - "Please see http://jackaudio.org/ and http://jackosx.com/" - ); + "JACK is not available.\n" + "You must have the JACK Audio Connection Kit installed to use the tools. " + "Please see http://jackaudio.org/"); #endif return 1; } #endif #ifdef _WIN32 - pthread_win32_process_attach_np(); + pthread_win32_process_attach_np (); #endif #if (defined _WIN32 && defined RTK_STATIC_INIT) - glib_init_static(); - gobject_init_ctor(); + glib_init_static (); + gobject_init_ctor (); #endif - LV2_URID_Map uri_map = { NULL, &uri_to_id }; - const LV2_Feature map_feature = { LV2_URID__map, &uri_map}; - const LV2_Feature unmap_feature = { LV2_URID__unmap, NULL }; + LV2_URID_Map uri_map = { NULL, &uri_to_id }; + const LV2_Feature map_feature = { LV2_URID__map, &uri_map }; + const LV2_Feature unmap_feature = { LV2_URID__unmap, NULL }; - LV2_Worker_Schedule schedule = { NULL, lv2_worker_schedule }; - const LV2_Feature schedule_feature = { LV2_WORKER__schedule, &schedule }; + LV2_Worker_Schedule schedule = { NULL, lv2_worker_schedule }; + const LV2_Feature schedule_feature = { LV2_WORKER__schedule, &schedule }; const LV2_Feature* features[] = { &map_feature, &unmap_feature, &schedule_feature, NULL }; - const LV2_Feature external_lv_feature = { LV2_EXTERNAL_UI_URI, &extui_host}; - const LV2_Feature external_kx_feature = { LV2_EXTERNAL_UI_URI__KX__Host, &extui_host}; - LV2_Feature instance_feature = { "http://lv2plug.in/ns/ext/instance-access", NULL }; + const LV2_Feature external_lv_feature = { LV2_EXTERNAL_UI_URI, &extui_host }; + const LV2_Feature external_kx_feature = { LV2_EXTERNAL_UI_URI__KX__Host, &extui_host }; + LV2_Feature instance_feature = { "http://lv2plug.in/ns/ext/instance-access", NULL }; const LV2_Feature* ui_features[] = { &map_feature, &unmap_feature, @@ -1543,30 +1626,30 @@ // TODO check if allocs succeeded - OOM -> exit /* allocate data structure */ - portmap_a_in = (uint32_t*) malloc(inst->nports_audio_in * sizeof(uint32_t)); - portmap_a_out = (uint32_t*) malloc(inst->nports_audio_out * sizeof(uint32_t)); - portmap_rctl = (uint32_t*) malloc(inst->nports_ctrl * sizeof(uint32_t)); - portmap_ctrl = (uint32_t*) malloc(inst->nports_total * sizeof(uint32_t)); - - plugin_ports_pre = (float*) calloc(inst->nports_ctrl, sizeof(float)); - plugin_ports_post = (float*) calloc(inst->nports_ctrl, sizeof(float)); + portmap_a_in = (uint32_t*)malloc (inst->nports_audio_in * sizeof (uint32_t)); + portmap_a_out = (uint32_t*)malloc (inst->nports_audio_out * sizeof (uint32_t)); + portmap_rctl = (uint32_t*)malloc (inst->nports_ctrl * sizeof (uint32_t)); + portmap_ctrl = (uint32_t*)malloc (inst->nports_total * sizeof (uint32_t)); + + plugin_ports_pre = (float*)calloc (inst->nports_ctrl, sizeof (float)); + plugin_ports_post = (float*)calloc (inst->nports_ctrl, sizeof (float)); - atom_in = (LV2_Atom_Sequence*) malloc(inst->min_atom_bufsiz + sizeof(uint8_t)); - atom_out = (LV2_Atom_Sequence*) malloc(inst->min_atom_bufsiz + sizeof(uint8_t)); + atom_in = (LV2_Atom_Sequence*)malloc (inst->min_atom_bufsiz + sizeof (uint8_t)); + atom_out = (LV2_Atom_Sequence*)malloc (inst->min_atom_bufsiz + sizeof (uint8_t)); - rb_ctrl_to_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * inst->nports_ctrl * 2 * sizeof(float)); - rb_ctrl_from_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * inst->nports_ctrl * 2 * sizeof(float)); + rb_ctrl_to_ui = jack_ringbuffer_create ((UPDATE_FREQ_RATIO)*inst->nports_ctrl * 2 * sizeof (float)); + rb_ctrl_from_ui = jack_ringbuffer_create ((UPDATE_FREQ_RATIO)*inst->nports_ctrl * 2 * sizeof (float)); - rb_atom_to_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * inst->min_atom_bufsiz); - rb_atom_from_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * inst->min_atom_bufsiz); + rb_atom_to_ui = jack_ringbuffer_create ((UPDATE_FREQ_RATIO)*inst->min_atom_bufsiz); + rb_atom_from_ui = jack_ringbuffer_create ((UPDATE_FREQ_RATIO)*inst->min_atom_bufsiz); #ifdef HAVE_LIBLO - rb_osc_to_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * inst->nports_ctrl * 2 * sizeof(float)); + rb_osc_to_ui = jack_ringbuffer_create ((UPDATE_FREQ_RATIO)*inst->nports_ctrl * 2 * sizeof (float)); #endif /* resolve descriptors */ - plugin_dsp = inst->lv2_descriptor(inst->dsp_descriptor_id); - plugin_gui = inst->lv2ui_descriptor(inst->gui_descriptor_id); + plugin_dsp = inst->lv2_descriptor (inst->dsp_descriptor_id); + plugin_gui = inst->lv2ui_descriptor (inst->gui_descriptor_id); if (!plugin_dsp) { fprintf (stderr, "cannot resolve LV2 descriptor\n"); @@ -1574,27 +1657,26 @@ goto out; } /* jack-open -> samlerate */ - if (init_jack(jack_client_name ? jack_client_name : extui_host.plugin_human_id)) { + if (init_jack (jack_client_name ? jack_client_name : extui_host.plugin_human_id)) { fprintf (stderr, "cannot connect to JACK.\n"); #ifdef _WIN32 - MessageBox (NULL, TEXT( - "Cannot connect to JACK.\n" - "Please start the JACK Server first." - ), TEXT("Error"), MB_ICONERROR | MB_OK); + MessageBox (NULL, TEXT ( + "Cannot connect to JACK.\n" + "Please start the JACK Server first."), + TEXT ("Error"), MB_ICONERROR | MB_OK); #elif __APPLE__ rtk_osx_api_err ( - "Cannot connect to JACK.\n" - "Please start the JACK Server first." - ); + "Cannot connect to JACK.\n" + "Please start the JACK Server first."); #else - (void) system ("xmessage -button ok -center \"Cannot connect to JACK.\nPlease start the JACK Server first.\" &"); + (void)system ("xmessage -button ok -center \"Cannot connect to JACK.\nPlease start the JACK Server first.\" &"); #endif rv |= 4; goto out; } /* init plugin */ - plugin_instance = plugin_dsp->instantiate(plugin_dsp, j_samplerate, NULL, features); + plugin_instance = plugin_dsp->instantiate (plugin_dsp, j_samplerate, NULL, features); if (!plugin_instance) { fprintf (stderr, "instantiation failed\n"); rv |= 2; @@ -1602,15 +1684,15 @@ } /* connect ports */ - for (uint32_t p=0; p < inst->nports_total; ++p) { + for (uint32_t p = 0; p < inst->nports_total; ++p) { portmap_ctrl[p] = UINT32_MAX; switch (inst->ports[p].porttype) { case CONTROL_IN: plugin_ports_pre[c_ctrl] = inst->ports[p].val_default; case CONTROL_OUT: - portmap_ctrl[p] = c_ctrl; + portmap_ctrl[p] = c_ctrl; portmap_rctl[c_ctrl] = p; - plugin_dsp->connect_port(plugin_instance, p , &plugin_ports_pre[c_ctrl++]); + plugin_dsp->connect_port (plugin_instance, p, &plugin_ports_pre[c_ctrl++]); break; case AUDIO_IN: portmap_a_in[c_ain++] = p; @@ -1621,12 +1703,12 @@ case MIDI_IN: case ATOM_IN: portmap_atom_from_ui = p; - plugin_dsp->connect_port(plugin_instance, p , atom_in); + plugin_dsp->connect_port (plugin_instance, p, atom_in); break; case MIDI_OUT: case ATOM_OUT: portmap_atom_to_ui = p; - plugin_dsp->connect_port(plugin_instance, p , atom_out); + plugin_dsp->connect_port (plugin_instance, p, atom_out); break; default: fprintf (stderr, "yet unsupported port..\n"); @@ -1634,27 +1716,27 @@ } } - assert(c_ain == inst->nports_audio_in); - assert(c_aout == inst->nports_audio_out); - assert(c_ctrl == inst->nports_ctrl); + assert (c_ain == inst->nports_audio_in); + assert (c_aout == inst->nports_audio_out); + assert (c_ctrl == inst->nports_ctrl); if (inst->nports_atom_out > 0 || inst->nports_atom_in > 0 || inst->nports_midi_in > 0 || inst->nports_midi_out > 0) { - uri_atom_Sequence = uri_to_id(NULL, LV2_ATOM__Sequence); - uri_atom_EventTransfer = uri_to_id(NULL, LV2_ATOM__eventTransfer); - uri_midi_MidiEvent = uri_to_id(NULL, LV2_MIDI__MidiEvent); - uri_time_Position = uri_to_id(NULL, LV2_TIME__Position); - uri_time_frame = uri_to_id(NULL, LV2_TIME__frame); - uri_time_speed = uri_to_id(NULL, LV2_TIME__speed); - uri_time_bar = uri_to_id(NULL, LV2_TIME__bar); - uri_time_barBeat = uri_to_id(NULL, LV2_TIME__barBeat); - uri_time_beatUnit = uri_to_id(NULL, LV2_TIME__beatUnit); - uri_time_beatsPerBar = uri_to_id(NULL, LV2_TIME__beatsPerBar); - uri_time_beatsPerMinute = uri_to_id(NULL, LV2_TIME__beatsPerMinute); - lv2_atom_forge_init(&lv2_forge, &uri_map); + uri_atom_Sequence = uri_to_id (NULL, LV2_ATOM__Sequence); + uri_atom_EventTransfer = uri_to_id (NULL, LV2_ATOM__eventTransfer); + uri_midi_MidiEvent = uri_to_id (NULL, LV2_MIDI__MidiEvent); + uri_time_Position = uri_to_id (NULL, LV2_TIME__Position); + uri_time_frame = uri_to_id (NULL, LV2_TIME__frame); + uri_time_speed = uri_to_id (NULL, LV2_TIME__speed); + uri_time_bar = uri_to_id (NULL, LV2_TIME__bar); + uri_time_barBeat = uri_to_id (NULL, LV2_TIME__barBeat); + uri_time_beatUnit = uri_to_id (NULL, LV2_TIME__beatUnit); + uri_time_beatsPerBar = uri_to_id (NULL, LV2_TIME__beatsPerBar); + uri_time_beatsPerMinute = uri_to_id (NULL, LV2_TIME__beatsPerMinute); + lv2_atom_forge_init (&lv2_forge, &uri_map); } if (dump_ports) { - dump_control_ports(); + dump_control_ports (); } // apply user settings @@ -1674,8 +1756,8 @@ if (inst->ports[port_index].val_min < inst->ports[port_index].val_max) { if (pval[i].value < inst->ports[port_index].val_min || pval[i].value > inst->ports[port_index].val_max) { fprintf (stderr, "Value for port %d out of bounds %f <= %f <= %f\n", - pval[i].port_idx, - inst->ports[port_index].val_min, pval[i].value, inst->ports[port_index].val_max); + pval[i].port_idx, + inst->ports[port_index].val_min, pval[i].value, inst->ports[port_index].val_max); continue; } } @@ -1684,56 +1766,57 @@ plugin_ports_pre[pval[i].port_idx] = pval[i].value; } - if (jack_portsetup()) { + if (jack_portsetup ()) { rv |= 12; goto out; } - if (plugin_gui) { - /* init plugin GUI */ - extui_host.ui_closed = on_external_ui_closed; - instance_feature.data = plugin_instance; - gui_instance = plugin_gui->instantiate(plugin_gui, - plugin_dsp->URI, NULL, - &write_function, controller, - (void **)&extui, ui_features); - + if (plugin_gui && !headless) { + /* init plugin GUI */ + extui_host.ui_closed = on_external_ui_closed; + instance_feature.data = plugin_instance; + gui_instance = plugin_gui->instantiate (plugin_gui, + plugin_dsp->URI, NULL, + &write_function, controller, + (void**)&extui, ui_features); } if (!gui_instance || !extui) { #ifdef REQUIRE_UI - fprintf(stderr, "Error: GUI initialization failed.\n"); + fprintf (stderr, "Error: GUI initialization failed.\n"); rv |= 2; goto out; #else - fprintf(stderr, "Warning: GUI initialization failed.\n"); + if (!headless) { + fprintf (stderr, "Warning: GUI initialization failed.\n"); + } #endif } #ifndef _WIN32 if (mlockall (MCL_CURRENT | MCL_FUTURE)) { - fprintf(stderr, "Warning: Can not lock memory.\n"); + fprintf (stderr, "Warning: Can not lock memory.\n"); } #endif if (gui_instance) { for (uint32_t p = 0; p < inst->nports_ctrl; p++) { - if (jack_ringbuffer_write_space(rb_ctrl_to_ui) >= sizeof(uint32_t) + sizeof(float)) { - jack_ringbuffer_write(rb_ctrl_to_ui, (char *) &portmap_rctl[p], sizeof(uint32_t)); - jack_ringbuffer_write(rb_ctrl_to_ui, (char *) &plugin_ports_pre[p], sizeof(float)); + if (jack_ringbuffer_write_space (rb_ctrl_to_ui) >= sizeof (uint32_t) + sizeof (float)) { + jack_ringbuffer_write (rb_ctrl_to_ui, (char*)&portmap_rctl[p], sizeof (uint32_t)); + jack_ringbuffer_write (rb_ctrl_to_ui, (char*)&plugin_ports_pre[p], sizeof (float)); } } } if (plugin_dsp->extension_data) { - worker_iface = (LV2_Worker_Interface*) plugin_dsp->extension_data (LV2_WORKER__interface); + worker_iface = (LV2_Worker_Interface*)plugin_dsp->extension_data (LV2_WORKER__interface); } if (worker_iface) { - worker_init(); + worker_init (); } if (plugin_dsp->activate) { - plugin_dsp->activate(plugin_instance); + plugin_dsp->activate (plugin_instance); } if (jack_activate (j_client)) { @@ -1742,7 +1825,7 @@ goto out; } - jack_portconnect(JACK_AUTOCONNECT); + jack_portconnect (JACK_AUTOCONNECT); #ifdef HAVE_LIBLO if (osc_port > 0) { @@ -1761,34 +1844,32 @@ sleep (1); } } else { - - LV2_EXTERNAL_UI_SHOW(extui); + LV2_EXTERNAL_UI_SHOW (extui); #ifdef __APPLE__ - LV2_Atom_Sequence *data = (LV2_Atom_Sequence*) malloc(inst->min_atom_bufsiz * sizeof(uint8_t)); - CFRunLoopRef runLoop = CFRunLoopGetCurrent(); - CFRunLoopTimerContext context = {0, data, NULL, NULL, NULL}; - CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, 0, 1.0/UI_UPDATE_FPS, 0, 0, &osx_loop, &context); - CFRunLoopAddTimer(runLoop, timer, kCFRunLoopCommonModes); - rtk_osx_api_run(); - free(data); + LV2_Atom_Sequence* data = (LV2_Atom_Sequence*)malloc (inst->min_atom_bufsiz * sizeof (uint8_t)); + CFRunLoopRef runLoop = CFRunLoopGetCurrent (); + CFRunLoopTimerContext context = { 0, data, NULL, NULL, NULL }; + CFRunLoopTimerRef timer = CFRunLoopTimerCreate (kCFAllocatorDefault, 0, 1.0 / UI_UPDATE_FPS, 0, 0, &osx_loop, &context); + CFRunLoopAddTimer (runLoop, timer, kCFRunLoopCommonModes); + rtk_osx_api_run (); + free (data); #else - main_loop(); + main_loop (); #endif - LV2_EXTERNAL_UI_HIDE(extui); + LV2_EXTERNAL_UI_HIDE (extui); } out: free (pval); - cleanup(0); + cleanup (0); #ifdef _WIN32 - pthread_win32_process_detach_np(); + pthread_win32_process_detach_np (); #endif #if (defined _WIN32 && defined RTK_STATIC_INIT) - glib_cleanup_static(); + glib_cleanup_static (); #endif - return(rv); + return (rv); } -/* vi:set ts=2 sts=2 sw=2: */ diff -Nru x42-plugins-20170428/robtk/pugl/pugl_win.cpp x42-plugins-20190714/robtk/pugl/pugl_win.cpp --- x42-plugins-20170428/robtk/pugl/pugl_win.cpp 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/pugl/pugl_win.cpp 2019-07-14 19:08:03.000000000 +0000 @@ -81,22 +81,31 @@ // FIXME: This is nasty, and pugl should not have static anything. // Should class be a parameter? Does this make sense on other platforms? static int wc_count = 0; + int retry = 99; char classNameBuf[256]; - _snprintf(classNameBuf, sizeof(classNameBuf), "x%d%s", wc_count++, title); - classNameBuf[sizeof(classNameBuf)-1] = '\0'; + while (true) { + _snprintf(classNameBuf, sizeof(classNameBuf), "x%d%s", wc_count++, title); + classNameBuf[sizeof(classNameBuf)-1] = '\0'; - impl->wc.style = CS_OWNDC; - impl->wc.lpfnWndProc = wndProc; - impl->wc.cbClsExtra = 0; - impl->wc.cbWndExtra = 0; - impl->wc.hInstance = 0; - impl->wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - impl->wc.hCursor = LoadCursor(NULL, IDC_ARROW); - impl->wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - impl->wc.lpszMenuName = NULL; - impl->wc.lpszClassName = strdup(classNameBuf); + impl->wc.style = CS_OWNDC; + impl->wc.lpfnWndProc = wndProc; + impl->wc.cbClsExtra = 0; + impl->wc.cbWndExtra = 0; + impl->wc.hInstance = 0; + impl->wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + impl->wc.hCursor = LoadCursor(NULL, IDC_ARROW); + impl->wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + impl->wc.lpszMenuName = NULL; + impl->wc.lpszClassName = strdup(classNameBuf); - if (!RegisterClass(&impl->wc)) { + if (RegisterClass(&impl->wc)) { + break; + } + if (--retry > 0) { + free((void*)impl->wc.lpszClassName); + continue; + } + /* fail */ free((void*)impl->wc.lpszClassName); free(impl); free(view); diff -Nru x42-plugins-20170428/robtk/robtk.h x42-plugins-20190714/robtk/robtk.h --- x42-plugins-20170428/robtk/robtk.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/robtk.h 2019-07-14 19:08:03.000000000 +0000 @@ -32,6 +32,9 @@ #include #include "lv2/lv2plug.in/ns/extensions/ui/ui.h" +#include "lv2/lv2plug.in/ns/ext/options/options.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" #ifdef __APPLE__ #include diff -Nru x42-plugins-20170428/robtk/robtk.mk x42-plugins-20190714/robtk/robtk.mk --- x42-plugins-20170428/robtk/robtk.mk 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/robtk.mk 2019-07-14 19:08:03.000000000 +0000 @@ -1,5 +1,6 @@ RT=$(RW)rtk/ WD=$(RW)widgets/robtk_ +PKG_CONFIG?=pkg-config STRIP?=strip LIBSTRIPFLAGS?=-s APPSTRIPFLAGS?=-s @@ -33,12 +34,12 @@ JACKLIBS+=-ldl endif else - JACKLIBS+=`pkg-config $(PKG_UI_FLAGS) --libs jack` + JACKLIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs jack` endif -ifeq ($(shell pkg-config --exists liblo && echo yes), yes) - JACKCFLAGS+=`pkg-config $(PKG_UI_FLAGS) --cflags liblo` -DHAVE_LIBLO - JACKLIBS+=`pkg-config $(PKG_UI_FLAGS) --libs liblo` +ifeq ($(shell $(PKG_CONFIG) --exists liblo && echo yes), yes) + JACKCFLAGS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --cflags liblo` -DHAVE_LIBLO + JACKLIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs liblo` endif diff -Nru x42-plugins-20170428/robtk/rtk/style.h x42-plugins-20190714/robtk/rtk/style.h --- x42-plugins-20170428/robtk/rtk/style.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/rtk/style.h 2019-07-14 19:08:03.000000000 +0000 @@ -1,3 +1,5 @@ +#ifndef RTK_STYLE_H +#define RTK_STYLE_H /* colors */ static const float c_trs[4] = {0.0, 0.0, 0.0, 0.0}; @@ -50,3 +52,4 @@ ISBRIGHT(COL) ? COL[1] / (X) : COL[1] * (X), \ ISBRIGHT(COL) ? COL[2] / (X) : COL[2] * (X) +#endif diff -Nru x42-plugins-20170428/robtk/ui_gl.c x42-plugins-20190714/robtk/ui_gl.c --- x42-plugins-20170428/robtk/ui_gl.c 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/ui_gl.c 2019-07-14 19:08:03.000000000 +0000 @@ -100,7 +100,9 @@ #include "gl/posringbuf.h" #include "robtk.h" -#include "gpg_init.c" +#ifdef WITH_SIGNATURE +# include "gpg_init.c" +#endif static void opengl_init () { glClearColor (0.0f, 0.0f, 0.0f, 0.0f); @@ -652,7 +654,7 @@ self->width = nox; self->height = noy; } else if (nox > self->width || noy > self->height) { - LVGLResize rsz = plugin_scale_mode(self->ui); + enum LVGLResize rsz = plugin_scale_mode(self->ui); if (rsz == LVGL_ZOOM_TO_ASPECT || rsz == LVGL_LAYOUT_TO_FIT) { puglUpdateGeometryConstraints(self->view, nox, noy, rsz == LVGL_ZOOM_TO_ASPECT); return; @@ -662,7 +664,7 @@ if (nox > self->width) self->width = nox; if (noy > self->height) self->height = noy; } else if (nox < self->width || noy < self->height) { - LVGLResize rsz = plugin_scale_mode(self->ui); + enum LVGLResize rsz = plugin_scale_mode(self->ui); if (rsz == LVGL_ZOOM_TO_ASPECT || rsz == LVGL_LAYOUT_TO_FIT) { puglUpdateGeometryConstraints(self->view, nox, noy, rsz == LVGL_ZOOM_TO_ASPECT); } @@ -1190,7 +1192,7 @@ else if (self->gpg_shade < .5) self->gpg_shade += .05; puglPostRedisplay(self->view); } else { - rtk_open_url ("http://x42-plugins.com"); + rtk_open_url (RTK_URI); } return; } @@ -1253,7 +1255,7 @@ // Set up GL UI self->view = puglCreate( self->extui ? (PuglNativeWindow) NULL : self->parent, - self->extui ? self->extui->plugin_human_id : "robtk", + self->extui ? self->extui->plugin_human_id : RTK_URI, self->width, self->height, dflw, dflh, #ifdef LVGL_RESIZEABLE @@ -1449,11 +1451,18 @@ pthread_cond_init(&self->data_ready, NULL); #endif + const LV2_Options_Option* options = NULL; + LV2_URID_Map* map = NULL; + for (int i = 0; features && features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_UI__parent)) { self->parent = (PuglNativeWindow)features[i]->data; } else if (!strcmp(features[i]->URI, LV2_UI__resize)) { self->resize = (LV2UI_Resize*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)features[i]->data; } #ifdef XTERNAL_UI else if (!strcmp(features[i]->URI, LV2_EXTERNAL_UI_URI) && !self->extui) { @@ -1469,6 +1478,17 @@ #endif } + if (options && map) { + LV2_URID atom_Long = map->map(map->handle, LV2_ATOM__Long); + LV2_URID transient_for = map->map (map->handle, "http://kxstudio.sf.net/ns/lv2ext/props#TransientWindowId"); + + for (const LV2_Options_Option* o = options; o->key; ++o) { + if (o->context == LV2_OPTIONS_INSTANCE && o->key == transient_for && o->type == atom_Long) { + self->transient_id = *(const unsigned long*)o->value; + } + } + } + if (!self->parent && !self->extui) { fprintf(stderr, "error: No parent window provided.\n"); free(self); @@ -1481,9 +1501,8 @@ #ifdef WITH_SIGNATURE self->gpg_shade = 0; -#endif - # include "gpg_check.c" +#endif self->tl = NULL; self->ui = instantiate(self, diff -Nru x42-plugins-20170428/robtk/widgets/robtk_checkbutton.h x42-plugins-20190714/robtk/widgets/robtk_checkbutton.h --- x42-plugins-20170428/robtk/widgets/robtk_checkbutton.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_checkbutton.h 2019-07-14 19:08:03.000000000 +0000 @@ -43,6 +43,13 @@ bool (*cb) (RobWidget* w, void* handle); void* handle; + void (*touch_cb) (void*, uint32_t, bool); + void* touch_hd; + uint32_t touch_id; + + void (*ttip) (RobWidget* rw, bool on, void* handle); + void* ttip_handle; + cairo_pattern_t* btn_enabled; cairo_pattern_t* btn_inactive; cairo_pattern_t* btn_led; @@ -268,6 +275,12 @@ if (!d->sensitive) { return NULL; } if (!d->prelight) { return NULL; } if (d->radiomode && d->enabled) { return NULL; } + if (d->touch_cb && event->button == 1) { + d->touch_cb (d->touch_hd, d->touch_id, true); + } + if (d->ttip) { + d->ttip (d->rw, false, d->ttip_handle); + } if ( ((d->temporary_mode & 1) && event->button == 3) || ((d->temporary_mode & 2) && event->state & ROBTK_MOD_SHIFT) || ((d->temporary_mode & 4) && event->state & ROBTK_MOD_CTRL) @@ -281,10 +294,14 @@ static RobWidget* robtk_cbtn_mouseup(RobWidget *handle, RobTkBtnEvent *event) { RobTkCBtn * d = (RobTkCBtn *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } - if (!d->prelight) { return NULL; } if (d->radiomode && d->enabled) { return NULL; } if (event->button !=1 && !((d->temporary_mode & 1) && event->button == 3)) { return NULL; } - robtk_cbtn_update_enabled(d, ! d->enabled); + if (d->prelight) { + robtk_cbtn_update_enabled(d, ! d->enabled); + } + if (d->touch_cb && event->button == 1) { + d->touch_cb (d->touch_hd, d->touch_id, false); + } return NULL; } @@ -294,6 +311,9 @@ d->prelight = TRUE; queue_draw(d->rw); } + if (d->ttip) { + d->ttip (d->rw, true, d->ttip_handle); + } } static void robtk_cbtn_leave_notify(RobWidget *handle) { @@ -302,6 +322,9 @@ d->prelight = FALSE; queue_draw(d->rw); } + if (d->ttip) { + d->ttip (d->rw, false, d->ttip_handle); + } } /****************************************************************************** @@ -343,6 +366,11 @@ d->show_led = led; d->cb = NULL; d->handle = NULL; + d->touch_cb = NULL; + d->touch_hd = NULL; + d->touch_id = 0; + d->ttip = NULL; + d->ttip_handle = NULL; d->sensitive = TRUE; d->radiomode = FALSE; d->temporary_mode = 0; @@ -416,6 +444,17 @@ d->handle = handle; } +static void robtk_cbtn_set_touch(RobTkCBtn *d, void (*cb) (void*, uint32_t, bool), void* handle, uint32_t id) { + d->touch_cb = cb; + d->touch_hd = handle; + d->touch_id = id; +} + +static void robtk_cbtn_annotation_callback(RobTkCBtn *d, void (*cb) (RobWidget* w, bool, void* handle), void* handle) { + d->ttip = cb; + d->ttip_handle = handle; +} + static void robtk_cbtn_set_active(RobTkCBtn *d, bool v) { robtk_cbtn_update_enabled(d, v); } diff -Nru x42-plugins-20170428/robtk/widgets/robtk_checkimgbutton.h x42-plugins-20190714/robtk/widgets/robtk_checkimgbutton.h --- x42-plugins-20170428/robtk/widgets/robtk_checkimgbutton.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_checkimgbutton.h 2019-07-14 19:08:03.000000000 +0000 @@ -31,6 +31,10 @@ bool (*cb) (RobWidget* w, void* handle); void* handle; + void (*touch_cb) (void*, uint32_t, bool); + void* touch_hd; + uint32_t touch_id; + cairo_pattern_t* btn_enabled; cairo_pattern_t* btn_inactive; cairo_surface_t* sf_img_normal; @@ -135,6 +139,9 @@ RobTkIBtn * d = (RobTkIBtn *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } if (!d->prelight) { return NULL; } + if (d->touch_cb && event->button == 1) { + d->touch_cb (d->touch_hd, d->touch_id, true); + } if ( ((d->temporary_mode & 1) && event->button == 3) || ((d->temporary_mode & 2) && event->state & ROBTK_MOD_SHIFT) || ((d->temporary_mode & 4) && event->state & ROBTK_MOD_CTRL) @@ -149,9 +156,13 @@ static RobWidget* robtk_ibtn_mouseup(RobWidget *handle, RobTkBtnEvent *event) { RobTkIBtn * d = (RobTkIBtn *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } - if (!d->prelight) { return NULL; } if (event->button !=1 && !((d->temporary_mode & 1) && event->button == 3)) { return NULL; } - robtk_ibtn_update_enabled(d, ! d->enabled); + if (d->prelight) { + robtk_ibtn_update_enabled(d, ! d->enabled); + } + if (d->touch_cb && event->button == 1) { + d->touch_cb (d->touch_hd, d->touch_id, false); + } return NULL; } @@ -203,6 +214,9 @@ d->cb = NULL; d->handle = NULL; + d->touch_cb = NULL; + d->touch_hd = NULL; + d->touch_id = 0; d->sf_img_normal = n; d->sf_img_enabled = e; d->btn_enabled = NULL; @@ -254,6 +268,12 @@ d->handle = handle; } +static void robtk_ibtn_set_touch(RobTkIBtn *d, void (*cb) (void*, uint32_t, bool), void* handle, uint32_t id) { + d->touch_cb = cb; + d->touch_hd = handle; + d->touch_id = id; +} + static void robtk_ibtn_set_active(RobTkIBtn *d, bool v) { robtk_ibtn_update_enabled(d, v); } diff -Nru x42-plugins-20170428/robtk/widgets/robtk_dial.h x42-plugins-20190714/robtk/widgets/robtk_dial.h --- x42-plugins-20170428/robtk/widgets/robtk_dial.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_dial.h 2019-07-14 19:08:03.000000000 +0000 @@ -68,6 +68,11 @@ void (*ann) (struct _RobTkDial* d, cairo_t *cr, void* handle); void* ann_handle; + void (*touch_cb) (void*, uint32_t, bool); + void* touch_hd; + uint32_t touch_id; + bool touching; + cairo_pattern_t* dpat; cairo_surface_t* bg; float bg_scale; @@ -243,6 +248,9 @@ static RobWidget* robtk_dial_mousedown(RobWidget* handle, RobTkBtnEvent *ev) { RobTkDial * d = (RobTkDial *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, true); + } if (ev->state & ROBTK_MOD_SHIFT) { robtk_dial_update_value(d, d->dfl); robtk_dial_update_state(d, d->click_dflt); @@ -276,6 +284,9 @@ robtk_dial_update_state(d, (d->click_state + 1) % (d->click_states + 1)); } d->clicking = FALSE; + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, false); + } queue_draw(d->rw); return NULL; } @@ -365,6 +376,10 @@ static void robtk_dial_leave_notify(RobWidget *handle) { RobTkDial * d = (RobTkDial *)GET_HANDLE(handle); + if (d->touch_cb && d->touching) { + d->touch_cb (d->touch_hd, d->touch_id, false); + d->touching = FALSE; + } if (d->prelight) { d->prelight = FALSE; d->scroll_accel = 1.0; @@ -427,6 +442,12 @@ default: break; } + + if (d->touch_cb && !d->touching) { + d->touch_cb (d->touch_hd, d->touch_id, true); + d->touching = TRUE; + } + robtk_dial_update_value(d, val); return NULL; } @@ -541,6 +562,10 @@ d->handle = NULL; d->ann = NULL; d->ann_handle = NULL; + d->touch_cb = NULL; + d->touch_hd = NULL; + d->touch_id = 0; + d->touching = FALSE; d->min = min; d->max = max; d->acc = step; @@ -626,6 +651,12 @@ d->ann_handle = handle; } +static void robtk_dial_set_touch(RobTkDial *d, void (*cb) (void*, uint32_t, bool), void* handle, uint32_t id) { + d->touch_cb = cb; + d->touch_hd = handle; + d->touch_id = id; +} + static void robtk_dial_set_default(RobTkDial *d, float v) { if (d->constrain_to_accuracy) { v = d->min + rintf((v-d->min) / d->acc ) * d->acc; diff -Nru x42-plugins-20170428/robtk/widgets/robtk_label.h x42-plugins-20190714/robtk/widgets/robtk_label.h --- x42-plugins-20170428/robtk/widgets/robtk_label.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_label.h 2019-07-14 19:08:03.000000000 +0000 @@ -36,7 +36,7 @@ pthread_mutex_t _mutex; float scale; - void (*ttip) (struct _RobTkLbl* d, bool on, void* handle); + void (*ttip) (RobWidget* rw, bool on, void* handle); void* ttip_handle; } RobTkLbl; @@ -220,18 +220,18 @@ static void robtk_lbl_ttip_show (RobWidget *handle) { RobTkLbl* d = (RobTkLbl *)GET_HANDLE(handle); if (d->ttip) { - d->ttip (d, true, d->ttip_handle); + d->ttip (d->rw, true, d->ttip_handle); } } static void robtk_lbl_ttip_hide (RobWidget *handle) { RobTkLbl* d = (RobTkLbl *)GET_HANDLE(handle); if (d->ttip) { - d->ttip (d, false, d->ttip_handle); + d->ttip (d->rw, false, d->ttip_handle); } } -static void robtk_lbl_annotation_callback(RobTkLbl *d, void (*cb) (RobTkLbl* d, bool, void* handle), void* handle) { +static void robtk_lbl_annotation_callback(RobTkLbl *d, void (*cb) (RobWidget* w, bool, void* handle), void* handle) { d->ttip = cb; d->ttip_handle = handle; if (d->ttip) { diff -Nru x42-plugins-20170428/robtk/widgets/robtk_scale.h x42-plugins-20190714/robtk/widgets/robtk_scale.h --- x42-plugins-20170428/robtk/widgets/robtk_scale.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_scale.h 2019-07-14 19:08:03.000000000 +0000 @@ -42,6 +42,11 @@ bool (*cb) (RobWidget* w, void* handle); void* handle; + void (*touch_cb) (void*, uint32_t, bool); + void* touch_hd; + uint32_t touch_id; + bool touching; + cairo_pattern_t* dpat; cairo_pattern_t* fpat; cairo_surface_t* bg; @@ -123,6 +128,9 @@ static RobWidget* robtk_scale_mousedown(RobWidget *handle, RobTkBtnEvent *event) { RobTkScale * d = (RobTkScale *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, true); + } if (event->state & ROBTK_MOD_SHIFT) { robtk_scale_update_value(d, d->dfl); } else { @@ -138,6 +146,9 @@ RobTkScale * d = (RobTkScale *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } d->drag_x = d->drag_y = -1; + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, false); + } queue_draw(d->rw); return NULL; } @@ -188,6 +199,10 @@ static void robtk_scale_leave_notify(RobWidget *handle) { RobTkScale * d = (RobTkScale *)GET_HANDLE(handle); + if (d->touch_cb && d->touching) { + d->touch_cb (d->touch_hd, d->touch_id, false); + d->touching = FALSE; + } if (d->prelight) { d->prelight = FALSE; queue_draw(d->rw); @@ -253,6 +268,12 @@ default: break; } + + if (d->touch_cb && !d->touching) { + d->touch_cb (d->touch_hd, d->touch_id, true); + d->touching = TRUE; + } + robtk_scale_update_value(d, val); return NULL; } @@ -470,6 +491,10 @@ d->mark_expose = FALSE; d->cb = NULL; d->handle = NULL; + d->touch_cb = NULL; + d->touch_hd = NULL; + d->touch_id = 0; + d->touching = FALSE; d->min = min; d->max = max; d->acc = step; @@ -526,6 +551,12 @@ d->handle = handle; } +static void robtk_scale_set_touch(RobTkScale *d, void (*cb) (void*, uint32_t, bool), void* handle, uint32_t id) { + d->touch_cb = cb; + d->touch_hd = handle; + d->touch_id = id; +} + static void robtk_scale_set_value(RobTkScale *d, float v) { v = d->min + rint((v-d->min) / d->acc ) * d->acc; robtk_scale_update_value(d, v); diff -Nru x42-plugins-20170428/robtk/widgets/robtk_selector.h x42-plugins-20190714/robtk/widgets/robtk_selector.h --- x42-plugins-20170428/robtk/widgets/robtk_selector.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_selector.h 2019-07-14 19:08:03.000000000 +0000 @@ -39,8 +39,14 @@ bool wraparound; cairo_pattern_t* btn_bg; - bool (*cb) (RobWidget* w, gpointer handle); - gpointer handle; + bool (*cb) (RobWidget* w, void* handle); + void* handle; + + void (*touch_cb) (void*, uint32_t, bool); + void* touch_hd; + uint32_t touch_id; + bool touching; + int active_item; int item_count; int dfl; @@ -162,9 +168,25 @@ queue_draw(d->rw); } +static RobWidget* robtk_select_mousedown(RobWidget* handle, RobTkBtnEvent *ev) { + RobTkSelect * d = (RobTkSelect *)GET_HANDLE(handle); + if (!d->sensitive) { return NULL; } + if (!d->prelight) { return NULL; } + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, true); + } + return NULL; +} + static RobWidget* robtk_select_mouseup(RobWidget* handle, RobTkBtnEvent *ev) { RobTkSelect * d = (RobTkSelect *)GET_HANDLE(handle); if (!d->sensitive) { return NULL; } + if (!d->prelight) { + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, false); + } + return NULL; + } if (ev->state & ROBTK_MOD_SHIFT) { robtk_select_set_active_item(d, d->dfl); @@ -187,6 +209,10 @@ } robtk_select_set_active_item(d, active_item); + + if (d->touch_cb) { + d->touch_cb (d->touch_hd, d->touch_id, false); + } return NULL; } @@ -231,6 +257,11 @@ default: break; } + if (d->touch_cb && !d->touching) { + d->touch_cb (d->touch_hd, d->touch_id, true); + d->touching = TRUE; + } + robtk_select_set_active_item(d, active_item); return handle; } @@ -245,6 +276,10 @@ static void robtk_select_leave_notify(RobWidget *handle) { RobTkSelect * d = (RobTkSelect *)GET_HANDLE(handle); + if (d->touch_cb && d->touching) { + d->touch_cb (d->touch_hd, d->touch_id, false); + d->touching = FALSE; + } if (d->prelight) { d->prelight = FALSE; queue_draw(d->rw); @@ -287,6 +322,10 @@ d->lightarr = 0; d->cb = NULL; d->handle = NULL; + d->touch_cb = NULL; + d->touch_hd = NULL; + d->touch_id = 0; + d->touching = FALSE; d->scale = 1.0; pthread_mutex_init (&d->_mutex, 0); @@ -301,6 +340,7 @@ ROBWIDGET_SETNAME(d->rw, "select"); robwidget_set_expose_event(d->rw, robtk_select_expose_event); robwidget_set_mouseup(d->rw, robtk_select_mouseup); + robwidget_set_mousedown(d->rw, robtk_select_mousedown); robwidget_set_mousemove(d->rw, robtk_select_mousemove); robwidget_set_mousescroll(d->rw, robtk_select_scroll); robwidget_set_enter_notify(d->rw, robtk_select_enter_notify); @@ -344,11 +384,17 @@ return d->rw; } -static void robtk_select_set_callback(RobTkSelect *d, bool (*cb) (RobWidget* w, gpointer handle), gpointer handle) { +static void robtk_select_set_callback(RobTkSelect *d, bool (*cb) (RobWidget* w, void* handle), void* handle) { d->cb = cb; d->handle = handle; } +static void robtk_select_set_touch(RobTkSelect *d, void (*cb) (void*, uint32_t, bool), void* handle, uint32_t id) { + d->touch_cb = cb; + d->touch_hd = handle; + d->touch_id = id; +} + static void robtk_select_set_default_item(RobTkSelect *d, int i) { d->dfl = i; } diff -Nru x42-plugins-20170428/robtk/widgets/robtk_spinner.h x42-plugins-20190714/robtk/widgets/robtk_spinner.h --- x42-plugins-20170428/robtk/widgets/robtk_spinner.h 2017-03-09 00:05:05.000000000 +0000 +++ x42-plugins-20190714/robtk/widgets/robtk_spinner.h 2019-07-14 19:08:03.000000000 +0000 @@ -38,8 +38,8 @@ bool sensitive; char prec_fmt[8]; - bool (*cb) (RobWidget* w, gpointer handle); - gpointer handle; + bool (*cb) (RobWidget* w, void* handle); + void* handle; int lbl; pthread_mutex_t _mutex; } RobTkSpin; @@ -63,7 +63,7 @@ * child callbacks */ -static bool robtk_spin_callback(RobWidget *w, gpointer handle) { +static bool robtk_spin_callback(RobWidget *w, void* handle) { RobTkSpin *d = (RobTkSpin *) handle; robtk_spin_render(d); if (d->cb) d->cb(robtk_dial_widget(d->dial), d->handle); @@ -168,7 +168,7 @@ return d->rw; } -static void robtk_spin_set_callback(RobTkSpin *d, bool (*cb) (RobWidget* w, gpointer handle), gpointer handle) { +static void robtk_spin_set_callback(RobTkSpin *d, bool (*cb) (RobWidget* w, void* handle), void* handle) { d->cb = cb; d->handle = handle; } diff -Nru x42-plugins-20170428/sisco.lv2/gui/sisco.c x42-plugins-20190714/sisco.lv2/gui/sisco.c --- x42-plugins-20170428/sisco.lv2/gui/sisco.c 2017-03-09 00:06:03.000000000 +0000 +++ x42-plugins-20190714/sisco.lv2/gui/sisco.c 2019-07-14 19:11:45.000000000 +0000 @@ -2459,8 +2459,8 @@ 0.7, 0.7, 0.0, }; ui->btn_ann[c] = robtk_mbtn_new(4); - robtk_mbtn_set_active(ui->btn_ann[c], 1); - ui->cann[c] = 1; + robtk_mbtn_set_active(ui->btn_ann[c], 0); + ui->cann[c] = 0; robtk_mbtn_set_sensitive(ui->btn_ann[c], false); robtk_mbtn_set_leds_rgb(ui->btn_ann[c], mbtncolors); diff -Nru x42-plugins-20170428/sisco.lv2/Makefile x42-plugins-20190714/sisco.lv2/Makefile --- x42-plugins-20170428/sisco.lv2/Makefile 2017-03-09 00:06:03.000000000 +0000 +++ x42-plugins-20190714/sisco.lv2/Makefile 2019-07-14 19:11:45.000000000 +0000 @@ -1,20 +1,21 @@ #!/usr/bin/make -f -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +MANDIR ?= $(PREFIX)/share/man/man1 +LV2DIR ?= $(PREFIX)/lib/lv2 + +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CFLAGS ?= -g -Wall -Wno-unused-function -LIBDIR ?= lib -STRIP ?= strip + +PKG_CONFIG?=pkg-config +STRIP?= strip EXTERNALUI?=no BUILDGTK?=no KXURI?=yes RW?=robtk/ ############################################################################### -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 -bindir ?= $(PREFIX)/bin -mandir ?= $(PREFIX)/share/man -man1dir = $(mandir)/man1 BUILDDIR=build/ BUNDLE=sisco.lv2 @@ -52,8 +53,8 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_GL_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` -pthread - STRIPFLAGS=-s + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` -pthread + STRIPFLAGS= -s EXTENDED_RE=-r endif @@ -113,19 +114,19 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --atleast-version=1.6.0 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) $(error "LV2 SDK needs to be version 1.6.0 or later") endif -ifeq ($(shell pkg-config --exists pango cairo $(PKG_GTK_LIBS) $(PKG_GL_LIBS) || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GTK_LIBS) $(PKG_GL_LIBS) || echo no), no) $(error "This plugin requires cairo pango $(PKG_GTK_LIBS) $(PKG_GL_LIBS)") endif -ifeq ($(shell pkg-config --exists jack || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif @@ -147,19 +148,22 @@ LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif # add library dependent flags and libs -LV2CFLAGS += `pkg-config --cflags lv2` -LV2CFLAGS += -fPIC $(OPTIMIZATIONS) -DVERSION="\"$(sisco_VERSION)\"" +LV2CFLAGS += `$(PKG_CONFIG) --cflags lv2` +LV2CFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(sisco_VERSION)\"" +ifeq ($(XWIN),) + override LV2CFLAGS += -fPIC -fvisibility=hidden +endif -GTKUICFLAGS+= $(LV2CFLAGS) `pkg-config --cflags gtk+-2.0 cairo pango` -GTKUILIBS+=`pkg-config --libs gtk+-2.0 cairo pango` +GTKUICFLAGS+= $(LV2CFLAGS) `$(PKG_CONFIG) --cflags gtk+-2.0 cairo pango` +GTKUILIBS+=`$(PKG_CONFIG) --libs gtk+-2.0 cairo pango` -GLUICFLAGS+= $(LV2CFLAGS) `pkg-config --cflags cairo pango` -GLUILIBS+=`pkg-config $(PKG_UI_FLAGS) --libs cairo pangocairo pango $(PKG_GL_LIBS)` +GLUICFLAGS+= $(LV2CFLAGS) `$(PKG_CONFIG) --cflags cairo pango` +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango $(PKG_GL_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 endif @@ -168,8 +172,8 @@ GLUILIBS+=$(LIC_LOADLIBES) JACKCFLAGS+= $(OPTIMIZATIONS) -DVERSION="\"$(sisco_VERSION)\"" $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` -JACKLIBS=-lm `pkg-config $(PKG_UI_FLAGS) --libs pangocairo $(PKG_GL_LIBS)` $(GLUILIBS) $(LIC_LOADLIBES) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs pangocairo $(PKG_GL_LIBS)` $(GLUILIBS) GLUICFLAGS+=-DUSE_GUI_THREAD ifeq ($(GLTHREADSYNC), yes) @@ -265,24 +269,23 @@ install-bin: $(BUILDDIR)x42-scope$(EXE_EXT) ifneq ($(targets),) - install -d $(DESTDIR)$(bindir) - install -m755 $(BUILDDIR)x42-scope$(EXE_EXT) $(DESTDIR)$(bindir)/ + install -d $(DESTDIR)$(BINDIR) + install -m755 $(BUILDDIR)x42-scope$(EXE_EXT) $(DESTDIR)$(BINDIR)/ endif install-man: x42-scope.1 ifneq ($(targets),) - install -d $(DESTDIR)$(man1dir) - install -m644 x42-scope.1 $(DESTDIR)$(man1dir) + install -d $(DESTDIR)$(MANDIR) + install -m644 x42-scope.1 $(DESTDIR)$(MANDIR) endif uninstall-bin: - rm -f $(DESTDIR)$(bindir)/x42-scope$(EXE_EXT) - -rmdir $(DESTDIR)$(bindir) + rm -f $(DESTDIR)$(BINDIR)/x42-scope$(EXE_EXT) + -rmdir $(DESTDIR)$(BINDIR) uninstall-man: - rm -f $(DESTDIR)$(man1dir)/x42-scope.1 - -rmdir $(DESTDIR)$(man1dir) - -rmdir $(DESTDIR)$(mandir) + rm -f $(DESTDIR)$(MANDIR)/x42-scope.1 + -rmdir $(DESTDIR)$(MANDIR) install-lv2: all ifneq ($(targets),) diff -Nru x42-plugins-20170428/sisco.lv2/src/sisco.c x42-plugins-20190714/sisco.lv2/src/sisco.c --- x42-plugins-20170428/sisco.lv2/src/sisco.c 2017-03-09 00:06:03.000000000 +0000 +++ x42-plugins-20190714/sisco.lv2/src/sisco.c 2019-07-14 19:11:45.000000000 +0000 @@ -146,7 +146,7 @@ self->channelstate[c].gain = 1.0; self->channelstate[c].xoff = 0.0; self->channelstate[c].yoff = 0.0; - self->channelstate[c].opts = 3.0; + self->channelstate[c].opts = 1.0; } lv2_atom_forge_init(&self->forge, self->map); diff -Nru x42-plugins-20170428/spectra.lv2/COPYING x42-plugins-20190714/spectra.lv2/COPYING --- x42-plugins-20170428/spectra.lv2/COPYING 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/COPYING 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -Nru x42-plugins-20170428/spectra.lv2/git2lv2.mk x42-plugins-20190714/spectra.lv2/git2lv2.mk --- x42-plugins-20170428/spectra.lv2/git2lv2.mk 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/git2lv2.mk 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,43 @@ + +############################################################################### +# extract versions +GIT_REV_REGEXP="([0-9][0-9]*)\.([0-9][0-9]*)(\.([0-9][0-9]*))?(-([0-9][0-9]*))?(-g([a-f0-9]+))?" + +override MAJOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\1/) +override MINOR=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\2/) +override MICRO=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\4/) +override GITREV=$(shell echo $(LV2VERSION) | sed $(EXTENDED_RE) -e s/$(GIT_REV_REGEXP)/\\6/) + +ifeq ($(MAJOR),) + override MAJOR=0 +endif +ifeq ($(MINOR),) + override MINOR=0 +endif +ifeq ($(MICRO),) + override MICRO=0 +endif + +$(info Version: $(LV2VERSION) -> $(MAJOR) $(MINOR) $(MICRO) $(GITREV)) + +# version requirements, see +# http://lv2plug.in/ns/lv2core/#minorVersion +# http://lv2plug.in/ns/lv2core/#microVersion +ifeq ($(GITREV),) +# even numbers for tagged releases + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 ) + override LV2MIC = 0 +else +# odd-numbers for all non tagged git versions + override LV2MIN = $(shell expr $(MAJOR) \* 65536 + $(MINOR) \* 256 + $(MICRO) \* 2 + 1 ) + override LV2MIC = $(shell expr $(GITREV) \* 2 + 1) +endif + +ifeq ($(LV2MIN),) + $(error "Cannot extract required LV2 minor-version parameter") +endif +ifeq ($(LV2MIC),) + $(error "Cannot extract required LV2 micro-version parameter") +endif + +$(info LV2 Version: $(LV2MIN) $(LV2MIC)) diff -Nru x42-plugins-20170428/spectra.lv2/gui/fft.c x42-plugins-20190714/spectra.lv2/gui/fft.c --- x42-plugins-20170428/spectra.lv2/gui/fft.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/gui/fft.c 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,461 @@ +/* FFT analysis - spectrogram + * Copyright (C) 2013, 2019 Robin Gareus + * + * 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, 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. + */ + +#include +#include +#include +#include + +#ifndef MIN +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif + +static pthread_mutex_t fftw_planner_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int instance_count = 0; + +typedef enum { + W_HANN = 0, + W_HAMMMIN, + W_NUTTALL, + W_BLACKMAN_NUTTALL, + W_BLACKMAN_HARRIS, + W_FLAT_TOP +} window_t; + +/****************************************************************************** + * internal FFT abstraction + */ +struct FFTAnalysis { + uint32_t window_size; + window_t window_type; + uint32_t data_size; + double rate; + double freq_per_bin; + double phasediff_step; + float* window; + float* fft_in; + float* fft_out; + float* power; + float* phase; + float* phase_h; + fftwf_plan fftplan; + + float* ringbuf; + uint32_t rboff; + uint32_t smps; + uint32_t sps; + uint32_t step; + double phasediff_bin; +}; + +/* **************************************************************************** + * windows + */ +static double +ft_hannhamm (float* window, uint32_t n, double a, double b) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + for (uint32_t i = 0; i < n; ++i) { + window[i] = a - b * cos (c * i); + sum += window[i]; + } + return sum; +} + +static double +ft_bnh (float* window, uint32_t n, double a0, double a1, double a2, double a3) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i); + sum += window[i]; + } + return sum; +} + +static double +ft_flattop (float* window, uint32_t n) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + const double c4 = 4.0 * c; + + const double a0 = 1.0; + const double a1 = 1.93; + const double a2 = 1.29; + const double a3 = 0.388; + const double a4 = 0.028; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i) + a4 * cos(c4 * i); + sum += window[i]; + } + return sum; +} + + +/* **************************************************************************** + * internal private functions + */ +static float* +ft_gen_window (struct FFTAnalysis* ft) +{ + if (ft->window) { + return ft->window; + } + + ft->window = (float*)malloc (sizeof (float) * ft->window_size); + double sum = .0; + + /* https://en.wikipedia.org/wiki/Window_function */ + switch (ft->window_type) { + default: + case W_HANN: + sum = ft_hannhamm (ft->window, ft->window_size, .5, .5); + break; + case W_HAMMMIN: + sum = ft_hannhamm (ft->window, ft->window_size, .54, .46); + break; + case W_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .355768, .487396, .144232, .012604); + break; + case W_BLACKMAN_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .3635819, .4891775, .1365995, .0106411); + break; + case W_BLACKMAN_HARRIS: + sum = ft_bnh (ft->window, ft->window_size, .35875, .48829, .14128, .01168); + break; + case W_FLAT_TOP: + sum = ft_flattop (ft->window, ft->window_size); + break; + } + + const double isum = 2.0 / sum; + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->window[i] *= isum; + } + + return ft->window; +} + +static void +ft_analyze (struct FFTAnalysis* ft) +{ + fftwf_execute (ft->fftplan); + + memcpy (ft->phase_h, ft->phase, sizeof (float) * ft->data_size); + ft->power[0] = ft->fft_out[0] * ft->fft_out[0]; + ft->phase[0] = 0; + +#define FRe (ft->fft_out[i]) +#define FIm (ft->fft_out[ft->window_size - i]) + for (uint32_t i = 1; i < ft->data_size - 1; ++i) { + ft->power[i] = (FRe * FRe) + (FIm * FIm); + ft->phase[i] = atan2f (FIm, FRe); + } +#undef FRe +#undef FIm +} + +/****************************************************************************** + * public API (static for direct source inclusion) + */ +#ifndef FFTX_FN_PREFIX +#define FFTX_FN_PREFIX static +#endif + +FFTX_FN_PREFIX +void +fftx_reset (struct FFTAnalysis* ft) +{ + for (uint32_t i = 0; i < ft->data_size; ++i) { + ft->power[i] = 0; + ft->phase[i] = 0; + ft->phase_h[i] = 0; + } + for (uint32_t i = 0; i < ft->window_size; ++i) { + ft->ringbuf[i] = 0; + ft->fft_out[i] = 0; + } + ft->rboff = 0; + ft->smps = 0; + ft->step = 0; +} + +FFTX_FN_PREFIX +void +fftx_init (struct FFTAnalysis* ft, uint32_t window_size, double rate, double fps) +{ + ft->rate = rate; + ft->window_size = window_size; + ft->window_type = W_HANN; + ft->data_size = window_size / 2; + ft->window = NULL; + ft->rboff = 0; + ft->smps = 0; + ft->step = 0; + ft->sps = (fps > 0) ? ceil (rate / fps) : 0; + ft->freq_per_bin = ft->rate / ft->data_size / 2.f; + ft->phasediff_step = M_PI / ft->data_size; + ft->phasediff_bin = 0; + + ft->ringbuf = (float*)malloc (window_size * sizeof (float)); + ft->fft_in = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->fft_out = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->power = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase_h = (float*)malloc (ft->data_size * sizeof (float)); + + fftx_reset (ft); + + pthread_mutex_lock (&fftw_planner_lock); + ft->fftplan = fftwf_plan_r2r_1d (window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); + ++instance_count; + pthread_mutex_unlock (&fftw_planner_lock); +} + +FFTX_FN_PREFIX +void +fftx_set_window (struct FFTAnalysis* ft, window_t type) +{ + if (ft->window_type == type) { + return; + } + ft->window_type = type; + free (ft->window); + ft->window = NULL; +} + +FFTX_FN_PREFIX +void +fftx_free (struct FFTAnalysis* ft) +{ + if (!ft) { + return; + } + pthread_mutex_lock (&fftw_planner_lock); + fftwf_destroy_plan (ft->fftplan); + if (instance_count > 0) { + --instance_count; + } +#ifdef WITH_STATIC_FFTW_CLEANUP + /* use this only when statically linking to a local fftw! + * + * "After calling fftw_cleanup, all existing plans become undefined, + * and you should not attempt to execute them nor to destroy them." + * [http://www.fftw.org/fftw3_doc/Using-Plans.html] + * + * If libfftwf is shared with other plugins or the host this can + * cause undefined behavior. + */ + if (instance_count == 0) { + fftwf_cleanup (); + } +#endif + pthread_mutex_unlock (&fftw_planner_lock); + free (ft->window); + free (ft->ringbuf); + fftwf_free (ft->fft_in); + fftwf_free (ft->fft_out); + free (ft->power); + free (ft->phase); + free (ft->phase_h); + free (ft); +} + +static int +_fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) +{ + assert (n_samples <= ft->window_size); + + float* const f_buf = ft->fft_in; + float* const r_buf = ft->ringbuf; + + const uint32_t n_off = ft->rboff; + const uint32_t n_siz = ft->window_size; + const uint32_t n_old = n_siz - n_samples; + + for (uint32_t i = 0; i < n_samples; ++i) { + r_buf[(i + n_off) % n_siz] = data[i]; + f_buf[n_old + i] = data[i]; + } + + ft->rboff = (ft->rboff + n_samples) % n_siz; +#if 1 + ft->smps += n_samples; + if (ft->smps < ft->sps) { + return -1; + } + ft->step = ft->smps; + ft->smps = 0; +#else + ft->step = n_samples; +#endif + + /* copy samples from ringbuffer into fft-buffer */ + const uint32_t p0s = (n_off + n_samples) % n_siz; + if (p0s + n_old >= n_siz) { + const uint32_t n_p1 = n_siz - p0s; + const uint32_t n_p2 = n_old - n_p1; + memcpy (f_buf, &r_buf[p0s], sizeof (float) * n_p1); + memcpy (&f_buf[n_p1], &r_buf[0], sizeof (float) * n_p2); + } else { + memcpy (&f_buf[0], &r_buf[p0s], sizeof (float) * n_old); + } + + /* apply window function */ + float const* const window = ft_gen_window (ft); + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->fft_in[i] *= window[i]; + } + + /* ..and analyze */ + ft_analyze (ft); + + ft->phasediff_bin = ft->phasediff_step * (double)ft->step; + return 0; +} + +FFTX_FN_PREFIX +int +fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) +{ + if (n_samples <= ft->window_size) { + return _fftx_run (ft, n_samples, data); + } + + int rv = -1; + uint32_t n = 0; + while (n < n_samples) { + uint32_t step = MIN (ft->window_size, n_samples - n); + if (!_fftx_run (ft, step, &data[n])) { + rv = 0; + } + n += step; + } + return rv; +} + +FFTX_FN_PREFIX +void +fa_analyze_dsp (struct FFTAnalysis* ft, + void (*run) (void*, uint32_t, float*), void* handle) +{ + float* buf = ft->fft_in; + + /* pre-run 8K samples... (re-init/flush effect) */ + uint32_t prerun_n_samples = 8192; + while (prerun_n_samples > 0) { + uint32_t n_samples = MIN (prerun_n_samples, ft->window_size); + memset (buf, 0, sizeof (float) * n_samples); + run (handle, n_samples, buf); + prerun_n_samples -= n_samples; + } + + /* delta impulse */ + memset (buf, 0, sizeof (float) * ft->window_size); + *buf = 1.0; + /* call plugin's run() function -- in-place processing */ + run (handle, ft->window_size, buf); + ft->step = ft->window_size; + /* ..and analyze */ + ft_analyze (ft); +} + +/* *************************************************************************** + * convenient access functions + */ + +FFTX_FN_PREFIX +uint32_t +fftx_bins (struct FFTAnalysis* ft) +{ + return ft->data_size; +} + +FFTX_FN_PREFIX +inline float +fast_log2 (float val) +{ + union { + float f; + int i; + } t; + t.f = val; + int* const exp_ptr = &t.i; + int x = *exp_ptr; + const int log_2 = ((x >> 23) & 255) - 128; + x &= ~(255 << 23); + x += 127 << 23; + *exp_ptr = x; + val = ((-1.0f / 3) * t.f + 2) * t.f - 2.0f / 3; + return (val + log_2); +} + +FFTX_FN_PREFIX +inline float +fast_log (const float val) +{ + return (fast_log2 (val) * 0.69314718f); +} + +FFTX_FN_PREFIX +inline float +fast_log10 (const float val) +{ + return fast_log2 (val) / 3.312500f; +} + +FFTX_FN_PREFIX +inline float +fftx_power_to_dB (float a) +{ + /* 10 instead of 20 because of squared signal -- no sqrt(powerp[]) */ + return a > 1e-12 ? 10.0 * fast_log10 (a) : -INFINITY; +} + +FFTX_FN_PREFIX +float +fftx_power_at_bin (struct FFTAnalysis* ft, const int b) +{ + return (fftx_power_to_dB (ft->power[b])); +} + +FFTX_FN_PREFIX +float +fftx_freq_at_bin (struct FFTAnalysis* ft, const int b) +{ + /* calc phase: difference minus expected difference */ + float phase = ft->phase[b] - ft->phase_h[b] - (float)b * ft->phasediff_bin; + /* clamp to -M_PI .. M_PI */ + int over = phase / M_PI; + over += (over >= 0) ? (over & 1) : -(over & 1); + phase -= M_PI * (float)over; + /* scale according to overlap */ + phase *= (ft->data_size / ft->step) / M_PI; + return ft->freq_per_bin * ((float)b + phase); +} diff -Nru x42-plugins-20170428/spectra.lv2/gui/spectra.c x42-plugins-20190714/spectra.lv2/gui/spectra.c --- x42-plugins-20170428/spectra.lv2/gui/spectra.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/gui/spectra.c 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,681 @@ +/* simple spectrum analyzer + * + * Copyright (C) 2013 Robin Gareus + * + * 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, 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, see . + */ + +#define RTK_URI SPR_URI "#" +#define RTK_GUI "ui" + +#include +#include +#include + +#include "../src/uris.h" +#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" + +#include "fft.c" + +#ifndef MIN +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif +#ifndef MAX +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#endif + +/* widget, window size */ +#define WWIDTH (ui->xyp->w_width) +#define WHEIGHT (ui->xyp->w_height) + +/* annotation border left/top */ +#define AWIDTH (35.) +#define AHEIGHT (25.) + +/* actual data area size */ +#define DWIDTH (WWIDTH - AWIDTH) +#define DHEIGHT (WHEIGHT - AHEIGHT) + +struct FFTLogscale { + float log_rate; + float log_base; + float data_size; + float rate; +}; + +static void +fl_init (struct FFTLogscale* fl, uint32_t window_size, double rate) +{ + fl->data_size = window_size / 2; + fl->log_rate = (1.0f - 10000.0f / rate) / ((5000.0f / rate) * (5000.0f / rate)); + fl->log_base = log10f (1.0f + fl->log_rate); + fl->rate = rate; +} + +static float +ft_x_deflect_bin (struct FFTLogscale* fl, float b) +{ + assert (fl->data_size > 0); + return fast_log10 (1.0 + b * fl->log_rate / (float)fl->data_size) / fl->log_base; +} + +typedef struct { + LV2_Atom_Forge forge; + LV2_URID_Map* map; + SpectraLV2URIs uris; + + LV2UI_Write_Function write; + LV2UI_Controller controller; + + RobWidget* vbox; + RobTkXYp* xyp; + cairo_surface_t* ann_power; + + RobWidget* hbox; + RobTkLbl* lbl_fft; + RobTkSelect* sel_fft; + RobTkSelect* sel_window; + RobTkCBtn* btn_color; + RobTkSep* sep0; + RobTkSep* sep1; + + float rate; + float ann_rate; + uint32_t n_channels; + float min_dB, max_dB, step_dB; + + uint32_t window_size; + bool pink_scale; + window_t window_fun; + + bool disable_signals; + + struct FFTAnalysis* fa; + struct FFTLogscale fl; + float* p_x, *p_y; + +} SpectraUI; + +static void +draw_scales (SpectraUI* ui) +{ + float x, y; + robtk_xydraw_set_surface (ui->xyp, NULL); + + if (ui->ann_power) { + cairo_surface_destroy (ui->ann_power); + } + + ui->ann_power = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WWIDTH, WHEIGHT); + cairo_t* cr = cairo_create (ui->ann_power); + + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_rectangle (cr, 0.0, 0.0, WWIDTH, WHEIGHT); + cairo_fill (cr); + + const float divisor = ui->rate / 2.0 / (float)fftx_bins (ui->fa); + + cairo_set_font_size (cr, 9); + cairo_text_extents_t t_ext; + + char buf[32]; + /* horiz lines, dB */ + double dashes[] = { 3.0, 5.0 }; + cairo_set_line_width (cr, 1.0); + + for (float dB = 0; dB > ui->min_dB; dB -= ui->step_dB) { + sprintf (buf, "%+0.0fdB", dB); + + y = (dB - ui->min_dB) / (ui->max_dB - ui->min_dB); + y = WHEIGHT - DHEIGHT * y; + + if (dB == 0.0) { + cairo_set_dash (cr, NULL, 0, 0); + } else { + cairo_set_dash (cr, dashes, 2, 0.0); + } + + cairo_set_source_rgb (cr, 0.2, 0.2, 0.2); + cairo_move_to (cr, AWIDTH, rintf (y) + .5); + cairo_line_to (cr, WWIDTH, rintf (y) + .5); + cairo_stroke (cr); + + cairo_set_source_rgb (cr, 0.6, 0.6, 0.6); + cairo_text_extents (cr, buf, &t_ext); + cairo_move_to (cr, AWIDTH - 2 - t_ext.width - t_ext.x_bearing, y + t_ext.height / 2.0 - 1.0); + cairo_show_text (cr, buf); + cairo_stroke (cr); + } + + /* freq scale */ + cairo_set_line_width (cr, 1.25); + cairo_set_dash (cr, NULL, 0, 0); + + for (int32_t i = 0; i < 41; ++i) { + if (i < 7 && (i % 4)) + continue; + if (i == 8) + continue; + const double f_m = pow (2, (i - 17) / 3.) * 1000.0; + x = ft_x_deflect_bin (&ui->fl, f_m / divisor) * DWIDTH + AWIDTH; + + if (f_m >= ui->rate * .5) { + break; + } + + if (f_m < 1000.0) { + sprintf (buf, "%0.0fHz", f_m); + } else { + sprintf (buf, "%0.1fkHz", f_m / 1000.0); + } + + cairo_set_source_rgb (cr, 0.6, 0.6, 0.6); + cairo_move_to (cr, x + 2.0, 3.0); + + cairo_rotate (cr, M_PI / 2.0); + cairo_show_text (cr, buf); + cairo_rotate (cr, -M_PI / 2.0); + cairo_stroke (cr); + + cairo_set_source_rgb (cr, 0.3, 0.3, 0.3); + cairo_move_to (cr, rintf (x) - .5, WHEIGHT); + cairo_line_to (cr, rintf (x) - .5, 0.0); + cairo_stroke (cr); + } + + cairo_destroy (cr); + robtk_xydraw_set_surface (ui->xyp, ui->ann_power); +} + +static void +reinitialize_fft (SpectraUI* ui) +{ + uint32_t fft_size = MIN (16384, MAX (1024, ui->window_size)); + fft_size--; + fft_size |= fft_size >> 1; + fft_size |= fft_size >> 2; + fft_size |= fft_size >> 4; + fft_size |= fft_size >> 8; + fft_size |= fft_size >> 16; + fft_size++; + fft_size = MIN (16384, fft_size); + + if (ui->fa && ui->fa->window_size == fft_size) { + return; + } + + fftx_free (ui->fa); + free (ui->p_x); + free (ui->p_y); + ui->fa = (struct FFTAnalysis*)malloc (sizeof (struct FFTAnalysis)); + fftx_init (ui->fa, fft_size, ui->rate, 60); + fl_init (&ui->fl, fft_size, ui->rate); + ui->p_x = (float*)malloc (fftx_bins (ui->fa) * sizeof (float)); + ui->p_y = (float*)malloc (fftx_bins (ui->fa) * sizeof (float)); +} + +/****************************************************************************** + * Communication with DSP backend -- send/receive settings + */ + +/** notfiy backend that UI is closed */ +static void +ui_disable (LV2UI_Handle handle) +{ + SpectraUI* ui = (SpectraUI*)handle; + + uint8_t obj_buf[64]; + lv2_atom_forge_set_buffer (&ui->forge, obj_buf, 64); + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&ui->forge, 0); + LV2_Atom* msg = (LV2_Atom*)x_forge_object (&ui->forge, &frame, 1, ui->uris.ui_off); + lv2_atom_forge_pop (&ui->forge, &frame); + ui->write (ui->controller, 0, lv2_atom_total_size (msg), ui->uris.atom_eventTransfer, msg); +} + +/** notify backend that UI is active: + * request state and enable data-transmission */ +static void +ui_enable (LV2UI_Handle handle) +{ + SpectraUI* ui = (SpectraUI*)handle; + uint8_t obj_buf[64]; + lv2_atom_forge_set_buffer (&ui->forge, obj_buf, 64); + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&ui->forge, 0); + LV2_Atom* msg = (LV2_Atom*)x_forge_object (&ui->forge, &frame, 1, ui->uris.ui_on); + lv2_atom_forge_pop (&ui->forge, &frame); + ui->write (ui->controller, 0, lv2_atom_total_size (msg), ui->uris.atom_eventTransfer, msg); +} + +/****************************************************************************** + * WIDGET CALLBACKS + */ + +static bool +cb_set_fft (RobWidget* handle, void* data) +{ + SpectraUI* ui = (SpectraUI*)data; + const float fft_size = robtk_select_get_value (ui->sel_fft); + if (ui->window_size == fft_size) { + return TRUE; + } + ui->window_size = fft_size; + reinitialize_fft (ui); + draw_scales (ui); + if (ui->disable_signals) + return TRUE; + ui->write (ui->controller, SPR_FFTSIZE, sizeof (float), 0, (const void*)&fft_size); + return TRUE; +} + +static bool +cb_set_color (RobWidget* handle, void* data) +{ + SpectraUI* ui = (SpectraUI*)data; + float val = robtk_cbtn_get_active (ui->btn_color) ? 1.0 : 0.0; + ui->pink_scale = val > 0; + if (ui->disable_signals) { + return TRUE; + } + ui->write (ui->controller, SPR_WEIGHT, sizeof (float), 0, (const void*)&val); + return TRUE; +} + +static bool +cb_set_window (RobWidget* handle, void* data) +{ + SpectraUI* ui = (SpectraUI*)data; + const float val = robtk_select_get_value (ui->sel_window); + const window_t wf = (window_t) val; + if (ui->window_fun == wf) { + return TRUE; + } + ui->window_fun = wf; + if (ui->disable_signals) { + return TRUE; + } + ui->write (ui->controller, SPR_WINDOW, sizeof (float), 0, (const void*)&val); + return TRUE; +} + + +/******************************************************************************/ + +/** this callback runs in the "communication" thread of the LV2-host + * -- invoked via port_event(); please see notes there. + * + * it acts as 'glue' between LV2 port_event() and GTK expose_event_callback() + * + * This is a wrapper, around above 'update_scope_real()' it allows + * to update the UI state in sync with the 1st channel and + * upsamples the data if neccesary. + */ +static void +update_spectrum (SpectraUI* ui, const uint32_t channel, const size_t n_elem, float const* data) +{ + /* this callback runs in the "communication" thread of the LV2-host + * usually a g_timeout() at ~25fps + */ + if (channel > ui->n_channels || channel != 0) { + return; + } + + if (cairo_image_surface_get_width (ui->ann_power) != WWIDTH || cairo_image_surface_get_height (ui->ann_power) != WHEIGHT) { + draw_scales (ui); + } + + const float rwidth = DWIDTH / WWIDTH; + const float rheight = DHEIGHT / WHEIGHT; + const float aoffs_x = AWIDTH / WWIDTH; + const float min_coeff = powf (10.f, .1f * ui->min_dB); + const float hscale = rheight / (ui->max_dB - ui->min_dB); + const bool pink = ui->pink_scale; + + fftx_set_window (ui->fa, ui->window_fun); + + if (!fftx_run (ui->fa, n_elem, data)) { + uint32_t p = 0; + uint32_t b = fftx_bins (ui->fa); + for (uint32_t i = 1; i < b - 1; i++) { +#if 0 + float ffpow = ui->fa->power[i]; + if (pink) { + float norm = fftx_freq_at_bin(ui->fa, i) / ui->fa->freq_per_bin; + if (norm <= 1) { norm = 1; } + ffpow *= norm * .5; + } +#else + const float ffpow = pink ? (ui->fa->power[i] * i * .5) : ui->fa->power[i]; +#endif + if (ffpow < min_coeff) { + continue; + ui->p_x[p] = ft_x_deflect_bin (&ui->fl, i) * rwidth + aoffs_x; + ui->p_y[p] = 0; + } else { + ui->p_x[p] = ft_x_deflect_bin (&ui->fl, fftx_freq_at_bin (ui->fa, i) / ui->fa->freq_per_bin) * rwidth + aoffs_x; + ui->p_y[p] = (fftx_power_to_dB (ffpow) - ui->min_dB) * hscale; + } + p++; + } + robtk_xydraw_set_points (ui->xyp, p, ui->p_x, ui->p_y); + } +} + +/****************************************************************************** + * RobWidget + */ + +static void +xydraw_size_request (RobWidget* handle, int* w, int* h) +{ + *w = 800; + *h = 400; +} + +static void +xydraw_size_allocate (RobWidget* handle, int w, int h) +{ + RobTkXYp* d = (RobTkXYp*)GET_HANDLE (handle); + d->w_width = w; + d->w_height = h; + d->map_xw = w; + d->map_yh = h; + robwidget_set_size (d->rw, w, h); +} + +static void +xydraw_clip (cairo_t* cr, void* handle) +{ + RobTkXYp* d = (RobTkXYp*)(handle); + cairo_rectangle (cr, 0, 0, d->w_width, d->w_height); + cairo_clip (cr); +} + +static RobWidget* +toplevel (SpectraUI* ui, void* const top) +{ + ui->vbox = rob_vbox_new (FALSE, 2); + robwidget_make_toplevel (ui->vbox, top); + ROBWIDGET_SETNAME (ui->vbox, "spectra"); + + ui->xyp = robtk_xydraw_new (800, 400); + robwidget_set_size_allocate (ui->xyp->rw, xydraw_size_allocate); + robwidget_set_size_request (ui->xyp->rw, xydraw_size_request); + robtk_xydraw_set_clip_callback (ui->xyp, xydraw_clip, ui->xyp); + + robtk_xydraw_set_linewidth (ui->xyp, 1.5); + robtk_xydraw_set_drawing_mode (ui->xyp, RobTkXY_ymax_zline); + + /* fft bins */ + ui->lbl_fft = robtk_lbl_new ("FFT:"); + ui->sel_fft = robtk_select_new (); + robtk_select_add_item (ui->sel_fft, 1024, "1024"); + robtk_select_add_item (ui->sel_fft, 2048, "2048"); + robtk_select_add_item (ui->sel_fft, 4096, "4096"); + robtk_select_add_item (ui->sel_fft, 8192, "8192"); + robtk_select_add_item (ui->sel_fft, 16384, "16384"); + robtk_select_set_default_item (ui->sel_fft, 2); + robtk_select_set_value (ui->sel_fft, 4096); + robtk_select_set_callback (ui->sel_fft, cb_set_fft, ui); + + ui->btn_color = robtk_cbtn_new ("1/f (pink noise spectrum)", GBT_LED_LEFT, false); + robtk_cbtn_set_active (ui->btn_color, false); + robtk_cbtn_set_callback (ui->btn_color, cb_set_color, ui); + + ui->sel_window = robtk_select_new (); + robtk_select_add_item (ui->sel_window, W_HANN, "Hann"); +#if 0 + robtk_select_add_item (ui->sel_window, W_HAMMMIN, "Hamming"); + robtk_select_add_item (ui->sel_window, W_NUTTALL, "Nuttall"); + robtk_select_add_item (ui->sel_window, W_BLACKMAN_NUTTALL, "Blackman-Nuttall"); +#endif + robtk_select_add_item (ui->sel_window, W_BLACKMAN_HARRIS, "Blackman-Harris"); + robtk_select_add_item (ui->sel_window, W_FLAT_TOP, "Flat Top"); + robtk_select_set_default_item (ui->sel_window, 0); + robtk_select_set_item (ui->sel_window, 0); + robtk_select_set_callback (ui->sel_window, cb_set_window, ui); + + ui->sep0 = robtk_sep_new (true); + ui->sep1 = robtk_sep_new (true); + robtk_sep_set_linewidth (ui->sep0, 0); + robtk_sep_set_linewidth (ui->sep1, 0); + + ui->hbox = rob_hbox_new (FALSE, 0); + + rob_hbox_child_pack (ui->hbox, robtk_sep_widget (ui->sep0), TRUE, FALSE); + rob_hbox_child_pack (ui->hbox, robtk_lbl_widget (ui->lbl_fft), FALSE, FALSE); + rob_hbox_child_pack (ui->hbox, robtk_select_widget (ui->sel_fft), FALSE, FALSE); + rob_hbox_child_pack (ui->hbox, robtk_cbtn_widget (ui->btn_color), FALSE, FALSE); + rob_hbox_child_pack (ui->hbox, robtk_select_widget (ui->sel_window), FALSE, FALSE); + rob_hbox_child_pack (ui->hbox, robtk_sep_widget (ui->sep1), TRUE, FALSE); + + rob_vbox_child_pack (ui->vbox, robtk_xydraw_widget (ui->xyp), TRUE, TRUE); + rob_vbox_child_pack (ui->vbox, ui->hbox, FALSE, TRUE); + + ui->ann_power = NULL; + draw_scales (ui); + + //robtk_xydraw_set_color(ui->xyz, .2, .9, .1, 1.0); + robtk_xydraw_set_surface (ui->xyp, ui->ann_power); + + return ui->vbox; +} + +#define LVGL_RESIZEABLE + +/****************************************************************************** + * LV2 + */ + +static LV2UI_Handle +instantiate ( + void* const ui_toplevel, + const LV2UI_Descriptor* descriptor, + const char* plugin_uri, + const char* bundle_path, + LV2UI_Write_Function write_function, + LV2UI_Controller controller, + RobWidget** widget, + const LV2_Feature* const* features) +{ + SpectraUI* ui = (SpectraUI*)calloc (1, sizeof (SpectraUI)); + + if (!ui) { + fprintf (stderr, "Spectra.lv2 UI: out of memory\n"); + return NULL; + } + + ui->map = NULL; + *widget = NULL; + + if (!strncmp (plugin_uri, SPR_URI "#Mono", 31 + 5)) { + ui->n_channels = 1; + } else { + free (ui); + return NULL; + } + + for (int i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_URID_URI "#map")) { + ui->map = (LV2_URID_Map*)features[i]->data; + } + } + + if (!ui->map) { + fprintf (stderr, "Spectra.lv2 UI: Host does not support urid:map\n"); + free (ui); + return NULL; + } + + /* initialize private data structure */ + ui->write = write_function; + ui->controller = controller; + + ui->rate = 48000; + ui->min_dB = -92.0; + ui->max_dB = 6.0; + ui->step_dB = 6.0; + + ui->window_size = 4096; + ui->pink_scale = false; + ui->window_fun = W_HANN; + ui->disable_signals = false; + + map_spectra_uris (ui->map, &ui->uris); + lv2_atom_forge_init (&ui->forge, ui->map); + + reinitialize_fft (ui); + + *widget = toplevel (ui, ui_toplevel); + ui_enable (ui); + return ui; +} + +static enum LVGLResize +plugin_scale_mode (LV2UI_Handle handle) +{ + return LVGL_LAYOUT_TO_FIT; +} + +static void +cleanup (LV2UI_Handle handle) +{ + SpectraUI* ui = (SpectraUI*)handle; + /* send message to DSP backend: + * save state & disable message transmission + */ + ui_disable (ui); + + robtk_xydraw_destroy (ui->xyp); + cairo_surface_destroy (ui->ann_power); + + robtk_sep_destroy (ui->sep0); + robtk_sep_destroy (ui->sep1); + robtk_cbtn_destroy (ui->btn_color); + robtk_select_destroy (ui->sel_fft); + robtk_select_destroy (ui->sel_window); + robtk_lbl_destroy (ui->lbl_fft); + + rob_box_destroy (ui->hbox); + rob_box_destroy (ui->vbox); + fftx_free (ui->fa); + free (ui->p_x); + free (ui->p_y); + + free (ui); +} + +/** receive data from the DSP-backend. + * + * this callback runs in the "communication" thread of the LV2-host + * jalv and ardour do this via a g_timeout() function at ~25fps + * + * the atom-events from the DSP backend are written into a ringbuffer + * in the host (in the DSP|jack realtime thread) the host then + * empties this ringbuffer by sending port_event()s to the UI at some + * random time later. When CPU and DSP load are large the host-buffer + * may overflow and some events may get lost. + * + * This thread does is not [usually] the 'drawing' thread (it does not + * have X11 or gl context). + */ +static void +port_event (LV2UI_Handle handle, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer) +{ + SpectraUI* ui = (SpectraUI*)handle; + LV2_Atom* atom = (LV2_Atom*)buffer; + + /* check type of data received + * format == 0: [float] control-port event + * format > 0: message + * Every event message is sent as separate port-event + */ + if (format == 0) { + const float val = *((const float*)buffer); + switch (port_index) { + case SPR_FFTSIZE: + ui->disable_signals = true; + robtk_select_set_value (ui->sel_fft, val); + ui->disable_signals = false; + break; + case SPR_WEIGHT: + ui->disable_signals = true; + robtk_cbtn_set_active (ui->btn_color, val > 0); + ui->disable_signals = false; + break; + case SPR_WINDOW: + ui->disable_signals = true; + robtk_select_set_value (ui->sel_window, val); + ui->disable_signals = false; + break; + default: + break; + } + } else if (format == ui->uris.atom_eventTransfer && (atom->type == ui->uris.atom_Blank || atom->type == ui->uris.atom_Object)) { + /* cast the buffer to Atom Object */ + LV2_Atom_Object* obj = (LV2_Atom_Object*)atom; + LV2_Atom* a0 = NULL; + LV2_Atom* a1 = NULL; + if ( + /* handle raw-audio data objects */ + obj->body.otype == ui->uris.rawaudio + /* retrieve properties from object and + * check that there the [here] two required properties are set.. */ + && 2 == lv2_atom_object_get (obj, ui->uris.channelid, &a0, ui->uris.audiodata, &a1, NULL) + /* ..and non-null.. */ + && a0 && a1 + /* ..and match the expected type */ + && a0->type == ui->uris.atom_Int && a1->type == ui->uris.atom_Vector) { + /* single integer value can be directly dereferenced */ + const int32_t chn = ((LV2_Atom_Int*)a0)->body; + + /* dereference and typecast vector pointer */ + LV2_Atom_Vector* vof = (LV2_Atom_Vector*)LV2_ATOM_BODY (a1); + /* check if atom is indeed a vector of the expected type*/ + if (vof->atom.type == ui->uris.atom_Float) { + /* get number of elements in vector + * = (raw 8bit data-length - header-length) / sizeof(expected data type:float) */ + const size_t n_elem = (a1->size - sizeof (LV2_Atom_Vector_Body)) / vof->atom.size; + /* typecast, dereference pointer to vector */ + const float* data = (float*)LV2_ATOM_BODY (&vof->atom); + /* call function that handles the actual data */ + update_spectrum (ui, chn, n_elem, data); + } + } else if ( + /* handle 'state/settings' data object */ + obj->body.otype == ui->uris.ui_state + /* retrieve properties from object and + * check that there the [here] three required properties are set.. */ + && 1 == lv2_atom_object_get (obj, ui->uris.samplerate, &a0, NULL) + /* ..and non-null.. */ + && a0 + /* ..and match the expected type */ + && a0->type == ui->uris.atom_Float) { + ui->rate = ((LV2_Atom_Float*)a0)->body; + reinitialize_fft (ui); + draw_scales (ui); + } + } +} + +static const void* +extension_data (const char* uri) +{ + return NULL; +} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/spectra.lv2/img/spectr.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/spectra.lv2/img/spectr.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/spectra.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/spectra.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/spectra.lv2/img/x42-spectr.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/spectra.lv2/img/x42-spectr.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/spectra.lv2/img/x42-spectr.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/spectra.lv2/img/x42-spectr.png differ diff -Nru x42-plugins-20170428/spectra.lv2/lv2ttl/manifest.gui.in x42-plugins-20190714/spectra.lv2/lv2ttl/manifest.gui.in --- x42-plugins-20170428/spectra.lv2/lv2ttl/manifest.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/lv2ttl/manifest.gui.in 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,4 @@ +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + ui:binary <@LV2GUI@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/spectra.lv2/lv2ttl/manifest.ttl.in x42-plugins-20190714/spectra.lv2/lv2ttl/manifest.ttl.in --- x42-plugins-20170428/spectra.lv2/lv2ttl/manifest.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/lv2ttl/manifest.ttl.in 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,10 @@ +@prefix lv2: . +@prefix rdfs: . +@prefix ui: . +@prefix kx: . +@prefix @LV2NAME@: . + +@LV2NAME@:Mono + a lv2:Plugin ; + lv2:binary <@LV2NAME@@LIB_EXT@> ; + rdfs:seeAlso <@LV2NAME@.ttl> . diff -Nru x42-plugins-20170428/spectra.lv2/lv2ttl/spectra.gui.in x42-plugins-20190714/spectra.lv2/lv2ttl/spectra.gui.in --- x42-plugins-20170428/spectra.lv2/lv2ttl/spectra.gui.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/lv2ttl/spectra.gui.in 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,5 @@ + +@LV2NAME@:ui_gl + a @UI_TYPE@ ; + @UI_REQ@ + . diff -Nru x42-plugins-20170428/spectra.lv2/lv2ttl/spectra.h x42-plugins-20190714/spectra.lv2/lv2ttl/spectra.h --- x42-plugins-20170428/spectra.lv2/lv2ttl/spectra.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/lv2ttl/spectra.h 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,36 @@ +// generated by lv2ttl2c from +// http://gareus.org/oss/lv2/spectra#Mono + +extern const LV2_Descriptor* lv2_descriptor(uint32_t index); +extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); + +static const RtkLv2Description _plugin = { + &lv2_descriptor, + &lv2ui_descriptor + , 0 // uint32_t dsp_descriptor_id + , 0 // uint32_t gui_descriptor_id + , "Spectr" // const char *plugin_human_id + , (const struct LV2Port[7]) + { + { "control", ATOM_IN, nan, nan, nan, "GUI to plugin communication"}, + { "notify", ATOM_OUT, nan, nan, nan, "Plugin to GUI communication"}, + { "fftsize", CONTROL_IN, 4096.000000, 1024.000000, 16384.000000, "FFT Size"}, + { "color", CONTROL_IN, 0.000000, 0.000000, 1.000000, "1/f scale"}, + { "window", CONTROL_IN, 0.000000, 0.000000, 4.000000, "Window Function"}, + { "in", AUDIO_IN, nan, nan, nan, "Audio Input"}, + { "out", AUDIO_OUT, nan, nan, nan, "Audio Signal pass-thru"}, + } + , 7 // uint32_t nports_total + , 1 // uint32_t nports_audio_in + , 1 // uint32_t nports_audio_out + , 0 // uint32_t nports_midi_in + , 0 // uint32_t nports_midi_out + , 1 // uint32_t nports_atom_in + , 1 // uint32_t nports_atom_out + , 3 // uint32_t nports_ctrl + , 3 // uint32_t nports_ctrl_in + , 0 // uint32_t nports_ctrl_out + , 33024 // uint32_t min_atom_bufsiz + , false // bool send_time_info + , UINT32_MAX // uint32_t latency_ctrl_port +}; diff -Nru x42-plugins-20170428/spectra.lv2/lv2ttl/spectra.ttl.in x42-plugins-20190714/spectra.lv2/lv2ttl/spectra.ttl.in --- x42-plugins-20170428/spectra.lv2/lv2ttl/spectra.ttl.in 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/lv2ttl/spectra.ttl.in 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,115 @@ +@prefix atom: . +@prefix bufsz: . +@prefix doap: . +@prefix foaf: . +@prefix lv2: . +@prefix rdf: . +@prefix rdfs: . +@prefix ui: . +@prefix urid: . +@prefix rsz: . +@prefix state: . +@prefix kx: . +@prefix @LV2NAME@: . + + + a foaf:Person ; + foaf:name "Robin Gareus" ; + foaf:mbox ; + foaf:homepage . + + + a doap:Project ; + doap:maintainer ; + doap:name "Spectral-analysis" . + +@LV2NAME@:Mono + a lv2:Plugin, lv2:AnalyserPlugin ; + doap:name "Spectr" ; + lv2:project ; + doap:license ; + @VERSION@ + lv2:requiredFeature urid:map ; + lv2:optionalFeature lv2:hardRTCapable ; + @SIGNATURE@ + @UITTL@ + lv2:port [ + a atom:AtomPort , + lv2:InputPort ; + atom:bufferType atom:Sequence ; + lv2:designation lv2:control ; + lv2:index 0 ; + lv2:symbol "control" ; + lv2:name "Control" ; + rdfs:comment "GUI to plugin communication" + ] , [ + a atom:AtomPort , + lv2:OutputPort ; + atom:bufferType atom:Sequence ; + lv2:designation lv2:control ; + lv2:index 1 ; + lv2:symbol "notify" ; + lv2:name "Notify" ; + # 8192 * sizeof(float) + LV2-Atoms + rsz:minimumSize 33024; + rdfs:comment "Plugin to GUI communication" + ] , [ + a lv2:ControlPort, lv2:InputPort ; + lv2:index 2 ; + lv2:portProperty lv2:integer; + lv2:portProperty lv2:enumeration; + lv2:symbol "fftsize" ; + lv2:name "FFT Size" ; + lv2:default 4096 ; + lv2:minimum 1024 ; + lv2:maximum 16384 ; + lv2:scalePoint [ rdfs:label "1024"; rdf:value 1024 ; ] ; + lv2:scalePoint [ rdfs:label "2048"; rdf:value 2048 ; ] ; + lv2:scalePoint [ rdfs:label "4096"; rdf:value 4096 ; ] ; + lv2:scalePoint [ rdfs:label "8192"; rdf:value 8192 ; ] ; + lv2:scalePoint [ rdfs:label "16384"; rdf:value 16384 ; ] ; + ] , [ + a lv2:ControlPort, lv2:InputPort ; + lv2:portProperty lv2:toggled; + lv2:portProperty lv2:integer; + lv2:index 3 ; + lv2:symbol "color" ; + lv2:name "1/f scale" ; + lv2:default 0 ; + lv2:minimum 0 ; + lv2:maximum 1 ; + lv2:scalePoint [ rdfs:label "Off (White)"; rdf:value 0; ] ; + lv2:scalePoint [ rdfs:label "On (Pink)"; rdf:value 1; ] ; + ] , [ + a lv2:ControlPort, lv2:InputPort ; + lv2:portProperty lv2:integer; + lv2:portProperty lv2:enumeration; + lv2:index 4 ; + lv2:symbol "window" ; + lv2:name "Window Function" ; + lv2:default 0 ; + lv2:minimum 0 ; + lv2:maximum 4 ; + lv2:scalePoint [ rdfs:label "Hann"; rdf:value 0; ] ; + lv2:scalePoint [ rdfs:label "Hamming"; rdf:value 1; ] ; + lv2:scalePoint [ rdfs:label "Nuttall"; rdf:value 2; ] ; + lv2:scalePoint [ rdfs:label "Blackman–Nuttall"; rdf:value 3; ] ; + lv2:scalePoint [ rdfs:label "Blackman–Harris"; rdf:value 4; ] ; + lv2:scalePoint [ rdfs:label "Flat top"; rdf:value 5; ] ; + ] , [ + a lv2:AudioPort , + lv2:InputPort ; + lv2:index 5 ; + lv2:symbol "in" ; + lv2:name "In" ; + rdfs:comment "Audio Input" + ] , [ + a lv2:AudioPort , + lv2:OutputPort ; + lv2:index 6 ; + lv2:symbol "out" ; + lv2:name "Out" ; + rdfs:comment "Audio Signal pass-thru" + ] ; + rdfs:comment "Audio Apectrum Analyzer" + . diff -Nru x42-plugins-20170428/spectra.lv2/Makefile x42-plugins-20190714/spectra.lv2/Makefile --- x42-plugins-20170428/spectra.lv2/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/Makefile 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,306 @@ +#!/usr/bin/make -f + +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +MANDIR ?= $(PREFIX)/share/man/man1 +# see http://lv2plug.in/pages/filesystem-hierarchy-standard.html, don't use libdir +LV2DIR ?= $(PREFIX)/lib/lv2 + +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG # -fopt-info-vec-optimized +CFLAGS ?= -Wall -g -Wno-unused-function + +PKG_CONFIG?=pkg-config +STRIP?= strip + +BUILDOPENGL?=yes +BUILDJACKAPP?=yes + +spectra_VERSION ?= $(shell git describe --tags HEAD | sed 's/-g.*$$//;s/^v//' || echo "LV2") +RW ?= robtk/ + + +############################################################################### + +BUILDDIR = build/ +APPBLD = x42/ + +############################################################################### + +LV2NAME=spectra +LV2GUI=spectraUI_gl +BUNDLE=spectra.lv2 + + +targets= + +LOADLIBES=-lm +LV2UIREQ=lv2:requiredFeature urid:map ; +GLUICFLAGS=-I. + +UNAME=$(shell uname) +ifeq ($(UNAME),Darwin) + LV2LDFLAGS=-dynamiclib + LIB_EXT=.dylib + EXE_EXT= + UI_TYPE=ui:CocoaUI + PUGL_SRC=$(RW)pugl/pugl_osx.m + PKG_GL_LIBS= + GLUILIBS=-framework Cocoa -framework OpenGL -framework CoreFoundation + STRIPFLAGS=-u -r -arch all -s $(RW)lv2syms + EXTENDED_RE=-E +else + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.so + EXE_EXT= + UI_TYPE=ui:X11UI + PUGL_SRC=$(RW)pugl/pugl_x11.c + PKG_GL_LIBS=glu gl + GLUILIBS=-lX11 + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` + STRIPFLAGS= -s + EXTENDED_RE=-r +endif + +ifneq ($(XWIN),) + CC=$(XWIN)-gcc + CXX=$(XWIN)-g++ + STRIP=$(XWIN)-strip + LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed + LIB_EXT=.dll + EXE_EXT=.exe + PUGL_SRC=$(RW)pugl/pugl_win.cpp + PKG_GL_LIBS= + UI_TYPE=ui:WindowsUI + GLUILIBS=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread + GLUICFLAGS=-I. + override LDFLAGS += -static-libgcc -static-libstdc++ +endif + +ifeq ($(EXTERNALUI), yes) + UI_TYPE= +endif + +ifeq ($(UI_TYPE),) + UI_TYPE=kx:Widget + LV2UIREQ+=lv2:requiredFeature kx:Widget; + override CFLAGS += -DXTERNAL_UI +endif + +ifeq ($(BUILDOPENGL), no) + $(error openGL/LV2 UI is mandatory) +endif + +targets=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) +targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT) +UITTL=ui:ui $(LV2NAME):ui_gl ; + +############################################################################### +# extract versions +LV2VERSION=$(spectra_VERSION) +include git2lv2.mk + +############################################################################### +# check for build-dependencies + +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) + $(error "LV2 SDK was not found") +endif + +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) + $(error "LV2 SDK needs to be version 1.6.0 or later") +endif + +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f || echo no), no) + $(error "fftw3f library was not found") +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") + endif +endif + +ifneq ($(BUILDJACKAPP), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) + $(warning *** libjack from http://jackaudio.org is required) + $(error Please install libjack-dev or libjack-jackd2-dev) + endif + JACKAPP=$(APPBLD)x42-spectr$(EXE_EXT) +endif + +# check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) + override CFLAGS += -DHAVE_LV2_1_8 +endif + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + ifneq ($(MAKECMDGOALS), submodules) + ifeq ($(wildcard $(RW)robtk.mk),) + $(warning "**********************************************************") + $(warning This plugin needs https://github.com/x42/robtk) + $(warning "**********************************************************") + $(info ) + $(info set the RW environment variale to the location of the robtk headers) + ifeq ($(wildcard .git),.git) + $(info or run 'make submodules' to initialize robtk as git submodule) + endif + $(info ) + $(warning "**********************************************************") + $(error robtk not found) + endif + endif +endif + +# LV2 idle >= lv2-1.6.0 +GLUICFLAGS+=-DHAVE_IDLE_IFACE +LV2UIREQ+=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface; + +# add library dependent flags and libs +override CFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(spectra_VERSION)\"" +override CFLAGS += `$(PKG_CONFIG) --cflags lv2` +ifeq ($(XWIN),) +override CFLAGS += -fPIC -fvisibility=hidden +else +override CFLAGS += -DPTW32_STATIC_LIB +endif + +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango fftw3f` $(CFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo fftw3f $(PKG_GL_LIBS)` + +ifneq ($(XWIN),) +GLUILIBS+=-lpthread -lusp10 +endif + +GLUICFLAGS+=$(LIC_CFLAGS) +GLUILIBS+=$(LIC_LOADLIBES) + +ifneq ($(LIC_CFLAGS),) + LV2SIGN=lv2:extensionData \\; + override CFLAGS += -I$(RW) +endif + +ROBGL+= Makefile + +JACKCFLAGS=-I. $(CFLAGS) $(LIC_CFLAGS) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo fftw3f $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) + +############################################################################### +# build target definitions +default: all + +submodule_pull: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_pull + +submodule_update: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_update + +submodule_check: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodule_check + +submodules: + -test -d .git -a .gitmodules -a -f Makefile.git && $(MAKE) -f Makefile.git submodules + +all: submodule_check $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets) $(JACKAPP) + +$(BUILDDIR)manifest.ttl: lv2ttl/manifest.ttl.in lv2ttl/manifest.gui.in Makefile + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/" \ + lv2ttl/manifest.ttl.in > $(BUILDDIR)manifest.ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@LIB_EXT@/$(LIB_EXT)/;s/@UI_TYPE@/$(UI_TYPE)/;s/@LV2GUI@/$(LV2GUI)/g" \ + lv2ttl/manifest.gui.in >> $(BUILDDIR)manifest.ttl +endif + +$(BUILDDIR)$(LV2NAME).ttl: lv2ttl/$(LV2NAME).ttl.in lv2ttl/$(LV2NAME).gui.in Makefile + @mkdir -p $(BUILDDIR) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/" \ + lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl +ifneq ($(BUILDOPENGL), no) + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/" \ + lv2ttl/$(LV2NAME).gui.in >> $(BUILDDIR)$(LV2NAME).ttl +endif + + +DSP_SRC = src/$(LV2NAME).c +DSP_DEPS = $(DSP_SRC) src/uris.h +GUI_DEPS = gui/$(LV2NAME).c gui/fft.c src/uris.h + +$(BUILDDIR)$(LV2NAME)$(LIB_EXT): $(DSP_DEPS) Makefile + @mkdir -p $(BUILDDIR) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LIC_CFLAGS) -std=c99 \ + -o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DSP_SRC) \ + -shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES) $(LIC_LOADLIBES) + $(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT) + +jackapps: $(JACKAPP) + +$(eval x42_spectr_JACKSRC = $(DSP_SRC)) +x42_spectr_JACKGUI = gui/spectra.c +x42_spectr_LV2HTTL = lv2ttl/spectra.h +x42_spectr_JACKDESC = lv2ui_descriptor +$(APPBLD)x42-spectr$(EXE_EXT): $(DSP_DEPS) $(GUI_DEPS) \ + $(x42_spectr_JACKGUI) $(x42_spectr_LV2HTTL) + +ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) + -include $(RW)robtk.mk +endif + +$(BUILDDIR)$(LV2GUI)$(LIB_EXT): $(GUI_DEPS) + +############################################################################### +# install/uninstall/clean target definitions + +install: install-bin install-man + +uninstall: uninstall-bin uninstall-man + +install-bin: all + install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m644 $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE) + install -m755 $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +ifneq ($(BUILDOPENGL), no) + install -m755 $(BUILDDIR)$(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE) +endif +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(BINDIR) + install -m755 $(APPBLD)x42-spectr$(EXE_EXT) $(DESTDIR)$(BINDIR) +endif + +uninstall-bin: + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/manifest.ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME).ttl + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2NAME)$(LIB_EXT) + rm -f $(DESTDIR)$(LV2DIR)/$(BUNDLE)/$(LV2GUI)$(LIB_EXT) + rm -f $(DESTDIR)$(BINDIR)/x42-spectr$(EXE_EXT) + -rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE) + -rmdir $(DESTDIR)$(BINDIR) + +install-man: +ifneq ($(BUILDJACKAPP), no) + install -d $(DESTDIR)$(MANDIR) + install -m644 x42-spectr.1 $(DESTDIR)$(MANDIR) +endif + +uninstall-man: + rm -f $(DESTDIR)$(MANDIR)/x42-spectr.1 + -rmdir $(DESTDIR)$(MANDIR) + +man: $(APPBLD)x42-spectr + help2man -N -o x42-spectr.1 -n "x42-spectr Analyzer" $(APPBLD)x42-spectr + +clean: + rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl \ + $(BUILDDIR)$(LV2NAME)$(LIB_EXT) \ + $(BUILDDIR)$(LV2GUI)$(LIB_EXT) + rm -rf $(BUILDDIR)*.dSYM + rm -rf $(APPBLD)x42-* + -test -d $(APPBLD) && rmdir $(APPBLD) || true + -test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true + +distclean: clean + rm -f cscope.out cscope.files tags + +.PHONY: clean all install uninstall distclean jackapps man \ + install-bin uninstall-bin install-man uninstall-man \ + submodule_check submodules submodule_update submodule_pull diff -Nru x42-plugins-20170428/spectra.lv2/README.md x42-plugins-20190714/spectra.lv2/README.md --- x42-plugins-20170428/spectra.lv2/README.md 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/README.md 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,31 @@ +spectra.lv2 - Spectr Spectrum Analyzer +====================================== + +spectra.lv2 is lollipop graph spectrum analyzer. + +It is available as [LV2 plugin](http://lv2plug.in/) and standalone [JACK](http://jackaudio.org/)-application. + +Install +------- + +Compiling spectr.lv2 requires the LV2 SDK, jack-headers, gnu-make, a c++-compiler, +libpango, libcairo and openGL (sometimes called: glu, glx, mesa). + +```bash + git clone git://github.com/x42/spectra.lv2.git + cd spectra.lv2 + make submodules + make + sudo make install PREFIX=/usr +``` + +Note to packagers: the Makefile honors `PREFIX` and `DESTDIR` variables as well +as `CXXLAGS`, `LDFLAGS` and `OPTIMIZATIONS` (additions to `CXXFLAGS`), also +see the first 10 lines of the Makefile. +You really want to package the superset of [x42-plugins](https://github.com/x42/x42-plugins). + + +Screenshots +----------- + +![screenshot](https://raw.github.com/x42/spectra.lv2/master/img/spectr.png "Spectr LV2 GUI - 100Hz Sine") diff -Nru x42-plugins-20170428/spectra.lv2/src/spectra.c x42-plugins-20190714/spectra.lv2/src/spectra.c --- x42-plugins-20170428/spectra.lv2/src/spectra.c 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/src/spectra.c 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,277 @@ +/* simple spectrum analyzer + * + * Copyright (C) 2013 Robin Gareus + * + * 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, 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. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include + +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#include "./uris.h" + +static bool printed_capacity_warning = false; + +typedef struct { + /* I/O ports */ + float const* input[MAX_CHANNELS]; + float* output[MAX_CHANNELS]; + const LV2_Atom_Sequence* control; + LV2_Atom_Sequence* notify; + + /* atom-forge and URI mapping */ + LV2_URID_Map* map; + SpectraLV2URIs uris; + LV2_Atom_Forge forge; + LV2_Atom_Forge_Frame frame; + + uint32_t n_channels; + double rate; + + /* the state of the UI is stored here, so that + * the GUI can be displayed & closed + * without loosing current settings. + */ + bool ui_active; + bool send_settings_to_ui; + +} Spectra; + +static LV2_Handle +instantiate (const LV2_Descriptor* descriptor, + double rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + (void)descriptor; /* unused variable */ + (void)bundle_path; /* unused variable */ + + Spectra* self = (Spectra*)calloc (1, sizeof (Spectra)); + if (!self) { + return NULL; + } + + int i; + for (i = 0; features[i]; ++i) { + if (!strcmp (features[i]->URI, LV2_URID__map)) { + self->map = (LV2_URID_Map*)features[i]->data; + } + } + + if (!self->map) { + fprintf (stderr, "Spectra.lv2 error: Host does not support urid:map\n"); + free (self); + return NULL; + } + + if (!strncmp (descriptor->URI, SPR_URI "#Mono", 31 + 5)) { + self->n_channels = 1; + } else { + free (self); + return NULL; + } + + assert (self->n_channels <= MAX_CHANNELS); + + self->ui_active = false; + self->send_settings_to_ui = false; + self->rate = rate; + + lv2_atom_forge_init (&self->forge, self->map); + map_spectra_uris (self->map, &self->uris); + return (LV2_Handle)self; +} + +static void +connect_port (LV2_Handle handle, + uint32_t port, + void* data) +{ + Spectra* self = (Spectra*)handle; + + switch ((PortIndex)port) { + case SPR_CONTROL: + self->control = (const LV2_Atom_Sequence*)data; + break; + case SPR_NOTIFY: + self->notify = (LV2_Atom_Sequence*)data; + break; + default: + if (port > SPR_WINDOW && port <= SPR_WINDOW + 2 * MAX_CHANNELS) { + int chn = (port - SPR_WINDOW - 1) / 2; + if (port & 1) { + self->input[chn] = (float const*)data; + } else { + self->output[chn] = (float*)data; + } + } + break; + } +} + +/** forge atom-vector of raw data */ +static void +tx_rawaudio (LV2_Atom_Forge* forge, SpectraLV2URIs* uris, + const int32_t channel, const size_t n_samples, void const* data) +{ + LV2_Atom_Forge_Frame frame; + /* forge container object of type 'rawaudio' */ + lv2_atom_forge_frame_time (forge, 0); + x_forge_object (forge, &frame, 1, uris->rawaudio); + + /* add integer attribute 'channelid' */ + lv2_atom_forge_property_head (forge, uris->channelid, 0); + lv2_atom_forge_int (forge, channel); + + /* add vector of floats raw 'audiodata' */ + lv2_atom_forge_property_head (forge, uris->audiodata, 0); + lv2_atom_forge_vector (forge, sizeof (float), uris->atom_Float, n_samples, data); + + /* close off atom-object */ + lv2_atom_forge_pop (forge, &frame); +} + +static void +run (LV2_Handle handle, uint32_t n_samples) +{ + Spectra* self = (Spectra*)handle; + const size_t size = (sizeof (float) * n_samples + 64) * self->n_channels; + const uint32_t capacity = self->notify->atom.size; + + /* check if atom-port buffer is large enough to hold + * all audio-samples and configuration settings */ + if (capacity < size + 160 + self->n_channels * 32) { + if (!printed_capacity_warning) { + fprintf (stderr, "Spectra.lv2 error: LV2 comm-buffersize is insufficient %d/%ld bytes.\n", + capacity, size + 160 + self->n_channels * 32); + printed_capacity_warning = true; + } + return; + } + + /* prepare forge buffer and initialize atom-sequence */ + lv2_atom_forge_set_buffer (&self->forge, (uint8_t*)self->notify, capacity); + lv2_atom_forge_sequence_head (&self->forge, &self->frame, 0); + + /* Send settings to UI */ + if (self->send_settings_to_ui && self->ui_active) { + self->send_settings_to_ui = false; + /* forge container object of type 'ui_state' */ + LV2_Atom_Forge_Frame frame; + lv2_atom_forge_frame_time (&self->forge, 0); + x_forge_object (&self->forge, &frame, 1, self->uris.ui_state); + /* forge attributes for 'ui_state' */ + lv2_atom_forge_property_head (&self->forge, self->uris.samplerate, 0); + lv2_atom_forge_float (&self->forge, self->rate); + + /* close-off frame */ + lv2_atom_forge_pop (&self->forge, &frame); + } + + /* Process incoming events from GUI */ + if (self->control) { +#if 0 + printf("CTRL size %d\n", (self->control)->atom.size); + for(uint8_t xx=0; xx < (self->control)->atom.size + 8; ++xx) { + uint8_t d = ((uint8_t*)(self->control))[xx]; + printf("%02x%s", d, (xx%4)==3? "|": " "); + } + printf("\n"); +#endif + LV2_Atom_Event* ev = lv2_atom_sequence_begin (&(self->control)->body); + /* for each message from UI... */ + while (!lv2_atom_sequence_is_end (&(self->control)->body, (self->control)->atom.size, ev)) { + /* .. only look at atom-events.. */ + if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) { + const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; + //printf("BLANK recv.. %x %x %x %x\n", obj->atom.size, obj->atom.type, obj->body.id, obj->body.otype); + /* interpret atom-objects: */ + if (obj->body.otype == self->uris.ui_on) { + /* UI was activated */ + self->ui_active = true; + self->send_settings_to_ui = true; + } else if (obj->body.otype == self->uris.ui_off) { + /* UI was closed */ + self->ui_active = false; + } + } + ev = lv2_atom_sequence_next (ev); + } + } + + /* process audio data */ + for (uint32_t c = 0; c < self->n_channels; ++c) { + if (self->ui_active) { + /* if UI is active, send raw audio data to UI */ + tx_rawaudio (&self->forge, &self->uris, c, n_samples, self->input[c]); + } + /* if not processing in-place, forward audio */ + if (self->input[c] != self->output[c]) { + memcpy (self->output[c], self->input[c], sizeof (float) * n_samples); + } + } + + /* close off atom-sequence */ + lv2_atom_forge_pop (&self->forge, &self->frame); +} + +static void +cleanup (LV2_Handle handle) +{ + free (handle); +} + +/* clang-format off */ +#define mkdesc(ID, NAME) \ + static const LV2_Descriptor descriptor##ID = { \ + SPR_URI NAME, \ + instantiate, \ + connect_port, \ + NULL, \ + run, \ + NULL, \ + cleanup, \ + NULL \ + }; +/* clang-format on */ + +mkdesc (0, "#Mono") + mkdesc (1, "#Mono_gtk") + mkdesc (2, "#Stereo") + mkdesc (3, "#Stereo_gtk") + + LV2_SYMBOL_EXPORT + const LV2_Descriptor* lv2_descriptor (uint32_t index) +{ + switch (index) { + case 0: + return &descriptor0; + case 1: + return &descriptor1; + case 2: + return &descriptor2; + case 3: + return &descriptor3; + default: + return NULL; + } +} diff -Nru x42-plugins-20170428/spectra.lv2/src/uris.h x42-plugins-20190714/spectra.lv2/src/uris.h --- x42-plugins-20170428/spectra.lv2/src/uris.h 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/src/uris.h 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,81 @@ +/* simple spectrum analyzer + * + * Copyright (C) 2013 Robin Gareus + * + * 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, 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, see . + */ + +#ifndef SPR_URIS_H +#define SPR_URIS_H + +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/atom/forge.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" + +#define SPR_URI "http://gareus.org/oss/lv2/spectra" + +#ifdef HAVE_LV2_1_8 +#define x_forge_object lv2_atom_forge_object +#else +#define x_forge_object lv2_atom_forge_blank +#endif + +typedef struct { + LV2_URID atom_Blank; + LV2_URID atom_Object; + LV2_URID atom_Vector; + LV2_URID atom_Float; + LV2_URID atom_Int; + LV2_URID atom_eventTransfer; + LV2_URID rawaudio; + LV2_URID channelid; + LV2_URID audiodata; + + LV2_URID samplerate; + LV2_URID ui_on; + LV2_URID ui_off; + LV2_URID ui_state; +} SpectraLV2URIs; + +static inline void +map_spectra_uris (LV2_URID_Map* map, SpectraLV2URIs* uris) +{ + uris->atom_Blank = map->map (map->handle, LV2_ATOM__Blank); + uris->atom_Object = map->map (map->handle, LV2_ATOM__Object); + uris->atom_Vector = map->map (map->handle, LV2_ATOM__Vector); + uris->atom_Float = map->map (map->handle, LV2_ATOM__Float); + uris->atom_Int = map->map (map->handle, LV2_ATOM__Int); + uris->atom_eventTransfer = map->map (map->handle, LV2_ATOM__eventTransfer); + uris->rawaudio = map->map (map->handle, SPR_URI "#rawaudio"); + uris->audiodata = map->map (map->handle, SPR_URI "#audiodata"); + uris->channelid = map->map (map->handle, SPR_URI "#channelid"); + uris->samplerate = map->map (map->handle, SPR_URI "#samplerate"); + uris->ui_on = map->map (map->handle, SPR_URI "#ui_on"); + uris->ui_off = map->map (map->handle, SPR_URI "#ui_off"); + uris->ui_state = map->map (map->handle, SPR_URI "#ui_state"); +} + +typedef enum { + SPR_CONTROL = 0, + SPR_NOTIFY = 1, + SPR_FFTSIZE = 2, + SPR_WEIGHT = 3, + SPR_WINDOW = 4, + SPR_INPUT0 = 5, + SPR_OUTPUT0 = 6, +} PortIndex; + +#define MAX_CHANNELS (1) + +#endif diff -Nru x42-plugins-20170428/spectra.lv2/x42-spectr.1 x42-plugins-20190714/spectra.lv2/x42-spectr.1 --- x42-plugins-20170428/spectra.lv2/x42-spectr.1 1970-01-01 00:00:00.000000000 +0000 +++ x42-plugins-20190714/spectra.lv2/x42-spectr.1 2019-07-14 19:39:29.000000000 +0000 @@ -0,0 +1,60 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH X42-SPECTR "1" "July 2019" "x42-spectr version 0.4.1" "User Commands" +.SH NAME +x42-spectr \- x42-spectr Analyzer +.SH SYNOPSIS +.B x42-spectr +[ \fI\,OPTIONS \/\fR] +.SH DESCRIPTION +x42\-spectr \- JACK Spectr +.PP +This is a standalone JACK application of the LV2 plugin: +"Spectr". +.PP +Usage: +All control elements are operated in using the mouse: +.TP +Click+Drag +left/down: decrease, right/up: increase value. Hold the Ctrl key to increase sensitivity. +.TP +Shift+Click +reset to default value +.TP +Scroll\-wheel +up/down by 1 step (smallest possible adjustment for given setting). Rapid continuous scrolling increases the step\-size. +.PP +The application can be closed by sending a SIGTERM (CTRL+C) on the command\-line of by closing the window. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Display this help and exit +.TP +\fB\-j\fR, \fB\-\-jack\-name\fR +Set the JACK client name +(defaults to plugin\-name) +.TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP +\fB\-O\fR , \fB\-\-osc\fR +Listen for OSC messages on the given UDP port +.TP +\fB\-p\fR :, \fB\-\-port\fR : +Set initial value for given control port +.TP +\fB\-P\fR, \fB\-\-portlist\fR +Print control port list on startup +.TP +\fB\-\-osc\-doc\fR +Print available OSC commands and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version information and exit +.PP +See also: +Website: +.SH COPYRIGHT +Copyright \(co GPL 2013\-2019 Robin Gareus +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru x42-plugins-20170428/stepseq.lv2/gridgen.sh x42-plugins-20190714/stepseq.lv2/gridgen.sh --- x42-plugins-20170428/stepseq.lv2/gridgen.sh 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/gridgen.sh 2019-07-14 19:39:36.000000000 +0000 @@ -2,6 +2,23 @@ NOTES=$1 STEPS=$2 +if test -z "$NOTES" -o -z "$STEPS"; then + echo "Number of notes and steps must be given." + exit 1 +fi + +if ! [ "$NOTES" -eq "$NOTES" ] 2>/dev/null; then + echo "Number of Notes must be an integer" + exit 1 +fi + +if ! [ "$STEPS" -eq "$STEPS" ] 2>/dev/null; then + echo "Number of Steps must be an integer" + exit 1 +fi + + +mkdir -p modgui MODICON=modgui/icon-stepseq.html MODSTYLE=modgui/style-stepseq.css IDX=11 @@ -19,7 +36,7 @@ esac } -for n in `seq 1 $NOTES`; do +for ((n=1; n <= $NOTES; n++)); do # TODO musical scale OCT=$(( ($n - 1) / 7 )) NOT=$(twelvetet $n) @@ -40,9 +57,9 @@ cat misc/mod_icon.head > $MODICON -for n in `seq 1 $NOTES`; do +for ((n=1; n <= $NOTES; n++)); do echo '
' >> $MODICON - for s in `seq 1 $STEPS`; do + for ((s=1; s <= $STEPS; s++)); do sed "s/@IDX@/$IDX/;s/@NOTE@/$n/g;s/@STEP@/$s/g" << EOF ] , [ @@ -63,7 +80,7 @@ done echo '' >> $MODICON -for s in `seq 1 $STEPS`; do +for ((s=1; s <= $STEPS; s++)); do echo '
C
' >> $MODICON done echo '
C
' >> $MODICON diff -Nru x42-plugins-20170428/stepseq.lv2/gui/stepseq.c x42-plugins-20190714/stepseq.lv2/gui/stepseq.c --- x42-plugins-20170428/stepseq.lv2/gui/stepseq.c 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/gui/stepseq.c 2019-07-14 19:39:36.000000000 +0000 @@ -75,6 +75,62 @@ /////////////////////////////////////////////////////////////////////////////// +static const char* mdrums[] = { + "Kick 2", // "Bass Drum 2" #35 + "Kick 1", // "Bass Drum 1" + "RimShot", // "Side Stick/Rimshot" + "Snare 1", // "Snare Drum 1" + "Clap", // "Hand Clap" + "Snare 2", // "Snare Drum 2" + "Low Tom 2", // "Low Tom 2" + "HH Closed", // "Closed Hi-hat" + "Low Tom 1", // "Low Tom 1" + "HH Pedal", // "Pedal Hi-hat" + "Mid Tom 2", // "Mid Tom 2" + "HH Open", // "Open Hi-hat" + "Mid Tom 1", // "Mid Tom 1" + "Hi Tom 2", // "High Tom 2" + "Crash 1", // "Crash Cymbal 1" + "Hi Tom 1", // "High Tom 1" + "Ride 1", // "Ride Cymbal 1" + "China Cym", // "Chinese Cymbal" + "Ride Bell", // "Ride Bell" + "Tambour.", // "Tambourine" + "Splash", // "Splash Cymbal" + "Cowbell", // "Cowbell" + "Crash 2", // "Crash Cymbal 2" + "Slap", // "Vibra Slap" + "Ride 2", // "Ride Cymbal 2" + "Bongo Hi", // "High Bongo" + "Bongo Lo", // "Low Bongo" + "Conga Mt.", // "Mute High Conga" + "Conga Op.", // "Open High Conga" + "Conga Low", // "Low Conga" + "Timbale H", // "High Timbale" + "Timbale L", // "Low Timbale" + "Agogo H", // "High Agogô" + "Agogo L", // "Low Agogô" + "Cabasa", // "Cabasa" + "Maracas", // "Maracas" + "Whistle S", // "Short Whistle" + "Whistle L", // "Long Whistle" + "Guiro S", // "Short Güiro" + "Guiro L", // "Long Güiro" + "Claves", // "Claves" + "Woodblk H", // "High Wood Block" + "Woodblk L", // "Low Wood Block" + "Cuica Mt.", // "Mute Cuíca" + "Cuica Op.", // "Open Cuíca" + "Tri. Mt.", // "Mute Triangle" + "Tri. Op." // "Open Triangle" +}; + +static const char* notename[] = { + "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" +}; + +/////////////////////////////////////////////////////////////////////////////// + struct MyGimpImage { unsigned int width; unsigned int height; @@ -337,10 +393,13 @@ static void set_note_txt (SeqUI* ui, int n) { int mn = rintf (robtk_select_get_value (ui->sel_note[n])); - char txt[7]; - const char *nn[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; - sprintf (txt, "%2s%d", nn[mn%12], -1 + mn / 12); - robtk_lbl_set_text (ui->lbl_note[n], txt); + if (mn >= 35 && mn <= 81 && robtk_cbtn_get_active (ui->btn_drum)) { + robtk_lbl_set_text (ui->lbl_note[n], mdrums[mn-35]); + } else { + char txt[10]; + sprintf (txt, "%-2s%d ", notename[mn%12], -1 + mn / 12); + robtk_lbl_set_text (ui->lbl_note[n], txt); + } } /////////////////////////////////////////////////////////////////////////////// @@ -403,6 +462,9 @@ static bool cb_drum (RobWidget* w, void* handle) { SeqUI* ui = (SeqUI*)handle; + for (int n = 0; n < N_NOTES; ++n) { + set_note_txt (ui, n); + } if (ui->disable_signals) return TRUE; const float val = robtk_cbtn_get_active (ui->btn_drum) ? 1 : 0; ui->write (ui->controller, PORT_DRUM, sizeof (float), 0, (const void*) &val); @@ -419,9 +481,16 @@ return TRUE; } -static bool cb_btn_panic (RobWidget *w, void* handle) { +static bool cb_btn_panic_press (RobWidget *w, void* handle) { + SeqUI* ui = (SeqUI*)handle; + float val = 1; + ui->write (ui->controller, PORT_PANIC, sizeof (float), 0, (const void*) &val); + return TRUE; +} + +static bool cb_btn_panic_release (RobWidget *w, void* handle) { SeqUI* ui = (SeqUI*)handle; - float val = robtk_pbtn_get_pushed (ui->btn_panic) ? 1.f : 0.f; + float val = 0; ui->write (ui->controller, PORT_PANIC, sizeof (float), 0, (const void*) &val); return TRUE; } @@ -468,8 +537,9 @@ #define GSL_W(PTR) robtk_select_widget (PTR) for (uint32_t n = 0; n < N_NOTES; ++n) { - ui->lbl_note[n] = robtk_lbl_new ("A#-1"); - robtk_lbl_set_alignment (ui->lbl_note[n], .9, 0); + ui->lbl_note[n] = robtk_lbl_new ("##|G#-8|#"); + robtk_lbl_set_min_geometry (ui->lbl_note[n], ui->lbl_note[n]->w_width, ui->lbl_note[n]->w_height); + robtk_lbl_set_alignment (ui->lbl_note[n], .5, 0); ui->sel_note[n] = robtk_select_new (); for (uint32_t mn = 0; mn < 128; ++mn) { char txt[8]; @@ -562,7 +632,8 @@ /* panic */ ui->btn_panic = robtk_pbtn_new ("Panic"); - robtk_pbtn_set_callback (ui->btn_panic, cb_btn_panic, ui); + robtk_pbtn_set_callback_down (ui->btn_panic, cb_btn_panic_press, ui); + robtk_pbtn_set_callback_up (ui->btn_panic, cb_btn_panic_release, ui); robtk_pbtn_set_alignment(ui->btn_panic, 0.5, 0.5); /* labels */ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/img/x42-stepseq.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/img/x42-stepseq.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/img/x42-stepseq.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/img/x42-stepseq.png differ diff -Nru x42-plugins-20170428/stepseq.lv2/lv2ttl/manifest.modgui.in x42-plugins-20190714/stepseq.lv2/lv2ttl/manifest.modgui.in --- x42-plugins-20170428/stepseq.lv2/lv2ttl/manifest.modgui.in 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/lv2ttl/manifest.modgui.in 2019-07-14 19:39:36.000000000 +0000 @@ -7,7 +7,7 @@ modgui:screenshot ; modgui:thumbnail ; modgui:javascript ; - modgui:monitoredOutputs [ lv2:symbol "pos" ] ; + modgui:monitoredOutputs [ lv2:symbol "pos" ] , [ lv2:symbol "hostbpm" ] ; @MODBRAND@ @MODLABEL@ ] . diff -Nru x42-plugins-20170428/stepseq.lv2/lv2ttl/stepseq.ttl.in x42-plugins-20190714/stepseq.lv2/lv2ttl/stepseq.ttl.in --- x42-plugins-20170428/stepseq.lv2/lv2ttl/stepseq.ttl.in 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/lv2ttl/stepseq.ttl.in 2019-07-14 19:39:36.000000000 +0000 @@ -56,7 +56,7 @@ lv2:minimum 0; lv2:default 0; lv2:maximum 1; - lv2:portProperty lv2:integer, lv2:enumeration; + lv2:portProperty lv2:integer, lv2:enumeration, lv2:toggled; lv2:scalePoint [ rdfs:label "Free Running"; rdf:value 0 ; ] ; lv2:scalePoint [ rdfs:label "Host Sync (if available)"; rdf:value 1 ; ] ; ] , [ @@ -140,7 +140,9 @@ lv2:index 10; lv2:symbol "hostbpm"; lv2:name "Host BPM"; - lv2:minimum 40; + lv2:minimum -1; lv2:maximum 208; + lv2:scalePoint [ rdfs:label "N/A"; rdf:value -1 ; ] ; + lv2:scalePoint [ rdfs:label "No Sync"; rdf:value 0 ; ] ; lv2:portProperty pprop:notOnGUI ; units:unit units:bpm; diff -Nru x42-plugins-20170428/stepseq.lv2/Makefile x42-plugins-20190714/stepseq.lv2/Makefile --- x42-plugins-20170428/stepseq.lv2/Makefile 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/Makefile 2019-07-14 19:39:36.000000000 +0000 @@ -9,9 +9,11 @@ MANDIR ?= $(PREFIX)/share/man/man1 LV2DIR ?= $(PREFIX)/lib/lv2 -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CFLAGS ?= -Wall -g -Wno-unused-function -STRIP ?= strip + +PKG_CONFIG?=pkg-config +STRIP?= strip # grid-size (should be at least 4x4 for the MOD-GUI) N_NOTES ?= 8 @@ -62,7 +64,7 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_GL_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` -pthread + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` -pthread STRIPFLAGS= -s EXTENDED_RE=-r endif @@ -125,18 +127,18 @@ endif # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) - ifeq ($(shell pkg-config --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") endif endif ifneq ($(BUILDJACKAPP), no) - ifeq ($(shell pkg-config --exists jack || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif @@ -144,7 +146,7 @@ endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif @@ -172,18 +174,18 @@ # add library dependent flags and libs override CFLAGS += $(OPTIMIZATIONS) -DVERSION="\"$(stepseq_VERSION)\"" -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += `$(PKG_CONFIG) --cflags lv2` ifeq ($(XWIN),) override CFLAGS += -fPIC -fvisibility=hidden else override CFLAGS += -DPTW32_STATIC_LIB endif -override LOADLIBES += `pkg-config --libs lv2` +override LOADLIBES += `$(PKG_CONFIG) --libs lv2` -GLUICFLAGS+=`pkg-config --cflags cairo pango` $(CFLAGS) -GLUILIBS+=`pkg-config $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` $(CFLAGS) +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 @@ -194,15 +196,15 @@ ifneq ($(LIC_CFLAGS),) - SIGNATURE=lv2:extensionData \\; + LV2SIGN=lv2:extensionData \\; override CFLAGS += -I$(RW) endif ROBGL+= Makefile JACKCFLAGS=-I. $(CFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` -JACKLIBS=-lm $(GLUILIBS) $(LIC_LOADLIBES) $(LOADLIBES) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) # build target definitions @@ -237,7 +239,7 @@ $(BUILDDIR)$(LV2NAME).ttl: lv2ttl/$(LV2NAME).ttl.in Makefile gridgen.sh misc/mod_icon.head misc/mod_icon.tail misc/style.css.in @mkdir -p $(BUILDDIR) - sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(SIGNATURE)/;s/@NAMESUFFIX@/$(NAMESUFFIX)/;s/@URISUFFIX@/$(URISUFFIX)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@STEPS@/$(N_STEPS)/" \ + sed "s/@LV2NAME@/$(LV2NAME)/g;s/@SIGNATURE@/$(LV2SIGN)/;s/@NAMESUFFIX@/$(NAMESUFFIX)/;s/@URISUFFIX@/$(URISUFFIX)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g;s/@UITTL@/$(UITTL)/;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@STEPS@/$(N_STEPS)/" \ lv2ttl/$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl ./gridgen.sh $(N_NOTES) $(N_STEPS) >> $(BUILDDIR)$(LV2NAME).ttl echo "]; ." >> $(BUILDDIR)$(LV2NAME).ttl diff -Nru x42-plugins-20170428/stepseq.lv2/Makefile.git x42-plugins-20190714/stepseq.lv2/Makefile.git --- x42-plugins-20170428/stepseq.lv2/Makefile.git 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/Makefile.git 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -#!/usr/bin/make - -submodules: - git submodule init - git submodule update - -submodule_update: - git submodule update - -submodule_pull: - git submodule foreach "git pull" - -submodule_check: - @-test -d .git -a .gitmodules && \ - git submodule status \ - | grep -q "^-" \ - && $(MAKE) submodules || true - @-test -d .git -a .gitmodules && \ - git submodule status \ - | grep -q "^+" \ - && $(MAKE) submodule_update || true - -.PHONY: submodule_check submodules submodule_update submodule_pull diff -Nru x42-plugins-20170428/stepseq.lv2/misc/mod_icon.tail x42-plugins-20190714/stepseq.lv2/misc/mod_icon.tail --- x42-plugins-20170428/stepseq.lv2/misc/mod_icon.tail 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/misc/mod_icon.tail 2019-07-14 19:39:36.000000000 +0000 @@ -14,18 +14,27 @@ Step
+
+ Swing +
+
Midi Chan.
-
+
BPM
-
- Swing -
+
+
+ BPM +
+
+
+
+ Sync
diff -Nru x42-plugins-20170428/stepseq.lv2/misc/style.css.in x42-plugins-20190714/stepseq.lv2/misc/style.css.in --- x42-plugins-20170428/stepseq.lv2/misc/style.css.in 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/misc/style.css.in 2019-07-14 19:39:36.000000000 +0000 @@ -95,9 +95,9 @@ } .x42-stepseq{{{cns}}} .hidden-ctrl { - display:none; - height:0px; - width:0px; + display:none; + height:0px; + width:0px; } /* = Display Radio @@ -148,7 +148,7 @@ .x42-stepseq{{{cns}}} .bottom-group { margin:10px auto 0 auto; - width:280px; + width:328px; position:absolute; bottom:36px; left:64px; @@ -229,6 +229,15 @@ margin:4px auto 0 auto; } +.x42-stepseq{{{cns}}} .mod-control-group .mod-knob-image.host-sync { + background-image:url(/resources/sync.png{{{ns}}}); +} + +.x42-stepseq{{{cns}}} .mod-control-group .mod-knob.insensitive { + display:none; +} + + .x42-stepseq{{{cns}}} .mod-control-group .mod-knob-m16-image { background-image:url(/resources/m16.png{{{ns}}}); background-repeat:no-repeat; Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/division.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/division.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/footswitch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/footswitch.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/knob.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/knob.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/m16.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/m16.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/m_drum.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/m_drum.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/m_note.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/m_note.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/m_nums.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/m_nums.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/screenshot-stepseq.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/screenshot-stepseq.png differ diff -Nru x42-plugins-20170428/stepseq.lv2/modgui/script-stepseq.js x42-plugins-20190714/stepseq.lv2/modgui/script-stepseq.js --- x42-plugins-20170428/stepseq.lv2/modgui/script-stepseq.js 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/modgui/script-stepseq.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -function (event, funcs) { - - function update_note_display (nd) { - switch (nd) { - case 'drum': - event.icon.find ("[x42-role=seq-note]").removeClass ("note"); - event.icon.find ("[x42-role=seq-note]").removeClass ("nums"); - event.icon.find ("[x42-role=seq-note]").addClass ("drum"); - break; - case 'note': - event.icon.find ("[x42-role=seq-note]").removeClass ("drum"); - event.icon.find ("[x42-role=seq-note]").removeClass ("nums"); - event.icon.find ("[x42-role=seq-note]").addClass ("note"); - break; - case 'nums': - event.icon.find ("[x42-role=seq-note]").removeClass ("drum"); - event.icon.find ("[x42-role=seq-note]").removeClass ("note"); - event.icon.find ("[x42-role=seq-note]").addClass ("nums"); - break; - } - } - - function update_drummode_display (dm, force) { - var dmw = event.icon.find("[x42-role=seq-radio-drum]"); - if (!(dm || dmw.hasClass("selected")) || (dm && dmw.hasClass("selected"))) { - if (!force) { - return; - } - } - event.icon.find ("div.displayradio").removeClass ("selected"); - if (dm) { - event.icon.find("[x42-role=seq-radio-drum]").addClass ("selected"); - update_note_display ('drum'); - } else { - event.icon.find("[x42-role=seq-radio-note]").addClass ("selected"); - update_note_display ('note'); - } - } - - function set_current_step (step) { - /* TODO: incremental, keep track of highlighted column */ - event.icon.find("[mod-role=input-control-port][grid-row]").each(function () { $(this).removeClass("highlight"); }); - event.icon.find("[mod-role=input-control-port][grid-col="+step+"]").each(function () { $(this).addClass("highlight"); }); - } - - if (event.type == 'change') { - if (event.symbol == "drummode") { - update_drummode_display (event.value, false); - } - else if (event.symbol == "pos") { - set_current_step (Math.round (event.value)); - } - } - - if (event.type != "start") { - return; - } - - function set_ctrl (ctrl, value) { - if (event.api_version >= 1) { - funcs.set_port_value($(ctrl).attr('mod-port-symbol'), value); - } else { - /* this is for MOD v1.0 backwards compatibility and prototyping. - * DO NOT USE THIS APPROACH IN NEW CODE. It bypasses - * checks for bound controls among other things. */ - $(ctrl).controlWidget('setValue', value); - } - } - - function set_drummode (dm) { - var ctrl = event.icon.find ("[mod-port-symbol=drummode]"); - set_ctrl (ctrl, dm); - } - - function resetGridValue() { - set_ctrl (this, 0); - } - - /* initial setup */ - event.icon.find("[x42-role=seq-radio-nums]").click(function(){ - event.icon.find ("div.displayradio").removeClass ("selected"); - $(this).addClass ("selected"); - update_note_display ('nums'); - set_drummode (0); - }); - - event.icon.find("[x42-role=seq-radio-note]").click(function(){ - event.icon.find ("div.displayradio").removeClass ("selected"); - $(this).addClass ("selected"); - update_note_display ('note'); - set_drummode (0); - }); - - event.icon.find("[x42-role=seq-radio-drum]").click(function(){ - event.icon.find ("div.displayradio").removeClass ("selected"); - $(this).addClass ("selected"); - update_note_display ('drum'); - set_drummode (1); - }); - - event.icon.find("div.resetbutton.col").click(function(){ - var c = $(this).attr('grid-col'); - event.icon.find("[mod-role=input-control-port][grid-col="+c+"]").each(resetGridValue); - }); - - event.icon.find("div.resetbutton.row").click(function(){ - var r = $(this).attr('grid-row'); - event.icon.find("[mod-role=input-control-port][grid-row="+r+"]").each(resetGridValue); - }); - - event.icon.find("div.resetbutton.all").click(function(){ - event.icon.find("[mod-role=input-control-port][grid-row]").each(resetGridValue); - }); - - var ports = event.ports; - for (var p in ports) { - switch (ports[p].symbol) { - case 'drummode': - update_drummode_display (ports[p].value, true); - break; - case 'pos': - set_current_step (Math.round (event.value)); - break; - default: - break; - } - } -} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/swinger.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/swinger.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stepseq.lv2/modgui/thumbnail-stepseq.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stepseq.lv2/modgui/thumbnail-stepseq.png differ diff -Nru x42-plugins-20170428/stepseq.lv2/src/stepseq.c x42-plugins-20190714/stepseq.lv2/src/stepseq.c --- x42-plugins-20170428/stepseq.lv2/src/stepseq.c 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/src/stepseq.c 2019-07-14 19:39:36.000000000 +0000 @@ -85,26 +85,26 @@ float div; // beats per step /* Settings */ - float sample_rate; // samples per second - float sps; // samples per step + double sample_rate; // samples per second + double sps; // samples per step - float swing; - bool drum_mode; + double swing; + bool drum_mode; /* Host Time */ bool host_info; float host_bpm; - float bar_beats; + double bar_beats; float host_speed; int host_div; /* State */ - float stme; // sample-time + double stme; // sample-time int32_t step; // current step uint8_t chn; // midi channel uint8_t notes[N_NOTES]; - uint8_t active[127]; + uint8_t active[128]; bool rolling; } StepSeq; @@ -173,7 +173,7 @@ && speed && speed->type == uris->atom_Float) { float _bpb = ((LV2_Atom_Float*)bpb)->body; - long int _bar = ((LV2_Atom_Long*)bar)->body; + int64_t _bar = ((LV2_Atom_Long*)bar)->body; float _beat = ((LV2_Atom_Float*)beat)->body; self->host_div = ((LV2_Atom_Int*)bunit)->body; @@ -248,7 +248,8 @@ forge_midimessage (self, ts, msg, 3); } -float parse_division (float div) { +static float +parse_division (float div) { int d = rintf (div); switch (d) { case 0: return 0.125f; @@ -288,7 +289,6 @@ if (NSET (n, step) && ACTV (note) && self->drum_mode) { /* retrigger */ - const uint8_t note = NOTE (n); if (ts > 0) { forge_note_event (self, ts - 1, note, 0); forge_note_event (self, ts, note, NVEL(n, step)); @@ -315,7 +315,6 @@ } } if (retriger) { - const uint8_t note = NOTE (n); if (ts > 0) { forge_note_event (self, ts - 1, note, 0); forge_note_event (self, ts, note, NVEL(n, step)); @@ -328,7 +327,8 @@ } } -float calc_next_step (StepSeq* self) { +static double +calc_next_step (StepSeq* self) { const bool eighth = true; // self->div == 0.5; const uint32_t step = self->step; if (eighth && (step & 1) == 0) { @@ -336,9 +336,9 @@ * add 1/3 -> "2:1 medium swing -- triplet quarter note + triplet eighth" * add 1/2 -> "3:1 hard swing -- dotted eighth note + sixteenth note" */ - return (step + 1) * self->sps + self->swing * self->sps; + return (step + 1.0) * self->sps + self->swing * self->sps; } else { - return (step + 1) * self->sps; + return (step + 1.0) * self->sps; } } @@ -377,7 +377,7 @@ self->sample_rate = rate; self->bpm = 120.f; self->div = .5f; - self->sps = self->sample_rate * 60.f * self->div / self->bpm; + self->sps = self->sample_rate * 60.0 * self->div / self->bpm; self->step = N_STEPS - 1; self->stme = N_STEPS * self->sps; @@ -468,7 +468,7 @@ if (self->notes[n] == note) { continue; } - if (ACTV (NOTE (n))) { + if (NOTE (n) < 128 && ACTV (NOTE (n))) { forge_note_event (self, 0, NOTE (n), 0); } bool in_use = false; @@ -505,7 +505,7 @@ *self->p_hostbpm = self->host_bpm; if (self->host_speed <= 0) { /* keep track of host position.. */ - self->bar_beats += n_samples * self->host_bpm * self->host_speed / (60.f * self->sample_rate); + self->bar_beats += (double)n_samples * self->host_bpm * self->host_speed / (60.0 * self->sample_rate); /* report only, don't modify state (stme & step need to remain in sync) */ *self->p_step = 1 + ((int)floor (self->bar_beats / self->div) % N_STEPS); @@ -524,18 +524,18 @@ const float division = parse_division (*self->p_div); if (bpm != self->bpm || division != self->div) { - const float old = self->sps; + const double old = self->sps; self->bpm = bpm; self->div = division; - self->sps = self->sample_rate * 60.f * self->div / self->bpm; + self->sps = self->sample_rate * 60.0 * self->div / self->bpm; if (self->sps < 64) { self->sps = 64; } if (self->sps > 60 * self->sample_rate) { self->sps = 60 * self->sample_rate; } self->stme = self->stme * self->sps / old; } - const float sps = self->sps; - const float loop_duration = N_STEPS * sps; - float stme = self->stme; + const double sps = self->sps; + const double loop_duration = N_STEPS * sps; + double stme = self->stme; self->drum_mode = *self->p_drum > 0; self->swing = *self->p_swing; @@ -547,12 +547,12 @@ } if (self->host_info && *self->p_sync > 0) { - float hp = self->bar_beats / self->div; + double hp = self->bar_beats / self->div; - stme = fmodf (hp, N_STEPS) * sps; + stme = fmod (hp, N_STEPS) * sps; /* handle seek - jumps to step if needed */ - const float ns = calc_next_step (self); + const double ns = calc_next_step (self); if (ns < stme || ns - stme > 1.5 /* max swing*/ * sps || !self->rolling) { if (floor (hp) == hp) { @@ -570,7 +570,7 @@ } } - float next_step = calc_next_step (self); + double next_step = calc_next_step (self); uint32_t remain = n_samples; if (*self->p_panic > 0) { @@ -608,10 +608,34 @@ self->stme = stme + remain; self->rolling = true; + /* crude sort Atom sequence by event-time + * (in drum-mode or with re-trigger events may + * not be sequential in time) + */ + LV2_ATOM_SEQUENCE_FOREACH (self->midiout, ev1) { + LV2_ATOM_SEQUENCE_FOREACH (self->midiout, ev2) { + if (ev2 <= ev1) { + continue; + } + if (ev1->time.frames > ev2->time.frames) { + // swap events + assert (ev1->body.size == ev2->body.size); + assert (ev1->body.size == 3); + int64_t tme = ev1->time.frames; + uint8_t body[3]; + memcpy (body, (const uint8_t*)(ev1 + 1), 3); + memcpy ((uint8_t*)(ev1 + 1), (const uint8_t*)(ev2 + 1), 3); + ev1->time.frames = ev2->time.frames; + memcpy ((uint8_t*)(ev2 + 1), body, 3); + ev2->time.frames = tme; + } + } + } + *self->p_step = 1 + (self->step % N_STEPS); if (self->host_info) { /* keep track of host position.. */ - self->bar_beats += n_samples * self->host_bpm * self->host_speed / (60.f * self->sample_rate); + self->bar_beats += n_samples * self->host_bpm * self->host_speed / (60.0 * self->sample_rate); } } diff -Nru x42-plugins-20170428/stepseq.lv2/x42-stepseq.1 x42-plugins-20190714/stepseq.lv2/x42-stepseq.1 --- x42-plugins-20170428/stepseq.lv2/x42-stepseq.1 2017-04-27 23:58:25.000000000 +0000 +++ x42-plugins-20190714/stepseq.lv2/x42-stepseq.1 2019-07-14 19:39:36.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH X42-STEPSEQ "1" "April 2017" "x42-stepseq version 0.4.1" "User Commands" +.TH X42-STEPSEQ "1" "July 2019" "x42-stepseq version 0.5.5" "User Commands" .SH NAME x42-stepseq \- x42 Step Sequencer .SH SYNOPSIS @@ -33,6 +33,9 @@ Set the JACK client name (defaults to plugin\-name) .TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP \fB\-O\fR , \fB\-\-osc\fR Listen for OSC messages on the given UDP port .TP @@ -51,7 +54,7 @@ See also: Website: .SH COPYRIGHT -Copyright \(co GPL 2013\-2015 Robin Gareus +Copyright \(co GPL 2013\-2019 Robin Gareus .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stereoroute.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stereoroute.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stereoroute.lv2/img/x42-stereoroute.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stereoroute.lv2/img/x42-stereoroute.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/stereoroute.lv2/img/x42-stereoroute.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/stereoroute.lv2/img/x42-stereoroute.png differ diff -Nru x42-plugins-20170428/stereoroute.lv2/Makefile x42-plugins-20190714/stereoroute.lv2/Makefile --- x42-plugins-20170428/stereoroute.lv2/Makefile 2016-06-20 16:29:18.000000000 +0000 +++ x42-plugins-20190714/stereoroute.lv2/Makefile 2019-01-23 22:37:34.000000000 +0000 @@ -1,20 +1,16 @@ #!/usr/bin/make -f - -# these can be overridden using make variables. e.g. -# make CFLAGS=-O2 -# -OTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib -STRIP ?= strip -STRIPFLAGS=-s +PKG_CONFIG?=pkg-config +STRIP?=strip +STRIPFLAGS?=-s stereoroute_VERSION?=$(shell git describe --tags HEAD 2>/dev/null | sed 's/-g.*$$//;s/^v//' || echo "LV2") ############################################################################### -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm LV2NAME=stereoroute BUNDLE=stereoroute.lv2 @@ -40,6 +36,8 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) @@ -50,12 +48,11 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/stereoroute.lv2/stereoroute.c x42-plugins-20190714/stereoroute.lv2/stereoroute.c --- x42-plugins-20170428/stereoroute.lv2/stereoroute.c 2016-06-20 16:29:18.000000000 +0000 +++ x42-plugins-20190714/stereoroute.lv2/stereoroute.c 2019-01-23 22:37:34.000000000 +0000 @@ -99,6 +99,22 @@ memcpy (self->output[1], self->input[1], n_samples * sizeof(float)); } break; + case 7: + // left/right -> mid/side + for (uint32_t s = 0; s < n_samples; ++s) { + const float tmpS = self->input[0][s] - self->input[1][s]; + self->output[0][s] = .5 * (self->input[0][s] + self->input[1][s]); + self->output[1][s] = .5 * tmpS; + } + break; + case 8: + // mid/side <> left/right + for (uint32_t s = 0; s < n_samples; ++s) { + const float tmpS = self->input[0][s] - self->input[1][s]; + self->output[0][s] = (self->input[0][s] + self->input[1][s]); + self->output[1][s] = tmpS; + } + break; } } diff -Nru x42-plugins-20170428/stereoroute.lv2/stereoroute.ttl.in x42-plugins-20190714/stereoroute.lv2/stereoroute.ttl.in --- x42-plugins-20170428/stereoroute.lv2/stereoroute.ttl.in 2016-06-20 16:29:18.000000000 +0000 +++ x42-plugins-20190714/stereoroute.lv2/stereoroute.ttl.in 2019-01-23 22:37:34.000000000 +0000 @@ -48,8 +48,14 @@ rdfs:label "L->R, R->L (Swap Channels)" ; rdf:value 5 ] , [ - rdfs:label "L->L, R->R (Straight)" ; + rdfs:label "L->L, R->R (Straight Bypass)" ; rdf:value 6 + ] , [ + rdfs:label "L+R/2, L-R/2 (to Mid/Side)" ; + rdf:value 7 + ] , [ + rdfs:label "L+R, L-R (from Mid/Side)" ; + rdf:value 8 ] ] , [ a lv2:AudioPort , Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/testsignal.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/testsignal.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/testsignal.lv2/img/x42-testsignal.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/testsignal.lv2/img/x42-testsignal.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/testsignal.lv2/img/x42-testsignal.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/testsignal.lv2/img/x42-testsignal.png differ diff -Nru x42-plugins-20170428/testsignal.lv2/Makefile x42-plugins-20190714/testsignal.lv2/Makefile --- x42-plugins-20170428/testsignal.lv2/Makefile 2016-11-04 22:53:32.000000000 +0000 +++ x42-plugins-20190714/testsignal.lv2/Makefile 2019-05-04 23:03:39.000000000 +0000 @@ -1,8 +1,9 @@ #!/usr/bin/make -f -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s @@ -36,6 +37,8 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) @@ -46,12 +49,11 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/testsignal.lv2/testsignal.c x42-plugins-20190714/testsignal.lv2/testsignal.c --- x42-plugins-20170428/testsignal.lv2/testsignal.c 2016-11-04 22:53:32.000000000 +0000 +++ x42-plugins-20190714/testsignal.lv2/testsignal.c 2019-05-04 23:03:39.000000000 +0000 @@ -1,6 +1,6 @@ /* testsignal -- LV2 test-tone generator * - * Copyright (C) 2015 Robin Gareus + * Copyright (C) 2015,2018 Robin Gareus * * 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 @@ -32,6 +32,13 @@ #define TST_URI "http://gareus.org/oss/lv2/testsignal" +#if INTPTR_MAX == INT64_MAX +#warning PCG-random +#define PCGRANDOM +#else +#warning LCG-random +#endif + typedef enum { TST_MODE = 0, TST_REFLEV = 1, @@ -66,7 +73,12 @@ uint32_t swp_cnt; // pseudo-random number state +#ifdef PCGRANDOM + uint64_t rseed; +#else uint32_t rseed; +#endif + bool g_pass; float g_rn1; float b0, b1, b2, b3, b4, b5, b6; // pink noise @@ -79,6 +91,13 @@ static inline uint32_t rand_int (TestSignal *self) { +#ifdef PCGRANDOM + uint64_t oldstate = self->rseed; + self->rseed = oldstate * 6364136223846793005ULL + 1; + uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; + uint32_t rot = oldstate >> 59u; + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +#else // 31bit Park-Miller-Carta Pseudo-Random Number Generator // http://www.firstpr.com.au/dsp/rand31/ uint32_t hi, lo; @@ -89,12 +108,17 @@ lo += hi >> 15; lo = (lo & 0x7fffffff) + (lo >> 31); return (self->rseed = lo); +#endif } static inline float rand_float (TestSignal *self) { +#ifdef PCGRANDOM + return (rand_int (self) / 2147483648.f) - 1.f; +#else return (rand_int (self) / 1073741824.f) - 1.f; +#endif } static float @@ -134,25 +158,25 @@ const float level = self->lvl_coeff; for (uint32_t i = 0 ; i < n_samples; ++i) { - out[i] = level * sinf (2.0f * M_PI * phase); + out[i] = level * sinf (phase); phase += phase_inc; } - self->phase = fmodf (phase, 1.0); + self->phase = fmodf (phase, 2.0 * M_PI); } static void gen_square (TestSignal *self, uint32_t n_samples) { float *out = self->output; - float phase = self->phase; + double phase = self->phase; const float phase_inc = self->phase_inc; const float level = self->lvl_coeff; for (uint32_t i = 0 ; i < n_samples; ++i) { - out[i] = sinf (2.0f * M_PI * phase) > 0 ? level : - level; + out[i] = sinf (phase) >= 0 ? level : - level; phase += phase_inc; } - self->phase = fmodf (phase, 1.0); + self->phase = fmod (phase, 2.0 * M_PI); } static void @@ -237,8 +261,10 @@ { float *out = self->output; uint32_t k_cnt = self->k_cnt % period; + const float level = self->lvl_coeff; for (uint32_t i = 0 ; i < n_samples; ++i) { out[i] = -1.f + 2.f * k_cnt / (float) period; + out[i] *= level; k_cnt = (k_cnt + 1) % period; } self->k_cnt = k_cnt; @@ -249,8 +275,10 @@ { float *out = self->output; uint32_t k_cnt = self->k_cnt % period; + const float level = self->lvl_coeff; for (uint32_t i = 0 ; i < n_samples; ++i) { out[i] = -1.f + 2.f * fabsf (1 - 2.f * k_cnt / (float) period); + out[i] *= level; k_cnt = (k_cnt + 1) % period; } self->k_cnt = k_cnt; @@ -265,10 +293,11 @@ const uint32_t swp_period = self->swp_period; const double swp_log_a = self->swp_log_a; const double swp_log_b = self->swp_log_b; + const float level = self->lvl_coeff; for (uint32_t i = 0 ; i < n_samples; ++i) { const double phase = swp_log_a * exp (swp_log_b * swp_cnt) - swp_log_a; - out[i] = .12589f * sin (2. * M_PI * (phase - floor (phase))); + out[i] = level * sin (2. * M_PI * (phase - floor (phase))); swp_cnt = (swp_cnt + 1) % swp_period; } self->swp_cnt = swp_cnt; @@ -288,7 +317,7 @@ TestSignal* self = (TestSignal*)calloc (1, sizeof (TestSignal)); - self->phase_inc = 1000 / rate; + self->phase_inc = 2 * M_PI * 1000 / rate; self->k_period100 = rate / 100; self->k_period1 = rate; self->k_period5s = rate * 5; @@ -300,8 +329,12 @@ self->swp_log_b = log (f_max / f_min) / self->swp_period; self->swp_log_a = f_min / (self->swp_log_b * rate); - self->rseed = time (NULL) % UINT_MAX; +#ifdef PCGRANDOM + self->rseed = time (NULL) ^ (intptr_t)self; +#else + self->rseed = (time (NULL) + (intptr_t)self) % INT_MAX; if (self->rseed == 0) self->rseed = 1; +#endif return (LV2_Handle)self; } @@ -360,7 +393,7 @@ free (instance); } -const void* +static const void* extension_data (const char* uri) { return NULL; diff -Nru x42-plugins-20170428/tuna.lv2/lv2ttl/tuna.lv2.ttl.in x42-plugins-20190714/tuna.lv2/lv2ttl/tuna.lv2.ttl.in --- x42-plugins-20170428/tuna.lv2/lv2ttl/tuna.lv2.ttl.in 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/lv2ttl/tuna.lv2.ttl.in 2019-07-14 19:39:45.000000000 +0000 @@ -9,7 +9,8 @@ @UITTL@ @MODBRAND@ @MODLABEL@ - lv2:optionalFeature lv2:hardRTCapable ; + lv2:optionalFeature lv2:hardRTCapable, idpy:queue_draw ; + lv2:extensionData idpy:interface ; lv2:requiredFeature urid:map ; @SIGNATURE@ lv2:port diff -Nru x42-plugins-20170428/tuna.lv2/lv2ttl/tuna.ttl.in x42-plugins-20190714/tuna.lv2/lv2ttl/tuna.ttl.in --- x42-plugins-20170428/tuna.lv2/lv2ttl/tuna.ttl.in 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/lv2ttl/tuna.ttl.in 2019-07-14 19:39:45.000000000 +0000 @@ -1,6 +1,7 @@ @prefix atom: . @prefix doap: . @prefix foaf: . +@prefix idpy: . @prefix kx: . @prefix lv2: . @prefix mod: . @@ -12,6 +13,9 @@ @prefix units: . @prefix urid: . +idpy:queue_draw a lv2:Feature . +idpy:interface a lv2:ExtensionData . + @prefix @LV2NAME@: . diff -Nru x42-plugins-20170428/tuna.lv2/Makefile x42-plugins-20190714/tuna.lv2/Makefile --- x42-plugins-20170428/tuna.lv2/Makefile 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/Makefile 2019-07-14 19:39:45.000000000 +0000 @@ -12,7 +12,9 @@ OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG CFLAGS ?= -Wall -g -Wno-unused-function -STRIP ?= strip + +PKG_CONFIG?=pkg-config +STRIP?= strip BUILDOPENGL?=yes BUILDJACKAPP?=yes @@ -68,7 +70,7 @@ PUGL_SRC=$(RW)pugl/pugl_x11.c PKG_GL_LIBS=glu gl GLUILIBS=-lX11 - GLUICFLAGS+=`pkg-config --cflags glu` + GLUICFLAGS+=`$(PKG_CONFIG) --cflags glu` STRIPFLAGS= -s EXTENDED_RE=-r endif @@ -116,26 +118,26 @@ ############################################################################### # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -ifeq ($(shell pkg-config --exists fftw3f || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f || echo no), no) $(error "fftw3f library was not found") endif -ifeq ($(shell pkg-config --atleast-version=1.6.0 lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.6.0 lv2 || echo no), no) $(error "LV2 SDK needs to be version 1.6.0 or later") endif ifneq ($(BUILDOPENGL)$(BUILDJACKAPP), nono) - ifeq ($(shell pkg-config --exists pango cairo $(PKG_GL_LIBS) || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists pango cairo $(PKG_GL_LIBS) || echo no), no) $(error "This plugin requires cairo pango $(PKG_GL_LIBS)") endif endif ifneq ($(BUILDJACKAPP), no) - ifeq ($(shell pkg-config --exists jack || echo no), no) + ifeq ($(shell $(PKG_CONFIG) --exists jack || echo no), no) $(warning *** libjack from http://jackaudio.org is required) $(error Please install libjack-dev or libjack-jackd2-dev) endif @@ -143,7 +145,7 @@ endif # check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank -ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes) +ifeq ($(shell $(PKG_CONFIG) --atleast-version=1.8.1 lv2 && echo yes), yes) override CFLAGS += -DHAVE_LV2_1_8 endif @@ -171,17 +173,24 @@ # add library dependent flags and libs override CFLAGS +=-g $(OPTIMIZATIONS) -DVERSION="\"$(tuna_VERSION)\"" -override CFLAGS += `pkg-config --cflags lv2 fftw3f` +override CFLAGS += `$(PKG_CONFIG) --cflags lv2 fftw3f` ifeq ($(XWIN),) override CFLAGS += -fPIC -fvisibility=hidden else override CFLAGS += -DPTW32_STATIC_LIB endif -override LOADLIBES += `pkg-config --libs lv2 fftw3f` +override LOADLIBES += `$(PKG_CONFIG) --libs lv2 fftw3f` +ifneq ($(INLINEDISPLAY),no) +override CFLAGS += `$(PKG_CONFIG) --cflags cairo pangocairo pango` -I$(RW) -DDISPLAY_INTERFACE +override LOADLIBES += `$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pangocairo pango` + ifneq ($(XWIN),) + override LOADLIBES += -lpthread -lusp10 + endif +endif -GLUICFLAGS+=`pkg-config --cflags cairo pango` -GLUILIBS+=`pkg-config $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` +GLUICFLAGS+=`$(PKG_CONFIG) --cflags cairo pango` +GLUILIBS+=`$(PKG_CONFIG) $(PKG_UI_FLAGS) --libs cairo pango pangocairo $(PKG_GL_LIBS)` ifneq ($(XWIN),) GLUILIBS+=-lpthread -lusp10 @@ -196,14 +205,14 @@ endif ifneq ($(LIC_CFLAGS),) - SIGNATURE=lv2:extensionData \\; + LV2SIGN=lv2:extensionData \\; endif ROBGL+= Makefile JACKCFLAGS=-I. $(CXXFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo fftw3f $(PKG_GL_LIBS)` -JACKLIBS=-lm $(GLUILIBS) $(LIC_LOADLIBES) $(LOADLIBES) +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo fftw3f $(PKG_GL_LIBS)` +JACKLIBS=-lm $(GLUILIBS) $(LOADLIBES) ############################################################################### # build target definitions @@ -248,10 +257,10 @@ sed "s/@LV2NAME@/$(LV2NAME)/g;s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/;" \ lv2ttl/$(LV2NAME).gui.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl endif - sed "s/@INSTANCE@/${ONE}/g;s/@LV2NAME@/$(LV2NAME)/g;s/@NAME_SUFFIX@//g;s/@UITTL@/$(UITTL)/g;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@SIGNATURE@/$(SIGNATURE)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ + sed "s/@INSTANCE@/${ONE}/g;s/@LV2NAME@/$(LV2NAME)/g;s/@NAME_SUFFIX@//g;s/@UITTL@/$(UITTL)/g;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ lv2ttl/$(LV2NAME).lv2.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl ifneq ($(BUILDOPENGL), no) - sed "s/@INSTANCE@/two/g;s/@LV2NAME@/$(LV2NAME)/g;s/@NAME_SUFFIX@/[Spectrum]/g;s/@UITTL@/$(UITTL)/g;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@SIGNATURE@/$(SIGNATURE)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ + sed "s/@INSTANCE@/two/g;s/@LV2NAME@/$(LV2NAME)/g;s/@NAME_SUFFIX@/[Spectrum]/g;s/@UITTL@/$(UITTL)/g;s/@MODBRAND@/$(MODBRAND)/;s/@MODLABEL@/$(MODLABEL)/;s/@SIGNATURE@/$(LV2SIGN)/;s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \ lv2ttl/$(LV2NAME).lv2.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl endif @@ -272,7 +281,7 @@ $(APPBLD)x42-tuna-fft$(EXE_EXT) JACKCFLAGS=-I. $(CFLAGS) $(CXXFLAGS) $(LIC_CFLAGS) -JACKCFLAGS+=`pkg-config --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` +JACKCFLAGS+=`$(PKG_CONFIG) --cflags jack lv2 pango pangocairo $(PKG_GL_LIBS)` JACKLIBS=-lm $(LOADLIBES) $(GLUILIBS) $(LIC_LOADLIBES) $(eval x42_tuna_JACKSRC = src/tuna.c) Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/tuna.lv2/modgui/box.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/tuna.lv2/modgui/box.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/tuna.lv2/modgui/footswitch.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/tuna.lv2/modgui/footswitch.png differ diff -Nru x42-plugins-20170428/tuna.lv2/modgui/icon-tuna.html x42-plugins-20190714/tuna.lv2/modgui/icon-tuna.html --- x42-plugins-20170428/tuna.lv2/modgui/icon-tuna.html 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/modgui/icon-tuna.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -
-
- - -

x42 Tuna

- -
-
- Tuning (A4) -
-
-
- -
-
-

A

-

4

-
-
@ 440.10Hz
-
T: 110.00 Hz
-
-
-
-

>>>>>>

-
-
-

+00.00 ct

-

0000.00 Hz

-
-
- -
-
- -
- {{#effect.ports.audio.input}} -
-
-
- {{/effect.ports.audio.input}} -
-
- {{#effect.ports.audio.output}} -
-
-
- {{/effect.ports.audio.output}} -
-
Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/tuna.lv2/modgui/knob.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/tuna.lv2/modgui/knob.png differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/tuna.lv2/modgui/screenshot-tuna.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/tuna.lv2/modgui/screenshot-tuna.png differ diff -Nru x42-plugins-20170428/tuna.lv2/modgui/script-tuna.js x42-plugins-20190714/tuna.lv2/modgui/script-tuna.js --- x42-plugins-20170428/tuna.lv2/modgui/script-tuna.js 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/modgui/script-tuna.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,183 +0,0 @@ -function (event) { - - function notename (note) { - switch (note) { - case 0: return "C"; - case 1: return "C#"; - case 2: return "D"; - case 3: return "D#"; - case 4: return "E"; - case 5: return "F"; - case 6: return "F#"; - case 7: return "G"; - case 8: return "G#"; - case 9: return "A"; - case 10: return "A#"; - case 11: return "B"; - default: break; - } - return "?"; - } - - function set_target_freq (ds) { - var freq; - if (ds['mode'] > 0) { - freq = ds['mode']; - } else { - var note = ds['note'] + (ds['octave'] + 1) * 12; - freq = ds['tuning'] * Math.pow(2.0, (note - 69.0) / 12.0); - } - event.icon.find ('[mod-role=target]').text (freq.toFixed(2) + " Hz"); - } - - function cent_visualization (ds) { - var dpy_state; - var cent = ds['cent']; - if (cent <= -50 || cent >= 50) { - dpy_state = -5; - } - else if (cent < -20) { - dpy_state = -4; - } - else if (cent < -10) { - dpy_state = -3; - } - else if (cent < -5) { - dpy_state = -2; - } - else if (cent < -2) { - dpy_state = -1; - } - else if (cent <= 2) { - dpy_state = 0; - } - else if (cent <= 5) { - dpy_state = 1; - } - else if (cent <= 10) { - dpy_state = 2; - } - else if (cent <= 20) { - dpy_state = 3; - } - else { - dpy_state = 4; - } - - if (dpy_state == ds['dpy_state']) { - return; - } - ds['dpy_state'] = dpy_state; - - var dpy = event.icon.find ('[mod-role=tuner-display]'); - var adj; - switch (dpy_state) { - case -4: - adj = ">>>>>>>>"; - break; - case -3: - adj = ">>>>>>"; - break; - case -2: - adj = ">>>>"; - break; - case -1: - adj = ">>"; - break; - case -0: - adj = ">|<"; - break; - case 1: - adj = "<<"; - break; - case 2: - adj = "<<<<"; - break; - case 3: - adj = "<<<<<<"; - break; - case 4: - adj = "<<<<<<<<"; - break; - default: - adj = "---"; - break; - } - if (dpy_state == 0) { - dpy.addClass ('good'); - } else { - dpy.removeClass ('good'); - } - event.icon.find ('[mod-role=adjust]').text (adj); - } - - function handle_event (symbol, value) { - var dpy = event.icon.find ('[mod-role=tuner-display]'); - var ds = dpy.data ('xModPorts'); - switch (symbol) { - case 'mode': - case 'tuning': - ds[symbol] = value; - dpy.data ('xModPorts', ds); - set_target_freq (ds); - break; - case 'freq_out': - if (value < 10) { - dpy.addClass ('nosignal'); - event.icon.find ('[mod-role=freq]').text ("----- Hz"); - event.icon.find ('[mod-role=adjust]').text ("---"); - } else { - dpy.removeClass ('nosignal'); - event.icon.find ('[mod-role=freq]').text (value.toFixed(1) + " Hz"); - } - break; - case 'octave': - ds[symbol] = value; - dpy.data ('xModPorts', ds); - event.icon.find ('[mod-role=octave]').text (value.toFixed(0) + ""); - set_target_freq (ds); - break; - case 'note': - ds[symbol] = value; - dpy.data ('xModPorts', ds); - event.icon.find ('[mod-role=note]').text (notename (Math.trunc(value))); - set_target_freq (ds); - break; - case 'cent': - ds[symbol] = value; - dpy.data ('xModPorts', ds); - event.icon.find ('[mod-role=cent]').text (value.toFixed(2) + " ct"); - cent_visualization (ds); - break; - case 'rms': - break; - case 'accuracy': - break; - case 'strobetoui': - break; - default: - break; - } - } - - if (event.type == 'start') { - var dpy = event.icon.find ('[mod-role=tuner-display]'); - var ds = {}; - ds['octave'] = 3; - ds['note'] = 8; - ds['cent'] = 0; - ds['mode'] = 0; - ds['dpy_state'] = -10; - ds['freq_out'] = 0; - - dpy.data ('xModPorts', ds); - - var ports = event.ports; - for (var p in ports) { - handle_event (ports[p].symbol, ports[p].value); - } - } - else if (event.type == 'change') { - handle_event (event.symbol, event.value); - } -} diff -Nru x42-plugins-20170428/tuna.lv2/modgui/stylesheet-tuna.css x42-plugins-20190714/tuna.lv2/modgui/stylesheet-tuna.css --- x42-plugins-20170428/tuna.lv2/modgui/stylesheet-tuna.css 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/modgui/stylesheet-tuna.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -@import url(/fonts/nexa/stylesheet.css); -@import url(/fonts/questrial/stylesheet.css); - -/* = CONTAINER -================================================ */ -.x42-tuna{{{cns}}} { - background-image:url(/resources/box.png{{{ns}}}); - background-position:center center; - background-repeat:no-repeat; - background-size:364px 431px; - height:431px; - position:absolute; - width:364px; - border-radius: 21px; - - line-height:1.429; - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - - border-color:white; - color:white; -} - -/* = Labels -================================================ */ -.x42-tuna{{{cns}}} .x42-brand { - left:0; - position:absolute; - right:0; - text-align:center; - top:180px; -} - -.x42-tuna{{{cns}}} .x42-brand h1 { - border-radius:12px; - border-style:solid; - border-width:4px; - display:inline-block; - font-family:"Nexa"; - font-size:32px; - padding:3px 9px 0; -} - -.x42-tuna{{{cns}}} .x42-plugin-name { - left:30px; - overflow:hidden; - position:absolute; - right:30px; - text-align:center; - bottom:35px; -} - -.x42-tuna{{{cns}}} .x42-plugin-name h1 { - font-family:"Questrial"; - font-size:21px; - line-height:1; -} - -/* = LIGHT ON/OFF -================================================ */ -.x42-tuna{{{cns}}} .mod-light { - background-position:center center; - background-repeat:no-repeat; - height:32px; - left:10px; - position:absolute; - right:10px; - bottom:140px; -} - -/* = FOOTSWITCH -================================================ */ -.x42-tuna{{{cns}}} .mod-footswitch { - background-image:url(/resources/footswitch.png{{{ns}}}); - background-position:bottom center; - background-repeat:no-repeat; - background-size:auto 132px; - bottom: 75px; - cursor:pointer; - height:66px; - left: 20px; - margin: auto; - position:absolute; - right: 20px; - width: 66px; -} - -.x42-tuna{{{cns}}} .mod-tuner-display { - margin:0; - position:relative; - background-color:#ccaa66; - margin: 0 30px; - box-shadow: 2px 2px 2px 0px #000 inset, -1px -1px 1px 1px #888 inset; - color:black; -} - -.x42-tuna{{{cns}}} .mod-tuner-display.good { - background-color:#ccff66; -} - -.x42-tuna{{{cns}}} .mod-tuner-display.nosignal.good, -.x42-tuna{{{cns}}} .mod-tuner-display.nosignal { - background-color:#776633; -} - -.x42-tuna{{{cns}}} .tuner-freq-info { - position:absolute; - right:10px; - top:6px; -} - -.x42-tuna{{{cns}}} .mod-display-group { - margin:0; - position:relative; - text-align:center; - z-index:30; -} - -.x42-tuna{{{cns}}} .mod-display-group h2, -.x42-tuna{{{cns}}} .mod-display-group h3, -.x42-tuna{{{cns}}} .mod-display-group h4 -{ - padding:0; - display:inline-block; - line-height:1em; -} - -.x42-tuna{{{cns}}} .mod-display-group h2 { - font-size:32px; - margin:10px 0 5px 0; - width:64px; -} - -.x42-tuna{{{cns}}} .mod-display-group h3 { - font-size:24px; - margin:5px 6px 10px 6px; - text-align:right; - width:135px; -} - -.x42-tuna{{{cns}}} .mod-display-group h4 { - font-size:24px; - margin:0; - width:160px; -} - -/* = KNOBS -================================================ */ -.x42-tuna{{{cns}}} .mod-control-group { - margin:25px 10px 10px 10px !important; - position:relative; - text-align:center; - z-index:30; -} - -.x42-tuna{{{cns}}} .mod-control-group .mod-knob { - overflow:hidden; - position:relative; - display:inline-block; - height:80px; - margin: 0 14px; -} - -.x42-tuna{{{cns}}} .mod-control-group .mod-knob > span.mod-knob-title { - bottom:0px; - display:block; - font-size:11px; - font-weight:bold; - height:12px; - left:0; - line-height:1; - margin:0; - overflow:hidden; - padding:0; - position:absolute; - right:0; - text-transform:uppercase; -} - -.x42-tuna{{{cns}}} .mod-control-group .mod-knob .mod-knob-image { - background-image:url(/resources/knob.png{{{ns}}}); - background-repeat:no-repeat; - background-size:auto 60px; - height:60px; - width:60px; - margin:0 auto; -} - -.x42-tuna{{{cns}}} .bottom-group { - margin:10px auto 0 auto; - left:10px; - right:10px; - position:absolute; - bottom:70px; -} - - -/* = ENUMERATED LIST -================================================ */ -.x42-tuna{{{cns}}} .mod-enumerated-group { - height:31px; - margin:20px auto 0 !important; - position:relative; - width:190px; - z-index:35; -} - -.x42-tuna{{{cns}}} .mod-enumerated { - background-image:url(/resources/dropdown-arrow-white.png{{{ns}}}); - background-position:right center; - background-repeat:no-repeat; - font-size:11px; - font-weight:bold; - left:0; - line-height:2; - overflow:hidden; - position:absolute; - right:0; - text-align:center; -} - -.x42-tuna{{{cns}}} .mod-enumerated .mod-enumerated-selected { - background-color:rgba(0,0,0,.3); - box-shadow:inset 0 0 4px rgba(0,0,0,.3); - border-radius:4px; - padding:3px 9px; - border-radius:4px 4px 0 0; -} - -.x42-tuna{{{cns}}} .mod-enumerated .mod-enumerated-list { - background-color:rgba(0,0,0,.9); - color:#fff; - display:none; - height:115px; - overflow:auto; - position:relative; -} - -.x42-tuna{{{cns}}} .mod-enumerated .mod-enumerated-list > div { - padding:3px 9px; -} - -.x42-tuna{{{cns}}} .mod-enumerated .mod-enumerated-list > div:hover { - background-color:rgba(255,255,255,.2); - cursor:pointer; -} Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/tuna.lv2/modgui/thumbnail-tuna.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/tuna.lv2/modgui/thumbnail-tuna.png differ diff -Nru x42-plugins-20170428/tuna.lv2/src/fft.c x42-plugins-20190714/tuna.lv2/src/fft.c --- x42-plugins-20170428/tuna.lv2/src/fft.c 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/src/fft.c 2019-07-14 19:39:45.000000000 +0000 @@ -1,5 +1,5 @@ /* FFT analysis - spectrogram - * Copyright (C) 2013 Robin Gareus + * Copyright (C) 2013, 2019 Robin Gareus * * 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 @@ -16,88 +16,169 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include #include #include -#include -#include #ifndef MIN -#define MIN(A,B) ( (A) < (B) ? (A) : (B) ) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) #endif static pthread_mutex_t fftw_planner_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int instance_count = 0; + +typedef enum { + W_HANN = 0, + W_HAMMMIN, + W_NUTTALL, + W_BLACKMAN_NUTTALL, + W_BLACKMAN_HARRIS, + W_FLAT_TOP +} window_t; /****************************************************************************** * internal FFT abstraction */ struct FFTAnalysis { - uint32_t window_size; - uint32_t data_size; - double rate; - double freq_per_bin; - double phasediff_step; - float *hann_window; - float *fft_in; - float *fft_out; - float *power; - float *phase; - float *phase_h; + uint32_t window_size; + window_t window_type; + uint32_t data_size; + double rate; + double freq_per_bin; + double phasediff_step; + float* window; + float* fft_in; + float* fft_out; + float* power; + float* phase; + float* phase_h; fftwf_plan fftplan; - float *ringbuf; + float* ringbuf; uint32_t rboff; uint32_t smps; uint32_t sps; uint32_t step; - double phasediff_bin; + double phasediff_bin; }; -/****************************************************************************** - * internal private functions +/* **************************************************************************** + * windows */ -static float * ft_hann_window(struct FFTAnalysis *ft) { - if (ft->hann_window) return ft->hann_window; - ft->hann_window = (float *) malloc(sizeof(float) * ft->window_size); +static double +ft_hannhamm (float* window, uint32_t n, double a, double b) +{ double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + for (uint32_t i = 0; i < n; ++i) { + window[i] = a - b * cos (c * i); + sum += window[i]; + } + return sum; +} - for (uint32_t i=0; i < ft->window_size; i++) { - ft->hann_window[i] = 0.5f - (0.5f * (float) cos(2.0f * M_PI * (float)i / (float)(ft->window_size))); - sum += ft->hann_window[i]; +static double +ft_bnh (float* window, uint32_t n, double a0, double a1, double a2, double a3) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i); + sum += window[i]; } + return sum; +} + +static double +ft_flattop (float* window, uint32_t n) +{ + double sum = 0.0; + const double c = 2.0 * M_PI / (n - 1.0); + const double c2 = 2.0 * c; + const double c3 = 3.0 * c; + const double c4 = 4.0 * c; + + const double a0 = 1.0; + const double a1 = 1.93; + const double a2 = 1.29; + const double a3 = 0.388; + const double a4 = 0.028; + + for (uint32_t i = 0; i < n; ++i) { + window[i] = a0 - a1 * cos(c * i) + a2 * cos(c2 * i) - a3 * cos(c3 * i) + a4 * cos(c4 * i); + sum += window[i]; + } + return sum; +} + + +/* **************************************************************************** + * internal private functions + */ +static float* +ft_gen_window (struct FFTAnalysis* ft) +{ + if (ft->window) { + return ft->window; + } + + ft->window = (float*)malloc (sizeof (float) * ft->window_size); + double sum = .0; + + /* https://en.wikipedia.org/wiki/Window_function */ + switch (ft->window_type) { + default: + case W_HANN: + sum = ft_hannhamm (ft->window, ft->window_size, .5, .5); + break; + case W_HAMMMIN: + sum = ft_hannhamm (ft->window, ft->window_size, .54, .46); + break; + case W_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .355768, .487396, .144232, .012604); + break; + case W_BLACKMAN_NUTTALL: + sum = ft_bnh (ft->window, ft->window_size, .3635819, .4891775, .1365995, .0106411); + break; + case W_BLACKMAN_HARRIS: + sum = ft_bnh (ft->window, ft->window_size, .35875, .48829, .14128, .01168); + break; + case W_FLAT_TOP: + sum = ft_flattop (ft->window, ft->window_size); + break; + } + const double isum = 2.0 / sum; - for (uint32_t i=0; i < ft->window_size; i++) { - ft->hann_window[i] *= isum; + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->window[i] *= isum; } - return ft->hann_window; + return ft->window; } -static void ft_analyze(struct FFTAnalysis *ft) { - fftwf_execute(ft->fftplan); +static void +ft_analyze (struct FFTAnalysis* ft) +{ + fftwf_execute (ft->fftplan); - memcpy(ft->phase_h, ft->phase, sizeof(float) * ft->data_size); + memcpy (ft->phase_h, ft->phase, sizeof (float) * ft->data_size); ft->power[0] = ft->fft_out[0] * ft->fft_out[0]; ft->phase[0] = 0; #define FRe (ft->fft_out[i]) -#define FIm (ft->fft_out[ft->window_size-i]) +#define FIm (ft->fft_out[ft->window_size - i]) for (uint32_t i = 1; i < ft->data_size - 1; ++i) { ft->power[i] = (FRe * FRe) + (FIm * FIm); - ft->phase[i] = atan2f(FIm, FRe); + ft->phase[i] = atan2f (FIm, FRe); } #undef FRe #undef FIm } -static void ft_analyze_hann(struct FFTAnalysis *ft) { - float *window = ft_hann_window(ft); - for (uint32_t i = 0; i < ft->window_size; i++) { - ft->fft_in[i] *= window[i]; - } - ft_analyze(ft); -} - - /****************************************************************************** * public API (static for direct source inclusion) */ @@ -106,10 +187,12 @@ #endif FFTX_FN_PREFIX -void fftx_reset(struct FFTAnalysis *ft) { +void +fftx_reset (struct FFTAnalysis* ft) +{ for (uint32_t i = 0; i < ft->data_size; ++i) { - ft->power[i] = 0; - ft->phase[i] = 0; + ft->power[i] = 0; + ft->phase[i] = 0; ft->phase_h[i] = 0; } for (uint32_t i = 0; i < ft->window_size; ++i) { @@ -117,73 +200,107 @@ ft->fft_out[i] = 0; } ft->rboff = 0; - ft->smps = 0; - ft->step = 0; + ft->smps = 0; + ft->step = 0; } FFTX_FN_PREFIX -void fftx_init(struct FFTAnalysis *ft, uint32_t window_size, double rate, double fps) { - ft->rate = rate; - ft->window_size = window_size; - ft->data_size = window_size / 2; - ft->hann_window = NULL; - ft->rboff = 0; - ft->smps = 0; - ft->step = 0; - ft->sps = (fps > 0) ? ceil(rate / fps) : 0; - ft->freq_per_bin = ft->rate / ft->data_size / 2.f; +void +fftx_init (struct FFTAnalysis* ft, uint32_t window_size, double rate, double fps) +{ + ft->rate = rate; + ft->window_size = window_size; + ft->window_type = W_HANN; + ft->data_size = window_size / 2; + ft->window = NULL; + ft->rboff = 0; + ft->smps = 0; + ft->step = 0; + ft->sps = (fps > 0) ? ceil (rate / fps) : 0; + ft->freq_per_bin = ft->rate / ft->data_size / 2.f; ft->phasediff_step = M_PI / ft->data_size; - ft->phasediff_bin = 0; + ft->phasediff_bin = 0; + + ft->ringbuf = (float*)malloc (window_size * sizeof (float)); + ft->fft_in = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->fft_out = (float*)fftwf_malloc (sizeof (float) * window_size); + ft->power = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase = (float*)malloc (ft->data_size * sizeof (float)); + ft->phase_h = (float*)malloc (ft->data_size * sizeof (float)); - ft->ringbuf = (float *) malloc(window_size * sizeof(float)); - ft->fft_in = (float *) fftwf_malloc(sizeof(float) * window_size); - ft->fft_out = (float *) fftwf_malloc(sizeof(float) * window_size); - ft->power = (float *) malloc(ft->data_size * sizeof(float)); - ft->phase = (float *) malloc(ft->data_size * sizeof(float)); - ft->phase_h = (float *) malloc(ft->data_size * sizeof(float)); - - fftx_reset(ft); - - pthread_mutex_lock(&fftw_planner_lock); - ft->fftplan = fftwf_plan_r2r_1d(window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); - pthread_mutex_unlock(&fftw_planner_lock); + fftx_reset (ft); + + pthread_mutex_lock (&fftw_planner_lock); + ft->fftplan = fftwf_plan_r2r_1d (window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE); + ++instance_count; + pthread_mutex_unlock (&fftw_planner_lock); } FFTX_FN_PREFIX -void fftx_free(struct FFTAnalysis *ft) { - if (!ft) return; - pthread_mutex_lock(&fftw_planner_lock); - fftwf_destroy_plan(ft->fftplan); - pthread_mutex_unlock(&fftw_planner_lock); - free(ft->hann_window); - free(ft->ringbuf); - fftwf_free(ft->fft_in); - fftwf_free(ft->fft_out); - free(ft->power); - free(ft->phase); - free(ft->phase_h); - free(ft); -} - -static -int _fftx_run(struct FFTAnalysis *ft, - const uint32_t n_samples, float const * const data) +void +fftx_set_window (struct FFTAnalysis* ft, window_t type) { - assert(n_samples <= ft->window_size); + if (ft->window_type == type) { + return; + } + ft->window_type = type; + free (ft->window); + ft->window = NULL; +} - float * const f_buf = ft->fft_in; - float * const r_buf = ft->ringbuf; +FFTX_FN_PREFIX +void +fftx_free (struct FFTAnalysis* ft) +{ + if (!ft) { + return; + } + pthread_mutex_lock (&fftw_planner_lock); + fftwf_destroy_plan (ft->fftplan); + if (instance_count > 0) { + --instance_count; + } +#ifdef WITH_STATIC_FFTW_CLEANUP + /* use this only when statically linking to a local fftw! + * + * "After calling fftw_cleanup, all existing plans become undefined, + * and you should not attempt to execute them nor to destroy them." + * [http://www.fftw.org/fftw3_doc/Using-Plans.html] + * + * If libfftwf is shared with other plugins or the host this can + * cause undefined behavior. + */ + if (instance_count == 0) { + fftwf_cleanup (); + } +#endif + pthread_mutex_unlock (&fftw_planner_lock); + free (ft->window); + free (ft->ringbuf); + fftwf_free (ft->fft_in); + fftwf_free (ft->fft_out); + free (ft->power); + free (ft->phase); + free (ft->phase_h); + free (ft); +} + +static int +_fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) +{ + assert (n_samples <= ft->window_size); + + float* const f_buf = ft->fft_in; + float* const r_buf = ft->ringbuf; const uint32_t n_off = ft->rboff; const uint32_t n_siz = ft->window_size; const uint32_t n_old = n_siz - n_samples; - /* copy new data into ringbuffer and fft-buffer - * TODO: use memcpy - */ for (uint32_t i = 0; i < n_samples; ++i) { - r_buf[ (i + n_off) % n_siz ] = data[i]; - f_buf[n_old + i] = data[i]; + r_buf[(i + n_off) % n_siz] = data[i]; + f_buf[n_old + i] = data[i]; } ft->rboff = (ft->rboff + n_samples) % n_siz; @@ -203,117 +320,142 @@ if (p0s + n_old >= n_siz) { const uint32_t n_p1 = n_siz - p0s; const uint32_t n_p2 = n_old - n_p1; - memcpy(f_buf, &r_buf[p0s], sizeof(float) * n_p1); - memcpy(&f_buf[n_p1], &r_buf[0], sizeof(float) * n_p2); + memcpy (f_buf, &r_buf[p0s], sizeof (float) * n_p1); + memcpy (&f_buf[n_p1], &r_buf[0], sizeof (float) * n_p2); } else { - memcpy(&f_buf[0], &r_buf[p0s], sizeof(float) * n_old); + memcpy (&f_buf[0], &r_buf[p0s], sizeof (float) * n_old); + } + + /* apply window function */ + float const* const window = ft_gen_window (ft); + for (uint32_t i = 0; i < ft->window_size; i++) { + ft->fft_in[i] *= window[i]; } /* ..and analyze */ - ft_analyze_hann(ft); + ft_analyze (ft); + ft->phasediff_bin = ft->phasediff_step * (double)ft->step; return 0; } FFTX_FN_PREFIX -int fftx_run(struct FFTAnalysis *ft, - const uint32_t n_samples, float const * const data) +int +fftx_run (struct FFTAnalysis* ft, + const uint32_t n_samples, float const* const data) { if (n_samples <= ft->window_size) { - return _fftx_run(ft, n_samples, data); + return _fftx_run (ft, n_samples, data); } - int rv = -1; - uint32_t n = 0; + int rv = -1; + uint32_t n = 0; while (n < n_samples) { - uint32_t step = MIN(ft->window_size, n_samples - n); - if (!_fftx_run(ft, step, &data[n])) rv = 0; + uint32_t step = MIN (ft->window_size, n_samples - n); + if (!_fftx_run (ft, step, &data[n])) { + rv = 0; + } n += step; } return rv; } - FFTX_FN_PREFIX -void fa_analyze_dsp(struct FFTAnalysis *ft, - void (*run)(void *, uint32_t, float*), void *handle) +void +fa_analyze_dsp (struct FFTAnalysis* ft, + void (*run) (void*, uint32_t, float*), void* handle) { - float *buf = ft->fft_in; + float* buf = ft->fft_in; /* pre-run 8K samples... (re-init/flush effect) */ uint32_t prerun_n_samples = 8192; while (prerun_n_samples > 0) { uint32_t n_samples = MIN (prerun_n_samples, ft->window_size); - memset(buf, 0, sizeof(float) * n_samples); + memset (buf, 0, sizeof (float) * n_samples); run (handle, n_samples, buf); prerun_n_samples -= n_samples; } /* delta impulse */ - memset(buf, 0, sizeof(float) * ft->window_size); + memset (buf, 0, sizeof (float) * ft->window_size); *buf = 1.0; /* call plugin's run() function -- in-place processing */ run (handle, ft->window_size, buf); ft->step = ft->window_size; - /* ..and analyze */ - ft_analyze(ft); + ft_analyze (ft); } - -/***************************************************************************** +/* *************************************************************************** * convenient access functions */ FFTX_FN_PREFIX -uint32_t fftx_bins(struct FFTAnalysis *ft) { - return ft->data_size; +uint32_t +fftx_bins (struct FFTAnalysis* ft) +{ + return ft->data_size; } FFTX_FN_PREFIX -inline float fast_log2 (float val) { - union {float f; int i;} t; - t.f = val; - int * const exp_ptr = &t.i; - int x = *exp_ptr; - const int log_2 = ((x >> 23) & 255) - 128; +inline float +fast_log2 (float val) +{ + union { + float f; + int i; + } t; + t.f = val; + int* const exp_ptr = &t.i; + int x = *exp_ptr; + const int log_2 = ((x >> 23) & 255) - 128; x &= ~(255 << 23); x += 127 << 23; *exp_ptr = x; - val = ((-1.0f/3) * t.f + 2) * t.f - 2.0f/3; + val = ((-1.0f / 3) * t.f + 2) * t.f - 2.0f / 3; return (val + log_2); } FFTX_FN_PREFIX -inline float fast_log (const float val) { - return (fast_log2 (val) * 0.69314718f); +inline float +fast_log (const float val) +{ + return (fast_log2 (val) * 0.69314718f); } FFTX_FN_PREFIX -inline float fast_log10 (const float val) { - return fast_log2(val) / 3.312500f; +inline float +fast_log10 (const float val) +{ + return fast_log2 (val) / 3.312500f; } FFTX_FN_PREFIX -inline float fftx_power_to_dB(float a) { +inline float +fftx_power_to_dB (float a) +{ /* 10 instead of 20 because of squared signal -- no sqrt(powerp[]) */ - return a > 1e-12 ? 10.0 * fast_log10(a) : -INFINITY; + return a > 1e-12 ? 10.0 * fast_log10 (a) : -INFINITY; } FFTX_FN_PREFIX -float fftx_power_at_bin(struct FFTAnalysis *ft, const int b) { - return (fftx_power_to_dB(ft->power[b])); +float +fftx_power_at_bin (struct FFTAnalysis* ft, const int b) +{ + return (fftx_power_to_dB (ft->power[b])); } FFTX_FN_PREFIX -float fftx_freq_at_bin(struct FFTAnalysis *ft, const int b) { +float +fftx_freq_at_bin (struct FFTAnalysis* ft, const int b) +{ /* calc phase: difference minus expected difference */ - float phase = ft->phase[b] - ft->phase_h[b] - (float) b * ft->phasediff_bin; + float phase = ft->phase[b] - ft->phase_h[b] - (float)b * ft->phasediff_bin; /* clamp to -M_PI .. M_PI */ int over = phase / M_PI; - over += (over >= 0) ? (over&1) : -(over&1); - phase -= M_PI*(float)over; + over += (over >= 0) ? (over & 1) : -(over & 1); + phase -= M_PI * (float)over; /* scale according to overlap */ phase *= (ft->data_size / ft->step) / M_PI; - return ft->freq_per_bin * ((float) b + phase); + return ft->freq_per_bin * ((float)b + phase); } diff -Nru x42-plugins-20170428/tuna.lv2/src/spectr.c x42-plugins-20190714/tuna.lv2/src/spectr.c --- x42-plugins-20170428/tuna.lv2/src/spectr.c 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/src/spectr.c 2019-07-14 19:39:45.000000000 +0000 @@ -25,12 +25,22 @@ #include #include -#if __cplusplus >= 201103L || (defined __APPLE__ && defined __cplusplus) +#if __cplusplus >= 201103L || ((defined __APPLE__ || defined __FreeBSD__) && defined __cplusplus) # include # define csqrt(XX) std::sqrt(XX) # define creal(XX) std::real(XX) # define cimag(XX) std::imag(XX) -# define _I ((complex_t)(1i)) + +# ifdef __cpp_lib_complex_udls + using namespace std::literals::complex_literals; +# endif + +# if defined __clang_major__ && __clang_major__ > 4 +# define _I (std::complex(0.0,1.0)) +# else +# define _I ((complex_t)(1i)) +# endif + typedef std::complex complex_t; #else # include @@ -42,14 +52,15 @@ enum filterState {z1 = 0, z2}; #define NODENORMAL (1e-12) +#define MAXORDER (6) struct Filter { - double W[6]; + double W[MAXORDER]; double z[2]; }; struct FilterBank { - struct Filter f[6]; + struct Filter f[MAXORDER]; uint32_t filter_stages; bool ac; }; @@ -57,15 +68,15 @@ static inline double proc_one(struct Filter * const f, const double in) { - const double w = in - f->W[a1]*f->z[z1] - f->W[a2]*f->z[z2]; - const double out = f->W[b0]*w + f->W[b1]*f->z[z1] + f->W[b2]*f->z[z2]; - f->z[z2] = f->z[z1]; - f->z[z1] = w; - return out; + + const double y = f->W[b0] * in + f->z[z1]; + f->z[z1] = f->W[b1] * in - f->W[a1] * y + f->z[z2]; + f->z[z2] = f->W[b2] * in - f->W[a2] * y; + return y; } static inline float -bandpass_process(struct FilterBank * const fb, float in) +bandpass_process(struct FilterBank * const fb, const float in) { fb->ac = !fb->ac; double out = in + ((fb->ac) ? NODENORMAL : -NODENORMAL); @@ -86,7 +97,7 @@ /* must be an even number for the algorithm below */ fb->filter_stages = order; - assert (order > 0 && (order%2) == 0); + assert (order > 0 && (order%2) == 0 && order <= MAXORDER); assert (band > 0); for (uint32_t i = 0; i < fb->filter_stages; ++i) { @@ -183,6 +194,7 @@ fb->f[0].W[b2] *= creal(scale); #ifdef DEBUG_SPECTR + printf("CFG SR:%f FQ:%f BW:%f O:%d\n", rate, freq, band, order); printf("SCALE (%g, %g)\n", creal(scale), cimag(scale)); for (uint32_t i = 0; i < fb->filter_stages; ++i) { struct Filter *flt = &fb->f[i]; diff -Nru x42-plugins-20170428/tuna.lv2/src/tuna.c x42-plugins-20190714/tuna.lv2/src/tuna.c --- x42-plugins-20170428/tuna.lv2/src/tuna.c 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/src/tuna.c 2019-07-14 19:39:45.000000000 +0000 @@ -30,6 +30,12 @@ #include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#ifdef DISPLAY_INTERFACE +#include +#include +#include "lv2_rgext.h" +#endif + #ifndef MIN #define MIN(A,B) ( (A) < (B) ? (A) : (B) ) #endif @@ -246,6 +252,19 @@ /* Spectrum */ bool spectr_active; +#ifdef DISPLAY_INTERFACE + LV2_Inline_Display_Image_Surface surf; + PangoFontDescription* font; + cairo_surface_t* display; + LV2_Inline_Display* queue_draw; + uint32_t w, h; + uint32_t fps_cnt; + uint32_t aspvf; + float ui_strobe_dpy; + float ui_strobe_phase; + int guard1, guard2; + float ui_note, ui_octave, ui_cent, ui_strobe_tme; +#endif } Tuna; #ifdef BACKGROUND_FFT @@ -326,6 +345,11 @@ if (!strcmp(features[i]->URI, LV2_URID__map)) { self->map = (LV2_URID_Map*)features[i]->data; } +#ifdef DISPLAY_INTERFACE + else if (!strcmp(features[i]->URI, LV2_INLINEDISPLAY__queue_draw)) { + self->queue_draw = (LV2_Inline_Display*) features[i]->data; + } +#endif } if (!self->map) { fprintf(stderr, "tuna.lv2 error: Host does not support urid:map\n"); @@ -408,7 +432,9 @@ return NULL; } #endif - +#ifdef DISPLAY_INTERFACE + self->aspvf = rate / 25; +#endif return (LV2_Handle)self; } @@ -803,7 +829,7 @@ dfreq0, dfreq2, self->dll_e0, (self->dll_t1 - self->dll_t0) - self->dll_e2); float dfreq; - if (fabsf(self->dll_e0 * freq / self->rate) > .02) { + if (fabsf (self->dll_e0 * freq / self->rate) > .02) { dfreq = dfreq0; } else { dfreq = dfreq2; @@ -905,6 +931,24 @@ if (self->a_in != self->a_out) { memcpy(self->a_out, self->a_in, sizeof(float) * n_samples); } + +#ifdef DISPLAY_INTERFACE + if (self->queue_draw) { + self->fps_cnt += n_samples; + if (self->fps_cnt > self->aspvf) { + self->fps_cnt = self->fps_cnt % self->aspvf; + + self->guard1++; + self->ui_octave = *self->p_octave; + self->ui_note = *self->p_note; + self->ui_cent = *self->p_cent; + self->ui_strobe_tme = *self->p_strobe; + self->guard2++; + + self->queue_draw->queue_draw (self->queue_draw->handle); + } + } +#endif } static void @@ -912,6 +956,14 @@ { Tuna* self = (Tuna*)handle; +#ifdef DISPLAY_INTERFACE + if (self->display) { + cairo_surface_destroy (self->display); + } + if (self->font) { + pango_font_description_free (self->font); + } +#endif #ifdef BACKGROUND_FFT pthread_mutex_lock (&self->lock); self->keep_running = false; @@ -929,14 +981,160 @@ free(handle); } +#ifdef WITH_SIGNATURE +#define RTK_URI TUNA_URI +#include "gpg_init.c" +#include WITH_SIGNATURE +struct license_info license_infos = { + "x42-Tuner", + "http://x42-plugins.com/x42/x42-tuner" +}; +#include "gpg_lv2ext.c" +#endif /****************************************************************************** - * LV2 setup + * Inline Display */ +#ifdef DISPLAY_INTERFACE +static LV2_Inline_Display_Image_Surface * +tuna_render (LV2_Handle handle, uint32_t w, uint32_t max_h) +{ +#ifdef WITH_SIGNATURE + if (!is_licensed (handle)) { return NULL; } +#endif + uint32_t h = MAX (32, MIN (1 | (uint32_t)ceilf (w / 3.f), max_h)); + + static const char notename[12][3] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; + + Tuna* self = (Tuna*)handle; + char txt[32]; + + if (!self->display || self->w != w || self->h != h) { + if (self->display) cairo_surface_destroy(self->display); + self->display = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + self->w = w; + self->h = h; + if (self->font) { + pango_font_description_free (self->font); + } + snprintf(txt, 32, "Mono %.0fpx", floor (h * .375)); + self->font = pango_font_description_from_string (txt); + } + cairo_t* cr = cairo_create (self->display); + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba (cr, .2, .2, .2, 1.0); + cairo_fill (cr); + + float ui_octave; + float ui_note; + float ui_cent; + float ui_strobe_tme; + + int tries = 0; + do { + if (tries == 10) { + tries = 0; + sched_yield (); + } + ui_octave = self->ui_octave; + ui_note = self->ui_note; + ui_cent = self->ui_cent; + ui_strobe_tme = self->ui_strobe_tme; + ++tries; + } while (self->guard1 != self->guard2); + + /* strobe setup */ + cairo_set_source_rgba (cr, .5, .5, .5, .8); + if (self->ui_strobe_dpy != ui_strobe_tme) { + if (ui_strobe_tme > self->ui_strobe_dpy) { + float tdiff = ui_strobe_tme - self->ui_strobe_dpy; + self->ui_strobe_phase += tdiff * ui_cent * 4; + if (fabsf (ui_cent) < 5) { + cairo_set_source_rgba (cr, .2, .9, .2, .7); + } else if (fabsf (ui_cent) < 10) { + cairo_set_source_rgba (cr, .8, .8, .0, .7); + } else { + cairo_set_source_rgba (cr, .9, .2, .2, .7); + } + } + self->ui_strobe_dpy = ui_strobe_tme; + } + + /* render strobe */ + cairo_save(cr); + const double dash1[] = {8.0}; + const double dash2[] = {16.0}; + + cairo_set_dash(cr, dash1, 1, self->ui_strobe_phase * -2.); + cairo_set_line_width(cr, 8.0); + cairo_move_to(cr, 0, h * .75); + cairo_line_to(cr, w, h * .75); + cairo_stroke (cr); + + cairo_set_dash(cr, dash2, 1, -self->ui_strobe_phase); + cairo_set_line_width(cr, 16.0); + cairo_move_to(cr, 0, h * .75); + cairo_line_to(cr, w, h * .75); + cairo_stroke (cr); + cairo_restore(cr); + + /* render text */ + int tw, th; + if (fabsf (ui_cent) < 100) { + snprintf(txt, 32, "%-2s%.0f %+3.0f\u00A2", notename[(int)ui_note], ui_octave, ui_cent); + } else { + snprintf(txt, 32, "%-2s%.0f", notename[(int)ui_note], ui_octave); + } + PangoLayout * pl = pango_cairo_create_layout (cr); + pango_layout_set_font_description (pl, self->font); + pango_layout_set_text (pl, txt, -1); + pango_layout_get_pixel_size (pl, &tw, &th); + cairo_move_to (cr, 0.5 * (w - tw), 0.25 * h - .5 * th); +#if 0 + cairo_set_source_rgba (cr, 1, 1, 1, 1); + pango_cairo_show_layout (cr, pl); +#else + pango_cairo_layout_path (cr, pl); + cairo_set_line_width(cr, 2.5); + cairo_set_source_rgba (cr, 0, 0, 0, .5); + cairo_stroke_preserve (cr); + cairo_set_source_rgba (cr, 1, 1, 1, 1); + cairo_fill (cr); +#endif + g_object_unref(pl); + + /* finish surface */ + cairo_destroy (cr); + cairo_surface_flush (self->display); + self->surf.width = cairo_image_surface_get_width (self->display); + self->surf.height = cairo_image_surface_get_height (self->display); + self->surf.stride = cairo_image_surface_get_stride (self->display); + self->surf.data = cairo_image_surface_get_data (self->display); + + return &self->surf; +} +#endif + +/****************************************************************************** + * LV2 setup + */ const void* extension_data(const char* uri) { +#ifdef DISPLAY_INTERFACE + static const LV2_Inline_Display_Interface display = { tuna_render }; + if (!strcmp(uri, LV2_INLINEDISPLAY__interface)) { +#if (defined _WIN32 && defined RTK_STATIC_INIT) + static int once = 0; + if (!once) {once = 1; gobject_init_ctor();} +#endif + return &display; + } +#endif +#ifdef WITH_SIGNATURE + LV2_LICENSE_EXT_C +#endif return NULL; } diff -Nru x42-plugins-20170428/tuna.lv2/x42-tuna.1 x42-plugins-20190714/tuna.lv2/x42-tuna.1 --- x42-plugins-20170428/tuna.lv2/x42-tuna.1 2017-04-27 23:58:32.000000000 +0000 +++ x42-plugins-20190714/tuna.lv2/x42-tuna.1 2019-07-14 19:39:45.000000000 +0000 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH X42-TUNA "1" "April 2017" "x42-tuna version 0.4.3" "User Commands" +.TH X42-TUNA "1" "July 2019" "x42-tuna version 0.4.14" "User Commands" .SH NAME x42-tuna \- JACK Music Instrument Tuner .SH SYNOPSIS @@ -12,7 +12,7 @@ Use ID \fB\-1\fR, \fB\-l\fR or \fB\-\-list\fR for a dedicated list of included plugins. By default the first listed plugin (ID 0) is used. .PP -List if available plugins: (ID "Name" URI) +List of available plugins: (ID "Name" URI) .TP 0 "Instrument Tuner" http://gareus.org/oss/lv2/tuna#one @@ -42,6 +42,9 @@ Set the JACK client name (defaults to plugin\-name) .TP +\fB\-G\fR, \fB\-\-nogui\fR +run headless, useful for OSC remote ctrl. +.TP \fB\-l\fR, \fB\-\-list\fR Print list of available plugins and exit .TP @@ -63,7 +66,7 @@ See also: Website: .SH COPYRIGHT -Copyright \(co GPL 2013\-2015 Robin Gareus +Copyright \(co GPL 2013\-2019 Robin Gareus .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/xfade.lv2/img/x42.ico and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/xfade.lv2/img/x42.ico differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/xfade.lv2/img/x42-xfade.icns and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/xfade.lv2/img/x42-xfade.icns differ Binary files /tmp/tmpMTrSe7/ICNSUGsBiT/x42-plugins-20170428/xfade.lv2/img/x42-xfade.png and /tmp/tmpMTrSe7/u9fSO_BYjc/x42-plugins-20190714/xfade.lv2/img/x42-xfade.png differ diff -Nru x42-plugins-20170428/xfade.lv2/Makefile x42-plugins-20190714/xfade.lv2/Makefile --- x42-plugins-20170428/xfade.lv2/Makefile 2016-09-19 08:58:23.000000000 +0000 +++ x42-plugins-20190714/xfade.lv2/Makefile 2019-05-04 23:04:33.000000000 +0000 @@ -1,20 +1,16 @@ #!/usr/bin/make -f - -# these can be overridden using make variables. e.g. -# make CFLAGS=-O2 -# -OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only +OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only -DNDEBUG PREFIX ?= /usr/local CFLAGS ?= $(OPTIMIZATIONS) -Wall -LIBDIR ?= lib +PKG_CONFIG?=pkg-config STRIP?=strip STRIPFLAGS?=-s xfade_VERSION?=$(shell git describe --tags HEAD 2>/dev/null | sed 's/-g.*$$//;s/^v//' || echo "LV2") ############################################################################### -LV2DIR ?= $(PREFIX)/$(LIBDIR)/lv2 +LV2DIR ?= $(PREFIX)/lib/lv2 LOADLIBES=-lm LV2NAME=xfade BUNDLE=xfade.lv2 @@ -40,6 +36,8 @@ LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed LIB_EXT=.dll override LDFLAGS += -static-libgcc -static-libstdc++ +else + override CFLAGS += -fPIC -fvisibility=hidden endif targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT) @@ -50,12 +48,11 @@ include git2lv2.mk # check for build-dependencies -ifeq ($(shell pkg-config --exists lv2 || echo no), no) +ifeq ($(shell $(PKG_CONFIG) --exists lv2 || echo no), no) $(error "LV2 SDK was not found") endif -override CFLAGS += -fPIC -std=c99 -override CFLAGS += `pkg-config --cflags lv2` +override CFLAGS += -std=c99 `$(PKG_CONFIG) --cflags lv2` # build target definitions default: all diff -Nru x42-plugins-20170428/xfade.lv2/xfade.c x42-plugins-20190714/xfade.lv2/xfade.c --- x42-plugins-20170428/xfade.lv2/xfade.c 2016-09-19 08:58:23.000000000 +0000 +++ x42-plugins-20190714/xfade.lv2/xfade.c 2019-05-04 23:04:33.000000000 +0000 @@ -208,7 +208,7 @@ free(instance); } -const void* +static const void* extension_data(const char* uri) { return NULL;