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

Some official specification or design guideline on parameters or properties with input/output ports #80

Closed
atsushieno opened this issue May 4, 2021 · 7 comments

Comments

@atsushieno
Copy link
Owner

atsushieno commented May 4, 2021

Currently we don't really have "parameters" or "properties" on a plugin. Parameters are implicitly represented as in ports, and they have broad data width just like audio inputs/outputs. "Properties" (probably implying that they are not limited to floats) are also supposed to be transmitted via those ports.

A problem here is that we shouldn't really have to require / assign ports for each single parameter. If there are 100 parameters (which is likely to happen) there will be 100 ports, 100 x 4096 bytes if the buffer size is 1024, just for one cycle. And that's too much.

What we would like to have instead is to have one single input port to send a set of parameter changes, and output port based on user inquiry of parameter values. sfizz-lv2 has this kind of ports (manifest for input port and notification port), which would be ideal for most of us. mda-lv2, which I took to learn how plugin ports would be designed, is not designed like that.

"Properties" would work in quite similar manner, but I would make it work like MIDI 2.0 Property Exchange (maybe without forcing JSON syntax). If it works like standard way, then plugins would be made of MIDI standard constructs. Requests would be sent to the control input port, and the results would be sent to the notification port. As of v0.7.4 there will be no property exchange support; parameter changes should be all sent via MIDI2 output notifications.

We wouldn't need different names for parameters and properties, they can be both "property", with an optional "type" attribute (float by default). There will be no type support. Non-float properties should be set via sysex, a port, or an extension.

Control inputs are not necessarily real-time safe. In fact most of them wouldn't be. But the inputs will be processed in real-time loop anyways, and there should be some remedy to assure that a control input does not overwrite existing control inputs. An appropriate queue without locking is required.

@atsushieno
Copy link
Owner Author

Some related issues:

@atsushieno
Copy link
Owner Author

Here are somewhat concrete ideas:

  • Now: we have "port" for every "parameter". It is designed after how mda-lv2 looks like.
  • Next: we will have "parameters" that does not come with "port". Instead, there will be a MIDI2 control and notification ports, and every parameter will have a parameter index which is used as an Assignable Controller (NRPN).

Details:

  • The input port accepts property get/set messages.
  • For setter, it can be simply an Assignable Controller message. Get requests comes up with a correlation ID.
  • For getter, there will be a universal sysex-like request. I don't think MIDI 2.0 Property Exchange is good here, because it does not work like HTTP1.1 pipelines, HTTP/2 or QUIC, i.e. it does not specify parallel requests.
  • The notification port sends reply to a parameter get request, with correlation.
  • The input port also accepts property change "subscription" messages. In this case, MIDI 2.0 Property Exchange may be useful here.
  • <parameter> elements within the <parameters> element in aap_metadata.xml. Has name and content attributes.
  • ParameterInformation in audio-plugin-host.h/.cpp. Shares a new PropertyContainer parent class with existing PortInformation class.

atsushieno added a commit that referenced this issue May 28, 2021
context: #80

- There is now `<parameters>` and `<parameter>` elements.
- ParameterInformation class in Kotlin and native hosting API.
- UI components and aaphostsample reflected the changes.

There is still missing feature to actually change the parameters via
the input port.
@atsushieno
Copy link
Owner Author

After implementing in this repo above, I figured that it's not very obvious how LV2 ports should be mapped to parameters. Almost all LV2 ports are actually for parameters. If we define them as parameters, then they have no corresponding ports. If we also define corresponding ports, then there will be a lot of duplicates.

Also, I'm thinking of having message receiver (like notify() method in VST3 component) rather than a control "input port". It is to make it clearer that ports work only at active state.

A plugin developer can still develop control input port described above.

If we keep current port as is, then it would be needed to make it more like a parameter. A parameter needs to be retrievable. Then a port can have some annotation like parameterIndex.

@atsushieno
Copy link
Owner Author

Another design flaw in the previous comment was that the notification port does not work at inactive state, therefore the property getter reply message won't be sent. We would simply need "getProperty(index)" kind of plugin instance function that is supposed to return immediate property value without realtime priority as well as no realtime interference.

atsushieno added a commit that referenced this issue Feb 20, 2022
atsushieno added a commit that referenced this issue Aug 18, 2022
…ension)

Context:
- #80
- https://github.com/atsushieno/android-audio-plugin-framework/blob/main/docs/design/NEW_PORTS.md

This partially implements new aap::ParameterInformation and `<parameter>`
elements in aap_metadata.xml. They are filled by AudioPluginHostHelper,
which is also indirectly used by C++ hosting code (we have no XML metadata
parser in C++ yet).

aapbarebonepluginsample now has duplicate specification for ports and
parameters: DSP code has not switched to parameters and MIDI inputs yet,
and parameters are just passed to ports of the same name for each (hack,
to-be-removed behavior). The duplicate will go away once we switch to
parameter changes via MIDI inputs.
atsushieno added a commit that referenced this issue Aug 23, 2022
…ginsample)

context (partly): #80

If there is a MIDI2 port and <parameter>s exist, then PluginPreview now tries
to send parameters as MIDI2 Assignable Controller UMPs.
If there isn't MIDI2 port but <parameter>s exist, then it looks for the
port for each parameter, matching by name.
It is to avoid "fixed port index" (which should NOT be fixed) rather than
"fixed parameter index" (which should be fixed).
If there aren't <parameter>s either, then it works in the traditional way
(ports-based).
@atsushieno
Copy link
Owner Author

As of e6eab86, now we have MIDI2 Assignable Controller based implementation. Some details:

  • If there is a MIDI2 port, then plugin would assume that parameter changes are sent as Assignable Controller on the port. <parameter>s are either specified in the manifest, or dynamically by the parameters extension (get_parameter_count() and get_parameter()).
  • A parameter must have a stable ID (integer). Ports will not have stable indexes anymore, as they could be dynamically populated.
  • We don't need complicated stuff like MID2 property exchanges. Any parameter changes not triggered by process() , including state loading and preset loading, should be notified to host using MIDI2 output port. Maybe "bulk dump request" could be implemented. (We should probably provide "template instrument project" that implements these basic features...)

@atsushieno
Copy link
Owner Author

Remaining tasks:

  • aap-lv2 and aap-juce should migrate to the new parameters based plugin model.
  • Some working state load / preset load example that notifies parameter changes back to host.

@atsushieno
Copy link
Owner Author

With the latest v0.7.4 release, we have migrated to "V2" protocol which makes use of MIDI2 input port and UMP sysex8 for parameter changes. With this release, we can finally close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant