How Ecasound Registers JACK Input and Output Ports

Ecasound integrates directly with the JACK Audio Connection Kit by acting as a native JACK client that creates, names, and connects audio ports based on its chainsetup parameters. This article explains how Ecasound establishes its presence in the JACK graph, how input and output ports are named and allocated across audio channels, and how to manage automatic versus manual port connections.

Client Registration and Initialization

When Ecasound starts an engine configured to use JACK, it registers itself with the running JACK server as a new client. By default, Ecasound uses the client name ecasound. If multiple instances run simultaneously or custom naming is required, the client name can be set globally using the -G:jack,client_name option. Once the client is registered, all subsequent ports created by Ecasound will appear in the graph prefixed by this client name (for example, ecasound:in_1 or my_client:out_1).

Output Port Creation

Ecasound creates output ports within the JACK graph using the -o parameter targeting a JACK device object. When you specify -o jack, Ecasound evaluates the channel count defined for the active chain (set with -c:channels).

It then registers a corresponding number of playback/output ports in the graph:

These registered ports act as sources in the JACK graph, allowing other JACK applications or system playback devices to receive audio routed out of Ecasound.

Input Port Creation

Input ports are registered in the same manner using the -i parameter. Defining an input with -i jack instructs Ecasound to register writable destination ports in the JACK graph corresponding to the channel count of the chain:

Other JACK clients, such as synthesizers or system audio capture sources, can connect to these ports to stream audio into Ecasound's processing chains.

Explicit Routing vs. Floating Ports

Ecasound allows you to control whether registered ports float disconnected in the graph or automatically connect to target ports:

  1. Floating Ports (-i jack, -o jack): When no sub-arguments are provided, Ecasound simply registers the input or output ports and leaves them unconnected in the graph. This allows external patchbays, such as QjackCtl, Patchage, or WirePlumber, to handle connections manually or via automated session rules.

  2. Automatic Connections (-i jack,client:port, -o jack,client:port): If target port identifiers are appended to the JACK object declaration, Ecasound registers its internal ports and immediately requests the JACK graph to connect them to the specified external ports. For example, -o jack,system:playback_1,system:playback_2 creates the Ecasound output ports and wires them directly to the system's primary outputs.

  3. Multiple Port Mapping (jack_multi): For complex routings, the jack_multi object type allows explicit channel-to-port mapping across disparate clients. Declaring -o jack_multi,clientA:in_1,clientB:in_1 creates two output channels within Ecasound and automatically patches each channel to a different target port in the JACK matrix.

Port Lifecycle

Ecasound registers its ports during the chainsetup configuration phase, right before the processing engine starts. The ports remain active and visible in the JACK graph throughout the processing loop. When the engine stops, or when the Ecasound process terminates, the client unregisters all associated ports cleanly, notifying the JACK server to remove them and sever any existing connections in the graph.