alFilter.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  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 "alMain.h"
  23. #include "alu.h"
  24. #include "alFilter.h"
  25. #include "alThunk.h"
  26. #include "alError.h"
  27. extern inline void LockFiltersRead(ALCdevice *device);
  28. extern inline void UnlockFiltersRead(ALCdevice *device);
  29. extern inline void LockFiltersWrite(ALCdevice *device);
  30. extern inline void UnlockFiltersWrite(ALCdevice *device);
  31. extern inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id);
  32. extern inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id);
  33. extern inline void ALfilterState_clear(ALfilterState *filter);
  34. extern inline void ALfilterState_copyParams(ALfilterState *restrict dst, const ALfilterState *restrict src);
  35. extern inline void ALfilterState_processPassthru(ALfilterState *filter, const ALfloat *restrict src, ALsizei numsamples);
  36. extern inline ALfloat calc_rcpQ_from_slope(ALfloat gain, ALfloat slope);
  37. extern inline ALfloat calc_rcpQ_from_bandwidth(ALfloat freq_mult, ALfloat bandwidth);
  38. static void InitFilterParams(ALfilter *filter, ALenum type);
  39. AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
  40. {
  41. ALCdevice *device;
  42. ALCcontext *context;
  43. ALsizei cur = 0;
  44. ALenum err;
  45. context = GetContextRef();
  46. if(!context) return;
  47. if(!(n >= 0))
  48. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  49. device = context->Device;
  50. for(cur = 0;cur < n;cur++)
  51. {
  52. ALfilter *filter = al_calloc(16, sizeof(ALfilter));
  53. if(!filter)
  54. {
  55. alDeleteFilters(cur, filters);
  56. SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
  57. }
  58. InitFilterParams(filter, AL_FILTER_NULL);
  59. err = NewThunkEntry(&filter->id);
  60. if(err == AL_NO_ERROR)
  61. err = InsertUIntMapEntry(&device->FilterMap, filter->id, filter);
  62. if(err != AL_NO_ERROR)
  63. {
  64. FreeThunkEntry(filter->id);
  65. memset(filter, 0, sizeof(ALfilter));
  66. al_free(filter);
  67. alDeleteFilters(cur, filters);
  68. SET_ERROR_AND_GOTO(context, err, done);
  69. }
  70. filters[cur] = filter->id;
  71. }
  72. done:
  73. ALCcontext_DecRef(context);
  74. }
  75. AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters)
  76. {
  77. ALCdevice *device;
  78. ALCcontext *context;
  79. ALfilter *filter;
  80. ALsizei i;
  81. context = GetContextRef();
  82. if(!context) return;
  83. device = context->Device;
  84. LockFiltersWrite(device);
  85. if(!(n >= 0))
  86. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  87. for(i = 0;i < n;i++)
  88. {
  89. if(filters[i] && LookupFilter(device, filters[i]) == NULL)
  90. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  91. }
  92. for(i = 0;i < n;i++)
  93. {
  94. if((filter=RemoveFilter(device, filters[i])) == NULL)
  95. continue;
  96. FreeThunkEntry(filter->id);
  97. memset(filter, 0, sizeof(*filter));
  98. al_free(filter);
  99. }
  100. done:
  101. UnlockFiltersWrite(device);
  102. ALCcontext_DecRef(context);
  103. }
  104. AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
  105. {
  106. ALCcontext *Context;
  107. ALboolean result;
  108. Context = GetContextRef();
  109. if(!Context) return AL_FALSE;
  110. LockFiltersRead(Context->Device);
  111. result = ((!filter || LookupFilter(Context->Device, filter)) ?
  112. AL_TRUE : AL_FALSE);
  113. UnlockFiltersRead(Context->Device);
  114. ALCcontext_DecRef(Context);
  115. return result;
  116. }
  117. AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value)
  118. {
  119. ALCcontext *Context;
  120. ALCdevice *Device;
  121. ALfilter *ALFilter;
  122. Context = GetContextRef();
  123. if(!Context) return;
  124. Device = Context->Device;
  125. LockFiltersWrite(Device);
  126. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  127. alSetError(Context, AL_INVALID_NAME);
  128. else
  129. {
  130. if(param == AL_FILTER_TYPE)
  131. {
  132. if(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS ||
  133. value == AL_FILTER_HIGHPASS || value == AL_FILTER_BANDPASS)
  134. InitFilterParams(ALFilter, value);
  135. else
  136. alSetError(Context, AL_INVALID_VALUE);
  137. }
  138. else
  139. {
  140. /* Call the appropriate handler */
  141. ALfilter_SetParami(ALFilter, Context, param, value);
  142. }
  143. }
  144. UnlockFiltersWrite(Device);
  145. ALCcontext_DecRef(Context);
  146. }
  147. AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *values)
  148. {
  149. ALCcontext *Context;
  150. ALCdevice *Device;
  151. ALfilter *ALFilter;
  152. switch(param)
  153. {
  154. case AL_FILTER_TYPE:
  155. alFilteri(filter, param, values[0]);
  156. return;
  157. }
  158. Context = GetContextRef();
  159. if(!Context) return;
  160. Device = Context->Device;
  161. LockFiltersWrite(Device);
  162. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  163. alSetError(Context, AL_INVALID_NAME);
  164. else
  165. {
  166. /* Call the appropriate handler */
  167. ALfilter_SetParamiv(ALFilter, Context, param, values);
  168. }
  169. UnlockFiltersWrite(Device);
  170. ALCcontext_DecRef(Context);
  171. }
  172. AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value)
  173. {
  174. ALCcontext *Context;
  175. ALCdevice *Device;
  176. ALfilter *ALFilter;
  177. Context = GetContextRef();
  178. if(!Context) return;
  179. Device = Context->Device;
  180. LockFiltersWrite(Device);
  181. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  182. alSetError(Context, AL_INVALID_NAME);
  183. else
  184. {
  185. /* Call the appropriate handler */
  186. ALfilter_SetParamf(ALFilter, Context, param, value);
  187. }
  188. UnlockFiltersWrite(Device);
  189. ALCcontext_DecRef(Context);
  190. }
  191. AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *values)
  192. {
  193. ALCcontext *Context;
  194. ALCdevice *Device;
  195. ALfilter *ALFilter;
  196. Context = GetContextRef();
  197. if(!Context) return;
  198. Device = Context->Device;
  199. LockFiltersWrite(Device);
  200. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  201. alSetError(Context, AL_INVALID_NAME);
  202. else
  203. {
  204. /* Call the appropriate handler */
  205. ALfilter_SetParamfv(ALFilter, Context, param, values);
  206. }
  207. UnlockFiltersWrite(Device);
  208. ALCcontext_DecRef(Context);
  209. }
  210. AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value)
  211. {
  212. ALCcontext *Context;
  213. ALCdevice *Device;
  214. ALfilter *ALFilter;
  215. Context = GetContextRef();
  216. if(!Context) return;
  217. Device = Context->Device;
  218. LockFiltersRead(Device);
  219. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  220. alSetError(Context, AL_INVALID_NAME);
  221. else
  222. {
  223. if(param == AL_FILTER_TYPE)
  224. *value = ALFilter->type;
  225. else
  226. {
  227. /* Call the appropriate handler */
  228. ALfilter_GetParami(ALFilter, Context, param, value);
  229. }
  230. }
  231. UnlockFiltersRead(Device);
  232. ALCcontext_DecRef(Context);
  233. }
  234. AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *values)
  235. {
  236. ALCcontext *Context;
  237. ALCdevice *Device;
  238. ALfilter *ALFilter;
  239. switch(param)
  240. {
  241. case AL_FILTER_TYPE:
  242. alGetFilteri(filter, param, values);
  243. return;
  244. }
  245. Context = GetContextRef();
  246. if(!Context) return;
  247. Device = Context->Device;
  248. LockFiltersRead(Device);
  249. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  250. alSetError(Context, AL_INVALID_NAME);
  251. else
  252. {
  253. /* Call the appropriate handler */
  254. ALfilter_GetParamiv(ALFilter, Context, param, values);
  255. }
  256. UnlockFiltersRead(Device);
  257. ALCcontext_DecRef(Context);
  258. }
  259. AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *value)
  260. {
  261. ALCcontext *Context;
  262. ALCdevice *Device;
  263. ALfilter *ALFilter;
  264. Context = GetContextRef();
  265. if(!Context) return;
  266. Device = Context->Device;
  267. LockFiltersRead(Device);
  268. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  269. alSetError(Context, AL_INVALID_NAME);
  270. else
  271. {
  272. /* Call the appropriate handler */
  273. ALfilter_GetParamf(ALFilter, Context, param, value);
  274. }
  275. UnlockFiltersRead(Device);
  276. ALCcontext_DecRef(Context);
  277. }
  278. AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *values)
  279. {
  280. ALCcontext *Context;
  281. ALCdevice *Device;
  282. ALfilter *ALFilter;
  283. Context = GetContextRef();
  284. if(!Context) return;
  285. Device = Context->Device;
  286. LockFiltersRead(Device);
  287. if((ALFilter=LookupFilter(Device, filter)) == NULL)
  288. alSetError(Context, AL_INVALID_NAME);
  289. else
  290. {
  291. /* Call the appropriate handler */
  292. ALfilter_GetParamfv(ALFilter, Context, param, values);
  293. }
  294. UnlockFiltersRead(Device);
  295. ALCcontext_DecRef(Context);
  296. }
  297. void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_mult, ALfloat rcpQ)
  298. {
  299. ALfloat alpha, sqrtgain_alpha_2;
  300. ALfloat w0, sin_w0, cos_w0;
  301. ALfloat a[3] = { 1.0f, 0.0f, 0.0f };
  302. ALfloat b[3] = { 1.0f, 0.0f, 0.0f };
  303. // Limit gain to -100dB
  304. assert(gain > 0.00001f);
  305. w0 = F_TAU * freq_mult;
  306. sin_w0 = sinf(w0);
  307. cos_w0 = cosf(w0);
  308. alpha = sin_w0/2.0f * rcpQ;
  309. /* Calculate filter coefficients depending on filter type */
  310. switch(type)
  311. {
  312. case ALfilterType_HighShelf:
  313. sqrtgain_alpha_2 = 2.0f * sqrtf(gain) * alpha;
  314. b[0] = gain*((gain+1.0f) + (gain-1.0f)*cos_w0 + sqrtgain_alpha_2);
  315. b[1] = -2.0f*gain*((gain-1.0f) + (gain+1.0f)*cos_w0 );
  316. b[2] = gain*((gain+1.0f) + (gain-1.0f)*cos_w0 - sqrtgain_alpha_2);
  317. a[0] = (gain+1.0f) - (gain-1.0f)*cos_w0 + sqrtgain_alpha_2;
  318. a[1] = 2.0f* ((gain-1.0f) - (gain+1.0f)*cos_w0 );
  319. a[2] = (gain+1.0f) - (gain-1.0f)*cos_w0 - sqrtgain_alpha_2;
  320. break;
  321. case ALfilterType_LowShelf:
  322. sqrtgain_alpha_2 = 2.0f * sqrtf(gain) * alpha;
  323. b[0] = gain*((gain+1.0f) - (gain-1.0f)*cos_w0 + sqrtgain_alpha_2);
  324. b[1] = 2.0f*gain*((gain-1.0f) - (gain+1.0f)*cos_w0 );
  325. b[2] = gain*((gain+1.0f) - (gain-1.0f)*cos_w0 - sqrtgain_alpha_2);
  326. a[0] = (gain+1.0f) + (gain-1.0f)*cos_w0 + sqrtgain_alpha_2;
  327. a[1] = -2.0f* ((gain-1.0f) + (gain+1.0f)*cos_w0 );
  328. a[2] = (gain+1.0f) + (gain-1.0f)*cos_w0 - sqrtgain_alpha_2;
  329. break;
  330. case ALfilterType_Peaking:
  331. gain = sqrtf(gain);
  332. b[0] = 1.0f + alpha * gain;
  333. b[1] = -2.0f * cos_w0;
  334. b[2] = 1.0f - alpha * gain;
  335. a[0] = 1.0f + alpha / gain;
  336. a[1] = -2.0f * cos_w0;
  337. a[2] = 1.0f - alpha / gain;
  338. break;
  339. case ALfilterType_LowPass:
  340. b[0] = (1.0f - cos_w0) / 2.0f;
  341. b[1] = 1.0f - cos_w0;
  342. b[2] = (1.0f - cos_w0) / 2.0f;
  343. a[0] = 1.0f + alpha;
  344. a[1] = -2.0f * cos_w0;
  345. a[2] = 1.0f - alpha;
  346. break;
  347. case ALfilterType_HighPass:
  348. b[0] = (1.0f + cos_w0) / 2.0f;
  349. b[1] = -(1.0f + cos_w0);
  350. b[2] = (1.0f + cos_w0) / 2.0f;
  351. a[0] = 1.0f + alpha;
  352. a[1] = -2.0f * cos_w0;
  353. a[2] = 1.0f - alpha;
  354. break;
  355. case ALfilterType_BandPass:
  356. b[0] = alpha;
  357. b[1] = 0;
  358. b[2] = -alpha;
  359. a[0] = 1.0f + alpha;
  360. a[1] = -2.0f * cos_w0;
  361. a[2] = 1.0f - alpha;
  362. break;
  363. }
  364. filter->a1 = a[1] / a[0];
  365. filter->a2 = a[2] / a[0];
  366. filter->b0 = b[0] / a[0];
  367. filter->b1 = b[1] / a[0];
  368. filter->b2 = b[2] / a[0];
  369. }
  370. static void lp_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val))
  371. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  372. static void lp_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals))
  373. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  374. static void lp_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
  375. {
  376. switch(param)
  377. {
  378. case AL_LOWPASS_GAIN:
  379. if(!(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN))
  380. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  381. filter->Gain = val;
  382. break;
  383. case AL_LOWPASS_GAINHF:
  384. if(!(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF))
  385. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  386. filter->GainHF = val;
  387. break;
  388. default:
  389. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  390. }
  391. }
  392. static void lp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals)
  393. {
  394. lp_SetParamf(filter, context, param, vals[0]);
  395. }
  396. static void lp_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val))
  397. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  398. static void lp_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals))
  399. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  400. static void lp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
  401. {
  402. switch(param)
  403. {
  404. case AL_LOWPASS_GAIN:
  405. *val = filter->Gain;
  406. break;
  407. case AL_LOWPASS_GAINHF:
  408. *val = filter->GainHF;
  409. break;
  410. default:
  411. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  412. }
  413. }
  414. static void lp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
  415. {
  416. lp_GetParamf(filter, context, param, vals);
  417. }
  418. static void hp_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val))
  419. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  420. static void hp_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals))
  421. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  422. static void hp_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
  423. {
  424. switch(param)
  425. {
  426. case AL_HIGHPASS_GAIN:
  427. if(!(val >= AL_HIGHPASS_MIN_GAIN && val <= AL_HIGHPASS_MAX_GAIN))
  428. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  429. filter->Gain = val;
  430. break;
  431. case AL_HIGHPASS_GAINLF:
  432. if(!(val >= AL_HIGHPASS_MIN_GAINLF && val <= AL_HIGHPASS_MAX_GAINLF))
  433. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  434. filter->GainLF = val;
  435. break;
  436. default:
  437. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  438. }
  439. }
  440. static void hp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals)
  441. {
  442. hp_SetParamf(filter, context, param, vals[0]);
  443. }
  444. static void hp_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val))
  445. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  446. static void hp_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals))
  447. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  448. static void hp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
  449. {
  450. switch(param)
  451. {
  452. case AL_HIGHPASS_GAIN:
  453. *val = filter->Gain;
  454. break;
  455. case AL_HIGHPASS_GAINLF:
  456. *val = filter->GainLF;
  457. break;
  458. default:
  459. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  460. }
  461. }
  462. static void hp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
  463. {
  464. hp_GetParamf(filter, context, param, vals);
  465. }
  466. static void bp_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val))
  467. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  468. static void bp_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals))
  469. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  470. static void bp_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
  471. {
  472. switch(param)
  473. {
  474. case AL_BANDPASS_GAIN:
  475. if(!(val >= AL_BANDPASS_MIN_GAIN && val <= AL_BANDPASS_MAX_GAIN))
  476. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  477. filter->Gain = val;
  478. break;
  479. case AL_BANDPASS_GAINHF:
  480. if(!(val >= AL_BANDPASS_MIN_GAINHF && val <= AL_BANDPASS_MAX_GAINHF))
  481. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  482. filter->GainHF = val;
  483. break;
  484. case AL_BANDPASS_GAINLF:
  485. if(!(val >= AL_BANDPASS_MIN_GAINLF && val <= AL_BANDPASS_MAX_GAINLF))
  486. SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
  487. filter->GainLF = val;
  488. break;
  489. default:
  490. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  491. }
  492. }
  493. static void bp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals)
  494. {
  495. bp_SetParamf(filter, context, param, vals[0]);
  496. }
  497. static void bp_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val))
  498. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  499. static void bp_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals))
  500. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  501. static void bp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
  502. {
  503. switch(param)
  504. {
  505. case AL_BANDPASS_GAIN:
  506. *val = filter->Gain;
  507. break;
  508. case AL_BANDPASS_GAINHF:
  509. *val = filter->GainHF;
  510. break;
  511. case AL_BANDPASS_GAINLF:
  512. *val = filter->GainLF;
  513. break;
  514. default:
  515. SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
  516. }
  517. }
  518. static void bp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
  519. {
  520. bp_GetParamf(filter, context, param, vals);
  521. }
  522. static void null_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val))
  523. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  524. static void null_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals))
  525. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  526. static void null_SetParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val))
  527. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  528. static void null_SetParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals))
  529. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  530. static void null_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val))
  531. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  532. static void null_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals))
  533. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  534. static void null_GetParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val))
  535. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  536. static void null_GetParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals))
  537. { SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); }
  538. ALvoid ReleaseALFilters(ALCdevice *device)
  539. {
  540. ALsizei i;
  541. for(i = 0;i < device->FilterMap.size;i++)
  542. {
  543. ALfilter *temp = device->FilterMap.values[i];
  544. device->FilterMap.values[i] = NULL;
  545. // Release filter structure
  546. FreeThunkEntry(temp->id);
  547. memset(temp, 0, sizeof(ALfilter));
  548. al_free(temp);
  549. }
  550. }
  551. static void InitFilterParams(ALfilter *filter, ALenum type)
  552. {
  553. if(type == AL_FILTER_LOWPASS)
  554. {
  555. filter->Gain = AL_LOWPASS_DEFAULT_GAIN;
  556. filter->GainHF = AL_LOWPASS_DEFAULT_GAINHF;
  557. filter->HFReference = LOWPASSFREQREF;
  558. filter->GainLF = 1.0f;
  559. filter->LFReference = HIGHPASSFREQREF;
  560. filter->SetParami = lp_SetParami;
  561. filter->SetParamiv = lp_SetParamiv;
  562. filter->SetParamf = lp_SetParamf;
  563. filter->SetParamfv = lp_SetParamfv;
  564. filter->GetParami = lp_GetParami;
  565. filter->GetParamiv = lp_GetParamiv;
  566. filter->GetParamf = lp_GetParamf;
  567. filter->GetParamfv = lp_GetParamfv;
  568. }
  569. else if(type == AL_FILTER_HIGHPASS)
  570. {
  571. filter->Gain = AL_HIGHPASS_DEFAULT_GAIN;
  572. filter->GainHF = 1.0f;
  573. filter->HFReference = LOWPASSFREQREF;
  574. filter->GainLF = AL_HIGHPASS_DEFAULT_GAINLF;
  575. filter->LFReference = HIGHPASSFREQREF;
  576. filter->SetParami = hp_SetParami;
  577. filter->SetParamiv = hp_SetParamiv;
  578. filter->SetParamf = hp_SetParamf;
  579. filter->SetParamfv = hp_SetParamfv;
  580. filter->GetParami = hp_GetParami;
  581. filter->GetParamiv = hp_GetParamiv;
  582. filter->GetParamf = hp_GetParamf;
  583. filter->GetParamfv = hp_GetParamfv;
  584. }
  585. else if(type == AL_FILTER_BANDPASS)
  586. {
  587. filter->Gain = AL_BANDPASS_DEFAULT_GAIN;
  588. filter->GainHF = AL_BANDPASS_DEFAULT_GAINHF;
  589. filter->HFReference = LOWPASSFREQREF;
  590. filter->GainLF = AL_BANDPASS_DEFAULT_GAINLF;
  591. filter->LFReference = HIGHPASSFREQREF;
  592. filter->SetParami = bp_SetParami;
  593. filter->SetParamiv = bp_SetParamiv;
  594. filter->SetParamf = bp_SetParamf;
  595. filter->SetParamfv = bp_SetParamfv;
  596. filter->GetParami = bp_GetParami;
  597. filter->GetParamiv = bp_GetParamiv;
  598. filter->GetParamf = bp_GetParamf;
  599. filter->GetParamfv = bp_GetParamfv;
  600. }
  601. else
  602. {
  603. filter->Gain = 1.0f;
  604. filter->GainHF = 1.0f;
  605. filter->HFReference = LOWPASSFREQREF;
  606. filter->GainLF = 1.0f;
  607. filter->LFReference = HIGHPASSFREQREF;
  608. filter->SetParami = null_SetParami;
  609. filter->SetParamiv = null_SetParamiv;
  610. filter->SetParamf = null_SetParamf;
  611. filter->SetParamfv = null_SetParamfv;
  612. filter->GetParami = null_GetParami;
  613. filter->GetParamiv = null_GetParamiv;
  614. filter->GetParamf = null_GetParamf;
  615. filter->GetParamfv = null_GetParamfv;
  616. }
  617. filter->type = type;
  618. }