Jack2 1.9.10

JackFFADOMidiInputPort.cpp

00001 /*
00002 Copyright (C) 2010 Devin Anderson
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU Lesser General Public License as published by
00006 the Free Software Foundation; either version 2.1 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 
00018 */
00019 
00020 #include <memory>
00021 
00022 #include "JackFFADOMidiInputPort.h"
00023 #include "JackMidiUtil.h"
00024 #include "JackError.h"
00025 
00026 using Jack::JackFFADOMidiInputPort;
00027 
00028 JackFFADOMidiInputPort::JackFFADOMidiInputPort(size_t max_bytes)
00029 {
00030     event = 0;
00031     receive_queue = new JackFFADOMidiReceiveQueue();
00032     std::auto_ptr<JackFFADOMidiReceiveQueue> receive_queue_ptr(receive_queue);
00033     write_queue = new JackMidiBufferWriteQueue();
00034     std::auto_ptr<JackMidiBufferWriteQueue> write_queue_ptr(write_queue);
00035     raw_queue = new JackMidiRawInputWriteQueue(write_queue, max_bytes,
00036                                                max_bytes);
00037     write_queue_ptr.release();
00038     receive_queue_ptr.release();
00039 }
00040 
00041 JackFFADOMidiInputPort::~JackFFADOMidiInputPort()
00042 {
00043     delete raw_queue;
00044     delete receive_queue;
00045     delete write_queue;
00046 }
00047 
00048 void
00049 JackFFADOMidiInputPort::Process(JackMidiBuffer *port_buffer,
00050                                 uint32_t *input_buffer, jack_nframes_t frames)
00051 {
00052     receive_queue->ResetInputBuffer(input_buffer, frames);
00053     write_queue->ResetMidiBuffer(port_buffer, frames);
00054     jack_nframes_t boundary_frame = GetLastFrame() + frames;
00055     if (! event) {
00056         event = receive_queue->DequeueEvent();
00057     }
00058     for (; event; event = receive_queue->DequeueEvent()) {
00059         switch (raw_queue->EnqueueEvent(event)) {
00060         case JackMidiWriteQueue::BUFFER_FULL:
00061 
00062             // Processing events early might free up some space in the raw
00063             // input queue.
00064 
00065             raw_queue->Process(boundary_frame);
00066             switch (raw_queue->EnqueueEvent(event)) {
00067             case JackMidiWriteQueue::BUFFER_TOO_SMALL:
00068                 // This shouldn't really happen.  It indicates a bug if it
00069                 // does.
00070                 jack_error("JackFFADOMidiInputPort::Process - **BUG** "
00071                            "JackMidiRawInputWriteQueue::EnqueueEvent returned "
00072                            "`BUFFER_FULL`, and then returned "
00073                            "`BUFFER_TOO_SMALL` after a `Process()` call.");
00074                 // Fallthrough on purpose
00075             case JackMidiWriteQueue::OK:
00076                 continue;
00077             default:
00078                 return;
00079             }
00080         case JackMidiWriteQueue::BUFFER_TOO_SMALL:
00081             jack_error("JackFFADOMidiInputPort::Process - The write queue "
00082                        "couldn't enqueue a %d-byte event.  Dropping event.",
00083                        event->size);
00084             // Fallthrough on purpose
00085         case JackMidiWriteQueue::OK:
00086             continue;
00087         default:
00088             // This is here to stop compliers from warning us about not
00089             // handling enumeration values.
00090             ;
00091         }
00092         break;
00093     }
00094     raw_queue->Process(boundary_frame);
00095 }