PluginUI

Gain Reduction Meter

gain-reduction-meterViewers

The three bars on a compressor's front panel. Input and output level use the usual dB scale. Between them, the gain-reduction bar fills from the top downward, following the hardware convention for showing what is being taken away; a peak-hold tick marks the deepest recent bite. Supply dB values you already have, a per-frame callback (DynamicsCompressorNode.reduction works directly), or a pair of analysers for the level bars. Every column is optional, so a lone GR bar works too.

Bone / Studio
Loading interactive preview…
Planar / Flat
Loading interactive preview…
Midnight / Minimal
Loading interactive preview…
Ember / Vintage
Loading interactive preview…
Ink / Studio
Loading interactive preview…
Mint / Flat
Loading interactive preview…

Install

Copies the source into your project. Anything it depends on comes with it.

$ pnpm dlx shadcn@latest add @pluginui/core-gain-reduction-meter

Pulls in

use-audio-sourcecontrol-theme

First time? Add the registry to your components.json once:

components.json
{
  "registries": {
    "@pluginui": "https://pluginui.com/r/{name}.json"
  }
}

Usage

Connect the documented props to your application or host.

example.tsx
import { GainReductionMeter } from "@/components/ui/gain-reduction-meter"

// One compressor, tapped before and after:
const compressor = new DynamicsCompressorNode(context, { threshold: -24, ratio: 4 })
const inputAnalyser = new AnalyserNode(context)
const outputAnalyser = new AnalyserNode(context)
source.connect(inputAnalyser)
source.connect(compressor)
compressor.connect(outputAnalyser)
compressor.connect(context.destination)

<GainReductionMeter
  getLevels={() => ({ reduction: compressor.reduction })}
  inputAnalyser={inputAnalyser}
  outputAnalyser={outputAnalyser}
  segments={16}
  showScale
/>

Props

PropTypeDefaultDescription
levels{ input?: number; output?: number; reduction: number }—Levels you already computed, in dB (reduction ≤ 0). Highest precedence: any field given here overrides the same field from getLevels or the analysers.
getLevels() => { input?: number; output?: number; reduction: number }—Polled once per animation frame. The DynamicsCompressorNode hook: () => ({ reduction: compressor.reduction }).
inputAnalyser / outputAnalyserAnalyserNode—RMS dB for the IN / OUT bars is computed from these values each frame. Read-only. Analysers cannot report reduction, so the GR bar still needs levels or getLevels.
pausedbooleanfalseStop polling and hold the last frame.
showInput / showReduction / showOutputbooleantrueWhich columns render. Turn IN and OUT off for a lone GR bar.
orientation"vertical" | "horizontal""vertical"Which way the bars run. GR fills from the top downward when vertical, from the right edge inward when horizontal.
lengthnumber120Long axis in pixels.
thicknessnumber10Width of each bar in pixels.
segmentsnumber0Draw as discrete LED segments; 0 is a continuous bar. Segment colours belong to their scale position, hardware-style.
showScalebooleanfalsedB tick labels: the level scale on one side, the GR scale on the other.
showLabelsbooleantrueShow the IN / GR / OUT captions.
labels{ input?: string; reduction?: string; output?: string }—Caption overrides, e.g. { reduction: "COMP" }.
minDecibels / maxDecibelsnumber-60 / 0The dB range the level bars span.
minReductionnumber-24Deepest reduction the GR scale shows, in dB (negative).
zones{ amber?: number; red?: number }{ amber: -18, red: -6 }Where the level bars turn amber and red, in dB.
peakDecaynumber0.6GR peak-hold decay in full-scale units per second. 0 hides the tick.
colors{ low?; mid?; high?; reduction?; peak? }—Per-part colour overrides. Defaults read --uikit-meter-low/-mid/-high with traffic-light fallbacks; the GR bar uses the theme accent.

Interaction

  • Drag with pointer capture, so the gesture keeps tracking past the edge of the control.
  • Shift while dragging for a fine pass; release it mid-gesture and coarse tracking resumes.
  • Double-click resets to defaultValue.
  • Arrow keys step normally, Shift+arrow steps finely, PageUp/PageDown jump by ten, Home/End go to the extremes.
  • Proper slider and switch roles with live aria-valuetext, so a screen reader announces the formatted value rather than the raw number.
  • The scroll wheel adjusts the value while the pointer is over the control; stepped ranges move at least one declared step per notch by default.