Skip to content

Commit

Permalink
Merge pull request #160 from JuliaDSP/aa/fftw
Browse files Browse the repository at this point in the history
Move DSP functions from Base into this package
  • Loading branch information
ararslan committed Jun 14, 2017
2 parents e776bf2 + 1374a0a commit 3b9aad8
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 44 deletions.
2 changes: 2 additions & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ julia 0.6-rc1
Polynomials 0.1.0
Reexport
SpecialFunctions
AbstractFFTs
FFTW
25 changes: 24 additions & 1 deletion src/DSP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,37 @@ __precompile__()

module DSP

# We want to be very sure we don't pull in Base names unless we're very sure we want them
# This macro will be called in each submodule herein to do the appropriate imports
macro importffts()
quote
using AbstractFFTs, FFTW
importall AbstractFFTs, FFTW
if VERSION >= v"0.7.0-DEV.585"
import AbstractFFTs: fftshift, ifftshift
import FFTW: plan_fft, plan_fft!, plan_rfft, plan_brfft, plan_irfft, plan_bfft, plan_bfft!,
fft, fft!, ifft, ifft!, irfft, bfft, bfft!
if isdefined(Base, :DSP)
import Base: conv, conv2, deconv, filt, filt!, xcorr
end
else
import Base: plan_fft, plan_fft!, plan_rfft, plan_brfft, plan_irfft, plan_bfft, plan_bfft!,
fft, fft!, ifft, ifft!, irfft, bfft, bfft!, fftshift, ifftshift
end
end
end

@importffts

include("dspbase.jl")
include("util.jl")
include("windows.jl")
include("periodograms.jl")
include("Filters/Filters.jl")
include("lpc.jl")

using Reexport
@reexport using .Util, .Windows, .Periodograms, .Filters, .LPC
@reexport using .Util, .Windows, .Periodograms, .Filters, .LPC

include("deprecated.jl")
end
2 changes: 2 additions & 0 deletions src/Filters/Filters.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Filters
import ..DSP: @importffts, filt, filt!
using Polynomials, ..Util
import Base: *
@importffts

include("coefficients.jl")
export FilterCoefficients,
Expand Down
34 changes: 17 additions & 17 deletions src/Filters/filt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
_zerosi(f::PolynomialRatio{T}, x::AbstractArray{S}) where {T,S} =
zeros(promote_type(T, S), max(length(f.a), length(f.b))-1)

Base.filt!(out, f::PolynomialRatio{T}, x::AbstractArray{S}, si=_zerosi(f, x)) where {T,S} =
filt!(out, f::PolynomialRatio{T}, x::AbstractArray{S}, si=_zerosi(f, x)) where {T,S} =
filt!(out, coefb(f), coefa(f), x, si)
Base.filt(f::PolynomialRatio, x, si=_zerosi(f, x)) = filt(coefb(f), coefa(f), x, si)
filt(f::PolynomialRatio, x, si=_zerosi(f, x)) = filt(coefb(f), coefa(f), x, si)

## SecondOrderSections
_zerosi(f::SecondOrderSections{T,G}, x::AbstractArray{S}) where {T,G,S} =
Expand All @@ -36,7 +36,7 @@ function _filt!(out::AbstractArray, si::AbstractArray{S,N}, f::SecondOrderSectio
si
end

function Base.filt!(out::AbstractArray, f::SecondOrderSections, x::AbstractArray,
function filt!(out::AbstractArray, f::SecondOrderSections, x::AbstractArray,
si::AbstractArray{S,N}=_zerosi(f, x)) where {S,N}
biquads = f.biquads
ncols = Base.trailingsize(x, 2)
Expand All @@ -54,7 +54,7 @@ function Base.filt!(out::AbstractArray, f::SecondOrderSections, x::AbstractArray
out
end

Base.filt(f::SecondOrderSections{T,G}, x::AbstractArray{S}, si=_zerosi(f, x)) where {T,G,S<:Number} =
filt(f::SecondOrderSections{T,G}, x::AbstractArray{S}, si=_zerosi(f, x)) where {T,G,S<:Number} =
filt!(Array{promote_type(T, G, S)}(size(x)), f, x, si)

## Biquad
Expand All @@ -75,7 +75,7 @@ function _filt!(out::AbstractArray, si1::Number, si2::Number, f::Biquad,
end

# filt! variant that preserves si
function Base.filt!(out::AbstractArray, f::Biquad, x::AbstractArray,
function filt!(out::AbstractArray, f::Biquad, x::AbstractArray,
si::AbstractArray{S,N}=_zerosi(f, x)) where {S,N}
ncols = Base.trailingsize(x, 2)

Expand All @@ -90,12 +90,12 @@ function Base.filt!(out::AbstractArray, f::Biquad, x::AbstractArray,
out
end

Base.filt(f::Biquad{T}, x::AbstractArray{S}, si=_zerosi(f, x)) where {T,S<:Number} =
filt(f::Biquad{T}, x::AbstractArray{S}, si=_zerosi(f, x)) where {T,S<:Number} =
filt!(Array{promote_type(T, S)}(size(x)), f, x, si)

## For arbitrary filters, convert to SecondOrderSections
Base.filt(f::FilterCoefficients, x) = filt(convert(SecondOrderSections, f), x)
Base.filt!(out, f::FilterCoefficients, x) = filt!(out, convert(SecondOrderSections, f), x)
filt(f::FilterCoefficients, x) = filt(convert(SecondOrderSections, f), x)
filt!(out, f::FilterCoefficients, x) = filt!(out, convert(SecondOrderSections, f), x)

#
# Direct form II transposed filter with state
Expand Down Expand Up @@ -126,7 +126,7 @@ DF2TFilter(coef::PolynomialRatio{T},
state::Vector{S}=zeros(T, max(length(coef.a), length(coef.b))-1)) where {T,S} =
DF2TFilter{PolynomialRatio{T}, Vector{S}}(coef, state)

function Base.filt!(out::AbstractVector, f::DF2TFilter{PolynomialRatio{T},Vector{S}}, x::AbstractVector) where {T,S}
function filt!(out::AbstractVector, f::DF2TFilter{PolynomialRatio{T},Vector{S}}, x::AbstractVector) where {T,S}
length(x) != length(out) && throw(ArgumentError("out size must match x"))

si = f.state
Expand Down Expand Up @@ -156,7 +156,7 @@ DF2TFilter(coef::SecondOrderSections{T,G},
state::Matrix{S}=zeros(promote_type(T, G), 2, length(coef.biquads))) where {T,G,S} =
DF2TFilter{SecondOrderSections{T,G}, Matrix{S}}(coef, state)

function Base.filt!(out::AbstractVector, f::DF2TFilter{SecondOrderSections{T,G},Matrix{S}}, x::AbstractVector) where {T,G,S}
function filt!(out::AbstractVector, f::DF2TFilter{SecondOrderSections{T,G},Matrix{S}}, x::AbstractVector) where {T,G,S}
length(x) != length(out) && throw(ArgumentError("out size must match x"))
_filt!(out, f.state, f.coef, x, 1)
out
Expand All @@ -165,15 +165,15 @@ end
## Biquad
DF2TFilter(coef::Biquad{T}, state::Vector{S}=zeros(T, 2)) where {T,S} =
DF2TFilter{Biquad{T}, Vector{S}}(coef, state)
function Base.filt!(out::AbstractVector, f::DF2TFilter{Biquad{T},Vector{S}}, x::AbstractVector) where {T,S}
function filt!(out::AbstractVector, f::DF2TFilter{Biquad{T},Vector{S}}, x::AbstractVector) where {T,S}
length(x) != length(out) && throw(ArgumentError("out size must match x"))
si = f.state
(si[1], si[2]) =_filt!(out, si[1], si[2], f.coef, x, 1)
out
end

# Variant that allocates the output
Base.filt(f::DF2TFilter{T,S}, x::AbstractVector) where {T,S<:Array} =
filt(f::DF2TFilter{T,S}, x::AbstractVector) where {T,S<:Array} =
filt!(Array{eltype(S)}(length(x)), f, x)

# Fall back to SecondOrderSections
Expand Down Expand Up @@ -353,7 +353,7 @@ end
for n = 2:15
silen = n-1
si = [Symbol("si$i") for i = 1:silen]
@eval function Base.filt!(out, b::NTuple{$n,T}, x) where T
@eval function filt!(out, b::NTuple{$n,T}, x) where T
size(x) != size(out) && error("out size must match x")
ncols = Base.trailingsize(x, 2)
for col = 0:ncols-1
Expand Down Expand Up @@ -386,7 +386,7 @@ end
$chain
end

function Base.filt!(out::AbstractArray, h::AbstractVector, x::AbstractArray)
function filt!(out::AbstractArray, h::AbstractVector, x::AbstractArray)
if length(h) == 1
return scale!(out, h[1], x)
elseif length(h) <= 15
Expand Down Expand Up @@ -415,8 +415,8 @@ function Base.filt!(out::AbstractArray, h::AbstractVector, x::AbstractArray)
out
end

Base.filt(h::AbstractArray, x::AbstractArray) =
Base.filt!(Array{eltype(x)}(size(x)), h, x)
filt(h::AbstractArray, x::AbstractArray) =
filt!(Array{eltype(x)}(size(x)), h, x)

#
# fftfilt and filt
Expand Down Expand Up @@ -511,7 +511,7 @@ end
# Filter x using FIR filter b, heuristically choosing to perform
# convolution in the time domain using filt or in the frequency domain
# using fftfilt
function Base.filt(b::AbstractVector{T}, x::AbstractArray{T}) where T<:Number
function filt(b::AbstractVector{T}, x::AbstractArray{T}) where T<:Number
nb = length(b)
nx = size(x, 1)

Expand Down
24 changes: 12 additions & 12 deletions src/Filters/stream_filt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ end
# Single rate filtering
#

function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRStandard{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
function filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRStandard{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
kernel = self.kernel
history::Vector{Tx} = self.history
bufLen = length(buffer)
Expand All @@ -398,7 +398,7 @@ function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRStandard{Th}}
return xLen
end

function Base.filt(self::FIRFilter{FIRStandard{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
function filt(self::FIRFilter{FIRStandard{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
bufLen = outputlength(self, length(x))
buffer = Array{promote_type(Th,Tx)}(bufLen)
samplesWritten = filt!(buffer, self, x)
Expand All @@ -413,7 +413,7 @@ end
# Interpolation
#

function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRInterpolator{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
function filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRInterpolator{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
kernel = self.kernel
history::Vector{Tx} = self.history
interpolation = kernel.interpolation
Expand Down Expand Up @@ -449,7 +449,7 @@ function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRInterpolator{
return bufIdx
end

function Base.filt(self::FIRFilter{FIRInterpolator{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
function filt(self::FIRFilter{FIRInterpolator{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
bufLen = outputlength(self, length(x))
buffer = Array{promote_type(Th,Tx)}(bufLen)
samplesWritten = filt!(buffer, self, x)
Expand All @@ -464,7 +464,7 @@ end
# Rational resampling
#

function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRRational{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
function filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRRational{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
kernel = self.kernel
history::Vector{Tx} = self.history
xLen = length(x)
Expand Down Expand Up @@ -505,7 +505,7 @@ function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRRational{Th}}
return bufIdx
end

function Base.filt(self::FIRFilter{FIRRational{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
function filt(self::FIRFilter{FIRRational{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
bufLen = outputlength(self, length(x))
buffer = Array{promote_type(Th,Tx)}(bufLen)
samplesWritten = filt!(buffer, self, x)
Expand All @@ -519,7 +519,7 @@ end
# Decimation
#

function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRDecimator{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
function filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRDecimator{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
kernel = self.kernel
xLen = length(x)
history::Vector{Tx} = self.history
Expand Down Expand Up @@ -553,7 +553,7 @@ function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRDecimator{Th}
return bufIdx
end

function Base.filt(self::FIRFilter{FIRDecimator{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
function filt(self::FIRFilter{FIRDecimator{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
bufLen = outputlength(self, length(x))
buffer = Array{promote_type(Th,Tx)}(bufLen)
samplesWritten = filt!(buffer, self, x)
Expand Down Expand Up @@ -582,7 +582,7 @@ function update(kernel::FIRArbitrary)
kernel.α = kernel.ϕAccumulator - kernel.ϕIdx
end

function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRArbitrary{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
function filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRArbitrary{Th}}, x::AbstractVector{Tx}) where {Tb,Th,Tx}
kernel = self.kernel
pfb = kernel.pfb
dpfb = kernel.dpfb
Expand Down Expand Up @@ -624,7 +624,7 @@ function Base.filt!(buffer::AbstractVector{Tb}, self::FIRFilter{FIRArbitrary{Th}
return bufIdx
end

function Base.filt(self::FIRFilter{FIRArbitrary{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
function filt(self::FIRFilter{FIRArbitrary{Th}}, x::AbstractVector{Tx}) where {Th,Tx}
bufLen = outputlength(self, length(x))
buffer = Array{promote_type(Th,Tx)}(bufLen)
samplesWritten = filt!(buffer, self, x)
Expand All @@ -640,13 +640,13 @@ end
#

# Single-rate, decimation, interpolation, and rational resampling.
function Base.filt(h::Vector, x::AbstractVector, ratio::Rational)
function filt(h::Vector, x::AbstractVector, ratio::Rational)
self = FIRFilter(h, ratio)
filt(self, x)
end

# Arbitrary resampling with polyphase interpolation and two neighbor linear interpolation.
function Base.filt(h::Vector, x::AbstractVector, rate::AbstractFloat, Nϕ::Integer=32)
function filt(h::Vector, x::AbstractVector, rate::AbstractFloat, Nϕ::Integer=32)
self = FIRFilter(h, rate, Nϕ)
filt(self, x)
end
Expand Down

0 comments on commit 3b9aad8

Please sign in to comment.