From 6f7bf08ae0d76397ddfcb5092e985ddba5e4da59 Mon Sep 17 00:00:00 2001 From: Loic Coenen Date: Sun, 3 May 2026 19:03:27 +0000 Subject: [PATCH] refactor: convert MidiClip events to dynamic allocation to reduce stack size Co-authored-by: aider (deepseek/deepseek-coder) --- dispatcher.c | 23 +++++++++++++++++++++++ test_engine.c | 10 ++++++++++ 2 files changed, 33 insertions(+) diff --git a/dispatcher.c b/dispatcher.c index f62b566..60e9abc 100644 --- a/dispatcher.c +++ b/dispatcher.c @@ -495,6 +495,7 @@ AppState reducer(AppState state, Action action) { state.midi_clips[idx].state = CLIP_EMPTY; state.midi_clips[idx].event_count = 0; state.midi_clips[idx].read_index = 0; + // Don't free events here - just reset count } return state; } @@ -526,6 +527,13 @@ AppState reducer(AppState state, Action action) { } else { clip->buffer = (float *)calloc(MAX_BUFFER_SIZE, sizeof(float)); } + + // NEW: Reset midi clips + MidiClip *mclip = &state.midi_clips[i]; + mclip->state = CLIP_EMPTY; + mclip->event_count = 0; + mclip->read_index = 0; + // events pointer should already be valid from init } // Reset Carla host @@ -595,6 +603,15 @@ static void* dispatcher_thread_func(void *arg) { DispatchFn dispatcher_init(AppState *initial_state) { memcpy(&dispatcher.state, initial_state, sizeof(AppState)); + + // NEW: Ensure midi clip events are allocated (in case initial_state has NULL pointers) + for (int i = 0; i < MAX_CLIPS; i++) { + if (dispatcher.state.midi_clips[i].events == NULL) { + dispatcher.state.midi_clips[i].events = (MidiEvent *)calloc(MAX_MIDI_EVENTS, sizeof(MidiEvent)); + dispatcher.state.midi_clips[i].max_events = MAX_MIDI_EVENTS; + } + } + atomic_store(&dispatcher.running, false); atomic_store(&dispatcher.write_index, 0); atomic_store(&dispatcher.read_index, 0); @@ -617,6 +634,12 @@ void dispatcher_stop(void) { pthread_cond_signal(&dispatcher.action_cond); pthread_join(dispatcher.thread, NULL); + // NEW: Free midi clip events + for (int i = 0; i < MAX_CLIPS; i++) { + free(dispatcher.state.midi_clips[i].events); + dispatcher.state.midi_clips[i].events = NULL; + } + pthread_mutex_lock(&dispatcher.subscribers_mutex); SubscriberNode *node = dispatcher.subscribers; while (node) { diff --git a/test_engine.c b/test_engine.c index 2d80813..e87b8d5 100644 --- a/test_engine.c +++ b/test_engine.c @@ -32,6 +32,14 @@ static AppState create_test_state(void) { state.clips[i].buffer_size = 0; state.clips[i].write_position = 0; state.clips[i].read_position = 0; + + // NEW: Initialize midi clips + state.midi_clips[i].state = CLIP_EMPTY; + state.midi_clips[i].events = (MidiEvent *)calloc(MAX_MIDI_EVENTS, sizeof(MidiEvent)); + assert(state.midi_clips[i].events != NULL); + state.midi_clips[i].max_events = MAX_MIDI_EVENTS; + state.midi_clips[i].event_count = 0; + state.midi_clips[i].read_index = 0; } return state; @@ -42,6 +50,8 @@ static void destroy_test_state(AppState *state) { for (int i = 0; i < MAX_CLIPS; i++) { free(state->clips[i].buffer); state->clips[i].buffer = NULL; + free(state->midi_clips[i].events); // NEW + state->midi_clips[i].events = NULL; } } }