diff --git a/libs/ardour/ardour/surround_return.h b/libs/ardour/ardour/surround_return.h index 88c883082c..4c6ad722e3 100644 --- a/libs/ardour/ardour/surround_return.h +++ b/libs/ardour/ardour/surround_return.h @@ -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); diff --git a/libs/ardour/surround_return.cc b/libs/ardour/surround_return.cc index 0878958970..ed8ddfe271 100644 --- a/libs/ardour/surround_return.cc +++ b/libs/ardour/surround_return.cc @@ -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 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); diff --git a/share/scripts/_adm_bwf.lua b/share/scripts/_adm_bwf.lua index 899ebf5eec..4ecd09c403 100644 --- a/share/scripts/_adm_bwf.lua +++ b/share/scripts/_adm_bwf.lua @@ -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