PortAudio.jl/examples/waterfall_lines.jl
Brandon Taylor 5056541968 makie fail
2022-03-08 20:36:47 -05:00

57 lines
No EOL
1.7 KiB
Julia

using Makie, GeometryTypes
using PortAudio
using FFTW
using CairoMakie
function waterfall_lines(seconds;
N = 1024, # size of audio read
D = 200, # number of bins to display
M = 100, # number of lines to draw
S = 0.5, # motion speed of lines
)
PortAudioStream(1, 2) do src
N2 = N ÷ 2 + 1 # size of rfft output
buf = Array{Float32}(undef, N)
fftbuf = Array{Complex{Float32}}(undef, N2)
magbuf = Array{Float32}(undef, N2)
fftplan = plan_rfft(buf; flags = FFTW.EXHAUSTIVE)
scene = Scene(resolution = (500, 500))
ax = axis(0:0.1:1, 0:0.1:1, 0:0.1:0.5)
center!(scene)
ls = map(1:M) do _
yoffset = to_node(to_value(scene[:time]))
offset = lift_node(scene[:time], yoffset) do t, yoff
Point3f0(0.0f0, (t - yoff) * S, 0.0f0)
end
l = lines(
linspace(0, 1, D),
0.0f0,
zeros(Float32, D),
offset = offset,
color = (:black, 0.1),
)
(yoffset, l)
end
done = false
@sync begin
@async begin
while !done
for (yoffset, line) in ls
isopen(scene[:screen]) || break
read!(src, buf)
A_mul_B!(fftbuf, fftplan, buf)
@. magbuf = log(clamp(abs(fftbuf), 0.0001, Inf)) / 10 + 0.5
line[:z] = magbuf[1:D]
push!(yoffset, to_value(scene[:time]))
end
end
end
sleep(seconds)
done = true
end
end
end
waterfall_lines(5)