Commit 1bc405ef authored by Jaromír Mikeš's avatar Jaromír Mikeš

Imported Upstream version 20160822

parent 35917694
......@@ -6,11 +6,10 @@ export RW=../robtk/
###############################################################################
VERSION ?=$(shell date +%Y%m%d)
SUBDIRS = balance.lv2 convoLV2 nodelay.lv2 xfade.lv2 \
midifilter.lv2 meters.lv2 sisco.lv2 tuna.lv2 \
onsettrigger.lv2 mixtri.lv2 fil4.lv2 \
controlfilter.lv2 midimap.lv2 stereoroute.lv2 \
testsignal.lv2 midigen.lv2
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
all clean install uninstall: submodule_check $(SUBDIRS)
......
2016-06-17 (0.6.2) Robin Gareus <robin@gareus.org>
* clean up dist tar ball
* support cross-compile build-system
2015-06-27 (0.6.1) Robin Gareus <robin@gareus.org>
* add lv2 version
* specify integers as int in ttl.
2015-05-13 (0.6.0) Robin Gareus <robin@gareus.org>
* openGL details (multisampling etc)
* various minor tweaks
* use even minor version number (LV2 stable release)
2013-11-19 (0.4.3) Robin Gareus <robin@gareus.org>
* explicit built-dep on openGL
2013-09-15 (0.4.2) Robin Gareus <robin@gareus.org>
* NaN protection
* align RMS to sine-wave (not square wave)
* implement GL-UI thread-synchronization
* fix possible memory-leak (when re-opening ui)
* update (C) and GPL (FSF address)
2013-06-12 (0.4.1) Robin Gareus <robin@gareus.org>
* resize-port sz:minimumSize (fix jack1 issue)
* do not include production-files (xcf) in tar dist
2013-06-08 (0.4.0) Robin Gareus <robin@gareus.org>
* clean up build system (CFLAGS)
* fix meter-level text & alignment
* address some openGL rendering issues
* add LV2 plugin category
* built-in documentation & port annotation
2013-05-13 (0.3.3) Robin Gareus <robin@gareus.org>
* add state interface - save/restore level-meter config
2013-05-11 (0.3.2) Robin Gareus <robin@gareus.org>
* allow to configure meter (integration and peak-hold times)
* resizable window
* small tweaks to improve usability
2013-05-05 (0.3.1) Robin Gareus <robin@gareus.org>
* fix peak meter
* use absolute non-integrated max for peak-hold
2013-05-05 (0.3.0) Robin Gareus <robin@gareus.org>
* add phase-invert buttons in input stage
* add phase correlation meter
* IEC 60268-18 style meters
* do not calc levels/phase, nor send messages to UI, if UI is not visible
* use to FreeSansBold font as default
* various minor tweaks and fixes
2013-05-02 (0.2.0) Robin Gareus <robin@gareus.org>
* added openGL based UI
2013-05-01 (0.1.0) Robin Gareus <robin@gareus.org>
* initial version of panner with delaylines
......@@ -9,7 +9,7 @@ PREFIX ?= /usr/local
CXXFLAGS ?= $(OPTIMIZATIONS) -Wall
LIBDIR ?= lib
STRIP=strip
STRIP?=strip
STRIPFLAGS=-s
UISTRIPFLAGS=-s
......
......@@ -211,7 +211,7 @@ static void
channel_map(BalanceControl *self, int mode,
const uint32_t start, const uint32_t end)
{
int i;
uint32_t i;
switch (mode) {
case 1:
for (i=start; i < end; ++i) {
......@@ -360,7 +360,7 @@ static void update_meter_cfg(BalanceControl* self, int key, float val) {
static void
run(LV2_Handle instance, uint32_t n_samples)
{
int i,c;
uint32_t i,c;
BalanceControl* self = (BalanceControl*)instance;
const float balance = *self->balance;
const float trim = db_to_gain(*self->trim);
......
......@@ -1052,7 +1052,7 @@ onReshape(PuglView* view, int width, int height)
static void updateLight(PuglView* view) {
BLCui* ui = (BLCui*)puglGetHandle(view);
GLfloat light0_position[] = { .5 + ui->rot[0]/90.0, -.5 - ui->rot[1]/90.0, -10.0, 0 };
GLfloat light0_position[] = { (float)(.5 + ui->rot[0] / 90.0), (float)(-.5 - ui->rot[1] / 90.0), -10.f, 0.f };
GLfloat spot_direction[] = { -light0_position[0], -light0_position[1], -light0_position[2]};
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
......
/* convoLV2 -- LV2 convolution plugin
*
* Copyright (C) 2012 Robin Gareus <robin@gareus.org>
* Copyright (C) 2012-2016 Robin Gareus <robin@gareus.org>
*
* 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
......@@ -349,11 +349,11 @@ run(LV2_Handle instance, uint32_t n_samples)
}
if (*self->p_output_gain != self->output_gain_db) {
float g = *self->p_output_gain;
self->output_gain_db = *self->p_output_gain;
if (g < -40) g = -40;
if (g > 40) g = 40;
self->output_gain_target = powf(10.f, 0.05f * g);
float g = *self->p_output_gain;
self->output_gain_db = *self->p_output_gain;
if (g < -40) g = -40;
if (g > 40) g = 40;
self->output_gain_target = powf(10.f, 0.05f * g);
}
self->output_gain += .08f * (self->output_gain_target - self->output_gain);
......@@ -480,6 +480,20 @@ restore(LV2_Handle instance,
uint32_t type;
uint32_t valflags;
/* Get the work scheduler provided to restore() (state:threadSafeRestore
support), but fall back to instantiate() schedules (spec-violating
workaround for broken hosts). */
LV2_Worker_Schedule* schedule = self->schedule;
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 (schedule == self->schedule) {
DEBUG_printf("State: warning: using run() scheduler to restore\n");
}
if (self->clv_offline) {
// TODO use lv2_log_error()
VERBOSE_printf("State: offline instance in-use, state ignored.\n");
......@@ -496,6 +510,11 @@ restore(LV2_Handle instance,
}
}
#if 1 // prevent concurrent run() mess
// should use atomic -- but really hosts need to be fixed instead
self->flag_reinit_in_progress = 1;
#endif
const void* value = retrieve(handle, self->uris.clv2_state, &size, &type, &valflags);
if (value) {
......@@ -523,6 +542,13 @@ restore(LV2_Handle instance,
clv_configure(self->clv_offline, "convolution.ir.file", path);
}
#if 0
/* run() and restore() must not be called concurrently.
* except some hosts do..
*
* in any case re-initialize in a background thread to not
* block run() for a long time.
*/
clv_initialize(self->clv_offline, self->rate, self->chn_in, self->chn_out,
/*64 <= buffer-size <=4096*/ self->bufsize);
......@@ -537,6 +563,10 @@ restore(LV2_Handle instance,
DEBUG_printf("State: free offline instance\n");
clv_free(self->clv_offline);
self->clv_offline=NULL;
#else
int d = CMD_APPLY;
schedule->schedule_work(self->schedule->handle, sizeof(int), &d);
#endif
return LV2_STATE_SUCCESS;
}
......
......@@ -42,7 +42,7 @@ clv2:Mono
bufsz:maxBlockLength 8192 ;
lv2:extensionData work:interface ,
state:interface ;
lv2:optionalFeature lv2:hardRTCapable, <http://ardour.org/lv2/ext#noSampleAccurateControls> ;
lv2:optionalFeature lv2:hardRTCapable, state:threadSafeRestore, <http://ardour.org/lv2/ext#noSampleAccurateControls> ;
@CLV2UI@
patch:writable clv2:impulse ;
lv2:port [
......
[submodule "robtk"]
path = robtk
url = git://github.com/x42/robtk
This diff is collapsed.
This diff is collapsed.
#!/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
fat1.lv2 - AutoTune-1
=====================
fat1.lv2 is an auto-tuner based on Fons Adriaensen's zita-at1.
See [zita-at1's quickguide](http://kokkinizita.linuxaudio.org/linuxaudio/zita-at1-doc/quickguide.html) for an introduction.
The only differences to zita-at1 is that the plugin reports its latency
to the host, saves the state with the session and the MIDI input has
sidechain semantics.
Install
-------
Compiling fat1.lv2 requires the LV2 SDK, fftw, gnu-make, and a c-compiler.
```bash
git clone git://github.com/x42/fat1.lv2.git
cd fat1.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.
Screenshots
-----------
![screenshot](https://raw.github.com/x42/fat1.lv2/master/img/fat1_v1.png "Fat1 GUI")
###############################################################################
# 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))
This diff is collapsed.
@LV2NAME@:ui_gl
a @UI_TYPE@ ;
@UI_REQ@
.
// 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
};
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix kx: <http://kxstudio.sf.net/ns/lv2ext/external-ui#> .
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
@prefix mod: <http://moddevices.com/ns/mod#> .
@prefix pprop: <http://lv2plug.in/ns/ext/port-props#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
@prefix units: <http://lv2plug.in/ns/extensions/units#> .
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
@prefix @LV2NAME@: <http://gareus.org/oss/lv2/@LV2NAME@#> .
<http://gareus.org/rgareus#me>
a foaf:Person;
foaf:name "Robin Gareus";
foaf:mbox <mailto:robin@gareus.org>;
foaf:homepage <http://gareus.org/> .
<http://gareus.org/oss/lv2/fat1>
a lv2:Plugin, doap:Project, lv2:WaveshaperPlugin;
doap:license <http://usefulinc.com/doap/licenses/gpl>;
doap:maintainer <http://gareus.org/rgareus#me>;
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 ,