AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) { ALCdevice *device; ALCcontext *context; ALbuffer *albuf; ALsizei align; context = GetContextRef(); if(!context) return; device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(samples >= 0 && offset >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if(IsValidType(type) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); WriteLock(&albuf->lock); align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } if(channels != (ALenum)albuf->FmtChannels) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } if((samples%align) != 0) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } /* offset -> byte offset */ offset *= FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, data, type, ChannelsFromFmt(albuf->FmtChannels), samples, align); WriteUnlock(&albuf->lock); done: UnlockBuffersRead(device); ALCcontext_DecRef(context); }
AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values) { ALCdevice *device; ALCcontext *context; ALbuffer *albuf; if(values) { switch(param) { case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: case AL_PACK_BLOCK_ALIGNMENT_SOFT: alBufferi(buffer, param, values[0]); return; } } context = GetContextRef(); if(!context) return; device = context->Device; if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { case AL_LOOP_POINTS_SOFT: WriteLock(&albuf->lock); if(ReadRef(&albuf->ref) != 0) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } if(values[0] >= values[1] || values[0] < 0 || values[1] > albuf->SampleLen) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } albuf->LoopStart = values[0]; albuf->LoopEnd = values[1]; WriteUnlock(&albuf->lock); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: ALCcontext_DecRef(context); }
AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) { ALCdevice *device; ALCcontext *context; ALbuffer *ALBuf; ALsizei i; context = GetContextRef(); if(!context) return; device = context->Device; LockBuffersWrite(device); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) { if(!buffers[i]) continue; /* Check for valid Buffer ID */ if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(ReadRef(&ALBuf->ref) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } for(i = 0;i < n;i++) { if((ALBuf=LookupBuffer(device, buffers[i])) != NULL) DeleteBuffer(device, ALBuf); } done: UnlockBuffersWrite(device); ALCcontext_DecRef(context); }
AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer) { ALCcontext *context; ALboolean ret; context = GetContextRef(); if(!context) return AL_FALSE; ret = ((!buffer || LookupBuffer(context->Device, buffer)) ? AL_TRUE : AL_FALSE); ALCcontext_DecRef(context); return ret; }
/* * alIsBuffer(ALuint uiBuffer) * * Checks if ulBuffer is a valid Buffer Name */ AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer) { ALCcontext *Context; ALboolean result; Context = GetContextSuspended(); if(!Context) return AL_FALSE; result = ((!buffer || LookupBuffer(Context->Device->BufferMap, buffer)) ? AL_TRUE : AL_FALSE); ProcessContext(Context); return result; }
AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values) { ALCdevice *device; ALCcontext *context; ALbuffer *albuf; switch(param) { case AL_FREQUENCY: case AL_BITS: case AL_CHANNELS: case AL_SIZE: case AL_INTERNAL_FORMAT_SOFT: case AL_BYTE_LENGTH_SOFT: case AL_SAMPLE_LENGTH_SOFT: case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: case AL_PACK_BLOCK_ALIGNMENT_SOFT: alGetBufferi(buffer, param, values); return; } context = GetContextRef(); if(!context) return; device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { case AL_LOOP_POINTS_SOFT: ReadLock(&albuf->lock); values[0] = albuf->LoopStart; values[1] = albuf->LoopEnd; ReadUnlock(&albuf->lock); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: UnlockBuffersRead(device); ALCcontext_DecRef(context); }
AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues) { ALCcontext *pContext; ALCdevice *device; ALbuffer *ALBuf; pContext = GetContextSuspended(); if(!pContext) return; device = pContext->Device; if(!plValues) alSetError(pContext, AL_INVALID_VALUE); else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL) alSetError(pContext, AL_INVALID_NAME); else { switch(eParam) { case AL_LOOP_POINTS: if(ALBuf->refcount > 0) alSetError(pContext, AL_INVALID_OPERATION); else if(plValues[0] < 0 || plValues[1] < 0 || plValues[0] >= plValues[1] || ALBuf->size == 0) alSetError(pContext, AL_INVALID_VALUE); else { ALint maxlen = ALBuf->size / aluFrameSizeFromFormat(ALBuf->format); if(plValues[0] > maxlen || plValues[1] > maxlen) alSetError(pContext, AL_INVALID_VALUE); else { ALBuf->LoopStart = plValues[0]; ALBuf->LoopEnd = plValues[1]; } } break; default: alSetError(pContext, AL_INVALID_ENUM); break; } } ProcessContext(pContext); }
AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue) { ALCcontext *pContext; ALbuffer *pBuffer; ALCdevice *device; pContext = GetContextSuspended(); if(!pContext) return; device = pContext->Device; if(!plValue) alSetError(pContext, AL_INVALID_VALUE); else if((pBuffer=LookupBuffer(device->BufferMap, buffer)) == NULL) alSetError(pContext, AL_INVALID_NAME); else { switch(eParam) { case AL_FREQUENCY: *plValue = pBuffer->frequency; break; case AL_BITS: *plValue = aluBytesFromFormat(pBuffer->format) * 8; break; case AL_CHANNELS: *plValue = aluChannelsFromFormat(pBuffer->format); break; case AL_SIZE: *plValue = pBuffer->size; break; default: alSetError(pContext, AL_INVALID_ENUM); break; } } ProcessContext(pContext); }
AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) { ALCdevice *device; ALCcontext *context; ALbuffer *ALBuf; ALsizei i; context = GetContextRef(); if(!context) return; if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); device = context->Device; for(i = 0; i < n; i++) { if(!buffers[i]) continue; /* Check for valid Buffer ID */ if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(ReadRef(&ALBuf->ref) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } for(i = 0; i < n; i++) { if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL) continue; FreeThunkEntry(ALBuf->id); free(ALBuf->data); memset(ALBuf, 0, sizeof(*ALBuf)); free(ALBuf); } done: ALCcontext_DecRef(context); }
AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(value1), ALint UNUSED(value2), ALint UNUSED(value3)) { ALCdevice *device; ALCcontext *context; context = GetContextRef(); if(!context) return; device = context->Device; if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) { default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: ALCcontext_DecRef(context); }
AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues) { ALCcontext *pContext; ALCdevice *device; ALbuffer *ALBuf; pContext = GetContextSuspended(); if(!pContext) return; device = pContext->Device; if(!plValues) alSetError(pContext, AL_INVALID_VALUE); else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL) alSetError(pContext, AL_INVALID_NAME); else { switch(eParam) { case AL_FREQUENCY: case AL_BITS: case AL_CHANNELS: case AL_SIZE: alGetBufferi(buffer, eParam, plValues); break; case AL_LOOP_POINTS: plValues[0] = ALBuf->LoopStart; plValues[1] = ALBuf->LoopEnd; break; default: alSetError(pContext, AL_INVALID_ENUM); break; } } ProcessContext(pContext); }
AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values) { ALCdevice *device; ALCcontext *context; context = GetContextRef(); if(!context) return; device = context->Device; if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: ALCcontext_DecRef(context); }
AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) { ALCdevice *device; ALCcontext *context; ALbuffer *albuf; ALsizei align; ALenum err; context = GetContextRef(); if(!context) return; device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(samples >= 0 && samplerate != 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if((samples%align) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); err = LoadData(albuf, samplerate, internalformat, samples, channels, type, data, align, AL_FALSE); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); done: UnlockBuffersRead(device); ALCcontext_DecRef(context); }
AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue) { ALCcontext *pContext; ALCdevice *device; (void)flValue; pContext = GetContextSuspended(); if(!pContext) return; device = pContext->Device; if(LookupBuffer(device->BufferMap, buffer) == NULL) alSetError(pContext, AL_INVALID_NAME); { switch(eParam) { default: alSetError(pContext, AL_INVALID_ENUM); break; } } ProcessContext(pContext); }
AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) { ALCdevice *device; ALCcontext *context; ALbuffer *albuf; context = GetContextRef(); if(!context) return; device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) { case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); ATOMIC_STORE_SEQ(&albuf->PackAlign, value); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: UnlockBuffersRead(device); ALCcontext_DecRef(context); }
AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value) { ALCdevice *device; ALCcontext *context; ALbuffer *albuf; context = GetContextRef(); if(!context) return; device = context->Device; if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(value)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { case AL_FREQUENCY: *value = albuf->Frequency; break; case AL_BITS: *value = BytesFromFmt(albuf->FmtType) * 8; break; case AL_CHANNELS: *value = ChannelsFromFmt(albuf->FmtChannels); break; case AL_SIZE: ReadLock(&albuf->lock); *value = albuf->SampleLen * FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); ReadUnlock(&albuf->lock); break; case AL_INTERNAL_FORMAT_SOFT: *value = albuf->Format; break; case AL_BYTE_LENGTH_SOFT: *value = albuf->OriginalSize; break; case AL_SAMPLE_LENGTH_SOFT: *value = albuf->SampleLen; break; case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: *value = albuf->UnpackAlign; break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: *value = albuf->PackAlign; break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } done: ALCcontext_DecRef(context); }
/* * 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); }
/* * 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); }
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length) { enum UserFmtChannels srcchannels; enum UserFmtType srctype; ALCdevice *device; ALCcontext *context; ALbuffer *albuf; ALuint byte_align; ALuint channels; ALuint bytes; ALsizei align; context = GetContextRef(); if(!context) return; device = context->Device; if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(length >= 0 && offset >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); WriteLock(&albuf->lock); align = albuf->UnpackAlign; if(SanitizeAlignment(srctype, &align) == AL_FALSE) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } if(srcchannels != albuf->OriginalChannels || srctype != albuf->OriginalType) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(align != albuf->OriginalAlign) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(albuf->OriginalType == UserFmtIMA4) { byte_align = (albuf->OriginalAlign-1)/2 + 4; byte_align *= ChannelsFromUserFmt(albuf->OriginalChannels); } else if(albuf->OriginalType == UserFmtMSADPCM) { byte_align = (albuf->OriginalAlign-2)/2 + 7; byte_align *= ChannelsFromUserFmt(albuf->OriginalChannels); } else { byte_align = albuf->OriginalAlign; byte_align *= FrameSizeFromUserFmt(albuf->OriginalChannels, albuf->OriginalType); } if(offset > albuf->OriginalSize || length > albuf->OriginalSize-offset || (offset%byte_align) != 0 || (length%byte_align) != 0) { WriteUnlock(&albuf->lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } channels = ChannelsFromFmt(albuf->FmtChannels); bytes = BytesFromFmt(albuf->FmtType); /* offset -> byte offset, length -> sample count */ offset = offset/byte_align * channels*bytes; length = length/byte_align * albuf->OriginalAlign; ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, data, srctype, channels, length, align); WriteUnlock(&albuf->lock); done: ALCcontext_DecRef(context); }
AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq) { enum UserFmtChannels srcchannels; enum UserFmtType srctype; ALCdevice *device; ALCcontext *context; ALbuffer *albuf; ALenum newformat = AL_NONE; ALuint framesize; ALsizei align; ALenum err; context = GetContextRef(); if(!context) return; device = context->Device; if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(size >= 0 && freq > 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); align = albuf->UnpackAlign; if(SanitizeAlignment(srctype, &align) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srctype) { case UserFmtByte: case UserFmtUByte: case UserFmtShort: case UserFmtUShort: case UserFmtFloat: framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align; if((size%framesize) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); err = LoadData(albuf, freq, format, size/framesize*align, srcchannels, srctype, data, align, AL_TRUE); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; case UserFmtInt: case UserFmtUInt: case UserFmtByte3: case UserFmtUByte3: case UserFmtDouble: framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align; if((size%framesize) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srcchannels) { case UserFmtMono: newformat = AL_FORMAT_MONO_FLOAT32; break; case UserFmtStereo: newformat = AL_FORMAT_STEREO_FLOAT32; break; case UserFmtRear: newformat = AL_FORMAT_REAR32; break; case UserFmtQuad: newformat = AL_FORMAT_QUAD32; break; case UserFmtX51: newformat = AL_FORMAT_51CHN32; break; case UserFmtX61: newformat = AL_FORMAT_61CHN32; break; case UserFmtX71: newformat = AL_FORMAT_71CHN32; break; } err = LoadData(albuf, freq, newformat, size/framesize*align, srcchannels, srctype, data, align, AL_TRUE); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; case UserFmtMulaw: case UserFmtAlaw: framesize = FrameSizeFromUserFmt(srcchannels, srctype) * align; if((size%framesize) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srcchannels) { case UserFmtMono: newformat = AL_FORMAT_MONO16; break; case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; case UserFmtRear: newformat = AL_FORMAT_REAR16; break; case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; } err = LoadData(albuf, freq, newformat, size/framesize*align, srcchannels, srctype, data, align, AL_TRUE); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; case UserFmtIMA4: framesize = (align-1)/2 + 4; framesize *= ChannelsFromUserFmt(srcchannels); if((size%framesize) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srcchannels) { case UserFmtMono: newformat = AL_FORMAT_MONO16; break; case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; case UserFmtRear: newformat = AL_FORMAT_REAR16; break; case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; } err = LoadData(albuf, freq, newformat, size/framesize*align, srcchannels, srctype, data, align, AL_TRUE); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; case UserFmtMSADPCM: framesize = (align-2)/2 + 7; framesize *= ChannelsFromUserFmt(srcchannels); if((size%framesize) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srcchannels) { case UserFmtMono: newformat = AL_FORMAT_MONO16; break; case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; case UserFmtRear: newformat = AL_FORMAT_REAR16; break; case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; } err = LoadData(albuf, freq, newformat, size/framesize*align, srcchannels, srctype, data, align, AL_TRUE); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; } done: ALCcontext_DecRef(context); }
/* * alDeleteBuffers(ALsizei n, ALuint *puiBuffers) * * Deletes the n AL Buffers pointed to by puiBuffers */ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers) { ALCcontext *Context; ALbuffer *ALBuf; ALsizei i; Context = GetContextSuspended(); if(!Context) return; // Check we are actually Deleting some Buffers if(n < 0) alSetError(Context, AL_INVALID_VALUE); else { ALCdevice *device = Context->Device; ALboolean bFailed = AL_FALSE; // Check that all the buffers are valid and can actually be deleted for (i = 0; i < n; i++) { if(!puiBuffers[i]) continue; // Check for valid Buffer ID (can be NULL buffer) if((ALBuf=LookupBuffer(device->BufferMap, puiBuffers[i])) != NULL) { if(ALBuf->refcount != 0) { // Buffer still in use, cannot be deleted alSetError(Context, AL_INVALID_OPERATION); bFailed = AL_TRUE; break; } } else { // Invalid Buffer alSetError(Context, AL_INVALID_NAME); bFailed = AL_TRUE; break; } } // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them if (!bFailed) { for (i = 0; i < n; i++) { if((ALBuf=LookupBuffer(device->BufferMap, puiBuffers[i])) != NULL) { // Release the memory used to store audio data free(ALBuf->data); // Release buffer structure RemoveUIntMapKey(&device->BufferMap, ALBuf->buffer); ALTHUNK_REMOVEENTRY(ALBuf->buffer); memset(ALBuf, 0, sizeof(ALbuffer)); free(ALBuf); } } } } ProcessContext(Context); }