diff options
author | Devin Anderson <surfacepatterns (at) gmail (dot) com> | 2011-03-18 22:42:34 -0700 |
---|---|---|
committer | Devin Anderson <surfacepatterns (at) gmail (dot) com> | 2011-03-18 22:47:45 -0700 |
commit | 4bd1bef24c4b4bc0722fa92f7aa3ab07f49a0db8 (patch) | |
tree | 8e25142172c5c827a3cfa9a9c069e016472aa163 /linux/firewire | |
parent | e97dcccfa863288a22b6b42324aa385edd4f16d6 (diff) | |
download | jack2-4bd1bef24c4b4bc0722fa92f7aa3ab07f49a0db8.tar.gz |
Added MIDI queues, FFADO objects, etc. - see 'http://trac.jackaudio.org/ticket/187' for more details
Diffstat (limited to 'linux/firewire')
-rw-r--r-- | linux/firewire/JackFFADODriver.cpp | 38 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiInput.cpp | 59 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiInputPort.cpp | 94 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiInputPort.h | 51 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiOutput.cpp | 60 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiOutputPort.cpp | 98 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiOutputPort.h | 53 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiReceiveQueue.cpp | 55 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiReceiveQueue.h (renamed from linux/firewire/JackFFADOMidiInput.h) | 34 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiSendQueue.cpp | 64 | ||||
-rw-r--r-- | linux/firewire/JackFFADOMidiSendQueue.h (renamed from linux/firewire/JackFFADOMidiOutput.h) | 37 |
11 files changed, 460 insertions, 183 deletions
diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 0966b1da..e0a2e556 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -36,8 +36,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include <string.h> #include "JackFFADODriver.h" -#include "JackFFADOMidiInput.h" -#include "JackFFADOMidiOutput.h" +#include "JackFFADOMidiInputPort.h" +#include "JackFFADOMidiOutputPort.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" @@ -94,14 +94,9 @@ JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nfra /* process the midi data */ for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - JackFFADOMidiInput *midi_input = (JackFFADOMidiInput *) driver->capture_channels[chn].midi_input; + JackFFADOMidiInputPort *midi_input = (JackFFADOMidiInputPort *) driver->capture_channels[chn].midi_input; JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes); - if (! buffer) { - continue; - } - midi_input->SetInputBuffer(driver->capture_channels[chn].midi_buffer); - midi_input->SetPortBuffer(buffer); - midi_input->Process(nframes); + midi_input->Process(buffer, driver->capture_channels[chn].midi_buffer, nframes); } } @@ -138,16 +133,9 @@ JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nfr memset(midi_buffer, 0, nframes * sizeof(uint32_t)); buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer)); - /* if the returned buffer is invalid, continue */ - if (!buf) { - ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); - continue; - } - ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); - JackFFADOMidiOutput *midi_output = (JackFFADOMidiOutput *) driver->playback_channels[chn].midi_output; - midi_output->SetPortBuffer((JackMidiBuffer *) buf); - midi_output->SetOutputBuffer(midi_buffer); - midi_output->Process(nframes); + ffado_streaming_playback_stream_onoff(driver->dev, chn, buf ? 1 : 0); + JackFFADOMidiOutputPort *midi_output = (JackFFADOMidiOutputPort *) driver->playback_channels[chn].midi_output; + midi_output->Process((JackMidiBuffer *) buf, midi_buffer, nframes); } else { // always have a valid buffer ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); @@ -155,9 +143,7 @@ JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nfr } } } - ffado_streaming_transfer_playback_buffers(driver->dev); - printExit(); return 0; } @@ -476,7 +462,7 @@ int JackFFADODriver::Attach() printError(" cannot enable port %s", buf); } - driver->capture_channels[chn].midi_input = new JackFFADOMidiInput(); + driver->capture_channels[chn].midi_input = new JackFFADOMidiInputPort(); // setup the midi buffer driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); @@ -557,12 +543,12 @@ int JackFFADODriver::Attach() // This constructor optionally accepts arguments for the // non-realtime buffer size and the realtime buffer size. Ideally, // these would become command-line options for the FFADO driver. - driver->playback_channels[chn].midi_output = new JackFFADOMidiOutput(); + driver->playback_channels[chn].midi_output = new JackFFADOMidiOutputPort(); driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); - range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency; + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); fPlaybackPortList[chn] = port_index; jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index); @@ -600,7 +586,7 @@ int JackFFADODriver::Detach() if (driver->capture_channels[chn].midi_buffer) free(driver->capture_channels[chn].midi_buffer); if (driver->capture_channels[chn].midi_input) - delete ((JackFFADOMidiInput *) (driver->capture_channels[chn].midi_input)); + delete ((JackFFADOMidiInputPort *) (driver->capture_channels[chn].midi_input)); } free(driver->capture_channels); @@ -608,7 +594,7 @@ int JackFFADODriver::Detach() if (driver->playback_channels[chn].midi_buffer) free(driver->playback_channels[chn].midi_buffer); if (driver->playback_channels[chn].midi_output) - delete ((JackFFADOMidiOutput *) (driver->playback_channels[chn].midi_output)); + delete ((JackFFADOMidiOutputPort *) (driver->playback_channels[chn].midi_output)); } free(driver->playback_channels); diff --git a/linux/firewire/JackFFADOMidiInput.cpp b/linux/firewire/JackFFADOMidiInput.cpp deleted file mode 100644 index 38ed539b..00000000 --- a/linux/firewire/JackFFADOMidiInput.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include <cassert> - -#include "JackFFADOMidiInput.h" - -namespace Jack { - -JackFFADOMidiInput::JackFFADOMidiInput(size_t buffer_size): - JackPhysicalMidiInput(buffer_size) -{ - new_period = true; -} - -JackFFADOMidiInput::~JackFFADOMidiInput() -{ - // Empty -} - -jack_nframes_t -JackFFADOMidiInput::Receive(jack_midi_data_t *datum, - jack_nframes_t current_frame, - jack_nframes_t total_frames) -{ - assert(input_buffer); - if (! new_period) { - current_frame += 8; - } else { - new_period = false; - } - for (; current_frame < total_frames; current_frame += 8) { - uint32_t data = input_buffer[current_frame]; - if (data & 0xff000000) { - *datum = (jack_midi_data_t) (data & 0xff); - return current_frame; - } - } - new_period = true; - return total_frames; -} - -} diff --git a/linux/firewire/JackFFADOMidiInputPort.cpp b/linux/firewire/JackFFADOMidiInputPort.cpp new file mode 100644 index 00000000..3923bbe0 --- /dev/null +++ b/linux/firewire/JackFFADOMidiInputPort.cpp @@ -0,0 +1,94 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include <memory> + +#include "JackFFADOMidiInputPort.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiInputPort; + +JackFFADOMidiInputPort::JackFFADOMidiInputPort(size_t max_bytes) +{ + event = 0; + receive_queue = new JackFFADOMidiReceiveQueue(); + std::auto_ptr<JackFFADOMidiReceiveQueue> receive_queue_ptr(receive_queue); + write_queue = new JackMidiBufferWriteQueue(); + std::auto_ptr<JackMidiBufferWriteQueue> write_queue_ptr(write_queue); + raw_queue = new JackMidiRawInputWriteQueue(write_queue, max_bytes, + max_bytes); + write_queue_ptr.release(); + receive_queue_ptr.release(); +} + +JackFFADOMidiInputPort::~JackFFADOMidiInputPort() +{ + delete raw_queue; + delete receive_queue; + delete write_queue; +} + +void +JackFFADOMidiInputPort::Process(JackMidiBuffer *port_buffer, + uint32_t *input_buffer, jack_nframes_t frames) +{ + receive_queue->ResetInputBuffer(input_buffer, frames); + write_queue->ResetMidiBuffer(port_buffer, frames); + jack_nframes_t boundary_frame = GetLastFrame() + frames; + if (! event) { + event = receive_queue->DequeueEvent(); + } + for (; event; event = receive_queue->DequeueEvent()) { + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_FULL: + + // Processing events early might free up some space in the raw + // input queue. + + raw_queue->Process(boundary_frame); + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + // This shouldn't really happen. It indicates a bug if it + // does. + jack_error("JackFFADOMidiInputPort::Process - **BUG** " + "JackMidiRawInputWriteQueue::EnqueueEvent returned " + "`BUFFER_FULL`, and then returned " + "`BUFFER_TOO_SMALL` after a `Process()` call."); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + return; + } + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackFFADOMidiInputPort::Process - The write queue " + "couldn't enqueue a %d-byte event. Dropping event.", + event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + // This is here to stop compliers from warning us about not + // handling enumeration values. + ; + } + break; + } + raw_queue->Process(boundary_frame); +} diff --git a/linux/firewire/JackFFADOMidiInputPort.h b/linux/firewire/JackFFADOMidiInputPort.h new file mode 100644 index 00000000..f4c70a80 --- /dev/null +++ b/linux/firewire/JackFFADOMidiInputPort.h @@ -0,0 +1,51 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiInputPort__ +#define __JackFFADOMidiInputPort__ + +#include "JackFFADOMidiReceiveQueue.h" +#include "JackMidiBufferWriteQueue.h" +#include "JackMidiRawInputWriteQueue.h" + +namespace Jack { + + class JackFFADOMidiInputPort { + + private: + + jack_midi_event_t *event; + JackMidiRawInputWriteQueue *raw_queue; + JackFFADOMidiReceiveQueue *receive_queue; + JackMidiBufferWriteQueue *write_queue; + + public: + + JackFFADOMidiInputPort(size_t max_bytes=4096); + ~JackFFADOMidiInputPort(); + + void + Process(JackMidiBuffer *port_buffer, uint32_t *input_buffer, + jack_nframes_t frames); + + }; + +} + +#endif diff --git a/linux/firewire/JackFFADOMidiOutput.cpp b/linux/firewire/JackFFADOMidiOutput.cpp deleted file mode 100644 index 995f2d28..00000000 --- a/linux/firewire/JackFFADOMidiOutput.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2009 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include <cassert> - -#include "JackError.h" -#include "JackFFADOMidiOutput.h" - -namespace Jack { - -JackFFADOMidiOutput::JackFFADOMidiOutput(size_t non_rt_buffer_size, - size_t rt_buffer_size): - JackPhysicalMidiOutput(non_rt_buffer_size, rt_buffer_size) -{ - // Empty -} - -JackFFADOMidiOutput::~JackFFADOMidiOutput() -{ - // Empty -} - -jack_nframes_t -JackFFADOMidiOutput::Advance(jack_nframes_t current_frame) -{ - if (current_frame % 8) { - current_frame = (current_frame & (~ ((jack_nframes_t) 7))) + 8; - } - return current_frame; -} - -jack_nframes_t -JackFFADOMidiOutput::Send(jack_nframes_t current_frame, jack_midi_data_t datum) -{ - assert(output_buffer); - - jack_log("JackFFADOMidiOutput::Send (%d) - Sending '%x' byte.", - current_frame, (unsigned int) datum); - - output_buffer[current_frame] = 0x01000000 | ((uint32_t) datum); - return current_frame + 8; -} - -} diff --git a/linux/firewire/JackFFADOMidiOutputPort.cpp b/linux/firewire/JackFFADOMidiOutputPort.cpp new file mode 100644 index 00000000..3a7c21f5 --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutputPort.cpp @@ -0,0 +1,98 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include <memory> + +#include "JackFFADOMidiOutputPort.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiOutputPort; + +JackFFADOMidiOutputPort::JackFFADOMidiOutputPort(size_t non_rt_size, + size_t max_non_rt_messages, + size_t max_rt_messages) +{ + event = 0; + read_queue = new JackMidiBufferReadQueue(); + std::auto_ptr<JackMidiBufferReadQueue> read_queue_ptr(read_queue); + send_queue = new JackFFADOMidiSendQueue(); + std::auto_ptr<JackFFADOMidiSendQueue> send_queue_ptr(send_queue); + raw_queue = new JackMidiRawOutputWriteQueue(send_queue, max_rt_messages, + max_non_rt_messages, + non_rt_size); + send_queue_ptr.release(); + read_queue_ptr.release(); +} + +JackFFADOMidiOutputPort::~JackFFADOMidiOutputPort() +{ + delete raw_queue; + delete read_queue; + delete send_queue; +} + +void +JackFFADOMidiOutputPort::Process(JackMidiBuffer *port_buffer, + uint32_t *output_buffer, + jack_nframes_t frames) +{ + read_queue->ResetMidiBuffer(port_buffer); + send_queue->ResetOutputBuffer(output_buffer, frames); + jack_nframes_t boundary_frame = GetLastFrame() + frames; + if (! event) { + event = read_queue->DequeueEvent(); + } + for (; event; event = read_queue->DequeueEvent()) { + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_FULL: + + // Processing events early might free up some space in the raw + // output queue. + + raw_queue->Process(boundary_frame); + switch (raw_queue->EnqueueEvent(event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + // This shouldn't really happen. It indicates a bug if it + // does. + jack_error("JackFFADOMidiOutputPort::Process - **BUG** " + "JackMidiRawOutputWriteQueue::EnqueueEvent " + "returned `BUFFER_FULL`, and then returned " + "`BUFFER_TOO_SMALL` after a `Process()` call."); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + return; + } + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackFFADOMidiOutputPort::Process - The write queue " + "couldn't enqueue a %d-byte event. Dropping event.", + event->size); + // Fallthrough on purpose + case JackMidiWriteQueue::OK: + continue; + default: + // This is here to stop compliers from warning us about not + // handling enumeration values. + ; + } + break; + } + raw_queue->Process(boundary_frame); +} diff --git a/linux/firewire/JackFFADOMidiOutputPort.h b/linux/firewire/JackFFADOMidiOutputPort.h new file mode 100644 index 00000000..4ca309bb --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutputPort.h @@ -0,0 +1,53 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiOutputPort__ +#define __JackFFADOMidiOutputPort__ + +#include "JackFFADOMidiSendQueue.h" +#include "JackMidiBufferReadQueue.h" +#include "JackMidiRawOutputWriteQueue.h" + +namespace Jack { + + class JackFFADOMidiOutputPort { + + private: + + jack_midi_event_t *event; + JackMidiRawOutputWriteQueue *raw_queue; + JackMidiBufferReadQueue *read_queue; + JackFFADOMidiSendQueue *send_queue; + + public: + + JackFFADOMidiOutputPort(size_t non_rt_size=4096, + size_t max_non_rt_messages=1024, + size_t max_rt_messages=128); + ~JackFFADOMidiOutputPort(); + + void + Process(JackMidiBuffer *port_buffer, uint32_t *output_buffer, + jack_nframes_t frames); + + }; + +} + +#endif diff --git a/linux/firewire/JackFFADOMidiReceiveQueue.cpp b/linux/firewire/JackFFADOMidiReceiveQueue.cpp new file mode 100644 index 00000000..4b67f329 --- /dev/null +++ b/linux/firewire/JackFFADOMidiReceiveQueue.cpp @@ -0,0 +1,55 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "JackFFADOMidiReceiveQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiReceiveQueue; + +JackFFADOMidiReceiveQueue::JackFFADOMidiReceiveQueue() +{ + // Empty +} + +jack_midi_event_t * +JackFFADOMidiReceiveQueue::DequeueEvent() +{ + for (; index < length; index += 8) { + uint32_t data = input_buffer[index]; + if (data & 0xff000000) { + byte = (jack_midi_data_t) (data & 0xff); + event.buffer = &byte; + event.size = 1; + event.time = last_frame + index; + index += 8; + return &event; + } + } + return 0; +} + +void +JackFFADOMidiReceiveQueue::ResetInputBuffer(uint32_t *input_buffer, + jack_nframes_t length) +{ + this->input_buffer = input_buffer; + index = 0; + last_frame = GetLastFrame(); + this->length = length; +} diff --git a/linux/firewire/JackFFADOMidiInput.h b/linux/firewire/JackFFADOMidiReceiveQueue.h index 12dc043c..7647869d 100644 --- a/linux/firewire/JackFFADOMidiInput.h +++ b/linux/firewire/JackFFADOMidiReceiveQueue.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2009 Devin Anderson +Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,35 +17,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __JackFFADOMidiInput__ -#define __JackFFADOMidiInput__ +#ifndef __JackFFADOMidiReceiveQueue__ +#define __JackFFADOMidiReceiveQueue__ -#include "JackPhysicalMidiInput.h" +#include "JackMidiReceiveQueue.h" namespace Jack { - class JackFFADOMidiInput: public JackPhysicalMidiInput { + class JackFFADOMidiReceiveQueue: public JackMidiReceiveQueue { private: + jack_midi_data_t byte; + jack_midi_event_t event; + jack_nframes_t index; uint32_t *input_buffer; - bool new_period; - - protected: - - jack_nframes_t - Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t); + jack_nframes_t last_frame; + jack_nframes_t length; public: - JackFFADOMidiInput(size_t buffer_size=1024); - ~JackFFADOMidiInput(); + JackFFADOMidiReceiveQueue(); + + jack_midi_event_t * + DequeueEvent(); - inline void - SetInputBuffer(uint32_t *input_buffer) - { - this->input_buffer = input_buffer; - } + void + ResetInputBuffer(uint32_t *input_buffer, jack_nframes_t length); }; diff --git a/linux/firewire/JackFFADOMidiSendQueue.cpp b/linux/firewire/JackFFADOMidiSendQueue.cpp new file mode 100644 index 00000000..97fdf17d --- /dev/null +++ b/linux/firewire/JackFFADOMidiSendQueue.cpp @@ -0,0 +1,64 @@ +/* +Copyright (C) 2010 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include <cassert> + +#include "JackFFADOMidiSendQueue.h" +#include "JackMidiUtil.h" + +using Jack::JackFFADOMidiSendQueue; + +JackFFADOMidiSendQueue::JackFFADOMidiSendQueue() +{ + // Empty +} + +Jack::JackMidiWriteQueue::EnqueueResult +JackFFADOMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer) +{ + assert(size == 1); + jack_nframes_t relative_time = (time < last_frame) ? 0 : time - last_frame; + if (index < relative_time) { + index = (relative_time % 8) ? + (relative_time & (~ ((jack_nframes_t) 7))) + 8 : relative_time; + } + if (index >= length) { + return BUFFER_FULL; + } + output_buffer[index] = 0x01000000 | ((uint32_t) *buffer); + index += 8; + return OK; +} + +jack_nframes_t +JackFFADOMidiSendQueue::GetNextScheduleFrame() +{ + return last_frame + index; +} + +void +JackFFADOMidiSendQueue::ResetOutputBuffer(uint32_t *output_buffer, + jack_nframes_t length) +{ + index = 0; + last_frame = GetLastFrame(); + this->length = length; + this->output_buffer = output_buffer; +} diff --git a/linux/firewire/JackFFADOMidiOutput.h b/linux/firewire/JackFFADOMidiSendQueue.h index 309e7f61..f395f13d 100644 --- a/linux/firewire/JackFFADOMidiOutput.h +++ b/linux/firewire/JackFFADOMidiSendQueue.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2009 Devin Anderson +Copyright (C) 2010 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,38 +17,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __JackFFADOMidiOutput__ -#define __JackFFADOMidiOutput__ +#ifndef __JackFFADOMidiSendQueue__ +#define __JackFFADOMidiSendQueue__ -#include "JackPhysicalMidiOutput.h" +#include "JackMidiSendQueue.h" namespace Jack { - class JackFFADOMidiOutput: public JackPhysicalMidiOutput { + class JackFFADOMidiSendQueue: public JackMidiSendQueue { private: + jack_nframes_t index; + jack_nframes_t last_frame; + jack_nframes_t length; uint32_t *output_buffer; - protected: - - jack_nframes_t - Advance(jack_nframes_t); + public: - jack_nframes_t - Send(jack_nframes_t, jack_midi_data_t); + JackFFADOMidiSendQueue(); - public: + EnqueueResult + EnqueueEvent(jack_nframes_t time, size_t size, + jack_midi_data_t *buffer); - JackFFADOMidiOutput(size_t non_rt_buffer_size=1024, - size_t rt_buffer_size=64); - ~JackFFADOMidiOutput(); + jack_nframes_t + GetNextScheduleFrame(); - inline void - SetOutputBuffer(uint32_t *output_buffer) - { - this->output_buffer = output_buffer; - } + void + ResetOutputBuffer(uint32_t *output_buffer, jack_nframes_t length); }; |