Jack2 1.9.8

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 
00025 using Jack::JackFFADOMidiInputPort;
00026 
00027 JackFFADOMidiInputPort::JackFFADOMidiInputPort(size_t max_bytes)
00028 {
00029     event = 0;
00030     receive_queue = new JackFFADOMidiReceiveQueue();
00031     std::auto_ptr<JackFFADOMidiReceiveQueue> receive_queue_ptr(receive_queue);
00032     write_queue = new JackMidiBufferWriteQueue();
00033     std::auto_ptr<JackMidiBufferWriteQueue> write_queue_ptr(write_queue);
00034     raw_queue = new JackMidiRawInputWriteQueue(write_queue, max_bytes,
00035                                                max_bytes);
00036     write_queue_ptr.release();
00037     receive_queue_ptr.release();
00038 }
00039 
00040 JackFFADOMidiInputPort::~JackFFADOMidiInputPort()
00041 {
00042     delete raw_queue;
00043     delete receive_queue;
00044     delete write_queue;
00045 }
00046 
00047 void
00048 JackFFADOMidiInputPort::Process(JackMidiBuffer *port_buffer,
00049                                 uint32_t *input_buffer, jack_nframes_t frames)
00050 {
00051     receive_queue->ResetInputBuffer(input_buffer, frames);
00052     write_queue->ResetMidiBuffer(port_buffer, frames);
00053     jack_nframes_t boundary_frame = GetLastFrame() + frames;
00054     if (! event) {
00055         event = receive_queue->DequeueEvent();
00056     }
00057     for (; event; event = receive_queue->DequeueEvent()) {
00058         switch (raw_queue->EnqueueEvent(event)) {
00059         case JackMidiWriteQueue::BUFFER_FULL:
00060 
00061             // Processing events early might free up some space in the raw
00062             // input queue.
00063 
00064             raw_queue->Process(boundary_frame);
00065             switch (raw_queue->EnqueueEvent(event)) {
00066             case JackMidiWriteQueue::BUFFER_TOO_SMALL:
00067                 // This shouldn't really happen.  It indicates a bug if it
00068                 // does.
00069                 jack_error("JackFFADOMidiInputPort::Process - **BUG** "
00070                            "JackMidiRawInputWriteQueue::EnqueueEvent returned "
00071                            "`BUFFER_FULL`, and then returned "
00072                            "`BUFFER_TOO_SMALL` after a `Process()` call.");
00073                 // Fallthrough on purpose
00074             case JackMidiWriteQueue::OK:
00075                 continue;
00076             default:
00077                 return;
00078             }
00079         case JackMidiWriteQueue::BUFFER_TOO_SMALL:
00080             jack_error("JackFFADOMidiInputPort::Process - The write queue "
00081                        "couldn't enqueue a %d-byte event.  Dropping event.",
00082                        event->size);
00083             // Fallthrough on purpose
00084         case JackMidiWriteQueue::OK:
00085             continue;
00086         default:
00087             // This is here to stop compliers from warning us about not
00088             // handling enumeration values.
00089             ;
00090         }
00091         break;
00092     }
00093     raw_queue->Process(boundary_frame);
00094 }