Draw separate upwards and downwards curves
This commit is contained in:
parent
14cd737e8f
commit
4022fdd37c
|
@ -30,6 +30,9 @@ pub struct AnalyzerData {
|
||||||
/// The parameters used for the global threshold curve. This is used to draw the same curve used
|
/// The parameters used for the global threshold curve. This is used to draw the same curve used
|
||||||
/// by the compressors on the analyzer.
|
/// by the compressors on the analyzer.
|
||||||
pub curve_params: CurveParams,
|
pub curve_params: CurveParams,
|
||||||
|
/// The upwards and downwards threshold offsets for the curve. These are used to draw the curve
|
||||||
|
/// twice with some distance between them if either is non-zero.
|
||||||
|
pub curve_offsets_db: (f32, f32),
|
||||||
|
|
||||||
/// The number of used bins. This is part of the `AnalyzerData` since recomputing it in the
|
/// The number of used bins. This is part of the `AnalyzerData` since recomputing it in the
|
||||||
/// editor could result in a race condition.
|
/// editor could result in a race condition.
|
||||||
|
@ -53,6 +56,7 @@ impl Default for AnalyzerData {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
curve_params: CurveParams::default(),
|
curve_params: CurveParams::default(),
|
||||||
|
curve_offsets_db: (0.0, 0.0),
|
||||||
num_bins: 0,
|
num_bins: 0,
|
||||||
envelope_followers: [0.0; crate::MAX_WINDOW_SIZE / 2 + 1],
|
envelope_followers: [0.0; crate::MAX_WINDOW_SIZE / 2 + 1],
|
||||||
gain_difference_db: [0.0; crate::MAX_WINDOW_SIZE / 2 + 1],
|
gain_difference_db: [0.0; crate::MAX_WINDOW_SIZE / 2 + 1],
|
||||||
|
|
|
@ -621,6 +621,10 @@ impl CompressorBank {
|
||||||
|
|
||||||
// The editor needs to know about this too so it can draw the spectra correctly
|
// The editor needs to know about this too so it can draw the spectra correctly
|
||||||
analyzer_input_data.curve_params = params.threshold.curve_params();
|
analyzer_input_data.curve_params = params.threshold.curve_params();
|
||||||
|
analyzer_input_data.curve_offsets_db = (
|
||||||
|
params.compressors.upwards.threshold_offset_db.value(),
|
||||||
|
params.compressors.downwards.threshold_offset_db.value(),
|
||||||
|
);
|
||||||
analyzer_input_data.num_bins = num_bins;
|
analyzer_input_data.num_bins = num_bins;
|
||||||
|
|
||||||
// The gain reduction data needs to be averaged, see above
|
// The gain reduction data needs to be averaged, see above
|
||||||
|
|
|
@ -42,9 +42,12 @@ const LN_FREQ_RANGE: f32 = LN_FREQ_RANGE_END_HZ - LN_FREQ_RANGE_START_HZ;
|
||||||
/// backgrounds.
|
/// backgrounds.
|
||||||
const GR_BAR_OVERLAY_COLOR: vg::Color = vg::Color::rgbaf(0.85, 0.95, 1.0, 0.8);
|
const GR_BAR_OVERLAY_COLOR: vg::Color = vg::Color::rgbaf(0.85, 0.95, 1.0, 0.8);
|
||||||
|
|
||||||
/// The color used for drawing the target curve. Looks somewhat similar to `GR_BAR_OVERLAY_COLOR`
|
/// The color used for drawing the downwards compression threshold curve. Looks somewhat similar to
|
||||||
/// when factoring in the blending
|
/// `GR_BAR_OVERLAY_COLOR` when factoring in the blending.
|
||||||
const TARGET_CURVE_COLOR: vg::Color = vg::Color::rgbaf(0.45, 0.55, 0.6, 0.9);
|
const DOWNWARDS_THRESHOLD_CURVE_COLOR: vg::Color = vg::Color::rgbaf(0.45, 0.55, 0.6, 0.9);
|
||||||
|
/// The color used for drawing the upwards compression threshold curve. Slightly color to make to
|
||||||
|
/// make the output look less confusing.
|
||||||
|
const UPWARDS_THRESHOLD_CURVE_COLOR: vg::Color = vg::Color::rgbaf(0.55, 0.70, 0.65, 0.9);
|
||||||
|
|
||||||
/// A very analyzer showing the envelope followers as a magnitude spectrum with an overlay for the
|
/// A very analyzer showing the envelope followers as a magnitude spectrum with an overlay for the
|
||||||
/// gain reduction.
|
/// gain reduction.
|
||||||
|
@ -93,7 +96,7 @@ impl View for Analyzer {
|
||||||
let nyquist = self.sample_rate.load(Ordering::Relaxed) / 2.0;
|
let nyquist = self.sample_rate.load(Ordering::Relaxed) / 2.0;
|
||||||
|
|
||||||
draw_spectrum(cx, canvas, analyzer_data, nyquist);
|
draw_spectrum(cx, canvas, analyzer_data, nyquist);
|
||||||
draw_target_curve(cx, canvas, analyzer_data);
|
draw_threshold_curve(cx, canvas, analyzer_data);
|
||||||
draw_gain_reduction(cx, canvas, analyzer_data, nyquist);
|
draw_gain_reduction(cx, canvas, analyzer_data, nyquist);
|
||||||
// TODO: Display the frequency range below the graph
|
// TODO: Display the frequency range below the graph
|
||||||
|
|
||||||
|
@ -257,12 +260,15 @@ fn draw_spectrum(
|
||||||
canvas.fill_path(&mut mesh_path, &mesh_paint);
|
canvas.fill_path(&mut mesh_path, &mesh_paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overlays the target curve over the spectrum analyzer.
|
/// Overlays the threshold curve over the spectrum analyzer. If either the upwards or downwards
|
||||||
fn draw_target_curve(cx: &mut DrawContext, canvas: &mut Canvas, analyzer_data: &AnalyzerData) {
|
/// threshold offsets are non-zero then two curves are drawn.
|
||||||
|
fn draw_threshold_curve(cx: &mut DrawContext, canvas: &mut Canvas, analyzer_data: &AnalyzerData) {
|
||||||
let bounds = cx.bounds();
|
let bounds = cx.bounds();
|
||||||
|
|
||||||
let line_width = cx.style.dpi_factor as f32 * 3.0;
|
let line_width = cx.style.dpi_factor as f32 * 3.0;
|
||||||
let paint = vg::Paint::color(TARGET_CURVE_COLOR).with_line_width(line_width);
|
let downwards_paint =
|
||||||
|
vg::Paint::color(DOWNWARDS_THRESHOLD_CURVE_COLOR).with_line_width(line_width);
|
||||||
|
let upwards_paint = vg::Paint::color(UPWARDS_THRESHOLD_CURVE_COLOR).with_line_width(line_width);
|
||||||
|
|
||||||
// This can be done slightly cleverer but for our purposes drawing line segments that are either
|
// This can be done slightly cleverer but for our purposes drawing line segments that are either
|
||||||
// 1 pixel apart or that split the curve up into 100 segments (whichever results in the least
|
// 1 pixel apart or that split the curve up into 100 segments (whichever results in the least
|
||||||
|
@ -270,6 +276,7 @@ fn draw_target_curve(cx: &mut DrawContext, canvas: &mut Canvas, analyzer_data: &
|
||||||
let curve = Curve::new(&analyzer_data.curve_params);
|
let curve = Curve::new(&analyzer_data.curve_params);
|
||||||
let num_points = 100.min(bounds.w.ceil() as usize);
|
let num_points = 100.min(bounds.w.ceil() as usize);
|
||||||
|
|
||||||
|
let mut draw_with_offset = |offset_db: f32, paint: vg::Paint| {
|
||||||
let mut path = vg::Path::new();
|
let mut path = vg::Path::new();
|
||||||
for i in 0..num_points {
|
for i in 0..num_points {
|
||||||
let x_t = i as f32 / (num_points - 1) as f32;
|
let x_t = i as f32 / (num_points - 1) as f32;
|
||||||
|
@ -277,7 +284,7 @@ fn draw_target_curve(cx: &mut DrawContext, canvas: &mut Canvas, analyzer_data: &
|
||||||
|
|
||||||
// Evaluating the curve results in a value in dB, which must then be mapped to the same
|
// Evaluating the curve results in a value in dB, which must then be mapped to the same
|
||||||
// scale used in `draw_spectrum()`
|
// scale used in `draw_spectrum()`
|
||||||
let y_db = curve.evaluate_ln(ln_freq);
|
let y_db = curve.evaluate_ln(ln_freq) + offset_db;
|
||||||
let y_t = db_to_unclamped_t(y_db);
|
let y_t = db_to_unclamped_t(y_db);
|
||||||
|
|
||||||
let physical_x_pos = bounds.x + (bounds.w * x_t);
|
let physical_x_pos = bounds.x + (bounds.w * x_t);
|
||||||
|
@ -296,6 +303,11 @@ fn draw_target_curve(cx: &mut DrawContext, canvas: &mut Canvas, analyzer_data: &
|
||||||
canvas.scissor(bounds.x, bounds.y, bounds.w, bounds.h);
|
canvas.scissor(bounds.x, bounds.y, bounds.w, bounds.h);
|
||||||
canvas.stroke_path(&mut path, &paint);
|
canvas.stroke_path(&mut path, &paint);
|
||||||
canvas.reset_scissor();
|
canvas.reset_scissor();
|
||||||
|
};
|
||||||
|
|
||||||
|
let (upwards_offset_db, downwards_offset_db) = analyzer_data.curve_offsets_db;
|
||||||
|
draw_with_offset(upwards_offset_db, upwards_paint);
|
||||||
|
draw_with_offset(downwards_offset_db, downwards_paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overlays the gain reduction display over the spectrum analyzer.
|
/// Overlays the gain reduction display over the spectrum analyzer.
|
||||||
|
|
Loading…
Reference in a new issue