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.

167 lines
4.3KB

  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 doc/GPL.txt file.
  16. */
  17. #ifndef LV2_ATOM_QUEUE_HPP_INCLUDED
  18. #define LV2_ATOM_QUEUE_HPP_INCLUDED
  19. #include "CarlaMutex.hpp"
  20. #include "CarlaRingBuffer.hpp"
  21. #include "lv2/atom.h"
  22. // -----------------------------------------------------------------------
  23. class Lv2AtomRingBufferControl : public RingBufferControl
  24. {
  25. public:
  26. Lv2AtomRingBufferControl()
  27. : RingBufferControl(&fBuffer)
  28. {
  29. }
  30. // -------------------------------------------------------------------
  31. const LV2_Atom* readAtom(uint32_t* const portIndex)
  32. {
  33. fRetAtom.atom.size = 0;
  34. fRetAtom.atom.type = 0;
  35. tryRead(&fRetAtom.atom, sizeof(LV2_Atom));
  36. if (fRetAtom.atom.size == 0 || fRetAtom.atom.type == 0)
  37. return nullptr;
  38. CARLA_SAFE_ASSERT_RETURN(fRetAtom.atom.size < RING_BUFFER_SIZE, nullptr);
  39. int32_t index = -1;
  40. tryRead(&index, sizeof(int32_t));
  41. if (index == -1)
  42. return nullptr;
  43. if (portIndex != nullptr)
  44. *portIndex = static_cast<uint32_t>(index);
  45. carla_zeroChar(fRetAtom.data, fRetAtom.atom.size);
  46. tryRead(fRetAtom.data, fRetAtom.atom.size);
  47. return &fRetAtom.atom;
  48. }
  49. // -------------------------------------------------------------------
  50. bool writeAtom(const LV2_Atom* const atom, const int32_t portIndex)
  51. {
  52. tryWrite(atom, sizeof(LV2_Atom));
  53. tryWrite(&portIndex, sizeof(int32_t));
  54. tryWrite(LV2_ATOM_BODY_CONST(atom), atom->size);
  55. return commitWrite();
  56. }
  57. // -------------------------------------------------------------------
  58. private:
  59. RingBuffer fBuffer;
  60. struct RetAtom {
  61. LV2_Atom atom;
  62. char data[RING_BUFFER_SIZE];
  63. } fRetAtom;
  64. friend class Lv2AtomQueue;
  65. CARLA_PREVENT_HEAP_ALLOCATION
  66. CARLA_DECLARE_NON_COPY_CLASS(Lv2AtomRingBufferControl)
  67. };
  68. // -----------------------------------------------------------------------
  69. class Lv2AtomQueue
  70. {
  71. public:
  72. Lv2AtomQueue()
  73. {
  74. }
  75. void copyDataFromQueue(Lv2AtomQueue& queue)
  76. {
  77. // lock queue
  78. const CarlaMutex::ScopedLocker qsl(queue.fMutex);
  79. {
  80. // copy data from queue
  81. const CarlaMutex::ScopedLocker sl(fMutex);
  82. carla_copyStruct<RingBuffer>(fRingBufferCtrl.fBuffer, queue.fRingBufferCtrl.fBuffer);
  83. }
  84. // reset queque - FIXME? no queue.?
  85. queue.fRingBufferCtrl.clear();
  86. }
  87. void lock() const noexcept
  88. {
  89. fMutex.lock();
  90. }
  91. bool tryLock() const noexcept
  92. {
  93. return fMutex.tryLock();
  94. }
  95. void unlock() const noexcept
  96. {
  97. fMutex.unlock();
  98. }
  99. bool put(const LV2_Atom* const atom, const uint32_t portIndex)
  100. {
  101. CARLA_SAFE_ASSERT_RETURN(atom != nullptr && atom->size > 0, false);
  102. const CarlaMutex::ScopedLocker sl(fMutex);
  103. return fRingBufferCtrl.writeAtom(atom, static_cast<int32_t>(portIndex));
  104. }
  105. bool get(const LV2_Atom** const atom, uint32_t* const portIndex)
  106. {
  107. CARLA_SAFE_ASSERT_RETURN(atom != nullptr && portIndex != nullptr, false);
  108. const CarlaMutex::ScopedLocker sl(fMutex);
  109. if (! fRingBufferCtrl.isDataAvailable())
  110. return false;
  111. if (const LV2_Atom* retAtom = fRingBufferCtrl.readAtom(portIndex))
  112. {
  113. *atom = retAtom;
  114. return true;
  115. }
  116. return false;
  117. }
  118. private:
  119. CarlaMutex fMutex;
  120. Lv2AtomRingBufferControl fRingBufferCtrl;
  121. CARLA_PREVENT_HEAP_ALLOCATION
  122. CARLA_DECLARE_NON_COPY_CLASS(Lv2AtomQueue)
  123. };
  124. // -----------------------------------------------------------------------
  125. #endif // LV2_ATOM_QUEUE_HPP_INCLUDED