コード例 #1
0
ファイル: augment.py プロジェクト: paepcke/birds
 def create_original_spectrograms(self, samples, n, species_wav_input_dir,
                                  species_spectrogram_output_dir):
     samples = random.sample(samples, int(n))  # choose n from all samples
     for sample_name in samples:
         SoundProcessor.create_spectrogram(sample_name,
                                           species_wav_input_dir,
                                           species_spectrogram_output_dir,
                                           n_mels=128)
コード例 #2
0
ファイル: test_sound_processor.py プロジェクト: paepcke/birds
    def test_create_one_spectro(self):

        # Test creating one spectrogram from an audio
        # file. Ensure that sample rate, duration, and
        # species are included int the destination spectrogram
        # .png file:
        audio_path = os.path.join(self.cur_dir,
                                  'audio_aug_tst_data/DYSMEN_S/dys1.mp3')
        (aud, sr) = SoundProcessor.load_audio(audio_path)
        with tempfile.NamedTemporaryFile(suffix='.png',
                                         prefix='spectro',
                                         dir='/tmp',
                                         delete=True) as fd:
            SoundProcessor.create_spectrogram(aud,
                                              sr,
                                              fd.name,
                                              info={'species': 'DYSMEN_C'})
            _spectro, info = SoundProcessor.load_spectrogram(fd.name)
            truth = {'sr': '22050', 'duration': '10.8', 'species': 'DYSMEN_C'}
            self.assertDictEqual(info, truth)
コード例 #3
0
ファイル: augment.py プロジェクト: paepcke/birds
    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)
コード例 #4
0
    def chop_one_audio_file(self, in_dir, species, spectro_fname, out_dir, window_len = 5):
        """
        Generates window_len second sound file snippets
        and associated spectrograms from sound files of
        arbitrary length. 
        
        Performs a time shift on all the wav files in the 
        species directories. The shift is 'rolling' such that
        no information is lost.
    
        :param in_dir: directory of the audio file to chop 
        :type file_name: str
        :param species: the directory names of the species to 
            modify the wav files of. If species=None, all 
            subdirectories will be processed.
        :type species: {None | [str]}
        :param spectro_fname: basefile name of audio file to chop
        :type spectro_fname: str
        :param out_dir: root directory under which spectrogram
            and audio snippets will be saved (in different subdirs)
        :type out_dir: str
        """

        orig, sample_rate = librosa.load(os.path.join(in_dir, species, spectro_fname))
        length = int(librosa.get_duration(orig, sample_rate))
        for start_time in range(length - window_len):
            fpath = Path(spectro_fname)
            window_name = f"{fpath.stem}_sw-start{str(start_time)}"
            window_file_name = str(Path.joinpath(fpath.parent, window_name))

            outfile_spectro = os.path.join(out_dir, 
                                           'spectrograms/', 
                                           species,
                                           f"{window_file_name}.png")
            
            outfile_audio = os.path.join(out_dir, 
                                         'wav-files', 
                                         species, 
                                         f"{window_file_name}.{'wav'}")
            
            
            spectro_done = os.path.exists(outfile_spectro)
            audio_done   = os.path.exists(outfile_audio)

            if spectro_done and audio_done and WhenAlreadyDone.SKIP:
                # No brainer no need to even read the audio excerpt:
                continue
            
            if spectro_done and not audio_done and not self.generate_wav_files:
                continue

            # Need an audio snippet either for
            # a spectrogram or wav file:
            window_audio, sr = librosa.load(os.path.join(in_dir, species, spectro_fname),
                                      offset=start_time, duration=window_len)

            if not spectro_done or (spectro_done and self.overwrite_policy != WhenAlreadyDone.SKIP):
                SoundProcessor.create_spectrogram(window_audio,sr,outfile_spectro)
            

            if self.generate_wav_files:
                if audio_done and self.overwrite_policy == WhenAlreadyDone.SKIP:
                    continue 
                else:
                    sf.write(outfile_audio, window_audio, sr)