Correct XCode target.
[jack2.git] / linux / alsarawmidi / JackALSARawMidiInputPort.cpp
blobaab449cb2e4b004ee808b40eeab967d5782b74f0
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 "JackALSARawMidiInputPort.h"
24 #include "JackMidiUtil.h"
26 using Jack::JackALSARawMidiInputPort;
28 JackALSARawMidiInputPort::JackALSARawMidiInputPort(snd_rawmidi_info_t *info,
29 size_t index,
30 size_t max_bytes,
31 size_t max_messages):
32 JackALSARawMidiPort(info, index, POLLIN)
34 alsa_event = 0;
35 jack_event = 0;
36 receive_queue = new JackALSARawMidiReceiveQueue(rawmidi, max_bytes);
37 std::auto_ptr<JackALSARawMidiReceiveQueue> receive_ptr(receive_queue);
38 thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages);
39 std::auto_ptr<JackMidiAsyncQueue> thread_ptr(thread_queue);
40 write_queue = new JackMidiBufferWriteQueue();
41 std::auto_ptr<JackMidiBufferWriteQueue> write_ptr(write_queue);
42 raw_queue = new JackMidiRawInputWriteQueue(thread_queue, max_bytes,
43 max_messages);
44 write_ptr.release();
45 thread_ptr.release();
46 receive_ptr.release();
49 JackALSARawMidiInputPort::~JackALSARawMidiInputPort()
51 delete raw_queue;
52 delete receive_queue;
53 delete thread_queue;
54 delete write_queue;
57 bool
58 JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer,
59 jack_nframes_t frames)
61 write_queue->ResetMidiBuffer(port_buffer, frames);
62 bool dequeued = false;
63 if (! jack_event) {
64 goto dequeue_event;
66 for (;;) {
67 switch (write_queue->EnqueueEvent(jack_event, frames)) {
68 case JackMidiWriteQueue::BUFFER_TOO_SMALL:
69 jack_error("JackALSARawMidiInputPort::ProcessJack - The write "
70 "queue couldn't enqueue a %d-byte event. Dropping "
71 "event.", jack_event->size);
72 // Fallthrough on purpose.
73 case JackMidiWriteQueue::OK:
74 break;
75 default:
76 goto trigger_queue_event;
78 dequeue_event:
79 jack_event = thread_queue->DequeueEvent();
80 if (! jack_event) {
81 break;
83 dequeued = true;
85 trigger_queue_event:
86 return dequeued ? TriggerQueueEvent() : true;
89 bool
90 JackALSARawMidiInputPort::ProcessPollEvents(jack_nframes_t current_frame)
92 if (GetQueuePollEvent() == -1) {
93 return false;
95 int io_event = GetIOPollEvent();
96 switch (io_event) {
97 case -1:
98 return false;
99 case 1:
100 alsa_event = receive_queue->DequeueEvent();
102 if (alsa_event) {
103 size_t size = alsa_event->size;
104 size_t space = raw_queue->GetAvailableSpace();
105 bool enough_room = space >= size;
106 if (enough_room) {
107 assert(raw_queue->EnqueueEvent(current_frame, size,
108 alsa_event->buffer) ==
109 JackMidiWriteQueue::OK);
110 alsa_event = 0;
111 } else if (space) {
112 assert(raw_queue->EnqueueEvent(current_frame, space,
113 alsa_event->buffer) ==
114 JackMidiWriteQueue::OK);
115 alsa_event->buffer += space;
116 alsa_event->size -= space;
118 SetIOEventsEnabled(enough_room);
120 raw_queue->Process();
121 return true;