Skip to content

Audio Adapter

The AdapterConfig controls how transforms and sinks buffer and slice incoming data before processing. It handles overlap (context around each chunk), stride (output chunk size), gap handling, and offset alignment.

Most elements don't need an adapter — it's only required when processing requires context beyond a single buffer (e.g., filtering, resampling) or when output must be chunked to a specific size.

AdapterConfig Parameters

Parameter Default Description
overlap (0, 0) (before, after) padding in offset units
stride 0 Output chunk size in offsets (0 = all available data)
pad_zeros_startup False Zero-pad the beginning instead of waiting for enough data
skip_gaps False Produce a full gap buffer if any gaps appear in the chunk
backend NumpyBackend Array backend for buffer operations
align_to None Snap output offsets to multiples of this value
align_buffers False Align slices to the minimum sample rate across pads
offset_shift 0 Shift output offsets (for latency compensation)
enable None Force enable/disable (None = auto-detect)

Common Patterns

The two most frequently used parameters are overlap and stride. In practice, most elements fall into one of three patterns.

Overlap Only (Filtering/Context)

Use overlap when processing needs context around each chunk but doesn't need to control the output size. The overlap tuple specifies (before, after) padding in offset units:

from sgnts.base import AdapterConfig, Offset

# A filter that needs 127 samples of history before each chunk
config = AdapterConfig(
    overlap=(Offset.fromsamples(127, rate=2048), 0),
)

Used by: Correlate, Resampler.

Stride Only (Chunking)

Use stride to control the output chunk size. This is useful for sinks that need fixed-size blocks or transforms that operate on specific window lengths:

from sgnts.base import AdapterConfig, Offset

# Produce 1-second output chunks
config = AdapterConfig(
    stride=Offset.fromsec(1),
)

Used by: DumpSeriesSink (via downstream sinks), TDCF, Converter.

Overlap + Stride (Windowed Processing)

Combine both when processing needs both context and fixed output size. Common in spectral analysis with overlapping windows:

from sgnts.base import AdapterConfig, Offset

# 50% overlap with fixed output stride
config = AdapterConfig(
    overlap=(0, Offset.fromsamples(512, rate=2048)),
    stride=Offset.fromsamples(512, rate=2048),
)

Offset Alignment

Use align_to to snap output offsets to regular boundaries. This is useful for sinks that write data aligned to integer seconds or specific block sizes:

from sgnts.base import AdapterConfig, Offset

# Align output to integer-second boundaries
config = AdapterConfig(
    stride=Offset.fromsec(1),
    align_to=Offset.fromsec(1),
)

Gap Handling

By default, gaps in the input are passed through to processing. Set skip_gaps=True to produce a full gap buffer whenever any gap appears in the current chunk — useful for algorithms that cannot handle partial gaps:

config = AdapterConfig(
    overlap=(0, Offset.fromsamples(256, rate=2048)),
    stride=Offset.fromsamples(256, rate=2048),
    skip_gaps=True,
)

Startup Padding

When overlap is set, the adapter normally waits until enough data has accumulated to fill the overlap region. Set pad_zeros_startup=True to zero-pad the beginning instead, producing output from the very first buffer:

config = AdapterConfig(
    overlap=(Offset.fromsamples(64, rate=2048), Offset.fromsamples(64, rate=2048)),
    pad_zeros_startup=True,
)

Latency Compensation

Filters that introduce a known latency can shift output offsets backward to maintain correct timing:

from sgnts.base import AdapterConfig, Offset

# Compensate for 2-sample latency at 2048 Hz
config = AdapterConfig(
    overlap=(Offset.fromsamples(3, rate=2048), 0),
    offset_shift=-Offset.fromsamples(2, rate=2048),
)

Using AdapterConfig in Elements

Elements that extend TSTransform or TSSink set self.adapter_config in their __post_init__():

from dataclasses import dataclass
from sgnts.base import AdapterConfig, Offset, TSTransform

@dataclass
class MyFilter(TSTransform):
    kernel_size: int = 128

    def __post_init__(self):
        super().__post_init__()
        self.adapter_config = AdapterConfig(
            overlap=(Offset.fromsamples(self.kernel_size - 1, rate=2048), 0),
        )