def test_short_background_fg_events(): foreground_fd = os.path.join(absolute_dir_path, "material", "soundbank", "foreground") background_fd = os.path.join(absolute_dir_path, "material", "soundbank", "background") sc = Scaper(10, foreground_fd, background_fd, random_state=2020) sc.sr = 16000 sc.add_background( ("const", "label"), ("const", os.path.join(background_fd, "label", "noise-free-sound-0055.wav")), ("const", 0)) fname = "test_bg_fg" fpath = os.path.join(absolute_dir_path, "generated", "short_bg_scaper", fname) sc.add_event( ("const", "label"), ("const", os.path.join(foreground_fd, "label", "26104_0.wav")), ("const", 0), ("const", 5), ("const", 5), ("const", 6), ("const", 0), ("const", 1)) sc.generate(f"{fpath}.wav", f"{fpath}.jams") audio_g, sr_g = soundfile.read(f"{fpath}.wav") audio_s, sr_s = soundfile.read( os.path.join(absolute_dir_path, "material", "scaper", f"{fname}.wav")) print(f"audio gen: {audio_g}") print(f"audio source: {audio_s}") print(f"shapes, source: {audio_s.shape}, gen: {audio_g.shape}") assert audio_g.shape == audio_s.shape
def __test_gini_from_event_times(event_time_list, expected_gini, hop_size=0.01): print(event_time_list) # create scaper sc = Scaper(10.0, FG_PATH, BG_PATH) # add background sc.add_background(label=('choose', []), source_file=('choose', []), source_time=('const', 0)) # add foreground events based on the event time list # always use siren file since it is 26 s long, so we can choose the # event duration flexibly for onset, offset in event_time_list: sc.add_event(label=('const', 'siren'), source_file=('const', SIREN_FILE), source_time=('const', 0), event_time=('const', onset), event_duration=('const', offset - onset), snr=('uniform', 6, 30), pitch_shift=('uniform', -3, 3), time_stretch=None) jam = sc._instantiate() ann = jam.annotations[0] gini = polyphony_gini(ann, hop_size=hop_size) print(gini, expected_gini) assert np.allclose([gini], [expected_gini], atol=1e-5)
def mix_with_scaper(num_mixtures, foreground_path, background_path, scene_duration, sample_rate, target_folder, event_parameters, num_sources=None, labels=None, coherent=False, allow_repeated_label=False, ref_db=-40, bitdepth=16, seed=0, num_workers=1): nussl.utils.seed(seed) os.makedirs(target_folder, exist_ok=True) scaper_seed = np.random.randint(100) logging.info('Starting mixing.') if num_sources is None and labels is None: raise ValueError("One of labels or num_sources must be set!") if coherent and labels is None: raise ValueError("Coherent mixing requires explicit labels!") generators = [] if background_path is None: background_path = foreground_path for i in range(num_mixtures): sc = Scaper( scene_duration, fg_path=foreground_path, bg_path=background_path, random_state=scaper_seed, ) sc.ref_db = ref_db sc.sr = sample_rate sc.bitdepth = bitdepth generators.append(sc) scaper_seed += 1 mix_func = make_one_mixture_coherent if coherent else make_one_mixture def arg_tuple(i): _args = (generators[i], os.path.join(target_folder, f'{i:08d}.wav'), labels if coherent else num_sources, event_parameters, allow_repeated_label) return _args args = [arg_tuple(i) for i in range(num_mixtures)] # do one by itself for testing mix_func(*args[0]) args = list(zip(*args[1:])) args = [list(a) for a in args] # now do the rest in parallel p_tqdm.p_map(mix_func, *args, num_cpus=num_workers)
def test_polyphony_gini(): ''' Test computation of polyphony gini ''' # Annotation must have namespace scaper, otherwise raise error ann = jams.Annotation('tag_open', duration=10) gini = pytest.raises(ScaperError, polyphony_gini, ann) # Annotation without duration set should raise error ann = jams.Annotation('scaper', duration=None) gini = pytest.raises(ScaperError, polyphony_gini, ann) # Annotation with no foreground events returns a gini of 0 sc = Scaper(10.0, FG_PATH, BG_PATH) # add background sc.add_background(label=('choose', []), source_file=('choose', []), source_time=('const', 0)) jam = sc._instantiate() ann = jam.annotations[0] gini = polyphony_gini(ann) assert gini == 0 def __test_gini_from_event_times(event_time_list, expected_gini, hop_size=0.01): print(event_time_list) # create scaper sc = Scaper(10.0, FG_PATH, BG_PATH) # add background sc.add_background(label=('choose', []), source_file=('choose', []), source_time=('const', 0)) # add foreground events based on the event time list # always use siren file since it is 26 s long, so we can choose the # event duration flexibly for onset, offset in event_time_list: sc.add_event(label=('const', 'siren'), source_file=('const', SIREN_FILE), source_time=('const', 0), event_time=('const', onset), event_duration=('const', offset - onset), snr=('uniform', 6, 30), pitch_shift=('uniform', -3, 3), time_stretch=None) jam = sc._instantiate() ann = jam.annotations[0] gini = polyphony_gini(ann, hop_size=hop_size) print(gini, expected_gini) assert np.allclose([gini], [expected_gini], atol=1e-5) event_time_lists = ([[], [(0, 1)], [(0, 5), (5, 10)], [(0, 10), (3, 7), (4, 6)]]) expected_ginis = [0, 0.1, 1, 0.75] for etl, g in zip(event_time_lists, expected_ginis): __test_gini_from_event_times(etl, g, hop_size=0.01) for etl, g in zip(event_time_lists, expected_ginis): __test_gini_from_event_times(etl, g, hop_size=1.0)
def scaper_mix( mixture_parameters, sample_rate, event_parameters=None, coherent=False, ref_db=-40, bitdepth=16, seed=0, num_workers=1, ): np.random.seed(seed) logging.info('Making JAMS files') for key, params in mixture_parameters.items(): if 'event_parameters' in params: _event_parameters = params['event_parameters'] else: _event_parameters = event_parameters generators = [] logging.info('Making generators') bg_path = params['background_path'] if not bg_path: bg_path = params['foreground_path'] for i in tqdm(range(params['num_mixtures'])): sc = Scaper( params['scene_duration'], fg_path=params['foreground_path'], bg_path=bg_path, random_state=np.random.randint(params['num_mixtures']*10) ) sc.ref_db = ref_db sc.sr = sample_rate sc.bitdepth = bitdepth generators.append(sc) os.makedirs(params['target_path'], exist_ok=True) timings = {} silent_files = {'default': True} if coherent: args = [ { 'path_to_file': os.path.join(params['target_path'], f'{i:08d}.wav'), 'sc': generators[i], 'labels': params['labels'], 'event_parameters': _event_parameters, } for i in range(params['num_mixtures']) ] mix_func = make_one_mixture_coherent else: args = [ { 'path_to_file': os.path.join(params['target_path'], f'{i:08d}.wav'), 'sc': generators[i], 'num_sources': params['num_sources'], 'event_parameters': _event_parameters, } for i in range(params['num_mixtures']) ] mix_func = make_one_mixture parallel_process(args, mix_func, n_jobs=num_workers, front_num=1, use_kwargs=True) logging.info(f'Synthesizing mixtures in parallel across {num_workers} threads') for key, params in mixture_parameters.items(): synthesize_mixtures_in_parallel(params['target_path'], num_workers)
def test_polyphony_gini(): ''' Test computation of polyphony gini ''' # Annotation must have namespace scaper, otherwise raise error ann = jams.Annotation('tag_open', duration=10) gini = pytest.raises(ScaperError, polyphony_gini, ann) # Annotation without duration set should raise error ann = jams.Annotation('scaper', duration=None) gini = pytest.raises(ScaperError, polyphony_gini, ann) # Annotation with no foreground events returns a gini of 0 sc = Scaper(10.0, FG_PATH, BG_PATH) # add background sc.add_background(label=('choose', []), source_file=('choose', []), source_time=('const', 0)) jam = sc._instantiate() ann = jam.annotations[0] gini = polyphony_gini(ann) assert gini == 0 def __test_gini_from_event_times(event_time_list, expected_gini, hop_size=0.01): print(event_time_list) # create scaper sc = Scaper(10.0, FG_PATH, BG_PATH) # add background sc.add_background(label=('choose', []), source_file=('choose', []), source_time=('const', 0)) # add foreground events based on the event time list # always use siren file since it is 26 s long, so we can choose the # event duration flexibly for onset, offset in event_time_list: sc.add_event(label=('const', 'siren'), source_file=('const', SIREN_FILE), source_time=('const', 0), event_time=('const', onset), event_duration=('const', offset - onset), snr=('uniform', 6, 30), pitch_shift=('uniform', -3, 3), time_stretch=None) jam = sc._instantiate() ann = jam.annotations[0] gini = polyphony_gini(ann, hop_size=hop_size) print(gini, expected_gini) assert np.allclose([gini], [expected_gini], atol=1e-5) event_time_lists = ([ [], [(0, 1)], [(0, 5), (5, 10)], [(0, 10), (3, 7), (4, 6)] ]) expected_ginis = [0, 0.1, 1, 0.75] for etl, g in zip(event_time_lists, expected_ginis): __test_gini_from_event_times(etl, g, hop_size=0.01) for etl, g in zip(event_time_lists, expected_ginis): __test_gini_from_event_times(etl, g, hop_size=1.0)