aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-03-07 13:30:15 -0800
committerChris Robinson <[email protected]>2023-03-07 13:30:15 -0800
commited6b8230bd1f4ac502ce4915d24fedacf3eceee0 (patch)
treec7766a230fc26a2322ebd472a8022286f544545b
parentf11313c62dd6ab8666023e90dc6fbf3fc70cb1da (diff)
Add queries for the buffer byte/sample/sec length
These used to exist with the now-defunct AL_SOFT_buffer_samples extension, this just restores those queries without extra baggage. The sample length query are necessary when handling ADPCM buffers, since the size/channels*8/bits calculation is incorrect with ADPCM. 'Bits' is usually reported as 4 since most samples in a block are stored as nibbles, but that's only approximate and doesn't account for the block header. The average number of bits per sample in an ADPCM block can't be represented as an integer, so the more blocks there are stored in the buffer, the more inaccurate the calculation becomes.
-rw-r--r--al/buffer.cpp13
-rw-r--r--alc/context.cpp1
-rw-r--r--include/AL/alext.h7
3 files changed, 21 insertions, 0 deletions
diff --git a/al/buffer.cpp b/al/buffer.cpp
index 05657a2a..ae7bf0d9 100644
--- a/al/buffer.cpp
+++ b/al/buffer.cpp
@@ -1191,6 +1191,11 @@ START_API_FUNC
context->setError(AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
+ case AL_SEC_LENGTH_SOFT:
+ *value = (albuf->mSampleRate < 1) ? 0.0f :
+ (static_cast<float>(albuf->mSampleLen) / static_cast<float>(albuf->mSampleRate));
+ break;
+
default:
context->setError(AL_INVALID_ENUM, "Invalid buffer float property 0x%04x", param);
}
@@ -1276,10 +1281,18 @@ START_API_FUNC
break;
case AL_SIZE:
+ *value = albuf->mCallback ? 0 : static_cast<ALint>(albuf->mData.size());
+ break;
+
+ case AL_BYTE_LENGTH_SOFT:
*value = static_cast<ALint>(albuf->mSampleLen / albuf->mBlockAlign
* albuf->blockSizeFromFmt());
break;
+ case AL_SAMPLE_LENGTH_SOFT:
+ *value = static_cast<ALint>(albuf->mSampleLen);
+ break;
+
case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
*value = static_cast<ALint>(albuf->UnpackAlign);
break;
diff --git a/alc/context.cpp b/alc/context.cpp
index 288f5965..cff666e8 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -62,6 +62,7 @@ constexpr ALchar alExtList[] =
"AL_SOFT_bformat_ex "
"AL_SOFTX_bformat_hoa "
"AL_SOFT_block_alignment "
+ "AL_SOFT_buffer_length_query "
"AL_SOFT_callback_buffer "
"AL_SOFTX_convolution_reverb "
"AL_SOFT_deferred_updates "
diff --git a/include/AL/alext.h b/include/AL/alext.h
index 5d04a839..ae899315 100644
--- a/include/AL/alext.h
+++ b/include/AL/alext.h
@@ -391,6 +391,13 @@ AL_API void AL_APIENTRY alProcessUpdatesSOFT(void);
/*#define AL_SEC_LENGTH_SOFT 0x200B*/
#endif
+#ifndef AL_SOFT_buffer_length_query
+#define AL_SOFT_buffer_length_query 1
+/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
+/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
+/*#define AL_SEC_LENGTH_SOFT 0x200B*/
+#endif
+
#ifndef ALC_SOFT_pause_device
#define ALC_SOFT_pause_device 1
typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);