Exemplo n.º 1
0
def pulse_finder_file(file,
                      freq_range,
                      pulse_rate_range,
                      window_len,
                      rejection_bands=None,
                      plot=False):
    """a wrapper for pulse_finder with takes an audio file path as an argument
    
    creates the audio object and spectrogram within the function
    
    Args:
        file: path to an audio file
        freq_range: range to bandpass the spectrogram, in Hz
        pulse_rate_range: how many pulses per second? (where to look in the fft of the smoothed-amplitude), in Hz
        rejection_bands: list of frequency bands to subtract from the desired freq_range
        plot=False : if True, plot figures
    
    Returns:
        array of pulse_score: pulse score (float) for each time window
        array of time: start time of each window
    
    """
    # make spectrogram from file path
    audio = Audio(file)
    spec = Spectrogram.from_audio(audio)

    pulse_scores, window_start_times = pulse_finder(spec, freq_range,
                                                    pulse_rate_range,
                                                    window_len,
                                                    rejection_bands, plot)

    return pulse_scores, window_start_times
Exemplo n.º 2
0
    def image_from_audio(self, audio, mode="RGB"):
        """ Create a PIL image from audio

        Inputs:
            audio: audio object
            mode: PIL image mode, e.g. "L" or "RGB" [default: RGB]
        """
        spectrogram = Spectrogram.from_audio(audio)
        return spectrogram.to_image(shape=(self.width, self.height), mode=mode)
Exemplo n.º 3
0
def test_spectrogram_shape_of_veryshort(veryshort_wav_str):
    audio = Audio.from_file(veryshort_wav_str, sample_rate=22050)
    spec = Spectrogram.from_audio(audio, overlap_samples=384)
    assert spec.spectrogram.shape == (257, 21)
    assert spec.frequencies.shape == (257, )
    assert spec.times.shape == (21, )
    assert isclose(spec.window_length(), 0.02321995465, abs_tol=1e-4)
    assert isclose(spec.window_step(), 0.005804988662, abs_tol=1e-4)
    assert isclose(spec.duration(), audio.duration(), abs_tol=1e-2)
    assert isclose(spec.window_start_times()[0], 0, abs_tol=1e-4)
Exemplo n.º 4
0
def test_ribbit():
    path = "./tests/audio/silence_10s.mp3"
    audio = Audio.from_file(path, sample_rate=22050)
    spec = Spectrogram.from_audio(audio)

    scores, times = ribbit.ribbit(
        spec,
        pulse_rate_range=[5, 10],
        signal_band=[1000, 2000],
        window_len=5.0,
        noise_bands=[[0, 200]],
        plot=True,
    )
    assert len(scores) > 0
def test_pulse_finder():
    path = "./tests/silence_10s.mp3"
    audio = Audio(path)
    spec = Spectrogram.from_audio(audio)

    scores, times = pulse_finder(
        spec,
        pulse_rate_range=[5, 10],
        freq_range=[1000, 2000],
        window_len=5.0,
        rejection_bands=[[0, 200]],
        plot=True,
    )
    assert len(scores) > 0
Exemplo n.º 6
0
def process_audio(func_name, audio_io):
    """
    Check inputs and return spectrogram images

    Check that inputs are in correct format (single-channel,
    between 5-20 seconds), and convert to images

    Args:
        func_name (str): name of calling function (for printing)
        audio_io (bytes):

    Returns:
        array of 299x299 images, each representing up to
            5s of the original audio

    """
    print(f"runserver.py: {func_name}() checking inputs")
    # Just return error if no data was posted
    if not audio_io:
        return {"error": "No data was given with post?"}

    # Make sure we can load the data given to us
    print(f"runserver.py: {func_name}() loading samples")
    try:
        audio = Audio.from_bytesio(
            audio_io, sample_rate=22050, resample_type="kaiser_fast"
        )
    except:
        return {"error": "Unable to load audio, multi-chennel input is ignored"}
    print(
        f"runserver.py: {func_name}() loaded samples at sample_rate {audio.sample_rate}"
    )

    # Check the duration is between 5 and 20 seconds
    duration = audio.duration()
    if duration < 5:
        return {"error": "Audio is shorter than 5 seconds"}
    elif duration > 20:
        return {"error": "Audio is longer than 20 seconds"}

    # 1. split audio into 5 second chunks
    # 2. generate spectrograms
    # 3. generate images
    audio_splits = birds_detector.split_audio(audio)
    spectrograms = [Spectrogram.from_audio(x) for x in audio_splits]
    images = [x.to_image(shape=(224, 224)) for x in spectrograms]

    print(f"runserver.py: {func_name}(), opening audio as spectrograms")
    return {"images": images}
Exemplo n.º 7
0
def test_summarize_top_scores(gpt_path):
    df = pd.DataFrame(columns=[
        "species",
        "pulse_rate_low",
        "pulse_rate_high",
        "low_f",
        "high_f",
        "reject_low",
        "reject_high",
        "window_length",
    ])
    df.at[0, :] = ["sp1", 5, 10, 1000, 2000, 0, 500, 1.0]
    df.at[1, :] = ["sp2", 10, 15, 1000, 2000, 0, 500, 1.0]
    audio = Audio.from_file(gpt_path, sample_rate=32000)
    spec = Spectrogram.from_audio(audio, overlap_samples=256)
    df = ribbit.pulse_finder_species_set(spec, df)

    ribbit.summarize_top_scores(["1", "2"], [df, df], scale_factor=10.0)
Exemplo n.º 8
0
def test_ribbit_short_audio(veryshort_wav_str):
    audio = Audio.from_file(veryshort_wav_str, sample_rate=22050)
    spec = Spectrogram.from_audio(audio,
                                  window_samples=512,
                                  overlap_samples=256,
                                  decibel_limits=(-100, -20))

    df = ribbit.ribbit(
        spec,
        pulse_rate_range=[5, 10],
        signal_band=[1000, 2000],
        clip_duration=5.0,
        clip_overlap=2.5,
        final_clip=None,
        noise_bands=[[0, 200]],
        plot=False,
    )
    assert len(df) == 0
Exemplo n.º 9
0
def test_pulsefinder_species_set(gpt_path):
    df = pd.DataFrame(columns=[
        "species",
        "pulse_rate_low",
        "pulse_rate_high",
        "low_f",
        "high_f",
        "reject_low",
        "reject_high",
        "window_length",
    ])
    df.at[0, :] = ["sp1", 5, 10, 1000, 2000, 0, 500, 1.0]
    df.at[1, :] = ["sp2", 10, 15, 1000, 2000, 0, 500, 1.0]

    audio = Audio.from_file(gpt_path, sample_rate=32000)
    spec = Spectrogram.from_audio(audio, overlap_samples=256)

    df = ribbit.pulse_finder_species_set(spec, df)

    assert type(df) == pd.DataFrame
Exemplo n.º 10
0
def test_ribbit_high_spec_overlap(gpt_path):
    """spec params should not effect number of clips in results"""
    audio = Audio.from_file(gpt_path, sample_rate=22050).trim(0, 16)
    spec = Spectrogram.from_audio(audio,
                                  window_samples=512,
                                  overlap_samples=500,
                                  decibel_limits=(-100, -20))

    df = ribbit.ribbit(
        spec,
        pulse_rate_range=[5, 10],
        signal_band=[1000, 2000],
        clip_duration=5.0,
        clip_overlap=0,
        final_clip=None,
        noise_bands=[[0, 200]],
        plot=False,
    )
    assert len(df) == 3
    assert isclose(max(df["start_time"]), 10.0, abs_tol=1e-4)
Exemplo n.º 11
0
def test_ribbit(gpt_path):
    audio = Audio.from_file(gpt_path, sample_rate=22050).trim(0, 16)

    spec = Spectrogram.from_audio(audio,
                                  window_samples=512,
                                  overlap_samples=256,
                                  decibel_limits=(-100, -20))

    df = ribbit.ribbit(
        spec,
        pulse_rate_range=[5, 10],
        signal_band=[1000, 2000],
        clip_duration=5.0,
        clip_overlap=0,
        final_clip=None,
        noise_bands=[[0, 200]],
        plot=False,
    )

    assert len(df) == 3
    assert isclose(max(df["score"]), 0.0392323, abs_tol=1e-4)
Exemplo n.º 12
0
def test_pulsefinder_species_set():
    path = "./tests/great_plains_toad.wav"
    df = pd.DataFrame(columns=[
        "species",
        "pulse_rate_low",
        "pulse_rate_high",
        "low_f",
        "high_f",
        "reject_low",
        "reject_high",
        "window_length",
    ])
    df.at[0, :] = ["sp1", 5, 10, 1000, 2000, 0, 500, 1.0]
    df.at[1, :] = ["sp2", 10, 15, 1000, 2000, 0, 500, 1.0]

    audio = Audio(path, sample_rate=32000)
    spec = Spectrogram.from_audio(audio, overlap_samples=256)

    df = pulse_finder_species_set(spec, df)

    assert type(df) == pd.DataFrame
Exemplo n.º 13
0
def test_spectrogram_shape_of_veryshort(veryshort_wav_str):
    audio = Audio.from_file(veryshort_wav_str, sample_rate=22050)
    spec = Spectrogram.from_audio(audio, overlap_samples=384)
    assert spec.spectrogram.shape == (257, 21)
    assert spec.frequencies.shape == (257, )
    assert spec.times.shape == (21, )
Exemplo n.º 14
0
def test_spectrogram_raises_typeerror():
    with pytest.raises(TypeError):
        Spectrogram.from_audio("not samples")
Exemplo n.º 15
0
 def go(self, audio):
     return Spectrogram.from_audio(audio, **self.params)