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.

86 lines
2.8KB

  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. #include <new>
  16. #include "JackMidiAsyncWaitQueue.h"
  17. #include "JackMidiUtil.h"
  18. #include "JackTime.h"
  19. using Jack::JackMidiAsyncWaitQueue;
  20. JackMidiAsyncWaitQueue::JackMidiAsyncWaitQueue(size_t max_bytes,
  21. size_t max_messages):
  22. JackMidiAsyncQueue(max_bytes, max_messages)
  23. {
  24. if (semaphore.Allocate("JackMidiAsyncWaitQueue", "midi-thread", 0)) {
  25. throw std::bad_alloc();
  26. }
  27. }
  28. JackMidiAsyncWaitQueue::~JackMidiAsyncWaitQueue()
  29. {
  30. semaphore.Destroy();
  31. }
  32. jack_midi_event_t *
  33. JackMidiAsyncWaitQueue::DequeueEvent()
  34. {
  35. return DequeueEvent((long) 0);
  36. }
  37. jack_midi_event_t *
  38. JackMidiAsyncWaitQueue::DequeueEvent(jack_nframes_t frame)
  39. {
  40. // XXX: I worry about timer resolution on Solaris and Windows. When the
  41. // resolution for the `JackSynchro` object is milliseconds, the worst-case
  42. // scenario for processor objects is that the wait time becomes less than a
  43. // millisecond, and the processor object continually calls this method,
  44. // expecting to wait a certain amount of microseconds, and ends up not
  45. // waiting at all each time, essentially busy-waiting until the current
  46. // frame is reached. Perhaps there should be a #define that indicates the
  47. // wait time resolution for `JackSynchro` objects so that we can wait a
  48. // little longer if necessary.
  49. jack_time_t frame_time = GetTimeFromFrames(frame);
  50. jack_time_t current_time = GetMicroSeconds();
  51. return DequeueEvent((frame_time < current_time) ? 0 :
  52. (long) (frame_time - current_time));
  53. }
  54. jack_midi_event_t *
  55. JackMidiAsyncWaitQueue::DequeueEvent(long usec)
  56. {
  57. return ((usec < 0) ? semaphore.Wait() : semaphore.TimedWait(usec)) ?
  58. JackMidiAsyncQueue::DequeueEvent() : 0;
  59. }
  60. Jack::JackMidiWriteQueue::EnqueueResult
  61. JackMidiAsyncWaitQueue::EnqueueEvent(jack_nframes_t time, size_t size,
  62. jack_midi_data_t *buffer)
  63. {
  64. EnqueueResult result = JackMidiAsyncQueue::EnqueueEvent(time, size,
  65. buffer);
  66. if (result == OK) {
  67. semaphore.Signal();
  68. }
  69. return result;
  70. }