from typing import Optional
import torch


def get_spectrogram(
    waveform,
    *,
    n_fft: int = 2048,
    hop_length: Optional[int] = None,
    win_length: Optional[int] = None,
    window: Optional[torch.Tensor] = None,
    center: bool = True,
    pad_mode: str = "reflect",
    power: Optional[float] = None,
):
    """Generate a spectrogram of the given Tensor

    Args:
        n_fft: The number of FFT bins.
        hop_length: Stride for sliding window. default: ``n_fft // 4``.
        win_length: The size of window frame and STFT filter. default: ``n_fft``.
        winwdow: Window function. default: Hann window
        center: Pad the input sequence if True. See ``torch.stft`` for the detail.
        pad_mode: Padding method used when center is True. Default: "reflect".
        power: If ``None``, raw spectrogram with complex values are returned,
            otherwise the norm of the spectrogram is returned.
    """
    hop_length = hop_length or n_fft // 4
    win_length = win_length or n_fft
    window = torch.hann_window(win_length, device=waveform.device) if window is None else window
    spec = torch.stft(
        waveform,
        n_fft=n_fft,
        hop_length=hop_length,
        win_length=win_length,
        center=center,
        window=window,
        pad_mode=pad_mode,
        return_complex=True,
    )
    if power is not None:
        spec = spec.abs() ** power
    return spec