feat: ceiling-hit markers as top-edge ticks on the rolling plot
Flag each plot bucket with whether the output limiter hit the ceiling (limiter GR > 0.1 dB), carried through ScopeRing as a per-bucket hit field and folded into history columns. The editor draws a short red tick at the top of any hit column (one column wide, so runs merge into segments and a lone hit is a dot); nothing otherwise. Global marker, shown on every channel tab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-1
@@ -46,11 +46,16 @@ struct Codename206 {
|
||||
scope_in: [f32; 4],
|
||||
scope_out: [f32; 4],
|
||||
scope_gr: [f32; 4],
|
||||
/// Max output-limiter gain reduction seen in the current bucket (for the ceiling-hit marker).
|
||||
scope_hit: f32,
|
||||
/// Samples accumulated into the current bucket, and the bucket length (= sample_rate / BUCKET_HZ).
|
||||
scope_samples: usize,
|
||||
scope_bucket_len: usize,
|
||||
}
|
||||
|
||||
/// Limiter gain reduction (dB) above which a plot bucket is flagged as hitting the ceiling.
|
||||
const CEILING_HIT_GR_DB: f32 = 0.1;
|
||||
|
||||
impl Default for Codename206 {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -64,6 +69,7 @@ impl Default for Codename206 {
|
||||
scope_in: [0.0; 4],
|
||||
scope_out: [0.0; 4],
|
||||
scope_gr: [0.0; 4],
|
||||
scope_hit: 0.0,
|
||||
scope_samples: 0,
|
||||
scope_bucket_len: 1,
|
||||
}
|
||||
@@ -164,6 +170,7 @@ impl Plugin for Codename206 {
|
||||
self.scope_in = [0.0; 4];
|
||||
self.scope_out = [0.0; 4];
|
||||
self.scope_gr = [0.0; 4];
|
||||
self.scope_hit = 0.0;
|
||||
self.scope_samples = 0;
|
||||
}
|
||||
|
||||
@@ -287,14 +294,17 @@ impl Plugin for Codename206 {
|
||||
self.scope_in[ALL] = self.scope_in[ALL].max(in_mono);
|
||||
self.scope_out[ALL] = self.scope_out[ALL].max(out_l.max(out_r));
|
||||
self.scope_gr[ALL] = self.scope_gr[ALL].max(g);
|
||||
self.scope_hit = self.scope_hit.max(self.limiter.gain_reduction_db());
|
||||
|
||||
// Emit a plot bucket every scope_bucket_len samples (~BUCKET_HZ).
|
||||
self.scope_samples += 1;
|
||||
if self.scope_samples >= self.scope_bucket_len {
|
||||
self.meters.scope.push(&self.scope_in, &self.scope_out, &self.scope_gr);
|
||||
let hit = if self.scope_hit > CEILING_HIT_GR_DB { 1.0 } else { 0.0 };
|
||||
self.meters.scope.push(&self.scope_in, &self.scope_out, &self.scope_gr, hit);
|
||||
self.scope_in = [0.0; meters::NUM_CHANNELS];
|
||||
self.scope_out = [0.0; meters::NUM_CHANNELS];
|
||||
self.scope_gr = [0.0; meters::NUM_CHANNELS];
|
||||
self.scope_hit = 0.0;
|
||||
self.scope_samples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user