This extension can be used to group plugin ports together, for example to express that a pair of audio inputs should be used as a stereo input, or that a group of control inputs are used to change the behvaiour of a certain component of the plugin (e.g an ADSR envelope or a filter). The extension consists only of RDF definitions that a host is always free to ignore, wholly or partially.
Every port group has a unique URI. You could generate these URIs by taking the plugin URI and appending a short string. For example, if the URI for your plugin is http://myplugins/coolsynth and you wanted to add a stereo output group, you could give it the URI http://myplugins/coolsynth/stereoOut. The RDF data for your plugin might then look like this:
@prefix lv2: <http://lv2plug.in/ontology#>.
@prefix doap: <http://usefulinc.com/ns/doap#>.
@prefix pg: <http://ll-plugins.nongnu.org/lv2/ext/portgroups#>.
<http://myplugins/coolsynth/stereoOut> a pg:StereoGroup.
<http://myplugins/coolsynth>
a lv2:Plugin;
doap:name "Cool synth";
doap:license <http://usefulinc.com/doap/licenses/gpl>;
lv2:port [
a lv2:OutputPort, lv2:AudioPort;
lv2:index 0;
lv2:symbol "left";
lv2:name "Left";
pg:membership [
pg:group <http://myplugins/coolsynth/stereoOut>;
pg:role pg:leftChannel;
];
],
[
a lv2:OutputPort, lv2:AudioPort;
lv2:index 1;
lv2:symbol "right";
lv2:name "Right";
pg:membership [
pg:group <http://myplugins/coolsynth/stereoOut>;
pg:role pg:rightChannel;
];
].
The important bits are the lines in bold. The first bold line simply defines a prefix that saves typing later. The second bold line says that http://myplugins/coolsynth/stereoOut is of the class pg:StereoGroup. Port group classes are in general used to add semantics to port groups, but all groups do not need to have classes - you may simply want to group your ports to allow hosts to present them to the user in nice hierarchical views. The port group class pg:StereoGroup is used for grouping pairs of audio ports together so the host knows that they can be treated as a single stereo stream.
The other two bits in bold use the predicates pg:membership, pg:group and pg:role to define what group the port is a member of, and what its role is in that group. The possible roles and how many ports are allowed for each of them depends on the class of the port group, and sometimes the pg:role predicate may not be needed at all. In this case the class is pg:StereoGroup, which has two possible roles, pg:leftChannel and pg:rightChannel, which both must be filled by a single port each for the group to be valid. A port may only be a member of one single group, and all the member ports of a group must belong to the same plugin.
In addition to pg:membership, pg:group and pg:role, there is a fourth predicate, pg:subgroupOf. This is used to define when a port group should be considered a subgroup of another port group. For example, you may have written a synth plugin that has two separate synth engines. You could then define one group for each engine, and then define two subgroups for each one for oscillator and envelope control, like this:
<http://myplugins/coolsynth/engine1> rdfs:label "Engine 1".
<http://myplugins/coolsynth/engine1/oscControl> pg:subgroupOf <http://myplugins/coolsynth/engine1>.
<http://myplugins/coolsynth/engine1/oscControl> rdfs:label "Oscillator".
<http://myplugins/coolsynth/engine1/envControl> pg:subgroupOf <http://myplugins/coolsynth/engine1>.
<http://myplugins/coolsynth/engine1/envControl> rdfs:label "Envelope".
<http://myplugins/coolsynth/engine2> rdfs:label "Engine 2".
<http://myplugins/coolsynth/engine2/oscControl> pg:subgroupOf <http://myplugins/coolsynth/engine2>.
<http://myplugins/coolsynth/engine2/oscControl> rdfs:label "Oscillator".
<http://myplugins/coolsynth/engine2/envControl> pg:subgroupOf <http://myplugins/coolsynth/engine2>.
<http://myplugins/coolsynth/engine2/envControl> rdfs:label "Envelope".
...and then put your control ports into the right groups using pg:membership and pg:group. A host that knows about port groups could then generate an interface with the widgets for the control ports grouped accordingly, for example in different frames. In this example rdfs:label is used to give each group a name that the host can display in its interface.
Each group may be the subgroup of at most one other group, and there may not be any "loops" - the subgroup structure must form a tree (or a number of disjoint trees).
Port group classes
In the list below, pg: is assumed to be defined as a prefix for http://ll-plugins.nongnu.org/lv2/ext/portgroups#. The number in brackets after a role defines how many ports are allowed in that role for that port group class, for example [1] means "exactly one" and [*] means "any number". If the description doesn't explicitly mention port classes, the member ports are allowed to be of any class (audio, control etc) - it's up to the host to decide whether it can make sense of the group or not. Also, unless the group class description says otherwise, all groups may have members that doesn't have any roles or have roles other than the ones specified for that group class.
Note that this is not a complete list of all port group classes that could ever be used - plugin writers are free to make up their own classes that hosts may or may not choose to support. Also, many hosts will probably not support all the groups listed here, which is OK too.
pg:StereoGroup
pg:leftChannel [1]
pg:rightChannel [1]
This class represents a stereo stream. No members other than the two required roles are allowed. The ports must either both be input ports or both output ports, and must both be of the same port class.
pg:MidSideGroup
pg:midChannel [1]
pg:sideChannel [1]
This class represents a mid-side encoded stereo stream. No members other than the two required roles are allowed. The ports must either both be input ports or both output ports, and must both be of the same port class.
pg:ThreePointZeroGroup
pg:leftChannel [1]
pg:rightChannel [1]
pg:surroundChannel [1]
This class represents a 3.0 stream. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:FourPointZeroGroup
pg:leftChannel [1]
pg:rightChannel [1]
pg:centerChannel [1]
pg:surroundChannel [1]
This class represents a 4.0 stream. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:FivePointZeroGroup
pg:leftChannel [1]
pg:rightChannel [1]
pg:centerChannel [1]
pg:leftSurroundChannel [1]
pg:rightSurroundChannel [1]
This class represents a 5.0 stream. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:FivePointOneGroup
pg:leftChannel [1]
pg:rightChannel [1]
pg:centerChannel [1]
pg:leftSurroundChannel [1]
pg:rightSurroundChannel [1]
pg:lfeChannel [1]
This class represents a 5.1 stream. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:SixPointOneGroup
pg:leftChannel [1]
pg:rightChannel [1]
pg:centerChannel [1]
pg:leftSurroundChannel [1]
pg:rightSurroundChannel [1]
pg:centerRearChannel [1]
pg:lfeChannel [1]
This class represents a 6.1 stream. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:SevenPointOneGroup
pg:leftChannel [1]
pg:rightChannel [1]
pg:centerChannel [1]
pg:leftSurroundChannel [1]
pg:rightSurroundChannel [1]
pg:leftRearChannel [1]
pg:rightRearChannel [1]
pg:lfeChannel [1]
This class represents a 7.1 stream. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH1V0Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
This class represents an Ambisonic B stream of horizontal order 1 and vertical order 0. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH1V1Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:zChannel [1]
This class represents an Ambisonic B stream of horizontal order 1 and vertical order 1. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH2V0Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:uChannel [1]
pg:vChannel [1]
This class represents an Ambisonic B stream of horizontal order 2 and vertical order 0. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH2V1Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:zChannel [1]
pg:uChannel [1]
pg:vChannel [1]
This class represents an Ambisonic B stream of horizontal order 2 and vertical order 1. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH2V2Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:zChannel [1]
pg:rChannel [1]
pg:sChannel [1]
pg:tChannel [1]
pg:uChannel [1]
pg:vChannel [1]
This class represents an Ambisonic B stream of horizontal order 2 and vertical order 2. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH3V0Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:uChannel [1]
pg:vChannel [1]
pg:pChannel [1]
pg:qChannel [1]
This class represents an Ambisonic B stream of horizontal order 3 and vertical order 0. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH3V1Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:zChannel [1]
pg:uChannel [1]
pg:vChannel [1]
pg:pChannel [1]
pg:qChannel [1]
This class represents an Ambisonic B stream of horizontal order 3 and vertical order 1. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH3V2Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:zChannel [1]
pg:rChannel [1]
pg:sChannel [1]
pg:tChannel [1]
pg:uChannel [1]
pg:vChannel [1]
pg:pChannel [1]
pg:qChannel [1]
This class represents an Ambisonic B stream of horizontal order 3 and vertical order 2. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:AmbisonicBH3V3Group
pg:wChannel [1]
pg:xChannel [1]
pg:yChannel [1]
pg:zChannel [1]
pg:rChannel [1]
pg:sChannel [1]
pg:tChannel [1]
pg:uChannel [1]
pg:vChannel [1]
pg:kChannel [1]
pg:lChannel [1]
pg:mChannel [1]
pg:nChannel [1]
pg:oChannel [1]
pg:pChannel [1]
pg:qChannel [1]
This class represents an Ambisonic B stream of horizontal order 3 and vertical order 3. No member ports other than the listed roles are allowed. The member ports must have the same port classes and either be all input ports or all output ports.
pg:EnvelopeGroup
pg:delay [0..1]
pg:attack [0..1]
pg:hold [0..1]
pg:decay [0..1]
pg:sustain [0..1]
pg:release [0..1]
This class represents controls for an envelope. The member ports must either be all input ports or all output ports.
pg:OscillatorGroup
pg:frequency [0..1]
pg:amplitude [0..1]
pg:waveform [0..1]
pg:pulseWidth [0..1]
This class represents controls for an oscillator. The member ports must either be all input ports or all output ports.
pg:FilterGroup
pg:cutoffFrequency [0..1]
pg:resonance [0..1]
This class represents controls for a filter. The member ports must either be all input ports or all output ports.