More robust plugin I/O mapping.
This does not change the actual mapping logic, but makes the application of the mapping much more robust. If there is no valid mapping for a given port, that port is connected to silence (instead of crashing messily and/or via a failed assertion). Also tolerate mappings that nonsensically map to a buffer that is not present (this particularly happens for MIDI ports in some cases) as a temporary fix. The mapping logic needs work and/or our concept of just how much MIDI we support in a route needs simplification... git-svn-id: svn://localhost/ardour2/branches/3.0@10262 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
454f14d9c5
commit
96dcffcb22
@ -39,7 +39,7 @@ public:
|
||||
ChanMapping() {}
|
||||
ChanMapping(ARDOUR::ChanCount identity);
|
||||
|
||||
uint32_t get(DataType t, uint32_t from);
|
||||
uint32_t get(DataType t, uint32_t from, bool* valid);
|
||||
void set(DataType t, uint32_t from, uint32_t to);
|
||||
void offset_from(DataType t, int32_t delta);
|
||||
void offset_to(DataType t, int32_t delta);
|
||||
|
@ -41,12 +41,19 @@ ChanMapping::ChanMapping(ChanCount identity)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ChanMapping::get(DataType t, uint32_t from)
|
||||
ChanMapping::get(DataType t, uint32_t from, bool* valid)
|
||||
{
|
||||
Mappings::iterator tm = _mappings.find(t);
|
||||
assert(tm != _mappings.end());
|
||||
if (tm == _mappings.end()) {
|
||||
*valid = false;
|
||||
return -1;
|
||||
}
|
||||
TypeMapping::iterator m = tm->second.find(from);
|
||||
assert(m != tm->second.end());
|
||||
if (m == tm->second.end()) {
|
||||
*valid = false;
|
||||
return -1;
|
||||
}
|
||||
*valid = true;
|
||||
return m->second;
|
||||
}
|
||||
|
||||
|
@ -548,16 +548,24 @@ LadspaPlugin::connect_and_run (BufferSet& bufs,
|
||||
cycles_t now;
|
||||
cycles_t then = get_cycles ();
|
||||
|
||||
BufferSet& silent_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1));
|
||||
BufferSet& scratch_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1));
|
||||
|
||||
uint32_t audio_in_index = 0;
|
||||
uint32_t audio_out_index = 0;
|
||||
bool valid;
|
||||
for (uint32_t port_index = 0; port_index < parameter_count(); ++port_index) {
|
||||
if (LADSPA_IS_PORT_AUDIO(port_descriptor(port_index))) {
|
||||
if (LADSPA_IS_PORT_INPUT(port_descriptor(port_index))) {
|
||||
const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++);
|
||||
connect_port(port_index, bufs.get_audio(buf_index).data(offset));
|
||||
const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
|
||||
connect_port(port_index,
|
||||
valid ? bufs.get_audio(buf_index).data(offset)
|
||||
: silent_bufs.get_audio(0).data(offset));
|
||||
} else if (LADSPA_IS_PORT_OUTPUT(port_descriptor(port_index))) {
|
||||
const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++);
|
||||
connect_port(port_index, bufs.get_audio(buf_index).data(offset));
|
||||
const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++, &valid);
|
||||
connect_port(port_index,
|
||||
valid ? bufs.get_audio(buf_index).data(offset)
|
||||
: scratch_bufs.get_audio(0).data(offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -908,31 +908,54 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
|
||||
|
||||
cycles_t then = get_cycles();
|
||||
|
||||
ChanCount bufs_count;
|
||||
bufs_count.set(DataType::AUDIO, 1);
|
||||
bufs_count.set(DataType::MIDI, 1);
|
||||
BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
|
||||
BufferSet& scratch_bufs = _session.get_silent_buffers(bufs_count);
|
||||
|
||||
uint32_t audio_in_index = 0;
|
||||
uint32_t audio_out_index = 0;
|
||||
uint32_t midi_in_index = 0;
|
||||
uint32_t midi_out_index = 0;
|
||||
bool valid;
|
||||
for (uint32_t port_index = 0; port_index < parameter_count(); ++port_index) {
|
||||
if (parameter_is_audio(port_index)) {
|
||||
if (parameter_is_input(port_index)) {
|
||||
const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++);
|
||||
const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
bufs.get_audio(buf_index).data(offset));
|
||||
valid ? bufs.get_audio(buf_index).data(offset)
|
||||
: silent_bufs.get_audio(0).data(offset));
|
||||
} else if (parameter_is_output(port_index)) {
|
||||
const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++);
|
||||
const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++, &valid);
|
||||
//cerr << port_index << " : " << " AUDIO OUT " << buf_index << endl;
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
bufs.get_audio(buf_index).data(offset));
|
||||
valid ? bufs.get_audio(buf_index).data(offset)
|
||||
: scratch_bufs.get_audio(0).data(offset));
|
||||
}
|
||||
} else if (parameter_is_midi(port_index)) {
|
||||
/* FIXME: The checks here for bufs.count().n_midi() > buf_index shouldn't
|
||||
be necessary, but the mapping is illegal in some cases. Ideally
|
||||
that should be fixed, but this is easier...
|
||||
*/
|
||||
if (parameter_is_input(port_index)) {
|
||||
const uint32_t buf_index = in_map.get(DataType::MIDI, midi_in_index++);
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
bufs.get_lv2_midi(true, buf_index).data());
|
||||
const uint32_t buf_index = in_map.get(DataType::MIDI, midi_in_index++, &valid);
|
||||
if (valid && bufs.count().n_midi() > buf_index) {
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
bufs.get_lv2_midi(true, buf_index).data());
|
||||
} else {
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
silent_bufs.get_lv2_midi(true, 0).data());
|
||||
}
|
||||
} else if (parameter_is_output(port_index)) {
|
||||
const uint32_t buf_index = out_map.get(DataType::MIDI, midi_out_index++);
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
bufs.get_lv2_midi(false, buf_index).data());
|
||||
const uint32_t buf_index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
|
||||
if (valid && bufs.count().n_midi() > buf_index) {
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
bufs.get_lv2_midi(false, buf_index).data());
|
||||
} else {
|
||||
lilv_instance_connect_port(_impl->instance, port_index,
|
||||
scratch_bufs.get_lv2_midi(true, 0).data());
|
||||
}
|
||||
}
|
||||
} else if (!parameter_is_control(port_index)) {
|
||||
// Optional port (it'd better be if we've made it this far...)
|
||||
@ -945,8 +968,10 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
|
||||
midi_out_index = 0;
|
||||
for (uint32_t port_index = 0; port_index < parameter_count(); ++port_index) {
|
||||
if (parameter_is_midi(port_index) && parameter_is_output(port_index)) {
|
||||
const uint32_t buf_index = out_map.get(DataType::MIDI, midi_out_index++);
|
||||
bufs.flush_lv2_midi(true, buf_index);
|
||||
const uint32_t buf_index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
|
||||
if (valid) {
|
||||
bufs.flush_lv2_midi(true, buf_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,16 +322,16 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
|
||||
|
||||
ChanMapping in_map (in_streams);
|
||||
ChanMapping out_map (out_streams);
|
||||
|
||||
bool valid;
|
||||
if (_match.method == Split) {
|
||||
/* fix the input mapping so that we have maps for each of the plugin's inputs */
|
||||
in_map = ChanMapping (natural_input_streams ());
|
||||
|
||||
/* copy the first stream's buffer contents to the others */
|
||||
/* XXX: audio only */
|
||||
Sample const * mono = bufs.get_audio (in_map.get (DataType::AUDIO, 0)).data (offset);
|
||||
Sample const * mono = bufs.get_audio (in_map.get (DataType::AUDIO, 0, &valid)).data (offset);
|
||||
for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
|
||||
memcpy (bufs.get_audio (in_map.get (DataType::AUDIO, i)).data (offset), mono, sizeof (Sample) * nframes);
|
||||
memcpy (bufs.get_audio (in_map.get (DataType::AUDIO, i, &valid)).data (offset), mono, sizeof (Sample) * nframes);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user