fix: use atomic stores for clip state in dispatcher.c
Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
77
dispatcher.c
77
dispatcher.c
@@ -127,11 +127,11 @@ AppState* dispatcher_get_state_ptr(void) {
|
||||
|
||||
static void save_undo_state(AppState *state, int clip_index) {
|
||||
int undo_idx = state->undo.undo_index % MAX_UNDO_HISTORY;
|
||||
state->undo.prev_clip_states[undo_idx] = state->clips[clip_index].state;
|
||||
state->undo.prev_clip_states[undo_idx] = (ClipState)atomic_load(&state->clips[clip_index].state);
|
||||
state->undo.prev_clip_indices[undo_idx] = clip_index;
|
||||
state->undo.prev_buffer_sizes[undo_idx] = state->clips[clip_index].buffer_size;
|
||||
state->undo.prev_write_positions[undo_idx] = state->clips[clip_index].write_position;
|
||||
state->undo.prev_read_positions[undo_idx] = state->clips[clip_index].read_position;
|
||||
state->undo.prev_read_positions[undo_idx] = atomic_load(&state->clips[clip_index].read_position);
|
||||
state->undo.batch_sizes[undo_idx] = 0; // Will be set by caller
|
||||
state->undo.undo_index++;
|
||||
state->undo.redo_index = state->undo.undo_index;
|
||||
@@ -145,17 +145,19 @@ static void clip_trigger(AppState *state, int clip_index) {
|
||||
|
||||
// Do NOT save undo here - caller will do it
|
||||
|
||||
switch (clip->state) {
|
||||
ClipState current_state = (ClipState)atomic_load(&clip->state);
|
||||
|
||||
switch (current_state) {
|
||||
case CLIP_EMPTY:
|
||||
clip->state = CLIP_RECORDING;
|
||||
atomic_store(&clip->state, CLIP_RECORDING);
|
||||
clip->write_position = 0;
|
||||
clip->buffer_size = 0;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
case CLIP_RECORDING: {
|
||||
// Transition to looping: copy from ring buffer to clip buffer
|
||||
clip->state = CLIP_LOOPING;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
atomic_store(&clip->read_position, 0);
|
||||
|
||||
// Determine which channel this clip belongs to
|
||||
int channel = clip_index % MAX_CHANNELS;
|
||||
@@ -177,12 +179,12 @@ static void clip_trigger(AppState *state, int clip_index) {
|
||||
break;
|
||||
}
|
||||
case CLIP_LOOPING:
|
||||
clip->state = CLIP_STOPPED;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->state, CLIP_STOPPED);
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
case CLIP_STOPPED:
|
||||
clip->state = CLIP_LOOPING;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -192,22 +194,24 @@ static void midi_clip_trigger(AppState *state, int clip_index) {
|
||||
|
||||
MidiClip *clip = &state->midi_clips[clip_index];
|
||||
|
||||
switch (clip->state) {
|
||||
ClipState current_state = (ClipState)atomic_load(&clip->state);
|
||||
|
||||
switch (current_state) {
|
||||
case CLIP_EMPTY:
|
||||
clip->state = CLIP_RECORDING;
|
||||
atomic_store(&clip->state, CLIP_RECORDING);
|
||||
clip->event_count = 0;
|
||||
clip->read_index = 0;
|
||||
break;
|
||||
case CLIP_RECORDING:
|
||||
clip->state = CLIP_LOOPING;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
clip->read_index = 0;
|
||||
break;
|
||||
case CLIP_LOOPING:
|
||||
clip->state = CLIP_STOPPED;
|
||||
atomic_store(&clip->state, CLIP_STOPPED);
|
||||
clip->read_index = 0;
|
||||
break;
|
||||
case CLIP_STOPPED:
|
||||
clip->state = CLIP_LOOPING;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
clip->read_index = 0;
|
||||
break;
|
||||
}
|
||||
@@ -243,10 +247,10 @@ static void clip_reset(AppState *state, int clip_index) {
|
||||
|
||||
save_undo_state(state, clip_index);
|
||||
|
||||
clip->state = CLIP_EMPTY;
|
||||
atomic_store(&clip->state, CLIP_EMPTY);
|
||||
clip->buffer_size = 0;
|
||||
clip->write_position = 0;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->read_position, 0);
|
||||
if (clip->buffer) memset(clip->buffer, 0, MAX_BUFFER_SIZE * sizeof(float));
|
||||
|
||||
// Also reset the ring buffer read position for this channel
|
||||
@@ -269,10 +273,10 @@ static void undo_action(AppState *state) {
|
||||
|
||||
if (clip_idx >= 0 && clip_idx < MAX_CLIPS) {
|
||||
Clip *clip = &state->clips[clip_idx];
|
||||
clip->state = state->undo.prev_clip_states[current_idx];
|
||||
atomic_store(&clip->state, state->undo.prev_clip_states[current_idx]);
|
||||
clip->buffer_size = state->undo.prev_buffer_sizes[current_idx];
|
||||
clip->write_position = state->undo.prev_write_positions[current_idx];
|
||||
clip->read_position = state->undo.prev_read_positions[current_idx];
|
||||
atomic_store(&clip->read_position, state->undo.prev_read_positions[current_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,25 +298,26 @@ static void redo_action(AppState *state) {
|
||||
|
||||
if (clip_idx >= 0 && clip_idx < MAX_CLIPS) {
|
||||
Clip *clip = &state->clips[clip_idx];
|
||||
switch (clip->state) {
|
||||
ClipState current_state = (ClipState)atomic_load(&clip->state);
|
||||
switch (current_state) {
|
||||
case CLIP_EMPTY:
|
||||
clip->state = CLIP_RECORDING;
|
||||
atomic_store(&clip->state, CLIP_RECORDING);
|
||||
clip->write_position = 0;
|
||||
clip->buffer_size = 0;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
case CLIP_RECORDING:
|
||||
clip->state = CLIP_LOOPING;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
clip->buffer_size = clip->write_position;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
case CLIP_LOOPING:
|
||||
clip->state = CLIP_STOPPED;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->state, CLIP_STOPPED);
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
case CLIP_STOPPED:
|
||||
clip->state = CLIP_LOOPING;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
atomic_store(&clip->read_position, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -430,10 +435,10 @@ void reducer(AppState *state, Action action) {
|
||||
if (clip->buffer) {
|
||||
size_t copy_size = (num_samples < MAX_BUFFER_SIZE) ? num_samples : MAX_BUFFER_SIZE;
|
||||
memcpy(clip->buffer, new_buffer, copy_size * sizeof(float));
|
||||
clip->state = CLIP_LOOPING;
|
||||
atomic_store(&clip->state, CLIP_LOOPING);
|
||||
clip->buffer_size = copy_size;
|
||||
clip->write_position = copy_size;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->read_position, 0);
|
||||
printf("Loaded clip %d from %s\n", clip_idx, action.data.load_clip.filename);
|
||||
}
|
||||
free(new_buffer);
|
||||
@@ -516,7 +521,7 @@ void reducer(AppState *state, Action action) {
|
||||
case ACTION_MIDI_CLIP_RESET: {
|
||||
int idx = action.data.midi_clip_reset.clip_index;
|
||||
if (idx >= 0 && idx < MAX_CLIPS) {
|
||||
state->midi_clips[idx].state = CLIP_EMPTY;
|
||||
atomic_store(&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
|
||||
@@ -542,10 +547,10 @@ void reducer(AppState *state, Action action) {
|
||||
// Reset clips first
|
||||
for (int i = 0; i < MAX_CLIPS; i++) {
|
||||
Clip *clip = &state->clips[i];
|
||||
clip->state = CLIP_EMPTY;
|
||||
atomic_store(&clip->state, CLIP_EMPTY);
|
||||
clip->buffer_size = 0;
|
||||
clip->write_position = 0;
|
||||
clip->read_position = 0;
|
||||
atomic_store(&clip->read_position, 0);
|
||||
if (clip->buffer) {
|
||||
memset(clip->buffer, 0, MAX_BUFFER_SIZE * sizeof(float));
|
||||
} else {
|
||||
@@ -554,7 +559,7 @@ void reducer(AppState *state, Action action) {
|
||||
|
||||
// NEW: Reset midi clips
|
||||
MidiClip *mclip = &state->midi_clips[i];
|
||||
mclip->state = CLIP_EMPTY;
|
||||
atomic_store(&mclip->state, CLIP_EMPTY);
|
||||
mclip->event_count = 0;
|
||||
mclip->read_index = 0;
|
||||
mclip->max_events = MAX_MIDI_EVENTS;
|
||||
@@ -645,6 +650,7 @@ DispatchFn dispatcher_init(AppState *initial_state) {
|
||||
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.state.midi_clips[i].state, CLIP_EMPTY);
|
||||
}
|
||||
|
||||
atomic_store(&dispatcher.running, false);
|
||||
@@ -673,6 +679,7 @@ void dispatcher_stop(void) {
|
||||
for (int i = 0; i < MAX_CLIPS; i++) {
|
||||
free(dispatcher.state.midi_clips[i].events);
|
||||
dispatcher.state.midi_clips[i].events = NULL;
|
||||
atomic_store(&dispatcher.state.midi_clips[i].state, CLIP_EMPTY);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&dispatcher.subscribers_mutex);
|
||||
|
||||
Reference in New Issue
Block a user