Small fixes and additions
All checks were successful
Deploy Website / deploy (push) Has been skipped
All checks were successful
Deploy Website / deploy (push) Has been skipped
This commit is contained in:
@@ -23,7 +23,7 @@ fn redefine_word_overwrites() {
|
||||
|
||||
#[test]
|
||||
fn word_with_param() {
|
||||
let outputs = expect_outputs(": loud 0.9 gain ; \"kick\" s loud .", 1);
|
||||
let outputs = expect_outputs(": loud 0.9 gain ; \"kick\" snd loud .", 1);
|
||||
assert!(outputs[0].contains("gain/0.9"));
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ fn define_word_containing_quotation() {
|
||||
|
||||
#[test]
|
||||
fn define_word_with_sound() {
|
||||
let outputs = expect_outputs(": kick \"kick\" s . ; kick", 1);
|
||||
let outputs = expect_outputs(": kick \"kick\" snd . ; kick", 1);
|
||||
assert!(outputs[0].contains("sound/kick"));
|
||||
}
|
||||
|
||||
|
||||
@@ -59,20 +59,20 @@ fn nested_quotations() {
|
||||
|
||||
#[test]
|
||||
fn quotation_with_param() {
|
||||
let outputs = expect_outputs(r#""kick" s ( 2 distort ) 1 ? ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ( 2 distort ) 1 ? ."#, 1);
|
||||
assert!(outputs[0].contains("distort/2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quotation_skips_param() {
|
||||
let outputs = expect_outputs(r#""kick" s ( 2 distort ) 0 ? ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ( 2 distort ) 0 ? ."#, 1);
|
||||
assert!(!outputs[0].contains("distort"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quotation_with_emit() {
|
||||
// When true, . should fire
|
||||
let outputs = expect_outputs(r#""kick" s ( . ) 1 ?"#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ( . ) 1 ?"#, 1);
|
||||
assert!(outputs[0].contains("kick"));
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ fn quotation_skips_emit() {
|
||||
// When false, . should not fire
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(r#""kick" s ( . ) 0 ?"#, &default_ctx())
|
||||
.evaluate(r#""kick" snd ( . ) 0 ?"#, &default_ctx())
|
||||
.unwrap();
|
||||
// No output since . was skipped and no implicit emit
|
||||
assert_eq!(outputs.len(), 0);
|
||||
@@ -109,7 +109,7 @@ fn every_with_quotation_integration() {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(r#""kick" s ( 2 distort ) 2 every ."#, &ctx)
|
||||
.evaluate(r#""kick" snd ( 2 distort ) 2 every ."#, &ctx)
|
||||
.unwrap();
|
||||
if iter % 2 == 0 {
|
||||
assert!(
|
||||
@@ -134,7 +134,7 @@ fn bjork_with_sound() {
|
||||
let ctx = ctx_with(|c| c.runs = 2); // position 2 is a hit for (3,8)
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(r#""kick" s ( 2 distort ) 3 8 bjork ."#, &ctx)
|
||||
.evaluate(r#""kick" snd ( 2 distort ) 3 8 bjork ."#, &ctx)
|
||||
.unwrap();
|
||||
assert!(outputs[0].contains("distort/2"));
|
||||
}
|
||||
@@ -161,7 +161,7 @@ fn when_and_unless_complementary() {
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(
|
||||
r#""kick" s ( 2 distort ) iter 2 mod 0 = ? ( 4 distort ) iter 2 mod 0 = !? ."#,
|
||||
r#""kick" snd ( 2 distort ) iter 2 mod 0 = ? ( 4 distort ) iter 2 mod 0 = !? ."#,
|
||||
&ctx,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -8,13 +8,13 @@ fn basic_emit() {
|
||||
|
||||
#[test]
|
||||
fn alias_s() {
|
||||
let outputs = expect_outputs(r#""snare" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""snare" snd ."#, 1);
|
||||
assert!(outputs[0].contains("sound/snare"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_params() {
|
||||
let outputs = expect_outputs(r#""kick" s 440 freq 0.5 gain ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd 440 freq 0.5 gain ."#, 1);
|
||||
assert!(outputs[0].contains("sound/kick"));
|
||||
assert!(outputs[0].contains("freq/440"));
|
||||
assert!(outputs[0].contains("gain/0.5"));
|
||||
@@ -22,13 +22,13 @@ fn with_params() {
|
||||
|
||||
#[test]
|
||||
fn auto_dur() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ."#, 1);
|
||||
assert!(outputs[0].contains("dur/"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn auto_delaytime() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ."#, 1);
|
||||
assert!(outputs[0].contains("delaytime/"));
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ fn emit_no_sound() {
|
||||
|
||||
#[test]
|
||||
fn multiple_emits() {
|
||||
let outputs = expect_outputs(r#""kick" s . "snare" s ."#, 2);
|
||||
let outputs = expect_outputs(r#""kick" snd . "snare" snd ."#, 2);
|
||||
assert!(outputs[0].contains("sound/kick"));
|
||||
assert!(outputs[1].contains("sound/snare"));
|
||||
}
|
||||
@@ -48,7 +48,7 @@ fn multiple_emits() {
|
||||
fn envelope_params() {
|
||||
// Values are tempo-scaled: 0.01 * step_duration(0.125) = 0.00125, etc.
|
||||
let outputs = expect_outputs(
|
||||
r#""synth" s 0.01 attack 0.1 decay 0.7 sustain 0.3 release ."#,
|
||||
r#""synth" snd 0.01 attack 0.1 decay 0.7 sustain 0.3 release ."#,
|
||||
1,
|
||||
);
|
||||
assert!(outputs[0].contains("attack/0.00125"));
|
||||
@@ -59,14 +59,14 @@ fn envelope_params() {
|
||||
|
||||
#[test]
|
||||
fn filter_params() {
|
||||
let outputs = expect_outputs(r#""synth" s 2000 lpf 0.5 lpq ."#, 1);
|
||||
let outputs = expect_outputs(r#""synth" snd 2000 lpf 0.5 lpq ."#, 1);
|
||||
assert!(outputs[0].contains("lpf/2000"));
|
||||
assert!(outputs[0].contains("lpq/0.5"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adsr_sets_all_envelope_params() {
|
||||
let outputs = expect_outputs(r#""synth" s 0.01 0.1 0.5 0.3 adsr ."#, 1);
|
||||
let outputs = expect_outputs(r#""synth" snd 0.01 0.1 0.5 0.3 adsr ."#, 1);
|
||||
assert!(outputs[0].contains("attack/0.00125"));
|
||||
assert!(outputs[0].contains("decay/0.0125"));
|
||||
assert!(outputs[0].contains("sustain/0.5"));
|
||||
@@ -75,7 +75,7 @@ fn adsr_sets_all_envelope_params() {
|
||||
|
||||
#[test]
|
||||
fn ad_sets_attack_decay_sustain_zero() {
|
||||
let outputs = expect_outputs(r#""synth" s 0.01 0.1 ad ."#, 1);
|
||||
let outputs = expect_outputs(r#""synth" snd 0.01 0.1 ad ."#, 1);
|
||||
assert!(outputs[0].contains("attack/0.00125"));
|
||||
assert!(outputs[0].contains("decay/0.0125"));
|
||||
assert!(outputs[0].contains("sustain/0"));
|
||||
@@ -83,7 +83,7 @@ fn ad_sets_attack_decay_sustain_zero() {
|
||||
|
||||
#[test]
|
||||
fn bank_param() {
|
||||
let outputs = expect_outputs(r#""loop" s "a" bank ."#, 1);
|
||||
let outputs = expect_outputs(r#""loop" snd "a" bank ."#, 1);
|
||||
assert!(outputs[0].contains("sound/loop"));
|
||||
assert!(outputs[0].contains("bank/a"));
|
||||
}
|
||||
@@ -109,7 +109,7 @@ fn param_only_multiple_params() {
|
||||
|
||||
#[test]
|
||||
fn polyphonic_notes() {
|
||||
let outputs = expect_outputs(r#"60 64 67 note sine s ."#, 3);
|
||||
let outputs = expect_outputs(r#"60 64 67 note sine snd ."#, 3);
|
||||
assert!(outputs[0].contains("note/60"));
|
||||
assert!(outputs[1].contains("note/64"));
|
||||
assert!(outputs[2].contains("note/67"));
|
||||
@@ -117,14 +117,14 @@ fn polyphonic_notes() {
|
||||
|
||||
#[test]
|
||||
fn polyphonic_sounds() {
|
||||
let outputs = expect_outputs(r#"440 freq kick hat s ."#, 2);
|
||||
let outputs = expect_outputs(r#"440 freq kick hat snd ."#, 2);
|
||||
assert!(outputs[0].contains("sound/kick"));
|
||||
assert!(outputs[1].contains("sound/hat"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn polyphonic_cycling() {
|
||||
let outputs = expect_outputs(r#"60 64 67 note 0.5 1.0 gain sine s ."#, 3);
|
||||
let outputs = expect_outputs(r#"60 64 67 note 0.5 1.0 gain sine snd ."#, 3);
|
||||
assert!(outputs[0].contains("note/60"));
|
||||
assert!(outputs[0].contains("gain/0.5"));
|
||||
assert!(outputs[1].contains("note/64"));
|
||||
@@ -135,7 +135,7 @@ fn polyphonic_cycling() {
|
||||
|
||||
#[test]
|
||||
fn polyphonic_with_at() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at 60 64 note sine s ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at 60 64 note sine snd ."#, 4);
|
||||
assert_eq!(outputs.len(), 4);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ fn explicit_dur_zero_is_infinite() {
|
||||
#[test]
|
||||
fn all_before_sounds() {
|
||||
let outputs = expect_outputs(
|
||||
r#"500 lpf 0.5 verb all "kick" s 60 note . "hat" s 70 note ."#,
|
||||
r#"500 lpf 0.5 verb all "kick" snd 60 note . "hat" snd 70 note ."#,
|
||||
2,
|
||||
);
|
||||
assert!(outputs[0].contains("sound/kick"));
|
||||
@@ -162,7 +162,7 @@ fn all_before_sounds() {
|
||||
#[test]
|
||||
fn all_after_sounds() {
|
||||
let outputs = expect_outputs(
|
||||
r#""kick" s 60 note . "hat" s 70 note . 500 lpf 0.5 verb all"#,
|
||||
r#""kick" snd 60 note . "hat" snd 70 note . 500 lpf 0.5 verb all"#,
|
||||
2,
|
||||
);
|
||||
assert!(outputs[0].contains("sound/kick"));
|
||||
@@ -176,7 +176,7 @@ fn all_after_sounds() {
|
||||
#[test]
|
||||
fn noall_clears_global_params() {
|
||||
let outputs = expect_outputs(
|
||||
r#"500 lpf all "kick" s 60 note . noall "hat" s 70 note ."#,
|
||||
r#"500 lpf all "kick" snd 60 note . noall "hat" snd 70 note ."#,
|
||||
2,
|
||||
);
|
||||
assert!(outputs[0].contains("lpf/500"));
|
||||
@@ -187,7 +187,7 @@ fn noall_clears_global_params() {
|
||||
fn all_with_tempo_scaled_params() {
|
||||
// attack is tempo-scaled: 0.01 * step_duration(0.125) = 0.00125
|
||||
let outputs = expect_outputs(
|
||||
r#"0.01 attack all "kick" s 60 note ."#,
|
||||
r#"0.01 attack all "kick" snd 60 note ."#,
|
||||
1,
|
||||
);
|
||||
assert!(outputs[0].contains("attack/0.00125"));
|
||||
@@ -196,7 +196,7 @@ fn all_with_tempo_scaled_params() {
|
||||
#[test]
|
||||
fn all_per_sound_override() {
|
||||
let outputs = expect_outputs(
|
||||
r#"500 lpf all "kick" s 2000 lpf . "hat" s ."#,
|
||||
r#"500 lpf all "kick" snd 2000 lpf . "hat" snd ."#,
|
||||
2,
|
||||
);
|
||||
// kick has both global lpf=500 and per-sound lpf=2000; per-sound wins (comes last)
|
||||
@@ -210,7 +210,7 @@ fn all_persists_across_evaluations() {
|
||||
let f = forth();
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(r#"500 lpf 0.5 verb all"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" s 60 note ."#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd 60 note ."#, &ctx).unwrap();
|
||||
assert_eq!(outputs.len(), 1);
|
||||
assert!(outputs[0].contains("lpf/500"), "global lpf missing: {}", outputs[0]);
|
||||
assert!(outputs[0].contains("verb/0.5"), "global verb missing: {}", outputs[0]);
|
||||
@@ -222,7 +222,7 @@ fn noall_clears_across_evaluations() {
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(r#"500 lpf all"#, &ctx).unwrap();
|
||||
f.evaluate(r#"noall"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" s 60 note ."#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd 60 note ."#, &ctx).unwrap();
|
||||
assert_eq!(outputs.len(), 1);
|
||||
assert!(!outputs[0].contains("lpf"), "lpf should be cleared: {}", outputs[0]);
|
||||
}
|
||||
@@ -251,20 +251,20 @@ fn all_replaces_previous_global() {
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(r#"500 lpf 0.5 verb all"#, &ctx).unwrap();
|
||||
f.evaluate(r#"2000 lpf all"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" s ."#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ."#, &ctx).unwrap();
|
||||
assert_eq!(outputs.len(), 1);
|
||||
assert!(outputs[0].contains("lpf/2000"), "latest lpf should be 2000: {}", outputs[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice_param() {
|
||||
let outputs = expect_outputs(r#""break" s 8 slice ."#, 1);
|
||||
let outputs = expect_outputs(r#""break" snd 8 slice ."#, 1);
|
||||
assert!(outputs[0].contains("slice/8"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pick_param() {
|
||||
let outputs = expect_outputs(r#""break" s 8 slice 3 pick ."#, 1);
|
||||
let outputs = expect_outputs(r#""break" snd 8 slice 3 pick ."#, 1);
|
||||
assert!(outputs[0].contains("slice/8"));
|
||||
assert!(outputs[0].contains("pick/3"));
|
||||
}
|
||||
|
||||
@@ -56,14 +56,14 @@ fn stepdur_baseline() {
|
||||
|
||||
#[test]
|
||||
fn single_emit() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ."#, 1);
|
||||
let deltas = get_deltas(&outputs);
|
||||
assert!(approx_eq(deltas[0], 0.0), "single emit at start should have delta 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_emits_all_at_zero() {
|
||||
let outputs = expect_outputs(r#""kick" s . . . ."#, 4);
|
||||
let outputs = expect_outputs(r#""kick" snd . . . ."#, 4);
|
||||
let deltas = get_deltas(&outputs);
|
||||
for (i, delta) in deltas.iter().enumerate() {
|
||||
assert!(approx_eq(*delta, 0.0), "emit {}: expected delta 0, got {}", i, delta);
|
||||
@@ -72,7 +72,7 @@ fn multiple_emits_all_at_zero() {
|
||||
|
||||
#[test]
|
||||
fn sound_persists() {
|
||||
let outputs = expect_outputs(r#""kick" s . . "hat" s . ."#, 4);
|
||||
let outputs = expect_outputs(r#""kick" snd . . "hat" snd . ."#, 4);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds[0], "kick");
|
||||
assert_eq!(sounds[1], "kick");
|
||||
@@ -82,14 +82,14 @@ fn sound_persists() {
|
||||
|
||||
#[test]
|
||||
fn alternating_sounds() {
|
||||
let outputs = expect_outputs(r#""kick" s . "snare" s . "kick" s . "snare" s ."#, 4);
|
||||
let outputs = expect_outputs(r#""kick" snd . "snare" snd . "kick" snd . "snare" snd ."#, 4);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "snare", "kick", "snare"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dur_is_step_duration() {
|
||||
let outputs = expect_outputs(r#""kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#""kick" snd ."#, 1);
|
||||
let durs = get_durs(&outputs);
|
||||
assert!(approx_eq(durs[0], 0.5), "dur should be 4 * step_duration (0.5), got {}", durs[0]);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ fn cycle_picks_by_runs() {
|
||||
for runs in 0..4 {
|
||||
let ctx = ctx_with(|c| c.runs = runs);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) ( ) 2 cycle"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) ( ) 2 cycle"#, &ctx).unwrap();
|
||||
if runs % 2 == 0 {
|
||||
assert_eq!(outputs.len(), 1, "runs={}: emit should be picked", runs);
|
||||
} else {
|
||||
@@ -113,7 +113,7 @@ fn pcycle_picks_by_iter() {
|
||||
for iter in 0..4 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) ( ) 2 pcycle"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) ( ) 2 pcycle"#, &ctx).unwrap();
|
||||
if iter % 2 == 0 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: emit should be picked", iter);
|
||||
} else {
|
||||
@@ -128,7 +128,7 @@ fn cycle_with_sounds() {
|
||||
let ctx = ctx_with(|c| c.runs = runs);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(
|
||||
r#"( "kick" s . ) ( "hat" s . ) ( "snare" s . ) 3 cycle"#,
|
||||
r#"( "kick" snd . ) ( "hat" snd . ) ( "snare" snd . ) 3 cycle"#,
|
||||
&ctx
|
||||
).unwrap();
|
||||
assert_eq!(outputs.len(), 1, "runs={}: expected 1 output", runs);
|
||||
@@ -141,7 +141,7 @@ fn cycle_with_sounds() {
|
||||
|
||||
#[test]
|
||||
fn at_single_delta() {
|
||||
let outputs = expect_outputs(r#"0.5 at "kick" s ."#, 1);
|
||||
let outputs = expect_outputs(r#"0.5 at "kick" snd ."#, 1);
|
||||
let deltas = get_deltas(&outputs);
|
||||
let step_dur = 0.125;
|
||||
assert!(approx_eq(deltas[0], 0.5 * step_dur), "expected delta at 0.5 of step, got {}", deltas[0]);
|
||||
@@ -149,7 +149,7 @@ fn at_single_delta() {
|
||||
|
||||
#[test]
|
||||
fn at_list_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s ."#, 2);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd ."#, 2);
|
||||
let deltas = get_deltas(&outputs);
|
||||
let step_dur = 0.125;
|
||||
assert!(approx_eq(deltas[0], 0.0), "expected delta 0, got {}", deltas[0]);
|
||||
@@ -158,7 +158,7 @@ fn at_list_deltas() {
|
||||
|
||||
#[test]
|
||||
fn at_three_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.33 0.67 at "kick" s ."#, 3);
|
||||
let outputs = expect_outputs(r#"0 0.33 0.67 at "kick" snd ."#, 3);
|
||||
let deltas = get_deltas(&outputs);
|
||||
let step_dur = 0.125;
|
||||
assert!(approx_eq(deltas[0], 0.0), "expected delta 0");
|
||||
@@ -168,7 +168,7 @@ fn at_three_deltas() {
|
||||
|
||||
#[test]
|
||||
fn at_persists_across_emits() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . "hat" s ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd . "hat" snd ."#, 4);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat", "hat"]);
|
||||
}
|
||||
@@ -176,14 +176,14 @@ fn at_persists_across_emits() {
|
||||
|
||||
#[test]
|
||||
fn at_reset_with_zero() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . 0.0 at "hat" s ."#, 3);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd . 0.0 at "hat" snd ."#, 3);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_resets_at_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" s . clear "hat" s ."#, 3);
|
||||
let outputs = expect_outputs(r#"0 0.5 at "kick" snd . clear "hat" snd ."#, 3);
|
||||
let sounds = get_sounds(&outputs);
|
||||
assert_eq!(sounds, vec!["kick", "kick", "hat"]);
|
||||
let deltas = get_deltas(&outputs);
|
||||
@@ -196,7 +196,7 @@ fn at_records_selected_spans() {
|
||||
|
||||
let f = forth();
|
||||
let mut trace = ExecutionTrace::default();
|
||||
let script = r#"0 0.5 0.75 at "kick" s ."#;
|
||||
let script = r#"0 0.5 0.75 at "kick" snd ."#;
|
||||
f.evaluate_with_trace(script, &default_ctx(), &mut trace).unwrap();
|
||||
|
||||
// Should have 6 selected spans: 3 for at deltas + 3 for sound (one per emit)
|
||||
@@ -226,7 +226,7 @@ fn get_gains(outputs: &[String]) -> Vec<f64> {
|
||||
|
||||
#[test]
|
||||
fn arp_auto_subdivide() {
|
||||
let outputs = expect_outputs(r#"sine s c4 e4 g4 b4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"sine snd c4 e4 g4 b4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -242,7 +242,7 @@ fn arp_auto_subdivide() {
|
||||
|
||||
#[test]
|
||||
fn arp_with_explicit_at() {
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine s c4 e4 g4 b4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine snd c4 e4 g4 b4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -258,14 +258,14 @@ fn arp_with_explicit_at() {
|
||||
|
||||
#[test]
|
||||
fn arp_single_note() {
|
||||
let outputs = expect_outputs(r#"sine s c4 arp note ."#, 1);
|
||||
let outputs = expect_outputs(r#"sine snd c4 arp note ."#, 1);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arp_fewer_deltas_than_notes() {
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine s c4 e4 g4 b4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine snd c4 e4 g4 b4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -281,7 +281,7 @@ fn arp_fewer_deltas_than_notes() {
|
||||
|
||||
#[test]
|
||||
fn arp_fewer_notes_than_deltas() {
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine s c4 e4 arp note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.25 0.5 0.75 at sine snd c4 e4 arp note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -291,7 +291,7 @@ fn arp_fewer_notes_than_deltas() {
|
||||
|
||||
#[test]
|
||||
fn arp_multiple_params() {
|
||||
let outputs = expect_outputs(r#"sine s c4 e4 g4 arp note 0.5 0.7 0.9 arp gain ."#, 3);
|
||||
let outputs = expect_outputs(r#"sine snd c4 e4 g4 arp note 0.5 0.7 0.9 arp gain ."#, 3);
|
||||
let notes = get_notes(&outputs);
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
assert!(approx_eq(notes[1], 64.0));
|
||||
@@ -305,7 +305,7 @@ fn arp_multiple_params() {
|
||||
#[test]
|
||||
fn arp_no_arp_unchanged() {
|
||||
// Standard CycleList without arp → cross-product (backward compat)
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine s c4 e4 note ."#, 4);
|
||||
let outputs = expect_outputs(r#"0 0.5 at sine snd c4 e4 note ."#, 4);
|
||||
let notes = get_notes(&outputs);
|
||||
// Cross-product: each note at each delta
|
||||
assert!(approx_eq(notes[0], 60.0));
|
||||
@@ -318,7 +318,7 @@ fn arp_no_arp_unchanged() {
|
||||
fn arp_mixed_cycle_and_arp() {
|
||||
// CycleList sound (2) + ArpList note (3) → 3 arp × 2 poly = 6 voices
|
||||
// Each arp step plays both sine and saw simultaneously (poly stacking)
|
||||
let outputs = expect_outputs(r#"sine saw s c4 e4 g4 arp note ."#, 6);
|
||||
let outputs = expect_outputs(r#"sine saw snd c4 e4 g4 arp note ."#, 6);
|
||||
let sounds = get_sounds(&outputs);
|
||||
// Arp step 0: poly 0=sine, poly 1=saw
|
||||
assert_eq!(sounds[0], "sine");
|
||||
@@ -346,7 +346,7 @@ fn every_offset_fires_at_offset() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) 4 2 every+"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) 4 2 every+"#, &ctx).unwrap();
|
||||
if iter % 4 == 2 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: should fire", iter);
|
||||
} else {
|
||||
@@ -361,7 +361,7 @@ fn every_offset_wraps_large_offset() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) 4 6 every+"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) 4 6 every+"#, &ctx).unwrap();
|
||||
if iter % 4 == 2 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: should fire (wrapped offset)", iter);
|
||||
} else {
|
||||
@@ -375,7 +375,7 @@ fn except_offset_inverse() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f.evaluate(r#""kick" s ( . ) 4 2 except+"#, &ctx).unwrap();
|
||||
let outputs = f.evaluate(r#""kick" snd ( . ) 4 2 except+"#, &ctx).unwrap();
|
||||
if iter % 4 != 2 {
|
||||
assert_eq!(outputs.len(), 1, "iter={}: should fire", iter);
|
||||
} else {
|
||||
@@ -389,8 +389,8 @@ fn every_offset_zero_is_same_as_every() {
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let a = f.evaluate(r#""kick" s ( . ) 3 every"#, &ctx).unwrap();
|
||||
let b = f.evaluate(r#""kick" s ( . ) 3 0 every+"#, &ctx).unwrap();
|
||||
let a = f.evaluate(r#""kick" snd ( . ) 3 every"#, &ctx).unwrap();
|
||||
let b = f.evaluate(r#""kick" snd ( . ) 3 0 every+"#, &ctx).unwrap();
|
||||
assert_eq!(a.len(), b.len(), "iter={}: every and every+ 0 should match", iter);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user