summaryrefslogtreecommitdiff
path: root/scripts/spectrogram.lua
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-07-03 14:46:29 +0200
committerRobin Gareus <robin@gareus.org>2016-07-03 14:46:29 +0200
commit913609becc83f41072096b218025856677b1c3a3 (patch)
tree7a01ef286cdd1071699f94d2149a7d17833eecc5 /scripts/spectrogram.lua
parent9220e81e2032ca3c54dda304b6433bfa4a5043fb (diff)
add grid to inline-spectrum
Diffstat (limited to 'scripts/spectrogram.lua')
-rw-r--r--scripts/spectrogram.lua52
1 files changed, 45 insertions, 7 deletions
diff --git a/scripts/spectrogram.lua b/scripts/spectrogram.lua
index 94ae043914..f82d4fe4bb 100644
--- a/scripts/spectrogram.lua
+++ b/scripts/spectrogram.lua
@@ -145,6 +145,7 @@ local read_ptr = 0
local line = 0
local img = nil
local fft_size = 0
+local last_log = false
function render_inline (ctx, w, max_h)
local ctrl = CtrlPorts:array () -- get control port array (read/write)
@@ -188,6 +189,12 @@ function render_inline (ctx, w, max_h)
fft = ARDOUR.DSP.FFTSpectrum (fft_size, rate)
end
+ if last_log ~= logscale then
+ last_log = logscale
+ img = nil
+ line = 0
+ end
+
-- calc height
if hmode == 0 then
h = math.ceil (w * 10 / 16)
@@ -209,13 +216,19 @@ function render_inline (ctx, w, max_h)
if not img or img:get_width() ~= w or img:get_height () ~= h then
img = Cairo.ImageSurface (Cairo.Format.ARGB32, w, h)
end
+ local ictx = img:context ()
+
+ local bins = fft_size / 2 - 1 -- fft bin count
+ local bpx = bins / w -- bins per x-pixel (linear)
+ local fpb = rate / fft_size -- freq-step per bin
+ local f_e = rate / 2 / fpb -- log-scale exponent
+ local f_b = w / math.log (fft_size / 2) -- inverse log-scale base
+ local f_l = math.log (fft_size / rate) * f_b -- inverse logscale lower-bound
- -- read ring-buffer, analyze
+ -- available samples in ring-buffer
local write_ptr = shmem:atomic_get_int (0)
local avail = (write_ptr + buf_size - read_ptr) % buf_size
- local ictx = img:context ()
-
while (avail >= fft_size) do
-- process one line / buffer
if read_ptr + fft_size < buf_size then
@@ -232,12 +245,8 @@ function render_inline (ctx, w, max_h)
avail = (write_ptr + buf_size - read_ptr ) % buf_size
-- draw spectrum
- local bins = fft_size / 2 - 1
- local bpx = bins / w
- local fpb = rate / fft_size
assert (bpx >= 1)
- local f_e = rate / 2 / fpb
-- scroll
if line == 0 then line = h - 1; else line = line - 1; end
@@ -292,5 +301,34 @@ function render_inline (ctx, w, max_h)
ctx:fill ()
end
+
+ -- draw grid on top
+ function x_at_freq (f)
+ if logscale then
+ return f_l + f_b * math.log (f)
+ else
+ return 2 * w * f / rate;
+ end
+ end
+
+ function grid_freq (f)
+ -- draw vertical grid line
+ local x = .5 + math.floor (x_at_freq (f))
+ ctx:move_to (x, 0)
+ ctx:line_to (x, h)
+ ctx:stroke ()
+ end
+
+ -- draw grid on top
+ local dash3 = C.DoubleVector ()
+ dash3:add ({1, 3})
+ ctx:set_line_width (1.0)
+ ctx:set_dash (dash3, 2) -- dotted line
+ ctx:set_source_rgba (.5, .5, .5, .8)
+ grid_freq (100)
+ grid_freq (1000)
+ grid_freq (10000)
+ ctx:unset_dash ()
+
return {w, h}
end