def window(x, win_len, win_stride, win_fn):
    """
    Apply a window function to an array with window size win_len, advancing at win_stride.

    :param x: Array
    :param win_len: Number of samples per window
    :param win_stride: Stride to advance current window
    :param win_fn: Callable window function. Takes the slice of the array as input
    :return: List of windowed values
    """
    n = x.shape[0]
    n_win = ((n - win_len)//win_stride)+1
    x_win = [win_fn(x[i*win_stride:(i*win_stride)+win_len]) for i in range(n_win)]
    return x_win