<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_sources_framewise(reference_sources, estimated_sources, window=30*44100, hop=15*44100, compute_permutation=False):
 """Framewise computation of bss_eval_sources 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 :func:`mir_eval.separation.bss_eval_sources` called on ``reference_sources`` and ``estimated_sources`` (with the ``compute_permutation`` parameter passed to :func:`mir_eval.separation.bss_eval_sources`) is returned. Examples -------- reference_sources, Parameters reference_sources : np.ndarray, shape=(nsrc, nsampl) matrix containing true sources (must have the same shape as ``estimated_sources``) estimated_sources : np.ndarray, shape=(nsrc, nsampl) matrix containing estimated sources (must have the same shape as ``reference_sources``) window : int, optional Window length for framewise evaluation (default value is 30s at a sample rate of 44.1kHz) hop : int, optional Hop size for framewise evaluation (default value is 15s at a sample rate of 44.1kHz) 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) 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 is of shape (nsrc, nsampl)
    if estimated_sources.ndim == 1:
        estimated_sources = estimated_sources[np.newaxis, :]
    if reference_sources.ndim == 1:
        reference_sources = reference_sources[np.newaxis, :]

    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 sources result
    if nwin < 2:
        result = bss_eval_sources(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))
    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], sir[:, k], sar[:, k], perm[:, k] = bss_eval_sources(
                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, sir, sar, perm