13
0

add i/o map support for Audio Unit

untested - not even compile-tested.
This commit is contained in:
Robin Gareus 2016-03-30 22:41:13 +02:00
parent 86b9f07d63
commit 806fe2cba6
2 changed files with 67 additions and 38 deletions

View File

@ -202,6 +202,7 @@ class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
framecnt_t input_offset; framecnt_t input_offset;
framecnt_t cb_offset; framecnt_t cb_offset;
BufferSet* input_buffers; BufferSet* input_buffers;
ChanMapping * input_map;
framecnt_t frames_processed; framecnt_t frames_processed;
uint32_t audio_input_cnt; uint32_t audio_input_cnt;

View File

@ -436,6 +436,7 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
, input_maxbuf (0) , input_maxbuf (0)
, input_offset (0) , input_offset (0)
, input_buffers (0) , input_buffers (0)
, input_map (0)
, frames_processed (0) , frames_processed (0)
, audio_input_cnt (0) , audio_input_cnt (0)
, _parameter_listener (0) , _parameter_listener (0)
@ -468,6 +469,7 @@ AUPlugin::AUPlugin (const AUPlugin& other)
, input_maxbuf (0) , input_maxbuf (0)
, input_offset (0) , input_offset (0)
, input_buffers (0) , input_buffers (0)
, input_map (0)
, frames_processed (0) , frames_processed (0)
, _parameter_listener (0) , _parameter_listener (0)
, _parameter_listener_arg (0) , _parameter_listener_arg (0)
@ -1455,16 +1457,20 @@ AUPlugin::render_callback(AudioUnitRenderActionFlags*,
} }
uint32_t limit = min ((uint32_t) ioData->mNumberBuffers, input_maxbuf); uint32_t limit = min ((uint32_t) ioData->mNumberBuffers, input_maxbuf);
ChanCount bufs_count (DataType::AUDIO, 1);
BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
for (uint32_t i = 0; i < limit; ++i) { for (uint32_t i = 0; i < limit; ++i) {
ioData->mBuffers[i].mNumberChannels = 1; ioData->mBuffers[i].mNumberChannels = 1;
ioData->mBuffers[i].mDataByteSize = sizeof (Sample) * inNumberFrames; ioData->mBuffers[i].mDataByteSize = sizeof (Sample) * inNumberFrames;
/* we don't use the channel mapping because audiounits are bool valid = false;
* never replicated. one plugin instance uses all channels/buffers uint32_t idx = in_map->get (DataType::AUDIO, i, &valid);
* passed to PluginInsert::connect_and_run() if (valid) {
*/ ioData->mBuffers[i].mData = input_buffers->get_audio (idx).data (cb_offset + input_offset);
} else {
ioData->mBuffers[i].mData = input_buffers->get_audio (i).data (cb_offset + input_offset); ioData->mBuffers[i].mData = silent_bufs.get_audio(0).data (cb_offset + input_offset);
}
} }
cb_offset += inNumberFrames; cb_offset += inNumberFrames;
@ -1497,11 +1503,16 @@ AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_
assert (bufs.available() >= ChanCount (DataType::AUDIO, output_channels)); assert (bufs.available() >= ChanCount (DataType::AUDIO, output_channels));
input_buffers = &bufs; input_buffers = &bufs;
input_map = &in_map;
input_maxbuf = bufs.count().n_audio(); // number of input audio buffers input_maxbuf = bufs.count().n_audio(); // number of input audio buffers
input_offset = offset; input_offset = offset;
cb_offset = 0; cb_offset = 0;
buffers->mNumberBuffers = output_channels; buffers->mNumberBuffers = output_channels;
bool inplace = in_map == out_map;
ChanCount bufs_count (DataType::AUDIO, 1);
BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
for (int32_t i = 0; i < output_channels; ++i) { for (int32_t i = 0; i < output_channels; ++i) {
buffers->mBuffers[i].mNumberChannels = 1; buffers->mBuffers[i].mNumberChannels = 1;
@ -1513,7 +1524,17 @@ AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_
* a non-null values tells the plugin to render into the buffer pointed * a non-null values tells the plugin to render into the buffer pointed
* at by the value. * at by the value.
*/ */
if (inplace) {
buffers->mBuffers[i].mData = 0; buffers->mBuffers[i].mData = 0;
} else {
bool valid = false;
uint32_t idx = out_map.get (DataType::AUDIO, i, &valid);
if (valid) {
buffers->mBuffers[i].mData = bufs.et_audio (idx).data (offset);
} else {
buffers->mBuffers[i].mData = scratch_bufs.get_audio(0).data(offset);
}
}
} }
if (_has_midi_input) { if (_has_midi_input) {
@ -1560,8 +1581,12 @@ AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_
int32_t limit = min ((int32_t) buffers->mNumberBuffers, output_channels); int32_t limit = min ((int32_t) buffers->mNumberBuffers, output_channels);
int32_t i; int32_t i;
for (i = 0; i < limit; ++i) { for (i = 0; i < limit && inplace; ++i) {
Sample* expected_buffer_address= bufs.get_audio (i).data (offset); // we know in_map == out_map
bool valid = false;
uint32_t idx = out_map.get (DataType::AUDIO, i, &valid);
if (!valid) continue;
Sample* expected_buffer_address = bufs.get_audio (idx).data (offset);
if (expected_buffer_address != buffers->mBuffers[i].mData) { if (expected_buffer_address != buffers->mBuffers[i].mData) {
/* plugin provided its own buffer for output so copy it back to where we want it /* plugin provided its own buffer for output so copy it back to where we want it
*/ */
@ -1574,7 +1599,10 @@ AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_
*/ */
for (;i < output_channels; ++i) { for (;i < output_channels; ++i) {
memset (bufs.get_audio (i).data (offset), 0, nframes * sizeof (Sample)); bool valid = false;
uint32_t idx = out_map.get (DataType::AUDIO, i, &valid);
if (!valid) continue;
memset (bufs.get_audio (idx).data (offset), 0, nframes * sizeof (Sample));
} }
return 0; return 0;