Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for macos 11 and later (Big Sur onwards, including current Monterey) #43

Merged
merged 1 commit into from
Aug 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name = "AppleAccelerate"
uuid = "13e28ba4-7ad8-5781-acae-3021b1ed3924"
version = "0.3.1"

[deps]
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[compat]
julia = "1"

Expand All @@ -13,4 +16,4 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = [ "DSP", "Statistics", "LinearAlgebra", "Test", "Random"]
test = ["DSP", "Statistics", "LinearAlgebra", "Test", "Random"]
10 changes: 7 additions & 3 deletions src/AppleAccelerate.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
__precompile__()
module AppleAccelerate

const libacc = "/System/Library/Frameworks/Accelerate.framework/Accelerate"
using Libdl

if !isfile(libacc)
error("Accelerate framework not found at $(libacc)")
try
global const libacc = dlopen("/System/Library/Frameworks/Accelerate.framework/Accelerate")
catch
error("Accelerate framework not found.")
end

get_fptr(s) = dlsym(libacc, s)

include("Array.jl")
include("DSP.jl")
include("Util.jl")
Expand Down
44 changes: 26 additions & 18 deletions src/Array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ for (T, suff) in ((Float64, ""), (Float32, "f"))

# In-place mutating variant
function ($f!)(out::Array{$T}, X::Array{$T})
ccall(($(string("vv",fa,suff)),libacc),Cvoid,
(Ptr{$T},Ptr{$T},Ref{Cint}),out,X,length(X))
fptr = get_fptr($(string("vv", fa, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Ptr{$T}, Ref{Cint}), out, X, length(X))
out
end
end
Expand All @@ -52,8 +53,9 @@ for (T, suff) in ((Float64, ""), (Float32, "f"))
($f!)(out, X, Y)
end
function ($f!)(out::Array{$T}, X::Array{$T}, Y::Array{$T})
ccall(($(string("vv",fa,suff)),libacc),Cvoid,
(Ptr{$T},Ptr{$T},Ptr{$T},Ref{Cint}),out,X,Y,length(X))
fptr = get_fptr($(string("vv", fa, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Ptr{$T}, Ptr{$T}, Ref{Cint}), out, X, Y, length(X))
out
end
end
Expand All @@ -69,8 +71,9 @@ for (T, suff) in ((Float64, ""), (Float32, "f"))
($f!)(out, X, Y)
end
function ($f!)(out::Array{$T}, X::Array{$T}, Y::Array{$T})
ccall(($(string("vv",fa,suff)),libacc),Cvoid,
(Ptr{$T},Ptr{$T},Ptr{$T},Ref{Cint}),out,Y,X,length(X))
fptr = get_fptr($(string("vv", fa, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Ptr{$T}, Ptr{$T}, Ref{Cint}), out, Y, X, length(X))
out
end
end
Expand All @@ -86,8 +89,9 @@ for (T, suff) in ((Float64, ""), (Float32, "f"))
($f!)(out1, out2, X)
end
function ($f!)(out1::Array{$T}, out2::Array{$T}, X::Array{$T})
ccall(($(string("vv",f,suff)),libacc),Cvoid,
(Ptr{$T},Ptr{$T},Ptr{$T},Ref{Cint}),out1,out2,X,length(X))
fptr = get_fptr($(string("vv", f, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Ptr{$T}, Ptr{$T}, Ref{Cint}), out1, out2, X, length(X))
out1, out2
end
end
Expand All @@ -102,8 +106,9 @@ for (T, suff) in ((Float64, ""), (Float32, "f"))
($f!)(out, X)
end
function ($f!)(out::Array{Complex{$T}}, X::Array{$T})
ccall(($(string("vv",fa,suff)),libacc),Cvoid,
(Ptr{Complex{$T}},Ptr{$T},Ref{Cint}),out,X,length(X))
fptr = get_fptr($(string("vv", fa, suff)))
ccall(fptr, Cvoid,
(Ptr{Complex{$T}}, Ptr{$T}, Ref{Cint}), out, X, length(X))
out
end
end
Expand Down Expand Up @@ -135,9 +140,10 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
@eval begin
function ($f)(X::Vector{$T})
val = Ref{$T}(0.0)
ccall(($(string("vDSP_", fa, suff), libacc)), Cvoid,
(Ptr{$T}, Int64, Ref{$T}, UInt64),
X, 1, val, length(X))
fptr = get_fptr($(string("vDSP_", fa, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Int64, Ref{$T}, UInt64),
X, 1, val, length(X))
return val[]
end
end
Expand All @@ -148,10 +154,11 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
function ($f)(X::Vector{$T})
index = Ref{Int}(0)
val = Ref{$T}(0.0)
ccall(($(string("vDSP_", fa, suff), libacc)), Cvoid,
(Ptr{$T}, Int64, Ref{$T}, Ref{Int}, UInt64),
X, 1, val, index, length(X))
return (val[], index[]+1)
fptr = get_fptr($(string("vDSP_", fa, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Int64, Ref{$T}, Ref{Int}, UInt64),
X, 1, val, index, length(X))
return (val[], index[] + 1)
end
end
end
Expand All @@ -172,7 +179,8 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
the result vector with computed value. *Returns:* **Vector{$($T)}** `result`
""" ->
function ($f!)(result::Vector{$T}, X::Vector{$T}, Y::Vector{$T})
ccall(($(string("vDSP_", f, suff), libacc)), Cvoid,
fptr = get_fptr($(string("vDSP_", f, suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Int64, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64),
Y, 1, X, 1, result, 1, length(result))
return result
Expand Down
114 changes: 63 additions & 51 deletions src/DSP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ for (T, suff) in ((Float64, "D"), (Float32, ""))
if (rsize < xsize + ksize - 1)
error("'result' must have at least length(X) + length(K) - 1 elements")
end
xpadded::Vector{$T} = [zeros($T, ksize-1); X; zeros($T, ksize)]
ccall(($(string("vDSP_conv", suff), libacc)), Cvoid,
(Ptr{$T}, Int64, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64, UInt64),
xpadded, 1, pointer(K, ksize), -1, result, 1, rsize, ksize)
xpadded::Vector{$T} = [zeros($T, ksize - 1); X; zeros($T, ksize)]
fptr = get_fptr($(string("vDSP_conv", suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Int64, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64, UInt64),
xpadded, 1, pointer(K, ksize), -1, result, 1, rsize, ksize)
return result
end
end
Expand Down Expand Up @@ -87,10 +88,11 @@ for (T, suff) in ((Float64, "D"), (Float32, ""))
if (rsize < xsize + ysize - 1)
error("'result' must have at least length(X) + length(Y) - 1 elements")
end
xpadded::Vector{$T} = [zeros($T, ysize-1); X; zeros($T, ysize)]
ccall(($(string("vDSP_conv", suff), libacc)), Cvoid,
(Ptr{$T}, Int64, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64, UInt64),
xpadded, 1, Y, 1, result, 1, rsize, ysize)
xpadded::Vector{$T} = [zeros($T, ysize - 1); X; zeros($T, ysize)]
fptr = get_fptr($(string("vDSP_conv", suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, Int64, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64, UInt64),
xpadded, 1, Y, 1, result, 1, rsize, ysize)
return result
end
end
Expand Down Expand Up @@ -134,7 +136,7 @@ for (T, suff) in ((Float64, "D"), (Float32, ""))
end

## == Biquadratic/IIR filtering
for (T, suff) in ((Float64, "D"), )
for (T, suff) in ((Float64, "D"),)

"""
Initializes a vDSP_biquad_setup for use with vDSP_biquad. A multi-section filter
Expand All @@ -145,14 +147,15 @@ for (T, suff) in ((Float64, "D"), )
Returns: Biquad{T}
"""
@eval begin
function biquadcreate(coefficients::Vector{$T}, sections::Int)
if length(coefficients) < 5*sections
function biquadcreate(coefficients::Vector{$T}, sections::Int)
if length(coefficients) < 5 * sections
error("Incomplete biquad specification provided - coefficients must
contain 5 elements for each filter section")
end
setup = ccall(($(string("vDSP_biquad_CreateSetup", suff), libacc)), Ptr{Cvoid},
(Ptr{$T}, UInt64),
coefficients, sections)
fptr = get_fptr($(string("vDSP_biquad_CreateSetup", suff)))
setup = ccall(fptr, Ptr{Cvoid},
(Ptr{$T}, UInt64),
coefficients, sections)
return Biquad($T, setup, sections)
end
end
Expand All @@ -167,14 +170,15 @@ for (T, suff) in ((Float64, "D"), )
"""
@eval begin
function biquad(X::Vector{$T}, delays::Vector{$T}, numelem::Int, biquad::Biquad{$T})
if length(delays) < (2*(biquad.sections)+2)
if length(delays) < (2 * (biquad.sections) + 2)
error("Incomplete delay specification provided - delays must contain 2*M + 2
values where M is the number of sections in the biquad")
end
result::Vector{$T} = similar(X)
ccall(($(string("vDSP_biquad", suff), libacc)), Cvoid,
(Ptr{Cvoid}, Ptr{$T}, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64),
biquad.setup, delays, X, 1, result, 1, numelem)
fptr = get_fptr($(string("vDSP_biquad", suff)))
ccall(fptr, Cvoid,
(Ptr{Cvoid}, Ptr{$T}, Ptr{$T}, Int64, Ptr{$T}, Int64, UInt64),
biquad.setup, delays, X, 1, result, 1, numelem)
return result
end
end
Expand All @@ -189,9 +193,10 @@ for (T, suff) in ((Float64, "D"), )
"""
@eval begin
function biquaddestroy(biquad::Biquad{$T})
ccall(($(string("vDSP_biquad_DestroySetup", suff), libacc)), Cvoid,
(Ptr{Cvoid}, ),
biquad.setup)
fptr = get_fptr($(string("vDSP_biquad_DestroySetup", suff)))
ccall(fptr, Cvoid,
(Ptr{Cvoid},),
biquad.setup)
end
end
end
Expand All @@ -205,7 +210,7 @@ Generates a Blackman window of length 'length'. Default return type
is Vector{Float64}, but if rtype=Float32, Vector{Float32}
will be returned.
"""
function blackman(length::Int, rtype::DataType=Float64)
function blackman(length::Int, rtype::DataType = Float64)
result::Vector{rtype} = Array{rtype}(undef, length)
blackman!(result, length, 0)
end
Expand All @@ -217,7 +222,7 @@ Generates a Hamming window of length 'length'. Default return type
is Vector{Float64}, but if rtype=Float32, Vector{Float32}
will be returned.
"""
function hamming(length::Int, rtype::DataType=Float64)
function hamming(length::Int, rtype::DataType = Float64)
result::Vector{rtype} = Array{rtype}(undef, length)
hamming!(result, length, 0)
end
Expand All @@ -229,15 +234,15 @@ Generates a denormalized Hanning window of length 'length'. Default
return type is Vector{Float64}, but if rtype=Float32, Vector{Float32}
will be returned.
"""
function hanning(length::Int, rtype::DataType=Float64)
function hanning(length::Int, rtype::DataType = Float64)
result::Vector{rtype} = Array{rtype}(undef, length)
hanning!(result, length, 0)
end

"""
Alias function for `hanning`
"""
function hann(length::Int, rtype::DataType=Float64)
function hann(length::Int, rtype::DataType = Float64)
hanning(length, rtype)
end

Expand All @@ -251,10 +256,11 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
Returns: Vector{$T}
"""
@eval begin
function blackman!(result::Vector{$T}, length::Int, flag::Int=0)
ccall(($(string("vDSP_blkman_window", suff), libacc)), Cvoid,
(Ptr{$T}, UInt64, Int64),
result, length, flag)
function blackman!(result::Vector{$T}, length::Int, flag::Int = 0)
fptr = get_fptr($(string("vDSP_blkman_window", suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, UInt64, Int64),
result, length, flag)
return result
end
end
Expand All @@ -268,10 +274,11 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
Returns: Vector{$T}
"""
@eval begin
function hamming!(result::Vector{$T}, length::Int, flag::Int=0)
ccall(($(string("vDSP_hamm_window", suff), libacc)), Cvoid,
(Ptr{$T}, UInt64, Int64),
result, length, flag)
function hamming!(result::Vector{$T}, length::Int, flag::Int = 0)
fptr = get_fptr($(string("vDSP_hamm_window", suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, UInt64, Int64),
result, length, flag)
return result
end
end
Expand All @@ -289,10 +296,11 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
Returns: Vector{$T}
"""
@eval begin
function hanning!(result::Vector{$T}, length::Int, flag::Int=0)
ccall(($(string("vDSP_hann_window", suff), libacc)), Cvoid,
(Ptr{$T}, UInt64, Int64),
result, length, flag)
function hanning!(result::Vector{$T}, length::Int, flag::Int = 0)
fptr = get_fptr($(string("vDSP_hann_window", suff)))
ccall(fptr, Cvoid,
(Ptr{$T}, UInt64, Int64),
result, length, flag)
return result
end
end
Expand All @@ -303,7 +311,7 @@ for (T, suff) in ((Float32, ""), (Float64, "D"))
Returns: Vector{$T}
"""
@eval begin
function hann!(result::Vector{$T}, length::Int, flag::Int=0)
function hann!(result::Vector{$T}, length::Int, flag::Int = 0)
hanning!(result, length, flag)
end
end
Expand All @@ -320,17 +328,18 @@ storage of the previous setup object.

Returns: DFTSetup
"""
function plan_dct(length::Int, dct_type::Int, previous=C_NULL)
function plan_dct(length::Int, dct_type::Int, previous = C_NULL)
n = trailing_zeros(length)
f = length >> n
if dct_type < 2 && dct_type > 4
if dct_type < 2 && dct_type > 4
error("DCT type ", dct_type, " is not supported. Only DCT types 2, 3 and 4 are supported")
elseif !(n >= 4 && f in (1,3,5,15))
elseif !(n >= 4 && f in (1, 3, 5, 15))
error("Invalid DCT length. Length must be equal to f*(2^n) where f = 1,3,5,15 and n >= 4")
end
setup::Ptr{Cvoid} = ccall(("vDSP_DCT_CreateSetup", libacc), Ptr{Cvoid},
(Ptr{Cvoid}, UInt64, UInt64),
previous, length, dct_type)
fptr = get_fptr("vDSP_DCT_CreateSetup")
setup::Ptr{Cvoid} = ccall(fptr, Ptr{Cvoid},
(Ptr{Cvoid}, UInt64, UInt64),
previous, length, dct_type)
return DFTSetup(Float32, setup, 0)
end

Expand All @@ -343,9 +352,11 @@ Returns: Vector{Float32}
"""
function dct(X::Vector{Float32}, setup::DFTSetup)
result = similar(X)
ccall(("vDSP_DCT_Execute", libacc), Cvoid,
(Ptr{Cvoid}, Ptr{Float32}, Ptr{Float32}),
setup.setup, X, result)
fptr = get_fptr("vDSP_DCT_Execute")

ccall(fptr, Cvoid,
(Ptr{Cvoid}, Ptr{Float32}, Ptr{Float32}),
setup.setup, X, result)
return result
end

Expand All @@ -356,7 +367,7 @@ This function does not require a separate call to dct_setup.

Returns: Vector{Float32}
"""
function dct(X::Vector{Float32}, dct_type::Int=2)
function dct(X::Vector{Float32}, dct_type::Int = 2)
setup = plan_dct(length(X), dct_type)
return dct(X, setup)
end
Expand All @@ -366,9 +377,10 @@ end
Deinitializes a DFTSetup object created by plan_dct
"""
function plan_destroy(setup::DFTSetup)
ccall(("vDSP_DFT_DestroySetup", libacc), Cvoid,
(Ptr{Cvoid},),
setup.setup)
fptr = get_fptr("vDSP_DFT_DestroySetup")
ccall(fptr, Cvoid,
(Ptr{Cvoid},),
setup.setup)
end


Expand Down