Audio plugin host https://kx.studio/carla
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.

186 lines
4.5KB

  1. /*
  2. * Simple Queue, specially developed for Atom types
  3. * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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 GPL.txt file
  16. */
  17. #ifndef __LV2_ATOM_QUEUE_HPP__
  18. #define __LV2_ATOM_QUEUE_HPP__
  19. #include "CarlaLv2Utils.hpp"
  20. #include "CarlaMutex.hpp"
  21. class Lv2AtomQueue
  22. {
  23. public:
  24. Lv2AtomQueue()
  25. {
  26. index = indexPool = 0;
  27. empty = true;
  28. full = false;
  29. std::memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
  30. }
  31. void copyDataFrom(Lv2AtomQueue* const queue)
  32. {
  33. // lock mutexes
  34. queue->lock();
  35. lock();
  36. // copy data from queue
  37. std::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
  38. std::memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE);
  39. index = queue->index;
  40. indexPool = queue->indexPool;
  41. empty = queue->empty;
  42. full = queue->full;
  43. // unlock our mutex, no longer needed
  44. unlock();
  45. // reset queque
  46. std::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
  47. std::memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
  48. queue->index = queue->indexPool = 0;
  49. queue->empty = true;
  50. queue->full = false;
  51. // unlock queque mutex
  52. queue->unlock();
  53. }
  54. bool isEmpty()
  55. {
  56. return empty;
  57. }
  58. bool isFull()
  59. {
  60. return full;
  61. }
  62. void lock()
  63. {
  64. mutex.lock();
  65. }
  66. bool tryLock()
  67. {
  68. return mutex.tryLock();
  69. }
  70. void unlock()
  71. {
  72. mutex.unlock();
  73. }
  74. void put(const uint32_t portIndex, const LV2_Atom* const atom)
  75. {
  76. CARLA_ASSERT(atom != nullptr && atom->size > 0);
  77. CARLA_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow
  78. if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE)
  79. return;
  80. lock();
  81. for (unsigned short i=0; i < MAX_SIZE; ++i)
  82. {
  83. if (data[i].size == 0)
  84. {
  85. data[i].portIndex = portIndex;
  86. data[i].size = atom->size;
  87. data[i].type = atom->type;
  88. data[i].poolOffset = indexPool;
  89. std::memcpy(dataPool + indexPool, LV2NV_ATOM_BODY_CONST(atom), atom->size);
  90. empty = false;
  91. full = (i == MAX_SIZE-1);
  92. indexPool += atom->size;
  93. break;
  94. }
  95. }
  96. unlock();
  97. }
  98. // needs to be locked first!
  99. bool get(uint32_t* const portIndex, const LV2_Atom** const atom)
  100. {
  101. CARLA_ASSERT(portIndex != nullptr && atom != nullptr);
  102. if (empty || portIndex == nullptr || atom == nullptr)
  103. return false;
  104. full = false;
  105. if (data[index].size == 0)
  106. {
  107. index = indexPool = 0;
  108. empty = true;
  109. unlock();
  110. return false;
  111. }
  112. retAtom.atom.size = data[index].size;
  113. retAtom.atom.type = data[index].type;
  114. std::memcpy(retAtom.data, dataPool + data[index].poolOffset, data[index].size);
  115. *portIndex = data[index].portIndex;
  116. *atom = (LV2_Atom*)&retAtom;
  117. data[index].portIndex = 0;
  118. data[index].size = 0;
  119. data[index].type = 0;
  120. data[index].poolOffset = 0;
  121. index++;
  122. empty = false;
  123. return true;
  124. }
  125. private:
  126. struct datatype {
  127. size_t size;
  128. uint32_t type;
  129. uint32_t portIndex;
  130. uint32_t poolOffset;
  131. datatype()
  132. : size(0),
  133. type(0),
  134. portIndex(0),
  135. poolOffset(0) {}
  136. };
  137. static const unsigned short MAX_SIZE = 128;
  138. static const unsigned short MAX_POOL_SIZE = 8192;
  139. datatype data[MAX_SIZE];
  140. unsigned char dataPool[MAX_POOL_SIZE];
  141. struct {
  142. LV2_Atom atom;
  143. unsigned char data[MAX_POOL_SIZE];
  144. } retAtom;
  145. unsigned short index, indexPool;
  146. bool empty, full;
  147. CarlaMutex mutex;
  148. };
  149. #endif // __LV2_ATOM_QUEUE_HPP__