pulseaudio.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494
  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., 59 Temple Place - Suite 330,
  18. * Boston, MA 02111-1307, USA.
  19. * Or go to http://www.gnu.org/copyleft/lgpl.html
  20. */
  21. #include "config.h"
  22. #include "alMain.h"
  23. #include <pulse/pulseaudio.h>
  24. #if PA_API_VERSION == 12
  25. #ifndef PA_CHECK_VERSION
  26. #define PA_CHECK_VERSION(major,minor,micro) \
  27. ((PA_MAJOR > (major)) || \
  28. (PA_MAJOR == (major) && PA_MINOR > (minor)) || \
  29. (PA_MAJOR == (major) && PA_MINOR == (minor) && PA_MICRO >= (micro)))
  30. #endif
  31. #ifdef HAVE_DYNLOAD
  32. static void *pa_handle;
  33. #define MAKE_FUNC(x) static typeof(x) * p##x
  34. MAKE_FUNC(pa_context_unref);
  35. MAKE_FUNC(pa_sample_spec_valid);
  36. MAKE_FUNC(pa_frame_size);
  37. MAKE_FUNC(pa_stream_drop);
  38. MAKE_FUNC(pa_strerror);
  39. MAKE_FUNC(pa_context_get_state);
  40. MAKE_FUNC(pa_stream_get_state);
  41. MAKE_FUNC(pa_threaded_mainloop_signal);
  42. MAKE_FUNC(pa_stream_peek);
  43. MAKE_FUNC(pa_threaded_mainloop_wait);
  44. MAKE_FUNC(pa_threaded_mainloop_unlock);
  45. MAKE_FUNC(pa_threaded_mainloop_in_thread);
  46. MAKE_FUNC(pa_context_new);
  47. MAKE_FUNC(pa_threaded_mainloop_stop);
  48. MAKE_FUNC(pa_context_disconnect);
  49. MAKE_FUNC(pa_threaded_mainloop_start);
  50. MAKE_FUNC(pa_threaded_mainloop_get_api);
  51. MAKE_FUNC(pa_context_set_state_callback);
  52. MAKE_FUNC(pa_stream_write);
  53. MAKE_FUNC(pa_xfree);
  54. MAKE_FUNC(pa_stream_connect_record);
  55. MAKE_FUNC(pa_stream_connect_playback);
  56. MAKE_FUNC(pa_stream_readable_size);
  57. MAKE_FUNC(pa_stream_writable_size);
  58. MAKE_FUNC(pa_stream_is_corked);
  59. MAKE_FUNC(pa_stream_cork);
  60. MAKE_FUNC(pa_stream_is_suspended);
  61. MAKE_FUNC(pa_stream_get_device_name);
  62. MAKE_FUNC(pa_path_get_filename);
  63. MAKE_FUNC(pa_get_binary_name);
  64. MAKE_FUNC(pa_threaded_mainloop_free);
  65. MAKE_FUNC(pa_context_errno);
  66. MAKE_FUNC(pa_xmalloc);
  67. MAKE_FUNC(pa_stream_unref);
  68. MAKE_FUNC(pa_threaded_mainloop_accept);
  69. MAKE_FUNC(pa_stream_set_write_callback);
  70. MAKE_FUNC(pa_threaded_mainloop_new);
  71. MAKE_FUNC(pa_context_connect);
  72. MAKE_FUNC(pa_stream_set_buffer_attr);
  73. MAKE_FUNC(pa_stream_get_buffer_attr);
  74. MAKE_FUNC(pa_stream_get_sample_spec);
  75. MAKE_FUNC(pa_stream_get_time);
  76. MAKE_FUNC(pa_stream_set_read_callback);
  77. MAKE_FUNC(pa_stream_set_state_callback);
  78. MAKE_FUNC(pa_stream_set_moved_callback);
  79. MAKE_FUNC(pa_stream_set_underflow_callback);
  80. MAKE_FUNC(pa_stream_new_with_proplist);
  81. MAKE_FUNC(pa_stream_disconnect);
  82. MAKE_FUNC(pa_threaded_mainloop_lock);
  83. MAKE_FUNC(pa_channel_map_init_auto);
  84. MAKE_FUNC(pa_channel_map_parse);
  85. MAKE_FUNC(pa_channel_map_snprint);
  86. MAKE_FUNC(pa_channel_map_equal);
  87. MAKE_FUNC(pa_context_get_server_info);
  88. MAKE_FUNC(pa_context_get_sink_info_by_name);
  89. MAKE_FUNC(pa_context_get_sink_info_list);
  90. MAKE_FUNC(pa_context_get_source_info_by_name);
  91. MAKE_FUNC(pa_context_get_source_info_list);
  92. MAKE_FUNC(pa_operation_get_state);
  93. MAKE_FUNC(pa_operation_unref);
  94. MAKE_FUNC(pa_proplist_new);
  95. MAKE_FUNC(pa_proplist_free);
  96. MAKE_FUNC(pa_proplist_set);
  97. #if PA_CHECK_VERSION(0,9,15)
  98. MAKE_FUNC(pa_channel_map_superset);
  99. MAKE_FUNC(pa_stream_set_buffer_attr_callback);
  100. #endif
  101. #if PA_CHECK_VERSION(0,9,16)
  102. MAKE_FUNC(pa_stream_begin_write);
  103. #endif
  104. #undef MAKE_FUNC
  105. #define pa_context_unref ppa_context_unref
  106. #define pa_sample_spec_valid ppa_sample_spec_valid
  107. #define pa_frame_size ppa_frame_size
  108. #define pa_stream_drop ppa_stream_drop
  109. #define pa_strerror ppa_strerror
  110. #define pa_context_get_state ppa_context_get_state
  111. #define pa_stream_get_state ppa_stream_get_state
  112. #define pa_threaded_mainloop_signal ppa_threaded_mainloop_signal
  113. #define pa_stream_peek ppa_stream_peek
  114. #define pa_threaded_mainloop_wait ppa_threaded_mainloop_wait
  115. #define pa_threaded_mainloop_unlock ppa_threaded_mainloop_unlock
  116. #define pa_threaded_mainloop_in_thread ppa_threaded_mainloop_in_thread
  117. #define pa_context_new ppa_context_new
  118. #define pa_threaded_mainloop_stop ppa_threaded_mainloop_stop
  119. #define pa_context_disconnect ppa_context_disconnect
  120. #define pa_threaded_mainloop_start ppa_threaded_mainloop_start
  121. #define pa_threaded_mainloop_get_api ppa_threaded_mainloop_get_api
  122. #define pa_context_set_state_callback ppa_context_set_state_callback
  123. #define pa_stream_write ppa_stream_write
  124. #define pa_xfree ppa_xfree
  125. #define pa_stream_connect_record ppa_stream_connect_record
  126. #define pa_stream_connect_playback ppa_stream_connect_playback
  127. #define pa_stream_readable_size ppa_stream_readable_size
  128. #define pa_stream_writable_size ppa_stream_writable_size
  129. #define pa_stream_is_corked ppa_stream_is_corked
  130. #define pa_stream_cork ppa_stream_cork
  131. #define pa_stream_is_suspended ppa_stream_is_suspended
  132. #define pa_stream_get_device_name ppa_stream_get_device_name
  133. #define pa_path_get_filename ppa_path_get_filename
  134. #define pa_get_binary_name ppa_get_binary_name
  135. #define pa_threaded_mainloop_free ppa_threaded_mainloop_free
  136. #define pa_context_errno ppa_context_errno
  137. #define pa_xmalloc ppa_xmalloc
  138. #define pa_stream_unref ppa_stream_unref
  139. #define pa_threaded_mainloop_accept ppa_threaded_mainloop_accept
  140. #define pa_stream_set_write_callback ppa_stream_set_write_callback
  141. #define pa_threaded_mainloop_new ppa_threaded_mainloop_new
  142. #define pa_context_connect ppa_context_connect
  143. #define pa_stream_set_buffer_attr ppa_stream_set_buffer_attr
  144. #define pa_stream_get_buffer_attr ppa_stream_get_buffer_attr
  145. #define pa_stream_get_sample_spec ppa_stream_get_sample_spec
  146. #define pa_stream_get_time ppa_stream_get_time
  147. #define pa_stream_set_read_callback ppa_stream_set_read_callback
  148. #define pa_stream_set_state_callback ppa_stream_set_state_callback
  149. #define pa_stream_set_moved_callback ppa_stream_set_moved_callback
  150. #define pa_stream_set_underflow_callback ppa_stream_set_underflow_callback
  151. #define pa_stream_new_with_proplist ppa_stream_new_with_proplist
  152. #define pa_stream_disconnect ppa_stream_disconnect
  153. #define pa_threaded_mainloop_lock ppa_threaded_mainloop_lock
  154. #define pa_channel_map_init_auto ppa_channel_map_init_auto
  155. #define pa_channel_map_parse ppa_channel_map_parse
  156. #define pa_channel_map_snprint ppa_channel_map_snprint
  157. #define pa_channel_map_equal ppa_channel_map_equal
  158. #define pa_context_get_server_info ppa_context_get_server_info
  159. #define pa_context_get_sink_info_by_name ppa_context_get_sink_info_by_name
  160. #define pa_context_get_sink_info_list ppa_context_get_sink_info_list
  161. #define pa_context_get_source_info_by_name ppa_context_get_source_info_by_name
  162. #define pa_context_get_source_info_list ppa_context_get_source_info_list
  163. #define pa_operation_get_state ppa_operation_get_state
  164. #define pa_operation_unref ppa_operation_unref
  165. #define pa_proplist_new ppa_proplist_new
  166. #define pa_proplist_free ppa_proplist_free
  167. #define pa_proplist_set ppa_proplist_set
  168. #if PA_CHECK_VERSION(0,9,15)
  169. #define pa_channel_map_superset ppa_channel_map_superset
  170. #define pa_stream_set_buffer_attr_callback ppa_stream_set_buffer_attr_callback
  171. #endif
  172. #if PA_CHECK_VERSION(0,9,16)
  173. #define pa_stream_begin_write ppa_stream_begin_write
  174. #endif
  175. #endif
  176. #ifndef PATH_MAX
  177. #define PATH_MAX 4096
  178. #endif
  179. typedef struct {
  180. char *device_name;
  181. const void *cap_store;
  182. size_t cap_len;
  183. size_t cap_remain;
  184. ALCuint last_readable;
  185. pa_buffer_attr attr;
  186. pa_sample_spec spec;
  187. pa_threaded_mainloop *loop;
  188. ALvoid *thread;
  189. volatile ALboolean killNow;
  190. pa_stream *stream;
  191. pa_context *context;
  192. } pulse_data;
  193. typedef struct {
  194. char *name;
  195. char *device_name;
  196. } DevMap;
  197. static DevMap *allDevNameMap;
  198. static ALuint numDevNames;
  199. static DevMap *allCaptureDevNameMap;
  200. static ALuint numCaptureDevNames;
  201. static pa_context_flags_t pulse_ctx_flags;
  202. static pa_proplist *prop_filter;
  203. static ALCboolean pulse_load(void)
  204. {
  205. ALCboolean ret = ALC_TRUE;
  206. #ifdef HAVE_DYNLOAD
  207. if(!pa_handle)
  208. {
  209. #ifdef _WIN32
  210. #define PALIB "libpulse-0.dll"
  211. #elif defined(__APPLE__) && defined(__MACH__)
  212. #define PALIB "libpulse.0.dylib"
  213. #else
  214. #define PALIB "libpulse.so.0"
  215. #endif
  216. pa_handle = LoadLib(PALIB);
  217. if(!pa_handle)
  218. return ALC_FALSE;
  219. #define LOAD_FUNC(x) do { \
  220. p##x = GetSymbol(pa_handle, #x); \
  221. if(!(p##x)) { \
  222. ret = ALC_FALSE; \
  223. } \
  224. } while(0)
  225. LOAD_FUNC(pa_context_unref);
  226. LOAD_FUNC(pa_sample_spec_valid);
  227. LOAD_FUNC(pa_stream_drop);
  228. LOAD_FUNC(pa_frame_size);
  229. LOAD_FUNC(pa_strerror);
  230. LOAD_FUNC(pa_context_get_state);
  231. LOAD_FUNC(pa_stream_get_state);
  232. LOAD_FUNC(pa_threaded_mainloop_signal);
  233. LOAD_FUNC(pa_stream_peek);
  234. LOAD_FUNC(pa_threaded_mainloop_wait);
  235. LOAD_FUNC(pa_threaded_mainloop_unlock);
  236. LOAD_FUNC(pa_threaded_mainloop_in_thread);
  237. LOAD_FUNC(pa_context_new);
  238. LOAD_FUNC(pa_threaded_mainloop_stop);
  239. LOAD_FUNC(pa_context_disconnect);
  240. LOAD_FUNC(pa_threaded_mainloop_start);
  241. LOAD_FUNC(pa_threaded_mainloop_get_api);
  242. LOAD_FUNC(pa_context_set_state_callback);
  243. LOAD_FUNC(pa_stream_write);
  244. LOAD_FUNC(pa_xfree);
  245. LOAD_FUNC(pa_stream_connect_record);
  246. LOAD_FUNC(pa_stream_connect_playback);
  247. LOAD_FUNC(pa_stream_readable_size);
  248. LOAD_FUNC(pa_stream_writable_size);
  249. LOAD_FUNC(pa_stream_is_corked);
  250. LOAD_FUNC(pa_stream_cork);
  251. LOAD_FUNC(pa_stream_is_suspended);
  252. LOAD_FUNC(pa_stream_get_device_name);
  253. LOAD_FUNC(pa_path_get_filename);
  254. LOAD_FUNC(pa_get_binary_name);
  255. LOAD_FUNC(pa_threaded_mainloop_free);
  256. LOAD_FUNC(pa_context_errno);
  257. LOAD_FUNC(pa_xmalloc);
  258. LOAD_FUNC(pa_stream_unref);
  259. LOAD_FUNC(pa_threaded_mainloop_accept);
  260. LOAD_FUNC(pa_stream_set_write_callback);
  261. LOAD_FUNC(pa_threaded_mainloop_new);
  262. LOAD_FUNC(pa_context_connect);
  263. LOAD_FUNC(pa_stream_set_buffer_attr);
  264. LOAD_FUNC(pa_stream_get_buffer_attr);
  265. LOAD_FUNC(pa_stream_get_sample_spec);
  266. LOAD_FUNC(pa_stream_get_time);
  267. LOAD_FUNC(pa_stream_set_read_callback);
  268. LOAD_FUNC(pa_stream_set_state_callback);
  269. LOAD_FUNC(pa_stream_set_moved_callback);
  270. LOAD_FUNC(pa_stream_set_underflow_callback);
  271. LOAD_FUNC(pa_stream_new_with_proplist);
  272. LOAD_FUNC(pa_stream_disconnect);
  273. LOAD_FUNC(pa_threaded_mainloop_lock);
  274. LOAD_FUNC(pa_channel_map_init_auto);
  275. LOAD_FUNC(pa_channel_map_parse);
  276. LOAD_FUNC(pa_channel_map_snprint);
  277. LOAD_FUNC(pa_channel_map_equal);
  278. LOAD_FUNC(pa_context_get_server_info);
  279. LOAD_FUNC(pa_context_get_sink_info_by_name);
  280. LOAD_FUNC(pa_context_get_sink_info_list);
  281. LOAD_FUNC(pa_context_get_source_info_by_name);
  282. LOAD_FUNC(pa_context_get_source_info_list);
  283. LOAD_FUNC(pa_operation_get_state);
  284. LOAD_FUNC(pa_operation_unref);
  285. LOAD_FUNC(pa_proplist_new);
  286. LOAD_FUNC(pa_proplist_free);
  287. LOAD_FUNC(pa_proplist_set);
  288. #undef LOAD_FUNC
  289. #define LOAD_OPTIONAL_FUNC(x) do { \
  290. p##x = GetSymbol(pa_handle, #x); \
  291. } while(0)
  292. #if PA_CHECK_VERSION(0,9,15)
  293. LOAD_OPTIONAL_FUNC(pa_channel_map_superset);
  294. LOAD_OPTIONAL_FUNC(pa_stream_set_buffer_attr_callback);
  295. #endif
  296. #if PA_CHECK_VERSION(0,9,16)
  297. LOAD_OPTIONAL_FUNC(pa_stream_begin_write);
  298. #endif
  299. #undef LOAD_OPTIONAL_FUNC
  300. if(ret == ALC_FALSE)
  301. {
  302. CloseLib(pa_handle);
  303. pa_handle = NULL;
  304. }
  305. }
  306. #endif /* HAVE_DYNLOAD */
  307. return ret;
  308. }
  309. /* PulseAudio Event Callbacks */
  310. static void context_state_callback(pa_context *context, void *pdata)
  311. {
  312. pa_threaded_mainloop *loop = pdata;
  313. pa_context_state_t state;
  314. state = pa_context_get_state(context);
  315. if(state == PA_CONTEXT_READY || !PA_CONTEXT_IS_GOOD(state))
  316. pa_threaded_mainloop_signal(loop, 0);
  317. }
  318. static void stream_state_callback(pa_stream *stream, void *pdata)
  319. {
  320. pa_threaded_mainloop *loop = pdata;
  321. pa_stream_state_t state;
  322. state = pa_stream_get_state(stream);
  323. if(state == PA_STREAM_READY || !PA_STREAM_IS_GOOD(state))
  324. pa_threaded_mainloop_signal(loop, 0);
  325. }
  326. static void stream_buffer_attr_callback(pa_stream *stream, void *pdata)
  327. {
  328. ALCdevice *device = pdata;
  329. pulse_data *data = device->ExtraData;
  330. data->attr = *pa_stream_get_buffer_attr(stream);
  331. TRACE("minreq=%d, tlength=%d, prebuf=%d\n", data->attr.minreq, data->attr.tlength, data->attr.prebuf);
  332. }
  333. static void context_state_callback2(pa_context *context, void *pdata)
  334. {
  335. ALCdevice *Device = pdata;
  336. pulse_data *data = Device->ExtraData;
  337. if(pa_context_get_state(context) == PA_CONTEXT_FAILED)
  338. {
  339. ERR("Received context failure!\n");
  340. aluHandleDisconnect(Device);
  341. }
  342. pa_threaded_mainloop_signal(data->loop, 0);
  343. }
  344. static void stream_state_callback2(pa_stream *stream, void *pdata)
  345. {
  346. ALCdevice *Device = pdata;
  347. pulse_data *data = Device->ExtraData;
  348. if(pa_stream_get_state(stream) == PA_STREAM_FAILED)
  349. {
  350. ERR("Received stream failure!\n");
  351. aluHandleDisconnect(Device);
  352. }
  353. pa_threaded_mainloop_signal(data->loop, 0);
  354. }
  355. static void stream_success_callback(pa_stream *stream, int success, void *pdata)
  356. {
  357. ALCdevice *Device = pdata;
  358. pulse_data *data = Device->ExtraData;
  359. (void)stream;
  360. (void)success;
  361. pa_threaded_mainloop_signal(data->loop, 0);
  362. }
  363. static void sink_info_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata)
  364. {
  365. ALCdevice *device = pdata;
  366. pulse_data *data = device->ExtraData;
  367. char chanmap_str[256] = "";
  368. const struct {
  369. const char *str;
  370. enum DevFmtChannels chans;
  371. } chanmaps[] = {
  372. { "front-left,front-right,front-center,lfe,rear-left,rear-right,side-left,side-right",
  373. DevFmtX71 },
  374. { "front-left,front-right,front-center,lfe,rear-center,side-left,side-right",
  375. DevFmtX61 },
  376. { "front-left,front-right,front-center,lfe,rear-left,rear-right",
  377. DevFmtX51 },
  378. { "front-left,front-right,front-center,lfe,side-left,side-right",
  379. DevFmtX51Side },
  380. { "front-left,front-right,rear-left,rear-right", DevFmtQuad },
  381. { "front-left,front-right", DevFmtStereo },
  382. { "mono", DevFmtMono },
  383. { NULL, 0 }
  384. };
  385. int i;
  386. (void)context;
  387. if(eol)
  388. {
  389. pa_threaded_mainloop_signal(data->loop, 0);
  390. return;
  391. }
  392. for(i = 0;chanmaps[i].str;i++)
  393. {
  394. pa_channel_map map;
  395. if(!pa_channel_map_parse(&map, chanmaps[i].str))
  396. continue;
  397. if(pa_channel_map_equal(&info->channel_map, &map)
  398. #if PA_CHECK_VERSION(0,9,15)
  399. || (pa_channel_map_superset &&
  400. pa_channel_map_superset(&info->channel_map, &map))
  401. #endif
  402. )
  403. {
  404. device->FmtChans = chanmaps[i].chans;
  405. return;
  406. }
  407. }
  408. pa_channel_map_snprint(chanmap_str, sizeof(chanmap_str), &info->channel_map);
  409. ERR("Failed to find format for channel map:\n %s\n", chanmap_str);
  410. }
  411. static void sink_device_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata)
  412. {
  413. pa_threaded_mainloop *loop = pdata;
  414. void *temp;
  415. ALuint i;
  416. (void)context;
  417. if(eol)
  418. {
  419. pa_threaded_mainloop_signal(loop, 0);
  420. return;
  421. }
  422. for(i = 0;i < numDevNames;i++)
  423. {
  424. if(strcmp(info->name, allDevNameMap[i].device_name) == 0)
  425. return;
  426. }
  427. TRACE("Got device \"%s\", \"%s\"\n", info->description, info->name);
  428. temp = realloc(allDevNameMap, (numDevNames+1) * sizeof(*allDevNameMap));
  429. if(temp)
  430. {
  431. allDevNameMap = temp;
  432. allDevNameMap[numDevNames].name = strdup(info->description);
  433. allDevNameMap[numDevNames].device_name = strdup(info->name);
  434. numDevNames++;
  435. }
  436. }
  437. static void source_device_callback(pa_context *context, const pa_source_info *info, int eol, void *pdata)
  438. {
  439. pa_threaded_mainloop *loop = pdata;
  440. void *temp;
  441. ALuint i;
  442. (void)context;
  443. if(eol)
  444. {
  445. pa_threaded_mainloop_signal(loop, 0);
  446. return;
  447. }
  448. for(i = 0;i < numCaptureDevNames;i++)
  449. {
  450. if(strcmp(info->name, allCaptureDevNameMap[i].device_name) == 0)
  451. return;
  452. }
  453. TRACE("Got device \"%s\", \"%s\"\n", info->description, info->name);
  454. temp = realloc(allCaptureDevNameMap, (numCaptureDevNames+1) * sizeof(*allCaptureDevNameMap));
  455. if(temp)
  456. {
  457. allCaptureDevNameMap = temp;
  458. allCaptureDevNameMap[numCaptureDevNames].name = strdup(info->description);
  459. allCaptureDevNameMap[numCaptureDevNames].device_name = strdup(info->name);
  460. numCaptureDevNames++;
  461. }
  462. }
  463. static void sink_name_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata)
  464. {
  465. ALCdevice *device = pdata;
  466. pulse_data *data = device->ExtraData;
  467. (void)context;
  468. if(eol)
  469. {
  470. pa_threaded_mainloop_signal(data->loop, 0);
  471. return;
  472. }
  473. free(device->szDeviceName);
  474. device->szDeviceName = strdup(info->description);
  475. }
  476. static void source_name_callback(pa_context *context, const pa_source_info *info, int eol, void *pdata)
  477. {
  478. ALCdevice *device = pdata;
  479. pulse_data *data = device->ExtraData;
  480. (void)context;
  481. if(eol)
  482. {
  483. pa_threaded_mainloop_signal(data->loop, 0);
  484. return;
  485. }
  486. free(device->szDeviceName);
  487. device->szDeviceName = strdup(info->description);
  488. }
  489. static pa_context *connect_context(pa_threaded_mainloop *loop, ALboolean silent)
  490. {
  491. const char *name = "OpenAL Soft";
  492. char path_name[PATH_MAX];
  493. pa_context_state_t state;
  494. pa_context *context;
  495. int err;
  496. if(pa_get_binary_name(path_name, sizeof(path_name)))
  497. name = pa_path_get_filename(path_name);
  498. context = pa_context_new(pa_threaded_mainloop_get_api(loop), name);
  499. if(!context)
  500. {
  501. ERR("pa_context_new() failed\n");
  502. return NULL;
  503. }
  504. pa_context_set_state_callback(context, context_state_callback, loop);
  505. if((err=pa_context_connect(context, NULL, pulse_ctx_flags, NULL)) >= 0)
  506. {
  507. while((state=pa_context_get_state(context)) != PA_CONTEXT_READY)
  508. {
  509. if(!PA_CONTEXT_IS_GOOD(state))
  510. {
  511. err = pa_context_errno(context);
  512. if(err > 0) err = -err;
  513. break;
  514. }
  515. pa_threaded_mainloop_wait(loop);
  516. }
  517. }
  518. pa_context_set_state_callback(context, NULL, NULL);
  519. if(err < 0)
  520. {
  521. if(!silent)
  522. ERR("Context did not connect: %s\n", pa_strerror(err));
  523. pa_context_unref(context);
  524. return NULL;
  525. }
  526. return context;
  527. }
  528. static pa_stream *connect_playback_stream(const char *device_name,
  529. pa_threaded_mainloop *loop, pa_context *context,
  530. pa_stream_flags_t flags, pa_buffer_attr *attr, pa_sample_spec *spec,
  531. pa_channel_map *chanmap)
  532. {
  533. pa_stream_state_t state;
  534. pa_stream *stream;
  535. stream = pa_stream_new_with_proplist(context, "Playback Stream", spec, chanmap, prop_filter);
  536. if(!stream)
  537. {
  538. ERR("pa_stream_new_with_proplist() failed: %s\n", pa_strerror(pa_context_errno(context)));
  539. return NULL;
  540. }
  541. pa_stream_set_state_callback(stream, stream_state_callback, loop);
  542. if(pa_stream_connect_playback(stream, device_name, attr, flags, NULL, NULL) < 0)
  543. {
  544. ERR("Stream did not connect: %s\n", pa_strerror(pa_context_errno(context)));
  545. pa_stream_unref(stream);
  546. return NULL;
  547. }
  548. while((state=pa_stream_get_state(stream)) != PA_STREAM_READY)
  549. {
  550. if(!PA_STREAM_IS_GOOD(state))
  551. {
  552. ERR("Stream did not get ready: %s\n", pa_strerror(pa_context_errno(context)));
  553. pa_stream_unref(stream);
  554. return NULL;
  555. }
  556. pa_threaded_mainloop_wait(loop);
  557. }
  558. pa_stream_set_state_callback(stream, NULL, NULL);
  559. return stream;
  560. }
  561. static pa_stream *connect_record_stream(const char *device_name,
  562. pa_threaded_mainloop *loop, pa_context *context,
  563. pa_stream_flags_t flags, pa_buffer_attr *attr, pa_sample_spec *spec,
  564. pa_channel_map *chanmap)
  565. {
  566. pa_stream_state_t state;
  567. pa_stream *stream;
  568. stream = pa_stream_new_with_proplist(context, "Capture Stream", spec, chanmap, prop_filter);
  569. if(!stream)
  570. {
  571. ERR("pa_stream_new_with_proplist() failed: %s\n", pa_strerror(pa_context_errno(context)));
  572. return NULL;
  573. }
  574. pa_stream_set_state_callback(stream, stream_state_callback, loop);
  575. if(pa_stream_connect_record(stream, device_name, attr, flags) < 0)
  576. {
  577. ERR("Stream did not connect: %s\n", pa_strerror(pa_context_errno(context)));
  578. pa_stream_unref(stream);
  579. return NULL;
  580. }
  581. while((state=pa_stream_get_state(stream)) != PA_STREAM_READY)
  582. {
  583. if(!PA_STREAM_IS_GOOD(state))
  584. {
  585. ERR("Stream did not get ready: %s\n", pa_strerror(pa_context_errno(context)));
  586. pa_stream_unref(stream);
  587. return NULL;
  588. }
  589. pa_threaded_mainloop_wait(loop);
  590. }
  591. pa_stream_set_state_callback(stream, NULL, NULL);
  592. return stream;
  593. }
  594. #define WAIT_FOR_OPERATION(x, l) do { \
  595. pa_threaded_mainloop *_l = (l); \
  596. pa_operation *_o = (x); \
  597. if(!_o) break; \
  598. while(pa_operation_get_state(_o) == PA_OPERATION_RUNNING) \
  599. pa_threaded_mainloop_wait(_l); \
  600. pa_operation_unref(_o); \
  601. } while(0)
  602. static void probe_devices(ALboolean capture)
  603. {
  604. pa_threaded_mainloop *loop;
  605. if(capture == AL_FALSE)
  606. allDevNameMap = malloc(sizeof(DevMap) * 1);
  607. else
  608. allCaptureDevNameMap = malloc(sizeof(DevMap) * 1);
  609. if((loop=pa_threaded_mainloop_new()) &&
  610. pa_threaded_mainloop_start(loop) >= 0)
  611. {
  612. pa_context *context;
  613. pa_threaded_mainloop_lock(loop);
  614. context = connect_context(loop, AL_FALSE);
  615. if(context)
  616. {
  617. pa_operation *o;
  618. if(capture == AL_FALSE)
  619. {
  620. pa_stream_flags_t flags;
  621. pa_sample_spec spec;
  622. pa_stream *stream;
  623. flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
  624. PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE;
  625. spec.format = PA_SAMPLE_S16NE;
  626. spec.rate = 44100;
  627. spec.channels = 2;
  628. stream = connect_playback_stream(NULL, loop, context, flags,
  629. NULL, &spec, NULL);
  630. if(stream)
  631. {
  632. o = pa_context_get_sink_info_by_name(context, pa_stream_get_device_name(stream), sink_device_callback, loop);
  633. WAIT_FOR_OPERATION(o, loop);
  634. pa_stream_disconnect(stream);
  635. pa_stream_unref(stream);
  636. stream = NULL;
  637. }
  638. o = pa_context_get_sink_info_list(context, sink_device_callback, loop);
  639. }
  640. else
  641. {
  642. pa_stream_flags_t flags;
  643. pa_sample_spec spec;
  644. pa_stream *stream;
  645. flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
  646. PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE;
  647. spec.format = PA_SAMPLE_S16NE;
  648. spec.rate = 44100;
  649. spec.channels = 1;
  650. stream = connect_record_stream(NULL, loop, context, flags,
  651. NULL, &spec, NULL);
  652. if(stream)
  653. {
  654. o = pa_context_get_source_info_by_name(context, pa_stream_get_device_name(stream), source_device_callback, loop);
  655. WAIT_FOR_OPERATION(o, loop);
  656. pa_stream_disconnect(stream);
  657. pa_stream_unref(stream);
  658. stream = NULL;
  659. }
  660. o = pa_context_get_source_info_list(context, source_device_callback, loop);
  661. }
  662. WAIT_FOR_OPERATION(o, loop);
  663. pa_context_disconnect(context);
  664. pa_context_unref(context);
  665. }
  666. pa_threaded_mainloop_unlock(loop);
  667. pa_threaded_mainloop_stop(loop);
  668. }
  669. if(loop)
  670. pa_threaded_mainloop_free(loop);
  671. }
  672. static ALuint PulseProc(ALvoid *param)
  673. {
  674. ALCdevice *Device = param;
  675. pulse_data *data = Device->ExtraData;
  676. ALuint buffer_size;
  677. ALint update_size;
  678. size_t frame_size;
  679. ssize_t len;
  680. SetRTPriority();
  681. pa_threaded_mainloop_lock(data->loop);
  682. frame_size = pa_frame_size(&data->spec);
  683. update_size = Device->UpdateSize * frame_size;
  684. /* Sanitize buffer metrics, in case we actually have less than what we
  685. * asked for. */
  686. buffer_size = minu(update_size*Device->NumUpdates, data->attr.tlength);
  687. update_size = minu(update_size, buffer_size/2);
  688. do {
  689. len = pa_stream_writable_size(data->stream) - data->attr.tlength +
  690. buffer_size;
  691. if(len < update_size)
  692. {
  693. if(pa_stream_is_corked(data->stream) == 1)
  694. {
  695. pa_operation *o;
  696. o = pa_stream_cork(data->stream, 0, NULL, NULL);
  697. if(o) pa_operation_unref(o);
  698. }
  699. pa_threaded_mainloop_unlock(data->loop);
  700. Sleep(1);
  701. pa_threaded_mainloop_lock(data->loop);
  702. continue;
  703. }
  704. len -= len%update_size;
  705. while(len > 0)
  706. {
  707. size_t newlen = len;
  708. void *buf;
  709. pa_free_cb_t free_func = NULL;
  710. #if PA_CHECK_VERSION(0,9,16)
  711. if(!pa_stream_begin_write ||
  712. pa_stream_begin_write(data->stream, &buf, &newlen) < 0)
  713. #endif
  714. {
  715. buf = pa_xmalloc(newlen);
  716. free_func = pa_xfree;
  717. }
  718. pa_threaded_mainloop_unlock(data->loop);
  719. aluMixData(Device, buf, newlen/frame_size);
  720. pa_threaded_mainloop_lock(data->loop);
  721. pa_stream_write(data->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE);
  722. len -= newlen;
  723. }
  724. } while(!data->killNow && Device->Connected);
  725. pa_threaded_mainloop_unlock(data->loop);
  726. return 0;
  727. }
  728. static ALCboolean pulse_open(ALCdevice *device)
  729. {
  730. pulse_data *data = pa_xmalloc(sizeof(pulse_data));
  731. memset(data, 0, sizeof(*data));
  732. if(!(data->loop = pa_threaded_mainloop_new()))
  733. {
  734. ERR("pa_threaded_mainloop_new() failed!\n");
  735. goto out;
  736. }
  737. if(pa_threaded_mainloop_start(data->loop) < 0)
  738. {
  739. ERR("pa_threaded_mainloop_start() failed\n");
  740. goto out;
  741. }
  742. pa_threaded_mainloop_lock(data->loop);
  743. device->ExtraData = data;
  744. data->context = connect_context(data->loop, AL_FALSE);
  745. if(!data->context)
  746. {
  747. pa_threaded_mainloop_unlock(data->loop);
  748. goto out;
  749. }
  750. pa_context_set_state_callback(data->context, context_state_callback2, device);
  751. pa_threaded_mainloop_unlock(data->loop);
  752. return ALC_TRUE;
  753. out:
  754. if(data->loop)
  755. {
  756. pa_threaded_mainloop_stop(data->loop);
  757. pa_threaded_mainloop_free(data->loop);
  758. }
  759. device->ExtraData = NULL;
  760. pa_xfree(data);
  761. return ALC_FALSE;
  762. }
  763. static void pulse_close(ALCdevice *device)
  764. {
  765. pulse_data *data = device->ExtraData;
  766. pa_threaded_mainloop_lock(data->loop);
  767. if(data->stream)
  768. {
  769. #if PA_CHECK_VERSION(0,9,15)
  770. if(pa_stream_set_buffer_attr_callback)
  771. pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL);
  772. #endif
  773. pa_stream_disconnect(data->stream);
  774. pa_stream_unref(data->stream);
  775. }
  776. pa_context_disconnect(data->context);
  777. pa_context_unref(data->context);
  778. pa_threaded_mainloop_unlock(data->loop);
  779. pa_threaded_mainloop_stop(data->loop);
  780. pa_threaded_mainloop_free(data->loop);
  781. free(data->device_name);
  782. device->ExtraData = NULL;
  783. pa_xfree(data);
  784. }
  785. /* OpenAL */
  786. static ALCenum pulse_open_playback(ALCdevice *device, const ALCchar *device_name)
  787. {
  788. const char *pulse_name = NULL;
  789. pa_stream_flags_t flags;
  790. pa_sample_spec spec;
  791. pulse_data *data;
  792. pa_operation *o;
  793. if(device_name)
  794. {
  795. ALuint i;
  796. if(!allDevNameMap)
  797. probe_devices(AL_FALSE);
  798. for(i = 0;i < numDevNames;i++)
  799. {
  800. if(strcmp(device_name, allDevNameMap[i].name) == 0)
  801. {
  802. pulse_name = allDevNameMap[i].device_name;
  803. break;
  804. }
  805. }
  806. if(i == numDevNames)
  807. return ALC_INVALID_VALUE;
  808. }
  809. if(pulse_open(device) == ALC_FALSE)
  810. return ALC_INVALID_VALUE;
  811. data = device->ExtraData;
  812. pa_threaded_mainloop_lock(data->loop);
  813. flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
  814. PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE;
  815. spec.format = PA_SAMPLE_S16NE;
  816. spec.rate = 44100;
  817. spec.channels = 2;
  818. data->stream = connect_playback_stream(pulse_name, data->loop, data->context,
  819. flags, NULL, &spec, NULL);
  820. if(!data->stream)
  821. {
  822. pa_threaded_mainloop_unlock(data->loop);
  823. pulse_close(device);
  824. return ALC_INVALID_VALUE;
  825. }
  826. data->device_name = strdup(pa_stream_get_device_name(data->stream));
  827. o = pa_context_get_sink_info_by_name(data->context, data->device_name,
  828. sink_name_callback, device);
  829. WAIT_FOR_OPERATION(o, data->loop);
  830. pa_threaded_mainloop_unlock(data->loop);
  831. return ALC_NO_ERROR;
  832. }
  833. static void pulse_close_playback(ALCdevice *device)
  834. {
  835. pulse_close(device);
  836. }
  837. static ALCboolean pulse_reset_playback(ALCdevice *device)
  838. {
  839. pulse_data *data = device->ExtraData;
  840. pa_stream_flags_t flags = 0;
  841. pa_channel_map chanmap;
  842. pa_threaded_mainloop_lock(data->loop);
  843. if(data->stream)
  844. {
  845. #if PA_CHECK_VERSION(0,9,15)
  846. if(pa_stream_set_buffer_attr_callback)
  847. pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL);
  848. #endif
  849. pa_stream_disconnect(data->stream);
  850. pa_stream_unref(data->stream);
  851. data->stream = NULL;
  852. }
  853. if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
  854. {
  855. pa_operation *o;
  856. o = pa_context_get_sink_info_by_name(data->context, data->device_name, sink_info_callback, device);
  857. WAIT_FOR_OPERATION(o, data->loop);
  858. }
  859. if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
  860. flags |= PA_STREAM_FIX_RATE;
  861. flags |= PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE;
  862. flags |= PA_STREAM_ADJUST_LATENCY;
  863. flags |= PA_STREAM_START_CORKED;
  864. flags |= PA_STREAM_DONT_MOVE;
  865. switch(device->FmtType)
  866. {
  867. case DevFmtByte:
  868. device->FmtType = DevFmtUByte;
  869. /* fall-through */
  870. case DevFmtUByte:
  871. data->spec.format = PA_SAMPLE_U8;
  872. break;
  873. case DevFmtUShort:
  874. device->FmtType = DevFmtShort;
  875. /* fall-through */
  876. case DevFmtShort:
  877. data->spec.format = PA_SAMPLE_S16NE;
  878. break;
  879. case DevFmtUInt:
  880. device->FmtType = DevFmtInt;
  881. /* fall-through */
  882. case DevFmtInt:
  883. data->spec.format = PA_SAMPLE_S32NE;
  884. break;
  885. case DevFmtFloat:
  886. data->spec.format = PA_SAMPLE_FLOAT32NE;
  887. break;
  888. }
  889. data->spec.rate = device->Frequency;
  890. data->spec.channels = ChannelsFromDevFmt(device->FmtChans);
  891. if(pa_sample_spec_valid(&data->spec) == 0)
  892. {
  893. ERR("Invalid sample format\n");
  894. pa_threaded_mainloop_unlock(data->loop);
  895. return ALC_FALSE;
  896. }
  897. if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX))
  898. {
  899. ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels);
  900. pa_threaded_mainloop_unlock(data->loop);
  901. return ALC_FALSE;
  902. }
  903. SetDefaultWFXChannelOrder(device);
  904. data->attr.fragsize = -1;
  905. data->attr.prebuf = 0;
  906. data->attr.minreq = device->UpdateSize * pa_frame_size(&data->spec);
  907. data->attr.tlength = data->attr.minreq * maxu(device->NumUpdates, 2);
  908. data->attr.maxlength = -1;
  909. data->stream = connect_playback_stream(data->device_name, data->loop,
  910. data->context, flags, &data->attr,
  911. &data->spec, &chanmap);
  912. if(!data->stream)
  913. {
  914. pa_threaded_mainloop_unlock(data->loop);
  915. return ALC_FALSE;
  916. }
  917. pa_stream_set_state_callback(data->stream, stream_state_callback2, device);
  918. data->spec = *(pa_stream_get_sample_spec(data->stream));
  919. if(device->Frequency != data->spec.rate)
  920. {
  921. pa_operation *o;
  922. /* Server updated our playback rate, so modify the buffer attribs
  923. * accordingly. */
  924. data->attr.minreq = (ALuint64)device->UpdateSize * data->spec.rate /
  925. device->Frequency * pa_frame_size(&data->spec);
  926. data->attr.tlength = data->attr.minreq * maxu(device->NumUpdates, 2);
  927. data->attr.prebuf = 0;
  928. o = pa_stream_set_buffer_attr(data->stream, &data->attr,
  929. stream_success_callback, device);
  930. WAIT_FOR_OPERATION(o, data->loop);
  931. device->Frequency = data->spec.rate;
  932. }
  933. #if PA_CHECK_VERSION(0,9,15)
  934. if(pa_stream_set_buffer_attr_callback)
  935. pa_stream_set_buffer_attr_callback(data->stream, stream_buffer_attr_callback, device);
  936. #endif
  937. stream_buffer_attr_callback(data->stream, device);
  938. device->NumUpdates = device->UpdateSize*device->NumUpdates /
  939. (data->attr.minreq/pa_frame_size(&data->spec));
  940. device->NumUpdates = maxu(device->NumUpdates, 2);
  941. device->UpdateSize = data->attr.minreq / pa_frame_size(&data->spec);
  942. pa_threaded_mainloop_unlock(data->loop);
  943. return ALC_TRUE;
  944. }
  945. static ALCboolean pulse_start_playback(ALCdevice *device)
  946. {
  947. pulse_data *data = device->ExtraData;
  948. data->thread = StartThread(PulseProc, device);
  949. if(!data->thread)
  950. return ALC_FALSE;
  951. return ALC_TRUE;
  952. }
  953. static void pulse_stop_playback(ALCdevice *device)
  954. {
  955. pulse_data *data = device->ExtraData;
  956. pa_operation *o;
  957. if(!data->stream)
  958. return;
  959. data->killNow = AL_TRUE;
  960. if(data->thread)
  961. {
  962. StopThread(data->thread);
  963. data->thread = NULL;
  964. }
  965. data->killNow = AL_FALSE;
  966. pa_threaded_mainloop_lock(data->loop);
  967. o = pa_stream_cork(data->stream, 1, stream_success_callback, device);
  968. WAIT_FOR_OPERATION(o, data->loop);
  969. pa_threaded_mainloop_unlock(data->loop);
  970. }
  971. static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name)
  972. {
  973. const char *pulse_name = NULL;
  974. pa_stream_flags_t flags = 0;
  975. pa_channel_map chanmap;
  976. pulse_data *data;
  977. pa_operation *o;
  978. ALuint samples;
  979. if(device_name)
  980. {
  981. ALuint i;
  982. if(!allCaptureDevNameMap)
  983. probe_devices(AL_TRUE);
  984. for(i = 0;i < numCaptureDevNames;i++)
  985. {
  986. if(strcmp(device_name, allCaptureDevNameMap[i].name) == 0)
  987. {
  988. pulse_name = allCaptureDevNameMap[i].device_name;
  989. break;
  990. }
  991. }
  992. if(i == numCaptureDevNames)
  993. return ALC_INVALID_VALUE;
  994. }
  995. if(pulse_open(device) == ALC_FALSE)
  996. return ALC_INVALID_VALUE;
  997. data = device->ExtraData;
  998. pa_threaded_mainloop_lock(data->loop);
  999. data->spec.rate = device->Frequency;
  1000. data->spec.channels = ChannelsFromDevFmt(device->FmtChans);
  1001. switch(device->FmtType)
  1002. {
  1003. case DevFmtUByte:
  1004. data->spec.format = PA_SAMPLE_U8;
  1005. break;
  1006. case DevFmtShort:
  1007. data->spec.format = PA_SAMPLE_S16NE;
  1008. break;
  1009. case DevFmtInt:
  1010. data->spec.format = PA_SAMPLE_S32NE;
  1011. break;
  1012. case DevFmtFloat:
  1013. data->spec.format = PA_SAMPLE_FLOAT32NE;
  1014. break;
  1015. case DevFmtByte:
  1016. case DevFmtUShort:
  1017. case DevFmtUInt:
  1018. ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
  1019. pa_threaded_mainloop_unlock(data->loop);
  1020. goto fail;
  1021. }
  1022. if(pa_sample_spec_valid(&data->spec) == 0)
  1023. {
  1024. ERR("Invalid sample format\n");
  1025. pa_threaded_mainloop_unlock(data->loop);
  1026. goto fail;
  1027. }
  1028. if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX))
  1029. {
  1030. ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels);
  1031. pa_threaded_mainloop_unlock(data->loop);
  1032. goto fail;
  1033. }
  1034. samples = device->UpdateSize * device->NumUpdates;
  1035. samples = maxu(samples, 100 * device->Frequency / 1000);
  1036. data->attr.minreq = -1;
  1037. data->attr.prebuf = -1;
  1038. data->attr.maxlength = samples * pa_frame_size(&data->spec);
  1039. data->attr.tlength = -1;
  1040. data->attr.fragsize = minu(samples, 50*device->Frequency/1000) *
  1041. pa_frame_size(&data->spec);
  1042. flags |= PA_STREAM_DONT_MOVE;
  1043. flags |= PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY;
  1044. data->stream = connect_record_stream(pulse_name, data->loop, data->context,
  1045. flags, &data->attr, &data->spec,
  1046. &chanmap);
  1047. if(!data->stream)
  1048. {
  1049. pa_threaded_mainloop_unlock(data->loop);
  1050. goto fail;
  1051. }
  1052. pa_stream_set_state_callback(data->stream, stream_state_callback2, device);
  1053. data->device_name = strdup(pa_stream_get_device_name(data->stream));
  1054. o = pa_context_get_source_info_by_name(data->context, data->device_name,
  1055. source_name_callback, device);
  1056. WAIT_FOR_OPERATION(o, data->loop);
  1057. pa_threaded_mainloop_unlock(data->loop);
  1058. return ALC_NO_ERROR;
  1059. fail:
  1060. pulse_close(device);
  1061. return ALC_INVALID_VALUE;
  1062. }
  1063. static void pulse_close_capture(ALCdevice *device)
  1064. {
  1065. pulse_close(device);
  1066. }
  1067. static void pulse_start_capture(ALCdevice *device)
  1068. {
  1069. pulse_data *data = device->ExtraData;
  1070. pa_operation *o;
  1071. pa_threaded_mainloop_lock(data->loop);
  1072. o = pa_stream_cork(data->stream, 0, stream_success_callback, device);
  1073. WAIT_FOR_OPERATION(o, data->loop);
  1074. pa_threaded_mainloop_unlock(data->loop);
  1075. }
  1076. static void pulse_stop_capture(ALCdevice *device)
  1077. {
  1078. pulse_data *data = device->ExtraData;
  1079. pa_operation *o;
  1080. pa_threaded_mainloop_lock(data->loop);
  1081. o = pa_stream_cork(data->stream, 1, stream_success_callback, device);
  1082. WAIT_FOR_OPERATION(o, data->loop);
  1083. pa_threaded_mainloop_unlock(data->loop);
  1084. }
  1085. static ALCenum pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
  1086. {
  1087. pulse_data *data = device->ExtraData;
  1088. ALCuint todo = samples * pa_frame_size(&data->spec);
  1089. pa_threaded_mainloop_lock(data->loop);
  1090. /* Capture is done in fragment-sized chunks, so we loop until we get all
  1091. * that's available */
  1092. data->last_readable -= todo;
  1093. while(todo > 0)
  1094. {
  1095. size_t rem = todo;
  1096. if(data->cap_len == 0)
  1097. {
  1098. pa_stream_state_t state;
  1099. state = pa_stream_get_state(data->stream);
  1100. if(!PA_STREAM_IS_GOOD(state))
  1101. {
  1102. aluHandleDisconnect(device);
  1103. break;
  1104. }
  1105. if(pa_stream_peek(data->stream, &data->cap_store, &data->cap_len) < 0)
  1106. {
  1107. ERR("pa_stream_peek() failed: %s\n",
  1108. pa_strerror(pa_context_errno(data->context)));
  1109. aluHandleDisconnect(device);
  1110. break;
  1111. }
  1112. data->cap_remain = data->cap_len;
  1113. }
  1114. if(rem > data->cap_remain)
  1115. rem = data->cap_remain;
  1116. memcpy(buffer, data->cap_store, rem);
  1117. buffer = (ALbyte*)buffer + rem;
  1118. todo -= rem;
  1119. data->cap_store = (ALbyte*)data->cap_store + rem;
  1120. data->cap_remain -= rem;
  1121. if(data->cap_remain == 0)
  1122. {
  1123. pa_stream_drop(data->stream);
  1124. data->cap_len = 0;
  1125. }
  1126. }
  1127. if(todo > 0)
  1128. memset(buffer, ((device->FmtType==DevFmtUByte) ? 0x80 : 0), todo);
  1129. pa_threaded_mainloop_unlock(data->loop);
  1130. return ALC_NO_ERROR;
  1131. }
  1132. static ALCuint pulse_available_samples(ALCdevice *device)
  1133. {
  1134. pulse_data *data = device->ExtraData;
  1135. size_t readable = data->cap_remain;
  1136. pa_threaded_mainloop_lock(data->loop);
  1137. if(device->Connected)
  1138. {
  1139. ssize_t got = pa_stream_readable_size(data->stream);
  1140. if(got < 0)
  1141. {
  1142. ERR("pa_stream_readable_size() failed: %s\n", pa_strerror(got));
  1143. aluHandleDisconnect(device);
  1144. }
  1145. else if((size_t)got > data->cap_len)
  1146. readable += got - data->cap_len;
  1147. }
  1148. pa_threaded_mainloop_unlock(data->loop);
  1149. if(data->last_readable < readable)
  1150. data->last_readable = readable;
  1151. return data->last_readable / pa_frame_size(&data->spec);
  1152. }
  1153. static const BackendFuncs pulse_funcs = {
  1154. pulse_open_playback,
  1155. pulse_close_playback,
  1156. pulse_reset_playback,
  1157. pulse_start_playback,
  1158. pulse_stop_playback,
  1159. pulse_open_capture,
  1160. pulse_close_capture,
  1161. pulse_start_capture,
  1162. pulse_stop_capture,
  1163. pulse_capture_samples,
  1164. pulse_available_samples
  1165. };
  1166. ALCboolean alc_pulse_init(BackendFuncs *func_list)
  1167. {
  1168. ALCboolean ret = ALC_FALSE;
  1169. if(pulse_load())
  1170. {
  1171. pa_threaded_mainloop *loop;
  1172. pulse_ctx_flags = 0;
  1173. if(!GetConfigValueBool("pulse", "spawn-server", 0))
  1174. pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN;
  1175. if((loop=pa_threaded_mainloop_new()) &&
  1176. pa_threaded_mainloop_start(loop) >= 0)
  1177. {
  1178. pa_context *context;
  1179. pa_threaded_mainloop_lock(loop);
  1180. context = connect_context(loop, AL_TRUE);
  1181. if(context)
  1182. {
  1183. *func_list = pulse_funcs;
  1184. ret = ALC_TRUE;
  1185. /* Some libraries (Phonon, Qt) set some pulseaudio properties
  1186. * through environment variables, which causes all streams in
  1187. * the process to inherit them. This attempts to filter those
  1188. * properties out by setting them to 0-length data. */
  1189. prop_filter = pa_proplist_new();
  1190. pa_proplist_set(prop_filter, PA_PROP_MEDIA_ROLE, NULL, 0);
  1191. pa_proplist_set(prop_filter, "phonon.streamid", NULL, 0);
  1192. pa_context_disconnect(context);
  1193. pa_context_unref(context);
  1194. }
  1195. pa_threaded_mainloop_unlock(loop);
  1196. pa_threaded_mainloop_stop(loop);
  1197. }
  1198. if(loop)
  1199. pa_threaded_mainloop_free(loop);
  1200. }
  1201. return ret;
  1202. }
  1203. void alc_pulse_deinit(void)
  1204. {
  1205. ALuint i;
  1206. for(i = 0;i < numDevNames;++i)
  1207. {
  1208. free(allDevNameMap[i].name);
  1209. free(allDevNameMap[i].device_name);
  1210. }
  1211. free(allDevNameMap);
  1212. allDevNameMap = NULL;
  1213. numDevNames = 0;
  1214. for(i = 0;i < numCaptureDevNames;++i)
  1215. {
  1216. free(allCaptureDevNameMap[i].name);
  1217. free(allCaptureDevNameMap[i].device_name);
  1218. }
  1219. free(allCaptureDevNameMap);
  1220. allCaptureDevNameMap = NULL;
  1221. numCaptureDevNames = 0;
  1222. if(prop_filter)
  1223. pa_proplist_free(prop_filter);
  1224. prop_filter = NULL;
  1225. /* PulseAudio doesn't like being CloseLib'd sometimes */
  1226. }
  1227. void alc_pulse_probe(enum DevProbe type)
  1228. {
  1229. ALuint i;
  1230. switch(type)
  1231. {
  1232. case ALL_DEVICE_PROBE:
  1233. for(i = 0;i < numDevNames;++i)
  1234. {
  1235. free(allDevNameMap[i].name);
  1236. free(allDevNameMap[i].device_name);
  1237. }
  1238. free(allDevNameMap);
  1239. allDevNameMap = NULL;
  1240. numDevNames = 0;
  1241. probe_devices(AL_FALSE);
  1242. for(i = 0;i < numDevNames;i++)
  1243. AppendAllDeviceList(allDevNameMap[i].name);
  1244. break;
  1245. case CAPTURE_DEVICE_PROBE:
  1246. for(i = 0;i < numCaptureDevNames;++i)
  1247. {
  1248. free(allCaptureDevNameMap[i].name);
  1249. free(allCaptureDevNameMap[i].device_name);
  1250. }
  1251. free(allCaptureDevNameMap);
  1252. allCaptureDevNameMap = NULL;
  1253. numCaptureDevNames = 0;
  1254. probe_devices(AL_TRUE);
  1255. for(i = 0;i < numCaptureDevNames;i++)
  1256. AppendCaptureDeviceList(allCaptureDevNameMap[i].name);
  1257. break;
  1258. }
  1259. }
  1260. #else
  1261. #warning "Unsupported API version, backend will be unavailable!"
  1262. ALCboolean alc_pulse_init(BackendFuncs *func_list)
  1263. { return ALC_FALSE; (void)func_list; }
  1264. void alc_pulse_deinit(void)
  1265. { }
  1266. void alc_pulse_probe(enum DevProbe type)
  1267. { (void)type; }
  1268. #endif