huggingface/transformers · error · ValueError

Complex-valued input waveforms are not currently supported

Error message

Complex-valued input waveforms are not currently supported

What it means

Thrown by `spectrogram` when the input waveform is complex-valued (np.iscomplexobj is true, including complex64/complex128). The implementation casts the waveform to float64 before windowing and FFT, and the downstream mel/log path assumes real inputs, so complex waveforms (e.g. from an inverse STFT or IQ data) are unsupported and rejected explicitly.

Source

Thrown at src/transformers/audio_utils.py:945

    window_length = len(window)

    if fft_length is None:
        fft_length = frame_length

    if frame_length > fft_length:
        raise ValueError(f"frame_length ({frame_length}) may not be larger than fft_length ({fft_length})")

    if window_length != frame_length:
        raise ValueError(f"Length of the window ({window_length}) must equal frame_length ({frame_length})")

    if hop_length <= 0:
        raise ValueError("hop_length must be greater than zero")

    if waveform.ndim != 1:
        raise ValueError(f"Input waveform must have only one dimension, shape is {waveform.shape}")

    if np.iscomplexobj(waveform):
        raise ValueError("Complex-valued input waveforms are not currently supported")

    if power is None and mel_filters is not None:
        raise ValueError(
            "You have provided `mel_filters` but `power` is `None`. Mel spectrogram computation is not yet supported for complex-valued spectrogram."
            "Specify `power` to fix this issue."
        )

    # center pad the waveform
    if center:
        padding = [(int(frame_length // 2), int(frame_length // 2))]
        waveform = np.pad(waveform, padding, mode=pad_mode)

    # promote to float64, since np.fft uses float64 internally
    waveform = waveform.astype(np.float64)
    window = window.astype(np.float64)

    # split waveform into frames of frame_length size
    num_frames = int(1 + np.floor((waveform.size - frame_length) / hop_length))

View on GitHub (pinned to a597f97485)

Solutions

  1. Take the real part before calling: spectrogram(waveform.real.astype(np.float64), ...)
  2. If magnitude is what you need, use np.abs(waveform) instead
  3. Check upstream processing that introduced a complex dtype and cast there

Example fix

// before
spec = spectrogram(complex_waveform, window, 400, 160)  # ValueError

// after
spec = spectrogram(complex_waveform.real.astype(np.float64), window, 400, 160)
Defensive patterns

Strategy: type-guard

Validate before calling

if np.iscomplexobj(waveform):
    waveform = waveform.real.astype(np.float64)
spec = spectrogram(waveform, window, frame_length, hop_length)

Type guard

def is_real_waveform(waveform) -> bool:
    import numpy as np
    return not np.iscomplexobj(waveform)

Try / catch

try:
    spec = spectrogram(waveform, window, frame_length, hop_length)
except ValueError as e:
    if "Complex-valued" in str(e):
        spec = spectrogram(np.asarray(waveform).real.astype(np.float64), window, frame_length, hop_length)
    else:
        raise

Prevention

When it happens

Trigger: Passing a complex array produced by np.fft.ifft/istft reconstruction, analytic-signal computations (hilbert transform), or RF/IQ data; also a real array stored with a complex dtype containing zero imaginary parts.

Common situations: Griffin-Lim style reconstruction pipelines feeding complex frames back into `spectrogram`; scipy.signal.hilbert output; data loaded with dtype=np.complex128 from MATLAB or HDF5 files.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/c61ec749b18cc05c. Report an issue: GitHub.