Advertisement
Guest User

Audio resampler

a guest
Feb 28th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 2.14 KB | None | 0 0
  1. module Resampler
  2.  
  3. int_steps = 250
  4.  
  5. trig_poly(w::AbstractFloat) = (-cos(3pi*w) + 9cos(pi*w) + 8)/16
  6.  
  7. function integrate_function(func, min :: T, max :: T) where {T <: AbstractFloat}
  8.     local delta :: T = 1 / int_steps
  9.     local sum :: T = 0
  10.  
  11.     for x in min:delta:max
  12.         sum += delta * (func(x) + 4func(x + delta/2) + func(x + delta))/6
  13.     end
  14.     return sum
  15. end
  16.  
  17. function filter_coeff(n :: Int64, cutoff, transition)
  18.     if n == 0
  19.         return cutoff
  20.     end
  21.     return 2*cutoff*transition*integrate_function((w) ->
  22.                  trig_poly(w) * cos(2pi*n*(cutoff*transition*w + cutoff*(1-transition)/2)), 0.0, 1.0) +
  23.                      sin(cutoff*(1-transition)*n*pi) / (pi*n)
  24. end
  25.  
  26. function filter_bank(phases :: Int64, length :: Int64; cutoff = 0.5f0, transition = 0.1f0, T = Float64)
  27.     local filter = Array{T, 2}(undef, phases, length)
  28.     local total_len = phases*length
  29.     local max_idx = (total_len & 1 == 0) ? total_len-1 : total_len
  30.     local lin_len = div(max_idx-1,2)
  31.     for i in 0:phases-1
  32.         for j in 0:length-1
  33.             local idx = j*phases + i
  34.             filter[i+1,j+1] = filter_coeff(abs(idx - lin_len), cutoff, transition)
  35.         end
  36.     end
  37.     return filter        
  38. end
  39.  
  40. function resample(array :: Array{T, 1}, ratio :: Rational{Int64}) where {T <: AbstractFloat}
  41.     local up = numerator(ratio)
  42.     local down = denominator(ratio)
  43.     local filter = filter_bank(up, 270, cutoff = 1/max(up, down), transition = 1/15f0, T=T)
  44.     local in_len = length(array)
  45.     local filter_len = size(filter,2)
  46.     local out_len = div(in_len*up, down)
  47.     local output = zeros(T, out_len)
  48.     @Threads.threads for i1 = 0:4:out_len-1
  49.         for i2 = 0:3
  50.             local i = i1+i2
  51.             if i<out_len
  52.                 local in_idx = div(i*down, up)
  53.                 local flt_idx = rem(i*down, up)
  54.                 for j = 0:filter_len-1
  55.                     local idx = in_idx - j
  56.                     output[i+1] += up * filter[flt_idx+1, j+1] * ((idx < 0) ? 0 : array[idx+1])
  57.                 end
  58.             end
  59.         end
  60.     end
  61.     return output
  62. end
  63.  
  64. export filter_bank, resample
  65. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement