Vapor: parse and use additional meta-data from adm

This commit is contained in:
Robin Gareus 2024-02-25 03:22:26 +01:00
parent 4bd2de2f72
commit 305b2778b4
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 58 additions and 15 deletions

View File

@ -109,7 +109,7 @@ protected:
private:
static const size_t max_object_id = 128; // happens to be the same as a constant in a well known surround system
static const size_t num_pan_parameters = 5; // X, Y, Z, Size, Snap
static const size_t num_pan_parameters = 8; // X, Y, Z, Size, Snap [ElevEn, Ramp, Zones]
void forge_int_msg (uint32_t obj_id, uint32_t key, int val, uint32_t key2 = 0, int val2 = 0);
void maybe_send_metadata (size_t id, pframes_t frame, pan_t const v[num_pan_parameters], bool force = false);

View File

@ -418,7 +418,10 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
(pan_t)p->pan_pos_y->get_value (),
(pan_t)p->pan_pos_z->get_value (),
(pan_t)p->pan_size->get_value (),
(pan_t)p->pan_snap->get_value ()
(pan_t)p->pan_snap->get_value (),
(pan_t)p->sur_elevation_enable->get_value (),
(pan_t)p->sur_ramp->get_value (),
(pan_t)p->sur_zones->get_value ()
};
maybe_send_metadata (id, 0, v);
} else {
@ -434,7 +437,7 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
bool found_event = false;
timepos_t start (start_sample + latency);
timepos_t end (end_sample + latency);
timepos_t next = start;
timepos_t next (start_sample + latency - 1);
while (true) {
Evoral::ControlEvent next_event (timepos_t (Temporal::AudioTime), 0.0f);
@ -442,7 +445,7 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
break;
}
samplecnt_t pos = std::min (timepos_t (start).distance (next_event.when).samples (), (samplecnt_t)nframes - 1);
evaluate (id, p, next_event.when, pos);
evaluate (id, p, next_event.when, pos, with_bed);
next = next_event.when;
}
/* inform live renderer */
@ -542,7 +545,10 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
(pan_t)p->pan_pos_y->get_value (),
(pan_t)p->pan_pos_z->get_value (),
(pan_t)p->pan_size->get_value (),
(pan_t)p->pan_snap->get_value ()
(pan_t)p->pan_snap->get_value (),
(pan_t)p->sur_elevation_enable->get_value (),
(pan_t)p->sur_ramp->get_value (),
(pan_t)p->sur_zones->get_value ()
};
maybe_send_metadata (id, 0, v, true);
} else {
@ -653,7 +659,7 @@ void
SurroundReturn::maybe_send_metadata (size_t id, pframes_t sample, pan_t const v[num_pan_parameters], bool force)
{
bool changed = false;
for (size_t i = 0; i < num_pan_parameters; ++i) {
for (size_t i = 0; i < (_with_bed ? num_pan_parameters : 5); ++i) {
if (_current_value[id][i] != v[i]) {
changed = true;
}
@ -683,6 +689,16 @@ SurroundReturn::maybe_send_metadata (size_t id, pframes_t sample, pan_t const v[
lv2_atom_forge_float (&_forge, v[3]);
lv2_atom_forge_key (&_forge, urids.surr_Snap);
lv2_atom_forge_bool (&_forge, v[4] > 0 ? true : false);
if (_with_bed) {
lv2_atom_forge_key (&_forge, urids.surr_ElevEn);
lv2_atom_forge_bool (&_forge, v[5] > 0 ? true : false);
lv2_atom_forge_key (&_forge, urids.surr_Ramp);
lv2_atom_forge_bool (&_forge, v[6] > 0 ? true : false);
lv2_atom_forge_key (&_forge, urids.surr_Zones);
lv2_atom_forge_int (&_forge, (int) v[7]);
}
lv2_atom_forge_pop (&_forge, &frame);
_surround_processor->write_from_ui (0, urids.atom_eventTransfer, lv2_atom_total_size (msg), (const uint8_t*)msg);
@ -698,7 +714,10 @@ SurroundReturn::evaluate (size_t id, std::shared_ptr<SurroundPannable> const& p,
(pan_t)p->pan_pos_y->list ()->rt_safe_eval (when, ok[1]),
(pan_t)p->pan_pos_z->list ()->rt_safe_eval (when, ok[2]),
(pan_t)p->pan_size->list ()->rt_safe_eval (when, ok[3]),
(pan_t)p->pan_snap->list ()->rt_safe_eval (when, ok[4])
(pan_t)p->pan_snap->list ()->rt_safe_eval (when, ok[4]),
force ? (pan_t)p->sur_elevation_enable->list ()->rt_safe_eval (when, ok[5]) : 1,
force ? (pan_t)p->sur_ramp->list ()->rt_safe_eval (when, ok[6]) : 0,
force ? (pan_t)p->sur_zones->list ()->rt_safe_eval (when, ok[7]) : 0
};
if (ok[0] && ok[1] && ok[2] && ok[3] && ok[4]) {
maybe_send_metadata (id, sample, v, force);

View File

@ -14,6 +14,20 @@ function factory () return function ()
return 0 -- "Undefined" ie "Mid"
end
function parse_zone (zone)
if zone == "No Back" then return 1 end
if zone == "No Sides" then return 2 end
if zone == "Center Back" then return 3 end
if zone == "Screen Only" then return 4 end
if zone == "Surround Only" then return 5 end
return 0
end
function parse_ramp (ramp)
if tonumber(ramp) == 0 then return 0 end
return 1
end
local rv = LuaDialog.Dialog ("Load ADM/BWF File",
{
{ type = "file", key = "file", title = "Choose ADM/BWF File", path = "" },
@ -57,13 +71,13 @@ function factory () return function ()
goto next
end
local rv, _, obj, tme, pan_x, pan_y, pan_z, pan_snap, pan_size, bin_mode = string.find (line,
"Metadata.* index: (%d+) offset: (%d+) .* pos: %(([%d%.]+),([%d%.]+),([%d%.]+)%) snap: (%d) .* size: %(([%d%.]+),.* binaural: '(%a+)'")
local rv, _, obj, tme, pan_ramp, pan_x, pan_y, pan_z, pan_snap, pan_eleven, pan_zone, pan_size, bin_mode = string.find (line,
"Metadata.* index: (%d+) offset: (%d+) .* ramp: (%d+) pos: %(([%d%.]+),([%d%.]+),([%d%.-]+)%) snap: (%d) elevation: (%d) zone: '([%a ]+)' size: %(([%d%.]+),.* binaural: '(%a+)'")
if not rv then goto next end
if not meta[obj] then
meta[obj] = {x = {}, y = {}, z = {}, sz = {}, sn = {}}
meta[obj] = {x = {}, y = {}, z = {}, sz = {}, sn = {}, el = {}, rp = {}, zn = {}}
end
tme = tonumber(tme)
meta[obj]['x'][tme] = tonumber(pan_x)
@ -71,6 +85,9 @@ function factory () return function ()
meta[obj]['z'][tme] = tonumber(pan_z)
meta[obj]['sz'][tme] = tonumber(pan_size)
meta[obj]['sn'][tme] = tonumber(pan_snap)
meta[obj]['el'][tme] = tonumber(pan_eleven)
meta[obj]['rp'][tme] = parse_ramp(pan_ramp)
meta[obj]['zn'][tme] = parse_zone(pan_zone)
meta[obj]['bin'] = bin_mode
::next::
@ -86,11 +103,18 @@ function factory () return function ()
assert(1 == s:n_pannables ())
local p = s:pannable (0)
ARDOUR.LuaAPI.set_automation_data (p.pan_pos_x, d['x'], 0.00001)
ARDOUR.LuaAPI.set_automation_data (p.pan_pos_y, d['y'], 0.00001)
ARDOUR.LuaAPI.set_automation_data (p.pan_pos_z, d['z'], 0.00001)
ARDOUR.LuaAPI.set_automation_data (p.pan_size, d['sz'], 0.00001)
ARDOUR.LuaAPI.set_automation_data (p.pan_snap, d['sn'], 0.00001)
local thin = 0.00001
ARDOUR.LuaAPI.set_automation_data (p.pan_pos_x, d['x'], thin)
ARDOUR.LuaAPI.set_automation_data (p.pan_pos_y, d['y'], thin)
ARDOUR.LuaAPI.set_automation_data (p.pan_pos_z, d['z'], thin)
ARDOUR.LuaAPI.set_automation_data (p.pan_size, d['sz'], thin)
ARDOUR.LuaAPI.set_automation_data (p.pan_snap, d['sn'], thin)
ARDOUR.LuaAPI.set_automation_data (p.sur_elevation_enable, d['el'], thin)
ARDOUR.LuaAPI.set_automation_data (p.sur_zones, d['zn'], thin)
ARDOUR.LuaAPI.set_automation_data (p.sur_ramp, d['rp'], thin)
p.binaural_render_mode:set_value (parse_bin_mode (d['bin']), PBD.GroupControlDisposition.NoGroup)
-- this changes all