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.

178 lines
5.7KB

  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 __JackMidiRawInputWriteQueue__
  16. #define __JackMidiRawInputWriteQueue__
  17. #include "JackMidiAsyncQueue.h"
  18. #include "JackMidiWriteQueue.h"
  19. namespace Jack {
  20. /**
  21. * This queue enqueues raw, unparsed MIDI packets, and outputs complete
  22. * MIDI messages to a write queue.
  23. *
  24. * Use this queue if the MIDI API you're interfacing with gives you raw
  25. * MIDI bytes that must be parsed.
  26. */
  27. class SERVER_EXPORT JackMidiRawInputWriteQueue: public JackMidiWriteQueue {
  28. private:
  29. jack_midi_event_t event;
  30. jack_midi_data_t event_byte;
  31. bool event_pending;
  32. size_t expected_bytes;
  33. jack_midi_data_t *input_buffer;
  34. size_t input_buffer_size;
  35. jack_midi_event_t *packet;
  36. JackMidiAsyncQueue *packet_queue;
  37. jack_midi_data_t status_byte;
  38. size_t total_bytes;
  39. size_t unbuffered_bytes;
  40. JackMidiWriteQueue *write_queue;
  41. void
  42. Clear();
  43. bool
  44. PrepareBufferedEvent(jack_nframes_t time);
  45. bool
  46. PrepareByteEvent(jack_nframes_t time, jack_midi_data_t byte);
  47. void
  48. PrepareEvent(jack_nframes_t time, size_t size,
  49. jack_midi_data_t *buffer);
  50. bool
  51. ProcessByte(jack_nframes_t time, jack_midi_data_t byte);
  52. void
  53. RecordByte(jack_midi_data_t byte);
  54. bool
  55. WriteEvent(jack_nframes_t boundary_frame);
  56. protected:
  57. /**
  58. * Override this method to specify what happens when there isn't enough
  59. * room in the ringbuffer to contain a parsed event. The default
  60. * method outputs an error message.
  61. */
  62. virtual void
  63. HandleBufferFailure(size_t unbuffered_bytes, size_t total_bytes);
  64. /**
  65. * Override this method to specify what happens when a parsed event
  66. * can't be written to the write queue because the event's size exceeds
  67. * the total possible space in the write queue. The default method
  68. * outputs an error message.
  69. */
  70. virtual void
  71. HandleEventLoss(jack_midi_event_t *event);
  72. /**
  73. * Override this method to specify what happens when an incomplete MIDI
  74. * message is parsed. The default method outputs an error message.
  75. */
  76. virtual void
  77. HandleIncompleteMessage(size_t total_bytes);
  78. /**
  79. * Override this method to specify what happens when an invalid MIDI
  80. * status byte is parsed. The default method outputs an error message.
  81. */
  82. virtual void
  83. HandleInvalidStatusByte(jack_midi_data_t byte);
  84. /**
  85. * Override this method to specify what happens when a sysex end byte
  86. * is parsed without first parsing a sysex begin byte. The default
  87. * method outputs an error message.
  88. */
  89. virtual void
  90. HandleUnexpectedSysexEnd(size_t total_bytes);
  91. public:
  92. using JackMidiWriteQueue::EnqueueEvent;
  93. /**
  94. * Called to create a new raw input write queue. The `write_queue`
  95. * argument is the queue to write parsed messages to. The optional
  96. * `max_packets` argument specifies the number of packets that can be
  97. * enqueued in the internal queue. The optional `max_packet_data`
  98. * argument specifies the total number of MIDI bytes that can be put in
  99. * the internal queue, AND the maximum size for an event that can be
  100. * written to the write queue.
  101. */
  102. JackMidiRawInputWriteQueue(JackMidiWriteQueue *write_queue,
  103. size_t max_packet_data=4096,
  104. size_t max_packets=1024);
  105. ~JackMidiRawInputWriteQueue();
  106. EnqueueResult
  107. EnqueueEvent(jack_nframes_t time, size_t size,
  108. jack_midi_data_t *buffer);
  109. /**
  110. * Returns the maximum size event that can be enqueued right *now*.
  111. */
  112. size_t
  113. GetAvailableSpace();
  114. /**
  115. * The `Process()` method should be called each time the
  116. * `EnqueueEvent()` method returns `OK`. The `Process()` method will
  117. * return the next frame at which an event should be sent. The return
  118. * value from `Process()` depends upon the result of writing bytes to
  119. * the write queue:
  120. *
  121. * -If the return value is '0', then all *complete* events have been
  122. * sent successfully to the write queue. Don't call `Process()` again
  123. * until another event has been enqueued.
  124. *
  125. * -If the return value is a non-zero value, then it specifies the
  126. * frame that a pending event is scheduled to sent at. If the frame is
  127. * in the future, then `Process()` should be called again at that time;
  128. * otherwise, `Process()` should be called as soon as the write queue
  129. * will accept events again.
  130. */
  131. jack_nframes_t
  132. Process(jack_nframes_t boundary_frame=0);
  133. };
  134. }
  135. #endif