base.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include "config.h"
  2. #include "base.h"
  3. #include <algorithm>
  4. #include <array>
  5. #include <atomic>
  6. #include "core/devformat.h"
  7. namespace al {
  8. backend_exception::backend_exception(backend_error code, const char *msg, ...) : mErrorCode{code}
  9. {
  10. /* NOLINTBEGIN(*-array-to-pointer-decay) */
  11. std::va_list args;
  12. va_start(args, msg);
  13. setMessage(msg, args);
  14. va_end(args);
  15. /* NOLINTEND(*-array-to-pointer-decay) */
  16. }
  17. backend_exception::~backend_exception() = default;
  18. } // namespace al
  19. bool BackendBase::reset()
  20. { throw al::backend_exception{al::backend_error::DeviceError, "Invalid BackendBase call"}; }
  21. void BackendBase::captureSamples(std::byte*, uint)
  22. { }
  23. uint BackendBase::availableSamples()
  24. { return 0; }
  25. ClockLatency BackendBase::getClockLatency()
  26. {
  27. ClockLatency ret{};
  28. uint refcount;
  29. do {
  30. refcount = mDevice->waitForMix();
  31. ret.ClockTime = mDevice->getClockTime();
  32. std::atomic_thread_fence(std::memory_order_acquire);
  33. } while(refcount != mDevice->mMixCount.load(std::memory_order_relaxed));
  34. /* NOTE: The device will generally have about all but one periods filled at
  35. * any given time during playback. Without a more accurate measurement from
  36. * the output, this is an okay approximation.
  37. */
  38. ret.Latency = std::chrono::seconds{mDevice->BufferSize - mDevice->UpdateSize};
  39. ret.Latency /= mDevice->Frequency;
  40. return ret;
  41. }
  42. void BackendBase::setDefaultWFXChannelOrder() const
  43. {
  44. mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
  45. switch(mDevice->FmtChans)
  46. {
  47. case DevFmtMono:
  48. mDevice->RealOut.ChannelIndex[FrontCenter] = 0;
  49. break;
  50. case DevFmtStereo:
  51. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  52. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  53. break;
  54. case DevFmtQuad:
  55. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  56. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  57. mDevice->RealOut.ChannelIndex[BackLeft] = 2;
  58. mDevice->RealOut.ChannelIndex[BackRight] = 3;
  59. break;
  60. case DevFmtX51:
  61. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  62. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  63. mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
  64. mDevice->RealOut.ChannelIndex[LFE] = 3;
  65. mDevice->RealOut.ChannelIndex[SideLeft] = 4;
  66. mDevice->RealOut.ChannelIndex[SideRight] = 5;
  67. break;
  68. case DevFmtX61:
  69. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  70. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  71. mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
  72. mDevice->RealOut.ChannelIndex[LFE] = 3;
  73. mDevice->RealOut.ChannelIndex[BackCenter] = 4;
  74. mDevice->RealOut.ChannelIndex[SideLeft] = 5;
  75. mDevice->RealOut.ChannelIndex[SideRight] = 6;
  76. break;
  77. case DevFmtX71:
  78. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  79. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  80. mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
  81. mDevice->RealOut.ChannelIndex[LFE] = 3;
  82. mDevice->RealOut.ChannelIndex[BackLeft] = 4;
  83. mDevice->RealOut.ChannelIndex[BackRight] = 5;
  84. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  85. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  86. break;
  87. case DevFmtX714:
  88. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  89. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  90. mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
  91. mDevice->RealOut.ChannelIndex[LFE] = 3;
  92. mDevice->RealOut.ChannelIndex[BackLeft] = 4;
  93. mDevice->RealOut.ChannelIndex[BackRight] = 5;
  94. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  95. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  96. mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
  97. mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
  98. mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
  99. mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
  100. break;
  101. case DevFmtX7144:
  102. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  103. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  104. mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
  105. mDevice->RealOut.ChannelIndex[LFE] = 3;
  106. mDevice->RealOut.ChannelIndex[BackLeft] = 4;
  107. mDevice->RealOut.ChannelIndex[BackRight] = 5;
  108. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  109. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  110. mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
  111. mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
  112. mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
  113. mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
  114. mDevice->RealOut.ChannelIndex[BottomFrontLeft] = 12;
  115. mDevice->RealOut.ChannelIndex[BottomFrontRight] = 13;
  116. mDevice->RealOut.ChannelIndex[BottomBackLeft] = 14;
  117. mDevice->RealOut.ChannelIndex[BottomBackRight] = 15;
  118. break;
  119. case DevFmtX3D71:
  120. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  121. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  122. mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
  123. mDevice->RealOut.ChannelIndex[LFE] = 3;
  124. mDevice->RealOut.ChannelIndex[Aux0] = 4;
  125. mDevice->RealOut.ChannelIndex[Aux1] = 5;
  126. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  127. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  128. break;
  129. case DevFmtAmbi3D:
  130. break;
  131. }
  132. }
  133. void BackendBase::setDefaultChannelOrder() const
  134. {
  135. mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
  136. switch(mDevice->FmtChans)
  137. {
  138. case DevFmtX51:
  139. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  140. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  141. mDevice->RealOut.ChannelIndex[SideLeft] = 2;
  142. mDevice->RealOut.ChannelIndex[SideRight] = 3;
  143. mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
  144. mDevice->RealOut.ChannelIndex[LFE] = 5;
  145. return;
  146. case DevFmtX71:
  147. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  148. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  149. mDevice->RealOut.ChannelIndex[BackLeft] = 2;
  150. mDevice->RealOut.ChannelIndex[BackRight] = 3;
  151. mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
  152. mDevice->RealOut.ChannelIndex[LFE] = 5;
  153. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  154. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  155. return;
  156. case DevFmtX714:
  157. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  158. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  159. mDevice->RealOut.ChannelIndex[BackLeft] = 2;
  160. mDevice->RealOut.ChannelIndex[BackRight] = 3;
  161. mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
  162. mDevice->RealOut.ChannelIndex[LFE] = 5;
  163. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  164. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  165. mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
  166. mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
  167. mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
  168. mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
  169. break;
  170. case DevFmtX7144:
  171. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  172. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  173. mDevice->RealOut.ChannelIndex[BackLeft] = 2;
  174. mDevice->RealOut.ChannelIndex[BackRight] = 3;
  175. mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
  176. mDevice->RealOut.ChannelIndex[LFE] = 5;
  177. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  178. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  179. mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
  180. mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
  181. mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
  182. mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
  183. mDevice->RealOut.ChannelIndex[BottomFrontLeft] = 12;
  184. mDevice->RealOut.ChannelIndex[BottomFrontRight] = 13;
  185. mDevice->RealOut.ChannelIndex[BottomBackLeft] = 14;
  186. mDevice->RealOut.ChannelIndex[BottomBackRight] = 15;
  187. break;
  188. case DevFmtX3D71:
  189. mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
  190. mDevice->RealOut.ChannelIndex[FrontRight] = 1;
  191. mDevice->RealOut.ChannelIndex[Aux0] = 2;
  192. mDevice->RealOut.ChannelIndex[Aux1] = 3;
  193. mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
  194. mDevice->RealOut.ChannelIndex[LFE] = 5;
  195. mDevice->RealOut.ChannelIndex[SideLeft] = 6;
  196. mDevice->RealOut.ChannelIndex[SideRight] = 7;
  197. return;
  198. /* Same as WFX order */
  199. case DevFmtMono:
  200. case DevFmtStereo:
  201. case DevFmtQuad:
  202. case DevFmtX61:
  203. case DevFmtAmbi3D:
  204. setDefaultWFXChannelOrder();
  205. break;
  206. }
  207. }