craffel: Awesome, thank you.  I assume this is tried and true since it appeared in JAMS first.  The only pedantic comment I have is that `_open` is not a very descriptive function name, I would call it something like `open_file_or_str` (or `_open_file_or_str` if you insist on the pseudo-private function/not supplying a typical docstring).  Change that if you want, then feel free to squash and merge!
diff --git a/evaluators/separation_eval.py b/evaluators/separation_eval.py
index 2f6bde1..a9c8e0b 100755
--- a/evaluators/separation_eval.py
+++ b/evaluators/separation_eval.py
@@ -12,6 +12,7 @@ import argparse
 import sys
 import os
 import glob
+import os
 import numpy as np
 import eval_utilities
 
diff --git a/mir_eval/io.py b/mir_eval/io.py
index 9aaf449..4e95b34 100644
--- a/mir_eval/io.py
+++ b/mir_eval/io.py
@@ -2,6 +2,7 @@
 Functions for loading in annotations from files in different formats.
 """
 
+import contextlib
 import numpy as np
 import re
 import warnings
@@ -12,6 +13,25 @@ from . import util
 from . import key
 
 
+@contextlib.contextmanager
+def _open(file_or_str, **kwargs):
+    '''Either open a file handle, or use an existing file-like object.
+
+    This will behave as the `open` function if `file_or_str` is a string.
+
+    If `file_or_str` has the `read` attribute, it will return `file_or_str`.
+
+    Otherwise, an `IOError` is raised.
+    '''
+    if hasattr(file_or_str, 'read'):
+        yield file_or_str
+    elif isinstance(file_or_str, six.string_types):
+        with open(file_or_str, **kwargs) as file_desc:
+            yield file_desc
+    else:
+        raise IOError('Invalid file-or-str object: {}'.format(file_or_str))
+
+
 def load_delimited(filename, converters, delimiter=r'\s+'):
     r"""Utility function for loading in data from an annotation file where columns
     are delimited.  The number of columns is inferred from the length of
@@ -49,51 +69,33 @@ def load_delimited(filename, converters, delimiter=r'\s+'):
     # Create re object for splitting lines
     splitter = re.compile(delimiter)
 
-    # Keep track of whether we create our own file handle
-    own_fh = False
-    # If the filename input is a string, need to open it
-    if isinstance(filename, six.string_types):
-        # Remember that we need to close it later
-        own_fh = True
-        # Open the file for reading
-        input_file = open(filename, 'r')
-    # If the provided has a read attribute, we can use it as a file handle
-    elif hasattr(filename, 'read'):
-        input_file = filename
-    # Raise error otherwise
-    else:
-        raise ValueError('filename must be a string or file handle')
-
     # Note: we do io manually here for two reasons.
     #   1. The csv module has difficulties with unicode, which may lead
     #      to failures on certain annotation strings
     #
     #   2. numpy's text loader does not handle non-numeric data
     #
-    for row, line in enumerate(input_file, 1):
-        # Split each line using the supplied delimiter
-        data = splitter.split(line.strip(), n_columns - 1)
-
-        # Throw a helpful error if we got an unexpected # of columns
-        if n_columns != len(data):
-            raise ValueError('Expected {} columns, got {} at '
-                             '{}:{:d}:\n\t{}'.format(n_columns, len(data),
-                                                     filename, row, line))
-
-        for value, column, converter in zip(data, columns, converters):
-            # Try converting the value, throw a helpful error on failure
-            try:
-                converted_value = converter(value)
-            except:
-                raise ValueError("Couldn't convert value {} using {} "
-                                 "found at {}:{:d}:\n\t{}".format(
-                                     value, converter.__name__, filename, row,
-                                     line))
-            column.append(converted_value)
-
-    # Close the file handle if we opened it
-    if own_fh:
-        input_file.close()
+    with _open(filename, mode='r') as input_file:
+        for row, line in enumerate(input_file, 1):
+            # Split each line using the supplied delimiter
+            data = splitter.split(line.strip(), n_columns - 1)
+
+            # Throw a helpful error if we got an unexpected # of columns
+            if n_columns != len(data):
+                raise ValueError('Expected {} columns, got {} at '
+                                 '{}:{:d}:\n\t{}'.format(n_columns, len(data),
+                                                         filename, row, line))
+
+            for value, column, converter in zip(data, columns, converters):
+                # Try converting the value, throw a helpful error on failure
+                try:
+                    converted_value = converter(value)
+                except:
+                    raise ValueError("Couldn't convert value {} using {} "
+                                     "found at {}:{:d}:\n\t{}".format(
+                                         value, converter.__name__, filename,
+                                         row, line))
+                column.append(converted_value)
 
     # Sane output
     if n_columns == 1:
@@ -313,54 +315,36 @@ def load_patterns(filename):
 
     """
 
-    # Keep track of whether we create our own file handle
-    own_fh = False
-    # If the filename input is a string, need to open it
-    if isinstance(filename, six.string_types):
-        # Remember that we need to close it later
-        own_fh = True
-        # Open the file for reading
-        input_file = open(filename, 'r')
-    # If the provided has a read attribute, we can use it as a file handle
-    elif hasattr(filename, 'read'):
-        input_file = filename
-    # Raise error otherwise
-    else:
-        raise ValueError('filename must be a string or file handle')
-
     # List with all the patterns
     pattern_list = []
     # Current pattern, which will contain all occs
     pattern = []
     # Current occurrence, containing (onset, midi)
     occurrence = []
-    for line in input_file.readlines():
-        if "pattern" in line:
-            if occurrence != []:
-                pattern.append(occurrence)
-            if pattern != []:
-                pattern_list.append(pattern)
-            occurrence = []
-            pattern = []
-            continue
-        if "occurrence" in line:
-            if occurrence != []:
-                pattern.append(occurrence)
-            occurrence = []
-            continue
-        string_values = line.split(",")
-        onset_midi = (float(string_values[0]), float(string_values[1]))
-        occurrence.append(onset_midi)
-
-    # Add last occurrence and pattern to pattern_list
-    if occurrence != []:
-        pattern.append(occurrence)
-    if pattern != []:
-        pattern_list.append(pattern)
-
-    # If we opened an input file, we need to close it
-    if own_fh:
-        input_file.close()
+    with _open(filename, mode='r') as input_file:
+        for line in input_file.readlines():
+            if "pattern" in line:
+                if occurrence != []:
+                    pattern.append(occurrence)
+                if pattern != []:
+                    pattern_list.append(pattern)
+                occurrence = []
+                pattern = []
+                continue
+            if "occurrence" in line:
+                if occurrence != []:
+                    pattern.append(occurrence)
+                occurrence = []
+                continue
+            string_values = line.split(",")
+            onset_midi = (float(string_values[0]), float(string_values[1]))
+            occurrence.append(onset_midi)
+
+        # Add last occurrence and pattern to pattern_list
+        if occurrence != []:
+            pattern.append(occurrence)
+        if pattern != []:
+            pattern_list.append(pattern)
 
     return pattern_list
 
@@ -523,49 +507,32 @@ def load_ragged_time_series(filename, dtype=float, delimiter=r'\s+',
     # Create re object for splitting lines
     splitter = re.compile(delimiter)
 
-    # Keep track of whether we create our own file handle
-    own_fh = False
-    # If the filename input is a string, need to open it
-    if isinstance(filename, six.string_types):
-        # Remember that we need to close it later
-        own_fh = True
-        # Open the file for reading
-        input_file = open(filename, 'r')
-    # If the provided has a read attribute, we can use it as a file handle
-    elif hasattr(filename, 'read'):
-        input_file = filename
-    # Raise error otherwise
-    else:
-        raise ValueError('filename must be a string or file handle')
     if header:
         start_row = 1
     else:
         start_row = 0
-    for row, line in enumerate(input_file, start_row):
-        # Split each line using the supplied delimiter
-        data = splitter.split(line.strip())
-        try:
-            converted_time = float(data[0])
-        except (TypeError, ValueError) as exe:
-            six.raise_from(ValueError("Couldn't convert value {} using {} "
-                                      "found at {}:{:d}:\n\t{}".format(
-                                        data[0], float.__name__,
-                                        filename, row, line)), exe)
-        times.append(converted_time)
-
-        # cast values to a numpy array. time stamps with no values are cast
-        # to an empty array.
-        try:
-            converted_value = np.array(data[1:], dtype=dtype)
-        except (TypeError, ValueError) as exe:
-            six.raise_from(ValueError("Couldn't convert value {} using {} "
-                                      "found at {}:{:d}:\n\t{}".format(
-                                        data[1:], dtype.__name__,
-                                        filename, row, line)), exe)
-        values.append(converted_value)
-
-    # Close the file handle if we opened it
-    if own_fh:
-        input_file.close()
+    with _open(filename, mode='r') as input_file:
+        for row, line in enumerate(input_file, start_row):
+            # Split each line using the supplied delimiter
+            data = splitter.split(line.strip())
+            try:
+                converted_time = float(data[0])
+            except (TypeError, ValueError) as exe:
+                six.raise_from(ValueError("Couldn't convert value {} using {} "
+                                          "found at {}:{:d}:\n\t{}".format(
+                                            data[0], float.__name__,
+                                            filename, row, line)), exe)
+            times.append(converted_time)
+
+            # cast values to a numpy array. time stamps with no values are cast
+            # to an empty array.
+            try:
+                converted_value = np.array(data[1:], dtype=dtype)
+            except (TypeError, ValueError) as exe:
+                six.raise_from(ValueError("Couldn't convert value {} using {} "
+                                          "found at {}:{:d}:\n\t{}".format(
+                                            data[1:], dtype.__name__,
+                                            filename, row, line)), exe)
+            values.append(converted_value)
 
     return np.array(times), values
diff --git a/mir_eval/separation.py b/mir_eval/separation.py
index b52e1c2..43d1963 100644
--- a/mir_eval/separation.py
+++ b/mir_eval/separation.py
@@ -62,7 +62,7 @@ def validate(reference_sources, estimated_sources):
     if reference_sources.shape != estimated_sources.shape:
         raise ValueError('The shape of estimated sources and the true '
                          'sources should match.  reference_sources.shape '
-                         '= {}, estimated_sources.shape '
+                         '= {}, estimated_sources '
                          '= {}'.format(reference_sources.shape,
                                        estimated_sources.shape))
 
@@ -88,21 +88,26 @@ def validate(reference_sources, estimated_sources):
                          'source to be non-silent, having a silent estiamted '
                          'source will result in an underdetermined system.')
 
-    if (estimated_sources.shape[0] > MAX_SOURCES or
-            reference_sources.shape[0] > MAX_SOURCES):
-        raise ValueError('The supplied matrices should be of shape (nsrc,'
-                         ' nsampl) but reference_sources.shape[0] = {} and '
-                         'estimated_sources.shape[0] = {} which is greater '
-                         'than mir_eval.separation.MAX_SOURCES = {}.  To '
-                         'override this check, set '
-                         'mir_eval.separation.MAX_SOURCES to a '
-                         'larger value.'.format(reference_sources.shape[0],
-                                                estimated_sources.shape[0],
-                                                MAX_SOURCES))
-
-
-def bss_eval_sources(reference_sources, estimated_sources,
-                     compute_permutation=True):
+    if estimated_sources.shape[0] > MAX_SOURCES:
+        raise ValueError('The supplied matrices should be of shape (n_sources,'
+                         ' n_samples) but estimated_sources.shape[0] = {} '
+                         'which is greater than '
+                         'mir_eval.separation.MAX_SOURCES = {}.  To override '
+                         'this check, set mir_eval.separation.MAX_SOURCES to '
+                         'a larger value.'.format(estimated_sources.shape[0],
+                                                  MAX_SOURCES))
+
+    if reference_sources.shape[0] > MAX_SOURCES:
+        raise ValueError('The supplied matrices should be of shape (n_sources,'
+                         ' n_samples) but reference_sources.shape[0] = {} '
+                         'which is greater than '
+                         'mir_eval.separation.MAX_SOURCES = {}.  To override '
+                         'this check, set mir_eval.separation.MAX_SOURCES to '
+                         'a larger value.'.format(estimated_sources.shape[0],
+                                                  MAX_SOURCES))
+
+
+def bss_eval_sources(reference_sources, estimated_sources):
     """MATLAB translation of BSS_EVAL Toolbox
 
     Ordering and measurement of the separation quality for estimated source
@@ -124,13 +129,9 @@ def bss_eval_sources(reference_sources, estimated_sources,
     Parameters
     ----------
     reference_sources : np.ndarray, shape=(nsrc, nsampl)
-        matrix containing true sources (must have same shape as
-        estimated_sources)
+        matrix containing true sources
     estimated_sources : np.ndarray, shape=(nsrc, nsampl)
-        matrix containing estimated sources (must have same shape as
-        reference_sources)
-    compute_permutation : bool, optional
-        compute permutation of estimate/source combinations (True by default)
+        matrix containing estimated sources
 
     Returns
     -------
@@ -144,7 +145,6 @@ def bss_eval_sources(reference_sources, estimated_sources,
         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 [0, 1, ..., nsrc-1] if compute_permutation is False
 
     """
 
@@ -161,143 +161,28 @@ def bss_eval_sources(reference_sources, estimated_sources,
 
     nsrc = estimated_sources.shape[0]
 
-    # does user desire permutations?
-    if compute_permutation:
-        # compute criteria for all possible pair matches
-        sdr = np.empty((nsrc, nsrc))
-        sir = np.empty((nsrc, nsrc))
-        sar = np.empty((nsrc, nsrc))
-        for jest in range(nsrc):
-            for jtrue in range(nsrc):
-                s_true, e_spat, e_interf, e_artif = \
-                    _bss_decomp_mtifilt(reference_sources,
-                                        estimated_sources[jest],
-                                        jtrue, 512)
-                sdr[jest, jtrue], sir[jest, jtrue], sar[jest, jtrue] = \
-                    _bss_source_crit(s_true, e_spat, e_interf, e_artif)
-
-        # select the best ordering
-        perms = list(itertools.permutations(list(range(nsrc))))
-        mean_sir = np.empty(len(perms))
-        dum = np.arange(nsrc)
-        for (i, perm) in enumerate(perms):
-            mean_sir[i] = np.mean(sir[perm, dum])
-        popt = perms[np.argmax(mean_sir)]
-        idx = (popt, dum)
-        return (sdr[idx], sir[idx], sar[idx], np.asarray(popt))
-    else:
-        # compute criteria for only the simple correspondence
-        # (estimate 1 is estimate corresponding to reference source 1, etc.)
-        sdr = np.empty(nsrc)
-        sir = np.empty(nsrc)
-        sar = np.empty(nsrc)
-        for j in range(nsrc):
+    # compute criteria for all possible pair matches
+    sdr = np.empty((nsrc, nsrc))
+    sir = np.empty((nsrc, nsrc))
+    sar = np.empty((nsrc, nsrc))
+    for jest in range(nsrc):
+        for jtrue in range(nsrc):
             s_true, e_spat, e_interf, e_artif = \
                 _bss_decomp_mtifilt(reference_sources,
-                                    estimated_sources[j],
-                                    j, 512)
-            sdr[j], sir[j], sar[j] = \
+                                    estimated_sources[jest],
+                                    jtrue, 512)
+            sdr[jest, jtrue], sir[jest, jtrue], sar[jest, jtrue] = \
                 _bss_source_crit(s_true, e_spat, e_interf, e_artif)
 
-        # return the default permutation for compatibility
-        popt = np.arange(nsrc)
-        return (sdr, sir, sar, popt)
-
-
-def bss_eval_sources_framewise(reference_sources, estimated_sources,
-                               window=30*44100, hop=15*44100,
-                               compute_permutation=False):
-    """Framewise computation of bss_eval_sources
-
-    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_sources called on reference_sources and estimated_sources (with
-    the compute_permutation parameter passed to bss_eval_sources) is returned
-
-    Examples
-    --------
-    >>> # reference_sources[n] should be an ndarray of samples of the
-    >>> # n'th reference source
-    >>> # estimated_sources[n] should be the same for the n'th estimated
-    >>> # source
-    >>> (sdr, sir, sar,
-    ...  perm) = mir_eval.separation.bss_eval_sources_framewise(
-             reference_sources,
-    ...      estimated_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, optionals
-        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:
-        return bss_eval_sources(reference_sources,
-                                estimated_sources,
-                                compute_permutation)
-
-    # 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)
-        sdr[:, k], sir[:, k], sar[:, k], perm[:, k] = bss_eval_sources(
-            reference_sources[:, win_slice],
-            estimated_sources[:, win_slice],
-            compute_permutation
-        )
-
-    return sdr, sir, sar, perm
+    # select the best ordering
+    perms = list(itertools.permutations(range(nsrc)))
+    mean_sir = np.empty(len(perms))
+    dum = np.arange(nsrc)
+    for (i, perm) in enumerate(perms):
+        mean_sir[i] = np.mean(sir[perm, dum])
+    popt = perms[np.argmax(mean_sir)]
+    idx = (popt, dum)
+    return (sdr[idx], sir[idx], sar[idx], popt)
 
 
 def _bss_decomp_mtifilt(reference_sources, estimated_source, j, flen):
@@ -474,26 +359,13 @@ def evaluate(reference_sources, estimated_sources, **kwargs):
     # Compute all the metrics
     scores = collections.OrderedDict()
 
-    sdr, sir, sar, perm = util.filter_kwargs(
-        bss_eval_sources_framewise,
-        reference_sources,
-        estimated_sources,
-        **kwargs
-    )
-    scores['Sources Frames - Source to Distortion'] = sdr.tolist()
-    scores['Sources Frames - Source to Interference'] = sir.tolist()
-    scores['Sources Frames - Source to Artifact'] = sar.tolist()
-    scores['Sources Frames - Source permutation'] = perm
-
-    sdr, sir, sar, perm = util.filter_kwargs(
-        bss_eval_sources,
-        reference_sources,
-        estimated_sources,
-        **kwargs
-    )
-    scores['Sources - Source to Distortion'] = sdr.tolist()
-    scores['Sources - Source to Interference'] = sir.tolist()
-    scores['Sources - Source to Artifact'] = sar.tolist()
-    scores['Sources - Source permutation'] = perm
+    sdr, sir, sar, perm = util.filter_kwargs(bss_eval_sources,
+                                             reference_sources,
+                                             estimated_sources, **kwargs)
+
+    scores['Source to Distortion'] = sdr.tolist()
+    scores['Source to Interference'] = sir.tolist()
+    scores['Source to Artifact'] = sar.tolist()
+    scores['Source permutation'] = perm
 
     return scores

use context managers for open file handles
In ```io.py``` ```load_delimited``` and ```load_ragged_delimited```:

[This line](https://github.com/craffel/mir_eval/blob/master/mir_eval/io.py#L59) could leak file descriptors if there's an error anywhere below (before the call to close). Replace with ```with my_open(buf_or_str, 'r') as fdisc: ....```
diff --git a/tests/data/separation/output00.json b/tests/data/separation/output00.json
index d39c46e..e654605 100644
--- a/tests/data/separation/output00.json
+++ b/tests/data/separation/output00.json
@@ -1,123 +1,1 @@
-{"Sources":{"Source to Distortion": [8.074516496485167, 2.3238107088056337, 10.59298942747381], "Source to Interference": [10.511510621253269, 6.414675884826599, 16.689700107719524], "Source to Artifact": [12.1153186579709, 5.3626402019988815, 11.90938782345642], "Source permutation": [0, 1, 2]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              7.003379175140978,
-              6.653586221697303,
-              12.237134757057607,
-              11.833631549135184,
-              9.14533484841669,
-              9.769401126143185,
-              10.818726521923772
-          ],
-          [
-              5.259477271768409,
-              1.0870444743607524,
-              2.7595031859487555,
-              4.8213034562456265,
-              2.335285351280622,
-              1.287670185831756,
-              2.208336942144048
-          ],
-          [
-              11.021545369187734,
-              12.881535872489314,
-              16.164826936020013,
-              14.279785796366973,
-              7.8346197629189485,
-              9.130776047100174,
-              14.366434227665735
-          ]
-      ],
-      "Source to Interference": [
-          [
-              8.016968293220785,
-              7.4460177802319185,
-              14.1805514008335,
-              13.557483756968399,
-              10.957166114172953,
-              10.914280057498356,
-              11.380123870369651
-          ],
-          [
-              6.95226839367966,
-              2.265997677262244,
-              3.901721704192529,
-              6.001650769645548,
-              4.4166458085838025,
-              2.6699249332943262,
-              3.663576978586449
-          ],
-          [
-              12.806427187790558,
-              13.849668966610674,
-              17.160438398807386,
-              15.404242628795954,
-              11.517641634723681,
-              11.42593105936697,
-              15.980085734372054
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              14.4561481683209,
-              15.151016426672175,
-              16.82761826923016,
-              16.867269335693113,
-              14.151589455554511,
-              16.457842011642533,
-              20.28663151827989
-          ],
-          [
-              10.968298151061472,
-              9.349515922226328,
-              10.602070035628559,
-              12.028760168115767,
-              7.869632319403728,
-              8.80980474820171,
-              9.218038247020408
-          ],
-          [
-              15.967034050213103,
-              20.0505015871559,
-              23.132788599190015,
-              20.821666264926254,
-              10.558458821112227,
-              13.299652158016828,
-              19.556283795641203
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ],
-          [
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0
-          ]
-      ],
-      "win": 2000,
-      "hop": 1000
-  }
-}
+{"Source to Distortion": [8.074516496485167, 2.3238107088056337, 10.59298942747381], "Source to Interference": [10.511510621253269, 6.414675884826599, 16.689700107719524], "Source to Artifact": [12.1153186579709, 5.3626402019988815, 11.90938782345642], "Source permutation": [0, 1, 2]}
\ No newline at end of file
diff --git a/tests/data/separation/output01.json b/tests/data/separation/output01.json
index 37493e7..a4c9ca9 100644
--- a/tests/data/separation/output01.json
+++ b/tests/data/separation/output01.json
@@ -1,87 +1,1 @@
-{"Sources":{"Source to Distortion": [1.6357250261616694, 8.35730768374355], "Source to Interference": [2.869614536623785, 19.596668518613885], "Source to Artifact": [9.511469033244348, 8.744100747692844], "Source permutation": [0, 1]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              5.149669474914772,
-              3.1488100796540404,
-              1.6539826780575286,
-              2.8748397843157396,
-              2.6745263013094145,
-              2.5542948621892525,
-              0.41438689453916433
-          ],
-          [
-              8.140962974194387,
-              9.168101838553662,
-              9.20529893957309,
-              8.556308362721357,
-              18.666441030639284,
-              16.815137099504994,
-              10.585218780016422
-          ]
-      ],
-      "Source to Interference": [
-          [
-              7.904800707297028,
-              4.0570038445068395,
-              2.22137218148402,
-              3.61373944766269,
-              3.149070649891711,
-              3.1501808657513037,
-              1.8032413005929873
-          ],
-          [
-              15.402937023765805,
-              13.875470944863594,
-              16.175846921346125,
-              14.675806974690932,
-              22.988234803441774,
-              20.54239992419536,
-              15.217408852352577
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              9.08313970096718,
-              11.83030341933345,
-              12.813737665972784,
-              12.499974926704931,
-              14.239859841858657,
-              13.189827403144259,
-              8.243205007241274
-          ],
-          [
-              9.167978020038662,
-              11.135668579824056,
-              10.282717737529854,
-              9.918738648986986,
-              20.69256955203501,
-              19.24839646750305,
-              12.546051958209466
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ]
-      ],
-      "win": 2000,
-      "hop": 1000
-  }
-}
+{"Source to Distortion": [1.6357250261616694, 8.35730768374355], "Source to Interference": [2.869614536623785, 19.596668518613885], "Source to Artifact": [9.511469033244348, 8.744100747692844], "Source permutation": [0, 1]}
\ No newline at end of file
diff --git a/tests/data/separation/output02.json b/tests/data/separation/output02.json
index d01a8dc..8e8a2fc 100644
--- a/tests/data/separation/output02.json
+++ b/tests/data/separation/output02.json
@@ -1,147 +1,1 @@
-{"Sources":{"Source to Distortion": [10.402442396290404, 11.615179897174547, 8.213820164496585], "Source to Interference": [13.688266627376017, 15.194137115835119, 10.084397177627933], "Source to Artifact": [13.335559184910213, 14.252119758894345, 13.179999062945116], "Source permutation": [2, 0, 1]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              -3.3683586251724176,
-              -0.4258131004730029,
-              5.737954384287263,
-              13.496549686251882,
-              11.133937944745513,
-              11.744969792989144,
-              8.783665593807779,
-              0.10586742903207497,
-              -3.392353303563334
-          ],
-          [
-              4.114269729136045,
-              3.6731744276418876,
-              4.706638787684438,
-              4.608061014987869,
-              2.501270404894758,
-              3.7095657831177444,
-              1.3676712483128473,
-              2.956226287243273,
-              5.2440986381143295
-          ],
-          [
-              16.978354236989194,
-              17.741897091793426,
-              14.577608333324958,
-              12.739000711173317,
-              2.2621375012667193,
-              1.6333311475483014,
-              1.2550203261532684,
-              1.6631735614600018,
-              -1.1497584991656096
-          ]
-      ],
-      "Source to Interference": [
-          [
-              -3.361311383159377,
-              -0.41805884675415195,
-              5.750722251019655,
-              13.873877733477302,
-              11.422785774638367,
-              11.873782070113656,
-              9.384159481188938,
-              0.14357942689956213,
-              -3.3915520815178564
-          ],
-          [
-              4.161081265635496,
-              3.6783663733941028,
-              4.713902939683422,
-              4.6264150711234775,
-              2.5491113448998397,
-              3.8484107075454532,
-              1.4468443722471211,
-              2.981135208402449,
-              5.28057243985441
-          ],
-          [
-              17.03250354285748,
-              17.84514324717382,
-              14.647512686549733,
-              12.895973966261625,
-              2.298647095986888,
-              1.689623136425914,
-              1.3021291134452864,
-              1.7020151192991826,
-              -1.1403297080800905
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              29.54115930781021,
-              30.284864375869876,
-              32.085430463346434,
-              24.4689397612799,
-              23.350922624102438,
-              27.360805465204532,
-              18.14687428019694,
-              23.676861051371574,
-              38.977423833872535
-          ],
-          [
-              25.22211095634335,
-              34.44975192272571,
-              33.740050065681054,
-              29.643799086772052,
-              24.025161181124336,
-              20.230457095212245,
-              21.146116053327013,
-              27.153624667590456,
-              27.147893385072148
-          ],
-          [
-              36.1324813954066,
-              34.10327241414194,
-              32.691764718319675,
-              27.454243214145258,
-              25.045465569457566,
-              22.781967782806024,
-              23.333232859196787,
-              24.409599008507577,
-              29.106022947569375
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ],
-          [
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0
-          ]
-      ],
-      "win": 1200,
-      "hop": 800
-  }
-}
+{"Source to Distortion": [10.402442396290404, 11.615179897174547, 8.213820164496585], "Source to Interference": [13.688266627376017, 15.194137115835119, 10.084397177627933], "Source to Artifact": [13.335559184910213, 14.252119758894345, 13.179999062945116], "Source permutation": [2, 0, 1]}
\ No newline at end of file
diff --git a/tests/data/separation/output03.json b/tests/data/separation/output03.json
index b00ad69..6b0bf8c 100644
--- a/tests/data/separation/output03.json
+++ b/tests/data/separation/output03.json
@@ -1,159 +1,1 @@
-{"Sources":{"Source to Distortion": [7.227899883748847, -4.463066010999018, 1.2821108384488062, 12.080451610955636], "Source to Interference": [9.099154153186786, -0.6395992455508694, 4.933804919293891, 18.322102002191336], "Source to Artifact": [12.29049343816683, 1.2044404039163803, 4.942972769893187, 13.322032058619765], "Source permutation": [0, 1, 2, 3]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              6.334331918339612,
-              5.669633027022265,
-              9.514464186545139,
-              10.71164392578315,
-              9.297428445800008,
-              8.771713568590616,
-              10.403935522673704
-          ],
-          [
-              -8.513135611073594,
-              -8.064798819888791,
-              -8.251509304933107,
-              -7.850194258047162,
-              -12.458178865642155,
-              -4.6179776078665995,
-              -2.644615618710851
-          ],
-          [
-              3.9540843403165615,
-              -3.0720269164432774,
-              -12.10520682558961,
-              11.990534899929347,
-              4.810319300991273,
-              -0.47816637025080955,
-              -5.219895828058016
-          ],
-          [
-              12.060237250059458,
-              13.935491387386808,
-              12.426917555156134,
-              13.636511936766013,
-              15.425723921844167,
-              14.704418986550998,
-              14.483143404404505
-          ]
-      ],
-      "Source to Interference": [
-          [
-              6.517511430418773,
-              5.811584235204686,
-              9.584118567039901,
-              12.0535044371654,
-              9.757649467411412,
-              8.950021021537328,
-              10.46565243486915
-          ],
-          [
-              -7.063426513233857,
-              -6.919588115314706,
-              -7.0510675813016475,
-              -6.414204157657953,
-              -11.905715000061399,
-              -4.197909156233509,
-              -2.4813855006475842
-          ],
-          [
-              4.141014910687602,
-              -3.0662821416570836,
-              -10.876089318848761,
-              13.1396178007717,
-              5.717548749645411,
-              0.2376957317518501,
-              -4.954793379034611
-          ],
-          [
-              12.922416671673943,
-              14.906538658441146,
-              13.278126105039757,
-              14.832517357389065,
-              15.848218198376067,
-              15.42135925531434,
-              15.706812594153735
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              21.048836346016834,
-              21.608583262197634,
-              27.951027125793622,
-              16.72864879954062,
-              19.710211838041786,
-              23.24729692355166,
-              29.2821572605892
-          ],
-          [
-              4.79964549937246,
-              6.007384762964339,
-              5.752039211870982,
-              4.961749710617883,
-              8.947021685277118,
-              11.332878323275246,
-              16.112437890835338
-          ],
-          [
-              19.123969289544746,
-              30.52457226127728,
-              5.194061850315177,
-              18.53256678532119,
-              13.088137800677963,
-              10.597476679719989,
-              13.214694804585587
-          ],
-          [
-              19.72218257905594,
-              21.055515792722215,
-              20.12256294009786,
-              19.96175152988701,
-              25.866418972581066,
-              23.003854645101143,
-              20.69699250545369
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ],
-          [
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0
-          ],
-          [
-              3.0,
-              3.0,
-              3.0,
-              3.0,
-              3.0,
-              3.0,
-              3.0
-          ]
-      ],
-      "win": 2000,
-      "hop": 1000
-  }
-}
+{"Source to Distortion": [7.227899883748847, -4.463066010999018, 1.2821108384488062, 12.080451610955636], "Source to Interference": [9.099154153186786, -0.6395992455508694, 4.933804919293891, 18.322102002191336], "Source to Artifact": [12.29049343816683, 1.2044404039163803, 4.942972769893187, 13.322032058619765], "Source permutation": [0, 1, 2, 3]}
\ No newline at end of file
diff --git a/tests/data/separation/output04.json b/tests/data/separation/output04.json
index e5cfb2e..cc77c23 100644
--- a/tests/data/separation/output04.json
+++ b/tests/data/separation/output04.json
@@ -1,171 +1,1 @@
-{"Sources":{"Source to Distortion": [-2.7660575557183185, 7.422147051733475, 9.263472486410315], "Source to Interference": [-1.8344520578819126, 12.049225023575314, 12.996500884384705], "Source to Artifact": [8.4006174794115, 9.51977911283253, 11.866882959029592], "Source permutation": [0, 1, 2]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              -8.860597417628203,
-              -24.10090894772071,
-              7.04876196909683,
-              4.057992735632969,
-              5.6161336151044905,
-              4.116028133023433,
-              7.137264114222281,
-              6.636553746354682,
-              12.671565105493684,
-              1.9583919993494792,
-              11.069899473115337
-          ],
-          [
-              9.926523346344258,
-              9.987905896373597,
-              7.564523016796219,
-              7.945669353150655,
-              10.1539600741427,
-              12.082487584834462,
-              12.2727939834995,
-              15.649761269420077,
-              13.083103548628648,
-              8.845073839026895,
-              9.92613048474913
-          ],
-          [
-              6.406157295298719,
-              11.062787420473574,
-              11.28985547419708,
-              12.308004177812876,
-              15.624813247889296,
-              17.142738926831534,
-              16.14316407043284,
-              12.956929782952958,
-              13.371332285847053,
-              10.264216790139692,
-              7.2072926453065165
-          ]
-      ],
-      "Source to Interference": [
-          [
-              -8.829303699736036,
-              -23.480971584617542,
-              7.059521904992345,
-              4.133735396275103,
-              5.838892506631115,
-              4.493799198471704,
-              7.9676787726683465,
-              6.8886566706296515,
-              13.015310310122434,
-              2.008554702262554,
-              11.094100774894205
-          ],
-          [
-              10.756786152273978,
-              10.371661990150942,
-              7.689352089948397,
-              8.247678199534551,
-              10.274758588402717,
-              12.403974605169143,
-              12.525958494815628,
-              15.947799336792347,
-              13.191164677085126,
-              8.99559445141815,
-              9.95304241751627
-          ],
-          [
-              6.953158659593384,
-              11.777345856069614,
-              11.87402860507859,
-              12.696043304602817,
-              15.846527057082639,
-              17.56302335695188,
-              17.372991193012698,
-              13.29305658664679,
-              13.426441220326566,
-              10.445126096419328,
-              7.232275788138401
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              21.942007741639706,
-              8.160150539271873,
-              33.89414025641505,
-              23.097987925406912,
-              19.632584539349377,
-              16.229520360723676,
-              15.37410685616707,
-              19.93287690106841,
-              24.069435281296478,
-              23.478601553224365,
-              33.946550973306174
-          ],
-          [
-              17.871055928174687,
-              21.09708482129742,
-              23.72422772257833,
-              20.279304037871118,
-              26.16110133402111,
-              23.7912164804018,
-              24.978800046122483,
-              27.542082756455642,
-              29.381619254014986,
-              24.037462376768236,
-              32.436190488427485
-          ],
-          [
-              16.472670800178136,
-              19.53189663687499,
-              20.564398946746863,
-              23.21705178956808,
-              28.766682632782498,
-              27.569054390609846,
-              22.301781261939087,
-              24.435558731439023,
-              32.55743586438283,
-              24.532885695704984,
-              30.373463076829687
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ],
-          [
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0
-          ]
-      ],
-      "win": 1200,
-      "hop": 650
-  }
-}
+{"Source to Distortion": [-2.7660575557183185, 7.422147051733475, 9.263472486410315], "Source to Interference": [-1.8344520578819126, 12.049225023575314, 12.996500884384705], "Source to Artifact": [8.4006174794115, 9.51977911283253, 11.866882959029592], "Source permutation": [0, 1, 2]}
\ No newline at end of file
diff --git a/tests/data/separation/output05.json b/tests/data/separation/output05.json
index eae6c2a..052d99a 100644
--- a/tests/data/separation/output05.json
+++ b/tests/data/separation/output05.json
@@ -1,123 +1,1 @@
-{"Sources":{"Source to Distortion": [15.989628144732425, 2.92585277037319, 10.390551440343547], "Source to Interference": [19.310156466664875, 5.042019427791443, 13.118530603652601], "Source to Artifact": [18.76100033748606, 8.24665350507413, 13.909608717243112], "Source permutation": [0, 1, 2]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              11.440536675067579,
-              17.328375913229216,
-              19.246247909082772,
-              19.15107868850007,
-              23.354771324431663,
-              23.2109174572615,
-              18.48919767884879
-          ],
-          [
-              3.200499507597892,
-              2.4697810981951642,
-              -3.834624099549914,
-              7.9313336264114165,
-              11.17292272933065,
-              -2.3006149433583194,
-              3.30279924326439
-          ],
-          [
-              13.12435813742717,
-              12.993318101201163,
-              5.859129776687109,
-              3.147786090782722,
-              -8.938596094423708,
-              14.239433380167759,
-              13.548815748136056
-          ]
-      ],
-      "Source to Interference": [
-          [
-              12.765247980489129,
-              17.486351217195573,
-              20.940410354949456,
-              20.026300194268384,
-              23.96794059785485,
-              25.230972473267187,
-              19.4020464311528
-          ],
-          [
-              3.75929678707931,
-              2.5558209152386198,
-              -3.2068474186796414,
-              8.55800311839287,
-              11.583077988395162,
-              -0.8357643907276845,
-              4.022718590112774
-          ],
-          [
-              13.999773465737002,
-              13.100223365279911,
-              6.902335250633238,
-              3.6665574675697377,
-              -8.731410599686226,
-              16.160022781780587,
-              14.258939589164363
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              17.466580806940193,
-              31.875865139417332,
-              24.188953472076662,
-              26.580960148056274,
-              32.17717152062089,
-              27.519079324974953,
-              25.761041518334498
-          ],
-          [
-              13.907516503437991,
-              21.46132816292758,
-              9.778502652957963,
-              17.2150438419717,
-              21.916364560727757,
-              6.579408542410596,
-              12.911739918453357
-          ],
-          [
-              20.679969040167208,
-              29.342166172612735,
-              13.370936872608572,
-              14.185660075488357,
-              13.656085168710208,
-              18.811784798091374,
-              21.9234509312971
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ],
-          [
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0
-          ]
-      ],
-      "win": 1600,
-      "hop": 1000
-  }
-}
+{"Source to Distortion": [15.989628144732425, 2.92585277037319, 10.390551440343547], "Source to Interference": [19.310156466664875, 5.042019427791443, 13.118530603652601], "Source to Artifact": [18.76100033748606, 8.24665350507413, 13.909608717243112], "Source permutation": [0, 1, 2]}
\ No newline at end of file
diff --git a/tests/data/separation/output06.json b/tests/data/separation/output06.json
index 8ac626b..9a0b800 100644
--- a/tests/data/separation/output06.json
+++ b/tests/data/separation/output06.json
@@ -1,199 +1,1 @@
-{"Sources":{"Source to Distortion": [13.78338204929278, 7.250163706520247], "Source to Interference": [16.204235407537556, 11.658569116183275], "Source to Artifact": [17.578736233831776, 9.491272183553724], "Source permutation": [0, 1]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              15.770861118084023,
-              10.266491728120815,
-              10.616425286260341,
-              10.402612463899505,
-              11.341693557777493,
-              17.977919644661608,
-              20.899809133103066,
-              20.684958728768006,
-              19.81641283106371,
-              15.157352480870586,
-              10.918400740940763,
-              12.794284048570162,
-              16.35341492981471,
-              19.142915379163863,
-              20.356182145650912,
-              19.68432366646042,
-              21.236160511571388,
-              21.498314308873177,
-              21.411517037797086,
-              15.689348142010811,
-              14.973688010752495
-          ],
-          [
-              10.234148337188175,
-              13.494352305226032,
-              13.261602906653147,
-              10.270234658668533,
-              8.926526735416843,
-              0.7285082470816284,
-              -1.445026004087403,
-              -0.3491037224516751,
-              -3.5361158771361154,
-              -4.871801382705655,
-              7.024768329666901,
-              9.435832460228072,
-              10.397105843295142,
-              1.8924601837813337,
-              -5.498679269679663,
-              -5.707465929170647,
-              -3.016408381580664,
-              0.9723598073007549,
-              -8.41491576524177,
-              9.75331347871246,
-              11.817349843774206
-          ]
-      ],
-      "Source to Interference": [
-          [
-              16.983165650601777,
-              11.066620858416801,
-              11.119816633976619,
-              11.248434408988468,
-              12.128696219803377,
-              19.13596762600305,
-              22.814960093766867,
-              22.86219678218422,
-              24.300128659029884,
-              23.182897730381974,
-              13.635867354293921,
-              13.74969822569331,
-              17.406888721891345,
-              20.68435836131071,
-              23.949389057429066,
-              23.57485883876062,
-              25.266629368983104,
-              22.704300333535944,
-              28.52307118467533,
-              17.130537763017905,
-              16.54037884417558
-          ],
-          [
-              12.761302701100185,
-              16.725423398871758,
-              15.505315585789596,
-              12.82284038108909,
-              11.569695660595814,
-              3.5198548561320138,
-              0.3365083764479299,
-              1.1806141185060266,
-              -0.9230897029461725,
-              -2.5762143138651847,
-              9.106024425218664,
-              11.226290236310998,
-              12.707662470216736,
-              3.5750031043137893,
-              -4.155211115828419,
-              -3.156892835441405,
-              0.8942659663030604,
-              2.39831853815833,
-              -5.992697570650662,
-              12.918316411158452,
-              15.40943603382166
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              21.99077800512083,
-              18.333746530033405,
-              20.547726687968467,
-              18.23786659984539,
-              19.405526331340425,
-              24.337330971503963,
-              25.400719693560223,
-              24.749387110512938,
-              21.74464595790909,
-              15.92278043653074,
-              14.426776962742522,
-              20.018559739001624,
-              23.099310341295208,
-              24.426373457428518,
-              22.870091804407828,
-              21.982106951716652,
-              23.433829394223462,
-              27.675020583617965,
-              22.35677824908201,
-              21.2639494831869,
-              20.25679399600904
-          ],
-          [
-              14.012229445929318,
-              16.385904318487157,
-              17.32399989862944,
-              14.013214533201253,
-              12.630371248910073,
-              5.567003858183554,
-              6.130538618398581,
-              7.385045791985439,
-              3.4078156073272456,
-              3.4811516488943166,
-              11.721747364516004,
-              14.464250937066641,
-              14.468754307872985,
-              8.405501929920156,
-              5.818303254181928,
-              2.6865395454609016,
-              1.8346519846706522,
-              8.477254710078228,
-              2.2431515909826487,
-              12.83054983253958,
-              14.437888709785698
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ]
-      ],
-      "win": 1400,
-      "hop": 700
-  }
-}
+{"Source to Distortion": [13.78338204929278, 7.250163706520247], "Source to Interference": [16.204235407537556, 11.658569116183275], "Source to Artifact": [17.578736233831776, 9.491272183553724], "Source permutation": [0, 1]}
\ No newline at end of file
diff --git a/tests/data/separation/output07.json b/tests/data/separation/output07.json
index da11327..c51b627 100644
--- a/tests/data/separation/output07.json
+++ b/tests/data/separation/output07.json
@@ -1,111 +1,1 @@
-{"Sources":{"Source to Distortion": [31.65426748072045, 30.509880888730656], "Source to Interference": [41.534168992046155, 37.73978731132595], "Source to Artifact": [32.12569904260708, 31.421680139098243], "Source permutation": [0, 1]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              34.80070239467067,
-              26.233964206351303,
-              35.52152001095222,
-              37.491913036007325,
-              34.44692576864385,
-              30.644871381679888,
-              29.53300714715028,
-              34.512840543932896,
-              33.31009727280657,
-              34.36391651078961
-          ],
-          [
-              26.130863585770637,
-              30.05752044658083,
-              36.18594879129595,
-              34.537511946262526,
-              35.130012109898374,
-              34.565317116657496,
-              34.63959606031987,
-              39.223908390181435,
-              31.063860723680932,
-              29.51190339241336
-          ]
-      ],
-      "Source to Interference": [
-          [
-              37.056235077666095,
-              29.04314269432124,
-              38.35924656300556,
-              39.94487087965189,
-              39.60727483981047,
-              36.322356323417075,
-              32.809992822610944,
-              37.373695325278916,
-              34.47844491232085,
-              37.066900409631224
-          ],
-          [
-              27.845610482037387,
-              34.54337418412345,
-              38.54337124412963,
-              35.20532609957952,
-              37.13331392820961,
-              38.31297112963255,
-              37.57026768557177,
-              41.02765296670008,
-              32.00348725573812,
-              33.393514333858064
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              38.725975834383235,
-              29.46056377159172,
-              38.71216923960858,
-              41.142198992353336,
-              36.026084877124205,
-              32.015943551221454,
-              32.29432790970611,
-              37.678707082629735,
-              39.584853266235726,
-              37.70579937932512
-          ],
-          [
-              31.003032704566586,
-              31.969991606105687,
-              39.96554793807786,
-              42.99973779383219,
-              39.454447341682354,
-              36.946110823960595,
-              37.73177148964179,
-              43.91104655903011,
-              38.176234225694444,
-              31.798816376280424
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ]
-      ],
-      "win": 1000,
-      "hop": 750
-  }
-}
+{"Source to Distortion": [31.65426748072045, 30.509880888730656], "Source to Interference": [41.534168992046155, 37.73978731132595], "Source to Artifact": [32.12569904260708, 31.421680139098243], "Source permutation": [0, 1]}
\ No newline at end of file
diff --git a/tests/data/separation/output08.json b/tests/data/separation/output08.json
index 063e082..c9a89ae 100644
--- a/tests/data/separation/output08.json
+++ b/tests/data/separation/output08.json
@@ -1,147 +1,1 @@
-{"Sources":{"Source to Distortion": [12.658621714161605, 19.353779851187323, 16.490559932201563], "Source to Interference": [16.647925846010466, 24.298418678982788, 19.534653901953313], "Source to Artifact": [14.963487364475371, 21.04662056008085, 19.51540110868908], "Source permutation": [0, 1, 2]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              16.192865169727398,
-              13.028356898467596,
-              14.893095079349159,
-              13.206184448743779,
-              11.278322194600843,
-              11.149686478954122,
-              13.481957165397043,
-              10.418114868053863,
-              13.680843762014243
-          ],
-          [
-              19.16928643751411,
-              22.33260979627913,
-              20.88501614523839,
-              23.17546022589123,
-              23.569714393137026,
-              25.417457455374443,
-              22.707319453703875,
-              19.755994742864043,
-              16.47491192002275
-          ],
-          [
-              20.149927282268454,
-              20.267695322224103,
-              18.496572664869277,
-              16.18703221162405,
-              19.024302145824258,
-              14.190596411379516,
-              16.88279138847638,
-              19.921302938784912,
-              21.2584705532771
-          ]
-      ],
-      "Source to Interference": [
-          [
-              16.288295958752727,
-              13.118430955873595,
-              14.930286338199622,
-              13.264972384336719,
-              11.365058006587974,
-              11.200327720655764,
-              13.56547042390435,
-              10.467023286202862,
-              13.865385487811974
-          ],
-          [
-              19.51303533008609,
-              22.42708511693099,
-              21.00741091217366,
-              23.30046863949658,
-              23.734218387200183,
-              25.514157962740356,
-              22.775316455057478,
-              19.874311587607504,
-              16.583023468025996
-          ],
-          [
-              20.31754190446126,
-              20.345014205362993,
-              18.562319621923248,
-              16.269550631841422,
-              19.241210680291484,
-              14.207980885183762,
-              16.920950511451522,
-              19.97320737927088,
-              21.36217552372802
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              32.92235489483052,
-              30.111966640647857,
-              35.72247463881086,
-              32.12060555291033,
-              28.623592109542486,
-              30.825308450625837,
-              30.870941019057348,
-              30.30003790763802,
-              27.664459179077237
-          ],
-          [
-              30.403770694506083,
-              39.02918697290886,
-              36.480585812213675,
-              38.66653008995361,
-              37.88613537966818,
-              42.00145811413804,
-              40.81708087956089,
-              35.50687209189353,
-              32.66233068093355
-          ],
-          [
-              34.40837037041166,
-              37.84121399852104,
-              36.788544740106815,
-              33.54189410422633,
-              32.19879673409346,
-              38.33727533707226,
-              37.55107654103121,
-              39.216506650434496,
-              37.56168867998662
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ],
-          [
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0,
-              1.0
-          ],
-          [
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0,
-              2.0
-          ]
-      ],
-      "win": 1100,
-      "hop": 850
-  }
-}
+{"Source to Distortion": [12.658621714161605, 19.353779851187323, 16.490559932201563], "Source to Interference": [16.647925846010466, 24.298418678982788, 19.534653901953313], "Source to Artifact": [14.963487364475371, 21.04662056008085, 19.51540110868908], "Source permutation": [0, 1, 2]}
\ No newline at end of file
diff --git a/tests/data/separation/output09.json b/tests/data/separation/output09.json
index 999a027..09caf52 100644
--- a/tests/data/separation/output09.json
+++ b/tests/data/separation/output09.json
@@ -1,87 +1,1 @@
-{"Sources":{"Source to Distortion": [6.533836035573265], "Source to Interference": [Infinity], "Source to Artifact": [6.533836035573265], "Source permutation": [0]},
-"Framewise":
-  {
-      "Source to Distortion": [
-          [
-              12.119934389970112,
-              9.839136413593899,
-              10.104607545126424,
-              14.83174440067323,
-              10.402492739711457,
-              9.962792788321892,
-              7.591397020480595,
-              6.953836345225294,
-              19.31013868039556,
-              14.789903496557441,
-              11.069772397512526,
-              10.153206550236124,
-              9.717806202451953,
-              7.908023275472441,
-              8.189812854799017,
-              18.577301858851083
-          ]
-      ],
-      "Source to Interference": [
-          [
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity,
-              Infinity
-          ]
-      ],
-      "Source to Artifact": [
-          [
-              12.119934389970112,
-              9.839136413593899,
-              10.104607545126424,
-              14.83174440067323,
-              10.402492739711457,
-              9.962792788321892,
-              7.591397020480595,
-              6.953836345225294,
-              19.31013868039556,
-              14.789903496557441,
-              11.069772397512526,
-              10.153206550236124,
-              9.717806202451953,
-              7.908023275472441,
-              8.189812854799017,
-              18.577301858851083
-          ]
-      ],
-      "Source permutation": [
-          [
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0,
-              0.0
-          ]
-      ],
-      "win": 500,
-      "hop": 500
-  }
-}
+{"Source to Distortion": [6.533836035573265], "Source to Interference": [Infinity], "Source to Artifact": [6.533836035573265], "Source permutation": [0]}
\ No newline at end of file
diff --git a/tests/test_input_output.py b/tests/test_input_output.py
index 5d51261..87074d4 100644
--- a/tests/test_input_output.py
+++ b/tests/test_input_output.py
@@ -11,7 +11,7 @@ import tempfile
 def test_load_delimited():
     # Test for ValueError when a non-string or file handle is passed
     nose.tools.assert_raises(
-        ValueError, mir_eval.io.load_delimited, None, [int])
+        IOError, mir_eval.io.load_delimited, None, [int])
     # Test for a value error when the wrong number of columns is passed
     with tempfile.TemporaryFile('r+') as f:
         f.write('10 20')
@@ -119,7 +119,7 @@ def test_load_valued_intervals():
 def test_load_ragged_time_series():
     # Test for ValueError when a non-string or file handle is passed
     nose.tools.assert_raises(
-        ValueError, mir_eval.io.load_ragged_time_series, None, float,
+        IOError, mir_eval.io.load_ragged_time_series, None, float,
         header=False)
     # Test for a value error on conversion failure
     with tempfile.TemporaryFile('r+') as f:
diff --git a/tests/test_separation.py b/tests/test_separation.py
index 7db01c7..9c51205 100644
--- a/tests/test_separation.py
+++ b/tests/test_separation.py
@@ -34,15 +34,11 @@ def __load_and_stack_wavs(directory):
     return np.vstack(stacked_audio_data)
 
 
-def __unit_test_empty_input(metric):
-    if metric == mir_eval.separation.bss_eval_sources:
-        args = [np.array([]), np.array([])]
-    elif metric == mir_eval.separation.bss_eval_sources_framewise:
-        args = [np.array([]), np.array([]), 40, 20]
+def __unit_test_separation_function(metric):
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter('always')
         # First, test for a warning on empty audio data
-        metric(*args)
+        metric(np.array([]), np.array([]))
         assert len(w) == 2
         assert issubclass(w[-1].category, UserWarning)
         assert str(w[-1].message) == ("estimated_sources is empty, "
@@ -50,77 +46,26 @@ def __unit_test_empty_input(metric):
                                       "sdr, sir, sar, and perm will all be "
                                       "empty np.ndarrays")
         # And that the metric returns empty arrays
-        assert np.allclose(metric(*args), np.array([]))
+        assert np.allclose(metric(np.array([]), np.array([])), np.array([]))
 
-
-def __unit_test_silent_input(metric):
     # Test for error when there is a silent reference/estimated source
     ref_sources = np.vstack((np.zeros(100),
                              np.random.random_sample((2, 100))))
     est_sources = np.vstack((np.zeros(100),
                              np.random.random_sample((2, 100))))
-    if metric == mir_eval.separation.bss_eval_sources:
-        nose.tools.assert_raises(ValueError, metric, ref_sources[:2],
-                                 est_sources[1:])
-        nose.tools.assert_raises(ValueError, metric, ref_sources[1:],
-                                 est_sources[:2])
-    elif metric == mir_eval.separation.bss_eval_sources_framewise:
-        nose.tools.assert_raises(ValueError, metric, ref_sources[:2],
-                                 est_sources[1:], 40, 20)
-        nose.tools.assert_raises(ValueError, metric, ref_sources[1:],
-                                 est_sources[:2], 40, 20)
-
-
-def __unit_test_incompatible_shapes(metric):
+    nose.tools.assert_raises(ValueError, metric, ref_sources[:2],
+                             est_sources[1:])
+    nose.tools.assert_raises(ValueError, metric, ref_sources[1:],
+                             est_sources[:2])
+
     # Test for error when shape is different
-    sources_4 = np.random.random_sample((4, 100))
-    sources_3 = np.random.random_sample((3, 100))
-    if metric == mir_eval.separation.bss_eval_sources:
-        args1 = [sources_3, sources_4]
-        args2 = [sources_4, sources_3]
-    elif metric == mir_eval.separation.bss_eval_sources_framewise:
-        args1 = [sources_3, sources_4, 40, 20]
-        args2 = [sources_4, sources_3, 40, 20]
-    nose.tools.assert_raises(ValueError, metric, *args1)
-    nose.tools.assert_raises(ValueError, metric, *args2)
-
-
-def __unit_test_too_many_sources(metric):
-    # Test for error when too many sources or references are provided
-    many_sources = np.random.random_sample((mir_eval.separation.MAX_SOURCES*2,
-                                            400))
-    if metric == mir_eval.separation.bss_eval_sources:
-        nose.tools.assert_raises(ValueError, metric, many_sources,
-                                 many_sources)
-    elif metric == mir_eval.separation.bss_eval_sources_framewise:
-        nose.tools.assert_raises(ValueError, metric, many_sources,
-                                 many_sources, 40, 20)
-
-
-def __unit_test_default_permutation(metric):
-    # Test for default permutation matrix when not computing permutation
     ref_sources = np.random.random_sample((4, 100))
-    est_sources = np.random.random_sample((4, 100))
-    results = metric(ref_sources, est_sources, compute_permutation=False)
-    assert np.array_equal(results[-1], np.asarray([0, 1, 2, 3]))
+    est_sources = np.random.random_sample((3, 100))
+    nose.tools.assert_raises(ValueError, metric, ref_sources, est_sources)
 
-
-def __unit_test_framewise_small_window(metric):
-    # Test for invalid win/hop parameter detection
-    ref_sources = np.random.random_sample((4, 100))
-    est_sources = np.random.random_sample((4, 100))
-    # Rest with window larger than source lengths
-    assert np.allclose(metric(ref_sources, est_sources, window=120, hop=20),
-                       mir_eval.separation.bss_eval_sources(ref_sources,
-                                                            est_sources,
-                                                            False),
-                       atol=A_TOL)
-    # Test with hop larger than source length
-    assert np.allclose(metric(ref_sources, est_sources, window=20, hop=120),
-                       mir_eval.separation.bss_eval_sources(ref_sources,
-                                                            est_sources,
-                                                            False),
-                       atol=A_TOL)
+    # Test for error when too many sources are provided
+    sources = np.random.random_sample((mir_eval.separation.MAX_SOURCES*2, 400))
+    nose.tools.assert_raises(ValueError, metric, sources, sources)
 
 
 def __check_score(sco_f, metric, score, expected_score):
@@ -136,39 +81,19 @@ def test_separation_functions():
     assert len(ref_files) == len(est_files) == len(sco_files) > 0
 
     # Unit tests
-    for metric in [mir_eval.separation.bss_eval_sources,
-                   mir_eval.separation.bss_eval_sources_framewise]:
-        yield (__unit_test_empty_input, metric)
-        yield (__unit_test_silent_input, metric)
-        yield (__unit_test_incompatible_shapes, metric)
-        yield (__unit_test_too_many_sources, metric)
     for metric in [mir_eval.separation.bss_eval_sources]:
-        yield (__unit_test_default_permutation, metric)
-    for metric in [mir_eval.separation.bss_eval_sources_framewise]:
-        yield (__unit_test_framewise_small_window, metric)
+        yield (__unit_test_separation_function, metric)
     # Regression tests
     for ref_f, est_f, sco_f in zip(ref_files, est_files, sco_files):
         with open(sco_f, 'r') as f:
-            expected_results = json.load(f)
-            expected_scores = expected_results['Sources']
-            expected_frames = expected_results['Framewise']
+            expected_scores = json.load(f)
         # Load in example source separation data
         ref_sources = __load_and_stack_wavs(ref_f)
         est_sources = __load_and_stack_wavs(est_f)
         # Compute scores
-        scores = mir_eval.separation.evaluate(
-            ref_sources, est_sources,
-            window=expected_frames['win'], hop=expected_frames['hop']
-        )
+        scores = mir_eval.separation.evaluate(ref_sources, est_sources)
         # Compare them
         for metric in scores:
-            if 'Sources - ' in metric:
-                test_data_name = metric.replace('Sources - ', '')
-                # This is a simple hack to make nosetest's messages more useful
-                yield (__check_score, sco_f, metric, scores[metric],
-                       expected_scores[test_data_name])
-            elif 'Sources Frames - ' in metric:
-                test_data_name = metric.replace('Sources Frames - ', '')
-                # This is a simple hack to make nosetest's messages more useful
-                yield (__check_score, sco_f, metric, scores[metric],
-                       expected_frames[test_data_name])
+            # This is a simple hack to make nosetest's messages more useful
+            yield (__check_score, sco_f, metric, scores[metric],
+                   expected_scores[metric])

pip install -e .[display]
parse_log_pytest
requirements.txt
nose nose-cov pytest
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
contourpy==1.3.0
cov-core==1.15.0
coverage==7.8.0
cycler==0.12.1
exceptiongroup==1.2.2
fonttools==4.56.0
future==1.0.0
importlib_resources==6.5.2
iniconfig==2.1.0
kiwisolver==1.4.7
matplotlib==3.9.4
-e git+https://github.com/craffel/mir_eval.git@4425853f27d9039bd48c985fe4ef0c29b53a9385#egg=mir_eval
nose==1.3.7
nose-cov==1.6
numpy==2.0.2
packaging==24.2
pillow==11.1.0
pluggy==1.5.0
pyparsing==3.2.3
pytest==8.3.5
python-dateutil==2.9.0.post0
scipy==1.13.1
six==1.17.0
tomli==2.2.1
zipp==3.21.0

name: mir_eval
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - contourpy==1.3.0
      - cov-core==1.15.0
      - coverage==7.8.0
      - cycler==0.12.1
      - exceptiongroup==1.2.2
      - fonttools==4.56.0
      - future==1.0.0
      - importlib-resources==6.5.2
      - iniconfig==2.1.0
      - kiwisolver==1.4.7
      - matplotlib==3.9.4
      - nose==1.3.7
      - nose-cov==1.6
      - numpy==2.0.2
      - packaging==24.2
      - pillow==11.1.0
      - pluggy==1.5.0
      - pyparsing==3.2.3
      - pytest==8.3.5
      - python-dateutil==2.9.0.post0
      - scipy==1.13.1
      - six==1.17.0
      - tomli==2.2.1
      - zipp==3.21.0
prefix: /opt/conda/envs/mir_eval

tests/test_input_output.py::test_load_delimited tests/test_input_output.py::test_load_ragged_time_series
tests/test_input_output.py::test_load_events tests/test_input_output.py::test_load_labeled_events tests/test_input_output.py::test_load_intervals tests/test_input_output.py::test_load_labeled_intervals tests/test_input_output.py::test_load_valued_intervals
mir_eval/io.py evaluators/separation_eval.py mir_eval/separation.py
mir_eval/io.py evaluators/separation_eval.py mir_eval/separation.py