Merge branch 'julia1' of https://github.com/JuliaAudio/PortAudio.jl into julia1
This commit is contained in:
commit
0425fbfe3b
2 changed files with 105 additions and 0 deletions
67
examples/waterfall_heatmap.jl
Normal file
67
examples/waterfall_heatmap.jl
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
using Makie
|
||||||
|
using PortAudio
|
||||||
|
using DSP
|
||||||
|
|
||||||
|
"""
|
||||||
|
Slide the values in the given matrix to the right by 1.
|
||||||
|
The rightmosts column is discarded and the leftmost column is
|
||||||
|
left alone.
|
||||||
|
"""
|
||||||
|
function shift1!(buf::AbstractMatrix)
|
||||||
|
for col in size(buf,2):-1:2
|
||||||
|
@. buf[:, col] = buf[:, col-1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
takes a block of audio, FFT it, and write it to the beginning of the buffer
|
||||||
|
"""
|
||||||
|
function processbuf!(readbuf, win, dispbuf, fftbuf, fftplan)
|
||||||
|
readbuf .*= win
|
||||||
|
A_mul_B!(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)
|
||||||
|
read!(src, buf)
|
||||||
|
for dispbuf in dispbufs
|
||||||
|
processbuf!(buf, win, dispbuf, fftbuf, fftplan)
|
||||||
|
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, blocksize=N)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
heatmaps = map(enumerate(IndexCartesian(), 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
|
||||||
|
|
||||||
|
center!(scene)
|
||||||
|
|
||||||
|
while isopen(scene[:screen])
|
||||||
|
processblock!(src, buf, dispbufs, fftbuf, fftplan)
|
||||||
|
for (hm, db) in zip(heatmaps, dispbufs)
|
||||||
|
hm[:heatmap] = db
|
||||||
|
end
|
||||||
|
render_frame(scene)
|
||||||
|
end
|
38
examples/waterfall_lines.jl
Normal file
38
examples/waterfall_lines.jl
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using Makie, GeometryTypes
|
||||||
|
using PortAudio
|
||||||
|
|
||||||
|
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, blocksize=N)
|
||||||
|
buf = Array{Float32}(N)
|
||||||
|
fftbuf = Array{Complex{Float32}}(N2)
|
||||||
|
magbuf = Array{Float32}(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
|
||||||
|
|
||||||
|
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]))
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue