paaudio.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. /* public domain */
  2. #include "qemu/osdep.h"
  3. #include "qemu/module.h"
  4. #include "audio.h"
  5. #include "qapi/error.h"
  6. #include <pulse/pulseaudio.h>
  7. #define AUDIO_CAP "pulseaudio"
  8. #include "audio_int.h"
  9. typedef struct PAConnection {
  10. char *server;
  11. int refcount;
  12. QTAILQ_ENTRY(PAConnection) list;
  13. pa_threaded_mainloop *mainloop;
  14. pa_context *context;
  15. } PAConnection;
  16. static QTAILQ_HEAD(PAConnectionHead, PAConnection) pa_conns =
  17. QTAILQ_HEAD_INITIALIZER(pa_conns);
  18. typedef struct {
  19. Audiodev *dev;
  20. PAConnection *conn;
  21. } paaudio;
  22. typedef struct {
  23. HWVoiceOut hw;
  24. pa_stream *stream;
  25. paaudio *g;
  26. } PAVoiceOut;
  27. typedef struct {
  28. HWVoiceIn hw;
  29. pa_stream *stream;
  30. const void *read_data;
  31. size_t read_length;
  32. paaudio *g;
  33. } PAVoiceIn;
  34. static void qpa_conn_fini(PAConnection *c);
  35. static void G_GNUC_PRINTF (2, 3) qpa_logerr (int err, const char *fmt, ...)
  36. {
  37. va_list ap;
  38. va_start (ap, fmt);
  39. AUD_vlog (AUDIO_CAP, fmt, ap);
  40. va_end (ap);
  41. AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
  42. }
  43. #ifndef PA_CONTEXT_IS_GOOD
  44. static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
  45. {
  46. return
  47. x == PA_CONTEXT_CONNECTING ||
  48. x == PA_CONTEXT_AUTHORIZING ||
  49. x == PA_CONTEXT_SETTING_NAME ||
  50. x == PA_CONTEXT_READY;
  51. }
  52. #endif
  53. #ifndef PA_STREAM_IS_GOOD
  54. static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
  55. {
  56. return
  57. x == PA_STREAM_CREATING ||
  58. x == PA_STREAM_READY;
  59. }
  60. #endif
  61. #define CHECK_SUCCESS_GOTO(c, expression, label, msg) \
  62. do { \
  63. if (!(expression)) { \
  64. qpa_logerr(pa_context_errno((c)->context), msg); \
  65. goto label; \
  66. } \
  67. } while (0)
  68. #define CHECK_DEAD_GOTO(c, stream, label, msg) \
  69. do { \
  70. if (!(c)->context || !PA_CONTEXT_IS_GOOD (pa_context_get_state((c)->context)) || \
  71. !(stream) || !PA_STREAM_IS_GOOD (pa_stream_get_state ((stream)))) { \
  72. if (((c)->context && pa_context_get_state ((c)->context) == PA_CONTEXT_FAILED) || \
  73. ((stream) && pa_stream_get_state ((stream)) == PA_STREAM_FAILED)) { \
  74. qpa_logerr(pa_context_errno((c)->context), msg); \
  75. } else { \
  76. qpa_logerr(PA_ERR_BADSTATE, msg); \
  77. } \
  78. goto label; \
  79. } \
  80. } while (0)
  81. static void *qpa_get_buffer_in(HWVoiceIn *hw, size_t *size)
  82. {
  83. PAVoiceIn *p = (PAVoiceIn *) hw;
  84. PAConnection *c = p->g->conn;
  85. int r;
  86. pa_threaded_mainloop_lock(c->mainloop);
  87. CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
  88. "pa_threaded_mainloop_lock failed\n");
  89. if (!p->read_length) {
  90. r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
  91. CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
  92. "pa_stream_peek failed\n");
  93. }
  94. *size = MIN(p->read_length, *size);
  95. pa_threaded_mainloop_unlock(c->mainloop);
  96. return (void *) p->read_data;
  97. unlock_and_fail:
  98. pa_threaded_mainloop_unlock(c->mainloop);
  99. *size = 0;
  100. return NULL;
  101. }
  102. static void qpa_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
  103. {
  104. PAVoiceIn *p = (PAVoiceIn *) hw;
  105. PAConnection *c = p->g->conn;
  106. int r;
  107. pa_threaded_mainloop_lock(c->mainloop);
  108. CHECK_DEAD_GOTO(c, p->stream, unlock,
  109. "pa_threaded_mainloop_lock failed\n");
  110. assert(buf == p->read_data && size <= p->read_length);
  111. p->read_data += size;
  112. p->read_length -= size;
  113. if (size && !p->read_length) {
  114. r = pa_stream_drop(p->stream);
  115. CHECK_SUCCESS_GOTO(c, r == 0, unlock, "pa_stream_drop failed\n");
  116. }
  117. unlock:
  118. pa_threaded_mainloop_unlock(c->mainloop);
  119. }
  120. static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
  121. {
  122. PAVoiceIn *p = (PAVoiceIn *) hw;
  123. PAConnection *c = p->g->conn;
  124. size_t total = 0;
  125. pa_threaded_mainloop_lock(c->mainloop);
  126. CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
  127. "pa_threaded_mainloop_lock failed\n");
  128. if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
  129. /* wait for stream to become ready */
  130. goto unlock;
  131. }
  132. while (total < length) {
  133. size_t l;
  134. int r;
  135. if (!p->read_length) {
  136. r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
  137. CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
  138. "pa_stream_peek failed\n");
  139. if (!p->read_length) {
  140. /* buffer is empty */
  141. break;
  142. }
  143. }
  144. l = MIN(p->read_length, length - total);
  145. memcpy((char *)data + total, p->read_data, l);
  146. p->read_data += l;
  147. p->read_length -= l;
  148. total += l;
  149. if (!p->read_length) {
  150. r = pa_stream_drop(p->stream);
  151. CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
  152. "pa_stream_drop failed\n");
  153. }
  154. }
  155. unlock:
  156. pa_threaded_mainloop_unlock(c->mainloop);
  157. return total;
  158. unlock_and_fail:
  159. pa_threaded_mainloop_unlock(c->mainloop);
  160. return 0;
  161. }
  162. static size_t qpa_buffer_get_free(HWVoiceOut *hw)
  163. {
  164. PAVoiceOut *p = (PAVoiceOut *)hw;
  165. PAConnection *c = p->g->conn;
  166. size_t l;
  167. pa_threaded_mainloop_lock(c->mainloop);
  168. CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
  169. "pa_threaded_mainloop_lock failed\n");
  170. if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
  171. /* wait for stream to become ready */
  172. l = 0;
  173. goto unlock;
  174. }
  175. l = pa_stream_writable_size(p->stream);
  176. CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail,
  177. "pa_stream_writable_size failed\n");
  178. unlock:
  179. pa_threaded_mainloop_unlock(c->mainloop);
  180. return l;
  181. unlock_and_fail:
  182. pa_threaded_mainloop_unlock(c->mainloop);
  183. return 0;
  184. }
  185. static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
  186. {
  187. PAVoiceOut *p = (PAVoiceOut *)hw;
  188. PAConnection *c = p->g->conn;
  189. void *ret;
  190. int r;
  191. pa_threaded_mainloop_lock(c->mainloop);
  192. CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
  193. "pa_threaded_mainloop_lock failed\n");
  194. *size = -1;
  195. r = pa_stream_begin_write(p->stream, &ret, size);
  196. CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail,
  197. "pa_stream_begin_write failed\n");
  198. pa_threaded_mainloop_unlock(c->mainloop);
  199. return ret;
  200. unlock_and_fail:
  201. pa_threaded_mainloop_unlock(c->mainloop);
  202. *size = 0;
  203. return NULL;
  204. }
  205. static size_t qpa_put_buffer_out(HWVoiceOut *hw, void *data, size_t length)
  206. {
  207. PAVoiceOut *p = (PAVoiceOut *)hw;
  208. PAConnection *c = p->g->conn;
  209. int r;
  210. pa_threaded_mainloop_lock(c->mainloop);
  211. CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
  212. "pa_threaded_mainloop_lock failed\n");
  213. r = pa_stream_write(p->stream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
  214. CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail, "pa_stream_write failed\n");
  215. pa_threaded_mainloop_unlock(c->mainloop);
  216. return length;
  217. unlock_and_fail:
  218. pa_threaded_mainloop_unlock(c->mainloop);
  219. return 0;
  220. }
  221. static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length)
  222. {
  223. PAVoiceOut *p = (PAVoiceOut *) hw;
  224. PAConnection *c = p->g->conn;
  225. size_t l;
  226. int r;
  227. pa_threaded_mainloop_lock(c->mainloop);
  228. CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
  229. "pa_threaded_mainloop_lock failed\n");
  230. if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
  231. /* wait for stream to become ready */
  232. l = 0;
  233. goto unlock;
  234. }
  235. l = pa_stream_writable_size(p->stream);
  236. CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail,
  237. "pa_stream_writable_size failed\n");
  238. if (l > length) {
  239. l = length;
  240. }
  241. r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
  242. CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail, "pa_stream_write failed\n");
  243. unlock:
  244. pa_threaded_mainloop_unlock(c->mainloop);
  245. return l;
  246. unlock_and_fail:
  247. pa_threaded_mainloop_unlock(c->mainloop);
  248. return 0;
  249. }
  250. static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness)
  251. {
  252. int format;
  253. switch (afmt) {
  254. case AUDIO_FORMAT_S8:
  255. case AUDIO_FORMAT_U8:
  256. format = PA_SAMPLE_U8;
  257. break;
  258. case AUDIO_FORMAT_S16:
  259. case AUDIO_FORMAT_U16:
  260. format = endianness ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
  261. break;
  262. case AUDIO_FORMAT_S32:
  263. case AUDIO_FORMAT_U32:
  264. format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
  265. break;
  266. case AUDIO_FORMAT_F32:
  267. format = endianness ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
  268. break;
  269. default:
  270. dolog ("Internal logic error: Bad audio format %d\n", afmt);
  271. format = PA_SAMPLE_U8;
  272. break;
  273. }
  274. return format;
  275. }
  276. static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
  277. {
  278. switch (fmt) {
  279. case PA_SAMPLE_U8:
  280. return AUDIO_FORMAT_U8;
  281. case PA_SAMPLE_S16BE:
  282. *endianness = 1;
  283. return AUDIO_FORMAT_S16;
  284. case PA_SAMPLE_S16LE:
  285. *endianness = 0;
  286. return AUDIO_FORMAT_S16;
  287. case PA_SAMPLE_S32BE:
  288. *endianness = 1;
  289. return AUDIO_FORMAT_S32;
  290. case PA_SAMPLE_S32LE:
  291. *endianness = 0;
  292. return AUDIO_FORMAT_S32;
  293. case PA_SAMPLE_FLOAT32BE:
  294. *endianness = 1;
  295. return AUDIO_FORMAT_F32;
  296. case PA_SAMPLE_FLOAT32LE:
  297. *endianness = 0;
  298. return AUDIO_FORMAT_F32;
  299. default:
  300. dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt);
  301. return AUDIO_FORMAT_U8;
  302. }
  303. }
  304. static void context_state_cb (pa_context *c, void *userdata)
  305. {
  306. PAConnection *conn = userdata;
  307. switch (pa_context_get_state(c)) {
  308. case PA_CONTEXT_READY:
  309. case PA_CONTEXT_TERMINATED:
  310. case PA_CONTEXT_FAILED:
  311. pa_threaded_mainloop_signal(conn->mainloop, 0);
  312. break;
  313. case PA_CONTEXT_UNCONNECTED:
  314. case PA_CONTEXT_CONNECTING:
  315. case PA_CONTEXT_AUTHORIZING:
  316. case PA_CONTEXT_SETTING_NAME:
  317. break;
  318. }
  319. }
  320. static void stream_state_cb (pa_stream *s, void * userdata)
  321. {
  322. PAConnection *c = userdata;
  323. switch (pa_stream_get_state (s)) {
  324. case PA_STREAM_READY:
  325. case PA_STREAM_FAILED:
  326. case PA_STREAM_TERMINATED:
  327. pa_threaded_mainloop_signal(c->mainloop, 0);
  328. break;
  329. case PA_STREAM_UNCONNECTED:
  330. case PA_STREAM_CREATING:
  331. break;
  332. }
  333. }
  334. static pa_stream *qpa_simple_new (
  335. PAConnection *c,
  336. const char *name,
  337. pa_stream_direction_t dir,
  338. const char *dev,
  339. const pa_sample_spec *ss,
  340. const pa_buffer_attr *attr,
  341. int *rerror)
  342. {
  343. int r;
  344. pa_stream *stream = NULL;
  345. pa_stream_flags_t flags;
  346. pa_channel_map map;
  347. pa_threaded_mainloop_lock(c->mainloop);
  348. pa_channel_map_init(&map);
  349. map.channels = ss->channels;
  350. /*
  351. * TODO: This currently expects the only frontend supporting more than 2
  352. * channels is the usb-audio. We will need some means to set channel
  353. * order when a new frontend gains multi-channel support.
  354. */
  355. switch (ss->channels) {
  356. case 1:
  357. map.map[0] = PA_CHANNEL_POSITION_MONO;
  358. break;
  359. case 2:
  360. map.map[0] = PA_CHANNEL_POSITION_LEFT;
  361. map.map[1] = PA_CHANNEL_POSITION_RIGHT;
  362. break;
  363. case 6:
  364. map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
  365. map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
  366. map.map[2] = PA_CHANNEL_POSITION_CENTER;
  367. map.map[3] = PA_CHANNEL_POSITION_LFE;
  368. map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
  369. map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
  370. break;
  371. case 8:
  372. map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
  373. map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
  374. map.map[2] = PA_CHANNEL_POSITION_CENTER;
  375. map.map[3] = PA_CHANNEL_POSITION_LFE;
  376. map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
  377. map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
  378. map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
  379. map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
  380. break;
  381. default:
  382. dolog("Internal error: unsupported channel count %d\n", ss->channels);
  383. goto fail;
  384. }
  385. stream = pa_stream_new(c->context, name, ss, &map);
  386. if (!stream) {
  387. goto fail;
  388. }
  389. pa_stream_set_state_callback(stream, stream_state_cb, c);
  390. flags = PA_STREAM_EARLY_REQUESTS;
  391. if (dev) {
  392. /* don't move the stream if the user specified a sink/source */
  393. flags |= PA_STREAM_DONT_MOVE;
  394. }
  395. if (dir == PA_STREAM_PLAYBACK) {
  396. r = pa_stream_connect_playback(stream, dev, attr, flags, NULL, NULL);
  397. } else {
  398. r = pa_stream_connect_record(stream, dev, attr, flags);
  399. }
  400. if (r < 0) {
  401. goto fail;
  402. }
  403. pa_threaded_mainloop_unlock(c->mainloop);
  404. return stream;
  405. fail:
  406. pa_threaded_mainloop_unlock(c->mainloop);
  407. if (stream) {
  408. pa_stream_unref (stream);
  409. }
  410. *rerror = pa_context_errno(c->context);
  411. return NULL;
  412. }
  413. static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
  414. void *drv_opaque)
  415. {
  416. int error;
  417. pa_sample_spec ss;
  418. pa_buffer_attr ba;
  419. struct audsettings obt_as = *as;
  420. PAVoiceOut *pa = (PAVoiceOut *) hw;
  421. paaudio *g = pa->g = drv_opaque;
  422. AudiodevPaOptions *popts = &g->dev->u.pa;
  423. AudiodevPaPerDirectionOptions *ppdo = popts->out;
  424. PAConnection *c = g->conn;
  425. ss.format = audfmt_to_pa (as->fmt, as->endianness);
  426. ss.channels = as->nchannels;
  427. ss.rate = as->freq;
  428. ba.tlength = pa_usec_to_bytes(ppdo->latency, &ss);
  429. ba.minreq = pa_usec_to_bytes(MIN(ppdo->latency >> 2,
  430. (g->dev->timer_period >> 2) * 3), &ss);
  431. ba.maxlength = -1;
  432. ba.prebuf = -1;
  433. obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
  434. pa->stream = qpa_simple_new (
  435. c,
  436. ppdo->stream_name ?: g->dev->id,
  437. PA_STREAM_PLAYBACK,
  438. ppdo->name,
  439. &ss,
  440. &ba, /* buffering attributes */
  441. &error
  442. );
  443. if (!pa->stream) {
  444. qpa_logerr (error, "pa_simple_new for playback failed\n");
  445. goto fail1;
  446. }
  447. audio_pcm_init_info (&hw->info, &obt_as);
  448. /* hw->samples counts in frames */
  449. hw->samples = audio_buffer_frames(
  450. qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440);
  451. return 0;
  452. fail1:
  453. return -1;
  454. }
  455. static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
  456. {
  457. int error;
  458. pa_sample_spec ss;
  459. pa_buffer_attr ba;
  460. struct audsettings obt_as = *as;
  461. PAVoiceIn *pa = (PAVoiceIn *) hw;
  462. paaudio *g = pa->g = drv_opaque;
  463. AudiodevPaOptions *popts = &g->dev->u.pa;
  464. AudiodevPaPerDirectionOptions *ppdo = popts->in;
  465. PAConnection *c = g->conn;
  466. ss.format = audfmt_to_pa (as->fmt, as->endianness);
  467. ss.channels = as->nchannels;
  468. ss.rate = as->freq;
  469. ba.fragsize = pa_usec_to_bytes((g->dev->timer_period >> 1) * 3, &ss);
  470. ba.maxlength = pa_usec_to_bytes(
  471. MAX(ppdo->latency, g->dev->timer_period * 3), &ss);
  472. ba.minreq = -1;
  473. ba.prebuf = -1;
  474. obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
  475. pa->stream = qpa_simple_new (
  476. c,
  477. ppdo->stream_name ?: g->dev->id,
  478. PA_STREAM_RECORD,
  479. ppdo->name,
  480. &ss,
  481. &ba, /* buffering attributes */
  482. &error
  483. );
  484. if (!pa->stream) {
  485. qpa_logerr (error, "pa_simple_new for capture failed\n");
  486. goto fail1;
  487. }
  488. audio_pcm_init_info (&hw->info, &obt_as);
  489. /* hw->samples counts in frames */
  490. hw->samples = audio_buffer_frames(
  491. qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440);
  492. return 0;
  493. fail1:
  494. return -1;
  495. }
  496. static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
  497. {
  498. int err;
  499. /*
  500. * wait until actually connects. workaround pa bug #247
  501. * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247
  502. */
  503. while (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
  504. pa_threaded_mainloop_wait(c->mainloop);
  505. }
  506. err = pa_stream_disconnect(stream);
  507. if (err != 0) {
  508. dolog("Failed to disconnect! err=%d\n", err);
  509. }
  510. pa_stream_unref(stream);
  511. }
  512. static void qpa_fini_out (HWVoiceOut *hw)
  513. {
  514. PAVoiceOut *pa = (PAVoiceOut *) hw;
  515. if (pa->stream) {
  516. PAConnection *c = pa->g->conn;
  517. pa_threaded_mainloop_lock(c->mainloop);
  518. qpa_simple_disconnect(c, pa->stream);
  519. pa->stream = NULL;
  520. pa_threaded_mainloop_unlock(c->mainloop);
  521. }
  522. }
  523. static void qpa_fini_in (HWVoiceIn *hw)
  524. {
  525. PAVoiceIn *pa = (PAVoiceIn *) hw;
  526. if (pa->stream) {
  527. PAConnection *c = pa->g->conn;
  528. pa_threaded_mainloop_lock(c->mainloop);
  529. if (pa->read_length) {
  530. int r = pa_stream_drop(pa->stream);
  531. if (r) {
  532. qpa_logerr(pa_context_errno(c->context),
  533. "pa_stream_drop failed\n");
  534. }
  535. pa->read_length = 0;
  536. }
  537. qpa_simple_disconnect(c, pa->stream);
  538. pa->stream = NULL;
  539. pa_threaded_mainloop_unlock(c->mainloop);
  540. }
  541. }
  542. static void qpa_volume_out(HWVoiceOut *hw, Volume *vol)
  543. {
  544. PAVoiceOut *pa = (PAVoiceOut *) hw;
  545. pa_operation *op;
  546. pa_cvolume v;
  547. PAConnection *c = pa->g->conn;
  548. int i;
  549. #ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */
  550. pa_cvolume_init (&v); /* function is present in 0.9.13+ */
  551. #endif
  552. v.channels = vol->channels;
  553. for (i = 0; i < vol->channels; ++i) {
  554. v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255;
  555. }
  556. pa_threaded_mainloop_lock(c->mainloop);
  557. op = pa_context_set_sink_input_volume(c->context,
  558. pa_stream_get_index(pa->stream),
  559. &v, NULL, NULL);
  560. if (!op) {
  561. qpa_logerr(pa_context_errno(c->context),
  562. "set_sink_input_volume() failed\n");
  563. } else {
  564. pa_operation_unref(op);
  565. }
  566. op = pa_context_set_sink_input_mute(c->context,
  567. pa_stream_get_index(pa->stream),
  568. vol->mute, NULL, NULL);
  569. if (!op) {
  570. qpa_logerr(pa_context_errno(c->context),
  571. "set_sink_input_mute() failed\n");
  572. } else {
  573. pa_operation_unref(op);
  574. }
  575. pa_threaded_mainloop_unlock(c->mainloop);
  576. }
  577. static void qpa_volume_in(HWVoiceIn *hw, Volume *vol)
  578. {
  579. PAVoiceIn *pa = (PAVoiceIn *) hw;
  580. pa_operation *op;
  581. pa_cvolume v;
  582. PAConnection *c = pa->g->conn;
  583. int i;
  584. #ifdef PA_CHECK_VERSION
  585. pa_cvolume_init (&v);
  586. #endif
  587. v.channels = vol->channels;
  588. for (i = 0; i < vol->channels; ++i) {
  589. v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255;
  590. }
  591. pa_threaded_mainloop_lock(c->mainloop);
  592. op = pa_context_set_source_output_volume(c->context,
  593. pa_stream_get_index(pa->stream),
  594. &v, NULL, NULL);
  595. if (!op) {
  596. qpa_logerr(pa_context_errno(c->context),
  597. "set_source_output_volume() failed\n");
  598. } else {
  599. pa_operation_unref(op);
  600. }
  601. op = pa_context_set_source_output_mute(c->context,
  602. pa_stream_get_index(pa->stream),
  603. vol->mute, NULL, NULL);
  604. if (!op) {
  605. qpa_logerr(pa_context_errno(c->context),
  606. "set_source_output_mute() failed\n");
  607. } else {
  608. pa_operation_unref(op);
  609. }
  610. pa_threaded_mainloop_unlock(c->mainloop);
  611. }
  612. static int qpa_validate_per_direction_opts(Audiodev *dev,
  613. AudiodevPaPerDirectionOptions *pdo)
  614. {
  615. if (!pdo->has_latency) {
  616. pdo->has_latency = true;
  617. pdo->latency = 46440;
  618. }
  619. return 1;
  620. }
  621. /* common */
  622. static void *qpa_conn_init(const char *server)
  623. {
  624. PAConnection *c = g_new0(PAConnection, 1);
  625. QTAILQ_INSERT_TAIL(&pa_conns, c, list);
  626. c->mainloop = pa_threaded_mainloop_new();
  627. if (!c->mainloop) {
  628. goto fail;
  629. }
  630. c->context = pa_context_new(pa_threaded_mainloop_get_api(c->mainloop),
  631. audio_application_name());
  632. if (!c->context) {
  633. goto fail;
  634. }
  635. pa_context_set_state_callback(c->context, context_state_cb, c);
  636. if (pa_context_connect(c->context, server, 0, NULL) < 0) {
  637. qpa_logerr(pa_context_errno(c->context),
  638. "pa_context_connect() failed\n");
  639. goto fail;
  640. }
  641. pa_threaded_mainloop_lock(c->mainloop);
  642. if (pa_threaded_mainloop_start(c->mainloop) < 0) {
  643. goto unlock_and_fail;
  644. }
  645. for (;;) {
  646. pa_context_state_t state;
  647. state = pa_context_get_state(c->context);
  648. if (state == PA_CONTEXT_READY) {
  649. break;
  650. }
  651. if (!PA_CONTEXT_IS_GOOD(state)) {
  652. qpa_logerr(pa_context_errno(c->context),
  653. "Wrong context state\n");
  654. goto unlock_and_fail;
  655. }
  656. /* Wait until the context is ready */
  657. pa_threaded_mainloop_wait(c->mainloop);
  658. }
  659. pa_threaded_mainloop_unlock(c->mainloop);
  660. return c;
  661. unlock_and_fail:
  662. pa_threaded_mainloop_unlock(c->mainloop);
  663. fail:
  664. AUD_log (AUDIO_CAP, "Failed to initialize PA context");
  665. qpa_conn_fini(c);
  666. return NULL;
  667. }
  668. static void *qpa_audio_init(Audiodev *dev, Error **errp)
  669. {
  670. paaudio *g;
  671. AudiodevPaOptions *popts = &dev->u.pa;
  672. const char *server;
  673. PAConnection *c;
  674. assert(dev->driver == AUDIODEV_DRIVER_PA);
  675. if (!popts->server) {
  676. char pidfile[64];
  677. char *runtime;
  678. struct stat st;
  679. runtime = getenv("XDG_RUNTIME_DIR");
  680. if (!runtime) {
  681. error_setg(errp, "XDG_RUNTIME_DIR not set");
  682. return NULL;
  683. }
  684. snprintf(pidfile, sizeof(pidfile), "%s/pulse/pid", runtime);
  685. if (stat(pidfile, &st) != 0) {
  686. error_setg_errno(errp, errno, "could not stat pidfile %s", pidfile);
  687. return NULL;
  688. }
  689. }
  690. if (!qpa_validate_per_direction_opts(dev, popts->in)) {
  691. return NULL;
  692. }
  693. if (!qpa_validate_per_direction_opts(dev, popts->out)) {
  694. return NULL;
  695. }
  696. g = g_new0(paaudio, 1);
  697. server = popts->server;
  698. g->dev = dev;
  699. QTAILQ_FOREACH(c, &pa_conns, list) {
  700. if (server == NULL || c->server == NULL ?
  701. server == c->server :
  702. strcmp(server, c->server) == 0) {
  703. g->conn = c;
  704. break;
  705. }
  706. }
  707. if (!g->conn) {
  708. g->conn = qpa_conn_init(server);
  709. }
  710. if (!g->conn) {
  711. g_free(g);
  712. error_setg(errp, "could not connect to PulseAudio server");
  713. return NULL;
  714. }
  715. ++g->conn->refcount;
  716. return g;
  717. }
  718. static void qpa_conn_fini(PAConnection *c)
  719. {
  720. if (c->mainloop) {
  721. pa_threaded_mainloop_stop(c->mainloop);
  722. }
  723. if (c->context) {
  724. pa_context_disconnect(c->context);
  725. pa_context_unref(c->context);
  726. }
  727. if (c->mainloop) {
  728. pa_threaded_mainloop_free(c->mainloop);
  729. }
  730. QTAILQ_REMOVE(&pa_conns, c, list);
  731. g_free(c);
  732. }
  733. static void qpa_audio_fini (void *opaque)
  734. {
  735. paaudio *g = opaque;
  736. PAConnection *c = g->conn;
  737. if (--c->refcount == 0) {
  738. qpa_conn_fini(c);
  739. }
  740. g_free(g);
  741. }
  742. static struct audio_pcm_ops qpa_pcm_ops = {
  743. .init_out = qpa_init_out,
  744. .fini_out = qpa_fini_out,
  745. .write = qpa_write,
  746. .buffer_get_free = qpa_buffer_get_free,
  747. .get_buffer_out = qpa_get_buffer_out,
  748. .put_buffer_out = qpa_put_buffer_out,
  749. .volume_out = qpa_volume_out,
  750. .init_in = qpa_init_in,
  751. .fini_in = qpa_fini_in,
  752. .read = qpa_read,
  753. .get_buffer_in = qpa_get_buffer_in,
  754. .put_buffer_in = qpa_put_buffer_in,
  755. .volume_in = qpa_volume_in
  756. };
  757. static struct audio_driver pa_audio_driver = {
  758. .name = "pa",
  759. .descr = "http://www.pulseaudio.org/",
  760. .init = qpa_audio_init,
  761. .fini = qpa_audio_fini,
  762. .pcm_ops = &qpa_pcm_ops,
  763. .max_voices_out = INT_MAX,
  764. .max_voices_in = INT_MAX,
  765. .voice_size_out = sizeof (PAVoiceOut),
  766. .voice_size_in = sizeof (PAVoiceIn),
  767. };
  768. static void register_audio_pa(void)
  769. {
  770. audio_driver_register(&pa_audio_driver);
  771. }
  772. type_init(register_audio_pa);