From ee30bf233314cc1f40e3afa59ae2ebacf2df1717 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Tue, 19 Nov 2024 10:45:05 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Fix=20`setphase!(::Union{FIRInterpolator,?= =?UTF-8?q?=20FIRRational},=20=CF=95)`=20for=20pathological=20cases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For odd number of phases `Nφ` and even length of the filter kernel, the old code would yield `qidx` above `Nφ`, namely equal tp `Nφ+1`, which would result in a `BoundsError` during `resample`. Rewrite the code to reduce `qidx` to `1` in this case and increase `inputDeficit` by one instead. All other constellations should be unaffected. --- src/Filters/stream_filt.jl | 6 +++--- test/filt_stream.jl | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Filters/stream_filt.jl b/src/Filters/stream_filt.jl index c4a35742a..235c02e42 100644 --- a/src/Filters/stream_filt.jl +++ b/src/Filters/stream_filt.jl @@ -218,9 +218,9 @@ end function setphase!(kernel::Union{FIRInterpolator, FIRRational}, ϕ::Real) ϕ >= zero(ϕ) || throw(ArgumentError("ϕ must be >= 0")) - (ϕ, xThrowaway) = modf(ϕ) - kernel.inputDeficit += round(Int, xThrowaway) - kernel.ϕIdx = round(ϕ*(kernel.Nϕ) + 1.0) + xThrowaway, ϕIdx = divrem(round(Int, ϕ * kernel.Nϕ), kernel.Nϕ) + kernel.inputDeficit += xThrowaway + kernel.ϕIdx = ϕIdx + 1 nothing end diff --git a/test/filt_stream.jl b/test/filt_stream.jl index 51bee9dee..65457f1e0 100644 --- a/test/filt_stream.jl +++ b/test/filt_stream.jl @@ -361,3 +361,7 @@ end test_rational(h, x, interpolation) end end + +# check that these don't throw; the output should actually probably be longer +@test resample(1:2, 3, [zeros(2); 1; zeros(3)]) == [1, 0, 0, 2] # [1, 0, 0, 2, 0, 0] +@test resample(1:2, 3//2, [zeros(2); 1; zeros(3)]) == [1, 0] # [1, 0, 0] From 4e6d621555fd5d6ddf7b76a58f4838c60ff10dbf Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Tue, 19 Nov 2024 16:45:04 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Fix=20`setphase!(::FIRArbitrary,=20=CF=95)`?= =?UTF-8?q?=20similarly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Here, the problem is less severe as it requires an explcit call to `setphase!` with a problematic phase which cannot be hit within normal `resample` operation. --- src/Filters/stream_filt.jl | 2 +- test/filt_stream.jl | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Filters/stream_filt.jl b/src/Filters/stream_filt.jl index 235c02e42..10d424ce6 100644 --- a/src/Filters/stream_filt.jl +++ b/src/Filters/stream_filt.jl @@ -229,7 +229,7 @@ function setphase!(kernel::FIRArbitrary, ϕ::Real) (ϕ, xThrowaway) = modf(ϕ) kernel.inputDeficit += round(Int, xThrowaway) kernel.ϕAccumulator = ϕ*(kernel.Nϕ) + 1.0 - kernel.ϕIdx = round(kernel.ϕAccumulator) + kernel.ϕIdx = floor(kernel.ϕAccumulator) kernel.α = modf(kernel.ϕAccumulator)[1] nothing end diff --git a/test/filt_stream.jl b/test/filt_stream.jl index 65457f1e0..1c17e1c03 100644 --- a/test/filt_stream.jl +++ b/test/filt_stream.jl @@ -365,3 +365,11 @@ end # check that these don't throw; the output should actually probably be longer @test resample(1:2, 3, [zeros(2); 1; zeros(3)]) == [1, 0, 0, 2] # [1, 0, 0, 2, 0, 0] @test resample(1:2, 3//2, [zeros(2); 1; zeros(3)]) == [1, 0] # [1, 0, 0] +let H = FIRFilter(2.22) + setphase!(H, 0.99) + @test length(filt(H, 1:2)) == 3 +end +let H = FIRFilter(122.2) + setphase!(H, 0.99) + @test length(filt(H, 1:2)) == 124 +end