alBuffer.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2007 by authors.
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <assert.h>
  24. #include <limits.h>
  25. #ifdef HAVE_MALLOC_H
  26. #include <malloc.h>
  27. #endif
  28. #include "alMain.h"
  29. #include "alu.h"
  30. #include "alError.h"
  31. #include "alBuffer.h"
  32. #include "alThunk.h"
  33. #include "sample_cvt.h"
  34. extern inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id);
  35. extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id);
  36. extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type);
  37. extern inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type);
  38. static ALboolean IsValidType(ALenum type) DECL_CONST;
  39. static ALboolean IsValidChannels(ALenum channels) DECL_CONST;
  40. static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans, enum UserFmtType *type) DECL_CONST;
  41. static ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type) DECL_CONST;
  42. static ALboolean SanitizeAlignment(enum UserFmtType type, ALsizei *align);
  43. AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
  44. {
  45. ALCcontext *context;
  46. ALsizei cur = 0;
  47. context = GetContextRef();
  48. if(!context) return;
  49. if(!(n >= 0))
  50. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  51. for(cur = 0;cur < n;cur++)
  52. {
  53. ALbuffer *buffer = NewBuffer(context);
  54. if(!buffer)
  55. {
  56. alDeleteBuffers(cur, buffers);
  57. break;
  58. }
  59. buffers[cur] = buffer->id;
  60. }
  61. done:
  62. ALCcontext_DecRef(context);
  63. }
  64. AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
  65. {
  66. ALCdevice *device;
  67. ALCcontext *context;
  68. ALbuffer *ALBuf;
  69. ALsizei i;
  70. context = GetContextRef();
  71. if(!context) return;
  72. if(!(n >= 0))
  73. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  74. device = context->Device;
  75. for(i = 0;i < n;i++)
  76. {
  77. if(!buffers[i])
  78. continue;
  79. /* Check for valid Buffer ID */
  80. if((ALBuf=LookupBuffer(device, buffers[i])) == NULL)
  81. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  82. if(ReadRef(&ALBuf->ref) != 0)
  83. SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
  84. }
  85. for(i = 0;i < n;i++)
  86. {
  87. if((ALBuf=LookupBuffer(device, buffers[i])) != NULL)
  88. DeleteBuffer(device, ALBuf);
  89. }
  90. done:
  91. ALCcontext_DecRef(context);
  92. }
  93. AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
  94. {
  95. ALCcontext *context;
  96. ALboolean ret;
  97. context = GetContextRef();
  98. if(!context) return AL_FALSE;
  99. ret = ((!buffer || LookupBuffer(context->Device, buffer)) ?
  100. AL_TRUE : AL_FALSE);
  101. ALCcontext_DecRef(context);
  102. return ret;
  103. }
  104. AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
  105. {
  106. enum UserFmtChannels srcchannels;
  107. enum UserFmtType srctype;
  108. ALCdevice *device;
  109. ALCcontext *context;
  110. ALbuffer *albuf;
  111. ALenum newformat = AL_NONE;
  112. ALuint framesize;
  113. ALsizei align;
  114. ALenum err;
  115. context = GetContextRef();
  116. if(!context) return;
  117. device = context->Device;
  118. if((albuf=LookupBuffer(device, buffer)) == NULL)
  119. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  120. if(!(size >= 0 && freq > 0))
  121. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  122. if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)
  123. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  124. align = ATOMIC_LOAD(&albuf->UnpackAlign);
  125. if(SanitizeAlignment(srctype, &align) == AL_FALSE)
  126. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  127. switch(srctype)
  128. {
  129. case UserFmtByte:
  130. case UserFmtUByte:
  131. case UserFmtShort:
  132. case UserFmtUShort:
  133. case UserFmtFloat:
  134. framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align;
  135. if((size%framesize) != 0)
  136. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  137. err = LoadData(albuf, freq, format, size/framesize*align,
  138. srcchannels, srctype, data, align, AL_TRUE);
  139. if(err != AL_NO_ERROR)
  140. SET_ERROR_AND_GOTO(context, err, done);
  141. break;
  142. case UserFmtInt:
  143. case UserFmtUInt:
  144. case UserFmtByte3:
  145. case UserFmtUByte3:
  146. case UserFmtDouble:
  147. framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align;
  148. if((size%framesize) != 0)
  149. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  150. switch(srcchannels)
  151. {
  152. case UserFmtMono: newformat = AL_FORMAT_MONO_FLOAT32; break;
  153. case UserFmtStereo: newformat = AL_FORMAT_STEREO_FLOAT32; break;
  154. case UserFmtRear: newformat = AL_FORMAT_REAR32; break;
  155. case UserFmtQuad: newformat = AL_FORMAT_QUAD32; break;
  156. case UserFmtX51: newformat = AL_FORMAT_51CHN32; break;
  157. case UserFmtX61: newformat = AL_FORMAT_61CHN32; break;
  158. case UserFmtX71: newformat = AL_FORMAT_71CHN32; break;
  159. case UserFmtBFormat2D: newformat = AL_FORMAT_BFORMAT2D_FLOAT32; break;
  160. case UserFmtBFormat3D: newformat = AL_FORMAT_BFORMAT3D_FLOAT32; break;
  161. }
  162. err = LoadData(albuf, freq, newformat, size/framesize*align,
  163. srcchannels, srctype, data, align, AL_TRUE);
  164. if(err != AL_NO_ERROR)
  165. SET_ERROR_AND_GOTO(context, err, done);
  166. break;
  167. case UserFmtMulaw:
  168. case UserFmtAlaw:
  169. framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align;
  170. if((size%framesize) != 0)
  171. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  172. switch(srcchannels)
  173. {
  174. case UserFmtMono: newformat = AL_FORMAT_MONO16; break;
  175. case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break;
  176. case UserFmtRear: newformat = AL_FORMAT_REAR16; break;
  177. case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break;
  178. case UserFmtX51: newformat = AL_FORMAT_51CHN16; break;
  179. case UserFmtX61: newformat = AL_FORMAT_61CHN16; break;
  180. case UserFmtX71: newformat = AL_FORMAT_71CHN16; break;
  181. case UserFmtBFormat2D: newformat = AL_FORMAT_BFORMAT2D_16; break;
  182. case UserFmtBFormat3D: newformat = AL_FORMAT_BFORMAT3D_16; break;
  183. }
  184. err = LoadData(albuf, freq, newformat, size/framesize*align,
  185. srcchannels, srctype, data, align, AL_TRUE);
  186. if(err != AL_NO_ERROR)
  187. SET_ERROR_AND_GOTO(context, err, done);
  188. break;
  189. case UserFmtIMA4:
  190. framesize = (align-1)/2 + 4;
  191. framesize *= ChannelsFromUserFmt(srcchannels);
  192. if((size%framesize) != 0)
  193. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  194. switch(srcchannels)
  195. {
  196. case UserFmtMono: newformat = AL_FORMAT_MONO16; break;
  197. case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break;
  198. case UserFmtRear: newformat = AL_FORMAT_REAR16; break;
  199. case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break;
  200. case UserFmtX51: newformat = AL_FORMAT_51CHN16; break;
  201. case UserFmtX61: newformat = AL_FORMAT_61CHN16; break;
  202. case UserFmtX71: newformat = AL_FORMAT_71CHN16; break;
  203. case UserFmtBFormat2D: newformat = AL_FORMAT_BFORMAT2D_16; break;
  204. case UserFmtBFormat3D: newformat = AL_FORMAT_BFORMAT3D_16; break;
  205. }
  206. err = LoadData(albuf, freq, newformat, size/framesize*align,
  207. srcchannels, srctype, data, align, AL_TRUE);
  208. if(err != AL_NO_ERROR)
  209. SET_ERROR_AND_GOTO(context, err, done);
  210. break;
  211. case UserFmtMSADPCM:
  212. framesize = (align-2)/2 + 7;
  213. framesize *= ChannelsFromUserFmt(srcchannels);
  214. if((size%framesize) != 0)
  215. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  216. switch(srcchannels)
  217. {
  218. case UserFmtMono: newformat = AL_FORMAT_MONO16; break;
  219. case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break;
  220. case UserFmtRear: newformat = AL_FORMAT_REAR16; break;
  221. case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break;
  222. case UserFmtX51: newformat = AL_FORMAT_51CHN16; break;
  223. case UserFmtX61: newformat = AL_FORMAT_61CHN16; break;
  224. case UserFmtX71: newformat = AL_FORMAT_71CHN16; break;
  225. case UserFmtBFormat2D: newformat = AL_FORMAT_BFORMAT2D_16; break;
  226. case UserFmtBFormat3D: newformat = AL_FORMAT_BFORMAT3D_16; break;
  227. }
  228. err = LoadData(albuf, freq, newformat, size/framesize*align,
  229. srcchannels, srctype, data, align, AL_TRUE);
  230. if(err != AL_NO_ERROR)
  231. SET_ERROR_AND_GOTO(context, err, done);
  232. break;
  233. }
  234. done:
  235. ALCcontext_DecRef(context);
  236. }
  237. AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length)
  238. {
  239. enum UserFmtChannels srcchannels;
  240. enum UserFmtType srctype;
  241. ALCdevice *device;
  242. ALCcontext *context;
  243. ALbuffer *albuf;
  244. ALuint byte_align;
  245. ALuint channels;
  246. ALuint bytes;
  247. ALsizei align;
  248. context = GetContextRef();
  249. if(!context) return;
  250. device = context->Device;
  251. if((albuf=LookupBuffer(device, buffer)) == NULL)
  252. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  253. if(!(length >= 0 && offset >= 0))
  254. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  255. if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)
  256. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  257. WriteLock(&albuf->lock);
  258. align = ATOMIC_LOAD(&albuf->UnpackAlign);
  259. if(SanitizeAlignment(srctype, &align) == AL_FALSE)
  260. {
  261. WriteUnlock(&albuf->lock);
  262. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  263. }
  264. if(srcchannels != albuf->OriginalChannels || srctype != albuf->OriginalType)
  265. {
  266. WriteUnlock(&albuf->lock);
  267. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  268. }
  269. if(align != albuf->OriginalAlign)
  270. {
  271. WriteUnlock(&albuf->lock);
  272. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  273. }
  274. if(albuf->OriginalType == UserFmtIMA4)
  275. {
  276. byte_align = (albuf->OriginalAlign-1)/2 + 4;
  277. byte_align *= ChannelsFromUserFmt(albuf->OriginalChannels);
  278. }
  279. else if(albuf->OriginalType == UserFmtMSADPCM)
  280. {
  281. byte_align = (albuf->OriginalAlign-2)/2 + 7;
  282. byte_align *= ChannelsFromUserFmt(albuf->OriginalChannels);
  283. }
  284. else
  285. {
  286. byte_align = albuf->OriginalAlign;
  287. byte_align *= FrameSizeFromUserFmt(albuf->OriginalChannels,
  288. albuf->OriginalType);
  289. }
  290. if(offset > albuf->OriginalSize || length > albuf->OriginalSize-offset ||
  291. (offset%byte_align) != 0 || (length%byte_align) != 0)
  292. {
  293. WriteUnlock(&albuf->lock);
  294. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  295. }
  296. channels = ChannelsFromFmt(albuf->FmtChannels);
  297. bytes = BytesFromFmt(albuf->FmtType);
  298. /* offset -> byte offset, length -> sample count */
  299. offset = offset/byte_align * channels*bytes;
  300. length = length/byte_align * albuf->OriginalAlign;
  301. ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
  302. data, srctype, channels, length, align);
  303. WriteUnlock(&albuf->lock);
  304. done:
  305. ALCcontext_DecRef(context);
  306. }
  307. AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer,
  308. ALuint samplerate, ALenum internalformat, ALsizei samples,
  309. ALenum channels, ALenum type, const ALvoid *data)
  310. {
  311. ALCdevice *device;
  312. ALCcontext *context;
  313. ALbuffer *albuf;
  314. ALsizei align;
  315. ALenum err;
  316. context = GetContextRef();
  317. if(!context) return;
  318. device = context->Device;
  319. if((albuf=LookupBuffer(device, buffer)) == NULL)
  320. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  321. if(!(samples >= 0 && samplerate != 0))
  322. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  323. if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE)
  324. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  325. align = ATOMIC_LOAD(&albuf->UnpackAlign);
  326. if(SanitizeAlignment(type, &align) == AL_FALSE)
  327. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  328. if((samples%align) != 0)
  329. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  330. err = LoadData(albuf, samplerate, internalformat, samples,
  331. channels, type, data, align, AL_FALSE);
  332. if(err != AL_NO_ERROR)
  333. SET_ERROR_AND_GOTO(context, err, done);
  334. done:
  335. ALCcontext_DecRef(context);
  336. }
  337. AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer,
  338. ALsizei offset, ALsizei samples,
  339. ALenum channels, ALenum type, const ALvoid *data)
  340. {
  341. ALCdevice *device;
  342. ALCcontext *context;
  343. ALbuffer *albuf;
  344. ALsizei align;
  345. context = GetContextRef();
  346. if(!context) return;
  347. device = context->Device;
  348. if((albuf=LookupBuffer(device, buffer)) == NULL)
  349. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  350. if(!(samples >= 0 && offset >= 0))
  351. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  352. if(IsValidType(type) == AL_FALSE)
  353. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  354. WriteLock(&albuf->lock);
  355. align = ATOMIC_LOAD(&albuf->UnpackAlign);
  356. if(SanitizeAlignment(type, &align) == AL_FALSE)
  357. {
  358. WriteUnlock(&albuf->lock);
  359. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  360. }
  361. if(channels != (ALenum)albuf->FmtChannels)
  362. {
  363. WriteUnlock(&albuf->lock);
  364. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  365. }
  366. if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset)
  367. {
  368. WriteUnlock(&albuf->lock);
  369. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  370. }
  371. if((samples%align) != 0)
  372. {
  373. WriteUnlock(&albuf->lock);
  374. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  375. }
  376. /* offset -> byte offset */
  377. offset *= FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType);
  378. ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
  379. data, type, ChannelsFromFmt(albuf->FmtChannels), samples, align);
  380. WriteUnlock(&albuf->lock);
  381. done:
  382. ALCcontext_DecRef(context);
  383. }
  384. AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer,
  385. ALsizei offset, ALsizei samples,
  386. ALenum channels, ALenum type, ALvoid *data)
  387. {
  388. ALCdevice *device;
  389. ALCcontext *context;
  390. ALbuffer *albuf;
  391. ALsizei align;
  392. context = GetContextRef();
  393. if(!context) return;
  394. device = context->Device;
  395. if((albuf=LookupBuffer(device, buffer)) == NULL)
  396. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  397. if(!(samples >= 0 && offset >= 0))
  398. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  399. if(IsValidType(type) == AL_FALSE)
  400. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  401. ReadLock(&albuf->lock);
  402. align = ATOMIC_LOAD(&albuf->PackAlign);
  403. if(SanitizeAlignment(type, &align) == AL_FALSE)
  404. {
  405. ReadUnlock(&albuf->lock);
  406. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  407. }
  408. if(channels != (ALenum)albuf->FmtChannels)
  409. {
  410. ReadUnlock(&albuf->lock);
  411. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  412. }
  413. if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset)
  414. {
  415. ReadUnlock(&albuf->lock);
  416. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  417. }
  418. if((samples%align) != 0)
  419. {
  420. ReadUnlock(&albuf->lock);
  421. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  422. }
  423. /* offset -> byte offset */
  424. offset *= FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType);
  425. ConvertData(data, type, (char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
  426. ChannelsFromFmt(albuf->FmtChannels), samples, align);
  427. ReadUnlock(&albuf->lock);
  428. done:
  429. ALCcontext_DecRef(context);
  430. }
  431. AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format)
  432. {
  433. enum FmtChannels dstchannels;
  434. enum FmtType dsttype;
  435. ALCcontext *context;
  436. ALboolean ret;
  437. context = GetContextRef();
  438. if(!context) return AL_FALSE;
  439. ret = DecomposeFormat(format, &dstchannels, &dsttype);
  440. ALCcontext_DecRef(context);
  441. return ret;
  442. }
  443. AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(value))
  444. {
  445. ALCdevice *device;
  446. ALCcontext *context;
  447. context = GetContextRef();
  448. if(!context) return;
  449. device = context->Device;
  450. if(LookupBuffer(device, buffer) == NULL)
  451. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  452. switch(param)
  453. {
  454. default:
  455. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  456. }
  457. done:
  458. ALCcontext_DecRef(context);
  459. }
  460. AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(value1), ALfloat UNUSED(value2), ALfloat UNUSED(value3))
  461. {
  462. ALCdevice *device;
  463. ALCcontext *context;
  464. context = GetContextRef();
  465. if(!context) return;
  466. device = context->Device;
  467. if(LookupBuffer(device, buffer) == NULL)
  468. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  469. switch(param)
  470. {
  471. default:
  472. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  473. }
  474. done:
  475. ALCcontext_DecRef(context);
  476. }
  477. AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values)
  478. {
  479. ALCdevice *device;
  480. ALCcontext *context;
  481. context = GetContextRef();
  482. if(!context) return;
  483. device = context->Device;
  484. if(LookupBuffer(device, buffer) == NULL)
  485. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  486. if(!(values))
  487. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  488. switch(param)
  489. {
  490. default:
  491. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  492. }
  493. done:
  494. ALCcontext_DecRef(context);
  495. }
  496. AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value)
  497. {
  498. ALCdevice *device;
  499. ALCcontext *context;
  500. ALbuffer *albuf;
  501. context = GetContextRef();
  502. if(!context) return;
  503. device = context->Device;
  504. if((albuf=LookupBuffer(device, buffer)) == NULL)
  505. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  506. switch(param)
  507. {
  508. case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
  509. if(!(value >= 0))
  510. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  511. ATOMIC_STORE(&albuf->UnpackAlign, value);
  512. break;
  513. case AL_PACK_BLOCK_ALIGNMENT_SOFT:
  514. if(!(value >= 0))
  515. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  516. ATOMIC_STORE(&albuf->PackAlign, value);
  517. break;
  518. default:
  519. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  520. }
  521. done:
  522. ALCcontext_DecRef(context);
  523. }
  524. AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(value1), ALint UNUSED(value2), ALint UNUSED(value3))
  525. {
  526. ALCdevice *device;
  527. ALCcontext *context;
  528. context = GetContextRef();
  529. if(!context) return;
  530. device = context->Device;
  531. if(LookupBuffer(device, buffer) == NULL)
  532. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  533. switch(param)
  534. {
  535. default:
  536. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  537. }
  538. done:
  539. ALCcontext_DecRef(context);
  540. }
  541. AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values)
  542. {
  543. ALCdevice *device;
  544. ALCcontext *context;
  545. ALbuffer *albuf;
  546. if(values)
  547. {
  548. switch(param)
  549. {
  550. case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
  551. case AL_PACK_BLOCK_ALIGNMENT_SOFT:
  552. alBufferi(buffer, param, values[0]);
  553. return;
  554. }
  555. }
  556. context = GetContextRef();
  557. if(!context) return;
  558. device = context->Device;
  559. if((albuf=LookupBuffer(device, buffer)) == NULL)
  560. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  561. if(!(values))
  562. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  563. switch(param)
  564. {
  565. case AL_LOOP_POINTS_SOFT:
  566. WriteLock(&albuf->lock);
  567. if(ReadRef(&albuf->ref) != 0)
  568. {
  569. WriteUnlock(&albuf->lock);
  570. SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
  571. }
  572. if(values[0] >= values[1] || values[0] < 0 ||
  573. values[1] > albuf->SampleLen)
  574. {
  575. WriteUnlock(&albuf->lock);
  576. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  577. }
  578. albuf->LoopStart = values[0];
  579. albuf->LoopEnd = values[1];
  580. WriteUnlock(&albuf->lock);
  581. break;
  582. default:
  583. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  584. }
  585. done:
  586. ALCcontext_DecRef(context);
  587. }
  588. AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value)
  589. {
  590. ALCdevice *device;
  591. ALCcontext *context;
  592. ALbuffer *albuf;
  593. context = GetContextRef();
  594. if(!context) return;
  595. device = context->Device;
  596. if((albuf=LookupBuffer(device, buffer)) == NULL)
  597. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  598. if(!(value))
  599. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  600. switch(param)
  601. {
  602. case AL_SEC_LENGTH_SOFT:
  603. ReadLock(&albuf->lock);
  604. if(albuf->SampleLen != 0)
  605. *value = albuf->SampleLen / (ALfloat)albuf->Frequency;
  606. else
  607. *value = 0.0f;
  608. ReadUnlock(&albuf->lock);
  609. break;
  610. default:
  611. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  612. }
  613. done:
  614. ALCcontext_DecRef(context);
  615. }
  616. AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
  617. {
  618. ALCdevice *device;
  619. ALCcontext *context;
  620. context = GetContextRef();
  621. if(!context) return;
  622. device = context->Device;
  623. if(LookupBuffer(device, buffer) == NULL)
  624. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  625. if(!(value1 && value2 && value3))
  626. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  627. switch(param)
  628. {
  629. default:
  630. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  631. }
  632. done:
  633. ALCcontext_DecRef(context);
  634. }
  635. AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values)
  636. {
  637. ALCdevice *device;
  638. ALCcontext *context;
  639. switch(param)
  640. {
  641. case AL_SEC_LENGTH_SOFT:
  642. alGetBufferf(buffer, param, values);
  643. return;
  644. }
  645. context = GetContextRef();
  646. if(!context) return;
  647. device = context->Device;
  648. if(LookupBuffer(device, buffer) == NULL)
  649. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  650. if(!(values))
  651. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  652. switch(param)
  653. {
  654. default:
  655. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  656. }
  657. done:
  658. ALCcontext_DecRef(context);
  659. }
  660. AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value)
  661. {
  662. ALCdevice *device;
  663. ALCcontext *context;
  664. ALbuffer *albuf;
  665. context = GetContextRef();
  666. if(!context) return;
  667. device = context->Device;
  668. if((albuf=LookupBuffer(device, buffer)) == NULL)
  669. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  670. if(!(value))
  671. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  672. switch(param)
  673. {
  674. case AL_FREQUENCY:
  675. *value = albuf->Frequency;
  676. break;
  677. case AL_BITS:
  678. *value = BytesFromFmt(albuf->FmtType) * 8;
  679. break;
  680. case AL_CHANNELS:
  681. *value = ChannelsFromFmt(albuf->FmtChannels);
  682. break;
  683. case AL_SIZE:
  684. ReadLock(&albuf->lock);
  685. *value = albuf->SampleLen * FrameSizeFromFmt(albuf->FmtChannels,
  686. albuf->FmtType);
  687. ReadUnlock(&albuf->lock);
  688. break;
  689. case AL_INTERNAL_FORMAT_SOFT:
  690. *value = albuf->Format;
  691. break;
  692. case AL_BYTE_LENGTH_SOFT:
  693. *value = albuf->OriginalSize;
  694. break;
  695. case AL_SAMPLE_LENGTH_SOFT:
  696. *value = albuf->SampleLen;
  697. break;
  698. case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
  699. *value = ATOMIC_LOAD(&albuf->UnpackAlign);
  700. break;
  701. case AL_PACK_BLOCK_ALIGNMENT_SOFT:
  702. *value = ATOMIC_LOAD(&albuf->PackAlign);
  703. break;
  704. default:
  705. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  706. }
  707. done:
  708. ALCcontext_DecRef(context);
  709. }
  710. AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3)
  711. {
  712. ALCdevice *device;
  713. ALCcontext *context;
  714. context = GetContextRef();
  715. if(!context) return;
  716. device = context->Device;
  717. if(LookupBuffer(device, buffer) == NULL)
  718. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  719. if(!(value1 && value2 && value3))
  720. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  721. switch(param)
  722. {
  723. default:
  724. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  725. }
  726. done:
  727. ALCcontext_DecRef(context);
  728. }
  729. AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values)
  730. {
  731. ALCdevice *device;
  732. ALCcontext *context;
  733. ALbuffer *albuf;
  734. switch(param)
  735. {
  736. case AL_FREQUENCY:
  737. case AL_BITS:
  738. case AL_CHANNELS:
  739. case AL_SIZE:
  740. case AL_INTERNAL_FORMAT_SOFT:
  741. case AL_BYTE_LENGTH_SOFT:
  742. case AL_SAMPLE_LENGTH_SOFT:
  743. case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
  744. case AL_PACK_BLOCK_ALIGNMENT_SOFT:
  745. alGetBufferi(buffer, param, values);
  746. return;
  747. }
  748. context = GetContextRef();
  749. if(!context) return;
  750. device = context->Device;
  751. if((albuf=LookupBuffer(device, buffer)) == NULL)
  752. SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
  753. if(!(values))
  754. SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
  755. switch(param)
  756. {
  757. case AL_LOOP_POINTS_SOFT:
  758. ReadLock(&albuf->lock);
  759. values[0] = albuf->LoopStart;
  760. values[1] = albuf->LoopEnd;
  761. ReadUnlock(&albuf->lock);
  762. break;
  763. default:
  764. SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
  765. }
  766. done:
  767. ALCcontext_DecRef(context);
  768. }
  769. /*
  770. * LoadData
  771. *
  772. * Loads the specified data into the buffer, using the specified formats.
  773. * Currently, the new format must have the same channel configuration as the
  774. * original format.
  775. */
  776. ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc)
  777. {
  778. ALuint NewChannels, NewBytes;
  779. enum FmtChannels DstChannels;
  780. enum FmtType DstType;
  781. ALuint64 newsize;
  782. ALvoid *temp;
  783. if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE ||
  784. (long)SrcChannels != (long)DstChannels)
  785. return AL_INVALID_ENUM;
  786. NewChannels = ChannelsFromFmt(DstChannels);
  787. NewBytes = BytesFromFmt(DstType);
  788. newsize = frames;
  789. newsize *= NewBytes;
  790. newsize *= NewChannels;
  791. if(newsize > INT_MAX)
  792. return AL_OUT_OF_MEMORY;
  793. WriteLock(&ALBuf->lock);
  794. if(ReadRef(&ALBuf->ref) != 0)
  795. {
  796. WriteUnlock(&ALBuf->lock);
  797. return AL_INVALID_OPERATION;
  798. }
  799. temp = realloc(ALBuf->data, (size_t)newsize);
  800. if(!temp && newsize)
  801. {
  802. WriteUnlock(&ALBuf->lock);
  803. return AL_OUT_OF_MEMORY;
  804. }
  805. ALBuf->data = temp;
  806. if(data != NULL)
  807. ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames, align);
  808. if(storesrc)
  809. {
  810. ALBuf->OriginalChannels = SrcChannels;
  811. ALBuf->OriginalType = SrcType;
  812. if(SrcType == UserFmtIMA4)
  813. {
  814. ALsizei byte_align = ((align-1)/2 + 4) * ChannelsFromUserFmt(SrcChannels);
  815. ALBuf->OriginalSize = frames / align * byte_align;
  816. ALBuf->OriginalAlign = align;
  817. }
  818. else if(SrcType == UserFmtMSADPCM)
  819. {
  820. ALsizei byte_align = ((align-2)/2 + 7) * ChannelsFromUserFmt(SrcChannels);
  821. ALBuf->OriginalSize = frames / align * byte_align;
  822. ALBuf->OriginalAlign = align;
  823. }
  824. else
  825. {
  826. ALBuf->OriginalSize = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
  827. ALBuf->OriginalAlign = 1;
  828. }
  829. }
  830. else
  831. {
  832. ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels;
  833. ALBuf->OriginalType = (enum UserFmtType)DstType;
  834. ALBuf->OriginalSize = frames * NewBytes * NewChannels;
  835. ALBuf->OriginalAlign = 1;
  836. }
  837. ALBuf->Frequency = freq;
  838. ALBuf->FmtChannels = DstChannels;
  839. ALBuf->FmtType = DstType;
  840. ALBuf->Format = NewFormat;
  841. ALBuf->SampleLen = frames;
  842. ALBuf->LoopStart = 0;
  843. ALBuf->LoopEnd = ALBuf->SampleLen;
  844. WriteUnlock(&ALBuf->lock);
  845. return AL_NO_ERROR;
  846. }
  847. ALuint BytesFromUserFmt(enum UserFmtType type)
  848. {
  849. switch(type)
  850. {
  851. case UserFmtByte: return sizeof(ALbyte);
  852. case UserFmtUByte: return sizeof(ALubyte);
  853. case UserFmtShort: return sizeof(ALshort);
  854. case UserFmtUShort: return sizeof(ALushort);
  855. case UserFmtInt: return sizeof(ALint);
  856. case UserFmtUInt: return sizeof(ALuint);
  857. case UserFmtFloat: return sizeof(ALfloat);
  858. case UserFmtDouble: return sizeof(ALdouble);
  859. case UserFmtByte3: return sizeof(ALbyte[3]);
  860. case UserFmtUByte3: return sizeof(ALubyte[3]);
  861. case UserFmtMulaw: return sizeof(ALubyte);
  862. case UserFmtAlaw: return sizeof(ALubyte);
  863. case UserFmtIMA4: break; /* not handled here */
  864. case UserFmtMSADPCM: break; /* not handled here */
  865. }
  866. return 0;
  867. }
  868. ALuint ChannelsFromUserFmt(enum UserFmtChannels chans)
  869. {
  870. switch(chans)
  871. {
  872. case UserFmtMono: return 1;
  873. case UserFmtStereo: return 2;
  874. case UserFmtRear: return 2;
  875. case UserFmtQuad: return 4;
  876. case UserFmtX51: return 6;
  877. case UserFmtX61: return 7;
  878. case UserFmtX71: return 8;
  879. case UserFmtBFormat2D: return 3;
  880. case UserFmtBFormat3D: return 4;
  881. }
  882. return 0;
  883. }
  884. static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans,
  885. enum UserFmtType *type)
  886. {
  887. static const struct {
  888. ALenum format;
  889. enum UserFmtChannels channels;
  890. enum UserFmtType type;
  891. } list[] = {
  892. { AL_FORMAT_MONO8, UserFmtMono, UserFmtUByte },
  893. { AL_FORMAT_MONO16, UserFmtMono, UserFmtShort },
  894. { AL_FORMAT_MONO_FLOAT32, UserFmtMono, UserFmtFloat },
  895. { AL_FORMAT_MONO_DOUBLE_EXT, UserFmtMono, UserFmtDouble },
  896. { AL_FORMAT_MONO_IMA4, UserFmtMono, UserFmtIMA4 },
  897. { AL_FORMAT_MONO_MSADPCM_SOFT, UserFmtMono, UserFmtMSADPCM },
  898. { AL_FORMAT_MONO_MULAW, UserFmtMono, UserFmtMulaw },
  899. { AL_FORMAT_MONO_ALAW_EXT, UserFmtMono, UserFmtAlaw },
  900. { AL_FORMAT_STEREO8, UserFmtStereo, UserFmtUByte },
  901. { AL_FORMAT_STEREO16, UserFmtStereo, UserFmtShort },
  902. { AL_FORMAT_STEREO_FLOAT32, UserFmtStereo, UserFmtFloat },
  903. { AL_FORMAT_STEREO_DOUBLE_EXT, UserFmtStereo, UserFmtDouble },
  904. { AL_FORMAT_STEREO_IMA4, UserFmtStereo, UserFmtIMA4 },
  905. { AL_FORMAT_STEREO_MSADPCM_SOFT, UserFmtStereo, UserFmtMSADPCM },
  906. { AL_FORMAT_STEREO_MULAW, UserFmtStereo, UserFmtMulaw },
  907. { AL_FORMAT_STEREO_ALAW_EXT, UserFmtStereo, UserFmtAlaw },
  908. { AL_FORMAT_REAR8, UserFmtRear, UserFmtUByte },
  909. { AL_FORMAT_REAR16, UserFmtRear, UserFmtShort },
  910. { AL_FORMAT_REAR32, UserFmtRear, UserFmtFloat },
  911. { AL_FORMAT_REAR_MULAW, UserFmtRear, UserFmtMulaw },
  912. { AL_FORMAT_QUAD8_LOKI, UserFmtQuad, UserFmtUByte },
  913. { AL_FORMAT_QUAD16_LOKI, UserFmtQuad, UserFmtShort },
  914. { AL_FORMAT_QUAD8, UserFmtQuad, UserFmtUByte },
  915. { AL_FORMAT_QUAD16, UserFmtQuad, UserFmtShort },
  916. { AL_FORMAT_QUAD32, UserFmtQuad, UserFmtFloat },
  917. { AL_FORMAT_QUAD_MULAW, UserFmtQuad, UserFmtMulaw },
  918. { AL_FORMAT_51CHN8, UserFmtX51, UserFmtUByte },
  919. { AL_FORMAT_51CHN16, UserFmtX51, UserFmtShort },
  920. { AL_FORMAT_51CHN32, UserFmtX51, UserFmtFloat },
  921. { AL_FORMAT_51CHN_MULAW, UserFmtX51, UserFmtMulaw },
  922. { AL_FORMAT_61CHN8, UserFmtX61, UserFmtUByte },
  923. { AL_FORMAT_61CHN16, UserFmtX61, UserFmtShort },
  924. { AL_FORMAT_61CHN32, UserFmtX61, UserFmtFloat },
  925. { AL_FORMAT_61CHN_MULAW, UserFmtX61, UserFmtMulaw },
  926. { AL_FORMAT_71CHN8, UserFmtX71, UserFmtUByte },
  927. { AL_FORMAT_71CHN16, UserFmtX71, UserFmtShort },
  928. { AL_FORMAT_71CHN32, UserFmtX71, UserFmtFloat },
  929. { AL_FORMAT_71CHN_MULAW, UserFmtX71, UserFmtMulaw },
  930. { AL_FORMAT_BFORMAT2D_8, UserFmtBFormat2D, UserFmtUByte },
  931. { AL_FORMAT_BFORMAT2D_16, UserFmtBFormat2D, UserFmtShort },
  932. { AL_FORMAT_BFORMAT2D_FLOAT32, UserFmtBFormat2D, UserFmtFloat },
  933. { AL_FORMAT_BFORMAT2D_MULAW, UserFmtBFormat2D, UserFmtMulaw },
  934. { AL_FORMAT_BFORMAT3D_8, UserFmtBFormat3D, UserFmtUByte },
  935. { AL_FORMAT_BFORMAT3D_16, UserFmtBFormat3D, UserFmtShort },
  936. { AL_FORMAT_BFORMAT3D_FLOAT32, UserFmtBFormat3D, UserFmtFloat },
  937. { AL_FORMAT_BFORMAT3D_MULAW, UserFmtBFormat3D, UserFmtMulaw },
  938. };
  939. ALuint i;
  940. for(i = 0;i < COUNTOF(list);i++)
  941. {
  942. if(list[i].format == format)
  943. {
  944. *chans = list[i].channels;
  945. *type = list[i].type;
  946. return AL_TRUE;
  947. }
  948. }
  949. return AL_FALSE;
  950. }
  951. ALuint BytesFromFmt(enum FmtType type)
  952. {
  953. switch(type)
  954. {
  955. case FmtByte: return sizeof(ALbyte);
  956. case FmtShort: return sizeof(ALshort);
  957. case FmtFloat: return sizeof(ALfloat);
  958. }
  959. return 0;
  960. }
  961. ALuint ChannelsFromFmt(enum FmtChannels chans)
  962. {
  963. switch(chans)
  964. {
  965. case FmtMono: return 1;
  966. case FmtStereo: return 2;
  967. case FmtRear: return 2;
  968. case FmtQuad: return 4;
  969. case FmtX51: return 6;
  970. case FmtX61: return 7;
  971. case FmtX71: return 8;
  972. case FmtBFormat2D: return 3;
  973. case FmtBFormat3D: return 4;
  974. }
  975. return 0;
  976. }
  977. static ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type)
  978. {
  979. static const struct {
  980. ALenum format;
  981. enum FmtChannels channels;
  982. enum FmtType type;
  983. } list[] = {
  984. { AL_MONO8_SOFT, FmtMono, FmtByte },
  985. { AL_MONO16_SOFT, FmtMono, FmtShort },
  986. { AL_MONO32F_SOFT, FmtMono, FmtFloat },
  987. { AL_STEREO8_SOFT, FmtStereo, FmtByte },
  988. { AL_STEREO16_SOFT, FmtStereo, FmtShort },
  989. { AL_STEREO32F_SOFT, FmtStereo, FmtFloat },
  990. { AL_REAR8_SOFT, FmtRear, FmtByte },
  991. { AL_REAR16_SOFT, FmtRear, FmtShort },
  992. { AL_REAR32F_SOFT, FmtRear, FmtFloat },
  993. { AL_FORMAT_QUAD8_LOKI, FmtQuad, FmtByte },
  994. { AL_FORMAT_QUAD16_LOKI, FmtQuad, FmtShort },
  995. { AL_QUAD8_SOFT, FmtQuad, FmtByte },
  996. { AL_QUAD16_SOFT, FmtQuad, FmtShort },
  997. { AL_QUAD32F_SOFT, FmtQuad, FmtFloat },
  998. { AL_5POINT1_8_SOFT, FmtX51, FmtByte },
  999. { AL_5POINT1_16_SOFT, FmtX51, FmtShort },
  1000. { AL_5POINT1_32F_SOFT, FmtX51, FmtFloat },
  1001. { AL_6POINT1_8_SOFT, FmtX61, FmtByte },
  1002. { AL_6POINT1_16_SOFT, FmtX61, FmtShort },
  1003. { AL_6POINT1_32F_SOFT, FmtX61, FmtFloat },
  1004. { AL_7POINT1_8_SOFT, FmtX71, FmtByte },
  1005. { AL_7POINT1_16_SOFT, FmtX71, FmtShort },
  1006. { AL_7POINT1_32F_SOFT, FmtX71, FmtFloat },
  1007. { AL_FORMAT_BFORMAT2D_8, FmtBFormat2D, FmtByte },
  1008. { AL_FORMAT_BFORMAT2D_16, FmtBFormat2D, FmtShort },
  1009. { AL_FORMAT_BFORMAT2D_FLOAT32, FmtBFormat2D, FmtFloat },
  1010. { AL_FORMAT_BFORMAT3D_8, FmtBFormat3D, FmtByte },
  1011. { AL_FORMAT_BFORMAT3D_16, FmtBFormat3D, FmtShort },
  1012. { AL_FORMAT_BFORMAT3D_FLOAT32, FmtBFormat3D, FmtFloat },
  1013. };
  1014. ALuint i;
  1015. for(i = 0;i < COUNTOF(list);i++)
  1016. {
  1017. if(list[i].format == format)
  1018. {
  1019. *chans = list[i].channels;
  1020. *type = list[i].type;
  1021. return AL_TRUE;
  1022. }
  1023. }
  1024. return AL_FALSE;
  1025. }
  1026. static ALboolean SanitizeAlignment(enum UserFmtType type, ALsizei *align)
  1027. {
  1028. if(*align < 0)
  1029. return AL_FALSE;
  1030. if(*align == 0)
  1031. {
  1032. if(type == UserFmtIMA4)
  1033. {
  1034. /* Here is where things vary:
  1035. * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel
  1036. * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel
  1037. */
  1038. *align = 65;
  1039. }
  1040. else if(type == UserFmtMSADPCM)
  1041. *align = 64;
  1042. else
  1043. *align = 1;
  1044. return AL_TRUE;
  1045. }
  1046. if(type == UserFmtIMA4)
  1047. {
  1048. /* IMA4 block alignment must be a multiple of 8, plus 1. */
  1049. return ((*align)&7) == 1;
  1050. }
  1051. if(type == UserFmtMSADPCM)
  1052. {
  1053. /* MSADPCM block alignment must be a multiple of 2. */
  1054. /* FIXME: Too strict? Might only require align*channels to be a
  1055. * multiple of 2. */
  1056. return ((*align)&1) == 0;
  1057. }
  1058. return AL_TRUE;
  1059. }
  1060. static ALboolean IsValidType(ALenum type)
  1061. {
  1062. switch(type)
  1063. {
  1064. case AL_BYTE_SOFT:
  1065. case AL_UNSIGNED_BYTE_SOFT:
  1066. case AL_SHORT_SOFT:
  1067. case AL_UNSIGNED_SHORT_SOFT:
  1068. case AL_INT_SOFT:
  1069. case AL_UNSIGNED_INT_SOFT:
  1070. case AL_FLOAT_SOFT:
  1071. case AL_DOUBLE_SOFT:
  1072. case AL_BYTE3_SOFT:
  1073. case AL_UNSIGNED_BYTE3_SOFT:
  1074. return AL_TRUE;
  1075. }
  1076. return AL_FALSE;
  1077. }
  1078. static ALboolean IsValidChannels(ALenum channels)
  1079. {
  1080. switch(channels)
  1081. {
  1082. case AL_MONO_SOFT:
  1083. case AL_STEREO_SOFT:
  1084. case AL_REAR_SOFT:
  1085. case AL_QUAD_SOFT:
  1086. case AL_5POINT1_SOFT:
  1087. case AL_6POINT1_SOFT:
  1088. case AL_7POINT1_SOFT:
  1089. return AL_TRUE;
  1090. }
  1091. return AL_FALSE;
  1092. }
  1093. ALbuffer *NewBuffer(ALCcontext *context)
  1094. {
  1095. ALCdevice *device = context->Device;
  1096. ALbuffer *buffer;
  1097. ALenum err;
  1098. buffer = calloc(1, sizeof(ALbuffer));
  1099. if(!buffer)
  1100. SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL);
  1101. RWLockInit(&buffer->lock);
  1102. err = NewThunkEntry(&buffer->id);
  1103. if(err == AL_NO_ERROR)
  1104. err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer);
  1105. if(err != AL_NO_ERROR)
  1106. {
  1107. FreeThunkEntry(buffer->id);
  1108. memset(buffer, 0, sizeof(ALbuffer));
  1109. free(buffer);
  1110. SET_ERROR_AND_RETURN_VALUE(context, err, NULL);
  1111. }
  1112. return buffer;
  1113. }
  1114. void DeleteBuffer(ALCdevice *device, ALbuffer *buffer)
  1115. {
  1116. RemoveBuffer(device, buffer->id);
  1117. FreeThunkEntry(buffer->id);
  1118. free(buffer->data);
  1119. memset(buffer, 0, sizeof(*buffer));
  1120. free(buffer);
  1121. }
  1122. /*
  1123. * ReleaseALBuffers()
  1124. *
  1125. * INTERNAL: Called to destroy any buffers that still exist on the device
  1126. */
  1127. ALvoid ReleaseALBuffers(ALCdevice *device)
  1128. {
  1129. ALsizei i;
  1130. for(i = 0;i < device->BufferMap.size;i++)
  1131. {
  1132. ALbuffer *temp = device->BufferMap.array[i].value;
  1133. device->BufferMap.array[i].value = NULL;
  1134. free(temp->data);
  1135. FreeThunkEntry(temp->id);
  1136. memset(temp, 0, sizeof(ALbuffer));
  1137. free(temp);
  1138. }
  1139. }