Skip to content

Commit

Permalink
Bugfix/dpf improvements (Wasted-Audio#28)
Browse files Browse the repository at this point in the history
* example.pd needs at least one receiver object (parameter) for DPF (otherwise it segfaults)

* update readme. enable midi-out. some scaling for delayMs, adapted from old vst2 version

* enable triggers (to use as bang object)

* use patch_meta_file var instead

* add meta to DPF; use selector for meta; clean up DPF code; add some docs to DPF example dir
  • Loading branch information
dromer committed Aug 13, 2021
1 parent 5e48364 commit 7028357
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 65 deletions.
2 changes: 0 additions & 2 deletions docs/08.dpf.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ Each [exposed parameter](02.getting_started.md#exposing-parameters) will automat
## MIDI Control
In order to receive MIDI note on and off events, as well as control change messages, the `[notein]` and `[ctlin]` objects should be used, respectively.

:warning: the following example currently seems to segfault :warning:

![notein](img/docs_notein.png)


Expand Down
Binary file modified docs/img/docs_notein.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions examples/daisy/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Daisy Generator example help

To build these test patches:

Install `arm-none-eabi-gcc` on your respective OS.
Expand Down
4 changes: 3 additions & 1 deletion examples/daisy/patch_meta.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"board": "patch"
"daisy": {
"board": "patch"
}
}
4 changes: 3 additions & 1 deletion examples/daisy/petal_meta.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"board": "petal"
"daisy": {
"board": "petal"
}
}
4 changes: 3 additions & 1 deletion examples/daisy/pod_meta.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"board": "pod"
"daisy": {
"board": "pod"
}
}
4 changes: 3 additions & 1 deletion examples/daisy/seed_meta.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"board": "seed"
"daisy": {
"board": "seed"
}
}
22 changes: 22 additions & 0 deletions examples/dpf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Distrho Plugin Format Generator example help

DPF generator supports extra configuration via a supplied meta-data file. Each of these are optional and have either a default value or are entirely optional (description and homepage). Midi i/o ports are on by default, but can be set to `0` and they will be disabled.

```json
{
"dpf": {
"description": "super simple test patch",
"maker": "nobody",
"homepage": "https://wasted.audio/plugin/test",
"plugin_uri": "lv2://wasted.audio/lv2/testplugin",
"version": "6, 6, 6",
"license": "WTFPL",
"midi_input": 0,
"midi_output": 1,
"plugin_formats": [
"lv2_dsp",
"vst"
]
}
}
```
22 changes: 13 additions & 9 deletions hvcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def generate_extern_info(hvir, results):
}


def compile_dataflow(in_path, out_dir, patch_name=None, patch_meta=None,
def compile_dataflow(in_path, out_dir, patch_name=None, patch_meta_file=None,
search_paths=None, generators=None, verbose=False,
copyright=None, hvir=None):

Expand All @@ -145,15 +145,18 @@ def compile_dataflow(in_path, out_dir, patch_name=None, patch_meta=None,
if not os.path.basename("c"):
return add_error(results, "Can only process c directories.")
else:
return add_error(results, "Unknown input path {0}".format(in_path))
return add_error(results, f"Unknown input path {in_path}")

if patch_meta:
if os.path.isfile(patch_meta):
with open(patch_meta) as json_file:
# meta-data file
if patch_meta_file:
if os.path.isfile(patch_meta_file):
with open(patch_meta_file) as json_file:
try:
patch_meta = json.load(json_file)
except Exception as e:
raise e
return add_error(results, f"Unable to open json_file: {e}")
else:
patch_meta = {}

patch_name = patch_name or "heavy"
generators = generators or {"c"}
Expand Down Expand Up @@ -235,7 +238,7 @@ def compile_dataflow(in_path, out_dir, patch_name=None, patch_meta=None,
else:
return add_error(results, "Cannot find hvir file.")
except Exception as e:
return add_error(results, "ir could not be found or loaded: {0}.".format(e))
return add_error(results, f"ir could not be found or loaded: {e}.")

# run the c2x generators, merge the results
num_input_channels = hvir["signal"]["numInputBuffers"]
Expand Down Expand Up @@ -286,7 +289,7 @@ def compile_dataflow(in_path, out_dir, patch_name=None, patch_meta=None,
c_src_dir=c_src_dir,
out_dir=os.path.join(out_dir, "daisy"),
patch_name=patch_name,
board=patch_meta["board"],
patch_meta=patch_meta,
num_input_channels=num_input_channels,
num_output_channels=num_output_channels,
externs=externs,
Expand All @@ -300,6 +303,7 @@ def compile_dataflow(in_path, out_dir, patch_name=None, patch_meta=None,
c_src_dir=c_src_dir,
out_dir=os.path.join(out_dir, "plugin"),
patch_name=patch_name,
patch_meta=patch_meta,
num_input_channels=num_input_channels,
num_output_channels=num_output_channels,
externs=externs,
Expand Down Expand Up @@ -400,7 +404,7 @@ def main():
in_path=in_path,
out_dir=args.out_dir or os.path.dirname(in_path),
patch_name=args.name,
patch_meta=args.meta,
patch_meta_file=args.meta,
search_paths=args.search_paths,
generators=args.gen,
verbose=args.verbose,
Expand Down
11 changes: 8 additions & 3 deletions hvcc/generators/c2daisy/c2daisy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@ class c2daisy:

@classmethod
def compile(clazz, c_src_dir, out_dir, externs,
patch_name=None, board: str = None,
patch_name=None, patch_meta: dict = None,
num_input_channels=0, num_output_channels=0,
copyright=None, verbose=False):

tick = time.time()

receiver_list = externs['parameters']['in']

patch_name = patch_name or "heavy"
board = board or "seed"
if patch_meta:
patch_name = patch_meta.get("name", patch_name)
daisy_meta = patch_meta.get("daisy")
else:
daisy_meta = {}

board = daisy_meta.get("board", "seed")

copyright_c = copyright_manager.get_copyright_for_c(copyright)
# copyright_plist = copyright or u"Copyright {0} Enzien Audio, Ltd." \
Expand Down
15 changes: 12 additions & 3 deletions hvcc/generators/c2dpf/c2dpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class c2dpf:

@classmethod
def filter_uniqueid(clazz, s):
""" Return a unique id (in hexadcemial) for the VST interface.
""" Return a unique id (in hexadecemial) for the Plugin interface.
"""
s = hashlib.md5(s.encode('utf-8'))
s = s.hexdigest().upper()[0:8]
Expand All @@ -23,14 +23,19 @@ def filter_uniqueid(clazz, s):

@classmethod
def compile(clazz, c_src_dir, out_dir, externs,
patch_name=None, num_input_channels=0, num_output_channels=0,
patch_name=None, patch_meta: dict = None,
num_input_channels=0, num_output_channels=0,
copyright=None, verbose=False):

tick = time.time()

receiver_list = externs['parameters']['in']

patch_name = patch_name or "heavy"
if patch_meta:
patch_name = patch_meta.get("name", patch_name)
dpf_meta = patch_meta.get("dpf", {})
else:
dpf_meta = {}

copyright_c = copyright_manager.get_copyright_for_c(copyright)
# copyright_plist = copyright or u"Copyright {0} Enzien Audio, Ltd." \
Expand Down Expand Up @@ -61,6 +66,7 @@ def compile(clazz, c_src_dir, out_dir, externs,
with open(dpf_h_path, "w") as f:
f.write(env.get_template("HeavyDPF.hpp").render(
name=patch_name,
meta=dpf_meta,
class_name=f"HeavyDPF_{patch_name}",
num_input_channels=num_input_channels,
num_output_channels=num_output_channels,
Expand All @@ -70,6 +76,7 @@ def compile(clazz, c_src_dir, out_dir, externs,
with open(dpf_cpp_path, "w") as f:
f.write(env.get_template("HeavyDPF.cpp").render(
name=patch_name,
meta=dpf_meta,
class_name=f"HeavyDPF_{patch_name}",
num_input_channels=num_input_channels,
num_output_channels=num_output_channels,
Expand All @@ -80,6 +87,7 @@ def compile(clazz, c_src_dir, out_dir, externs,
with open(dpf_h_path, "w") as f:
f.write(env.get_template("DistrhoPluginInfo.h").render(
name=patch_name,
meta=dpf_meta,
class_name=f"HeavyDPF_{patch_name}",
num_input_channels=num_input_channels,
num_output_channels=num_output_channels,
Expand All @@ -99,6 +107,7 @@ def compile(clazz, c_src_dir, out_dir, externs,
with open(os.path.join(source_dir, "Makefile"), "w") as f:
f.write(env.get_template("Makefile").render(
name=patch_name,
meta=dpf_meta,
class_name=f"HeavyDPF_{patch_name}"))

buildjson.generate_json(
Expand Down
35 changes: 35 additions & 0 deletions hvcc/generators/c2dpf/static/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Distrho Plugin Format

This output is for the Distrho Plugin Format ([DPF](https://github.com/DISTRHO/DPF)), and can be used to build LV2, VST2 and jack standalone versions of your Heavy code.

# Build Instructions

Make sure you have a (recent) DPF in the root of your output directory

`$ git clone https://github.com/DISTRHO/DPF.git <out_dir>/dpf`

Then compile the plugins from the source folder:

`$ cd <out_dir>/plugin/source/ && make`

This will result in an `<out_dir>/bin/` folder with all binary assets.

## LV2

After this you will likely have to create the `.ttl` files for the LV2 version. First make sure you have a functioning `lv2_ttl_generator`:

`$ cd <out_dir>/dpf/utils/lv2-ttl-generator && make`

Then run it on your LV2 build from the binary directory and move the files into the target dir:

`$ cd bin/ && ../dpf/utils/lv2_ttl_generator <plugin>.lv2/<plugin>_dsp.so && mv *ttl <plugin>.lv2/`

You can now add your `<plugin>.lv2/` forder to your local `~/.lv2/` directory.

## VST2

The VST2, `bin/<plugin>-vst.so`, can be placed directly into your `~/.vst/` dir and accessed by your DAW of choice.

## Jack

The Jack binary can be executed in place and used to test functionality `./bin/<plugin>`. Currently there is no UI, so this is not recommended. You will have to be running jack in order to use this.
22 changes: 9 additions & 13 deletions hvcc/generators/c2dpf/templates/DistrhoPluginInfo.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
{{copyright}}

#pragma once

#define DISTRHO_PLUGIN_BRAND "Wasted Audio"
#define DISTRHO_PLUGIN_NAME "{{name}}"
{% if meta.plugin_uri is defined %}
#define DISTRHO_PLUGIN_URI "{{meta.plugin_uri}}"
{% else %}
#define DISTRHO_PLUGIN_URI "http://wasted.audio/lv2/plugin/{{name}}"
#define DISTRHO_PLUGIN_HOMEPAGE "https://github.com/wasted.audio/{{name}}"
#define DISTRHO_PLUGIN_UNIQUE_ID 'p','l','u','g'
#define DISTRHO_PLUGIN_VERSION 0,0,0
#define DISTRHO_PLUGIN_LABEL "my plugin"
#define DISTRHO_PLUGIN_LICENSE "http://spdx.org/licenses/BSL-1.0"
#define DISTRHO_PLUGIN_MAKER "Wasted Audio"
#define DISTRHO_PLUGIN_DESCRIPTION "a plugin that does stuff"
{% endif %}
#define DISTRHO_PLUGIN_NUM_INPUTS {{num_input_channels}}
#define DISTRHO_PLUGIN_NUM_OUTPUTS {{num_output_channels}}
#define DISTRHO_PLUGIN_IS_SYNTH {{1 if num_input_channels == 0 and num_output_channels > 0 else 1}}
#define DISTRHO_PLUGIN_HAS_UI 0
#define DISTRHO_PLUGIN_HAS_EMBED_UI 0
#define DISTRHO_PLUGIN_HAS_EXTERNAL_UI 0
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0
#define DISTRHO_PLUGIN_WANT_STATE 0
#define DISTRHO_PLUGIN_WANT_FULL_STATE 0
#define DISTRHO_PLUGIN_NUM_PROGRAMS 0
#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1
#define DISTRHO_PLUGIN_WANT_MIDI_INPUT {{meta.midi_input if meta.midi_input is defined else 1}}
#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT {{meta.midi_output if meta.midi_output is defined else 1}}

// for level monitoring
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0
Loading

0 comments on commit 7028357

Please sign in to comment.