Fix: audio engine fixes
This commit is contained in:
@@ -279,8 +279,6 @@ impl Plugin for CagirePlugin {
|
|||||||
};
|
};
|
||||||
let lookahead_end = beat + lookahead_beats;
|
let lookahead_end = beat + lookahead_beats;
|
||||||
|
|
||||||
let engine_time = self.sample_pos as f64 / self.sample_rate as f64;
|
|
||||||
|
|
||||||
// Drain commands from the editor
|
// Drain commands from the editor
|
||||||
let commands: Vec<SeqCommand> = self.bridge.cmd_rx.try_iter().collect();
|
let commands: Vec<SeqCommand> = self.bridge.cmd_rx.try_iter().collect();
|
||||||
|
|
||||||
@@ -294,7 +292,8 @@ impl Plugin for CagirePlugin {
|
|||||||
fill: false,
|
fill: false,
|
||||||
nudge_secs: 0.0,
|
nudge_secs: 0.0,
|
||||||
current_time_us: 0,
|
current_time_us: 0,
|
||||||
engine_time,
|
audio_sample_pos: self.sample_pos,
|
||||||
|
sr: self.sample_rate as f64,
|
||||||
mouse_x: 0.5,
|
mouse_x: 0.5,
|
||||||
mouse_y: 0.5,
|
mouse_y: 0.5,
|
||||||
mouse_down: 0.0,
|
mouse_down: 0.0,
|
||||||
@@ -310,12 +309,12 @@ impl Plugin for CagirePlugin {
|
|||||||
// Drain audio commands from the editor (preview, hush, load samples, etc.)
|
// Drain audio commands from the editor (preview, hush, load samples, etc.)
|
||||||
for audio_cmd in self.bridge.audio_cmd_rx.try_iter() {
|
for audio_cmd in self.bridge.audio_cmd_rx.try_iter() {
|
||||||
match audio_cmd {
|
match audio_cmd {
|
||||||
AudioCommand::Evaluate { ref cmd, time } => {
|
AudioCommand::Evaluate { ref cmd, tick } => {
|
||||||
let cmd_ref = match time {
|
let cmd_ref = match tick {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
self.cmd_buffer.clear();
|
self.cmd_buffer.clear();
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
let _ = write!(&mut self.cmd_buffer, "{cmd}/time/{t:.6}");
|
let _ = write!(&mut self.cmd_buffer, "{cmd}/tick/{t}");
|
||||||
self.cmd_buffer.as_str()
|
self.cmd_buffer.as_str()
|
||||||
}
|
}
|
||||||
None => cmd.as_str(),
|
None => cmd.as_str(),
|
||||||
@@ -419,11 +418,11 @@ impl Plugin for CagirePlugin {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let cmd_ref = match tsc.time {
|
let cmd_ref = match tsc.tick {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
self.cmd_buffer.clear();
|
self.cmd_buffer.clear();
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
let _ = write!(&mut self.cmd_buffer, "{}/time/{t:.6}", tsc.cmd);
|
let _ = write!(&mut self.cmd_buffer, "{}/tick/{t}", tsc.cmd);
|
||||||
self.cmd_buffer.as_str()
|
self.cmd_buffer.as_str()
|
||||||
}
|
}
|
||||||
None => &tsc.cmd,
|
None => &tsc.cmd,
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ impl App {
|
|||||||
}
|
}
|
||||||
let _ = audio_tx
|
let _ = audio_tx
|
||||||
.load()
|
.load()
|
||||||
.send(crate::engine::AudioCommand::Evaluate { cmd, time: None });
|
.send(crate::engine::AudioCommand::Evaluate { cmd, tick: None });
|
||||||
}
|
}
|
||||||
Ok(if print_output.is_empty() {
|
Ok(if print_output.is_empty() {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -454,12 +454,12 @@ pub fn build_stream(
|
|||||||
|
|
||||||
while let Ok(cmd) = audio_rx.try_recv() {
|
while let Ok(cmd) = audio_rx.try_recv() {
|
||||||
match cmd {
|
match cmd {
|
||||||
AudioCommand::Evaluate { cmd, time } => {
|
AudioCommand::Evaluate { cmd, tick } => {
|
||||||
let cmd_ref = match time {
|
let cmd_ref = match tick {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
cmd_buffer.clear();
|
cmd_buffer.clear();
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
let _ = write!(&mut cmd_buffer, "{cmd}/time/{t:.6}");
|
let _ = write!(&mut cmd_buffer, "{cmd}/tick/{t}");
|
||||||
cmd_buffer.as_str()
|
cmd_buffer.as_str()
|
||||||
}
|
}
|
||||||
None => &cmd,
|
None => &cmd,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ impl PatternChange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum AudioCommand {
|
pub enum AudioCommand {
|
||||||
Evaluate { cmd: String, time: Option<f64> },
|
Evaluate { cmd: String, tick: Option<u64> },
|
||||||
Hush,
|
Hush,
|
||||||
Panic,
|
Panic,
|
||||||
LoadSamples(Vec<doux::sampling::SampleEntry>),
|
LoadSamples(Vec<doux::sampling::SampleEntry>),
|
||||||
@@ -521,7 +521,8 @@ pub struct TickInput {
|
|||||||
pub fill: bool,
|
pub fill: bool,
|
||||||
pub nudge_secs: f64,
|
pub nudge_secs: f64,
|
||||||
pub current_time_us: SyncTime,
|
pub current_time_us: SyncTime,
|
||||||
pub engine_time: f64,
|
pub audio_sample_pos: u64,
|
||||||
|
pub sr: f64,
|
||||||
pub mouse_x: f64,
|
pub mouse_x: f64,
|
||||||
pub mouse_y: f64,
|
pub mouse_y: f64,
|
||||||
pub mouse_down: f64,
|
pub mouse_down: f64,
|
||||||
@@ -529,7 +530,7 @@ pub struct TickInput {
|
|||||||
|
|
||||||
pub struct TimestampedCommand {
|
pub struct TimestampedCommand {
|
||||||
pub cmd: String,
|
pub cmd: String,
|
||||||
pub time: Option<f64>,
|
pub tick: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TickOutput {
|
pub struct TickOutput {
|
||||||
@@ -774,7 +775,8 @@ impl SequencerState {
|
|||||||
input.fill,
|
input.fill,
|
||||||
input.nudge_secs,
|
input.nudge_secs,
|
||||||
input.current_time_us,
|
input.current_time_us,
|
||||||
input.engine_time,
|
input.audio_sample_pos,
|
||||||
|
input.sr,
|
||||||
input.mouse_x,
|
input.mouse_x,
|
||||||
input.mouse_y,
|
input.mouse_y,
|
||||||
input.mouse_down,
|
input.mouse_down,
|
||||||
@@ -788,7 +790,8 @@ impl SequencerState {
|
|||||||
input.quantum,
|
input.quantum,
|
||||||
input.fill,
|
input.fill,
|
||||||
input.nudge_secs,
|
input.nudge_secs,
|
||||||
input.engine_time,
|
input.audio_sample_pos,
|
||||||
|
input.sr,
|
||||||
input.mouse_x,
|
input.mouse_x,
|
||||||
input.mouse_y,
|
input.mouse_y,
|
||||||
input.mouse_down,
|
input.mouse_down,
|
||||||
@@ -922,7 +925,8 @@ impl SequencerState {
|
|||||||
fill: bool,
|
fill: bool,
|
||||||
nudge_secs: f64,
|
nudge_secs: f64,
|
||||||
_current_time_us: SyncTime,
|
_current_time_us: SyncTime,
|
||||||
engine_time: f64,
|
audio_sample_pos: u64,
|
||||||
|
sr: f64,
|
||||||
mouse_x: f64,
|
mouse_x: f64,
|
||||||
mouse_y: f64,
|
mouse_y: f64,
|
||||||
mouse_down: f64,
|
mouse_down: f64,
|
||||||
@@ -969,7 +973,7 @@ impl SequencerState {
|
|||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
let event_time = Some(engine_time + time_delta);
|
let event_tick = Some(audio_sample_pos + (time_delta * sr).round() as u64);
|
||||||
|
|
||||||
if let Some(step) = pattern.steps.get(step_idx) {
|
if let Some(step) = pattern.steps.get(step_idx) {
|
||||||
let resolved_script = pattern.resolve_script(step_idx);
|
let resolved_script = pattern.resolve_script(step_idx);
|
||||||
@@ -1037,7 +1041,7 @@ impl SequencerState {
|
|||||||
self.event_count += 1;
|
self.event_count += 1;
|
||||||
self.buf_audio_commands.push(TimestampedCommand {
|
self.buf_audio_commands.push(TimestampedCommand {
|
||||||
cmd,
|
cmd,
|
||||||
time: event_time,
|
tick: event_tick,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1080,7 +1084,8 @@ impl SequencerState {
|
|||||||
quantum: f64,
|
quantum: f64,
|
||||||
fill: bool,
|
fill: bool,
|
||||||
nudge_secs: f64,
|
nudge_secs: f64,
|
||||||
engine_time: f64,
|
audio_sample_pos: u64,
|
||||||
|
sr: f64,
|
||||||
mouse_x: f64,
|
mouse_x: f64,
|
||||||
mouse_y: f64,
|
mouse_y: f64,
|
||||||
mouse_down: f64,
|
mouse_down: f64,
|
||||||
@@ -1105,7 +1110,7 @@ impl SequencerState {
|
|||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
let event_time = Some(engine_time + time_delta);
|
let event_tick = Some(audio_sample_pos + (time_delta * sr).round() as u64);
|
||||||
|
|
||||||
let step_in_cycle = self.script_step % self.script_length;
|
let step_in_cycle = self.script_step % self.script_length;
|
||||||
|
|
||||||
@@ -1149,7 +1154,7 @@ impl SequencerState {
|
|||||||
self.event_count += 1;
|
self.event_count += 1;
|
||||||
self.buf_audio_commands.push(TimestampedCommand {
|
self.buf_audio_commands.push(TimestampedCommand {
|
||||||
cmd,
|
cmd,
|
||||||
time: event_time,
|
tick: event_tick,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1305,11 +1310,6 @@ fn sequencer_loop(
|
|||||||
|
|
||||||
let sr = sample_rate.load(Ordering::Relaxed) as f64;
|
let sr = sample_rate.load(Ordering::Relaxed) as f64;
|
||||||
let audio_samples = audio_sample_pos.load(Ordering::Acquire);
|
let audio_samples = audio_sample_pos.load(Ordering::Acquire);
|
||||||
let engine_time = if sr > 0.0 {
|
|
||||||
audio_samples as f64 / sr
|
|
||||||
} else {
|
|
||||||
0.0
|
|
||||||
};
|
|
||||||
let input = TickInput {
|
let input = TickInput {
|
||||||
commands,
|
commands,
|
||||||
playing: playing.load(Ordering::Relaxed),
|
playing: playing.load(Ordering::Relaxed),
|
||||||
@@ -1320,7 +1320,8 @@ fn sequencer_loop(
|
|||||||
fill: live_keys.fill(),
|
fill: live_keys.fill(),
|
||||||
nudge_secs: nudge_us.load(Ordering::Relaxed) as f64 / 1_000_000.0,
|
nudge_secs: nudge_us.load(Ordering::Relaxed) as f64 / 1_000_000.0,
|
||||||
current_time_us,
|
current_time_us,
|
||||||
engine_time,
|
audio_sample_pos: audio_samples,
|
||||||
|
sr,
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
mouse_x: f32::from_bits(mouse_x.load(Ordering::Relaxed)) as f64,
|
mouse_x: f32::from_bits(mouse_x.load(Ordering::Relaxed)) as f64,
|
||||||
#[cfg(not(feature = "desktop"))]
|
#[cfg(not(feature = "desktop"))]
|
||||||
@@ -1370,7 +1371,7 @@ fn sequencer_loop(
|
|||||||
} else {
|
} else {
|
||||||
let _ = audio_tx.load().send(AudioCommand::Evaluate {
|
let _ = audio_tx.load().send(AudioCommand::Evaluate {
|
||||||
cmd: tsc.cmd,
|
cmd: tsc.cmd,
|
||||||
time: tsc.time,
|
tick: tsc.tick,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1542,7 +1543,8 @@ mod tests {
|
|||||||
fill: false,
|
fill: false,
|
||||||
nudge_secs: 0.0,
|
nudge_secs: 0.0,
|
||||||
current_time_us: 0,
|
current_time_us: 0,
|
||||||
engine_time: 0.0,
|
audio_sample_pos: 0,
|
||||||
|
sr: 48000.0,
|
||||||
mouse_x: 0.5,
|
mouse_x: 0.5,
|
||||||
mouse_y: 0.5,
|
mouse_y: 0.5,
|
||||||
mouse_down: 0.0,
|
mouse_down: 0.0,
|
||||||
@@ -1560,7 +1562,8 @@ mod tests {
|
|||||||
fill: false,
|
fill: false,
|
||||||
nudge_secs: 0.0,
|
nudge_secs: 0.0,
|
||||||
current_time_us: 0,
|
current_time_us: 0,
|
||||||
engine_time: 0.0,
|
audio_sample_pos: 0,
|
||||||
|
sr: 48000.0,
|
||||||
mouse_x: 0.5,
|
mouse_x: 0.5,
|
||||||
mouse_y: 0.5,
|
mouse_y: 0.5,
|
||||||
mouse_down: 0.0,
|
mouse_down: 0.0,
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ pub(super) fn handle_engine_page(ctx: &mut InputContext, key: KeyEvent) -> Input
|
|||||||
KeyCode::Char('t') if !ctx.app.plugin_mode => {
|
KeyCode::Char('t') if !ctx.app.plugin_mode => {
|
||||||
let _ = ctx.audio_tx.load().send(AudioCommand::Evaluate {
|
let _ = ctx.audio_tx.load().send(AudioCommand::Evaluate {
|
||||||
cmd: "/sound/sine/dur/0.5/decay/0.2".into(),
|
cmd: "/sound/sine/dur/0.5/decay/0.2".into(),
|
||||||
time: None,
|
tick: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
KeyCode::Char('s') => super::open_save(ctx),
|
KeyCode::Char('s') => super::open_save(ctx),
|
||||||
|
|||||||
@@ -796,7 +796,7 @@ fn execute_palette_entry(
|
|||||||
.load()
|
.load()
|
||||||
.send(crate::engine::AudioCommand::Evaluate {
|
.send(crate::engine::AudioCommand::Evaluate {
|
||||||
cmd: "/sound/sine/dur/0.5/decay/0.2".into(),
|
cmd: "/sound/sine/dur/0.5/decay/0.2".into(),
|
||||||
time: None,
|
tick: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ pub(super) fn handle_sample_explorer(ctx: &mut InputContext, key: KeyEvent) -> I
|
|||||||
let _ = ctx
|
let _ = ctx
|
||||||
.audio_tx
|
.audio_tx
|
||||||
.load()
|
.load()
|
||||||
.send(AudioCommand::Evaluate { cmd, time: None });
|
.send(AudioCommand::Evaluate { cmd, tick: None });
|
||||||
ctx.dispatch(AppCommand::SetStatus(format!(
|
ctx.dispatch(AppCommand::SetStatus(format!(
|
||||||
"\u{25B8} {}/{}",
|
"\u{25B8} {}/{}",
|
||||||
folder, entry.label
|
folder, entry.label
|
||||||
|
|||||||
Reference in New Issue
Block a user