pulseaudio.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 2009 by Konstantinos Natsakis <[email protected]>
  4. * Copyright (C) 2010 by Chris Robinson <[email protected]>
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Library General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library 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 GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public
  16. * License along with this library; if not, write to the
  17. * Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. * Or go to http://www.gnu.org/copyleft/lgpl.html
  20. */
  21. #include "config.h"
  22. #include "pulseaudio.h"
  23. #include <algorithm>
  24. #include <array>
  25. #include <atomic>
  26. #include <bitset>
  27. #include <chrono>
  28. #include <cmath>
  29. #include <cstddef>
  30. #include <cstdint>
  31. #include <cstring>
  32. #include <exception>
  33. #include <limits>
  34. #include <mutex>
  35. #include <optional>
  36. #include <string>
  37. #include <string_view>
  38. #include <sys/types.h>
  39. #include <utility>
  40. #include <vector>
  41. #include "alc/alconfig.h"
  42. #include "alspan.h"
  43. #include "alstring.h"
  44. #include "base.h"
  45. #include "core/devformat.h"
  46. #include "core/device.h"
  47. #include "core/logging.h"
  48. #include "dynload.h"
  49. #include "opthelpers.h"
  50. #include "strutils.h"
  51. #include <pulse/pulseaudio.h>
  52. namespace {
  53. using uint = unsigned int;
  54. #ifdef HAVE_DYNLOAD
  55. #define PULSE_FUNCS(MAGIC) \
  56. MAGIC(pa_context_new); \
  57. MAGIC(pa_context_unref); \
  58. MAGIC(pa_context_get_state); \
  59. MAGIC(pa_context_disconnect); \
  60. MAGIC(pa_context_set_state_callback); \
  61. MAGIC(pa_context_set_subscribe_callback); \
  62. MAGIC(pa_context_subscribe); \
  63. MAGIC(pa_context_errno); \
  64. MAGIC(pa_context_connect); \
  65. MAGIC(pa_context_get_server_info); \
  66. MAGIC(pa_context_get_sink_info_by_name); \
  67. MAGIC(pa_context_get_sink_info_list); \
  68. MAGIC(pa_context_get_source_info_by_name); \
  69. MAGIC(pa_context_get_source_info_list); \
  70. MAGIC(pa_stream_new); \
  71. MAGIC(pa_stream_unref); \
  72. MAGIC(pa_stream_drop); \
  73. MAGIC(pa_stream_get_state); \
  74. MAGIC(pa_stream_peek); \
  75. MAGIC(pa_stream_write); \
  76. MAGIC(pa_stream_connect_record); \
  77. MAGIC(pa_stream_connect_playback); \
  78. MAGIC(pa_stream_readable_size); \
  79. MAGIC(pa_stream_writable_size); \
  80. MAGIC(pa_stream_is_corked); \
  81. MAGIC(pa_stream_cork); \
  82. MAGIC(pa_stream_is_suspended); \
  83. MAGIC(pa_stream_get_device_name); \
  84. MAGIC(pa_stream_get_latency); \
  85. MAGIC(pa_stream_set_write_callback); \
  86. MAGIC(pa_stream_set_buffer_attr); \
  87. MAGIC(pa_stream_get_buffer_attr); \
  88. MAGIC(pa_stream_get_sample_spec); \
  89. MAGIC(pa_stream_get_time); \
  90. MAGIC(pa_stream_set_read_callback); \
  91. MAGIC(pa_stream_set_state_callback); \
  92. MAGIC(pa_stream_set_moved_callback); \
  93. MAGIC(pa_stream_set_underflow_callback); \
  94. MAGIC(pa_stream_new_with_proplist); \
  95. MAGIC(pa_stream_disconnect); \
  96. MAGIC(pa_stream_set_buffer_attr_callback); \
  97. MAGIC(pa_stream_begin_write); \
  98. MAGIC(pa_threaded_mainloop_free); \
  99. MAGIC(pa_threaded_mainloop_get_api); \
  100. MAGIC(pa_threaded_mainloop_lock); \
  101. MAGIC(pa_threaded_mainloop_new); \
  102. MAGIC(pa_threaded_mainloop_signal); \
  103. MAGIC(pa_threaded_mainloop_start); \
  104. MAGIC(pa_threaded_mainloop_stop); \
  105. MAGIC(pa_threaded_mainloop_unlock); \
  106. MAGIC(pa_threaded_mainloop_wait); \
  107. MAGIC(pa_channel_map_init_auto); \
  108. MAGIC(pa_channel_map_parse); \
  109. MAGIC(pa_channel_map_snprint); \
  110. MAGIC(pa_channel_map_equal); \
  111. MAGIC(pa_channel_map_superset); \
  112. MAGIC(pa_channel_position_to_string); \
  113. MAGIC(pa_operation_get_state); \
  114. MAGIC(pa_operation_unref); \
  115. MAGIC(pa_sample_spec_valid); \
  116. MAGIC(pa_frame_size); \
  117. MAGIC(pa_strerror); \
  118. MAGIC(pa_path_get_filename); \
  119. MAGIC(pa_get_binary_name); \
  120. MAGIC(pa_xmalloc); \
  121. MAGIC(pa_xfree);
  122. void *pulse_handle;
  123. #define MAKE_FUNC(x) decltype(x) * p##x
  124. PULSE_FUNCS(MAKE_FUNC)
  125. #undef MAKE_FUNC
  126. #ifndef IN_IDE_PARSER
  127. #define pa_context_new ppa_context_new
  128. #define pa_context_unref ppa_context_unref
  129. #define pa_context_get_state ppa_context_get_state
  130. #define pa_context_disconnect ppa_context_disconnect
  131. #define pa_context_set_state_callback ppa_context_set_state_callback
  132. #define pa_context_set_subscribe_callback ppa_context_set_subscribe_callback
  133. #define pa_context_subscribe ppa_context_subscribe
  134. #define pa_context_errno ppa_context_errno
  135. #define pa_context_connect ppa_context_connect
  136. #define pa_context_get_server_info ppa_context_get_server_info
  137. #define pa_context_get_sink_info_by_name ppa_context_get_sink_info_by_name
  138. #define pa_context_get_sink_info_list ppa_context_get_sink_info_list
  139. #define pa_context_get_source_info_by_name ppa_context_get_source_info_by_name
  140. #define pa_context_get_source_info_list ppa_context_get_source_info_list
  141. #define pa_stream_new ppa_stream_new
  142. #define pa_stream_unref ppa_stream_unref
  143. #define pa_stream_disconnect ppa_stream_disconnect
  144. #define pa_stream_drop ppa_stream_drop
  145. #define pa_stream_set_write_callback ppa_stream_set_write_callback
  146. #define pa_stream_set_buffer_attr ppa_stream_set_buffer_attr
  147. #define pa_stream_get_buffer_attr ppa_stream_get_buffer_attr
  148. #define pa_stream_get_sample_spec ppa_stream_get_sample_spec
  149. #define pa_stream_get_time ppa_stream_get_time
  150. #define pa_stream_set_read_callback ppa_stream_set_read_callback
  151. #define pa_stream_set_state_callback ppa_stream_set_state_callback
  152. #define pa_stream_set_moved_callback ppa_stream_set_moved_callback
  153. #define pa_stream_set_underflow_callback ppa_stream_set_underflow_callback
  154. #define pa_stream_connect_record ppa_stream_connect_record
  155. #define pa_stream_connect_playback ppa_stream_connect_playback
  156. #define pa_stream_readable_size ppa_stream_readable_size
  157. #define pa_stream_writable_size ppa_stream_writable_size
  158. #define pa_stream_is_corked ppa_stream_is_corked
  159. #define pa_stream_cork ppa_stream_cork
  160. #define pa_stream_is_suspended ppa_stream_is_suspended
  161. #define pa_stream_get_device_name ppa_stream_get_device_name
  162. #define pa_stream_get_latency ppa_stream_get_latency
  163. #define pa_stream_set_buffer_attr_callback ppa_stream_set_buffer_attr_callback
  164. #define pa_stream_begin_write ppa_stream_begin_write
  165. #define pa_threaded_mainloop_free ppa_threaded_mainloop_free
  166. #define pa_threaded_mainloop_get_api ppa_threaded_mainloop_get_api
  167. #define pa_threaded_mainloop_lock ppa_threaded_mainloop_lock
  168. #define pa_threaded_mainloop_new ppa_threaded_mainloop_new
  169. #define pa_threaded_mainloop_signal ppa_threaded_mainloop_signal
  170. #define pa_threaded_mainloop_start ppa_threaded_mainloop_start
  171. #define pa_threaded_mainloop_stop ppa_threaded_mainloop_stop
  172. #define pa_threaded_mainloop_unlock ppa_threaded_mainloop_unlock
  173. #define pa_threaded_mainloop_wait ppa_threaded_mainloop_wait
  174. #define pa_channel_map_init_auto ppa_channel_map_init_auto
  175. #define pa_channel_map_parse ppa_channel_map_parse
  176. #define pa_channel_map_snprint ppa_channel_map_snprint
  177. #define pa_channel_map_equal ppa_channel_map_equal
  178. #define pa_channel_map_superset ppa_channel_map_superset
  179. #define pa_channel_position_to_string ppa_channel_position_to_string
  180. #define pa_operation_get_state ppa_operation_get_state
  181. #define pa_operation_unref ppa_operation_unref
  182. #define pa_sample_spec_valid ppa_sample_spec_valid
  183. #define pa_frame_size ppa_frame_size
  184. #define pa_strerror ppa_strerror
  185. #define pa_stream_get_state ppa_stream_get_state
  186. #define pa_stream_peek ppa_stream_peek
  187. #define pa_stream_write ppa_stream_write
  188. #define pa_xfree ppa_xfree
  189. #define pa_path_get_filename ppa_path_get_filename
  190. #define pa_get_binary_name ppa_get_binary_name
  191. #define pa_xmalloc ppa_xmalloc
  192. #endif /* IN_IDE_PARSER */
  193. #endif
  194. constexpr pa_channel_map MonoChanMap{
  195. 1, {PA_CHANNEL_POSITION_MONO}
  196. }, StereoChanMap{
  197. 2, {PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT}
  198. }, QuadChanMap{
  199. 4, {
  200. PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
  201. PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT
  202. }
  203. }, X51ChanMap{
  204. 6, {
  205. PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
  206. PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
  207. PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT
  208. }
  209. }, X51RearChanMap{
  210. 6, {
  211. PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
  212. PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
  213. PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT
  214. }
  215. }, X61ChanMap{
  216. 7, {
  217. PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
  218. PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
  219. PA_CHANNEL_POSITION_REAR_CENTER,
  220. PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT
  221. }
  222. }, X71ChanMap{
  223. 8, {
  224. PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
  225. PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
  226. PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
  227. PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT
  228. }
  229. }, X714ChanMap{
  230. 12, {
  231. PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
  232. PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
  233. PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
  234. PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT,
  235. PA_CHANNEL_POSITION_TOP_FRONT_LEFT, PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,
  236. PA_CHANNEL_POSITION_TOP_REAR_LEFT, PA_CHANNEL_POSITION_TOP_REAR_RIGHT
  237. }
  238. };
  239. /* *grumble* Don't use enums for bitflags. */
  240. constexpr pa_stream_flags_t operator|(pa_stream_flags_t lhs, pa_stream_flags_t rhs)
  241. { return pa_stream_flags_t(lhs | al::to_underlying(rhs)); }
  242. constexpr pa_stream_flags_t& operator|=(pa_stream_flags_t &lhs, pa_stream_flags_t rhs)
  243. {
  244. lhs = lhs | rhs;
  245. return lhs;
  246. }
  247. constexpr pa_stream_flags_t operator~(pa_stream_flags_t flag)
  248. { return pa_stream_flags_t(~al::to_underlying(flag)); }
  249. constexpr pa_stream_flags_t& operator&=(pa_stream_flags_t &lhs, pa_stream_flags_t rhs)
  250. {
  251. lhs = pa_stream_flags_t(al::to_underlying(lhs) & rhs);
  252. return lhs;
  253. }
  254. constexpr pa_context_flags_t operator|(pa_context_flags_t lhs, pa_context_flags_t rhs)
  255. { return pa_context_flags_t(lhs | al::to_underlying(rhs)); }
  256. constexpr pa_context_flags_t& operator|=(pa_context_flags_t &lhs, pa_context_flags_t rhs)
  257. {
  258. lhs = lhs | rhs;
  259. return lhs;
  260. }
  261. constexpr pa_subscription_mask_t operator|(pa_subscription_mask_t lhs, pa_subscription_mask_t rhs)
  262. { return pa_subscription_mask_t(lhs | al::to_underlying(rhs)); }
  263. struct DevMap {
  264. std::string name;
  265. std::string device_name;
  266. };
  267. bool checkName(const al::span<const DevMap> list, const std::string &name)
  268. {
  269. auto match_name = [&name](const DevMap &entry) -> bool { return entry.name == name; };
  270. return std::find_if(list.cbegin(), list.cend(), match_name) != list.cend();
  271. }
  272. std::vector<DevMap> PlaybackDevices;
  273. std::vector<DevMap> CaptureDevices;
  274. /* Global flags and properties */
  275. pa_context_flags_t pulse_ctx_flags;
  276. class PulseMainloop {
  277. pa_threaded_mainloop *mLoop{};
  278. pa_context *mContext{};
  279. public:
  280. PulseMainloop() = default;
  281. PulseMainloop(const PulseMainloop&) = delete;
  282. PulseMainloop(PulseMainloop&& rhs) noexcept : mLoop{rhs.mLoop} { rhs.mLoop = nullptr; }
  283. explicit PulseMainloop(pa_threaded_mainloop *loop) noexcept : mLoop{loop} { }
  284. ~PulseMainloop();
  285. PulseMainloop& operator=(const PulseMainloop&) = delete;
  286. PulseMainloop& operator=(PulseMainloop&& rhs) noexcept
  287. { std::swap(mLoop, rhs.mLoop); return *this; }
  288. PulseMainloop& operator=(std::nullptr_t) noexcept
  289. {
  290. if(mLoop)
  291. pa_threaded_mainloop_free(mLoop);
  292. mLoop = nullptr;
  293. return *this;
  294. }
  295. explicit operator bool() const noexcept { return mLoop != nullptr; }
  296. [[nodiscard]]
  297. auto start() const { return pa_threaded_mainloop_start(mLoop); }
  298. auto stop() const { return pa_threaded_mainloop_stop(mLoop); }
  299. [[nodiscard]] auto getApi() const { return pa_threaded_mainloop_get_api(mLoop); }
  300. [[nodiscard]] auto getContext() const noexcept { return mContext; }
  301. auto lock() const { return pa_threaded_mainloop_lock(mLoop); }
  302. auto unlock() const { return pa_threaded_mainloop_unlock(mLoop); }
  303. auto signal(bool wait=false) const { return pa_threaded_mainloop_signal(mLoop, wait); }
  304. static auto Create() { return PulseMainloop{pa_threaded_mainloop_new()}; }
  305. void streamSuccessCallback(pa_stream*, int) const noexcept { signal(); }
  306. static void streamSuccessCallbackC(pa_stream *stream, int success, void *pdata) noexcept
  307. { static_cast<PulseMainloop*>(pdata)->streamSuccessCallback(stream, success); }
  308. void close(pa_stream *stream=nullptr);
  309. void deviceSinkCallback(pa_context*, const pa_sink_info *info, int eol) const noexcept
  310. {
  311. if(eol)
  312. {
  313. signal();
  314. return;
  315. }
  316. /* Skip this device is if it's already in the list. */
  317. auto match_devname = [info](const DevMap &entry) -> bool
  318. { return entry.device_name == info->name; };
  319. if(std::find_if(PlaybackDevices.cbegin(), PlaybackDevices.cend(), match_devname) != PlaybackDevices.cend())
  320. return;
  321. /* Make sure the display name (description) is unique. Append a number
  322. * counter as needed.
  323. */
  324. int count{1};
  325. std::string newname{info->description};
  326. while(checkName(PlaybackDevices, newname))
  327. {
  328. newname = info->description;
  329. newname += " #";
  330. newname += std::to_string(++count);
  331. }
  332. PlaybackDevices.emplace_back(DevMap{std::move(newname), info->name});
  333. DevMap &newentry = PlaybackDevices.back();
  334. TRACE("Got device \"%s\", \"%s\"\n", newentry.name.c_str(), newentry.device_name.c_str());
  335. }
  336. void deviceSourceCallback(pa_context*, const pa_source_info *info, int eol) const noexcept
  337. {
  338. if(eol)
  339. {
  340. signal();
  341. return;
  342. }
  343. /* Skip this device is if it's already in the list. */
  344. auto match_devname = [info](const DevMap &entry) -> bool
  345. { return entry.device_name == info->name; };
  346. if(std::find_if(CaptureDevices.cbegin(), CaptureDevices.cend(), match_devname) != CaptureDevices.cend())
  347. return;
  348. /* Make sure the display name (description) is unique. Append a number
  349. * counter as needed.
  350. */
  351. int count{1};
  352. std::string newname{info->description};
  353. while(checkName(CaptureDevices, newname))
  354. {
  355. newname = info->description;
  356. newname += " #";
  357. newname += std::to_string(++count);
  358. }
  359. CaptureDevices.emplace_back(DevMap{std::move(newname), info->name});
  360. DevMap &newentry = CaptureDevices.back();
  361. TRACE("Got device \"%s\", \"%s\"\n", newentry.name.c_str(), newentry.device_name.c_str());
  362. }
  363. void probePlaybackDevices();
  364. void probeCaptureDevices();
  365. friend struct MainloopUniqueLock;
  366. };
  367. struct MainloopUniqueLock : public std::unique_lock<PulseMainloop> {
  368. using std::unique_lock<PulseMainloop>::unique_lock;
  369. MainloopUniqueLock& operator=(MainloopUniqueLock&&) = default;
  370. auto wait() const -> void
  371. { pa_threaded_mainloop_wait(mutex()->mLoop); }
  372. template<typename Predicate>
  373. auto wait(Predicate done_waiting) const -> void
  374. { while(!done_waiting()) wait(); }
  375. void waitForOperation(pa_operation *op) const
  376. {
  377. if(op)
  378. {
  379. wait([op]{ return pa_operation_get_state(op) != PA_OPERATION_RUNNING; });
  380. pa_operation_unref(op);
  381. }
  382. }
  383. void setEventHandler()
  384. {
  385. pa_operation *op{pa_context_subscribe(mutex()->mContext,
  386. PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE,
  387. [](pa_context*, int, void *pdata) noexcept
  388. { static_cast<PulseMainloop*>(pdata)->signal(); },
  389. mutex())};
  390. waitForOperation(op);
  391. /* Watch for device added/removed events.
  392. *
  393. * TODO: Also track the "default" device, in as much as PulseAudio has
  394. * the concept of a default device (whatever device is opened when not
  395. * specifying a specific sink or source name). There doesn't seem to be
  396. * an event for this.
  397. */
  398. auto handler = [](pa_context*, pa_subscription_event_type_t t, uint32_t, void*) noexcept
  399. {
  400. const auto eventFacility = (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK);
  401. if(eventFacility == PA_SUBSCRIPTION_EVENT_SINK
  402. || eventFacility == PA_SUBSCRIPTION_EVENT_SOURCE)
  403. {
  404. const auto deviceType = (eventFacility == PA_SUBSCRIPTION_EVENT_SINK)
  405. ? alc::DeviceType::Playback : alc::DeviceType::Capture;
  406. const auto eventType = (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK);
  407. if(eventType == PA_SUBSCRIPTION_EVENT_NEW)
  408. alc::Event(alc::EventType::DeviceAdded, deviceType, "Device added");
  409. else if(eventType == PA_SUBSCRIPTION_EVENT_REMOVE)
  410. alc::Event(alc::EventType::DeviceRemoved, deviceType, "Device removed");
  411. }
  412. };
  413. pa_context_set_subscribe_callback(mutex()->mContext, handler, nullptr);
  414. }
  415. void contextStateCallback(pa_context *context) noexcept
  416. {
  417. pa_context_state_t state{pa_context_get_state(context)};
  418. if(state == PA_CONTEXT_READY || !PA_CONTEXT_IS_GOOD(state))
  419. mutex()->signal();
  420. }
  421. void streamStateCallback(pa_stream *stream) noexcept
  422. {
  423. pa_stream_state_t state{pa_stream_get_state(stream)};
  424. if(state == PA_STREAM_READY || !PA_STREAM_IS_GOOD(state))
  425. mutex()->signal();
  426. }
  427. void connectContext();
  428. pa_stream *connectStream(const char *device_name, pa_stream_flags_t flags,
  429. pa_buffer_attr *attr, pa_sample_spec *spec, pa_channel_map *chanmap, BackendType type);
  430. };
  431. using MainloopLockGuard = std::lock_guard<PulseMainloop>;
  432. PulseMainloop::~PulseMainloop()
  433. {
  434. if(mContext)
  435. {
  436. MainloopUniqueLock looplock{*this};
  437. pa_context_disconnect(mContext);
  438. pa_context_unref(mContext);
  439. }
  440. if(mLoop)
  441. pa_threaded_mainloop_free(mLoop);
  442. }
  443. void MainloopUniqueLock::connectContext()
  444. {
  445. if(mutex()->mContext)
  446. return;
  447. mutex()->mContext = pa_context_new(mutex()->getApi(), nullptr);
  448. if(!mutex()->mContext) throw al::backend_exception{al::backend_error::OutOfMemory,
  449. "pa_context_new() failed"};
  450. pa_context_set_state_callback(mutex()->mContext, [](pa_context *ctx, void *pdata) noexcept
  451. { return static_cast<MainloopUniqueLock*>(pdata)->contextStateCallback(ctx); }, this);
  452. int err{pa_context_connect(mutex()->mContext, nullptr, pulse_ctx_flags, nullptr)};
  453. if(err >= 0)
  454. {
  455. wait([&err,this]()
  456. {
  457. pa_context_state_t state{pa_context_get_state(mutex()->mContext)};
  458. if(!PA_CONTEXT_IS_GOOD(state))
  459. {
  460. err = pa_context_errno(mutex()->mContext);
  461. if(err > 0) err = -err;
  462. return true;
  463. }
  464. return state == PA_CONTEXT_READY;
  465. });
  466. }
  467. pa_context_set_state_callback(mutex()->mContext, nullptr, nullptr);
  468. if(err < 0)
  469. {
  470. pa_context_unref(mutex()->mContext);
  471. mutex()->mContext = nullptr;
  472. throw al::backend_exception{al::backend_error::DeviceError, "Context did not connect (%s)",
  473. pa_strerror(err)};
  474. }
  475. }
  476. pa_stream *MainloopUniqueLock::connectStream(const char *device_name, pa_stream_flags_t flags,
  477. pa_buffer_attr *attr, pa_sample_spec *spec, pa_channel_map *chanmap, BackendType type)
  478. {
  479. const char *stream_id{(type==BackendType::Playback) ? "Playback Stream" : "Capture Stream"};
  480. pa_stream *stream{pa_stream_new(mutex()->mContext, stream_id, spec, chanmap)};
  481. if(!stream)
  482. throw al::backend_exception{al::backend_error::OutOfMemory, "pa_stream_new() failed (%s)",
  483. pa_strerror(pa_context_errno(mutex()->mContext))};
  484. pa_stream_set_state_callback(stream, [](pa_stream *strm, void *pdata) noexcept
  485. { return static_cast<MainloopUniqueLock*>(pdata)->streamStateCallback(strm); }, this);
  486. int err{(type==BackendType::Playback) ?
  487. pa_stream_connect_playback(stream, device_name, attr, flags, nullptr, nullptr) :
  488. pa_stream_connect_record(stream, device_name, attr, flags)};
  489. if(err < 0)
  490. {
  491. pa_stream_unref(stream);
  492. throw al::backend_exception{al::backend_error::DeviceError, "%s did not connect (%s)",
  493. stream_id, pa_strerror(err)};
  494. }
  495. wait([&err,stream,stream_id,this]()
  496. {
  497. pa_stream_state_t state{pa_stream_get_state(stream)};
  498. if(!PA_STREAM_IS_GOOD(state))
  499. {
  500. err = pa_context_errno(mutex()->mContext);
  501. pa_stream_unref(stream);
  502. throw al::backend_exception{al::backend_error::DeviceError,
  503. "%s did not get ready (%s)", stream_id, pa_strerror(err)};
  504. }
  505. return state == PA_STREAM_READY;
  506. });
  507. pa_stream_set_state_callback(stream, nullptr, nullptr);
  508. return stream;
  509. }
  510. void PulseMainloop::close(pa_stream *stream)
  511. {
  512. if(!stream)
  513. return;
  514. MainloopUniqueLock looplock{*this};
  515. pa_stream_set_state_callback(stream, nullptr, nullptr);
  516. pa_stream_set_moved_callback(stream, nullptr, nullptr);
  517. pa_stream_set_write_callback(stream, nullptr, nullptr);
  518. pa_stream_set_buffer_attr_callback(stream, nullptr, nullptr);
  519. pa_stream_disconnect(stream);
  520. pa_stream_unref(stream);
  521. }
  522. void PulseMainloop::probePlaybackDevices()
  523. {
  524. PlaybackDevices.clear();
  525. try {
  526. MainloopUniqueLock plock{*this};
  527. plock.connectContext();
  528. auto sink_callback = [](pa_context *ctx, const pa_sink_info *info, int eol, void *pdata) noexcept
  529. { return static_cast<PulseMainloop*>(pdata)->deviceSinkCallback(ctx, info, eol); };
  530. pa_operation *op{pa_context_get_sink_info_by_name(mContext, nullptr, sink_callback, this)};
  531. plock.waitForOperation(op);
  532. op = pa_context_get_sink_info_list(mContext, sink_callback, this);
  533. plock.waitForOperation(op);
  534. }
  535. catch(std::exception &e) {
  536. ERR("Error enumerating devices: %s\n", e.what());
  537. }
  538. }
  539. void PulseMainloop::probeCaptureDevices()
  540. {
  541. CaptureDevices.clear();
  542. try {
  543. MainloopUniqueLock plock{*this};
  544. plock.connectContext();
  545. auto src_callback = [](pa_context *ctx, const pa_source_info *info, int eol, void *pdata) noexcept
  546. { return static_cast<PulseMainloop*>(pdata)->deviceSourceCallback(ctx, info, eol); };
  547. pa_operation *op{pa_context_get_source_info_by_name(mContext, nullptr, src_callback,
  548. this)};
  549. plock.waitForOperation(op);
  550. op = pa_context_get_source_info_list(mContext, src_callback, this);
  551. plock.waitForOperation(op);
  552. }
  553. catch(std::exception &e) {
  554. ERR("Error enumerating devices: %s\n", e.what());
  555. }
  556. }
  557. /* Used for initial connection test and enumeration. */
  558. PulseMainloop gGlobalMainloop;
  559. struct PulsePlayback final : public BackendBase {
  560. PulsePlayback(DeviceBase *device) noexcept : BackendBase{device} { }
  561. ~PulsePlayback() override;
  562. void bufferAttrCallback(pa_stream *stream) noexcept;
  563. void streamStateCallback(pa_stream *stream) noexcept;
  564. void streamWriteCallback(pa_stream *stream, size_t nbytes) noexcept;
  565. void sinkInfoCallback(pa_context *context, const pa_sink_info *info, int eol) noexcept;
  566. void sinkNameCallback(pa_context *context, const pa_sink_info *info, int eol) noexcept;
  567. void streamMovedCallback(pa_stream *stream) noexcept;
  568. void open(std::string_view name) override;
  569. bool reset() override;
  570. void start() override;
  571. void stop() override;
  572. ClockLatency getClockLatency() override;
  573. PulseMainloop mMainloop;
  574. std::optional<std::string> mDeviceName{std::nullopt};
  575. bool mIs51Rear{false};
  576. pa_buffer_attr mAttr{};
  577. pa_sample_spec mSpec{};
  578. pa_stream *mStream{nullptr};
  579. uint mFrameSize{0u};
  580. };
  581. PulsePlayback::~PulsePlayback()
  582. { if(mStream) mMainloop.close(mStream); }
  583. void PulsePlayback::bufferAttrCallback(pa_stream *stream) noexcept
  584. {
  585. /* FIXME: Update the device's UpdateSize (and/or BufferSize) using the new
  586. * buffer attributes? Changing UpdateSize will change the ALC_REFRESH
  587. * property, which probably shouldn't change between device resets. But
  588. * leaving it alone means ALC_REFRESH will be off.
  589. */
  590. mAttr = *(pa_stream_get_buffer_attr(stream));
  591. TRACE("minreq=%d, tlength=%d, prebuf=%d\n", mAttr.minreq, mAttr.tlength, mAttr.prebuf);
  592. }
  593. void PulsePlayback::streamStateCallback(pa_stream *stream) noexcept
  594. {
  595. if(pa_stream_get_state(stream) == PA_STREAM_FAILED)
  596. {
  597. ERR("Received stream failure!\n");
  598. mDevice->handleDisconnect("Playback stream failure");
  599. }
  600. mMainloop.signal();
  601. }
  602. void PulsePlayback::streamWriteCallback(pa_stream *stream, size_t nbytes) noexcept
  603. {
  604. do {
  605. pa_free_cb_t free_func{nullptr};
  606. auto buflen = static_cast<size_t>(-1);
  607. void *buf{};
  608. if(pa_stream_begin_write(stream, &buf, &buflen) || !buf) UNLIKELY
  609. {
  610. buflen = nbytes;
  611. buf = pa_xmalloc(buflen);
  612. free_func = pa_xfree;
  613. }
  614. else
  615. buflen = std::min(buflen, nbytes);
  616. nbytes -= buflen;
  617. mDevice->renderSamples(buf, static_cast<uint>(buflen/mFrameSize), mSpec.channels);
  618. int ret{pa_stream_write(stream, buf, buflen, free_func, 0, PA_SEEK_RELATIVE)};
  619. if(ret != PA_OK) UNLIKELY
  620. ERR("Failed to write to stream: %d, %s\n", ret, pa_strerror(ret));
  621. } while(nbytes > 0);
  622. }
  623. void PulsePlayback::sinkInfoCallback(pa_context*, const pa_sink_info *info, int eol) noexcept
  624. {
  625. struct ChannelMap {
  626. DevFmtChannels fmt;
  627. pa_channel_map map;
  628. bool is_51rear;
  629. };
  630. static constexpr std::array<ChannelMap,8> chanmaps{{
  631. { DevFmtX714, X714ChanMap, false },
  632. { DevFmtX71, X71ChanMap, false },
  633. { DevFmtX61, X61ChanMap, false },
  634. { DevFmtX51, X51ChanMap, false },
  635. { DevFmtX51, X51RearChanMap, true },
  636. { DevFmtQuad, QuadChanMap, false },
  637. { DevFmtStereo, StereoChanMap, false },
  638. { DevFmtMono, MonoChanMap, false }
  639. }};
  640. if(eol)
  641. {
  642. mMainloop.signal();
  643. return;
  644. }
  645. auto chaniter = std::find_if(chanmaps.cbegin(), chanmaps.cend(),
  646. [info](const ChannelMap &chanmap) -> bool
  647. { return pa_channel_map_superset(&info->channel_map, &chanmap.map); }
  648. );
  649. if(chaniter != chanmaps.cend())
  650. {
  651. if(!mDevice->Flags.test(ChannelsRequest))
  652. mDevice->FmtChans = chaniter->fmt;
  653. mIs51Rear = chaniter->is_51rear;
  654. }
  655. else
  656. {
  657. mIs51Rear = false;
  658. std::array<char,PA_CHANNEL_MAP_SNPRINT_MAX> chanmap_str{};
  659. pa_channel_map_snprint(chanmap_str.data(), chanmap_str.size(), &info->channel_map);
  660. WARN("Failed to find format for channel map:\n %s\n", chanmap_str.data());
  661. }
  662. if(info->active_port)
  663. TRACE("Active port: %s (%s)\n", info->active_port->name, info->active_port->description);
  664. mDevice->Flags.set(DirectEar, (info->active_port
  665. && strcmp(info->active_port->name, "analog-output-headphones") == 0));
  666. }
  667. void PulsePlayback::sinkNameCallback(pa_context*, const pa_sink_info *info, int eol) noexcept
  668. {
  669. if(eol)
  670. {
  671. mMainloop.signal();
  672. return;
  673. }
  674. mDevice->DeviceName = info->description;
  675. }
  676. void PulsePlayback::streamMovedCallback(pa_stream *stream) noexcept
  677. {
  678. mDeviceName = pa_stream_get_device_name(stream);
  679. TRACE("Stream moved to %s\n", mDeviceName->c_str());
  680. }
  681. void PulsePlayback::open(std::string_view name)
  682. {
  683. mMainloop = PulseMainloop::Create();
  684. if(mMainloop.start() != 0)
  685. throw al::backend_exception{al::backend_error::DeviceError,
  686. "Failed to start device mainloop"};
  687. const char *pulse_name{nullptr};
  688. std::string_view display_name;
  689. if(!name.empty())
  690. {
  691. if(PlaybackDevices.empty())
  692. mMainloop.probePlaybackDevices();
  693. auto match_name = [name](const DevMap &entry) -> bool
  694. { return entry.name == name || entry.device_name == name; };
  695. auto iter = std::find_if(PlaybackDevices.cbegin(), PlaybackDevices.cend(), match_name);
  696. if(iter == PlaybackDevices.cend())
  697. throw al::backend_exception{al::backend_error::NoDevice,
  698. "Device name \"%.*s\" not found", al::sizei(name), name.data()};
  699. pulse_name = iter->device_name.c_str();
  700. display_name = iter->name;
  701. }
  702. MainloopUniqueLock plock{mMainloop};
  703. plock.connectContext();
  704. pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
  705. PA_STREAM_FIX_CHANNELS};
  706. if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
  707. flags |= PA_STREAM_DONT_MOVE;
  708. pa_sample_spec spec{};
  709. spec.format = PA_SAMPLE_S16NE;
  710. spec.rate = 44100;
  711. spec.channels = 2;
  712. if(!pulse_name)
  713. {
  714. static const auto defname = al::getenv("ALSOFT_PULSE_DEFAULT");
  715. if(defname) pulse_name = defname->c_str();
  716. }
  717. TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
  718. mStream = plock.connectStream(pulse_name, flags, nullptr, &spec, nullptr,
  719. BackendType::Playback);
  720. constexpr auto move_callback = [](pa_stream *stream, void *pdata) noexcept
  721. { return static_cast<PulsePlayback*>(pdata)->streamMovedCallback(stream); };
  722. pa_stream_set_moved_callback(mStream, move_callback, this);
  723. mFrameSize = static_cast<uint>(pa_frame_size(pa_stream_get_sample_spec(mStream)));
  724. if(pulse_name) mDeviceName.emplace(pulse_name);
  725. else mDeviceName.reset();
  726. if(display_name.empty())
  727. {
  728. auto name_callback = [](pa_context *context, const pa_sink_info *info, int eol, void *pdata) noexcept
  729. { return static_cast<PulsePlayback*>(pdata)->sinkNameCallback(context, info, eol); };
  730. pa_operation *op{pa_context_get_sink_info_by_name(mMainloop.getContext(),
  731. pa_stream_get_device_name(mStream), name_callback, this)};
  732. plock.waitForOperation(op);
  733. }
  734. else
  735. mDevice->DeviceName = display_name;
  736. }
  737. bool PulsePlayback::reset()
  738. {
  739. MainloopUniqueLock plock{mMainloop};
  740. const auto deviceName = mDeviceName ? mDeviceName->c_str() : nullptr;
  741. if(mStream)
  742. {
  743. pa_stream_set_state_callback(mStream, nullptr, nullptr);
  744. pa_stream_set_moved_callback(mStream, nullptr, nullptr);
  745. pa_stream_set_write_callback(mStream, nullptr, nullptr);
  746. pa_stream_set_buffer_attr_callback(mStream, nullptr, nullptr);
  747. pa_stream_disconnect(mStream);
  748. pa_stream_unref(mStream);
  749. mStream = nullptr;
  750. }
  751. auto info_cb = [](pa_context *context, const pa_sink_info *info, int eol, void *pdata) noexcept
  752. { return static_cast<PulsePlayback*>(pdata)->sinkInfoCallback(context, info, eol); };
  753. pa_operation *op{pa_context_get_sink_info_by_name(mMainloop.getContext(), deviceName, info_cb,
  754. this)};
  755. plock.waitForOperation(op);
  756. pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING |
  757. PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_EARLY_REQUESTS};
  758. if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
  759. flags |= PA_STREAM_DONT_MOVE;
  760. if(GetConfigValueBool(mDevice->DeviceName, "pulse", "adjust-latency", false))
  761. {
  762. /* ADJUST_LATENCY can't be specified with EARLY_REQUESTS, for some
  763. * reason. So if the user wants to adjust the overall device latency,
  764. * we can't ask to get write signals as soon as minreq is reached.
  765. */
  766. flags &= ~PA_STREAM_EARLY_REQUESTS;
  767. flags |= PA_STREAM_ADJUST_LATENCY;
  768. }
  769. if(GetConfigValueBool(mDevice->DeviceName, "pulse", "fix-rate", false)
  770. || !mDevice->Flags.test(FrequencyRequest))
  771. flags |= PA_STREAM_FIX_RATE;
  772. pa_channel_map chanmap{};
  773. switch(mDevice->FmtChans)
  774. {
  775. case DevFmtMono:
  776. chanmap = MonoChanMap;
  777. break;
  778. case DevFmtAmbi3D:
  779. mDevice->FmtChans = DevFmtStereo;
  780. /*fall-through*/
  781. case DevFmtStereo:
  782. chanmap = StereoChanMap;
  783. break;
  784. case DevFmtQuad:
  785. chanmap = QuadChanMap;
  786. break;
  787. case DevFmtX51:
  788. chanmap = (mIs51Rear ? X51RearChanMap : X51ChanMap);
  789. break;
  790. case DevFmtX61:
  791. chanmap = X61ChanMap;
  792. break;
  793. case DevFmtX71:
  794. case DevFmtX3D71:
  795. chanmap = X71ChanMap;
  796. break;
  797. case DevFmtX7144:
  798. mDevice->FmtChans = DevFmtX714;
  799. /*fall-through*/
  800. case DevFmtX714:
  801. chanmap = X714ChanMap;
  802. break;
  803. }
  804. setDefaultWFXChannelOrder();
  805. switch(mDevice->FmtType)
  806. {
  807. case DevFmtByte:
  808. mDevice->FmtType = DevFmtUByte;
  809. /* fall-through */
  810. case DevFmtUByte:
  811. mSpec.format = PA_SAMPLE_U8;
  812. break;
  813. case DevFmtUShort:
  814. mDevice->FmtType = DevFmtShort;
  815. /* fall-through */
  816. case DevFmtShort:
  817. mSpec.format = PA_SAMPLE_S16NE;
  818. break;
  819. case DevFmtUInt:
  820. mDevice->FmtType = DevFmtInt;
  821. /* fall-through */
  822. case DevFmtInt:
  823. mSpec.format = PA_SAMPLE_S32NE;
  824. break;
  825. case DevFmtFloat:
  826. mSpec.format = PA_SAMPLE_FLOAT32NE;
  827. break;
  828. }
  829. mSpec.rate = mDevice->Frequency;
  830. mSpec.channels = static_cast<uint8_t>(mDevice->channelsFromFmt());
  831. if(pa_sample_spec_valid(&mSpec) == 0)
  832. throw al::backend_exception{al::backend_error::DeviceError, "Invalid sample spec"};
  833. const auto frame_size = static_cast<uint>(pa_frame_size(&mSpec));
  834. mAttr.maxlength = ~0u;
  835. mAttr.tlength = mDevice->BufferSize * frame_size;
  836. mAttr.prebuf = 0u;
  837. mAttr.minreq = mDevice->UpdateSize * frame_size;
  838. mAttr.fragsize = ~0u;
  839. mStream = plock.connectStream(deviceName, flags, &mAttr, &mSpec, &chanmap,
  840. BackendType::Playback);
  841. constexpr auto state_callback = [](pa_stream *stream, void *pdata) noexcept
  842. { return static_cast<PulsePlayback*>(pdata)->streamStateCallback(stream); };
  843. pa_stream_set_state_callback(mStream, state_callback, this);
  844. constexpr auto move_callback = [](pa_stream *stream, void *pdata) noexcept
  845. { return static_cast<PulsePlayback*>(pdata)->streamMovedCallback(stream); };
  846. pa_stream_set_moved_callback(mStream, move_callback, this);
  847. mSpec = *(pa_stream_get_sample_spec(mStream));
  848. mFrameSize = static_cast<uint>(pa_frame_size(&mSpec));
  849. if(mDevice->Frequency != mSpec.rate)
  850. {
  851. /* Server updated our playback rate, so modify the buffer attribs
  852. * accordingly.
  853. */
  854. const auto scale = static_cast<double>(mSpec.rate) / mDevice->Frequency;
  855. const auto perlen = std::clamp(std::round(scale*mDevice->UpdateSize), 64.0, 8192.0);
  856. const auto bufmax = uint{std::numeric_limits<int>::max()} / mFrameSize;
  857. const auto buflen = std::clamp(std::round(scale*mDevice->BufferSize), perlen*2.0,
  858. static_cast<double>(bufmax));
  859. mAttr.maxlength = ~0u;
  860. mAttr.tlength = static_cast<uint>(buflen) * mFrameSize;
  861. mAttr.prebuf = 0u;
  862. mAttr.minreq = static_cast<uint>(perlen) * mFrameSize;
  863. op = pa_stream_set_buffer_attr(mStream, &mAttr, &PulseMainloop::streamSuccessCallbackC,
  864. &mMainloop);
  865. plock.waitForOperation(op);
  866. mDevice->Frequency = mSpec.rate;
  867. }
  868. constexpr auto attr_callback = [](pa_stream *stream, void *pdata) noexcept
  869. { return static_cast<PulsePlayback*>(pdata)->bufferAttrCallback(stream); };
  870. pa_stream_set_buffer_attr_callback(mStream, attr_callback, this);
  871. bufferAttrCallback(mStream);
  872. mDevice->BufferSize = mAttr.tlength / mFrameSize;
  873. mDevice->UpdateSize = mAttr.minreq / mFrameSize;
  874. return true;
  875. }
  876. void PulsePlayback::start()
  877. {
  878. MainloopUniqueLock plock{mMainloop};
  879. /* Write some samples to fill the buffer before we start feeding it newly
  880. * mixed samples.
  881. */
  882. if(size_t todo{pa_stream_writable_size(mStream)})
  883. {
  884. void *buf{pa_xmalloc(todo)};
  885. mDevice->renderSamples(buf, static_cast<uint>(todo/mFrameSize), mSpec.channels);
  886. pa_stream_write(mStream, buf, todo, pa_xfree, 0, PA_SEEK_RELATIVE);
  887. }
  888. constexpr auto stream_write = [](pa_stream *stream, size_t nbytes, void *pdata) noexcept
  889. { return static_cast<PulsePlayback*>(pdata)->streamWriteCallback(stream, nbytes); };
  890. pa_stream_set_write_callback(mStream, stream_write, this);
  891. pa_operation *op{pa_stream_cork(mStream, 0, &PulseMainloop::streamSuccessCallbackC,
  892. &mMainloop)};
  893. plock.waitForOperation(op);
  894. }
  895. void PulsePlayback::stop()
  896. {
  897. MainloopUniqueLock plock{mMainloop};
  898. pa_operation *op{pa_stream_cork(mStream, 1, &PulseMainloop::streamSuccessCallbackC,
  899. &mMainloop)};
  900. plock.waitForOperation(op);
  901. pa_stream_set_write_callback(mStream, nullptr, nullptr);
  902. }
  903. ClockLatency PulsePlayback::getClockLatency()
  904. {
  905. ClockLatency ret{};
  906. pa_usec_t latency{};
  907. int neg{}, err{};
  908. {
  909. MainloopUniqueLock plock{mMainloop};
  910. ret.ClockTime = mDevice->getClockTime();
  911. err = pa_stream_get_latency(mStream, &latency, &neg);
  912. }
  913. if(err != 0) UNLIKELY
  914. {
  915. /* If err = -PA_ERR_NODATA, it means we were called too soon after
  916. * starting the stream and no timing info has been received from the
  917. * server yet. Give a generic value since nothing better is available.
  918. */
  919. if(err != -PA_ERR_NODATA)
  920. ERR("Failed to get stream latency: 0x%x\n", err);
  921. latency = mDevice->BufferSize - mDevice->UpdateSize;
  922. neg = 0;
  923. }
  924. else if(neg) UNLIKELY
  925. latency = 0;
  926. ret.Latency = std::chrono::microseconds{latency};
  927. return ret;
  928. }
  929. struct PulseCapture final : public BackendBase {
  930. PulseCapture(DeviceBase *device) noexcept : BackendBase{device} { }
  931. ~PulseCapture() override;
  932. void streamStateCallback(pa_stream *stream) noexcept;
  933. void sourceNameCallback(pa_context *context, const pa_source_info *info, int eol) noexcept;
  934. void streamMovedCallback(pa_stream *stream) noexcept;
  935. void open(std::string_view name) override;
  936. void start() override;
  937. void stop() override;
  938. void captureSamples(std::byte *buffer, uint samples) override;
  939. uint availableSamples() override;
  940. ClockLatency getClockLatency() override;
  941. PulseMainloop mMainloop;
  942. std::optional<std::string> mDeviceName{std::nullopt};
  943. al::span<const std::byte> mCapBuffer;
  944. size_t mHoleLength{0};
  945. size_t mPacketLength{0};
  946. uint mLastReadable{0u};
  947. std::byte mSilentVal{};
  948. pa_buffer_attr mAttr{};
  949. pa_sample_spec mSpec{};
  950. pa_stream *mStream{nullptr};
  951. };
  952. PulseCapture::~PulseCapture()
  953. { if(mStream) mMainloop.close(mStream); }
  954. void PulseCapture::streamStateCallback(pa_stream *stream) noexcept
  955. {
  956. if(pa_stream_get_state(stream) == PA_STREAM_FAILED)
  957. {
  958. ERR("Received stream failure!\n");
  959. mDevice->handleDisconnect("Capture stream failure");
  960. }
  961. mMainloop.signal();
  962. }
  963. void PulseCapture::sourceNameCallback(pa_context*, const pa_source_info *info, int eol) noexcept
  964. {
  965. if(eol)
  966. {
  967. mMainloop.signal();
  968. return;
  969. }
  970. mDevice->DeviceName = info->description;
  971. }
  972. void PulseCapture::streamMovedCallback(pa_stream *stream) noexcept
  973. {
  974. mDeviceName = pa_stream_get_device_name(stream);
  975. TRACE("Stream moved to %s\n", mDeviceName->c_str());
  976. }
  977. void PulseCapture::open(std::string_view name)
  978. {
  979. if(!mMainloop)
  980. {
  981. mMainloop = PulseMainloop::Create();
  982. if(mMainloop.start() != 0)
  983. throw al::backend_exception{al::backend_error::DeviceError,
  984. "Failed to start device mainloop"};
  985. }
  986. const char *pulse_name{nullptr};
  987. if(!name.empty())
  988. {
  989. if(CaptureDevices.empty())
  990. mMainloop.probeCaptureDevices();
  991. auto match_name = [name](const DevMap &entry) -> bool
  992. { return entry.name == name || entry.device_name == name; };
  993. auto iter = std::find_if(CaptureDevices.cbegin(), CaptureDevices.cend(), match_name);
  994. if(iter == CaptureDevices.cend())
  995. throw al::backend_exception{al::backend_error::NoDevice,
  996. "Device name \"%.*s\" not found", al::sizei(name), name.data()};
  997. pulse_name = iter->device_name.c_str();
  998. mDevice->DeviceName = iter->name;
  999. }
  1000. MainloopUniqueLock plock{mMainloop};
  1001. plock.connectContext();
  1002. pa_channel_map chanmap{};
  1003. switch(mDevice->FmtChans)
  1004. {
  1005. case DevFmtMono: chanmap = MonoChanMap; break;
  1006. case DevFmtStereo: chanmap = StereoChanMap; break;
  1007. case DevFmtQuad: chanmap = QuadChanMap; break;
  1008. case DevFmtX51: chanmap = X51ChanMap; break;
  1009. case DevFmtX61: chanmap = X61ChanMap; break;
  1010. case DevFmtX71: chanmap = X71ChanMap; break;
  1011. case DevFmtX714: chanmap = X714ChanMap; break;
  1012. case DevFmtX7144:
  1013. case DevFmtX3D71:
  1014. case DevFmtAmbi3D:
  1015. throw al::backend_exception{al::backend_error::DeviceError, "%s capture not supported",
  1016. DevFmtChannelsString(mDevice->FmtChans)};
  1017. }
  1018. setDefaultWFXChannelOrder();
  1019. switch(mDevice->FmtType)
  1020. {
  1021. case DevFmtUByte:
  1022. mSilentVal = std::byte(0x80);
  1023. mSpec.format = PA_SAMPLE_U8;
  1024. break;
  1025. case DevFmtShort:
  1026. mSpec.format = PA_SAMPLE_S16NE;
  1027. break;
  1028. case DevFmtInt:
  1029. mSpec.format = PA_SAMPLE_S32NE;
  1030. break;
  1031. case DevFmtFloat:
  1032. mSpec.format = PA_SAMPLE_FLOAT32NE;
  1033. break;
  1034. case DevFmtByte:
  1035. case DevFmtUShort:
  1036. case DevFmtUInt:
  1037. throw al::backend_exception{al::backend_error::DeviceError,
  1038. "%s capture samples not supported", DevFmtTypeString(mDevice->FmtType)};
  1039. }
  1040. mSpec.rate = mDevice->Frequency;
  1041. mSpec.channels = static_cast<uint8_t>(mDevice->channelsFromFmt());
  1042. if(pa_sample_spec_valid(&mSpec) == 0)
  1043. throw al::backend_exception{al::backend_error::DeviceError, "Invalid sample format"};
  1044. const auto frame_size = static_cast<uint>(pa_frame_size(&mSpec));
  1045. const uint samples{std::max(mDevice->BufferSize, mDevice->Frequency*100u/1000u)};
  1046. mAttr.minreq = ~0u;
  1047. mAttr.prebuf = ~0u;
  1048. mAttr.maxlength = samples * frame_size;
  1049. mAttr.tlength = ~0u;
  1050. mAttr.fragsize = std::min(samples, mDevice->Frequency*50u/1000u) * frame_size;
  1051. pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY};
  1052. if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
  1053. flags |= PA_STREAM_DONT_MOVE;
  1054. TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
  1055. mStream = plock.connectStream(pulse_name, flags, &mAttr, &mSpec, &chanmap,
  1056. BackendType::Capture);
  1057. constexpr auto move_callback = [](pa_stream *stream, void *pdata) noexcept
  1058. { return static_cast<PulseCapture*>(pdata)->streamMovedCallback(stream); };
  1059. pa_stream_set_moved_callback(mStream, move_callback, this);
  1060. constexpr auto state_callback = [](pa_stream *stream, void *pdata) noexcept
  1061. { return static_cast<PulseCapture*>(pdata)->streamStateCallback(stream); };
  1062. pa_stream_set_state_callback(mStream, state_callback, this);
  1063. if(pulse_name) mDeviceName.emplace(pulse_name);
  1064. else mDeviceName.reset();
  1065. if(mDevice->DeviceName.empty())
  1066. {
  1067. constexpr auto name_callback = [](pa_context *context, const pa_source_info *info, int eol,
  1068. void *pdata) noexcept
  1069. { return static_cast<PulseCapture*>(pdata)->sourceNameCallback(context, info, eol); };
  1070. pa_operation *op{pa_context_get_source_info_by_name(mMainloop.getContext(),
  1071. pa_stream_get_device_name(mStream), name_callback, this)};
  1072. plock.waitForOperation(op);
  1073. }
  1074. }
  1075. void PulseCapture::start()
  1076. {
  1077. MainloopUniqueLock plock{mMainloop};
  1078. pa_operation *op{pa_stream_cork(mStream, 0, &PulseMainloop::streamSuccessCallbackC,
  1079. &mMainloop)};
  1080. plock.waitForOperation(op);
  1081. }
  1082. void PulseCapture::stop()
  1083. {
  1084. MainloopUniqueLock plock{mMainloop};
  1085. pa_operation *op{pa_stream_cork(mStream, 1, &PulseMainloop::streamSuccessCallbackC,
  1086. &mMainloop)};
  1087. plock.waitForOperation(op);
  1088. }
  1089. void PulseCapture::captureSamples(std::byte *buffer, uint samples)
  1090. {
  1091. al::span<std::byte> dstbuf{buffer, samples * pa_frame_size(&mSpec)};
  1092. /* Capture is done in fragment-sized chunks, so we loop until we get all
  1093. * that's available.
  1094. */
  1095. mLastReadable -= static_cast<uint>(dstbuf.size());
  1096. while(!dstbuf.empty())
  1097. {
  1098. if(mHoleLength > 0) UNLIKELY
  1099. {
  1100. const size_t rem{std::min(dstbuf.size(), mHoleLength)};
  1101. std::fill_n(dstbuf.begin(), rem, mSilentVal);
  1102. dstbuf = dstbuf.subspan(rem);
  1103. mHoleLength -= rem;
  1104. continue;
  1105. }
  1106. if(!mCapBuffer.empty())
  1107. {
  1108. const size_t rem{std::min(dstbuf.size(), mCapBuffer.size())};
  1109. std::copy_n(mCapBuffer.begin(), rem, dstbuf.begin());
  1110. dstbuf = dstbuf.subspan(rem);
  1111. mCapBuffer = mCapBuffer.subspan(rem);
  1112. continue;
  1113. }
  1114. if(!mDevice->Connected.load(std::memory_order_acquire)) UNLIKELY
  1115. break;
  1116. MainloopUniqueLock plock{mMainloop};
  1117. if(mPacketLength > 0)
  1118. {
  1119. pa_stream_drop(mStream);
  1120. mPacketLength = 0;
  1121. }
  1122. const pa_stream_state_t state{pa_stream_get_state(mStream)};
  1123. if(!PA_STREAM_IS_GOOD(state)) UNLIKELY
  1124. {
  1125. mDevice->handleDisconnect("Bad capture state: %u", state);
  1126. break;
  1127. }
  1128. const void *capbuf{};
  1129. size_t caplen{};
  1130. if(pa_stream_peek(mStream, &capbuf, &caplen) < 0) UNLIKELY
  1131. {
  1132. mDevice->handleDisconnect("Failed retrieving capture samples: %s",
  1133. pa_strerror(pa_context_errno(mMainloop.getContext())));
  1134. break;
  1135. }
  1136. plock.unlock();
  1137. if(caplen == 0) break;
  1138. if(!capbuf) UNLIKELY
  1139. mHoleLength = caplen;
  1140. else
  1141. mCapBuffer = {static_cast<const std::byte*>(capbuf), caplen};
  1142. mPacketLength = caplen;
  1143. }
  1144. if(!dstbuf.empty())
  1145. std::fill(dstbuf.begin(), dstbuf.end(), mSilentVal);
  1146. }
  1147. uint PulseCapture::availableSamples()
  1148. {
  1149. size_t readable{std::max(mCapBuffer.size(), mHoleLength)};
  1150. if(mDevice->Connected.load(std::memory_order_acquire))
  1151. {
  1152. MainloopUniqueLock plock{mMainloop};
  1153. size_t got{pa_stream_readable_size(mStream)};
  1154. if(static_cast<ssize_t>(got) < 0) UNLIKELY
  1155. {
  1156. const char *err{pa_strerror(static_cast<int>(got))};
  1157. ERR("pa_stream_readable_size() failed: %s\n", err);
  1158. mDevice->handleDisconnect("Failed getting readable size: %s", err);
  1159. }
  1160. else
  1161. {
  1162. /* "readable" is the number of bytes from the last packet that have
  1163. * not yet been read by the caller. So add the stream's readable
  1164. * size excluding the last packet (the stream size includes the
  1165. * last packet until it's dropped).
  1166. */
  1167. if(got > mPacketLength)
  1168. readable += got - mPacketLength;
  1169. }
  1170. }
  1171. /* Avoid uint overflow, and avoid decreasing the readable count. */
  1172. readable = std::min<size_t>(readable, std::numeric_limits<uint>::max());
  1173. mLastReadable = std::max(mLastReadable, static_cast<uint>(readable));
  1174. return mLastReadable / static_cast<uint>(pa_frame_size(&mSpec));
  1175. }
  1176. ClockLatency PulseCapture::getClockLatency()
  1177. {
  1178. ClockLatency ret{};
  1179. pa_usec_t latency{};
  1180. int neg{}, err{};
  1181. {
  1182. MainloopUniqueLock plock{mMainloop};
  1183. ret.ClockTime = mDevice->getClockTime();
  1184. err = pa_stream_get_latency(mStream, &latency, &neg);
  1185. }
  1186. if(err != 0) UNLIKELY
  1187. {
  1188. ERR("Failed to get stream latency: 0x%x\n", err);
  1189. latency = 0;
  1190. neg = 0;
  1191. }
  1192. else if(neg) UNLIKELY
  1193. latency = 0;
  1194. ret.Latency = std::chrono::microseconds{latency};
  1195. return ret;
  1196. }
  1197. } // namespace
  1198. bool PulseBackendFactory::init()
  1199. {
  1200. #ifdef HAVE_DYNLOAD
  1201. if(!pulse_handle)
  1202. {
  1203. #ifdef _WIN32
  1204. #define PALIB "libpulse-0.dll"
  1205. #elif defined(__APPLE__) && defined(__MACH__)
  1206. #define PALIB "libpulse.0.dylib"
  1207. #else
  1208. #define PALIB "libpulse.so.0"
  1209. #endif
  1210. pulse_handle = LoadLib(PALIB);
  1211. if(!pulse_handle)
  1212. {
  1213. WARN("Failed to load %s\n", PALIB);
  1214. return false;
  1215. }
  1216. std::string missing_funcs;
  1217. #define LOAD_FUNC(x) do { \
  1218. p##x = reinterpret_cast<decltype(p##x)>(GetSymbol(pulse_handle, #x)); \
  1219. if(!(p##x)) missing_funcs += "\n" #x; \
  1220. } while(0)
  1221. PULSE_FUNCS(LOAD_FUNC)
  1222. #undef LOAD_FUNC
  1223. if(!missing_funcs.empty())
  1224. {
  1225. WARN("Missing expected functions:%s\n", missing_funcs.c_str());
  1226. CloseLib(pulse_handle);
  1227. pulse_handle = nullptr;
  1228. return false;
  1229. }
  1230. }
  1231. #endif /* HAVE_DYNLOAD */
  1232. pulse_ctx_flags = PA_CONTEXT_NOFLAGS;
  1233. if(!GetConfigValueBool({}, "pulse", "spawn-server", false))
  1234. pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN;
  1235. try {
  1236. if(!gGlobalMainloop)
  1237. {
  1238. gGlobalMainloop = PulseMainloop::Create();
  1239. if(gGlobalMainloop.start() != 0)
  1240. {
  1241. gGlobalMainloop = nullptr;
  1242. return false;
  1243. }
  1244. }
  1245. MainloopUniqueLock plock{gGlobalMainloop};
  1246. plock.connectContext();
  1247. plock.setEventHandler();
  1248. return true;
  1249. }
  1250. catch(...) {
  1251. return false;
  1252. }
  1253. }
  1254. bool PulseBackendFactory::querySupport(BackendType type)
  1255. { return type == BackendType::Playback || type == BackendType::Capture; }
  1256. auto PulseBackendFactory::enumerate(BackendType type) -> std::vector<std::string>
  1257. {
  1258. std::vector<std::string> outnames;
  1259. auto add_device = [&outnames](const DevMap &entry) -> void
  1260. { outnames.push_back(entry.name); };
  1261. switch(type)
  1262. {
  1263. case BackendType::Playback:
  1264. gGlobalMainloop.probePlaybackDevices();
  1265. outnames.reserve(PlaybackDevices.size());
  1266. std::for_each(PlaybackDevices.cbegin(), PlaybackDevices.cend(), add_device);
  1267. break;
  1268. case BackendType::Capture:
  1269. gGlobalMainloop.probeCaptureDevices();
  1270. outnames.reserve(CaptureDevices.size());
  1271. std::for_each(CaptureDevices.cbegin(), CaptureDevices.cend(), add_device);
  1272. break;
  1273. }
  1274. return outnames;
  1275. }
  1276. BackendPtr PulseBackendFactory::createBackend(DeviceBase *device, BackendType type)
  1277. {
  1278. if(type == BackendType::Playback)
  1279. return BackendPtr{new PulsePlayback{device}};
  1280. if(type == BackendType::Capture)
  1281. return BackendPtr{new PulseCapture{device}};
  1282. return nullptr;
  1283. }
  1284. BackendFactory &PulseBackendFactory::getFactory()
  1285. {
  1286. static PulseBackendFactory factory{};
  1287. return factory;
  1288. }
  1289. alc::EventSupport PulseBackendFactory::queryEventSupport(alc::EventType eventType, BackendType)
  1290. {
  1291. switch(eventType)
  1292. {
  1293. case alc::EventType::DeviceAdded:
  1294. case alc::EventType::DeviceRemoved:
  1295. return alc::EventSupport::FullSupport;
  1296. case alc::EventType::DefaultDeviceChanged:
  1297. case alc::EventType::Count:
  1298. break;
  1299. }
  1300. return alc::EventSupport::NoSupport;
  1301. }