aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/eg-amp.lv2/meson.build41
l---------plugins/eg-amp.lv2/waf1
-rw-r--r--plugins/eg-amp.lv2/wscript51
-rw-r--r--plugins/eg-fifths.lv2/meson.build41
l---------plugins/eg-fifths.lv2/waf1
-rw-r--r--plugins/eg-fifths.lv2/wscript49
-rw-r--r--plugins/eg-metro.lv2/meson.build41
-rw-r--r--plugins/eg-metro.lv2/metro.c13
l---------plugins/eg-metro.lv2/waf1
-rw-r--r--plugins/eg-metro.lv2/wscript50
-rw-r--r--plugins/eg-midigate.lv2/meson.build41
-rw-r--r--plugins/eg-midigate.lv2/midigate.c6
l---------plugins/eg-midigate.lv2/waf1
-rw-r--r--plugins/eg-midigate.lv2/wscript49
-rw-r--r--plugins/eg-params.lv2/meson.build41
-rw-r--r--plugins/eg-params.lv2/params.c11
-rw-r--r--plugins/eg-params.lv2/state_map.h2
-rw-r--r--plugins/eg-params.lv2/wscript49
-rw-r--r--plugins/eg-sampler.lv2/manifest.ttl.in2
-rw-r--r--plugins/eg-sampler.lv2/meson.build48
-rw-r--r--plugins/eg-sampler.lv2/peaks.h4
-rw-r--r--plugins/eg-sampler.lv2/sampler.c121
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c8
l---------plugins/eg-sampler.lv2/waf1
-rw-r--r--plugins/eg-sampler.lv2/wscript64
-rw-r--r--plugins/eg-scope.lv2/examploscope.c5
-rw-r--r--plugins/eg-scope.lv2/examploscope_ui.c4
-rw-r--r--plugins/eg-scope.lv2/manifest.ttl.in2
-rw-r--r--plugins/eg-scope.lv2/meson.build41
-rw-r--r--plugins/eg-scope.lv2/wscript56
-rwxr-xr-xplugins/literasc.py158
-rw-r--r--plugins/meson.build82
-rw-r--r--plugins/wscript45
33 files changed, 592 insertions, 538 deletions
diff --git a/plugins/eg-amp.lv2/meson.build b/plugins/eg-amp.lv2/meson.build
new file mode 100644
index 0000000..2b15b01
--- /dev/null
+++ b/plugins/eg-amp.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('amp.c')
+bundle_name = 'eg-amp.lv2'
+data_filenames = ['manifest.ttl.in', 'amp.ttl']
+
+module = shared_library(
+ 'amp',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-amp.lv2/waf b/plugins/eg-amp.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-amp.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-amp.lv2/wscript b/plugins/eg-amp.lv2/wscript
deleted file mode 100644
index 822825d..0000000
--- a/plugins/eg-amp.lv2/wscript
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-amp.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2', uselib_store='LV2')
-
- conf.check(features='c cshlib', lib='m', uselib_store='M', mandatory=False)
-
-def build(bld):
- bundle = 'eg-amp.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-amp.lv2)
- for i in ['amp.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'amp.c',
- name = 'amp',
- target = 'lv2/%s/amp' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- uselib = 'M LV2')
diff --git a/plugins/eg-fifths.lv2/meson.build b/plugins/eg-fifths.lv2/meson.build
new file mode 100644
index 0000000..fd38ee3
--- /dev/null
+++ b/plugins/eg-fifths.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('fifths.c')
+bundle_name = 'eg-fifths.lv2'
+data_filenames = ['manifest.ttl.in', 'fifths.ttl']
+
+module = shared_library(
+ 'fifths',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-fifths.lv2/waf b/plugins/eg-fifths.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-fifths.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-fifths.lv2/wscript b/plugins/eg-fifths.lv2/wscript
deleted file mode 100644
index 8b2991b..0000000
--- a/plugins/eg-fifths.lv2/wscript
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-fifths.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
-
-def build(bld):
- bundle = 'eg-fifths.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-fifths.lv2)
- for i in ['fifths.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'fifths.c',
- name = 'fifths',
- target = 'lv2/%s/fifths' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'LV2')
diff --git a/plugins/eg-metro.lv2/meson.build b/plugins/eg-metro.lv2/meson.build
new file mode 100644
index 0000000..f881eca
--- /dev/null
+++ b/plugins/eg-metro.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('metro.c')
+bundle_name = 'eg-metro.lv2'
+data_filenames = ['manifest.ttl.in', 'metro.ttl']
+
+module = shared_library(
+ 'metro',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-metro.lv2/metro.c b/plugins/eg-metro.lv2/metro.c
index 87a9029..c89c542 100644
--- a/plugins/eg-metro.lv2/metro.c
+++ b/plugins/eg-metro.lv2/metro.c
@@ -212,7 +212,7 @@ static void
play(Metro* self, uint32_t begin, uint32_t end)
{
float* const output = self->ports.output;
- const uint32_t frames_per_beat = 60.0f / self->bpm * self->rate;
+ const uint32_t frames_per_beat = (uint32_t)(60.0f / self->bpm * self->rate);
if (self->speed == 0.0f) {
memset(output, 0, (end - begin) * sizeof(float));
@@ -289,7 +289,7 @@ update_position(Metro* self, const LV2_Atom_Object* obj)
const float frames_per_beat = (float)(60.0 / self->bpm * self->rate);
const float bar_beats = ((LV2_Atom_Float*)beat)->body;
const float beat_beats = bar_beats - floorf(bar_beats);
- self->elapsed_len = beat_beats * frames_per_beat;
+ self->elapsed_len = (uint32_t)(beat_beats * frames_per_beat);
if (self->elapsed_len < self->attack_len) {
self->state = STATE_ATTACK;
} else if (self->elapsed_len < self->attack_len + self->decay_len) {
@@ -313,7 +313,7 @@ run(LV2_Handle instance, uint32_t sample_count)
!lv2_atom_sequence_is_end(&in->body, in->atom.size, ev);
ev = lv2_atom_sequence_next(ev)) {
// Play the click for the time slice from last_t until now
- play(self, last_t, ev->time.frames);
+ play(self, last_t, (uint32_t)ev->time.frames);
// Check if this event is an Object
// (or deprecated Blank to tolerate old hosts)
@@ -327,7 +327,7 @@ run(LV2_Handle instance, uint32_t sample_count)
}
// Update time for next iteration and move to next event
- last_t = ev->time.frames;
+ last_t = (uint32_t)ev->time.frames;
}
// Play for remainder of cycle
@@ -345,8 +345,9 @@ static const LV2_Descriptor descriptor = {
NULL, // extension_data
};
-LV2_SYMBOL_EXPORT const LV2_Descriptor*
- lv2_descriptor(uint32_t index)
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
{
return index == 0 ? &descriptor : NULL;
}
diff --git a/plugins/eg-metro.lv2/waf b/plugins/eg-metro.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-metro.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-metro.lv2/wscript b/plugins/eg-metro.lv2/wscript
deleted file mode 100644
index 5fb0d07..0000000
--- a/plugins/eg-metro.lv2/wscript
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-metro.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 0.2.0', uselib_store='LV2')
-
- conf.check(features='c cshlib', lib='m', uselib_store='M', mandatory=False)
-
-def build(bld):
- bundle = 'eg-metro.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-metro.lv2)
- bld(features = 'subst',
- is_copy = True,
- source = 'metro.ttl',
- target = 'lv2/%s/metro.ttl' % bundle,
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'metro.c',
- name = 'metro',
- target = 'lv2/%s/metro' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = ['M', 'LV2'])
diff --git a/plugins/eg-midigate.lv2/meson.build b/plugins/eg-midigate.lv2/meson.build
new file mode 100644
index 0000000..0e35fd1
--- /dev/null
+++ b/plugins/eg-midigate.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('midigate.c')
+bundle_name = 'eg-midigate.lv2'
+data_filenames = ['manifest.ttl.in', 'midigate.ttl']
+
+module = shared_library(
+ 'midigate',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-midigate.lv2/midigate.c b/plugins/eg-midigate.lv2/midigate.c
index 5379440..d98f670 100644
--- a/plugins/eg-midigate.lv2/midigate.c
+++ b/plugins/eg-midigate.lv2/midigate.c
@@ -160,6 +160,9 @@ run(LV2_Handle instance, uint32_t sample_count)
uint32_t offset = 0;
LV2_ATOM_SEQUENCE_FOREACH (self->control, ev) {
+ write_output(self, offset, (uint32_t)(ev->time.frames - offset));
+ offset = (uint32_t)ev->time.frames;
+
if (ev->body.type == self->uris.midi_MidiEvent) {
const uint8_t* const msg = (const uint8_t*)(ev + 1);
switch (lv2_midi_message_type(msg)) {
@@ -185,9 +188,6 @@ run(LV2_Handle instance, uint32_t sample_count)
break;
}
}
-
- write_output(self, offset, ev->time.frames - offset);
- offset = (uint32_t)ev->time.frames;
}
write_output(self, offset, sample_count - offset);
diff --git a/plugins/eg-midigate.lv2/waf b/plugins/eg-midigate.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-midigate.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-midigate.lv2/wscript b/plugins/eg-midigate.lv2/wscript
deleted file mode 100644
index 5862721..0000000
--- a/plugins/eg-midigate.lv2/wscript
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-midigate.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2', uselib_store='LV2')
-
-def build(bld):
- bundle = 'eg-midigate.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-midigate.lv2)
- for i in ['midigate.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'midigate.c',
- name = 'midigate',
- target = 'lv2/%s/midigate' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- uselib = 'LV2')
diff --git a/plugins/eg-params.lv2/meson.build b/plugins/eg-params.lv2/meson.build
new file mode 100644
index 0000000..4c1e576
--- /dev/null
+++ b/plugins/eg-params.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('params.c')
+bundle_name = 'eg-params.lv2'
+data_filenames = ['manifest.ttl.in', 'params.ttl']
+
+module = shared_library(
+ 'params',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-params.lv2/params.c b/plugins/eg-params.lv2/params.c
index 56c39cd..052b43b 100644
--- a/plugins/eg-params.lv2/params.c
+++ b/plugins/eg-params.lv2/params.c
@@ -199,10 +199,10 @@ unmap(Params* self, LV2_URID urid)
{
if (self->unmap) {
return self->unmap->unmap(self->unmap->handle, urid);
- } else {
- snprintf(self->urid_buf, sizeof(self->urid_buf), "%u", urid);
- return self->urid_buf;
}
+
+ snprintf(self->urid_buf, sizeof(self->urid_buf), "%u", urid);
+ return self->urid_buf;
}
static LV2_State_Status
@@ -526,8 +526,9 @@ static const LV2_Descriptor descriptor = {EG_PARAMS_URI,
cleanup,
extension_data};
-LV2_SYMBOL_EXPORT const LV2_Descriptor*
- lv2_descriptor(uint32_t index)
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
{
return (index == 0) ? &descriptor : NULL;
}
diff --git a/plugins/eg-params.lv2/state_map.h b/plugins/eg-params.lv2/state_map.h
index f534f60..4a00d2f 100644
--- a/plugins/eg-params.lv2/state_map.h
+++ b/plugins/eg-params.lv2/state_map.h
@@ -48,7 +48,7 @@ state_map_cmp(const void* a, const void* b)
/** Helper macro for terse state map initialisation. */
#define STATE_MAP_INIT(type, ptr) \
- (LV2_ATOM__##type), (sizeof(*ptr) - sizeof(LV2_Atom)), (ptr)
+ (LV2_ATOM__##type), (sizeof(*(ptr)) - sizeof(LV2_Atom)), (ptr)
/**
Initialise a state map.
diff --git a/plugins/eg-params.lv2/wscript b/plugins/eg-params.lv2/wscript
deleted file mode 100644
index 503e8db..0000000
--- a/plugins/eg-params.lv2/wscript
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-params.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.12.1', uselib_store='LV2')
-
-def build(bld):
- bundle = 'eg-params.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-params.lv2)
- for i in ['params.ttl']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'params.c',
- name = 'params',
- target = 'lv2/%s/params' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'LV2')
diff --git a/plugins/eg-sampler.lv2/manifest.ttl.in b/plugins/eg-sampler.lv2/manifest.ttl.in
index 8a01428..e688256 100644
--- a/plugins/eg-sampler.lv2/manifest.ttl.in
+++ b/plugins/eg-sampler.lv2/manifest.ttl.in
@@ -15,5 +15,5 @@
<http://lv2plug.in/plugins/eg-sampler#ui>
a ui:GtkUI ;
- ui:binary <sampler_ui@LIB_EXT@> ;
+ lv2:binary <sampler_ui@LIB_EXT@> ;
rdfs:seeAlso <sampler.ttl> .
diff --git a/plugins/eg-sampler.lv2/meson.build b/plugins/eg-sampler.lv2/meson.build
new file mode 100644
index 0000000..1283a8f
--- /dev/null
+++ b/plugins/eg-sampler.lv2/meson.build
@@ -0,0 +1,48 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('sampler.c')
+bundle_name = 'eg-sampler.lv2'
+data_filenames = ['manifest.ttl.in', 'sampler.ttl', 'click.wav']
+
+samplerate_dep = dependency('samplerate',
+ version: '>= 0.1.0',
+ required: get_option('plugins'))
+
+sndfile_dep = dependency('sndfile',
+ version: '>= 1.0.0',
+ required: get_option('plugins'))
+
+if samplerate_dep.found() and sndfile_dep.found()
+ module = shared_library(
+ 'sampler',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep, samplerate_dep, sndfile_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+ )
+
+ extension = '.' + module.full_path().split('.')[-1]
+ config = configuration_data({'LIB_EXT': extension})
+
+ foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+ endforeach
+endif
diff --git a/plugins/eg-sampler.lv2/peaks.h b/plugins/eg-sampler.lv2/peaks.h
index ca5328d..7a5f3e3 100644
--- a/plugins/eg-sampler.lv2/peaks.h
+++ b/plugins/eg-sampler.lv2/peaks.h
@@ -153,11 +153,11 @@ peaks_sender_send(PeaksSender* sender,
// eg:offset = OFFSET
lv2_atom_forge_key(forge, uris->peaks_offset);
- lv2_atom_forge_int(forge, sender->current_offset);
+ lv2_atom_forge_int(forge, (int32_t)sender->current_offset);
// eg:total = TOTAL
lv2_atom_forge_key(forge, uris->peaks_total);
- lv2_atom_forge_int(forge, sender->n_peaks);
+ lv2_atom_forge_int(forge, (int32_t)sender->n_peaks);
// eg:magnitudes = Vector<Float>(PEAK, PEAK, ...)
lv2_atom_forge_key(forge, uris->peaks_magnitudes);
diff --git a/plugins/eg-sampler.lv2/sampler.c b/plugins/eg-sampler.lv2/sampler.c
index e7fbbab..c978d2b 100644
--- a/plugins/eg-sampler.lv2/sampler.c
+++ b/plugins/eg-sampler.lv2/sampler.c
@@ -33,6 +33,7 @@
#include "lv2/urid/urid.h"
#include "lv2/worker/worker.h"
+#include <samplerate.h>
#include <sndfile.h>
#include <math.h>
@@ -80,6 +81,7 @@ typedef struct {
bool activated;
bool gain_changed;
bool sample_changed;
+ int sample_rate;
} Sampler;
/**
@@ -96,6 +98,23 @@ typedef struct {
} SampleMessage;
/**
+ Convert an interleaved audio buffer to mono.
+
+ This simply ignores the data on all channels but the first.
+*/
+static sf_count_t
+convert_to_mono(float* data, sf_count_t num_input_frames, uint32_t channels)
+{
+ sf_count_t num_output_frames = 0;
+
+ for (sf_count_t i = 0; i < num_input_frames * channels; i += channels) {
+ data[num_output_frames++] = data[i];
+ }
+
+ return num_output_frames;
+}
+
+/**
Load a new sample and return it.
Since this is of course not a real-time safe action, this is called in the
@@ -103,7 +122,7 @@ typedef struct {
not modified.
*/
static Sample*
-load_sample(LV2_Log_Logger* logger, const char* path)
+load_sample(LV2_Log_Logger* logger, const char* path, const int sample_rate)
{
lv2_log_trace(logger, "Loading %s\n", path);
@@ -115,9 +134,8 @@ load_sample(LV2_Log_Logger* logger, const char* path)
bool error = true;
if (!sndfile || !info->frames) {
lv2_log_error(logger, "Failed to open %s\n", path);
- } else if (info->channels != 1) {
- lv2_log_error(logger, "%s has %d channels\n", path, info->channels);
- } else if (!(data = (float*)malloc(sizeof(float) * info->frames))) {
+ } else if (!(data = (float*)malloc(sizeof(float) * info->frames *
+ info->channels))) {
lv2_log_error(logger, "Failed to allocate memory for sample\n");
} else {
error = false;
@@ -131,9 +149,50 @@ load_sample(LV2_Log_Logger* logger, const char* path)
}
sf_seek(sndfile, 0ul, SEEK_SET);
- sf_read_float(sndfile, data, info->frames);
+ sf_read_float(sndfile, data, info->frames * info->channels);
sf_close(sndfile);
+ if (info->channels != 1) {
+ info->frames = convert_to_mono(data, info->frames, info->channels);
+ info->channels = 1;
+ }
+
+ if (info->samplerate != sample_rate) {
+ lv2_log_trace(logger,
+ "Converting from %d Hz to %d Hz\n",
+ info->samplerate,
+ sample_rate);
+
+ const double src_ratio = (double)sample_rate / (double)info->samplerate;
+ const double output_length = ceil((double)info->frames * src_ratio);
+ const long output_frames = (long)output_length;
+ float* const output_buffer = (float*)malloc(sizeof(float) * output_frames);
+
+ SRC_DATA src_data = {
+ data,
+ output_buffer,
+ info->frames,
+ output_frames,
+ 0,
+ 0,
+ 0,
+ src_ratio,
+ };
+
+ if (src_simple(&src_data, SRC_SINC_BEST_QUALITY, 1) != 0) {
+ lv2_log_error(logger, "Sample rate conversion failed\n");
+ free(output_buffer);
+ } else {
+ // Replace original data with converted buffer
+ free(data);
+ data = output_buffer;
+ info->frames = src_data.output_frames_gen;
+ }
+ } else {
+ lv2_log_trace(
+ logger, "Sample matches the current rate of %d Hz\n", sample_rate);
+ }
+
// Fill sample struct and return it
sample->data = data;
sample->path = (char*)malloc(path_len + 1);
@@ -184,7 +243,7 @@ work(LV2_Handle instance,
}
// Load sample.
- Sample* sample = load_sample(&self->logger, path);
+ Sample* sample = load_sample(&self->logger, path, self->sample_rate);
if (sample) {
// Send new sample to run() to be applied
respond(handle, sizeof(Sample*), &sample);
@@ -280,8 +339,9 @@ instantiate(const LV2_Descriptor* descriptor,
lv2_atom_forge_init(&self->forge, self->map);
peaks_sender_init(&self->psend, self->map);
- self->gain = 1.0f;
- self->gain_dB = 0.0f;
+ self->gain = 1.0f;
+ self->gain_dB = 0.0f;
+ self->sample_rate = (int)rate;
return (LV2_Handle)self;
}
@@ -348,7 +408,9 @@ handle_event(Sampler* self, LV2_Atom_Event* ev)
if (!property) {
lv2_log_error(&self->logger, "Set message with no property\n");
return;
- } else if (property->type != uris->atom_URID) {
+ }
+
+ if (property->type != uris->atom_URID) {
lv2_log_error(&self->logger, "Set property is not a URID\n");
return;
}
@@ -438,20 +500,19 @@ run(LV2_Handle instance, uint32_t sample_count)
// Start a sequence in the notify output port.
lv2_atom_forge_sequence_head(&self->forge, &self->notify_frame, 0);
- // Send update to UI if gain or sample has changed due to state restore
- if (self->gain_changed || self->sample_changed) {
+ // Send update to UI if gain has changed due to state restore
+ if (self->gain_changed) {
lv2_atom_forge_frame_time(&self->forge, 0);
+ write_set_gain(&self->forge, &self->uris, self->gain_dB);
+ self->gain_changed = false;
+ }
- if (self->gain_changed) {
- write_set_gain(&self->forge, &self->uris, self->gain_dB);
- self->gain_changed = false;
- }
-
- if (self->sample_changed) {
- write_set_file(
- &self->forge, &self->uris, self->sample->path, self->sample->path_len);
- self->sample_changed = false;
- }
+ // Send update to UI if sample has changed due to state restore
+ if (self->sample_changed) {
+ lv2_atom_forge_frame_time(&self->forge, 0);
+ write_set_file(
+ &self->forge, &self->uris, self->sample->path, self->sample->path_len);
+ self->sample_changed = false;
}
// Iterate over incoming events, emitting audio along the way
@@ -553,10 +614,13 @@ restore(LV2_Handle instance,
uint32_t valflags = 0;
const void* value =
retrieve(handle, self->uris.eg_sample, &size, &type, &valflags);
+
if (!value) {
lv2_log_error(&self->logger, "Missing eg:sample\n");
return LV2_STATE_ERR_NO_PROPERTY;
- } else if (type != self->uris.atom_Path) {
+ }
+
+ if (type != self->uris.atom_Path) {
lv2_log_error(&self->logger, "Non-path eg:sample\n");
return LV2_STATE_ERR_BAD_TYPE;
}
@@ -569,7 +633,7 @@ restore(LV2_Handle instance,
if (!self->activated || !schedule) {
// No scheduling available, load sample immediately
lv2_log_trace(&self->logger, "Synchronous restore\n");
- Sample* sample = load_sample(&self->logger, path);
+ Sample* sample = load_sample(&self->logger, path, self->sample_rate);
if (sample) {
free_sample(self, self->sample);
self->sample = sample;
@@ -593,11 +657,14 @@ restore(LV2_Handle instance,
// Get param:gain from state
value = retrieve(handle, self->uris.param_gain, &size, &type, &valflags);
+
if (!value) {
// Not an error, since older versions did not save this property
lv2_log_note(&self->logger, "Missing param:gain\n");
return LV2_STATE_SUCCESS;
- } else if (type != self->uris.atom_Float) {
+ }
+
+ if (type != self->uris.atom_Float) {
lv2_log_error(&self->logger, "Non-float param:gain\n");
return LV2_STATE_ERR_BAD_TYPE;
}
@@ -614,11 +681,15 @@ extension_data(const char* uri)
{
static const LV2_State_Interface state = {save, restore};
static const LV2_Worker_Interface worker = {work, work_response, NULL};
+
if (!strcmp(uri, LV2_STATE__interface)) {
return &state;
- } else if (!strcmp(uri, LV2_WORKER__interface)) {
+ }
+
+ if (!strcmp(uri, LV2_WORKER__interface)) {
return &worker;
}
+
return NULL;
}
diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c
index 533e720..630fc22 100644
--- a/plugins/eg-sampler.lv2/sampler_ui.c
+++ b/plugins/eg-sampler.lv2/sampler_ui.c
@@ -365,7 +365,7 @@ port_event(LV2UI_Handle handle,
const LV2_Atom_Object* obj = (const LV2_Atom_Object*)atom;
if (obj->body.otype == ui->uris.patch_Set) {
const char* path = read_set_file(&ui->uris, obj);
- if (path && (!ui->filename || strcmp(path, ui->filename))) {
+ if (path && (!ui->filename || !!strcmp(path, ui->filename))) {
g_free(ui->filename);
ui->filename = g_strdup(path);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(ui->file_button),
@@ -447,11 +447,15 @@ extension_data(const char* uri)
{
static const LV2UI_Show_Interface show = {ui_show, ui_hide};
static const LV2UI_Idle_Interface idle = {ui_idle};
+
if (!strcmp(uri, LV2_UI__showInterface)) {
return &show;
- } else if (!strcmp(uri, LV2_UI__idleInterface)) {
+ }
+
+ if (!strcmp(uri, LV2_UI__idleInterface)) {
return &idle;
}
+
return NULL;
}
diff --git a/plugins/eg-sampler.lv2/waf b/plugins/eg-sampler.lv2/waf
deleted file mode 120000
index 59a1ac9..0000000
--- a/plugins/eg-sampler.lv2/waf
+++ /dev/null
@@ -1 +0,0 @@
-../../waf \ No newline at end of file
diff --git a/plugins/eg-sampler.lv2/wscript b/plugins/eg-sampler.lv2/wscript
deleted file mode 100644
index 8c640c1..0000000
--- a/plugins/eg-sampler.lv2/wscript
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-sampler.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
- conf.check_pkg('sndfile >= 1.0.0', uselib_store='SNDFILE')
- conf.check_pkg('gtk+-2.0 >= 2.18.0',
- uselib_store='GTK2',
- system=True,
- mandatory=False)
- conf.check(features='c cshlib', lib='m', uselib_store='M', mandatory=False)
-
-def build(bld):
- bundle = 'eg-sampler.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- bld(features = 'subst',
- source = 'manifest.ttl.in',
- target = 'lv2/%s/%s' % (bundle, 'manifest.ttl'),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Copy other data files to build bundle (build/eg-sampler.lv2)
- for i in ['sampler.ttl', 'click.wav']:
- bld(features = 'subst',
- is_copy = True,
- source = i,
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'sampler.c',
- name = 'sampler',
- target = 'lv2/%s/sampler' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = ['M', 'SNDFILE', 'LV2'])
-
- # Build UI library
- if bld.env.HAVE_GTK2:
- obj = bld(features = 'c cshlib lv2lib',
- source = 'sampler_ui.c',
- name = 'sampler_ui',
- target = 'lv2/%s/sampler_ui' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = ['GTK2', 'LV2'])
diff --git a/plugins/eg-scope.lv2/examploscope.c b/plugins/eg-scope.lv2/examploscope.c
index ec013a1..8bc4ca1 100644
--- a/plugins/eg-scope.lv2/examploscope.c
+++ b/plugins/eg-scope.lv2/examploscope.c
@@ -249,7 +249,7 @@ run(LV2_Handle handle, uint32_t n_samples)
// Add UI state as properties
lv2_atom_forge_key(&self->forge, self->uris.ui_spp);
- lv2_atom_forge_int(&self->forge, self->ui_spp);
+ lv2_atom_forge_int(&self->forge, (int32_t)self->ui_spp);
lv2_atom_forge_key(&self->forge, self->uris.ui_amp);
lv2_atom_forge_float(&self->forge, self->ui_amp);
lv2_atom_forge_key(&self->forge, self->uris.param_sampleRate);
@@ -295,7 +295,8 @@ run(LV2_Handle handle, uint32_t n_samples)
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]);
+ tx_rawaudio(
+ &self->forge, &self->uris, (int32_t)c, n_samples, self->input[c]);
}
// If not processing audio in-place, forward audio
if (self->input[c] != self->output[c]) {
diff --git a/plugins/eg-scope.lv2/examploscope_ui.c b/plugins/eg-scope.lv2/examploscope_ui.c
index e601843..8a9b588 100644
--- a/plugins/eg-scope.lv2/examploscope_ui.c
+++ b/plugins/eg-scope.lv2/examploscope_ui.c
@@ -261,7 +261,9 @@ on_expose_event(GtkWidget* widget, GdkEventExpose* ev, gpointer data)
for (uint32_t i = start; i < end; ++i) {
if (i == chn->idx) {
continue;
- } else if (i % 2) {
+ }
+
+ if (i % 2) {
cairo_line_to(cr, i - .5, CYPOS(chn->data_min[i]));
cairo_line_to(cr, i - .5, CYPOS(chn->data_max[i]));
++pathlength;
diff --git a/plugins/eg-scope.lv2/manifest.ttl.in b/plugins/eg-scope.lv2/manifest.ttl.in
index a64aff1..66c3c9d 100644
--- a/plugins/eg-scope.lv2/manifest.ttl.in
+++ b/plugins/eg-scope.lv2/manifest.ttl.in
@@ -17,5 +17,5 @@
# ==== Gtk 2.0 UI ====
<http://lv2plug.in/plugins/eg-scope#ui>
a ui:GtkUI ;
- ui:binary <examploscope_ui@LIB_EXT@> ;
+ lv2:binary <examploscope_ui@LIB_EXT@> ;
rdfs:seeAlso <examploscope.ttl> .
diff --git a/plugins/eg-scope.lv2/meson.build b/plugins/eg-scope.lv2/meson.build
new file mode 100644
index 0000000..ecf01b2
--- /dev/null
+++ b/plugins/eg-scope.lv2/meson.build
@@ -0,0 +1,41 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+plugin_sources = files('examploscope.c')
+bundle_name = 'eg-scope.lv2'
+data_filenames = ['manifest.ttl.in', 'examploscope.ttl.in']
+
+module = shared_library(
+ 'examploscope',
+ plugin_sources,
+ c_args: c_suppressions,
+ dependencies: [lv2_dep, m_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ install_dir: lv2dir / bundle_name,
+ name_prefix: '',
+)
+
+config = configuration_data(
+ {
+ 'LIB_EXT': '.' + module.full_path().split('.')[-1],
+ }
+)
+
+foreach filename : data_filenames
+ if filename.endswith('.in')
+ configure_file(
+ configuration: config,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename.substring(0, -3),
+ )
+ else
+ configure_file(
+ copy: true,
+ input: files(filename),
+ install_dir: lv2dir / bundle_name,
+ output: filename,
+ )
+ endif
+endforeach
diff --git a/plugins/eg-scope.lv2/wscript b/plugins/eg-scope.lv2/wscript
deleted file mode 100644
index 4333502..0000000
--- a/plugins/eg-scope.lv2/wscript
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-import re
-
-# Variables for 'waf dist'
-APPNAME = 'eg-scope.lv2'
-VERSION = '1.0.0'
-
-# Mandatory variables
-top = '.'
-out = 'build'
-
-def options(opt):
- opt.load('compiler_c')
- opt.load('lv2')
- autowaf.set_options(opt)
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- conf.load('lv2', cache=True)
- conf.load('autowaf', cache=True)
-
- conf.check_pkg('lv2 >= 1.2.1', uselib_store='LV2')
- conf.check_pkg('cairo >= 1.8.10', uselib_store='CAIRO')
- conf.check_pkg('gtk+-2.0 >= 2.18.0',
- uselib_store='GTK2',
- system=True,
- mandatory=False)
-
-def build(bld):
- bundle = 'eg-scope.lv2'
-
- # Build manifest.ttl by substitution (for portable lib extension)
- for i in ['manifest.ttl', 'examploscope.ttl']:
- bld(features = 'subst',
- source = i + '.in',
- target = 'lv2/%s/%s' % (bundle, i),
- install_path = '${LV2DIR}/%s' % bundle,
- LIB_EXT = bld.env.LV2_LIB_EXT)
-
- # Build plugin library
- obj = bld(features = 'c cshlib lv2lib',
- source = 'examploscope.c',
- name = 'examploscope',
- target = 'lv2/%s/examploscope' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'LV2')
-
- # Build UI library
- if bld.env.HAVE_GTK2:
- obj = bld(features = 'c cshlib lv2lib',
- source = 'examploscope_ui.c',
- name = 'examploscope_ui',
- target = 'lv2/%s/examploscope_ui' % bundle,
- install_path = '${LV2DIR}/%s' % bundle,
- use = 'GTK2 CAIRO LV2')
diff --git a/plugins/literasc.py b/plugins/literasc.py
index 0bcd8f2..74b13a7 100755
--- a/plugins/literasc.py
+++ b/plugins/literasc.py
@@ -1,127 +1,143 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Literasc, a simple literate programming tool for C, C++, and Turtle.
-# Copyright 2012 David Robillard <d@drobilla.net>
-#
-# Unlike many LP tools, this tool uses normal source code as input, there is no
-# tangle/weave and no special file format. The literate parts of the program
-# are written in comments, which are emitted as paragraphs of regular text
-# interleaved with code. Asciidoc is both the comment and output syntax.
+#!/usr/bin/env python3
+
+# Copyright 2012-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: ISC
+
+"""
+A simple literate programming tool for C, C++, and Turtle.
+
+Unlike many LP tools, this tool uses normal source code as input, there is no
+tangle/weave and no special file format. The literate parts of the program are
+written in comments, which are emitted as paragraphs of regular text
+interleaved with code. Asciidoc is both the comment and output syntax.
+"""
import os
import re
import sys
+
def format_text(text):
- 'Format a text (comment) fragment and return it as a marked up string'
- return '\n\n' + re.sub('\n *', '\n', text.strip()) + '\n\n'
+ "Format a text (comment) fragment and return it as a marked up string."
+ return "\n\n" + re.sub("\n *", "\n", text.strip()) + "\n\n"
+
def format_code(lang, code):
- if code.strip() == '':
+ "Format a block of code and return it as a marked up string."
+
+ if code.strip() == "":
return code
- head = '[source,%s]' % lang
- sep = '-' * len(head) + '\n'
- return head + '\n' + sep + code.strip('\n') + '\n' + sep
+ head = f"[source,{lang}]"
+ code = code.strip("\n")
+ sep = "-" * len(head)
+ return "\n".join([head, sep, code, sep]) + "\n"
+
-def format_c_source(filename, file):
- output = '=== %s ===\n' % os.path.basename(filename)
- chunk = ''
- prev_c = 0
- in_comment = False
+def format_c_source(filename, in_file):
+ "Format an annotated C source file as a marked up string."
+
+ output = f"=== {os.path.basename(filename)} ===\n"
+ chunk = ""
+ prev_c = 0
+ in_comment = False
in_comment_start = False
- n_stars = 0
- code = ''
- for line in file:
- code += line
+ n_stars = 0
+ code = "".join(in_file)
# Skip initial license comment
- if code[0:2] == '/*':
- code = code[code.find('*/') + 2:]
+ if code[0:2] == "/*":
+ end = code.find("*/") + 2
+ code = code[end:]
- for c in code:
- if prev_c == '/' and c == '*':
+ def last_chunk(chunk):
+ length = len(chunk) - 1
+ return chunk[0:length]
+
+ for char in code:
+ if prev_c == "/" and char == "*":
in_comment_start = True
n_stars = 1
elif in_comment_start:
- if c == '*':
+ if char == "*":
n_stars += 1
else:
if n_stars > 1:
- output += format_code('c', chunk[0:len(chunk) - 1])
- chunk = ''
+ output += format_code("c", last_chunk(chunk))
+ chunk = ""
in_comment = True
else:
- chunk += '*' + c
+ chunk += "*" + char
in_comment_start = False
- elif in_comment and prev_c == '*' and c == '/':
+ elif in_comment and prev_c == "*" and char == "/":
if n_stars > 1:
- output += format_text(chunk[0:len(chunk) - 1])
+ output += format_text(last_chunk(chunk))
else:
- output += format_code('c', '/* ' + chunk[0:len(chunk) - 1] + '*/')
+ output += format_code("c", "/* " + last_chunk(chunk) + "*/")
in_comment = False
in_comment_start = False
- chunk = ''
- elif in_comment_start and c == '*':
- n_stars += 1
+ chunk = ""
else:
- chunk += c
- prev_c = c
+ chunk += char
+
+ prev_c = char
+
+ return output + format_code("c", chunk)
- return output + format_code('c', chunk)
-def format_ttl_source(filename, file):
- output = '=== %s ===\n' % os.path.basename(filename)
+def format_ttl_source(filename, in_file):
+ "Format an annotated Turtle source file as a marked up string."
+
+ output = f"=== {os.path.basename(filename)} ===\n"
in_comment = False
- chunk = ''
- for line in file:
- is_comment = line.strip().startswith('#')
+ chunk = ""
+ for line in in_file:
+ is_comment = line.strip().startswith("#")
if in_comment:
if is_comment:
- chunk += line.strip().lstrip('# ') + ' \n'
+ chunk += line.strip().lstrip("# ") + " \n"
else:
output += format_text(chunk)
in_comment = False
chunk = line
else:
if is_comment:
- output += format_code('turtle', chunk)
+ output += format_code("turtle", chunk)
in_comment = True
- chunk = line.strip().lstrip('# ') + ' \n'
+ chunk = line.strip().lstrip("# ") + " \n"
else:
chunk += line
if in_comment:
return output + format_text(chunk)
- else:
- return output + format_code('turtle', chunk)
+
+ return output + format_code("turtle", chunk)
+
def gen(out, filenames):
+ "Write markup generated from filenames to an output file."
+
for filename in filenames:
- file = open(filename)
- if not file:
- sys.stderr.write('Failed to open file %s\n' % filename)
- continue
-
- if filename.endswith('.c') or filename.endswith('.h'):
- out.write(format_c_source(filename, file))
- elif filename.endswith('.ttl') or filename.endswith('.ttl.in'):
- out.write(format_ttl_source(filename, file))
- elif filename.endswith('.txt'):
- for line in file:
- out.write(line)
- out.write('\n')
- else:
- sys.stderr.write("Unknown source format `%s'" % (
- filename[filename.find('.'):]))
+ with open(filename, "r", encoding="utf-8") as in_file:
+ if filename.endswith(".c") or filename.endswith(".h"):
+ out.write(format_c_source(filename, in_file))
+ elif filename.endswith(".ttl") or filename.endswith(".ttl.in"):
+ out.write(format_ttl_source(filename, in_file))
+ elif filename.endswith(".txt"):
+ for line in in_file:
+ out.write(line)
+ out.write("\n")
+ else:
+ sys.stderr.write(
+ f"Unknown source format `{filename.splitext()[1]}`\n"
+ )
- file.close()
if __name__ == "__main__":
if len(sys.argv) < 2:
- sys.stderr.write('Usage: %s FILENAME...\n' % sys.argv[1])
+ sys.stderr.write(f"Usage: {sys.argv[0]} OUT_FILE IN_FILE...\n")
sys.exit(1)
- gen(sys.argv[1:])
+ with open(sys.argv[1], "w", encoding="utf-8") as out_file:
+ gen(out_file, sys.argv[2:])
diff --git a/plugins/meson.build b/plugins/meson.build
new file mode 100644
index 0000000..08b3feb
--- /dev/null
+++ b/plugins/meson.build
@@ -0,0 +1,82 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR ISC
+
+if not get_option('plugins').disabled()
+ m_dep = cc.find_library('m', required: false)
+
+ subdir('eg-amp.lv2')
+ subdir('eg-fifths.lv2')
+ subdir('eg-metro.lv2')
+ subdir('eg-midigate.lv2')
+ subdir('eg-params.lv2')
+ subdir('eg-sampler.lv2')
+ subdir('eg-scope.lv2')
+endif
+
+if not get_option('docs').disabled()
+ literasc_py = files('literasc.py')
+ asciidoc = find_program('asciidoc', required: get_option('docs'))
+
+ if asciidoc.found()
+ book_inputs = files(
+ 'README.txt',
+ 'eg-amp.lv2/README.txt',
+ 'eg-amp.lv2/amp.c',
+ 'eg-amp.lv2/amp.ttl',
+ 'eg-fifths.lv2/README.txt',
+ 'eg-fifths.lv2/fifths.c',
+ 'eg-fifths.lv2/fifths.ttl',
+ 'eg-fifths.lv2/uris.h',
+ 'eg-metro.lv2/README.txt',
+ 'eg-metro.lv2/metro.c',
+ 'eg-metro.lv2/metro.ttl',
+ 'eg-midigate.lv2/README.txt',
+ 'eg-midigate.lv2/midigate.c',
+ 'eg-midigate.lv2/midigate.ttl',
+ 'eg-params.lv2/README.txt',
+ 'eg-params.lv2/params.c',
+ 'eg-params.lv2/params.ttl',
+ 'eg-params.lv2/state_map.h',
+ 'eg-sampler.lv2/README.txt',
+ 'eg-sampler.lv2/atom_sink.h',
+ 'eg-sampler.lv2/peaks.h',
+ 'eg-sampler.lv2/sampler.c',
+ 'eg-sampler.lv2/sampler.ttl',
+ 'eg-sampler.lv2/sampler_ui.c',
+ 'eg-sampler.lv2/uris.h',
+ 'eg-scope.lv2/README.txt',
+ 'eg-scope.lv2/examploscope.c',
+ 'eg-scope.lv2/examploscope_ui.c',
+ 'eg-scope.lv2/uris.h',
+ )
+
+ # Compile book sources into book.txt asciidoc source
+ book_txt = custom_target(
+ 'book.txt',
+ command: [
+ literasc_py,
+ '@OUTPUT@',
+ '@INPUT@',
+ ],
+ input: book_inputs,
+ output: 'book.txt',
+ )
+
+ # Run asciidoc to generate book.html
+ book_html = custom_target(
+ 'book.html',
+ build_by_default: true,
+ command: [
+ asciidoc,
+ '-a', 'stylesdir=' + lv2_source_root / 'doc' / 'style',
+ '-a', 'source-highlighter=pygments',
+ '-a', 'pygments-style=' + lv2_source_root / 'doc' / 'style' / 'style.css',
+ '-b', 'html',
+ '-o', '@OUTPUT@',
+ '@INPUT@',
+ ],
+ input: book_txt,
+ output: 'book.html',
+ )
+ endif
+endif
diff --git a/plugins/wscript b/plugins/wscript
deleted file mode 100644
index f5f6571..0000000
--- a/plugins/wscript
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import os
-
-from waflib.extras import autowaf as autowaf
-import waflib.Logs as Logs
-
-import literasc
-
-def confgure(conf):
- pass
-
-def bld_book_src(task):
- filenames = []
- for i in task.inputs:
- filenames += [i.abspath()]
-
- literasc.gen(open(task.outputs[0].abspath(), 'w'), filenames)
-
-def build(bld):
- files = [bld.path.find_node('README.txt')]
- for i in ['eg-amp.lv2',
- 'eg-midigate.lv2',
- 'eg-fifths.lv2',
- 'eg-metro.lv2',
- 'eg-sampler.lv2',
- 'eg-scope.lv2',
- 'eg-params.lv2']:
- files += bld.path.ant_glob('%s/*.txt' % i)
- files += bld.path.ant_glob('%s/manifest.ttl*' % i)
- files += bld.path.ant_glob('%s/*.ttl' % i)
- files += bld.path.ant_glob('%s/*.c' % i)
- files += bld.path.ant_glob('%s/*.h' % i)
-
- # Compile book sources into book.txt asciidoc source
- bld(rule = bld_book_src,
- source = files,
- target = 'book.txt')
-
- # Run asciidoc to generate book.html
- stylesdir = bld.path.find_node('../doc/').abspath()
- pygments_style = bld.path.find_node('../doc/style.css').abspath()
- bld(rule = 'asciidoc -a stylesdir=%s -a source-highlighter=pygments -a pygments-style=%s -b html -o ${TGT} ${SRC}' % (
- stylesdir, pygments_style),
- source = 'book.txt',
- target = 'book.html')