Skip to content

Input Boost can clip with the clip indicator dark: the level meter reads only negative samples #3951

Description

@mcfnord

🤖 AI: Input Boost can drive the signal into hard clipping while the clip indicator stays dark and the feedback auto-mute stays silent, because the level meter reads only negative samples.

Describe the bug

#3834 made Input Boost clamp with Float2Short instead of wrapping, so overload now clips. The level meter runs on that same buffer inside the same block, and its loop takes std::min over negatives only, every third one. A clip that goes positive reads zero.

One cause, two consumers: the clip indicator and the feedback auto-mute both read the single value Update() writes.

To Reproduce

A real client sending into a real server, with the server's own recording as the evidence and the client's clip indicator read off the screen. Three arms, same source peak, only the skew differs:

source, Input Boost within 1% of full scale, positive negative clip indicator
symmetric, 4x 15.16% 15.16% lights
6:1 positive-skewed, 4x 15.05% 0.00% dark
6:1 positive-skewed, 10x 29.41% 0.00% dark
2:1 positive-skewed, 4x 16.37% 0.00% dark
2:1 positive-skewed, 10x 31.16% 22.59% lights

The control and the 4x skewed arm clip by the same amount. The last two rows set the boundary: at a 2:1 crest asymmetry, which is the most any real recording to hand reaches over a loud 100 ms window, the indicator is still dark on 16.37% clipped samples at 4x — and lights at 10x only because that boost drives the quiet half to full scale as well. So what hides a clip is the quiet half staying below full scale, not the ratio itself.

Expected behavior

Clipping lights the clip indicator whichever way the waveform clips.

Version of Jamulus

3.12.5dev, built at 267bf6b7. The end-to-end arm ran on Linux (g++ 13.3.0, Qt 5.15.13, JACK). The meter itself was additionally built and run from the same src/util.cpp on macOS 12.7.6 (Apple clang 14, Qt 5.15.2), on Windows 11 (MSVC 19.44, Qt 6.10.2) and on aarch64 Linux (g++ 14.2.0, Qt 5.15.15): all four emit byte-identical output over 54 lines of arms, so neither the platform, the architecture, nor the Qt major version changes what the indicator does.

Additional context

  • Driving the shipped CStereoSignalLevelMeter directly gives the same split at block level: at Input Boost 4x a symmetric and a 6:1 skewed source both pin 18.6% of samples at full scale, and only the symmetric one lights the indicator.
  • The auto-mute inherits the bias and does more than light an indicator: it mutes the channel and opens a modal. Run end to end with detection enabled, the symmetric control at 4x opens "Audio feedback or loud signal detected" and it stays up for 11 of 14 sampled frames, while the 6:1 skewed source at 4x and at 10x never opens it. Its reach is narrow either way: DETECT_FEEDBACK_TIME_MS is a single-shot 3-second window armed on connection, so it never sees a level that rises later in a session.
  • The indicator needs exactly -32768: an all--32767 block reads 8.0000000 and stays dark, all--32768 reads 8.0000424 and lights. corrados intended that in 2020, when nothing on this path applied gain above 1.
  • Decimation: the stereo loop steps i += 6 reading [i] and [i+1], so four of every six sample positions are never examined. A single-sample clip is seen at interleaved index 0 and 1 and missed at 2, 3, 4 and 5.
  • The recording is taken after Opus, which rings around a flat top, so "within 1% of full scale" is the measure rather than a count of exact +32767 samples.
  • The server keeps its own meter of the same type — CChannel::SignalLevelMeter is also a CStereoSignalLevelMeter — so it inherits the same bias, and the channel meter it feeds over CLM_CHANNEL_LEVEL_LIST has its own clip indicator. In the runs above that indicator is dark on exactly the arms where the client's is, and lit on exactly the arms where the client's is. Two meters, computed independently at each end, agree row for row.
  • The same thing happens on Windows through ASIO rather than JACK, using the CI build of this commit: with the 6:1 source at Input Boost 4x the server's recording reaches +32767 on 7.57% of samples and −7797 at the other extreme, while the client's input meter carries no red pixel at all.
  • Not measured: the end-to-end client path on macOS, and any real recording with a crest asymmetry beyond 2:1.

🤖 This message was written by AI and reviewed by @mcfnord.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions