5.3 KiB
Integration Plan: Carla Plugin Host (Client‑side)
1. Strategy
Carla lives in the client (the TUI), not the looper engine.
The client becomes a lightweight JACK client itself, capable of loading plugins via the Carla host API and bridging audio/MIDI between the looper’s JACK ports and the plugin’s ports.
2. Client (TUI) – new modules
2.1 Carla dependency
- Link the client binary with
libcarla_host(C static/shared library). - Use the official
carla_standalone.hAPI.
2.2 New files client/src/plugins.c / plugins.h
Functions (same signatures as before, but run inside the client):
int plugin_load(const char *binary, const char *plugin_id, int *out_id)int plugin_unload(int id)int plugin_connect(int id, const char *port_name, const char *looper_port)int plugin_disconnect(const char *from, const char *to)void plugin_set_bypass(int id, bool bypass)
The module owns the list of loaded plugins, their Carla‑native IDs, and the mapping between looper JACK ports and plugin ports.
2.3 JACK client for plugin I/O
- In
client/src/tui.c(or a newclient/src/jack_io.c), open a JACK client withjack_client_open(). - Register input/output ports that will be connected to the looper’s ports (usually via
jack_connectcalled once at start‑up). - In the process callback, copy audio between looper ports and plugin ports (using Carla’s
process()‑like functions). - This keeps the engine completely unaware of plugins.
3. TUI commands (colon‑mode)
All already exist in the plan; only the implementation target changes:
:from <port>→ describe a looper output port (e.g.,looper:out_0):to <port>→ destination port (e.g.,plugin1:in_left):addplugin <path>→ loads the plugin and, iffrom/toare set, connects them automatically:connect→ creates a JACK‑connection between the storedfromandto(or, if one side belongs to a plugin, uses Carla’s internal connect):disconnect:rack→ toggles rack view (list of plugins with ports and bypass status):grid→ back to the original grid view
4. Rack view (TUI)
Identical to the original description, but the data comes from the client’s internal Carla handle instead of the status FIFO.
5. Integration Tests
5.1 Mock plugin (client‑side)
- Create
client/tests/mock_plugin/mock_plugin.c. - A trivial JACK client that copies input to output and adds a 1 kHz tone when the input is silent.
- Compiled to
libmock_plugin.so→ the TUI’s plugin loader will load it.
5.2 Test infrastructure (client/tests)
- Start the TUI in a headless test mode (or fork a child and feed it commands via stdin).
- Observe the status output (sent to stdout or a temporary file) to verify plugin list and connections.
5.3 Test cases (new file client/tests/test_plugin_client.c)
test_plugin_load_unload– load mock plugin, confirm list shows 1 entry, unload, confirm list empty.test_plugin_connect_audio– load plugin, connect to looper ports, inject audio from a test JACK client, verify plugin output reaches a monitor port.test_rack_view– send:rackcommand, parse the printed lines, verify they match the expected layout.- (Later)
test_bypass– load, bypass, verify audio passes unaltered.
6. Build System Changes
- client/makefile:
- Add
-lcarla_hosttoLDFLAGS. - Add
plugins.c(and optionallyjack_io.c) toSRCS. - Build mock plugin as a separate target.
- Add
- engine/makefile – no changes (engine stays pure looper).
- top‑level makefile – no changes.
7. Implementation Steps (ordered)
-
Add Carla dependency & stub tests (client side)
- Link client binary with
-lcarla_host. - Create
client/src/plugins.h/client/src/plugins.cwith stub implementations. - Create
client/tests/test_plugins.cwith failing (Red) unit tests for:plugin_loadreturns -1 on NULL binaryplugin_unloadreturns -1 on invalid id- (optional)
plugin_connectreturns -1 on invalid id
- Add a
testtarget inclient/makefilethat builds and runstest_plugins. - Verify the tests compile and pass (Green).
- Link client binary with
-
Implement real Carla integration (client side)
- Open a private JACK client inside the TUI using
jack_client_open(). - Implement
plugin_load/plugin_unloadusing Carla’scarla_new_nativeetc. - Write integration tests that load a mock plugin and verify it appears in the rack.
- Open a private JACK client inside the TUI using
-
Add
:addplugincommand parsing in TUI- When colon mode is entered, parse
:addplugin <path>. - Call the underlying
plugin_loadand update the internal plugin list.
- When colon mode is entered, parse
-
Implement rack view (TUI)
- Toggle between grid view and plugin‑list view.
- Display plugin name, ID, bypass status.
- Add
B,D,Xkeybindings.
-
Build mock plugin and write integration tests
- Create
client/tests/mock_plugin/mock_plugin.c. - Target
libmock_plugin.so. - Write tests in
client/tests/test_plugin_client.c:test_plugin_load_unloadtest_plugin_connect_audiotest_rack_view
- Create
-
Polish and document
- Clean up error messages, handle edge cases.
- Add comments to new modules.
- Update root
READMEwith Carla instructions.