aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/backends/oss.c64
-rw-r--r--Alc/bformatdec.c110
-rw-r--r--common/rwlock.c10
-rw-r--r--include/atomic.h52
-rw-r--r--include/rwlock.h9
5 files changed, 147 insertions, 98 deletions
diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c
index 432c75f2..689a5c71 100644
--- a/Alc/backends/oss.c
+++ b/Alc/backends/oss.c
@@ -88,7 +88,7 @@ static struct oss_device oss_capture = {
#ifdef ALC_OSS_COMPAT
-static void ALCossListPopulate(struct oss_device *UNUSED(playback), struct oss_device *UNUSED(capture))
+static void ALCossListPopulate(struct oss_device *UNUSED(devlist), int UNUSED(type_flag))
{
}
@@ -153,7 +153,7 @@ static void ALCossListAppend(struct oss_device *list, const char *handle, size_t
TRACE("Got device \"%s\", \"%s\"\n", next->handle, next->path);
}
-static void ALCossListPopulate(struct oss_device *playback, struct oss_device *capture)
+static void ALCossListPopulate(struct oss_device *devlist, int type_flag)
{
struct oss_sysinfo si;
struct oss_audioinfo ai;
@@ -193,10 +193,9 @@ static void ALCossListPopulate(struct oss_device *playback, struct oss_device *c
len = strnlen(ai.name, sizeof(ai.name));
handle = ai.name;
}
- if((ai.caps&DSP_CAP_INPUT) && capture != NULL)
- ALCossListAppend(capture, handle, len, ai.devnode, strnlen(ai.devnode, sizeof(ai.devnode)));
- if((ai.caps&DSP_CAP_OUTPUT) && playback != NULL)
- ALCossListAppend(playback, handle, len, ai.devnode, strnlen(ai.devnode, sizeof(ai.devnode)));
+ if((ai.caps&type_flag))
+ ALCossListAppend(devlist, handle, len, ai.devnode,
+ strnlen(ai.devnode, sizeof(ai.devnode)));
}
done:
@@ -320,18 +319,26 @@ static ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name)
struct oss_device *dev = &oss_playback;
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- if(!name)
+ if(!name || strcmp(name, dev->handle) == 0)
name = dev->handle;
else
{
- while (dev != NULL)
+ if(!dev->next)
+ {
+ ALCossListPopulate(&oss_playback, DSP_CAP_OUTPUT);
+ dev = &oss_playback;
+ }
+ while(dev != NULL)
{
if (strcmp(dev->handle, name) == 0)
break;
dev = dev->next;
}
- if (dev == NULL)
+ if(dev == NULL)
+ {
+ WARN("Could not find \"%s\" in device list\n", name);
return ALC_INVALID_VALUE;
+ }
}
self->killNow = 0;
@@ -574,18 +581,26 @@ static ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
int ossSpeed;
char *err;
- if(!name)
+ if(!name || strcmp(name, dev->handle) == 0)
name = dev->handle;
else
{
- while (dev != NULL)
+ if(!dev->next)
+ {
+ ALCossListPopulate(&oss_capture, DSP_CAP_INPUT);
+ dev = &oss_capture;
+ }
+ while(dev != NULL)
{
if (strcmp(dev->handle, name) == 0)
break;
dev = dev->next;
}
- if (dev == NULL)
+ if(dev == NULL)
+ {
+ WARN("Could not find \"%s\" in device list\n", name);
return ALC_INVALID_VALUE;
+ }
}
self->fd = open(dev->path, O_RDONLY);
@@ -770,33 +785,30 @@ ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory* UNUSED(self),
void ALCossBackendFactory_probe(ALCossBackendFactory* UNUSED(self), enum DevProbe type)
{
+ struct oss_device *cur;
switch(type)
{
case ALL_DEVICE_PROBE:
- {
- struct oss_device *cur = &oss_playback;
- ALCossListFree(cur);
- ALCossListPopulate(cur, NULL);
- while (cur != NULL)
+ ALCossListFree(&oss_playback);
+ ALCossListPopulate(&oss_playback, DSP_CAP_OUTPUT);
+ cur = &oss_playback;
+ while(cur != NULL)
{
AppendAllDevicesList(cur->handle);
cur = cur->next;
}
- }
- break;
+ break;
case CAPTURE_DEVICE_PROBE:
- {
- struct oss_device *cur = &oss_capture;
- ALCossListFree(cur);
- ALCossListPopulate(NULL, cur);
- while (cur != NULL)
+ ALCossListFree(&oss_capture);
+ ALCossListPopulate(&oss_capture, DSP_CAP_INPUT);
+ cur = &oss_capture;
+ while(cur != NULL)
{
AppendCaptureDeviceList(cur->handle);
cur = cur->next;
}
- }
- break;
+ break;
}
}
diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c
index 2aab4ed8..5556c2ef 100644
--- a/Alc/bformatdec.c
+++ b/Alc/bformatdec.c
@@ -135,7 +135,7 @@ static const ALfloat Ambi2DDecoder[4][FB_Max][MAX_AMBI_COEFFS] = {
{ { 0.353553f, 0.204094f, 0.0f, -0.204094f }, { 0.25f, 0.204094f, 0.0f, -0.204094f } },
{ { 0.353553f, -0.204094f, 0.0f, -0.204094f }, { 0.25f, -0.204094f, 0.0f, -0.204094f } },
};
-static ALfloat Ambi2DEncoder[4][MAX_AMBI_COEFFS];
+static ALfloat Ambi2DEncoderT[4][MAX_AMBI_COEFFS];
/* These points are in AL coordinates! */
static const ALfloat Ambi3DPoints[8][3] = {
@@ -158,7 +158,7 @@ static const ALfloat Ambi3DDecoder[8][FB_Max][MAX_AMBI_COEFFS] = {
{ { 0.25f, 0.1443375672f, -0.1443375672f, -0.1443375672f }, { 0.125f, 0.125f, -0.125f, -0.125f } },
{ { 0.25f, -0.1443375672f, -0.1443375672f, -0.1443375672f }, { 0.125f, -0.125f, -0.125f, -0.125f } },
};
-static ALfloat Ambi3DEncoder[8][MAX_AMBI_COEFFS];
+static ALfloat Ambi3DEncoderT[8][MAX_AMBI_COEFFS];
static RowMixerFunc MixMatrixRow = MixRow_C;
@@ -173,20 +173,53 @@ static void init_bformatdec(void)
MixMatrixRow = SelectRowMixer();
for(i = 0;i < COUNTOF(Ambi3DPoints);i++)
- CalcDirectionCoeffs(Ambi3DPoints[i], 0.0f, Ambi3DEncoder[i]);
+ CalcDirectionCoeffs(Ambi3DPoints[i], 0.0f, Ambi3DEncoderT[i]);
for(i = 0;i < COUNTOF(Ambi2DPoints);i++)
{
- CalcDirectionCoeffs(Ambi2DPoints[i], 0.0f, Ambi2DEncoder[i]);
+ CalcDirectionCoeffs(Ambi2DPoints[i], 0.0f, Ambi2DEncoderT[i]);
/* Remove the skipped height-related coefficients for 2D rendering. */
- Ambi2DEncoder[i][2] = Ambi2DEncoder[i][3];
- Ambi2DEncoder[i][3] = Ambi2DEncoder[i][4];
- Ambi2DEncoder[i][4] = Ambi2DEncoder[i][8];
- Ambi2DEncoder[i][5] = Ambi2DEncoder[i][9];
- Ambi2DEncoder[i][6] = Ambi2DEncoder[i][15];
+ Ambi2DEncoderT[i][2] = Ambi2DEncoderT[i][3];
+ Ambi2DEncoderT[i][3] = Ambi2DEncoderT[i][4];
+ Ambi2DEncoderT[i][4] = Ambi2DEncoderT[i][8];
+ Ambi2DEncoderT[i][5] = Ambi2DEncoderT[i][9];
+ Ambi2DEncoderT[i][6] = Ambi2DEncoderT[i][15];
for(j = 7;j < MAX_AMBI_COEFFS;j++)
- Ambi2DEncoder[i][j] = 0.0f;
+ Ambi2DEncoderT[i][j] = 0.0f;
+ }
+}
+
+
+/* This typedef is needed for SAFE_CONST to work. */
+typedef ALfloat ALfloatMAX_AMBI_COEFFS[MAX_AMBI_COEFFS];
+
+static void GenUpsamplerGains(const ALfloat (*restrict EncoderT)[MAX_AMBI_COEFFS],
+ const ALfloat (*restrict Decoder)[FB_Max][MAX_AMBI_COEFFS],
+ ALsizei InChannels,
+ ALfloat (*restrict OutGains)[MAX_OUTPUT_CHANNELS][FB_Max],
+ ALsizei OutChannels)
+{
+ ALsizei i, j, k;
+
+ /* Combine the matrices that do the in->virt and virt->out conversions so
+ * we get a single in->out conversion. NOTE: the Encoder matrix and output
+ * are transposed, so the input channels line up with the rows and the
+ * output channels line up with the columns.
+ */
+ for(i = 0;i < 4;i++)
+ {
+ for(j = 0;j < OutChannels;j++)
+ {
+ ALfloat hfgain=0.0f, lfgain=0.0f;
+ for(k = 0;k < InChannels;k++)
+ {
+ hfgain += Decoder[k][FB_HighFreq][i]*EncoderT[k][j];
+ lfgain += Decoder[k][FB_LowFreq][i]*EncoderT[k][j];
+ }
+ OutGains[i][j][FB_HighFreq] = hfgain;
+ OutGains[i][j][FB_LowFreq] = lfgain;
+ }
}
}
@@ -272,7 +305,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount,
const ALfloat *coeff_scale = UnitScale;
ALfloat distgain[MAX_OUTPUT_CHANNELS];
ALfloat maxdist, ratio;
- ALuint i, j, k;
+ ALuint i;
al_free(dec->Samples);
dec->Samples = NULL;
@@ -300,39 +333,16 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALuint chancount,
memset(dec->UpSampler.Gains, 0, sizeof(dec->UpSampler.Gains));
if((conf->ChanMask&AMBI_PERIPHONIC_MASK))
{
- /* Combine the matrices that do the in->virt and virt->out conversions
- * so we get a single in->out conversion.
- */
- for(i = 0;i < 4;i++)
- {
- for(j = 0;j < dec->NumChannels;j++)
- {
- ALfloat *gains = dec->UpSampler.Gains[i][j];
- for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
- {
- gains[FB_HighFreq] += Ambi3DDecoder[k][FB_HighFreq][i]*Ambi3DEncoder[k][j];
- gains[FB_LowFreq] += Ambi3DDecoder[k][FB_LowFreq][i]*Ambi3DEncoder[k][j];
- }
- }
- }
-
+ GenUpsamplerGains(SAFE_CONST(ALfloatMAX_AMBI_COEFFS*,Ambi3DEncoderT),
+ Ambi3DDecoder, COUNTOF(Ambi3DDecoder),
+ dec->UpSampler.Gains, dec->NumChannels);
dec->Periphonic = AL_TRUE;
}
else
{
- for(i = 0;i < 4;i++)
- {
- for(j = 0;j < dec->NumChannels;j++)
- {
- ALfloat *gains = dec->UpSampler.Gains[i][j];
- for(k = 0;k < COUNTOF(Ambi2DDecoder);k++)
- {
- gains[FB_HighFreq] += Ambi2DDecoder[k][FB_HighFreq][i]*Ambi2DEncoder[k][j];
- gains[FB_LowFreq] += Ambi2DDecoder[k][FB_LowFreq][i]*Ambi2DEncoder[k][j];
- }
- }
- }
-
+ GenUpsamplerGains(SAFE_CONST(ALfloatMAX_AMBI_COEFFS*,Ambi2DEncoderT),
+ Ambi2DDecoder, COUNTOF(Ambi2DDecoder),
+ dec->UpSampler.Gains, dec->NumChannels);
dec->Periphonic = AL_FALSE;
}
@@ -627,27 +637,19 @@ void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device)
{
ALfloat gains[8][MAX_OUTPUT_CHANNELS];
ALfloat ratio;
- ALuint i, j, k;
+ ALuint i;
ratio = 400.0f / (ALfloat)device->Frequency;
for(i = 0;i < 4;i++)
bandsplit_init(&ambiup->XOver[i], ratio);
- for(i = 0;i < COUNTOF(Ambi3DEncoder);i++)
- ComputePanningGains(device->Dry, Ambi3DEncoder[i], 1.0f, gains[i]);
+ for(i = 0;i < COUNTOF(Ambi3DEncoderT);i++)
+ ComputePanningGains(device->Dry, Ambi3DEncoderT[i], 1.0f, gains[i]);
memset(ambiup->Gains, 0, sizeof(ambiup->Gains));
- for(i = 0;i < 4;i++)
- {
- for(j = 0;j < device->Dry.NumChannels;j++)
- {
- for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
- {
- ambiup->Gains[i][j][FB_HighFreq] += Ambi3DDecoder[k][FB_HighFreq][i]*gains[k][j];
- ambiup->Gains[i][j][FB_LowFreq] += Ambi3DDecoder[k][FB_LowFreq][i]*gains[k][j];
- }
- }
- }
+ GenUpsamplerGains(SAFE_CONST(ALfloatMAX_AMBI_COEFFS*,gains),
+ Ambi3DDecoder, COUNTOF(Ambi3DDecoder),
+ ambiup->Gains, device->Dry.NumChannels);
}
void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo)
diff --git a/common/rwlock.c b/common/rwlock.c
index f1a86fa6..67cf3acf 100644
--- a/common/rwlock.c
+++ b/common/rwlock.c
@@ -11,19 +11,19 @@
/* A simple spinlock. Yield the thread while the given integer is set by
* another. Could probably be improved... */
#define LOCK(l) do { \
- while(ATOMIC_EXCHANGE(int, &(l), true, almemory_order_acq_rel) == true) \
+ while(ATOMIC_FLAG_TEST_AND_SET(&(l), almemory_order_acq_rel) == true) \
althrd_yield(); \
} while(0)
-#define UNLOCK(l) ATOMIC_STORE(&(l), false, almemory_order_release)
+#define UNLOCK(l) ATOMIC_FLAG_CLEAR(&(l), almemory_order_release)
void RWLockInit(RWLock *lock)
{
InitRef(&lock->read_count, 0);
InitRef(&lock->write_count, 0);
- ATOMIC_INIT(&lock->read_lock, false);
- ATOMIC_INIT(&lock->read_entry_lock, false);
- ATOMIC_INIT(&lock->write_lock, false);
+ ATOMIC_FLAG_CLEAR(&lock->read_lock, almemory_order_relaxed);
+ ATOMIC_FLAG_CLEAR(&lock->read_entry_lock, almemory_order_relaxed);
+ ATOMIC_FLAG_CLEAR(&lock->write_lock, almemory_order_relaxed);
}
void ReadLock(RWLock *lock)
diff --git a/include/atomic.h b/include/atomic.h
index 3a662f8e..4dff05da 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -22,9 +22,11 @@ extern "C" {
#define almemory_order_seq_cst memory_order_seq_cst
#define ATOMIC(T) T _Atomic
+#define ATOMIC_FLAG atomic_flag
#define ATOMIC_INIT(_val, _newval) atomic_init((_val), (_newval))
#define ATOMIC_INIT_STATIC(_newval) ATOMIC_VAR_INIT(_newval)
+/*#define ATOMIC_FLAG_INIT ATOMIC_FLAG_INIT*/
#define PARAM2(f, a, b, ...) (f((a), (b)))
#define PARAM3(f, a, b, c, ...) (f((a), (b), (c)))
@@ -42,6 +44,11 @@ extern "C" {
#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) \
PARAM5(atomic_compare_exchange_weak_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst)
+#define ATOMIC_FLAG_TEST_AND_SET(...) \
+ PARAM2(atomic_flag_test_and_set_explicit, __VA_ARGS__, memory_order_seq_cst)
+#define ATOMIC_FLAG_CLEAR(...) \
+ PARAM2(atomic_flag_clear_explicit, __VA_ARGS__, memory_order_seq_cst)
+
#define ATOMIC_THREAD_FENCE atomic_thread_fence
/* Atomics using GCC intrinsics */
@@ -57,9 +64,11 @@ enum almemory_order {
};
#define ATOMIC(T) struct { T volatile value; }
+#define ATOMIC_FLAG ATOMIC(int)
#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0)
#define ATOMIC_INIT_STATIC(_newval) {(_newval)}
+#define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0)
#define ATOMIC_LOAD(_val, ...) __extension__({ \
__typeof((_val)->value) _r = (_val)->value; \
@@ -76,6 +85,7 @@ enum almemory_order {
#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
+ __asm__ __volatile__("" ::: "memory"); \
__sync_lock_test_and_set(&(_val)->value, (_newval)); \
})
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \
@@ -85,6 +95,16 @@ enum almemory_order {
*(_oldval) == _o; \
})
+#define ATOMIC_FLAG_TEST_AND_SET(_val, ...) __extension__({ \
+ __asm__ __volatile__("" ::: "memory"); \
+ __sync_lock_test_and_set(&(_val)->value, 1); \
+})
+#define ATOMIC_FLAG_CLEAR(_val, ...) __extension__({ \
+ __sync_lock_release(&(_val)->value); \
+ __asm__ __volatile__("" ::: "memory"); \
+})
+
+
#define ATOMIC_THREAD_FENCE(order) do { \
enum { must_be_constant = (order) }; \
const int _o = must_be_constant; \
@@ -297,19 +317,23 @@ int _al_invalid_atomic_size(); /* not defined */
#define ATOMIC(T) T
+#define ATOMIC_INIT(_val, _newval) ((void)0)
#define ATOMIC_INIT_STATIC(_newval) (0)
-#define ATOMIC_LOAD_UNSAFE(_val) (0)
-#define ATOMIC_STORE_UNSAFE(_val, _newval) ((void)0)
+#define ATOMIC_LOAD(...) (0)
+#define ATOMIC_STORE(...) ((void)0)
-#define ATOMIC_LOAD(_val, ...) (0)
-#define ATOMIC_STORE(_val, _newval, ...) ((void)0)
+#define ATOMIC_ADD(...) (0)
+#define ATOMIC_SUB(...) (0)
-#define ATOMIC_ADD(_val, _incr, ...) (0)
-#define ATOMIC_SUB(_val, _decr, ...) (0)
+#define ATOMIC_EXCHANGE(T, ...) (0)
+#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, ...) (0)
+#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) (0)
-#define ATOMIC_EXCHANGE(T, _val, _newval, ...) (0)
-#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) (0)
+#define ATOMIC_FLAG_TEST_AND_SET(...) (0)
+#define ATOMIC_FLAG_CLEAR(...) ((void)0)
+
+#define ATOMIC_THREAD_FENCE ((void)0)
#endif
/* If no weak cmpxchg is provided (not all systems will have one), substitute a
@@ -318,6 +342,18 @@ int _al_invalid_atomic_size(); /* not defined */
#define ATOMIC_COMPARE_EXCHANGE_WEAK ATOMIC_COMPARE_EXCHANGE_STRONG
#endif
+/* If no ATOMIC_FLAG is defined, simulate one with an atomic int using exchange
+ * and store ops.
+ */
+#ifndef ATOMIC_FLAG
+#define ATOMIC_FLAG ATOMIC(int)
+#define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0)
+#define ATOMIC_FLAG_TEST_AND_SET_(_val, ...) ATOMIC_EXCHANGE(int, _val, 1, __VA_ARGS__)
+#define ATOMIC_FLAG_TEST_AND_SET(...) ATOMIC_FLAG_TEST_AND_SET_(__VA_ARGS__, almemory_order_seq_cst)
+#define ATOMIC_FLAG_CLEAR_(_val, ...) ATOMIC_STORE(_val, 0, __VA_ARGS__)
+#define ATOMIC_FLAG_CLEAR(...) ATOMIC_FLAG_CLEAR_(__VA_ARGS__, almemory_order_seq_cst)
+#endif
+
typedef unsigned int uint;
typedef ATOMIC(uint) RefCount;
diff --git a/include/rwlock.h b/include/rwlock.h
index 158a0670..8e36fa1a 100644
--- a/include/rwlock.h
+++ b/include/rwlock.h
@@ -11,13 +11,12 @@ extern "C" {
typedef struct {
RefCount read_count;
RefCount write_count;
- ATOMIC(int) read_lock;
- ATOMIC(int) read_entry_lock;
- ATOMIC(int) write_lock;
+ ATOMIC_FLAG read_lock;
+ ATOMIC_FLAG read_entry_lock;
+ ATOMIC_FLAG write_lock;
} RWLock;
#define RWLOCK_STATIC_INITIALIZE { ATOMIC_INIT_STATIC(0), ATOMIC_INIT_STATIC(0), \
- ATOMIC_INIT_STATIC(false), ATOMIC_INIT_STATIC(false), \
- ATOMIC_INIT_STATIC(false) }
+ ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT }
void RWLockInit(RWLock *lock);
void ReadLock(RWLock *lock);