use crate::*; const COLS: usize = 5; const ROWS: usize = 5; pub struct ProcessHandler { osc: OscController, ports: JackPorts, metronome: Metronome, track_matrix: TrackMatrix, selected_row: usize, selected_column: usize, } impl ProcessHandler { pub fn new( client: &jack::Client, ports: JackPorts, chunk_factory: F, beep_samples: Arc, state: &State, osc: OscController, post_record_controller: PostRecordController, ) -> Result { let track_matrix = TrackMatrix::new( client, chunk_factory, state, post_record_controller, )?; Ok(Self { osc, ports, metronome: Metronome::new(beep_samples, state), track_matrix, selected_row: 0, selected_column: 0, }) } pub fn ports(&self) -> &JackPorts { &self.ports } pub fn handle_button_1(&mut self) -> Result<()> { self.track_matrix.handle_record_button(self.selected_column, self.selected_row) } pub fn handle_button_2(&mut self) -> Result<()> { self.track_matrix.handle_play_button(self.selected_column, self.selected_row) } pub fn handle_button_3(&mut self) -> Result<()> { Ok(()) } pub fn handle_button_4(&mut self) -> Result<()> { Ok(()) } pub fn handle_button_5(&mut self) -> Result<()> { self.track_matrix.handle_clear_button(self.selected_column, self.selected_row) } pub fn handle_button_6(&mut self) -> Result<()> { self.selected_column = 0; self.osc.selected_column_changed(self.selected_column)?; Ok(()) } pub fn handle_button_7(&mut self) -> Result<()> { self.selected_column = 1; self.osc.selected_column_changed(self.selected_column)?; Ok(()) } pub fn handle_button_8(&mut self) -> Result<()> { self.selected_column = 2; self.osc.selected_column_changed(self.selected_column)?; Ok(()) } pub fn handle_button_9(&mut self) -> Result<()> { self.selected_column = 3; self.osc.selected_column_changed(self.selected_column)?; Ok(()) } pub fn handle_button_10(&mut self) -> Result<()> { self.selected_column = 4; self.osc.selected_column_changed(self.selected_column)?; Ok(()) } pub fn handle_button_up(&mut self) -> Result<()> { if self.selected_row == 0 { self.selected_row = ROWS - 1; } else { self.selected_row -= 1; } self.osc.selected_row_changed(self.selected_row)?; Ok(()) } pub fn handle_button_down(&mut self) -> Result<()> { self.selected_row = (self.selected_row + 1) % ROWS; self.osc.selected_row_changed(self.selected_row)?; Ok(()) } } impl jack::ProcessHandler for ProcessHandler { fn process(&mut self, client: &jack::Client, ps: &jack::ProcessScope) -> jack::Control { if let Err(e) = self.process_with_error_handling(client, ps) { log::error!("Error processing audio: {}", e); jack::Control::Quit } else { jack::Control::Continue } } } impl ProcessHandler { fn process_with_error_handling( &mut self, client: &jack::Client, ps: &jack::ProcessScope, ) -> Result<()> { // Process metronome and get beat timing information let timing = self.metronome.process(ps, &mut self.ports)?; // Process MIDI midi::process_events(self, ps)?; // Process audio self.track_matrix.process( client, ps, &mut self.ports, &timing, &mut self.osc, )?; Ok(()) } }