aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2007-12-31 19:34:52 -0800
committerChris Robinson <[email protected]>2007-12-31 19:34:52 -0800
commit3d78d93b4033ea94d38981e75f10c6dee5264860 (patch)
treeeff0ee8b22ea032075fd16046d6cb24fa52a8243 /OpenAL32
parent5a2f509104b196bbef336b6c772cd621473f2e55 (diff)
parent9382956b0ec459a696805a23656a9e94b6ed94d9 (diff)
Merge branch 'master' into efx-experiment
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alMain.h37
-rw-r--r--OpenAL32/Include/alSource.h4
-rw-r--r--OpenAL32/Include/alu.h6
-rw-r--r--OpenAL32/alAuxEffectSlot.c2
-rw-r--r--OpenAL32/alBuffer.c278
-rw-r--r--OpenAL32/alEffect.c2
-rw-r--r--OpenAL32/alExtension.c16
-rw-r--r--OpenAL32/alFilter.c2
-rw-r--r--OpenAL32/alSource.c71
9 files changed, 312 insertions, 106 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 168991b7..a5e5184a 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -1,9 +1,6 @@
#ifndef AL_MAIN_H
#define AL_MAIN_H
-#define AL_MAX_CHANNELS 4
-#define AL_MAX_SOURCES 32
-
#include <string.h>
#include "alu.h"
@@ -59,13 +56,7 @@ static inline void DeleteCriticalSection(CRITICAL_SECTION *cs)
#define max(x,y) (((x)>(y))?(x):(y))
#endif
-#include "alBuffer.h"
-#include "alError.h"
-#include "alExtension.h"
#include "alListener.h"
-#include "alSource.h"
-#include "alState.h"
-#include "alThunk.h"
#ifdef __cplusplus
extern "C"
@@ -82,20 +73,36 @@ extern char _alDebug[256];
if(!_al_print_fn) _al_print_fn = __FILE__; \
else _al_print_fn += 1; \
_al_print_i = snprintf(_alDebug, sizeof(_alDebug), "AL lib: %s:%d: ", _al_print_fn, __LINE__); \
- snprintf(_alDebug+_al_print_i, sizeof(_alDebug)-_al_print_i, __VA_ARGS__); \
+ if(_al_print_i < (int)sizeof(_alDebug) && _al_print_i > 0) \
+ snprintf(_alDebug+_al_print_i, sizeof(_alDebug)-_al_print_i, __VA_ARGS__); \
+ _alDebug[sizeof(_alDebug)-1] = 0; \
fprintf(stderr, "%s", _alDebug); \
} while(0)
+#define AL_FORMAT_MONO_FLOAT32 0x10010
+#define AL_FORMAT_STEREO_FLOAT32 0x10011
+
#define AL_FORMAT_MONO_IMA4 0x1300
#define AL_FORMAT_STEREO_IMA4 0x1301
-// These are from AL_EXT_MCFORMATS, which we don't support yet but the mixer
-// can use 4-channel formats
+
+#define AL_FORMAT_51CHN8 0x120A
+#define AL_FORMAT_51CHN16 0x120B
+#define AL_FORMAT_51CHN32 0x120C
+#define AL_FORMAT_61CHN8 0x120D
+#define AL_FORMAT_61CHN16 0x120E
+#define AL_FORMAT_61CHN32 0x120F
+#define AL_FORMAT_71CHN8 0x1210
+#define AL_FORMAT_71CHN16 0x1211
+#define AL_FORMAT_71CHN32 0x1212
#define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205
+#define AL_FORMAT_QUAD32 0x1206
+#define AL_FORMAT_REAR8 0x1207
+#define AL_FORMAT_REAR16 0x1208
+#define AL_FORMAT_REAR32 0x1209
#define SWMIXER_OUTPUT_RATE 44100
-//#define OUTPUT_BUFFER_SIZE (32768*SWMIXER_OUTPUT_RATE/22050)
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
#define AIRABSORBGAINHF (0.994f)
@@ -154,8 +161,8 @@ struct ALCcontext_struct
{
ALlistener Listener;
- ALsource *Source;
- ALuint SourceCount;
+ struct ALsource *Source;
+ ALuint SourceCount;
ALenum LastError;
ALboolean InUse;
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index f54d4721..09651fa5 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -31,7 +31,7 @@ typedef struct ALbufferlistitem
struct ALbufferlistitem *next;
} ALbufferlistitem;
-typedef struct ALsource_struct
+typedef struct ALsource
{
ALfloat flPitch;
ALfloat flGain;
@@ -94,7 +94,7 @@ typedef struct ALsource_struct
// Source Type (Static, Streaming, or Undetermined)
ALint lSourceType;
- struct ALsource_struct *next;
+ struct ALsource *next;
} ALsource;
#ifdef __cplusplus
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index e4fe0dc3..d43e0127 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -1,12 +1,6 @@
#ifndef _ALU_H_
#define _ALU_H_
-#define BUFFERSIZE 48000
-#define FRACTIONBITS 14
-#define FRACTIONMASK ((1L<<FRACTIONBITS)-1)
-#define MAX_PITCH 4
-#define OUTPUTCHANNELS 4
-
#include "AL/al.h"
#include "AL/alc.h"
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 6b8a335c..282b8030 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -27,6 +27,8 @@
#include "alMain.h"
#include "alAuxEffectSlot.h"
+#include "alThunk.h"
+#include "alError.h"
static ALeffectslot *g_AuxiliaryEffectSlotList;
static ALuint g_AuxiliaryEffectSlotCount;
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index 0abdb61f..2bcb6562 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -27,8 +27,11 @@
#include "AL/alc.h"
#include "alError.h"
#include "alBuffer.h"
+#include "alThunk.h"
+static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
+
/*
* AL Buffer Functions
*
@@ -273,91 +276,143 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
switch(format)
{
case AL_FORMAT_MONO8:
- if ((size%1) == 0)
+ 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));
+ ALsizei i;
+
+ assert(aluBytesFromFormat(NewFormat) == 2);
+
+ if ((size%(OrigBytes*2)) != 0)
{
- // 8bit Samples are converted to 16 bit here
- // Allocate 8 extra samples (16 bytes)
- ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALubyte))*(1*sizeof(ALshort)));
- if (ALBuf->data)
- {
- ALBuf->format = AL_FORMAT_MONO16;
- ALBuf->eOriginalFormat = AL_FORMAT_MONO8;
- for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++)
- ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8);
- memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 16);
- ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort);
- ALBuf->frequency=freq;
- }
- else
- alSetError(AL_OUT_OF_MEMORY);
- }
- else
alSetError(AL_INVALID_VALUE);
- break;
+ break;
+ }
- case AL_FORMAT_MONO16:
- if ((size%2) == 0)
+ switch(OrigBytes)
{
- // Allocate 8 extra samples (16 bytes)
- ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALshort))*(1*sizeof(ALshort)));
+ case 1:
+ size /= sizeof(ALubyte);
+ size *= 2;
+
+ // 8bit Samples are converted to 16 bit here
+ // Allocate 8 extra samples
+ ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
if (ALBuf->data)
{
- ALBuf->format = AL_FORMAT_MONO16;
- ALBuf->eOriginalFormat = AL_FORMAT_MONO16;
- memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort));
- memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 16);
- ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort);
- ALBuf->frequency=freq;
+ for (i = 0;i < size;i+=4)
+ {
+ ALBuf->data[i+0] = 0;
+ ALBuf->data[i+1] = 0;
+ ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
+ ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
+ }
+ memset(&(ALBuf->data[size]), 0, 16*NewChannels);
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = format;
+ ALBuf->size = size*1*sizeof(ALshort);
+ ALBuf->frequency = freq;
}
else
alSetError(AL_OUT_OF_MEMORY);
- }
- else
- alSetError(AL_INVALID_VALUE);
- break;
+ break;
- case AL_FORMAT_STEREO8:
- if ((size%2) == 0)
- {
- // 8bit Samples are converted to 16 bit here
- // Allocate 8 extra samples (32 bytes)
- ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALubyte))*(1*sizeof(ALshort)));
+ case 2:
+ size /= sizeof(ALshort);
+ size *= 2;
+
+ // Allocate 8 extra samples
+ ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
if (ALBuf->data)
{
- ALBuf->format = AL_FORMAT_STEREO16;
- ALBuf->eOriginalFormat = AL_FORMAT_STEREO8;
- for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++)
- ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8);
- memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 32);
- ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort);
- ALBuf->frequency=freq;
+ for (i = 0;i < size;i+=4)
+ {
+ ALBuf->data[i+0] = 0;
+ ALBuf->data[i+1] = 0;
+ ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
+ ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
+ }
+ memset(&(ALBuf->data[size]), 0, 16*NewChannels);
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = format;
+ ALBuf->size = size*1*sizeof(ALshort);
+ ALBuf->frequency = freq;
}
else
alSetError(AL_OUT_OF_MEMORY);
- }
- else
- alSetError(AL_INVALID_VALUE);
- break;
+ break;
- case AL_FORMAT_STEREO16:
- if ((size%4) == 0)
- {
- // Allocate 8 extra samples (32 bytes)
- ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALshort))*(1*sizeof(ALshort)));
+ case 4:
+ size /= sizeof(ALfloat);
+ size *= 2;
+
+ // Allocate 8 extra samples
+ ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
if (ALBuf->data)
{
- ALBuf->format = AL_FORMAT_STEREO16;
- ALBuf->eOriginalFormat = AL_FORMAT_STEREO16;
- memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort));
- memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 32);
- ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort);
- ALBuf->frequency=freq;
+ for (i = 0;i < size;i+=4)
+ {
+ ALBuf->data[i+0] = 0;
+ ALBuf->data[i+1] = 0;
+ ALBuf->data[i+2] = (ALshort)(((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
+ ALBuf->data[i+3] = (ALshort)(((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
+ }
+ memset(&(ALBuf->data[size]), 0, 16*NewChannels);
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = format;
+ ALBuf->size = size*1*sizeof(ALshort);
+ ALBuf->frequency = freq;
}
else
alSetError(AL_OUT_OF_MEMORY);
+ break;
+
+ default:
+ assert(0);
}
- else
- alSetError(AL_INVALID_VALUE);
+ } break;
+
+ 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:
@@ -489,7 +544,7 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
else if (LeftIndex>88) LeftIndex=88;
ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
LeftIMACode>>=4;
-
+
RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
if (RightSample<-32768) RightSample=-32768;
@@ -817,11 +872,11 @@ ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValu
break;
case AL_BITS:
- *plValue= (((pBuffer->format==AL_FORMAT_MONO8)||(pBuffer->format==AL_FORMAT_STEREO8))?8:16);
+ *plValue = aluBytesFromFormat(pBuffer->format) * 8;
break;
case AL_CHANNELS:
- *plValue = (((pBuffer->format==AL_FORMAT_MONO8)||(pBuffer->format==AL_FORMAT_MONO16))?1:2);
+ *plValue = aluChannelsFromFormat(pBuffer->format);
break;
case AL_SIZE:
@@ -917,6 +972,97 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue
ProcessContext(pContext);
}
+/*
+ * LoadData
+ *
+ * Loads the specified data into the buffer, using the specified formats.
+ * Currently, the new format must be 16-bit, and must have the same channel
+ * configuration as the original format. This does NOT handle compressed
+ * formats (eg. IMA4).
+ */
+static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
+{
+ ALuint NewChannels = aluChannelsFromFormat(NewFormat);
+ ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
+ ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
+ ALsizei i;
+
+ assert(aluBytesFromFormat(NewFormat) == 2);
+ assert(NewChannels == OrigChannels);
+
+ if ((size%(OrigBytes*OrigChannels)) != 0)
+ {
+ alSetError(AL_INVALID_VALUE);
+ return;
+ }
+
+ switch(OrigBytes)
+ {
+ case 1:
+ size /= sizeof(ALubyte);
+
+ // 8bit Samples are converted to 16 bit here
+ // Allocate 8 extra samples
+ ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
+ if (ALBuf->data)
+ {
+ for (i = 0;i < size;i++)
+ ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
+ memset(&(ALBuf->data[size]), 0, 16*NewChannels);
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = OrigFormat;
+ ALBuf->size = size*1*sizeof(ALshort);
+ ALBuf->frequency = freq;
+ }
+ else
+ alSetError(AL_OUT_OF_MEMORY);
+ break;
+
+ case 2:
+ size /= sizeof(ALshort);
+
+ // Allocate 8 extra samples
+ ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
+ if (ALBuf->data)
+ {
+ memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
+ memset(&(ALBuf->data[size]), 0, 16*NewChannels);
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = OrigFormat;
+ ALBuf->size = size*1*sizeof(ALshort);
+ ALBuf->frequency = freq;
+ }
+ else
+ alSetError(AL_OUT_OF_MEMORY);
+ break;
+
+ case 4:
+ size /= sizeof(ALfloat);
+
+ // Allocate 8 extra samples
+ ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
+ if (ALBuf->data)
+ {
+ for (i = 0;i < size;i++)
+ ALBuf->data[i] = (ALshort)(((ALfloat*)data)[i] * 32767.5f - 0.5);
+ memset(&(ALBuf->data[size]), 0, 16*NewChannels);
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = OrigFormat;
+ ALBuf->size = size*1*sizeof(ALshort);
+ ALBuf->frequency = freq;
+ }
+ else
+ alSetError(AL_OUT_OF_MEMORY);
+ break;
+
+ default:
+ assert(0);
+ }
+}
+
/*
* ReleaseALBuffers()
diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c
index 823d09ae..97778f9e 100644
--- a/OpenAL32/alEffect.c
+++ b/OpenAL32/alEffect.c
@@ -27,6 +27,8 @@
#include "alMain.h"
#include "alEffect.h"
+#include "alThunk.h"
+#include "alError.h"
static ALeffect *g_EffectList;
static ALuint g_EffectCount;
diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c
index 54371ff4..fff46d0a 100644
--- a/OpenAL32/alExtension.c
+++ b/OpenAL32/alExtension.c
@@ -27,6 +27,7 @@
#include "alFilter.h"
#include "alEffect.h"
#include "alAuxEffectSlot.h"
+#include "alSource.h"
#include "AL/al.h"
#include "AL/alc.h"
@@ -202,12 +203,27 @@ static ALenums enumeration[]={
// Buffer Formats
{ (ALchar *)"AL_FORMAT_MONO8", AL_FORMAT_MONO8 },
{ (ALchar *)"AL_FORMAT_MONO16", AL_FORMAT_MONO16 },
+ { (ALchar *)"AL_FORMAT_MONO_FLOAT32", AL_FORMAT_MONO_FLOAT32 },
{ (ALchar *)"AL_FORMAT_STEREO8", AL_FORMAT_STEREO8 },
{ (ALchar *)"AL_FORMAT_STEREO16", AL_FORMAT_STEREO16 },
+ { (ALchar *)"AL_FORMAT_STEREO_FLOAT32", AL_FORMAT_STEREO_FLOAT32 },
{ (ALchar *)"AL_FORMAT_MONO_IMA4", AL_FORMAT_MONO_IMA4 },
{ (ALchar *)"AL_FORMAT_STEREO_IMA4", AL_FORMAT_STEREO_IMA4 },
{ (ALchar *)"AL_FORMAT_QUAD8", AL_FORMAT_QUAD8 },
{ (ALchar *)"AL_FORMAT_QUAD16", AL_FORMAT_QUAD16 },
+ { (ALchar *)"AL_FORMAT_QUAD32", AL_FORMAT_QUAD32 },
+ { (ALchar *)"AL_FORMAT_51CHN8", AL_FORMAT_51CHN8 },
+ { (ALchar *)"AL_FORMAT_51CHN16", AL_FORMAT_51CHN16 },
+ { (ALchar *)"AL_FORMAT_51CHN32", AL_FORMAT_51CHN32 },
+ { (ALchar *)"AL_FORMAT_61CHN8", AL_FORMAT_61CHN8 },
+ { (ALchar *)"AL_FORMAT_61CHN16", AL_FORMAT_61CHN16 },
+ { (ALchar *)"AL_FORMAT_61CHN32", AL_FORMAT_61CHN32 },
+ { (ALchar *)"AL_FORMAT_71CHN8", AL_FORMAT_71CHN8 },
+ { (ALchar *)"AL_FORMAT_71CHN16", AL_FORMAT_71CHN16 },
+ { (ALchar *)"AL_FORMAT_71CHN32", AL_FORMAT_71CHN32 },
+ { (ALchar *)"AL_FORMAT_REAR8", AL_FORMAT_REAR8 },
+ { (ALchar *)"AL_FORMAT_REAR16", AL_FORMAT_REAR16 },
+ { (ALchar *)"AL_FORMAT_REAR32", AL_FORMAT_REAR32 },
// Buffer attributes
{ (ALchar *)"AL_FREQUENCY", AL_FREQUENCY },
diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c
index 80da100a..0753d799 100644
--- a/OpenAL32/alFilter.c
+++ b/OpenAL32/alFilter.c
@@ -27,6 +27,8 @@
#include "alMain.h"
#include "alFilter.h"
+#include "alThunk.h"
+#include "alError.h"
static ALfilter *g_FilterList;
static ALuint g_FilterCount;
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 5b40f7eb..746ec821 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -26,6 +26,8 @@
#include "AL/alc.h"
#include "alError.h"
#include "alSource.h"
+#include "alBuffer.h"
+#include "alThunk.h"
static ALvoid InitSourceParams(ALsource *pSource);
static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOffset);
@@ -1983,6 +1985,7 @@ static ALvoid InitSourceParams(ALsource *pSource)
static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOffset)
{
ALbufferlistitem *pBufferList;
+ ALbuffer *pBuffer;
ALfloat flBufferFreq;
ALint lBytesPlayed, lChannels;
ALenum eOriginalFormat;
@@ -1991,10 +1994,11 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
if (((pSource->state == AL_PLAYING) || (pSource->state == AL_PAUSED)) && (pSource->ulBufferID))
{
+ pBuffer = ALTHUNK_LOOKUPENTRY(pSource->ulBufferID);
// Get Current Buffer Size and frequency (in milliseconds)
- flBufferFreq = (ALfloat)(((ALbuffer*)ALTHUNK_LOOKUPENTRY(pSource->ulBufferID))->frequency);
- eOriginalFormat = ((ALbuffer*)ALTHUNK_LOOKUPENTRY(pSource->ulBufferID))->eOriginalFormat;
- lChannels = ((((ALbuffer*)ALTHUNK_LOOKUPENTRY(pSource->ulBufferID))->format == AL_FORMAT_MONO16)?1:2);
+ flBufferFreq = (ALfloat)pBuffer->frequency;
+ eOriginalFormat = pBuffer->eOriginalFormat;
+ lChannels = aluChannelsFromFormat(pBuffer->format);
// Get Current BytesPlayed
lBytesPlayed = pSource->position * lChannels * 2; // NOTE : This is the byte offset into the *current* buffer
@@ -2041,17 +2045,30 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
break;
case AL_BYTE_OFFSET:
// Take into account the original format of the Buffer
- if ((eOriginalFormat == AL_FORMAT_MONO8) || (eOriginalFormat == AL_FORMAT_STEREO8))
- {
- *pflOffset = (ALfloat)(lBytesPlayed >> 1);
- }
- else if ((eOriginalFormat == AL_FORMAT_MONO_IMA4) || (eOriginalFormat == AL_FORMAT_STEREO_IMA4))
+ if ((eOriginalFormat == AL_FORMAT_MONO_IMA4) ||
+ (eOriginalFormat == AL_FORMAT_STEREO_IMA4))
{
// Compression rate of the ADPCM supported is 3.6111 to 1
lBytesPlayed = (ALint)((ALfloat)lBytesPlayed / 3.6111f);
// Round down to nearest ADPCM block
*pflOffset = (ALfloat)((lBytesPlayed / (36 * lChannels)) * 36 * lChannels);
}
+ else if (eOriginalFormat == AL_FORMAT_REAR8)
+ {
+ *pflOffset = (ALfloat)(lBytesPlayed >> 2);
+ }
+ else if (eOriginalFormat == AL_FORMAT_REAR16)
+ {
+ *pflOffset = (ALfloat)(lBytesPlayed >> 1);
+ }
+ else if (aluBytesFromFormat(eOriginalFormat) == 1)
+ {
+ *pflOffset = (ALfloat)(lBytesPlayed >> 1);
+ }
+ else if (aluBytesFromFormat(eOriginalFormat) == 4)
+ {
+ *pflOffset = (ALfloat)(lBytesPlayed << 1);
+ }
else
{
*pflOffset = (ALfloat)lBytesPlayed;
@@ -2077,6 +2094,7 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
static void ApplyOffset(ALsource *pSource, ALboolean bUpdateContext)
{
ALbufferlistitem *pBufferList;
+ ALbuffer *pBuffer;
ALint lBufferSize, lTotalBufferSize;
ALint lByteOffset;
@@ -2093,7 +2111,8 @@ static void ApplyOffset(ALsource *pSource, ALboolean bUpdateContext)
pSource->BuffersProcessed = 0;
while (pBufferList)
{
- lBufferSize = pBufferList->buffer ? ((ALbuffer*)ALTHUNK_LOOKUPENTRY(pBufferList->buffer))->size : 0;
+ pBuffer = ALTHUNK_LOOKUPENTRY(pBufferList->buffer);
+ lBufferSize = pBuffer ? pBuffer->size : 0;
if ((lTotalBufferSize + lBufferSize) <= lByteOffset)
{
@@ -2122,7 +2141,9 @@ static void ApplyOffset(ALsource *pSource, ALboolean bUpdateContext)
pSource->lBytesPlayed = lByteOffset;
// SW Mixer Positions are in Samples
- pSource->position = pSource->BufferPosition / ((((ALbuffer*)ALTHUNK_LOOKUPENTRY(pBufferList->buffer))->format == AL_FORMAT_MONO16)?2:4);
+ pSource->position = pSource->BufferPosition /
+ aluBytesFromFormat(pBuffer->format) /
+ aluChannelsFromFormat(pBuffer->format);
}
else
{
@@ -2179,19 +2200,15 @@ static ALint GetByteOffset(ALsource *pSource)
if (pBuffer)
{
flBufferFreq = ((ALfloat)pBuffer->frequency);
- lChannels = (pBuffer->format == AL_FORMAT_MONO16)?1:2;
+ lChannels = aluChannelsFromFormat(pBuffer->format);
// Determine the ByteOffset (and ensure it is block aligned)
switch (pSource->lOffsetType)
{
case AL_BYTE_OFFSET:
// Take into consideration the original format
- if ((pBuffer->eOriginalFormat == AL_FORMAT_MONO8) || (pBuffer->eOriginalFormat == AL_FORMAT_STEREO8))
- {
- lByteOffset = pSource->lOffset * 2;
- lByteOffset -= (lByteOffset % (lChannels * 2));
- }
- else if ((pBuffer->eOriginalFormat == AL_FORMAT_MONO_IMA4) || (pBuffer->eOriginalFormat == AL_FORMAT_STEREO_IMA4))
+ if ((pBuffer->eOriginalFormat == AL_FORMAT_MONO_IMA4) ||
+ (pBuffer->eOriginalFormat == AL_FORMAT_STEREO_IMA4))
{
// Round down to nearest ADPCM block
lByteOffset = (pSource->lOffset / (36 * lChannels)) * 36 * lChannels;
@@ -2199,6 +2216,26 @@ static ALint GetByteOffset(ALsource *pSource)
lByteOffset = (ALint)(3.6111f * (ALfloat)lByteOffset);
lByteOffset -= (lByteOffset % (lChannels * 2));
}
+ else if (pBuffer->eOriginalFormat == AL_FORMAT_REAR8)
+ {
+ lByteOffset = pSource->lOffset * 4;
+ lByteOffset -= (lByteOffset % (lChannels * 2));
+ }
+ else if (pBuffer->eOriginalFormat == AL_FORMAT_REAR16)
+ {
+ lByteOffset = pSource->lOffset * 2;
+ lByteOffset -= (lByteOffset % (lChannels * 2));
+ }
+ else if (aluBytesFromFormat(pBuffer->eOriginalFormat) == 1)
+ {
+ lByteOffset = pSource->lOffset * 2;
+ lByteOffset -= (lByteOffset % (lChannels * 2));
+ }
+ else if (aluBytesFromFormat(pBuffer->eOriginalFormat) == 4)
+ {
+ lByteOffset = pSource->lOffset / 2;
+ lByteOffset -= (lByteOffset % (lChannels * 2));
+ }
else
{
lByteOffset = pSource->lOffset;