Use a separate structure for buffer storage
This commit is contained in:
@@ -453,7 +453,7 @@ START_API_FUNC
|
||||
{
|
||||
buffer = LookupBuffer(device, static_cast<ALuint>(value));
|
||||
if(!buffer) SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid buffer ID");
|
||||
if(buffer->Callback)
|
||||
if(buffer->mBuffer.mCallback)
|
||||
SETERR_RETURN(context, AL_INVALID_OPERATION,,
|
||||
"Callback buffer not valid for effects");
|
||||
|
||||
@@ -469,8 +469,9 @@ START_API_FUNC
|
||||
{
|
||||
FPUCtl mixer_mode{};
|
||||
auto *state = slot->Effect.State.get();
|
||||
slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mData.data(),
|
||||
buffer->Frequency, buffer->mFmtType, buffer->mFmtChannels, buffer->SampleLen));
|
||||
slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer.mData.data(),
|
||||
buffer->mBuffer.mSampleRate, buffer->mBuffer.mType, buffer->mBuffer.mChannels,
|
||||
buffer->mBuffer.mSampleLen));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -745,8 +746,9 @@ ALenum ALeffectslot::initEffect(ALeffect *effect, ALCcontext *context)
|
||||
State->deviceUpdate(Device);
|
||||
Effect.Buffer = nullptr;
|
||||
if(Buffer)
|
||||
Effect.Buffer.reset(State->createBuffer(Device, Buffer->mData.data(),
|
||||
Buffer->Frequency, Buffer->mFmtType, Buffer->mFmtChannels, Buffer->SampleLen));
|
||||
Effect.Buffer.reset(State->createBuffer(Device, Buffer->mBuffer.mData.data(),
|
||||
Buffer->mBuffer.mSampleRate, Buffer->mBuffer.mType, Buffer->mBuffer.mChannels,
|
||||
Buffer->mBuffer.mSampleLen));
|
||||
}
|
||||
|
||||
if(!effect)
|
||||
|
||||
+46
-46
@@ -466,11 +466,11 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||
if((access&AL_PRESERVE_DATA_BIT_SOFT))
|
||||
{
|
||||
/* Can only preserve data with the same format and alignment. */
|
||||
if UNLIKELY(ALBuf->mFmtChannels != DstChannels || ALBuf->OriginalType != SrcType)
|
||||
if UNLIKELY(ALBuf->mBuffer.mChannels != DstChannels || ALBuf->OriginalType != SrcType)
|
||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched format");
|
||||
if UNLIKELY(ALBuf->OriginalAlign != align)
|
||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched alignment");
|
||||
if(ALBuf->AmbiOrder != ambiorder)
|
||||
if(ALBuf->mBuffer.mAmbiOrder != ambiorder)
|
||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched order");
|
||||
}
|
||||
|
||||
@@ -508,55 +508,55 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||
* use AL_SIZE to try to get the buffer's play length.
|
||||
*/
|
||||
newsize = RoundUp(newsize, 16);
|
||||
if(newsize != ALBuf->mData.size())
|
||||
if(newsize != ALBuf->mBuffer.mData.size())
|
||||
{
|
||||
auto newdata = al::vector<al::byte,16>(newsize, al::byte{});
|
||||
if((access&AL_PRESERVE_DATA_BIT_SOFT))
|
||||
{
|
||||
const size_t tocopy{minz(newdata.size(), ALBuf->mData.size())};
|
||||
std::copy_n(ALBuf->mData.begin(), tocopy, newdata.begin());
|
||||
const size_t tocopy{minz(newdata.size(), ALBuf->mBuffer.mData.size())};
|
||||
std::copy_n(ALBuf->mBuffer.mData.begin(), tocopy, newdata.begin());
|
||||
}
|
||||
newdata.swap(ALBuf->mData);
|
||||
newdata.swap(ALBuf->mBuffer.mData);
|
||||
}
|
||||
|
||||
if(SrcType == UserFmtIMA4)
|
||||
{
|
||||
assert(DstType == FmtShort);
|
||||
if(SrcData != nullptr && !ALBuf->mData.empty())
|
||||
Convert_int16_ima4(reinterpret_cast<int16_t*>(ALBuf->mData.data()), SrcData,
|
||||
if(SrcData != nullptr && !ALBuf->mBuffer.mData.empty())
|
||||
Convert_int16_ima4(reinterpret_cast<int16_t*>(ALBuf->mBuffer.mData.data()), SrcData,
|
||||
NumChannels, frames, align);
|
||||
ALBuf->OriginalAlign = align;
|
||||
}
|
||||
else if(SrcType == UserFmtMSADPCM)
|
||||
{
|
||||
assert(DstType == FmtShort);
|
||||
if(SrcData != nullptr && !ALBuf->mData.empty())
|
||||
Convert_int16_msadpcm(reinterpret_cast<int16_t*>(ALBuf->mData.data()), SrcData,
|
||||
if(SrcData != nullptr && !ALBuf->mBuffer.mData.empty())
|
||||
Convert_int16_msadpcm(reinterpret_cast<int16_t*>(ALBuf->mBuffer.mData.data()), SrcData,
|
||||
NumChannels, frames, align);
|
||||
ALBuf->OriginalAlign = align;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(static_cast<long>(SrcType) == static_cast<long>(DstType));
|
||||
if(SrcData != nullptr && !ALBuf->mData.empty())
|
||||
std::copy_n(SrcData, frames*FrameSize, ALBuf->mData.begin());
|
||||
if(SrcData != nullptr && !ALBuf->mBuffer.mData.empty())
|
||||
std::copy_n(SrcData, frames*FrameSize, ALBuf->mBuffer.mData.begin());
|
||||
ALBuf->OriginalAlign = 1;
|
||||
}
|
||||
ALBuf->OriginalSize = size;
|
||||
ALBuf->OriginalType = SrcType;
|
||||
|
||||
ALBuf->Frequency = static_cast<ALuint>(freq);
|
||||
ALBuf->mFmtChannels = DstChannels;
|
||||
ALBuf->mFmtType = DstType;
|
||||
ALBuf->mBuffer.mSampleRate = static_cast<ALuint>(freq);
|
||||
ALBuf->mBuffer.mChannels = DstChannels;
|
||||
ALBuf->mBuffer.mType = DstType;
|
||||
ALBuf->Access = access;
|
||||
ALBuf->AmbiOrder = ambiorder;
|
||||
ALBuf->mBuffer.mAmbiOrder = ambiorder;
|
||||
|
||||
ALBuf->Callback = nullptr;
|
||||
ALBuf->UserData = nullptr;
|
||||
ALBuf->mBuffer.mCallback = nullptr;
|
||||
ALBuf->mBuffer.mUserData = nullptr;
|
||||
|
||||
ALBuf->SampleLen = frames;
|
||||
ALBuf->mBuffer.mSampleLen = frames;
|
||||
ALBuf->LoopStart = 0;
|
||||
ALBuf->LoopEnd = ALBuf->SampleLen;
|
||||
ALBuf->LoopEnd = ALBuf->mBuffer.mSampleLen;
|
||||
}
|
||||
|
||||
/** Prepares the buffer to use the specified callback, using the specified format. */
|
||||
@@ -605,24 +605,24 @@ void PrepareCallback(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq,
|
||||
ALBuf->UnpackAmbiOrder : 0};
|
||||
|
||||
al::vector<al::byte,16>(FrameSizeFromFmt(DstChannels, DstType, ambiorder) *
|
||||
size_t{BUFFERSIZE + (MAX_RESAMPLER_PADDING>>1)}).swap(ALBuf->mData);
|
||||
size_t{BUFFERSIZE + (MAX_RESAMPLER_PADDING>>1)}).swap(ALBuf->mBuffer.mData);
|
||||
|
||||
ALBuf->Callback = callback;
|
||||
ALBuf->UserData = userptr;
|
||||
ALBuf->mBuffer.mCallback = callback;
|
||||
ALBuf->mBuffer.mUserData = userptr;
|
||||
|
||||
ALBuf->OriginalType = SrcType;
|
||||
ALBuf->OriginalSize = 0;
|
||||
ALBuf->OriginalAlign = 1;
|
||||
|
||||
ALBuf->Frequency = static_cast<ALuint>(freq);
|
||||
ALBuf->mFmtChannels = DstChannels;
|
||||
ALBuf->mFmtType = DstType;
|
||||
ALBuf->mBuffer.mSampleRate = static_cast<ALuint>(freq);
|
||||
ALBuf->mBuffer.mChannels = DstChannels;
|
||||
ALBuf->mBuffer.mType = DstType;
|
||||
ALBuf->Access = 0;
|
||||
ALBuf->AmbiOrder = ambiorder;
|
||||
ALBuf->mBuffer.mAmbiOrder = ambiorder;
|
||||
|
||||
ALBuf->SampleLen = 0;
|
||||
ALBuf->mBuffer.mSampleLen = 0;
|
||||
ALBuf->LoopStart = 0;
|
||||
ALBuf->LoopEnd = ALBuf->SampleLen;
|
||||
ALBuf->LoopEnd = ALBuf->mBuffer.mSampleLen;
|
||||
}
|
||||
|
||||
|
||||
@@ -883,7 +883,7 @@ START_API_FUNC
|
||||
offset, length, buffer);
|
||||
else
|
||||
{
|
||||
void *retval = albuf->mData.data() + offset;
|
||||
void *retval{albuf->mBuffer.mData.data() + offset};
|
||||
albuf->MappedAccess = access;
|
||||
albuf->MappedOffset = offset;
|
||||
albuf->MappedSize = length;
|
||||
@@ -977,15 +977,15 @@ START_API_FUNC
|
||||
ALuint align{SanitizeAlignment(usrfmt->type, unpack_align)};
|
||||
if UNLIKELY(align < 1)
|
||||
context->setError(AL_INVALID_VALUE, "Invalid unpack alignment %u", unpack_align);
|
||||
else if UNLIKELY(long{usrfmt->channels} != long{albuf->mFmtChannels}
|
||||
else if UNLIKELY(long{usrfmt->channels} != long{albuf->mBuffer.mChannels}
|
||||
|| usrfmt->type != albuf->OriginalType)
|
||||
context->setError(AL_INVALID_ENUM, "Unpacking data with mismatched format");
|
||||
else if UNLIKELY(align != albuf->OriginalAlign)
|
||||
context->setError(AL_INVALID_VALUE,
|
||||
"Unpacking data with alignment %u does not match original alignment %u", align,
|
||||
albuf->OriginalAlign);
|
||||
else if UNLIKELY((albuf->mFmtChannels == FmtBFormat2D || albuf->mFmtChannels == FmtBFormat3D)
|
||||
&& albuf->UnpackAmbiOrder != albuf->AmbiOrder)
|
||||
else if UNLIKELY(albuf->mBuffer.isBFormat()
|
||||
&& albuf->UnpackAmbiOrder != albuf->mBuffer.mAmbiOrder)
|
||||
context->setError(AL_INVALID_VALUE, "Unpacking data with mismatched ambisonic order");
|
||||
else if UNLIKELY(albuf->MappedAccess != 0)
|
||||
context->setError(AL_INVALID_OPERATION, "Unpacking data into mapped buffer %u", buffer);
|
||||
@@ -1017,16 +1017,16 @@ START_API_FUNC
|
||||
size_t byteoff{static_cast<ALuint>(offset)/byte_align * align * frame_size};
|
||||
size_t samplen{static_cast<ALuint>(length)/byte_align * align};
|
||||
|
||||
void *dst = albuf->mData.data() + byteoff;
|
||||
if(usrfmt->type == UserFmtIMA4 && albuf->mFmtType == FmtShort)
|
||||
void *dst = albuf->mBuffer.mData.data() + byteoff;
|
||||
if(usrfmt->type == UserFmtIMA4 && albuf->mBuffer.mType == FmtShort)
|
||||
Convert_int16_ima4(static_cast<int16_t*>(dst), static_cast<const al::byte*>(data),
|
||||
num_chans, samplen, align);
|
||||
else if(usrfmt->type == UserFmtMSADPCM && albuf->mFmtType == FmtShort)
|
||||
else if(usrfmt->type == UserFmtMSADPCM && albuf->mBuffer.mType == FmtShort)
|
||||
Convert_int16_msadpcm(static_cast<int16_t*>(dst),
|
||||
static_cast<const al::byte*>(data), num_chans, samplen, align);
|
||||
else
|
||||
{
|
||||
assert(long{usrfmt->type} == long{albuf->mFmtType});
|
||||
assert(long{usrfmt->type} == long{albuf->mBuffer.mType});
|
||||
memcpy(dst, data, size_t{samplen} * frame_size);
|
||||
}
|
||||
}
|
||||
@@ -1177,7 +1177,7 @@ START_API_FUNC
|
||||
else if UNLIKELY(value != AL_FUMA_SOFT && value != AL_ACN_SOFT)
|
||||
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic layout %04x", value);
|
||||
else
|
||||
albuf->AmbiLayout = value;
|
||||
albuf->mBuffer.mAmbiLayout = static_cast<AmbiLayout>(value);
|
||||
break;
|
||||
|
||||
case AL_AMBISONIC_SCALING_SOFT:
|
||||
@@ -1187,7 +1187,7 @@ START_API_FUNC
|
||||
else if UNLIKELY(value != AL_FUMA_SOFT && value != AL_SN3D_SOFT && value != AL_N3D_SOFT)
|
||||
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic scaling %04x", value);
|
||||
else
|
||||
albuf->AmbiScaling = value;
|
||||
albuf->mBuffer.mAmbiScaling = static_cast<AmbiScaling>(value);
|
||||
break;
|
||||
|
||||
case AL_UNPACK_AMBISONIC_ORDER_SOFT:
|
||||
@@ -1258,7 +1258,7 @@ START_API_FUNC
|
||||
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's loop points",
|
||||
buffer);
|
||||
else if UNLIKELY(values[0] < 0 || values[0] >= values[1]
|
||||
|| static_cast<ALuint>(values[1]) > albuf->SampleLen)
|
||||
|| static_cast<ALuint>(values[1]) > albuf->mBuffer.mSampleLen)
|
||||
context->setError(AL_INVALID_VALUE, "Invalid loop point range %d -> %d on buffer %u",
|
||||
values[0], values[1], buffer);
|
||||
else
|
||||
@@ -1363,7 +1363,7 @@ START_API_FUNC
|
||||
else switch(param)
|
||||
{
|
||||
case AL_FREQUENCY:
|
||||
*value = static_cast<ALint>(albuf->Frequency);
|
||||
*value = static_cast<ALint>(albuf->mBuffer.mSampleRate);
|
||||
break;
|
||||
|
||||
case AL_BITS:
|
||||
@@ -1375,7 +1375,7 @@ START_API_FUNC
|
||||
break;
|
||||
|
||||
case AL_SIZE:
|
||||
*value = static_cast<ALint>(albuf->SampleLen * albuf->frameSizeFromFmt());
|
||||
*value = static_cast<ALint>(albuf->mBuffer.mSampleLen * albuf->frameSizeFromFmt());
|
||||
break;
|
||||
|
||||
case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
|
||||
@@ -1387,11 +1387,11 @@ START_API_FUNC
|
||||
break;
|
||||
|
||||
case AL_AMBISONIC_LAYOUT_SOFT:
|
||||
*value = albuf->AmbiLayout;
|
||||
*value = static_cast<int>(albuf->mBuffer.mAmbiLayout);
|
||||
break;
|
||||
|
||||
case AL_AMBISONIC_SCALING_SOFT:
|
||||
*value = albuf->AmbiScaling;
|
||||
*value = static_cast<int>(albuf->mBuffer.mAmbiScaling);
|
||||
break;
|
||||
|
||||
case AL_UNPACK_AMBISONIC_ORDER_SOFT:
|
||||
@@ -1516,10 +1516,10 @@ START_API_FUNC
|
||||
else switch(param)
|
||||
{
|
||||
case AL_BUFFER_CALLBACK_FUNCTION_SOFT:
|
||||
*value = reinterpret_cast<void*>(albuf->Callback);
|
||||
*value = reinterpret_cast<void*>(albuf->mBuffer.mCallback);
|
||||
break;
|
||||
case AL_BUFFER_CALLBACK_USER_PARAM_SOFT:
|
||||
*value = albuf->UserData;
|
||||
*value = albuf->mBuffer.mUserData;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+4
-18
@@ -39,27 +39,14 @@ enum UserFmtChannels : unsigned char {
|
||||
|
||||
|
||||
struct ALbuffer {
|
||||
al::vector<al::byte,16> mData;
|
||||
BufferStorage mBuffer;
|
||||
|
||||
ALuint Frequency{0u};
|
||||
ALbitfieldSOFT Access{0u};
|
||||
ALuint SampleLen{0u};
|
||||
|
||||
FmtChannels mFmtChannels{};
|
||||
FmtType mFmtType{};
|
||||
|
||||
UserFmtType OriginalType{};
|
||||
ALuint OriginalSize{0};
|
||||
ALuint OriginalAlign{0};
|
||||
|
||||
ALenum AmbiLayout{AL_FUMA_SOFT};
|
||||
ALenum AmbiScaling{AL_FUMA_SOFT};
|
||||
/* AmbiOrder is only updated when loading new data. */
|
||||
ALuint AmbiOrder{0};
|
||||
|
||||
LPALBUFFERCALLBACKTYPESOFT Callback{nullptr};
|
||||
void *UserData{nullptr};
|
||||
|
||||
ALuint LoopStart{0u};
|
||||
ALuint LoopEnd{0u};
|
||||
|
||||
@@ -77,10 +64,9 @@ struct ALbuffer {
|
||||
/* Self ID */
|
||||
ALuint id{0};
|
||||
|
||||
inline ALuint bytesFromFmt() const noexcept { return BytesFromFmt(mFmtType); }
|
||||
inline ALuint channelsFromFmt() const noexcept
|
||||
{ return ChannelsFromFmt(mFmtChannels, AmbiOrder); }
|
||||
inline ALuint frameSizeFromFmt() const noexcept { return channelsFromFmt() * bytesFromFmt(); }
|
||||
inline ALuint bytesFromFmt() const noexcept { return mBuffer.bytesFromFmt(); }
|
||||
inline ALuint channelsFromFmt() const noexcept { return mBuffer.channelsFromFmt(); }
|
||||
inline ALuint frameSizeFromFmt() const noexcept { return mBuffer.frameSizeFromFmt(); }
|
||||
|
||||
DISABLE_ALLOC()
|
||||
};
|
||||
|
||||
+22
-21
@@ -257,7 +257,7 @@ double GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds *cl
|
||||
}
|
||||
assert(BufferFmt != nullptr);
|
||||
|
||||
return static_cast<double>(readPos) / double{FRACTIONONE} / BufferFmt->Frequency;
|
||||
return static_cast<double>(readPos) / double{FRACTIONONE} / BufferFmt->mBuffer.mSampleRate;
|
||||
}
|
||||
|
||||
/* GetSourceOffset
|
||||
@@ -313,7 +313,8 @@ double GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context)
|
||||
switch(name)
|
||||
{
|
||||
case AL_SEC_OFFSET:
|
||||
offset = (readPos + static_cast<double>(readPosFrac)/FRACTIONONE) / BufferFmt->Frequency;
|
||||
offset = (readPos + static_cast<double>(readPosFrac)/FRACTIONONE) /
|
||||
BufferFmt->mBuffer.mSampleRate;
|
||||
break;
|
||||
|
||||
case AL_SAMPLE_OFFSET:
|
||||
@@ -409,7 +410,7 @@ al::optional<VoicePos> GetSampleOffset(ALbufferlistitem *BufferList, ALenum Offs
|
||||
break;
|
||||
|
||||
case AL_SEC_OFFSET:
|
||||
dblfrac = std::modf(Offset*BufferFmt->Frequency, &dbloff);
|
||||
dblfrac = std::modf(Offset*BufferFmt->mBuffer.mSampleRate, &dbloff);
|
||||
offset = static_cast<ALuint>(mind(dbloff, std::numeric_limits<ALuint>::max()));
|
||||
frac = static_cast<ALuint>(mind(dblfrac*FRACTIONONE, FRACTIONONE-1.0));
|
||||
break;
|
||||
@@ -442,14 +443,14 @@ void InitVoice(Voice *voice, ALsource *source, ALbufferlistitem *BufferList, ALC
|
||||
|
||||
ALbuffer *buffer{BufferList->mBuffer};
|
||||
ALuint num_channels{buffer->channelsFromFmt()};
|
||||
voice->mFrequency = buffer->Frequency;
|
||||
voice->mFmtChannels = buffer->mFmtChannels;
|
||||
voice->mFrequency = buffer->mBuffer.mSampleRate;
|
||||
voice->mFmtChannels = buffer->mBuffer.mChannels;
|
||||
voice->mSampleSize = buffer->bytesFromFmt();
|
||||
voice->mAmbiLayout = static_cast<AmbiLayout>(buffer->AmbiLayout);
|
||||
voice->mAmbiScaling = static_cast<AmbiNorm>(buffer->AmbiScaling);
|
||||
voice->mAmbiOrder = buffer->AmbiOrder;
|
||||
voice->mAmbiLayout = buffer->mBuffer.mAmbiLayout;
|
||||
voice->mAmbiScaling = buffer->mBuffer.mAmbiScaling;
|
||||
voice->mAmbiOrder = buffer->mBuffer.mAmbiOrder;
|
||||
|
||||
if(buffer->Callback) voice->mFlags |= VOICE_IS_CALLBACK;
|
||||
if(buffer->mBuffer.mCallback) voice->mFlags |= VOICE_IS_CALLBACK;
|
||||
else if(source->SourceType == AL_STATIC) voice->mFlags |= VOICE_IS_STATIC;
|
||||
voice->mNumCallbackSamples = 0;
|
||||
|
||||
@@ -1311,7 +1312,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
if(buffer && buffer->MappedAccess && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT))
|
||||
SETERR_RETURN(Context, AL_INVALID_OPERATION, false,
|
||||
"Setting non-persistently mapped buffer %u", buffer->id);
|
||||
else if(buffer && buffer->Callback && ReadRef(buffer->ref) != 0)
|
||||
else if(buffer && buffer->mBuffer.mCallback && ReadRef(buffer->ref) != 0)
|
||||
SETERR_RETURN(Context, AL_INVALID_OPERATION, false,
|
||||
"Setting already-set callback buffer %u", buffer->id);
|
||||
else
|
||||
@@ -1327,7 +1328,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
{
|
||||
/* Add the selected buffer to a one-item queue */
|
||||
auto newlist = new ALbufferlistitem{};
|
||||
newlist->mSampleLen = buffer->SampleLen;
|
||||
newlist->mSampleLen = buffer->mBuffer.mSampleLen;
|
||||
newlist->mBuffer = buffer;
|
||||
IncrementRef(buffer->ref);
|
||||
|
||||
@@ -2858,8 +2859,8 @@ START_API_FUNC
|
||||
while(BufferList && BufferList->mSampleLen == 0)
|
||||
{
|
||||
ALbuffer *buffer{BufferList->mBuffer};
|
||||
if(buffer && buffer->Callback) break;
|
||||
|
||||
if(buffer && buffer->mBuffer.mCallback)
|
||||
break;
|
||||
BufferList = BufferList->mNext.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
@@ -3209,7 +3210,7 @@ START_API_FUNC
|
||||
context->setError(AL_INVALID_NAME, "Queueing invalid buffer ID %u", buffers[i]);
|
||||
goto buffer_error;
|
||||
}
|
||||
if(buffer && buffer->Callback)
|
||||
if(buffer && buffer->mBuffer.mCallback)
|
||||
{
|
||||
context->setError(AL_INVALID_OPERATION, "Queueing callback buffer %u", buffers[i]);
|
||||
goto buffer_error;
|
||||
@@ -3227,7 +3228,7 @@ START_API_FUNC
|
||||
BufferList = item;
|
||||
}
|
||||
BufferList->mNext.store(nullptr, std::memory_order_relaxed);
|
||||
BufferList->mSampleLen = buffer ? buffer->SampleLen : 0;
|
||||
BufferList->mSampleLen = buffer ? buffer->mBuffer.mSampleLen : 0;
|
||||
BufferList->mBuffer = buffer;
|
||||
if(!buffer) continue;
|
||||
|
||||
@@ -3244,14 +3245,14 @@ START_API_FUNC
|
||||
BufferFmt = buffer;
|
||||
else
|
||||
{
|
||||
fmt_mismatch |= BufferFmt->Frequency != buffer->Frequency;
|
||||
fmt_mismatch |= BufferFmt->mFmtChannels != buffer->mFmtChannels;
|
||||
if(BufferFmt->mFmtChannels == FmtBFormat2D || BufferFmt->mFmtChannels == FmtBFormat3D)
|
||||
fmt_mismatch |= BufferFmt->mBuffer.mSampleRate != buffer->mBuffer.mSampleRate;
|
||||
fmt_mismatch |= BufferFmt->mBuffer.mChannels != buffer->mBuffer.mChannels;
|
||||
if(BufferFmt->mBuffer.isBFormat())
|
||||
{
|
||||
fmt_mismatch |= BufferFmt->AmbiLayout != buffer->AmbiLayout;
|
||||
fmt_mismatch |= BufferFmt->AmbiScaling != buffer->AmbiScaling;
|
||||
fmt_mismatch |= BufferFmt->mBuffer.mAmbiLayout != buffer->mBuffer.mAmbiLayout;
|
||||
fmt_mismatch |= BufferFmt->mBuffer.mAmbiScaling != buffer->mBuffer.mAmbiScaling;
|
||||
}
|
||||
fmt_mismatch |= BufferFmt->AmbiOrder != buffer->AmbiOrder;
|
||||
fmt_mismatch |= BufferFmt->mBuffer.mAmbiOrder != buffer->mBuffer.mAmbiOrder;
|
||||
fmt_mismatch |= BufferFmt->OriginalType != buffer->OriginalType;
|
||||
}
|
||||
if(fmt_mismatch)
|
||||
|
||||
+15
-13
@@ -1834,8 +1834,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
||||
if(schans == ALC_BFORMAT3D_SOFT)
|
||||
{
|
||||
device->mAmbiOrder = aorder;
|
||||
device->mAmbiLayout = static_cast<AmbiLayout>(alayout);
|
||||
device->mAmbiScale = static_cast<AmbiNorm>(ascale);
|
||||
device->mAmbiLayout = static_cast<DevAmbiLayout>(alayout);
|
||||
device->mAmbiScale = static_cast<DevAmbiScaling>(ascale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2101,8 +2101,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
||||
if(ALbuffer *buffer{slot->Buffer})
|
||||
{
|
||||
slot->Effect.Buffer = nullptr;
|
||||
slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mData.data(),
|
||||
buffer->Frequency, buffer->mFmtType, buffer->mFmtChannels, buffer->SampleLen));
|
||||
slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mBuffer.mData.data(),
|
||||
buffer->mBuffer.mSampleRate, buffer->mBuffer.mType, buffer->mBuffer.mChannels,
|
||||
buffer->mBuffer.mSampleLen));
|
||||
}
|
||||
slot->updateProps(context);
|
||||
}
|
||||
@@ -2128,9 +2129,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
||||
if(ALbuffer *buffer{slot->Buffer})
|
||||
{
|
||||
slot->Effect.Buffer = nullptr;
|
||||
slot->Effect.Buffer.reset(state->createBuffer(device, buffer->mData.data(),
|
||||
buffer->Frequency, buffer->mFmtType, buffer->mFmtChannels,
|
||||
buffer->SampleLen));
|
||||
slot->Effect.Buffer.reset(state->createBuffer(device,
|
||||
buffer->mBuffer.mData.data(), buffer->mBuffer.mSampleRate,
|
||||
buffer->mBuffer.mType, buffer->mBuffer.mChannels,
|
||||
buffer->mBuffer.mSampleLen));
|
||||
}
|
||||
slot->updateProps(context);
|
||||
}
|
||||
@@ -3634,19 +3636,19 @@ START_API_FUNC
|
||||
((device->mAmbiOrder%10) == 3) ? "rd" : "th");
|
||||
else
|
||||
{
|
||||
device->mAmbiLayout = AmbiLayout::FuMa;
|
||||
device->mAmbiScale = AmbiNorm::FuMa;
|
||||
device->mAmbiLayout = DevAmbiLayout::FuMa;
|
||||
device->mAmbiScale = DevAmbiScaling::FuMa;
|
||||
}
|
||||
}
|
||||
else if(al::strcasecmp(fmt, "ambix") == 0 || al::strcasecmp(fmt, "acn+sn3d") == 0)
|
||||
{
|
||||
device->mAmbiLayout = AmbiLayout::ACN;
|
||||
device->mAmbiScale = AmbiNorm::SN3D;
|
||||
device->mAmbiLayout = DevAmbiLayout::ACN;
|
||||
device->mAmbiScale = DevAmbiScaling::SN3D;
|
||||
}
|
||||
else if(al::strcasecmp(fmt, "acn+n3d") == 0)
|
||||
{
|
||||
device->mAmbiLayout = AmbiLayout::ACN;
|
||||
device->mAmbiScale = AmbiNorm::N3D;
|
||||
device->mAmbiLayout = DevAmbiLayout::ACN;
|
||||
device->mAmbiScale = DevAmbiScaling::N3D;
|
||||
}
|
||||
else
|
||||
ERR("Unsupported ambi-format: %s\n", fmt);
|
||||
|
||||
+2
-2
@@ -210,8 +210,8 @@ struct ALCdevice : public al::intrusive_ref<ALCdevice> {
|
||||
/* For DevFmtAmbi* output only, specifies the channel order and
|
||||
* normalization.
|
||||
*/
|
||||
AmbiLayout mAmbiLayout{AmbiLayout::Default};
|
||||
AmbiNorm mAmbiScale{AmbiNorm::Default};
|
||||
DevAmbiLayout mAmbiLayout{DevAmbiLayout::Default};
|
||||
DevAmbiScaling mAmbiScale{DevAmbiScaling::Default};
|
||||
|
||||
ALCenum LimiterState{ALC_DONT_CARE_SOFT};
|
||||
|
||||
|
||||
+3
-3
@@ -342,10 +342,10 @@ inline ALuint dither_rng(ALuint *seed) noexcept
|
||||
}
|
||||
|
||||
|
||||
auto GetAmbiScales(AmbiNorm scaletype) noexcept -> const std::array<float,MAX_AMBI_CHANNELS>&
|
||||
auto GetAmbiScales(AmbiScaling scaletype) noexcept -> const std::array<float,MAX_AMBI_CHANNELS>&
|
||||
{
|
||||
if(scaletype == AmbiNorm::FuMa) return AmbiScale::FromFuMa;
|
||||
if(scaletype == AmbiNorm::SN3D) return AmbiScale::FromSN3D;
|
||||
if(scaletype == AmbiScaling::FuMa) return AmbiScale::FromFuMa;
|
||||
if(scaletype == AmbiScaling::SN3D) return AmbiScale::FromSN3D;
|
||||
return AmbiScale::FromN3D;
|
||||
}
|
||||
|
||||
|
||||
@@ -271,8 +271,8 @@ bool WaveBackend::reset()
|
||||
case DevFmtAmbi3D:
|
||||
/* .amb output requires FuMa */
|
||||
mDevice->mAmbiOrder = minu(mDevice->mAmbiOrder, 3);
|
||||
mDevice->mAmbiLayout = AmbiLayout::FuMa;
|
||||
mDevice->mAmbiScale = AmbiNorm::FuMa;
|
||||
mDevice->mAmbiLayout = DevAmbiLayout::FuMa;
|
||||
mDevice->mAmbiScale = DevAmbiScaling::FuMa;
|
||||
isbformat = 1;
|
||||
chanmask = 0;
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
#define ALC_BUFFER_FORMATS_H
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "albyte.h"
|
||||
#include "inprogext.h"
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
/* Storable formats */
|
||||
@@ -25,9 +30,44 @@ enum FmtChannels : unsigned char {
|
||||
FmtBFormat3D,
|
||||
};
|
||||
|
||||
enum class AmbiLayout : unsigned char {
|
||||
FuMa = AL_FUMA_SOFT,
|
||||
ACN = AL_ACN_SOFT,
|
||||
};
|
||||
enum class AmbiScaling : unsigned char {
|
||||
FuMa = AL_FUMA_SOFT,
|
||||
SN3D = AL_SN3D_SOFT,
|
||||
N3D = AL_N3D_SOFT,
|
||||
};
|
||||
|
||||
ALuint BytesFromFmt(FmtType type) noexcept;
|
||||
ALuint ChannelsFromFmt(FmtChannels chans, ALuint ambiorder) noexcept;
|
||||
inline ALuint FrameSizeFromFmt(FmtChannels chans, FmtType type, ALuint ambiorder) noexcept
|
||||
{ return ChannelsFromFmt(chans, ambiorder) * BytesFromFmt(type); }
|
||||
|
||||
|
||||
struct BufferStorage {
|
||||
al::vector<al::byte,16> mData;
|
||||
|
||||
LPALBUFFERCALLBACKTYPESOFT mCallback{nullptr};
|
||||
void *mUserData{nullptr};
|
||||
|
||||
ALuint mSampleRate{0u};
|
||||
FmtChannels mChannels{};
|
||||
FmtType mType{};
|
||||
ALuint mSampleLen{0u};
|
||||
|
||||
AmbiLayout mAmbiLayout{AmbiLayout::FuMa};
|
||||
AmbiScaling mAmbiScaling{AmbiScaling::FuMa};
|
||||
ALuint mAmbiOrder{0u};
|
||||
|
||||
inline ALuint bytesFromFmt() const noexcept { return BytesFromFmt(mType); }
|
||||
inline ALuint channelsFromFmt() const noexcept
|
||||
{ return ChannelsFromFmt(mChannels, mAmbiOrder); }
|
||||
inline ALuint frameSizeFromFmt() const noexcept { return channelsFromFmt() * bytesFromFmt(); }
|
||||
|
||||
inline bool isBFormat() const noexcept
|
||||
{ return mChannels == FmtBFormat2D || mChannels == FmtBFormat3D; }
|
||||
};
|
||||
|
||||
#endif /* ALC_BUFFER_FORMATS_H */
|
||||
|
||||
+2
-2
@@ -85,14 +85,14 @@ ALuint ChannelsFromDevFmt(DevFmtChannels chans, ALuint ambiorder) noexcept;
|
||||
inline ALuint FrameSizeFromDevFmt(DevFmtChannels chans, DevFmtType type, ALuint ambiorder) noexcept
|
||||
{ return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type); }
|
||||
|
||||
enum class AmbiLayout {
|
||||
enum class DevAmbiLayout : ALenum {
|
||||
FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
|
||||
ACN = ALC_ACN_SOFT, /* ACN channel order */
|
||||
|
||||
Default = ACN
|
||||
};
|
||||
|
||||
enum class AmbiNorm {
|
||||
enum class DevAmbiScaling : ALenum {
|
||||
FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
|
||||
SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
|
||||
N3D = ALC_N3D_SOFT, /* N3D normalization */
|
||||
|
||||
+5
-5
@@ -303,16 +303,16 @@ void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf,
|
||||
}
|
||||
|
||||
|
||||
auto GetAmbiScales(AmbiNorm scaletype) noexcept -> const std::array<float,MAX_AMBI_CHANNELS>&
|
||||
auto GetAmbiScales(DevAmbiScaling scaletype) noexcept -> const std::array<float,MAX_AMBI_CHANNELS>&
|
||||
{
|
||||
if(scaletype == AmbiNorm::FuMa) return AmbiScale::FromFuMa;
|
||||
if(scaletype == AmbiNorm::SN3D) return AmbiScale::FromSN3D;
|
||||
if(scaletype == DevAmbiScaling::FuMa) return AmbiScale::FromFuMa;
|
||||
if(scaletype == DevAmbiScaling::SN3D) return AmbiScale::FromSN3D;
|
||||
return AmbiScale::FromN3D;
|
||||
}
|
||||
|
||||
auto GetAmbiLayout(AmbiLayout layouttype) noexcept -> const std::array<uint8_t,MAX_AMBI_CHANNELS>&
|
||||
auto GetAmbiLayout(DevAmbiLayout layouttype) noexcept -> const std::array<uint8_t,MAX_AMBI_CHANNELS>&
|
||||
{
|
||||
if(layouttype == AmbiLayout::FuMa) return AmbiIndex::FromFuMa;
|
||||
if(layouttype == DevAmbiLayout::FuMa) return AmbiIndex::FromFuMa;
|
||||
return AmbiIndex::FromACN;
|
||||
}
|
||||
|
||||
|
||||
+18
-18
@@ -255,12 +255,12 @@ float *LoadBufferStatic(ALbufferlistitem *BufferListItem, ALbufferlistitem *&Buf
|
||||
BufferLoopItem = nullptr;
|
||||
|
||||
/* Load what's left to play from the buffer */
|
||||
const size_t DataRem{minz(SrcBuffer.size(), Buffer->SampleLen-DataPosInt)};
|
||||
const size_t DataRem{minz(SrcBuffer.size(), Buffer->mBuffer.mSampleLen-DataPosInt)};
|
||||
|
||||
const al::byte *Data{Buffer->mData.data()};
|
||||
const al::byte *Data{Buffer->mBuffer.mData.data()};
|
||||
Data += (DataPosInt*NumChannels + chan)*SampleSize;
|
||||
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataRem);
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mBuffer.mType, DataRem);
|
||||
SrcBuffer = SrcBuffer.subspan(DataRem);
|
||||
}
|
||||
else
|
||||
@@ -268,10 +268,10 @@ float *LoadBufferStatic(ALbufferlistitem *BufferListItem, ALbufferlistitem *&Buf
|
||||
/* Load what's left of this loop iteration */
|
||||
const size_t DataRem{minz(SrcBuffer.size(), LoopEnd-DataPosInt)};
|
||||
|
||||
const al::byte *Data{Buffer->mData.data()};
|
||||
const al::byte *Data{Buffer->mBuffer.mData.data()};
|
||||
Data += (DataPosInt*NumChannels + chan)*SampleSize;
|
||||
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataRem);
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mBuffer.mType, DataRem);
|
||||
SrcBuffer = SrcBuffer.subspan(DataRem);
|
||||
|
||||
/* Load any repeats of the loop we can to fill the buffer. */
|
||||
@@ -280,9 +280,9 @@ float *LoadBufferStatic(ALbufferlistitem *BufferListItem, ALbufferlistitem *&Buf
|
||||
{
|
||||
const size_t DataSize{minz(SrcBuffer.size(), LoopSize)};
|
||||
|
||||
Data = Buffer->mData.data() + (LoopStart*NumChannels + chan)*SampleSize;
|
||||
Data = Buffer->mBuffer.mData.data() + (LoopStart*NumChannels + chan)*SampleSize;
|
||||
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataSize);
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mBuffer.mType, DataSize);
|
||||
SrcBuffer = SrcBuffer.subspan(DataSize);
|
||||
}
|
||||
}
|
||||
@@ -298,9 +298,9 @@ float *LoadBufferCallback(ALbufferlistitem *BufferListItem, const size_t NumChan
|
||||
/* Load what's left to play from the buffer */
|
||||
const size_t DataRem{minz(SrcBuffer.size(), NumCallbackSamples)};
|
||||
|
||||
const al::byte *Data{Buffer->mData.data() + chan*SampleSize};
|
||||
const al::byte *Data{Buffer->mBuffer.mData.data() + chan*SampleSize};
|
||||
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataRem);
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mBuffer.mType, DataRem);
|
||||
SrcBuffer = SrcBuffer.subspan(DataRem);
|
||||
|
||||
return SrcBuffer.begin();
|
||||
@@ -314,20 +314,20 @@ float *LoadBufferQueue(ALbufferlistitem *BufferListItem, ALbufferlistitem *Buffe
|
||||
while(BufferListItem && !SrcBuffer.empty())
|
||||
{
|
||||
ALbuffer *Buffer{BufferListItem->mBuffer};
|
||||
if(!(Buffer && DataPosInt < Buffer->SampleLen))
|
||||
if(!(Buffer && DataPosInt < Buffer->mBuffer.mSampleLen))
|
||||
{
|
||||
if(Buffer) DataPosInt -= Buffer->SampleLen;
|
||||
if(Buffer) DataPosInt -= Buffer->mBuffer.mSampleLen;
|
||||
BufferListItem = BufferListItem->mNext.load(std::memory_order_acquire);
|
||||
if(!BufferListItem) BufferListItem = BufferLoopItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
const size_t DataSize{minz(SrcBuffer.size(), Buffer->SampleLen-DataPosInt)};
|
||||
const size_t DataSize{minz(SrcBuffer.size(), Buffer->mBuffer.mSampleLen-DataPosInt)};
|
||||
|
||||
const al::byte *Data{Buffer->mData.data()};
|
||||
const al::byte *Data{Buffer->mBuffer.mData.data()};
|
||||
Data += (DataPosInt*NumChannels + chan)*SampleSize;
|
||||
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataSize);
|
||||
LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mBuffer.mType, DataSize);
|
||||
SrcBuffer = SrcBuffer.subspan(DataSize);
|
||||
if(SrcBuffer.empty()) break;
|
||||
|
||||
@@ -564,8 +564,8 @@ void Voice::mix(const State vstate, ALCcontext *Context, const ALuint SamplesToD
|
||||
const size_t byteOffset{mNumCallbackSamples*FrameSize};
|
||||
const size_t needBytes{toLoad*FrameSize - byteOffset};
|
||||
|
||||
const ALsizei gotBytes{buffer->Callback(buffer->UserData,
|
||||
&buffer->mData[byteOffset], static_cast<ALsizei>(needBytes))};
|
||||
const ALsizei gotBytes{buffer->mBuffer.mCallback(buffer->mBuffer.mUserData,
|
||||
&buffer->mBuffer.mData[byteOffset], static_cast<ALsizei>(needBytes))};
|
||||
if(gotBytes < 1)
|
||||
mFlags |= VOICE_CALLBACK_STOPPED;
|
||||
else if(static_cast<ALuint>(gotBytes) < needBytes)
|
||||
@@ -727,8 +727,8 @@ void Voice::mix(const State vstate, ALCcontext *Context, const ALuint SamplesToD
|
||||
{
|
||||
const size_t byteOffset{SrcSamplesDone*FrameSize};
|
||||
const size_t byteEnd{mNumCallbackSamples*FrameSize};
|
||||
std::copy(buffer->mData.data()+byteOffset, buffer->mData.data()+byteEnd,
|
||||
buffer->mData.data());
|
||||
al::byte *data{buffer->mBuffer.mData.data()};
|
||||
std::copy(data+byteOffset, data+byteEnd, data);
|
||||
mNumCallbackSamples -= SrcSamplesDone;
|
||||
}
|
||||
else
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
#include "almalloc.h"
|
||||
#include "alspan.h"
|
||||
#include "alu.h"
|
||||
#include "buffer_storage.h"
|
||||
#include "devformat.h"
|
||||
#include "filters/biquad.h"
|
||||
#include "filters/nfc.h"
|
||||
@@ -221,7 +222,7 @@ struct Voice {
|
||||
ALuint mFrequency;
|
||||
ALuint mSampleSize;
|
||||
AmbiLayout mAmbiLayout;
|
||||
AmbiNorm mAmbiScaling;
|
||||
AmbiScaling mAmbiScaling;
|
||||
ALuint mAmbiOrder;
|
||||
|
||||
/** Current target parameters used for mixing. */
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define AL_BYTE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user