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.
23 #include "JackALSARawMidiInputPort.h"
24 #include "JackMidiUtil.h"
25 #include "JackError.h"
27 using Jack::JackALSARawMidiInputPort
;
29 JackALSARawMidiInputPort::JackALSARawMidiInputPort(const char* client_name
,
30 snd_rawmidi_info_t
*info
,
34 JackALSARawMidiPort(client_name
, info
, index
, POLLIN
)
38 receive_queue
= new JackALSARawMidiReceiveQueue(rawmidi
, max_bytes
);
39 std::unique_ptr
<JackALSARawMidiReceiveQueue
> receive_ptr(receive_queue
);
40 thread_queue
= new JackMidiAsyncQueue(max_bytes
, max_messages
);
41 std::unique_ptr
<JackMidiAsyncQueue
> thread_ptr(thread_queue
);
42 write_queue
= new JackMidiBufferWriteQueue();
43 std::unique_ptr
<JackMidiBufferWriteQueue
> write_ptr(write_queue
);
44 raw_queue
= new JackMidiRawInputWriteQueue(thread_queue
, max_bytes
,
48 receive_ptr
.release();
51 JackALSARawMidiInputPort::~JackALSARawMidiInputPort()
60 JackALSARawMidiInputPort::ProcessJack(JackMidiBuffer
*port_buffer
,
61 jack_nframes_t frames
)
63 write_queue
->ResetMidiBuffer(port_buffer
, frames
);
64 bool dequeued
= false;
69 switch (write_queue
->EnqueueEvent(jack_event
, frames
)) {
70 case JackMidiWriteQueue::BUFFER_TOO_SMALL
:
71 jack_error("JackALSARawMidiInputPort::ProcessJack - The write "
72 "queue couldn't enqueue a %d-byte event. Dropping "
73 "event.", jack_event
->size
);
74 // Fallthrough on purpose.
75 case JackMidiWriteQueue::OK
:
78 goto trigger_queue_event
;
81 jack_event
= thread_queue
->DequeueEvent();
88 return dequeued
? TriggerQueueEvent() : true;
92 JackALSARawMidiInputPort::ProcessPollEvents(jack_nframes_t current_frame
)
94 if (GetQueuePollEvent() == -1) {
97 int io_event
= GetIOPollEvent();
102 alsa_event
= receive_queue
->DequeueEvent();
105 size_t size
= alsa_event
->size
;
106 size_t space
= raw_queue
->GetAvailableSpace();
107 bool enough_room
= space
>= size
;
109 assert(raw_queue
->EnqueueEvent(current_frame
, size
,
110 alsa_event
->buffer
) ==
111 JackMidiWriteQueue::OK
);
114 assert(raw_queue
->EnqueueEvent(current_frame
, space
,
115 alsa_event
->buffer
) ==
116 JackMidiWriteQueue::OK
);
117 alsa_event
->buffer
+= space
;
118 alsa_event
->size
-= space
;
120 SetIOEventsEnabled(enough_room
);
122 raw_queue
->Process();