Skip to content

Audio

soundscapy.audio

Provides tools for working with audio signals, particularly binaural recordings.

Key Components:

  • Binaural: A class for processing and analyzing binaural audio signals.
  • Various metric calculation functions for audio analysis.

The module integrates with external libraries such as mosqito, maad, and acoustic_toolbox to provide a comprehensive suite of audio analysis tools.

Examples:

>>>
>>> from soundscapy.audio import Binaural
>>> signal = Binaural.from_wav("audio.wav")
>>> results = signal.process_all_metrics(analysis_settings)
See Also
  • soundscapy.audio.binaural: For detailed Binaural class documentation.
  • soundscapy.audio.metrics: For individual metric calculation functions.
Notes

This module requires the soundscapy[audio] optional dependencies.

MODULE DESCRIPTION
analysis_settings

Module for managing audio analysis settings using Pydantic models.

audio_analysis

Audio analysis module for psychoacoustic analysis of audio files.

binaural

Provides tools for working with binaural audio signals.

metrics

Functions for calculating various acoustic and psychoacoustic metrics for audio signals.

parallel_processing

Functions for parallel processing of binaural audio files.

soundscapy.audio.analysis_settings

Module for managing audio analysis settings using Pydantic models.

This module defines Pydantic models for configuring analysis settings for different audio processing libraries (AcousticToolbox, MoSQITo, scikit-maad). It includes classes for individual metric settings, library settings, and overall analysis settings. It also provides a ConfigManager class for loading, saving, merging, and managing configurations from YAML files or dictionaries.

CLASS DESCRIPTION
MetricSettings

Settings for an individual metric.

LibrarySettings

Settings for a library of metrics.

AnalysisSettings

Settings for audio analysis methods.

ConfigManager

Manage configuration settings for audio analysis.

MetricSettings

Bases: BaseModel

Settings for an individual metric.

ATTRIBUTE DESCRIPTION
run

Whether to run this metric.

TYPE: bool

main

The main statistic to calculate.

TYPE: str | int | None

statistics

List of statistics to calculate.

TYPE: list[str | int] | None

channel

List of channels to analyze.

TYPE: list[str]

label

Label for the metric.

TYPE: str

parallel

Whether to run the metric in parallel.

TYPE: bool

func_args

Additional arguments for the metric function.

TYPE: dict[str, Any]

METHOD DESCRIPTION
check_main_in_statistics

Check that the main statistic is in the statistics list.

check_main_in_statistics classmethod
check_main_in_statistics(
    values: dict[str, Any],
) -> dict[str, Any]

Check that the main statistic is in the statistics list.

Source code in src/soundscapy/audio/analysis_settings.py
@model_validator(mode="before")
@classmethod
def check_main_in_statistics(cls, values: dict[str, Any]) -> dict[str, Any]:
    """Check that the main statistic is in the statistics list."""
    main = values.get("main")
    statistics = values.get("statistics", [])
    if main and main not in statistics:
        statistics.append(main)
        values["statistics"] = statistics
    return values

LibrarySettings

Bases: RootModel

Settings for a library of metrics.

METHOD DESCRIPTION
get_metric_settings

Get the settings for a specific metric.

get_metric_settings
get_metric_settings(metric: str) -> MetricSettings

Get the settings for a specific metric.

PARAMETER DESCRIPTION
metric

The name of the metric.

TYPE: str

RETURNS DESCRIPTION
MetricSettings

The settings for the specified metric.

RAISES DESCRIPTION
KeyError

If the specified metric is not found.

Source code in src/soundscapy/audio/analysis_settings.py
def get_metric_settings(self, metric: str) -> MetricSettings:
    """
    Get the settings for a specific metric.

    Parameters
    ----------
    metric
        The name of the metric.

    Returns
    -------
    :
        The settings for the specified metric.

    Raises
    ------
    KeyError
        If the specified metric is not found.

    """
    if metric in self.root:
        return self.root[metric]
    logger.error(f"Metric '{metric}' not found in library")
    msg = f"Metric '{metric}' not found in library"
    raise KeyError(msg)

AnalysisSettings

Bases: BaseModel

Settings for audio analysis methods.

ATTRIBUTE DESCRIPTION
version

Version of the configuration.

TYPE: str

AcousticToolbox

Settings for AcousticToolbox metrics.

TYPE: LibrarySettings | None

MoSQITo

Settings for MoSQITo metrics.

TYPE: LibrarySettings | None

scikit_maad

Settings for scikit-maad metrics.

TYPE: LibrarySettings | None

METHOD DESCRIPTION
validate_library_settings

Validate library settings.

from_yaml

Create an AnalysisSettings object from a YAML file.

default

Create a default AnalysisSettings using the package default configuration file.

from_dict

Create an AnalysisSettings object from a dictionary.

to_yaml

Save the current settings to a YAML file.

update_setting

Update the settings for a specific metric.

get_metric_settings

Get the settings for a specific metric.

get_enabled_metrics

Get a dictionary of enabled metrics.

validate_library_settings classmethod
validate_library_settings(
    v: dict | LibrarySettings,
) -> LibrarySettings

Validate library settings.

Source code in src/soundscapy/audio/analysis_settings.py
@field_validator("*", mode="before")
@classmethod
def validate_library_settings(cls, v: dict | LibrarySettings) -> LibrarySettings:
    """Validate library settings."""
    if isinstance(v, dict):
        return LibrarySettings(root=v)
    return v
from_yaml classmethod
from_yaml(filepath: str | Path) -> AnalysisSettings

Create an AnalysisSettings object from a YAML file.

PARAMETER DESCRIPTION
filepath

Path to the YAML configuration file.

TYPE: str | Path

RETURNS DESCRIPTION
AnalysisSettings

An instance of AnalysisSettings.

Source code in src/soundscapy/audio/analysis_settings.py
@classmethod
def from_yaml(cls, filepath: str | Path) -> AnalysisSettings:
    """
    Create an AnalysisSettings object from a YAML file.

    Parameters
    ----------
    filepath
        Path to the YAML configuration file.

    Returns
    -------
    :
        An instance of AnalysisSettings.

    """
    filepath = _ensure_path(filepath)
    logger.info(f"Loading configuration from {filepath}")
    with Path.open(filepath) as f:
        config_dict = yaml.safe_load(f)
    return cls(**config_dict)
default classmethod
default() -> AnalysisSettings

Create a default AnalysisSettings using the package default configuration file.

RETURNS DESCRIPTION
AnalysisSettings

An instance of AnalysisSettings with default settings.

Source code in src/soundscapy/audio/analysis_settings.py
@classmethod
def default(cls) -> AnalysisSettings:
    """
    Create a default AnalysisSettings using the package default configuration file.

    Returns
    -------
    :
        An instance of AnalysisSettings with default settings.

    """
    config_resource = resources.files("soundscapy.data").joinpath(
        "default_settings.yaml"
    )
    with resources.as_file(config_resource) as f:
        logger.info(f"Loading default configuration from {f}")
        return cls.from_yaml(f)
from_dict classmethod
from_dict(d: dict) -> AnalysisSettings

Create an AnalysisSettings object from a dictionary.

PARAMETER DESCRIPTION
d

Dictionary containing the configuration settings.

TYPE: dict

RETURNS DESCRIPTION
AnalysisSettings

An instance of AnalysisSettings.

Source code in src/soundscapy/audio/analysis_settings.py
@classmethod
def from_dict(cls, d: dict) -> AnalysisSettings:
    """
    Create an AnalysisSettings object from a dictionary.

    Parameters
    ----------
    d
        Dictionary containing the configuration settings.

    Returns
    -------
    :
        An instance of AnalysisSettings.

    """
    return cls(**d)
to_yaml
to_yaml(filepath: str | Path) -> None

Save the current settings to a YAML file.

PARAMETER DESCRIPTION
filepath

Path to save the YAML file.

TYPE: str | Path

Source code in src/soundscapy/audio/analysis_settings.py
def to_yaml(self, filepath: str | Path) -> None:
    """
    Save the current settings to a YAML file.

    Parameters
    ----------
    filepath
        Path to save the YAML file.

    """
    filepath = _ensure_path(filepath)
    logger.info(f"Saving configuration to {filepath}")
    with Path.open(filepath, "w") as f:
        yaml.dump(self.model_dump(by_alias=True), f)
update_setting
update_setting(
    library: str, metric: str, **kwargs: dict
) -> None

Update the settings for a specific metric.

PARAMETER DESCRIPTION
library

The name of the library.

TYPE: str

metric

The name of the metric.

TYPE: str

**kwargs

Keyword arguments to update the metric settings.

TYPE: dict DEFAULT: {}

RAISES DESCRIPTION
KeyError

If the specified library or metric is not found.

Source code in src/soundscapy/audio/analysis_settings.py
def update_setting(self, library: str, metric: str, **kwargs: dict) -> None:
    """
    Update the settings for a specific metric.

    Parameters
    ----------
    library
        The name of the library.
    metric
        The name of the metric.
    **kwargs
        Keyword arguments to update the metric settings.

    Raises
    ------
    KeyError
        If the specified library or metric is not found.

    """
    library_settings = getattr(self, library)
    if library_settings and metric in library_settings.root:
        metric_settings = library_settings.root[metric]
        for key, value in kwargs.items():
            if hasattr(metric_settings, key):
                setattr(metric_settings, key, value)
            else:
                logger.error(f"Invalid setting '{key}' for metric '{metric}'")
    else:
        logger.error(f"Metric '{metric}' not found in library '{library}'")
        msg = f"Metric '{metric}' not found in library '{library}'"
        raise KeyError(msg)
get_metric_settings
get_metric_settings(
    library: str, metric: str
) -> MetricSettings

Get the settings for a specific metric.

PARAMETER DESCRIPTION
library

The name of the library.

TYPE: str

metric

The name of the metric.

TYPE: str

RETURNS DESCRIPTION
MetricSettings

The settings for the specified metric.

RAISES DESCRIPTION
KeyError

If the specified library or metric is not found.

Source code in src/soundscapy/audio/analysis_settings.py
def get_metric_settings(self, library: str, metric: str) -> MetricSettings:
    """
    Get the settings for a specific metric.

    Parameters
    ----------
    library
        The name of the library.
    metric
        The name of the metric.

    Returns
    -------
    :
        The settings for the specified metric.

    Raises
    ------
    KeyError
        If the specified library or metric is not found.

    """
    library_settings = getattr(self, library)
    if library_settings and metric in library_settings.root:
        return library_settings.root[metric]
    logger.error(f"Metric '{metric}' not found in library '{library}'")
    msg = f"Metric '{metric}' not found in library '{library}'"
    raise KeyError(msg)
get_enabled_metrics
get_enabled_metrics() -> dict[
    str, dict[str, MetricSettings]
]

Get a dictionary of enabled metrics.

RETURNS DESCRIPTION
dict[str, dict[str, MetricSettings]]

A dictionary of enabled metrics grouped by library.

Source code in src/soundscapy/audio/analysis_settings.py
def get_enabled_metrics(self) -> dict[str, dict[str, MetricSettings]]:
    """
    Get a dictionary of enabled metrics.

    Returns
    -------
    :
        A dictionary of enabled metrics grouped by library.

    """
    enabled_metrics = {}
    for library in ["AcousticToolbox", "MoSQITo", "scikit_maad"]:
        library_settings = getattr(self, library)
        if library_settings:
            enabled_metrics[library] = {
                metric: settings
                for metric, settings in library_settings.root.items()
                if settings.run
            }
    logger.debug(f"Enabled metrics: {enabled_metrics}")
    return enabled_metrics

ConfigManager

ConfigManager(config_path: str | Path | None = None)

Manage configuration settings for audio analysis.

PARAMETER DESCRIPTION
config_path

Path to the default configuration file.

TYPE: str | Path | None DEFAULT: None

METHOD DESCRIPTION
load_config

Load a configuration file or use the default configuration.

save_config

Save the current configuration to a file.

merge_configs

Merge the current config with override values and update the current_config.

generate_minimal_config

Generate a minimal configuration containing only changes from the default.

Source code in src/soundscapy/audio/analysis_settings.py
def __init__(self, config_path: str | Path | None = None) -> None:  # noqa: D107
    self.config_path = _ensure_path(config_path) if config_path else None
    self.current_config: AnalysisSettings | None = None
load_config
load_config(
    config_path: str | Path | None = None,
) -> AnalysisSettings

Load a configuration file or use the default configuration.

PARAMETER DESCRIPTION
config_path

Path to the configuration file. If None, uses the default configuration.

TYPE: str | Path | None DEFAULT: None

RETURNS DESCRIPTION
AnalysisSettings

The loaded configuration.

Source code in src/soundscapy/audio/analysis_settings.py
def load_config(self, config_path: str | Path | None = None) -> AnalysisSettings:
    """
    Load a configuration file or use the default configuration.

    Parameters
    ----------
    config_path
        Path to the configuration file. If None, uses the default configuration.

    Returns
    -------
    :
        The loaded configuration.

    """
    if config_path:
        logger.info(f"Loading configuration from {config_path}")
        self.current_config = AnalysisSettings.from_yaml(config_path)
    elif self.config_path:
        logger.info(f"Loading configuration from {self.config_path}")
        self.current_config = AnalysisSettings.from_yaml(self.config_path)
    else:
        logger.info("Loading default configuration")
        self.current_config = AnalysisSettings.default()
    return self.current_config
save_config
save_config(filepath: str | Path) -> None

Save the current configuration to a file.

PARAMETER DESCRIPTION
filepath

Path to save the configuration file.

TYPE: str | Path

RAISES DESCRIPTION
ValueError

If no current configuration is loaded.

Source code in src/soundscapy/audio/analysis_settings.py
def save_config(self, filepath: str | Path) -> None:
    """
    Save the current configuration to a file.

    Parameters
    ----------
    filepath
        Path to save the configuration file.

    Raises
    ------
    ValueError
        If no current configuration is loaded.

    """
    if self.current_config:
        logger.info(f"Saving configuration to {filepath}")
        self.current_config.to_yaml(filepath)
    else:
        logger.error("No current configuration to save")
        msg = "No current configuration to save."
        raise ValueError(msg)
merge_configs
merge_configs(override_config: dict) -> AnalysisSettings

Merge the current config with override values and update the current_config.

PARAMETER DESCRIPTION
override_config

Dictionary containing override configuration values.

TYPE: dict

RETURNS DESCRIPTION
AnalysisSettings

The merged configuration.

RAISES DESCRIPTION
ValueError

If no base configuration is loaded.

Source code in src/soundscapy/audio/analysis_settings.py
def merge_configs(self, override_config: dict) -> AnalysisSettings:
    """
    Merge the current config with override values and update the current_config.

    Parameters
    ----------
    override_config
        Dictionary containing override configuration values.

    Returns
    -------
    :
        The merged configuration.

    Raises
    ------
    ValueError
        If no base configuration is loaded.

    """
    if not self.current_config:
        logger.error("No base configuration loaded")
        msg = "No base configuration loaded."
        raise ValueError(msg)
    logger.info("Merging configurations")
    merged_dict = self.current_config.model_dump()
    self._deep_update(merged_dict, override_config)
    merged_config = AnalysisSettings(**merged_dict)
    self.current_config = merged_config  # Update the current_config
    return merged_config
generate_minimal_config
generate_minimal_config() -> dict

Generate a minimal configuration containing only changes from the default.

RETURNS DESCRIPTION
dict

A dictionary containing the minimal configuration.

RAISES DESCRIPTION
ValueError

If no current configuration is loaded.

Source code in src/soundscapy/audio/analysis_settings.py
def generate_minimal_config(self) -> dict:
    """
    Generate a minimal configuration containing only changes from the default.

    Returns
    -------
    :
        A dictionary containing the minimal configuration.

    Raises
    ------
    ValueError
        If no current configuration is loaded.

    """
    if not self.current_config:
        msg = "No current configuration loaded."
        raise ValueError(msg)
    default_config = AnalysisSettings.default()
    current_dict = self.current_config.model_dump()
    default_dict = default_config.model_dump()
    return self._get_diff(current_dict, default_dict)

The main audio analysis surface is split across the focused pages below: