makie fail

This commit is contained in:
Brandon Taylor 2022-03-08 20:36:47 -05:00
parent f708835e5a
commit 5056541968
3 changed files with 95 additions and 69 deletions

View file

@ -18,8 +18,6 @@ jobs:
matrix: matrix:
version: version:
- '1.3' - '1.3'
- '1.4'
- '1.5'
- '1' - '1'
- 'nightly' - 'nightly'
os: os:

View file

@ -1,6 +1,8 @@
using Makie using Makie
using PortAudio using PortAudio
using DSP using DSP
using LinearAlgebra
using FFTW
""" """
Slide the values in the given matrix to the right by 1. Slide the values in the given matrix to the right by 1.
@ -16,52 +18,64 @@ end
""" """
takes a block of audio, FFT it, and write it to the beginning of the buffer takes a block of audio, FFT it, and write it to the beginning of the buffer
""" """
function processbuf!(readbuf, win, dispbuf, fftbuf, fftplan) function processbuf!(readbuf, win, dispbuf, fftbuf, fftplan; D = 200)
readbuf .*= win readbuf .*= win
A_mul_B!(fftbuf, fftplan, readbuf) mul!(fftbuf, fftplan, readbuf)
shift1!(dispbuf) shift1!(dispbuf)
@. dispbuf[end:-1:1, 1] = log(clamp(abs(fftbuf[1:D]), 0.0001, Inf)) @. dispbuf[end:-1:1, 1] = log(clamp(abs(fftbuf[1:D]), 0.0001, Inf))
end end
function processblock!(src, buf, win, dispbufs, fftbuf, fftplan) function processblock!(src, buf, win, dispbufs, fftbuf, fftplan; D = 200)
read!(src, buf) read!(src, buf)
for dispbuf in dispbufs for dispbuf in dispbufs
processbuf!(buf, win, dispbuf, fftbuf, fftplan) processbuf!(buf, win, dispbuf, fftbuf, fftplan; D = D)
end end
end end
N = 1024 # size of audio read function waterfall_heatmap(seconds;
N2 = N ÷ 2 + 1 # size of rfft output N = 1024, # size of audio read
D = 200 # number of bins to display D = 200, # number of bins to display
M = 200 # amount of history to keep M = 200, # amount of history to keep
src = PortAudioStream(1, 2) )
buf = Array{Float32}(N) # buffer for reading N2 = N ÷ 2 + 1 # size of rfft output
fftplan = plan_rfft(buf; flags = FFTW.EXHAUSTIVE) PortAudioStream(1, 2) do src
fftbuf = Array{Complex{Float32}}(N2) # destination buf for FFT buf = Array{Float32}(undef, N) # buffer for reading
dispbufs = [zeros(Float32, D, M) for i in 1:5, j in 1:5] # STFT bufs fftplan = plan_rfft(buf; flags = FFTW.EXHAUSTIVE)
win = gaussian(N, 0.125) fftbuf = Array{Complex{Float32}}(undef, N2) # destination buf for FFT
dispbufs = [zeros(Float32, D, M) for i in 1:5, j in 1:5] # STFT bufs
win = gaussian(N, 0.125)
scene = Scene(resolution = (1000, 1000)) scene = Scene(resolution = (1000, 1000))
#pre-fill the display buffer so we can do a reasonable colormap #pre-fill the display buffer so we can do a reasonable colormap
for _ in 1:M for _ in 1:M
processblock!(src, buf, win, dispbufs, fftbuf, fftplan) processblock!(src, buf, win, dispbufs, fftbuf, fftplan; D = D)
end end
heatmaps = map(enumerate(IndexCartesian(), dispbufs)) do ibuf heatmaps = map(zip(CartesianIndices(dispbufs), dispbufs)) do ibuf
i = ibuf[1] i = ibuf[1]
buf = ibuf[2] buf = ibuf[2]
# some function of the 2D index and the value # some function of the 2D index and the value
heatmap(buf, offset = (i[2] * size(buf, 2), i[1] * size(buf, 1))) heatmap(buf, offset = (i[2] * size(buf, 2), i[1] * size(buf, 1)))
end end
center!(scene) center!(scene)
while isopen(scene[:screen]) done = false
processblock!(src, buf, dispbufs, fftbuf, fftplan)
for (hm, db) in zip(heatmaps, dispbufs) @sync begin
hm[:heatmap] = db @async while !done
processblock!(src, buf, win, dispbufs, fftbuf, fftplan)
for (hm, db) in zip(heatmaps, dispbufs)
hm[:heatmap] = db
end
render_frame(scene)
end
sleep(seconds)
done = true
end
end end
render_frame(scene)
end end
waterfall_heatmap(5)

View file

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