From c40ddfc0eebbcb3333d6cc9e3df7fb62ecb45941 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 30 Sep 2007 17:36:38 +0000 Subject: Better driver interface for input/output. MIDI output (pass-through anyway, plugin->output is still screwy). Fix crash on failure to instantiate LV2 plugin. git-svn-id: http://svn.drobilla.net/lad/ingen@786 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/JackMidiDriver.cpp | 68 +++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 9 deletions(-) (limited to 'src/libs/engine/JackMidiDriver.cpp') diff --git a/src/libs/engine/JackMidiDriver.cpp b/src/libs/engine/JackMidiDriver.cpp index 9abe83f6..f49794d7 100644 --- a/src/libs/engine/JackMidiDriver.cpp +++ b/src/libs/engine/JackMidiDriver.cpp @@ -52,7 +52,6 @@ JackMidiPort::JackMidiPort(JackMidiDriver* driver, DuplexPort* patch_port) 0); patch_port->buffer(0)->clear(); - patch_port->fixed_buffers(true); } @@ -62,22 +61,25 @@ JackMidiPort::~JackMidiPort() } -/** Prepare events for a block. +/** Prepare input for a block before a cycle is run, in the audio thread. * - * This is basically simple since Jack MIDI data is in-band with the audio thread. + * This is simple since Jack MIDI is in-band with audio. */ void -JackMidiPort::prepare_block(const SampleCount block_start, const SampleCount block_end) +JackMidiPort::pre_process(SampleCount block_start, SampleCount block_end) { - const SampleCount nframes = block_end - block_start; - void* jack_buffer = jack_port_get_buffer(_jack_port, nframes); - const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer); + if ( ! is_input() ) + return; assert(_patch_port->poly() == 1); MidiBuffer* patch_buf = dynamic_cast(_patch_port->buffer(0)); assert(patch_buf); + const SampleCount nframes = block_end - block_start; + void* jack_buffer = jack_port_get_buffer(_jack_port, nframes); + const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer); + patch_buf->prepare_write(nframes); // Copy events from Jack port buffer into patch port buffer @@ -95,6 +97,44 @@ JackMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo } +/** Prepare output for a block after a cycle is run, in the audio thread. + * + * This is simple since Jack MIDI is in-band with audio. + */ +void +JackMidiPort::post_process(SampleCount block_start, SampleCount block_end) +{ + if (is_input()) + return; + + assert(_patch_port->poly() == 1); + + MidiBuffer* patch_buf = dynamic_cast(_patch_port->buffer(0)); + assert(patch_buf); + + const SampleCount nframes = block_end - block_start; + void* jack_buffer = jack_port_get_buffer(_jack_port, nframes); + const jack_nframes_t event_count = patch_buf->event_count(); + + patch_buf->prepare_read(nframes); + + jack_midi_clear_buffer(jack_buffer); + + double time = 0; + uint32_t size = 0; + unsigned char* data = NULL; + + // Copy events from Jack port buffer into patch port buffer + for (jack_nframes_t i=0; i < event_count; ++i) { + patch_buf->get_event(&time, &size, &data); + jack_midi_event_write(jack_buffer, time, data, size); + } + + //if (event_count) + // cerr << "Jack MIDI wrote " << event_count << " events." << endl; +} + + //// JackMidiDriver //// @@ -137,10 +177,20 @@ JackMidiDriver::deactivate() /** Build flat arrays of events to be used as input for the given cycle. */ void -JackMidiDriver::prepare_block(const SampleCount block_start, const SampleCount block_end) +JackMidiDriver::pre_process(ProcessContext& context, SampleCount nframes, FrameTime start, FrameTime end) { for (Raul::List::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - (*i)->prepare_block(block_start, block_end); + (*i)->pre_process(start, end); +} + + +/** Write the output from any (top-level, exported) MIDI output ports to Jack ports. + */ +void +JackMidiDriver::post_process(ProcessContext& context, SampleCount nframes, FrameTime start, FrameTime end) +{ + for (Raul::List::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) + (*i)->post_process(start, end); } -- cgit v1.2.1