feat(ballast): add Ballast switch-up leveller
Ballast gives every part of a bassline one gain that brings it to the target loudness, with no compression inside a part. Parts start at note starts, detected from the audio or taken from MIDI, or on the host's beat grid, so a patch change on the same note counts too. - Loudness is K-weighted over each part's first 100 ms, in 10 ms blocks with a relative gate, and every part is weighted from rest so the last part does not ring into it. - The audio path is delayed by the tracker's lookahead, the window and a 5 ms glide, so each gain is in place on its part's first sample. - Learn takes the next part's loudness as the target. Amount, Range, Measure from (leave the sub out), Gate, Output, Bypass. - Editor shows the last 32 parts in and out, the target, and the spread of the last 16 parts. - Registered in the catalog, workflows, editor-check, README, chain and development docs, and the website copy.
This commit is contained in:
1 parent
d77b88c7a9
commit
d93dd942a8
28 files changed
+4716
-21
No files matched your search
@@ -12,13 +12,13 @@ fn main() {
|
||||
.unwrap_or("rivet");
|
||||
if ![
|
||||
"rivet", "patina", "anvil", "crucible", "lathe", "temper", "weld", "knurl", "planish",
|
||||
"braze", "quench",
|
||||
"braze", "quench", "ballast",
|
||||
]
|
||||
.contains(&plugin)
|
||||
{
|
||||
eprintln!(
|
||||
"Use --plugin rivet, patina, anvil, crucible, lathe, temper, weld, knurl, planish, \
|
||||
braze or quench"
|
||||
braze, quench or ballast"
|
||||
);
|
||||
std::process::exit(2);
|
||||
}
|
||||
@@ -33,7 +33,10 @@ fn main() {
|
||||
let planish = plugin == "planish";
|
||||
let braze = plugin == "braze";
|
||||
let quench = plugin == "quench";
|
||||
let (width, height) = if quench {
|
||||
let ballast = plugin == "ballast";
|
||||
let (width, height) = if ballast {
|
||||
(ballast_ui::WIDTH, ballast_ui::HEIGHT)
|
||||
} else if quench {
|
||||
(quench_ui::WIDTH, quench_ui::HEIGHT)
|
||||
} else if braze {
|
||||
(braze_ui::WIDTH, braze_ui::HEIGHT)
|
||||
@@ -253,6 +256,37 @@ fn main() {
|
||||
}
|
||||
quench_state.accept_frame(engine.take_analyzer());
|
||||
}
|
||||
let mut ballast_settings = ballast_core::Settings {
|
||||
segment: ballast_core::Segment::Grid,
|
||||
target: -16.,
|
||||
..Default::default()
|
||||
};
|
||||
let mut ballast_state = ballast_ui::State::default();
|
||||
if ballast {
|
||||
// A switch-up every quarter at 140 BPM, cycling four patches of different loudness.
|
||||
let mut engine = ballast_core::Engine::new(48000., 2).unwrap();
|
||||
engine.set_settings(ballast_settings).unwrap();
|
||||
let mut saw = common_dsp::Saw::new(48000., 43.65);
|
||||
let quarter = 48000. * 60. / 140.;
|
||||
for i in 0..48000 * 9 {
|
||||
if i % 512 == 0 {
|
||||
engine.set_transport(Some(140.), Some(i as f64 / 48000. * 140. / 60.));
|
||||
}
|
||||
let part = (i as f32 / quarter) as usize;
|
||||
let s = saw.sample();
|
||||
let x = match part % 4 {
|
||||
0 => (s * 4.).tanh() * 0.6,
|
||||
1 => s * 0.15,
|
||||
2 => (s * 2.).tanh() * 0.35,
|
||||
_ => (s * 8.).tanh() * 0.9,
|
||||
};
|
||||
engine.process_sample([x, x]);
|
||||
if i % 1600 == 0 {
|
||||
ballast_state.accept_frame(engine.take_analyzer());
|
||||
}
|
||||
}
|
||||
ballast_state.accept_frame(engine.take_analyzer());
|
||||
}
|
||||
let mut weld_settings = weld_core::Settings::default();
|
||||
let mut weld_state = weld_ui::State::default();
|
||||
if weld {
|
||||
@@ -382,7 +416,9 @@ fn main() {
|
||||
let session_motif = session.motifs[0].id;
|
||||
shared.replace(session).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
if quench {
|
||||
if ballast {
|
||||
ballast_ui::style(&ctx);
|
||||
} else if quench {
|
||||
quench_ui::style(&ctx);
|
||||
} else if braze {
|
||||
braze_ui::style(&ctx);
|
||||
@@ -425,7 +461,9 @@ fn main() {
|
||||
},
|
||||
|ui| {
|
||||
egui::CentralPanel::default().show(ui, |ui| {
|
||||
if quench {
|
||||
if ballast {
|
||||
ballast_ui::show(ui, &mut ballast_settings, &mut ballast_state);
|
||||
} else if quench {
|
||||
quench_ui::show(ui, &mut quench_settings, &mut quench_state);
|
||||
} else if braze {
|
||||
braze_ui::show(ui, &mut braze_settings, &mut braze_state);
|
||||
|
||||
Reference in new issue
Block a user