Collection of tools useful for audio production
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.

160 lines
3.3KB

  1. /*
  2. * Simple Queue, specially developed for MIDI messages
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #ifndef MIDI_QUEUE_HPP
  18. #define MIDI_QUEUE_HPP
  19. #include <cstring>
  20. #include <QtCore/QMutex>
  21. class Queue
  22. {
  23. public:
  24. Queue()
  25. {
  26. index = 0;
  27. empty = true;
  28. full = false;
  29. }
  30. void copyDataFrom(Queue* queue)
  31. {
  32. // lock mutexes
  33. queue->mutex.lock();
  34. mutex.lock();
  35. // copy data from queue
  36. ::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
  37. index = queue->index;
  38. empty = queue->empty;
  39. full = queue->full;
  40. // unlock our mutex, no longer needed
  41. mutex.unlock();
  42. // reset queque
  43. ::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
  44. queue->index = 0;
  45. queue->empty = true;
  46. queue->full = false;
  47. // unlock queque mutex
  48. queue->mutex.unlock();
  49. }
  50. bool isEmpty()
  51. {
  52. return empty;
  53. }
  54. bool isFull()
  55. {
  56. return full;
  57. }
  58. void lock()
  59. {
  60. mutex.lock();
  61. }
  62. void unlock()
  63. {
  64. mutex.unlock();
  65. }
  66. void put(unsigned char d1, unsigned char d2, unsigned char d3, bool lock = true)
  67. {
  68. Q_ASSERT(d1 != 0);
  69. if (full || d1 == 0)
  70. return;
  71. if (lock)
  72. mutex.lock();
  73. for (unsigned short i=0; i < MAX_SIZE; i++)
  74. {
  75. if (data[i].d1 == 0)
  76. {
  77. data[i].d1 = d1;
  78. data[i].d2 = d2;
  79. data[i].d3 = d3;
  80. empty = false;
  81. full = (i == MAX_SIZE-1);
  82. break;
  83. }
  84. }
  85. if (lock)
  86. mutex.unlock();
  87. }
  88. bool get(unsigned char* d1, unsigned char* d2, unsigned char* d3, bool lock = true)
  89. {
  90. Q_ASSERT(d1 && d2 && d3);
  91. if (empty || ! (d1 && d2 && d3))
  92. return false;
  93. if (lock)
  94. mutex.lock();
  95. full = false;
  96. if (data[index].d1 == 0)
  97. {
  98. index = 0;
  99. empty = true;
  100. if (lock)
  101. mutex.unlock();
  102. return false;
  103. }
  104. *d1 = data[index].d1;
  105. *d2 = data[index].d2;
  106. *d3 = data[index].d3;
  107. data[index].d1 = data[index].d2 = data[index].d3 = 0;
  108. index++;
  109. empty = false;
  110. if (lock)
  111. mutex.unlock();
  112. return true;
  113. }
  114. private:
  115. struct datatype {
  116. unsigned char d1, d2, d3;
  117. datatype()
  118. : d1(0), d2(0), d3(0) {}
  119. };
  120. static const unsigned short MAX_SIZE = 512;
  121. datatype data[MAX_SIZE];
  122. unsigned short index;
  123. bool empty, full;
  124. QMutex mutex;
  125. };
  126. #endif // MIDI_QUEUE_HPP