def _frequency_shift(X, fs, f_shift):
    """
    Shift the specified signal by the specified frequency.

    See https://gist.github.com/lebedov/4428122
    """
    # Pad the signal with zeros to prevent the FFT invoked by the transform
    # from slowing down the computation:
    n_channels, N_orig = X.shape[-2:]
    N_padded = 2 ** _nextpow2(N_orig)
    t = torch.arange(N_padded, device=X.device) / fs
    padded = pad(X, (0, N_padded - N_orig))
    analytical = _analytic_transform(padded)
    if isinstance(f_shift, (float, int, np.ndarray, list)):
        f_shift = torch.as_tensor(f_shift).float()
    f_shift_stack = f_shift.repeat(N_padded, n_channels, 1)
    reshaped_f_shift = f_shift_stack.permute(
        *torch.arange(f_shift_stack.ndim - 1, -1, -1)
    )
    shifted = analytical * torch.exp(2j * np.pi * reshaped_f_shift * t)
    return shifted[..., :N_orig].real.float()

    Shift the specified signal by the specified frequency.

    See https://gist.github.com/lebedov/4428122
    
braindecode/augmentation/functional.py