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.

154 lines
3.2KB

  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. #include <QtCore/QMutex>
  18. class Queue
  19. {
  20. public:
  21. Queue()
  22. {
  23. index = 0;
  24. empty = true;
  25. full = false;
  26. }
  27. void copyDataFrom(Queue* queue)
  28. {
  29. // lock mutexes
  30. queue->mutex.lock();
  31. mutex.lock();
  32. // copy data from queue
  33. memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
  34. index = queue->index;
  35. empty = queue->empty;
  36. full = queue->full;
  37. // unlock our mutex, no longer needed
  38. mutex.unlock();
  39. // reset queque
  40. memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
  41. queue->index = 0;
  42. queue->empty = true;
  43. queue->full = false;
  44. // unlock queque mutex
  45. queue->mutex.unlock();
  46. }
  47. bool isEmpty()
  48. {
  49. return empty;
  50. }
  51. bool isFull()
  52. {
  53. return full;
  54. }
  55. void lock()
  56. {
  57. mutex.lock();
  58. }
  59. void unlock()
  60. {
  61. mutex.unlock();
  62. }
  63. void put(unsigned char d1, unsigned char d2, unsigned char d3, bool lock = true)
  64. {
  65. Q_ASSERT(d1 != 0);
  66. if (full || d1 == 0)
  67. return;
  68. if (lock)
  69. mutex.lock();
  70. for (unsigned short i=0; i < MAX_SIZE; i++)
  71. {
  72. if (data[i].d1 == 0)
  73. {
  74. data[i].d1 = d1;
  75. data[i].d2 = d2;
  76. data[i].d3 = d3;
  77. empty = false;
  78. full = (i == MAX_SIZE-1);
  79. break;
  80. }
  81. }
  82. if (lock)
  83. mutex.unlock();
  84. }
  85. bool get(unsigned char* d1, unsigned char* d2, unsigned char* d3, bool lock = true)
  86. {
  87. Q_ASSERT(d1 && d2 && d3);
  88. if (empty || ! (d1 && d2 && d3))
  89. return false;
  90. if (lock)
  91. mutex.lock();
  92. full = false;
  93. if (data[index].d1 == 0)
  94. {
  95. index = 0;
  96. empty = true;
  97. if (lock)
  98. mutex.lock();
  99. return false;
  100. }
  101. *d1 = data[index].d1;
  102. *d2 = data[index].d2;
  103. *d3 = data[index].d3;
  104. data[index].d1 = data[index].d2 = data[index].d3 = 0;
  105. index++;
  106. empty = false;
  107. if (lock)
  108. mutex.unlock();
  109. return true;
  110. }
  111. private:
  112. struct datatype {
  113. unsigned char d1, d2, d3;
  114. datatype()
  115. : d1(0), d2(0), d3(0) {}
  116. };
  117. static const unsigned short MAX_SIZE = 512;
  118. datatype data[MAX_SIZE];
  119. unsigned short index;
  120. bool empty, full;
  121. QMutex mutex;
  122. };