diff --git a/src/Filters/stream_filt.jl b/src/Filters/stream_filt.jl index 4f542958..17cc1666 100644 --- a/src/Filters/stream_filt.jl +++ b/src/Filters/stream_filt.jl @@ -630,6 +630,19 @@ end function filt(self::FIRFilter{Tk}, x::AbstractVector{Tx}) where {Th,Tx,Tk<:FIRKernel{Th}} bufLen = outputlength(self, length(x)) + # In some cases when `filt(::FIRFilter{FIRArbitrary}, x)` is called + # with certain values of `x`, `filt!(buffer, ::FIRFilter{FIRArbitrary}, x)` + # tries to write one sample too many to the buffer and a `BoundsError` + # is thrown. Add one extra sample to catch these exceptional cases. + # + # See https://github.com/JuliaDSP/DSP.jl/issues/317 + # + # FIXME: Remove this if and when the code in + # `filt!(buffer, ::FIRFilter{FIRArbitrary}, x)` + # is updated to properly account for pathological arbitrary rates. + if Tk <: FIRArbitrary + bufLen += 1 + end buffer = Vector{promote_type(Th,Tx)}(undef, bufLen) samplesWritten = filt!(buffer, self, x) diff --git a/test/resample.jl b/test/resample.jl index 7a437db2..78b174f4 100644 --- a/test/resample.jl +++ b/test/resample.jl @@ -97,6 +97,16 @@ end @test all(map(delta -> abs(delta) < 0.005, yDelta)) end +@testset "arbitrary ratio" begin + # https://github.com/JuliaDSP/DSP.jl/issues/317 + @testset "Buffer length calculation" begin + @test length(resample(sin.(1:1:35546), 1/55.55)) == 641 + @test length(resample(randn(1822), 0.9802414928649835)) == 1787 + @test length(resample(1:16_367_000*2, 10_000_000/16_367_000)) == 20_000_001 + @test resample(zeros(1000), 0.012) == zeros(13) + end +end + @testset "resample_filter" begin @testset "decimation" begin ratio = 1//2