microsoft/VibeVoice · error · ValueError

Unexpected audio shape: {audio.shape}

Error message

Unexpected audio shape: {audio.shape}

What it means

_to_mono (the 2D branch of audio normalization) accepts exactly three 2D layouts: (2, time) and (time, 2) stereo (averaged to mono) and squeezable (1, time)/(time, 1). A 2D array that is neither stereo nor single-channel along either axis — e.g. (3, 5000) or (256, 100) — is ambiguous (is time on rows or columns? is it 3-channel?) and is rejected rather than guessed at.

Source

Thrown at vibevoice/processor/vibevoice_tokenizer_processor.py:89

            
        Returns:
            np.ndarray: Mono audio array
        """
        if len(audio.shape) == 1:
            return audio
        elif len(audio.shape) == 2:
            if audio.shape[0] == 2:  # (2, time)
                return np.mean(audio, axis=0)
            elif audio.shape[1] == 2:  # (time, 2)
                return np.mean(audio, axis=1)
            else:
                # If one dimension is 1, squeeze it
                if audio.shape[0] == 1:
                    return audio.squeeze(0)
                elif audio.shape[1] == 1:
                    return audio.squeeze(1)
                else:
                    raise ValueError(f"Unexpected audio shape: {audio.shape}")
        else:
            raise ValueError(f"Audio should be 1D or 2D, got shape: {audio.shape}")
    
    def _process_single_audio(self, audio: Union[np.ndarray, List[float]]) -> np.ndarray:
        """
        Process a single audio array.
        
        Args:
            audio: Single audio input
            
        Returns:
            np.ndarray: Processed audio
        """
        # Convert to numpy array
        if not isinstance(audio, np.ndarray):
            audio = np.array(audio, dtype=np.float32)
        else:
            audio = audio.astype(np.float32)

View on GitHub (pinned to 94da20d98b)

Solutions

  1. Pass raw 1D mono waveforms: reduce stereo yourself with np.mean(audio, axis=0/1) or slice one channel.
  2. If you meant a batch, pass a Python list of 1D arrays instead of a stacked 2D array.
  3. Keep the batch dim out of the array handed to _to_mono; batching is handled one level up in __call__.

Example fix

# before
audio = np.stack([wav_a, wav_b, wav_c])  # (3, time) -> ValueError
enc = processor(audio=audio)

# after
enc = processor(audio=[wav_a, wav_b, wav_c])  # list -> batched input
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
def to_mono_1d(a: np.ndarray) -> np.ndarray:
    a = np.asarray(a)
    if a.ndim == 1:
        return a
    if a.ndim == 2 and 1 in a.shape:
        return a.reshape(-1)
    if a.ndim == 2 and 2 in a.shape:
        return a.mean(axis=0 if a.shape[0] == 2 else 1)
    raise ValueError(f'cannot interpret shape {a.shape} as mono audio')

Type guard

def is_interpretable_audio(a) -> bool:
    import numpy as np
    a = np.asarray(a)
    return a.ndim == 1 or (a.ndim == 2 and (1 in a.shape or 2 in a.shape))

Try / catch

try:
    enc = processor(audio=audio)
except ValueError as e:
    if 'Unexpected audio shape' in str(e):
        enc = processor(audio=np.asarray(audio).mean(axis=-1))  # explicit mono mixdown
    else:
        raise

Prevention

When it happens

Trigger: Passing a 2D audio array whose second dimension is neither 2 nor 1 and first dimension neither 2 nor 1 — commonly mel-spectrogram-shaped (n_mels, frames) input, or multi-channel (3+) audio arrays.

Common situations: Feeding precomputed features (log-mel frames) where raw waveforms were expected; microphones arrays with >2 channels; accidentally stacking a batch into one array, producing (batch, time) with batch > 2.

Related errors


AI-assisted analysis of microsoft/VibeVoice@94da20d98b (2026-08-15). Data as JSON: /api/errors/32428d8796205928. Report an issue: GitHub.