Filtering & Spectral Analysis

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) - 1
AppleAccelerate.convFunction
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.

source
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.

source

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.xcorrFunction
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.

source
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.

source

Biquad Filtering

Wraps vDSP_biquad. IIR filtering via cascaded biquad sections. Both Float64 and Float32 processing are supported; coefficients are always Float64.

X = randn(Float64, 100)
coefficients = randn(5)  # 5 coefficients per section
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)
AppleAccelerate.biquadcreateFunction
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.

source
AppleAccelerate.biquadFunction
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.

source

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)
AppleAccelerate.biquadmFunction
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.

source

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 samples

The 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) + 1

Wiener-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 success
AppleAccelerate.deq22Function
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)

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

source
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

source
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

source
AppleAccelerate.desampFunction
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}

source
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}

source
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

source
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

source
AppleAccelerate.wienerFunction
wiener(A::Vector{Float32}, C::Vector{Float32}; flag::Int=0)

Allocating version of wiener!. Returns (F, error_code).

source
wiener(A::Vector{Float64}, C::Vector{Float64}; flag::Int=0)

Allocating version of wiener!. Returns (F, error_code).

source
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.

source
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.

source

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]|^2

The 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], accumulated

Coherence (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.zaspecFunction
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.

source
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.

source

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.

source
AppleAccelerate.zcspecFunction
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.

source
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.

source

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.

source
AppleAccelerate.zcoherFunction
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.

source
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.

source

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.

source
AppleAccelerate.ztransFunction
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.

source
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.

source

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.

source

Window Functions

Wraps Apple's vDSP window generation functions.

FunctionDescription
blackmanGenerate a Blackman window
hammingGenerate a Hamming window
hanningGenerate a Hanning window