Files
spleeter/tests/test_separator.py

141 lines
4.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# coding: utf8
""" Unit testing for Separator class. """
2020-07-17 13:30:42 +02:00
__email__ = 'spleeter@deezer.com'
__author__ = 'Deezer Research'
__license__ = 'MIT License'
import itertools
2019-11-23 15:42:40 -08:00
from os.path import splitext, basename, exists, join
from tempfile import TemporaryDirectory
2019-11-08 20:03:16 -05:00
import pytest
import numpy as np
2019-11-08 20:03:16 -05:00
import tensorflow as tf
2019-11-20 15:18:53 +01:00
from spleeter import SpleeterError
2020-12-08 12:38:18 +01:00
from spleeter.audio.adapter import AudioAdapter
from spleeter.separator import Separator
TEST_AUDIO_DESCRIPTORS = ['audio_example.mp3', 'audio_example_mono.mp3']
BACKENDS = ["tensorflow", "librosa"]
MODELS = ['spleeter:2stems', 'spleeter:4stems', 'spleeter:5stems']
MODEL_TO_INST = {
'spleeter:2stems': ('vocals', 'accompaniment'),
'spleeter:4stems': ('vocals', 'drums', 'bass', 'other'),
'spleeter:5stems': ('vocals', 'drums', 'bass', 'piano', 'other'),
}
MODELS_AND_TEST_FILES = list(itertools.product(TEST_AUDIO_DESCRIPTORS, MODELS))
TEST_CONFIGURATIONS = list(itertools.product(
TEST_AUDIO_DESCRIPTORS, MODELS, BACKENDS))
print("RUNNING TESTS WITH TF VERSION {}".format(tf.__version__))
2020-06-18 18:01:03 +02:00
@pytest.mark.parametrize('test_file', TEST_AUDIO_DESCRIPTORS)
def test_separator_backends(test_file):
2020-12-08 12:38:18 +01:00
adapter = AudioAdapter.default()
2020-06-18 18:01:03 +02:00
waveform, _ = adapter.load(test_file)
separator_lib = Separator(
"spleeter:2stems", stft_backend="librosa", multiprocess=False)
separator_tf = Separator(
"spleeter:2stems", stft_backend="tensorflow", multiprocess=False)
2020-06-18 18:01:03 +02:00
# Test the stft and inverse stft provides exact reconstruction
stft_matrix = separator_lib._stft(waveform)
2020-06-18 18:12:43 +02:00
reconstructed = separator_lib._stft(
stft_matrix, inverse=True, length=waveform.shape[0])
assert np.allclose(reconstructed, waveform, atol=3e-2)
2020-06-18 18:01:03 +02:00
# compare both separation, it should be close
out_tf = separator_tf._separate_tensorflow(waveform, test_file)
out_lib = separator_lib._separate_librosa(waveform, test_file)
for instrument in out_lib.keys():
2020-06-19 00:48:09 +02:00
# test that both outputs are close everywhere
assert np.allclose(out_tf[instrument], out_lib[instrument], atol=1e-5)
2020-06-18 18:12:43 +02:00
2020-12-08 12:38:18 +01:00
@pytest.mark.parametrize(
'test_file, configuration, backend',
TEST_CONFIGURATIONS)
2020-03-26 14:27:19 +01:00
def test_separate(test_file, configuration, backend):
""" Test separation from raw data. """
instruments = MODEL_TO_INST[configuration]
2020-12-08 12:38:18 +01:00
adapter = AudioAdapter.default()
waveform, _ = adapter.load(test_file)
separator = Separator(
configuration, stft_backend=backend, multiprocess=False)
prediction = separator.separate(waveform, test_file)
assert len(prediction) == len(instruments)
for instrument in instruments:
assert instrument in prediction
for instrument in instruments:
track = prediction[instrument]
assert waveform.shape[:-1] == track.shape[:-1]
assert not np.allclose(waveform, track)
for compared in instruments:
if instrument != compared:
assert not np.allclose(track, prediction[compared])
2020-12-08 12:38:18 +01:00
@pytest.mark.parametrize(
'test_file, configuration, backend',
TEST_CONFIGURATIONS)
2020-03-26 14:27:19 +01:00
def test_separate_to_file(test_file, configuration, backend):
""" Test file based separation. """
instruments = MODEL_TO_INST[configuration]
separator = Separator(
configuration, stft_backend=backend, multiprocess=False)
name = splitext(basename(test_file))[0]
with TemporaryDirectory() as directory:
separator.separate_to_file(
test_file,
directory)
for instrument in instruments:
assert exists(join(
directory,
'{}/{}.wav'.format(name, instrument)))
2019-11-20 15:18:53 +01:00
2020-12-08 12:38:18 +01:00
@pytest.mark.parametrize(
'test_file, configuration, backend',
TEST_CONFIGURATIONS)
2020-03-26 14:27:19 +01:00
def test_filename_format(test_file, configuration, backend):
2019-11-20 15:18:53 +01:00
""" Test custom filename format. """
instruments = MODEL_TO_INST[configuration]
separator = Separator(
configuration, stft_backend=backend, multiprocess=False)
name = splitext(basename(test_file))[0]
with TemporaryDirectory() as directory:
separator.separate_to_file(
test_file,
directory,
filename_format='export/{filename}/{instrument}.{codec}')
for instrument in instruments:
assert exists(join(
2019-11-20 15:18:53 +01:00
directory,
'export/{}/{}.wav'.format(name, instrument)))
2019-11-20 15:18:53 +01:00
2020-12-08 12:38:18 +01:00
@pytest.mark.parametrize(
'test_file, configuration',
MODELS_AND_TEST_FILES)
def test_filename_conflict(test_file, configuration):
2019-11-20 15:18:53 +01:00
""" Test error handling with static pattern. """
separator = Separator(configuration, multiprocess=False)
with TemporaryDirectory() as directory:
with pytest.raises(SpleeterError):
separator.separate_to_file(
test_file,
directory,
filename_format='I wanna be your lover')