fix: add atomic operations for clip state and read_position to fix race conditions
Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
@@ -268,7 +268,7 @@ static void send_sine_wave(int channel, float frequency, float amplitude, jack_n
|
||||
|
||||
// Wait for the JACK callback to consume the audio
|
||||
// (the callback runs in a separate thread)
|
||||
usleep(duration * 1000 + 100000); // duration ms + 100ms extra
|
||||
usleep(duration * 1000 + 300000); // duration ms + 300ms extra
|
||||
}
|
||||
|
||||
static void send_midi_note(int note, int velocity) {
|
||||
@@ -285,7 +285,8 @@ static void send_midi_note(int note, int velocity) {
|
||||
|
||||
pthread_mutex_unlock(&test_buffer_mutex);
|
||||
|
||||
usleep(100000); // 100ms to let JACK process
|
||||
// Wait longer for JACK to process the MIDI message
|
||||
usleep(300000); // 300ms to let JACK process
|
||||
}
|
||||
|
||||
static float get_channel_rms(int channel) {
|
||||
@@ -331,24 +332,30 @@ static void test_basic_audio_routing(void) {
|
||||
clear_output_buffers();
|
||||
|
||||
// Step 1: Start recording on clip 0 (note 0 triggers clip 0)
|
||||
printf(" Sending MIDI note 0 to start recording...\n");
|
||||
send_midi_note(0, 100);
|
||||
usleep(100000);
|
||||
|
||||
// Step 2: Send audio to channel 0 while recording
|
||||
send_sine_wave(0, 440.0, 0.5, 500);
|
||||
usleep(200000);
|
||||
|
||||
// Step 2: Send audio to channel 0 while recording
|
||||
printf(" Sending sine wave to channel 0...\n");
|
||||
send_sine_wave(0, 440.0, 0.5, 500);
|
||||
usleep(300000);
|
||||
|
||||
// Step 3: Stop recording (toggle to looping)
|
||||
printf(" Sending MIDI note 0 to toggle to looping...\n");
|
||||
send_midi_note(0, 100);
|
||||
usleep(100000);
|
||||
usleep(200000);
|
||||
|
||||
// Step 4: Clear output and check that looped audio appears
|
||||
printf(" Clearing output buffers and waiting for looped audio...\n");
|
||||
clear_output_buffers();
|
||||
usleep(300000);
|
||||
usleep(500000);
|
||||
|
||||
float rms_0 = get_channel_rms(0);
|
||||
float rms_1 = get_channel_rms(1);
|
||||
|
||||
printf(" RMS channel 0: %f, channel 1: %f\n", rms_0, rms_1);
|
||||
|
||||
TEST("Channel 0 has audio output", rms_0 > 0.01f);
|
||||
TEST("Channel 1 has no audio (no input)", rms_1 < 0.01f);
|
||||
}
|
||||
@@ -360,21 +367,23 @@ static void test_multi_channel_routing(void) {
|
||||
|
||||
// Record clips on channels 0, 1, 2
|
||||
for (int ch = 0; ch < 3; ch++) {
|
||||
printf(" Recording clip on channel %d...\n", ch);
|
||||
// Note ch triggers clip ch (since note % MAX_CLIPS = ch for ch < 512)
|
||||
send_midi_note(ch, 100);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_sine_wave(ch, 440.0 * (ch + 1), 0.5, 300);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_midi_note(ch, 100); // Toggle to looping
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
}
|
||||
|
||||
clear_output_buffers();
|
||||
usleep(300000);
|
||||
usleep(500000);
|
||||
|
||||
float rms[3];
|
||||
for (int ch = 0; ch < 3; ch++) {
|
||||
rms[ch] = get_channel_rms(ch);
|
||||
printf(" RMS channel %d: %f\n", ch, rms[ch]);
|
||||
}
|
||||
|
||||
TEST("Channel 0 has audio", rms[0] > 0.01f);
|
||||
@@ -389,23 +398,28 @@ static void test_midi_clip_trigger(void) {
|
||||
clear_output_buffers();
|
||||
|
||||
// Send MIDI note to trigger clip recording (note 0 triggers clip 0)
|
||||
printf(" Sending MIDI note 0 to start recording...\n");
|
||||
send_midi_note(0, 100);
|
||||
usleep(100000);
|
||||
|
||||
// Send audio to channel 0 while clip is recording
|
||||
send_sine_wave(0, 440.0, 0.5, 500);
|
||||
usleep(200000);
|
||||
|
||||
// Send audio to channel 0 while clip is recording
|
||||
printf(" Sending sine wave to channel 0...\n");
|
||||
send_sine_wave(0, 440.0, 0.5, 500);
|
||||
usleep(300000);
|
||||
|
||||
// Send another MIDI note to stop recording (toggle to looping)
|
||||
printf(" Sending MIDI note 0 to toggle to looping...\n");
|
||||
send_midi_note(0, 100);
|
||||
usleep(100000);
|
||||
usleep(200000);
|
||||
|
||||
// Now the clip should be looping - clear output and check
|
||||
printf(" Clearing output buffers and waiting for looped audio...\n");
|
||||
clear_output_buffers();
|
||||
usleep(300000);
|
||||
usleep(500000);
|
||||
|
||||
// Check that audio is still coming out (from the looped clip)
|
||||
float rms = get_channel_rms(0);
|
||||
printf(" RMS channel 0: %f\n", rms);
|
||||
TEST("Looped clip produces audio", rms > 0.01f);
|
||||
}
|
||||
|
||||
@@ -416,20 +430,22 @@ static void test_midi_scene_launch(void) {
|
||||
|
||||
// Record clips on channels 0-3 using notes 0-3
|
||||
for (int ch = 0; ch < 4; ch++) {
|
||||
printf(" Recording clip on channel %d...\n", ch);
|
||||
send_midi_note(ch, 100); // Start recording
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_sine_wave(ch, 440.0 * (ch + 1), 0.3, 200);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_midi_note(ch, 100); // Toggle to looping
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
}
|
||||
|
||||
clear_output_buffers();
|
||||
usleep(300000);
|
||||
usleep(500000);
|
||||
|
||||
// All 4 channels should have audio from their looped clips
|
||||
for (int ch = 0; ch < 4; ch++) {
|
||||
float rms = get_channel_rms(ch);
|
||||
printf(" RMS channel %d: %f\n", ch, rms);
|
||||
char test_name[64];
|
||||
snprintf(test_name, sizeof(test_name), "Channel %d has looped audio", ch);
|
||||
TEST(test_name, rms > 0.01f);
|
||||
@@ -442,20 +458,23 @@ static void test_channel_independence(void) {
|
||||
clear_output_buffers();
|
||||
|
||||
// Record on channel 0 only
|
||||
printf(" Recording on channel 0 only...\n");
|
||||
send_midi_note(0, 100);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_sine_wave(0, 440.0, 0.8, 500);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_midi_note(0, 100); // Toggle to looping
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
|
||||
clear_output_buffers();
|
||||
usleep(300000);
|
||||
usleep(500000);
|
||||
|
||||
float rms_0 = get_channel_rms(0);
|
||||
float rms_1 = get_channel_rms(1);
|
||||
float rms_2 = get_channel_rms(2);
|
||||
|
||||
printf(" RMS channel 0: %f, channel 1: %f, channel 2: %f\n", rms_0, rms_1, rms_2);
|
||||
|
||||
TEST("Channel 0 has strong signal", rms_0 > 0.1f);
|
||||
TEST("Channel 1 has no crosstalk", rms_1 < 0.01f);
|
||||
TEST("Channel 2 has no crosstalk", rms_2 < 0.01f);
|
||||
@@ -467,17 +486,19 @@ static void test_volume_control(void) {
|
||||
clear_output_buffers();
|
||||
|
||||
// Record on channel 0
|
||||
printf(" Recording on channel 0...\n");
|
||||
send_midi_note(0, 100);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_sine_wave(0, 440.0, 0.5, 500);
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
send_midi_note(0, 100); // Toggle to looping
|
||||
usleep(50000);
|
||||
usleep(200000);
|
||||
|
||||
clear_output_buffers();
|
||||
usleep(300000);
|
||||
usleep(500000);
|
||||
|
||||
float rms = get_channel_rms(0);
|
||||
printf(" RMS channel 0: %f\n", rms);
|
||||
TEST("Audio passes through at default volume", rms > 0.01f);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user