140 lines
5.0 KiB
C++
140 lines
5.0 KiB
C++
/*
|
|
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 __JackMidiRawOutputWriteQueue__
|
|
#define __JackMidiRawOutputWriteQueue__
|
|
|
|
#include "JackMidiAsyncQueue.h"
|
|
#include "JackMidiSendQueue.h"
|
|
|
|
namespace Jack {
|
|
|
|
/**
|
|
* This queue enqueues valid MIDI events and modifies them for raw output
|
|
* to a write queue. It has a couple of advantages over straight MIDI
|
|
* event copying:
|
|
*
|
|
* -Running status: Status bytes can be omitted when the status byte of the
|
|
* current MIDI message is the same as the status byte of the last sent
|
|
* MIDI message.
|
|
*
|
|
* -Realtime messages: Realtime messages are given priority over
|
|
* non-realtime messages. Realtime bytes are interspersed with
|
|
* non-realtime bytes so that realtime messages can be sent as close as
|
|
* possible to the time they're scheduled for sending.
|
|
*
|
|
* Use this queue if the MIDI API you're interfacing with allows you to
|
|
* send raw MIDI bytes.
|
|
*/
|
|
|
|
class SERVER_EXPORT JackMidiRawOutputWriteQueue:
|
|
public JackMidiWriteQueue {
|
|
|
|
private:
|
|
|
|
jack_midi_event_t *non_rt_event;
|
|
jack_nframes_t non_rt_event_time;
|
|
JackMidiAsyncQueue *non_rt_queue;
|
|
jack_midi_event_t *rt_event;
|
|
jack_nframes_t rt_event_time;
|
|
JackMidiAsyncQueue *rt_queue;
|
|
jack_midi_data_t running_status;
|
|
JackMidiSendQueue *send_queue;
|
|
|
|
void
|
|
DequeueNonRealtimeEvent();
|
|
|
|
void
|
|
DequeueRealtimeEvent();
|
|
|
|
bool
|
|
SendByte(jack_nframes_t time, jack_midi_data_t byte);
|
|
|
|
bool
|
|
SendNonRTBytes(jack_nframes_t boundary_frame);
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Override this method to specify what happens when the write queue
|
|
* says that a 1-byte event is too large for its buffer. Basically,
|
|
* this should never happen.
|
|
*/
|
|
|
|
virtual void
|
|
HandleWriteQueueBug(jack_nframes_t time, jack_midi_data_t byte);
|
|
|
|
public:
|
|
|
|
using JackMidiWriteQueue::EnqueueEvent;
|
|
|
|
/**
|
|
* Called to create a new raw write queue. The `send_queue` argument
|
|
* is the queue to write raw bytes to. The optional `max_rt_messages`
|
|
* argument specifies the number of messages that can be enqueued in
|
|
* the internal realtime queue. The optional `max_non_rt_messages`
|
|
* argument specifies the number of messages that can be enqueued in
|
|
* the internal non-realtime queue. The optional `non_rt_size`
|
|
* argument specifies the total number of MIDI bytes that can be put in
|
|
* the non-realtime queue.
|
|
*/
|
|
|
|
JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue,
|
|
size_t non_rt_size=4096,
|
|
size_t max_non_rt_messages=1024,
|
|
size_t max_rt_messages=128);
|
|
|
|
~JackMidiRawOutputWriteQueue();
|
|
|
|
EnqueueResult
|
|
EnqueueEvent(jack_nframes_t time, size_t size,
|
|
jack_midi_data_t *buffer);
|
|
|
|
/**
|
|
* The `Process()` method should be called each time the
|
|
* `EnqueueEvent()` method returns 'OK'. The `Process()` method will
|
|
* return the next frame at which an event should be sent. The return
|
|
* value from `Process()` depends upon the result of writing bytes to
|
|
* the write queue:
|
|
*
|
|
* -If the return value is '0', then all events that have been enqueued
|
|
* in this queue have been sent successfully to the write queue. Don't
|
|
* call `Process()` again until another event has been enqueued.
|
|
*
|
|
* -If the return value is an earlier frame or the current frame, it
|
|
* means that the write queue returned 'BUFFER_FULL', 'ERROR', or
|
|
* 'EVENT_EARLY' when this queue attempted to send the next byte, and
|
|
* that the byte should have already been sent, or is scheduled to be
|
|
* sent *now*. `Process()` should be called again when the write queue
|
|
* can enqueue events again successfully. How to determine when this
|
|
* will happen is left up to the caller.
|
|
*
|
|
* -If the return value is in the future, then `Process()` should be
|
|
* called again at that time, or after another event is enqueued.
|
|
*/
|
|
|
|
jack_nframes_t
|
|
Process(jack_nframes_t boundary_frame=0);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|