diff --git a/engine.c b/engine.c index 4409adf..91d8183 100644 --- a/engine.c +++ b/engine.c @@ -157,8 +157,29 @@ static void shutdown_callback(void *arg) { // Get the next quantization boundary frame static jack_nframes_t get_next_quantize_frame(Engine *engine, jack_nframes_t current_frame) { - if (!engine->transport) return current_frame; - return transport_get_next_quantize_frame(engine->transport, current_frame, engine->quantize_mode); + if (!engine->transport || engine->transport->state != TRANSPORT_PLAYING || + engine->quantize_mode == QUANTIZE_OFF) { + return current_frame; + } + + // Calculate frames per beat + jack_nframes_t frames_per_beat = (jack_nframes_t)engine->transport->samples_per_beat; + jack_nframes_t frames_per_bar = frames_per_beat * BEATS_PER_BAR; + + // Current position in frames + jack_nframes_t current_pos = engine->transport->sample_position + current_frame; + + if (engine->quantize_mode == QUANTIZE_BEAT) { + // Next beat boundary + jack_nframes_t beat_frames = frames_per_beat; + jack_nframes_t next_beat = ((current_pos / beat_frames) + 1) * beat_frames; + return next_beat - engine->transport->sample_position; + } else { // QUANTIZE_BAR + // Next bar boundary + jack_nframes_t bar_frames = frames_per_bar; + jack_nframes_t next_bar = ((current_pos / bar_frames) + 1) * bar_frames; + return next_bar - engine->transport->sample_position; + } } // Queue a trigger for quantization diff --git a/transport.c b/transport.c index 80a22f0..e047d4d 100644 --- a/transport.c +++ b/transport.c @@ -22,7 +22,8 @@ void transport_init(Transport *transport, jack_nframes_t sample_rate) { atomic_store(&transport->bar_position_atomic, 0); atomic_store(&transport->sample_position_atomic, 0); atomic_store(&transport->clock_source_atomic, CLOCK_SOURCE_INTERNAL); - atomic_store(&transport->bpm_atomic, DEFAULT_BPM); + transport->bpm_atomic = DEFAULT_BPM; + atomic_store(&transport->bpm_atomic_raw, (unsigned int)(DEFAULT_BPM * 100.0)); } void transport_cleanup(Transport *transport) { @@ -100,7 +101,8 @@ void transport_set_bpm(Transport *transport, double bpm) { transport->bpm = bpm; transport->samples_per_beat = (transport->sample_rate * 60.0) / bpm; - atomic_store(&transport->bpm_atomic, bpm); + transport->bpm_atomic = bpm; + atomic_store(&transport->bpm_atomic_raw, (unsigned int)(bpm * 100.0)); } double transport_get_bpm(Transport *transport) { @@ -221,32 +223,6 @@ void transport_reset(Transport *transport) { atomic_store(&transport->sample_position_atomic, 0); } -jack_nframes_t transport_get_next_quantize_frame(Transport *transport, - jack_nframes_t current_frame, - QuantizeMode mode) { - if (!transport || transport->state != TRANSPORT_PLAYING || mode == QUANTIZE_OFF) { - return current_frame; - } - - // Calculate frames per beat - jack_nframes_t frames_per_beat = (jack_nframes_t)transport->samples_per_beat; - jack_nframes_t frames_per_bar = frames_per_beat * BEATS_PER_BAR; - - // Current position in frames - jack_nframes_t current_pos = transport->sample_position + current_frame; - - if (mode == QUANTIZE_BEAT) { - // Next beat boundary - jack_nframes_t beat_frames = frames_per_beat; - jack_nframes_t next_beat = ((current_pos / beat_frames) + 1) * beat_frames; - return next_beat - transport->sample_position; - } else { // QUANTIZE_BAR - // Next bar boundary - jack_nframes_t bar_frames = frames_per_bar; - jack_nframes_t next_bar = ((current_pos / bar_frames) + 1) * bar_frames; - return next_bar - transport->sample_position; - } -} const char* transport_state_to_string(TransportState state) { switch (state) { diff --git a/transport.h b/transport.h index b0d6a7a..bc47b36 100644 --- a/transport.h +++ b/transport.h @@ -45,7 +45,8 @@ typedef struct { atomic_uint bar_position_atomic; atomic_uint sample_position_atomic; atomic_int clock_source_atomic; // ClockSource - atomic_double bpm_atomic; + double bpm_atomic; // Direct read for audio thread + atomic_uint bpm_atomic_raw; // Fixed-point (BPM * 100) for frontend reads // JACK ports for MIDI clock output (when master) jack_port_t *midi_clock_out_port; @@ -80,10 +81,6 @@ int transport_process(Transport *transport, jack_nframes_t nframes, // Reset position void transport_reset(Transport *transport); -// Get next quantization boundary (in frames from current position) -jack_nframes_t transport_get_next_quantize_frame(Transport *transport, - jack_nframes_t current_frame, - QuantizeMode mode); // Utility const char* transport_state_to_string(TransportState state); diff --git a/tui.c b/tui.c index a6d9e76..ca1b3cb 100644 --- a/tui.c +++ b/tui.c @@ -284,7 +284,7 @@ static void draw_grid(void) { "Transport: %s | Clock: %s | BPM: %.1f | Quantize: %s | Threshold: %u", transport_state_to_string(transport_state), clock_source_to_string(clock_source), - atomic_load(&g_engine->transport->bpm_atomic), + (double)atomic_load(&g_engine->transport->bpm_atomic_raw) / 100.0, quantize_mode_to_string((QuantizeMode)atomic_load(&g_engine->quantize_mode_atomic)), (unsigned int)atomic_load(&g_engine->quantize_threshold_atomic));