Jack2 1.9.12

JackALSARawMidiInputPort.cpp
1 /*
2 Copyright (C) 2011 Devin Anderson
3
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.
8
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.
13
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.
17
18 */
19
20 #include <cassert>
21 #include <memory>
22
23 #include "JackALSARawMidiInputPort.h"
24 #include "JackMidiUtil.h"
25 #include "JackError.h"
26
27 using Jack::JackALSARawMidiInputPort;
28
29 JackALSARawMidiInputPort::JackALSARawMidiInputPort(snd_rawmidi_info_t *info,
30 size_t index,
31 size_t max_bytes,
32 size_t max_messages):
33 JackALSARawMidiPort(info, index, POLLIN)
34 {
35 alsa_event = 0;
36 jack_event = 0;
37 receive_queue = new JackALSARawMidiReceiveQueue(rawmidi, max_bytes);
38 std::auto_ptr<JackALSARawMidiReceiveQueue> receive_ptr(receive_queue);
39 thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages);
40 std::auto_ptr<JackMidiAsyncQueue> thread_ptr(thread_queue);
41 write_queue = new JackMidiBufferWriteQueue();
42 std::auto_ptr<JackMidiBufferWriteQueue> write_ptr(write_queue);
43 raw_queue = new JackMidiRawInputWriteQueue(thread_queue, max_bytes,
44 max_messages);
45 write_ptr.release();
46 thread_ptr.release();
47 receive_ptr.release();
48 }
49
50 JackALSARawMidiInputPort::~JackALSARawMidiInputPort()
51 {
52 delete raw_queue;
53 delete receive_queue;
54 delete thread_queue;
55 delete write_queue;
56 }
57
58 bool
59 JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer *port_buffer,
60 jack_nframes_t frames)
61 {
62 write_queue->ResetMidiBuffer(port_buffer, frames);
63 bool dequeued = false;
64 if (! jack_event) {
65 goto dequeue_event;
66 }
67 for (;;) {
68 switch (write_queue->EnqueueEvent(jack_event, frames)) {
69 case JackMidiWriteQueue::BUFFER_TOO_SMALL:
70 jack_error("JackALSARawMidiInputPort::ProcessJack - The write "
71 "queue couldn't enqueue a %d-byte event. Dropping "
72 "event.", jack_event->size);
73 // Fallthrough on purpose.
74 case JackMidiWriteQueue::OK:
75 break;
76 default:
77 goto trigger_queue_event;
78 }
79 dequeue_event:
80 jack_event = thread_queue->DequeueEvent();
81 if (! jack_event) {
82 break;
83 }
84 dequeued = true;
85 }
86 trigger_queue_event:
87 return dequeued ? TriggerQueueEvent() : true;
88 }
89
90 bool
91 JackALSARawMidiInputPort::ProcessPollEvents(jack_nframes_t current_frame)
92 {
93 if (GetQueuePollEvent() == -1) {
94 return false;
95 }
96 int io_event = GetIOPollEvent();
97 switch (io_event) {
98 case -1:
99 return false;
100 case 1:
101 alsa_event = receive_queue->DequeueEvent();
102 }
103 if (alsa_event) {
104 size_t size = alsa_event->size;
105 size_t space = raw_queue->GetAvailableSpace();
106 bool enough_room = space >= size;
107 if (enough_room) {
108 assert(raw_queue->EnqueueEvent(current_frame, size,
109 alsa_event->buffer) ==
110 JackMidiWriteQueue::OK);
111 alsa_event = 0;
112 } else if (space) {
113 assert(raw_queue->EnqueueEvent(current_frame, space,
114 alsa_event->buffer) ==
115 JackMidiWriteQueue::OK);
116 alsa_event->buffer += space;
117 alsa_event->size -= space;
118 }
119 SetIOEventsEnabled(enough_room);
120 }
121 raw_queue->Process();
122 return true;
123 }
Jack::JackALSARawMidiInputPort
Definition: JackALSARawMidiInputPort.h:31
jack_midi_event_t::buffer
jack_midi_data_t * buffer
Definition: JackMidiPort.h:37
Jack::JackALSARawMidiReceiveQueue::DequeueEvent
jack_midi_event_t * DequeueEvent()
Definition: JackALSARawMidiReceiveQueue.cpp:40
Jack::JackMidiBufferWriteQueue::EnqueueEvent
EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer)
Definition: JackMidiBufferWriteQueue.cpp:32
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jack_midi_event_t::size
size_t size
Definition: JackMidiPort.h:36
Jack::JackMidiRawInputWriteQueue::Process
jack_nframes_t Process(jack_nframes_t boundary_frame=0)
Definition: JackMidiRawInputWriteQueue.cpp:151
Jack::JackMidiRawInputWriteQueue::GetAvailableSpace
size_t GetAvailableSpace()
Definition: JackMidiRawInputWriteQueue.cpp:67
Jack::JackMidiRawInputWriteQueue::EnqueueEvent
EnqueueResult EnqueueEvent(jack_nframes_t time, size_t size, jack_midi_data_t *buffer)
Definition: JackMidiRawInputWriteQueue.cpp:60
Jack::JackMidiBufferWriteQueue::ResetMidiBuffer
void ResetMidiBuffer(JackMidiBuffer *buffer, jack_nframes_t frames)
Definition: JackMidiBufferWriteQueue.cpp:50
Jack::JackMidiAsyncQueue::DequeueEvent
virtual jack_midi_event_t * DequeueEvent()
Definition: JackMidiAsyncQueue.cpp:53