audiocn

LCD Meter

A level meter on an LCD Display's screen, with block segments, a held peak, readouts, a printed scale and a CLIP flag.

Input
−∞

Installation

$ pnpm dlx shadcn@latest add @audiocn/lcd-meter

Usage

import { LcdDisplay } from "@/components/ui/lcd-display";
import { LcdMeter } from "@/components/ui/lcd-meter";
<LcdDisplay>
  <LcdMeter aria-label="Input level" source={analyser.meter} />
</LcdDisplay>

The meter lives on an LCD Display's screen, so it takes that screen's ink, glass, dot grid and glow, and it can share the screen with settings rows and the status pixel. It follows your theme the same way: dark pixels on a backlit glass in light mode, glowing ink in dark mode, in the theme's --primary or a fixed hardware ink.

With no children, it draws one row per channel (labelled L and R for a pair), each with a track, a held peak and a readout, then the scale and a CLIP flag. The metering is Level Meter's: the same sources, ballistics, peak hold and clip hold.

Anatomy

<LcdDisplay>
  <LcdMeter>
    <LcdMeterChannel index={0}>
      <LcdMeterLabel />
      <LcdMeterTrack>
        <LcdMeterBar />
        <LcdMeterHold />
      </LcdMeterTrack>
      <LcdMeterValue />
    </LcdMeterChannel>
    <LcdMeterScale />
    <LcdMeterClip />
  </LcdMeter>
</LcdDisplay>

The meter is a three-column grid: labels, tracks and readouts. Each LcdMeterChannel is one row of it; the scale sits under the tracks and the CLIP flag under the readouts. A readout inside a channel shows that channel, and one outside shows the loudest.

Examples

Inks

The meter has no colours of its own. Set variant on the display for a fixed hardware ink, or appearance="dark" for a dark screen on a light page.

−∞
−∞
−∞
−∞

Segments

Segments are whole dots of the display's grid: 3 dots wide with a 1-dot gap by default. A lit segment lights whole, never in part. Set --lcd-meter-segment to one dot for a fine ladder, or --lcd-meter-gap to 0px for a solid bar.

−∞
−∞
−∞
<LcdMeter className="[--lcd-meter-segment:var(--lcd-display-pitch)]" />
<LcdMeter className="[--lcd-meter-gap:0px]" />

Peak and RMS

Layer an rms bar over a dimmed peak bar for a dual meter.

<LcdMeterTrack>
  <LcdMeterBar className="opacity-40" />
  <LcdMeterBar measure="rms" />
  <LcdMeterHold />
</LcdMeterTrack>

Microphone

Custom rows take labels of any length. The meter moves its tracks onto the screen's dot grid, so segments never cut a dot in half.

Mic
−∞

Feeding data

A meter accepts levels three ways, as Level Meter does. See Feeding data.

// A source: subscribes and paints itself, no React renders.
<LcdMeter source={analyser.meter} />

// Values: for slow data. Ballistics smooth the movement.
<LcdMeter peakDb={-9.1} rmsDb={-18} />

// A handle: for callers that own their own frame loop.
const meter = useRef<LevelMeterActions>(null);
meter.current?.paint({ channels: [{ peakDb: -9.1 }] });
<LcdMeter actionsRef={meter} />

The meter uses the audio taper by default, which gives the loud end of the range most of the track, like a recorder's screen. Pass taper="linear" for equal distance per dB.

Theming

VariableDefault
--lcd-meter-segment3 dots of --lcd-display-pitch
--lcd-meter-gap1 dot. 0px gives a solid bar
--lcd-meter-thickness5, 7 or 10 dots for the display's sm, default and lg
--lcd-meter-unlitUnlit segments and the CLIP flag at rest: the lit pixels at 14%
--lcd-display-*Everything else: the ink, lit and dim pixels, glass, glow, pitch and font. See LCD Display
--meter-level, --meter-rms, --meter-holdOn each channel, live, 0..1
Data attributeOnMeaning
data-zoneroot, channelsok, warn or clip
data-clippingroot, CLIP flagThe signal clipped in the last 1.5 s
data-activechannelsThe level is above the bottom of the range
data-sizerootThe display's size
data-measurebarspeak or rms

The screen has one ink, so zones show as a bracket printed over the clip zone and a CLIP flag that inverts while the signal clips. data-zone is there if you want to style them yourself.

Accessibility

  • The meter has role="meter" with its value in dB, updated at most four times a second. Give it a name with aria-label or aria-labelledby.
  • The CLIP flag is a button that turns the flag off, and announces clipping to screen readers.
  • With reduced motion, the meter shows the current level four times a second instead of animating, and the CLIP flag inverts without a transition.

API reference

LcdMeter

Takes LevelMeter's data and scale props, except orientation, variant, segments and size. The size comes from the display.

Prop

Type

LcdMeterChannel

Prop

Type

LcdMeterBar

Prop

Type

LcdMeterValue

Takes DbReadout's props.

Prop

Type

LcdMeterScale

Prop

Type

LcdMeterClip

Takes ClipIndicator's props. Children replace the word CLIP.