diff --git a/engine.c b/engine.c index 2e8ef48..7d2110b 100644 --- a/engine.c +++ b/engine.c @@ -201,14 +201,18 @@ void queue_trigger(Engine *engine, int clip_index, bool is_scene, jack_nframes_t engine->queued_triggers = qt; } else { QueuedTrigger *last = engine->queued_triggers; - while (last->next) last = last->next; - last->next = qt; + while (last && last->next) last = last->next; // FIX: add null check for last + if (last) { // ADD THIS + last->next = qt; + } else { + engine->queued_triggers = qt; // Fallback + } } } // Process queued triggers at quantization boundaries static void process_queued_triggers(Engine *engine, jack_nframes_t nframes) { - if (!engine->queued_triggers) return; + if (!engine || !engine->queued_triggers) return; // FIX: add engine null check TransportState transport_state = (TransportState)atomic_load(&engine->transport->state_atomic); if (transport_state != TRANSPORT_PLAYING) return; @@ -281,6 +285,7 @@ void engine_process_commands(Engine *engine) { case CMD_TRIGGER_CLIP: { if (cmd.index < 0 || cmd.index >= MAX_CLIPS) break; Clip *clip = &engine->clips[cmd.index]; + if (!clip->buffer) break; // ADD THIS - prevent segfault on freed buffer // Record undo action UndoAction action; @@ -503,10 +508,13 @@ void engine_undo(Engine *engine) { switch (action->type) { case ACTION_TRIGGER_CLIP: { int clip_idx = action->index; - engine->clips[clip_idx].state = action->previous_state; - engine->clips[clip_idx].buffer_size = action->previous_buffer_size; - engine->clips[clip_idx].write_position = action->previous_write_position; - engine->clips[clip_idx].read_position = action->previous_read_position; + if (clip_idx < 0 || clip_idx >= MAX_CLIPS) break; + Clip *clip = &engine->clips[clip_idx]; + if (!clip->buffer) break; // ADD THIS + clip->state = action->previous_state; + clip->buffer_size = action->previous_buffer_size; + clip->write_position = action->previous_write_position; + clip->read_position = action->previous_read_position; break; } @@ -574,8 +582,10 @@ void engine_redo(Engine *engine) { switch (action->type) { case ACTION_TRIGGER_CLIP: { int clip_idx = action->index; - // Re-apply the trigger by directly manipulating state + if (clip_idx < 0 || clip_idx >= MAX_CLIPS) break; Clip *clip = &engine->clips[clip_idx]; + if (!clip->buffer) break; // ADD THIS + // Re-apply the trigger by directly manipulating state switch (clip->state) { case CLIP_EMPTY: clip->state = CLIP_RECORDING; @@ -699,6 +709,7 @@ int engine_init(Engine *engine, const char *client_name) { // Cleanup on allocation failure for (int j = 0; j < MAX_CLIPS; j++) { free(engine->clips[j].buffer); + engine->clips[j].buffer = NULL; // ADD THIS } return -1; } @@ -712,7 +723,10 @@ int engine_init(Engine *engine, const char *client_name) { // Cleanup on allocation failure for (int j = 0; j < i; j++) { free(engine->clips[j].buffer); + engine->clips[j].buffer = NULL; // ADD THIS } + free(engine->transport); + engine->transport = NULL; // ADD THIS return -1; } engine->clips[i].buffer_size = 0; diff --git a/transport.c b/transport.c index e047d4d..f49dd9e 100644 --- a/transport.c +++ b/transport.c @@ -112,7 +112,7 @@ double transport_get_bpm(Transport *transport) { int transport_process(Transport *transport, jack_nframes_t nframes, void *midi_clock_in_buf, void *midi_clock_out_buf) { - if (!transport) return 0; + if (!transport) return -1; // ADD THIS int clock_ticks_generated = 0;