Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Resampler
- int_steps = 250
- trig_poly(w::AbstractFloat) = (-cos(3pi*w) + 9cos(pi*w) + 8)/16
- function integrate_function(func, min :: T, max :: T) where {T <: AbstractFloat}
- local delta :: T = 1 / int_steps
- local sum :: T = 0
- for x in min:delta:max
- sum += delta * (func(x) + 4func(x + delta/2) + func(x + delta))/6
- end
- return sum
- end
- function filter_coeff(n :: Int64, cutoff, transition)
- if n == 0
- return cutoff
- end
- return 2*cutoff*transition*integrate_function((w) ->
- trig_poly(w) * cos(2pi*n*(cutoff*transition*w + cutoff*(1-transition)/2)), 0.0, 1.0) +
- sin(cutoff*(1-transition)*n*pi) / (pi*n)
- end
- function filter_bank(phases :: Int64, length :: Int64; cutoff = 0.5f0, transition = 0.1f0, T = Float64)
- local filter = Array{T, 2}(undef, phases, length)
- local total_len = phases*length
- local max_idx = (total_len & 1 == 0) ? total_len-1 : total_len
- local lin_len = div(max_idx-1,2)
- for i in 0:phases-1
- for j in 0:length-1
- local idx = j*phases + i
- filter[i+1,j+1] = filter_coeff(abs(idx - lin_len), cutoff, transition)
- end
- end
- return filter
- end
- function resample(array :: Array{T, 1}, ratio :: Rational{Int64}) where {T <: AbstractFloat}
- local up = numerator(ratio)
- local down = denominator(ratio)
- local filter = filter_bank(up, 270, cutoff = 1/max(up, down), transition = 1/15f0, T=T)
- local in_len = length(array)
- local filter_len = size(filter,2)
- local out_len = div(in_len*up, down)
- local output = zeros(T, out_len)
- @Threads.threads for i1 = 0:4:out_len-1
- for i2 = 0:3
- local i = i1+i2
- if i<out_len
- local in_idx = div(i*down, up)
- local flt_idx = rem(i*down, up)
- for j = 0:filter_len-1
- local idx = in_idx - j
- output[i+1] += up * filter[flt_idx+1, j+1] * ((idx < 0) ? 0 : array[idx+1])
- end
- end
- end
- end
- return output
- end
- export filter_bank, resample
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement