Use specialized methods for converting IMA4 and MSADPCM to ALshort
[openal-soft.git] / OpenAL32 / alBuffer.c
blobddd9e59fe3b90b0efce8a25259d6e8338c48a9fb
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.
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.
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
21 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <assert.h>
26 #include <limits.h>
27 #ifdef HAVE_ALLOCA_H
28 #include <alloca.h>
29 #endif
30 #ifdef HAVE_MALLOC_H
31 #include <malloc.h>
32 #endif
34 #include "alMain.h"
35 #include "alu.h"
36 #include "alError.h"
37 #include "alBuffer.h"
38 #include "alThunk.h"
41 extern inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id);
42 extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id);
43 extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type);
44 extern inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type);
46 static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels chans, enum UserFmtType type, const ALvoid *data, ALsizei align, ALboolean storesrc);
47 static void ConvertData(ALvoid *dst, enum UserFmtType dstType, const ALvoid *src, enum UserFmtType srcType, ALsizei numchans, ALsizei len, ALsizei align);
48 static ALboolean IsValidType(ALenum type);
49 static ALboolean IsValidChannels(ALenum channels);
50 static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans, enum UserFmtType *type);
51 static ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type);
52 static ALboolean SanitizeAlignment(enum UserFmtType type, ALsizei *align);
56 * Global Variables
59 /* IMA ADPCM Stepsize table */
60 static const int IMAStep_size[89] = {
61 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19,
62 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55,
63 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157,
64 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
65 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
66 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660,
67 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,
68 11487,12635,13899,15289,16818,18500,20350,22358,24633,27086,29794,
69 32767
72 /* IMA4 ADPCM Codeword decode table */
73 static const int IMA4Codeword[16] = {
74 1, 3, 5, 7, 9, 11, 13, 15,
75 -1,-3,-5,-7,-9,-11,-13,-15,
78 /* IMA4 ADPCM Step index adjust decode table */
79 static const int IMA4Index_adjust[16] = {
80 -1,-1,-1,-1, 2, 4, 6, 8,
81 -1,-1,-1,-1, 2, 4, 6, 8
85 /* MSADPCM Adaption table */
86 static const int MSADPCMAdaption[16] = {
87 230, 230, 230, 230, 307, 409, 512, 614,
88 768, 614, 512, 409, 307, 230, 230, 230
91 /* MSADPCM Adaption Coefficient tables */
92 static const int MSADPCMAdaptionCoeff[7][2] = {
93 { 256, 0 },
94 { 512, -256 },
95 { 0, 0 },
96 { 192, 64 },
97 { 240, 0 },
98 { 460, -208 },
99 { 392, -232 }
103 /* A quick'n'dirty lookup table to decode a muLaw-encoded byte sample into a
104 * signed 16-bit sample */
105 static const ALshort muLawDecompressionTable[256] = {
106 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
107 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
108 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
109 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
110 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
111 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
112 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
113 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
114 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
115 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
116 -876, -844, -812, -780, -748, -716, -684, -652,
117 -620, -588, -556, -524, -492, -460, -428, -396,
118 -372, -356, -340, -324, -308, -292, -276, -260,
119 -244, -228, -212, -196, -180, -164, -148, -132,
120 -120, -112, -104, -96, -88, -80, -72, -64,
121 -56, -48, -40, -32, -24, -16, -8, 0,
122 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
123 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
124 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
125 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
126 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
127 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
128 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
129 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
130 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
131 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
132 876, 844, 812, 780, 748, 716, 684, 652,
133 620, 588, 556, 524, 492, 460, 428, 396,
134 372, 356, 340, 324, 308, 292, 276, 260,
135 244, 228, 212, 196, 180, 164, 148, 132,
136 120, 112, 104, 96, 88, 80, 72, 64,
137 56, 48, 40, 32, 24, 16, 8, 0
140 /* Values used when encoding a muLaw sample */
141 static const int muLawBias = 0x84;
142 static const int muLawClip = 32635;
143 static const char muLawCompressTable[256] = {
144 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
145 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
146 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
147 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
148 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
149 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
150 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
151 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
152 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
153 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
154 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
155 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
156 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
157 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
158 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
159 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
163 /* A quick'n'dirty lookup table to decode an aLaw-encoded byte sample into a
164 * signed 16-bit sample */
165 static const ALshort aLawDecompressionTable[256] = {
166 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
167 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
168 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
169 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
170 -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,
171 -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,
172 -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,
173 -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,
174 -344, -328, -376, -360, -280, -264, -312, -296,
175 -472, -456, -504, -488, -408, -392, -440, -424,
176 -88, -72, -120, -104, -24, -8, -56, -40,
177 -216, -200, -248, -232, -152, -136, -184, -168,
178 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
179 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
180 -688, -656, -752, -720, -560, -528, -624, -592,
181 -944, -912, -1008, -976, -816, -784, -880, -848,
182 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
183 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
184 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
185 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
186 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
187 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
188 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
189 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
190 344, 328, 376, 360, 280, 264, 312, 296,
191 472, 456, 504, 488, 408, 392, 440, 424,
192 88, 72, 120, 104, 24, 8, 56, 40,
193 216, 200, 248, 232, 152, 136, 184, 168,
194 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
195 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
196 688, 656, 752, 720, 560, 528, 624, 592,
197 944, 912, 1008, 976, 816, 784, 880, 848
200 /* Values used when encoding an aLaw sample */
201 static const int aLawClip = 32635;
202 static const char aLawCompressTable[128] = {
203 1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
204 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
205 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
206 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
207 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
208 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
209 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
210 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
214 AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
216 ALCdevice *device;
217 ALCcontext *context;
218 ALsizei cur = 0;
219 ALenum err;
221 context = GetContextRef();
222 if(!context) return;
224 if(!(n >= 0))
225 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
227 device = context->Device;
228 for(cur = 0;cur < n;cur++)
230 ALbuffer *buffer = calloc(1, sizeof(ALbuffer));
231 if(!buffer)
233 alDeleteBuffers(cur, buffers);
234 SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
236 RWLockInit(&buffer->lock);
238 err = NewThunkEntry(&buffer->id);
239 if(err == AL_NO_ERROR)
240 err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer);
241 if(err != AL_NO_ERROR)
243 FreeThunkEntry(buffer->id);
244 memset(buffer, 0, sizeof(ALbuffer));
245 free(buffer);
247 alDeleteBuffers(cur, buffers);
248 SET_ERROR_AND_GOTO(context, err, done);
251 buffers[cur] = buffer->id;
254 done:
255 ALCcontext_DecRef(context);
258 AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
260 ALCdevice *device;
261 ALCcontext *context;
262 ALbuffer *ALBuf;
263 ALsizei i;
265 context = GetContextRef();
266 if(!context) return;
268 if(!(n >= 0))
269 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
271 device = context->Device;
272 for(i = 0;i < n;i++)
274 if(!buffers[i])
275 continue;
277 /* Check for valid Buffer ID */
278 if((ALBuf=LookupBuffer(device, buffers[i])) == NULL)
279 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
280 if(ALBuf->ref != 0)
281 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
284 for(i = 0;i < n;i++)
286 if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL)
287 continue;
288 FreeThunkEntry(ALBuf->id);
290 free(ALBuf->data);
292 memset(ALBuf, 0, sizeof(*ALBuf));
293 free(ALBuf);
296 done:
297 ALCcontext_DecRef(context);
300 AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
302 ALCcontext *context;
303 ALboolean ret;
305 context = GetContextRef();
306 if(!context) return AL_FALSE;
308 ret = ((!buffer || LookupBuffer(context->Device, buffer)) ?
309 AL_TRUE : AL_FALSE);
311 ALCcontext_DecRef(context);
313 return ret;
317 AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
319 enum UserFmtChannels srcchannels;
320 enum UserFmtType srctype;
321 ALCdevice *device;
322 ALCcontext *context;
323 ALuint framesize;
324 ALenum newformat;
325 ALbuffer *albuf;
326 ALsizei align;
327 ALenum err;
329 context = GetContextRef();
330 if(!context) return;
332 device = context->Device;
333 if((albuf=LookupBuffer(device, buffer)) == NULL)
334 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
335 if(!(size >= 0 && freq > 0))
336 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
337 if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)
338 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
340 align = albuf->UnpackAlign;
341 if(SanitizeAlignment(srctype, &align) == AL_FALSE)
342 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
343 switch(srctype)
345 case UserFmtByte:
346 case UserFmtUByte:
347 case UserFmtShort:
348 case UserFmtUShort:
349 case UserFmtFloat:
350 framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align;
351 if((size%framesize) != 0)
352 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
354 err = LoadData(albuf, freq, format, size/framesize*align,
355 srcchannels, srctype, data, align, AL_TRUE);
356 if(err != AL_NO_ERROR)
357 SET_ERROR_AND_GOTO(context, err, done);
358 break;
360 case UserFmtInt:
361 case UserFmtUInt:
362 case UserFmtByte3:
363 case UserFmtUByte3:
364 case UserFmtDouble:
365 framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align;
366 if((size%framesize) != 0)
367 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
369 newformat = AL_FORMAT_MONO_FLOAT32;
370 switch(srcchannels)
372 case UserFmtMono: newformat = AL_FORMAT_MONO_FLOAT32; break;
373 case UserFmtStereo: newformat = AL_FORMAT_STEREO_FLOAT32; break;
374 case UserFmtRear: newformat = AL_FORMAT_REAR32; break;
375 case UserFmtQuad: newformat = AL_FORMAT_QUAD32; break;
376 case UserFmtX51: newformat = AL_FORMAT_51CHN32; break;
377 case UserFmtX61: newformat = AL_FORMAT_61CHN32; break;
378 case UserFmtX71: newformat = AL_FORMAT_71CHN32; break;
380 err = LoadData(albuf, freq, newformat, size/framesize*align,
381 srcchannels, srctype, data, align, AL_TRUE);
382 if(err != AL_NO_ERROR)
383 SET_ERROR_AND_GOTO(context, err, done);
384 break;
386 case UserFmtMulaw:
387 case UserFmtAlaw:
388 framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align;
389 if((size%framesize) != 0)
390 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
392 newformat = AL_FORMAT_MONO16;
393 switch(srcchannels)
395 case UserFmtMono: newformat = AL_FORMAT_MONO16; break;
396 case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break;
397 case UserFmtRear: newformat = AL_FORMAT_REAR16; break;
398 case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break;
399 case UserFmtX51: newformat = AL_FORMAT_51CHN16; break;
400 case UserFmtX61: newformat = AL_FORMAT_61CHN16; break;
401 case UserFmtX71: newformat = AL_FORMAT_71CHN16; break;
403 err = LoadData(albuf, freq, newformat, size/framesize*align,
404 srcchannels, srctype, data, align, AL_TRUE);
405 if(err != AL_NO_ERROR)
406 SET_ERROR_AND_GOTO(context, err, done);
407 break;
409 case UserFmtIMA4:
410 framesize = (align-1)/2 + 4;
411 framesize *= ChannelsFromUserFmt(srcchannels);
412 if((size%framesize) != 0)
413 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
415 newformat = AL_FORMAT_MONO16;
416 switch(srcchannels)
418 case UserFmtMono: newformat = AL_FORMAT_MONO16; break;
419 case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break;
420 case UserFmtRear: newformat = AL_FORMAT_REAR16; break;
421 case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break;
422 case UserFmtX51: newformat = AL_FORMAT_51CHN16; break;
423 case UserFmtX61: newformat = AL_FORMAT_61CHN16; break;
424 case UserFmtX71: newformat = AL_FORMAT_71CHN16; break;
426 err = LoadData(albuf, freq, newformat, size/framesize*align,
427 srcchannels, srctype, data, align, AL_TRUE);
428 if(err != AL_NO_ERROR)
429 SET_ERROR_AND_GOTO(context, err, done);
430 break;
432 case UserFmtMSADPCM:
433 framesize = (align-2)/2 + 7;
434 framesize *= ChannelsFromUserFmt(srcchannels);
435 if((size%framesize) != 0)
436 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
438 newformat = AL_FORMAT_MONO16;
439 switch(srcchannels)
441 case UserFmtMono: newformat = AL_FORMAT_MONO16; break;
442 case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break;
443 case UserFmtRear: newformat = AL_FORMAT_REAR16; break;
444 case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break;
445 case UserFmtX51: newformat = AL_FORMAT_51CHN16; break;
446 case UserFmtX61: newformat = AL_FORMAT_61CHN16; break;
447 case UserFmtX71: newformat = AL_FORMAT_71CHN16; break;
449 err = LoadData(albuf, freq, newformat, size/framesize*align,
450 srcchannels, srctype, data, align, AL_TRUE);
451 if(err != AL_NO_ERROR)
452 SET_ERROR_AND_GOTO(context, err, done);
453 break;
456 done:
457 ALCcontext_DecRef(context);
460 AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length)
462 enum UserFmtChannels srcchannels;
463 enum UserFmtType srctype;
464 ALCdevice *device;
465 ALCcontext *context;
466 ALbuffer *albuf;
467 ALuint byte_align;
468 ALuint channels;
469 ALuint bytes;
470 ALsizei align;
472 context = GetContextRef();
473 if(!context) return;
475 device = context->Device;
476 if((albuf=LookupBuffer(device, buffer)) == NULL)
477 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
478 if(!(length >= 0 && offset >= 0))
479 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
480 if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)
481 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
483 WriteLock(&albuf->lock);
484 align = albuf->UnpackAlign;
485 if(SanitizeAlignment(srctype, &align) == AL_FALSE)
487 WriteUnlock(&albuf->lock);
488 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
490 if(srcchannels != albuf->OriginalChannels || srctype != albuf->OriginalType)
492 WriteUnlock(&albuf->lock);
493 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
495 if(align != albuf->OriginalAlign)
497 WriteUnlock(&albuf->lock);
498 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
501 if(albuf->OriginalType == UserFmtIMA4)
503 byte_align = (albuf->OriginalAlign-1)/2 + 4;
504 byte_align *= ChannelsFromUserFmt(albuf->OriginalChannels);
506 else if(albuf->OriginalType == UserFmtMSADPCM)
508 byte_align = (albuf->OriginalAlign-2)/2 + 7;
509 byte_align *= ChannelsFromUserFmt(albuf->OriginalChannels);
511 else
513 byte_align = albuf->OriginalAlign;
514 byte_align *= FrameSizeFromUserFmt(albuf->OriginalChannels,
515 albuf->OriginalType);
518 if(offset > albuf->OriginalSize || length > albuf->OriginalSize-offset ||
519 (offset%byte_align) != 0 || (length%byte_align) != 0)
521 WriteUnlock(&albuf->lock);
522 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
525 channels = ChannelsFromFmt(albuf->FmtChannels);
526 bytes = BytesFromFmt(albuf->FmtType);
527 /* offset -> byte offset, length -> sample count */
528 offset = offset/byte_align * channels*bytes;
529 length = length/byte_align * albuf->OriginalAlign;
531 ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
532 data, srctype, channels, length, align);
533 WriteUnlock(&albuf->lock);
535 done:
536 ALCcontext_DecRef(context);
540 AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer,
541 ALuint samplerate, ALenum internalformat, ALsizei samples,
542 ALenum channels, ALenum type, const ALvoid *data)
544 ALCdevice *device;
545 ALCcontext *context;
546 ALbuffer *albuf;
547 ALsizei align;
548 ALenum err;
550 context = GetContextRef();
551 if(!context) return;
553 device = context->Device;
554 if((albuf=LookupBuffer(device, buffer)) == NULL)
555 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
556 if(!(samples >= 0 && samplerate != 0))
557 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
558 if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE)
559 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
561 align = albuf->UnpackAlign;
562 if(SanitizeAlignment(type, &align) == AL_FALSE)
563 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
564 if((samples%align) != 0)
565 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
567 err = LoadData(albuf, samplerate, internalformat, samples,
568 channels, type, data, align, AL_FALSE);
569 if(err != AL_NO_ERROR)
570 SET_ERROR_AND_GOTO(context, err, done);
572 done:
573 ALCcontext_DecRef(context);
576 AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer,
577 ALsizei offset, ALsizei samples,
578 ALenum channels, ALenum type, const ALvoid *data)
580 ALCdevice *device;
581 ALCcontext *context;
582 ALbuffer *albuf;
583 ALsizei align;
585 context = GetContextRef();
586 if(!context) return;
588 device = context->Device;
589 if((albuf=LookupBuffer(device, buffer)) == NULL)
590 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
591 if(!(samples >= 0 && offset >= 0))
592 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
593 if(IsValidType(type) == AL_FALSE)
594 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
596 WriteLock(&albuf->lock);
597 align = albuf->UnpackAlign;
598 if(SanitizeAlignment(type, &align) == AL_FALSE)
600 WriteUnlock(&albuf->lock);
601 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
603 if(channels != (ALenum)albuf->FmtChannels)
605 WriteUnlock(&albuf->lock);
606 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
608 if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset)
610 WriteUnlock(&albuf->lock);
611 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
613 if((samples%align) != 0)
615 WriteUnlock(&albuf->lock);
616 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
619 /* offset -> byte offset */
620 offset *= FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType);
621 ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
622 data, type, ChannelsFromFmt(albuf->FmtChannels), samples, align);
623 WriteUnlock(&albuf->lock);
625 done:
626 ALCcontext_DecRef(context);
629 AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer,
630 ALsizei offset, ALsizei samples,
631 ALenum channels, ALenum type, ALvoid *data)
633 ALCdevice *device;
634 ALCcontext *context;
635 ALbuffer *albuf;
636 ALsizei align;
638 context = GetContextRef();
639 if(!context) return;
641 device = context->Device;
642 if((albuf=LookupBuffer(device, buffer)) == NULL)
643 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
644 if(!(samples >= 0 && offset >= 0))
645 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
646 if(IsValidType(type) == AL_FALSE)
647 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
649 ReadLock(&albuf->lock);
650 align = albuf->PackAlign;
651 if(SanitizeAlignment(type, &align) == AL_FALSE)
653 ReadUnlock(&albuf->lock);
654 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
656 if(channels != (ALenum)albuf->FmtChannels)
658 ReadUnlock(&albuf->lock);
659 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
661 if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset)
663 ReadUnlock(&albuf->lock);
664 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
666 if((samples%align) != 0)
668 ReadUnlock(&albuf->lock);
669 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
672 /* offset -> byte offset */
673 offset *= FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType);
674 ConvertData(data, type, (char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
675 ChannelsFromFmt(albuf->FmtChannels), samples, align);
676 ReadUnlock(&albuf->lock);
678 done:
679 ALCcontext_DecRef(context);
682 AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format)
684 enum FmtChannels dstchannels;
685 enum FmtType dsttype;
686 ALCcontext *context;
687 ALboolean ret;
689 context = GetContextRef();
690 if(!context) return AL_FALSE;
692 ret = DecomposeFormat(format, &dstchannels, &dsttype);
694 ALCcontext_DecRef(context);
696 return ret;
700 AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(value))
702 ALCdevice *device;
703 ALCcontext *context;
705 context = GetContextRef();
706 if(!context) return;
708 device = context->Device;
709 if(LookupBuffer(device, buffer) == NULL)
710 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
712 switch(param)
714 default:
715 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
718 done:
719 ALCcontext_DecRef(context);
723 AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(value1), ALfloat UNUSED(value2), ALfloat UNUSED(value3))
725 ALCdevice *device;
726 ALCcontext *context;
728 context = GetContextRef();
729 if(!context) return;
731 device = context->Device;
732 if(LookupBuffer(device, buffer) == NULL)
733 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
735 switch(param)
737 default:
738 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
741 done:
742 ALCcontext_DecRef(context);
746 AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values)
748 ALCdevice *device;
749 ALCcontext *context;
751 context = GetContextRef();
752 if(!context) return;
754 device = context->Device;
755 if(LookupBuffer(device, buffer) == NULL)
756 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
758 if(!(values))
759 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
760 switch(param)
762 default:
763 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
766 done:
767 ALCcontext_DecRef(context);
771 AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value)
773 ALCdevice *device;
774 ALCcontext *context;
775 ALbuffer *albuf;
777 context = GetContextRef();
778 if(!context) return;
780 device = context->Device;
781 if((albuf=LookupBuffer(device, buffer)) == NULL)
782 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
784 switch(param)
786 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
787 if(!(value >= 0))
788 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
789 ExchangeInt(&albuf->UnpackAlign, value);
790 break;
792 case AL_PACK_BLOCK_ALIGNMENT_SOFT:
793 if(!(value >= 0))
794 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
795 ExchangeInt(&albuf->PackAlign, value);
796 break;
798 default:
799 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
802 done:
803 ALCcontext_DecRef(context);
807 AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(value1), ALint UNUSED(value2), ALint UNUSED(value3))
809 ALCdevice *device;
810 ALCcontext *context;
812 context = GetContextRef();
813 if(!context) return;
815 device = context->Device;
816 if(LookupBuffer(device, buffer) == NULL)
817 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
819 switch(param)
821 default:
822 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
825 done:
826 ALCcontext_DecRef(context);
830 AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values)
832 ALCdevice *device;
833 ALCcontext *context;
834 ALbuffer *albuf;
836 if(values)
838 switch(param)
840 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
841 case AL_PACK_BLOCK_ALIGNMENT_SOFT:
842 alBufferi(buffer, param, values[0]);
843 return;
847 context = GetContextRef();
848 if(!context) return;
850 device = context->Device;
851 if((albuf=LookupBuffer(device, buffer)) == NULL)
852 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
854 if(!(values))
855 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
856 switch(param)
858 case AL_LOOP_POINTS_SOFT:
859 WriteLock(&albuf->lock);
860 if(albuf->ref != 0)
862 WriteUnlock(&albuf->lock);
863 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
865 if(values[0] >= values[1] || values[0] < 0 ||
866 values[1] > albuf->SampleLen)
868 WriteUnlock(&albuf->lock);
869 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
872 albuf->LoopStart = values[0];
873 albuf->LoopEnd = values[1];
874 WriteUnlock(&albuf->lock);
875 break;
877 default:
878 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
881 done:
882 ALCcontext_DecRef(context);
886 AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value)
888 ALCdevice *device;
889 ALCcontext *context;
890 ALbuffer *albuf;
892 context = GetContextRef();
893 if(!context) return;
895 device = context->Device;
896 if((albuf=LookupBuffer(device, buffer)) == NULL)
897 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
899 if(!(value))
900 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
901 switch(param)
903 case AL_SEC_LENGTH_SOFT:
904 ReadLock(&albuf->lock);
905 if(albuf->SampleLen != 0)
906 *value = albuf->SampleLen / (ALfloat)albuf->Frequency;
907 else
908 *value = 0.0f;
909 ReadUnlock(&albuf->lock);
910 break;
912 default:
913 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
916 done:
917 ALCcontext_DecRef(context);
921 AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
923 ALCdevice *device;
924 ALCcontext *context;
926 context = GetContextRef();
927 if(!context) return;
929 device = context->Device;
930 if(LookupBuffer(device, buffer) == NULL)
931 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
933 if(!(value1 && value2 && value3))
934 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
935 switch(param)
937 default:
938 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
941 done:
942 ALCcontext_DecRef(context);
946 AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values)
948 ALCdevice *device;
949 ALCcontext *context;
951 switch(param)
953 case AL_SEC_LENGTH_SOFT:
954 alGetBufferf(buffer, param, values);
955 return;
958 context = GetContextRef();
959 if(!context) return;
961 device = context->Device;
962 if(LookupBuffer(device, buffer) == NULL)
963 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
965 if(!(values))
966 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
967 switch(param)
969 default:
970 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
973 done:
974 ALCcontext_DecRef(context);
978 AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value)
980 ALCdevice *device;
981 ALCcontext *context;
982 ALbuffer *albuf;
984 context = GetContextRef();
985 if(!context) return;
987 device = context->Device;
988 if((albuf=LookupBuffer(device, buffer)) == NULL)
989 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
991 if(!(value))
992 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
993 switch(param)
995 case AL_FREQUENCY:
996 *value = albuf->Frequency;
997 break;
999 case AL_BITS:
1000 *value = BytesFromFmt(albuf->FmtType) * 8;
1001 break;
1003 case AL_CHANNELS:
1004 *value = ChannelsFromFmt(albuf->FmtChannels);
1005 break;
1007 case AL_SIZE:
1008 ReadLock(&albuf->lock);
1009 *value = albuf->SampleLen * FrameSizeFromFmt(albuf->FmtChannels,
1010 albuf->FmtType);
1011 ReadUnlock(&albuf->lock);
1012 break;
1014 case AL_INTERNAL_FORMAT_SOFT:
1015 *value = albuf->Format;
1016 break;
1018 case AL_BYTE_LENGTH_SOFT:
1019 *value = albuf->OriginalSize;
1020 break;
1022 case AL_SAMPLE_LENGTH_SOFT:
1023 *value = albuf->SampleLen;
1024 break;
1026 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
1027 *value = albuf->UnpackAlign;
1028 break;
1030 case AL_PACK_BLOCK_ALIGNMENT_SOFT:
1031 *value = albuf->PackAlign;
1032 break;
1034 default:
1035 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
1038 done:
1039 ALCcontext_DecRef(context);
1043 AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3)
1045 ALCdevice *device;
1046 ALCcontext *context;
1048 context = GetContextRef();
1049 if(!context) return;
1051 device = context->Device;
1052 if(LookupBuffer(device, buffer) == NULL)
1053 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
1055 if(!(value1 && value2 && value3))
1056 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
1057 switch(param)
1059 default:
1060 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
1063 done:
1064 ALCcontext_DecRef(context);
1068 AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values)
1070 ALCdevice *device;
1071 ALCcontext *context;
1072 ALbuffer *albuf;
1074 switch(param)
1076 case AL_FREQUENCY:
1077 case AL_BITS:
1078 case AL_CHANNELS:
1079 case AL_SIZE:
1080 case AL_INTERNAL_FORMAT_SOFT:
1081 case AL_BYTE_LENGTH_SOFT:
1082 case AL_SAMPLE_LENGTH_SOFT:
1083 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
1084 case AL_PACK_BLOCK_ALIGNMENT_SOFT:
1085 alGetBufferi(buffer, param, values);
1086 return;
1089 context = GetContextRef();
1090 if(!context) return;
1092 device = context->Device;
1093 if((albuf=LookupBuffer(device, buffer)) == NULL)
1094 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
1096 if(!(values))
1097 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
1098 switch(param)
1100 case AL_LOOP_POINTS_SOFT:
1101 ReadLock(&albuf->lock);
1102 values[0] = albuf->LoopStart;
1103 values[1] = albuf->LoopEnd;
1104 ReadUnlock(&albuf->lock);
1105 break;
1107 default:
1108 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
1111 done:
1112 ALCcontext_DecRef(context);
1116 typedef ALubyte ALmulaw;
1117 typedef ALubyte ALalaw;
1118 typedef ALubyte ALima4;
1119 typedef ALubyte ALmsadpcm;
1120 typedef struct {
1121 ALbyte b[3];
1122 } ALbyte3;
1123 extern ALbyte ALbyte3_size_is_not_3[(sizeof(ALbyte3)==sizeof(ALbyte[3]))?1:-1];
1124 typedef struct {
1125 ALubyte b[3];
1126 } ALubyte3;
1127 extern ALbyte ALubyte3_size_is_not_3[(sizeof(ALubyte3)==sizeof(ALubyte[3]))?1:-1];
1129 static inline ALshort DecodeMuLaw(ALmulaw val)
1130 { return muLawDecompressionTable[val]; }
1132 static ALmulaw EncodeMuLaw(ALshort val)
1134 ALint mant, exp, sign;
1136 sign = (val>>8) & 0x80;
1137 if(sign)
1139 /* -32768 doesn't properly negate on a short; it results in itself.
1140 * So clamp to -32767 */
1141 val = maxi(val, -32767);
1142 val = -val;
1145 val = mini(val, muLawClip);
1146 val += muLawBias;
1148 exp = muLawCompressTable[(val>>7) & 0xff];
1149 mant = (val >> (exp+3)) & 0x0f;
1151 return ~(sign | (exp<<4) | mant);
1154 static inline ALshort DecodeALaw(ALalaw val)
1155 { return aLawDecompressionTable[val]; }
1157 static ALalaw EncodeALaw(ALshort val)
1159 ALint mant, exp, sign;
1161 sign = ((~val) >> 8) & 0x80;
1162 if(!sign)
1164 val = maxi(val, -32767);
1165 val = -val;
1167 val = mini(val, aLawClip);
1169 if(val >= 256)
1171 exp = aLawCompressTable[(val>>8) & 0x7f];
1172 mant = (val >> (exp+3)) & 0x0f;
1174 else
1176 exp = 0;
1177 mant = val >> 4;
1180 return ((exp<<4) | mant) ^ (sign^0x55);
1183 static void DecodeIMA4Block(ALshort *dst, const ALima4 *src, ALint numchans, ALsizei align)
1185 ALint sample[MAX_INPUT_CHANNELS], index[MAX_INPUT_CHANNELS];
1186 ALuint code[MAX_INPUT_CHANNELS];
1187 ALsizei j,k,c;
1189 for(c = 0;c < numchans;c++)
1191 sample[c] = *(src++);
1192 sample[c] |= *(src++) << 8;
1193 sample[c] = (sample[c]^0x8000) - 32768;
1194 index[c] = *(src++);
1195 index[c] |= *(src++) << 8;
1196 index[c] = (index[c]^0x8000) - 32768;
1198 index[c] = clampi(index[c], 0, 88);
1200 dst[c] = sample[c];
1203 for(j = 1;j < align;j += 8)
1205 for(c = 0;c < numchans;c++)
1207 code[c] = *(src++);
1208 code[c] |= *(src++) << 8;
1209 code[c] |= *(src++) << 16;
1210 code[c] |= *(src++) << 24;
1213 for(k = 0;k < 8;k++)
1215 for(c = 0;c < numchans;c++)
1217 int nibble = code[c]&0xf;
1218 code[c] >>= 4;
1220 sample[c] += IMA4Codeword[nibble] * IMAStep_size[index[c]] / 8;
1221 sample[c] = clampi(sample[c], -32768, 32767);
1223 index[c] += IMA4Index_adjust[nibble];
1224 index[c] = clampi(index[c], 0, 88);
1226 dst[(j+k)*numchans + c] = sample[c];
1232 static void EncodeIMA4Block(ALima4 *dst, const ALshort *src, ALint *sample, ALint *index, ALint numchans, ALsizei align)
1234 ALsizei j,k,c;
1236 for(c = 0;c < numchans;c++)
1238 int diff = src[c] - sample[c];
1239 int step = IMAStep_size[index[c]];
1240 int nibble;
1242 nibble = 0;
1243 if(diff < 0)
1245 nibble = 0x8;
1246 diff = -diff;
1249 diff = mini(step*2, diff);
1250 nibble |= (diff*8/step - 1) / 2;
1252 sample[c] += IMA4Codeword[nibble] * step / 8;
1253 sample[c] = clampi(sample[c], -32768, 32767);
1255 index[c] += IMA4Index_adjust[nibble];
1256 index[c] = clampi(index[c], 0, 88);
1258 *(dst++) = sample[c] & 0xff;
1259 *(dst++) = (sample[c]>>8) & 0xff;
1260 *(dst++) = index[c] & 0xff;
1261 *(dst++) = (index[c]>>8) & 0xff;
1264 for(j = 1;j < align;j += 8)
1266 for(c = 0;c < numchans;c++)
1268 for(k = 0;k < 8;k++)
1270 int diff = src[(j+k)*numchans + c] - sample[c];
1271 int step = IMAStep_size[index[c]];
1272 int nibble;
1274 nibble = 0;
1275 if(diff < 0)
1277 nibble = 0x8;
1278 diff = -diff;
1281 diff = mini(step*2, diff);
1282 nibble |= (diff*8/step - 1) / 2;
1284 sample[c] += IMA4Codeword[nibble] * step / 8;
1285 sample[c] = clampi(sample[c], -32768, 32767);
1287 index[c] += IMA4Index_adjust[nibble];
1288 index[c] = clampi(index[c], 0, 88);
1290 if(!(k&1)) *dst = nibble;
1291 else *(dst++) |= nibble<<4;
1298 static void DecodeMSADPCMBlock(ALshort *dst, const ALmsadpcm *src, ALint numchans, ALsizei align)
1300 ALubyte blockpred[MAX_INPUT_CHANNELS];
1301 ALint delta[MAX_INPUT_CHANNELS];
1302 ALshort samples[MAX_INPUT_CHANNELS][2];
1303 ALint i, j;
1305 for(i = 0;i < numchans;i++)
1307 blockpred[i] = *(src++);
1308 blockpred[i] = minu(blockpred[i], 6);
1310 for(i = 0;i < numchans;i++)
1312 delta[i] = *(src++);
1313 delta[i] |= *(src++) << 8;
1314 delta[i] = (delta[i]^0x8000) - 0x8000;
1316 for(i = 0;i < numchans;i++)
1318 samples[i][0] = *(src++);
1319 samples[i][0] |= *(src++) << 8;
1320 samples[i][0] = (samples[i][0]^0x8000) - 0x8000;
1322 for(i = 0;i < numchans;i++)
1324 samples[i][1] = *(src++);
1325 samples[i][1] |= *(src++) << 8;
1326 samples[i][1] = (samples[i][1]^0x8000) - 0x8000;
1329 /* Second sample is written first. */
1330 for(i = 0;i < numchans;i++)
1331 *(dst++) = samples[i][1];
1332 for(i = 0;i < numchans;i++)
1333 *(dst++) = samples[i][0];
1335 for(j = 2;j < align;j++)
1337 for(i = 0;i < numchans;i++)
1339 const ALint num = (j*numchans) + i;
1340 ALint nibble, pred;
1342 /* Read the nibble and sign-expand it. */
1343 if(!(num&1))
1344 nibble = (*src>>4)&0x0f;
1345 else
1346 nibble = (*(src++))&0x0f;
1347 nibble = (nibble^0x08) - 0x08;
1349 pred = (samples[i][0]*MSADPCMAdaptionCoeff[blockpred[i]][0] +
1350 samples[i][1]*MSADPCMAdaptionCoeff[blockpred[i]][1]) / 256;
1351 pred += nibble * delta[i];
1352 pred = clampi(pred, -32768, 32767);
1354 samples[i][1] = samples[i][0];
1355 samples[i][0] = pred;
1357 delta[i] = (MSADPCMAdaption[nibble&0x0f] * delta[i]) / 256;
1358 delta[i] = maxi(16, delta[i]);
1360 *(dst++) = pred;
1365 /* FIXME: Stubbed. Just inserts silence. */
1366 static void EncodeMSADPCMBlock(ALmsadpcm *dst, const ALshort* UNUSED(src), ALint* UNUSED(sample), ALint* UNUSED(index), ALint numchans, ALsizei align)
1368 ALint i, j;
1370 /* Block predictor */
1371 for(i = 0;i < numchans;i++)
1372 *(dst++) = 2;
1373 /* Initial delta */
1374 for(i = 0;i < numchans;i++)
1376 *(dst++) = 16;
1377 *(dst++) = 0;
1379 /* Initial sample 1 */
1380 for(i = 0;i < numchans;i++)
1382 *(dst++) = 0;
1383 *(dst++) = 0;
1385 /* Initial sample 2 */
1386 for(i = 0;i < numchans;i++)
1388 *(dst++) = 0;
1389 *(dst++) = 0;
1392 for(j = 2;j < align;j++)
1394 for(i = 0;i < numchans;i++)
1396 const ALint num = (j*numchans) + i;
1397 ALubyte nibble = 0;
1399 if(!(num&1))
1400 *dst = nibble << 4;
1401 else
1403 *dst |= nibble;
1404 dst++;
1411 static inline ALint DecodeByte3(ALbyte3 val)
1413 if(IS_LITTLE_ENDIAN)
1414 return (val.b[2]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[0]);
1415 return (val.b[0]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[2]);
1418 static inline ALbyte3 EncodeByte3(ALint val)
1420 if(IS_LITTLE_ENDIAN)
1422 ALbyte3 ret = {{ val, val>>8, val>>16 }};
1423 return ret;
1425 else
1427 ALbyte3 ret = {{ val>>16, val>>8, val }};
1428 return ret;
1432 static inline ALint DecodeUByte3(ALubyte3 val)
1434 if(IS_LITTLE_ENDIAN)
1435 return (val.b[2]<<16) | (val.b[1]<<8) | (val.b[0]);
1436 return (val.b[0]<<16) | (val.b[1]<<8) | val.b[2];
1439 static inline ALubyte3 EncodeUByte3(ALint val)
1441 if(IS_LITTLE_ENDIAN)
1443 ALubyte3 ret = {{ val, val>>8, val>>16 }};
1444 return ret;
1446 else
1448 ALubyte3 ret = {{ val>>16, val>>8, val }};
1449 return ret;
1454 static inline ALbyte Conv_ALbyte_ALbyte(ALbyte val)
1455 { return val; }
1456 static inline ALbyte Conv_ALbyte_ALubyte(ALubyte val)
1457 { return val-128; }
1458 static inline ALbyte Conv_ALbyte_ALshort(ALshort val)
1459 { return val>>8; }
1460 static inline ALbyte Conv_ALbyte_ALushort(ALushort val)
1461 { return (val>>8)-128; }
1462 static inline ALbyte Conv_ALbyte_ALint(ALint val)
1463 { return val>>24; }
1464 static inline ALbyte Conv_ALbyte_ALuint(ALuint val)
1465 { return (val>>24)-128; }
1466 static inline ALbyte Conv_ALbyte_ALfloat(ALfloat val)
1468 if(val > 1.0f) return 127;
1469 if(val < -1.0f) return -128;
1470 return (ALint)(val * 127.0f);
1472 static inline ALbyte Conv_ALbyte_ALdouble(ALdouble val)
1474 if(val > 1.0) return 127;
1475 if(val < -1.0) return -128;
1476 return (ALint)(val * 127.0);
1478 static inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val)
1479 { return Conv_ALbyte_ALshort(DecodeMuLaw(val)); }
1480 static inline ALbyte Conv_ALbyte_ALalaw(ALalaw val)
1481 { return Conv_ALbyte_ALshort(DecodeALaw(val)); }
1482 static inline ALbyte Conv_ALbyte_ALbyte3(ALbyte3 val)
1483 { return DecodeByte3(val)>>16; }
1484 static inline ALbyte Conv_ALbyte_ALubyte3(ALubyte3 val)
1485 { return (DecodeUByte3(val)>>16)-128; }
1487 static inline ALubyte Conv_ALubyte_ALbyte(ALbyte val)
1488 { return val+128; }
1489 static inline ALubyte Conv_ALubyte_ALubyte(ALubyte val)
1490 { return val; }
1491 static inline ALubyte Conv_ALubyte_ALshort(ALshort val)
1492 { return (val>>8)+128; }
1493 static inline ALubyte Conv_ALubyte_ALushort(ALushort val)
1494 { return val>>8; }
1495 static inline ALubyte Conv_ALubyte_ALint(ALint val)
1496 { return (val>>24)+128; }
1497 static inline ALubyte Conv_ALubyte_ALuint(ALuint val)
1498 { return val>>24; }
1499 static inline ALubyte Conv_ALubyte_ALfloat(ALfloat val)
1501 if(val > 1.0f) return 255;
1502 if(val < -1.0f) return 0;
1503 return (ALint)(val * 127.0f) + 128;
1505 static inline ALubyte Conv_ALubyte_ALdouble(ALdouble val)
1507 if(val > 1.0) return 255;
1508 if(val < -1.0) return 0;
1509 return (ALint)(val * 127.0) + 128;
1511 static inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val)
1512 { return Conv_ALubyte_ALshort(DecodeMuLaw(val)); }
1513 static inline ALubyte Conv_ALubyte_ALalaw(ALalaw val)
1514 { return Conv_ALubyte_ALshort(DecodeALaw(val)); }
1515 static inline ALubyte Conv_ALubyte_ALbyte3(ALbyte3 val)
1516 { return (DecodeByte3(val)>>16)+128; }
1517 static inline ALubyte Conv_ALubyte_ALubyte3(ALubyte3 val)
1518 { return DecodeUByte3(val)>>16; }
1520 static inline ALshort Conv_ALshort_ALbyte(ALbyte val)
1521 { return val<<8; }
1522 static inline ALshort Conv_ALshort_ALubyte(ALubyte val)
1523 { return (val-128)<<8; }
1524 static inline ALshort Conv_ALshort_ALshort(ALshort val)
1525 { return val; }
1526 static inline ALshort Conv_ALshort_ALushort(ALushort val)
1527 { return val-32768; }
1528 static inline ALshort Conv_ALshort_ALint(ALint val)
1529 { return val>>16; }
1530 static inline ALshort Conv_ALshort_ALuint(ALuint val)
1531 { return (val>>16)-32768; }
1532 static inline ALshort Conv_ALshort_ALfloat(ALfloat val)
1534 if(val > 1.0f) return 32767;
1535 if(val < -1.0f) return -32768;
1536 return (ALint)(val * 32767.0f);
1538 static inline ALshort Conv_ALshort_ALdouble(ALdouble val)
1540 if(val > 1.0) return 32767;
1541 if(val < -1.0) return -32768;
1542 return (ALint)(val * 32767.0);
1544 static inline ALshort Conv_ALshort_ALmulaw(ALmulaw val)
1545 { return Conv_ALshort_ALshort(DecodeMuLaw(val)); }
1546 static inline ALshort Conv_ALshort_ALalaw(ALalaw val)
1547 { return Conv_ALshort_ALshort(DecodeALaw(val)); }
1548 static inline ALshort Conv_ALshort_ALbyte3(ALbyte3 val)
1549 { return DecodeByte3(val)>>8; }
1550 static inline ALshort Conv_ALshort_ALubyte3(ALubyte3 val)
1551 { return (DecodeUByte3(val)>>8)-32768; }
1553 static inline ALushort Conv_ALushort_ALbyte(ALbyte val)
1554 { return (val+128)<<8; }
1555 static inline ALushort Conv_ALushort_ALubyte(ALubyte val)
1556 { return val<<8; }
1557 static inline ALushort Conv_ALushort_ALshort(ALshort val)
1558 { return val+32768; }
1559 static inline ALushort Conv_ALushort_ALushort(ALushort val)
1560 { return val; }
1561 static inline ALushort Conv_ALushort_ALint(ALint val)
1562 { return (val>>16)+32768; }
1563 static inline ALushort Conv_ALushort_ALuint(ALuint val)
1564 { return val>>16; }
1565 static inline ALushort Conv_ALushort_ALfloat(ALfloat val)
1567 if(val > 1.0f) return 65535;
1568 if(val < -1.0f) return 0;
1569 return (ALint)(val * 32767.0f) + 32768;
1571 static inline ALushort Conv_ALushort_ALdouble(ALdouble val)
1573 if(val > 1.0) return 65535;
1574 if(val < -1.0) return 0;
1575 return (ALint)(val * 32767.0) + 32768;
1577 static inline ALushort Conv_ALushort_ALmulaw(ALmulaw val)
1578 { return Conv_ALushort_ALshort(DecodeMuLaw(val)); }
1579 static inline ALushort Conv_ALushort_ALalaw(ALalaw val)
1580 { return Conv_ALushort_ALshort(DecodeALaw(val)); }
1581 static inline ALushort Conv_ALushort_ALbyte3(ALbyte3 val)
1582 { return (DecodeByte3(val)>>8)+32768; }
1583 static inline ALushort Conv_ALushort_ALubyte3(ALubyte3 val)
1584 { return DecodeUByte3(val)>>8; }
1586 static inline ALint Conv_ALint_ALbyte(ALbyte val)
1587 { return val<<24; }
1588 static inline ALint Conv_ALint_ALubyte(ALubyte val)
1589 { return (val-128)<<24; }
1590 static inline ALint Conv_ALint_ALshort(ALshort val)
1591 { return val<<16; }
1592 static inline ALint Conv_ALint_ALushort(ALushort val)
1593 { return (val-32768)<<16; }
1594 static inline ALint Conv_ALint_ALint(ALint val)
1595 { return val; }
1596 static inline ALint Conv_ALint_ALuint(ALuint val)
1597 { return val-2147483648u; }
1598 static inline ALint Conv_ALint_ALfloat(ALfloat val)
1600 if(val > 1.0f) return 2147483647;
1601 if(val < -1.0f) return -2147483647-1;
1602 return (ALint)(val*16777215.0f) << 7;
1604 static inline ALint Conv_ALint_ALdouble(ALdouble val)
1606 if(val > 1.0) return 2147483647;
1607 if(val < -1.0) return -2147483647-1;
1608 return (ALint)(val * 2147483647.0);
1610 static inline ALint Conv_ALint_ALmulaw(ALmulaw val)
1611 { return Conv_ALint_ALshort(DecodeMuLaw(val)); }
1612 static inline ALint Conv_ALint_ALalaw(ALalaw val)
1613 { return Conv_ALint_ALshort(DecodeALaw(val)); }
1614 static inline ALint Conv_ALint_ALbyte3(ALbyte3 val)
1615 { return DecodeByte3(val)<<8; }
1616 static inline ALint Conv_ALint_ALubyte3(ALubyte3 val)
1617 { return (DecodeUByte3(val)-8388608)<<8; }
1619 static inline ALuint Conv_ALuint_ALbyte(ALbyte val)
1620 { return (val+128)<<24; }
1621 static inline ALuint Conv_ALuint_ALubyte(ALubyte val)
1622 { return val<<24; }
1623 static inline ALuint Conv_ALuint_ALshort(ALshort val)
1624 { return (val+32768)<<16; }
1625 static inline ALuint Conv_ALuint_ALushort(ALushort val)
1626 { return val<<16; }
1627 static inline ALuint Conv_ALuint_ALint(ALint val)
1628 { return val+2147483648u; }
1629 static inline ALuint Conv_ALuint_ALuint(ALuint val)
1630 { return val; }
1631 static inline ALuint Conv_ALuint_ALfloat(ALfloat val)
1633 if(val > 1.0f) return 4294967295u;
1634 if(val < -1.0f) return 0;
1635 return ((ALint)(val*16777215.0f)<<7) + 2147483648u;
1637 static inline ALuint Conv_ALuint_ALdouble(ALdouble val)
1639 if(val > 1.0) return 4294967295u;
1640 if(val < -1.0) return 0;
1641 return (ALint)(val * 2147483647.0) + 2147483648u;
1643 static inline ALuint Conv_ALuint_ALmulaw(ALmulaw val)
1644 { return Conv_ALuint_ALshort(DecodeMuLaw(val)); }
1645 static inline ALuint Conv_ALuint_ALalaw(ALalaw val)
1646 { return Conv_ALuint_ALshort(DecodeALaw(val)); }
1647 static inline ALuint Conv_ALuint_ALbyte3(ALbyte3 val)
1648 { return (DecodeByte3(val)+8388608)<<8; }
1649 static inline ALuint Conv_ALuint_ALubyte3(ALubyte3 val)
1650 { return DecodeUByte3(val)<<8; }
1652 static inline ALfloat Conv_ALfloat_ALbyte(ALbyte val)
1653 { return val * (1.0f/127.0f); }
1654 static inline ALfloat Conv_ALfloat_ALubyte(ALubyte val)
1655 { return (val-128) * (1.0f/127.0f); }
1656 static inline ALfloat Conv_ALfloat_ALshort(ALshort val)
1657 { return val * (1.0f/32767.0f); }
1658 static inline ALfloat Conv_ALfloat_ALushort(ALushort val)
1659 { return (val-32768) * (1.0f/32767.0f); }
1660 static inline ALfloat Conv_ALfloat_ALint(ALint val)
1661 { return (ALfloat)(val * (1.0/2147483647.0)); }
1662 static inline ALfloat Conv_ALfloat_ALuint(ALuint val)
1663 { return (ALfloat)((ALint)(val-2147483648u) * (1.0/2147483647.0)); }
1664 static inline ALfloat Conv_ALfloat_ALfloat(ALfloat val)
1665 { return (val==val) ? val : 0.0f; }
1666 static inline ALfloat Conv_ALfloat_ALdouble(ALdouble val)
1667 { return (val==val) ? (ALfloat)val : 0.0f; }
1668 static inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val)
1669 { return Conv_ALfloat_ALshort(DecodeMuLaw(val)); }
1670 static inline ALfloat Conv_ALfloat_ALalaw(ALalaw val)
1671 { return Conv_ALfloat_ALshort(DecodeALaw(val)); }
1672 static inline ALfloat Conv_ALfloat_ALbyte3(ALbyte3 val)
1673 { return (ALfloat)(DecodeByte3(val) * (1.0/8388607.0)); }
1674 static inline ALfloat Conv_ALfloat_ALubyte3(ALubyte3 val)
1675 { return (ALfloat)((DecodeUByte3(val)-8388608) * (1.0/8388607.0)); }
1677 static inline ALdouble Conv_ALdouble_ALbyte(ALbyte val)
1678 { return val * (1.0/127.0); }
1679 static inline ALdouble Conv_ALdouble_ALubyte(ALubyte val)
1680 { return (val-128) * (1.0/127.0); }
1681 static inline ALdouble Conv_ALdouble_ALshort(ALshort val)
1682 { return val * (1.0/32767.0); }
1683 static inline ALdouble Conv_ALdouble_ALushort(ALushort val)
1684 { return (val-32768) * (1.0/32767.0); }
1685 static inline ALdouble Conv_ALdouble_ALint(ALint val)
1686 { return val * (1.0/2147483647.0); }
1687 static inline ALdouble Conv_ALdouble_ALuint(ALuint val)
1688 { return (ALint)(val-2147483648u) * (1.0/2147483647.0); }
1689 static inline ALdouble Conv_ALdouble_ALfloat(ALfloat val)
1690 { return (val==val) ? val : 0.0f; }
1691 static inline ALdouble Conv_ALdouble_ALdouble(ALdouble val)
1692 { return (val==val) ? val : 0.0; }
1693 static inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val)
1694 { return Conv_ALdouble_ALshort(DecodeMuLaw(val)); }
1695 static inline ALdouble Conv_ALdouble_ALalaw(ALalaw val)
1696 { return Conv_ALdouble_ALshort(DecodeALaw(val)); }
1697 static inline ALdouble Conv_ALdouble_ALbyte3(ALbyte3 val)
1698 { return DecodeByte3(val) * (1.0/8388607.0); }
1699 static inline ALdouble Conv_ALdouble_ALubyte3(ALubyte3 val)
1700 { return (DecodeUByte3(val)-8388608) * (1.0/8388607.0); }
1702 #define DECL_TEMPLATE(T) \
1703 static inline ALmulaw Conv_ALmulaw_##T(T val) \
1704 { return EncodeMuLaw(Conv_ALshort_##T(val)); }
1706 DECL_TEMPLATE(ALbyte)
1707 DECL_TEMPLATE(ALubyte)
1708 DECL_TEMPLATE(ALshort)
1709 DECL_TEMPLATE(ALushort)
1710 DECL_TEMPLATE(ALint)
1711 DECL_TEMPLATE(ALuint)
1712 DECL_TEMPLATE(ALfloat)
1713 DECL_TEMPLATE(ALdouble)
1714 static inline ALmulaw Conv_ALmulaw_ALmulaw(ALmulaw val)
1715 { return val; }
1716 DECL_TEMPLATE(ALalaw)
1717 DECL_TEMPLATE(ALbyte3)
1718 DECL_TEMPLATE(ALubyte3)
1720 #undef DECL_TEMPLATE
1722 #define DECL_TEMPLATE(T) \
1723 static inline ALalaw Conv_ALalaw_##T(T val) \
1724 { return EncodeALaw(Conv_ALshort_##T(val)); }
1726 DECL_TEMPLATE(ALbyte)
1727 DECL_TEMPLATE(ALubyte)
1728 DECL_TEMPLATE(ALshort)
1729 DECL_TEMPLATE(ALushort)
1730 DECL_TEMPLATE(ALint)
1731 DECL_TEMPLATE(ALuint)
1732 DECL_TEMPLATE(ALfloat)
1733 DECL_TEMPLATE(ALdouble)
1734 DECL_TEMPLATE(ALmulaw)
1735 static inline ALalaw Conv_ALalaw_ALalaw(ALalaw val)
1736 { return val; }
1737 DECL_TEMPLATE(ALbyte3)
1738 DECL_TEMPLATE(ALubyte3)
1740 #undef DECL_TEMPLATE
1742 #define DECL_TEMPLATE(T) \
1743 static inline ALbyte3 Conv_ALbyte3_##T(T val) \
1744 { return EncodeByte3(Conv_ALint_##T(val)>>8); }
1746 DECL_TEMPLATE(ALbyte)
1747 DECL_TEMPLATE(ALubyte)
1748 DECL_TEMPLATE(ALshort)
1749 DECL_TEMPLATE(ALushort)
1750 DECL_TEMPLATE(ALint)
1751 DECL_TEMPLATE(ALuint)
1752 DECL_TEMPLATE(ALfloat)
1753 DECL_TEMPLATE(ALdouble)
1754 DECL_TEMPLATE(ALmulaw)
1755 DECL_TEMPLATE(ALalaw)
1756 static inline ALbyte3 Conv_ALbyte3_ALbyte3(ALbyte3 val)
1757 { return val; }
1758 DECL_TEMPLATE(ALubyte3)
1760 #undef DECL_TEMPLATE
1762 #define DECL_TEMPLATE(T) \
1763 static inline ALubyte3 Conv_ALubyte3_##T(T val) \
1764 { return EncodeUByte3(Conv_ALuint_##T(val)>>8); }
1766 DECL_TEMPLATE(ALbyte)
1767 DECL_TEMPLATE(ALubyte)
1768 DECL_TEMPLATE(ALshort)
1769 DECL_TEMPLATE(ALushort)
1770 DECL_TEMPLATE(ALint)
1771 DECL_TEMPLATE(ALuint)
1772 DECL_TEMPLATE(ALfloat)
1773 DECL_TEMPLATE(ALdouble)
1774 DECL_TEMPLATE(ALmulaw)
1775 DECL_TEMPLATE(ALalaw)
1776 DECL_TEMPLATE(ALbyte3)
1777 static inline ALubyte3 Conv_ALubyte3_ALubyte3(ALubyte3 val)
1778 { return val; }
1780 #undef DECL_TEMPLATE
1783 #define DECL_TEMPLATE(T1, T2) \
1784 static void Convert_##T1##_##T2(T1 *dst, const T2 *src, ALuint numchans, \
1785 ALuint len, ALsizei UNUSED(align)) \
1787 ALuint i, j; \
1788 for(i = 0;i < len;i++) \
1790 for(j = 0;j < numchans;j++) \
1791 *(dst++) = Conv_##T1##_##T2(*(src++)); \
1795 #define DECL_TEMPLATE2(T) \
1796 DECL_TEMPLATE(T, ALbyte) \
1797 DECL_TEMPLATE(T, ALubyte) \
1798 DECL_TEMPLATE(T, ALshort) \
1799 DECL_TEMPLATE(T, ALushort) \
1800 DECL_TEMPLATE(T, ALint) \
1801 DECL_TEMPLATE(T, ALuint) \
1802 DECL_TEMPLATE(T, ALfloat) \
1803 DECL_TEMPLATE(T, ALdouble) \
1804 DECL_TEMPLATE(T, ALmulaw) \
1805 DECL_TEMPLATE(T, ALalaw) \
1806 DECL_TEMPLATE(T, ALbyte3) \
1807 DECL_TEMPLATE(T, ALubyte3)
1809 DECL_TEMPLATE2(ALbyte)
1810 DECL_TEMPLATE2(ALubyte)
1811 DECL_TEMPLATE2(ALshort)
1812 DECL_TEMPLATE2(ALushort)
1813 DECL_TEMPLATE2(ALint)
1814 DECL_TEMPLATE2(ALuint)
1815 DECL_TEMPLATE2(ALfloat)
1816 DECL_TEMPLATE2(ALdouble)
1817 DECL_TEMPLATE2(ALmulaw)
1818 DECL_TEMPLATE2(ALalaw)
1819 DECL_TEMPLATE2(ALbyte3)
1820 DECL_TEMPLATE2(ALubyte3)
1822 #undef DECL_TEMPLATE2
1823 #undef DECL_TEMPLATE
1825 #define DECL_TEMPLATE(T) \
1826 static void Convert_##T##_ALima4(T *dst, const ALima4 *src, ALuint numchans, \
1827 ALuint len, ALuint align) \
1829 ALsizei byte_align = ((align-1)/2 + 4) * numchans; \
1830 ALuint i, j, k; \
1831 ALshort *tmp; \
1833 tmp = alloca(align*numchans); \
1834 for(i = 0;i < len;i += align) \
1836 DecodeIMA4Block(tmp, src, numchans, align); \
1837 src += byte_align; \
1839 for(j = 0;j < align;j++) \
1841 for(k = 0;k < numchans;k++) \
1842 *(dst++) = Conv_##T##_ALshort(tmp[j*numchans + k]); \
1847 DECL_TEMPLATE(ALbyte)
1848 DECL_TEMPLATE(ALubyte)
1849 static void Convert_ALshort_ALima4(ALshort *dst, const ALima4 *src, ALuint numchans,
1850 ALuint len, ALuint align)
1852 ALsizei byte_align = ((align-1)/2 + 4) * numchans;
1853 ALuint i;
1855 for(i = 0;i < len;i += align)
1857 DecodeIMA4Block(dst, src, numchans, align);
1858 src += byte_align;
1859 dst += align*numchans;
1862 DECL_TEMPLATE(ALushort)
1863 DECL_TEMPLATE(ALint)
1864 DECL_TEMPLATE(ALuint)
1865 DECL_TEMPLATE(ALfloat)
1866 DECL_TEMPLATE(ALdouble)
1867 DECL_TEMPLATE(ALmulaw)
1868 DECL_TEMPLATE(ALalaw)
1869 DECL_TEMPLATE(ALbyte3)
1870 DECL_TEMPLATE(ALubyte3)
1872 #undef DECL_TEMPLATE
1874 #define DECL_TEMPLATE(T) \
1875 static void Convert_ALima4_##T(ALima4 *dst, const T *src, ALuint numchans, \
1876 ALuint len, ALuint align) \
1878 ALint sample[MaxChannels] = {0,0,0,0,0,0,0,0}; \
1879 ALint index[MaxChannels] = {0,0,0,0,0,0,0,0}; \
1880 ALsizei byte_align = ((align-1)/2 + 4) * numchans; \
1881 ALuint i, j, k; \
1882 ALshort *tmp; \
1884 tmp = alloca(align*numchans); \
1885 for(i = 0;i < len;i += align) \
1887 for(j = 0;j < align;j++) \
1889 for(k = 0;k < numchans;k++) \
1890 tmp[j*numchans + k] = Conv_ALshort_##T(*(src++)); \
1892 EncodeIMA4Block(dst, tmp, sample, index, numchans, align); \
1893 dst += byte_align; \
1897 DECL_TEMPLATE(ALbyte)
1898 DECL_TEMPLATE(ALubyte)
1899 DECL_TEMPLATE(ALshort)
1900 DECL_TEMPLATE(ALushort)
1901 DECL_TEMPLATE(ALint)
1902 DECL_TEMPLATE(ALuint)
1903 DECL_TEMPLATE(ALfloat)
1904 DECL_TEMPLATE(ALdouble)
1905 DECL_TEMPLATE(ALmulaw)
1906 DECL_TEMPLATE(ALalaw)
1907 DECL_TEMPLATE(ALbyte3)
1908 DECL_TEMPLATE(ALubyte3)
1910 #undef DECL_TEMPLATE
1913 #define DECL_TEMPLATE(T) \
1914 static void Convert_##T##_ALmsadpcm(T *dst, const ALmsadpcm *src, \
1915 ALuint numchans, ALuint len, \
1916 ALuint align) \
1918 ALsizei byte_align = ((align-2)/2 + 7) * numchans; \
1919 ALuint i, j, k; \
1920 ALshort *tmp; \
1922 tmp = alloca(align*numchans); \
1923 for(i = 0;i < len;i += align) \
1925 DecodeMSADPCMBlock(tmp, src, numchans, align); \
1926 src += byte_align; \
1928 for(j = 0;j < align;j++) \
1930 for(k = 0;k < numchans;k++) \
1931 *(dst++) = Conv_##T##_ALshort(tmp[j*numchans + k]); \
1936 DECL_TEMPLATE(ALbyte)
1937 DECL_TEMPLATE(ALubyte)
1938 static void Convert_ALshort_ALmsadpcm(ALshort *dst, const ALmsadpcm *src,
1939 ALuint numchans, ALuint len,
1940 ALuint align)
1942 ALsizei byte_align = ((align-2)/2 + 7) * numchans;
1943 ALuint i;
1945 for(i = 0;i < len;i += align)
1947 DecodeMSADPCMBlock(dst, src, numchans, align);
1948 src += byte_align;
1949 dst += align*numchans;
1952 DECL_TEMPLATE(ALushort)
1953 DECL_TEMPLATE(ALint)
1954 DECL_TEMPLATE(ALuint)
1955 DECL_TEMPLATE(ALfloat)
1956 DECL_TEMPLATE(ALdouble)
1957 DECL_TEMPLATE(ALmulaw)
1958 DECL_TEMPLATE(ALalaw)
1959 DECL_TEMPLATE(ALbyte3)
1960 DECL_TEMPLATE(ALubyte3)
1962 #undef DECL_TEMPLATE
1964 #define DECL_TEMPLATE(T) \
1965 static void Convert_ALmsadpcm_##T(ALmsadpcm *dst, const T *src, \
1966 ALuint numchans, ALuint len, ALuint align) \
1968 ALint sample[MaxChannels] = {0,0,0,0,0,0,0,0}; \
1969 ALint index[MaxChannels] = {0,0,0,0,0,0,0,0}; \
1970 ALsizei byte_align = ((align-2)/2 + 7) * numchans; \
1971 ALuint i, j, k; \
1972 ALshort *tmp; \
1974 ERR("MSADPCM encoding not currently supported!\n"); \
1976 tmp = alloca(align*numchans); \
1977 for(i = 0;i < len;i += align) \
1979 for(j = 0;j < align;j++) \
1981 for(k = 0;k < numchans;k++) \
1982 tmp[j*numchans + k] = Conv_ALshort_##T(*(src++)); \
1984 EncodeMSADPCMBlock(dst, tmp, sample, index, numchans, align); \
1985 dst += byte_align; \
1989 DECL_TEMPLATE(ALbyte)
1990 DECL_TEMPLATE(ALubyte)
1991 DECL_TEMPLATE(ALshort)
1992 DECL_TEMPLATE(ALushort)
1993 DECL_TEMPLATE(ALint)
1994 DECL_TEMPLATE(ALuint)
1995 DECL_TEMPLATE(ALfloat)
1996 DECL_TEMPLATE(ALdouble)
1997 DECL_TEMPLATE(ALmulaw)
1998 DECL_TEMPLATE(ALalaw)
1999 DECL_TEMPLATE(ALbyte3)
2000 DECL_TEMPLATE(ALubyte3)
2002 #undef DECL_TEMPLATE
2004 /* NOTE: We don't store compressed samples internally, so these conversions
2005 * should never happen. */
2006 static void Convert_ALima4_ALima4(ALima4* UNUSED(dst), const ALima4* UNUSED(src),
2007 ALuint UNUSED(numchans), ALuint UNUSED(len),
2008 ALuint UNUSED(align))
2010 ERR("Unexpected IMA4-to-IMA4 conversion!\n");
2013 static void Convert_ALmsadpcm_ALmsadpcm(ALmsadpcm* UNUSED(dst), const ALmsadpcm* UNUSED(src),
2014 ALuint UNUSED(numchans), ALuint UNUSED(len),
2015 ALuint UNUSED(align))
2017 ERR("Unexpected MSADPCM-to-MSADPCM conversion!\n");
2020 static void Convert_ALmsadpcm_ALima4(ALmsadpcm* UNUSED(dst), const ALima4* UNUSED(src),
2021 ALuint UNUSED(numchans), ALuint UNUSED(len),
2022 ALuint UNUSED(align))
2024 ERR("Unexpected IMA4-to-MSADPCM conversion!\n");
2027 static void Convert_ALima4_ALmsadpcm(ALima4* UNUSED(dst), const ALmsadpcm* UNUSED(src),
2028 ALuint UNUSED(numchans), ALuint UNUSED(len),
2029 ALuint UNUSED(align))
2031 ERR("Unexpected MSADPCM-to-IMA4 conversion!\n");
2035 #define DECL_TEMPLATE(T) \
2036 static void Convert_##T(T *dst, const ALvoid *src, enum UserFmtType srcType, \
2037 ALsizei numchans, ALsizei len, ALsizei align) \
2039 switch(srcType) \
2041 case UserFmtByte: \
2042 Convert_##T##_ALbyte(dst, src, numchans, len, align); \
2043 break; \
2044 case UserFmtUByte: \
2045 Convert_##T##_ALubyte(dst, src, numchans, len, align); \
2046 break; \
2047 case UserFmtShort: \
2048 Convert_##T##_ALshort(dst, src, numchans, len, align); \
2049 break; \
2050 case UserFmtUShort: \
2051 Convert_##T##_ALushort(dst, src, numchans, len, align); \
2052 break; \
2053 case UserFmtInt: \
2054 Convert_##T##_ALint(dst, src, numchans, len, align); \
2055 break; \
2056 case UserFmtUInt: \
2057 Convert_##T##_ALuint(dst, src, numchans, len, align); \
2058 break; \
2059 case UserFmtFloat: \
2060 Convert_##T##_ALfloat(dst, src, numchans, len, align); \
2061 break; \
2062 case UserFmtDouble: \
2063 Convert_##T##_ALdouble(dst, src, numchans, len, align); \
2064 break; \
2065 case UserFmtMulaw: \
2066 Convert_##T##_ALmulaw(dst, src, numchans, len, align); \
2067 break; \
2068 case UserFmtAlaw: \
2069 Convert_##T##_ALalaw(dst, src, numchans, len, align); \
2070 break; \
2071 case UserFmtIMA4: \
2072 Convert_##T##_ALima4(dst, src, numchans, len, align); \
2073 break; \
2074 case UserFmtMSADPCM: \
2075 Convert_##T##_ALmsadpcm(dst, src, numchans, len, align); \
2076 break; \
2077 case UserFmtByte3: \
2078 Convert_##T##_ALbyte3(dst, src, numchans, len, align); \
2079 break; \
2080 case UserFmtUByte3: \
2081 Convert_##T##_ALubyte3(dst, src, numchans, len, align); \
2082 break; \
2086 DECL_TEMPLATE(ALbyte)
2087 DECL_TEMPLATE(ALubyte)
2088 DECL_TEMPLATE(ALshort)
2089 DECL_TEMPLATE(ALushort)
2090 DECL_TEMPLATE(ALint)
2091 DECL_TEMPLATE(ALuint)
2092 DECL_TEMPLATE(ALfloat)
2093 DECL_TEMPLATE(ALdouble)
2094 DECL_TEMPLATE(ALmulaw)
2095 DECL_TEMPLATE(ALalaw)
2096 DECL_TEMPLATE(ALima4)
2097 DECL_TEMPLATE(ALmsadpcm)
2098 DECL_TEMPLATE(ALbyte3)
2099 DECL_TEMPLATE(ALubyte3)
2101 #undef DECL_TEMPLATE
2104 static void ConvertData(ALvoid *dst, enum UserFmtType dstType, const ALvoid *src, enum UserFmtType srcType, ALsizei numchans, ALsizei len, ALsizei align)
2106 switch(dstType)
2108 case UserFmtByte:
2109 Convert_ALbyte(dst, src, srcType, numchans, len, align);
2110 break;
2111 case UserFmtUByte:
2112 Convert_ALubyte(dst, src, srcType, numchans, len, align);
2113 break;
2114 case UserFmtShort:
2115 Convert_ALshort(dst, src, srcType, numchans, len, align);
2116 break;
2117 case UserFmtUShort:
2118 Convert_ALushort(dst, src, srcType, numchans, len, align);
2119 break;
2120 case UserFmtInt:
2121 Convert_ALint(dst, src, srcType, numchans, len, align);
2122 break;
2123 case UserFmtUInt:
2124 Convert_ALuint(dst, src, srcType, numchans, len, align);
2125 break;
2126 case UserFmtFloat:
2127 Convert_ALfloat(dst, src, srcType, numchans, len, align);
2128 break;
2129 case UserFmtDouble:
2130 Convert_ALdouble(dst, src, srcType, numchans, len, align);
2131 break;
2132 case UserFmtMulaw:
2133 Convert_ALmulaw(dst, src, srcType, numchans, len, align);
2134 break;
2135 case UserFmtAlaw:
2136 Convert_ALalaw(dst, src, srcType, numchans, len, align);
2137 break;
2138 case UserFmtIMA4:
2139 Convert_ALima4(dst, src, srcType, numchans, len, align);
2140 break;
2141 case UserFmtMSADPCM:
2142 Convert_ALmsadpcm(dst, src, srcType, numchans, len, align);
2143 break;
2144 case UserFmtByte3:
2145 Convert_ALbyte3(dst, src, srcType, numchans, len, align);
2146 break;
2147 case UserFmtUByte3:
2148 Convert_ALubyte3(dst, src, srcType, numchans, len, align);
2149 break;
2155 * LoadData
2157 * Loads the specified data into the buffer, using the specified formats.
2158 * Currently, the new format must have the same channel configuration as the
2159 * original format.
2161 static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc)
2163 ALuint NewChannels, NewBytes;
2164 enum FmtChannels DstChannels;
2165 enum FmtType DstType;
2166 ALuint64 newsize;
2167 ALvoid *temp;
2169 if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE ||
2170 (long)SrcChannels != (long)DstChannels)
2171 return AL_INVALID_ENUM;
2173 NewChannels = ChannelsFromFmt(DstChannels);
2174 NewBytes = BytesFromFmt(DstType);
2176 newsize = frames;
2177 newsize *= NewBytes;
2178 newsize *= NewChannels;
2179 if(newsize > INT_MAX)
2180 return AL_OUT_OF_MEMORY;
2182 WriteLock(&ALBuf->lock);
2183 if(ALBuf->ref != 0)
2185 WriteUnlock(&ALBuf->lock);
2186 return AL_INVALID_OPERATION;
2189 temp = realloc(ALBuf->data, (size_t)newsize);
2190 if(!temp && newsize)
2192 WriteUnlock(&ALBuf->lock);
2193 return AL_OUT_OF_MEMORY;
2195 ALBuf->data = temp;
2197 if(data != NULL)
2198 ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames, align);
2200 if(storesrc)
2202 ALBuf->OriginalChannels = SrcChannels;
2203 ALBuf->OriginalType = SrcType;
2204 if(SrcType == UserFmtIMA4)
2206 ALsizei byte_align = ((align-1)/2 + 4) * ChannelsFromUserFmt(SrcChannels);
2207 ALBuf->OriginalSize = frames / align * byte_align;
2208 ALBuf->OriginalAlign = align;
2210 else if(SrcType == UserFmtMSADPCM)
2212 ALsizei byte_align = ((align-2)/2 + 7) * ChannelsFromUserFmt(SrcChannels);
2213 ALBuf->OriginalSize = frames / align * byte_align;
2214 ALBuf->OriginalAlign = align;
2216 else
2218 ALBuf->OriginalSize = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
2219 ALBuf->OriginalAlign = 1;
2222 else
2224 ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels;
2225 ALBuf->OriginalType = (enum UserFmtType)DstType;
2226 ALBuf->OriginalSize = frames * NewBytes * NewChannels;
2227 ALBuf->OriginalAlign = 1;
2230 ALBuf->Frequency = freq;
2231 ALBuf->FmtChannels = DstChannels;
2232 ALBuf->FmtType = DstType;
2233 ALBuf->Format = NewFormat;
2235 ALBuf->SampleLen = frames;
2236 ALBuf->LoopStart = 0;
2237 ALBuf->LoopEnd = ALBuf->SampleLen;
2239 WriteUnlock(&ALBuf->lock);
2240 return AL_NO_ERROR;
2244 ALuint BytesFromUserFmt(enum UserFmtType type)
2246 switch(type)
2248 case UserFmtByte: return sizeof(ALbyte);
2249 case UserFmtUByte: return sizeof(ALubyte);
2250 case UserFmtShort: return sizeof(ALshort);
2251 case UserFmtUShort: return sizeof(ALushort);
2252 case UserFmtInt: return sizeof(ALint);
2253 case UserFmtUInt: return sizeof(ALuint);
2254 case UserFmtFloat: return sizeof(ALfloat);
2255 case UserFmtDouble: return sizeof(ALdouble);
2256 case UserFmtByte3: return sizeof(ALbyte3);
2257 case UserFmtUByte3: return sizeof(ALubyte3);
2258 case UserFmtMulaw: return sizeof(ALubyte);
2259 case UserFmtAlaw: return sizeof(ALubyte);
2260 case UserFmtIMA4: break; /* not handled here */
2261 case UserFmtMSADPCM: break; /* not handled here */
2263 return 0;
2265 ALuint ChannelsFromUserFmt(enum UserFmtChannels chans)
2267 switch(chans)
2269 case UserFmtMono: return 1;
2270 case UserFmtStereo: return 2;
2271 case UserFmtRear: return 2;
2272 case UserFmtQuad: return 4;
2273 case UserFmtX51: return 6;
2274 case UserFmtX61: return 7;
2275 case UserFmtX71: return 8;
2277 return 0;
2279 static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans,
2280 enum UserFmtType *type)
2282 static const struct {
2283 ALenum format;
2284 enum UserFmtChannels channels;
2285 enum UserFmtType type;
2286 } list[] = {
2287 { AL_FORMAT_MONO8, UserFmtMono, UserFmtUByte },
2288 { AL_FORMAT_MONO16, UserFmtMono, UserFmtShort },
2289 { AL_FORMAT_MONO_FLOAT32, UserFmtMono, UserFmtFloat },
2290 { AL_FORMAT_MONO_DOUBLE_EXT, UserFmtMono, UserFmtDouble },
2291 { AL_FORMAT_MONO_IMA4, UserFmtMono, UserFmtIMA4 },
2292 { AL_FORMAT_MONO_MSADPCM_SOFT, UserFmtMono, UserFmtMSADPCM },
2293 { AL_FORMAT_MONO_MULAW, UserFmtMono, UserFmtMulaw },
2294 { AL_FORMAT_MONO_ALAW_EXT, UserFmtMono, UserFmtAlaw },
2296 { AL_FORMAT_STEREO8, UserFmtStereo, UserFmtUByte },
2297 { AL_FORMAT_STEREO16, UserFmtStereo, UserFmtShort },
2298 { AL_FORMAT_STEREO_FLOAT32, UserFmtStereo, UserFmtFloat },
2299 { AL_FORMAT_STEREO_DOUBLE_EXT, UserFmtStereo, UserFmtDouble },
2300 { AL_FORMAT_STEREO_IMA4, UserFmtStereo, UserFmtIMA4 },
2301 { AL_FORMAT_STEREO_MSADPCM_SOFT, UserFmtStereo, UserFmtMSADPCM },
2302 { AL_FORMAT_STEREO_MULAW, UserFmtStereo, UserFmtMulaw },
2303 { AL_FORMAT_STEREO_ALAW_EXT, UserFmtStereo, UserFmtAlaw },
2305 { AL_FORMAT_REAR8, UserFmtRear, UserFmtUByte },
2306 { AL_FORMAT_REAR16, UserFmtRear, UserFmtShort },
2307 { AL_FORMAT_REAR32, UserFmtRear, UserFmtFloat },
2308 { AL_FORMAT_REAR_MULAW, UserFmtRear, UserFmtMulaw },
2310 { AL_FORMAT_QUAD8_LOKI, UserFmtQuad, UserFmtUByte },
2311 { AL_FORMAT_QUAD16_LOKI, UserFmtQuad, UserFmtShort },
2313 { AL_FORMAT_QUAD8, UserFmtQuad, UserFmtUByte },
2314 { AL_FORMAT_QUAD16, UserFmtQuad, UserFmtShort },
2315 { AL_FORMAT_QUAD32, UserFmtQuad, UserFmtFloat },
2316 { AL_FORMAT_QUAD_MULAW, UserFmtQuad, UserFmtMulaw },
2318 { AL_FORMAT_51CHN8, UserFmtX51, UserFmtUByte },
2319 { AL_FORMAT_51CHN16, UserFmtX51, UserFmtShort },
2320 { AL_FORMAT_51CHN32, UserFmtX51, UserFmtFloat },
2321 { AL_FORMAT_51CHN_MULAW, UserFmtX51, UserFmtMulaw },
2323 { AL_FORMAT_61CHN8, UserFmtX61, UserFmtUByte },
2324 { AL_FORMAT_61CHN16, UserFmtX61, UserFmtShort },
2325 { AL_FORMAT_61CHN32, UserFmtX61, UserFmtFloat },
2326 { AL_FORMAT_61CHN_MULAW, UserFmtX61, UserFmtMulaw },
2328 { AL_FORMAT_71CHN8, UserFmtX71, UserFmtUByte },
2329 { AL_FORMAT_71CHN16, UserFmtX71, UserFmtShort },
2330 { AL_FORMAT_71CHN32, UserFmtX71, UserFmtFloat },
2331 { AL_FORMAT_71CHN_MULAW, UserFmtX71, UserFmtMulaw },
2333 ALuint i;
2335 for(i = 0;i < COUNTOF(list);i++)
2337 if(list[i].format == format)
2339 *chans = list[i].channels;
2340 *type = list[i].type;
2341 return AL_TRUE;
2345 return AL_FALSE;
2348 ALuint BytesFromFmt(enum FmtType type)
2350 switch(type)
2352 case FmtByte: return sizeof(ALbyte);
2353 case FmtShort: return sizeof(ALshort);
2354 case FmtFloat: return sizeof(ALfloat);
2356 return 0;
2358 ALuint ChannelsFromFmt(enum FmtChannels chans)
2360 switch(chans)
2362 case FmtMono: return 1;
2363 case FmtStereo: return 2;
2364 case FmtRear: return 2;
2365 case FmtQuad: return 4;
2366 case FmtX51: return 6;
2367 case FmtX61: return 7;
2368 case FmtX71: return 8;
2370 return 0;
2372 static ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type)
2374 static const struct {
2375 ALenum format;
2376 enum FmtChannels channels;
2377 enum FmtType type;
2378 } list[] = {
2379 { AL_MONO8_SOFT, FmtMono, FmtByte },
2380 { AL_MONO16_SOFT, FmtMono, FmtShort },
2381 { AL_MONO32F_SOFT, FmtMono, FmtFloat },
2383 { AL_STEREO8_SOFT, FmtStereo, FmtByte },
2384 { AL_STEREO16_SOFT, FmtStereo, FmtShort },
2385 { AL_STEREO32F_SOFT, FmtStereo, FmtFloat },
2387 { AL_REAR8_SOFT, FmtRear, FmtByte },
2388 { AL_REAR16_SOFT, FmtRear, FmtShort },
2389 { AL_REAR32F_SOFT, FmtRear, FmtFloat },
2391 { AL_FORMAT_QUAD8_LOKI, FmtQuad, FmtByte },
2392 { AL_FORMAT_QUAD16_LOKI, FmtQuad, FmtShort },
2394 { AL_QUAD8_SOFT, FmtQuad, FmtByte },
2395 { AL_QUAD16_SOFT, FmtQuad, FmtShort },
2396 { AL_QUAD32F_SOFT, FmtQuad, FmtFloat },
2398 { AL_5POINT1_8_SOFT, FmtX51, FmtByte },
2399 { AL_5POINT1_16_SOFT, FmtX51, FmtShort },
2400 { AL_5POINT1_32F_SOFT, FmtX51, FmtFloat },
2402 { AL_6POINT1_8_SOFT, FmtX61, FmtByte },
2403 { AL_6POINT1_16_SOFT, FmtX61, FmtShort },
2404 { AL_6POINT1_32F_SOFT, FmtX61, FmtFloat },
2406 { AL_7POINT1_8_SOFT, FmtX71, FmtByte },
2407 { AL_7POINT1_16_SOFT, FmtX71, FmtShort },
2408 { AL_7POINT1_32F_SOFT, FmtX71, FmtFloat },
2410 ALuint i;
2412 for(i = 0;i < COUNTOF(list);i++)
2414 if(list[i].format == format)
2416 *chans = list[i].channels;
2417 *type = list[i].type;
2418 return AL_TRUE;
2422 return AL_FALSE;
2425 static ALboolean SanitizeAlignment(enum UserFmtType type, ALsizei *align)
2427 if(*align < 0)
2428 return AL_FALSE;
2430 if(*align == 0)
2432 if(type == UserFmtIMA4)
2434 /* Here is where things vary:
2435 * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel
2436 * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel
2438 *align = 65;
2440 else if(type == UserFmtMSADPCM)
2441 *align = 64;
2442 else
2443 *align = 1;
2444 return AL_TRUE;
2447 if(type == UserFmtIMA4)
2449 /* IMA4 block alignment must be a multiple of 8, plus 1. */
2450 return ((*align)&7) == 1;
2452 if(type == UserFmtMSADPCM)
2454 /* MSADPCM block alignment must be a multiple of 8. */
2455 /* FIXME: Too strict? Might only require align*channels to be a
2456 * multiple of 2. */
2457 return ((*align)&7) == 0;
2460 return AL_TRUE;
2464 static ALboolean IsValidType(ALenum type)
2466 switch(type)
2468 case AL_BYTE_SOFT:
2469 case AL_UNSIGNED_BYTE_SOFT:
2470 case AL_SHORT_SOFT:
2471 case AL_UNSIGNED_SHORT_SOFT:
2472 case AL_INT_SOFT:
2473 case AL_UNSIGNED_INT_SOFT:
2474 case AL_FLOAT_SOFT:
2475 case AL_DOUBLE_SOFT:
2476 case AL_BYTE3_SOFT:
2477 case AL_UNSIGNED_BYTE3_SOFT:
2478 return AL_TRUE;
2480 return AL_FALSE;
2483 static ALboolean IsValidChannels(ALenum channels)
2485 switch(channels)
2487 case AL_MONO_SOFT:
2488 case AL_STEREO_SOFT:
2489 case AL_REAR_SOFT:
2490 case AL_QUAD_SOFT:
2491 case AL_5POINT1_SOFT:
2492 case AL_6POINT1_SOFT:
2493 case AL_7POINT1_SOFT:
2494 return AL_TRUE;
2496 return AL_FALSE;
2501 * ReleaseALBuffers()
2503 * INTERNAL: Called to destroy any buffers that still exist on the device
2505 ALvoid ReleaseALBuffers(ALCdevice *device)
2507 ALsizei i;
2508 for(i = 0;i < device->BufferMap.size;i++)
2510 ALbuffer *temp = device->BufferMap.array[i].value;
2511 device->BufferMap.array[i].value = NULL;
2513 free(temp->data);
2515 FreeThunkEntry(temp->id);
2516 memset(temp, 0, sizeof(ALbuffer));
2517 free(temp);