147 lines
3.9 KiB
Rust
147 lines
3.9 KiB
Rust
use crate::*;
|
|
|
|
const COLS: usize = 5;
|
|
const ROWS: usize = 5;
|
|
|
|
pub struct ProcessHandler<F: ChunkFactory> {
|
|
osc: OscController,
|
|
ports: JackPorts,
|
|
metronome: Metronome,
|
|
track_matrix: TrackMatrix<F, COLS, ROWS>,
|
|
selected_row: usize,
|
|
selected_column: usize,
|
|
}
|
|
|
|
impl<F: ChunkFactory> ProcessHandler<F> {
|
|
pub fn new(
|
|
client: &jack::Client,
|
|
ports: JackPorts,
|
|
chunk_factory: F,
|
|
beep_samples: Arc<AudioChunk>,
|
|
state: &State,
|
|
osc: OscController,
|
|
post_record_controller: PostRecordController,
|
|
) -> Result<Self> {
|
|
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<F: ChunkFactory> jack::ProcessHandler for ProcessHandler<F> {
|
|
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<F: ChunkFactory> ProcessHandler<F> {
|
|
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(())
|
|
}
|
|
}
|