feat: add filename format

This commit is contained in:
Félix Voituret
2019-11-20 15:07:12 +01:00
parent bfb0225083
commit d771fbae34
4 changed files with 36 additions and 24 deletions

View File

@@ -28,6 +28,18 @@ OPT_OUTPUT = {
'help': 'Path of the output directory to write audio files in'
}
# -f opt specification (separate).
OPT_FORMAT = {
'dest': 'filename_format',
'default': '{filename}/{instrument}.{codec}',
'help': (
'Template string that will be formatted to generated'
'output filename. Such template should be Python formattable'
'string, and could use {filename}, {instrument}, and {codec}'
'variables.'
)
}
# -p opt specification (train, evaluate and separate).
OPT_PARAMS = {
'dest': 'configuration',
@@ -37,23 +49,6 @@ OPT_PARAMS = {
'help': 'JSON filename that contains params'
}
# -n opt specification (separate).
OPT_OUTPUT_NAMING = {
'dest': 'output_naming',
'default': 'filename',
'choices': ('directory', 'filename'),
'help': (
'Choice for naming the output base path: '
'"filename" (use the input filename, i.e '
'/path/to/audio/mix.wav will be separated to '
'<output_path>/mix/<instument1>.wav, '
'<output_path>/mix/<instument2>.wav...) or '
'"directory" (use the name of the input last level'
' directory, for instance /path/to/audio/mix.wav '
'will be separated to <output_path>/audio/<instument1>.wav'
', <output_path>/audio/<instument2>.wav)')
}
# -s opt specification (separate).
OPT_OFFSET = {
'dest': 'offset',
@@ -175,7 +170,7 @@ def _create_separate_parser(parser_factory):
_add_common_options(parser)
parser.add_argument('-i', '--inputs', **OPT_INPUT)
parser.add_argument('-o', '--output_path', **OPT_OUTPUT)
parser.add_argument('-n', '--output_naming', **OPT_OUTPUT_NAMING)
parser.add_argument('-f', '--filename_format', **OPT_FORMAT)
parser.add_argument('-d', '--duration', **OPT_DURATION)
parser.add_argument('-s', '--offset', **OPT_OFFSET)
parser.add_argument('-c', '--codec', **OPT_CODEC)

View File

@@ -44,7 +44,6 @@ __license__ = 'MIT License'
_SPLIT = 'test'
_MIXTURE = 'mixture.wav'
_NAMING = 'directory'
_AUDIO_DIRECTORY = 'audio'
_METRICS_DIRECTORY = 'metrics'
_INSTRUMENTS = ('vocals', 'drums', 'bass', 'other')
@@ -71,7 +70,6 @@ def _separate_evaluation_dataset(arguments, musdb_root_directory, params):
audio_filenames=mixtures,
audio_codec='wav',
output_path=join(audio_output_directory, _SPLIT),
output_naming=_NAMING,
max_duration=600.,
MWF=arguments.MWF,
verbose=arguments.verbose),

View File

@@ -27,7 +27,9 @@ def entrypoint(arguments, params):
"""
# TODO: check with output naming.
audio_adapter = get_audio_adapter(arguments.audio_adapter)
separator = Separator(arguments.configuration, arguments.MWF)
separator = Separator(
arguments.configuration,
arguments.MWF)
for filename in arguments.inputs:
separator.separate_to_file(
filename,
@@ -37,6 +39,7 @@ def entrypoint(arguments, params):
duration=arguments.duration,
codec=arguments.codec,
bitrate=arguments.bitrate,
filename_format=arguments.filename_format,
synchronous=False
)
separator.join()

View File

@@ -18,8 +18,9 @@ import json
from functools import partial
from multiprocessing import Pool
from pathlib import Path
from os.path import join
from os.path import basename, join
from . import SpleeterError
from .audio.adapter import get_default_audio_adapter
from .audio.convertor import to_stereo
from .model import model_fn
@@ -93,10 +94,13 @@ class Separator(object):
self, audio_descriptor, destination,
audio_adapter=get_default_audio_adapter(),
offset=0, duration=600., codec='wav', bitrate='128k',
synchronous=True):
filename_format='{filename}/{instrument}.{codec}', synchronous=True):
""" Performs source separation and export result to file using
given audio adapter.
Filename format should be a Python formattable string that could use
following parameters : {instrument}, {filename} and {codec}.
:param audio_descriptor: Describe song to separate, used by audio
adapter to retrieve and load audio data,
in case of file based audio adapter, such
@@ -107,6 +111,7 @@ class Separator(object):
:param duration: (Optional) Duration of loaded song.
:param codec: (Optional) Export codec.
:param bitrate: (Optional) Export bitrate.
:param filename_format: (Optional) Filename format.
:param synchronous: (Optional) True is should by synchronous.
"""
waveform, _ = audio_adapter.load(
@@ -115,9 +120,20 @@ class Separator(object):
duration=duration,
sample_rate=self._sample_rate)
sources = self.separate(waveform)
filename = basename(audio_descriptor)
generated = []
for instrument, data in sources.items():
path = join(destination, filename_format.format(
filename=filename,
instrument=instrument,
codec=codec))
if path in generated:
raise SpleeterError((
f'Separated source path conflict : {path},'
'please check your filename format'))
generated.append(path)
task = self._pool.apply_async(audio_adapter.save, (
join(destination, f'{instrument}.{codec}'),
path,
data,
self._sample_rate,
codec,