alState.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2000 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 "alMain.h"
  23. #include "AL/alc.h"
  24. #include "AL/al.h"
  25. #include "AL/alext.h"
  26. #include "alError.h"
  27. #include "alListener.h"
  28. #include "alSource.h"
  29. #include "alAuxEffectSlot.h"
  30. #include "backends/base.h"
  31. static const ALchar alVendor[] = "OpenAL Community";
  32. static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
  33. static const ALchar alRenderer[] = "OpenAL Soft";
  34. // Error Messages
  35. static const ALchar alNoError[] = "No Error";
  36. static const ALchar alErrInvalidName[] = "Invalid Name";
  37. static const ALchar alErrInvalidEnum[] = "Invalid Enum";
  38. static const ALchar alErrInvalidValue[] = "Invalid Value";
  39. static const ALchar alErrInvalidOp[] = "Invalid Operation";
  40. static const ALchar alErrOutOfMemory[] = "Out of Memory";
  41. AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
  42. {
  43. ALCcontext *context;
  44. context = GetContextRef();
  45. if(!context) return;
  46. WriteLock(&context->PropLock);
  47. switch(capability)
  48. {
  49. case AL_SOURCE_DISTANCE_MODEL:
  50. context->SourceDistanceModel = AL_TRUE;
  51. break;
  52. default:
  53. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  54. }
  55. if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
  56. UpdateListenerProps(context);
  57. done:
  58. WriteUnlock(&context->PropLock);
  59. ALCcontext_DecRef(context);
  60. }
  61. AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
  62. {
  63. ALCcontext *context;
  64. context = GetContextRef();
  65. if(!context) return;
  66. WriteLock(&context->PropLock);
  67. switch(capability)
  68. {
  69. case AL_SOURCE_DISTANCE_MODEL:
  70. context->SourceDistanceModel = AL_FALSE;
  71. break;
  72. default:
  73. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  74. }
  75. if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
  76. UpdateListenerProps(context);
  77. done:
  78. WriteUnlock(&context->PropLock);
  79. ALCcontext_DecRef(context);
  80. }
  81. AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
  82. {
  83. ALCcontext *context;
  84. ALboolean value=AL_FALSE;
  85. context = GetContextRef();
  86. if(!context) return AL_FALSE;
  87. switch(capability)
  88. {
  89. case AL_SOURCE_DISTANCE_MODEL:
  90. value = context->SourceDistanceModel;
  91. break;
  92. default:
  93. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  94. }
  95. done:
  96. ALCcontext_DecRef(context);
  97. return value;
  98. }
  99. AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
  100. {
  101. ALCcontext *context;
  102. ALboolean value=AL_FALSE;
  103. context = GetContextRef();
  104. if(!context) return AL_FALSE;
  105. switch(pname)
  106. {
  107. case AL_DOPPLER_FACTOR:
  108. if(context->DopplerFactor != 0.0f)
  109. value = AL_TRUE;
  110. break;
  111. case AL_DOPPLER_VELOCITY:
  112. if(context->DopplerVelocity != 0.0f)
  113. value = AL_TRUE;
  114. break;
  115. case AL_DISTANCE_MODEL:
  116. if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
  117. value = AL_TRUE;
  118. break;
  119. case AL_SPEED_OF_SOUND:
  120. if(context->SpeedOfSound != 0.0f)
  121. value = AL_TRUE;
  122. break;
  123. case AL_DEFERRED_UPDATES_SOFT:
  124. if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
  125. value = AL_TRUE;
  126. break;
  127. case AL_GAIN_LIMIT_SOFT:
  128. if(GAIN_MIX_MAX/context->GainBoost != 0.0f)
  129. value = AL_TRUE;
  130. break;
  131. default:
  132. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  133. }
  134. done:
  135. ALCcontext_DecRef(context);
  136. return value;
  137. }
  138. AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
  139. {
  140. ALCcontext *context;
  141. ALdouble value = 0.0;
  142. context = GetContextRef();
  143. if(!context) return 0.0;
  144. switch(pname)
  145. {
  146. case AL_DOPPLER_FACTOR:
  147. value = (ALdouble)context->DopplerFactor;
  148. break;
  149. case AL_DOPPLER_VELOCITY:
  150. value = (ALdouble)context->DopplerVelocity;
  151. break;
  152. case AL_DISTANCE_MODEL:
  153. value = (ALdouble)context->DistanceModel;
  154. break;
  155. case AL_SPEED_OF_SOUND:
  156. value = (ALdouble)context->SpeedOfSound;
  157. break;
  158. case AL_DEFERRED_UPDATES_SOFT:
  159. if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
  160. value = (ALdouble)AL_TRUE;
  161. break;
  162. case AL_GAIN_LIMIT_SOFT:
  163. value = (ALdouble)GAIN_MIX_MAX/context->GainBoost;
  164. break;
  165. default:
  166. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  167. }
  168. done:
  169. ALCcontext_DecRef(context);
  170. return value;
  171. }
  172. AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
  173. {
  174. ALCcontext *context;
  175. ALfloat value = 0.0f;
  176. context = GetContextRef();
  177. if(!context) return 0.0f;
  178. switch(pname)
  179. {
  180. case AL_DOPPLER_FACTOR:
  181. value = context->DopplerFactor;
  182. break;
  183. case AL_DOPPLER_VELOCITY:
  184. value = context->DopplerVelocity;
  185. break;
  186. case AL_DISTANCE_MODEL:
  187. value = (ALfloat)context->DistanceModel;
  188. break;
  189. case AL_SPEED_OF_SOUND:
  190. value = context->SpeedOfSound;
  191. break;
  192. case AL_DEFERRED_UPDATES_SOFT:
  193. if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
  194. value = (ALfloat)AL_TRUE;
  195. break;
  196. case AL_GAIN_LIMIT_SOFT:
  197. value = GAIN_MIX_MAX/context->GainBoost;
  198. break;
  199. default:
  200. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  201. }
  202. done:
  203. ALCcontext_DecRef(context);
  204. return value;
  205. }
  206. AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
  207. {
  208. ALCcontext *context;
  209. ALint value = 0;
  210. context = GetContextRef();
  211. if(!context) return 0;
  212. switch(pname)
  213. {
  214. case AL_DOPPLER_FACTOR:
  215. value = (ALint)context->DopplerFactor;
  216. break;
  217. case AL_DOPPLER_VELOCITY:
  218. value = (ALint)context->DopplerVelocity;
  219. break;
  220. case AL_DISTANCE_MODEL:
  221. value = (ALint)context->DistanceModel;
  222. break;
  223. case AL_SPEED_OF_SOUND:
  224. value = (ALint)context->SpeedOfSound;
  225. break;
  226. case AL_DEFERRED_UPDATES_SOFT:
  227. if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
  228. value = (ALint)AL_TRUE;
  229. break;
  230. case AL_GAIN_LIMIT_SOFT:
  231. value = (ALint)(GAIN_MIX_MAX/context->GainBoost);
  232. break;
  233. default:
  234. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  235. }
  236. done:
  237. ALCcontext_DecRef(context);
  238. return value;
  239. }
  240. AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
  241. {
  242. ALCcontext *context;
  243. ALint64SOFT value = 0;
  244. context = GetContextRef();
  245. if(!context) return 0;
  246. switch(pname)
  247. {
  248. case AL_DOPPLER_FACTOR:
  249. value = (ALint64SOFT)context->DopplerFactor;
  250. break;
  251. case AL_DOPPLER_VELOCITY:
  252. value = (ALint64SOFT)context->DopplerVelocity;
  253. break;
  254. case AL_DISTANCE_MODEL:
  255. value = (ALint64SOFT)context->DistanceModel;
  256. break;
  257. case AL_SPEED_OF_SOUND:
  258. value = (ALint64SOFT)context->SpeedOfSound;
  259. break;
  260. case AL_DEFERRED_UPDATES_SOFT:
  261. if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
  262. value = (ALint64SOFT)AL_TRUE;
  263. break;
  264. case AL_GAIN_LIMIT_SOFT:
  265. value = (ALint64SOFT)(GAIN_MIX_MAX/context->GainBoost);
  266. break;
  267. default:
  268. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  269. }
  270. done:
  271. ALCcontext_DecRef(context);
  272. return value;
  273. }
  274. AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
  275. {
  276. ALCcontext *context;
  277. if(values)
  278. {
  279. switch(pname)
  280. {
  281. case AL_DOPPLER_FACTOR:
  282. case AL_DOPPLER_VELOCITY:
  283. case AL_DISTANCE_MODEL:
  284. case AL_SPEED_OF_SOUND:
  285. case AL_DEFERRED_UPDATES_SOFT:
  286. case AL_GAIN_LIMIT_SOFT:
  287. values[0] = alGetBoolean(pname);
  288. return;
  289. }
  290. }
  291. context = GetContextRef();
  292. if(!context) return;
  293. if(!(values))
  294. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  295. switch(pname)
  296. {
  297. default:
  298. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  299. }
  300. done:
  301. ALCcontext_DecRef(context);
  302. }
  303. AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
  304. {
  305. ALCcontext *context;
  306. if(values)
  307. {
  308. switch(pname)
  309. {
  310. case AL_DOPPLER_FACTOR:
  311. case AL_DOPPLER_VELOCITY:
  312. case AL_DISTANCE_MODEL:
  313. case AL_SPEED_OF_SOUND:
  314. case AL_DEFERRED_UPDATES_SOFT:
  315. case AL_GAIN_LIMIT_SOFT:
  316. values[0] = alGetDouble(pname);
  317. return;
  318. }
  319. }
  320. context = GetContextRef();
  321. if(!context) return;
  322. if(!(values))
  323. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  324. switch(pname)
  325. {
  326. default:
  327. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  328. }
  329. done:
  330. ALCcontext_DecRef(context);
  331. }
  332. AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
  333. {
  334. ALCcontext *context;
  335. if(values)
  336. {
  337. switch(pname)
  338. {
  339. case AL_DOPPLER_FACTOR:
  340. case AL_DOPPLER_VELOCITY:
  341. case AL_DISTANCE_MODEL:
  342. case AL_SPEED_OF_SOUND:
  343. case AL_DEFERRED_UPDATES_SOFT:
  344. case AL_GAIN_LIMIT_SOFT:
  345. values[0] = alGetFloat(pname);
  346. return;
  347. }
  348. }
  349. context = GetContextRef();
  350. if(!context) return;
  351. if(!(values))
  352. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  353. switch(pname)
  354. {
  355. default:
  356. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  357. }
  358. done:
  359. ALCcontext_DecRef(context);
  360. }
  361. AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
  362. {
  363. ALCcontext *context;
  364. if(values)
  365. {
  366. switch(pname)
  367. {
  368. case AL_DOPPLER_FACTOR:
  369. case AL_DOPPLER_VELOCITY:
  370. case AL_DISTANCE_MODEL:
  371. case AL_SPEED_OF_SOUND:
  372. case AL_DEFERRED_UPDATES_SOFT:
  373. case AL_GAIN_LIMIT_SOFT:
  374. values[0] = alGetInteger(pname);
  375. return;
  376. }
  377. }
  378. context = GetContextRef();
  379. if(!context) return;
  380. switch(pname)
  381. {
  382. default:
  383. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  384. }
  385. done:
  386. ALCcontext_DecRef(context);
  387. }
  388. AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
  389. {
  390. ALCcontext *context;
  391. if(values)
  392. {
  393. switch(pname)
  394. {
  395. case AL_DOPPLER_FACTOR:
  396. case AL_DOPPLER_VELOCITY:
  397. case AL_DISTANCE_MODEL:
  398. case AL_SPEED_OF_SOUND:
  399. case AL_DEFERRED_UPDATES_SOFT:
  400. case AL_GAIN_LIMIT_SOFT:
  401. values[0] = alGetInteger64SOFT(pname);
  402. return;
  403. }
  404. }
  405. context = GetContextRef();
  406. if(!context) return;
  407. switch(pname)
  408. {
  409. default:
  410. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  411. }
  412. done:
  413. ALCcontext_DecRef(context);
  414. }
  415. AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
  416. {
  417. const ALchar *value = NULL;
  418. ALCcontext *context;
  419. context = GetContextRef();
  420. if(!context) return NULL;
  421. switch(pname)
  422. {
  423. case AL_VENDOR:
  424. value = alVendor;
  425. break;
  426. case AL_VERSION:
  427. value = alVersion;
  428. break;
  429. case AL_RENDERER:
  430. value = alRenderer;
  431. break;
  432. case AL_EXTENSIONS:
  433. value = context->ExtensionList;
  434. break;
  435. case AL_NO_ERROR:
  436. value = alNoError;
  437. break;
  438. case AL_INVALID_NAME:
  439. value = alErrInvalidName;
  440. break;
  441. case AL_INVALID_ENUM:
  442. value = alErrInvalidEnum;
  443. break;
  444. case AL_INVALID_VALUE:
  445. value = alErrInvalidValue;
  446. break;
  447. case AL_INVALID_OPERATION:
  448. value = alErrInvalidOp;
  449. break;
  450. case AL_OUT_OF_MEMORY:
  451. value = alErrOutOfMemory;
  452. break;
  453. default:
  454. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  455. }
  456. done:
  457. ALCcontext_DecRef(context);
  458. return value;
  459. }
  460. AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
  461. {
  462. ALCcontext *context;
  463. context = GetContextRef();
  464. if(!context) return;
  465. if(!(value >= 0.0f && isfinite(value)))
  466. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  467. WriteLock(&context->PropLock);
  468. context->DopplerFactor = value;
  469. if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
  470. UpdateListenerProps(context);
  471. WriteUnlock(&context->PropLock);
  472. done:
  473. ALCcontext_DecRef(context);
  474. }
  475. AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
  476. {
  477. ALCcontext *context;
  478. context = GetContextRef();
  479. if(!context) return;
  480. if(!(value >= 0.0f && isfinite(value)))
  481. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  482. WriteLock(&context->PropLock);
  483. context->DopplerVelocity = value;
  484. if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
  485. UpdateListenerProps(context);
  486. WriteUnlock(&context->PropLock);
  487. done:
  488. ALCcontext_DecRef(context);
  489. }
  490. AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
  491. {
  492. ALCcontext *context;
  493. context = GetContextRef();
  494. if(!context) return;
  495. if(!(value > 0.0f && isfinite(value)))
  496. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  497. WriteLock(&context->PropLock);
  498. context->SpeedOfSound = value;
  499. if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
  500. UpdateListenerProps(context);
  501. WriteUnlock(&context->PropLock);
  502. done:
  503. ALCcontext_DecRef(context);
  504. }
  505. AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
  506. {
  507. ALCcontext *context;
  508. context = GetContextRef();
  509. if(!context) return;
  510. if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
  511. value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
  512. value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
  513. value == AL_NONE))
  514. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  515. WriteLock(&context->PropLock);
  516. context->DistanceModel = value;
  517. if(!context->SourceDistanceModel)
  518. {
  519. if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
  520. UpdateListenerProps(context);
  521. }
  522. WriteUnlock(&context->PropLock);
  523. done:
  524. ALCcontext_DecRef(context);
  525. }
  526. AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
  527. {
  528. ALCcontext *context;
  529. context = GetContextRef();
  530. if(!context) return;
  531. ALCcontext_DeferUpdates(context, DeferAll);
  532. ALCcontext_DecRef(context);
  533. }
  534. AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
  535. {
  536. ALCcontext *context;
  537. context = GetContextRef();
  538. if(!context) return;
  539. ALCcontext_ProcessUpdates(context);
  540. ALCcontext_DecRef(context);
  541. }