From 978de93cf2cb7d872cd48b1c213fbd81d4f9ecdd Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 20 Jan 2020 06:37:30 +0100 Subject: [PATCH] Add/update scripts reading raw audio-data --- scripts/_find_nonzero_sample.lua | 75 ++++++++++++++++++++++++++++++++ scripts/s_region_gain.lua | 9 ++-- 2 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 scripts/_find_nonzero_sample.lua diff --git a/scripts/_find_nonzero_sample.lua b/scripts/_find_nonzero_sample.lua new file mode 100644 index 0000000000..b3c146dd48 --- /dev/null +++ b/scripts/_find_nonzero_sample.lua @@ -0,0 +1,75 @@ +ardour { + ["type"] = "EditorAction", + name = "Find non zero audio sample", + author = "Ardour Team", + description = [[Find the position of first non-zero audio sample in selected regions.]] +} + +function factory () return function () + -- get Editor GUI Selection + -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:Selection + local sel = Editor:get_selection () + + -- allocate a buffer (float* in C) + -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:DSP:DspShm + local cmem = ARDOUR.DSP.DspShm (8192) + local msg = "" + + -- iterate over selected regions + -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:RegionSelection + for r in sel.regions:regionlist ():iter () do + -- test if it's an audio region + if r:to_audioregion ():isnil () then + goto next + end + + -- to read the Region data, we use the Readable interface of the Region + -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Readable + local rd = r:to_readable () + + local n_samples = rd:readable_length () + local n_channels = rd:n_channels () + + local nonzeropos = -1 + + -- iterate over all channels in Audio Region + for c = 0, n_channels -1 do + local pos = 0 + repeat + -- read at most 8K samples of channel 'c' starting at 'pos' + local s = rd:read (cmem:to_float (0), pos, 8192, c) + -- access the raw audio data + -- http://manual.ardour.org/lua-scripting/class_reference/#C:FloatArray + local d = cmem:to_float (0):array() + -- iterate over the audio sample data + for i = 0, s do + if math.abs (d[i]) > 0 then + print ("nonzero at", pos + i) + if (nonzeropos < 0 or pos + i < nonzeropos) then + nonzeropos = pos + i + end + break + end + end + pos = pos + s + if (nonzeropos >= 0 and pos > nonzeropos) then + break + end + until s < 8192 + end + + if (nonzeropos >= 0) then + msg = msg .. string.format("%s: %d\n", r:name (), nonzeropos + r:position()) + else + msg = msg .. "Region: '%s' is silent\n" + end + + ::next:: + end + + if (msg ~= "") then + local md = LuaDialog.Message ("First Non Zero Sample", msg, LuaDialog.MessageType.Info, LuaDialog.ButtonType.Close) + print (md:run()) + end + +end end diff --git a/scripts/s_region_gain.lua b/scripts/s_region_gain.lua index dec9899828..648e76629c 100644 --- a/scripts/s_region_gain.lua +++ b/scripts/s_region_gain.lua @@ -31,10 +31,10 @@ function factory () return function () local peak = 0 -- the audio peak to be calculated -- iterate over all channels in Audio Region - for c = 0, n_channels do + for c = 0, n_channels -1 do + local pos = 0 repeat - local pos = 0 - -- read at most 8K samples of channel 'c' + -- read at most 8K samples of channel 'c' starting at 'pos' local s = rd:read (cmem:to_float (0), pos, 8192, c) pos = pos + s -- access the raw audio data @@ -46,7 +46,8 @@ function factory () return function () peak = math.abs (d[i]) end end - until pos < n_samples + until s < 8192 + assert (pos == n_samples) end if (peak > 0) then