alsa.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2007 by authors.
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <memory.h>
  24. #include "alMain.h"
  25. #include "alu.h"
  26. #include "alconfig.h"
  27. #include "ringbuffer.h"
  28. #include "threads.h"
  29. #include "compat.h"
  30. #include "backends/base.h"
  31. #include <alsa/asoundlib.h>
  32. static const ALCchar alsaDevice[] = "ALSA Default";
  33. #ifdef HAVE_DYNLOAD
  34. #define ALSA_FUNCS(MAGIC) \
  35. MAGIC(snd_strerror); \
  36. MAGIC(snd_pcm_open); \
  37. MAGIC(snd_pcm_close); \
  38. MAGIC(snd_pcm_nonblock); \
  39. MAGIC(snd_pcm_frames_to_bytes); \
  40. MAGIC(snd_pcm_bytes_to_frames); \
  41. MAGIC(snd_pcm_hw_params_malloc); \
  42. MAGIC(snd_pcm_hw_params_free); \
  43. MAGIC(snd_pcm_hw_params_any); \
  44. MAGIC(snd_pcm_hw_params_current); \
  45. MAGIC(snd_pcm_hw_params_set_access); \
  46. MAGIC(snd_pcm_hw_params_set_format); \
  47. MAGIC(snd_pcm_hw_params_set_channels); \
  48. MAGIC(snd_pcm_hw_params_set_periods_near); \
  49. MAGIC(snd_pcm_hw_params_set_rate_near); \
  50. MAGIC(snd_pcm_hw_params_set_rate); \
  51. MAGIC(snd_pcm_hw_params_set_rate_resample); \
  52. MAGIC(snd_pcm_hw_params_set_buffer_time_near); \
  53. MAGIC(snd_pcm_hw_params_set_period_time_near); \
  54. MAGIC(snd_pcm_hw_params_set_buffer_size_near); \
  55. MAGIC(snd_pcm_hw_params_set_period_size_near); \
  56. MAGIC(snd_pcm_hw_params_set_buffer_size_min); \
  57. MAGIC(snd_pcm_hw_params_get_buffer_time_min); \
  58. MAGIC(snd_pcm_hw_params_get_buffer_time_max); \
  59. MAGIC(snd_pcm_hw_params_get_period_time_min); \
  60. MAGIC(snd_pcm_hw_params_get_period_time_max); \
  61. MAGIC(snd_pcm_hw_params_get_buffer_size); \
  62. MAGIC(snd_pcm_hw_params_get_period_size); \
  63. MAGIC(snd_pcm_hw_params_get_access); \
  64. MAGIC(snd_pcm_hw_params_get_periods); \
  65. MAGIC(snd_pcm_hw_params_test_format); \
  66. MAGIC(snd_pcm_hw_params_test_channels); \
  67. MAGIC(snd_pcm_hw_params); \
  68. MAGIC(snd_pcm_sw_params_malloc); \
  69. MAGIC(snd_pcm_sw_params_current); \
  70. MAGIC(snd_pcm_sw_params_set_avail_min); \
  71. MAGIC(snd_pcm_sw_params_set_stop_threshold); \
  72. MAGIC(snd_pcm_sw_params); \
  73. MAGIC(snd_pcm_sw_params_free); \
  74. MAGIC(snd_pcm_prepare); \
  75. MAGIC(snd_pcm_start); \
  76. MAGIC(snd_pcm_resume); \
  77. MAGIC(snd_pcm_reset); \
  78. MAGIC(snd_pcm_wait); \
  79. MAGIC(snd_pcm_delay); \
  80. MAGIC(snd_pcm_state); \
  81. MAGIC(snd_pcm_avail_update); \
  82. MAGIC(snd_pcm_areas_silence); \
  83. MAGIC(snd_pcm_mmap_begin); \
  84. MAGIC(snd_pcm_mmap_commit); \
  85. MAGIC(snd_pcm_readi); \
  86. MAGIC(snd_pcm_writei); \
  87. MAGIC(snd_pcm_drain); \
  88. MAGIC(snd_pcm_drop); \
  89. MAGIC(snd_pcm_recover); \
  90. MAGIC(snd_pcm_info_malloc); \
  91. MAGIC(snd_pcm_info_free); \
  92. MAGIC(snd_pcm_info_set_device); \
  93. MAGIC(snd_pcm_info_set_subdevice); \
  94. MAGIC(snd_pcm_info_set_stream); \
  95. MAGIC(snd_pcm_info_get_name); \
  96. MAGIC(snd_ctl_pcm_next_device); \
  97. MAGIC(snd_ctl_pcm_info); \
  98. MAGIC(snd_ctl_open); \
  99. MAGIC(snd_ctl_close); \
  100. MAGIC(snd_ctl_card_info_malloc); \
  101. MAGIC(snd_ctl_card_info_free); \
  102. MAGIC(snd_ctl_card_info); \
  103. MAGIC(snd_ctl_card_info_get_name); \
  104. MAGIC(snd_ctl_card_info_get_id); \
  105. MAGIC(snd_card_next); \
  106. MAGIC(snd_config_update_free_global)
  107. static void *alsa_handle;
  108. #define MAKE_FUNC(f) static __typeof(f) * p##f
  109. ALSA_FUNCS(MAKE_FUNC);
  110. #undef MAKE_FUNC
  111. #define snd_strerror psnd_strerror
  112. #define snd_pcm_open psnd_pcm_open
  113. #define snd_pcm_close psnd_pcm_close
  114. #define snd_pcm_nonblock psnd_pcm_nonblock
  115. #define snd_pcm_frames_to_bytes psnd_pcm_frames_to_bytes
  116. #define snd_pcm_bytes_to_frames psnd_pcm_bytes_to_frames
  117. #define snd_pcm_hw_params_malloc psnd_pcm_hw_params_malloc
  118. #define snd_pcm_hw_params_free psnd_pcm_hw_params_free
  119. #define snd_pcm_hw_params_any psnd_pcm_hw_params_any
  120. #define snd_pcm_hw_params_current psnd_pcm_hw_params_current
  121. #define snd_pcm_hw_params_set_access psnd_pcm_hw_params_set_access
  122. #define snd_pcm_hw_params_set_format psnd_pcm_hw_params_set_format
  123. #define snd_pcm_hw_params_set_channels psnd_pcm_hw_params_set_channels
  124. #define snd_pcm_hw_params_set_periods_near psnd_pcm_hw_params_set_periods_near
  125. #define snd_pcm_hw_params_set_rate_near psnd_pcm_hw_params_set_rate_near
  126. #define snd_pcm_hw_params_set_rate psnd_pcm_hw_params_set_rate
  127. #define snd_pcm_hw_params_set_rate_resample psnd_pcm_hw_params_set_rate_resample
  128. #define snd_pcm_hw_params_set_buffer_time_near psnd_pcm_hw_params_set_buffer_time_near
  129. #define snd_pcm_hw_params_set_period_time_near psnd_pcm_hw_params_set_period_time_near
  130. #define snd_pcm_hw_params_set_buffer_size_near psnd_pcm_hw_params_set_buffer_size_near
  131. #define snd_pcm_hw_params_set_period_size_near psnd_pcm_hw_params_set_period_size_near
  132. #define snd_pcm_hw_params_set_buffer_size_min psnd_pcm_hw_params_set_buffer_size_min
  133. #define snd_pcm_hw_params_get_buffer_time_min psnd_pcm_hw_params_get_buffer_time_min
  134. #define snd_pcm_hw_params_get_buffer_time_max psnd_pcm_hw_params_get_buffer_time_max
  135. #define snd_pcm_hw_params_get_period_time_min psnd_pcm_hw_params_get_period_time_min
  136. #define snd_pcm_hw_params_get_period_time_max psnd_pcm_hw_params_get_period_time_max
  137. #define snd_pcm_hw_params_get_buffer_size psnd_pcm_hw_params_get_buffer_size
  138. #define snd_pcm_hw_params_get_period_size psnd_pcm_hw_params_get_period_size
  139. #define snd_pcm_hw_params_get_access psnd_pcm_hw_params_get_access
  140. #define snd_pcm_hw_params_get_periods psnd_pcm_hw_params_get_periods
  141. #define snd_pcm_hw_params_test_format psnd_pcm_hw_params_test_format
  142. #define snd_pcm_hw_params_test_channels psnd_pcm_hw_params_test_channels
  143. #define snd_pcm_hw_params psnd_pcm_hw_params
  144. #define snd_pcm_sw_params_malloc psnd_pcm_sw_params_malloc
  145. #define snd_pcm_sw_params_current psnd_pcm_sw_params_current
  146. #define snd_pcm_sw_params_set_avail_min psnd_pcm_sw_params_set_avail_min
  147. #define snd_pcm_sw_params_set_stop_threshold psnd_pcm_sw_params_set_stop_threshold
  148. #define snd_pcm_sw_params psnd_pcm_sw_params
  149. #define snd_pcm_sw_params_free psnd_pcm_sw_params_free
  150. #define snd_pcm_prepare psnd_pcm_prepare
  151. #define snd_pcm_start psnd_pcm_start
  152. #define snd_pcm_resume psnd_pcm_resume
  153. #define snd_pcm_reset psnd_pcm_reset
  154. #define snd_pcm_wait psnd_pcm_wait
  155. #define snd_pcm_delay psnd_pcm_delay
  156. #define snd_pcm_state psnd_pcm_state
  157. #define snd_pcm_avail_update psnd_pcm_avail_update
  158. #define snd_pcm_areas_silence psnd_pcm_areas_silence
  159. #define snd_pcm_mmap_begin psnd_pcm_mmap_begin
  160. #define snd_pcm_mmap_commit psnd_pcm_mmap_commit
  161. #define snd_pcm_readi psnd_pcm_readi
  162. #define snd_pcm_writei psnd_pcm_writei
  163. #define snd_pcm_drain psnd_pcm_drain
  164. #define snd_pcm_drop psnd_pcm_drop
  165. #define snd_pcm_recover psnd_pcm_recover
  166. #define snd_pcm_info_malloc psnd_pcm_info_malloc
  167. #define snd_pcm_info_free psnd_pcm_info_free
  168. #define snd_pcm_info_set_device psnd_pcm_info_set_device
  169. #define snd_pcm_info_set_subdevice psnd_pcm_info_set_subdevice
  170. #define snd_pcm_info_set_stream psnd_pcm_info_set_stream
  171. #define snd_pcm_info_get_name psnd_pcm_info_get_name
  172. #define snd_ctl_pcm_next_device psnd_ctl_pcm_next_device
  173. #define snd_ctl_pcm_info psnd_ctl_pcm_info
  174. #define snd_ctl_open psnd_ctl_open
  175. #define snd_ctl_close psnd_ctl_close
  176. #define snd_ctl_card_info_malloc psnd_ctl_card_info_malloc
  177. #define snd_ctl_card_info_free psnd_ctl_card_info_free
  178. #define snd_ctl_card_info psnd_ctl_card_info
  179. #define snd_ctl_card_info_get_name psnd_ctl_card_info_get_name
  180. #define snd_ctl_card_info_get_id psnd_ctl_card_info_get_id
  181. #define snd_card_next psnd_card_next
  182. #define snd_config_update_free_global psnd_config_update_free_global
  183. #endif
  184. static ALCboolean alsa_load(void)
  185. {
  186. ALCboolean error = ALC_FALSE;
  187. #ifdef HAVE_DYNLOAD
  188. if(!alsa_handle)
  189. {
  190. al_string missing_funcs = AL_STRING_INIT_STATIC();
  191. alsa_handle = LoadLib("libasound.so.2");
  192. if(!alsa_handle)
  193. {
  194. WARN("Failed to load %s\n", "libasound.so.2");
  195. return ALC_FALSE;
  196. }
  197. error = ALC_FALSE;
  198. #define LOAD_FUNC(f) do { \
  199. p##f = GetSymbol(alsa_handle, #f); \
  200. if(p##f == NULL) { \
  201. error = ALC_TRUE; \
  202. alstr_append_cstr(&missing_funcs, "\n" #f); \
  203. } \
  204. } while(0)
  205. ALSA_FUNCS(LOAD_FUNC);
  206. #undef LOAD_FUNC
  207. if(error)
  208. {
  209. WARN("Missing expected functions:%s\n", alstr_get_cstr(missing_funcs));
  210. CloseLib(alsa_handle);
  211. alsa_handle = NULL;
  212. }
  213. alstr_reset(&missing_funcs);
  214. }
  215. #endif
  216. return !error;
  217. }
  218. typedef struct {
  219. al_string name;
  220. al_string device_name;
  221. } DevMap;
  222. TYPEDEF_VECTOR(DevMap, vector_DevMap)
  223. static vector_DevMap PlaybackDevices;
  224. static vector_DevMap CaptureDevices;
  225. static void clear_devlist(vector_DevMap *devlist)
  226. {
  227. #define FREE_DEV(i) do { \
  228. AL_STRING_DEINIT((i)->name); \
  229. AL_STRING_DEINIT((i)->device_name); \
  230. } while(0)
  231. VECTOR_FOR_EACH(DevMap, *devlist, FREE_DEV);
  232. VECTOR_RESIZE(*devlist, 0, 0);
  233. #undef FREE_DEV
  234. }
  235. static const char *prefix_name(snd_pcm_stream_t stream)
  236. {
  237. assert(stream == SND_PCM_STREAM_PLAYBACK || stream == SND_PCM_STREAM_CAPTURE);
  238. return (stream==SND_PCM_STREAM_PLAYBACK) ? "device-prefix" : "capture-prefix";
  239. }
  240. static void probe_devices(snd_pcm_stream_t stream, vector_DevMap *DeviceList)
  241. {
  242. const char *main_prefix = "plughw:";
  243. snd_ctl_t *handle;
  244. snd_ctl_card_info_t *info;
  245. snd_pcm_info_t *pcminfo;
  246. int card, err, dev;
  247. DevMap entry;
  248. clear_devlist(DeviceList);
  249. snd_ctl_card_info_malloc(&info);
  250. snd_pcm_info_malloc(&pcminfo);
  251. AL_STRING_INIT(entry.name);
  252. AL_STRING_INIT(entry.device_name);
  253. alstr_copy_cstr(&entry.name, alsaDevice);
  254. alstr_copy_cstr(&entry.device_name, GetConfigValue(
  255. NULL, "alsa", (stream==SND_PCM_STREAM_PLAYBACK) ? "device" : "capture", "default"
  256. ));
  257. VECTOR_PUSH_BACK(*DeviceList, entry);
  258. if(stream == SND_PCM_STREAM_PLAYBACK)
  259. {
  260. const char *customdevs, *sep, *next;
  261. next = GetConfigValue(NULL, "alsa", "custom-devices", "");
  262. while((customdevs=next) != NULL && customdevs[0])
  263. {
  264. next = strchr(customdevs, ';');
  265. sep = strchr(customdevs, '=');
  266. if(!sep)
  267. {
  268. al_string spec = AL_STRING_INIT_STATIC();
  269. if(next)
  270. alstr_copy_range(&spec, customdevs, next++);
  271. else
  272. alstr_copy_cstr(&spec, customdevs);
  273. ERR("Invalid ALSA device specification \"%s\"\n", alstr_get_cstr(spec));
  274. alstr_reset(&spec);
  275. continue;
  276. }
  277. AL_STRING_INIT(entry.name);
  278. AL_STRING_INIT(entry.device_name);
  279. alstr_copy_range(&entry.name, customdevs, sep++);
  280. if(next)
  281. alstr_copy_range(&entry.device_name, sep, next++);
  282. else
  283. alstr_copy_cstr(&entry.device_name, sep);
  284. TRACE("Got device \"%s\", \"%s\"\n", alstr_get_cstr(entry.name),
  285. alstr_get_cstr(entry.device_name));
  286. VECTOR_PUSH_BACK(*DeviceList, entry);
  287. }
  288. }
  289. card = -1;
  290. if((err=snd_card_next(&card)) < 0)
  291. ERR("Failed to find a card: %s\n", snd_strerror(err));
  292. ConfigValueStr(NULL, "alsa", prefix_name(stream), &main_prefix);
  293. while(card >= 0)
  294. {
  295. const char *card_prefix = main_prefix;
  296. const char *cardname, *cardid;
  297. char name[256];
  298. snprintf(name, sizeof(name), "hw:%d", card);
  299. if((err = snd_ctl_open(&handle, name, 0)) < 0)
  300. {
  301. ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
  302. goto next_card;
  303. }
  304. if((err = snd_ctl_card_info(handle, info)) < 0)
  305. {
  306. ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
  307. snd_ctl_close(handle);
  308. goto next_card;
  309. }
  310. cardname = snd_ctl_card_info_get_name(info);
  311. cardid = snd_ctl_card_info_get_id(info);
  312. snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid);
  313. ConfigValueStr(NULL, "alsa", name, &card_prefix);
  314. dev = -1;
  315. while(1)
  316. {
  317. const char *device_prefix = card_prefix;
  318. const char *devname;
  319. char device[128];
  320. if(snd_ctl_pcm_next_device(handle, &dev) < 0)
  321. ERR("snd_ctl_pcm_next_device failed\n");
  322. if(dev < 0)
  323. break;
  324. snd_pcm_info_set_device(pcminfo, dev);
  325. snd_pcm_info_set_subdevice(pcminfo, 0);
  326. snd_pcm_info_set_stream(pcminfo, stream);
  327. if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0)
  328. {
  329. if(err != -ENOENT)
  330. ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
  331. continue;
  332. }
  333. devname = snd_pcm_info_get_name(pcminfo);
  334. snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev);
  335. ConfigValueStr(NULL, "alsa", name, &device_prefix);
  336. snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)",
  337. cardname, devname, cardid, dev);
  338. snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d",
  339. device_prefix, cardid, dev);
  340. TRACE("Got device \"%s\", \"%s\"\n", name, device);
  341. AL_STRING_INIT(entry.name);
  342. AL_STRING_INIT(entry.device_name);
  343. alstr_copy_cstr(&entry.name, name);
  344. alstr_copy_cstr(&entry.device_name, device);
  345. VECTOR_PUSH_BACK(*DeviceList, entry);
  346. }
  347. snd_ctl_close(handle);
  348. next_card:
  349. if(snd_card_next(&card) < 0) {
  350. ERR("snd_card_next failed\n");
  351. break;
  352. }
  353. }
  354. snd_pcm_info_free(pcminfo);
  355. snd_ctl_card_info_free(info);
  356. }
  357. static int verify_state(snd_pcm_t *handle)
  358. {
  359. snd_pcm_state_t state = snd_pcm_state(handle);
  360. int err;
  361. switch(state)
  362. {
  363. case SND_PCM_STATE_OPEN:
  364. case SND_PCM_STATE_SETUP:
  365. case SND_PCM_STATE_PREPARED:
  366. case SND_PCM_STATE_RUNNING:
  367. case SND_PCM_STATE_DRAINING:
  368. case SND_PCM_STATE_PAUSED:
  369. /* All Okay */
  370. break;
  371. case SND_PCM_STATE_XRUN:
  372. if((err=snd_pcm_recover(handle, -EPIPE, 1)) < 0)
  373. return err;
  374. break;
  375. case SND_PCM_STATE_SUSPENDED:
  376. if((err=snd_pcm_recover(handle, -ESTRPIPE, 1)) < 0)
  377. return err;
  378. break;
  379. case SND_PCM_STATE_DISCONNECTED:
  380. return -ENODEV;
  381. }
  382. return state;
  383. }
  384. typedef struct ALCplaybackAlsa {
  385. DERIVE_FROM_TYPE(ALCbackend);
  386. snd_pcm_t *pcmHandle;
  387. ALvoid *buffer;
  388. ALsizei size;
  389. ATOMIC(ALenum) killNow;
  390. althrd_t thread;
  391. } ALCplaybackAlsa;
  392. static int ALCplaybackAlsa_mixerProc(void *ptr);
  393. static int ALCplaybackAlsa_mixerNoMMapProc(void *ptr);
  394. static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device);
  395. static void ALCplaybackAlsa_Destruct(ALCplaybackAlsa *self);
  396. static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name);
  397. static ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self);
  398. static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self);
  399. static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self);
  400. static DECLARE_FORWARD2(ALCplaybackAlsa, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
  401. static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, ALCuint, availableSamples)
  402. static ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self);
  403. static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, lock)
  404. static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, unlock)
  405. DECLARE_DEFAULT_ALLOCATORS(ALCplaybackAlsa)
  406. DEFINE_ALCBACKEND_VTABLE(ALCplaybackAlsa);
  407. static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device)
  408. {
  409. ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
  410. SET_VTABLE2(ALCplaybackAlsa, ALCbackend, self);
  411. self->pcmHandle = NULL;
  412. self->buffer = NULL;
  413. ATOMIC_INIT(&self->killNow, AL_TRUE);
  414. }
  415. void ALCplaybackAlsa_Destruct(ALCplaybackAlsa *self)
  416. {
  417. if(self->pcmHandle)
  418. snd_pcm_close(self->pcmHandle);
  419. self->pcmHandle = NULL;
  420. ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
  421. }
  422. static int ALCplaybackAlsa_mixerProc(void *ptr)
  423. {
  424. ALCplaybackAlsa *self = (ALCplaybackAlsa*)ptr;
  425. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  426. const snd_pcm_channel_area_t *areas = NULL;
  427. snd_pcm_uframes_t update_size, num_updates;
  428. snd_pcm_sframes_t avail, commitres;
  429. snd_pcm_uframes_t offset, frames;
  430. char *WritePtr;
  431. int err;
  432. SetRTPriority();
  433. althrd_setname(althrd_current(), MIXER_THREAD_NAME);
  434. update_size = device->UpdateSize;
  435. num_updates = device->NumUpdates;
  436. while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire))
  437. {
  438. int state = verify_state(self->pcmHandle);
  439. if(state < 0)
  440. {
  441. ERR("Invalid state detected: %s\n", snd_strerror(state));
  442. ALCplaybackAlsa_lock(self);
  443. aluHandleDisconnect(device, "Bad state: %s", snd_strerror(state));
  444. ALCplaybackAlsa_unlock(self);
  445. break;
  446. }
  447. avail = snd_pcm_avail_update(self->pcmHandle);
  448. if(avail < 0)
  449. {
  450. ERR("available update failed: %s\n", snd_strerror(avail));
  451. continue;
  452. }
  453. if((snd_pcm_uframes_t)avail > update_size*(num_updates+1))
  454. {
  455. WARN("available samples exceeds the buffer size\n");
  456. snd_pcm_reset(self->pcmHandle);
  457. continue;
  458. }
  459. // make sure there's frames to process
  460. if((snd_pcm_uframes_t)avail < update_size)
  461. {
  462. if(state != SND_PCM_STATE_RUNNING)
  463. {
  464. err = snd_pcm_start(self->pcmHandle);
  465. if(err < 0)
  466. {
  467. ERR("start failed: %s\n", snd_strerror(err));
  468. continue;
  469. }
  470. }
  471. if(snd_pcm_wait(self->pcmHandle, 1000) == 0)
  472. ERR("Wait timeout... buffer size too low?\n");
  473. continue;
  474. }
  475. avail -= avail%update_size;
  476. // it is possible that contiguous areas are smaller, thus we use a loop
  477. ALCplaybackAlsa_lock(self);
  478. while(avail > 0)
  479. {
  480. frames = avail;
  481. err = snd_pcm_mmap_begin(self->pcmHandle, &areas, &offset, &frames);
  482. if(err < 0)
  483. {
  484. ERR("mmap begin error: %s\n", snd_strerror(err));
  485. break;
  486. }
  487. WritePtr = (char*)areas->addr + (offset * areas->step / 8);
  488. aluMixData(device, WritePtr, frames);
  489. commitres = snd_pcm_mmap_commit(self->pcmHandle, offset, frames);
  490. if(commitres < 0 || (commitres-frames) != 0)
  491. {
  492. ERR("mmap commit error: %s\n",
  493. snd_strerror(commitres >= 0 ? -EPIPE : commitres));
  494. break;
  495. }
  496. avail -= frames;
  497. }
  498. ALCplaybackAlsa_unlock(self);
  499. }
  500. return 0;
  501. }
  502. static int ALCplaybackAlsa_mixerNoMMapProc(void *ptr)
  503. {
  504. ALCplaybackAlsa *self = (ALCplaybackAlsa*)ptr;
  505. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  506. snd_pcm_uframes_t update_size, num_updates;
  507. snd_pcm_sframes_t avail;
  508. char *WritePtr;
  509. int err;
  510. SetRTPriority();
  511. althrd_setname(althrd_current(), MIXER_THREAD_NAME);
  512. update_size = device->UpdateSize;
  513. num_updates = device->NumUpdates;
  514. while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire))
  515. {
  516. int state = verify_state(self->pcmHandle);
  517. if(state < 0)
  518. {
  519. ERR("Invalid state detected: %s\n", snd_strerror(state));
  520. ALCplaybackAlsa_lock(self);
  521. aluHandleDisconnect(device, "Bad state: %s", snd_strerror(state));
  522. ALCplaybackAlsa_unlock(self);
  523. break;
  524. }
  525. avail = snd_pcm_avail_update(self->pcmHandle);
  526. if(avail < 0)
  527. {
  528. ERR("available update failed: %s\n", snd_strerror(avail));
  529. continue;
  530. }
  531. if((snd_pcm_uframes_t)avail > update_size*num_updates)
  532. {
  533. WARN("available samples exceeds the buffer size\n");
  534. snd_pcm_reset(self->pcmHandle);
  535. continue;
  536. }
  537. if((snd_pcm_uframes_t)avail < update_size)
  538. {
  539. if(state != SND_PCM_STATE_RUNNING)
  540. {
  541. err = snd_pcm_start(self->pcmHandle);
  542. if(err < 0)
  543. {
  544. ERR("start failed: %s\n", snd_strerror(err));
  545. continue;
  546. }
  547. }
  548. if(snd_pcm_wait(self->pcmHandle, 1000) == 0)
  549. ERR("Wait timeout... buffer size too low?\n");
  550. continue;
  551. }
  552. ALCplaybackAlsa_lock(self);
  553. WritePtr = self->buffer;
  554. avail = snd_pcm_bytes_to_frames(self->pcmHandle, self->size);
  555. aluMixData(device, WritePtr, avail);
  556. while(avail > 0)
  557. {
  558. int ret = snd_pcm_writei(self->pcmHandle, WritePtr, avail);
  559. switch (ret)
  560. {
  561. case -EAGAIN:
  562. continue;
  563. #if ESTRPIPE != EPIPE
  564. case -ESTRPIPE:
  565. #endif
  566. case -EPIPE:
  567. case -EINTR:
  568. ret = snd_pcm_recover(self->pcmHandle, ret, 1);
  569. if(ret < 0)
  570. avail = 0;
  571. break;
  572. default:
  573. if (ret >= 0)
  574. {
  575. WritePtr += snd_pcm_frames_to_bytes(self->pcmHandle, ret);
  576. avail -= ret;
  577. }
  578. break;
  579. }
  580. if (ret < 0)
  581. {
  582. ret = snd_pcm_prepare(self->pcmHandle);
  583. if(ret < 0)
  584. break;
  585. }
  586. }
  587. ALCplaybackAlsa_unlock(self);
  588. }
  589. return 0;
  590. }
  591. static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name)
  592. {
  593. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  594. const char *driver = NULL;
  595. int err;
  596. if(name)
  597. {
  598. const DevMap *iter;
  599. if(VECTOR_SIZE(PlaybackDevices) == 0)
  600. probe_devices(SND_PCM_STREAM_PLAYBACK, &PlaybackDevices);
  601. #define MATCH_NAME(i) (alstr_cmp_cstr((i)->name, name) == 0)
  602. VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_NAME);
  603. #undef MATCH_NAME
  604. if(iter == VECTOR_END(PlaybackDevices))
  605. return ALC_INVALID_VALUE;
  606. driver = alstr_get_cstr(iter->device_name);
  607. }
  608. else
  609. {
  610. name = alsaDevice;
  611. driver = GetConfigValue(NULL, "alsa", "device", "default");
  612. }
  613. TRACE("Opening device \"%s\"\n", driver);
  614. err = snd_pcm_open(&self->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
  615. if(err < 0)
  616. {
  617. ERR("Could not open playback device '%s': %s\n", driver, snd_strerror(err));
  618. return ALC_OUT_OF_MEMORY;
  619. }
  620. /* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */
  621. snd_config_update_free_global();
  622. alstr_copy_cstr(&device->DeviceName, name);
  623. return ALC_NO_ERROR;
  624. }
  625. static ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
  626. {
  627. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  628. snd_pcm_uframes_t periodSizeInFrames;
  629. unsigned int periodLen, bufferLen;
  630. snd_pcm_sw_params_t *sp = NULL;
  631. snd_pcm_hw_params_t *hp = NULL;
  632. snd_pcm_format_t format = -1;
  633. snd_pcm_access_t access;
  634. unsigned int periods;
  635. unsigned int rate;
  636. const char *funcerr;
  637. int allowmmap;
  638. int dir;
  639. int err;
  640. switch(device->FmtType)
  641. {
  642. case DevFmtByte:
  643. format = SND_PCM_FORMAT_S8;
  644. break;
  645. case DevFmtUByte:
  646. format = SND_PCM_FORMAT_U8;
  647. break;
  648. case DevFmtShort:
  649. format = SND_PCM_FORMAT_S16;
  650. break;
  651. case DevFmtUShort:
  652. format = SND_PCM_FORMAT_U16;
  653. break;
  654. case DevFmtInt:
  655. format = SND_PCM_FORMAT_S32;
  656. break;
  657. case DevFmtUInt:
  658. format = SND_PCM_FORMAT_U32;
  659. break;
  660. case DevFmtFloat:
  661. format = SND_PCM_FORMAT_FLOAT;
  662. break;
  663. }
  664. allowmmap = GetConfigValueBool(alstr_get_cstr(device->DeviceName), "alsa", "mmap", 1);
  665. periods = device->NumUpdates;
  666. periodLen = (ALuint64)device->UpdateSize * 1000000 / device->Frequency;
  667. bufferLen = periodLen * periods;
  668. rate = device->Frequency;
  669. snd_pcm_hw_params_malloc(&hp);
  670. #define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
  671. CHECK(snd_pcm_hw_params_any(self->pcmHandle, hp));
  672. /* set interleaved access */
  673. if(!allowmmap || snd_pcm_hw_params_set_access(self->pcmHandle, hp, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0)
  674. {
  675. /* No mmap */
  676. CHECK(snd_pcm_hw_params_set_access(self->pcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
  677. }
  678. /* test and set format (implicitly sets sample bits) */
  679. if(snd_pcm_hw_params_test_format(self->pcmHandle, hp, format) < 0)
  680. {
  681. static const struct {
  682. snd_pcm_format_t format;
  683. enum DevFmtType fmttype;
  684. } formatlist[] = {
  685. { SND_PCM_FORMAT_FLOAT, DevFmtFloat },
  686. { SND_PCM_FORMAT_S32, DevFmtInt },
  687. { SND_PCM_FORMAT_U32, DevFmtUInt },
  688. { SND_PCM_FORMAT_S16, DevFmtShort },
  689. { SND_PCM_FORMAT_U16, DevFmtUShort },
  690. { SND_PCM_FORMAT_S8, DevFmtByte },
  691. { SND_PCM_FORMAT_U8, DevFmtUByte },
  692. };
  693. size_t k;
  694. for(k = 0;k < COUNTOF(formatlist);k++)
  695. {
  696. format = formatlist[k].format;
  697. if(snd_pcm_hw_params_test_format(self->pcmHandle, hp, format) >= 0)
  698. {
  699. device->FmtType = formatlist[k].fmttype;
  700. break;
  701. }
  702. }
  703. }
  704. CHECK(snd_pcm_hw_params_set_format(self->pcmHandle, hp, format));
  705. /* test and set channels (implicitly sets frame bits) */
  706. if(snd_pcm_hw_params_test_channels(self->pcmHandle, hp, ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder)) < 0)
  707. {
  708. static const enum DevFmtChannels channellist[] = {
  709. DevFmtStereo,
  710. DevFmtQuad,
  711. DevFmtX51,
  712. DevFmtX71,
  713. DevFmtMono,
  714. };
  715. size_t k;
  716. for(k = 0;k < COUNTOF(channellist);k++)
  717. {
  718. if(snd_pcm_hw_params_test_channels(self->pcmHandle, hp, ChannelsFromDevFmt(channellist[k], 0)) >= 0)
  719. {
  720. device->FmtChans = channellist[k];
  721. device->AmbiOrder = 0;
  722. break;
  723. }
  724. }
  725. }
  726. CHECK(snd_pcm_hw_params_set_channels(self->pcmHandle, hp, ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder)));
  727. /* set rate (implicitly constrains period/buffer parameters) */
  728. if(!GetConfigValueBool(alstr_get_cstr(device->DeviceName), "alsa", "allow-resampler", 0) ||
  729. !(device->Flags&DEVICE_FREQUENCY_REQUEST))
  730. {
  731. if(snd_pcm_hw_params_set_rate_resample(self->pcmHandle, hp, 0) < 0)
  732. ERR("Failed to disable ALSA resampler\n");
  733. }
  734. else if(snd_pcm_hw_params_set_rate_resample(self->pcmHandle, hp, 1) < 0)
  735. ERR("Failed to enable ALSA resampler\n");
  736. CHECK(snd_pcm_hw_params_set_rate_near(self->pcmHandle, hp, &rate, NULL));
  737. /* set buffer time (implicitly constrains period/buffer parameters) */
  738. if((err=snd_pcm_hw_params_set_buffer_time_near(self->pcmHandle, hp, &bufferLen, NULL)) < 0)
  739. ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
  740. /* set period time (implicitly sets buffer size/bytes/time and period size/bytes) */
  741. if((err=snd_pcm_hw_params_set_period_time_near(self->pcmHandle, hp, &periodLen, NULL)) < 0)
  742. ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
  743. /* install and prepare hardware configuration */
  744. CHECK(snd_pcm_hw_params(self->pcmHandle, hp));
  745. /* retrieve configuration info */
  746. CHECK(snd_pcm_hw_params_get_access(hp, &access));
  747. CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, NULL));
  748. CHECK(snd_pcm_hw_params_get_periods(hp, &periods, &dir));
  749. if(dir != 0)
  750. WARN("Inexact period count: %u (%d)\n", periods, dir);
  751. snd_pcm_hw_params_free(hp);
  752. hp = NULL;
  753. snd_pcm_sw_params_malloc(&sp);
  754. CHECK(snd_pcm_sw_params_current(self->pcmHandle, sp));
  755. CHECK(snd_pcm_sw_params_set_avail_min(self->pcmHandle, sp, periodSizeInFrames));
  756. CHECK(snd_pcm_sw_params_set_stop_threshold(self->pcmHandle, sp, periodSizeInFrames*periods));
  757. CHECK(snd_pcm_sw_params(self->pcmHandle, sp));
  758. #undef CHECK
  759. snd_pcm_sw_params_free(sp);
  760. sp = NULL;
  761. device->NumUpdates = periods;
  762. device->UpdateSize = periodSizeInFrames;
  763. device->Frequency = rate;
  764. SetDefaultChannelOrder(device);
  765. return ALC_TRUE;
  766. error:
  767. ERR("%s failed: %s\n", funcerr, snd_strerror(err));
  768. if(hp) snd_pcm_hw_params_free(hp);
  769. if(sp) snd_pcm_sw_params_free(sp);
  770. return ALC_FALSE;
  771. }
  772. static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self)
  773. {
  774. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  775. int (*thread_func)(void*) = NULL;
  776. snd_pcm_hw_params_t *hp = NULL;
  777. snd_pcm_access_t access;
  778. const char *funcerr;
  779. int err;
  780. snd_pcm_hw_params_malloc(&hp);
  781. #define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
  782. CHECK(snd_pcm_hw_params_current(self->pcmHandle, hp));
  783. /* retrieve configuration info */
  784. CHECK(snd_pcm_hw_params_get_access(hp, &access));
  785. #undef CHECK
  786. snd_pcm_hw_params_free(hp);
  787. hp = NULL;
  788. self->size = snd_pcm_frames_to_bytes(self->pcmHandle, device->UpdateSize);
  789. if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
  790. {
  791. self->buffer = al_malloc(16, self->size);
  792. if(!self->buffer)
  793. {
  794. ERR("buffer malloc failed\n");
  795. return ALC_FALSE;
  796. }
  797. thread_func = ALCplaybackAlsa_mixerNoMMapProc;
  798. }
  799. else
  800. {
  801. err = snd_pcm_prepare(self->pcmHandle);
  802. if(err < 0)
  803. {
  804. ERR("snd_pcm_prepare(data->pcmHandle) failed: %s\n", snd_strerror(err));
  805. return ALC_FALSE;
  806. }
  807. thread_func = ALCplaybackAlsa_mixerProc;
  808. }
  809. ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
  810. if(althrd_create(&self->thread, thread_func, self) != althrd_success)
  811. {
  812. ERR("Could not create playback thread\n");
  813. al_free(self->buffer);
  814. self->buffer = NULL;
  815. return ALC_FALSE;
  816. }
  817. return ALC_TRUE;
  818. error:
  819. ERR("%s failed: %s\n", funcerr, snd_strerror(err));
  820. if(hp) snd_pcm_hw_params_free(hp);
  821. return ALC_FALSE;
  822. }
  823. static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self)
  824. {
  825. int res;
  826. if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel))
  827. return;
  828. althrd_join(self->thread, &res);
  829. al_free(self->buffer);
  830. self->buffer = NULL;
  831. }
  832. static ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self)
  833. {
  834. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  835. snd_pcm_sframes_t delay = 0;
  836. ClockLatency ret;
  837. int err;
  838. ALCplaybackAlsa_lock(self);
  839. ret.ClockTime = GetDeviceClockTime(device);
  840. if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0)
  841. {
  842. ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
  843. delay = 0;
  844. }
  845. if(delay < 0) delay = 0;
  846. ret.Latency = delay * DEVICE_CLOCK_RES / device->Frequency;
  847. ALCplaybackAlsa_unlock(self);
  848. return ret;
  849. }
  850. typedef struct ALCcaptureAlsa {
  851. DERIVE_FROM_TYPE(ALCbackend);
  852. snd_pcm_t *pcmHandle;
  853. ALvoid *buffer;
  854. ALsizei size;
  855. ALboolean doCapture;
  856. ll_ringbuffer_t *ring;
  857. snd_pcm_sframes_t last_avail;
  858. } ALCcaptureAlsa;
  859. static void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device);
  860. static void ALCcaptureAlsa_Destruct(ALCcaptureAlsa *self);
  861. static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name);
  862. static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, ALCboolean, reset)
  863. static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self);
  864. static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self);
  865. static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples);
  866. static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self);
  867. static ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self);
  868. static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, lock)
  869. static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, unlock)
  870. DECLARE_DEFAULT_ALLOCATORS(ALCcaptureAlsa)
  871. DEFINE_ALCBACKEND_VTABLE(ALCcaptureAlsa);
  872. static void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device)
  873. {
  874. ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
  875. SET_VTABLE2(ALCcaptureAlsa, ALCbackend, self);
  876. self->pcmHandle = NULL;
  877. self->buffer = NULL;
  878. self->ring = NULL;
  879. }
  880. void ALCcaptureAlsa_Destruct(ALCcaptureAlsa *self)
  881. {
  882. if(self->pcmHandle)
  883. snd_pcm_close(self->pcmHandle);
  884. self->pcmHandle = NULL;
  885. al_free(self->buffer);
  886. self->buffer = NULL;
  887. ll_ringbuffer_free(self->ring);
  888. self->ring = NULL;
  889. ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
  890. }
  891. static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
  892. {
  893. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  894. const char *driver = NULL;
  895. snd_pcm_hw_params_t *hp;
  896. snd_pcm_uframes_t bufferSizeInFrames;
  897. snd_pcm_uframes_t periodSizeInFrames;
  898. ALboolean needring = AL_FALSE;
  899. snd_pcm_format_t format = -1;
  900. const char *funcerr;
  901. int err;
  902. if(name)
  903. {
  904. const DevMap *iter;
  905. if(VECTOR_SIZE(CaptureDevices) == 0)
  906. probe_devices(SND_PCM_STREAM_CAPTURE, &CaptureDevices);
  907. #define MATCH_NAME(i) (alstr_cmp_cstr((i)->name, name) == 0)
  908. VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_NAME);
  909. #undef MATCH_NAME
  910. if(iter == VECTOR_END(CaptureDevices))
  911. return ALC_INVALID_VALUE;
  912. driver = alstr_get_cstr(iter->device_name);
  913. }
  914. else
  915. {
  916. name = alsaDevice;
  917. driver = GetConfigValue(NULL, "alsa", "capture", "default");
  918. }
  919. TRACE("Opening device \"%s\"\n", driver);
  920. err = snd_pcm_open(&self->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
  921. if(err < 0)
  922. {
  923. ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(err));
  924. return ALC_INVALID_VALUE;
  925. }
  926. /* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */
  927. snd_config_update_free_global();
  928. switch(device->FmtType)
  929. {
  930. case DevFmtByte:
  931. format = SND_PCM_FORMAT_S8;
  932. break;
  933. case DevFmtUByte:
  934. format = SND_PCM_FORMAT_U8;
  935. break;
  936. case DevFmtShort:
  937. format = SND_PCM_FORMAT_S16;
  938. break;
  939. case DevFmtUShort:
  940. format = SND_PCM_FORMAT_U16;
  941. break;
  942. case DevFmtInt:
  943. format = SND_PCM_FORMAT_S32;
  944. break;
  945. case DevFmtUInt:
  946. format = SND_PCM_FORMAT_U32;
  947. break;
  948. case DevFmtFloat:
  949. format = SND_PCM_FORMAT_FLOAT;
  950. break;
  951. }
  952. funcerr = NULL;
  953. bufferSizeInFrames = maxu(device->UpdateSize*device->NumUpdates,
  954. 100*device->Frequency/1000);
  955. periodSizeInFrames = minu(bufferSizeInFrames, 25*device->Frequency/1000);
  956. snd_pcm_hw_params_malloc(&hp);
  957. #define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
  958. CHECK(snd_pcm_hw_params_any(self->pcmHandle, hp));
  959. /* set interleaved access */
  960. CHECK(snd_pcm_hw_params_set_access(self->pcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
  961. /* set format (implicitly sets sample bits) */
  962. CHECK(snd_pcm_hw_params_set_format(self->pcmHandle, hp, format));
  963. /* set channels (implicitly sets frame bits) */
  964. CHECK(snd_pcm_hw_params_set_channels(self->pcmHandle, hp, ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder)));
  965. /* set rate (implicitly constrains period/buffer parameters) */
  966. CHECK(snd_pcm_hw_params_set_rate(self->pcmHandle, hp, device->Frequency, 0));
  967. /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
  968. if(snd_pcm_hw_params_set_buffer_size_min(self->pcmHandle, hp, &bufferSizeInFrames) < 0)
  969. {
  970. TRACE("Buffer too large, using intermediate ring buffer\n");
  971. needring = AL_TRUE;
  972. CHECK(snd_pcm_hw_params_set_buffer_size_near(self->pcmHandle, hp, &bufferSizeInFrames));
  973. }
  974. /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
  975. CHECK(snd_pcm_hw_params_set_period_size_near(self->pcmHandle, hp, &periodSizeInFrames, NULL));
  976. /* install and prepare hardware configuration */
  977. CHECK(snd_pcm_hw_params(self->pcmHandle, hp));
  978. /* retrieve configuration info */
  979. CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, NULL));
  980. #undef CHECK
  981. snd_pcm_hw_params_free(hp);
  982. hp = NULL;
  983. if(needring)
  984. {
  985. self->ring = ll_ringbuffer_create(
  986. device->UpdateSize*device->NumUpdates,
  987. FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder),
  988. false
  989. );
  990. if(!self->ring)
  991. {
  992. ERR("ring buffer create failed\n");
  993. goto error2;
  994. }
  995. }
  996. alstr_copy_cstr(&device->DeviceName, name);
  997. return ALC_NO_ERROR;
  998. error:
  999. ERR("%s failed: %s\n", funcerr, snd_strerror(err));
  1000. if(hp) snd_pcm_hw_params_free(hp);
  1001. error2:
  1002. ll_ringbuffer_free(self->ring);
  1003. self->ring = NULL;
  1004. snd_pcm_close(self->pcmHandle);
  1005. self->pcmHandle = NULL;
  1006. return ALC_INVALID_VALUE;
  1007. }
  1008. static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self)
  1009. {
  1010. int err = snd_pcm_prepare(self->pcmHandle);
  1011. if(err < 0)
  1012. ERR("prepare failed: %s\n", snd_strerror(err));
  1013. else
  1014. {
  1015. err = snd_pcm_start(self->pcmHandle);
  1016. if(err < 0)
  1017. ERR("start failed: %s\n", snd_strerror(err));
  1018. }
  1019. if(err < 0)
  1020. {
  1021. aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, "Capture state failure: %s",
  1022. snd_strerror(err));
  1023. return ALC_FALSE;
  1024. }
  1025. self->doCapture = AL_TRUE;
  1026. return ALC_TRUE;
  1027. }
  1028. static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self)
  1029. {
  1030. ALCuint avail;
  1031. int err;
  1032. /* OpenAL requires access to unread audio after stopping, but ALSA's
  1033. * snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's
  1034. * available now so it'll be available later after the drop. */
  1035. avail = ALCcaptureAlsa_availableSamples(self);
  1036. if(!self->ring && avail > 0)
  1037. {
  1038. /* The ring buffer implicitly captures when checking availability.
  1039. * Direct access needs to explicitly capture it into temp storage. */
  1040. ALsizei size;
  1041. void *ptr;
  1042. size = snd_pcm_frames_to_bytes(self->pcmHandle, avail);
  1043. ptr = al_malloc(16, size);
  1044. if(ptr)
  1045. {
  1046. ALCcaptureAlsa_captureSamples(self, ptr, avail);
  1047. al_free(self->buffer);
  1048. self->buffer = ptr;
  1049. self->size = size;
  1050. }
  1051. }
  1052. err = snd_pcm_drop(self->pcmHandle);
  1053. if(err < 0)
  1054. ERR("drop failed: %s\n", snd_strerror(err));
  1055. self->doCapture = AL_FALSE;
  1056. }
  1057. static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples)
  1058. {
  1059. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  1060. if(self->ring)
  1061. {
  1062. ll_ringbuffer_read(self->ring, buffer, samples);
  1063. return ALC_NO_ERROR;
  1064. }
  1065. self->last_avail -= samples;
  1066. while(ATOMIC_LOAD(&device->Connected, almemory_order_acquire) && samples > 0)
  1067. {
  1068. snd_pcm_sframes_t amt = 0;
  1069. if(self->size > 0)
  1070. {
  1071. /* First get any data stored from the last stop */
  1072. amt = snd_pcm_bytes_to_frames(self->pcmHandle, self->size);
  1073. if((snd_pcm_uframes_t)amt > samples) amt = samples;
  1074. amt = snd_pcm_frames_to_bytes(self->pcmHandle, amt);
  1075. memcpy(buffer, self->buffer, amt);
  1076. if(self->size > amt)
  1077. {
  1078. memmove(self->buffer, self->buffer+amt, self->size - amt);
  1079. self->size -= amt;
  1080. }
  1081. else
  1082. {
  1083. al_free(self->buffer);
  1084. self->buffer = NULL;
  1085. self->size = 0;
  1086. }
  1087. amt = snd_pcm_bytes_to_frames(self->pcmHandle, amt);
  1088. }
  1089. else if(self->doCapture)
  1090. amt = snd_pcm_readi(self->pcmHandle, buffer, samples);
  1091. if(amt < 0)
  1092. {
  1093. ERR("read error: %s\n", snd_strerror(amt));
  1094. if(amt == -EAGAIN)
  1095. continue;
  1096. if((amt=snd_pcm_recover(self->pcmHandle, amt, 1)) >= 0)
  1097. {
  1098. amt = snd_pcm_start(self->pcmHandle);
  1099. if(amt >= 0)
  1100. amt = snd_pcm_avail_update(self->pcmHandle);
  1101. }
  1102. if(amt < 0)
  1103. {
  1104. ERR("restore error: %s\n", snd_strerror(amt));
  1105. aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt));
  1106. break;
  1107. }
  1108. /* If the amount available is less than what's asked, we lost it
  1109. * during recovery. So just give silence instead. */
  1110. if((snd_pcm_uframes_t)amt < samples)
  1111. break;
  1112. continue;
  1113. }
  1114. buffer = (ALbyte*)buffer + amt;
  1115. samples -= amt;
  1116. }
  1117. if(samples > 0)
  1118. memset(buffer, ((device->FmtType == DevFmtUByte) ? 0x80 : 0),
  1119. snd_pcm_frames_to_bytes(self->pcmHandle, samples));
  1120. return ALC_NO_ERROR;
  1121. }
  1122. static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
  1123. {
  1124. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  1125. snd_pcm_sframes_t avail = 0;
  1126. if(ATOMIC_LOAD(&device->Connected, almemory_order_acquire) && self->doCapture)
  1127. avail = snd_pcm_avail_update(self->pcmHandle);
  1128. if(avail < 0)
  1129. {
  1130. ERR("avail update failed: %s\n", snd_strerror(avail));
  1131. if((avail=snd_pcm_recover(self->pcmHandle, avail, 1)) >= 0)
  1132. {
  1133. if(self->doCapture)
  1134. avail = snd_pcm_start(self->pcmHandle);
  1135. if(avail >= 0)
  1136. avail = snd_pcm_avail_update(self->pcmHandle);
  1137. }
  1138. if(avail < 0)
  1139. {
  1140. ERR("restore error: %s\n", snd_strerror(avail));
  1141. aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(avail));
  1142. }
  1143. }
  1144. if(!self->ring)
  1145. {
  1146. if(avail < 0) avail = 0;
  1147. avail += snd_pcm_bytes_to_frames(self->pcmHandle, self->size);
  1148. if(avail > self->last_avail) self->last_avail = avail;
  1149. return self->last_avail;
  1150. }
  1151. while(avail > 0)
  1152. {
  1153. ll_ringbuffer_data_t vec[2];
  1154. snd_pcm_sframes_t amt;
  1155. ll_ringbuffer_get_write_vector(self->ring, vec);
  1156. if(vec[0].len == 0) break;
  1157. amt = (vec[0].len < (snd_pcm_uframes_t)avail) ?
  1158. vec[0].len : (snd_pcm_uframes_t)avail;
  1159. amt = snd_pcm_readi(self->pcmHandle, vec[0].buf, amt);
  1160. if(amt < 0)
  1161. {
  1162. ERR("read error: %s\n", snd_strerror(amt));
  1163. if(amt == -EAGAIN)
  1164. continue;
  1165. if((amt=snd_pcm_recover(self->pcmHandle, amt, 1)) >= 0)
  1166. {
  1167. if(self->doCapture)
  1168. amt = snd_pcm_start(self->pcmHandle);
  1169. if(amt >= 0)
  1170. amt = snd_pcm_avail_update(self->pcmHandle);
  1171. }
  1172. if(amt < 0)
  1173. {
  1174. ERR("restore error: %s\n", snd_strerror(amt));
  1175. aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt));
  1176. break;
  1177. }
  1178. avail = amt;
  1179. continue;
  1180. }
  1181. ll_ringbuffer_write_advance(self->ring, amt);
  1182. avail -= amt;
  1183. }
  1184. return ll_ringbuffer_read_space(self->ring);
  1185. }
  1186. static ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
  1187. {
  1188. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  1189. snd_pcm_sframes_t delay = 0;
  1190. ClockLatency ret;
  1191. int err;
  1192. ALCcaptureAlsa_lock(self);
  1193. ret.ClockTime = GetDeviceClockTime(device);
  1194. if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0)
  1195. {
  1196. ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
  1197. delay = 0;
  1198. }
  1199. if(delay < 0) delay = 0;
  1200. ret.Latency = delay * DEVICE_CLOCK_RES / device->Frequency;
  1201. ALCcaptureAlsa_unlock(self);
  1202. return ret;
  1203. }
  1204. typedef struct ALCalsaBackendFactory {
  1205. DERIVE_FROM_TYPE(ALCbackendFactory);
  1206. } ALCalsaBackendFactory;
  1207. #define ALCALSABACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCalsaBackendFactory, ALCbackendFactory) } }
  1208. static ALCboolean ALCalsaBackendFactory_init(ALCalsaBackendFactory* UNUSED(self))
  1209. {
  1210. VECTOR_INIT(PlaybackDevices);
  1211. VECTOR_INIT(CaptureDevices);
  1212. if(!alsa_load())
  1213. return ALC_FALSE;
  1214. return ALC_TRUE;
  1215. }
  1216. static void ALCalsaBackendFactory_deinit(ALCalsaBackendFactory* UNUSED(self))
  1217. {
  1218. clear_devlist(&PlaybackDevices);
  1219. VECTOR_DEINIT(PlaybackDevices);
  1220. clear_devlist(&CaptureDevices);
  1221. VECTOR_DEINIT(CaptureDevices);
  1222. #ifdef HAVE_DYNLOAD
  1223. if(alsa_handle)
  1224. CloseLib(alsa_handle);
  1225. alsa_handle = NULL;
  1226. #endif
  1227. }
  1228. static ALCboolean ALCalsaBackendFactory_querySupport(ALCalsaBackendFactory* UNUSED(self), ALCbackend_Type type)
  1229. {
  1230. if(type == ALCbackend_Playback || type == ALCbackend_Capture)
  1231. return ALC_TRUE;
  1232. return ALC_FALSE;
  1233. }
  1234. static void ALCalsaBackendFactory_probe(ALCalsaBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
  1235. {
  1236. switch(type)
  1237. {
  1238. #define APPEND_OUTNAME(i) do { \
  1239. if(!alstr_empty((i)->name)) \
  1240. alstr_append_range(outnames, VECTOR_BEGIN((i)->name), \
  1241. VECTOR_END((i)->name)+1); \
  1242. } while(0)
  1243. case ALL_DEVICE_PROBE:
  1244. probe_devices(SND_PCM_STREAM_PLAYBACK, &PlaybackDevices);
  1245. VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_OUTNAME);
  1246. break;
  1247. case CAPTURE_DEVICE_PROBE:
  1248. probe_devices(SND_PCM_STREAM_CAPTURE, &CaptureDevices);
  1249. VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_OUTNAME);
  1250. break;
  1251. #undef APPEND_OUTNAME
  1252. }
  1253. }
  1254. static ALCbackend* ALCalsaBackendFactory_createBackend(ALCalsaBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
  1255. {
  1256. if(type == ALCbackend_Playback)
  1257. {
  1258. ALCplaybackAlsa *backend;
  1259. NEW_OBJ(backend, ALCplaybackAlsa)(device);
  1260. if(!backend) return NULL;
  1261. return STATIC_CAST(ALCbackend, backend);
  1262. }
  1263. if(type == ALCbackend_Capture)
  1264. {
  1265. ALCcaptureAlsa *backend;
  1266. NEW_OBJ(backend, ALCcaptureAlsa)(device);
  1267. if(!backend) return NULL;
  1268. return STATIC_CAST(ALCbackend, backend);
  1269. }
  1270. return NULL;
  1271. }
  1272. DEFINE_ALCBACKENDFACTORY_VTABLE(ALCalsaBackendFactory);
  1273. ALCbackendFactory *ALCalsaBackendFactory_getFactory(void)
  1274. {
  1275. static ALCalsaBackendFactory factory = ALCALSABACKENDFACTORY_INITIALIZER;
  1276. return STATIC_CAST(ALCbackendFactory, &factory);
  1277. }