<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def bss_eval_images_framewise(reference_sources, estimated_sources, window=30*44100, hop=15*44100, compute_permutation=False):
 """Framewise computation of bss_eval_images Please be aware that this function does not compute permutations (by default) on the possible relations between ``reference_sources`` and ``estimated_sources`` due to the dangers of a changing permutation. Therefore (by default), it assumes that ``reference_sources[i]`` corresponds to ``estimated_sources[i]``. To enable computing permutations please set ``compute_permutation`` to be ``True`` and check that the returned ``perm`` is identical for all windows. NOTE: if ``reference_sources`` and ``estimated_sources`` would be evaluated using only a single window or are shorter than the window length, the result of ``bss_eval_images`` called on ``reference_sources`` and ``estimated_sources`` (with the ``compute_permutation`` parameter passed to ``bss_eval_images``) is returned Examples -------- reference_sources, window, Parameters reference_sources : np.ndarray, shape=(nsrc, nsampl, nchan) matrix containing true sources (must have the same shape as ``estimated_sources``) estimated_sources : np.ndarray, shape=(nsrc, nsampl, nchan) matrix containing estimated sources (must have the same shape as ``reference_sources``) window : int Window length for framewise evaluation hop : int Hop size for framewise evaluation compute_permutation : bool, optional compute permutation of estimate/source combinations for all windows (False by default) Returns ------- sdr : np.ndarray, shape=(nsrc, nframes) vector of Signal to Distortion Ratios (SDR) isr : np.ndarray, shape=(nsrc, nframes) vector of source Image to Spatial distortion Ratios (ISR) sir : np.ndarray, shape=(nsrc, nframes) vector of Source to Interference Ratios (SIR) sar : np.ndarray, shape=(nsrc, nframes) vector of Sources to Artifacts Ratios (SAR) perm : np.ndarray, shape=(nsrc, nframes) vector containing the best ordering of estimated sources in the mean SIR sense (estimated source number perm[j] corresponds to true source number j) Note: perm will be range(nsrc) for all windows if compute_permutation is False """


    # make sure the input has 3 dimensions
    # assuming input is in shape (nsampl) or (nsrc, nsampl)
    estimated_sources = np.atleast_3d(estimated_sources)
    reference_sources = np.atleast_3d(reference_sources)
    # we will ensure input doesn't have more than 3 dimensions in validate

    validate(reference_sources, estimated_sources)
    # If empty matrices were supplied, return empty lists (special case)
    if reference_sources.size == 0 or estimated_sources.size == 0:
        return np.array([]), np.array([]), np.array([]), np.array([])

    nsrc = reference_sources.shape[0]

    nwin = int(
        np.floor((reference_sources.shape[1] - window + hop) / hop)
    )
    # if fewer than 2 windows would be evaluated, return the images result
    if nwin < 2:
        result = bss_eval_images(reference_sources,
                                 estimated_sources,
                                 compute_permutation)
        return [np.expand_dims(score, -1) for score in result]

    # compute the criteria across all windows
    sdr = np.empty((nsrc, nwin))
    isr = np.empty((nsrc, nwin))
    sir = np.empty((nsrc, nwin))
    sar = np.empty((nsrc, nwin))
    perm = np.empty((nsrc, nwin))

    # k iterates across all the windows
    for k in range(nwin):
        win_slice = slice(k * hop, k * hop + window)
        ref_slice = reference_sources[:, win_slice, :]
        est_slice = estimated_sources[:, win_slice, :]
        # check for a silent frame
        if (not _any_source_silent(ref_slice) and
                not _any_source_silent(est_slice)):
            sdr[:, k], isr[:, k], sir[:, k], sar[:, k], perm[:, k] = \
                bss_eval_images(
                    ref_slice, est_slice, compute_permutation
                )
        else:
            # if we have a silent frame set results as np.nan
            sdr[:, k] = sir[:, k] = sar[:, k] = perm[:, k] = np.nan

    return sdr, isr, sir, sar, perm