Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pydantic types for Metadata input #197

Merged
merged 14 commits into from
Sep 18, 2024
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Next Release
Features:

* Only disable DSP with new `--nodsp` flag
* Use pydantic types to define metadata objects
* DPF: CV flag in portgroups

0.12.0
-----
Expand Down
4 changes: 1 addition & 3 deletions docs/03.gen.daisy.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ Daisy is an embedded platform for music. It features everything you need for cre

Currently daisy platform is supported for:

* `seed`
* `pod`
* `petal`
* `patch`
* `patch_init`
* `patch_sm`
* `field`

Which can be configured using the `-m` metadata.json `daisy.board` setting:

```json
{
"daisy": {
"board": "seed"
"board": "pod"
}
}
```
Expand Down
6 changes: 3 additions & 3 deletions examples/dpf/dpf_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
"midi_input": 1,
"midi_output": 0,
"plugin_formats": [
"lv2_dsp",
"vst",
"lv2_sep",
"vst2",
"jack"
]
}
}
}
8 changes: 5 additions & 3 deletions hvcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from hvcc.generators.c2pdext import c2pdext
from hvcc.generators.c2wwise import c2wwise
from hvcc.generators.c2unity import c2unity
from hvcc.generators.types.meta import Meta


class Colours:
Expand Down Expand Up @@ -214,7 +215,7 @@ def compile_dataflow(
) -> OrderedDict:

results: OrderedDict = OrderedDict() # default value, empty dictionary
patch_meta = {}
patch_meta = Meta()

# basic error checking on input
if os.path.isfile(in_path):
Expand All @@ -231,11 +232,12 @@ def compile_dataflow(
if os.path.isfile(patch_meta_file):
with open(patch_meta_file) as json_file:
try:
patch_meta = json.load(json_file)
patch_meta_json = json.load(json_file)
patch_meta = Meta(**patch_meta_json)
except Exception as e:
return add_error(results, f"Unable to open json_file: {e}")

patch_name = patch_meta.get("name", patch_name)
patch_name = patch_meta.name or patch_name
generators = ["c"] if generators is None else [x.lower() for x in generators]

if in_path.endswith((".pd")):
Expand Down
42 changes: 17 additions & 25 deletions hvcc/generators/c2daisy/c2daisy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import time
import json2daisy # type: ignore

from typing import Dict, Optional
from typing import Any, Dict, Optional

from ..copyright import copyright_manager
from ..types.meta import Meta, Daisy
from . import parameters


Expand All @@ -33,7 +34,7 @@ def compile(
out_dir: str,
externs: Dict,
patch_name: Optional[str] = None,
patch_meta: Optional[Dict] = None,
patch_meta: Meta = Meta(),
num_input_channels: int = 0,
num_output_channels: int = 0,
copyright: Optional[str] = None,
Expand All @@ -44,17 +45,10 @@ def compile(

out_dir = os.path.join(out_dir, "daisy")

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", "pod")
daisy_meta: Daisy = patch_meta.daisy
board = daisy_meta.board

copyright_c = copyright_manager.get_copyright_for_c(copyright)
# copyright_plist = copyright or u"Copyright {0} Enzien Audio, Ltd." \
# " All Rights Reserved.".format(datetime.datetime.now().year)

try:
# ensure that the output directory does not exist
Expand All @@ -69,8 +63,8 @@ def compile(
source_dir = os.path.join(out_dir, "source")
shutil.copytree(c_src_dir, source_dir)

if daisy_meta.get('board_file'):
header, board_info = json2daisy.generate_header_from_file(daisy_meta['board_file'])
if daisy_meta.board_file is not None:
header, board_info = json2daisy.generate_header_from_file(daisy_meta.board_file)
else:
header, board_info = json2daisy.generate_header_from_name(board)

Expand All @@ -87,12 +81,12 @@ def compile(
component_glue['num_output_channels'] = num_output_channels
component_glue['has_midi'] = board_info['has_midi']
component_glue['displayprocess'] = board_info['displayprocess']
component_glue['debug_printing'] = daisy_meta.get('debug_printing', False)
component_glue['usb_midi'] = daisy_meta.get('usb_midi', False)
component_glue['debug_printing'] = daisy_meta.debug_printing
component_glue['usb_midi'] = daisy_meta.usb_midi
component_glue['pool_sizes_kb'] = externs["memoryPoolSizesKb"]

# samplerate
samplerate = daisy_meta.get('samplerate', 48000)
samplerate = daisy_meta.samplerate
if samplerate >= 96000:
component_glue['samplerate'] = 96000
elif samplerate >= 48000:
Expand All @@ -105,8 +99,8 @@ def compile(
component_glue['samplerate'] = 8000

# blocksize
blocksize = daisy_meta.get('blocksize')
if blocksize:
blocksize = daisy_meta.blocksize
if blocksize is not None:
component_glue['blocksize'] = max(min(256, blocksize), 1)
else:
component_glue['blocksize'] = None
Expand All @@ -125,20 +119,18 @@ def compile(
with open(daisy_cpp_path, 'w') as f:
f.write(rendered_cpp)

makefile_replacements = {'name': patch_name}
makefile_replacements['linker_script'] = daisy_meta.get('linker_script', '')
if makefile_replacements['linker_script'] != '':
makefile_replacements['linker_script'] = daisy_meta["linker_script"]
makefile_replacements: Dict[str, Any] = {'name': patch_name}
makefile_replacements['linker_script'] = daisy_meta.linker_script

# libdaisy path
path = daisy_meta.get('libdaisy_path', 2)
path = daisy_meta.libdaisy_path
if isinstance(path, int):
makefile_replacements['libdaisy_path'] = f'{"../" * path}libdaisy'
elif isinstance(path, str):
makefile_replacements['libdaisy_path'] = path

makefile_replacements['bootloader'] = daisy_meta.get('bootloader', '')
makefile_replacements['debug_printing'] = daisy_meta.get('debug_printing', False)
makefile_replacements['bootloader'] = daisy_meta.bootloader
makefile_replacements['debug_printing'] = daisy_meta.debug_printing

rendered_makefile = env.get_template('Makefile').render(makefile_replacements)
with open(os.path.join(source_dir, "Makefile"), "w") as f:
Expand Down
26 changes: 13 additions & 13 deletions hvcc/generators/c2daisy/templates/HeavyDaisy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ Heavy_{{patch_name}}* hv;

void audiocallback(daisy::AudioHandle::InputBuffer in, daisy::AudioHandle::OutputBuffer out, size_t size);
static void sendHook(HeavyContextInterface *c, const char *receiverName, uint32_t receiverHash, const HvMessage * m);
{% if debug_printing %}
{% if debug_printing is sameas true %}
static void printHook(HeavyContextInterface *c, const char *printLabel, const char *msgString, const HvMessage *m);
/** FIFO to hold messages as we're ready to print them */
FIFO<FixedCapStr<64>, 64> event_log;
{% elif usb_midi %}
{% elif usb_midi is sameas true %}
daisy::MidiUsbHandler midiusb;
{% endif %}
// int midiOutCount;
Expand Down Expand Up @@ -95,7 +95,7 @@ DaisyHvParamOut DaisyOutputParameters[DaisyNumOutputParameters] = {
};
{% endif %}

{% if has_midi or usb_midi %}
{% if (has_midi is sameas true) or (usb_midi is sameas true) %}
// Typical Switch case for Message Type.
void HandleMidiMessage(MidiEvent m)
{
Expand Down Expand Up @@ -208,19 +208,19 @@ int main(void)
{% if blocksize %}
hardware.SetAudioBlockSize({{blocksize}});
{% endif %}
{% if has_midi %}
{% if has_midi is sameas true %}
MidiUartHandler::Config midi_config;
hardware.midi.Init(midi_config);
hardware.midi.StartReceive();
{% endif %}
{% if not debug_printing and usb_midi %}
{% if (debug_printing is not sameas true) and (usb_midi is sameas true) %}
MidiUsbHandler::Config midiusb_config;
midiusb.Init(midiusb_config);
midiusb.StartReceive();
{% endif %}

hardware.StartAudio(audiocallback);
{% if debug_printing %}
{% if debug_printing is sameas true %}
hardware.som.StartLog();
hv->setPrintHook(printHook);

Expand All @@ -243,7 +243,7 @@ int main(void)
HandleMidiMessage(hardware.midi.PopEvent());
}
{% endif %}
{% if not debug_printing and usb_midi %}
{% if (debug_printing is not sameas true) and (usb_midi is sameas true) %}
midiusb.Listen();
while(midiusb.HasEvents())
{
Expand All @@ -258,7 +258,7 @@ int main(void)
LoopWriteOut();
{% endif %}

{% if debug_printing %}
{% if debug_printing is sameas true %}
/** Now separately, every 5ms we'll print the top message in our queue if there is one */
if(now - log_time > 5)
{
Expand Down Expand Up @@ -297,13 +297,13 @@ void audiocallback(daisy::AudioHandle::InputBuffer in, daisy::AudioHandle::Outpu
hardware.PostProcess();
}

{% if has_midi or usb_midi %}
{% if (has_midi is sameas true) or (usb_midi is sameas true) %}
void HandleMidiOut(uint8_t *midiData, const uint8_t numElements)
{
{% if has_midi %}
{% if has_midi is sameas true %}
hardware.midi.SendMessage(midiData, numElements);
{% endif %}
{% if not debug_printing and usb_midi %}
{% if (debug_printing is not sameas true) and (usb_midi is sameas true) %}
midiusb.SendMessage(midiData, numElements);
{% endif %}
}
Expand Down Expand Up @@ -448,12 +448,12 @@ static void sendHook(HeavyContextInterface *c, const char *receiverName, uint32_
}
}
{% endif %}
{% if has_midi or usb_midi %}
{% if (has_midi is sameas true) or (usb_midi is sameas true) %}
HandleMidiSend(receiverHash, m);
{% endif %}
}

{% if debug_printing %}
{% if debug_printing is sameas true %}
/** Receives messages from the PD [print] object and writes them to the serial console.
*
*/
Expand Down
8 changes: 4 additions & 4 deletions hvcc/generators/c2daisy/templates/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ TARGET = HeavyDaisy_{{name}}
# Library Locations
LIBDAISY_DIR = {{libdaisy_path}}

{% if linker_script != '' %}
{%- if linker_script != '' %}
LDSCRIPT = {{linker_script}}
{% endif %}
{%- endif %}

{% if bootloader != '' %}
{% if bootloader != None %}
APP_TYPE = {{bootloader}}
{% endif %}

{% if debug_printing %}
{% if debug_printing is sameas true %}
LDFLAGS += -u _printf_float
{% endif %}

Expand Down
14 changes: 5 additions & 9 deletions hvcc/generators/c2dpf/c2dpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from ..copyright import copyright_manager
from ..filters import filter_uniqueid
from ..types.meta import Meta, DPF


class c2dpf:
Expand All @@ -34,7 +35,7 @@ def compile(
out_dir: str,
externs: Dict,
patch_name: Optional[str] = None,
patch_meta: Optional[Dict] = None,
patch_meta: Meta = Meta(),
num_input_channels: int = 0,
num_output_channels: int = 0,
copyright: Optional[str] = None,
Expand All @@ -47,13 +48,8 @@ def compile(
receiver_list = externs['parameters']['in']
sender_list = externs["parameters"]["out"]

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

dpf_path = dpf_meta.get('dpf_path', '')
dpf_meta: DPF = patch_meta.dpf
dpf_path = dpf_meta.dpf_path

copyright_c = copyright_manager.get_copyright_for_c(copyright)

Expand Down Expand Up @@ -102,7 +98,7 @@ def compile(
senders=sender_list,
pool_sizes_kb=externs["memoryPoolSizesKb"],
copyright=copyright_c))
if dpf_meta.get("enable_ui"):
if dpf_meta.enable_ui:
dpf_ui_path = os.path.join(source_dir, f"HeavyDPF_{patch_name}_UI.cpp")
with open(dpf_ui_path, "w") as f:
f.write(env.get_template("HeavyDPF_UI.cpp").render(
Expand Down
Loading
Loading