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.

lv2_atom_queue.hpp 4.5KB

11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Simple Queue, specially developed for Atom types
  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 __LV2_ATOM_QUEUE_HPP__
  18. #define __LV2_ATOM_QUEUE_HPP__
  19. #include "carla_utils.hpp"
  20. #include "lv2/atom.h"
  21. #include <cstring> // memcpy, memset
  22. class Lv2AtomQueue
  23. {
  24. public:
  25. Lv2AtomQueue()
  26. {
  27. index = indexPool = 0;
  28. empty = true;
  29. full = false;
  30. ::memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
  31. }
  32. void copyDataFrom(Lv2AtomQueue* const queue)
  33. {
  34. // lock mutexes
  35. queue->lock();
  36. lock();
  37. // copy data from queue
  38. ::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
  39. ::memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE);
  40. index = queue->index;
  41. indexPool = queue->indexPool;
  42. empty = queue->empty;
  43. full = queue->full;
  44. // unlock our mutex, no longer needed
  45. unlock();
  46. // reset queque
  47. ::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
  48. ::memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
  49. queue->index = queue->indexPool = 0;
  50. queue->empty = true;
  51. queue->full = false;
  52. // unlock queque mutex
  53. queue->unlock();
  54. }
  55. bool isEmpty()
  56. {
  57. return empty;
  58. }
  59. bool isFull()
  60. {
  61. return full;
  62. }
  63. bool lock()
  64. {
  65. return mutex.lock();
  66. }
  67. bool tryLock()
  68. {
  69. return mutex.tryLock();
  70. }
  71. bool unlock()
  72. {
  73. return mutex.unlock();
  74. }
  75. void put(const uint32_t portIndex, const LV2_Atom* const atom)
  76. {
  77. CARLA_ASSERT(atom && atom->size > 0);
  78. CARLA_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow
  79. if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE)
  80. return;
  81. lock();
  82. for (unsigned short i=0; i < MAX_SIZE; i++)
  83. {
  84. if (data[i].size == 0)
  85. {
  86. data[i].portIndex = portIndex;
  87. data[i].size = atom->size;
  88. data[i].type = atom->type;
  89. data[i].poolOffset = indexPool;
  90. ::memcpy(dataPool + indexPool, (const unsigned char*)LV2_ATOM_BODY_CONST(atom), atom->size);
  91. empty = false;
  92. full = (i == MAX_SIZE-1);
  93. indexPool += atom->size;
  94. break;
  95. }
  96. }
  97. unlock();
  98. }
  99. bool get(uint32_t* const portIndex, const LV2_Atom** const atom)
  100. {
  101. CARLA_ASSERT(portIndex && atom);
  102. if (empty || ! (portIndex && atom))
  103. return false;
  104. if (! tryLock())
  105. return false;
  106. full = false;
  107. if (data[index].size == 0)
  108. {
  109. index = indexPool = 0;
  110. empty = true;
  111. unlock();
  112. return false;
  113. }
  114. retAtom.atom.size = data[index].size;
  115. retAtom.atom.type = data[index].type;
  116. ::memcpy(retAtom.data, dataPool + data[index].poolOffset, data[index].size);
  117. *portIndex = data[index].portIndex;
  118. *atom = (LV2_Atom*)&retAtom;
  119. data[index].portIndex = 0;
  120. data[index].size = 0;
  121. data[index].type = 0;
  122. data[index].poolOffset = 0;
  123. index++;
  124. empty = false;
  125. unlock();
  126. return true;
  127. }
  128. private:
  129. struct datatype {
  130. size_t size;
  131. uint32_t type;
  132. uint32_t portIndex;
  133. uint32_t poolOffset;
  134. datatype()
  135. : size(0),
  136. type(0),
  137. portIndex(0),
  138. poolOffset(0) {}
  139. };
  140. static const unsigned short MAX_SIZE = 128;
  141. static const unsigned short MAX_POOL_SIZE = 8192;
  142. datatype data[MAX_SIZE];
  143. unsigned char dataPool[MAX_POOL_SIZE];
  144. struct {
  145. LV2_Atom atom;
  146. unsigned char data[MAX_POOL_SIZE];
  147. } retAtom;
  148. unsigned short index, indexPool;
  149. bool empty, full;
  150. CarlaMutex mutex;
  151. };
  152. #endif // __LV2_ATOM_QUEUE_HPP__