def test_save_estimations_existing(): # Copy estimations file temporarily est_file = "tmp.jams" shutil.copy(os.path.join("fixtures", "01-Sargon-Mindless-ests.jams"), est_file) # First, find estimation jam = jams.load(est_file) params = {"hier": False} ann = msaf.io.find_estimation(jam, "sf", None, params) assert len(ann.data) == 21 # Add to estimation which will replace it file_struct = FileStruct("dummy") file_struct.est_file = est_file file_struct.features_file = os.path.join("fixtures", "01_-_Come_Together.json") times = np.array([0, 10, 20, 30]) labels = np.array([-1] * (len(times) - 1)) msaf.io.save_estimations(file_struct, times, labels, "sf", None, **params) jam = jams.load(est_file) ann = msaf.io.find_estimation(jam, "sf", None, params) assert len(ann.data) == len(times) - 1 # Add to estimation which will add a new one times2 = np.array([0, 10, 20, 30, 40]) labels2 = np.array([-1] * (len(times2) - 1)) params2 = {"sf_param": 0.1, "hier": False} msaf.io.save_estimations(file_struct, times2, labels2, "sf", None, **params2) # Make sure the old one is the same jam = jams.load(est_file) ann = msaf.io.find_estimation(jam, "sf", None, params) assert len(ann.data) == len(times) - 1 # Make sure the new one is the same ann = msaf.io.find_estimation(jam, "sf", None, params2) assert len(ann.data) == len(times2) - 1 # Add hierarchical times3 = [np.array([0, 40]), np.array([0, 10, 20, 30, 40])] labels3 = [np.array([-1] * (len(times3[0]) - 1)), np.array([-1] * (len(times3[1]) - 1))] params3 = {"sf_param": 0.1, "hier": True} msaf.io.save_estimations(file_struct, times3, labels3, "sf", None, **params3) jam = jams.load(est_file) ann = msaf.io.find_estimation(jam, "sf", None, params3) assert len(ann.data) == 5 assert ann.data[0].value["level"] == 0 assert ann.data[1].value["level"] == 1 assert ann.data[2].value["level"] == 1 assert ann.data[3].value["level"] == 1 assert ann.data[4].value["level"] == 1 # Cleanup os.remove(est_file)
def test_transcription_valid(): ref_jam = jams.load('fixtures/transcription_ref.jams') est_jam = jams.load('fixtures/transcription_est.jams') ref_ann = ref_jam.search(namespace='pitch_hz')[0] est_ann = est_jam.search(namespace='pitch_hz')[0] jams.eval.transcription(ref_ann, est_ann)
def __test_warn(filename, valid, strict): clean_warning_registry() with warnings.catch_warnings(record=True) as out: jams.load(filename, validate=valid, strict=strict) assert len(out) > 0 assert out[0].category is UserWarning assert 'failed validating' in str(out[0].message).lower()
def test_load_valid(): # 3. test good jams file with strict validation # 4. test good jams file without strict validation fn = 'tests/fixtures/valid' for ext in ['jams', 'jamz']: for validate in [False, True]: for strict in [False, True]: jams.load('{:s}.{:s}'.format(fn, ext), validate=validate, strict=strict)
def test_transcription_invalid(): ref_jam = jams.load('fixtures/transcription_ref.jams') est_jam = jams.load('fixtures/transcription_est.jams') ref_ann = ref_jam.search(namespace='pitch_hz')[0] est_ann = est_jam.search(namespace='pitch_hz')[0] ref_ann.append(time=2., duration=1., value='A', confidence=1) est_ann.append(time=2., duration=1., value='B', confidence=1) yield raises(jams.SchemaError)(jams.eval.transcription), ref_ann, est_ann yield raises(jams.SchemaError)(jams.eval.transcription), est_ann, ref_ann
def compare_beats(f_ref, f_est): # f_ref contains the reference annotations j_ref = jams.load(f_ref) # f_est contains the estimated annotations j_est = jams.load(f_est) # Get the first reference beats beat_ref = j_ref.search(namespace="beat")[0] beat_est = j_est.search(namespace="beat")[0] # Get the scores return jams.eval.beat(beat_ref, beat_est)
def __test(ext): fn = 'fixtures/valid.{:s}'.format(ext) jam = jams.load(fn) # Save to a temp file _, jam_out = tempfile.mkstemp(suffix='.{:s}'.format(ext)) try: jam.save(jam_out) jam2 = jams.load(jam_out) eq_(jam, jam2) finally: os.unlink(jam_out)
def read_references(audio_path, annotator_id=0): """Reads the boundary times and the labels. Parameters ---------- audio_path : str Path to the audio file Returns ------- ref_times : list List of boundary times ref_labels : list List of labels Raises ------ IOError: if `audio_path` doesn't exist. """ # Dataset path ds_path = os.path.dirname(os.path.dirname(audio_path)) # Read references jam_path = os.path.join(ds_path, ds_config.references_dir, os.path.basename(audio_path)[:-4] + ds_config.references_ext) jam = jams.load(jam_path, validate=False) ann = jam.search(namespace='segment_.*')[annotator_id] ref_inters, ref_labels = ann.to_interval_values() # Intervals to times ref_times = utils.intervals_to_times(ref_inters) return ref_times, ref_labels
def test_pattern_valid(): ref_jam = jams.load('fixtures/pattern_data.jams') ref_ann = ref_jam.search(namespace='pattern_jku')[0] jams.eval.pattern(ref_ann, ref_ann)
def fit_model(X, Y, B, T, n_jobs, annot_beats, ds_path): SIGMA = 10 ** np.arange(-2, 18) best_score = -np.inf best_sigma = None model = None for sig in SIGMA: O = OLDA.OLDA(sigma=sig) O.fit(X, Y) scores = [] files = msaf.io.get_dataset_files(ds_path) for f, z in zip(files, zip(X, B, T)): f = f.ref_file beats = z[1] if annot_beats: jam = jams.load(f) ann = jam.search(namespace="beat")[0] beats = ann.data.to_interval_values()[0][:, 0] print("\t\tProcessing ", f) scores.append(score_model(O.components_, z[0], beats, z[2])) mean_score = np.mean(scores) print('Sigma=%.2e, score=%.3f' % (sig, mean_score)) if mean_score > best_score: best_score = mean_score best_sigma = sig model = O.components_ print('Best sigma: %.2e' % best_sigma) return model
def getIntervalFromJAMS(path): j = jams.load(path) res = [] for i in zip(list(j.annotations[0].data.time), list(j.annotations[0].data.time + j.annotations[0].data.duration), j.annotations[0].data.value): v = [[librosa.time_to_frames([i[0].total_seconds(), i[1].total_seconds()]), i[2].encode("ascii")]] res += v return res
def load_jam_audio(jam_in, audio_file, **kwargs): '''Load a jam and pack it with audio. Parameters ---------- jam_in : str, file descriptor, or jams.JAMS JAMS filename, open file-descriptor, or object to load. See ``jams.load`` for acceptable formats. audio_file : str Audio filename to load kwargs : additional keyword arguments See `librosa.load` Returns ------- jam : jams.JAMS A jams object with audio data in the top-level sandbox See Also -------- jams.load librosa.core.load ''' if isinstance(jam_in, jams.JAMS): jam = jam_in else: jam = jams.load(jam_in) y, sr = librosa.load(audio_file, **kwargs) return jam_pack(jam, _audio=dict(y=y, sr=sr))
def jams_mapping(jams_in, task_map, validate=False): '''Convert jams annotations to crema outputs. Given a jams file and a collection of TaskTransformers, each TaskTransformer is applied to the jams annotations, and the results are collected in a single dictionary. All data is cast to a numpy array, and reshaped to have a new batch axis 0. Parameters ---------- jams_in : str or file-like path to a jams object. See ``jams.load`` for acceptable formats task_map: iterable of BaseTaskTransformers The task transformation objects to apply validate : bool Validate data on load Returns ------- output : dict All task transformer outputs, collected in one dictionary and reshaped. ''' jam = jams.load(jams_in, validate=validate) output = {} for task in task_map: for key, value in six.iteritems(task.transform(jam)): output[key] = np.asarray(value)[np.newaxis] return output
def read_ann_beats(self): """Reads the annotated beats if available. Returns ------- times: np.array Times of annotated beats in seconds. frames: np.array Frame indeces of annotated beats. """ times, frames = (None, None) # Read annotations if they exist in correct folder if os.path.isfile(self.file_struct.ref_file): try: jam = jams.load(self.file_struct.ref_file) except TypeError: logging.warning( "Can't read JAMS file %s. Maybe it's not " "compatible with current JAMS version?" % self.file_struct.ref_file) return times, frames beat_annot = jam.search(namespace="beat.*") # If beat annotations exist, get times and frames if len(beat_annot) > 0: beats_inters, _ = beat_annot[0].to_interval_values() times = beats_inters[:, 0] frames = librosa.time_to_frames(times, sr=self.sr, hop_length=self.hop_length) return times, frames
def load_jam_audio(jam_in, audio_file, **kwargs): '''Load a jam and pack it with audio. Parameters ---------- jam_in : str or jams.JAMS JAM filename to load audio_file : str Audio filename to load kwargs : additional keyword arguments See `librosa.load` Returns ------- jam : jams.JAMS A jams object with audio data in the top-level sandbox ''' if isinstance(jam_in, six.string_types): jam = jams.load(jam_in) elif isinstance(jam_in, jams.JAMS): jam = jam_in else: raise TypeError('Invalid input type: ' + type(jam_in)) y, sr = librosa.load(audio_file, **kwargs) return jam_pack(jam, _audio=dict(y=y, sr=sr))
def convert_jams(jams_file, output_prefix, csv=False, comment_char='#', namespaces=None): '''Convert jams to labs. Parameters ---------- jams_file : str The path on disk to the jams file in question output_prefix : str The file path prefix of the outputs csv : bool Whether to output in csv (True) or lab (False) format comment_char : str The character used to denote comments namespaces : list-like The set of namespace patterns to match for output ''' if namespaces is None: raise ValueError('No namespaces provided. Try ".*" for all namespaces.') jam = jams.load(jams_file) # Get all the annotations # Filter down to the unique ones # For each annotation # generate the comment string # generate the output filename # dump to csv # Make a counter object for each namespace type counter = collections.Counter() annotations = [] for query in namespaces: annotations.extend(jam.search(namespace=query)) if csv: suffix = 'csv' sep = ',' else: suffix = 'lab' sep = '\t' for ann in annotations: index = counter[ann.namespace] counter[ann.namespace] += 1 filename = os.path.extsep.join([get_output_name(output_prefix, ann.namespace, index), suffix]) comment = get_comments(jam, ann) # Dump to disk lab_dump(ann, comment, filename, sep, comment_char)
def test_jams_validate_good(): fn = 'tests/fixtures/valid.jams' j1 = jams.load(fn, validate=False) j1.validate() j1.file_metadata.validate()
def filter_by_artist(file_structs, artist_name="The Beatles"): """Filters data set files by artist name.""" new_file_structs = [] for file_struct in file_structs: jam = jams.load(file_struct.ref_file, validate=False) if jam.file_metadata.artist == artist_name: new_file_structs.append(file_struct) return new_file_structs
def test_scaper_instantiate(): for sr in (44100, 22050): REG_JAM_PATH = TEST_PATHS[sr]['REG'].jams # Here we just instantiate a known fixed spec and check if that jams # we get back is as expected. sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH) sc.ref_db = -50 sc.sr = sr # background sc.add_background( label=('const', 'park'), source_file=( 'const', 'tests/data/audio/background/park/' '268903__yonts__city-park-tel-aviv-israel.wav'), source_time=('const', 0)) # foreground events sc.add_event( label=('const', 'siren'), source_file=('const', 'tests/data/audio/foreground/' 'siren/69-Siren-1.wav'), source_time=('const', 5), event_time=('const', 2), event_duration=('const', 5), snr=('const', 5), pitch_shift=None, time_stretch=None) sc.add_event( label=('const', 'car_horn'), source_file=('const', 'tests/data/audio/foreground/' 'car_horn/17-CAR-Rolls-Royce-Horn.wav'), source_time=('const', 0), event_time=('const', 5), event_duration=('const', 2), snr=('const', 20), pitch_shift=('const', 1), time_stretch=None) sc.add_event( label=('const', 'human_voice'), source_file=('const', 'tests/data/audio/foreground/' 'human_voice/42-Human-Vocal-Voice-taxi-2_edit.wav'), source_time=('const', 0), event_time=('const', 7), event_duration=('const', 2), snr=('const', 10), pitch_shift=None, time_stretch=('const', 1.2)) jam = sc._instantiate(disable_instantiation_warnings=True) regjam = jams.load(REG_JAM_PATH) _compare_scaper_jams(jam, regjam)
def __test_conflict(on_conflict): fn = 'fixtures/valid.jams' # The original jam jam = jams.load(fn) jam_orig = jams.load(fn) # The copy jam2 = jams.load(fn) jam2.file_metadata = jams.FileMetadata() jam.add(jam2, on_conflict=on_conflict) if on_conflict == 'overwrite': eq_(jam.file_metadata, jam2.file_metadata) elif on_conflict == 'ignore': eq_(jam.file_metadata, jam_orig.file_metadata)
def test_jams_add_conflict(on_conflict): fn = 'tests/fixtures/valid.jams' # The original jam jam = jams.load(fn) jam_orig = jams.load(fn) # The copy jam2 = jams.load(fn) jam2.file_metadata = jams.FileMetadata() jam.add(jam2, on_conflict=on_conflict) if on_conflict == 'overwrite': assert jam.file_metadata == jam2.file_metadata elif on_conflict == 'ignore': assert jam.file_metadata == jam_orig.file_metadata
def plot_one_track(file_struct, est_times, est_labels, boundaries_id, labels_id, title=None): """Plots the results of one track, with ground truth if it exists.""" import matplotlib.pyplot as plt # Set up the boundaries id bid_lid = boundaries_id if labels_id is not None: bid_lid += " + " + labels_id try: # Read file jam = jams.load(file_struct.ref_file) ann = jam.search(namespace='segment_.*')[0] ref_inters, ref_labels = ann.to_interval_values() # To times ref_times = utils.intervals_to_times(ref_inters) all_boundaries = [ref_times, est_times] all_labels = [ref_labels, est_labels] algo_ids = ["GT", bid_lid] except: logging.warning("No references found in %s. Not plotting groundtruth" % file_struct.ref_file) all_boundaries = [est_times] all_labels = [est_labels] algo_ids = [bid_lid] N = len(all_boundaries) # Index the labels to normalize them for i, labels in enumerate(all_labels): all_labels[i] = mir_eval.util.index_labels(labels)[0] # Get color map cm = plt.get_cmap('gist_rainbow') max_label = max(max(labels) for labels in all_labels) figsize = (8, 4) plt.figure(1, figsize=figsize, dpi=120, facecolor='w', edgecolor='k') for i, boundaries in enumerate(all_boundaries): color = "b" if i == 0: color = "g" for b in boundaries: plt.axvline(b, i / float(N), (i + 1) / float(N), color=color) if labels_id is not None: labels = all_labels[i] inters = utils.times_to_intervals(boundaries) for label, inter in zip(labels, inters): plt.axvspan(inter[0], inter[1], ymin=i / float(N), ymax=(i + 1) / float(N), alpha=0.6, color=cm(label / float(max_label))) plt.axhline(i / float(N), color="k", linewidth=1) # Format plot _plot_formatting(title, os.path.basename(file_struct.audio_file), algo_ids, all_boundaries[0][-1], N, None)
def test_jams_add(tag_data): fn = 'tests/fixtures/valid.jams' # The original jam jam_orig = jams.load(fn) jam = jams.load(fn) # Make a new jam with the same metadata and different data jam2 = jams.load(fn) ann = jams.Annotation('tag_open', data=tag_data) jam2.annotations = jams.AnnotationArray(annotations=[ann]) # Add the two jam.add(jam2) assert len(jam.annotations) == 3 assert jam.annotations[:-1] == jam_orig.annotations assert jam.annotations[-1] == jam2.annotations[0]
def compute_all_features(file_struct, sonify_beats=False, overwrite=False, out_beats="out_beats.wav"): """Computes all the features for a specific audio file and its respective human annotations. It creates an audio file with the sonified estimated beats if needed. Parameters ---------- file_struct: FileStruct Object containing all the set of file paths of the input file. sonify_beats: bool Whether to sonify the beats. overwrite: bool Whether to overwrite previous features JSON file. out_beats: str Path to the new file containing the sonified beats. """ # Output file out_file = file_struct.features_file if os.path.isfile(out_file) and not overwrite: return # Do nothing, file already exist and we are not overwriting it # Compute the features for the given audio file features = compute_features_for_audio_file(file_struct.audio_file) # Save output as audio file if sonify_beats: logging.info("Sonifying beats...") fs = 44100 audio, sr = librosa.load(file_struct.audio_file, sr=fs) msaf.utils.sonify_clicks(audio, features["beats"], out_beats, fs, offset=0.0) # Read annotations if they exist in path/references_dir/file.jams if os.path.isfile(file_struct.ref_file): jam = jams.load(file_struct.ref_file) beat_annot = jam.search(namespace="beat.*") # If beat annotations exist, compute also annotated beatsync features if len(beat_annot) > 0: logging.info("Reading beat annotations from JAMS") annot_beats_inters, _ = beat_annot[0].data.to_interval_values() annot_beats_times = annot_beats_inters[:, 0] annot_beats_idx = librosa.time_to_frames( annot_beats_times, sr=msaf.Anal.sample_rate, hop_length=msaf.Anal.hop_size) features["ann_mfcc"], features["ann_hpcp"], \ features["ann_tonnetz"], features["ann_cqt"], features["ann_tempogram"] = \ compute_beat_sync_features(features, annot_beats_idx) # Save output as json file save_features(out_file, features)
def run(infile='', output_prefix='annotation'): '''Do the conversion''' jam = jams.load(infile) mapping = defaultdict(int) for annotation in jam.annotations: ns = annotation.namespace filename = os.path.extsep.join([output_prefix, ns, str(mapping[ns]), 'lab']) mapping[ns] += 1 annotation.data.to_csv(filename, sep='\t')
def __test(strict): fn = 'fixtures/invalid.jams' j1 = jams.load(fn, validate=False) clean_warning_registry() with warnings.catch_warnings(record=True) as out: j1.validate(strict=strict) assert len(out) > 0 assert out[0].category is UserWarning assert 'failed validating' in str(out[0].message).lower()
def load_jam_audio(jam_in, audio_file, validate=True, strict=True, fmt='auto', **kwargs): '''Load a jam and pack it with audio. Parameters ---------- jam_in : str, file descriptor, or jams.JAMS JAMS filename, open file-descriptor, or object to load. See ``jams.load`` for acceptable formats. audio_file : str Audio filename to load validate : bool strict : bool fmt : str Parameters to `jams.load` kwargs : additional keyword arguments See `librosa.load` Returns ------- jam : jams.JAMS A jams object with audio data in the top-level sandbox Notes ----- This operation can modify the `file_metadata.duration` field of `jam_in`: If it is not currently set, it will be populated with the duration of the audio file. See Also -------- jams.load librosa.core.load ''' if isinstance(jam_in, jams.JAMS): jam = jam_in else: jam = jams.load(jam_in, validate=validate, strict=strict, fmt=fmt) y, sr = librosa.load(audio_file, **kwargs) if jam.file_metadata.duration is None: jam.file_metadata.duration = librosa.get_duration(y=y, sr=sr) return jam_pack(jam, _audio=dict(y=y, sr=sr))
def jam_loader(request): if request.param == 0: yield jams.JAMS() elif request.param == 1: yield 'tests/data/fixture.jams' elif request.param == 2: yield jams.load('tests/data/fixture.jams') else: with open('tests/data/fixture.jams', 'r') as fdesc: yield fdesc
def process_track(file_struct, boundaries_id, labels_id, config, annotator_id=0): """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 = jams.load(file_struct.ref_file) annots = jam.search(namespace="beat.*") if not annots: logging.warning("No beat information in file %s" % file_struct.ref_file) return np.array([]), np.array([]) 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_times, est_labels, boundaries_id, labels_id, **config) return est_times, est_labels
def __test(): fn = 'fixtures/valid.jams' # The original jam jam_orig = jams.load(fn) jam = jams.load(fn) # Make a new jam with the same metadata and different data jam2 = jams.load(fn) data = dict(time=[0.0, 1.0], duration=[0.5, 0.5], value=['one', 'two'], confidence=[0.9, 0.9]) ann = jams.Annotation('tag_open', data=data) jam2.annotations = jams.AnnotationArray(annotations=[ann]) # Add the two jam.add(jam2) eq_(len(jam.annotations), 3) eq_(jam.annotations[:-1], jam_orig.annotations) eq_(jam.annotations[-1], jam2.annotations[0])
event_duration=('const', 2), snr=('const', 10), pitch_shift=None, time_stretch=('const', 1.2)) wav_file, jam_file, txt_file = test_names(REG_NAME) sc.generate(wav_file, jam_file, txt_path=txt_file, disable_instantiation_warnings=True) print('Wrote:', wav_file, jam_file, txt_file) wav_file, jam_file, txt_file = test_names(REG_REVERB_NAME) sc.generate(wav_file, jam_file, txt_path=txt_file, reverb=0.2, disable_instantiation_warnings=True) print('Wrote:', wav_file, jam_file, txt_file) import jams jams.load(jam_file) # soundscape with only one event will use transformer (regression test) sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH) sc.ref_db = -20 sc.sr = 22050 # background sc.add_background( label=('const', 'park'), source_file=('const', 'tests/data/audio/background/park/' '268903__yonts__city-park-tel-aviv-israel.wav'), source_time=('const', 0)) wav_file, jam_file, txt_file = test_names(REG_BGONLY_NAME)
def __test(filename, valid, strict): jams.load(filename, validate=valid, strict=strict)
from ambiscaper import * import os import jams # Add Ambiscaper namespaces jams.schema.add_namespace(os.path.abspath('../ambiscaper/namespaces/ambiscaper_sound_event.json')) jams.schema.add_namespace(os.path.abspath('../ambiscaper/namespaces/ambiscaper_sofa_reverb.json')) # Set target soundscape path soundscape_path = os.path.abspath('../tests/data/soundscape_for_test') soundscape_jams_file_name = os.path.join(soundscape_path,'soundscape_for_test.jams') # Load jams file jam = jams.load(soundscape_jams_file_name, validate=False, strict=False) # Let's find the `ambiscaper_sound_event` AnnotationArray. # The `search` method returns all annotations that matches the namespace query. # In our case, there should be only one annotation. event_annotation_array = jam.search(namespace='ambiscaper_sound_event') event_annotation = event_annotation_array[0] # `event_annotation` is an instance of the Annotation class # We can check the annotation contents with a print call print(event_annotation) # The Annotation class provides some handful methods to manage the data, # for example slice(), trim(), etc. # Please refer to the Jams documentation for more info.
def jam_to_key(jam_file): jam = jams.load(jam_file) return jam.file_metadata.identifiers.artist_id
def __test(filename, fmt): jams.load(filename, fmt=fmt)
def test_scaper_instantiate(): # Here we just instantiate a known fixed spec and check if that jams # we get back is as expected. sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH) sc.ref_db = -50 # background sc.add_background( label=('const', 'park'), source_file=('const', 'tests/data/audio/background/park/' '268903__yonts__city-park-tel-aviv-israel.wav'), source_time=('const', 0)) # foreground events sc.add_event(label=('const', 'siren'), source_file=('const', 'tests/data/audio/foreground/' 'siren/69-Siren-1.wav'), source_time=('const', 5), event_time=('const', 2), event_duration=('const', 5), snr=('const', 5), pitch_shift=None, time_stretch=None) sc.add_event(label=('const', 'car_horn'), source_file=('const', 'tests/data/audio/foreground/' 'car_horn/17-CAR-Rolls-Royce-Horn.wav'), source_time=('const', 0), event_time=('const', 5), event_duration=('const', 2), snr=('const', 20), pitch_shift=('const', 1), time_stretch=None) sc.add_event( label=('const', 'human_voice'), source_file=('const', 'tests/data/audio/foreground/' 'human_voice/42-Human-Vocal-Voice-taxi-2_edit.wav'), source_time=('const', 0), event_time=('const', 7), event_duration=('const', 2), snr=('const', 10), pitch_shift=None, time_stretch=('const', 1.2)) jam = sc._instantiate(disable_instantiation_warnings=True) regjam = jams.load(REG_JAM_PATH) # print(jam) # print(regression_jam) # Note: can't compare directly, since: # 1. scaper/and jams liberary versions may change # 2. raw annotation sandbox stores specs as OrderedDict and tuples, whereas # loaded ann (regann) simplifies those to dicts and lists # assert jam == regression_jam # Must compare each part "manually" # 1. compare file metadata for k, kreg in zip(jam.file_metadata.keys(), regjam.file_metadata.keys()): assert k == kreg if k != 'jams_version': assert jam.file_metadata[k] == regjam.file_metadata[kreg] # 2. compare jams sandboxes assert jam.sandbox == regjam.sandbox # 3. compare annotations assert len(jam.annotations) == len(regjam.annotations) == 1 ann = jam.annotations[0] regann = regjam.annotations[0] # 3.1 compare annotation metadata assert ann.annotation_metadata == regann.annotation_metadata # 3.2 compare sandboxes # Note: can't compare sandboxes directly, since in raw jam scaper sandbox # stores event specs in EventSpec object (named tuple), whereas in loaded # jam these will get converted to list of lists. # assert ann.sandbox == regann.sandbox assert len(ann.sandbox.keys()) == len(regann.sandbox.keys()) == 1 assert 'scaper' in ann.sandbox.keys() assert 'scaper' in regann.sandbox.keys() # everything but the specs and version can be compared directly: for k, kreg in zip(sorted(ann.sandbox.scaper.keys()), sorted(regann.sandbox.scaper.keys())): assert k == kreg if k not in ['bg_spec', 'fg_spec', 'scaper_version']: assert ann.sandbox.scaper[k] == regann.sandbox.scaper[kreg] # to compare specs need to covert raw specs to list of lists assert ([[list(x) if type(x) == tuple else x for x in e] for e in ann.sandbox.scaper['bg_spec'] ] == regann.sandbox.scaper['bg_spec']) assert ([[list(x) if type(x) == tuple else x for x in e] for e in ann.sandbox.scaper['fg_spec'] ] == regann.sandbox.scaper['fg_spec']) # 3.3. compare namespace, time and duration assert ann.namespace == regann.namespace assert ann.time == regann.time assert ann.duration == regann.duration # 3.4 compare data (ann.data == regann.data).all().all()
def load_key_mode(jams_path): jam = jams.load(jams_path) anno = jam.search(namespace='key_mode')[0] intervals, values = anno.to_interval_values() return utils.KeyData(intervals[:, 0], intervals[:, 1], values)
def refine_jams(audio_dirs, jams_dirs, tau=0.04, hop=1, rmse=256, update_jam=False): """ Refine estimates/annotations from jams. :param audio_dirs: list of directories, containing audio files :param jams_dirs: list of directories, containing jams files :param tau: tau :param hop: RMSE hop length :param rmse: RMSE window length :param update_jam: if ``True`` annotations are added to the existing jams files """ print( 'Refining jams from {} based on audio files in {} using tau={}'.format( jams_dirs, audio_dirs, tau)) audio_files = _scan_audio_files(audio_dirs) def create_tempo_annotation(tempo1=0.0, tempo2=0.0, confidence1=1.0, confidence2=0.0): tempo = jams.Annotation(namespace='tempo') tempo.append(time=0.0, duration='nan', value=tempo1, confidence=confidence1) if tempo2 != 0.0: tempo.append(time=0.0, duration='nan', value=tempo2, confidence=confidence2) return tempo for d in jams_dirs: for (dirpath, _, filenames) in walk(d): for file in [f for f in filenames if f.endswith('.jams')]: k = file.replace('.jams', '') jam_file = join(dirpath, file) print('Processing \'{}\' ...'.format(jam_file)) if k in audio_files: jam = jams.load(jam_file, validate=False) if update_jam: new_jam = jam else: new_jam = jams.JAMS() modified = False for annotation in jam.annotations['tempo']: # always correct duration new_jam.file_metadata.duration = audio_files[k][1] if not update_jam: new_jam.file_metadata.identifiers = { 'file': basename(audio_files[k][0]) } t1 = annotation.data[0].value c1 = annotation.data[0].confidence new_t1 = rlac(audio_files[k][0], t1, hop, rmse, tau=tau) if len(annotation.data) > 1: t2 = annotation.data[1].value c2 = annotation.data[1].confidence new_t2 = rlac(audio_files[k][0], t2, hop, rmse, tau=tau) else: c2 = 0.0 new_t2 = 0.0 # create new annotations new_annotation = create_tempo_annotation( tempo1=new_t1, confidence1=c1, tempo2=new_t2, confidence2=c2) data_source = '' metadata = annotation.annotation_metadata if metadata.data_source is not None\ and len(metadata.data_source) > 0: data_source = metadata.data_source + ', ' data_source = data_source + 'postprocessed with RLAC (tau={}, hop={}, rmse={})' \ .format(tau, hop, rmse) new_annotation.annotation_metadata = jams.AnnotationMetadata( corpus=metadata.corpus, version=metadata.version, curator=metadata.curator, data_source=data_source, annotator=metadata.annotator) new_jam.annotations.append(new_annotation) modified = True if modified: if update_jam: jam.save(jam_file) else: if jam.file_metadata.artist is not None: new_jam.file_metadata.artist = jam.file_metadata.artist if jam.file_metadata.title is not None: new_jam.file_metadata.title = jam.file_metadata.title if jam.file_metadata.release is not None: new_jam.file_metadata.release = jam.file_metadata.release new_jam.save( jam_file.replace('.jams', '_refined.jams')) else: print('Failed to find audio file for \'{}\''.format( jam_file), file=sys.stderr)
def print_outputs(jam_name): import jams jam = jams.load(os.path.join(ANNOTATIONS_DIR, jam_name)) outputs = [s.tolist() for s in get_segmented_outputs(jam, SEGMENT_LENGTH)] print("Chords for", jam_name + ":") print(outputs)
def test_trim(atol=1e-5, rtol=1e-8): # Things we want to test: # 1. Jam trimmed correctly (mainly handled by jams.slice) # 2. value dict updated correctly (event_time, event_duration, source_time) # 3. scaper sandbox updated correctly (n_events, poly, gini, duration) # 4. audio trimmed correctly tmpfiles = [] with _close_temp_files(tmpfiles): # Create all necessary temp files orig_wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) orig_jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) trim_wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) trim_jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) trimstrict_wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) trimstrict_jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) tmpfiles.append(orig_wav_file) tmpfiles.append(orig_jam_file) tmpfiles.append(trim_wav_file) tmpfiles.append(trim_jam_file) tmpfiles.append(trimstrict_wav_file) tmpfiles.append(trimstrict_jam_file) # --- Create soundscape and save to tempfiles --- # sc = scaper.Scaper(10, FG_PATH, BG_PATH) sc.protected_labels = [] sc.ref_db = -50 sc.add_background(label=('const', 'park'), source_file=('choose', []), source_time=('const', 0)) # Add 5 events start_times = [0.5, 2.5, 4.5, 6.5, 8.5] for event_time in start_times: sc.add_event(label=('const', 'siren'), source_file=('choose', []), source_time=('const', 5), event_time=('const', event_time), event_duration=('const', 1), snr=('const', 10), pitch_shift=None, time_stretch=None) sc.generate(orig_wav_file.name, orig_jam_file.name, disable_instantiation_warnings=True) # --- Trim soundscape using scaper.trim with strict=False --- # scaper.trim(orig_wav_file.name, orig_jam_file.name, trim_wav_file.name, trim_jam_file.name, 3, 7, no_audio=False) # --- Validate output --- # # validate JAMS trimjam = jams.load(trim_jam_file.name) trimann = trimjam.annotations.search(namespace='sound_event')[0] # Time and duration of annotation observation must be changed, but # values in the value dict must remained unchanged! for idx, event in trimann.data.iterrows(): if event.value['role'] == 'background': assert (event.time.total_seconds() == 0 and event.duration.total_seconds() == 4 and event.value['event_time'] == 0 and event.value['event_duration'] == 10 and event.value['source_time'] == 0) else: if event.time.total_seconds() == 0: assert (event.duration.total_seconds() == 0.5 and event.value['event_time'] == 2.5 and event.value['event_duration'] == 1 and event.value['source_time'] == 5) elif event.time.total_seconds() == 1.5: assert (event.duration.total_seconds() == 1 and event.value['event_time'] == 4.5 and event.value['event_duration'] == 1 and event.value['source_time'] == 5) elif event.time.total_seconds() == 3.5: assert (event.duration.total_seconds() == 0.5 and event.value['event_time'] == 6.5 and event.value['event_duration'] == 1 and event.value['source_time'] == 5) else: assert False # validate audio orig_wav, sr = soundfile.read(orig_wav_file.name) trim_wav, sr = soundfile.read(trim_wav_file.name) assert np.allclose(trim_wav, orig_wav[3 * sr:7 * sr], atol=atol, rtol=rtol)
def test_generate_from_jams(atol=1e-5, rtol=1e-8): # Test for invalid jams: no annotations tmpfiles = [] with _close_temp_files(tmpfiles): jam = jams.JAMS() jam.file_metadata.duration = 10 jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) gen_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) jam.save(jam_file.name) pytest.raises(ScaperError, scaper.generate_from_jams, jam_file.name, gen_file.name) # Test for valid jams files tmpfiles = [] with _close_temp_files(tmpfiles): # Create all necessary temp files orig_wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) orig_jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) gen_wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) gen_jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) tmpfiles.append(orig_wav_file) tmpfiles.append(orig_jam_file) tmpfiles.append(gen_wav_file) tmpfiles.append(gen_jam_file) # --- Define scaper --- * sc = scaper.Scaper(10, FG_PATH, BG_PATH) sc.protected_labels = [] sc.ref_db = -50 sc.add_background(label=('choose', []), source_file=('choose', []), source_time=('const', 0)) # Add 5 events for _ in range(5): sc.add_event(label=('choose', []), source_file=('choose', []), source_time=('const', 0), event_time=('uniform', 0, 9), event_duration=('choose', [1, 2, 3]), snr=('uniform', 10, 20), pitch_shift=('uniform', -1, 1), time_stretch=('uniform', 0.8, 1.2)) # generate, then generate from the jams and compare audio files # repeat 5 time for _ in range(5): sc.generate(orig_wav_file.name, orig_jam_file.name, disable_instantiation_warnings=True) scaper.generate_from_jams(orig_jam_file.name, gen_wav_file.name) # validate audio orig_wav, sr = soundfile.read(orig_wav_file.name) gen_wav, sr = soundfile.read(gen_wav_file.name) assert np.allclose(gen_wav, orig_wav, atol=atol, rtol=rtol) # Now add in trimming! for _ in range(5): sc.generate(orig_wav_file.name, orig_jam_file.name, disable_instantiation_warnings=True) scaper.trim(orig_wav_file.name, orig_jam_file.name, orig_wav_file.name, orig_jam_file.name, np.random.uniform(0, 5), np.random.uniform(5, 10)) scaper.generate_from_jams(orig_jam_file.name, gen_wav_file.name) # validate audio orig_wav, sr = soundfile.read(orig_wav_file.name) gen_wav, sr = soundfile.read(gen_wav_file.name) assert np.allclose(gen_wav, orig_wav, atol=atol, rtol=rtol) # Double trimming for _ in range(2): sc.generate(orig_wav_file.name, orig_jam_file.name, disable_instantiation_warnings=True) scaper.trim(orig_wav_file.name, orig_jam_file.name, orig_wav_file.name, orig_jam_file.name, np.random.uniform(0, 2), np.random.uniform(8, 10)) scaper.trim(orig_wav_file.name, orig_jam_file.name, orig_wav_file.name, orig_jam_file.name, np.random.uniform(0, 2), np.random.uniform(4, 6)) scaper.generate_from_jams(orig_jam_file.name, gen_wav_file.name) # Tripple trimming for _ in range(2): sc.generate(orig_wav_file.name, orig_jam_file.name, disable_instantiation_warnings=True) scaper.trim(orig_wav_file.name, orig_jam_file.name, orig_wav_file.name, orig_jam_file.name, np.random.uniform(0, 2), np.random.uniform(8, 10)) scaper.trim(orig_wav_file.name, orig_jam_file.name, orig_wav_file.name, orig_jam_file.name, np.random.uniform(0, 1), np.random.uniform(5, 6)) scaper.trim(orig_wav_file.name, orig_jam_file.name, orig_wav_file.name, orig_jam_file.name, np.random.uniform(0, 1), np.random.uniform(3, 4)) scaper.generate_from_jams(orig_jam_file.name, gen_wav_file.name) # validate audio orig_wav, sr = soundfile.read(orig_wav_file.name) gen_wav, sr = soundfile.read(gen_wav_file.name) assert np.allclose(gen_wav, orig_wav, atol=atol, rtol=rtol) # Test with new FG and BG paths for _ in range(5): sc.generate(orig_wav_file.name, orig_jam_file.name, disable_instantiation_warnings=True) scaper.generate_from_jams(orig_jam_file.name, gen_wav_file.name, fg_path=ALT_FG_PATH, bg_path=ALT_BG_PATH) # validate audio orig_wav, sr = soundfile.read(orig_wav_file.name) gen_wav, sr = soundfile.read(gen_wav_file.name) assert np.allclose(gen_wav, orig_wav, atol=atol, rtol=rtol) # Ensure jam file saved correctly scaper.generate_from_jams(orig_jam_file.name, gen_wav_file.name, jams_outfile=gen_jam_file.name) orig_jam = jams.load(orig_jam_file.name) gen_jam = jams.load(gen_jam_file.name) assert orig_jam == gen_jam
def save_estimations(file_struct, times, labels, boundaries_id, labels_id, **params): """Saves the segment estimations in a JAMS file. Parameters ---------- file_struct : FileStruct Object with the different file paths of the current file. times : np.array or list Estimated boundary times. If `list`, estimated hierarchical boundaries. labels : np.array(N, 2) Estimated labels (None in case we are only storing boundary evaluations). boundaries_id : str Boundary algorithm identifier. labels_id : str Labels algorithm identifier. params : dict Dictionary with additional parameters for both algorithms. """ # Remove features if they exist params.pop("features", None) # Get duration dur = get_duration(file_struct.features_file) # Convert to intervals and sanity check if 'numpy' in str(type(times)): # Flat check inters = utils.times_to_intervals(times) assert len(inters) == len(labels), "Number of boundary intervals " \ "(%d) and labels (%d) do not match" % (len(inters), len(labels)) # Put into lists to simplify the writing process later inters = [inters] labels = [labels] else: # Hierarchical check inters = [] for level in range(len(times)): est_inters = utils.times_to_intervals(times[level]) inters.append(est_inters) assert len(inters[level]) == len(labels[level]), \ "Number of boundary intervals (%d) and labels (%d) do not " \ "match in level %d" % (len(inters[level]), len(labels[level]), level) # Create new estimation namespace = "multi_segment" if params["hier"] else "segment_open" ann = jams.Annotation(namespace=namespace) # Find estimation in file if os.path.isfile(file_struct.est_file): jam = jams.load(file_struct.est_file, validate=False) curr_ann = find_estimation(jam, boundaries_id, labels_id, params) if curr_ann is not None: curr_ann.data = ann.data # cleanup all data ann = curr_ann # This will overwrite the existing estimation else: jam.annotations.append(ann) else: # Create new JAMS if it doesn't exist jam = jams.JAMS() jam.file_metadata.duration = dur jam.annotations.append(ann) # Save metadata and parameters ann.annotation_metadata.version = msaf.__version__ ann.annotation_metadata.data_source = "MSAF" sandbox = {} sandbox["boundaries_id"] = boundaries_id sandbox["labels_id"] = labels_id sandbox["timestamp"] = \ datetime.datetime.today().strftime("%Y/%m/%d %H:%M:%S") for key in params: sandbox[key] = params[key] ann.sandbox = sandbox # Save actual data for i, (level_inters, level_labels) in enumerate(zip(inters, labels)): for bound_inter, label in zip(level_inters, level_labels): dur = float(bound_inter[1]) - float(bound_inter[0]) label = chr(int(label) + 65) if params["hier"]: value = {"label": label, "level": i} else: value = label ann.append(time=bound_inter[0], duration=dur, value=value) # Write results jam.save(file_struct.est_file)
def test_find_estimation_multiple(): est_file = os.path.join("fixtures", "01-Sargon-Mindless-est-multiple.jams") jam = jams.load(est_file) params = {"hier": True} ann = msaf.io.find_estimation(jam, "sf", None, params) assert len(ann.data) == 86
def load_beats(file): df = jams.load(file)['annotations'][0].to_dataframe() beats = df['time'].values return beats
def jam_to_audio(jam_file): jam = jams.load(jam_file) return str(jam.sandbox.content_path)
def load_beats(jams_path): jam = jams.load(jams_path) anno = jam.search(namespace='beat_position')[0] times, values = anno.to_event_values() positions = [int(v['position']) for v in values] return utils.BeatData(times, positions)
def transform(self, audio_f=None, jam=None, y=None, sr=None, crop=False): '''Apply the transformations to an audio file, and optionally JAMS object. Parameters ---------- audio_f : str Path to audio file jam : optional, `jams.JAMS`, str or file-like Optional JAMS object/path to JAMS file/open file descriptor. If provided, this will provide data for task transformers. y : np.ndarray sr : number > 0 If provided, operate directly on an existing audio buffer `y` at sampling rate `sr` rather than load from `audio_f`. crop : bool If `True`, then data are cropped to a common time index across all fields. Otherwise, data may have different time extents. Returns ------- data : dict Data dictionary containing the transformed audio (and annotations) Raises ------ ParameterError At least one of `audio_f` or `(y, sr)` must be provided. ''' if y is None: if audio_f is None: raise ParameterError('At least one of `y` or `audio_f` ' 'must be provided') # Load the audio y, sr = librosa.load(audio_f, sr=sr, mono=True) if sr is None: raise ParameterError('If audio is provided as `y`, you must ' 'specify the sampling rate as sr=') if jam is None: jam = jams.JAMS() jam.file_metadata.duration = librosa.get_duration(y=y, sr=sr) # Load the jams if not isinstance(jam, jams.JAMS): jam = jams.load(jam) data = dict() for operator in self.ops: if isinstance(operator, BaseTaskTransformer): data.update(operator.transform(jam)) elif isinstance(operator, FeatureExtractor): data.update(operator.transform(y, sr)) if crop: data = self.crop(data) return data
def load_annotations(path): J = jams.load(path + '00_BN1-129-Eb_comp.jams') for a in J.annotations: if (a.namespace == 'note_midi'): jams.display.display(a)
def jam_raw(): return jams.load('tests/data/fixture.jams')
def test_jams_validate_good(): fn = 'fixtures/valid.jams' j1 = jams.load(fn, validate=False) j1.validate()
def jam_search(): jam = jams.load('tests/fixtures/valid.jams', validate=False) jam.annotations[0].sandbox.foo = None return jam
def _test_generate(SR, REG_WAV_PATH, REG_JAM_PATH, REG_TXT_PATH, atol=1e-4, rtol=1e-8): # Final regression test on all files sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH) sc.ref_db = -50 sc.sr = SR # background sc.add_background( label=('const', 'park'), source_file=('const', 'tests/data/audio/background/park/' '268903__yonts__city-park-tel-aviv-israel.wav'), source_time=('const', 0)) # foreground events sc.add_event(label=('const', 'siren'), source_file=('const', 'tests/data/audio/foreground/' 'siren/69-Siren-1.wav'), source_time=('const', 5), event_time=('const', 2), event_duration=('const', 5), snr=('const', 5), pitch_shift=None, time_stretch=None) sc.add_event(label=('const', 'car_horn'), source_file=('const', 'tests/data/audio/foreground/' 'car_horn/17-CAR-Rolls-Royce-Horn.wav'), source_time=('const', 0), event_time=('const', 5), event_duration=('const', 2), snr=('const', 20), pitch_shift=('const', 1), time_stretch=None) sc.add_event( label=('const', 'human_voice'), source_file=('const', 'tests/data/audio/foreground/' 'human_voice/42-Human-Vocal-Voice-taxi-2_edit.wav'), source_time=('const', 0), event_time=('const', 7), event_duration=('const', 2), snr=('const', 10), pitch_shift=None, time_stretch=('const', 1.2)) tmpfiles = [] with _close_temp_files(tmpfiles): wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) txt_file = tempfile.NamedTemporaryFile(suffix='.txt', delete=True) tmpfiles.append(wav_file) tmpfiles.append(jam_file) tmpfiles.append(txt_file) sc.generate(wav_file.name, jam_file.name, txt_path=txt_file.name, disable_instantiation_warnings=True) # validate audio wav, sr = soundfile.read(wav_file.name) regwav, sr = soundfile.read(REG_WAV_PATH) assert np.allclose(wav, regwav, atol=atol, rtol=rtol) # validate jams jam = jams.load(jam_file.name) regjam = jams.load(REG_JAM_PATH) _compare_scaper_jams(jam, regjam) # validate txt # read in both files txt_data = [] with open(txt_file.name) as file: reader = csv.reader(file, delimiter='\t') for row in reader: txt_data.append(row) txt_data = np.asarray(txt_data) regtxt_data = [] with open(REG_TXT_PATH) as file: reader = csv.reader(file, delimiter='\t') for row in reader: regtxt_data.append(row) regtxt_data = np.asarray(regtxt_data) # compare start and end times assert np.allclose([float(x) for x in txt_data[:, 0]], [float(x) for x in regtxt_data[:, 0]]) assert np.allclose([float(x) for x in txt_data[:, 1]], [float(x) for x in regtxt_data[:, 1]]) # compare labels assert (txt_data[:, 2] == regtxt_data[:, 2]).all() # reverb value must be in (0, 1) range for reverb in [-1, 2]: pytest.raises(ScaperError, sc.generate, wav_file.name, jam_file.name, reverb=reverb, disable_instantiation_warnings=True)
def jam_validate(): j1 = jams.load('tests/fixtures/invalid.jams', validate=False) return j1
def test_load_fail(): # 1. test bad file path # 2. test non-json file # 3. test bad extensions # 4. test bad codecs # Make a non-existent file tdir = tempfile.mkdtemp() with pytest.raises(IOError): jams.load(os.path.join(tdir, 'nonexistent.jams'), fmt='jams') os.rmdir(tdir) # Make a non-json file tdir = tempfile.mkdtemp() badfile = os.path.join(tdir, 'nonexistent.jams') with open(badfile, mode='w') as fp: fp.write('some garbage') with pytest.raises(ValueError): jams.load(os.path.join(tdir, 'nonexistent.jams'), fmt='jams') os.unlink(badfile) os.rmdir(tdir) tdir = tempfile.mkdtemp() for ext in ['txt', '']: badfile = os.path.join(tdir, 'nonexistent') with pytest.raises(jams.ParameterError): jams.load('{:s}.{:s}'.format(badfile, ext), fmt='auto') with pytest.raises(jams.ParameterError): jams.load('{:s}.{:s}'.format(badfile, ext), fmt=ext) with pytest.raises(jams.ParameterError): jams.load('{:s}.jams'.format(badfile, ext), fmt=ext) # one last test, trying to load form a non-file-like object with pytest.raises(jams.ParameterError): jams.load(None, fmt='auto') os.rmdir(tdir)
def compute_gt_results(est_file, ref_file, boundaries_id, labels_id, config, bins=251, annotator_id=0): """Computes the results by using the ground truth dataset identified by the annotator parameter. Return ------ results : dict Dictionary of the results (see function compute_results). """ try: if config["hier"]: ref_times, ref_labels, ref_levels = \ msaf.io.read_hier_references( ref_file, annotation_id=0, exclude_levels=["segment_salami_function"]) else: jam = jams.load(ref_file, validate=False) ann = jam.search(namespace='segment_.*')[annotator_id] ref_inter, ref_labels = ann.data.to_interval_values() except: logging.warning("No references for file: %s" % ref_file) return {} # Read estimations with correct configuration est_inter, est_labels = io.read_estimations(est_file, boundaries_id, labels_id, **config) if len(est_inter) == 0: logging.warning("No estimations for file: %s" % est_file) return {} # Compute the results and return logging.info("Evaluating %s" % os.path.basename(est_file)) if config["hier"]: # Hierarchical assert len(est_inter) == len(est_labels), "Same number of levels " \ "are required in the boundaries and labels for the hierarchical " \ "evaluation." est_times = [] est_labels = [] # Sort based on how many segments per level est_inter = sorted(est_inter, key=lambda level: len(level)) for inter in est_inter: est_times.append(msaf.utils.intervals_to_times(inter)) # Add fake labels (hierarchical eval does not use labels --yet--) est_labels.append(np.ones(len(est_times[-1]) - 1) * -1) # Align the times utils.align_end_hierarchies(est_times, ref_times, thres=1) # To intervals est_hier = [utils.times_to_intervals(times) for times in est_times] ref_hier = [utils.times_to_intervals(times) for times in ref_times] # Compute evaluations res = {} res["t_recall10"], res["t_precision10"], res["t_measure10"] = \ mir_eval.hierarchy.tmeasure(ref_hier, est_hier, window=10) res["t_recall15"], res["t_precision15"], res["t_measure15"] = \ mir_eval.hierarchy.tmeasure(ref_hier, est_hier, window=15) res["track_id"] = os.path.basename(est_file)[:-5] return res else: # Flat return compute_results(ref_inter, est_inter, ref_labels, est_labels, bins, est_file)
def input_jam(): return jams.load('tests/fixtures/valid.jams')
def to_jams(self): """Jams: the track's data in jams format""" return jams.load(self.jams_path)
def test_jams_save(input_jam, output_path): input_jam.save(output_path) reload_jam = jams.load(output_path) assert input_jam == reload_jam
def test_generate(atol=1e-4, rtol=1e-8): # Final regression test on all files sc = scaper.Scaper(10.0, fg_path=FG_PATH, bg_path=BG_PATH) sc.ref_db = -50 # background sc.add_background( label=('const', 'park'), source_file=('const', 'tests/data/audio/background/park/' '268903__yonts__city-park-tel-aviv-israel.wav'), source_time=('const', 0)) # foreground events sc.add_event(label=('const', 'siren'), source_file=('const', 'tests/data/audio/foreground/' 'siren/69-Siren-1.wav'), source_time=('const', 5), event_time=('const', 2), event_duration=('const', 5), snr=('const', 5), pitch_shift=None, time_stretch=None) sc.add_event(label=('const', 'car_horn'), source_file=('const', 'tests/data/audio/foreground/' 'car_horn/17-CAR-Rolls-Royce-Horn.wav'), source_time=('const', 0), event_time=('const', 5), event_duration=('const', 2), snr=('const', 20), pitch_shift=('const', 1), time_stretch=None) sc.add_event( label=('const', 'human_voice'), source_file=('const', 'tests/data/audio/foreground/' 'human_voice/42-Human-Vocal-Voice-taxi-2_edit.wav'), source_time=('const', 0), event_time=('const', 7), event_duration=('const', 2), snr=('const', 10), pitch_shift=None, time_stretch=('const', 1.2)) tmpfiles = [] with _close_temp_files(tmpfiles): wav_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=True) jam_file = tempfile.NamedTemporaryFile(suffix='.jams', delete=True) txt_file = tempfile.NamedTemporaryFile(suffix='.txt', delete=True) tmpfiles.append(wav_file) tmpfiles.append(jam_file) tmpfiles.append(txt_file) sc.generate(wav_file.name, jam_file.name, txt_path=txt_file.name, disable_instantiation_warnings=True) # validate audio wav, sr = soundfile.read(wav_file.name) regwav, sr = soundfile.read(REG_WAV_PATH) assert np.allclose(wav, regwav, atol=atol, rtol=rtol) # validate jams jam = jams.load(jam_file.name) regjam = jams.load(REG_JAM_PATH) # version might change, rest should be the same regjam.annotations[0].sandbox.scaper['scaper_version'] = \ scaper.__version__ assert jam == regjam # validate txt txt = pd.read_csv(txt_file.name, header=None, sep='\t') regtxt = pd.read_csv(REG_TXT_PATH, header=None, sep='\t') assert (txt == regtxt).all().all() # reverb value must be in (0, 1) range for reverb in [-1, 2]: pytest.raises(ScaperError, sc.generate, wav_file.name, jam_file.name, reverb=reverb, disable_instantiation_warnings=True)