MonoGame/MonoGame · error · ArgumentException

The loopStart cannot be greater than the total number of sam

Error message

The loopStart cannot be greater than the total number of samples.

What it means

Thrown as ArgumentException (paramName 'loopStart') from the public SoundEffect constructor when loopStart > totalSamples (totalSamples = count / blockAlign). A loop start beyond the sample range is unreachable; the loop region must begin within the actual audio. The check uses '>' (not '>=') so loopStart == totalSamples is allowed only when loopLength is 0/empty, which is then defaulted.

Source

Thrown at MonoGame.Framework/Audio/SoundEffect.cs:189

                throw new ArgumentException("Ensure that the buffer length is non-zero.", "buffer");

            var blockAlign = (int)channels * 2;
            if (count <= 0)
                throw new ArgumentException("Ensure that the count is greater than zero.", "count");
            if ((count % blockAlign) != 0)
                throw new ArgumentException("Ensure that the count meets the block alignment requirements for the number of channels.", "count");

            if (offset < 0)
                throw new ArgumentException("The offset cannot be negative.", "offset");
            if (((ulong)count + (ulong)offset) > (ulong)buffer.Length)
                throw new ArgumentException("Ensure that the offset+count region lines within the buffer.", "offset");

            var totalSamples = count / blockAlign;

            if (loopStart < 0)
                throw new ArgumentException("The loopStart cannot be negative.", "loopStart");
            if (loopStart > totalSamples)
                throw new ArgumentException("The loopStart cannot be greater than the total number of samples.", "loopStart");

            if (loopLength == 0)
                loopLength = totalSamples - loopStart;

            if (loopLength < 0)
                throw new ArgumentException("The loopLength cannot be negative.", "loopLength");
            if (((ulong)loopStart + (ulong)loopLength) > (ulong)totalSamples)
                throw new ArgumentException("Ensure that the loopStart+loopLength region lies within the sample range.", "loopLength");

            _duration = GetSampleDuration(count, sampleRate, channels);

            PlatformInitializePcm(buffer, offset, count, 16, sampleRate, channels, loopStart, loopLength);
        }

        #endregion

        #region Finalizer

View on GitHub (pinned to 1d71bbd0ff)

Solutions

  1. Recompute loopStart in samples against the actual buffer: ensure 0 <= loopStart <= totalSamples.
  2. When trimming or resampling, rescale loopStart by the same ratio.
  3. Clamp loopStart to totalSamples (or pass 0 to disable looping).
  4. Pass loopStart=0, loopLength=0 to let MonoGame default to a full-buffer loop if you only want whole-sample looping.

Example fix

// before
var sfx = new SoundEffect(trimmedBuf, 0, trimmedBuf.Length, rate, ch, origLoopStart, loopLen);
// origLoopStart refers to the pre-trim source -> throws

// after
int totalSamples = trimmedBuf.Length / ((int)ch * 2);
int loopStart = Math.Min(origLoopStart - trimHeadSamples, totalSamples);
loopStart = Math.Max(0, loopStart);
var sfx = new SoundEffect(trimmedBuf, 0, trimmedBuf.Length, rate, ch, loopStart, loopLen);
Defensive patterns

Strategy: validation

Validate before calling

int totalSamples = count / ((int)ch * 2);
int loopStart = Math.Clamp(requestedLoopStart, 0, totalSamples);
var sfx = new SoundEffect(buffer, offset, count, rate, ch, loopStart, loopLength);

Type guard

static bool LoopStartInRange(int loopStart, int totalSamples)
    => loopStart >= 0 && loopStart <= totalSamples;

Try / catch

try { return new SoundEffect(buf, off, count, rate, ch, ls, ll); }
catch (ArgumentException ex) when (ex.ParamName == "loopStart" && ex.Message.Contains("greater than the total"))
{ int t = count/((int)ch*2); return new SoundEffect(buf, off, count, rate, ch, Math.Min(ls,t), ll); }

Prevention

When it happens

Trigger: Passing a loopStart larger than the number of available samples; computing loop points from a different sample-rate than the source (resample mismatch); forwarding loop markers from a longer source after trimming the buffer.

Common situations: Loop points derived from the original untrimmed audio applied to a trimmed clip; resampling the buffer without rescaling loop points; loop points read in bytes but passed as samples (or vice versa); stale loop metadata after editing the PCM.

Related errors


AI-assisted analysis of MonoGame/MonoGame@1d71bbd0ff (2026-08-13). Data as JSON: /api/errors/fa3cd71c6ae47b23. Report an issue: GitHub.