From b2aaffadc51ad38939e52d5f792e3e9a098ff2d7 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 19 Nov 2016 21:58:03 +0100 Subject: Add a Lua script snippet processing region data from the editor --- scripts/s_region_gain.lua | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 scripts/s_region_gain.lua (limited to 'scripts') diff --git a/scripts/s_region_gain.lua b/scripts/s_region_gain.lua new file mode 100644 index 0000000000..dec9899828 --- /dev/null +++ b/scripts/s_region_gain.lua @@ -0,0 +1,81 @@ +ardour { ["type"] = "Snippet", name = "Set Region Gain" } + +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) + + -- prepare undo operation + Session:begin_reversible_command ("Lua Region Gain") + local add_undo = false -- keep track if something has changed + + -- 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 peak = 0 -- the audio peak to be calculated + + -- iterate over all channels in Audio Region + for c = 0, n_channels do + repeat + local pos = 0 + -- read at most 8K samples of channel 'c' + local s = rd:read (cmem:to_float (0), pos, 8192, c) + pos = pos + s + -- 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]) > peak then + peak = math.abs (d[i]) + end + end + until pos < n_samples + end + + if (peak > 0) then + print ("Region:", r:name (), "peak:", 20 * math.log (peak) / math.log(10), "dBFS") + else + print ("Region:", r:name (), " is silent") + end + + -- normalize region + if (peak > 0) then + -- prepare for undo + r:to_stateful ():clear_changes () + -- apply gain + r:to_audioregion (): set_scale_amplitude (1 / peak) + -- save changes (if any) to undo command + if not Session:add_stateful_diff_command (r:to_statefuldestructible ()):empty () then + add_undo = true + end + end + + ::next:: + end + + -- all done. now commit the combined undo operation + if add_undo then + -- the 'nil' command here means to use all collected diffs + Session:commit_reversible_command (nil) + else + Session:abort_reversible_command () + end + +end end -- cgit v1.2.3