jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
5.0KB

  1. /*
  2. Copyright (C) 2010 Devin Anderson
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #ifndef __JackMidiRawOutputWriteQueue__
  16. #define __JackMidiRawOutputWriteQueue__
  17. #include "JackMidiAsyncQueue.h"
  18. #include "JackMidiPort.h"
  19. #include "JackMidiSendQueue.h"
  20. namespace Jack {
  21. /**
  22. * This queue enqueues valid MIDI events and modifies them for raw output
  23. * to a write queue. It has a couple of advantages over straight MIDI
  24. * event copying:
  25. *
  26. * -Running status: Status bytes can be omitted when the status byte of the
  27. * current MIDI message is the same as the status byte of the last sent
  28. * MIDI message.
  29. *
  30. * -Realtime messages: Realtime messages are given priority over
  31. * non-realtime messages. Realtime bytes are interspersed with
  32. * non-realtime bytes so that realtime messages can be sent as close as
  33. * possible to the time they're scheduled for sending.
  34. *
  35. * Use this queue if the MIDI API you're interfacing with allows you to
  36. * send raw MIDI bytes.
  37. */
  38. class SERVER_EXPORT JackMidiRawOutputWriteQueue:
  39. public JackMidiWriteQueue {
  40. private:
  41. jack_midi_event_t *non_rt_event;
  42. jack_nframes_t non_rt_event_time;
  43. JackMidiAsyncQueue *non_rt_queue;
  44. jack_midi_event_t *rt_event;
  45. jack_nframes_t rt_event_time;
  46. JackMidiAsyncQueue *rt_queue;
  47. jack_midi_data_t running_status;
  48. JackMidiSendQueue *send_queue;
  49. void
  50. DequeueNonRealtimeEvent();
  51. void
  52. DequeueRealtimeEvent();
  53. bool
  54. SendByte(jack_nframes_t time, jack_midi_data_t byte);
  55. bool
  56. SendNonRTBytes(jack_nframes_t boundary_frame);
  57. protected:
  58. /**
  59. * Override this method to specify what happens when the write queue
  60. * says that a 1-byte event is too large for its buffer. Basically,
  61. * this should never happen.
  62. */
  63. virtual void
  64. HandleWriteQueueBug(jack_nframes_t time, jack_midi_data_t byte);
  65. public:
  66. using JackMidiWriteQueue::EnqueueEvent;
  67. /**
  68. * Called to create a new raw write queue. The `send_queue` argument
  69. * is the queue to write raw bytes to. The optional `max_rt_messages`
  70. * argument specifies the number of messages that can be enqueued in
  71. * the internal realtime queue. The optional `max_non_rt_messages`
  72. * argument specifies the number of messages that can be enqueued in
  73. * the internal non-realtime queue. The optional `non_rt_size`
  74. * argument specifies the total number of MIDI bytes that can be put in
  75. * the non-realtime queue.
  76. */
  77. JackMidiRawOutputWriteQueue(JackMidiSendQueue *send_queue,
  78. size_t non_rt_size=4096,
  79. size_t max_non_rt_messages=1024,
  80. size_t max_rt_messages=128);
  81. ~JackMidiRawOutputWriteQueue();
  82. EnqueueResult
  83. EnqueueEvent(jack_nframes_t time, size_t size,
  84. jack_midi_data_t *buffer);
  85. /**
  86. * The `Process()` method should be called each time the
  87. * `EnqueueEvent()` method returns 'OK'. The `Process()` method will
  88. * return the next frame at which an event should be sent. The return
  89. * value from `Process()` depends upon the result of writing bytes to
  90. * the write queue:
  91. *
  92. * -If the return value is '0', then all events that have been enqueued
  93. * in this queue have been sent successfully to the write queue. Don't
  94. * call `Process()` again until another event has been enqueued.
  95. *
  96. * -If the return value is an earlier frame or the current frame, it
  97. * means that the write queue returned 'BUFFER_FULL', 'ERROR', or
  98. * 'EVENT_EARLY' when this queue attempted to send the next byte, and
  99. * that the byte should have already been sent, or is scheduled to be
  100. * sent *now*. `Process()` should be called again when the write queue
  101. * can enqueue events again successfully. How to determine when this
  102. * will happen is left up to the caller.
  103. *
  104. * -If the return value is in the future, then `Process()` should be
  105. * called again at that time, or after another event is enqueued.
  106. */
  107. jack_nframes_t
  108. Process(jack_nframes_t boundary_frame=0);
  109. };
  110. }
  111. #endif