Skip to content

DelayLine.Process with an out-of-range delay throws after writing the sample, so a rejected call still shifts every later tap by one sample #95

Description

@matt-edmondson

What's wrong

DelayLine.Process(float input, int delaySamples) (Containers/DelayLine.cs ~line 152) is implemented as:

Write(input);
return Read(delaySamples);

The range check on delaySamples (ThrowIfNegative / ThrowIfGreaterThan(delaySamples, Capacity)) lives in Read, so it only runs after Write has stored the sample and advanced the write cursor.

Repro (verified by running against the current main)

var line = new DelayLine(4);
try { line.Process(99f, 5); } catch (ArgumentOutOfRangeException) { }
Console.WriteLine(line.Read(0)); // expected 0 (the call was rejected), actual 99

Why it matters

The call throws, so the caller treats it as rejected, but the delay line's state has still changed. The write cursor has moved and a sample the caller thinks was discarded is now in the buffer. Every later read is off by one sample relative to the caller's own sample count. In an audio callback that catches and carries on, this puts a click into the output and shifts the timing of every tap.

Suggested fix

Validate before mutating. Either:

  • add ArgumentOutOfRangeException.ThrowIfNegative(delaySamples); ArgumentOutOfRangeException.ThrowIfGreaterThan(delaySamples, Capacity); at the top of Process, or
  • move the check into a small shared helper that both Read and Process call before doing anything.

Acceptance criteria

  • Process with a negative delay, or a delay above Capacity, throws ArgumentOutOfRangeException and leaves the buffer contents and write position unchanged.
  • A test that covers the repro above.

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions