summaryrefslogtreecommitdiff
path: root/linux/firewire
diff options
context:
space:
mode:
authorDevin Anderson <surfacepatterns (at) gmail (dot) com>2011-03-18 22:42:34 -0700
committerDevin Anderson <surfacepatterns (at) gmail (dot) com>2011-03-18 22:47:45 -0700
commit4bd1bef24c4b4bc0722fa92f7aa3ab07f49a0db8 (patch)
tree8e25142172c5c827a3cfa9a9c069e016472aa163 /linux/firewire
parente97dcccfa863288a22b6b42324aa385edd4f16d6 (diff)
downloadjack2-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.cpp38
-rw-r--r--linux/firewire/JackFFADOMidiInput.cpp59
-rw-r--r--linux/firewire/JackFFADOMidiInputPort.cpp94
-rw-r--r--linux/firewire/JackFFADOMidiInputPort.h51
-rw-r--r--linux/firewire/JackFFADOMidiOutput.cpp60
-rw-r--r--linux/firewire/JackFFADOMidiOutputPort.cpp98
-rw-r--r--linux/firewire/JackFFADOMidiOutputPort.h53
-rw-r--r--linux/firewire/JackFFADOMidiReceiveQueue.cpp55
-rw-r--r--linux/firewire/JackFFADOMidiReceiveQueue.h (renamed from linux/firewire/JackFFADOMidiInput.h)34
-rw-r--r--linux/firewire/JackFFADOMidiSendQueue.cpp64
-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);
};