VarnetDerivative#

Defined in: voxatlas.features.acoustic.envelope.derivative

class voxatlas.features.acoustic.envelope.derivative.VarnetDerivative#

Bases: BaseExtractor

Extract a frame-level derivative contour from an upstream envelope feature.

This public extractor converts an already computed envelope-like contour into its first temporal difference. In the VoxAtlas pipeline, it is used to expose local change information that can then be reused by onset and peak-rate features without recomputing the base envelope.

Algorithm#

The implementation is intentionally simple and closely mirrors the code path.

  1. Dependency retrieval The extractor reads the upstream frame-aligned contour \(x_t\) from the feature store. The exact source depends on dependency_name and may be RMS, log energy, Hilbert envelope, Praat intensity, or another envelope representation.

  2. Finite differencing VoxAtlas applies the backward difference

    \[d_t = x_t - x_{t-1},\]

    while preserving the original frame count by prepending the first sample.

  3. Alignment and packaging The derivative values remain aligned to the dependency time axis so later stages can quote and aggregate the contour without any resampling.

Notes

This extractor depends on exactly one upstream envelope feature and returns a VectorFeatureOutput aligned to frame units.

name#

Registry key for this extractor. This is derived from the chosen dependency and has the form "{dependency}.derivative" (for example, "acoustic.envelope.oganian.derivative").

Type:

str

input_units#

Required input unit level. None means this extractor does not require linguistic units and instead consumes dependency outputs from the feature store.

Type:

str | None

output_units#

Output alignment unit ("frame").

Type:

str | None

dependencies#

Exactly one upstream contour ([dependency_name]), such as "acoustic.envelope.oganian" for OganianDerivative.

Type:

list[str]

default_config#

Default runtime parameters: frame_length=0.025, frame_step=0.01, peak_threshold=0.1, smoothing=1.

Type:

dict

Examples

>>> import numpy as np
>>> from voxatlas.features.acoustic.envelope.derivative import OganianDerivative
>>> from voxatlas.features.feature_input import FeatureInput
>>> from voxatlas.features.feature_output import VectorFeatureOutput
>>> from voxatlas.pipeline.feature_store import FeatureStore
>>> store = FeatureStore()
>>> base = VectorFeatureOutput(
...     feature="acoustic.envelope.oganian",
...     unit="frame",
...     time=np.array([0.0, 0.01, 0.02], dtype=np.float32),
...     values=np.array([0.0, 1.0, 1.0], dtype=np.float32),
... )
>>> store.add("acoustic.envelope.oganian", base)
>>> feature_input = FeatureInput(audio=None, units=None, context={"feature_store": store})
>>> out = OganianDerivative().compute(feature_input, {})
>>> out.values.tolist()
[0.0, 1.0, 0.0]
compute(feature_input, params)#

Compute the feature output for a single stream.

This method is called by the pipeline after dependency resolution has completed. It receives the prepared feature input object together with the resolved feature-specific configuration.

Parameters:
  • feature_input (FeatureInput) – Container with audio, unit tables, and pipeline context.

  • params (dict) – Resolved configuration dictionary for the extractor.

Returns:

Structured VoxAtlas feature output.

Return type:

object

Raises:

ValueError – Raised when required inputs are unavailable for the feature.

Notes

Implementations should remain side-effect free and should read dependency outputs from feature_input.context['feature_store'] when needed.

Examples

>>> import numpy as np
>>> from voxatlas.features.acoustic.envelope.derivative import LogEnergyDerivative
>>> from voxatlas.features.feature_input import FeatureInput
>>> from voxatlas.features.feature_output import VectorFeatureOutput
>>> from voxatlas.pipeline.feature_store import FeatureStore
>>> store = FeatureStore()
>>> base = VectorFeatureOutput(
...     feature="acoustic.envelope.log_energy",
...     unit="frame",
...     time=np.array([0.0, 0.01, 0.02], dtype=np.float32),
...     values=np.array([0.0, 0.0, 2.0], dtype=np.float32),
... )
>>> store.add("acoustic.envelope.log_energy", base)
>>> feature_input = FeatureInput(audio=None, units=None, context={"feature_store": store})
>>> LogEnergyDerivative().compute(feature_input, {}).values.tolist()
[0.0, 0.0, 2.0]
>>> import numpy as np
>>> from voxatlas.features.acoustic.envelope.derivative import PraatIntensityDerivative
>>> from voxatlas.features.feature_input import FeatureInput
>>> from voxatlas.features.feature_output import VectorFeatureOutput
>>> from voxatlas.pipeline.feature_store import FeatureStore
>>> store = FeatureStore()
>>> base = VectorFeatureOutput(
...     feature="acoustic.envelope.praat_intensity",
...     unit="frame",
...     time=np.array([0.0, 0.01, 0.02], dtype=np.float32),
...     values=np.array([1.0, 3.0, 6.0], dtype=np.float32),
... )
>>> store.add("acoustic.envelope.praat_intensity", base)
>>> feature_input = FeatureInput(audio=None, units=None, context={"feature_store": store})
>>> PraatIntensityDerivative().compute(feature_input, {}).values.tolist()
[0.0, 2.0, 3.0]
>>> import numpy as np
>>> from voxatlas.features.acoustic.envelope.derivative import RmsDerivative
>>> from voxatlas.features.feature_input import FeatureInput
>>> from voxatlas.features.feature_output import VectorFeatureOutput
>>> from voxatlas.pipeline.feature_store import FeatureStore
>>> store = FeatureStore()
>>> base = VectorFeatureOutput(
...     feature="acoustic.envelope.rms",
...     unit="frame",
...     time=np.array([0.0, 0.01, 0.02], dtype=np.float32),
...     values=np.array([0.5, 0.5, 0.0], dtype=np.float32),
... )
>>> store.add("acoustic.envelope.rms", base)
>>> feature_input = FeatureInput(audio=None, units=None, context={"feature_store": store})
>>> RmsDerivative().compute(feature_input, {}).values.tolist()
[0.0, 0.0, -0.5]
default_config: dict = {'frame_length': 0.025, 'frame_step': 0.01, 'peak_threshold': 0.1, 'smoothing': 1}#
dependencies: list[str] = ['acoustic.envelope.varnet']#
input_units: str | None = None#
name: str = 'acoustic.envelope.varnet.derivative'#
output_units: str | None = 'frame'#