makie fail
This commit is contained in:
parent
f708835e5a
commit
5056541968
3 changed files with 95 additions and 69 deletions
2
.github/workflows/Tests.yml
vendored
2
.github/workflows/Tests.yml
vendored
|
@ -18,8 +18,6 @@ jobs:
|
|||
matrix:
|
||||
version:
|
||||
- '1.3'
|
||||
- '1.4'
|
||||
- '1.5'
|
||||
- '1'
|
||||
- 'nightly'
|
||||
os:
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
Loading…
Add table
Reference in a new issue