alsa.c 47 KB

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