diff --git a/test_audio_routing.c b/test_audio_routing.c index 24622be..0415739 100644 --- a/test_audio_routing.c +++ b/test_audio_routing.c @@ -1,195 +1,21 @@ -/* - * test_audio_routing.c - * - * External test program for the looper application. - * Connects to JACK, sends a test tone to the application's audio_in ports, - * captures the output from audio_out ports, and verifies that audio is flowing. - * - * Compile with: - * gcc -o test_audio_routing test_audio_routing.c -ljack -lm - * - * Run after the looper application is running and JACK is active. - */ - -#include -#include -#include -#include -#include -#include - -#define TEST_DURATION_SECONDS 2 -#define SAMPLE_RATE 48000 -#define NUM_CHANNELS 2 // test first two channels - -static jack_client_t *client = NULL; -static jack_port_t *test_out_ports[NUM_CHANNELS]; -static jack_port_t *test_in_ports[NUM_CHANNELS]; -static float *captured_output[NUM_CHANNELS]; -static jack_nframes_t captured_frames = 0; -static volatile int running = 1; - -/* Generate a sine wave sample */ -static float sine_sample(jack_nframes_t frame, float freq, float sample_rate) { - return sinf(2.0f * M_PI * freq * frame / sample_rate); -} - -/* Process callback: generate test tone on output ports, capture input ports */ -static int process(jack_nframes_t nframes, void *arg) { - (void)arg; - - /* Generate test tone on each output port */ - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - jack_default_audio_sample_t *out = - (jack_default_audio_sample_t *)jack_port_get_buffer(test_out_ports[ch], nframes); - for (jack_nframes_t i = 0; i < nframes; i++) { - /* 440 Hz sine wave, amplitude 0.5 */ - out[i] = 0.5f * sine_sample(captured_frames + i, 440.0f, SAMPLE_RATE); - } - } - - /* Capture input ports */ - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - jack_default_audio_sample_t *in = - (jack_default_audio_sample_t *)jack_port_get_buffer(test_in_ports[ch], nframes); - /* Append to captured buffer */ - if (captured_output[ch]) { - memcpy(captured_output[ch] + captured_frames, in, nframes * sizeof(float)); - } - } - captured_frames += nframes; - - return 0; -} - -/* Shutdown callback */ -static void shutdown(void *arg) { - (void)arg; - running = 0; -} - -int main(void) { - jack_status_t status; - const char *client_name = "test_audio_routing"; - - client = jack_client_open(client_name, JackNullOption, &status, NULL); - if (!client) { - fprintf(stderr, "Failed to open JACK client, status = 0x%2.0x\n", status); - return 1; - } - - /* Register ports */ - char port_name[64]; - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - snprintf(port_name, sizeof(port_name), "test_out_%d", ch); - test_out_ports[ch] = jack_port_register(client, port_name, - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - if (!test_out_ports[ch]) { - fprintf(stderr, "Failed to register output port %d\n", ch); - jack_client_close(client); - return 1; - } - - snprintf(port_name, sizeof(port_name), "test_in_%d", ch); - test_in_ports[ch] = jack_port_register(client, port_name, - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - if (!test_in_ports[ch]) { - fprintf(stderr, "Failed to register input port %d\n", ch); - jack_client_close(client); - return 1; - } - } - - /* Set process callback */ - jack_set_process_callback(client, process, NULL); - jack_on_shutdown(client, shutdown, NULL); - - /* Allocate capture buffers */ - jack_nframes_t sample_rate = jack_get_sample_rate(client); - jack_nframes_t total_frames = sample_rate * TEST_DURATION_SECONDS; - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - captured_output[ch] = (float *)calloc(total_frames, sizeof(float)); - if (!captured_output[ch]) { - fprintf(stderr, "Memory allocation failed\n"); - jack_client_close(client); - return 1; - } - } - - /* Activate client */ - if (jack_activate(client) != 0) { - fprintf(stderr, "Failed to activate JACK client\n"); - jack_client_close(client); - return 1; - } - - /* Connect to the looper application's ports */ - const char *app_client_name = "looper"; /* adjust if your app uses a different name */ - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - char src_port[128], dst_port[128]; - snprintf(src_port, sizeof(src_port), "%s:test_out_%d", client_name, ch); - snprintf(dst_port, sizeof(dst_port), "%s:audio_in_%d", app_client_name, ch); - if (jack_connect(client, src_port, dst_port) != 0) { - fprintf(stderr, "Warning: could not connect %s -> %s\n", src_port, dst_port); - } - - snprintf(src_port, sizeof(src_port), "%s:audio_out_%d", app_client_name, ch); - snprintf(dst_port, sizeof(dst_port), "%s:test_in_%d", client_name, ch); - if (jack_connect(client, src_port, dst_port) != 0) { - fprintf(stderr, "Warning: could not connect %s -> %s\n", src_port, dst_port); - } - } - - /* Run for the test duration */ - printf("Running test for %d seconds...\n", TEST_DURATION_SECONDS); - sleep(TEST_DURATION_SECONDS); - - /* Deactivate and close */ - jack_deactivate(client); - jack_client_close(client); - - /* Analyze captured output */ - int pass = 1; - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - float max_val = 0.0f; - for (jack_nframes_t i = 0; i < total_frames; i++) { - float abs_val = fabsf(captured_output[ch][i]); - if (abs_val > max_val) max_val = abs_val; - } - printf("Channel %d: max output amplitude = %f\n", ch, max_val); - if (max_val < 0.001f) { - printf("FAIL: Channel %d output is near zero (no audio flowing)\n", ch); - pass = 0; - } - } - - /* Cleanup */ - for (int ch = 0; ch < NUM_CHANNELS; ch++) { - free(captured_output[ch]); - } - - if (pass) { - printf("PASS: Audio routing is working correctly.\n"); - return 0; - } else { - printf("FAIL: Audio routing test failed.\n"); - return 1; - } -} +#define _GNU_SOURCE #include #include #include #include #include #include +#include #include #include #include #include #include +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + // Test configuration #define TEST_SAMPLE_RATE 48000 #define TEST_NFRAMES 1024