3 #include "JackALSARawMidiOutputPort.h"
5 using Jack::JackALSARawMidiOutputPort
;
7 JackALSARawMidiOutputPort::JackALSARawMidiOutputPort(snd_rawmidi_info_t
*info
,
11 JackALSARawMidiPort(info
, index
)
15 read_queue
= new JackMidiBufferReadQueue();
16 std::auto_ptr
<JackMidiBufferReadQueue
> read_ptr(read_queue
);
17 send_queue
= new JackALSARawMidiSendQueue(rawmidi
);
18 std::auto_ptr
<JackALSARawMidiSendQueue
> send_ptr(send_queue
);
19 thread_queue
= new JackMidiAsyncQueue(max_bytes
, max_messages
);
20 std::auto_ptr
<JackMidiAsyncQueue
> thread_ptr(thread_queue
);
21 raw_queue
= new JackMidiRawOutputWriteQueue(send_queue
, max_bytes
,
22 max_messages
, max_messages
);
28 JackALSARawMidiOutputPort::~JackALSARawMidiOutputPort()
37 JackALSARawMidiOutputPort::DequeueALSAEvent(int read_fd
)
39 jack_midi_event_t
*event
= thread_queue
->DequeueEvent();
42 ssize_t result
= read(read_fd
, &c
, 1);
44 jack_error("JackALSARawMidiOutputPort::DequeueALSAEvent - **BUG** "
45 "An event was dequeued from the thread queue, but no "
46 "byte was available for reading from the pipe file "
48 } else if (result
< 0) {
49 jack_error("JackALSARawMidiOutputPort::DequeueALSAEvent - error "
50 "reading a byte from the pipe file descriptor: %s",
58 JackALSARawMidiOutputPort::ProcessALSA(int read_fd
, jack_nframes_t
*frame
)
60 unsigned short revents
;
61 if (! ProcessPollEvents(&revents
)) {
65 if (! (revents
& POLLOUT
)) {
72 alsa_event
= DequeueALSAEvent(read_fd
);
74 for (; alsa_event
; alsa_event
= DequeueALSAEvent(read_fd
)) {
75 switch (raw_queue
->EnqueueEvent(alsa_event
)) {
76 case JackMidiWriteQueue::BUFFER_FULL
:
77 // Try to free up some space by processing events early.
79 switch (raw_queue
->EnqueueEvent(alsa_event
)) {
80 case JackMidiWriteQueue::BUFFER_TOO_SMALL
:
81 jack_error("JackALSARawMidiOutputPort::ProcessALSA - **BUG** "
82 "JackMidiRawOutputWriteQueue::EnqueueEvent "
83 "returned `BUFFER_FULL`, and then returned "
84 "`BUFFER_TOO_SMALL` after a Process() call.");
85 // Fallthrough on purpose
86 case JackMidiWriteQueue::OK
:
92 case JackMidiWriteQueue::BUFFER_TOO_SMALL
:
93 jack_error("JackALSARawMidiOutputPort::ProcessALSA - The raw "
94 "output queue couldn't enqueue a %d-byte event. "
95 "Dropping event.", alsa_event
->size
);
96 // Fallthrough on purpose
97 case JackMidiWriteQueue::OK
:
105 *frame
= raw_queue
->Process();
106 blocked
= send_queue
->IsBlocked();
109 jack_info("JackALSARawMidiOutputPort::ProcessALSA - MIDI port is "
112 SetPollEventMask(POLLERR
| POLLNVAL
| POLLOUT
);
115 SetPollEventMask(POLLERR
| POLLNVAL
);
121 JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer
*port_buffer
,
122 jack_nframes_t frames
, int write_fd
)
124 read_queue
->ResetMidiBuffer(port_buffer
);
125 for (jack_midi_event_t
*event
= read_queue
->DequeueEvent(); event
;
126 event
= read_queue
->DequeueEvent()) {
127 if (event
->size
> thread_queue
->GetAvailableSpace()) {
128 jack_error("JackALSARawMidiOutputPort::ProcessJack - The thread "
129 "queue doesn't have enough room to enqueue a %d-byte "
130 "event. Dropping event.", event
->size
);
134 ssize_t result
= write(write_fd
, &c
, 1);
137 jack_error("JackALSARawMidiOutputPort::ProcessJack - error "
138 "writing a byte to the pipe file descriptor: %s",
144 jack_error("JackALSARawMidiOutputPort::ProcessJack - Couldn't "
145 "write a byte to the pipe file descriptor. Dropping "
148 assert(thread_queue
->EnqueueEvent(event
, frames
) ==
149 JackMidiWriteQueue::OK
);