Custom operations
dspk.custom runs your own Python function over a recording of any length. dsp-kitchen reads the
windows, the next one on another thread while your function runs. Your function only ever sees a
NumPy window (channels, samples), float32.
Measure: one row of results per window
Section titled “Measure: one row of results per window”import numpy as npimport dspk
rec = dspk.io.open("session.zarr")table = dspk.custom.measure(rec, lambda x: {"rms": np.sqrt((x ** 2).mean(axis=1))}, window_s=1.0)
table["start_s"], table["stop_s"], table["rms"] # rms is (windows, channels)Transform: a processed copy
Section titled “Transform: a processed copy”Tell it how many samples your function looks away, the halo. Windows are read with that much
context on each side and trimmed back, so the result equals your function on the whole array.
@dspk.custom.transform(halo=12)def smooth(x): k = np.ones(25, dtype=np.float32) / 25 return np.stack([np.convolve(c, k, mode="same") for c in x])
y = smooth.apply(rec, start=0, stop=30_000) # one array in memorysmooth.write(rec, "smoothed.zarr") # the whole recording, window by windowIf your function needs to know where it is, take a second argument: fn(x, w) gets the
Window, with its sample range and time.
Your function runs on the calling thread, one window at a time, in order, so it can keep state.
Full details: dspk.custom.