aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h1
-rw-r--r--OpenAL32/Include/alEffect.h10
-rw-r--r--OpenAL32/Include/alMain.h4
-rw-r--r--OpenAL32/alAuxEffectSlot.c1
-rw-r--r--OpenAL32/alEffect.c7
-rw-r--r--OpenAL32/alSource.c115
6 files changed, 137 insertions, 1 deletions
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h
index bb9aef59..c1eae443 100644
--- a/OpenAL32/Include/alAuxEffectSlot.h
+++ b/OpenAL32/Include/alAuxEffectSlot.h
@@ -166,6 +166,7 @@ EffectStateFactory *DistortionStateFactory_getFactory(void);
EffectStateFactory *EchoStateFactory_getFactory(void);
EffectStateFactory *EqualizerStateFactory_getFactory(void);
EffectStateFactory *FlangerStateFactory_getFactory(void);
+EffectStateFactory *FshifterStateFactory_getFactory(void);
EffectStateFactory *ModulatorStateFactory_getFactory(void);
EffectStateFactory *PshifterStateFactory_getFactory(void);
diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h
index 50b64ee1..4d28a708 100644
--- a/OpenAL32/Include/alEffect.h
+++ b/OpenAL32/Include/alEffect.h
@@ -18,6 +18,7 @@ enum {
ECHO_EFFECT,
EQUALIZER_EFFECT,
FLANGER_EFFECT,
+ FSHIFTER_EFFECT,
MODULATOR_EFFECT,
PSHIFTER_EFFECT,
DEDICATED_EFFECT,
@@ -33,7 +34,7 @@ struct EffectList {
int type;
ALenum val;
};
-#define EFFECTLIST_SIZE 12
+#define EFFECTLIST_SIZE 13
extern const struct EffectList EffectList[EFFECTLIST_SIZE];
@@ -65,6 +66,7 @@ extern const struct ALeffectVtable ALdistortion_vtable;
extern const struct ALeffectVtable ALecho_vtable;
extern const struct ALeffectVtable ALequalizer_vtable;
extern const struct ALeffectVtable ALflanger_vtable;
+extern const struct ALeffectVtable ALfshifter_vtable;
extern const struct ALeffectVtable ALmodulator_vtable;
extern const struct ALeffectVtable ALnull_vtable;
extern const struct ALeffectVtable ALpshifter_vtable;
@@ -147,6 +149,12 @@ typedef union ALeffectProps {
struct {
ALfloat Frequency;
+ ALint LeftDirection;
+ ALint RightDirection;
+ } Fshifter;
+
+ struct {
+ ALfloat Frequency;
ALfloat HighPassCutoff;
ALint Waveform;
} Modulator;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 886f3ab1..093f7950 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -184,11 +184,15 @@ inline int fallback_ctz64(ALuint64 value)
#define CTZ64 fallback_ctz64
#endif
+#if defined(__BYTE_ORDER__) && defined(__LITTLE_ENDIAN__)
+#define IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
+#else
static const union {
ALuint u;
ALubyte b[sizeof(ALuint)];
} EndianTest = { 1 };
#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
+#endif
#define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index d04fc4a7..6f6ef163 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -54,6 +54,7 @@ static const struct {
{ AL_EFFECT_ECHO, EchoStateFactory_getFactory },
{ AL_EFFECT_EQUALIZER, EqualizerStateFactory_getFactory },
{ AL_EFFECT_FLANGER, FlangerStateFactory_getFactory },
+ { AL_EFFECT_FREQUENCY_SHIFTER, FshifterStateFactory_getFactory },
{ AL_EFFECT_RING_MODULATOR, ModulatorStateFactory_getFactory },
{ AL_EFFECT_PITCH_SHIFTER, PshifterStateFactory_getFactory},
{ AL_EFFECT_DEDICATED_DIALOGUE, DedicatedStateFactory_getFactory },
diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c
index e7dc6ace..aacddd4c 100644
--- a/OpenAL32/alEffect.c
+++ b/OpenAL32/alEffect.c
@@ -44,6 +44,7 @@ const struct EffectList EffectList[EFFECTLIST_SIZE] = {
{ "echo", ECHO_EFFECT, AL_EFFECT_ECHO },
{ "equalizer", EQUALIZER_EFFECT, AL_EFFECT_EQUALIZER },
{ "flanger", FLANGER_EFFECT, AL_EFFECT_FLANGER },
+ { "fshifter", FSHIFTER_EFFECT, AL_EFFECT_FREQUENCY_SHIFTER },
{ "modulator", MODULATOR_EFFECT, AL_EFFECT_RING_MODULATOR },
{ "pshifter", PSHIFTER_EFFECT, AL_EFFECT_PITCH_SHIFTER },
{ "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT },
@@ -584,6 +585,12 @@ static void InitEffectParams(ALeffect *effect, ALenum type)
effect->Props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY;
effect->vtab = &ALflanger_vtable;
break;
+ case AL_EFFECT_FREQUENCY_SHIFTER:
+ effect->Props.Fshifter.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY;
+ effect->Props.Fshifter.LeftDirection = AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION;
+ effect->Props.Fshifter.RightDirection = AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION;
+ effect->vtab = &ALfshifter_vtable;
+ break;
case AL_EFFECT_RING_MODULATOR:
effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY;
effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF;
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index ed6bd8ee..5ce439c7 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -2826,6 +2826,121 @@ done:
ALCcontext_DecRef(context);
}
+AL_API void AL_APIENTRY alSourceQueueBufferLayersSOFT(ALuint src, ALsizei nb, const ALuint *buffers)
+{
+ ALCdevice *device;
+ ALCcontext *context;
+ ALbufferlistitem *BufferListStart;
+ ALbufferlistitem *BufferList;
+ ALbuffer *BufferFmt = NULL;
+ ALsource *source;
+ ALsizei i;
+
+ if(nb == 0)
+ return;
+
+ context = GetContextRef();
+ if(!context) return;
+
+ device = context->Device;
+
+ LockSourceList(context);
+ if(!(nb >= 0 && nb < 16))
+ SETERR_GOTO(context, AL_INVALID_VALUE, done, "Queueing %d buffer layers", nb);
+ if((source=LookupSource(context, src)) == NULL)
+ SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", src);
+
+ if(source->SourceType == AL_STATIC)
+ {
+ /* Can't queue on a Static Source */
+ SETERR_GOTO(context, AL_INVALID_OPERATION, done, "Queueing onto static source %u", src);
+ }
+
+ /* Check for a valid Buffer, for its frequency and format */
+ BufferList = source->queue;
+ while(BufferList)
+ {
+ for(i = 0;i < BufferList->num_buffers;i++)
+ {
+ if((BufferFmt=BufferList->buffers[i]) != NULL)
+ break;
+ }
+ if(BufferFmt) break;
+ BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed);
+ }
+
+ LockBufferList(device);
+ BufferListStart = al_calloc(DEF_ALIGN, FAM_SIZE(ALbufferlistitem, buffers, nb));
+ BufferList = BufferListStart;
+ ATOMIC_INIT(&BufferList->next, NULL);
+ BufferList->max_samples = 0;
+ BufferList->num_buffers = 0;
+ for(i = 0;i < nb;i++)
+ {
+ ALbuffer *buffer = NULL;
+ if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL)
+ SETERR_GOTO(context, AL_INVALID_NAME, buffer_error, "Queueing invalid buffer ID %u",
+ buffers[i]);
+
+ BufferList->buffers[BufferList->num_buffers++] = buffer;
+ if(!buffer) continue;
+
+ IncrementRef(&buffer->ref);
+
+ BufferList->max_samples = maxi(BufferList->max_samples, buffer->SampleLen);
+
+ if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT))
+ SETERR_GOTO(context, AL_INVALID_OPERATION, buffer_error,
+ "Queueing non-persistently mapped buffer %u", buffer->id);
+
+ if(BufferFmt == NULL)
+ BufferFmt = buffer;
+ else if(BufferFmt->Frequency != buffer->Frequency ||
+ BufferFmt->FmtChannels != buffer->FmtChannels ||
+ BufferFmt->OriginalType != buffer->OriginalType)
+ {
+ alSetError(context, AL_INVALID_OPERATION, "Queueing buffer with mismatched format");
+
+ buffer_error:
+ /* A buffer failed (invalid ID or format), so unlock and release
+ * each buffer we had. */
+ while(BufferListStart)
+ {
+ ALbufferlistitem *next = ATOMIC_LOAD(&BufferListStart->next,
+ almemory_order_relaxed);
+ for(i = 0;i < BufferListStart->num_buffers;i++)
+ {
+ if((buffer=BufferListStart->buffers[i]) != NULL)
+ DecrementRef(&buffer->ref);
+ }
+ al_free(BufferListStart);
+ BufferListStart = next;
+ }
+ UnlockBufferList(device);
+ goto done;
+ }
+ }
+ /* All buffers good. */
+ UnlockBufferList(device);
+
+ /* Source is now streaming */
+ source->SourceType = AL_STREAMING;
+
+ if(!(BufferList=source->queue))
+ source->queue = BufferListStart;
+ else
+ {
+ ALbufferlistitem *next;
+ while((next=ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed)) != NULL)
+ BufferList = next;
+ ATOMIC_STORE(&BufferList->next, BufferListStart, almemory_order_release);
+ }
+
+done:
+ UnlockSourceList(context);
+ ALCcontext_DecRef(context);
+}
+
AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint *buffers)
{
ALCcontext *context;