alsa.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  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_start(self->pcmHandle);
  1011. if(err < 0)
  1012. {
  1013. ERR("start failed: %s\n", snd_strerror(err));
  1014. aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, "Capture state failure: %s",
  1015. snd_strerror(err));
  1016. return ALC_FALSE;
  1017. }
  1018. self->doCapture = AL_TRUE;
  1019. return ALC_TRUE;
  1020. }
  1021. static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self)
  1022. {
  1023. ALCuint avail;
  1024. int err;
  1025. /* OpenAL requires access to unread audio after stopping, but ALSA's
  1026. * snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's
  1027. * available now so it'll be available later after the drop. */
  1028. avail = ALCcaptureAlsa_availableSamples(self);
  1029. if(!self->ring && avail > 0)
  1030. {
  1031. /* The ring buffer implicitly captures when checking availability.
  1032. * Direct access needs to explicitly capture it into temp storage. */
  1033. ALsizei size;
  1034. void *ptr;
  1035. size = snd_pcm_frames_to_bytes(self->pcmHandle, avail);
  1036. ptr = al_malloc(16, size);
  1037. if(ptr)
  1038. {
  1039. ALCcaptureAlsa_captureSamples(self, ptr, avail);
  1040. al_free(self->buffer);
  1041. self->buffer = ptr;
  1042. self->size = size;
  1043. }
  1044. }
  1045. err = snd_pcm_drop(self->pcmHandle);
  1046. if(err < 0)
  1047. ERR("drop failed: %s\n", snd_strerror(err));
  1048. self->doCapture = AL_FALSE;
  1049. }
  1050. static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples)
  1051. {
  1052. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  1053. if(self->ring)
  1054. {
  1055. ll_ringbuffer_read(self->ring, buffer, samples);
  1056. return ALC_NO_ERROR;
  1057. }
  1058. self->last_avail -= samples;
  1059. while(ATOMIC_LOAD(&device->Connected, almemory_order_acquire) && samples > 0)
  1060. {
  1061. snd_pcm_sframes_t amt = 0;
  1062. if(self->size > 0)
  1063. {
  1064. /* First get any data stored from the last stop */
  1065. amt = snd_pcm_bytes_to_frames(self->pcmHandle, self->size);
  1066. if((snd_pcm_uframes_t)amt > samples) amt = samples;
  1067. amt = snd_pcm_frames_to_bytes(self->pcmHandle, amt);
  1068. memcpy(buffer, self->buffer, amt);
  1069. if(self->size > amt)
  1070. {
  1071. memmove(self->buffer, self->buffer+amt, self->size - amt);
  1072. self->size -= amt;
  1073. }
  1074. else
  1075. {
  1076. al_free(self->buffer);
  1077. self->buffer = NULL;
  1078. self->size = 0;
  1079. }
  1080. amt = snd_pcm_bytes_to_frames(self->pcmHandle, amt);
  1081. }
  1082. else if(self->doCapture)
  1083. amt = snd_pcm_readi(self->pcmHandle, buffer, samples);
  1084. if(amt < 0)
  1085. {
  1086. ERR("read error: %s\n", snd_strerror(amt));
  1087. if(amt == -EAGAIN)
  1088. continue;
  1089. if((amt=snd_pcm_recover(self->pcmHandle, amt, 1)) >= 0)
  1090. {
  1091. amt = snd_pcm_start(self->pcmHandle);
  1092. if(amt >= 0)
  1093. amt = snd_pcm_avail_update(self->pcmHandle);
  1094. }
  1095. if(amt < 0)
  1096. {
  1097. ERR("restore error: %s\n", snd_strerror(amt));
  1098. aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt));
  1099. break;
  1100. }
  1101. /* If the amount available is less than what's asked, we lost it
  1102. * during recovery. So just give silence instead. */
  1103. if((snd_pcm_uframes_t)amt < samples)
  1104. break;
  1105. continue;
  1106. }
  1107. buffer = (ALbyte*)buffer + amt;
  1108. samples -= amt;
  1109. }
  1110. if(samples > 0)
  1111. memset(buffer, ((device->FmtType == DevFmtUByte) ? 0x80 : 0),
  1112. snd_pcm_frames_to_bytes(self->pcmHandle, samples));
  1113. return ALC_NO_ERROR;
  1114. }
  1115. static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
  1116. {
  1117. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  1118. snd_pcm_sframes_t avail = 0;
  1119. if(ATOMIC_LOAD(&device->Connected, almemory_order_acquire) && self->doCapture)
  1120. avail = snd_pcm_avail_update(self->pcmHandle);
  1121. if(avail < 0)
  1122. {
  1123. ERR("avail update failed: %s\n", snd_strerror(avail));
  1124. if((avail=snd_pcm_recover(self->pcmHandle, avail, 1)) >= 0)
  1125. {
  1126. if(self->doCapture)
  1127. avail = snd_pcm_start(self->pcmHandle);
  1128. if(avail >= 0)
  1129. avail = snd_pcm_avail_update(self->pcmHandle);
  1130. }
  1131. if(avail < 0)
  1132. {
  1133. ERR("restore error: %s\n", snd_strerror(avail));
  1134. aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(avail));
  1135. }
  1136. }
  1137. if(!self->ring)
  1138. {
  1139. if(avail < 0) avail = 0;
  1140. avail += snd_pcm_bytes_to_frames(self->pcmHandle, self->size);
  1141. if(avail > self->last_avail) self->last_avail = avail;
  1142. return self->last_avail;
  1143. }
  1144. while(avail > 0)
  1145. {
  1146. ll_ringbuffer_data_t vec[2];
  1147. snd_pcm_sframes_t amt;
  1148. ll_ringbuffer_get_write_vector(self->ring, vec);
  1149. if(vec[0].len == 0) break;
  1150. amt = (vec[0].len < (snd_pcm_uframes_t)avail) ?
  1151. vec[0].len : (snd_pcm_uframes_t)avail;
  1152. amt = snd_pcm_readi(self->pcmHandle, vec[0].buf, amt);
  1153. if(amt < 0)
  1154. {
  1155. ERR("read error: %s\n", snd_strerror(amt));
  1156. if(amt == -EAGAIN)
  1157. continue;
  1158. if((amt=snd_pcm_recover(self->pcmHandle, amt, 1)) >= 0)
  1159. {
  1160. if(self->doCapture)
  1161. amt = snd_pcm_start(self->pcmHandle);
  1162. if(amt >= 0)
  1163. amt = snd_pcm_avail_update(self->pcmHandle);
  1164. }
  1165. if(amt < 0)
  1166. {
  1167. ERR("restore error: %s\n", snd_strerror(amt));
  1168. aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt));
  1169. break;
  1170. }
  1171. avail = amt;
  1172. continue;
  1173. }
  1174. ll_ringbuffer_write_advance(self->ring, amt);
  1175. avail -= amt;
  1176. }
  1177. return ll_ringbuffer_read_space(self->ring);
  1178. }
  1179. static ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
  1180. {
  1181. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  1182. snd_pcm_sframes_t delay = 0;
  1183. ClockLatency ret;
  1184. int err;
  1185. ALCcaptureAlsa_lock(self);
  1186. ret.ClockTime = GetDeviceClockTime(device);
  1187. if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0)
  1188. {
  1189. ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
  1190. delay = 0;
  1191. }
  1192. if(delay < 0) delay = 0;
  1193. ret.Latency = delay * DEVICE_CLOCK_RES / device->Frequency;
  1194. ALCcaptureAlsa_unlock(self);
  1195. return ret;
  1196. }
  1197. static inline void AppendAllDevicesList2(const DevMap *entry)
  1198. { AppendAllDevicesList(alstr_get_cstr(entry->name)); }
  1199. static inline void AppendCaptureDeviceList2(const DevMap *entry)
  1200. { AppendCaptureDeviceList(alstr_get_cstr(entry->name)); }
  1201. typedef struct ALCalsaBackendFactory {
  1202. DERIVE_FROM_TYPE(ALCbackendFactory);
  1203. } ALCalsaBackendFactory;
  1204. #define ALCALSABACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCalsaBackendFactory, ALCbackendFactory) } }
  1205. static ALCboolean ALCalsaBackendFactory_init(ALCalsaBackendFactory* UNUSED(self))
  1206. {
  1207. VECTOR_INIT(PlaybackDevices);
  1208. VECTOR_INIT(CaptureDevices);
  1209. if(!alsa_load())
  1210. return ALC_FALSE;
  1211. return ALC_TRUE;
  1212. }
  1213. static void ALCalsaBackendFactory_deinit(ALCalsaBackendFactory* UNUSED(self))
  1214. {
  1215. clear_devlist(&PlaybackDevices);
  1216. VECTOR_DEINIT(PlaybackDevices);
  1217. clear_devlist(&CaptureDevices);
  1218. VECTOR_DEINIT(CaptureDevices);
  1219. #ifdef HAVE_DYNLOAD
  1220. if(alsa_handle)
  1221. CloseLib(alsa_handle);
  1222. alsa_handle = NULL;
  1223. #endif
  1224. }
  1225. static ALCboolean ALCalsaBackendFactory_querySupport(ALCalsaBackendFactory* UNUSED(self), ALCbackend_Type type)
  1226. {
  1227. if(type == ALCbackend_Playback || type == ALCbackend_Capture)
  1228. return ALC_TRUE;
  1229. return ALC_FALSE;
  1230. }
  1231. static void ALCalsaBackendFactory_probe(ALCalsaBackendFactory* UNUSED(self), enum DevProbe type)
  1232. {
  1233. switch(type)
  1234. {
  1235. case ALL_DEVICE_PROBE:
  1236. probe_devices(SND_PCM_STREAM_PLAYBACK, &PlaybackDevices);
  1237. VECTOR_FOR_EACH(const DevMap, PlaybackDevices, AppendAllDevicesList2);
  1238. break;
  1239. case CAPTURE_DEVICE_PROBE:
  1240. probe_devices(SND_PCM_STREAM_CAPTURE, &CaptureDevices);
  1241. VECTOR_FOR_EACH(const DevMap, CaptureDevices, AppendCaptureDeviceList2);
  1242. break;
  1243. }
  1244. }
  1245. static ALCbackend* ALCalsaBackendFactory_createBackend(ALCalsaBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
  1246. {
  1247. if(type == ALCbackend_Playback)
  1248. {
  1249. ALCplaybackAlsa *backend;
  1250. NEW_OBJ(backend, ALCplaybackAlsa)(device);
  1251. if(!backend) return NULL;
  1252. return STATIC_CAST(ALCbackend, backend);
  1253. }
  1254. if(type == ALCbackend_Capture)
  1255. {
  1256. ALCcaptureAlsa *backend;
  1257. NEW_OBJ(backend, ALCcaptureAlsa)(device);
  1258. if(!backend) return NULL;
  1259. return STATIC_CAST(ALCbackend, backend);
  1260. }
  1261. return NULL;
  1262. }
  1263. DEFINE_ALCBACKENDFACTORY_VTABLE(ALCalsaBackendFactory);
  1264. ALCbackendFactory *ALCalsaBackendFactory_getFactory(void)
  1265. {
  1266. static ALCalsaBackendFactory factory = ALCALSABACKENDFACTORY_INITIALIZER;
  1267. return STATIC_CAST(ALCbackendFactory, &factory);
  1268. }