aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c287
-rw-r--r--Alc/ALu.c31
-rw-r--r--Alc/bformatdec.c28
-rw-r--r--Alc/bformatdec.h1
-rw-r--r--Alc/panning.c18
-rw-r--r--OpenAL32/Include/alMain.h40
-rw-r--r--OpenAL32/Include/alSource.h8
-rw-r--r--OpenAL32/alSource.c54
-rw-r--r--utils/alsoft-config/mainwindow.ui24
9 files changed, 360 insertions, 131 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 41d5cb44..59475e48 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -157,6 +157,8 @@ static const ALCfunction alcFunctions[] = {
DECL(alcIsRenderFormatSupportedSOFT),
DECL(alcRenderSamplesSOFT),
+ DECL(alcIsAmbisonicFormatSupportedSOFT),
+
DECL(alcDevicePauseSOFT),
DECL(alcDeviceResumeSOFT),
@@ -335,6 +337,7 @@ static const ALCenums enumeration[] = {
DECL(ALC_5POINT1_SOFT),
DECL(ALC_6POINT1_SOFT),
DECL(ALC_7POINT1_SOFT),
+ DECL(ALC_BFORMAT3D_SOFT),
DECL(ALC_BYTE_SOFT),
DECL(ALC_UNSIGNED_BYTE_SOFT),
@@ -357,6 +360,14 @@ static const ALCenums enumeration[] = {
DECL(ALC_HRTF_SPECIFIER_SOFT),
DECL(ALC_HRTF_ID_SOFT),
+ DECL(ALC_AMBISONIC_LAYOUT_SOFT),
+ DECL(ALC_AMBISONIC_SCALING_SOFT),
+ DECL(ALC_AMBISONIC_ORDER_SOFT),
+ DECL(ALC_ACN_SOFT),
+ DECL(ALC_FUMA_SOFT),
+ DECL(ALC_N3D_SOFT),
+ DECL(ALC_SN3D_SOFT),
+
DECL(ALC_NO_ERROR),
DECL(ALC_INVALID_DEVICE),
DECL(ALC_INVALID_CONTEXT),
@@ -1478,11 +1489,34 @@ static ALCboolean IsValidALCChannels(ALCenum channels)
case ALC_5POINT1_SOFT:
case ALC_6POINT1_SOFT:
case ALC_7POINT1_SOFT:
+ case ALC_BFORMAT3D_SOFT:
return ALC_TRUE;
}
return ALC_FALSE;
}
+static ALCboolean IsValidAmbiLayout(ALCenum layout)
+{
+ switch(layout)
+ {
+ case ALC_ACN_SOFT:
+ case ALC_FUMA_SOFT:
+ return ALC_TRUE;
+ }
+ return ALC_FALSE;
+}
+
+static ALCboolean IsValidAmbiScaling(ALCenum scaling)
+{
+ switch(scaling)
+ {
+ case ALC_N3D_SOFT:
+ case ALC_SN3D_SOFT:
+ case ALC_FUMA_SOFT:
+ return ALC_TRUE;
+ }
+ return ALC_FALSE;
+}
/************************************************
* Miscellaneous ALC helpers
@@ -1746,12 +1780,15 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode)
*
* Updates the device's base clock time with however many samples have been
* done. This is used so frequency changes on the device don't cause the time
- * to jump forward or back.
+ * to jump forward or back. Must not be called while the device is running/
+ * mixing.
*/
static inline void UpdateClockBase(ALCdevice *device)
{
+ IncrementRef(&device->MixCount);
device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
device->SamplesDone = 0;
+ IncrementRef(&device->MixCount);
}
/* UpdateDeviceParams
@@ -1773,22 +1810,19 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
ALCuint oldFreq;
FPUCtl oldMode;
size_t size;
+ ALCsizei i;
// Check for attributes
if(device->Type == Loopback)
{
- enum {
- GotFreq = 1<<0,
- GotChans = 1<<1,
- GotType = 1<<2,
- GotAll = GotFreq|GotChans|GotType
- };
- ALCuint freq, numMono, numStereo;
- enum DevFmtChannels schans;
- enum DevFmtType stype;
- ALCuint attrIdx = 0;
- ALCint gotFmt = 0;
- ALCsizei numSends;
+ ALCsizei numMono, numStereo, numSends;
+ ALCenum alayout = AL_NONE;
+ ALCenum ascale = AL_NONE;
+ ALCenum schans = AL_NONE;
+ ALCenum stype = AL_NONE;
+ ALCsizei attrIdx = 0;
+ ALCsizei aorder = 0;
+ ALCuint freq = 0;
if(!attrList)
{
@@ -1798,9 +1832,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
numMono = device->NumMonoSources;
numStereo = device->NumStereoSources;
- schans = device->FmtChans;
- stype = device->FmtType;
- freq = device->Frequency;
numSends = old_sends;
#define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
@@ -1808,22 +1839,18 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
{
if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
{
- ALCint val = attrList[attrIdx + 1];
- TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, val);
- if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
+ schans = attrList[attrIdx + 1];
+ TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
+ if(!IsValidALCChannels(schans))
return ALC_INVALID_VALUE;
- schans = val;
- gotFmt |= GotChans;
}
if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
{
- ALCint val = attrList[attrIdx + 1];
- TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, val);
- if(!IsValidALCType(val) || !BytesFromDevFmt(val))
+ stype = attrList[attrIdx + 1];
+ TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
+ if(!IsValidALCType(stype))
return ALC_INVALID_VALUE;
- stype = val;
- gotFmt |= GotType;
}
if(attrList[attrIdx] == ALC_FREQUENCY)
@@ -1832,16 +1859,38 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
TRACE_ATTR(ALC_FREQUENCY, freq);
if(freq < MIN_OUTPUT_RATE)
return ALC_INVALID_VALUE;
- gotFmt |= GotFreq;
+ }
+
+ if(attrList[attrIdx] == ALC_AMBISONIC_LAYOUT_SOFT)
+ {
+ alayout = attrList[attrIdx + 1];
+ TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
+ if(!IsValidAmbiLayout(alayout))
+ return ALC_INVALID_VALUE;
+ }
+
+ if(attrList[attrIdx] == ALC_AMBISONIC_SCALING_SOFT)
+ {
+ ascale = attrList[attrIdx + 1];
+ TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
+ if(!IsValidAmbiScaling(ascale))
+ return ALC_INVALID_VALUE;
+ }
+
+ if(attrList[attrIdx] == ALC_AMBISONIC_ORDER_SOFT)
+ {
+ aorder = attrList[attrIdx + 1];
+ TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
+ if(aorder < 1 || aorder > MAX_AMBI_ORDER)
+ return ALC_INVALID_VALUE;
}
if(attrList[attrIdx] == ALC_STEREO_SOURCES)
{
numStereo = attrList[attrIdx + 1];
TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
- if(numStereo > device->SourcesMax)
- numStereo = device->SourcesMax;
+ numStereo = clampi(numStereo, 0, device->SourcesMax);
numMono = device->SourcesMax - numStereo;
}
@@ -1849,14 +1898,16 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
{
numSends = attrList[attrIdx + 1];
TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
+ numSends = clampi(numSends, 0, MAX_SENDS);
}
if(attrList[attrIdx] == ALC_HRTF_SOFT)
{
- TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
- if(attrList[attrIdx + 1] == ALC_FALSE)
+ ALCint val = attrList[attrIdx + 1];
+ TRACE_ATTR(ALC_HRTF_SOFT, val);
+ if(val == ALC_FALSE)
hrtf_appreq = Hrtf_Disable;
- else if(attrList[attrIdx + 1] == ALC_TRUE)
+ else if(val == ALC_TRUE)
hrtf_appreq = Hrtf_Enable;
else
hrtf_appreq = Hrtf_Default;
@@ -1872,11 +1923,16 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
#undef TRACE_ATTR
- if(gotFmt != GotAll)
+ if(!schans || !stype || !freq)
{
WARN("Missing format for loopback device\n");
return ALC_INVALID_VALUE;
}
+ if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
+ {
+ WARN("Missing ambisonic info for loopback device\n");
+ return ALC_INVALID_VALUE;
+ }
if((device->Flags&DEVICE_RUNNING))
V0(device->Backend,stop)();
@@ -1884,22 +1940,29 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
UpdateClockBase(device);
+ if(schans == ALC_BFORMAT3D_SOFT)
+ {
+ device->FmtChans = DevFmtAmbi1 + aorder;
+ device->AmbiLayout = alayout;
+ device->AmbiScale = ascale;
+ }
+ else
+ device->FmtChans = schans;
device->Frequency = freq;
- device->FmtChans = schans;
device->FmtType = stype;
device->NumMonoSources = numMono;
device->NumStereoSources = numStereo;
if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
- new_sends = clampi(numSends, 0, clampi(new_sends, 0, MAX_SENDS));
+ new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
else
- new_sends = clampi(numSends, 0, MAX_SENDS);
+ new_sends = numSends;
}
else if(attrList && attrList[0])
{
- ALCuint freq, numMono, numStereo;
- ALCuint attrIdx = 0;
- ALCsizei numSends;
+ ALCsizei numMono, numStereo, numSends;
+ ALCsizei attrIdx = 0;
+ ALCuint freq;
/* If a context is already running on the device, stop playback so the
* device attributes can be updated. */
@@ -1928,9 +1991,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
{
numStereo = attrList[attrIdx + 1];
TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
- if(numStereo > device->SourcesMax)
- numStereo = device->SourcesMax;
+ numStereo = clampi(numStereo, 0, device->SourcesMax);
numMono = device->SourcesMax - numStereo;
}
@@ -1938,6 +2000,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
{
numSends = attrList[attrIdx + 1];
TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
+ numSends = clampi(numSends, 0, MAX_SENDS);
}
if(attrList[attrIdx] == ALC_HRTF_SOFT)
@@ -1975,9 +2038,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->NumStereoSources = numStereo;
if(ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
- new_sends = clampi(numSends, 0, clampi(new_sends, 0, MAX_SENDS));
+ new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
else
- new_sends = clampi(numSends, 0, MAX_SENDS);
+ new_sends = numSends;
}
if((device->Flags&DEVICE_RUNNING))
@@ -1989,6 +2052,13 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
al_free(device->Bs2b);
device->Bs2b = NULL;
+ al_free(device->ChannelDelay[0].Buffer);
+ for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
+ {
+ device->ChannelDelay[i].Length = 0;
+ device->ChannelDelay[i].Buffer = NULL;
+ }
+
al_free(device->Dry.Buffer);
device->Dry.Buffer = NULL;
device->Dry.NumChannels = 0;
@@ -2270,6 +2340,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
*/
static ALCvoid FreeDevice(ALCdevice *device)
{
+ ALsizei i;
+
TRACE("%p\n", device);
V0(device->Backend,close)();
@@ -2323,6 +2395,14 @@ static ALCvoid FreeDevice(ALCdevice *device)
ambiup_free(device->AmbiUp);
device->AmbiUp = NULL;
+ al_free(device->ChannelDelay[0].Buffer);
+ for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
+ {
+ device->ChannelDelay[i].Gain = 1.0f;
+ device->ChannelDelay[i].Length = 0;
+ device->ChannelDelay[i].Buffer = NULL;
+ }
+
AL_STRING_DEINIT(device->DeviceName);
al_free(device->Dry.Buffer);
@@ -2883,6 +2963,14 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
}
+static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
+{
+ if(device->Type == Loopback && device->FmtChans >= DevFmtAmbi1 &&
+ device->FmtChans <= DevFmtAmbi3)
+ return 23;
+ return 17;
+}
+
static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
{
ALCsizei i;
@@ -2914,6 +3002,9 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
case ALC_CAPTURE_SAMPLES:
case ALC_FORMAT_CHANNELS_SOFT:
case ALC_FORMAT_TYPE_SOFT:
+ case ALC_AMBISONIC_LAYOUT_SOFT:
+ case ALC_AMBISONIC_SCALING_SOFT:
+ case ALC_AMBISONIC_ORDER_SOFT:
alcSetError(NULL, ALC_INVALID_DEVICE);
return 0;
@@ -2965,11 +3056,11 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
return 1;
case ALC_ATTRIBUTES_SIZE:
- values[0] = 17;
+ values[0] = NumAttrsForDevice(device);
return 1;
case ALC_ALL_ATTRIBUTES:
- if(size < 17)
+ if(size < NumAttrsForDevice(device))
{
alcSetError(device, ALC_INVALID_VALUE);
return 0;
@@ -2990,8 +3081,25 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
}
else
{
- values[i++] = ALC_FORMAT_CHANNELS_SOFT;
- values[i++] = device->FmtChans;
+ if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
+ {
+ values[i++] = ALC_FORMAT_CHANNELS_SOFT;
+ values[i++] = ALC_BFORMAT3D_SOFT;
+
+ values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
+ values[i++] = device->AmbiLayout;
+
+ values[i++] = ALC_AMBISONIC_SCALING_SOFT;
+ values[i++] = device->AmbiScale;
+
+ values[i++] = ALC_AMBISONIC_ORDER_SOFT;
+ values[i++] = device->FmtChans-DevFmtAmbi1+1;
+ }
+ else
+ {
+ values[i++] = ALC_FORMAT_CHANNELS_SOFT;
+ values[i++] = device->FmtChans;
+ }
values[i++] = ALC_FORMAT_TYPE_SOFT;
values[i++] = device->FmtType;
@@ -3046,7 +3154,10 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
alcSetError(device, ALC_INVALID_DEVICE);
return 0;
}
- values[0] = device->FmtChans;
+ if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
+ values[0] = ALC_BFORMAT3D_SOFT;
+ else
+ values[0] = device->FmtChans;
return 1;
case ALC_FORMAT_TYPE_SOFT:
@@ -3058,6 +3169,36 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
values[0] = device->FmtType;
return 1;
+ case ALC_AMBISONIC_LAYOUT_SOFT:
+ if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
+ device->FmtChans <= DevFmtAmbi3))
+ {
+ alcSetError(device, ALC_INVALID_DEVICE);
+ return 0;
+ }
+ values[0] = device->AmbiLayout;
+ return 1;
+
+ case ALC_AMBISONIC_SCALING_SOFT:
+ if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
+ device->FmtChans <= DevFmtAmbi3))
+ {
+ alcSetError(device, ALC_INVALID_DEVICE);
+ return 0;
+ }
+ values[0] = device->AmbiScale;
+ return 1;
+
+ case ALC_AMBISONIC_ORDER_SOFT:
+ if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
+ device->FmtChans <= DevFmtAmbi3))
+ {
+ alcSetError(device, ALC_INVALID_DEVICE);
+ return 0;
+ }
+ values[0] = device->FmtChans - DevFmtAmbi1 + 1;
+ return 1;
+
case ALC_MONO_SOURCES:
values[0] = device->NumMonoSources;
return 1;
@@ -3567,6 +3708,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
const ALCchar *fmt;
ALCdevice *device;
ALCenum err;
+ ALCsizei i;
DO_INITCONFIG();
@@ -3628,6 +3770,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
InitUIntMap(&device->EffectMap, ~0);
InitUIntMap(&device->FilterMap, ~0);
+ for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
+ {
+ device->ChannelDelay[i].Gain = 1.0f;
+ device->ChannelDelay[i].Length = 0;
+ device->ChannelDelay[i].Buffer = NULL;
+ }
+
//Set output format
device->FmtChans = DevFmtChannelsDefault;
device->FmtType = DevFmtTypeDefault;
@@ -3871,6 +4020,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
{
ALCdevice *device = NULL;
ALCenum err;
+ ALCsizei i;
DO_INITCONFIG();
@@ -3916,6 +4066,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
InitUIntMap(&device->EffectMap, ~0);
InitUIntMap(&device->FilterMap, ~0);
+ for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
+ {
+ device->ChannelDelay[i].Gain = 1.0f;
+ device->ChannelDelay[i].Length = 0;
+ device->ChannelDelay[i].Buffer = NULL;
+ }
+
if(!CaptureBackend.getFactory)
device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
ALCbackend_Capture);
@@ -4078,6 +4235,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
{
ALCbackendFactory *factory;
ALCdevice *device;
+ ALCsizei i;
DO_INITCONFIG();
@@ -4128,6 +4286,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
InitUIntMap(&device->EffectMap, ~0);
InitUIntMap(&device->FilterMap, ~0);
+ for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
+ {
+ device->ChannelDelay[i].Gain = 1.0f;
+ device->ChannelDelay[i].Length = 0;
+ device->ChannelDelay[i].Buffer = NULL;
+ }
+
factory = ALCloopbackFactory_getFactory();
device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
if(!device->Backend)
@@ -4191,9 +4356,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device
alcSetError(device, ALC_INVALID_VALUE);
else
{
- if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
- IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
- freq >= MIN_OUTPUT_RATE)
+ if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
ret = ALC_TRUE;
}
if(device) ALCdevice_DecRef(device);
@@ -4223,6 +4386,28 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL
/************************************************
+ * ALC loopback2 functions
+ ************************************************/
+
+ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
+{
+ ALCboolean ret = ALC_FALSE;
+
+ if(!VerifyDevice(&device) || device->Type != Loopback)
+ alcSetError(device, ALC_INVALID_DEVICE);
+ else if(order <= 0)
+ alcSetError(device, ALC_INVALID_VALUE);
+ else
+ {
+ if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
+ ret = ALC_TRUE;
+ }
+ if(device) ALCdevice_DecRef(device);
+
+ return ret;
+}
+
+/************************************************
* ALC DSP pause/resume functions
************************************************/
diff --git a/Alc/ALu.c b/Alc/ALu.c
index b4938152..0a1b919a 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1224,9 +1224,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro
}
}
-static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force)
+static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *context, ALboolean force)
{
- ALsource *source = voice->Source;
const ALbufferlistitem *BufferListItem;
struct ALsourceProps *props;
@@ -1278,11 +1277,8 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot)
voice_end = voice + ctx->VoiceCount;
for(;voice != voice_end;++voice)
{
- if(!(source=(*voice)->Source)) continue;
- if(!IsPlayingOrPaused(source))
- (*voice)->Source = NULL;
- else
- CalcSourceParams(*voice, ctx, force);
+ if((source=(*voice)->Source) != NULL)
+ CalcSourceParams(*voice, source, ctx, force);
}
}
IncrementRef(&ctx->UpdateCount);
@@ -1332,24 +1328,24 @@ static void Write_##T(const ALfloatBUFFERSIZE *InBuffer, ALvoid *OutBuffer, \
T *restrict out = (T*)OutBuffer + j; \
const ALfloat gain = distcomp[j].Gain; \
const ALsizei base = distcomp[j].Length; \
+ ALfloat *restrict distbuf = ASSUME_ALIGNED(distcomp[j].Buffer, 16); \
if(base > 0 || gain != 1.0f) \
{ \
if(SamplesToDo >= base) \
{ \
for(i = 0;i < base;i++) \
- out[i*numchans] = func(distcomp[j].Buffer[i]*gain); \
+ out[i*numchans] = func(distbuf[i]*gain); \
for(;i < SamplesToDo;i++) \
out[i*numchans] = func(in[i-base]*gain); \
- memcpy(distcomp[j].Buffer, &in[SamplesToDo-base], \
- base*sizeof(ALfloat)); \
+ memcpy(distbuf, &in[SamplesToDo-base], base*sizeof(ALfloat)); \
} \
else \
{ \
for(i = 0;i < SamplesToDo;i++) \
- out[i*numchans] = func(distcomp[j].Buffer[i]*gain); \
- memmove(distcomp[j].Buffer, distcomp[j].Buffer+SamplesToDo, \
+ out[i*numchans] = func(distbuf[i]*gain); \
+ memmove(distbuf, distbuf+SamplesToDo, \
(base-SamplesToDo)*sizeof(ALfloat)); \
- memcpy(distcomp[j].Buffer+base-SamplesToDo, in, \
+ memcpy(distbuf+base-SamplesToDo, in, \
SamplesToDo*sizeof(ALfloat)); \
} \
} \
@@ -1423,13 +1419,15 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
voice_end = voice + ctx->VoiceCount;
for(;voice != voice_end;++voice)
{
- ALboolean IsVoiceInit = ((*voice)->Step > 0);
source = (*voice)->Source;
- if(IsVoiceInit && source &&
- ATOMIC_LOAD(&source->state, almemory_order_relaxed) == AL_PLAYING)
+ if(source && ATOMIC_LOAD(&(*voice)->Playing, almemory_order_relaxed) &&
+ (*voice)->Step > 0)
{
if(!MixSource(*voice, source, device, SamplesToDo))
+ {
(*voice)->Source = NULL;
+ ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release);
+ }
}
}
@@ -1596,6 +1594,7 @@ void aluHandleDisconnect(ALCdevice *device)
{
ALsource *source = (*voice)->Source;
(*voice)->Source = NULL;
+ ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release);
if(source)
{
diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c
index a0aa4e44..92a2aecf 100644
--- a/Alc/bformatdec.c
+++ b/Alc/bformatdec.c
@@ -6,6 +6,7 @@
#include "mixer_defs.h"
#include "alu.h"
+#include "bool.h"
#include "threads.h"
#include "almalloc.h"
@@ -181,7 +182,6 @@ typedef struct BFormatDec {
ALsizei NumChannels;
ALboolean DualBand;
- ALboolean Periphonic;
} BFormatDec;
BFormatDec *bformatdec_alloc()
@@ -204,29 +204,13 @@ void bformatdec_free(BFormatDec *dec)
}
}
-int bformatdec_getOrder(const struct BFormatDec *dec)
-{
- if(dec->Periphonic)
- {
- if(dec->NumChannels > 9) return 3;
- if(dec->NumChannels > 4) return 2;
- if(dec->NumChannels > 1) return 1;
- }
- else
- {
- if(dec->NumChannels > 5) return 3;
- if(dec->NumChannels > 3) return 2;
- if(dec->NumChannels > 1) return 1;
- }
- return 0;
-}
-
void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS])
{
static const ALsizei map2DTo3D[MAX_AMBI2D_COEFFS] = {
0, 1, 3, 4, 8, 9, 15
};
const ALfloat *coeff_scale = UnitScale;
+ bool periphonic;
ALfloat ratio;
ALsizei i;
@@ -256,7 +240,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount
bandsplit_init(&dec->UpSampler[i].XOver, ratio);
if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
{
- dec->Periphonic = AL_TRUE;
+ periphonic = true;
dec->UpSampler[0].Gains[FB_HighFreq] = (dec->NumChannels > 9) ? W_SCALE3D_THIRD :
(dec->NumChannels > 4) ? W_SCALE3D_SECOND : 1.0f;
@@ -270,7 +254,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount
}
else
{
- dec->Periphonic = AL_FALSE;
+ periphonic = false;
dec->UpSampler[0].Gains[FB_HighFreq] = (dec->NumChannels > 5) ? W_SCALE2D_THIRD :
(dec->NumChannels > 3) ? W_SCALE2D_SECOND : 1.0f;
@@ -295,7 +279,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount
ALfloat gain;
ALsizei j, k;
- if(!dec->Periphonic)
+ if(!periphonic)
{
for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
{
@@ -339,7 +323,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount
ALfloat gain;
ALsizei j, k;
- if(!dec->Periphonic)
+ if(!periphonic)
{
for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++)
{
diff --git a/Alc/bformatdec.h b/Alc/bformatdec.h
index 889d59f4..162f2652 100644
--- a/Alc/bformatdec.h
+++ b/Alc/bformatdec.h
@@ -28,7 +28,6 @@ struct AmbiUpsampler;
struct BFormatDec *bformatdec_alloc();
void bformatdec_free(struct BFormatDec *dec);
-int bformatdec_getOrder(const struct BFormatDec *dec);
void bformatdec_reset(struct BFormatDec *dec, const struct AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]);
/* Decodes the ambisonic input to the given output channels. */
diff --git a/Alc/panning.c b/Alc/panning.c
index 77f8e31b..c4d3e43f 100644
--- a/Alc/panning.c
+++ b/Alc/panning.c
@@ -616,6 +616,7 @@ static void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const AL
{
const char *devname = al_string_get_cstr(device->DeviceName);
ALfloat maxdist = 0.0f;
+ ALsizei total = 0;
ALsizei i;
for(i = 0;i < conf->NumSpeakers;i++)
@@ -649,6 +650,21 @@ static void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const AL
al_string_get_cstr(conf->Speakers[i].Name), device->ChannelDelay[chan].Length,
device->ChannelDelay[chan].Gain
);
+
+ /* Round up to the next 4th sample, so each channel buffer starts
+ * 16-byte aligned.
+ */
+ total += RoundUp(device->ChannelDelay[chan].Length, 4);
+ }
+ }
+
+ if(total > 0)
+ {
+ device->ChannelDelay[0].Buffer = al_calloc(16, total * sizeof(ALfloat));
+ for(i = 1;i < MAX_OUTPUT_CHANNELS;i++)
+ {
+ size_t len = RoundUp(device->ChannelDelay[i-1].Length, 4);
+ device->ChannelDelay[i].Buffer = device->ChannelDelay[i-1].Buffer + len;
}
}
}
@@ -775,7 +791,7 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsiz
);
bformatdec_reset(device->AmbiDecoder, conf, count, device->Frequency, speakermap);
- if(bformatdec_getOrder(device->AmbiDecoder) < 2)
+ if(!(conf->ChanMask > 0xf))
{
device->FOAOut.Ambi = device->Dry.Ambi;
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 23572a90..cc30dcef 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -29,6 +29,29 @@
#include "almalloc.h"
#include "threads.h"
+#ifndef ALC_SOFT_loopback2
+#define ALC_SOFT_loopback2 1
+#define ALC_AMBISONIC_LAYOUT_SOFT 0x1997
+#define ALC_AMBISONIC_SCALING_SOFT 0x1998
+#define ALC_AMBISONIC_ORDER_SOFT 0x1999
+
+#define ALC_BFORMAT3D_SOFT 0x1508
+
+/* Ambisonic layouts */
+#define ALC_ACN_SOFT 0x1600
+#define ALC_FUMA_SOFT 0x1601
+
+/* Ambisonic scalings (normalization) */
+#define ALC_N3D_SOFT 0x1700
+#define ALC_SN3D_SOFT 0x1701
+/*#define ALC_FUMA_SOFT*/
+
+typedef ALCboolean (ALC_APIENTRY*LPALCISAMBISONICFORMATSUPPORTEDSOFT)(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order);
+#ifdef AL_ALEXT_PROTOTYPES
+ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order);
+#endif
+#endif
+
#ifndef ALC_SOFT_device_clock
#define ALC_SOFT_device_clock 1
typedef int64_t ALCint64SOFT;
@@ -408,9 +431,6 @@ typedef struct {
ALCboolean alc_ca_init(BackendFuncs *func_list);
void alc_ca_deinit(void);
void alc_ca_probe(enum DevProbe type);
-ALCboolean alc_opensl_init(BackendFuncs *func_list);
-void alc_opensl_deinit(void);
-void alc_opensl_probe(enum DevProbe type);
ALCboolean alc_qsa_init(BackendFuncs *func_list);
void alc_qsa_deinit(void);
void alc_qsa_probe(enum DevProbe type);
@@ -511,16 +531,16 @@ inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType ty
}
enum AmbiLayout {
- AmbiLayout_FuMa, /* FuMa channel order */
- AmbiLayout_ACN, /* ACN channel order */
+ AmbiLayout_FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
+ AmbiLayout_ACN = ALC_ACN_SOFT, /* ACN channel order */
AmbiLayout_Default = AmbiLayout_ACN
};
enum AmbiNorm {
- AmbiNorm_FuMa, /* FuMa normalization */
- AmbiNorm_SN3D, /* SN3D normalization */
- AmbiNorm_N3D, /* N3D normalization */
+ AmbiNorm_FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
+ AmbiNorm_SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
+ AmbiNorm_N3D = ALC_N3D_SOFT, /* N3D normalization */
AmbiNorm_Default = AmbiNorm_SN3D
};
@@ -611,12 +631,12 @@ TYPEDEF_VECTOR(HrtfEntry, vector_HrtfEntry)
/* Maximum delay in samples for speaker distance compensation. */
-#define MAX_DELAY_LENGTH 128
+#define MAX_DELAY_LENGTH 1024
typedef struct DistanceComp {
ALfloat Gain;
ALsizei Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
- alignas(16) ALfloat Buffer[MAX_DELAY_LENGTH];
+ ALfloat *Buffer;
} DistanceComp;
/* Size for temporary storage of buffer data, in ALfloats. Larger values need
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index f8a32f71..fc1756e5 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -1,13 +1,14 @@
#ifndef _AL_SOURCE_H_
#define _AL_SOURCE_H_
-#define MAX_SENDS 16
-#define DEFAULT_SENDS 2
-
+#include "bool.h"
#include "alMain.h"
#include "alu.h"
#include "hrtf.h"
+#define MAX_SENDS 16
+#define DEFAULT_SENDS 2
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -80,6 +81,7 @@ typedef struct ALvoice {
struct ALsourceProps *Props;
struct ALsource *Source;
+ ATOMIC(bool) Playing;
/* Current buffer queue item being played. */
ATOMIC(ALbufferlistitem*) current_buffer;
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 40aa855c..14329bc2 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -1637,8 +1637,11 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
FreeThunkEntry(Source->id);
ALCdevice_Lock(device);
- voice = GetSourceVoice(Source, context);
- if(voice) voice->Source = NULL;
+ if((voice=GetSourceVoice(Source, context)) != NULL)
+ {
+ voice->Source = NULL;
+ ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
+ }
ALCdevice_Unlock(device);
DeinitSource(Source, device->NumAuxSends);
@@ -2963,6 +2966,8 @@ void UpdateAllSourceProps(ALCcontext *context)
*/
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
{
+ ALCdevice *device = Context->Device;
+ ALuint refcount;
ALvoice *voice;
WriteLock(&Source->queue_lock);
@@ -2994,11 +2999,12 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
{
case AL_PLAYING:
assert(voice != NULL);
- /* A source that's already playing is restarted. */
+ /* A source that's already playing is restarted from the beginning. */
ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed);
ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed);
ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release);
- /* fall-through */
+ goto done;
+
case AL_PAUSED:
assert(voice != NULL);
/* A source that's paused simply resumes. Make sure it uses the
@@ -3006,12 +3012,16 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
* it stopped at.
*/
voice->Moving = AL_FALSE;
+ ATOMIC_STORE(&voice->Playing, true, almemory_order_release);
goto done;
default:
break;
}
+ Source->NeedsUpdate = AL_FALSE;
+ UpdateSourceProps(Source, device->NumAuxSends);
+
/* Make sure this source isn't already active, and if not, look for an
* unused voice to put it in.
*/
@@ -3021,22 +3031,20 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
if(Context->Voices[i]->Source == NULL)
{
voice = Context->Voices[i];
- voice->Source = Source;
break;
}
}
if(voice == NULL)
- {
voice = Context->Voices[Context->VoiceCount++];
- voice->Source = Source;
- }
+ ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
+ ATOMIC_THREAD_FENCE(almemory_order_acquire);
/* A source that's not playing or paused has any offset applied when it
* starts playing.
*/
ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed);
ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed);
- ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release);
+ ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_relaxed);
if(Source->OffsetType != AL_NONE)
ApplyOffset(Source, voice);
@@ -3061,19 +3069,30 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
}
}
- Source->NeedsUpdate = AL_FALSE;
- UpdateSourceProps(Source, device->NumAuxSends);
+ voice->Source = Source;
+ ATOMIC_STORE(&voice->Playing, true, almemory_order_release);
}
else if(state == AL_PAUSED)
{
ALenum playing = AL_PLAYING;
+ if((voice=GetSourceVoice(Source, Context)) != NULL)
+ {
+ ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
+ while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1))
+ althrd_yield();
+ }
ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Source->state, &playing, AL_PAUSED);
}
else if(state == AL_STOPPED)
{
do_stop:
- voice = GetSourceVoice(Source, Context);
- if(voice) voice->Source = NULL;
+ if((voice=GetSourceVoice(Source, Context)) != NULL)
+ {
+ voice->Source = NULL;
+ ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
+ while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1))
+ althrd_yield();
+ }
if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL)
ATOMIC_STORE(&Source->state, AL_STOPPED, almemory_order_relaxed);
Source->OffsetType = AL_NONE;
@@ -3081,8 +3100,13 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
}
else if(state == AL_INITIAL)
{
- voice = GetSourceVoice(Source, Context);
- if(voice) voice->Source = NULL;
+ if((voice=GetSourceVoice(Source, Context)) != NULL)
+ {
+ voice->Source = NULL;
+ ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
+ while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1))
+ althrd_yield();
+ }
if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL)
ATOMIC_STORE(&Source->state, AL_INITIAL, almemory_order_relaxed);
Source->OffsetType = AL_NONE;
diff --git a/utils/alsoft-config/mainwindow.ui b/utils/alsoft-config/mainwindow.ui
index 18392430..806b0ce0 100644
--- a/utils/alsoft-config/mainwindow.ui
+++ b/utils/alsoft-config/mainwindow.ui
@@ -635,9 +635,9 @@ configuration file.</string>
<widget class="QLineEdit" name="decoderQuadLineEdit">
<property name="geometry">
<rect>
- <x>150</x>
+ <x>120</x>
<y>30</y>
- <width>281</width>
+ <width>311</width>
<height>21</height>
</rect>
</property>
@@ -647,7 +647,7 @@ configuration file.</string>
<rect>
<x>20</x>
<y>30</y>
- <width>121</width>
+ <width>91</width>
<height>21</height>
</rect>
</property>
@@ -674,9 +674,9 @@ configuration file.</string>
<widget class="QLineEdit" name="decoder51LineEdit">
<property name="geometry">
<rect>
- <x>150</x>
+ <x>120</x>
<y>60</y>
- <width>281</width>
+ <width>311</width>
<height>21</height>
</rect>
</property>
@@ -699,7 +699,7 @@ configuration file.</string>
<rect>
<x>20</x>
<y>60</y>
- <width>121</width>
+ <width>91</width>
<height>21</height>
</rect>
</property>
@@ -715,7 +715,7 @@ configuration file.</string>
<rect>
<x>20</x>
<y>90</y>
- <width>121</width>
+ <width>91</width>
<height>21</height>
</rect>
</property>
@@ -729,9 +729,9 @@ configuration file.</string>
<widget class="QLineEdit" name="decoder61LineEdit">
<property name="geometry">
<rect>
- <x>150</x>
+ <x>120</x>
<y>90</y>
- <width>281</width>
+ <width>311</width>
<height>21</height>
</rect>
</property>
@@ -765,9 +765,9 @@ configuration file.</string>
<widget class="QLineEdit" name="decoder71LineEdit">
<property name="geometry">
<rect>
- <x>150</x>
+ <x>120</x>
<y>120</y>
- <width>281</width>
+ <width>311</width>
<height>21</height>
</rect>
</property>
@@ -777,7 +777,7 @@ configuration file.</string>
<rect>
<x>20</x>
<y>120</y>
- <width>121</width>
+ <width>91</width>
<height>21</height>
</rect>
</property>