Renaming for Windows compatibility.
[jack2.git] / linux / alsarawmidi / JackALSARawMidiOutputPort.cpp
blobc1a2bfb89e2a667e03f41ecf5b7704e30f2878be
1 #include <memory>
3 #include "JackALSARawMidiOutputPort.h"
5 using Jack::JackALSARawMidiOutputPort;
7 JackALSARawMidiOutputPort::JackALSARawMidiOutputPort(snd_rawmidi_info_t *info,
8 size_t index,
9 size_t max_bytes,
10 size_t max_messages):
11 JackALSARawMidiPort(info, index)
13 alsa_event = 0;
14 blocked = false;
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);
23 thread_ptr.release();
24 send_ptr.release();
25 read_ptr.release();
28 JackALSARawMidiOutputPort::~JackALSARawMidiOutputPort()
30 delete raw_queue;
31 delete read_queue;
32 delete send_queue;
33 delete thread_queue;
36 jack_midi_event_t *
37 JackALSARawMidiOutputPort::DequeueALSAEvent(int read_fd)
39 jack_midi_event_t *event = thread_queue->DequeueEvent();
40 if (event) {
41 char c;
42 ssize_t result = read(read_fd, &c, 1);
43 if (! result) {
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 "
47 "descriptor.");
48 } else if (result < 0) {
49 jack_error("JackALSARawMidiOutputPort::DequeueALSAEvent - error "
50 "reading a byte from the pipe file descriptor: %s",
51 strerror(errno));
54 return event;
57 bool
58 JackALSARawMidiOutputPort::ProcessALSA(int read_fd, jack_nframes_t *frame)
60 unsigned short revents;
61 if (! ProcessPollEvents(&revents)) {
62 return false;
64 if (blocked) {
65 if (! (revents & POLLOUT)) {
66 *frame = 0;
67 return true;
69 blocked = false;
71 if (! alsa_event) {
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.
78 raw_queue->Process();
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:
87 continue;
88 default:
91 goto process_events;
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:
98 continue;
99 default:
102 break;
104 process_events:
105 *frame = raw_queue->Process();
106 blocked = send_queue->IsBlocked();
107 if (blocked) {
109 jack_info("JackALSARawMidiOutputPort::ProcessALSA - MIDI port is "
110 "blocked");
112 SetPollEventMask(POLLERR | POLLNVAL | POLLOUT);
113 *frame = 0;
114 } else {
115 SetPollEventMask(POLLERR | POLLNVAL);
117 return true;
120 bool
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);
131 continue;
133 char c = 1;
134 ssize_t result = write(write_fd, &c, 1);
135 assert(result <= 1);
136 if (result < 0) {
137 jack_error("JackALSARawMidiOutputPort::ProcessJack - error "
138 "writing a byte to the pipe file descriptor: %s",
139 strerror(errno));
140 return false;
142 if (! result) {
143 // Recoverable.
144 jack_error("JackALSARawMidiOutputPort::ProcessJack - Couldn't "
145 "write a byte to the pipe file descriptor. Dropping "
146 "event.");
147 } else {
148 assert(thread_queue->EnqueueEvent(event, frames) ==
149 JackMidiWriteQueue::OK);
152 return true;