alState.c 16 KB

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