Skip to content

Commit

Permalink
Merge branch 'v0.13.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
dromer committed Dec 13, 2024
2 parents 44708e7 + a43fe0a commit 6ec59cc
Show file tree
Hide file tree
Showing 131 changed files with 3,122 additions and 2,435 deletions.
8 changes: 6 additions & 2 deletions .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[bumpversion]
current_version = 0.12.1
current_version = 0.13.0

[bumpversion:file:setup.cfg]
[bumpversion:file:pyproject.toml]
search = {current_version}

[bumpversion:file:CHANGELOG.md]
search = Next Release

[bumpversion:file:hvcc/version.py]
search = {current_version}
30 changes: 28 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,42 @@ jobs:
- name: Initialize lfs
run: git lfs pull
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade pip setuptools wheel
pip install tox tox-gh-actions
- name: Run tox
run: tox

binary:

runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
lfs: true
submodules: true
- name: Initialize lfs
run: git lfs pull
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
pip install poetry poetry-pyinstaller-plugin
- name: Build binaries
run: poetry build

- uses: actions/upload-artifact@v4
with:
name: heavy-binary-linux-x86_64
path: dist/pyinstaller/manylinux_2_31_x86_64/Heavy

dispatch:
needs: build
strategy:
Expand Down
28 changes: 27 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
CHANGELOG
=====

0.13.0
-----

Features:

* Migrating to poetry for project management
* Standalone binary (only Linux for now)
* DPF: Allow modgui on desktop
* DPF: Enable host transport events without midi input
* JS: midi out and device select by @Reinissance
* Docs: general updates/corrections and improvements
* Allow loading external generator python module @eu-ch
* Meta: additional global setting to automatically set `HV_SIMD_NONE`
* Add version info to cli and IR result.

Bugfixes:

* Daisy template newline

Typing:

* HeavyLang and HeavyIR objects
* Compiler results
* Extern info
* Heavy IR Graph

0.12.1
-----

Expand All @@ -11,7 +37,7 @@ Features:
* DPF: CV flag in portgroups
* DPF: flag to disable scoped denormals

Bugfixes
Bugfixes:

* wwise: allow Bang messages in OnSendMessageCallback()
* Improve `[cos~]` precision.
Expand Down
3 changes: 2 additions & 1 deletion docs/02.getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ This list will be continuously epanded to document differences in object behavio
* 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.
* On the `[select]` object it is currently not possible to set the arguments via the right inlet (internally a hardcoded switch_case is used).
* Heavy supports remote/send messages, however empty messages are currently removed. So the typical `[; bla 1(` multiline message needs to contain at least something on the first line: `[_; bla 1(`.
* Remote/send messages with `sinesum` argument to fill tables are not supported.
* `[metro]` and `[timer]` objects do not accept tempo messages or unit arguments.
* `[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.
* `[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.
* 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).
* Heavy does not support multichannel connections.
46 changes: 37 additions & 9 deletions docs/03.gen.dpf.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,44 @@ In order to receive MIDI note on and off events, as well as control change messa

DPF supports all note/ctl/pgm/touch/bend I/O events. The implementation is further discussed in the [midi docs](04.midi.md)

We can also use `[midirealtimein]` to receive realtime midi messages like clock/start/continue/stop/reset (no active sense). It is up to the user to create the appropriate handling inside the patch.
![notein](img/docs_notein.png)

Additionally you can use the special `[r __hv_dpf_bpm]` receiver to get the current transport BPM value directly.
## Host Transport Events

![notein](img/docs_notein.png)
We can use `[midirealtimein]` to receive host transport events in the form of realtime midi messages like clock/start/continue/stop/reset (no active sense). It is up to the user to create the appropriate handling inside the patch.

This object does not require the plugin to have MIDI input enabled.

Additionally you can use the special `[r __hv_dpf_bpm]` receiver to get the current transport BPM value directly.

## Parameter Types

In DPF a parameter can get an optional type configured. The default type is `float`. Other assignable types are `bool` - for toggling a value - and `trig` - for momentary signals.
In DPF a parameter can get an optional type configured. The default type is `float`.

Other assignable types are `int` - or whole numbers, `bool` - for toggling a value, and `trig` - for momentary signals.

![dpf](img/docs_param_type.png)

Using jinja the `v.attributes.type` can be evaluated for a specific string and different templating applied to the parameter. In DPF the extra types `bool` and `trig` result in the following plugin code:

```c++
parameter.hints = kParameterIsAutomable | kParameterIsBoolean;
parameter.hints = kParameterIsInteger
// or
parameter.hints = kParameterIsAutomable | kParameterIsTrigger;
parameter.hints = kParameterIsBoolean;
// or
parameter.hints = kParameterIsTrigger;
```

Other special types can give additional information to the host:

* `dB` - unit `dB` - min_value `-inf` label (assumes `0.0f`)
* `Hz` - unit `Hz`
* `log` - hints `kParameterIsLogarithmic`
* `log_hz` - unit `Hz` - hints `kParameterIsLogarithmic`

## Metadata

An accomponying metadata.json file can be included to set additional plugin settings.
An accompanying metadata.json file can be included to set additional plugin settings.

The `project` flag creates a `README.md` and `Makefile` in the root of the project output, but may conflict with other generators.

Expand All @@ -55,7 +70,7 @@ Each of these are optional and have either a default value or are entirely optio
"midi_input": 1,
"midi_output": 0,
"plugin_formats": [
"lv2_dsp",
"lv2_sep",
"vst2",
"vst3",
"clap",
Expand All @@ -67,7 +82,7 @@ Each of these are optional and have either a default value or are entirely optio

Other fields that the DPF metadata supports are:

* `port_groups` - If your plugin has more audio i/o that need to be grouped together.
* `port_groups` - If your plugin has more audio i/o that need to be grouped together or given Control Voltage status
* `enumerators` - Configure a set of parameters that cycle over `<key>: <value>`
* `enable_ui` - Boolean that creates a generic GUI. Requires `dpf-widgets` on the same level as `dpf`.
* `enable_modgui` - Boolean for use in MOD audio based systems.
Expand All @@ -77,6 +92,19 @@ Other fields that the DPF metadata supports are:
* `vst3_info` - String describing the VST3 plugin type.
* `clap_info` - List of strings describing the CLAP plugin type.

You can also fully disable SIMD optimizations using the global `nosimd` flag:

```json
{
"nosimd": true,
"DPF": {
...
}
}
```

The full type specification can be found [here](https://github.com/Wasted-Audio/hvcc/blob/develop/hvcc/types/meta.py).

An example plugin that uses some of these extended metadata is [WSTD 3Q](https://github.com/Wasted-Audio/wstd-3q).

## Notes
Expand Down
59 changes: 59 additions & 0 deletions docs/03.gen.external.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# External Generators

It's possible to implement custom generators without modifying HVCC. For this, you need to:

* subclass `hvcc.types.compiler.Generator` abstract class in your module (e.g. a Python file)
* add `-G your_module_name` command-line argument when executing `hvcc`

It's recommended to have only one Generator subclass per module, otherwise any one of them can be executed.

Check out `hvcc.generators.c2daisy.c2daisy` or `hvcc.generators.c2dpf.c2dpf` modules for reference implementations.

## Example

This example demonstrates how to create a custom generator that prints a message into stdout.

This is `example_hvcc_generator.py`:

```python
import time

from typing import Dict, Optional

from hvcc.types.compiler import CompilerResp, ExternInfo, Generator
from hvcc.types.meta import Meta


class ExampleHvccGenerator(Generator):
@classmethod
def compile(
cls,
c_src_dir: str,
out_dir: str,
externs: ExternInfo,
patch_name: Optional[str] = None,
patch_meta: Meta = Meta(),
num_input_channels: int = 0,
num_output_channels: int = 0,
copyright: Optional[str] = None,
verbose: Optional[bool] = False
) -> CompilerResp:
begin_time = time.time()
print("--> Invoking ExampleHvccGenerator")
time.sleep(1)
end_time = time.time()

# Please see code example on how CompilerResp class is used and adapt to your case.
return CompilerResp(
stage='example_hvcc_generator', # module name
compile_time=end_time - begin_time,
in_dir=c_src_dir,
out_dir=out_dir
)
```

With this file in your current directory, execute the following command:

```bash
hvcc patch.pd -G example_hvcc_generator
```
2 changes: 1 addition & 1 deletion docs/03.gen.javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Note: these are calls directly to the `AudioLib` so make sure to include `.audio

## Loading Custom Samples

If you have a table that is externed, using the `@hv_param` annotation, it can be used to load audio files from the web page. The table will be resized to fit this sample data.
If you have a table that is externed, using the `@hv_table` annotation, it can be used to load audio files from the web page. The table will be resized to fit this sample data.

`[table array1 100 @hv_table]`

Expand Down
2 changes: 2 additions & 0 deletions docs/03.generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ HVCC supports a number of dedicated generators that can help to wrap the heavy c
* [Pdext](03.gen.pdext.md)
* [Wwise](03.gen.wwise.md)
* [Unity](03.gen.unity.md)

You can also create your own generator without modifying HVCC, see [External Generators](03.gen.external.md).
Loading

0 comments on commit 6ec59cc

Please sign in to comment.