def process_track(file_struct, boundaries_id, labels_id, config, annotator_id=0, plot=False): """Prepares the parameters, runs the algorithms, and saves results. Parameters ---------- file_struct: Object FileStruct containing the paths of the input files (audio file, features file, reference file, output estimation file). boundaries_id: str Identifier of the boundaries algorithm to use ("gt" for ground truth). labels_id: str Identifier of the labels algorithm to use (None for not labeling). config: dict Dictionary containing the custom parameters of the algorithms to use. annotator_id: int Annotator identificator in the ground truth. Returns ------- est_times: np.array List of estimated times for the segment boundaries. est_labels: np.array List of all the labels associated segments. """ # Only analize files with annotated beats if config["annot_beats"]: jam = jams2.load(file_struct.ref_file) if len(jam.beats) > 0 and len(jam.beats[0].data) > 0: pass else: logging.warning("No beat information in file %s" % file_struct.ref_file) return logging.info("Segmenting %s" % file_struct.audio_file) # Compute features if needed if not os.path.isfile(file_struct.features_file): featextract.compute_all_features(file_struct) # Get estimations est_times, est_labels = run_algorithms(file_struct.audio_file, boundaries_id, labels_id, config, annotator_id=annotator_id) # Save logging.info("Writing results in: %s" % file_struct.est_file) io.save_estimations(file_struct.est_file, est_times, est_labels, boundaries_id, labels_id, **config) if plot: audio_name = splitext(basename(file_struct.audio_file))[0] plot_name = join(dirname(dirname(file_struct.audio_file)), 'plots', audio_name+'_'+'mfcc'+'_'+boundaries_id+'.pdf') dataset_name = basename(dirname(dirname(file_struct.audio_file))) plotting.plot_one_track(plot_name, file_struct, est_times, est_labels, boundaries_id, labels_id, dataset_name) return est_times, est_labels
def process( in_path, annot_beats=False, feature="hpcp", ds_name="*", framesync=False, boundaries_id=msaf.DEFAULT_BOUND_ID, labels_id=msaf.DEFAULT_LABEL_ID, hier=False, sonify_bounds=False, plot=False, n_jobs=4, annotator_id=0, config=None, out_bounds="out_bounds.wav", out_sr=22050, ): """Main process to segment a file or a collection of files. Parameters ---------- in_path: str Input path. If a directory, MSAF will function in collection mode. If audio file, MSAF will be in single file mode. annot_beats: bool Whether to use annotated beats or not. Only available in collection mode. feature: str String representing the feature to be used (e.g. hpcp, mfcc, tonnetz) ds_name: str Prefix of the dataset to be used (e.g. SALAMI, Isophonics) framesync: str Whether to use framesync features or not (default: False -> beatsync) boundaries_id: str Identifier of the boundaries algorithm (use "gt" for groundtruth) labels_id: str Identifier of the labels algorithm (use None to not compute labels) hier : bool Whether to compute a hierarchical or flat segmentation. sonify_bounds: bool Whether to write an output audio file with the annotated boundaries or not (only available in Single File Mode). plot: bool Whether to plot the boundaries and labels against the ground truth. n_jobs: int Number of processes to run in parallel. Only available in collection mode. annotator_id: int Annotator identificator in the ground truth. config: dict Dictionary containing custom configuration parameters for the algorithms. If None, the default parameters are used. out_bounds: str Path to the output for the sonified boundaries (only in single file mode, when sonify_bounds is True. out_sr : int Sampling rate for the sonified bounds. Returns ------- results : list List containing tuples of (est_times, est_labels) of estimated boundary times and estimated labels. If labels_id is None, est_labels will be a list of -1. """ # Seed random to reproduce results np.random.seed(123) # Make sure that the features used are correct assert feature in msaf.AVAILABLE_FEATS # Set up configuration based on algorithms parameters if config is None: config = io.get_configuration(feature, annot_beats, framesync, boundaries_id, labels_id) config["features"] = None # Save multi-segment (hierarchical) configuration config["hier"] = hier if os.path.isfile(in_path): # Single file mode # Get (if they exitst) or compute features file_struct = msaf.io.FileStruct(in_path) if not os.path.exists(file_struct.features_file): # Compute and save features all_features = featextract.compute_features_for_audio_file(in_path) msaf.utils.ensure_dir(os.path.dirname(file_struct.features_file)) msaf.featextract.save_features(file_struct.features_file, all_features) # Get correct features config["features"] = msaf.io.get_features(in_path, annot_beats=annot_beats, framesync=framesync) # And run the algorithms est_times, est_labels = run_algorithms(in_path, boundaries_id, labels_id, config, annotator_id=annotator_id) if sonify_bounds: logging.info("Sonifying boundaries in %s..." % out_bounds) audio_hq, sr = librosa.load(in_path, sr=out_sr) utils.sonify_clicks(audio_hq, est_times, out_bounds, out_sr) if plot: plotting.plot_one_track(file_struct, est_times, est_labels, boundaries_id, labels_id, ds_name) # Save estimations msaf.utils.ensure_dir(os.path.dirname(file_struct.est_file)) io.save_estimations(file_struct, est_times, est_labels, boundaries_id, labels_id, **config) return est_times, est_labels else: # Collection mode file_structs = io.get_dataset_files(in_path, ds_name) # Call in parallel return Parallel(n_jobs=n_jobs)( delayed(process_track)(file_struct, boundaries_id, labels_id, config, annotator_id=annotator_id) for file_struct in file_structs[:] )
def process(in_path, annot_beats=False, feature="mfcc", ds_name="*", framesync=False, boundaries_id="gt", labels_id=None, hier=False, sonify_bounds=False, plot=False, n_jobs=4, annotator_id=0, config=None, out_bounds="out_bounds.wav"): """Main process to segment a file or a collection of files. Parameters ---------- in_path: str Input path. If a directory, MSAF will function in collection mode. If audio file, MSAF will be in single file mode. annot_beats: bool Whether to use annotated beats or not. Only available in collection mode. feature: str String representing the feature to be used (e.g. hpcp, mfcc, tonnetz) ds_name: str Prefix of the dataset to be used (e.g. SALAMI, Isophonics) framesync: str Whether to use framesync features or not (default: False -> beatsync) boundaries_id: str Identifier of the boundaries algorithm (use "gt" for groundtruth) labels_id: str Identifier of the labels algorithm (use None to not compute labels) hier : bool Whether to compute a hierarchical or flat segmentation. sonify_bounds: bool Whether to write an output audio file with the annotated boundaries or not (only available in Single File Mode). plot: bool Whether to plot the boundaries and labels against the ground truth. n_jobs: int Number of processes to run in parallel. Only available in collection mode. annotator_id: int Annotator identificator in the ground truth. config: dict Dictionary containing custom configuration parameters for the algorithms. If None, the default parameters are used. out_bounds: str Path to the output for the sonified boundaries (only in single file mode, when sonify_bounds is True. Returns ------- results : list List containing tuples of (est_times, est_labels) of estimated boundary times and estimated labels. If labels_id is None, est_labels will be a list of -1. """ # Seed random to reproduce results np.random.seed(123) # Set up configuration based on algorithms parameters if config is None: config = io.get_configuration(feature, annot_beats, framesync, boundaries_id, labels_id) config["features"] = None config["hier"] = hier if os.path.isfile(in_path): # Single file mode # Get (if they exitst) or compute features # TODO:Modularize! file_struct = msaf.io.FileStruct(in_path) if os.path.exists(file_struct.features_file): feat_prefix = "" if not framesync: feat_prefix = "bs_" features = {} '''Mi: added the Gammatone featureset''' features["%shpcp" % feat_prefix], features["%smfcc" % feat_prefix], \ features["%stonnetz" % feat_prefix], features["%scqt" % feat_prefix], \ features["%sgmt" % feat_prefix], features["beats"], dur, \ features["anal"] = msaf.io.get_features(in_path, annot_beats=annot_beats, framesync=framesync, pre_features=None) else: # Compute and save features features = featextract.compute_features_for_audio_file(in_path) msaf.utils.ensure_dir(os.path.dirname(file_struct.features_file)) msaf.featextract.save_features(file_struct.features_file, features) config["features"] = features config["hier"] = hier # And run the algorithms est_times, est_labels = run_algorithms(in_path, boundaries_id, labels_id, config, annotator_id=annotator_id) if sonify_bounds: logging.info("Sonifying boundaries in %s..." % out_bounds) fs = 44100 audio_hq, sr = librosa.load(in_path, sr=fs) utils.sonify_clicks(audio_hq, est_times, out_bounds, fs) if plot: plotting.plot_one_track(save_plot_path, file_struct, est_times, est_labels, boundaries_id, labels_id, ds_name) # Save estimations msaf.utils.ensure_dir(os.path.dirname(file_struct.est_file)) config["features"] = None io.save_estimations(file_struct.est_file, est_times, est_labels, boundaries_id, labels_id, **config) return est_times, est_labels else: # Collection mode file_structs = io.get_dataset_files(in_path, ds_name) # Call in parallel return Parallel(n_jobs=n_jobs)(delayed(process_track)( file_struct, boundaries_id, labels_id, config, annotator_id=annotator_id, plot=plot) for file_struct in file_structs[:])
def process(in_path, annot_beats=False, feature="hpcp", ds_name="*", framesync=False, boundaries_id=msaf.DEFAULT_BOUND_ID, labels_id=msaf.DEFAULT_LABEL_ID, hier=False, sonify_bounds=False, plot=False, n_jobs=4, annotator_id=0, config=None, out_bounds="out_bounds.wav", out_sr=22050): """Main process to segment a file or a collection of files. Parameters ---------- in_path: str Input path. If a directory, MSAF will function in collection mode. If audio file, MSAF will be in single file mode. annot_beats: bool Whether to use annotated beats or not. Only available in collection mode. feature: str String representing the feature to be used (e.g. hpcp, mfcc, tonnetz) ds_name: str Prefix of the dataset to be used (e.g. SALAMI, Isophonics) framesync: str Whether to use framesync features or not (default: False -> beatsync) boundaries_id: str Identifier of the boundaries algorithm (use "gt" for groundtruth) labels_id: str Identifier of the labels algorithm (use None to not compute labels) hier : bool Whether to compute a hierarchical or flat segmentation. sonify_bounds: bool Whether to write an output audio file with the annotated boundaries or not (only available in Single File Mode). plot: bool Whether to plot the boundaries and labels against the ground truth. n_jobs: int Number of processes to run in parallel. Only available in collection mode. annotator_id: int Annotator identificator in the ground truth. config: dict Dictionary containing custom configuration parameters for the algorithms. If None, the default parameters are used. out_bounds: str Path to the output for the sonified boundaries (only in single file mode, when sonify_bounds is True. out_sr : int Sampling rate for the sonified bounds. Returns ------- results : list List containing tuples of (est_times, est_labels) of estimated boundary times and estimated labels. If labels_id is None, est_labels will be a list of -1. """ # Seed random to reproduce results np.random.seed(123) # Make sure that the features used are correct assert feature in msaf.AVAILABLE_FEATS # Set up configuration based on algorithms parameters if config is None: config = io.get_configuration(feature, annot_beats, framesync, boundaries_id, labels_id) config["features"] = None # Save multi-segment (hierarchical) configuration config["hier"] = hier if not os.path.exists(in_path): raise RuntimeError("File or directory does not exists, %s" % in_path) if os.path.isfile(in_path): # Single file mode # Get (if they exitst) or compute features file_struct = msaf.io.FileStruct(in_path) if not os.path.exists(file_struct.features_file): # Compute and save features all_features = featextract.compute_features_for_audio_file(in_path) msaf.utils.ensure_dir(os.path.dirname(file_struct.features_file)) msaf.featextract.save_features(file_struct.features_file, all_features) # Get correct features config["features"] = msaf.io.get_features( in_path, annot_beats=annot_beats, framesync=framesync) # And run the algorithms est_times, est_labels = run_algorithms(in_path, boundaries_id, labels_id, config, annotator_id=annotator_id) if sonify_bounds: logging.info("Sonifying boundaries in %s..." % out_bounds) audio_hq, sr = librosa.load(in_path, sr=out_sr) utils.sonify_clicks(audio_hq, est_times, out_bounds, out_sr) if plot: plotting.plot_one_track(file_struct, est_times, est_labels, boundaries_id, labels_id, ds_name) # Save estimations msaf.utils.ensure_dir(os.path.dirname(file_struct.est_file)) io.save_estimations(file_struct, est_times, est_labels, boundaries_id, labels_id, **config) return est_times, est_labels else: # Collection mode file_structs = io.get_dataset_files(in_path, ds_name) # Call in parallel return Parallel(n_jobs=n_jobs)(delayed(process_track)( file_struct, boundaries_id, labels_id, config, annotator_id=annotator_id) for file_struct in file_structs[:])
def process(in_path, annot_beats=False, feature="mfcc", ds_name="*", framesync=False, boundaries_id="gt", labels_id=None, out_audio=False, plot=False, n_jobs=4, config=None): """Main process to segment a file or a collection of files. Parameters ---------- in_path: str Input path. If a directory, MSAF will function in collection mode. If audio file, MSAF will be in single file mode. annot_beats: bool Whether to use annotated beats or not. Only available in collection mode. feature: str String representing the feature to be used (e.g. hpcp, mfcc, tonnetz) ds_name: str Prefix of the dataset to be used (e.g. SALAMI, Isophonics) framesync: str Whether to use framesync features or not (default: False -> beatsync) boundaries_id: str Identifier of the boundaries algorithm (use "gt" for groundtruth) labels_id: str Identifier of the labels algorithm (use None to not compute labels) out_audio: bool Whether to write an output audio file with the annotated boundaries or not (only available in Single File Mode). plot: bool Whether to plot the boundaries and labels against the ground truth. n_jobs: int Number of processes to run in parallel. Only available in collection mode. config: dict Dictionary containing custom configuration parameters for the algorithms. If None, the default parameters are used. Returns ------- results : list List containing tuples of (est_times, est_labels) of estimated boundary times and estimated labels. If labels_id is None, est_labels will be a list of -1. """ # Seed random to reproduce results np.random.seed(123) # Set up configuration based on algorithms parameters if config is None: config = io.get_configuration(feature, annot_beats, framesync, boundaries_id, labels_id, algorithms) if os.path.isfile(in_path): # Single file mode audio, features = featextract.compute_features_for_audio_file(in_path) config["features"] = features # And run the algorithms est_times, est_labels = run_algorithms(in_path, boundaries_id, labels_id, config) if out_audio: # TODO: Set a nicer output file name? #out_file = in_path[:-4] + msaf.out_boundaries_ext out_file = "out_boundaries.wav" logging.info("Sonifying boundaries in %s..." % out_file) fs = 44100 audio_hq = featextract.read_audio(in_path, fs) utils.write_audio_boundaries( audio_hq, np.delete(est_times, [1, len(est_times) - 2]), out_file, fs) if plot: plotting.plot_one_track(in_path, est_times, est_labels, boundaries_id, labels_id) return est_times, est_labels else: # Collection mode file_structs = io.get_dataset_files(in_path, ds_name) # Call in parallel return Parallel(n_jobs=n_jobs)(delayed(process_track)( file_struct, boundaries_id, labels_id, config) for file_struct in file_structs[:])