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),
)