Ejemplo n.º 1
0
/*
*    alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
*
*    Fill buffer with audio data
*/
ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
{
    ALCcontext *Context;
    ALbuffer *ALBuf;

    Context = alcGetCurrentContext();
    SuspendContext(Context);

    if(alIsBuffer(buffer) && buffer != 0)
    {
        ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
        if(ALBuf->data == NULL)
        {
            // buffer does not have any data
            alSetError(AL_INVALID_NAME);
        }
        else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
        {
            // data is NULL or offset/length is negative
            alSetError(AL_INVALID_VALUE);
        }
        else
        {
            switch(format)
            {
                case AL_FORMAT_REAR8:
                case AL_FORMAT_REAR16:
                case AL_FORMAT_REAR32: {
                    ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
                                        ((format==AL_FORMAT_REAR16) ? 2 :
                                         4));

                    if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
                       ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
                       ALBuf->eOriginalFormat != AL_FORMAT_REAR32)
                    {
                        alSetError(AL_INVALID_ENUM);
                        break;
                    }

                    if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
                    {
                        alSetError(AL_INVALID_VALUE);
                        break;
                    }

                    ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2);
                }   break;

                case AL_FORMAT_MONO_IMA4:
                case AL_FORMAT_STEREO_IMA4: {
                    int Channels = aluChannelsFromFormat(ALBuf->format);

                    if(ALBuf->eOriginalFormat != format)
                    {
                        alSetError(AL_INVALID_ENUM);
                        break;
                    }

                    if((offset%65) != 0 || (length%65) != 0 ||
                       ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
                    {
                        alSetError(AL_INVALID_VALUE);
                        break;
                    }

                    ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels);
                }   break;

                default: {
                    ALuint Channels = aluChannelsFromFormat(format);
                    ALuint Bytes = aluBytesFromFormat(format);

                    if(Channels != aluChannelsFromFormat(ALBuf->format))
                    {
                        alSetError(AL_INVALID_ENUM);
                        break;
                    }

                    if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
                    {
                        alSetError(AL_INVALID_VALUE);
                        break;
                    }

                    ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels);
                }   break;
            }
        }
    }
    else
    {
        // Invalid Buffer Name
        alSetError(AL_INVALID_NAME);
    }

    ProcessContext(Context);
}
Ejemplo n.º 2
0
/*
*    alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
*
*    Fill buffer with audio data
*/
AL_API ALvoid AL_APIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
{
    ALCcontext *Context;
    ALCdevice  *device;
    ALbuffer   *ALBuf;

    Context = GetContextSuspended();
    if(!Context) return;

    device = Context->Device;
    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
        alSetError(Context, AL_INVALID_NAME);
    else
    {
        if(Context->SampleSource)
        {
            ALintptrEXT offset;

            if(Context->SampleSource->state == MAPPED)
            {
                alSetError(Context, AL_INVALID_OPERATION);
                ProcessContext(Context);
                return;
            }

            offset = (const ALubyte*)data - (ALubyte*)NULL;
            data = Context->SampleSource->data + offset;
        }

        if(length < 0 || offset < 0 || (length > 0 && data == NULL))
            alSetError(Context, AL_INVALID_VALUE);
        else if(ALBuf->eOriginalFormat != format)
            alSetError(Context, AL_INVALID_ENUM);
        else if(offset+length < offset ||
                offset+length > ALBuf->OriginalSize ||
                (offset%ALBuf->OriginalAlign) != 0 ||
                (length%ALBuf->OriginalAlign) != 0)
            alSetError(Context, AL_INVALID_VALUE);
        else
        {
            switch(format)
            {
                case AL_FORMAT_MONO8:
                case AL_FORMAT_MONO16:
                case AL_FORMAT_MONO_FLOAT32:
                case AL_FORMAT_MONO_DOUBLE_EXT:
                case AL_FORMAT_STEREO8:
                case AL_FORMAT_STEREO16:
                case AL_FORMAT_STEREO_FLOAT32:
                case AL_FORMAT_STEREO_DOUBLE_EXT:
                case AL_FORMAT_QUAD8_LOKI:
                case AL_FORMAT_QUAD16_LOKI:
                case AL_FORMAT_QUAD8:
                case AL_FORMAT_QUAD16:
                case AL_FORMAT_QUAD32:
                case AL_FORMAT_51CHN8:
                case AL_FORMAT_51CHN16:
                case AL_FORMAT_51CHN32:
                case AL_FORMAT_61CHN8:
                case AL_FORMAT_61CHN16:
                case AL_FORMAT_61CHN32:
                case AL_FORMAT_71CHN8:
                case AL_FORMAT_71CHN16:
                case AL_FORMAT_71CHN32: {
                    ALuint Bytes = aluBytesFromFormat(format);

                    offset /= Bytes;
                    length /= Bytes;

                    ConvertData(&ALBuf->data[offset], data, Bytes, length);
                }   break;

                case AL_FORMAT_REAR8:
                case AL_FORMAT_REAR16:
                case AL_FORMAT_REAR32: {
                    ALuint Bytes = ((format==AL_FORMAT_REAR8) ? 1 :
                                    ((format==AL_FORMAT_REAR16) ? 2 :
                                     4));

                    offset /= Bytes;
                    offset *= 2;
                    length /= Bytes;
                    length *= 2;

                    ConvertDataRear(&ALBuf->data[offset], data, Bytes, length);
                }   break;

                case AL_FORMAT_MONO_IMA4:
                case AL_FORMAT_STEREO_IMA4: {
                    int Channels = aluChannelsFromFormat(ALBuf->format);

                    // offset -> sample*channel offset, length -> block count
                    offset /= 36;
                    offset *= 65;
                    length /= ALBuf->OriginalAlign;

                    ConvertDataIMA4(&ALBuf->data[offset], data, Channels, length);
                }   break;

                case AL_FORMAT_MONO_MULAW:
                case AL_FORMAT_STEREO_MULAW:
                case AL_FORMAT_QUAD_MULAW:
                case AL_FORMAT_51CHN_MULAW:
                case AL_FORMAT_61CHN_MULAW:
                case AL_FORMAT_71CHN_MULAW:
                    ConvertDataMULaw(&ALBuf->data[offset], data, length);
                    break;

                case AL_FORMAT_REAR_MULAW:
                    offset *= 2;
                    length *= 2;
                    ConvertDataMULawRear(&ALBuf->data[offset], data, length);
                    break;

                default:
                    alSetError(Context, AL_INVALID_ENUM);
                    break;
            }
        }
    }

    ProcessContext(Context);
}
Ejemplo n.º 3
0
/*
*    alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
*
*    Fill buffer with audio data
*/
ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
{
    ALCcontext *Context;
    ALsizei padding = 2;
    ALbuffer *ALBuf;
    ALvoid *temp;

    Context = alcGetCurrentContext();
    SuspendContext(Context);

    if (alIsBuffer(buffer) && (buffer != 0))
    {
        ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
        if ((ALBuf->refcount==0)&&(data))
        {
            switch(format)
            {
                case AL_FORMAT_MONO8:
                case AL_FORMAT_MONO16:
                case AL_FORMAT_MONO_FLOAT32:
                    LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
                    break;

                case AL_FORMAT_STEREO8:
                case AL_FORMAT_STEREO16:
                case AL_FORMAT_STEREO_FLOAT32:
                    LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
                    break;

                case AL_FORMAT_REAR8:
                case AL_FORMAT_REAR16:
                case AL_FORMAT_REAR32: {
                    ALuint NewFormat = AL_FORMAT_QUAD16;
                    ALuint NewChannels = aluChannelsFromFormat(NewFormat);
                    ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
                                        ((format==AL_FORMAT_REAR16) ? 2 :
                                         4));

                    assert(aluBytesFromFormat(NewFormat) == 2);

                    if((size%(OrigBytes*2)) != 0)
                    {
                        alSetError(AL_INVALID_VALUE);
                        break;
                    }

                    size /= OrigBytes;
                    size *= 2;

                    // Samples are converted to 16 bit here
                    temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
                    if(temp)
                    {
                        ALBuf->data = temp;
                        ConvertDataRear(ALBuf->data, data, OrigBytes, size);

                        memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));

                        ALBuf->format = NewFormat;
                        ALBuf->eOriginalFormat = format;
                        ALBuf->size = size*sizeof(ALshort);
                        ALBuf->frequency = freq;
                        ALBuf->padding = padding;
                    }
                    else
                        alSetError(AL_OUT_OF_MEMORY);
                }   break;

                case AL_FORMAT_QUAD8_LOKI:
                case AL_FORMAT_QUAD16_LOKI:
                case AL_FORMAT_QUAD8:
                case AL_FORMAT_QUAD16:
                case AL_FORMAT_QUAD32:
                    LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
                    break;

                case AL_FORMAT_51CHN8:
                case AL_FORMAT_51CHN16:
                case AL_FORMAT_51CHN32:
                    LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
                    break;

                case AL_FORMAT_61CHN8:
                case AL_FORMAT_61CHN16:
                case AL_FORMAT_61CHN32:
                    LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
                    break;

                case AL_FORMAT_71CHN8:
                case AL_FORMAT_71CHN16:
                case AL_FORMAT_71CHN32:
                    LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
                    break;

                case AL_FORMAT_MONO_IMA4:
                case AL_FORMAT_STEREO_IMA4: {
                    int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);

                    // Here is where things vary:
                    // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
                    // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
                    if((size%(36*OrigChans)) != 0)
                    {
                        alSetError(AL_INVALID_VALUE);
                        break;
                    }

                    size /= 36;
                    size *= 65;

                    // Allocate extra padding samples
                    temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort));
                    if(temp)
                    {
                        ALBuf->data = temp;
                        ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);

                        memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans);

                        ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
                        ALBuf->eOriginalFormat = format;
                        ALBuf->size = size*sizeof(ALshort);
                        ALBuf->frequency = freq;
                        ALBuf->padding = padding;
                    }
                    else
                        alSetError(AL_OUT_OF_MEMORY);
                }   break;

                default:
                    alSetError(AL_INVALID_ENUM);
                    break;
            }
        }
        else
        {
            // Buffer is in use, or data is a NULL pointer
            alSetError(AL_INVALID_VALUE);
        }
    }
    else
    {
        // Invalid Buffer Name
        alSetError(AL_INVALID_NAME);
    }

    ProcessContext(Context);
}
Ejemplo n.º 4
0
/*
*    alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
*
*    Fill buffer with audio data
*/
AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
{
    ALCcontext *Context;
    ALCdevice *device;
    ALbuffer *ALBuf;
    ALvoid *temp;
    ALenum err;

    Context = GetContextSuspended();
    if(!Context) return;

    device = Context->Device;
    if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
        alSetError(Context, AL_INVALID_NAME); /* Invalid Buffer Name */
    else
    {
        if(Context->SampleSource)
        {
            ALintptrEXT offset;

            if(Context->SampleSource->state == MAPPED)
            {
                alSetError(Context, AL_INVALID_OPERATION);
                ProcessContext(Context);
                return;
            }

            offset = (const ALubyte*)data - (ALubyte*)NULL;
            data = Context->SampleSource->data + offset;
        }

        if(size < 0)
            alSetError(Context, AL_INVALID_VALUE);
        else if(ALBuf->refcount != 0)
            alSetError(Context, AL_INVALID_VALUE);
        else
        {
            switch(format)
            {
                case AL_FORMAT_MONO8:
                case AL_FORMAT_MONO16:
                case AL_FORMAT_MONO_FLOAT32:
                case AL_FORMAT_MONO_DOUBLE_EXT:
                    err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32);
                    if(err != AL_NO_ERROR)
                        alSetError(Context, err);
                    break;

                case AL_FORMAT_STEREO8:
                case AL_FORMAT_STEREO16:
                case AL_FORMAT_STEREO_FLOAT32:
                case AL_FORMAT_STEREO_DOUBLE_EXT:
                    err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32);
                    if(err != AL_NO_ERROR)
                        alSetError(Context, err);
                    break;

                case AL_FORMAT_REAR8:
                case AL_FORMAT_REAR16:
                case AL_FORMAT_REAR32: {
                    ALenum NewFormat = AL_FORMAT_QUAD32;
                    ALuint NewChannels = aluChannelsFromFormat(NewFormat);
                    ALuint NewBytes = aluBytesFromFormat(NewFormat);
                    ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
                                        ((format==AL_FORMAT_REAR16) ? 2 :
                                         4));
                    ALuint64 newsize, allocsize;

                    if((size%(OrigBytes*2)) != 0)
                    {
                        alSetError(Context, AL_INVALID_VALUE);
                        break;
                    }

                    newsize = size / OrigBytes;
                    newsize *= 2;

                    allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
                    if(allocsize > INT_MAX)
                    {
                        alSetError(Context, AL_OUT_OF_MEMORY);
                        break;
                    }
                    temp = realloc(ALBuf->data, allocsize);
                    if(temp)
                    {
                        ALBuf->data = temp;
                        ConvertDataRear(ALBuf->data, data, OrigBytes, newsize);

                        ALBuf->format = NewFormat;
                        ALBuf->eOriginalFormat = format;
                        ALBuf->size = newsize*NewBytes;
                        ALBuf->frequency = freq;

                        ALBuf->LoopStart = 0;
                        ALBuf->LoopEnd = newsize / NewChannels;

                        ALBuf->OriginalSize = size;
                        ALBuf->OriginalAlign = OrigBytes * 2;
                    }
                    else
                        alSetError(Context, AL_OUT_OF_MEMORY);
                }   break;

                case AL_FORMAT_QUAD8_LOKI:
                case AL_FORMAT_QUAD16_LOKI:
                case AL_FORMAT_QUAD8:
                case AL_FORMAT_QUAD16:
                case AL_FORMAT_QUAD32:
                    err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32);
                    if(err != AL_NO_ERROR)
                        alSetError(Context, err);
                    break;

                case AL_FORMAT_51CHN8:
                case AL_FORMAT_51CHN16:
                case AL_FORMAT_51CHN32:
                    err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32);
                    if(err != AL_NO_ERROR)
                        alSetError(Context, err);
                    break;

                case AL_FORMAT_61CHN8:
                case AL_FORMAT_61CHN16:
                case AL_FORMAT_61CHN32:
                    err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32);
                    if(err != AL_NO_ERROR)
                        alSetError(Context, err);
                    break;

                case AL_FORMAT_71CHN8:
                case AL_FORMAT_71CHN16:
                case AL_FORMAT_71CHN32:
                    err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32);
                    if(err != AL_NO_ERROR)
                        alSetError(Context, err);
                    break;

                case AL_FORMAT_MONO_IMA4:
                case AL_FORMAT_STEREO_IMA4: {
                    int Channels = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
                    ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 :
                                                        AL_FORMAT_STEREO_FLOAT32);
                    ALuint NewBytes = aluBytesFromFormat(NewFormat);
                    ALuint64 newsize, allocsize;

                    // Here is where things vary:
                    // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
                    // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
                    if((size%(36*Channels)) != 0)
                    {
                        alSetError(Context, AL_INVALID_VALUE);
                        break;
                    }

                    newsize = size / 36;
                    newsize *= 65;

                    allocsize = (BUFFER_PADDING*Channels + newsize)*NewBytes;
                    if(allocsize > INT_MAX)
                    {
                        alSetError(Context, AL_OUT_OF_MEMORY);
                        break;
                    }
                    temp = realloc(ALBuf->data, allocsize);
                    if(temp)
                    {
                        ALBuf->data = temp;
                        ConvertDataIMA4(ALBuf->data, data, Channels, newsize/(65*Channels));

                        ALBuf->format = NewFormat;
                        ALBuf->eOriginalFormat = format;
                        ALBuf->size = newsize*NewBytes;
                        ALBuf->frequency = freq;

                        ALBuf->LoopStart = 0;
                        ALBuf->LoopEnd = newsize / Channels;

                        ALBuf->OriginalSize = size;
                        ALBuf->OriginalAlign = 36 * Channels;
                    }
                    else
                        alSetError(Context, AL_OUT_OF_MEMORY);
                }   break;

                case AL_FORMAT_MONO_MULAW:
                case AL_FORMAT_STEREO_MULAW:
                case AL_FORMAT_QUAD_MULAW:
                case AL_FORMAT_51CHN_MULAW:
                case AL_FORMAT_61CHN_MULAW:
                case AL_FORMAT_71CHN_MULAW: {
                    int Channels = ((format==AL_FORMAT_MONO_MULAW) ? 1 :
                                    ((format==AL_FORMAT_STEREO_MULAW) ? 2 :
                                     ((format==AL_FORMAT_QUAD_MULAW) ? 4 :
                                      ((format==AL_FORMAT_51CHN_MULAW) ? 6 :
                                       ((format==AL_FORMAT_61CHN_MULAW) ? 7 : 8)))));
                    ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 :
                                        ((Channels==2) ? AL_FORMAT_STEREO_FLOAT32 :
                                         ((Channels==4) ? AL_FORMAT_QUAD32 :
                                          ((Channels==6) ? AL_FORMAT_51CHN32 :
                                           ((Channels==7) ? AL_FORMAT_61CHN32 :
                                                            AL_FORMAT_71CHN32)))));
                    ALuint NewBytes = aluBytesFromFormat(NewFormat);
                    ALuint64 allocsize;

                    if((size%(1*Channels)) != 0)
                    {
                        alSetError(Context, AL_INVALID_VALUE);
                        break;
                    }

                    allocsize = (BUFFER_PADDING*Channels + size)*NewBytes;
                    if(allocsize > INT_MAX)
                    {
                        alSetError(Context, AL_OUT_OF_MEMORY);
                        break;
                    }
                    temp = realloc(ALBuf->data, allocsize);
                    if(temp)
                    {
                        ALBuf->data = temp;
                        ConvertDataMULaw(ALBuf->data, data, size);

                        ALBuf->format = NewFormat;
                        ALBuf->eOriginalFormat = format;
                        ALBuf->size = size*NewBytes;
                        ALBuf->frequency = freq;

                        ALBuf->LoopStart = 0;
                        ALBuf->LoopEnd = size / Channels;

                        ALBuf->OriginalSize = size;
                        ALBuf->OriginalAlign = 1 * Channels;
                    }
                    else
                        alSetError(Context, AL_OUT_OF_MEMORY);
                }   break;

                case AL_FORMAT_REAR_MULAW: {
                    ALenum NewFormat = AL_FORMAT_QUAD32;
                    ALuint NewChannels = aluChannelsFromFormat(NewFormat);
                    ALuint NewBytes = aluBytesFromFormat(NewFormat);
                    ALuint64 newsize, allocsize;

                    if((size%(1*2)) != 0)
                    {
                        alSetError(Context, AL_INVALID_VALUE);
                        break;
                    }

                    newsize = size * 2;

                    allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
                    if(allocsize > INT_MAX)
                    {
                        alSetError(Context, AL_OUT_OF_MEMORY);
                        break;
                    }
                    temp = realloc(ALBuf->data, allocsize);
                    if(temp)
                    {
                        ALBuf->data = temp;
                        ConvertDataMULawRear(ALBuf->data, data, newsize);

                        ALBuf->format = NewFormat;
                        ALBuf->eOriginalFormat = format;
                        ALBuf->size = newsize*NewBytes;
                        ALBuf->frequency = freq;

                        ALBuf->LoopStart = 0;
                        ALBuf->LoopEnd = newsize / NewChannels;

                        ALBuf->OriginalSize = size;
                        ALBuf->OriginalAlign = 1 * 2;
                    }
                    else
                        alSetError(Context, AL_OUT_OF_MEMORY);
                }   break;

                default:
                    alSetError(Context, AL_INVALID_ENUM);
                    break;
            }
        }
    }

    ProcessContext(Context);
}