#!/bin/bash # jack-looper-test.sh - Test audio routing for the jack-looper Carla plugin set -e # Configuration PLUGIN_BINARY="./jack-looper" # Adjust path to your compiled binary TEST_DURATION=5 # seconds TEST_FREQ=440 # Hz TEST_AMP=0.5 # amplitude SAMPLE_RATE=48000 # must match JACK server # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color echo -e "${YELLOW}=== JACK Looper Plugin Test ===${NC}" # 1. Check if JACK is running, start if not if ! jack_wait -c 2>/dev/null; then echo -e "${YELLOW}Starting JACK server...${NC}" jackd -d alsa -r $SAMPLE_RATE -p 1024 -n 2 & JACK_PID=$! sleep 2 if ! jack_wait -c; then echo -e "${RED}Failed to start JACK server${NC}" exit 1 fi echo -e "${GREEN}JACK server started (PID: $JACK_PID)${NC}" else echo -e "${GREEN}JACK server already running${NC}" fi # 2. Start the plugin echo -e "${YELLOW}Starting plugin...${NC}" $PLUGIN_BINARY & PLUGIN_PID=$! sleep 1 # Check if plugin is running if ! kill -0 $PLUGIN_PID 2>/dev/null; then echo -e "${RED}Plugin failed to start${NC}" exit 1 fi echo -e "${GREEN}Plugin started (PID: $PLUGIN_PID)${NC}" # 3. List available JACK ports echo -e "${YELLOW}Available JACK ports:${NC}" jack_lsp # 4. Connect system capture to plugin input echo -e "${YELLOW}Connecting system capture to plugin input...${NC}" jack_connect system:capture_1 "$PLUGIN_BINARY:in_1" 2>/dev/null || true jack_connect system:capture_2 "$PLUGIN_BINARY:in_2" 2>/dev/null || true # 5. Connect plugin output to system playback echo -e "${YELLOW}Connecting plugin output to system playback...${NC}" jack_connect "$PLUGIN_BINARY:out_1" system:playback_1 2>/dev/null || true jack_connect "$PLUGIN_BINARY:out_2" system:playback_2 2>/dev/null || true # 6. Generate a test tone and play it through system capture echo -e "${YELLOW}Playing test tone (${TEST_FREQ}Hz) for ${TEST_DURATION} seconds...${NC}" # Generate sine wave and play through JACK python3 -c " import numpy as np import jack import time client = jack.Client('test_tone') client.activate() # Create output port out_port = client.outports.register('out_1') # Generate sine wave sample_rate = $SAMPLE_RATE duration = $TEST_DURATION frequency = $TEST_FREQ amplitude = $TEST_AMP t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False) sine_wave = (amplitude * np.sin(2 * np.pi * frequency * t)).astype(np.float32) # Play the tone chunk_size = 1024 for i in range(0, len(sine_wave), chunk_size): chunk = sine_wave[i:i+chunk_size] if len(chunk) < chunk_size: chunk = np.pad(chunk, (0, chunk_size - len(chunk)), 'constant') out_port.get_array()[:] = chunk time.sleep(chunk_size / sample_rate) client.deactivate() " & TONE_PID=$! sleep $TEST_DURATION # 7. Record the output to verify routing echo -e "${YELLOW}Recording output for verification...${NC}" # Record using jack_capture or jack_rec if command -v jack_capture &> /dev/null; then jack_capture --duration $TEST_DURATION --filename test_output.wav --port "$PLUGIN_BINARY:out_1" "$PLUGIN_BINARY:out_2" elif command -v jack_rec &> /dev/null; then jack_rec -f test_output.wav -d $TEST_DURATION -p "$PLUGIN_BINARY:out_1" -p "$PLUGIN_BINARY:out_2" else echo -e "${YELLOW}No recording tool found (jack_capture or jack_rec). Skipping recording.${NC}" fi # 8. Cleanup echo -e "${YELLOW}Cleaning up...${NC}" kill $TONE_PID 2>/dev/null || true kill $PLUGIN_PID 2>/dev/null || true sleep 1 # Stop JACK if we started it if [ -n "$JACK_PID" ]; then kill $JACK_PID 2>/dev/null || true fi echo -e "${GREEN}=== Test Complete ===${NC}" # Check if recording was made if [ -f test_output.wav ]; then echo -e "${GREEN}Recording saved to test_output.wav${NC}" echo -e "${YELLOW}You can play it back with: aplay test_output.wav${NC}" fi