diff OpenAL32/alBuffer.c @ 0:f9476ff7637e

initial forking of open-al to create multiple listeners
author Robert McIntyre <rlm@mit.edu>
date Tue, 25 Oct 2011 13:02:31 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/OpenAL32/alBuffer.c	Tue Oct 25 13:02:31 2011 -0700
     1.3 @@ -0,0 +1,2211 @@
     1.4 +/**
     1.5 + * OpenAL cross platform audio library
     1.6 + * Copyright (C) 1999-2007 by authors.
     1.7 + * This library is free software; you can redistribute it and/or
     1.8 + *  modify it under the terms of the GNU Library General Public
     1.9 + *  License as published by the Free Software Foundation; either
    1.10 + *  version 2 of the License, or (at your option) any later version.
    1.11 + *
    1.12 + * This library is distributed in the hope that it will be useful,
    1.13 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.14 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.15 + *  Library General Public License for more details.
    1.16 + *
    1.17 + * You should have received a copy of the GNU Library General Public
    1.18 + *  License along with this library; if not, write to the
    1.19 + *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    1.20 + *  Boston, MA  02111-1307, USA.
    1.21 + * Or go to http://www.gnu.org/copyleft/lgpl.html
    1.22 + */
    1.23 +
    1.24 +#include "config.h"
    1.25 +
    1.26 +#include <stdlib.h>
    1.27 +#include <stdio.h>
    1.28 +#include <assert.h>
    1.29 +#include <limits.h>
    1.30 +
    1.31 +#include "alMain.h"
    1.32 +#include "AL/al.h"
    1.33 +#include "AL/alc.h"
    1.34 +#include "alError.h"
    1.35 +#include "alBuffer.h"
    1.36 +#include "alThunk.h"
    1.37 +
    1.38 +
    1.39 +static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels chans, enum UserFmtType type, const ALvoid *data, ALboolean storesrc);
    1.40 +static void ConvertData(ALvoid *dst, enum UserFmtType dstType, const ALvoid *src, enum UserFmtType srcType, ALsizei numchans, ALsizei len);
    1.41 +static ALboolean IsValidType(ALenum type);
    1.42 +static ALboolean IsValidChannels(ALenum channels);
    1.43 +
    1.44 +#define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
    1.45 +
    1.46 +
    1.47 +/*
    1.48 + * Global Variables
    1.49 + */
    1.50 +
    1.51 +/* IMA ADPCM Stepsize table */
    1.52 +static const long IMAStep_size[89] = {
    1.53 +       7,    8,    9,   10,   11,   12,   13,   14,   16,   17,   19,
    1.54 +      21,   23,   25,   28,   31,   34,   37,   41,   45,   50,   55,
    1.55 +      60,   66,   73,   80,   88,   97,  107,  118,  130,  143,  157,
    1.56 +     173,  190,  209,  230,  253,  279,  307,  337,  371,  408,  449,
    1.57 +     494,  544,  598,  658,  724,  796,  876,  963, 1060, 1166, 1282,
    1.58 +    1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660,
    1.59 +    4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,
    1.60 +   11487,12635,13899,15289,16818,18500,20350,22358,24633,27086,29794,
    1.61 +   32767
    1.62 +};
    1.63 +
    1.64 +/* IMA4 ADPCM Codeword decode table */
    1.65 +static const long IMA4Codeword[16] = {
    1.66 +    1, 3, 5, 7, 9, 11, 13, 15,
    1.67 +   -1,-3,-5,-7,-9,-11,-13,-15,
    1.68 +};
    1.69 +
    1.70 +/* IMA4 ADPCM Step index adjust decode table */
    1.71 +static const long IMA4Index_adjust[16] = {
    1.72 +   -1,-1,-1,-1, 2, 4, 6, 8,
    1.73 +   -1,-1,-1,-1, 2, 4, 6, 8
    1.74 +};
    1.75 +
    1.76 +/* A quick'n'dirty lookup table to decode a muLaw-encoded byte sample into a
    1.77 + * signed 16-bit sample */
    1.78 +static const ALshort muLawDecompressionTable[256] = {
    1.79 +    -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
    1.80 +    -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
    1.81 +    -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
    1.82 +    -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
    1.83 +     -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
    1.84 +     -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
    1.85 +     -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
    1.86 +     -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
    1.87 +     -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
    1.88 +     -1372, -1308, -1244, -1180, -1116, -1052,  -988,  -924,
    1.89 +      -876,  -844,  -812,  -780,  -748,  -716,  -684,  -652,
    1.90 +      -620,  -588,  -556,  -524,  -492,  -460,  -428,  -396,
    1.91 +      -372,  -356,  -340,  -324,  -308,  -292,  -276,  -260,
    1.92 +      -244,  -228,  -212,  -196,  -180,  -164,  -148,  -132,
    1.93 +      -120,  -112,  -104,   -96,   -88,   -80,   -72,   -64,
    1.94 +       -56,   -48,   -40,   -32,   -24,   -16,    -8,     0,
    1.95 +     32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
    1.96 +     23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
    1.97 +     15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
    1.98 +     11900, 11388, 10876, 10364,  9852,  9340,  8828,  8316,
    1.99 +      7932,  7676,  7420,  7164,  6908,  6652,  6396,  6140,
   1.100 +      5884,  5628,  5372,  5116,  4860,  4604,  4348,  4092,
   1.101 +      3900,  3772,  3644,  3516,  3388,  3260,  3132,  3004,
   1.102 +      2876,  2748,  2620,  2492,  2364,  2236,  2108,  1980,
   1.103 +      1884,  1820,  1756,  1692,  1628,  1564,  1500,  1436,
   1.104 +      1372,  1308,  1244,  1180,  1116,  1052,   988,   924,
   1.105 +       876,   844,   812,   780,   748,   716,   684,   652,
   1.106 +       620,   588,   556,   524,   492,   460,   428,   396,
   1.107 +       372,   356,   340,   324,   308,   292,   276,   260,
   1.108 +       244,   228,   212,   196,   180,   164,   148,   132,
   1.109 +       120,   112,   104,    96,    88,    80,    72,    64,
   1.110 +        56,    48,    40,    32,    24,    16,     8,     0
   1.111 +};
   1.112 +
   1.113 +/* Values used when encoding a muLaw sample */
   1.114 +static const int muLawBias = 0x84;
   1.115 +static const int muLawClip = 32635;
   1.116 +static const char muLawCompressTable[256] =
   1.117 +{
   1.118 +     0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
   1.119 +     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
   1.120 +     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
   1.121 +     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
   1.122 +     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
   1.123 +     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
   1.124 +     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
   1.125 +     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
   1.126 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.127 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.128 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.129 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.130 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.131 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.132 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
   1.133 +     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
   1.134 +};
   1.135 +
   1.136 +/*
   1.137 + *    alGenBuffers(ALsizei n, ALuint *buffers)
   1.138 + *
   1.139 + *    Generates n AL Buffers, and stores the Buffers Names in the array pointed
   1.140 + *    to by buffers
   1.141 + */
   1.142 +AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
   1.143 +{
   1.144 +    ALCcontext *Context;
   1.145 +    ALsizei i=0;
   1.146 +
   1.147 +    Context = GetLockedContext();
   1.148 +    if(!Context) return;
   1.149 +
   1.150 +    /* Check that we are actually generating some Buffers */
   1.151 +    if(n < 0 || IsBadWritePtr((void*)buffers, n * sizeof(ALuint)))
   1.152 +        alSetError(Context, AL_INVALID_VALUE);
   1.153 +    else
   1.154 +    {
   1.155 +        ALCdevice *device = Context->Device;
   1.156 +        ALenum err;
   1.157 +
   1.158 +        // Create all the new Buffers
   1.159 +        while(i < n)
   1.160 +        {
   1.161 +            ALbuffer *buffer = calloc(1, sizeof(ALbuffer));
   1.162 +            if(!buffer)
   1.163 +            {
   1.164 +                alSetError(Context, AL_OUT_OF_MEMORY);
   1.165 +                alDeleteBuffers(i, buffers);
   1.166 +                break;
   1.167 +            }
   1.168 +
   1.169 +            err = NewThunkEntry(&buffer->buffer);
   1.170 +            if(err == AL_NO_ERROR)
   1.171 +                err = InsertUIntMapEntry(&device->BufferMap, buffer->buffer, buffer);
   1.172 +            if(err != AL_NO_ERROR)
   1.173 +            {
   1.174 +                FreeThunkEntry(buffer->buffer);
   1.175 +                memset(buffer, 0, sizeof(ALbuffer));
   1.176 +                free(buffer);
   1.177 +
   1.178 +                alSetError(Context, err);
   1.179 +                alDeleteBuffers(i, buffers);
   1.180 +                break;
   1.181 +            }
   1.182 +            buffers[i++] = buffer->buffer;
   1.183 +        }
   1.184 +    }
   1.185 +
   1.186 +    UnlockContext(Context);
   1.187 +}
   1.188 +
   1.189 +/*
   1.190 + *    alDeleteBuffers(ALsizei n, ALuint *buffers)
   1.191 + *
   1.192 + *    Deletes the n AL Buffers pointed to by buffers
   1.193 + */
   1.194 +AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
   1.195 +{
   1.196 +    ALCcontext *Context;
   1.197 +    ALCdevice *device;
   1.198 +    ALboolean Failed;
   1.199 +    ALbuffer *ALBuf;
   1.200 +    ALsizei i;
   1.201 +
   1.202 +    Context = GetLockedContext();
   1.203 +    if(!Context) return;
   1.204 +
   1.205 +    Failed = AL_TRUE;
   1.206 +    device = Context->Device;
   1.207 +    /* Check we are actually Deleting some Buffers */
   1.208 +    if(n < 0)
   1.209 +        alSetError(Context, AL_INVALID_VALUE);
   1.210 +    else
   1.211 +    {
   1.212 +        Failed = AL_FALSE;
   1.213 +
   1.214 +        /* Check that all the buffers are valid and can actually be deleted */
   1.215 +        for(i = 0;i < n;i++)
   1.216 +        {
   1.217 +            if(!buffers[i])
   1.218 +                continue;
   1.219 +
   1.220 +            /* Check for valid Buffer ID */
   1.221 +            if((ALBuf=LookupBuffer(device->BufferMap, buffers[i])) == NULL)
   1.222 +            {
   1.223 +                alSetError(Context, AL_INVALID_NAME);
   1.224 +                Failed = AL_TRUE;
   1.225 +                break;
   1.226 +            }
   1.227 +            else if(ALBuf->refcount != 0)
   1.228 +            {
   1.229 +                /* Buffer still in use, cannot be deleted */
   1.230 +                alSetError(Context, AL_INVALID_OPERATION);
   1.231 +                Failed = AL_TRUE;
   1.232 +                break;
   1.233 +            }
   1.234 +        }
   1.235 +    }
   1.236 +
   1.237 +    /* If all the Buffers were valid (and have Reference Counts of 0), then we
   1.238 +     * can delete them */
   1.239 +    if(!Failed)
   1.240 +    {
   1.241 +        for(i = 0;i < n;i++)
   1.242 +        {
   1.243 +            if((ALBuf=LookupBuffer(device->BufferMap, buffers[i])) == NULL)
   1.244 +                continue;
   1.245 +
   1.246 +            /* Release the memory used to store audio data */
   1.247 +            free(ALBuf->data);
   1.248 +
   1.249 +            /* Release buffer structure */
   1.250 +            RemoveUIntMapKey(&device->BufferMap, ALBuf->buffer);
   1.251 +            FreeThunkEntry(ALBuf->buffer);
   1.252 +
   1.253 +            memset(ALBuf, 0, sizeof(ALbuffer));
   1.254 +            free(ALBuf);
   1.255 +        }
   1.256 +    }
   1.257 +
   1.258 +    UnlockContext(Context);
   1.259 +}
   1.260 +
   1.261 +/*
   1.262 + *    alIsBuffer(ALuint buffer)
   1.263 + *
   1.264 + *    Checks if buffer is a valid Buffer Name
   1.265 + */
   1.266 +AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
   1.267 +{
   1.268 +    ALCcontext *Context;
   1.269 +    ALboolean  result;
   1.270 +
   1.271 +    Context = GetLockedContext();
   1.272 +    if(!Context) return AL_FALSE;
   1.273 +
   1.274 +    result = ((!buffer || LookupBuffer(Context->Device->BufferMap, buffer)) ?
   1.275 +              AL_TRUE : AL_FALSE);
   1.276 +
   1.277 +    UnlockContext(Context);
   1.278 +
   1.279 +    return result;
   1.280 +}
   1.281 +
   1.282 +/*
   1.283 + *    alBufferData(ALuint buffer, ALenum format, const ALvoid *data,
   1.284 + *                 ALsizei size, ALsizei freq)
   1.285 + *
   1.286 + *    Fill buffer with audio data
   1.287 + */
   1.288 +AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
   1.289 +{
   1.290 +    enum UserFmtChannels SrcChannels;
   1.291 +    enum UserFmtType SrcType;
   1.292 +    ALCcontext *Context;
   1.293 +    ALCdevice *device;
   1.294 +    ALbuffer *ALBuf;
   1.295 +    ALenum err;
   1.296 +
   1.297 +    Context = GetLockedContext();
   1.298 +    if(!Context) return;
   1.299 +
   1.300 +    device = Context->Device;
   1.301 +    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.302 +        alSetError(Context, AL_INVALID_NAME);
   1.303 +    else if(ALBuf->refcount != 0)
   1.304 +        alSetError(Context, AL_INVALID_VALUE);
   1.305 +    else if(size < 0 || freq < 0)
   1.306 +        alSetError(Context, AL_INVALID_VALUE);
   1.307 +    else if(DecomposeUserFormat(format, &SrcChannels, &SrcType) == AL_FALSE)
   1.308 +        alSetError(Context, AL_INVALID_ENUM);
   1.309 +    else switch(SrcType)
   1.310 +    {
   1.311 +        case UserFmtByte:
   1.312 +        case UserFmtUByte:
   1.313 +        case UserFmtShort:
   1.314 +        case UserFmtUShort:
   1.315 +        case UserFmtInt:
   1.316 +        case UserFmtUInt:
   1.317 +        case UserFmtFloat: {
   1.318 +            ALuint FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
   1.319 +            if((size%FrameSize) != 0)
   1.320 +                err = AL_INVALID_VALUE;
   1.321 +            else
   1.322 +                err = LoadData(ALBuf, freq, format, size/FrameSize,
   1.323 +                               SrcChannels, SrcType, data, AL_TRUE);
   1.324 +            if(err != AL_NO_ERROR)
   1.325 +                alSetError(Context, err);
   1.326 +        }   break;
   1.327 +
   1.328 +        case UserFmtByte3:
   1.329 +        case UserFmtUByte3:
   1.330 +        case UserFmtDouble: {
   1.331 +            ALuint FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
   1.332 +            ALenum NewFormat = AL_FORMAT_MONO_FLOAT32;
   1.333 +            switch(SrcChannels)
   1.334 +            {
   1.335 +                case UserFmtMono: NewFormat = AL_FORMAT_MONO_FLOAT32; break;
   1.336 +                case UserFmtStereo: NewFormat = AL_FORMAT_STEREO_FLOAT32; break;
   1.337 +                case UserFmtRear: NewFormat = AL_FORMAT_REAR32; break;
   1.338 +                case UserFmtQuad: NewFormat = AL_FORMAT_QUAD32; break;
   1.339 +                case UserFmtX51: NewFormat = AL_FORMAT_51CHN32; break;
   1.340 +                case UserFmtX61: NewFormat = AL_FORMAT_61CHN32; break;
   1.341 +                case UserFmtX71: NewFormat = AL_FORMAT_71CHN32; break;
   1.342 +            }
   1.343 +            if((size%FrameSize) != 0)
   1.344 +                err = AL_INVALID_VALUE;
   1.345 +            else
   1.346 +                err = LoadData(ALBuf, freq, NewFormat, size/FrameSize,
   1.347 +                               SrcChannels, SrcType, data, AL_TRUE);
   1.348 +            if(err != AL_NO_ERROR)
   1.349 +                alSetError(Context, err);
   1.350 +        }   break;
   1.351 +
   1.352 +        case UserFmtMulaw:
   1.353 +        case UserFmtIMA4: {
   1.354 +            /* Here is where things vary:
   1.355 +             * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel
   1.356 +             * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel
   1.357 +             */
   1.358 +            ALuint FrameSize = (SrcType == UserFmtIMA4) ?
   1.359 +                               (ChannelsFromUserFmt(SrcChannels) * 36) :
   1.360 +                               FrameSizeFromUserFmt(SrcChannels, SrcType);
   1.361 +            ALenum NewFormat = AL_FORMAT_MONO16;
   1.362 +            switch(SrcChannels)
   1.363 +            {
   1.364 +                case UserFmtMono: NewFormat = AL_FORMAT_MONO16; break;
   1.365 +                case UserFmtStereo: NewFormat = AL_FORMAT_STEREO16; break;
   1.366 +                case UserFmtRear: NewFormat = AL_FORMAT_REAR16; break;
   1.367 +                case UserFmtQuad: NewFormat = AL_FORMAT_QUAD16; break;
   1.368 +                case UserFmtX51: NewFormat = AL_FORMAT_51CHN16; break;
   1.369 +                case UserFmtX61: NewFormat = AL_FORMAT_61CHN16; break;
   1.370 +                case UserFmtX71: NewFormat = AL_FORMAT_71CHN16; break;
   1.371 +            }
   1.372 +            if((size%FrameSize) != 0)
   1.373 +                err = AL_INVALID_VALUE;
   1.374 +            else
   1.375 +                err = LoadData(ALBuf, freq, NewFormat, size/FrameSize,
   1.376 +                               SrcChannels, SrcType, data, AL_TRUE);
   1.377 +            if(err != AL_NO_ERROR)
   1.378 +                alSetError(Context, err);
   1.379 +        }   break;
   1.380 +    }
   1.381 +
   1.382 +    UnlockContext(Context);
   1.383 +}
   1.384 +
   1.385 +/*
   1.386 + *    alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data,
   1.387 + *                        ALsizei offset, ALsizei length)
   1.388 + *
   1.389 + *    Update buffer's audio data
   1.390 + */
   1.391 +AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
   1.392 +{
   1.393 +    enum UserFmtChannels SrcChannels;
   1.394 +    enum UserFmtType SrcType;
   1.395 +    ALCcontext *Context;
   1.396 +    ALCdevice  *device;
   1.397 +    ALbuffer   *ALBuf;
   1.398 +
   1.399 +    Context = GetLockedContext();
   1.400 +    if(!Context) return;
   1.401 +
   1.402 +    device = Context->Device;
   1.403 +    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.404 +        alSetError(Context, AL_INVALID_NAME);
   1.405 +    else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
   1.406 +        alSetError(Context, AL_INVALID_VALUE);
   1.407 +    else if(DecomposeUserFormat(format, &SrcChannels, &SrcType) == AL_FALSE ||
   1.408 +            SrcChannels != ALBuf->OriginalChannels ||
   1.409 +            SrcType != ALBuf->OriginalType)
   1.410 +        alSetError(Context, AL_INVALID_ENUM);
   1.411 +    else if(offset > ALBuf->OriginalSize ||
   1.412 +            length > ALBuf->OriginalSize-offset ||
   1.413 +            (offset%ALBuf->OriginalAlign) != 0 ||
   1.414 +            (length%ALBuf->OriginalAlign) != 0)
   1.415 +        alSetError(Context, AL_INVALID_VALUE);
   1.416 +    else
   1.417 +    {
   1.418 +        ALuint Channels = ChannelsFromFmt(ALBuf->FmtChannels);
   1.419 +        ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
   1.420 +        if(SrcType == UserFmtIMA4)
   1.421 +        {
   1.422 +            /* offset -> byte offset, length -> block count */
   1.423 +            offset /= 36;
   1.424 +            offset *= 65;
   1.425 +            offset *= Bytes;
   1.426 +            length /= ALBuf->OriginalAlign;
   1.427 +        }
   1.428 +        else
   1.429 +        {
   1.430 +            ALuint OldBytes = BytesFromUserFmt(SrcType);
   1.431 +
   1.432 +            offset /= OldBytes;
   1.433 +            offset *= Bytes;
   1.434 +            length /= OldBytes * Channels;
   1.435 +        }
   1.436 +        ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
   1.437 +                    data, SrcType, Channels, length);
   1.438 +    }
   1.439 +
   1.440 +    UnlockContext(Context);
   1.441 +}
   1.442 +
   1.443 +
   1.444 +AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer,
   1.445 +  ALuint samplerate, ALenum internalformat, ALsizei frames,
   1.446 +  ALenum channels, ALenum type, const ALvoid *data)
   1.447 +{
   1.448 +    ALCcontext *Context;
   1.449 +    ALCdevice *device;
   1.450 +    ALbuffer *ALBuf;
   1.451 +    ALenum err;
   1.452 +
   1.453 +    Context = GetLockedContext();
   1.454 +    if(!Context) return;
   1.455 +
   1.456 +    device = Context->Device;
   1.457 +    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.458 +        alSetError(Context, AL_INVALID_NAME);
   1.459 +    else if(ALBuf->refcount != 0)
   1.460 +        alSetError(Context, AL_INVALID_VALUE);
   1.461 +    else if(frames < 0 || samplerate == 0)
   1.462 +        alSetError(Context, AL_INVALID_VALUE);
   1.463 +    else if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE)
   1.464 +        alSetError(Context, AL_INVALID_ENUM);
   1.465 +    else
   1.466 +    {
   1.467 +        err = AL_NO_ERROR;
   1.468 +        if(type == UserFmtIMA4)
   1.469 +        {
   1.470 +            if((frames%65) == 0) frames /= 65;
   1.471 +            else err = AL_INVALID_VALUE;
   1.472 +        }
   1.473 +        if(err == AL_NO_ERROR)
   1.474 +            err = LoadData(ALBuf, samplerate, internalformat, frames,
   1.475 +                           channels, type, data, AL_FALSE);
   1.476 +        if(err != AL_NO_ERROR)
   1.477 +            alSetError(Context, err);
   1.478 +    }
   1.479 +
   1.480 +    UnlockContext(Context);
   1.481 +}
   1.482 +
   1.483 +AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer,
   1.484 +  ALsizei offset, ALsizei frames,
   1.485 +  ALenum channels, ALenum type, const ALvoid *data)
   1.486 +{
   1.487 +    ALCcontext *Context;
   1.488 +    ALCdevice  *device;
   1.489 +    ALbuffer   *ALBuf;
   1.490 +
   1.491 +    Context = GetLockedContext();
   1.492 +    if(!Context) return;
   1.493 +
   1.494 +    device = Context->Device;
   1.495 +    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.496 +        alSetError(Context, AL_INVALID_NAME);
   1.497 +    else if(frames < 0 || offset < 0 || (frames > 0 && data == NULL))
   1.498 +        alSetError(Context, AL_INVALID_VALUE);
   1.499 +    else if(channels != (ALenum)ALBuf->FmtChannels ||
   1.500 +            IsValidType(type) == AL_FALSE)
   1.501 +        alSetError(Context, AL_INVALID_ENUM);
   1.502 +    else
   1.503 +    {
   1.504 +        ALuint FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType);
   1.505 +        ALuint FrameCount = ALBuf->size / FrameSize;
   1.506 +        if((ALuint)offset > FrameCount || (ALuint)frames > FrameCount-offset)
   1.507 +            alSetError(Context, AL_INVALID_VALUE);
   1.508 +        else if(type == UserFmtIMA4 && (frames%65) != 0)
   1.509 +            alSetError(Context, AL_INVALID_VALUE);
   1.510 +        else
   1.511 +        {
   1.512 +            /* offset -> byte offset */
   1.513 +            offset *= FrameSize;
   1.514 +            /* frames -> IMA4 block count */
   1.515 +            if(type == UserFmtIMA4) frames /= 65;
   1.516 +            ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
   1.517 +                        data, type,
   1.518 +                        ChannelsFromFmt(ALBuf->FmtChannels), frames);
   1.519 +        }
   1.520 +    }
   1.521 +
   1.522 +    UnlockContext(Context);
   1.523 +}
   1.524 +
   1.525 +AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer,
   1.526 +  ALsizei offset, ALsizei frames,
   1.527 +  ALenum channels, ALenum type, ALvoid *data)
   1.528 +{
   1.529 +    ALCcontext *Context;
   1.530 +    ALCdevice  *device;
   1.531 +    ALbuffer   *ALBuf;
   1.532 +
   1.533 +    Context = GetLockedContext();
   1.534 +    if(!Context) return;
   1.535 +
   1.536 +    device = Context->Device;
   1.537 +    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.538 +        alSetError(Context, AL_INVALID_NAME);
   1.539 +    else if(frames < 0 || offset < 0 || (frames > 0 && data == NULL))
   1.540 +        alSetError(Context, AL_INVALID_VALUE);
   1.541 +    else if(channels != (ALenum)ALBuf->FmtChannels ||
   1.542 +            IsValidType(type) == AL_FALSE)
   1.543 +        alSetError(Context, AL_INVALID_ENUM);
   1.544 +    else
   1.545 +    {
   1.546 +        ALuint FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType);
   1.547 +        ALuint FrameCount = ALBuf->size / FrameSize;
   1.548 +        if((ALuint)offset > FrameCount || (ALuint)frames > FrameCount-offset)
   1.549 +            alSetError(Context, AL_INVALID_VALUE);
   1.550 +        else if(type == UserFmtIMA4 && (frames%65) != 0)
   1.551 +            alSetError(Context, AL_INVALID_VALUE);
   1.552 +        else
   1.553 +        {
   1.554 +            /* offset -> byte offset */
   1.555 +            offset *= FrameSize;
   1.556 +            /* frames -> IMA4 block count */
   1.557 +            if(type == UserFmtIMA4) frames /= 65;
   1.558 +            ConvertData(data, type,
   1.559 +                        &((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
   1.560 +                        ChannelsFromFmt(ALBuf->FmtChannels), frames);
   1.561 +        }
   1.562 +    }
   1.563 +
   1.564 +    UnlockContext(Context);
   1.565 +}
   1.566 +
   1.567 +AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format)
   1.568 +{
   1.569 +    enum FmtChannels DstChannels;
   1.570 +    enum FmtType DstType;
   1.571 +    ALCcontext *Context;
   1.572 +    ALboolean ret;
   1.573 +
   1.574 +    Context = GetLockedContext();
   1.575 +    if(!Context) return AL_FALSE;
   1.576 +
   1.577 +    ret = DecomposeFormat(format, &DstChannels, &DstType);
   1.578 +
   1.579 +    UnlockContext(Context);
   1.580 +
   1.581 +    return ret;
   1.582 +}
   1.583 +
   1.584 +
   1.585 +AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
   1.586 +{
   1.587 +    ALCcontext    *pContext;
   1.588 +    ALCdevice     *device;
   1.589 +
   1.590 +    (void)flValue;
   1.591 +
   1.592 +    pContext = GetLockedContext();
   1.593 +    if(!pContext) return;
   1.594 +
   1.595 +    device = pContext->Device;
   1.596 +    if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.597 +        alSetError(pContext, AL_INVALID_NAME);
   1.598 +    else
   1.599 +    {
   1.600 +        switch(eParam)
   1.601 +        {
   1.602 +        default:
   1.603 +            alSetError(pContext, AL_INVALID_ENUM);
   1.604 +            break;
   1.605 +        }
   1.606 +    }
   1.607 +
   1.608 +    UnlockContext(pContext);
   1.609 +}
   1.610 +
   1.611 +
   1.612 +AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
   1.613 +{
   1.614 +    ALCcontext    *pContext;
   1.615 +    ALCdevice     *device;
   1.616 +
   1.617 +    (void)flValue1;
   1.618 +    (void)flValue2;
   1.619 +    (void)flValue3;
   1.620 +
   1.621 +    pContext = GetLockedContext();
   1.622 +    if(!pContext) return;
   1.623 +
   1.624 +    device = pContext->Device;
   1.625 +    if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.626 +        alSetError(pContext, AL_INVALID_NAME);
   1.627 +    else
   1.628 +    {
   1.629 +        switch(eParam)
   1.630 +        {
   1.631 +        default:
   1.632 +            alSetError(pContext, AL_INVALID_ENUM);
   1.633 +            break;
   1.634 +        }
   1.635 +    }
   1.636 +
   1.637 +    UnlockContext(pContext);
   1.638 +}
   1.639 +
   1.640 +
   1.641 +AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
   1.642 +{
   1.643 +    ALCcontext    *pContext;
   1.644 +    ALCdevice     *device;
   1.645 +
   1.646 +    pContext = GetLockedContext();
   1.647 +    if(!pContext) return;
   1.648 +
   1.649 +    device = pContext->Device;
   1.650 +    if(!flValues)
   1.651 +        alSetError(pContext, AL_INVALID_VALUE);
   1.652 +    else if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.653 +        alSetError(pContext, AL_INVALID_NAME);
   1.654 +    else
   1.655 +    {
   1.656 +        switch(eParam)
   1.657 +        {
   1.658 +        default:
   1.659 +            alSetError(pContext, AL_INVALID_ENUM);
   1.660 +            break;
   1.661 +        }
   1.662 +    }
   1.663 +
   1.664 +    UnlockContext(pContext);
   1.665 +}
   1.666 +
   1.667 +
   1.668 +AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
   1.669 +{
   1.670 +    ALCcontext    *pContext;
   1.671 +    ALCdevice     *device;
   1.672 +
   1.673 +    (void)lValue;
   1.674 +
   1.675 +    pContext = GetLockedContext();
   1.676 +    if(!pContext) return;
   1.677 +
   1.678 +    device = pContext->Device;
   1.679 +    if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.680 +        alSetError(pContext, AL_INVALID_NAME);
   1.681 +    else
   1.682 +    {
   1.683 +        switch(eParam)
   1.684 +        {
   1.685 +        default:
   1.686 +            alSetError(pContext, AL_INVALID_ENUM);
   1.687 +            break;
   1.688 +        }
   1.689 +    }
   1.690 +
   1.691 +    UnlockContext(pContext);
   1.692 +}
   1.693 +
   1.694 +
   1.695 +AL_API void AL_APIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
   1.696 +{
   1.697 +    ALCcontext    *pContext;
   1.698 +    ALCdevice     *device;
   1.699 +
   1.700 +    (void)lValue1;
   1.701 +    (void)lValue2;
   1.702 +    (void)lValue3;
   1.703 +
   1.704 +    pContext = GetLockedContext();
   1.705 +    if(!pContext) return;
   1.706 +
   1.707 +    device = pContext->Device;
   1.708 +    if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.709 +        alSetError(pContext, AL_INVALID_NAME);
   1.710 +    else
   1.711 +    {
   1.712 +        switch(eParam)
   1.713 +        {
   1.714 +        default:
   1.715 +            alSetError(pContext, AL_INVALID_ENUM);
   1.716 +            break;
   1.717 +        }
   1.718 +    }
   1.719 +
   1.720 +    UnlockContext(pContext);
   1.721 +}
   1.722 +
   1.723 +
   1.724 +AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
   1.725 +{
   1.726 +    ALCcontext    *pContext;
   1.727 +    ALCdevice     *device;
   1.728 +    ALbuffer      *ALBuf;
   1.729 +
   1.730 +    pContext = GetLockedContext();
   1.731 +    if(!pContext) return;
   1.732 +
   1.733 +    device = pContext->Device;
   1.734 +    if(!plValues)
   1.735 +        alSetError(pContext, AL_INVALID_VALUE);
   1.736 +    else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.737 +        alSetError(pContext, AL_INVALID_NAME);
   1.738 +    else
   1.739 +    {
   1.740 +        switch(eParam)
   1.741 +        {
   1.742 +        case AL_LOOP_POINTS_SOFT:
   1.743 +            if(ALBuf->refcount > 0)
   1.744 +                alSetError(pContext, AL_INVALID_OPERATION);
   1.745 +            else if(plValues[0] < 0 || plValues[1] < 0 ||
   1.746 +                    plValues[0] >= plValues[1] || ALBuf->size == 0)
   1.747 +                alSetError(pContext, AL_INVALID_VALUE);
   1.748 +            else
   1.749 +            {
   1.750 +                ALint maxlen = ALBuf->size /
   1.751 +                               FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType);
   1.752 +                if(plValues[0] > maxlen || plValues[1] > maxlen)
   1.753 +                    alSetError(pContext, AL_INVALID_VALUE);
   1.754 +                else
   1.755 +                {
   1.756 +                    ALBuf->LoopStart = plValues[0];
   1.757 +                    ALBuf->LoopEnd = plValues[1];
   1.758 +                }
   1.759 +            }
   1.760 +            break;
   1.761 +
   1.762 +        default:
   1.763 +            alSetError(pContext, AL_INVALID_ENUM);
   1.764 +            break;
   1.765 +        }
   1.766 +    }
   1.767 +
   1.768 +    UnlockContext(pContext);
   1.769 +}
   1.770 +
   1.771 +
   1.772 +AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
   1.773 +{
   1.774 +    ALCcontext    *pContext;
   1.775 +    ALCdevice     *device;
   1.776 +
   1.777 +    pContext = GetLockedContext();
   1.778 +    if(!pContext) return;
   1.779 +
   1.780 +    device = pContext->Device;
   1.781 +    if(!pflValue)
   1.782 +        alSetError(pContext, AL_INVALID_VALUE);
   1.783 +    else if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.784 +        alSetError(pContext, AL_INVALID_NAME);
   1.785 +    else
   1.786 +    {
   1.787 +        switch(eParam)
   1.788 +        {
   1.789 +        default:
   1.790 +            alSetError(pContext, AL_INVALID_ENUM);
   1.791 +            break;
   1.792 +        }
   1.793 +    }
   1.794 +
   1.795 +    UnlockContext(pContext);
   1.796 +}
   1.797 +
   1.798 +
   1.799 +AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
   1.800 +{
   1.801 +    ALCcontext    *pContext;
   1.802 +    ALCdevice     *device;
   1.803 +
   1.804 +    pContext = GetLockedContext();
   1.805 +    if(!pContext) return;
   1.806 +
   1.807 +    device = pContext->Device;
   1.808 +    if(!pflValue1 || !pflValue2 || !pflValue3)
   1.809 +        alSetError(pContext, AL_INVALID_VALUE);
   1.810 +    else if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.811 +        alSetError(pContext, AL_INVALID_NAME);
   1.812 +    else
   1.813 +    {
   1.814 +        switch(eParam)
   1.815 +        {
   1.816 +        default:
   1.817 +            alSetError(pContext, AL_INVALID_ENUM);
   1.818 +            break;
   1.819 +        }
   1.820 +    }
   1.821 +
   1.822 +    UnlockContext(pContext);
   1.823 +}
   1.824 +
   1.825 +
   1.826 +AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
   1.827 +{
   1.828 +    ALCcontext    *pContext;
   1.829 +    ALCdevice     *device;
   1.830 +
   1.831 +    pContext = GetLockedContext();
   1.832 +    if(!pContext) return;
   1.833 +
   1.834 +    device = pContext->Device;
   1.835 +    if(!pflValues)
   1.836 +        alSetError(pContext, AL_INVALID_VALUE);
   1.837 +    else if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.838 +        alSetError(pContext, AL_INVALID_NAME);
   1.839 +    else
   1.840 +    {
   1.841 +        switch(eParam)
   1.842 +        {
   1.843 +        default:
   1.844 +            alSetError(pContext, AL_INVALID_ENUM);
   1.845 +            break;
   1.846 +        }
   1.847 +    }
   1.848 +
   1.849 +    UnlockContext(pContext);
   1.850 +}
   1.851 +
   1.852 +
   1.853 +AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
   1.854 +{
   1.855 +    ALCcontext    *pContext;
   1.856 +    ALbuffer      *pBuffer;
   1.857 +    ALCdevice     *device;
   1.858 +
   1.859 +    pContext = GetLockedContext();
   1.860 +    if(!pContext) return;
   1.861 +
   1.862 +    device = pContext->Device;
   1.863 +    if(!plValue)
   1.864 +        alSetError(pContext, AL_INVALID_VALUE);
   1.865 +    else if((pBuffer=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.866 +        alSetError(pContext, AL_INVALID_NAME);
   1.867 +    else
   1.868 +    {
   1.869 +        switch(eParam)
   1.870 +        {
   1.871 +        case AL_FREQUENCY:
   1.872 +            *plValue = pBuffer->Frequency;
   1.873 +            break;
   1.874 +
   1.875 +        case AL_BITS:
   1.876 +            *plValue = BytesFromFmt(pBuffer->FmtType) * 8;
   1.877 +            break;
   1.878 +
   1.879 +        case AL_CHANNELS:
   1.880 +            *plValue = ChannelsFromFmt(pBuffer->FmtChannels);
   1.881 +            break;
   1.882 +
   1.883 +        case AL_SIZE:
   1.884 +            *plValue = pBuffer->size;
   1.885 +            break;
   1.886 +
   1.887 +        default:
   1.888 +            alSetError(pContext, AL_INVALID_ENUM);
   1.889 +            break;
   1.890 +        }
   1.891 +    }
   1.892 +
   1.893 +    UnlockContext(pContext);
   1.894 +}
   1.895 +
   1.896 +
   1.897 +AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
   1.898 +{
   1.899 +    ALCcontext    *pContext;
   1.900 +    ALCdevice     *device;
   1.901 +
   1.902 +    pContext = GetLockedContext();
   1.903 +    if(!pContext) return;
   1.904 +
   1.905 +    device = pContext->Device;
   1.906 +    if(!plValue1 || !plValue2 || !plValue3)
   1.907 +        alSetError(pContext, AL_INVALID_VALUE);
   1.908 +    else if(LookupBuffer(device->BufferMap, buffer) == NULL)
   1.909 +        alSetError(pContext, AL_INVALID_NAME);
   1.910 +    else
   1.911 +    {
   1.912 +        switch(eParam)
   1.913 +        {
   1.914 +        default:
   1.915 +            alSetError(pContext, AL_INVALID_ENUM);
   1.916 +            break;
   1.917 +        }
   1.918 +    }
   1.919 +
   1.920 +    UnlockContext(pContext);
   1.921 +}
   1.922 +
   1.923 +
   1.924 +AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
   1.925 +{
   1.926 +    ALCcontext    *pContext;
   1.927 +    ALCdevice     *device;
   1.928 +    ALbuffer      *ALBuf;
   1.929 +
   1.930 +    switch(eParam)
   1.931 +    {
   1.932 +    case AL_FREQUENCY:
   1.933 +    case AL_BITS:
   1.934 +    case AL_CHANNELS:
   1.935 +    case AL_SIZE:
   1.936 +        alGetBufferi(buffer, eParam, plValues);
   1.937 +        return;
   1.938 +    }
   1.939 +
   1.940 +    pContext = GetLockedContext();
   1.941 +    if(!pContext) return;
   1.942 +
   1.943 +    device = pContext->Device;
   1.944 +    if(!plValues)
   1.945 +        alSetError(pContext, AL_INVALID_VALUE);
   1.946 +    else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
   1.947 +        alSetError(pContext, AL_INVALID_NAME);
   1.948 +    else
   1.949 +    {
   1.950 +        switch(eParam)
   1.951 +        {
   1.952 +        case AL_LOOP_POINTS_SOFT:
   1.953 +            plValues[0] = ALBuf->LoopStart;
   1.954 +            plValues[1] = ALBuf->LoopEnd;
   1.955 +            break;
   1.956 +
   1.957 +        default:
   1.958 +            alSetError(pContext, AL_INVALID_ENUM);
   1.959 +            break;
   1.960 +        }
   1.961 +    }
   1.962 +
   1.963 +    UnlockContext(pContext);
   1.964 +}
   1.965 +
   1.966 +
   1.967 +typedef ALubyte ALmulaw;
   1.968 +typedef ALubyte ALima4;
   1.969 +typedef struct {
   1.970 +    ALbyte b[3];
   1.971 +} ALbyte3;
   1.972 +typedef struct {
   1.973 +    ALubyte b[3];
   1.974 +} ALubyte3;
   1.975 +
   1.976 +static __inline ALshort DecodeMuLaw(ALmulaw val)
   1.977 +{ return muLawDecompressionTable[val]; }
   1.978 +
   1.979 +static ALmulaw EncodeMuLaw(ALshort val)
   1.980 +{
   1.981 +    ALint mant, exp, sign;
   1.982 +
   1.983 +    sign = (val>>8) & 0x80;
   1.984 +    if(sign)
   1.985 +    {
   1.986 +        /* -32768 doesn't properly negate on a short; it results in itself.
   1.987 +         * So clamp to -32767 */
   1.988 +        val = maxi(val, -32767);
   1.989 +        val = -val;
   1.990 +    }
   1.991 +
   1.992 +    val = mini(val, muLawClip);
   1.993 +    val += muLawBias;
   1.994 +
   1.995 +    exp = muLawCompressTable[(val>>7) & 0xff];
   1.996 +    mant = (val >> (exp+3)) & 0x0f;
   1.997 +
   1.998 +    return ~(sign | (exp<<4) | mant);
   1.999 +}
  1.1000 +
  1.1001 +static void DecodeIMA4Block(ALshort *dst, const ALima4 *src, ALint numchans)
  1.1002 +{
  1.1003 +    ALint sample[MAXCHANNELS], index[MAXCHANNELS];
  1.1004 +    ALuint code[MAXCHANNELS];
  1.1005 +    ALsizei j,k,c;
  1.1006 +
  1.1007 +    for(c = 0;c < numchans;c++)
  1.1008 +    {
  1.1009 +        sample[c]  = *(src++);
  1.1010 +        sample[c] |= *(src++) << 8;
  1.1011 +        sample[c]  = (sample[c]^0x8000) - 32768;
  1.1012 +        index[c]  = *(src++);
  1.1013 +        index[c] |= *(src++) << 8;
  1.1014 +        index[c]  = (index[c]^0x8000) - 32768;
  1.1015 +
  1.1016 +        index[c] = clampi(index[c], 0, 88);
  1.1017 +
  1.1018 +        dst[c] = sample[c];
  1.1019 +    }
  1.1020 +
  1.1021 +    j = 1;
  1.1022 +    while(j < 65)
  1.1023 +    {
  1.1024 +        for(c = 0;c < numchans;c++)
  1.1025 +        {
  1.1026 +            code[c]  = *(src++);
  1.1027 +            code[c] |= *(src++) << 8;
  1.1028 +            code[c] |= *(src++) << 16;
  1.1029 +            code[c] |= *(src++) << 24;
  1.1030 +        }
  1.1031 +
  1.1032 +        for(k = 0;k < 8;k++,j++)
  1.1033 +        {
  1.1034 +            for(c = 0;c < numchans;c++)
  1.1035 +            {
  1.1036 +                int nibble = code[c]&0xf;
  1.1037 +                code[c] >>= 4;
  1.1038 +
  1.1039 +                sample[c] += IMA4Codeword[nibble] * IMAStep_size[index[c]] / 8;
  1.1040 +                sample[c] = clampi(sample[c], -32768, 32767);
  1.1041 +
  1.1042 +                index[c] += IMA4Index_adjust[nibble];
  1.1043 +                index[c] = clampi(index[c], 0, 88);
  1.1044 +
  1.1045 +                dst[j*numchans + c] = sample[c];
  1.1046 +            }
  1.1047 +        }
  1.1048 +    }
  1.1049 +}
  1.1050 +
  1.1051 +static void EncodeIMA4Block(ALima4 *dst, const ALshort *src, ALint *sample, ALint *index, ALint numchans)
  1.1052 +{
  1.1053 +    ALsizei j,k,c;
  1.1054 +
  1.1055 +    for(c = 0;c < numchans;c++)
  1.1056 +    {
  1.1057 +        int diff = src[c] - sample[c];
  1.1058 +        int step = IMAStep_size[index[c]];
  1.1059 +        int nibble;
  1.1060 +
  1.1061 +        nibble = 0;
  1.1062 +        if(diff < 0)
  1.1063 +        {
  1.1064 +            nibble = 0x8;
  1.1065 +            diff = -diff;
  1.1066 +        }
  1.1067 +
  1.1068 +        diff = mini(step*2, diff);
  1.1069 +        nibble |= (diff*8/step - 1) / 2;
  1.1070 +
  1.1071 +        sample[c] += IMA4Codeword[nibble] * step / 8;
  1.1072 +        sample[c] = clampi(sample[c], -32768, 32767);
  1.1073 +
  1.1074 +        index[c] += IMA4Index_adjust[nibble];
  1.1075 +        index[c] = clampi(index[c], 0, 88);
  1.1076 +
  1.1077 +        *(dst++) = sample[c] & 0xff;
  1.1078 +        *(dst++) = (sample[c]>>8) & 0xff;
  1.1079 +        *(dst++) = index[c] & 0xff;
  1.1080 +        *(dst++) = (index[c]>>8) & 0xff;
  1.1081 +    }
  1.1082 +
  1.1083 +    j = 1;
  1.1084 +    while(j < 65)
  1.1085 +    {
  1.1086 +        for(c = 0;c < numchans;c++)
  1.1087 +        {
  1.1088 +            for(k = 0;k < 8;k++)
  1.1089 +            {
  1.1090 +                int diff = src[(j+k)*numchans + c] - sample[c];
  1.1091 +                int step = IMAStep_size[index[c]];
  1.1092 +                int nibble;
  1.1093 +
  1.1094 +                nibble = 0;
  1.1095 +                if(diff < 0)
  1.1096 +                {
  1.1097 +                    nibble = 0x8;
  1.1098 +                    diff = -diff;
  1.1099 +                }
  1.1100 +
  1.1101 +                diff = mini(step*2, diff);
  1.1102 +                nibble |= (diff*8/step - 1) / 2;
  1.1103 +
  1.1104 +                sample[c] += IMA4Codeword[nibble] * step / 8;
  1.1105 +                sample[c] = clampi(sample[c], -32768, 32767);
  1.1106 +
  1.1107 +                index[c] += IMA4Index_adjust[nibble];
  1.1108 +                index[c] = clampi(index[c], 0, 88);
  1.1109 +
  1.1110 +                if(!(k&1)) *dst = nibble;
  1.1111 +                else *(dst++) |= nibble<<4;
  1.1112 +            }
  1.1113 +        }
  1.1114 +        j += 8;
  1.1115 +    }
  1.1116 +}
  1.1117 +
  1.1118 +static const union {
  1.1119 +    ALuint u;
  1.1120 +    ALubyte b[sizeof(ALuint)];
  1.1121 +} EndianTest = { 1 };
  1.1122 +#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
  1.1123 +
  1.1124 +static __inline ALint DecodeByte3(ALbyte3 val)
  1.1125 +{
  1.1126 +    if(IS_LITTLE_ENDIAN)
  1.1127 +        return (val.b[2]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[0]);
  1.1128 +    return (val.b[0]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[2]);
  1.1129 +}
  1.1130 +
  1.1131 +static __inline ALbyte3 EncodeByte3(ALint val)
  1.1132 +{
  1.1133 +    if(IS_LITTLE_ENDIAN)
  1.1134 +    {
  1.1135 +        ALbyte3 ret = {{ val, val>>8, val>>16 }};
  1.1136 +        return ret;
  1.1137 +    }
  1.1138 +    else
  1.1139 +    {
  1.1140 +        ALbyte3 ret = {{ val>>16, val>>8, val }};
  1.1141 +        return ret;
  1.1142 +    }
  1.1143 +}
  1.1144 +
  1.1145 +static __inline ALint DecodeUByte3(ALubyte3 val)
  1.1146 +{
  1.1147 +    if(IS_LITTLE_ENDIAN)
  1.1148 +        return (val.b[2]<<16) | (val.b[1]<<8) | (val.b[0]);
  1.1149 +    return (val.b[0]<<16) | (val.b[1]<<8) | val.b[2];
  1.1150 +}
  1.1151 +
  1.1152 +static __inline ALubyte3 EncodeUByte3(ALint val)
  1.1153 +{
  1.1154 +    if(IS_LITTLE_ENDIAN)
  1.1155 +    {
  1.1156 +        ALubyte3 ret = {{ val, val>>8, val>>16 }};
  1.1157 +        return ret;
  1.1158 +    }
  1.1159 +    else
  1.1160 +    {
  1.1161 +        ALubyte3 ret = {{ val>>16, val>>8, val }};
  1.1162 +        return ret;
  1.1163 +    }
  1.1164 +}
  1.1165 +
  1.1166 +
  1.1167 +static __inline ALbyte Conv_ALbyte_ALbyte(ALbyte val)
  1.1168 +{ return val; }
  1.1169 +static __inline ALbyte Conv_ALbyte_ALubyte(ALubyte val)
  1.1170 +{ return val-128; }
  1.1171 +static __inline ALbyte Conv_ALbyte_ALshort(ALshort val)
  1.1172 +{ return val>>8; }
  1.1173 +static __inline ALbyte Conv_ALbyte_ALushort(ALushort val)
  1.1174 +{ return (val>>8)-128; }
  1.1175 +static __inline ALbyte Conv_ALbyte_ALint(ALint val)
  1.1176 +{ return val>>24; }
  1.1177 +static __inline ALbyte Conv_ALbyte_ALuint(ALuint val)
  1.1178 +{ return (val>>24)-128; }
  1.1179 +static __inline ALbyte Conv_ALbyte_ALfloat(ALfloat val)
  1.1180 +{
  1.1181 +    if(val > 1.0f) return 127;
  1.1182 +    if(val < -1.0f) return -128;
  1.1183 +    return (ALint)(val * 127.0f);
  1.1184 +}
  1.1185 +static __inline ALbyte Conv_ALbyte_ALdouble(ALdouble val)
  1.1186 +{
  1.1187 +    if(val > 1.0) return 127;
  1.1188 +    if(val < -1.0) return -128;
  1.1189 +    return (ALint)(val * 127.0);
  1.1190 +}
  1.1191 +static __inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val)
  1.1192 +{ return Conv_ALbyte_ALshort(DecodeMuLaw(val)); }
  1.1193 +static __inline ALbyte Conv_ALbyte_ALbyte3(ALbyte3 val)
  1.1194 +{ return DecodeByte3(val)>>16; }
  1.1195 +static __inline ALbyte Conv_ALbyte_ALubyte3(ALubyte3 val)
  1.1196 +{ return (DecodeUByte3(val)>>16)-128; }
  1.1197 +
  1.1198 +static __inline ALubyte Conv_ALubyte_ALbyte(ALbyte val)
  1.1199 +{ return val+128; }
  1.1200 +static __inline ALubyte Conv_ALubyte_ALubyte(ALubyte val)
  1.1201 +{ return val; }
  1.1202 +static __inline ALubyte Conv_ALubyte_ALshort(ALshort val)
  1.1203 +{ return (val>>8)+128; }
  1.1204 +static __inline ALubyte Conv_ALubyte_ALushort(ALushort val)
  1.1205 +{ return val>>8; }
  1.1206 +static __inline ALubyte Conv_ALubyte_ALint(ALint val)
  1.1207 +{ return (val>>24)+128; }
  1.1208 +static __inline ALubyte Conv_ALubyte_ALuint(ALuint val)
  1.1209 +{ return val>>24; }
  1.1210 +static __inline ALubyte Conv_ALubyte_ALfloat(ALfloat val)
  1.1211 +{
  1.1212 +    if(val > 1.0f) return 255;
  1.1213 +    if(val < -1.0f) return 0;
  1.1214 +    return (ALint)(val * 127.0f) + 128;
  1.1215 +}
  1.1216 +static __inline ALubyte Conv_ALubyte_ALdouble(ALdouble val)
  1.1217 +{
  1.1218 +    if(val > 1.0) return 255;
  1.1219 +    if(val < -1.0) return 0;
  1.1220 +    return (ALint)(val * 127.0) + 128;
  1.1221 +}
  1.1222 +static __inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val)
  1.1223 +{ return Conv_ALubyte_ALshort(DecodeMuLaw(val)); }
  1.1224 +static __inline ALubyte Conv_ALubyte_ALbyte3(ALbyte3 val)
  1.1225 +{ return (DecodeByte3(val)>>16)+128; }
  1.1226 +static __inline ALubyte Conv_ALubyte_ALubyte3(ALubyte3 val)
  1.1227 +{ return DecodeUByte3(val)>>16; }
  1.1228 +
  1.1229 +static __inline ALshort Conv_ALshort_ALbyte(ALbyte val)
  1.1230 +{ return val<<8; }
  1.1231 +static __inline ALshort Conv_ALshort_ALubyte(ALubyte val)
  1.1232 +{ return (val-128)<<8; }
  1.1233 +static __inline ALshort Conv_ALshort_ALshort(ALshort val)
  1.1234 +{ return val; }
  1.1235 +static __inline ALshort Conv_ALshort_ALushort(ALushort val)
  1.1236 +{ return val-32768; }
  1.1237 +static __inline ALshort Conv_ALshort_ALint(ALint val)
  1.1238 +{ return val>>16; }
  1.1239 +static __inline ALshort Conv_ALshort_ALuint(ALuint val)
  1.1240 +{ return (val>>16)-32768; }
  1.1241 +static __inline ALshort Conv_ALshort_ALfloat(ALfloat val)
  1.1242 +{
  1.1243 +    if(val > 1.0f) return 32767;
  1.1244 +    if(val < -1.0f) return -32768;
  1.1245 +    return (ALint)(val * 32767.0f);
  1.1246 +}
  1.1247 +static __inline ALshort Conv_ALshort_ALdouble(ALdouble val)
  1.1248 +{
  1.1249 +    if(val > 1.0) return 32767;
  1.1250 +    if(val < -1.0) return -32768;
  1.1251 +    return (ALint)(val * 32767.0);
  1.1252 +}
  1.1253 +static __inline ALshort Conv_ALshort_ALmulaw(ALmulaw val)
  1.1254 +{ return Conv_ALshort_ALshort(DecodeMuLaw(val)); }
  1.1255 +static __inline ALshort Conv_ALshort_ALbyte3(ALbyte3 val)
  1.1256 +{ return DecodeByte3(val)>>8; }
  1.1257 +static __inline ALshort Conv_ALshort_ALubyte3(ALubyte3 val)
  1.1258 +{ return (DecodeUByte3(val)>>8)-32768; }
  1.1259 +
  1.1260 +static __inline ALushort Conv_ALushort_ALbyte(ALbyte val)
  1.1261 +{ return (val+128)<<8; }
  1.1262 +static __inline ALushort Conv_ALushort_ALubyte(ALubyte val)
  1.1263 +{ return val<<8; }
  1.1264 +static __inline ALushort Conv_ALushort_ALshort(ALshort val)
  1.1265 +{ return val+32768; }
  1.1266 +static __inline ALushort Conv_ALushort_ALushort(ALushort val)
  1.1267 +{ return val; }
  1.1268 +static __inline ALushort Conv_ALushort_ALint(ALint val)
  1.1269 +{ return (val>>16)+32768; }
  1.1270 +static __inline ALushort Conv_ALushort_ALuint(ALuint val)
  1.1271 +{ return val>>16; }
  1.1272 +static __inline ALushort Conv_ALushort_ALfloat(ALfloat val)
  1.1273 +{
  1.1274 +    if(val > 1.0f) return 65535;
  1.1275 +    if(val < -1.0f) return 0;
  1.1276 +    return (ALint)(val * 32767.0f) + 32768;
  1.1277 +}
  1.1278 +static __inline ALushort Conv_ALushort_ALdouble(ALdouble val)
  1.1279 +{
  1.1280 +    if(val > 1.0) return 65535;
  1.1281 +    if(val < -1.0) return 0;
  1.1282 +    return (ALint)(val * 32767.0) + 32768;
  1.1283 +}
  1.1284 +static __inline ALushort Conv_ALushort_ALmulaw(ALmulaw val)
  1.1285 +{ return Conv_ALushort_ALshort(DecodeMuLaw(val)); }
  1.1286 +static __inline ALushort Conv_ALushort_ALbyte3(ALbyte3 val)
  1.1287 +{ return (DecodeByte3(val)>>8)+32768; }
  1.1288 +static __inline ALushort Conv_ALushort_ALubyte3(ALubyte3 val)
  1.1289 +{ return DecodeUByte3(val)>>8; }
  1.1290 +
  1.1291 +static __inline ALint Conv_ALint_ALbyte(ALbyte val)
  1.1292 +{ return val<<24; }
  1.1293 +static __inline ALint Conv_ALint_ALubyte(ALubyte val)
  1.1294 +{ return (val-128)<<24; }
  1.1295 +static __inline ALint Conv_ALint_ALshort(ALshort val)
  1.1296 +{ return val<<16; }
  1.1297 +static __inline ALint Conv_ALint_ALushort(ALushort val)
  1.1298 +{ return (val-32768)<<16; }
  1.1299 +static __inline ALint Conv_ALint_ALint(ALint val)
  1.1300 +{ return val; }
  1.1301 +static __inline ALint Conv_ALint_ALuint(ALuint val)
  1.1302 +{ return val-2147483648u; }
  1.1303 +static __inline ALint Conv_ALint_ALfloat(ALfloat val)
  1.1304 +{
  1.1305 +    if(val > 1.0f) return 2147483647;
  1.1306 +    if(val < -1.0f) return -2147483647-1;
  1.1307 +    return (ALint)(val * 2147483647.0);
  1.1308 +}
  1.1309 +static __inline ALint Conv_ALint_ALdouble(ALdouble val)
  1.1310 +{
  1.1311 +    if(val > 1.0) return 2147483647;
  1.1312 +    if(val < -1.0) return -2147483647-1;
  1.1313 +    return (ALint)(val * 2147483647.0);
  1.1314 +}
  1.1315 +static __inline ALint Conv_ALint_ALmulaw(ALmulaw val)
  1.1316 +{ return Conv_ALint_ALshort(DecodeMuLaw(val)); }
  1.1317 +static __inline ALint Conv_ALint_ALbyte3(ALbyte3 val)
  1.1318 +{ return DecodeByte3(val)<<8; }
  1.1319 +static __inline ALint Conv_ALint_ALubyte3(ALubyte3 val)
  1.1320 +{ return (DecodeUByte3(val)-8388608)<<8; }
  1.1321 +
  1.1322 +static __inline ALuint Conv_ALuint_ALbyte(ALbyte val)
  1.1323 +{ return (val+128)<<24; }
  1.1324 +static __inline ALuint Conv_ALuint_ALubyte(ALubyte val)
  1.1325 +{ return val<<24; }
  1.1326 +static __inline ALuint Conv_ALuint_ALshort(ALshort val)
  1.1327 +{ return (val+32768)<<16; }
  1.1328 +static __inline ALuint Conv_ALuint_ALushort(ALushort val)
  1.1329 +{ return val<<16; }
  1.1330 +static __inline ALuint Conv_ALuint_ALint(ALint val)
  1.1331 +{ return val+2147483648u; }
  1.1332 +static __inline ALuint Conv_ALuint_ALuint(ALuint val)
  1.1333 +{ return val; }
  1.1334 +static __inline ALuint Conv_ALuint_ALfloat(ALfloat val)
  1.1335 +{
  1.1336 +    if(val > 1.0f) return 4294967295u;
  1.1337 +    if(val < -1.0f) return 0;
  1.1338 +    return (ALint)(val * 2147483647.0) + 2147483648u;
  1.1339 +}
  1.1340 +static __inline ALuint Conv_ALuint_ALdouble(ALdouble val)
  1.1341 +{
  1.1342 +    if(val > 1.0) return 4294967295u;
  1.1343 +    if(val < -1.0) return 0;
  1.1344 +    return (ALint)(val * 2147483647.0) + 2147483648u;
  1.1345 +}
  1.1346 +static __inline ALuint Conv_ALuint_ALmulaw(ALmulaw val)
  1.1347 +{ return Conv_ALuint_ALshort(DecodeMuLaw(val)); }
  1.1348 +static __inline ALuint Conv_ALuint_ALbyte3(ALbyte3 val)
  1.1349 +{ return (DecodeByte3(val)+8388608)<<8; }
  1.1350 +static __inline ALuint Conv_ALuint_ALubyte3(ALubyte3 val)
  1.1351 +{ return DecodeUByte3(val)<<8; }
  1.1352 +
  1.1353 +static __inline ALfloat Conv_ALfloat_ALbyte(ALbyte val)
  1.1354 +{ return val * (1.0f/127.0f); }
  1.1355 +static __inline ALfloat Conv_ALfloat_ALubyte(ALubyte val)
  1.1356 +{ return (val-128) * (1.0f/127.0f); }
  1.1357 +static __inline ALfloat Conv_ALfloat_ALshort(ALshort val)
  1.1358 +{ return val * (1.0f/32767.0f); }
  1.1359 +static __inline ALfloat Conv_ALfloat_ALushort(ALushort val)
  1.1360 +{ return (val-32768) * (1.0f/32767.0f); }
  1.1361 +static __inline ALfloat Conv_ALfloat_ALint(ALint val)
  1.1362 +{ return val * (1.0/2147483647.0); }
  1.1363 +static __inline ALfloat Conv_ALfloat_ALuint(ALuint val)
  1.1364 +{ return (ALint)(val-2147483648u) * (1.0/2147483647.0); }
  1.1365 +static __inline ALfloat Conv_ALfloat_ALfloat(ALfloat val)
  1.1366 +{ return (val==val) ? val : 0.0f; }
  1.1367 +static __inline ALfloat Conv_ALfloat_ALdouble(ALdouble val)
  1.1368 +{ return (val==val) ? val : 0.0; }
  1.1369 +static __inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val)
  1.1370 +{ return Conv_ALfloat_ALshort(DecodeMuLaw(val)); }
  1.1371 +static __inline ALfloat Conv_ALfloat_ALbyte3(ALbyte3 val)
  1.1372 +{ return DecodeByte3(val) * (1.0/8388607.0); }
  1.1373 +static __inline ALfloat Conv_ALfloat_ALubyte3(ALubyte3 val)
  1.1374 +{ return (DecodeUByte3(val)-8388608) * (1.0/8388607.0); }
  1.1375 +
  1.1376 +static __inline ALdouble Conv_ALdouble_ALbyte(ALbyte val)
  1.1377 +{ return val * (1.0/127.0); }
  1.1378 +static __inline ALdouble Conv_ALdouble_ALubyte(ALubyte val)
  1.1379 +{ return (val-128) * (1.0/127.0); }
  1.1380 +static __inline ALdouble Conv_ALdouble_ALshort(ALshort val)
  1.1381 +{ return val * (1.0/32767.0); }
  1.1382 +static __inline ALdouble Conv_ALdouble_ALushort(ALushort val)
  1.1383 +{ return (val-32768) * (1.0/32767.0); }
  1.1384 +static __inline ALdouble Conv_ALdouble_ALint(ALint val)
  1.1385 +{ return val * (1.0/2147483647.0); }
  1.1386 +static __inline ALdouble Conv_ALdouble_ALuint(ALuint val)
  1.1387 +{ return (ALint)(val-2147483648u) * (1.0/2147483647.0); }
  1.1388 +static __inline ALdouble Conv_ALdouble_ALfloat(ALfloat val)
  1.1389 +{ return (val==val) ? val : 0.0f; }
  1.1390 +static __inline ALdouble Conv_ALdouble_ALdouble(ALdouble val)
  1.1391 +{ return (val==val) ? val : 0.0; }
  1.1392 +static __inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val)
  1.1393 +{ return Conv_ALdouble_ALshort(DecodeMuLaw(val)); }
  1.1394 +static __inline ALdouble Conv_ALdouble_ALbyte3(ALbyte3 val)
  1.1395 +{ return DecodeByte3(val) * (1.0/8388607.0); }
  1.1396 +static __inline ALdouble Conv_ALdouble_ALubyte3(ALubyte3 val)
  1.1397 +{ return (DecodeUByte3(val)-8388608) * (1.0/8388607.0); }
  1.1398 +
  1.1399 +#define DECL_TEMPLATE(T)                                                      \
  1.1400 +static __inline ALmulaw Conv_ALmulaw_##T(T val)                               \
  1.1401 +{ return EncodeMuLaw(Conv_ALshort_##T(val)); }
  1.1402 +
  1.1403 +DECL_TEMPLATE(ALbyte)
  1.1404 +DECL_TEMPLATE(ALubyte)
  1.1405 +DECL_TEMPLATE(ALshort)
  1.1406 +DECL_TEMPLATE(ALushort)
  1.1407 +DECL_TEMPLATE(ALint)
  1.1408 +DECL_TEMPLATE(ALuint)
  1.1409 +DECL_TEMPLATE(ALfloat)
  1.1410 +DECL_TEMPLATE(ALdouble)
  1.1411 +static __inline ALmulaw Conv_ALmulaw_ALmulaw(ALmulaw val)
  1.1412 +{ return val; }
  1.1413 +DECL_TEMPLATE(ALbyte3)
  1.1414 +DECL_TEMPLATE(ALubyte3)
  1.1415 +
  1.1416 +#undef DECL_TEMPLATE
  1.1417 +
  1.1418 +#define DECL_TEMPLATE(T)                                                      \
  1.1419 +static __inline ALbyte3 Conv_ALbyte3_##T(T val)                               \
  1.1420 +{ return EncodeByte3(Conv_ALint_##T(val)>>8); }
  1.1421 +
  1.1422 +DECL_TEMPLATE(ALbyte)
  1.1423 +DECL_TEMPLATE(ALubyte)
  1.1424 +DECL_TEMPLATE(ALshort)
  1.1425 +DECL_TEMPLATE(ALushort)
  1.1426 +DECL_TEMPLATE(ALint)
  1.1427 +DECL_TEMPLATE(ALuint)
  1.1428 +DECL_TEMPLATE(ALfloat)
  1.1429 +DECL_TEMPLATE(ALdouble)
  1.1430 +DECL_TEMPLATE(ALmulaw)
  1.1431 +static __inline ALbyte3 Conv_ALbyte3_ALbyte3(ALbyte3 val)
  1.1432 +{ return val; }
  1.1433 +DECL_TEMPLATE(ALubyte3)
  1.1434 +
  1.1435 +#undef DECL_TEMPLATE
  1.1436 +
  1.1437 +#define DECL_TEMPLATE(T)                                                      \
  1.1438 +static __inline ALubyte3 Conv_ALubyte3_##T(T val)                             \
  1.1439 +{ return EncodeUByte3(Conv_ALuint_##T(val)>>8); }
  1.1440 +
  1.1441 +DECL_TEMPLATE(ALbyte)
  1.1442 +DECL_TEMPLATE(ALubyte)
  1.1443 +DECL_TEMPLATE(ALshort)
  1.1444 +DECL_TEMPLATE(ALushort)
  1.1445 +DECL_TEMPLATE(ALint)
  1.1446 +DECL_TEMPLATE(ALuint)
  1.1447 +DECL_TEMPLATE(ALfloat)
  1.1448 +DECL_TEMPLATE(ALdouble)
  1.1449 +DECL_TEMPLATE(ALmulaw)
  1.1450 +DECL_TEMPLATE(ALbyte3)
  1.1451 +static __inline ALubyte3 Conv_ALubyte3_ALubyte3(ALubyte3 val)
  1.1452 +{ return val; }
  1.1453 +
  1.1454 +#undef DECL_TEMPLATE
  1.1455 +
  1.1456 +
  1.1457 +#define DECL_TEMPLATE(T1, T2)                                                 \
  1.1458 +static void Convert_##T1##_##T2(T1 *dst, const T2 *src, ALuint numchans,      \
  1.1459 +                                ALuint len)                                   \
  1.1460 +{                                                                             \
  1.1461 +    ALuint i, j;                                                              \
  1.1462 +    for(i = 0;i < len;i++)                                                    \
  1.1463 +    {                                                                         \
  1.1464 +        for(j = 0;j < numchans;j++)                                           \
  1.1465 +            *(dst++) = Conv_##T1##_##T2(*(src++));                            \
  1.1466 +    }                                                                         \
  1.1467 +}
  1.1468 +
  1.1469 +DECL_TEMPLATE(ALbyte, ALbyte)
  1.1470 +DECL_TEMPLATE(ALbyte, ALubyte)
  1.1471 +DECL_TEMPLATE(ALbyte, ALshort)
  1.1472 +DECL_TEMPLATE(ALbyte, ALushort)
  1.1473 +DECL_TEMPLATE(ALbyte, ALint)
  1.1474 +DECL_TEMPLATE(ALbyte, ALuint)
  1.1475 +DECL_TEMPLATE(ALbyte, ALfloat)
  1.1476 +DECL_TEMPLATE(ALbyte, ALdouble)
  1.1477 +DECL_TEMPLATE(ALbyte, ALmulaw)
  1.1478 +DECL_TEMPLATE(ALbyte, ALbyte3)
  1.1479 +DECL_TEMPLATE(ALbyte, ALubyte3)
  1.1480 +
  1.1481 +DECL_TEMPLATE(ALubyte, ALbyte)
  1.1482 +DECL_TEMPLATE(ALubyte, ALubyte)
  1.1483 +DECL_TEMPLATE(ALubyte, ALshort)
  1.1484 +DECL_TEMPLATE(ALubyte, ALushort)
  1.1485 +DECL_TEMPLATE(ALubyte, ALint)
  1.1486 +DECL_TEMPLATE(ALubyte, ALuint)
  1.1487 +DECL_TEMPLATE(ALubyte, ALfloat)
  1.1488 +DECL_TEMPLATE(ALubyte, ALdouble)
  1.1489 +DECL_TEMPLATE(ALubyte, ALmulaw)
  1.1490 +DECL_TEMPLATE(ALubyte, ALbyte3)
  1.1491 +DECL_TEMPLATE(ALubyte, ALubyte3)
  1.1492 +
  1.1493 +DECL_TEMPLATE(ALshort, ALbyte)
  1.1494 +DECL_TEMPLATE(ALshort, ALubyte)
  1.1495 +DECL_TEMPLATE(ALshort, ALshort)
  1.1496 +DECL_TEMPLATE(ALshort, ALushort)
  1.1497 +DECL_TEMPLATE(ALshort, ALint)
  1.1498 +DECL_TEMPLATE(ALshort, ALuint)
  1.1499 +DECL_TEMPLATE(ALshort, ALfloat)
  1.1500 +DECL_TEMPLATE(ALshort, ALdouble)
  1.1501 +DECL_TEMPLATE(ALshort, ALmulaw)
  1.1502 +DECL_TEMPLATE(ALshort, ALbyte3)
  1.1503 +DECL_TEMPLATE(ALshort, ALubyte3)
  1.1504 +
  1.1505 +DECL_TEMPLATE(ALushort, ALbyte)
  1.1506 +DECL_TEMPLATE(ALushort, ALubyte)
  1.1507 +DECL_TEMPLATE(ALushort, ALshort)
  1.1508 +DECL_TEMPLATE(ALushort, ALushort)
  1.1509 +DECL_TEMPLATE(ALushort, ALint)
  1.1510 +DECL_TEMPLATE(ALushort, ALuint)
  1.1511 +DECL_TEMPLATE(ALushort, ALfloat)
  1.1512 +DECL_TEMPLATE(ALushort, ALdouble)
  1.1513 +DECL_TEMPLATE(ALushort, ALmulaw)
  1.1514 +DECL_TEMPLATE(ALushort, ALbyte3)
  1.1515 +DECL_TEMPLATE(ALushort, ALubyte3)
  1.1516 +
  1.1517 +DECL_TEMPLATE(ALint, ALbyte)
  1.1518 +DECL_TEMPLATE(ALint, ALubyte)
  1.1519 +DECL_TEMPLATE(ALint, ALshort)
  1.1520 +DECL_TEMPLATE(ALint, ALushort)
  1.1521 +DECL_TEMPLATE(ALint, ALint)
  1.1522 +DECL_TEMPLATE(ALint, ALuint)
  1.1523 +DECL_TEMPLATE(ALint, ALfloat)
  1.1524 +DECL_TEMPLATE(ALint, ALdouble)
  1.1525 +DECL_TEMPLATE(ALint, ALmulaw)
  1.1526 +DECL_TEMPLATE(ALint, ALbyte3)
  1.1527 +DECL_TEMPLATE(ALint, ALubyte3)
  1.1528 +
  1.1529 +DECL_TEMPLATE(ALuint, ALbyte)
  1.1530 +DECL_TEMPLATE(ALuint, ALubyte)
  1.1531 +DECL_TEMPLATE(ALuint, ALshort)
  1.1532 +DECL_TEMPLATE(ALuint, ALushort)
  1.1533 +DECL_TEMPLATE(ALuint, ALint)
  1.1534 +DECL_TEMPLATE(ALuint, ALuint)
  1.1535 +DECL_TEMPLATE(ALuint, ALfloat)
  1.1536 +DECL_TEMPLATE(ALuint, ALdouble)
  1.1537 +DECL_TEMPLATE(ALuint, ALmulaw)
  1.1538 +DECL_TEMPLATE(ALuint, ALbyte3)
  1.1539 +DECL_TEMPLATE(ALuint, ALubyte3)
  1.1540 +
  1.1541 +DECL_TEMPLATE(ALfloat, ALbyte)
  1.1542 +DECL_TEMPLATE(ALfloat, ALubyte)
  1.1543 +DECL_TEMPLATE(ALfloat, ALshort)
  1.1544 +DECL_TEMPLATE(ALfloat, ALushort)
  1.1545 +DECL_TEMPLATE(ALfloat, ALint)
  1.1546 +DECL_TEMPLATE(ALfloat, ALuint)
  1.1547 +DECL_TEMPLATE(ALfloat, ALfloat)
  1.1548 +DECL_TEMPLATE(ALfloat, ALdouble)
  1.1549 +DECL_TEMPLATE(ALfloat, ALmulaw)
  1.1550 +DECL_TEMPLATE(ALfloat, ALbyte3)
  1.1551 +DECL_TEMPLATE(ALfloat, ALubyte3)
  1.1552 +
  1.1553 +DECL_TEMPLATE(ALdouble, ALbyte)
  1.1554 +DECL_TEMPLATE(ALdouble, ALubyte)
  1.1555 +DECL_TEMPLATE(ALdouble, ALshort)
  1.1556 +DECL_TEMPLATE(ALdouble, ALushort)
  1.1557 +DECL_TEMPLATE(ALdouble, ALint)
  1.1558 +DECL_TEMPLATE(ALdouble, ALuint)
  1.1559 +DECL_TEMPLATE(ALdouble, ALfloat)
  1.1560 +DECL_TEMPLATE(ALdouble, ALdouble)
  1.1561 +DECL_TEMPLATE(ALdouble, ALmulaw)
  1.1562 +DECL_TEMPLATE(ALdouble, ALbyte3)
  1.1563 +DECL_TEMPLATE(ALdouble, ALubyte3)
  1.1564 +
  1.1565 +DECL_TEMPLATE(ALmulaw, ALbyte)
  1.1566 +DECL_TEMPLATE(ALmulaw, ALubyte)
  1.1567 +DECL_TEMPLATE(ALmulaw, ALshort)
  1.1568 +DECL_TEMPLATE(ALmulaw, ALushort)
  1.1569 +DECL_TEMPLATE(ALmulaw, ALint)
  1.1570 +DECL_TEMPLATE(ALmulaw, ALuint)
  1.1571 +DECL_TEMPLATE(ALmulaw, ALfloat)
  1.1572 +DECL_TEMPLATE(ALmulaw, ALdouble)
  1.1573 +DECL_TEMPLATE(ALmulaw, ALmulaw)
  1.1574 +DECL_TEMPLATE(ALmulaw, ALbyte3)
  1.1575 +DECL_TEMPLATE(ALmulaw, ALubyte3)
  1.1576 +
  1.1577 +DECL_TEMPLATE(ALbyte3, ALbyte)
  1.1578 +DECL_TEMPLATE(ALbyte3, ALubyte)
  1.1579 +DECL_TEMPLATE(ALbyte3, ALshort)
  1.1580 +DECL_TEMPLATE(ALbyte3, ALushort)
  1.1581 +DECL_TEMPLATE(ALbyte3, ALint)
  1.1582 +DECL_TEMPLATE(ALbyte3, ALuint)
  1.1583 +DECL_TEMPLATE(ALbyte3, ALfloat)
  1.1584 +DECL_TEMPLATE(ALbyte3, ALdouble)
  1.1585 +DECL_TEMPLATE(ALbyte3, ALmulaw)
  1.1586 +DECL_TEMPLATE(ALbyte3, ALbyte3)
  1.1587 +DECL_TEMPLATE(ALbyte3, ALubyte3)
  1.1588 +
  1.1589 +DECL_TEMPLATE(ALubyte3, ALbyte)
  1.1590 +DECL_TEMPLATE(ALubyte3, ALubyte)
  1.1591 +DECL_TEMPLATE(ALubyte3, ALshort)
  1.1592 +DECL_TEMPLATE(ALubyte3, ALushort)
  1.1593 +DECL_TEMPLATE(ALubyte3, ALint)
  1.1594 +DECL_TEMPLATE(ALubyte3, ALuint)
  1.1595 +DECL_TEMPLATE(ALubyte3, ALfloat)
  1.1596 +DECL_TEMPLATE(ALubyte3, ALdouble)
  1.1597 +DECL_TEMPLATE(ALubyte3, ALmulaw)
  1.1598 +DECL_TEMPLATE(ALubyte3, ALbyte3)
  1.1599 +DECL_TEMPLATE(ALubyte3, ALubyte3)
  1.1600 +
  1.1601 +#undef DECL_TEMPLATE
  1.1602 +
  1.1603 +#define DECL_TEMPLATE(T)                                                      \
  1.1604 +static void Convert_##T##_ALima4(T *dst, const ALima4 *src, ALuint numchans,  \
  1.1605 +                                 ALuint numblocks)                            \
  1.1606 +{                                                                             \
  1.1607 +    ALuint i, j;                                                              \
  1.1608 +    ALshort tmp[65*MAXCHANNELS]; /* Max samples an IMA4 frame can be */       \
  1.1609 +    for(i = 0;i < numblocks;i++)                                              \
  1.1610 +    {                                                                         \
  1.1611 +        DecodeIMA4Block(tmp, src, numchans);                                  \
  1.1612 +        src += 36*numchans;                                                   \
  1.1613 +        for(j = 0;j < 65*numchans;j++)                                        \
  1.1614 +            *(dst++) = Conv_##T##_ALshort(tmp[j]);                            \
  1.1615 +    }                                                                         \
  1.1616 +}
  1.1617 +
  1.1618 +DECL_TEMPLATE(ALbyte)
  1.1619 +DECL_TEMPLATE(ALubyte)
  1.1620 +DECL_TEMPLATE(ALshort)
  1.1621 +DECL_TEMPLATE(ALushort)
  1.1622 +DECL_TEMPLATE(ALint)
  1.1623 +DECL_TEMPLATE(ALuint)
  1.1624 +DECL_TEMPLATE(ALfloat)
  1.1625 +DECL_TEMPLATE(ALdouble)
  1.1626 +DECL_TEMPLATE(ALmulaw)
  1.1627 +DECL_TEMPLATE(ALbyte3)
  1.1628 +DECL_TEMPLATE(ALubyte3)
  1.1629 +
  1.1630 +#undef DECL_TEMPLATE
  1.1631 +
  1.1632 +#define DECL_TEMPLATE(T)                                                      \
  1.1633 +static void Convert_ALima4_##T(ALima4 *dst, const T *src, ALuint numchans,    \
  1.1634 +                               ALuint numblocks)                              \
  1.1635 +{                                                                             \
  1.1636 +    ALuint i, j;                                                              \
  1.1637 +    ALshort tmp[65*MAXCHANNELS]; /* Max samples an IMA4 frame can be */       \
  1.1638 +    ALint sample[MAXCHANNELS] = {0,0,0,0,0,0,0,0};                            \
  1.1639 +    ALint index[MAXCHANNELS] = {0,0,0,0,0,0,0,0};                             \
  1.1640 +    for(i = 0;i < numblocks;i++)                                              \
  1.1641 +    {                                                                         \
  1.1642 +        for(j = 0;j < 65*numchans;j++)                                        \
  1.1643 +            tmp[j] = Conv_ALshort_##T(*(src++));                              \
  1.1644 +        EncodeIMA4Block(dst, tmp, sample, index, numchans);                   \
  1.1645 +        dst += 36*numchans;                                                   \
  1.1646 +    }                                                                         \
  1.1647 +}
  1.1648 +
  1.1649 +DECL_TEMPLATE(ALbyte)
  1.1650 +DECL_TEMPLATE(ALubyte)
  1.1651 +DECL_TEMPLATE(ALshort)
  1.1652 +DECL_TEMPLATE(ALushort)
  1.1653 +DECL_TEMPLATE(ALint)
  1.1654 +DECL_TEMPLATE(ALuint)
  1.1655 +DECL_TEMPLATE(ALfloat)
  1.1656 +DECL_TEMPLATE(ALdouble)
  1.1657 +DECL_TEMPLATE(ALmulaw)
  1.1658 +static void Convert_ALima4_ALima4(ALima4 *dst, const ALima4 *src,
  1.1659 +                                  ALuint numchans, ALuint numblocks)
  1.1660 +{ memcpy(dst, src, numblocks*36*numchans); }
  1.1661 +DECL_TEMPLATE(ALbyte3)
  1.1662 +DECL_TEMPLATE(ALubyte3)
  1.1663 +
  1.1664 +#undef DECL_TEMPLATE
  1.1665 +
  1.1666 +#define DECL_TEMPLATE(T)                                                      \
  1.1667 +static void Convert_##T(T *dst, const ALvoid *src, enum UserFmtType srcType,  \
  1.1668 +                        ALsizei numchans, ALsizei len)                        \
  1.1669 +{                                                                             \
  1.1670 +    switch(srcType)                                                           \
  1.1671 +    {                                                                         \
  1.1672 +        case UserFmtByte:                                                     \
  1.1673 +            Convert_##T##_ALbyte(dst, src, numchans, len);                    \
  1.1674 +            break;                                                            \
  1.1675 +        case UserFmtUByte:                                                    \
  1.1676 +            Convert_##T##_ALubyte(dst, src, numchans, len);                   \
  1.1677 +            break;                                                            \
  1.1678 +        case UserFmtShort:                                                    \
  1.1679 +            Convert_##T##_ALshort(dst, src, numchans, len);                   \
  1.1680 +            break;                                                            \
  1.1681 +        case UserFmtUShort:                                                   \
  1.1682 +            Convert_##T##_ALushort(dst, src, numchans, len);                  \
  1.1683 +            break;                                                            \
  1.1684 +        case UserFmtInt:                                                      \
  1.1685 +            Convert_##T##_ALint(dst, src, numchans, len);                     \
  1.1686 +            break;                                                            \
  1.1687 +        case UserFmtUInt:                                                     \
  1.1688 +            Convert_##T##_ALuint(dst, src, numchans, len);                    \
  1.1689 +            break;                                                            \
  1.1690 +        case UserFmtFloat:                                                    \
  1.1691 +            Convert_##T##_ALfloat(dst, src, numchans, len);                   \
  1.1692 +            break;                                                            \
  1.1693 +        case UserFmtDouble:                                                   \
  1.1694 +            Convert_##T##_ALdouble(dst, src, numchans, len);                  \
  1.1695 +            break;                                                            \
  1.1696 +        case UserFmtMulaw:                                                    \
  1.1697 +            Convert_##T##_ALmulaw(dst, src, numchans, len);                   \
  1.1698 +            break;                                                            \
  1.1699 +        case UserFmtIMA4:                                                     \
  1.1700 +            Convert_##T##_ALima4(dst, src, numchans, len);                    \
  1.1701 +            break;                                                            \
  1.1702 +        case UserFmtByte3:                                                    \
  1.1703 +            Convert_##T##_ALbyte3(dst, src, numchans, len);                   \
  1.1704 +            break;                                                            \
  1.1705 +        case UserFmtUByte3:                                                   \
  1.1706 +            Convert_##T##_ALubyte3(dst, src, numchans, len);                  \
  1.1707 +            break;                                                            \
  1.1708 +    }                                                                         \
  1.1709 +}
  1.1710 +
  1.1711 +DECL_TEMPLATE(ALbyte)
  1.1712 +DECL_TEMPLATE(ALubyte)
  1.1713 +DECL_TEMPLATE(ALshort)
  1.1714 +DECL_TEMPLATE(ALushort)
  1.1715 +DECL_TEMPLATE(ALint)
  1.1716 +DECL_TEMPLATE(ALuint)
  1.1717 +DECL_TEMPLATE(ALfloat)
  1.1718 +DECL_TEMPLATE(ALdouble)
  1.1719 +DECL_TEMPLATE(ALmulaw)
  1.1720 +DECL_TEMPLATE(ALima4)
  1.1721 +DECL_TEMPLATE(ALbyte3)
  1.1722 +DECL_TEMPLATE(ALubyte3)
  1.1723 +
  1.1724 +#undef DECL_TEMPLATE
  1.1725 +
  1.1726 +
  1.1727 +static void ConvertData(ALvoid *dst, enum UserFmtType dstType, const ALvoid *src, enum UserFmtType srcType, ALsizei numchans, ALsizei len)
  1.1728 +{
  1.1729 +    switch(dstType)
  1.1730 +    {
  1.1731 +        case UserFmtByte:
  1.1732 +            Convert_ALbyte(dst, src, srcType, numchans, len);
  1.1733 +            break;
  1.1734 +        case UserFmtUByte:
  1.1735 +            Convert_ALubyte(dst, src, srcType, numchans, len);
  1.1736 +            break;
  1.1737 +        case UserFmtShort:
  1.1738 +            Convert_ALshort(dst, src, srcType, numchans, len);
  1.1739 +            break;
  1.1740 +        case UserFmtUShort:
  1.1741 +            Convert_ALushort(dst, src, srcType, numchans, len);
  1.1742 +            break;
  1.1743 +        case UserFmtInt:
  1.1744 +            Convert_ALint(dst, src, srcType, numchans, len);
  1.1745 +            break;
  1.1746 +        case UserFmtUInt:
  1.1747 +            Convert_ALuint(dst, src, srcType, numchans, len);
  1.1748 +            break;
  1.1749 +        case UserFmtFloat:
  1.1750 +            Convert_ALfloat(dst, src, srcType, numchans, len);
  1.1751 +            break;
  1.1752 +        case UserFmtDouble:
  1.1753 +            Convert_ALdouble(dst, src, srcType, numchans, len);
  1.1754 +            break;
  1.1755 +        case UserFmtMulaw:
  1.1756 +            Convert_ALmulaw(dst, src, srcType, numchans, len);
  1.1757 +            break;
  1.1758 +        case UserFmtIMA4:
  1.1759 +            Convert_ALima4(dst, src, srcType, numchans, len);
  1.1760 +            break;
  1.1761 +        case UserFmtByte3:
  1.1762 +            Convert_ALbyte3(dst, src, srcType, numchans, len);
  1.1763 +            break;
  1.1764 +        case UserFmtUByte3:
  1.1765 +            Convert_ALubyte3(dst, src, srcType, numchans, len);
  1.1766 +            break;
  1.1767 +    }
  1.1768 +}
  1.1769 +
  1.1770 +
  1.1771 +/*
  1.1772 + * LoadData
  1.1773 + *
  1.1774 + * Loads the specified data into the buffer, using the specified formats.
  1.1775 + * Currently, the new format must have the same channel configuration as the
  1.1776 + * original format.
  1.1777 + */
  1.1778 +static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALboolean storesrc)
  1.1779 +{
  1.1780 +    ALuint NewChannels, NewBytes;
  1.1781 +    enum FmtChannels DstChannels;
  1.1782 +    enum FmtType DstType;
  1.1783 +    ALuint64 newsize;
  1.1784 +    ALvoid *temp;
  1.1785 +
  1.1786 +    if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE ||
  1.1787 +       (long)SrcChannels != (long)DstChannels)
  1.1788 +        return AL_INVALID_ENUM;
  1.1789 +
  1.1790 +    NewChannels = ChannelsFromFmt(DstChannels);
  1.1791 +    NewBytes = BytesFromFmt(DstType);
  1.1792 +
  1.1793 +    if(SrcType == UserFmtIMA4)
  1.1794 +    {
  1.1795 +        ALuint OrigChannels = ChannelsFromUserFmt(SrcChannels);
  1.1796 +
  1.1797 +        newsize = frames;
  1.1798 +        newsize *= 65;
  1.1799 +        newsize *= NewBytes;
  1.1800 +        newsize *= NewChannels;
  1.1801 +        if(newsize > INT_MAX)
  1.1802 +            return AL_OUT_OF_MEMORY;
  1.1803 +
  1.1804 +        temp = realloc(ALBuf->data, newsize);
  1.1805 +        if(!temp && newsize) return AL_OUT_OF_MEMORY;
  1.1806 +        ALBuf->data = temp;
  1.1807 +        ALBuf->size = newsize;
  1.1808 +
  1.1809 +        if(data != NULL)
  1.1810 +            ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames);
  1.1811 +
  1.1812 +        if(storesrc)
  1.1813 +        {
  1.1814 +            ALBuf->OriginalChannels = SrcChannels;
  1.1815 +            ALBuf->OriginalType     = SrcType;
  1.1816 +            ALBuf->OriginalSize     = frames * 36 * OrigChannels;
  1.1817 +            ALBuf->OriginalAlign    = 36 * OrigChannels;
  1.1818 +        }
  1.1819 +    }
  1.1820 +    else
  1.1821 +    {
  1.1822 +        ALuint OrigBytes = BytesFromUserFmt(SrcType);
  1.1823 +        ALuint OrigChannels = ChannelsFromUserFmt(SrcChannels);
  1.1824 +
  1.1825 +        newsize = frames;
  1.1826 +        newsize *= NewBytes;
  1.1827 +        newsize *= NewChannels;
  1.1828 +        if(newsize > INT_MAX)
  1.1829 +            return AL_OUT_OF_MEMORY;
  1.1830 +
  1.1831 +        temp = realloc(ALBuf->data, newsize);
  1.1832 +        if(!temp && newsize) return AL_OUT_OF_MEMORY;
  1.1833 +        ALBuf->data = temp;
  1.1834 +        ALBuf->size = newsize;
  1.1835 +
  1.1836 +        if(data != NULL)
  1.1837 +            ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames);
  1.1838 +
  1.1839 +        if(storesrc)
  1.1840 +        {
  1.1841 +            ALBuf->OriginalChannels = SrcChannels;
  1.1842 +            ALBuf->OriginalType     = SrcType;
  1.1843 +            ALBuf->OriginalSize     = frames * OrigBytes * OrigChannels;
  1.1844 +            ALBuf->OriginalAlign    = OrigBytes * OrigChannels;
  1.1845 +        }
  1.1846 +    }
  1.1847 +
  1.1848 +    if(!storesrc)
  1.1849 +    {
  1.1850 +        ALBuf->OriginalChannels = DstChannels;
  1.1851 +        ALBuf->OriginalType     = DstType;
  1.1852 +        ALBuf->OriginalSize     = frames * NewBytes * NewChannels;
  1.1853 +        ALBuf->OriginalAlign    = NewBytes * NewChannels;
  1.1854 +    }
  1.1855 +    ALBuf->Frequency = freq;
  1.1856 +    ALBuf->FmtChannels = DstChannels;
  1.1857 +    ALBuf->FmtType = DstType;
  1.1858 +
  1.1859 +    ALBuf->LoopStart = 0;
  1.1860 +    ALBuf->LoopEnd = newsize / NewChannels / NewBytes;
  1.1861 +
  1.1862 +    return AL_NO_ERROR;
  1.1863 +}
  1.1864 +
  1.1865 +
  1.1866 +ALuint BytesFromUserFmt(enum UserFmtType type)
  1.1867 +{
  1.1868 +    switch(type)
  1.1869 +    {
  1.1870 +    case UserFmtByte: return sizeof(ALbyte);
  1.1871 +    case UserFmtUByte: return sizeof(ALubyte);
  1.1872 +    case UserFmtShort: return sizeof(ALshort);
  1.1873 +    case UserFmtUShort: return sizeof(ALushort);
  1.1874 +    case UserFmtInt: return sizeof(ALint);
  1.1875 +    case UserFmtUInt: return sizeof(ALuint);
  1.1876 +    case UserFmtFloat: return sizeof(ALfloat);
  1.1877 +    case UserFmtDouble: return sizeof(ALdouble);
  1.1878 +    case UserFmtByte3: return sizeof(ALbyte3);
  1.1879 +    case UserFmtUByte3: return sizeof(ALubyte3);
  1.1880 +    case UserFmtMulaw: return sizeof(ALubyte);
  1.1881 +    case UserFmtIMA4: break; /* not handled here */
  1.1882 +    }
  1.1883 +    return 0;
  1.1884 +}
  1.1885 +ALuint ChannelsFromUserFmt(enum UserFmtChannels chans)
  1.1886 +{
  1.1887 +    switch(chans)
  1.1888 +    {
  1.1889 +    case UserFmtMono: return 1;
  1.1890 +    case UserFmtStereo: return 2;
  1.1891 +    case UserFmtRear: return 2;
  1.1892 +    case UserFmtQuad: return 4;
  1.1893 +    case UserFmtX51: return 6;
  1.1894 +    case UserFmtX61: return 7;
  1.1895 +    case UserFmtX71: return 8;
  1.1896 +    }
  1.1897 +    return 0;
  1.1898 +}
  1.1899 +ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans,
  1.1900 +                              enum UserFmtType *type)
  1.1901 +{
  1.1902 +    switch(format)
  1.1903 +    {
  1.1904 +        case AL_FORMAT_MONO8:
  1.1905 +            *chans = UserFmtMono;
  1.1906 +            *type  = UserFmtUByte;
  1.1907 +            return AL_TRUE;
  1.1908 +        case AL_FORMAT_MONO16:
  1.1909 +            *chans = UserFmtMono;
  1.1910 +            *type  = UserFmtShort;
  1.1911 +            return AL_TRUE;
  1.1912 +        case AL_FORMAT_MONO_FLOAT32:
  1.1913 +            *chans = UserFmtMono;
  1.1914 +            *type  = UserFmtFloat;
  1.1915 +            return AL_TRUE;
  1.1916 +        case AL_FORMAT_MONO_DOUBLE_EXT:
  1.1917 +            *chans = UserFmtMono;
  1.1918 +            *type  = UserFmtDouble;
  1.1919 +            return AL_TRUE;
  1.1920 +        case AL_FORMAT_MONO_IMA4:
  1.1921 +            *chans = UserFmtMono;
  1.1922 +            *type  = UserFmtIMA4;
  1.1923 +            return AL_TRUE;
  1.1924 +        case AL_FORMAT_STEREO8:
  1.1925 +            *chans = UserFmtStereo;
  1.1926 +            *type  = UserFmtUByte;
  1.1927 +            return AL_TRUE;
  1.1928 +        case AL_FORMAT_STEREO16:
  1.1929 +            *chans = UserFmtStereo;
  1.1930 +            *type  = UserFmtShort;
  1.1931 +            return AL_TRUE;
  1.1932 +        case AL_FORMAT_STEREO_FLOAT32:
  1.1933 +            *chans = UserFmtStereo;
  1.1934 +            *type  = UserFmtFloat;
  1.1935 +            return AL_TRUE;
  1.1936 +        case AL_FORMAT_STEREO_DOUBLE_EXT:
  1.1937 +            *chans = UserFmtStereo;
  1.1938 +            *type  = UserFmtDouble;
  1.1939 +            return AL_TRUE;
  1.1940 +        case AL_FORMAT_STEREO_IMA4:
  1.1941 +            *chans = UserFmtStereo;
  1.1942 +            *type  = UserFmtIMA4;
  1.1943 +            return AL_TRUE;
  1.1944 +        case AL_FORMAT_QUAD8_LOKI:
  1.1945 +        case AL_FORMAT_QUAD8:
  1.1946 +            *chans = UserFmtQuad;
  1.1947 +            *type  = UserFmtUByte;
  1.1948 +            return AL_TRUE;
  1.1949 +        case AL_FORMAT_QUAD16_LOKI:
  1.1950 +        case AL_FORMAT_QUAD16:
  1.1951 +            *chans = UserFmtQuad;
  1.1952 +            *type  = UserFmtShort;
  1.1953 +            return AL_TRUE;
  1.1954 +        case AL_FORMAT_QUAD32:
  1.1955 +            *chans = UserFmtQuad;
  1.1956 +            *type  = UserFmtFloat;
  1.1957 +            return AL_TRUE;
  1.1958 +        case AL_FORMAT_REAR8:
  1.1959 +            *chans = UserFmtRear;
  1.1960 +            *type  = UserFmtUByte;
  1.1961 +            return AL_TRUE;
  1.1962 +        case AL_FORMAT_REAR16:
  1.1963 +            *chans = UserFmtRear;
  1.1964 +            *type  = UserFmtShort;
  1.1965 +            return AL_TRUE;
  1.1966 +        case AL_FORMAT_REAR32:
  1.1967 +            *chans = UserFmtRear;
  1.1968 +            *type  = UserFmtFloat;
  1.1969 +            return AL_TRUE;
  1.1970 +        case AL_FORMAT_51CHN8:
  1.1971 +            *chans = UserFmtX51;
  1.1972 +            *type  = UserFmtUByte;
  1.1973 +            return AL_TRUE;
  1.1974 +        case AL_FORMAT_51CHN16:
  1.1975 +            *chans = UserFmtX51;
  1.1976 +            *type  = UserFmtShort;
  1.1977 +            return AL_TRUE;
  1.1978 +        case AL_FORMAT_51CHN32:
  1.1979 +            *chans = UserFmtX51;
  1.1980 +            *type  = UserFmtFloat;
  1.1981 +            return AL_TRUE;
  1.1982 +        case AL_FORMAT_61CHN8:
  1.1983 +            *chans = UserFmtX61;
  1.1984 +            *type  = UserFmtUByte;
  1.1985 +            return AL_TRUE;
  1.1986 +        case AL_FORMAT_61CHN16:
  1.1987 +            *chans = UserFmtX61;
  1.1988 +            *type  = UserFmtShort;
  1.1989 +            return AL_TRUE;
  1.1990 +        case AL_FORMAT_61CHN32:
  1.1991 +            *chans = UserFmtX61;
  1.1992 +            *type  = UserFmtFloat;
  1.1993 +            return AL_TRUE;
  1.1994 +        case AL_FORMAT_71CHN8:
  1.1995 +            *chans = UserFmtX71;
  1.1996 +            *type  = UserFmtUByte;
  1.1997 +            return AL_TRUE;
  1.1998 +        case AL_FORMAT_71CHN16:
  1.1999 +            *chans = UserFmtX71;
  1.2000 +            *type  = UserFmtShort;
  1.2001 +            return AL_TRUE;
  1.2002 +        case AL_FORMAT_71CHN32:
  1.2003 +            *chans = UserFmtX71;
  1.2004 +            *type  = UserFmtFloat;
  1.2005 +            return AL_TRUE;
  1.2006 +        case AL_FORMAT_MONO_MULAW:
  1.2007 +            *chans = UserFmtMono;
  1.2008 +            *type  = UserFmtMulaw;
  1.2009 +            return AL_TRUE;
  1.2010 +        case AL_FORMAT_STEREO_MULAW:
  1.2011 +            *chans = UserFmtStereo;
  1.2012 +            *type  = UserFmtMulaw;
  1.2013 +            return AL_TRUE;
  1.2014 +        case AL_FORMAT_QUAD_MULAW:
  1.2015 +            *chans = UserFmtQuad;
  1.2016 +            *type  = UserFmtMulaw;
  1.2017 +            return AL_TRUE;
  1.2018 +        case AL_FORMAT_REAR_MULAW:
  1.2019 +            *chans = UserFmtRear;
  1.2020 +            *type  = UserFmtMulaw;
  1.2021 +            return AL_TRUE;
  1.2022 +        case AL_FORMAT_51CHN_MULAW:
  1.2023 +            *chans = UserFmtX51;
  1.2024 +            *type  = UserFmtMulaw;
  1.2025 +            return AL_TRUE;
  1.2026 +        case AL_FORMAT_61CHN_MULAW:
  1.2027 +            *chans = UserFmtX61;
  1.2028 +            *type  = UserFmtMulaw;
  1.2029 +            return AL_TRUE;
  1.2030 +        case AL_FORMAT_71CHN_MULAW:
  1.2031 +            *chans = UserFmtX71;
  1.2032 +            *type  = UserFmtMulaw;
  1.2033 +            return AL_TRUE;
  1.2034 +    }
  1.2035 +    return AL_FALSE;
  1.2036 +}
  1.2037 +
  1.2038 +ALuint BytesFromFmt(enum FmtType type)
  1.2039 +{
  1.2040 +    switch(type)
  1.2041 +    {
  1.2042 +    case FmtByte: return sizeof(ALbyte);
  1.2043 +    case FmtShort: return sizeof(ALshort);
  1.2044 +    case FmtFloat: return sizeof(ALfloat);
  1.2045 +    }
  1.2046 +    return 0;
  1.2047 +}
  1.2048 +ALuint ChannelsFromFmt(enum FmtChannels chans)
  1.2049 +{
  1.2050 +    switch(chans)
  1.2051 +    {
  1.2052 +    case FmtMono: return 1;
  1.2053 +    case FmtStereo: return 2;
  1.2054 +    case FmtRear: return 2;
  1.2055 +    case FmtQuad: return 4;
  1.2056 +    case FmtX51: return 6;
  1.2057 +    case FmtX61: return 7;
  1.2058 +    case FmtX71: return 8;
  1.2059 +    }
  1.2060 +    return 0;
  1.2061 +}
  1.2062 +ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type)
  1.2063 +{
  1.2064 +    switch(format)
  1.2065 +    {
  1.2066 +        case AL_MONO8:
  1.2067 +            *chans = FmtMono;
  1.2068 +            *type  = FmtByte;
  1.2069 +            return AL_TRUE;
  1.2070 +        case AL_MONO16:
  1.2071 +            *chans = FmtMono;
  1.2072 +            *type  = FmtShort;
  1.2073 +            return AL_TRUE;
  1.2074 +        case AL_MONO32F:
  1.2075 +            *chans = FmtMono;
  1.2076 +            *type  = FmtFloat;
  1.2077 +            return AL_TRUE;
  1.2078 +        case AL_STEREO8:
  1.2079 +            *chans = FmtStereo;
  1.2080 +            *type  = FmtByte;
  1.2081 +            return AL_TRUE;
  1.2082 +        case AL_STEREO16:
  1.2083 +            *chans = FmtStereo;
  1.2084 +            *type  = FmtShort;
  1.2085 +            return AL_TRUE;
  1.2086 +        case AL_STEREO32F:
  1.2087 +            *chans = FmtStereo;
  1.2088 +            *type  = FmtFloat;
  1.2089 +            return AL_TRUE;
  1.2090 +        case AL_FORMAT_QUAD8_LOKI:
  1.2091 +        case AL_QUAD8:
  1.2092 +            *chans = FmtQuad;
  1.2093 +            *type  = FmtByte;
  1.2094 +            return AL_TRUE;
  1.2095 +        case AL_FORMAT_QUAD16_LOKI:
  1.2096 +        case AL_QUAD16:
  1.2097 +            *chans = FmtQuad;
  1.2098 +            *type  = FmtShort;
  1.2099 +            return AL_TRUE;
  1.2100 +        case AL_QUAD32F:
  1.2101 +            *chans = FmtQuad;
  1.2102 +            *type  = FmtFloat;
  1.2103 +            return AL_TRUE;
  1.2104 +        case AL_REAR8:
  1.2105 +            *chans = FmtRear;
  1.2106 +            *type  = FmtByte;
  1.2107 +            return AL_TRUE;
  1.2108 +        case AL_REAR16:
  1.2109 +            *chans = FmtRear;
  1.2110 +            *type  = FmtShort;
  1.2111 +            return AL_TRUE;
  1.2112 +        case AL_REAR32F:
  1.2113 +            *chans = FmtRear;
  1.2114 +            *type  = FmtFloat;
  1.2115 +            return AL_TRUE;
  1.2116 +        case AL_5POINT1_8:
  1.2117 +            *chans = FmtX51;
  1.2118 +            *type  = FmtByte;
  1.2119 +            return AL_TRUE;
  1.2120 +        case AL_5POINT1_16:
  1.2121 +            *chans = FmtX51;
  1.2122 +            *type  = FmtShort;
  1.2123 +            return AL_TRUE;
  1.2124 +        case AL_5POINT1_32F:
  1.2125 +            *chans = FmtX51;
  1.2126 +            *type  = FmtFloat;
  1.2127 +            return AL_TRUE;
  1.2128 +        case AL_6POINT1_8:
  1.2129 +            *chans = FmtX61;
  1.2130 +            *type  = FmtByte;
  1.2131 +            return AL_TRUE;
  1.2132 +        case AL_6POINT1_16:
  1.2133 +            *chans = FmtX61;
  1.2134 +            *type  = FmtShort;
  1.2135 +            return AL_TRUE;
  1.2136 +        case AL_6POINT1_32F:
  1.2137 +            *chans = FmtX61;
  1.2138 +            *type  = FmtFloat;
  1.2139 +            return AL_TRUE;
  1.2140 +        case AL_7POINT1_8:
  1.2141 +            *chans = FmtX71;
  1.2142 +            *type  = FmtByte;
  1.2143 +            return AL_TRUE;
  1.2144 +        case AL_7POINT1_16:
  1.2145 +            *chans = FmtX71;
  1.2146 +            *type  = FmtShort;
  1.2147 +            return AL_TRUE;
  1.2148 +        case AL_7POINT1_32F:
  1.2149 +            *chans = FmtX71;
  1.2150 +            *type  = FmtFloat;
  1.2151 +            return AL_TRUE;
  1.2152 +    }
  1.2153 +    return AL_FALSE;
  1.2154 +}
  1.2155 +
  1.2156 +
  1.2157 +static ALboolean IsValidType(ALenum type)
  1.2158 +{
  1.2159 +    switch(type)
  1.2160 +    {
  1.2161 +        case AL_BYTE:
  1.2162 +        case AL_UNSIGNED_BYTE:
  1.2163 +        case AL_SHORT:
  1.2164 +        case AL_UNSIGNED_SHORT:
  1.2165 +        case AL_INT:
  1.2166 +        case AL_UNSIGNED_INT:
  1.2167 +        case AL_FLOAT:
  1.2168 +        case AL_DOUBLE:
  1.2169 +        case AL_MULAW:
  1.2170 +        case AL_IMA4:
  1.2171 +        case AL_BYTE3:
  1.2172 +        case AL_UNSIGNED_BYTE3:
  1.2173 +            return AL_TRUE;
  1.2174 +    }
  1.2175 +    return AL_FALSE;
  1.2176 +}
  1.2177 +
  1.2178 +static ALboolean IsValidChannels(ALenum channels)
  1.2179 +{
  1.2180 +    switch(channels)
  1.2181 +    {
  1.2182 +        case AL_MONO:
  1.2183 +        case AL_STEREO:
  1.2184 +        case AL_REAR:
  1.2185 +        case AL_QUAD:
  1.2186 +        case AL_5POINT1:
  1.2187 +        case AL_6POINT1:
  1.2188 +        case AL_7POINT1:
  1.2189 +            return AL_TRUE;
  1.2190 +    }
  1.2191 +    return AL_FALSE;
  1.2192 +}
  1.2193 +
  1.2194 +
  1.2195 +/*
  1.2196 + *    ReleaseALBuffers()
  1.2197 + *
  1.2198 + *    INTERNAL: Called to destroy any buffers that still exist on the device
  1.2199 + */
  1.2200 +ALvoid ReleaseALBuffers(ALCdevice *device)
  1.2201 +{
  1.2202 +    ALsizei i;
  1.2203 +    for(i = 0;i < device->BufferMap.size;i++)
  1.2204 +    {
  1.2205 +        ALbuffer *temp = device->BufferMap.array[i].value;
  1.2206 +        device->BufferMap.array[i].value = NULL;
  1.2207 +
  1.2208 +        free(temp->data);
  1.2209 +
  1.2210 +        FreeThunkEntry(temp->buffer);
  1.2211 +        memset(temp, 0, sizeof(ALbuffer));
  1.2212 +        free(temp);
  1.2213 +    }
  1.2214 +}