1 /* 2 Copyright (C) 2010 Devin Anderson 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as published by 6 the Free Software Foundation; either version 2.1 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 */ 19 20 #ifndef __JackMidiRawOutputWriteQueue__ 21 #define __JackMidiRawOutputWriteQueue__ 22 23 #include "JackMidiAsyncQueue.h" 24 #include "JackMidiSendQueue.h" 25 26 namespace Jack { 27 28 /** 29 * This queue enqueues valid MIDI events and modifies them for raw output 30 * to a write queue. It has a couple of advantages over straight MIDI 31 * event copying: 32 * 33 * -Running status: Status bytes can be omitted when the status byte of the 34 * current MIDI message is the same as the status byte of the last sent 35 * MIDI message. 36 * 37 * -Realtime messages: Realtime messages are given priority over 38 * non-realtime messages. Realtime bytes are interspersed with 39 * non-realtime bytes so that realtime messages can be sent as close as 40 * possible to the time they're scheduled for sending. 41 * 42 * Use this queue if the MIDI API you're interfacing with allows you to 43 * send raw MIDI bytes. 44 */ 45 46 class SERVER_EXPORT JackMidiRawOutputWriteQueue: 47 public JackMidiWriteQueue { 48 49 private: 50 51 jack_midi_event_t *non_rt_event; 52 jack_nframes_t non_rt_event_time; 53 JackMidiAsyncQueue *non_rt_queue; 54 jack_midi_event_t *rt_event; 55 jack_nframes_t rt_event_time; 56 JackMidiAsyncQueue *rt_queue; 57 jack_midi_data_t running_status; 58 JackMidiSendQueue *send_queue; 59 60 void 61 DequeueNonRealtimeEvent(); 62 63 void 64 DequeueRealtimeEvent(); 65 66 bool 67 SendByte(jack_nframes_t time, jack_midi_data_t byte); 68 69 bool 70 SendNonRTBytes(jack_nframes_t boundary_frame); 71 72 protected: 73 74 /** 75 * Override this method to specify what happens when the write queue 76 * says that a 1-byte event is too large for its buffer. Basically, 77 * this should never happen. 78 */ 79 80 virtual void 81 HandleWriteQueueBug(jack_nframes_t time, jack_midi_data_t byte); 82 83 public: 84 85 using JackMidiWriteQueue::EnqueueEvent; 86 87 /** 88 * Called to create a new raw write queue. The `send_queue` argument 89 * is the queue to write raw bytes to. The optional `max_rt_messages` 90 * argument specifies the number of messages that can be enqueued in 91 * the internal realtime queue. The optional `max_non_rt_messages` 92 * argument specifies the number of messages that can be enqueued in 93 * the internal non-realtime queue. The optional `non_rt_size` 94 * argument specifies the total number of MIDI bytes that can be put in 95 * the non-realtime queue. 96 */ 97 98 JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue, 99 size_t non_rt_size=4096, 100 size_t max_non_rt_messages=1024, 101 size_t max_rt_messages=128); 102 103 ~JackMidiRawOutputWriteQueue(); 104 105 EnqueueResult 106 EnqueueEvent(jack_nframes_t time, size_t size, 107 jack_midi_data_t *buffer); 108 109 /** 110 * The `Process()` method should be called each time the 111 * `EnqueueEvent()` method returns 'OK'. The `Process()` method will 112 * return the next frame at which an event should be sent. The return 113 * value from `Process()` depends upon the result of writing bytes to 114 * the write queue: 115 * 116 * -If the return value is '0', then all events that have been enqueued 117 * in this queue have been sent successfully to the write queue. Don't 118 * call `Process()` again until another event has been enqueued. 119 * 120 * -If the return value is an earlier frame or the current frame, it 121 * means that the write queue returned 'BUFFER_FULL', 'ERROR', or 122 * 'EVENT_EARLY' when this queue attempted to send the next byte, and 123 * that the byte should have already been sent, or is scheduled to be 124 * sent *now*. `Process()` should be called again when the write queue 125 * can enqueue events again successfully. How to determine when this 126 * will happen is left up to the caller. 127 * 128 * -If the return value is in the future, then `Process()` should be 129 * called again at that time, or after another event is enqueued. 130 */ 131 132 jack_nframes_t 133 Process(jack_nframes_t boundary_frame=0); 134 135 }; 136 137 } 138 139 #endif 140