#ifndef ENGINE_H #define ENGINE_H #include #include #include #include #include #include "transport.h" #define MAX_SCENES 8 #define MAX_CHANNELS 8 #define MAX_CLIPS (MAX_SCENES * MAX_CHANNELS) // 64 #define MAX_BUFFER_SIZE 441000 // 10 seconds at 44.1kHz // Convert scene/channel to flat clip index #define CLIP_INDEX(scene, channel) ((scene) * MAX_CHANNELS + (channel)) typedef enum { CLIP_EMPTY, CLIP_RECORDING, CLIP_LOOPING, CLIP_STOPPED } ClipState; typedef enum { QUANTIZE_OFF, QUANTIZE_BEAT, QUANTIZE_BAR } QuantizeMode; typedef struct { ClipState state; float *buffer; size_t buffer_size; size_t write_position; size_t read_position; bool is_playing; } Clip; // Maximum number of queued commands from frontend to audio thread #define MAX_QUEUED_COMMANDS 64 // Size of the pre-allocated trigger pool (must match engine.c) #define QUEUED_TRIGGER_POOL_SIZE 64 typedef enum { CMD_TRIGGER_CLIP, CMD_TRIGGER_SCENE, CMD_RESET_CLIP, CMD_SET_QUANTIZE_MODE, CMD_SET_QUANTIZE_THRESHOLD, CMD_RESET_TRANSPORT, CMD_UNDO, CMD_REDO, CMD_TRANSPORT_PLAY, CMD_TRANSPORT_PAUSE, CMD_TRANSPORT_STOP, CMD_TRANSPORT_TOGGLE_PLAY, CMD_SET_CLOCK_SOURCE, CMD_SET_BPM } CommandType; // Undo/Redo action types typedef enum { ACTION_TRIGGER_CLIP, ACTION_TRIGGER_SCENE, ACTION_RESET_CLIP, ACTION_SET_QUANTIZE_MODE, ACTION_SET_QUANTIZE_THRESHOLD, ACTION_RESET_TRANSPORT } ActionType; // Undo/Redo action record typedef struct { ActionType type; int index; // clip_index, scene_index, or mode value jack_nframes_t value; // threshold value or other numeric param ClipState previous_state; // For clip state changes size_t previous_buffer_size; size_t previous_write_position; size_t previous_read_position; bool previous_rolling; uint32_t previous_clock_count; uint32_t previous_beat_position; uint32_t previous_bar_position; uint32_t previous_sample_position; QuantizeMode previous_quantize_mode; jack_nframes_t previous_quantize_threshold; } UndoAction; // Undo/Redo history #define MAX_UNDO_HISTORY 256 typedef struct { UndoAction actions[MAX_UNDO_HISTORY]; int undo_index; // Points to next action to undo int redo_index; // Points to next action to redo int count; // Total actions in history } UndoHistory; typedef struct { CommandType type; int index; // clip_index, scene_index, or mode value jack_nframes_t value; // threshold value or other numeric param } Command; // Lock-free single-producer single-consumer ring buffer typedef struct { Command buffer[MAX_QUEUED_COMMANDS]; atomic_uint write_index; atomic_uint read_index; } CommandQueue; // Queued trigger for quantization typedef struct QueuedTrigger { int clip_index; bool is_scene; jack_nframes_t trigger_time; struct QueuedTrigger *next; } QueuedTrigger; typedef struct { jack_client_t *client; jack_port_t *audio_in_ports[MAX_CHANNELS]; jack_port_t *audio_out_ports[MAX_CHANNELS]; jack_port_t *midi_in_port; // Control channel MIDI jack_port_t *midi_scene_in_port; // Scene launch MIDI jack_port_t *midi_clock_in_port; // MIDI clock input jack_port_t *midi_out_port; Clip clips[MAX_CLIPS]; int control_channel; jack_nframes_t sample_rate; // Transport and clock Transport *transport; // Quantization QuantizeMode quantize_mode; jack_nframes_t quantize_threshold; // in samples (lookahead) QueuedTrigger *queued_triggers; // Thread-safe command queue for frontend -> audio thread communication CommandQueue command_queue; // Atomic flags for simple state that frontend reads atomic_int quantize_mode_atomic; // QuantizeMode atomic_uint quantize_threshold_atomic; bool running; // Undo/Redo UndoHistory undo_history; } Engine; // Engine lifecycle int engine_init(Engine *engine, const char *client_name); void engine_cleanup(Engine *engine); int engine_start(Engine *engine); void engine_stop(Engine *engine); // Clip management void engine_trigger_clip(Engine *engine, int clip_index); void engine_trigger_scene(Engine *engine, int scene_index); void engine_reset_clip(Engine *engine, int clip_index); // Transport void engine_set_quantize_mode(Engine *engine, QuantizeMode mode); void engine_set_quantize_threshold(Engine *engine, jack_nframes_t samples); void engine_transport_play(Engine *engine); void engine_transport_pause(Engine *engine); void engine_transport_stop(Engine *engine); void engine_transport_toggle_play(Engine *engine); void engine_set_clock_source(Engine *engine, ClockSource source); void engine_set_bpm(Engine *engine, double bpm); // Queue management (exposed for testing) void queue_trigger(Engine *engine, int clip_index, bool is_scene, jack_nframes_t time); // Thread-safe command submission (called from frontend threads) int engine_submit_command(Engine *engine, CommandType type, int index, jack_nframes_t value); // Process pending commands (called from audio thread) void engine_process_commands(Engine *engine); // Initialize command queue (exposed for testing) void command_queue_init(CommandQueue *q); // Utility const char* clip_state_to_string(ClipState state); uint8_t clip_state_to_velocity(ClipState state); const char* quantize_mode_to_string(QuantizeMode mode); // Undo/Redo void engine_undo(Engine *engine); void engine_redo(Engine *engine); void engine_push_undo_action(Engine *engine, UndoAction *action); void engine_undo_action(Engine *engine); void engine_redo_action(Engine *engine); #endif // ENGINE_H