def test_time_shift(self): with tempfile.TemporaryDirectory(prefix='aud_tests', dir='/tmp') as tmpdir_nm: out_file = SoundProcessor.time_shift(self.one_aud_file, tmpdir_nm) # Can't do more than try to load the new # file and check its length against manually # examined truth: self.assertEqualDurSR(out_file, self.one_aud_file)
def create_new_sample(self, sample_path, out_dir, method, noise_path=None): ''' Given one audio recording and an audio augmentation method name, compute that augmentation, create a file name that gives insight into the aug applied, and write that new audio file to out_dir. Currently available types of audio augmentation technique: o adding background sounds o randomly changing volume o random time shifts Returns the full path of the newly created audio file: :param sample_path: absolute path to audio sample :type sample_path: str :param out_dir: destination of resulting new samples :type out_dir: src :param method: the audio augmentation method to apply :type method: AudAugMethod :param noise_path: full path to audio files with background noises to overlay onto audio (wind, rain, etc.). Ignored unless method is AudAugMethod.ADD_NOISE. :type noise_path: str :return: Newly created audio file (full path) or an Exception object whose e.args attribute is a tuple with the error msg plus a manually added one :rtype: {str | Exception} ''' failures = None out_path = None if method == AudAugMethod.ADD_NOISE: if noise_path is None: noise_path = AudioAugmenter.NOISE_PATH # Add rain, wind, or such at random: try: out_path = SoundProcessor.add_background( sample_path, self.NOISE_PATH, out_dir, len_noise_to_add=5.0) except Exception as e: sample_fname = Path(sample_path).stem msg = f"Failed to add background sounds to {sample_fname} ({repr(e)})" self.log.err(msg) e.args = tuple([e.args[0], msg]) failures = e elif method == AudAugMethod.TIME_SHIFT: try: out_path = SoundProcessor.time_shift(sample_path, out_dir) except Exception as e: sample_fname = Path(sample_path).stem msg = f"Failed to time shift on {sample_fname} ({repr(e)})" self.log.err(msg) e.args = tuple([e.args[0], msg]) failures = e elif method == AudAugMethod.VOLUME: try: out_path = SoundProcessor.change_sample_volume(sample_path, out_dir) except Exception as e: sample_fname = Path(sample_path).stem msg = f"Failed to modify volume on {sample_fname} ({repr(e)})" self.log.err(msg) e.args = tuple([e.args[0], msg]) failures = e return out_path if failures is None else failures
def create_new_sample(self, sample_name, paths, num_augs=1): (species_wav_input_dir, species_wav_output_dir, species_spectrogram_output_dir) = paths aug_choices = np.random.choice(self.AUDIO_AUG_NAMES, size=num_augs, p=self.P_DIST, replace=False) # input(f"Aug choices: {aug_choices}") # Warping must be done after all the other augmentations take place, # after spectrogram is created warp = False if "warp" in aug_choices: warp = True aug_choices = aug_choices.tolist() # print(f"Aug chioces as list: {aug_choices}") aug_choices.remove("warp") # print(f"Aug chioces after: {aug_choices}") for i in range(len(aug_choices)): # print(aug_choices) aug_name = aug_choices[i] if i != 0: # if not first augmentation, then, source wav is in output wav directory species_wav_input_dir = species_wav_output_dir if aug_name == "add_noise": # Add_noise; which noise to add will be chosen at random updated_name = SoundProcessor.add_background( sample_name, self.NOISE_PATH, species_wav_input_dir, species_wav_output_dir, len_noise_to_add=5.0) elif aug_name == "time_shift": updated_name = SoundProcessor.time_shift( sample_name, species_wav_input_dir, species_wav_output_dir) sample_name = updated_name # create new spectrogram if augmented if len(aug_choices) != 0: sample_name = SoundProcessor.create_spectrogram( sample_name, species_wav_output_dir, species_spectrogram_output_dir, n_mels=128) if warp: #warp # if len(aug_choices) +1 > 1: # input(f"num_augs = {len(aug_choices) +1} for {sample_name}") sample_name = sample_name[:-len(".wav")] + ".png" # Above: if sample is unaugmented to this point, sample_name will be # *.wav. Since SoundProcessor.warp_spectrogram expects sample_name to be *.png, we # replace extension. If augmented and sample_name is already *.png, # there is no change. warped_name = SoundProcessor.warp_spectrogram( sample_name, species_spectrogram_output_dir, species_spectrogram_output_dir) # if warp is not the only augmentation, # we do not want spectrogram before warp if len(aug_choices) != 0: assert (warped_name != sample_name) fname = os.path.join(species_spectrogram_output_dir, sample_name) os.remove(fname)