Revert "Fix: try to fix the non working sync"
This reverts commit 1513d80a8d.
This commit is contained in:
20
Cargo.lock
generated
20
Cargo.lock
generated
@@ -873,7 +873,7 @@ dependencies = [
|
|||||||
"cpal 0.17.1",
|
"cpal 0.17.1",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"doux",
|
"doux 0.0.14",
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"egui_ratatui",
|
"egui_ratatui",
|
||||||
@@ -925,7 +925,7 @@ dependencies = [
|
|||||||
"cagire-ratatui",
|
"cagire-ratatui",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"doux",
|
"doux 0.0.13",
|
||||||
"egui_ratatui",
|
"egui_ratatui",
|
||||||
"nih_plug",
|
"nih_plug",
|
||||||
"nih_plug_egui",
|
"nih_plug_egui",
|
||||||
@@ -1822,6 +1822,22 @@ dependencies = [
|
|||||||
"litrs",
|
"litrs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "doux"
|
||||||
|
version = "0.0.13"
|
||||||
|
source = "git+https://github.com/sova-org/doux?tag=v0.0.13#b8150d907e4cc2764e82fdaa424df41ceef9b0d2"
|
||||||
|
dependencies = [
|
||||||
|
"arc-swap",
|
||||||
|
"clap",
|
||||||
|
"cpal 0.17.1",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"ringbuf",
|
||||||
|
"rosc",
|
||||||
|
"rustyline",
|
||||||
|
"soundfont",
|
||||||
|
"symphonia",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "doux"
|
name = "doux"
|
||||||
version = "0.0.14"
|
version = "0.0.14"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ cagire = { path = "../..", default-features = false, features = ["block-renderer
|
|||||||
cagire-forth = { path = "../../crates/forth" }
|
cagire-forth = { path = "../../crates/forth" }
|
||||||
cagire-project = { path = "../../crates/project" }
|
cagire-project = { path = "../../crates/project" }
|
||||||
cagire-ratatui = { path = "../../crates/ratatui" }
|
cagire-ratatui = { path = "../../crates/ratatui" }
|
||||||
doux = { git = "https://github.com/sova-org/doux", tag = "v0.0.14", features = ["native", "soundfont"] }
|
doux = { git = "https://github.com/sova-org/doux", tag = "v0.0.13", features = ["native", "soundfont"] }
|
||||||
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug", features = ["standalone"] }
|
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug", features = ["standalone"] }
|
||||||
nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug" }
|
nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug" }
|
||||||
egui_ratatui = "2.1"
|
egui_ratatui = "2.1"
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ impl Plugin for CagirePlugin {
|
|||||||
self.sample_rate,
|
self.sample_rate,
|
||||||
self.output_channels,
|
self.output_channels,
|
||||||
64,
|
64,
|
||||||
buffer_config.max_buffer_size as usize,
|
|
||||||
);
|
);
|
||||||
self.bridge
|
self.bridge
|
||||||
.sample_registry
|
.sample_registry
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ while [[ $# -gt 0 ]]; do
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " --platforms <list> Comma-separated: macos-arm64,macos-x86_64,linux-x86_64,linux-aarch64,windows-x86_64"
|
echo " --platforms <list> Comma-separated: macos-arm64,macos-x86_64,linux-x86_64,linux-aarch64,windows-x86_64"
|
||||||
echo " --targets <list> Comma-separated: cli,desktop,plugins,installer"
|
echo " --targets <list> Comma-separated: cli,desktop,plugins"
|
||||||
echo " --all Build all platforms and targets"
|
echo " --all Build all platforms and targets"
|
||||||
echo " --yes Skip confirmation prompt"
|
echo " --yes Skip confirmation prompt"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -105,30 +105,22 @@ prompt_platforms() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prompt_targets() {
|
prompt_targets() {
|
||||||
local show_installer=false
|
|
||||||
for p in "${selected_platforms[@]}"; do
|
|
||||||
[[ "$p" == *windows* ]] && show_installer=true
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Select targets (0=all, comma-separated):"
|
echo "Select targets (0=all, comma-separated):"
|
||||||
echo " 0) All"
|
echo " 0) All"
|
||||||
echo " 1) cagire"
|
echo " 1) cagire"
|
||||||
echo " 2) cagire-desktop"
|
echo " 2) cagire-desktop"
|
||||||
echo " 3) cagire-plugins (CLAP/VST3)"
|
echo " 3) cagire-plugins (CLAP/VST3)"
|
||||||
$show_installer && echo " 4) installer (NSIS, implies cli+desktop+plugins)"
|
|
||||||
read -rp "> " choice
|
read -rp "> " choice
|
||||||
|
|
||||||
build_cagire=false
|
build_cagire=false
|
||||||
build_desktop=false
|
build_desktop=false
|
||||||
build_plugins=false
|
build_plugins=false
|
||||||
build_installer=false
|
|
||||||
|
|
||||||
if [[ "$choice" == "0" || -z "$choice" ]]; then
|
if [[ "$choice" == "0" || -z "$choice" ]]; then
|
||||||
build_cagire=true
|
build_cagire=true
|
||||||
build_desktop=true
|
build_desktop=true
|
||||||
build_plugins=true
|
build_plugins=true
|
||||||
$show_installer && build_installer=true
|
|
||||||
else
|
else
|
||||||
IFS=',' read -ra targets <<< "$choice"
|
IFS=',' read -ra targets <<< "$choice"
|
||||||
for t in "${targets[@]}"; do
|
for t in "${targets[@]}"; do
|
||||||
@@ -137,24 +129,10 @@ prompt_targets() {
|
|||||||
1) build_cagire=true ;;
|
1) build_cagire=true ;;
|
||||||
2) build_desktop=true ;;
|
2) build_desktop=true ;;
|
||||||
3) build_plugins=true ;;
|
3) build_plugins=true ;;
|
||||||
4)
|
|
||||||
if $show_installer; then
|
|
||||||
build_installer=true
|
|
||||||
else
|
|
||||||
echo "Invalid target: $t"; exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*) echo "Invalid target: $t"; exit 1 ;;
|
*) echo "Invalid target: $t"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Installer requires cli+desktop+plugins
|
|
||||||
if $build_installer; then
|
|
||||||
build_cagire=true
|
|
||||||
build_desktop=true
|
|
||||||
build_plugins=true
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
confirm_summary() {
|
confirm_summary() {
|
||||||
@@ -170,7 +148,6 @@ confirm_summary() {
|
|||||||
$build_cagire && echo " - cagire"
|
$build_cagire && echo " - cagire"
|
||||||
$build_desktop && echo " - cagire-desktop"
|
$build_desktop && echo " - cagire-desktop"
|
||||||
$build_plugins && echo " - cagire-plugins (CLAP/VST3)"
|
$build_plugins && echo " - cagire-plugins (CLAP/VST3)"
|
||||||
$build_installer && echo " - installer (NSIS)"
|
|
||||||
echo ""
|
echo ""
|
||||||
read -rp "Proceed? [Y/n] " yn
|
read -rp "Proceed? [Y/n] " yn
|
||||||
case "${yn,,}" in
|
case "${yn,,}" in
|
||||||
@@ -351,7 +328,7 @@ copy_artifacts() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# NSIS installer for Windows targets
|
# NSIS installer for Windows targets
|
||||||
if $build_installer && [[ "$os" == "windows" ]] && command -v makensis &>/dev/null; then
|
if [[ "$os" == "windows" ]] && command -v makensis &>/dev/null; then
|
||||||
echo " Building NSIS installer..."
|
echo " Building NSIS installer..."
|
||||||
local version
|
local version
|
||||||
version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
|
version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
|
||||||
@@ -407,7 +384,6 @@ if $cli_all; then
|
|||||||
build_cagire=true
|
build_cagire=true
|
||||||
build_desktop=true
|
build_desktop=true
|
||||||
build_plugins=true
|
build_plugins=true
|
||||||
build_installer=true
|
|
||||||
elif [[ -n "$cli_platforms" || -n "$cli_targets" ]]; then
|
elif [[ -n "$cli_platforms" || -n "$cli_targets" ]]; then
|
||||||
# Resolve platforms from CLI
|
# Resolve platforms from CLI
|
||||||
if [[ -n "$cli_platforms" ]]; then
|
if [[ -n "$cli_platforms" ]]; then
|
||||||
@@ -429,7 +405,6 @@ elif [[ -n "$cli_platforms" || -n "$cli_targets" ]]; then
|
|||||||
build_cagire=false
|
build_cagire=false
|
||||||
build_desktop=false
|
build_desktop=false
|
||||||
build_plugins=false
|
build_plugins=false
|
||||||
build_installer=false
|
|
||||||
if [[ -n "$cli_targets" ]]; then
|
if [[ -n "$cli_targets" ]]; then
|
||||||
IFS=',' read -ra tgts <<< "$cli_targets"
|
IFS=',' read -ra tgts <<< "$cli_targets"
|
||||||
for t in "${tgts[@]}"; do
|
for t in "${tgts[@]}"; do
|
||||||
@@ -438,22 +413,13 @@ elif [[ -n "$cli_platforms" || -n "$cli_targets" ]]; then
|
|||||||
cli) build_cagire=true ;;
|
cli) build_cagire=true ;;
|
||||||
desktop) build_desktop=true ;;
|
desktop) build_desktop=true ;;
|
||||||
plugins) build_plugins=true ;;
|
plugins) build_plugins=true ;;
|
||||||
installer) build_installer=true ;;
|
*) echo "Unknown target: $t (expected: cli, desktop, plugins)"; exit 1 ;;
|
||||||
*) echo "Unknown target: $t (expected: cli, desktop, plugins, installer)"; exit 1 ;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
build_cagire=true
|
build_cagire=true
|
||||||
build_desktop=true
|
build_desktop=true
|
||||||
build_plugins=true
|
build_plugins=true
|
||||||
build_installer=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Installer requires cli+desktop+plugins
|
|
||||||
if $build_installer; then
|
|
||||||
build_cagire=true
|
|
||||||
build_desktop=true
|
|
||||||
build_plugins=true
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
prompt_platforms
|
prompt_platforms
|
||||||
|
|||||||
@@ -299,7 +299,6 @@ struct ActivePattern {
|
|||||||
step_index: usize,
|
step_index: usize,
|
||||||
iter: usize,
|
iter: usize,
|
||||||
last_step_beat: f64,
|
last_step_beat: f64,
|
||||||
activation_beat: Option<f64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -491,30 +490,6 @@ fn check_quantization_boundary(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quantization_boundary_beat(
|
|
||||||
quantization: LaunchQuantization,
|
|
||||||
prev_beat: f64,
|
|
||||||
quantum: f64,
|
|
||||||
) -> Option<f64> {
|
|
||||||
match quantization {
|
|
||||||
LaunchQuantization::Immediate => None,
|
|
||||||
LaunchQuantization::Beat => Some(prev_beat.floor() + 1.0),
|
|
||||||
LaunchQuantization::Bar => Some(((prev_beat / quantum).floor() + 1.0) * quantum),
|
|
||||||
LaunchQuantization::Bars2 => {
|
|
||||||
let q = quantum * 2.0;
|
|
||||||
Some(((prev_beat / q).floor() + 1.0) * q)
|
|
||||||
}
|
|
||||||
LaunchQuantization::Bars4 => {
|
|
||||||
let q = quantum * 4.0;
|
|
||||||
Some(((prev_beat / q).floor() + 1.0) * q)
|
|
||||||
}
|
|
||||||
LaunchQuantization::Bars8 => {
|
|
||||||
let q = quantum * 8.0;
|
|
||||||
Some(((prev_beat / q).floor() + 1.0) * q)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type StepKey = (usize, usize, usize);
|
type StepKey = (usize, usize, usize);
|
||||||
|
|
||||||
struct RunsCounter {
|
struct RunsCounter {
|
||||||
@@ -917,8 +892,6 @@ impl SequencerState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let boundary =
|
|
||||||
quantization_boundary_beat(pending.quantization, prev_beat, quantum);
|
|
||||||
self.runs_counter
|
self.runs_counter
|
||||||
.clear_pattern(pending.id.bank, pending.id.pattern);
|
.clear_pattern(pending.id.bank, pending.id.pattern);
|
||||||
self.audio_state.active_patterns.insert(
|
self.audio_state.active_patterns.insert(
|
||||||
@@ -929,7 +902,6 @@ impl SequencerState {
|
|||||||
step_index: start_step,
|
step_index: start_step,
|
||||||
iter: 0,
|
iter: 0,
|
||||||
last_step_beat: beat,
|
last_step_beat: beat,
|
||||||
activation_beat: boundary,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.buf_activated.push(pending.id);
|
self.buf_activated.push(pending.id);
|
||||||
@@ -1010,13 +982,8 @@ impl SequencerState {
|
|||||||
.unwrap_or_else(|| pattern.speed.multiplier());
|
.unwrap_or_else(|| pattern.speed.multiplier());
|
||||||
|
|
||||||
let step_beats = substeps_in_window(frontier, lookahead_end, speed_mult);
|
let step_beats = substeps_in_window(frontier, lookahead_end, speed_mult);
|
||||||
let activation = active.activation_beat.take();
|
|
||||||
let skip = activation.map_or(0, |ab| {
|
|
||||||
step_beats.iter().take_while(|&&b| b < ab).count()
|
|
||||||
});
|
|
||||||
|
|
||||||
for step_beat in &step_beats[skip..] {
|
for step_beat in step_beats {
|
||||||
let step_beat = *step_beat;
|
|
||||||
result.any_step_fired = true;
|
result.any_step_fired = true;
|
||||||
active.last_step_beat = step_beat;
|
active.last_step_beat = step_beat;
|
||||||
let step_idx = active.step_index % pattern.length;
|
let step_idx = active.step_index % pattern.length;
|
||||||
@@ -2424,118 +2391,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_quantization_boundary_beat() {
|
|
||||||
let quantum = 4.0;
|
|
||||||
|
|
||||||
// Immediate → None
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Immediate, 1.5, quantum),
|
|
||||||
None
|
|
||||||
);
|
|
||||||
|
|
||||||
// Beat → next integer beat
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Beat, 1.5, quantum),
|
|
||||||
Some(2.0)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Beat, 3.0, quantum),
|
|
||||||
Some(4.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bar → next multiple of quantum
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Bar, 3.9, quantum),
|
|
||||||
Some(4.0)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Bar, 0.0, quantum),
|
|
||||||
Some(4.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bars2 → next multiple of quantum*2
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Bars2, 3.9, quantum),
|
|
||||||
Some(8.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bars4 → next multiple of quantum*4
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Bars4, 3.9, quantum),
|
|
||||||
Some(16.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bars8 → next multiple of quantum*8
|
|
||||||
assert_eq!(
|
|
||||||
quantization_boundary_beat(LaunchQuantization::Bars8, 3.9, quantum),
|
|
||||||
Some(32.0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_activation_beat_prevents_early_substeps() {
|
|
||||||
let mut state = make_state();
|
|
||||||
|
|
||||||
state.tick(tick_with(
|
|
||||||
vec![SeqCommand::PatternUpdate {
|
|
||||||
bank: 0,
|
|
||||||
pattern: 0,
|
|
||||||
data: simple_pattern(16),
|
|
||||||
}],
|
|
||||||
0.0,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Queue Bar-quantized start (boundary at beat 4.0, quantum=4)
|
|
||||||
state.tick(tick_with(
|
|
||||||
vec![SeqCommand::PatternStart {
|
|
||||||
bank: 0,
|
|
||||||
pattern: 0,
|
|
||||||
quantization: LaunchQuantization::Bar,
|
|
||||||
sync_mode: SyncMode::Reset,
|
|
||||||
}],
|
|
||||||
3.5,
|
|
||||||
));
|
|
||||||
assert!(!state.audio_state.active_patterns.contains_key(&pid(0, 0)));
|
|
||||||
|
|
||||||
// Simulate a wide lookahead window that crosses the bar boundary:
|
|
||||||
// frontier=3.875, lookahead_end=4.125 — spans both sides of beat 4.0
|
|
||||||
// Without activation_beat filtering, substeps before 4.0 would fire.
|
|
||||||
state.tick(TickInput {
|
|
||||||
commands: Vec::new(),
|
|
||||||
playing: true,
|
|
||||||
beat: 4.125,
|
|
||||||
lookahead_end: 4.125,
|
|
||||||
tempo: 120.0,
|
|
||||||
quantum: 4.0,
|
|
||||||
fill: false,
|
|
||||||
nudge_secs: 0.0,
|
|
||||||
current_time_us: 0,
|
|
||||||
audio_sample_pos: 0,
|
|
||||||
sr: 48000.0,
|
|
||||||
mouse_x: 0.5,
|
|
||||||
mouse_y: 0.5,
|
|
||||||
mouse_down: 0.0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Pattern should be active
|
|
||||||
assert!(state.audio_state.active_patterns.contains_key(&pid(0, 0)));
|
|
||||||
|
|
||||||
// The activation_beat should have been consumed (set to None)
|
|
||||||
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
|
|
||||||
assert!(ap.activation_beat.is_none(), "activation_beat should be consumed after first execute");
|
|
||||||
|
|
||||||
// Step index should reflect only substeps at/after beat 4.0, not before
|
|
||||||
// At 1x speed: substeps at 0.25-beat intervals. From frontier 3.875 to 4.125:
|
|
||||||
// substeps_in_window yields beats at 4.0 (= 16/4). Pre-4.0 substeps should be skipped.
|
|
||||||
assert_eq!(ap.step_index, 1, "Only substep at beat 4.0 should fire, not pre-boundary ones");
|
|
||||||
|
|
||||||
// Second tick: activation_beat already consumed, all substeps should fire normally
|
|
||||||
let _output2 = state.tick(tick_at(4.375, true));
|
|
||||||
let ap2 = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
|
|
||||||
assert_eq!(ap2.step_index, 2, "Second tick should advance normally");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_no_false_boundary_after_pause_within_same_bar() {
|
fn test_no_false_boundary_after_pause_within_same_bar() {
|
||||||
let mut state = make_state();
|
let mut state = make_state();
|
||||||
|
|||||||
Reference in New Issue
Block a user