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:
version:
- '1.3'
- '1.4'
- '1.5'
- '1'
- 'nightly'
os:

View file

@ -1,6 +1,8 @@
using Makie
using PortAudio
using DSP
using LinearAlgebra
using FFTW
"""
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
"""
function processbuf!(readbuf, win, dispbuf, fftbuf, fftplan)
function processbuf!(readbuf, win, dispbuf, fftbuf, fftplan; D = 200)
readbuf .*= win
A_mul_B!(fftbuf, fftplan, readbuf)
mul!(fftbuf, fftplan, readbuf)
shift1!(dispbuf)
@. dispbuf[end:-1:1, 1] = log(clamp(abs(fftbuf[1:D]), 0.0001, Inf))
end
function processblock!(src, buf, win, dispbufs, fftbuf, fftplan)
function processblock!(src, buf, win, dispbufs, fftbuf, fftplan; D = 200)
read!(src, buf)
for dispbuf in dispbufs
processbuf!(buf, win, dispbuf, fftbuf, fftplan)
processbuf!(buf, win, dispbuf, fftbuf, fftplan; D = D)
end
end
N = 1024 # size of audio read
N2 = N ÷ 2 + 1 # size of rfft output
D = 200 # number of bins to display
M = 200 # amount of history to keep
src = PortAudioStream(1, 2)
buf = Array{Float32}(N) # buffer for reading
fftplan = plan_rfft(buf; flags = FFTW.EXHAUSTIVE)
fftbuf = Array{Complex{Float32}}(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)
function waterfall_heatmap(seconds;
N = 1024, # size of audio read
D = 200, # number of bins to display
M = 200, # amount of history to keep
)
N2 = N ÷ 2 + 1 # size of rfft output
PortAudioStream(1, 2) do src
buf = Array{Float32}(undef, N) # buffer for reading
fftplan = plan_rfft(buf; flags = FFTW.EXHAUSTIVE)
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
for _ in 1:M
processblock!(src, buf, win, dispbufs, fftbuf, fftplan)
end
#pre-fill the display buffer so we can do a reasonable colormap
for _ in 1:M
processblock!(src, buf, win, dispbufs, fftbuf, fftplan; D = D)
end
heatmaps = map(enumerate(IndexCartesian(), dispbufs)) do ibuf
i = ibuf[1]
buf = ibuf[2]
heatmaps = map(zip(CartesianIndices(dispbufs), dispbufs)) do ibuf
i = ibuf[1]
buf = ibuf[2]
# some function of the 2D index and the value
heatmap(buf, offset = (i[2] * size(buf, 2), i[1] * size(buf, 1)))
end
# some function of the 2D index and the value
heatmap(buf, offset = (i[2] * size(buf, 2), i[1] * size(buf, 1)))
end
center!(scene)
center!(scene)
while isopen(scene[:screen])
processblock!(src, buf, dispbufs, fftbuf, fftplan)
for (hm, db) in zip(heatmaps, dispbufs)
hm[:heatmap] = db
done = false
@sync begin
@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
render_frame(scene)
end
waterfall_heatmap(5)

View file

@ -1,43 +1,57 @@
using Makie, GeometryTypes
using PortAudio
using FFTW
using CairoMakie
N = 1024 # size of audio read
N2 = N ÷ 2 + 1 # size of rfft output
D = 200 # number of bins to display
M = 100 # number of lines to draw
S = 0.5 # motion speed of lines
src = PortAudioStream(1, 2)
buf = Array{Float32}(N)
fftbuf = Array{Complex{Float32}}(N2)
magbuf = Array{Float32}(N2)
fftplan = plan_rfft(buf; flags = FFTW.EXHAUSTIVE)
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)
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
while isopen(scene[:screen])
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]))
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)