Remove non-jackdbus man pages
[jackdbus.git] / linux / alsarawmidi / JackALSARawMidiOutputPort.cpp
blob52da5356b75b74c1fca77391656761a7f9792238
1 /*
2 Copyright (C) 2011 Devin Anderson
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
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 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <cassert>
21 #include <memory>
23 #include "JackALSARawMidiOutputPort.h"
24 #include "JackError.h"
26 using Jack::JackALSARawMidiOutputPort;
28 JackALSARawMidiOutputPort::JackALSARawMidiOutputPort(const char* client_name,
29 snd_rawmidi_info_t *info,
30 size_t index,
31 size_t max_bytes_per_poll,
32 size_t max_bytes,
33 size_t max_messages):
34 JackALSARawMidiPort(client_name, info, index, POLLOUT)
36 alsa_event = 0;
37 read_queue = new JackMidiBufferReadQueue();
38 std::unique_ptr<JackMidiBufferReadQueue> read_ptr(read_queue);
39 send_queue = new JackALSARawMidiSendQueue(rawmidi, max_bytes_per_poll);
40 std::unique_ptr<JackALSARawMidiSendQueue> send_ptr(send_queue);
41 thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages);
42 std::unique_ptr<JackMidiAsyncQueue> thread_ptr(thread_queue);
43 raw_queue = new JackMidiRawOutputWriteQueue(send_queue, max_bytes,
44 max_messages, max_messages);
45 thread_ptr.release();
46 send_ptr.release();
47 read_ptr.release();
50 JackALSARawMidiOutputPort::~JackALSARawMidiOutputPort()
52 delete raw_queue;
53 delete read_queue;
54 delete send_queue;
55 delete thread_queue;
58 bool
59 JackALSARawMidiOutputPort::ProcessJack(JackMidiBuffer *port_buffer,
60 jack_nframes_t frames)
62 read_queue->ResetMidiBuffer(port_buffer);
63 bool enqueued = false;
64 for (jack_midi_event_t *event = read_queue->DequeueEvent(); event;
65 event = read_queue->DequeueEvent()) {
66 switch (thread_queue->EnqueueEvent(event, frames)) {
67 case JackMidiWriteQueue::BUFFER_FULL:
68 jack_error("JackALSARawMidiOutputPort::ProcessJack - The thread "
69 "queue doesn't have enough room to enqueue a %d-byte "
70 "event. Dropping event.", event->size);
71 continue;
72 case JackMidiWriteQueue::BUFFER_TOO_SMALL:
73 jack_error("JackALSARawMidiOutputPort::ProcessJack - The thread "
74 "queue is too small to enqueue a %d-byte event. "
75 "Dropping event.", event->size);
76 continue;
77 default:
78 enqueued = true;
81 return enqueued ? TriggerQueueEvent() : true;
84 bool
85 JackALSARawMidiOutputPort::ProcessPollEvents(bool handle_output, bool timeout,
86 jack_nframes_t *frame)
88 int io_event;
89 int queue_event;
90 send_queue->ResetPollByteCount();
91 if (! handle_output) {
92 assert(timeout);
93 goto process_raw_queue;
95 io_event = GetIOPollEvent();
96 if (io_event == -1) {
97 return false;
99 queue_event = GetQueuePollEvent();
100 if (queue_event == -1) {
101 return false;
103 if (io_event || timeout) {
104 process_raw_queue:
105 // We call the 'Process' event early because there are events waiting
106 // to be processed that either need to be sent now, or before now.
107 raw_queue->Process();
108 } else if (! queue_event) {
109 return true;
111 if (! alsa_event) {
112 alsa_event = thread_queue->DequeueEvent();
114 for (; alsa_event; alsa_event = thread_queue->DequeueEvent()) {
115 switch (raw_queue->EnqueueEvent(alsa_event)) {
116 case JackMidiWriteQueue::BUFFER_TOO_SMALL:
117 jack_error("JackALSARawMidiOutputPort::ProcessQueues - The raw "
118 "output queue couldn't enqueue a %d-byte event. "
119 "Dropping event.", alsa_event->size);
120 // Fallthrough on purpose.
121 case JackMidiWriteQueue::OK:
122 continue;
123 default:
127 // Try to free up some space by processing events early.
128 *frame = raw_queue->Process();
130 switch (raw_queue->EnqueueEvent(alsa_event)) {
131 case JackMidiWriteQueue::BUFFER_FULL:
132 goto set_io_events;
133 case JackMidiWriteQueue::BUFFER_TOO_SMALL:
134 // This shouldn't happen.
135 assert(false);
136 default:
140 *frame = raw_queue->Process();
141 set_io_events:
142 bool blocked = send_queue->IsBlocked();
143 SetIOEventsEnabled(blocked);
144 if (blocked) {
145 *frame = 0;
147 return true;