feat: refactor transport into separate module with master/slave clock support

Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-01 21:08:38 +00:00
parent c2ad0e874c
commit a47598df8c
6 changed files with 490 additions and 229 deletions

View File

@@ -29,20 +29,13 @@ static Engine *create_test_engine(void) {
command_queue_init(&engine->command_queue);
// Initialize atomic state mirrors
atomic_store(&engine->transport_rolling, 0);
atomic_store(&engine->transport_clock_count, 0);
atomic_store(&engine->transport_beat_position, 0);
atomic_store(&engine->transport_bar_position, 0);
atomic_store(&engine->transport_sample_position, 0);
atomic_store(&engine->quantize_mode_atomic, (int)QUANTIZE_OFF);
atomic_store(&engine->quantize_threshold_atomic, 0);
// Initialize transport
engine->transport.rolling = false;
engine->transport.clock_count = 0;
engine->transport.beat_position = 0;
engine->transport.bar_position = 0;
engine->transport.sample_position = 0;
engine->transport = (Transport *)calloc(1, sizeof(Transport));
assert(engine->transport != NULL);
transport_init(engine->transport, 48000);
for (int i = 0; i < MAX_CLIPS; i++) {
engine->clips[i].state = CLIP_EMPTY;
@@ -65,6 +58,10 @@ static void destroy_test_engine(Engine *engine) {
qt = next;
}
if (engine->transport) {
transport_cleanup(engine->transport);
free(engine->transport);
}
for (int i = 0; i < MAX_CLIPS; i++) {
free(engine->clips[i].buffer);
}
@@ -196,17 +193,17 @@ void test_transport_reset_via_tui(void) {
Engine *engine = create_test_engine();
// Set up transport state
engine->transport.rolling = true;
engine->transport.clock_count = 100;
engine->transport.beat_position = 2;
engine->transport.bar_position = 5;
engine->transport.sample_position = 10000;
engine->transport->state = TRANSPORT_PLAYING;
engine->transport->clock_count = 100;
engine->transport->beat_position = 2;
engine->transport->bar_position = 5;
engine->transport->sample_position = 10000;
// Simulate pressing 'x'
engine_reset_transport(engine);
engine_process_commands(engine);
assert(engine->transport.rolling == false);
assert(engine->transport->state == TRANSPORT_STOPPED);
assert(engine->transport.clock_count == 0);
assert(engine->transport.beat_position == 0);
assert(engine->transport.bar_position == 0);
@@ -437,16 +434,16 @@ void test_multiple_transport_resets(void) {
// Reset transport multiple times
for (int i = 0; i < 5; i++) {
engine->transport.rolling = true;
engine->transport.clock_count = 100 + i;
engine->transport.beat_position = i % 4;
engine->transport.bar_position = i;
engine->transport.sample_position = 10000 * i;
engine->transport->state = TRANSPORT_PLAYING;
engine->transport->clock_count = 100 + i;
engine->transport->beat_position = i % 4;
engine->transport->bar_position = i;
engine->transport->sample_position = 10000 * i;
engine_reset_transport(engine);
engine_process_commands(engine);
assert(engine->transport.rolling == false);
assert(engine->transport->state == TRANSPORT_STOPPED);
assert(engine->transport.clock_count == 0);
assert(engine->transport.beat_position == 0);
assert(engine->transport.bar_position == 0);
@@ -1531,26 +1528,26 @@ void test_undo_transport_reset(void) {
Engine *engine = create_test_engine();
// Set up transport state
engine->transport.rolling = true;
engine->transport.clock_count = 100;
engine->transport.beat_position = 2;
engine->transport.bar_position = 5;
engine->transport.sample_position = 10000;
engine->transport->state = TRANSPORT_PLAYING;
engine->transport->clock_count = 100;
engine->transport->beat_position = 2;
engine->transport->bar_position = 5;
engine->transport->sample_position = 10000;
// Reset transport
engine_reset_transport(engine);
engine_process_commands(engine);
assert(engine->transport.rolling == false);
assert(engine->transport.clock_count == 0);
assert(engine->transport->state == TRANSPORT_STOPPED);
assert(engine->transport->clock_count == 0);
// Undo: should restore transport state
engine_undo_action(engine);
engine_process_commands(engine);
assert(engine->transport.rolling == true);
assert(engine->transport.clock_count == 100);
assert(engine->transport.beat_position == 2);
assert(engine->transport.bar_position == 5);
assert(engine->transport.sample_position == 10000);
assert(engine->transport->state == TRANSPORT_PLAYING);
assert(engine->transport->clock_count == 100);
assert(engine->transport->beat_position == 2);
assert(engine->transport->bar_position == 5);
assert(engine->transport->sample_position == 10000);
printf("PASSED\n");
destroy_test_engine(engine);