#!/bin/bash
# jack-latency-test — measure USB audio round-trip latency at various buffer sizes
# Usage: sudo jack-latency-test [device] [sample_rate]
#
# Prerequisites:
#   - JACK2 installed
#   - Physical loopback cable: Output 1 -> Input 1
#   - User in 'audio' group with realtime limits

set -e

DEVICE="${1:-hw:USB}"
RATE="${2:-48000}"
OUTPUT="system:playback_1"
INPUT="system:capture_1"
RESULT_FILE="/tmp/jack-latency-results.txt"

echo "=== JACK Latency Test ==="
echo "Device:       $DEVICE"
echo "Sample rate:  $RATE Hz"
echo "Output port:  $OUTPUT"
echo "Input port:   $INPUT"
echo ""
echo ">>> ENSURE PHYSICAL LOOPBACK CABLE IS CONNECTED: Output 1 -> Input 1 <<<"
echo "=========================================="
echo ""

: > "$RESULT_FILE"

# Test various buffer sizes
for PERIOD in 32 64 128 256 512 1024; do
    PERIOD_MS=$(echo "scale=2; $PERIOD / $RATE * 1000" | bc 2>/dev/null || \
                python3 -c "print(f'{$PERIOD / $RATE * 1000:.2f}')" 2>/dev/null || \
                echo "?")
    echo -n "Period ${PERIOD} frames (${PERIOD_MS}ms): "

    # Kill any running JACK
    killall -9 jackd 2>/dev/null || true
    sleep 1

    # Start JACK with this period
    jackd -P70 -t2000 -d alsa -d "$DEVICE" -r "$RATE" -p "$PERIOD" -n 3 -S \
        > /tmp/jackd-latency-test.log 2>&1 &
    JACK_PID=$!

    # Wait for JACK to be ready
    for _ in $(seq 1 15); do
        if jack_control status 2>/dev/null | grep -q "started"; then
            break
        fi
        sleep 1
    done

    if ! jack_control status 2>/dev/null | grep -q "started"; then
        echo "JACK failed to start with period $PERIOD, skipping"
        killall -9 jackd 2>/dev/null || true
        continue
    fi

    sleep 1

    # Run jack_delay measurement
    RESULT=$(jack_delay -O "$OUTPUT" -I "$INPUT" -c 128 2>&1)
    JACK_DELAY_EXIT=$?

    if [ $JACK_DELAY_EXIT -eq 0 ] && [ -n "$RESULT" ]; then
        # Parse the result line (last line is the measurement)
        MEASUREMENT=$(echo "$RESULT" | tail -1)
        echo "$MEASUREMENT"
        echo "${PERIOD} frames: ${MEASUREMENT}" >> "$RESULT_FILE"
    else
        echo "measurement failed (check loopback cable)"
        echo "error output: $RESULT" >> "$RESULT_FILE"
    fi

    killall -9 jackd jack_delay 2>/dev/null || true
    sleep 1
done

echo ""
echo "=========================================="
echo "Results saved to: $RESULT_FILE"
echo ""
cat "$RESULT_FILE"
echo ""
echo "Done."
echo ""
echo "Target: 128 frames should give <= 12ms round-trip."
echo "If above 12ms, check USB cable, power, CPU governor, and IRQ priorities."
