versions of single rate, interpolation, decimation, and rational resampling. The hardest part was getting stateful resampling working the I wanted it. I didn't want the user to have to think about the size of the data they are feeding the filters. If you feed one of the filters a single sample, and it doesn't have enough to calculate a new input, it will store the sample in the delay line. Or if you feed enough samples to return some results, but it still has some samples leftover, it will store those leftovers in the delay line until you call it again.
I'm not totally happy withe all my design choices. Currently, I have the state preserving version of
filt calling the stateless functions
decimate,
interpolate, and
resample. In order to get some of them to work that way, I had to add arguments indicating what x index to start at, the initial phase of the filter bank, and the delay line. I think I should do the reverse, where if you call a filtering operation without filter object, one is created in the background. There is a little overhead for very short filter lengths, but it is probably insignificant for long input vectors. There a bunch of early design choices that I now realize weren't great, so I'll be fixing those.
Here's an example of the rational resampler:
julia> ratio = 3//5;
julia> h = [1.0:9.0];
julia> x = [1.0:20.0];
julia> resampler = FIRFilter( h, ratio )
FIRFilter{FIRRational}(FIRRational(3x3 Array{Float64,2}:
1.0 2.0 3.0
4.0 5.0 6.0
7.0 8.0 9.0,3//5,1),[0.0,0.0],2)
julia> filt( resampler, x[1:1] )
1-element Array{Float64,1}:
1.0
julia> filt( resampler, x[2:2] )
1-element Array{Float64,1}:
12.0
julia> filt( resampler, x[3:3] )
0-element Array{Float64,1}
julia> filt( resampler, x[4:4] )
1-element Array{Float64,1}:
39.0
julia> filt( resampler, x[5:9] )
3-element Array{Float64,1}:
54.0
102.0
114.0
julia> filt( resampler, x[10:end] )
6-element Array{Float64,1}:
114.0
192.0
189.0
174.0
282.0
264.0