Jack2  1.9.8
JackFFADOMidiOutputPort.cpp
1 /*
2 Copyright (C) 2010 Devin Anderson
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
13 
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18 */
19 
20 #include <memory>
21 
22 #include "JackFFADOMidiOutputPort.h"
23 #include "JackMidiUtil.h"
24 
26 
27 JackFFADOMidiOutputPort::JackFFADOMidiOutputPort(size_t non_rt_size,
28  size_t max_non_rt_messages,
29  size_t max_rt_messages)
30 {
31  event = 0;
32  read_queue = new JackMidiBufferReadQueue();
33  std::auto_ptr<JackMidiBufferReadQueue> read_queue_ptr(read_queue);
34  send_queue = new JackFFADOMidiSendQueue();
35  std::auto_ptr<JackFFADOMidiSendQueue> send_queue_ptr(send_queue);
36  raw_queue = new JackMidiRawOutputWriteQueue(send_queue, non_rt_size,
37  max_non_rt_messages,
38  max_rt_messages);
39  send_queue_ptr.release();
40  read_queue_ptr.release();
41 }
42 
43 JackFFADOMidiOutputPort::~JackFFADOMidiOutputPort()
44 {
45  delete raw_queue;
46  delete read_queue;
47  delete send_queue;
48 }
49 
50 void
51 JackFFADOMidiOutputPort::Process(JackMidiBuffer *port_buffer,
52  uint32_t *output_buffer,
53  jack_nframes_t frames)
54 {
55  read_queue->ResetMidiBuffer(port_buffer);
56  send_queue->ResetOutputBuffer(output_buffer, frames);
57  jack_nframes_t boundary_frame = GetLastFrame() + frames;
58  if (! event) {
59  event = read_queue->DequeueEvent();
60  }
61  for (; event; event = read_queue->DequeueEvent()) {
62  switch (raw_queue->EnqueueEvent(event)) {
63  case JackMidiWriteQueue::BUFFER_FULL:
64 
65  // Processing events early might free up some space in the raw
66  // output queue.
67 
68  raw_queue->Process(boundary_frame);
69  switch (raw_queue->EnqueueEvent(event)) {
70  case JackMidiWriteQueue::BUFFER_TOO_SMALL:
71  // This shouldn't really happen. It indicates a bug if it
72  // does.
73  jack_error("JackFFADOMidiOutputPort::Process - **BUG** "
74  "JackMidiRawOutputWriteQueue::EnqueueEvent "
75  "returned `BUFFER_FULL`, and then returned "
76  "`BUFFER_TOO_SMALL` after a `Process()` call.");
77  // Fallthrough on purpose
78  case JackMidiWriteQueue::OK:
79  continue;
80  default:
81  return;
82  }
83  case JackMidiWriteQueue::BUFFER_TOO_SMALL:
84  jack_error("JackFFADOMidiOutputPort::Process - The write queue "
85  "couldn't enqueue a %d-byte event. Dropping event.",
86  event->size);
87  // Fallthrough on purpose
88  case JackMidiWriteQueue::OK:
89  continue;
90  default:
91  // This is here to stop compliers from warning us about not
92  // handling enumeration values.
93  ;
94  }
95  break;
96  }
97  raw_queue->Process(boundary_frame);
98 }