Skip to content

Commit 0a07c5a

Browse files
committed
Merge branch 'v0.14.0'
2 parents fdfdf25 + e96d7cb commit 0a07c5a

86 files changed

Lines changed: 7783 additions & 1218 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.13.4
2+
current_version = 0.14.0
33

44
[bumpversion:file:pyproject.toml]
55
search = {current_version}

.github/workflows/ci.yml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
name: HVCC
22

3-
on:
4-
push:
5-
pull_request:
6-
branches: [ develop ]
3+
on: [push, pull_request]
74

85
jobs:
96

107
test:
118
runs-on: ubuntu-22.04
129
strategy:
1310
matrix:
14-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
11+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
1512

1613
steps:
1714
- uses: actions/checkout@v3
@@ -54,7 +51,7 @@ jobs:
5451
- uses: actions/upload-artifact@v4
5552
with:
5653
name: heavy-binary-linux-x86_64
57-
path: dist/pyinstaller/manylinux_2_31_x86_64/Heavy
54+
path: dist/pyinstaller/manylinux_2_35_x86_64/Heavy
5855

5956
dispatch:
6057
needs: test

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
CHANGELOG
22
=====
33

4+
0.14.0
5+
-----
6+
7+
Features:
8+
9+
* Metadata: optional Dict for external generators
10+
* JS: audio inputs now work - thanks to @ZXMushroom63
11+
* Generator: new FMOD generator - thanks to @michaelhartung
12+
* Objects: support symbol in `[pack]` (not on first inlet!)
13+
* Objects: support receive/send configuration for GUI objects
14+
15+
Bugfixes:
16+
17+
* Core: dereferencing type-punned pointer warning - thanks to @grrr
18+
* Core: signed/unsigned mismatch in HvSignalTabwrite.h - thanks to @grrr
19+
* c2dpf: portGroup template fix with i/o port 0 as CV
20+
* c2wwise: use correct SDK header paths and allow any platform in the xml - thanks to @eu-ch
21+
22+
Updates:
23+
24+
* drop py3.8 - add py3.13
25+
* integrate json2daisy library, tests and documentation
26+
* move to libDaisy 8.x pin definitions
27+
428
0.13.4
529
-----
630

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,15 @@ hvcc has been integrated into several projects and services. This allows to easi
4242

4343
## Requirements
4444

45-
Python 3.8 up to 3.12
45+
Python 3.9 up to 3.13
4646

4747
* `jinja2` (for generator templating)
48-
* `importlib_resources` (for reading static resources)
4948
* `json2daisy` (for daisy integration)
5049

5150
For tests:
5251

5352
* `tox` (python install)
54-
* `numpy/scipy` (requirements-dev)
53+
* `numpy/scipy` (dev dependencies)
5554
* `midifile` (git submodule)
5655
* `tinywav` (git submodule)
5756
* `clang/clang++` (system install)
@@ -159,3 +158,10 @@ There are several places where heavy/hvcc conversation is happening:
159158
* [MOD](https://forum.moddevices.com/c/developers/pure-data/56)
160159

161160
Or you can use the [discussions](https://github.com/Wasted-Audio/hvcc/discussions) tab of this repository
161+
162+
## Funding
163+
164+
This project is funded through [NGI0 Commons Fund](https://nlnet.nl/commonsfund), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/HVCC).
165+
166+
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl)
167+
[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/commonsfund)

docs/01.introduction.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Heavy can interpret and convert a subset of features from Pure Data patches:
4848
* [CLAP](https://cleveraudio.org/)
4949
* [JACK](https://jackaudio.org)
5050
* [Wwise](https://www.audiokinetic.com)
51+
* [FMOD](https://www.fmod.com)
5152
* [Web Audio API (AudioWorkletProcessor)](https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletProcessor)
5253

5354
## Optimisations
@@ -62,7 +63,7 @@ All the `hvcc` python compiler code is [GPLv3](https://github.com/Wasted-Audio/h
6263

6364
The files that `hvcc` generates are split into two types:
6465

65-
* [Static](https://github.com/Wasted-Audio/hvcc/tree/master/hvcc/generators/ir2c/static): this code is independent of the input patch contents and provides the basic DSP functionality with which generated output can link against. It has a [BSD](https://github.com/Wasted-Audio/hvcc/blob/master/hvcc/generators/ir2c/static/HeavyContext.hpp#L2) licence.
66+
* [Static](https://github.com/Wasted-Audio/hvcc/tree/master/hvcc/generators/ir2c/static): this code is independent of the input patch contents and provides the basic DSP functionality with which generated output can link against. It has a liberal [ISC](https://github.com/Wasted-Audio/hvcc/blob/master/hvcc/generators/ir2c/static/HeavyContext.hpp#L2) licence.
6667

6768
* Generated: this relates to all the source files that use information about the input patch, for example `Heavy_{{name}}.cpp`. By default all these files will have a `Copyright (c) 2018 Enzien Audio, Ltd` header, but this can be modified with the [user copyright argument](../README.md#--copyright-user-copyright).
6869

docs/02.getting_started.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ Messages passed to these send objects can be forwarded on to other parts of the
3838

3939
See the specific framework details for more information on output parameter support and integration details.
4040

41+
### GUI Objects
42+
43+
Most GUI objects will also accept send/receive configurations. These will be converted to send/receive objects in the Control Graph.
44+
45+
The following objects are supported:
46+
47+
- Number box (nbx)
48+
- Vertical slider (vsl)
49+
- Horizontal slider (hsl)
50+
- Vertical radio buttons (vradio)
51+
- Horizontal radio buttons (hradio)
52+
- Bang (bng)
53+
- Toggle (tgl)
54+
- Knob (knob, else/knob)
55+
- Float atom (floatatom)
56+
4157
## Exposing Events
4258

4359
All (control) `[receive]` and `[r]` objects annotated with `@hv_event` will be exposed as events in the Unity and Javascript targets only.
@@ -95,8 +111,8 @@ Just because pd-vanilla can run your patch, does not mean it will behave exactly
95111
This list will be continuously epanded to document differences in object behavior between PD and Heavy.
96112

97113
* Many objects do not take control signals on their left inlet. `[osc~]` for instance always requires the use of `[sig~]` before connecting a value.
98-
* Heavy does not support symbols in `[pack]`. e.g. `[pack s f]`.
99-
* Heavy does not support numbers in `[unpack]`, e.g. `[unpack 0 0]` gives `Heavy only supports arguments 'f' and 's' to unpack.` Workaround is to use `f` instead, e.g. `[unpack f f]`, and if necessary prime the default values with a `[loadbang]` and `[0 0(`.
114+
* Heavy does not support symbols to the first inlet of `[pack]`. e.g. `[pack s f]`.
115+
* Heavy does not support initializing numbers in `[unpack]`, e.g. `[unpack 0 0]` gives `Heavy only supports arguments 'f' and 's' to unpack.` Workaround is to use `f` instead, e.g. `[unpack f f]`, and if necessary prime the default values with a `[loadbang]` and `[0 0(`.
100116
* Sliders and number inputs are converted to `[f ]` and thus do not store send/receive/initialization/etc. settings.
101117
* Heavy does not accept arguments and control connections to: `[rzero~]`, `[rzero_rev~]`, `[czero~]`, `[czero_rev~]`. In Heavy, these objects accept only signal inputs. Arguments and control connections are ignored.
102118
* On the `[select]` and `[route]` objects it is currently not possible to set the arguments via the right inlet (internally a hardcoded switch_case is used).
@@ -106,4 +122,5 @@ This list will be continuously epanded to document differences in object behavio
106122
* `[snapshot~]` does not respond within the same control flow as it executes in signal context. Its output happens on the next audio cycle, so additional care for this control flow needs to be taken into account if you depend on synchronous execution. It also doesn't accept `[set(` messages.
107123
* Certain filters are sensitive to ‘blowing up’ at very low or very high cutoff frequencies and/or resonances, due to the filter coefficients not being perfectly represented with a finite number of bits. While Pure data natively uses 64 bits, platforms like `OWL` and `Daisy` that use 32 bit float are more sensitive to this. For example, the Pure data `[bp~]` filter is implemented with a biquad which is prone to fail or distort with cutoff frequencies less than around 200 Hz (at 48kHz sample rate).
108124
* Right inlet for table onset of `[tabread4~]` does not do anything.
125+
* Right inlet for `[lop~]` does not support signal input.
109126
* Heavy does not support multichannel connections.

docs/03.gen.daisy.components.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
## Custom JSON
2+
3+
JSON is a human-readable file format for data storage, and it's what json2daisy uses to help translate your Pd patch into something that will run on a Daisy-based board. If you haven't worked with something like it before, it might look a little strange, but don't worry! We'll cover enough here to get you on your way to custom hardware in no time.
4+
5+
### JSON Basics
6+
7+
For most hardware descriptions, there are only three JSON concepts you need to know: numbers, strings, and objects.
8+
9+
#### Numbers and strings
10+
11+
Numbers are just numbers! They can be integers (1, 2, 3) or any real number (3.141), and don't need any special formatting or indication.
12+
13+
Text data is stored as "strings", which are strings of characters enclosed in double quote marks ("like this :O").
14+
15+
#### Objects
16+
17+
An object is a set of _name_, _value_ pairs, enclosed in curly brackets. Each name is a unique string, and each value can be a number, a string, or another object. The name and value are separated by a colon. For a simple object, you might just have one name with a simple value:
18+
19+
```json
20+
{ "pin": 15 }
21+
```
22+
23+
When things get a little more complicated, such as objects with mutliple pairs, the pairs are usually broken up into their own lines for readability:
24+
25+
```json
26+
{
27+
"component": "Encoder",
28+
"pin": {
29+
"a": 12,
30+
"b": 11,
31+
"click": 0
32+
}
33+
}
34+
```
35+
36+
An object with multiple pairs must have commas between each.
37+
38+
To make editing JSON by hand easy, it's usually best to use a program that provides syntax highlighting (like the colors you see on this page). [VS Code](https://code.visualstudio.com/) is a great cross-platform tool for this. Of course, you can just use a normal text editor, but errors may be more difficult to spot, and some may even mangle the text in undesireable ways.
39+
40+
### Board description format
41+
42+
To describe a board, your JSON will need an object with a few critical pairs:
43+
44+
- name
45+
- This describes your project name and determines the names of automatically generated files
46+
- som
47+
- This is the SOM (system-on-module) that your project uses. This will usually be the Daisy Seed, but can also be the Patch SM.
48+
- The exact strings are:
49+
- `"seed"`
50+
- `"patch_sm"`
51+
- audio
52+
- This is an object describing your audio layout. For most projects, this will simply have a single pair describing the number of audio channels:
53+
```json
54+
{ "channels": 2 }
55+
```
56+
- components
57+
- This is the meat of your description. Here, you'll describe all the input and output components of your design such as knobs, CVs, LEDs, and so on. The name determines the receive or send name in your Pd patch, and must have an object with a `"component"` name. For example, a gate input could be described as:
58+
59+
```json
60+
"components": {
61+
"myGateIn": {
62+
"component": "GateIn",
63+
"pin": 20
64+
}
65+
}
66+
```
67+
- More complicated objects may have more required fields.
68+
69+
So, a very simple but viable board description might look like:
70+
71+
```json
72+
{
73+
"name": "MyProject",
74+
"som": "seed",
75+
"audio": { "channels": 2 },
76+
"components": {
77+
"myGateIn": {
78+
"component": "GateIn",
79+
"pin": 20
80+
}
81+
}
82+
}
83+
84+
```
85+
86+
### Component reference
87+
88+
| Type | _variant | Behavior |
89+
| --- | --- | --- |
90+
| **Inputs** | --- | --- |
91+
| AnalogControl | --- | Returns a floating point representation of the voltage at its input. The typical range is 0-5 V, which is represented as 0-1. |
92+
| BipolarAnalogControl | --- | Similar to a regular analog control, but can handle negative voltages. |
93+
| Switch | --- | Returns a bang on the signal's rising edge (i.e. when the switch is actuated). |
94+
| Switch | _press | Returns a float representing the current state (1 = pressed, 0 = not pressed) |
95+
| Switch | _fall | Returns a bang on the signal's falling edge (i.e. when the switch is released). |
96+
| Switch | _seconds | Returns a float representing the number of seconds the switch has been held down. |
97+
| Switch3 | --- | Returns a float representing the current state, either 0 or 1. |
98+
| Encoder | --- | Returns a 1 if turned one direction, -1 if turned in the other, and 0 otherwise. |
99+
| Encoder | \_rise | Returns a bang when the encoder is pressed. The special alias _EncSwitch_ is always bound to this. |
100+
| Encoder | _press | Same as switch _press. |
101+
| Encoder | _fall | Same as switch _fall. |
102+
| Encoder | _seconds | Same as switch _seconds. |
103+
| GateIn | --- | Returns a float representing the current gate voltage, where a _high_ voltage is 1 and a _low_ voltage is 0. |
104+
| GateIn | _trig | Returns a bang on the rising edge of the gate signal. |
105+
| **Outputs** | --- | --- |
106+
| CVOuts | --- | Expects a floating point value from 0-1, usually converted to 0-5V. |
107+
| GateOut | --- | Expects a floating point value from 0-1. 0 sets the output low, and 1 sets it high. |
108+
| Led | --- | Expects a floating point value from 0-1. The brightness is PWM modulated to match the input. |
109+
| RgbLed | --- | Expects a floating point value from 0-1. The default behavior sets all three colors to the same brightness. |
110+
| RgbLed | _white | Same as default. |
111+
| RgbLed | _red | Expects a floating point value from 0-1. Sets the brightness of the red LED only. |
112+
| RgbLed | _green | Expects a floating point value from 0-1. Sets the brightness of the green LED only. |
113+
| RgbLed | _blue | Expects a floating point value from 0-1. Sets the brightness of the blue LED only. |
114+
115+
### Built-in descriptions
116+
117+
If some details are still unclear, the [JSON descriptions for the built-in boards](https://github.com/Wasted-Audio/hvcc/tree/develop/hvcc/generators/c2daisy/json2daisy/resources) might help.

docs/03.gen.daisy.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Which can be configured using the `-m` metadata.json `daisy.board` setting:
2020
}
2121
```
2222

23-
However one can also create custom board layouts. See [the Electro-Smith documentation](https://github.com/electro-smith/DaisyWiki/wiki/Pd2dsy-Guide) for more information.
23+
However one can also create custom board layouts. See [the Daisy Component documentation](03.gen.daisy.components.md) for more information.
2424

2525
The custom layout can be passed on via the meta.json as such:
2626

@@ -112,4 +112,4 @@ The linker and `APP_TYPE` can be set in the json metadata accordingly:
112112
"bootloader": <APP_TYPE>
113113
}
114114
}
115-
```
115+
```

docs/03.gen.fmod.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# FMOD
2+
3+
`hvcc` will generate a plugin for FMOD Studio and the FMOD Runtime.
4+
5+
## Feature Overview
6+
7+
The following features are currently supported.
8+
9+
- sound fx units
10+
- sound generators
11+
- input parameters (float, bool, int)
12+
13+
## FX Unit / Generator
14+
15+
Whether the resulting plugin is considered a generator plugin, like an oscillator , or an
16+
fx unit, is determined by the numbers of input/output channels of pd patch.
17+
18+
A patch without an `adc~` object is considered a generator.
19+
20+
See also [Multi-Channel Plugins](#multi-channel-plugins)
21+
22+
## Input Parameters
23+
24+
If no additional parameter type is set, all parameters are treated as float by default.
25+
26+
__Examples:__
27+
28+
`r gain @hv_param 0 1 0.5`
29+
30+
`r toggle_mute @hv_param 0 1 0 bool`
31+
32+
`r state @hv_param 0 3 0 int`
33+
34+
`FMOD_DSP_PARAMETER_TYPE_DATA` is not supported currently.
35+
36+
Fmod Studio recognizes certain parameter units like `Hz` for example, which affects how values are
37+
displayed.
38+
39+
For further information see: [Plugin Parameters](https://www.fmod.com/docs/2.03/api/white-papers-dsp-plugin-api.html#plug-in-parameters)
40+
41+
### Input Parameter Mappings
42+
43+
The how input parameters are mapped to their respective range can be further
44+
customized in the resulting `<pluginname>.cpp` file.
45+
46+
## Multi-Channel Plugins
47+
48+
An appropriate configuration will be selected at compile time based on the
49+
number of inputs and outputs in a patch (e.g. `[adc~ 1 2 3 4 5 6]` will create
50+
a 5.1 plugin). As this information is compiled in, the plugins can only be used
51+
on tracks/groups with a corresponding channel configurations.
52+
53+
In case a of a i/o miss-match, fx plugins will return `FMOD_ERR_DONTPROCESS` in
54+
the `PluginProcess()` callback, effectively bypassing the plugin.
55+
56+
## Plugin-Scripting API
57+
58+
A corresponding `<pluginname>.plugin.js` is generated alongside the build
59+
artifacts.
60+
61+
This file can be used to further customize the appearance of the
62+
plugin in FMOD Studio and needs to be placed into the `Plugins` folder along with the plugin binary.
63+
64+
See [Plugin-Scripting API](https://www.fmod.com/docs/2.03/studio/plugin-reference.html#plug-in-scripting-api)
65+
66+
## Building Your Plugin
67+
68+
The plugin folder contains a `CMakeLists.txt` file which will generate a **dynamic**
69+
and a **static** library version of the plugin prefixed with `lib`.
70+
71+
The static library can be used on platforms that don't support dynamic library
72+
loading such as the Nintendo Switch (see [Static Plugins](https://fmod.com/docs/2.03/unity/plugins.html#static-plugins)).
73+
74+
### CMake
75+
76+
From within the directory containing the `CMakeLists.txt` use.
77+
78+
```shell
79+
cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug
80+
cmake --build cmake-build-debug
81+
```
82+
83+
### VSCode
84+
85+
Install [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) and
86+
open the `fmod` folder containing the `CMakeLists.txt` in VSCode.
87+
88+
Check that the `[all]` target is selected and run `> cmake build`. The resulting binaries
89+
will be placed in `build\<CONFIG>`.

docs/03.gen.javascript.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ The initial set up should look something like this:
7070
blockSize: 2048, // number of samples on each audio processing block
7171
printHook: onPrint, // callback for [print] messages, can be null
7272
sendHook: onFloatMessage // callback for output parameters [s {name} @hv_param], can be null
73+
}).then(() => {
74+
// loader finished initialising
75+
// optional input oscillator:
76+
const sampleOscillator = loader.webAudioContext.createOscillator();
77+
sampleOscillator.connect(loader.webAudioWorklet || loader.webAudioProcessor);
78+
sampleOscillator.type = "square";
79+
sampleOscillator.frequency.setValueAtTime(440, 0); // A4
80+
sampleOscillator.start(0);
7381
});
7482
}
7583
loader.start();

0 commit comments

Comments
 (0)