Filtering & Spectral Analysis (vDSP)
AppleAccelerate wraps vDSP functions for convolution, correlation, filtering, spectral analysis, and window generation.
Convolution
Wraps vDSP_conv. conv(X, K) computes the convolution of vectors X and K. conv!(result, X, K) stores the result in a preallocated vector.
X = randn(Float64, 100)
K = randn(Float64, 10)
result = AppleAccelerate.conv(X, K) # length = length(X) + length(K) - 1AppleAccelerate.conv — Function
conv(X::Vector{T}, K::Vector{T}) where T <: Union{Float32, Float64}Compute the convolution of signal X with kernel K via vDSP_conv. Returns a vector of length length(X) + length(K) - 1.
AppleAccelerate.conv! — Function
conv!(result::Vector{T}, X::Vector{T}, K::Vector{T})
conv!(X::Vector{T}, K::Vector{T})In-place convolution. The 3-argument form stores the result in result (which must have at least length(X) + length(K) - 1 elements). The 2-argument form overwrites X. Wraps vDSP_conv.
Cross-Correlation
Wraps vDSP_conv (with reversed kernel). xcorr(X, Y) computes the cross-correlation. xcorr(X) computes auto-correlation.
X = randn(Float64, 100)
Y = randn(Float64, 100)
result = AppleAccelerate.xcorr(X, Y)AppleAccelerate.xcorr — Function
xcorr(X::Vector{T}, Y::Vector{T}) where T <: Union{Float32, Float64}
xcorr(X::Vector{T})Cross-correlation of X and Y via vDSP_conv (with reversed kernel). The single-argument form computes auto-correlation. Returns a vector of length length(X) + length(Y) - 1.
AppleAccelerate.xcorr! — Function
xcorr!(result::Vector{T}, X::Vector{T}, Y::Vector{T})
xcorr!(X::Vector{T}, Y::Vector{T})In-place cross-correlation. The 3-argument form stores the result in result. The 2-argument form overwrites X. Wraps vDSP_conv.
Biquad Filtering
Wraps vDSP_biquad. IIR filtering via cascaded biquad sections. Both Float64 and Float32 processing are supported; coefficients are always Float64.
Each section takes 5 coefficients in the order [b0, b1, b2, a1, a2] (feedforward then feedback). Use real filter-design coefficients rather than random values — an arbitrary a1/a2 can place the poles outside the unit circle and make the filter unstable. The example below is a stable second-order lowpass:
X = randn(Float64, 100)
coefficients = [0.2929, 0.5858, 0.2929, 0.0, 0.1716] # [b0, b1, b2, a1, a2]
bq = AppleAccelerate.biquadcreate(coefficients, 1) # defaults to Float64
delays = zeros(4)
result = AppleAccelerate.biquad(X, delays, length(X), bq)
# Float32 processing
X32 = randn(Float32, 100)
bq32 = AppleAccelerate.biquadcreate(coefficients, 1, Float32)
delays32 = zeros(Float32, 4)
result32 = AppleAccelerate.biquad(X32, delays32, length(X32), bq32)A single-precision setup's coefficients can be updated in place with biquad_setcoefficients!, avoiding a full recreate when re-tuning a filter (vDSP provides this setter only for the Float32 setup).
AppleAccelerate.biquadcreate — Function
biquadcreate(coefficients::Vector{Float64}, sections::Int, [T=Float64])Create a biquad IIR filter setup. coefficients must contain 5 values per section (3 feed-forward + 2 feedback). Returns a Biquad{T} setup object. Wraps vDSP_biquad_CreateSetup.
AppleAccelerate.biquad — Function
biquad(X, delays, numelem, bq::Biquad{T})Apply a cascaded biquad IIR filter to input X. delays holds the filter state and is updated in-place. Returns the filtered output vector. Wraps vDSP_biquad.
AppleAccelerate.biquad_setcoefficients! — Function
biquad_setcoefficients!(bq::Biquad{Float32}, coeffs::Vector, [start_sec=0, nsec])Update nsec sections of an existing single-channel biquad setup starting at 0-based section start_sec, in place. coeffs holds 5 values [b0, b1, b2, a1, a2] per section; supply Vector{Float32} (single-precision setter) or Vector{Float64} (double-precision setter). Lets a filter be re-tuned without recreating the setup.
Only single-precision biquad setups (Biquad{Float32}) can have their coefficients updated in place — vDSP provides no setter for the Float64 processing setup. Wraps vDSP_biquad_SetCoefficientsSingle / vDSP_biquad_SetCoefficientsDouble.
AppleAccelerate.biquaddestroy — Function
biquaddestroy(bq::Biquad{T})Free resources associated with a biquad setup. Called automatically by the finalizer. Wraps vDSP_biquad_DestroySetup.
Multi-Channel Biquad Filtering
Wraps vDSP_biquadm. Applies a multi-channel IIR filter in a single call. Both Float32 (default) and Float64 are supported.
channels = 2
sections = 1
coefficients = randn(5 * channels * sections)
setup = AppleAccelerate.biquadm_create(coefficients, channels, sections) # Float32
inputs = [randn(Float32, 64) for _ in 1:channels]
outputs = AppleAccelerate.biquadm(inputs, 64, setup)
# Float64 variant
setup64 = AppleAccelerate.biquadm_create(coefficients, channels, sections, Float64)
inputs64 = [randn(Float64, 64) for _ in 1:channels]
outputs64 = AppleAccelerate.biquadm(inputs64, 64, setup64)Live-state controls
A BiquadMulti setup keeps internal per-channel/section state and coefficients that can be manipulated between processing calls — for gain automation, click-free parameter changes, resetting or transplanting filter memory, and bypassing sections:
| Function | Effect |
|---|---|
biquadm_setcoefficients! | Immediately set a block of (section, channel) coefficients |
biquadm_settargets! | Set target coefficients the filter interpolates toward (smooth changes) |
biquadm_resetstate! | Zero all internal delays |
biquadm_copystate! | Copy internal state from one setup to another |
biquadm_setactivefilters! | Enable/disable (bypass) individual sections |
setup = AppleAccelerate.biquadm_create([1.0,0,0,0,0, 1.0,0,0,0,0], 2, 1, Float64)
# Retune channel 1 (0-based) to a gain of 5 without recreating the setup:
AppleAccelerate.biquadm_setcoefficients!(setup, [5.0,0,0,0,0], 0, 1, 1, 1)
y = AppleAccelerate.biquadm([ones(8), ones(8)], 8, setup)
@assert y[2] ≈ fill(5.0, 8)
AppleAccelerate.biquadm_resetstate!(setup) # clear filter memoryAppleAccelerate.biquadm_create — Function
biquadm_create(coefficients, channels, sections, [T=Float32])Create a multi-channel biquad IIR filter setup. coefficients must contain 5 * channels * sections Float64 values, laid out section-major: for each section, the [b0, b1, b2, a1, a2] block is given for every channel (so element 5 * (section * channels + channel) starts a given (section, channel) block). Returns a BiquadMulti{T} setup object. Wraps vDSP_biquadm_CreateSetup.
AppleAccelerate.biquadm — Function
biquadm(X, numelem, setup::BiquadMulti{T})Apply a multi-channel biquad IIR filter. X is a vector of per-channel input vectors. Returns a vector of per-channel output vectors. Wraps vDSP_biquadm.
AppleAccelerate.biquadm_setcoefficients! — Function
biquadm_setcoefficients!(setup::BiquadMulti{T}, coeffs, start_sec, start_chn, nsec, nchn)Immediately set the coefficients of a nsec×nchn block of an existing multi-channel biquad setup (0-based start_sec/start_chn). coeffs holds 5 values [b0, b1, b2, a1, a2] per (section, channel). Unlike biquadm_settargets!, the change is applied without interpolation. Wraps vDSP_biquadm_SetCoefficientsSingle / vDSP_biquadm_SetCoefficientsDouble.
AppleAccelerate.biquadm_settargets! — Function
biquadm_settargets!(setup::BiquadMulti{T}, targets, interp_rate, interp_threshold, start_sec, start_chn, nsec, nchn)Set target coefficients toward which the filter interpolates smoothly over successive samples (interp_rate controls the per-sample step; below interp_threshold the change snaps immediately). Used for click-free live parameter changes. Same block layout as biquadm_setcoefficients!. Wraps vDSP_biquadm_SetTargetsSingle / vDSP_biquadm_SetTargetsDouble.
AppleAccelerate.biquadm_resetstate! — Function
biquadm_resetstate!(setup::BiquadMulti{T})Reset the internal delay (state) of every channel/section of setup to zero, as if freshly created. Coefficients are unchanged. Wraps vDSP_biquadm_ResetState.
AppleAccelerate.biquadm_copystate! — Function
biquadm_copystate!(dest::BiquadMulti{T}, src::BiquadMulti{T})Copy the internal filter state (delays) from src into dest. Both setups must have the same number of channels and sections. Wraps vDSP_biquadm_CopyState.
AppleAccelerate.biquadm_setactivefilters! — Function
biquadm_setactivefilters!(setup::BiquadMulti{T}, states::Vector{Bool})Enable/disable each biquad section (states has one Bool per section). Disabled sections pass their input straight through (bypass). Wraps vDSP_biquadm_SetActiveFilters.
Recursive Filters
Second-Order Recursive Filter (deq22)
Wraps vDSP_deq22 for second-order (two-pole two-zero) recursive filtering. Both Float32 and Float64 are supported.
A = randn(Float64, 64)
B = Float64[0.5, -0.3, 0.2, 0.1, -0.05] # 5 filter coefficients
C = AppleAccelerate.deq22(A, B) # returns N output samplesThe deq22! variant operates on pre-padded arrays with explicit initial state.
FIR Decimation Filter (desamp)
Wraps vDSP_desamp for FIR filtering with decimation. Both Float32 and Float64 are supported.
A = randn(Float64, 100)
F = randn(Float64, 5) # 5-tap FIR filter
DF = 3 # decimation factor
C = AppleAccelerate.desamp(A, DF, F) # output length = div(100 - 5, 3) + 1Wiener-Levinson Filter (wiener)
Wraps vDSP_wiener for solving the Wiener-Hopf equation via Levinson-Durbin recursion. Both Float32 and Float64 are supported.
L = 8
autocorr = Float64[1.0 / (1 + abs(k)) for k in 0:(L-1)]
crosscorr = randn(Float64, L)
F, err = AppleAccelerate.wiener(autocorr, crosscorr) # err == 0 on successAppleAccelerate.deq22 — Function
deq22(A::Vector{Float32}, B::Vector{Float32})Allocating version of deq22!. Pads A with 2 leading zeros and returns only the N output samples (without the 2-element state prefix).
Returns: Vector{Float32} of length length(A)
deq22(A::Vector{Float64}, B::Vector{Float64})Allocating version of deq22!. Pads A with 2 leading zeros and returns only the N output samples (without the 2-element state prefix).
Returns: Vector{Float64} of length length(A)
AppleAccelerate.deq22! — Function
deq22!(C::Vector{Float32}, A::Vector{Float32}, B::Vector{Float32})Second-order (two-pole two-zero) recursive filter using vDSP_deq22. A has N+2 elements (A[1:2] are initial state), B has 5 coefficients, C has N+2 elements (C[1:2] must be preset as initial output state). Computes: C[n] = A[n]*B[1] + A[n-1]*B[2] + A[n-2]*B[3] - C[n-1]*B[4] - C[n-2]*B[5]
Returns: C
deq22!(C::Vector{Float64}, A::Vector{Float64}, B::Vector{Float64})Second-order (two-pole two-zero) recursive filter using vDSP_deq22. A has N+2 elements (A[1:2] are initial state), B has 5 coefficients, C has N+2 elements (C[1:2] must be preset as initial output state). Computes: C[n] = A[n]*B[1] + A[n-1]*B[2] + A[n-2]*B[3] - C[n-1]*B[4] - C[n-2]*B[5]
Returns: C
AppleAccelerate.desamp — Function
desamp(A::Vector{Float32}, DF::Int, F::Vector{Float32})Allocating version of desamp!. Returns a vector of length div(length(A) - length(F), DF) + 1.
Returns: Vector{Float32}
desamp(A::Vector{Float64}, DF::Int, F::Vector{Float64})Allocating version of desamp!. Returns a vector of length div(length(A) - length(F), DF) + 1.
Returns: Vector{Float64}
AppleAccelerate.desamp! — Function
desamp!(C::Vector{Float32}, A::Vector{Float32}, DF::Int, F::Vector{Float32})FIR decimation filter using vDSP_desamp. Filters input A with FIR coefficients F (P taps) and decimation factor DF. C must have at least div(length(A) - P, DF) + 1 elements. Computes: C[n] = sum(A[n*DF+p] * F[p] for p in 0:P-1) (0-indexed)
Returns: C
desamp!(C::Vector{Float64}, A::Vector{Float64}, DF::Int, F::Vector{Float64})FIR decimation filter using vDSP_desamp. Filters input A with FIR coefficients F (P taps) and decimation factor DF. C must have at least div(length(A) - P, DF) + 1 elements. Computes: C[n] = sum(A[n*DF+p] * F[p] for p in 0:P-1) (0-indexed)
Returns: C
AppleAccelerate.wiener — Function
wiener(A::Vector{Float32}, C::Vector{Float32}; flag::Int=0)Allocating version of wiener!. Returns (F, error_code).
wiener(A::Vector{Float64}, C::Vector{Float64}; flag::Int=0)Allocating version of wiener!. Returns (F, error_code).
AppleAccelerate.wiener! — Function
wiener!(F::Vector{Float32}, P::Vector{Float32}, A::Vector{Float32}, C::Vector{Float32}; flag::Int=0)Wiener-Levinson filter using vDSP_wiener. Solves the Wiener-Hopf equation R * F = C where R is the Toeplitz autocorrelation matrix formed from A. A = autocorrelation coefficients (L elements), C = cross-correlation (L), F = output filter coefficients (L), P = workspace (L).
Returns: (F, error_code) where error_code is 0 on success.
wiener!(F::Vector{Float64}, P::Vector{Float64}, A::Vector{Float64}, C::Vector{Float64}; flag::Int=0)Wiener-Levinson filter using vDSP_wiener. Solves the Wiener-Hopf equation R * F = C where R is the Toeplitz autocorrelation matrix formed from A. A = autocorrelation coefficients (L elements), C = cross-correlation (L), F = output filter coefficients (L), P = workspace (L).
Returns: (F, error_code) where error_code is 0 on success.
Spectral Analysis
Wraps Apple's vDSP spectral analysis functions for computing power spectra, cross-spectra, coherence, and transfer functions. All functions support both Float32 and Float64.
Autospectrum (vDSP_zaspec)
x = randn(ComplexF64, 256)
power = AppleAccelerate.zaspec(x) # |x[n]|^2The zaspec! variant accumulates into an existing vector (C[n] += |A[n]|^2), useful for averaging multiple frames.
Cross-Spectrum (vDSP_zcspec)
x = randn(ComplexF64, 256)
y = randn(ComplexF64, 256)
csd = AppleAccelerate.zcspec(x, y) # conj(x[n]) * y[n], accumulatedCoherence (vDSP_zcoher)
n = 256
Sxx = abs2.(randn(ComplexF64, n)) # autospectrum of x
Syy = abs2.(randn(ComplexF64, n)) # autospectrum of y
Sxy = randn(ComplexF64, n) # cross-spectrum
coh = AppleAccelerate.zcoher(Sxx, Syy, Sxy) # |Sxy|^2 / (Sxx * Syy)Transfer Function (vDSP_ztrans)
Sxx = abs2.(randn(ComplexF64, 256))
Sxy = randn(ComplexF64, 256)
H = AppleAccelerate.ztrans(Sxx, Sxy) # Sxy[n] / Sxx[n]AppleAccelerate.zaspec — Function
zaspec(A::Vector{Complex{T}}) -> Vector{T}Autospectrum (power spectrum): returns a real vector C where C[n] = |A[n]|^2. Wraps vDSP_zaspec.
See also zaspec! for the accumulating in-place variant.
AppleAccelerate.zaspec! — Function
Accumulating autospectrum: C[n] += |A[n]|^2. A is a complex vector, C is a real vector that accumulates the power spectrum.
Wraps vDSP_zaspec.
Accumulating autospectrum: C[n] += |A[n]|^2. A is a complex vector, C is a real vector that accumulates the power spectrum.
Wraps vDSP_zaspec.
AppleAccelerate.zcspec — Function
zcspec(A::Vector{Complex{T}}, B::Vector{Complex{T}}) -> Vector{Complex{T}}Cross-spectrum: returns a complex vector C where C[n] = conj(A[n]) * B[n]. Wraps vDSP_zcspec.
See also zcspec! for the accumulating in-place variant.
AppleAccelerate.zcspec! — Function
Accumulating cross-spectrum: C[n] += conj(A[n]) * B[n]. A and B are complex vectors, C is the complex output that accumulates.
Wraps vDSP_zcspec.
Accumulating cross-spectrum: C[n] += conj(A[n]) * B[n]. A and B are complex vectors, C is the complex output that accumulates.
Wraps vDSP_zcspec.
AppleAccelerate.zcoher — Function
zcoher(A::Vector{T}, B::Vector{T}, C::Vector{Complex{T}}) -> Vector{T}Coherence function: returns a real vector D where D[n] = |C[n]|^2 / (A[n] * B[n]). A and B are real power spectra, C is a complex cross-spectrum. Wraps vDSP_zcoher.
See also zcoher! for the in-place variant.
AppleAccelerate.zcoher! — Function
Coherence function: D[n] = |C[n]|^2 / (A[n] * B[n]). A and B are real power spectra, C is a complex cross-spectrum, D is the output coherence.
Wraps vDSP_zcoher.
Coherence function: D[n] = |C[n]|^2 / (A[n] * B[n]). A and B are real power spectra, C is a complex cross-spectrum, D is the output coherence.
Wraps vDSP_zcoher.
AppleAccelerate.ztrans — Function
ztrans(A::Vector{T}, B::Vector{Complex{T}}) -> Vector{Complex{T}}Transfer function: returns a complex vector C where C[n] = B[n] / A[n]. A is a real power spectrum, B is a complex cross-spectrum. Wraps vDSP_ztrans.
See also ztrans! for the in-place variant.
AppleAccelerate.ztrans! — Function
Transfer function: C[n] = B[n] / A[n]. A is a real power spectrum, B is a complex cross-spectrum, C is the output complex transfer function.
Wraps vDSP_ztrans.
Transfer function: C[n] = B[n] / A[n]. A is a real power spectrum, B is a complex cross-spectrum, C is the output complex transfer function.
Wraps vDSP_ztrans.
Window Functions
Wraps Apple's vDSP window generation functions.
| Function | Description |
|---|---|
blackman | Generate a Blackman window |
hamming | Generate a Hamming window |
hanning | Generate a Hanning window |
AppleAccelerate.blackman — Function
blackman(length, [rtype=Float64])Generate a Blackman window of the given length. Wraps vDSP_blkman_window.
AppleAccelerate.hamming — Function
hamming(length, [rtype=Float64])Generate a Hamming window of the given length. Wraps vDSP_hamm_window.
AppleAccelerate.hanning — Function
hanning(length, [rtype=Float64])Generate a Hanning window of the given length. Wraps vDSP_hann_window.