9.2 KiB
Manual Test Protocols – Guitar / Audio Looper
This document provides step‑by‑step manual testing procedures using a real guitar (or any line‑level mono audio source) with the looper engine.
Prerequisites
- A running JACK server (e.g.
jackd -d alsa -r 48000 -p 256) - The looper binary compiled (
cd engine && make) - An audio interface recognised by ALSA (or PulseAudio JACK bridge)
- A guitar connected to your interface’s input
qjackctl(optional, for visual wiring) or knowledge ofjack_connectcommands
Test 1 – Basic Audio Pass‑Through (Guitar Monitor)
-
Start the looper in a terminal:
./looper -
Launch
qjackctl(or usejack_connectfrom shell) to view available ports. -
Connect your interface’s capture port to the looper’s input:
jack_connect system:capture_1 looper:input -
Connect the looper’s output to your interface playback ports:
jack_connect looper:output system:playback_1 -
Pluck a few strings – you should hear your guitar coming through the looper immediately (channel 0 is in IDLE state, which passes input straight to output).
-
To stop, press
Ctrl+Cin the looper terminal.
Expected result: You hear your guitar with no latency issues (depending on JACK buffer size). If you hear nothing, check port names with jack_lsp.
Test 2 – Record a Short Loop (MIDI Control)
2a – Using MIDI keyboard (or a MIDI controller)
-
Start the looper as above.
-
Connect your MIDI controller to the looper’s control port:
jack_connect <controller>:midi_out looper:controlReplace
<controller>with the actual MIDI port name (usejack_lspto find it). -
Send note 1 (velocity 127) to switch channel 0 into RECORD state.
- On most keyboards, this is the C# key two octaves above middle C (MIDI note 1). Press it once.
-
Play your guitar for about 2 seconds. The looper is recording.
-
Press note 1 again. The looper transitions to LOOPING state. The recorded 2‑second phrase starts playing back repeatedly.
-
You should hear the loop repeating. Pluck strings while the loop plays – the IDLE monitoring is still active on channel 0 (the loop is mixed with the live input).
-
Press note 1 a third time to PAUSE the loop; press again to resume.
2b – Using FIFO commands (if you have no MIDI keyboard)
- Start the looper.
- Open a second terminal.
- Send:
echo "record 0" > /tmp/looper_cmd - Play guitar for a few seconds.
- Send again:
echo "record 0" > /tmp/looper_cmd - Loop should start repeating. Test pause by sending again (second command cycles IDLE→RECORD→LOOPING→PAUSED→…).
Expected result: The loop repeats seamlessly. If you hold a chord while the loop is playing, the live input still passes through.
Test 3 – Save the Loop to a WAV File
-
Ensure a loop is playing (LOOPING state) on channel 0.
-
Send the save command:
echo "save" > /tmp/looper_cmdor (MIDI) press control‑key (note 64) + note 71.
-
After a brief delay (the loop buffer is written synchronously), a file
save.wavappears in the engine directory. -
Check the file size is > 44 bytes and play it with any media player:
aplay save.wav
Expected result: The saved file contains exactly what the looper was playing (your recorded guitar phrase). The RMS of the playback should be similar to the live signal.
Test 4 – Load a WAV File into a Channel
-
Put a mono 16‑bit WAV file named
loop.wavin the engine directory (e.g. a short drum loop or a guitar riff). -
Start the looper and send the load command:
echo "load" > /tmp/looper_cmdor (MIDI) control‑key + note 70.
-
The loaded audio begins playing immediately on channel 0 (state = LOOPING).
-
Verify you hear the loop repeating.
Expected result: The WAV is loaded and plays correctly. The loop length matches the duration of the file (up to LOOP_BUF_SIZE frames, default 8 seconds).
Test 5 – Dynamic Channel Creation and Binding
-
Start the looper.
-
Add a second audio channel:
echo "add" > /tmp/looper_cmd -
Check that new ports appear:
jack_lsp | grep channel1 -
Bind the client to channel 1:
echo "bind 1" > /tmp/looper_cmd -
Connect your guitar to both channels for stereo testing? Not necessary. But you can route differently.
-
Now when you send
record 1, the bind ensures the command affects channel 1 instead of channel 0. -
Repeat the record/loop process on channel 1, while channel 0 continues its own loop.
Expected result: Two independent loops can play simultaneously without interfering.
Test 6 – Scene Switching
-
Make sure a loop is playing on channel 0.
-
Add a second scene to channel 0:
echo "scene_add" > /tmp/looper_cmd(Only adds scene if
MAX_SCENESnot exceeded, default 4.) -
Switch to the new scene:
echo "scene_next" > /tmp/looper_cmdThe playback stops because the new scene is IDLE.
-
Record a different phrase on the new scene (send
record 0). -
Switch back to the first scene (
scene_prev) – the original loop resumes.
Expected result: Different independent loops in separate scenes; switching scenes does not lose previously recorded loops.
Test 7 – MIDI Clock Sync
If you have an external MIDI clock source (e.g. a drum machine or DAW sending MIDI start/stop):
-
Connect the clock source to
looper:clockport. -
Send MIDI Start (
0xFA). The looper’s current scene (if IDLE) transitions to RECORD. -
Send MIDI Stop (
0xFC). The current scene goes IDLE (loop stops). -
Send MIDI Continue (
0xFB) while the scene is PAUSED – it resumes LOOPING.
Expected result: Transport commands control looper state reliably.
Test 8 – Edge Cases
8a – Rapid toggling
Cycle the RECORD/LOOPING/PAUSED states many times in quick succession (send record 0 every 200 ms for 5 seconds). The looper should not crash or produce glitches.
8b – Remove channel while playing
Add a channel, start a loop on it, then remove the channel with:
echo "remove" > /tmp/looper_cmd
The loop should stop gracefully after a one‑second grace period; the client should not crash.
8c – Save empty loop
Attempt to save when the current scene is not LOOPING or loop_count == 0. No file should be created. The engine should log a message to stderr.
Environment Variables
LOOPER_CMD_FIFO(overrides/tmp/looper_cmd) – useful for running multiple instances for testing.JACK_DEFAULT_SERVER(JACK environment) – can be set to run a separate JACK server.
Troubleshooting
- No audio after connection: Ensure
jack_lspshows both source and destination ports, and that the looper is the only client using those ports. - MIDI not recognised: Verify that
midi_control_portis created (looper:control). Usejack_midi_dumpto see if note events arrive. - “save.wav not created“ after save command: The scene must be in LOOPING state and
loop_count> 0. Check the engine’s terminal output for error messages.
Carla Plugin Management Manual Tests
Test C1 – Load a plugin via colon command
-
Ensure the looper engine is running, and the client (
looper-client) is also running. -
In the client, enter colon mode (
:) and type:from looper:outputthen press Enter.
-
Enter colon mode again and type:
to system:playback_1 -
Load a test LV2 plugin (e.g., /usr/lib/lv2/amsynth.lv2/amsynth.so):
addplugin /usr/lib/lv2/amsynth.lv2/amsynth.so -
The plugin should be loaded into Carla and its JACK ports are automatically connected (if
fromandtowere set). You should see the plugin appear in the rack view when you pressR. -
Play some audio through the looper – it should be processed by the plugin.
Test C2 – Toggle bypass
-
In rack view (
R), select the plugin usingj/k. -
Press
borBto toggle bypass. -
The effect should stop processing (bypass mode active); pressing again reactivates.
Test C3 – Disconnect a plugin
-
In rack view, select the plugin.
-
Press
xorXto disconnect all its JACK connections. -
The plugin should no longer be connected to any looper ports; the audio should pass through unaffected.
Test C4 – Unload a plugin
-
In rack view, select the plugin.
-
Press
dorDto unload (remove) the plugin. -
The plugin disappears from the rack list.
Test C5 – Manual connection using colon commands
-
Set
fromandtoports as in Test C1. -
Load a plugin without auto‑connection:
- Do not set
from/to, or set them after loading. - Use
addpluginwith only a path.
- Do not set
-
Manually connect ports in colon mode:
connect looper:output amsynth:inThe connection should be established.
-
Verify in
jack_lspthat the ports are connected.
Test C6 – Disconnect using colon commands
-
After a manual connection, disconnect using:
disconnect looper:output amsynth:in -
The ports should be disconnected.
Last updated: 18 May 2026