Skip to content

bioamla.indices

bioamla.indices

Acoustic indices for soundscape ecology.

Compute standard ecoacoustic indices (ACI, ADI, AEI, BIO, NDSI) plus spectral and temporal entropy from audio signals.

Example

from bioamla.audio import load_audio_data from bioamla.indices import compute_all_indices audio = load_audio_data("recording.wav") idx = compute_all_indices(audio.samples, audio.sample_rate, include_entropy=True) print(idx.aci, idx.ndsi)

AcousticIndices dataclass

Container for all acoustic indices computed from an audio signal.

Attributes:

Name Type Description
aci float

Acoustic Complexity Index

adi float

Acoustic Diversity Index

aei float

Acoustic Evenness Index

bio float

Bioacoustic Index

ndsi float

Normalized Difference Soundscape Index

anthrophony float

Anthrophony component (1-2 kHz)

biophony float

Biophony component (2-8 kHz)

sample_rate int

Sample rate used for computation

duration float

Duration of audio in seconds

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

batch_compute_indices

batch_compute_indices(
    filepaths: list[str | Path],
    verbose: bool = True,
    **kwargs: Any,
) -> list[dict[str, Any]]

Compute acoustic indices for multiple audio files.

Parameters:

Name Type Description Default
filepaths list[str | Path]

List of paths to audio files.

required
verbose bool

Print progress.

True
**kwargs Any

Additional arguments passed to compute_all_indices.

{}

Returns:

Type Description
list[dict[str, Any]]

List of dictionaries with indices and file information.

Example

files = ["file1.wav", "file2.wav", "file3.wav"] results = batch_compute_indices(files) for r in results: ... print(f"{r['filepath']}: NDSI={r['ndsi']:.3f}")

compute_aci

compute_aci(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
    min_freq: float = 0.0,
    max_freq: float | None = None,
    j: int = 5,
    precomputed_spec: tuple[ndarray, ndarray, ndarray]
    | None = None,
) -> float

Compute the Acoustic Complexity Index (ACI).

ACI measures the variability of sound intensities within frequency bands over time. Higher values indicate more complex acoustic environments, often associated with higher biodiversity.

The index is computed by calculating the absolute difference between adjacent amplitude values in each frequency bin, then summing across time and dividing by the total amplitude.

Reference

Pieretti, N., Farina, A., & Morri, D. (2011). A new methodology to infer the singing activity of an avian community: The Acoustic Complexity Index (ACI). Ecological Indicators, 11(3), 868-873.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size (default: 512).

512
hop_length int | None

Hop length (default: n_fft // 2).

None
min_freq float

Minimum frequency to consider in Hz.

0.0
max_freq float | None

Maximum frequency to consider in Hz (default: Nyquist).

None
j int

Number of temporal steps to cluster (default: 5).

5
precomputed_spec tuple[ndarray, ndarray, ndarray] | None

Optional precomputed (spectrogram, frequencies, times) tuple in LINEAR AMPLITUDE format (not dB).

None

Returns:

Type Description
float

Acoustic Complexity Index value.

Example

aci = compute_aci(audio, 22050, min_freq=2000, max_freq=8000)

compute_adi

compute_adi(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
    max_freq: float = 10000.0,
    freq_step: float = 1000.0,
    db_threshold: float = -50.0,
    precomputed_spec: tuple[ndarray, ndarray, ndarray]
    | None = None,
) -> float

Compute the Acoustic Diversity Index (ADI).

ADI is based on the Shannon diversity index applied to frequency bands. It measures the evenness of sound distribution across frequency bands. Higher values indicate more evenly distributed acoustic energy across frequency bands, suggesting higher acoustic diversity.

Reference

Villanueva-Rivera, L. J., Pijanowski, B. C., Doucette, J., & Pekin, B. (2011). A primer of acoustic analysis for landscape ecologists. Landscape Ecology, 26(9), 1233-1246.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

512
hop_length int | None

Hop length (default: n_fft // 2).

None
max_freq float

Maximum frequency to analyze in Hz.

10000.0
freq_step float

Frequency band width in Hz.

1000.0
db_threshold float

Threshold in dB for considering sound present.

-50.0
precomputed_spec tuple[ndarray, ndarray, ndarray] | None

Optional precomputed (spectrogram, frequencies, times) tuple in LINEAR AMPLITUDE format (not dB).

None

Returns:

Type Description
float

Acoustic Diversity Index value.

Example

adi = compute_adi(audio, 22050, max_freq=10000, freq_step=1000)

compute_aei

compute_aei(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
    max_freq: float = 10000.0,
    freq_step: float = 1000.0,
    db_threshold: float = -50.0,
    precomputed_spec: tuple[ndarray, ndarray, ndarray]
    | None = None,
) -> float

Compute the Acoustic Evenness Index (AEI).

AEI is based on the Gini coefficient applied to frequency bands. It measures the evenness of sound energy distribution across frequency bands. Lower values indicate more even distribution (higher evenness), while higher values indicate more uneven distribution.

Reference

Villanueva-Rivera, L. J., Pijanowski, B. C., Doucette, J., & Pekin, B. (2011). A primer of acoustic analysis for landscape ecologists. Landscape Ecology, 26(9), 1233-1246.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

512
hop_length int | None

Hop length (default: n_fft // 2).

None
max_freq float

Maximum frequency to analyze in Hz.

10000.0
freq_step float

Frequency band width in Hz.

1000.0
db_threshold float

Threshold in dB for considering sound present.

-50.0
precomputed_spec tuple[ndarray, ndarray, ndarray] | None

Optional precomputed (spectrogram, frequencies, times) tuple in LINEAR AMPLITUDE format (not dB).

None

Returns:

Type Description
float

Acoustic Evenness Index value (Gini coefficient).

Example

aei = compute_aei(audio, 22050, max_freq=10000)

compute_all_indices

compute_all_indices(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
    aci_min_freq: float = 0.0,
    aci_max_freq: float | None = None,
    adi_max_freq: float = 10000.0,
    adi_freq_step: float = 1000.0,
    bio_min_freq: float = 2000.0,
    bio_max_freq: float = 8000.0,
    db_threshold: float = -50.0,
    include_entropy: bool = False,
) -> AcousticIndices

Compute all acoustic indices at once.

This is more efficient than computing indices individually as the spectrogram is only computed once and reused across all indices.

PERFORMANCE OPTIMIZATION: This function computes the spectrogram ONCE and passes it to all index functions, avoiding redundant STFT computations which are the most expensive operation (~4-5x speedup vs calling indices separately).

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

512
hop_length int | None

Hop length (default: n_fft // 2).

None
aci_min_freq float

Minimum frequency for ACI in Hz.

0.0
aci_max_freq float | None

Maximum frequency for ACI in Hz.

None
adi_max_freq float

Maximum frequency for ADI/AEI in Hz.

10000.0
adi_freq_step float

Frequency band width for ADI/AEI in Hz.

1000.0
bio_min_freq float

Minimum frequency for BIO in Hz.

2000.0
bio_max_freq float

Maximum frequency for BIO in Hz.

8000.0
db_threshold float

Threshold in dB for ADI/AEI/BIO.

-50.0

Returns:

Type Description
AcousticIndices

AcousticIndices dataclass with all computed values.

Example

indices = compute_all_indices(audio, 22050) print(f"ACI: {indices.aci:.2f}") print(f"ADI: {indices.adi:.2f}") print(f"NDSI: {indices.ndsi:.3f}")

compute_bio

compute_bio(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
    min_freq: float = 2000.0,
    max_freq: float = 8000.0,
    db_threshold: float = -50.0,
    precomputed_spec: tuple[ndarray, ndarray, ndarray]
    | None = None,
) -> float

Compute the Bioacoustic Index (BIO).

BIO calculates the area under the mean spectrum curve within a specified frequency range, typically 2-8 kHz where most bird and insect sounds occur. Higher values indicate more acoustic activity in this biologically relevant frequency range.

Reference

Boelman, N. T., Asner, G. P., Hart, P. J., & Martin, R. E. (2007). Multi-trophic invasion resistance in Hawaii: Bioacoustics, field surveys, and airborne remote sensing. Ecological Applications, 17(8), 2137-2144.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

512
hop_length int | None

Hop length (default: n_fft // 2).

None
min_freq float

Minimum frequency in Hz (default: 2000).

2000.0
max_freq float

Maximum frequency in Hz (default: 8000).

8000.0
db_threshold float

Threshold in dB for baseline.

-50.0
precomputed_spec tuple[ndarray, ndarray, ndarray] | None

Optional precomputed (spectrogram, frequencies, times) tuple in LINEAR AMPLITUDE format (not dB).

None

Returns:

Type Description
float

Bioacoustic Index value.

Example

bio = compute_bio(audio, 22050, min_freq=2000, max_freq=11000)

compute_index

compute_index(
    audio: ndarray,
    sample_rate: int,
    index_name: str,
    n_fft: int = 512,
    hop_length: int | None = None,
    **kwargs: Any,
) -> float

Compute a single acoustic index by name.

Raises:

Type Description
InvalidInputError

if index_name is not a known index.

compute_indices_from_file

compute_indices_from_file(
    filepath: str | Path, **kwargs: Any
) -> AcousticIndices

Compute all acoustic indices from an audio file.

Parameters:

Name Type Description Default
filepath str | Path

Path to audio file.

required
**kwargs Any

Additional arguments passed to compute_all_indices.

{}

Returns:

Type Description
AcousticIndices

AcousticIndices dataclass.

Example

indices = compute_indices_from_file("recording.wav") print(indices.to_dict())

compute_ndsi

compute_ndsi(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 1024,
    hop_length: int | None = None,
    anthro_min: float = 1000.0,
    anthro_max: float = 2000.0,
    bio_min: float = 2000.0,
    bio_max: float = 8000.0,
) -> tuple[float, float, float]

Compute the Normalized Difference Soundscape Index (NDSI).

NDSI compares the amount of anthropogenic sound (typically 1-2 kHz) to biological sound (typically 2-8 kHz). Values range from -1 to +1, where: - +1 indicates pure biophony (biological sounds only) - -1 indicates pure anthrophony (human sounds only) - 0 indicates equal amounts of both

Reference

Kasten, E. P., Gage, S. H., Fox, J., & Joo, W. (2012). The remote environmental assessment laboratory's acoustic library: An archive for studying soundscape ecology. Ecological Informatics, 12, 50-67.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

1024
hop_length int | None

Hop length (default: n_fft // 2).

None
anthro_min float

Minimum frequency for anthrophony band (Hz).

1000.0
anthro_max float

Maximum frequency for anthrophony band (Hz).

2000.0
bio_min float

Minimum frequency for biophony band (Hz).

2000.0
bio_max float

Maximum frequency for biophony band (Hz).

8000.0

Returns:

Type Description
tuple[float, float, float]

Tuple of (NDSI value, anthrophony, biophony).

Example

ndsi, anthro, bio = compute_ndsi(audio, 22050) print(f"NDSI: {ndsi:.3f}, Anthrophony: {anthro:.3f}, Biophony: {bio:.3f}")

describe_index

describe_index(index_name: str) -> str | None

Return a human-readable description of an acoustic index, or None if unknown.

spectral_entropy

spectral_entropy(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
) -> float

Compute spectral entropy of the audio signal.

Spectral entropy measures the uniformity of the power spectrum. High entropy indicates a flat (noise-like) spectrum, while low entropy indicates concentration of energy in specific frequencies.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

512
hop_length int | None

Hop length (default: n_fft // 2).

None

Returns:

Type Description
float

Spectral entropy value (0 to log(n_fft/2)).

Example

entropy = spectral_entropy(audio, 22050)

temporal_entropy

temporal_entropy(
    audio: ndarray,
    sample_rate: int,
    n_fft: int = 512,
    hop_length: int | None = None,
) -> float

Compute temporal entropy of the audio signal.

Temporal entropy measures the uniformity of energy distribution over time. High entropy indicates constant sound levels, while low entropy indicates intermittent or varying sound patterns.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
n_fft int

FFT window size.

512
hop_length int | None

Hop length (default: n_fft // 2).

None

Returns:

Type Description
float

Temporal entropy value.

Example

entropy = temporal_entropy(audio, 22050)

temporal_indices

temporal_indices(
    audio: ndarray,
    sample_rate: int,
    window_duration: float = 60.0,
    hop_duration: float | None = None,
    **kwargs: Any,
) -> list[dict[str, Any]]

Compute acoustic indices over time windows.

Useful for analyzing how soundscape characteristics change over time.

Parameters:

Name Type Description Default
audio ndarray

Audio signal as numpy array.

required
sample_rate int

Sample rate in Hz.

required
window_duration float

Duration of each window in seconds.

60.0
hop_duration float | None

Hop between windows in seconds (default: window_duration).

None
**kwargs Any

Additional arguments passed to compute_all_indices.

{}

Returns:

Type Description
list[dict[str, Any]]

List of dictionaries with indices for each time window.

Example

Compute indices every minute for a long recording

results = temporal_indices(audio, 22050, window_duration=60) for r in results: ... print(f"Time {r['start_time']:.0f}s: NDSI={r['ndsi']:.3f}")