Updated SDL, Bullet and OpenAL soft libs

Fixed case sensitivity problem
Fixed clang compiler problem with having the class namespace used in an inline for the == operator
Tweaked some theme stuff to be more consistent.
Added initial test of no-pie for linux
test sidestep of getTexCoord in shadergen hlsl feature so we don't assert when getting the terrain's shaderstuffs(which uses float3 instead of normal float2)
This commit is contained in:
Areloch 2019-07-07 02:43:49 -05:00
parent e87dc787ee
commit f8750dd8ed
1102 changed files with 205083 additions and 62836 deletions

View file

@ -1153,10 +1153,17 @@ error2:
static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self)
{
int err = snd_pcm_start(self->pcmHandle);
int err = snd_pcm_prepare(self->pcmHandle);
if(err < 0)
ERR("prepare failed: %s\n", snd_strerror(err));
else
{
err = snd_pcm_start(self->pcmHandle);
if(err < 0)
ERR("start failed: %s\n", snd_strerror(err));
}
if(err < 0)
{
ERR("start failed: %s\n", snd_strerror(err));
aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, "Capture state failure: %s",
snd_strerror(err));
return ALC_FALSE;
@ -1368,11 +1375,6 @@ static ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
}
static inline void AppendAllDevicesList2(const DevMap *entry)
{ AppendAllDevicesList(alstr_get_cstr(entry->name)); }
static inline void AppendCaptureDeviceList2(const DevMap *entry)
{ AppendCaptureDeviceList(alstr_get_cstr(entry->name)); }
typedef struct ALCalsaBackendFactory {
DERIVE_FROM_TYPE(ALCbackendFactory);
} ALCalsaBackendFactory;
@ -1410,19 +1412,25 @@ static ALCboolean ALCalsaBackendFactory_querySupport(ALCalsaBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCalsaBackendFactory_probe(ALCalsaBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCalsaBackendFactory_probe(ALCalsaBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
#define APPEND_OUTNAME(i) do { \
if(!alstr_empty((i)->name)) \
alstr_append_range(outnames, VECTOR_BEGIN((i)->name), \
VECTOR_END((i)->name)+1); \
} while(0)
case ALL_DEVICE_PROBE:
probe_devices(SND_PCM_STREAM_PLAYBACK, &PlaybackDevices);
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, AppendAllDevicesList2);
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_OUTNAME);
break;
case CAPTURE_DEVICE_PROBE:
probe_devices(SND_PCM_STREAM_CAPTURE, &CaptureDevices);
VECTOR_FOR_EACH(const DevMap, CaptureDevices, AppendCaptureDeviceList2);
VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_OUTNAME);
break;
#undef APPEND_OUTNAME
}
}

View file

@ -12,6 +12,7 @@
extern inline ALuint64 GetDeviceClockTime(ALCdevice *device);
extern inline void ALCdevice_Lock(ALCdevice *device);
extern inline void ALCdevice_Unlock(ALCdevice *device);
extern inline ClockLatency GetClockLatency(ALCdevice *device);
/* Base ALCbackend method implementations. */
void ALCbackend_Construct(ALCbackend *self, ALCdevice *device)

View file

@ -3,6 +3,7 @@
#include "alMain.h"
#include "threads.h"
#include "alstring.h"
#ifdef __cplusplus
@ -115,7 +116,7 @@ struct ALCbackendFactoryVtable {
ALCboolean (*const querySupport)(ALCbackendFactory *self, ALCbackend_Type type);
void (*const probe)(ALCbackendFactory *self, enum DevProbe type);
void (*const probe)(ALCbackendFactory *self, enum DevProbe type, al_string *outnames);
ALCbackend* (*const createBackend)(ALCbackendFactory *self, ALCdevice *device, ALCbackend_Type type);
};
@ -124,7 +125,7 @@ struct ALCbackendFactoryVtable {
DECLARE_THUNK(T, ALCbackendFactory, ALCboolean, init) \
DECLARE_THUNK(T, ALCbackendFactory, void, deinit) \
DECLARE_THUNK1(T, ALCbackendFactory, ALCboolean, querySupport, ALCbackend_Type) \
DECLARE_THUNK1(T, ALCbackendFactory, void, probe, enum DevProbe) \
DECLARE_THUNK2(T, ALCbackendFactory, void, probe, enum DevProbe, al_string*) \
DECLARE_THUNK2(T, ALCbackendFactory, ALCbackend*, createBackend, ALCdevice*, ALCbackend_Type) \
\
static const struct ALCbackendFactoryVtable T##_ALCbackendFactory_vtable = { \
@ -142,7 +143,7 @@ ALCbackendFactory *ALCcoreAudioBackendFactory_getFactory(void);
ALCbackendFactory *ALCossBackendFactory_getFactory(void);
ALCbackendFactory *ALCjackBackendFactory_getFactory(void);
ALCbackendFactory *ALCsolarisBackendFactory_getFactory(void);
ALCbackendFactory *ALCsndioBackendFactory_getFactory(void);
ALCbackendFactory *SndioBackendFactory_getFactory(void);
ALCbackendFactory *ALCqsaBackendFactory_getFactory(void);
ALCbackendFactory *ALCwasapiBackendFactory_getFactory(void);
ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void);
@ -161,6 +162,15 @@ inline void ALCdevice_Lock(ALCdevice *device)
inline void ALCdevice_Unlock(ALCdevice *device)
{ V0(device->Backend,unlock)(); }
inline ClockLatency GetClockLatency(ALCdevice *device)
{
ClockLatency ret = V0(device->Backend,getClockLatency)();
ret.Latency += device->FixedLatency;
return ret;
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -28,7 +28,6 @@
#include "alu.h"
#include "ringbuffer.h"
#include <CoreServices/CoreServices.h>
#include <unistd.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
@ -112,7 +111,11 @@ static ALCenum ALCcoreAudioPlayback_open(ALCcoreAudioPlayback *self, const ALCch
/* open the default output unit */
desc.componentType = kAudioUnitType_Output;
#if TARGET_OS_IOS
desc.componentSubType = kAudioUnitSubType_RemoteIO;
#else
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
#endif
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
@ -451,7 +454,6 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
AudioStreamBasicDescription outputFormat; // The AudioUnit output format
AURenderCallbackStruct input;
AudioComponentDescription desc;
AudioDeviceID inputDevice;
UInt32 outputFrameCount;
UInt32 propertySize;
AudioObjectPropertyAddress propertyAddress;
@ -465,7 +467,11 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
return ALC_INVALID_VALUE;
desc.componentType = kAudioUnitType_Output;
#if TARGET_OS_IOS
desc.componentSubType = kAudioUnitSubType_RemoteIO;
#else
desc.componentSubType = kAudioUnitSubType_HALOutput;
#endif
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
@ -504,7 +510,9 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
goto error;
}
#if !TARGET_OS_IOS
// Get the default input device
AudioDeviceID inputDevice = kAudioDeviceUnknown;
propertySize = sizeof(AudioDeviceID);
propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
@ -517,7 +525,6 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
ERR("AudioObjectGetPropertyData failed\n");
goto error;
}
if(inputDevice == kAudioDeviceUnknown)
{
ERR("No input device found\n");
@ -531,6 +538,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
ERR("AudioUnitSetProperty failed\n");
goto error;
}
#endif
// set capture callback
input.inputProc = ALCcoreAudioCapture_RecordProc;
@ -752,7 +760,7 @@ ALCbackendFactory *ALCcoreAudioBackendFactory_getFactory(void);
static ALCboolean ALCcoreAudioBackendFactory_init(ALCcoreAudioBackendFactory *self);
static DECLARE_FORWARD(ALCcoreAudioBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCcoreAudioBackendFactory_querySupport(ALCcoreAudioBackendFactory *self, ALCbackend_Type type);
static void ALCcoreAudioBackendFactory_probe(ALCcoreAudioBackendFactory *self, enum DevProbe type);
static void ALCcoreAudioBackendFactory_probe(ALCcoreAudioBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCcoreAudioBackendFactory_createBackend(ALCcoreAudioBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCcoreAudioBackendFactory);
@ -776,15 +784,13 @@ static ALCboolean ALCcoreAudioBackendFactory_querySupport(ALCcoreAudioBackendFac
return ALC_FALSE;
}
static void ALCcoreAudioBackendFactory_probe(ALCcoreAudioBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCcoreAudioBackendFactory_probe(ALCcoreAudioBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(ca_device);
break;
case CAPTURE_DEVICE_PROBE:
AppendCaptureDeviceList(ca_device);
alstr_append_range(outnames, ca_device, ca_device+sizeof(ca_device));
break;
}
}

View file

@ -969,11 +969,6 @@ done:
}
static inline void AppendAllDevicesList2(const DevMap *entry)
{ AppendAllDevicesList(alstr_get_cstr(entry->name)); }
static inline void AppendCaptureDeviceList2(const DevMap *entry)
{ AppendCaptureDeviceList(alstr_get_cstr(entry->name)); }
typedef struct ALCdsoundBackendFactory {
DERIVE_FROM_TYPE(ALCbackendFactory);
} ALCdsoundBackendFactory;
@ -984,7 +979,7 @@ ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void);
static ALCboolean ALCdsoundBackendFactory_init(ALCdsoundBackendFactory *self);
static void ALCdsoundBackendFactory_deinit(ALCdsoundBackendFactory *self);
static ALCboolean ALCdsoundBackendFactory_querySupport(ALCdsoundBackendFactory *self, ALCbackend_Type type);
static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory *self, enum DevProbe type);
static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCdsoundBackendFactory_createBackend(ALCdsoundBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCdsoundBackendFactory);
@ -1028,7 +1023,7 @@ static ALCboolean ALCdsoundBackendFactory_querySupport(ALCdsoundBackendFactory*
return ALC_FALSE;
}
static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
HRESULT hr, hrcom;
@ -1036,12 +1031,17 @@ static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self),
hrcom = CoInitialize(NULL);
switch(type)
{
#define APPEND_OUTNAME(e) do { \
if(!alstr_empty((e)->name)) \
alstr_append_range(outnames, VECTOR_BEGIN((e)->name), \
VECTOR_END((e)->name)+1); \
} while(0)
case ALL_DEVICE_PROBE:
clear_devlist(&PlaybackDevices);
hr = DirectSoundEnumerateW(DSoundEnumDevices, &PlaybackDevices);
if(FAILED(hr))
ERR("Error enumerating DirectSound playback devices (0x%lx)!\n", hr);
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, AppendAllDevicesList2);
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_OUTNAME);
break;
case CAPTURE_DEVICE_PROBE:
@ -1049,8 +1049,9 @@ static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self),
hr = DirectSoundCaptureEnumerateW(DSoundEnumDevices, &CaptureDevices);
if(FAILED(hr))
ERR("Error enumerating DirectSound capture devices (0x%lx)!\n", hr);
VECTOR_FOR_EACH(const DevMap, CaptureDevices, AppendCaptureDeviceList2);
VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_OUTNAME);
break;
#undef APPEND_OUTNAME
}
if(SUCCEEDED(hrcom))
CoUninitialize();

View file

@ -571,12 +571,12 @@ static ALCboolean ALCjackBackendFactory_querySupport(ALCjackBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCjackBackendFactory_probe(ALCjackBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCjackBackendFactory_probe(ALCjackBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(jackDevice);
alstr_append_range(outnames, jackDevice, jackDevice+sizeof(jackDevice));
break;
case CAPTURE_DEVICE_PROBE:

View file

@ -87,7 +87,7 @@ ALCbackendFactory *ALCloopbackFactory_getFactory(void);
static ALCboolean ALCloopbackFactory_init(ALCloopbackFactory *self);
static DECLARE_FORWARD(ALCloopbackFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory *self, ALCbackend_Type type);
static void ALCloopbackFactory_probe(ALCloopbackFactory *self, enum DevProbe type);
static void ALCloopbackFactory_probe(ALCloopbackFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCloopbackFactory_createBackend(ALCloopbackFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCloopbackFactory);
@ -110,7 +110,7 @@ static ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory* UNUSED(sel
return ALC_FALSE;
}
static void ALCloopbackFactory_probe(ALCloopbackFactory* UNUSED(self), enum DevProbe UNUSED(type))
static void ALCloopbackFactory_probe(ALCloopbackFactory* UNUSED(self), enum DevProbe UNUSED(type), al_string* UNUSED(outnames))
{
}

View file

@ -171,7 +171,7 @@ ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory *self);
static DECLARE_FORWARD(ALCnullBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory *self, ALCbackend_Type type);
static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type);
static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCnullBackendFactory);
@ -195,14 +195,13 @@ static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(nullDevice);
break;
case CAPTURE_DEVICE_PROBE:
alstr_append_range(outnames, nullDevice, nullDevice+sizeof(nullDevice));
break;
}
}

View file

@ -206,6 +206,9 @@ static void ALCopenslPlayback_Destruct(ALCopenslPlayback* self)
self->mEngineObj = NULL;
self->mEngine = NULL;
ll_ringbuffer_free(self->mRing);
self->mRing = NULL;
alsem_destroy(&self->mSem);
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
@ -251,19 +254,16 @@ static int ALCopenslPlayback_mixerProc(void *arg)
result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY");
}
if(SL_RESULT_SUCCESS != result)
{
ALCopenslPlayback_lock(self);
aluHandleDisconnect(device, "Failed to get playback buffer: 0x%08x", result);
ALCopenslPlayback_unlock(self);
return 1;
}
ALCopenslPlayback_lock(self);
while(!ATOMIC_LOAD(&self->mKillNow, almemory_order_acquire) &&
if(SL_RESULT_SUCCESS != result)
aluHandleDisconnect(device, "Failed to get playback buffer: 0x%08x", result);
while(SL_RESULT_SUCCESS == result &&
!ATOMIC_LOAD(&self->mKillNow, almemory_order_acquire) &&
ATOMIC_LOAD(&device->Connected, almemory_order_acquire))
{
size_t todo, len0, len1;
size_t todo;
if(ll_ringbuffer_write_space(self->mRing) == 0)
{
@ -292,34 +292,33 @@ static int ALCopenslPlayback_mixerProc(void *arg)
}
ll_ringbuffer_get_write_vector(self->mRing, data);
aluMixData(device, data[0].buf, data[0].len*device->UpdateSize);
if(data[1].len > 0)
aluMixData(device, data[1].buf, data[1].len*device->UpdateSize);
todo = data[0].len+data[1].len;
ll_ringbuffer_write_advance(self->mRing, todo);
len0 = minu(todo, data[0].len);
len1 = minu(todo-len0, data[1].len);
aluMixData(device, data[0].buf, len0*device->UpdateSize);
for(size_t i = 0;i < len0;i++)
for(size_t i = 0;i < todo;i++)
{
if(!data[0].len)
{
data[0] = data[1];
data[1].buf = NULL;
data[1].len = 0;
}
result = VCALL(bufferQueue,Enqueue)(data[0].buf, device->UpdateSize*self->mFrameSize);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS == result)
ll_ringbuffer_write_advance(self->mRing, 1);
data[0].buf += device->UpdateSize*self->mFrameSize;
}
if(len1 > 0)
{
aluMixData(device, data[1].buf, len1*device->UpdateSize);
for(size_t i = 0;i < len1;i++)
if(SL_RESULT_SUCCESS != result)
{
result = VCALL(bufferQueue,Enqueue)(data[1].buf, device->UpdateSize*self->mFrameSize);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS == result)
ll_ringbuffer_write_advance(self->mRing, 1);
data[1].buf += device->UpdateSize*self->mFrameSize;
aluHandleDisconnect(device, "Failed to queue audio: 0x%08x", result);
break;
}
data[0].len--;
data[0].buf += device->UpdateSize*self->mFrameSize;
}
}
ALCopenslPlayback_unlock(self);
@ -392,19 +391,24 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
SLInterfaceID ids[2];
SLboolean reqs[2];
SLresult result;
JNIEnv *env;
if(self->mBufferQueueObj != NULL)
VCALL0(self->mBufferQueueObj,Destroy)();
self->mBufferQueueObj = NULL;
ll_ringbuffer_free(self->mRing);
self->mRing = NULL;
sampleRate = device->Frequency;
if(!(device->Flags&DEVICE_FREQUENCY_REQUEST) && (env=Android_GetJNIEnv()) != NULL)
#if 0
if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
{
/* FIXME: Disabled until I figure out how to get the Context needed for
* the getSystemService call.
*/
#if 0
JNIEnv *env = Android_GetJNIEnv();
jobject jctx = Android_GetContext();
/* Get necessary stuff for using java.lang.Integer,
* android.content.Context, and android.media.AudioManager.
*/
@ -440,7 +444,7 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
/* Now make the calls. */
//AudioManager audMgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
strobj = JCALL(env,GetStaticObjectField)(ctx_cls, ctx_audsvc);
jobject audMgr = JCALL(env,CallObjectMethod)(ctx_cls, ctx_getSysSvc, strobj);
jobject audMgr = JCALL(env,CallObjectMethod)(jctx, ctx_getSysSvc, strobj);
strchars = JCALL(env,GetStringUTFChars)(strobj, NULL);
TRACE("Context.getSystemService(%s) = %p\n", strchars, audMgr);
JCALL(env,ReleaseStringUTFChars)(strobj, strchars);
@ -461,8 +465,8 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
if(!sampleRate) sampleRate = device->Frequency;
else sampleRate = maxu(sampleRate, MIN_OUTPUT_RATE);
#endif
}
#endif
if(sampleRate != device->Frequency)
{
@ -546,6 +550,18 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
result = VCALL(self->mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "bufferQueue->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
self->mRing = ll_ringbuffer_create(device->NumUpdates,
self->mFrameSize*device->UpdateSize, true
);
if(!self->mRing)
{
ERR("Out of memory allocating ring buffer %ux%u %u\n", device->UpdateSize,
device->NumUpdates, self->mFrameSize);
result = SL_RESULT_MEMORY_FAILURE;
}
}
if(SL_RESULT_SUCCESS != result)
{
@ -561,13 +577,10 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
SLAndroidSimpleBufferQueueItf bufferQueue;
SLresult result;
ll_ringbuffer_free(self->mRing);
self->mRing = ll_ringbuffer_create(device->NumUpdates, self->mFrameSize*device->UpdateSize,
true);
ll_ringbuffer_reset(self->mRing);
result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
@ -634,9 +647,6 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
} while(SL_RESULT_SUCCESS == result && state.count > 0);
PRINTERR(result, "bufferQueue->GetState");
}
ll_ringbuffer_free(self->mRing);
self->mRing = NULL;
}
static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
@ -713,9 +723,6 @@ static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device
static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
{
ll_ringbuffer_free(self->mRing);
self->mRing = NULL;
if(self->mRecordObj != NULL)
VCALL0(self->mRecordObj,Destroy)();
self->mRecordObj = NULL;
@ -725,6 +732,9 @@ static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
self->mEngineObj = NULL;
self->mEngine = NULL;
ll_ringbuffer_free(self->mRing);
self->mRing = NULL;
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
}
@ -843,8 +853,9 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
if(SL_RESULT_SUCCESS == result)
{
self->mRing = ll_ringbuffer_create(device->NumUpdates, device->UpdateSize*self->mFrameSize,
false);
self->mRing = ll_ringbuffer_create(device->NumUpdates,
device->UpdateSize*self->mFrameSize, false
);
result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
@ -941,14 +952,16 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
SLAndroidSimpleBufferQueueItf bufferQueue;
ll_ringbuffer_data_t data[2];
SLresult result;
size_t advance;
ALCuint i;
result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
PRINTERR(result, "recordObj->GetInterface");
/* Read the desired samples from the ring buffer then advance its read
* pointer.
*/
ll_ringbuffer_get_read_vector(self->mRing, data);
advance = 0;
for(i = 0;i < samples;)
{
ALCuint rem = minu(samples - i, device->UpdateSize - self->mSplOffset);
@ -961,7 +974,11 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
{
/* Finished a chunk, reset the offset and advance the read pointer. */
self->mSplOffset = 0;
advance++;
ll_ringbuffer_read_advance(self->mRing, 1);
result = VCALL(bufferQueue,Enqueue)(data[0].buf, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS != result) break;
data[0].len--;
if(!data[0].len)
@ -972,24 +989,6 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
i += rem;
}
ll_ringbuffer_read_advance(self->mRing, advance);
result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
PRINTERR(result, "recordObj->GetInterface");
/* Enqueue any newly-writable chunks in the ring buffer. */
ll_ringbuffer_get_write_vector(self->mRing, data);
for(i = 0;i < data[0].len && SL_RESULT_SUCCESS == result;i++)
{
result = VCALL(bufferQueue,Enqueue)(data[0].buf + chunk_size*i, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
}
for(i = 0;i < data[1].len && SL_RESULT_SUCCESS == result;i++)
{
result = VCALL(bufferQueue,Enqueue)(data[1].buf + chunk_size*i, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
}
if(SL_RESULT_SUCCESS != result)
{
@ -1030,16 +1029,13 @@ static ALCboolean ALCopenslBackendFactory_querySupport(ALCopenslBackendFactory*
return ALC_FALSE;
}
static void ALCopenslBackendFactory_probe(ALCopenslBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCopenslBackendFactory_probe(ALCopenslBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(opensl_device);
break;
case CAPTURE_DEVICE_PROBE:
AppendAllDevicesList(opensl_device);
alstr_append_range(outnames, opensl_device, opensl_device+sizeof(opensl_device));
break;
}
}

View file

@ -786,7 +786,7 @@ ALCbackendFactory *ALCossBackendFactory_getFactory(void);
static ALCboolean ALCossBackendFactory_init(ALCossBackendFactory *self);
static void ALCossBackendFactory_deinit(ALCossBackendFactory *self);
static ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory *self, ALCbackend_Type type);
static void ALCossBackendFactory_probe(ALCossBackendFactory *self, enum DevProbe type);
static void ALCossBackendFactory_probe(ALCossBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCossBackendFactory_createBackend(ALCossBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCossBackendFactory);
@ -820,41 +820,32 @@ ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory* UNUSED(self),
return ALC_FALSE;
}
void ALCossBackendFactory_probe(ALCossBackendFactory* UNUSED(self), enum DevProbe type)
void ALCossBackendFactory_probe(ALCossBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
struct oss_device *cur;
struct oss_device *cur = NULL;
switch(type)
{
case ALL_DEVICE_PROBE:
ALCossListFree(&oss_playback);
ALCossListPopulate(&oss_playback, DSP_CAP_OUTPUT);
cur = &oss_playback;
while(cur != NULL)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(cur->path, &buf) == 0)
#endif
AppendAllDevicesList(cur->handle);
cur = cur->next;
}
break;
case CAPTURE_DEVICE_PROBE:
ALCossListFree(&oss_capture);
ALCossListPopulate(&oss_capture, DSP_CAP_INPUT);
cur = &oss_capture;
while(cur != NULL)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(cur->path, &buf) == 0)
#endif
AppendCaptureDeviceList(cur->handle);
cur = cur->next;
}
break;
}
while(cur != NULL)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(cur->path, &buf) == 0)
#endif
alstr_append_range(outnames, cur->handle, cur->handle+strlen(cur->handle)+1);
cur = cur->next;
}
}
ALCbackend* ALCossBackendFactory_createBackend(ALCossBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)

View file

@ -484,9 +484,8 @@ typedef struct ALCportBackendFactory {
static ALCboolean ALCportBackendFactory_init(ALCportBackendFactory *self);
static void ALCportBackendFactory_deinit(ALCportBackendFactory *self);
static ALCboolean ALCportBackendFactory_querySupport(ALCportBackendFactory *self, ALCbackend_Type type);
static void ALCportBackendFactory_probe(ALCportBackendFactory *self, enum DevProbe type);
static void ALCportBackendFactory_probe(ALCportBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCportBackendFactory_createBackend(ALCportBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCportBackendFactory);
@ -518,15 +517,13 @@ static ALCboolean ALCportBackendFactory_querySupport(ALCportBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCportBackendFactory_probe(ALCportBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCportBackendFactory_probe(ALCportBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(pa_device);
break;
case CAPTURE_DEVICE_PROBE:
AppendCaptureDeviceList(pa_device);
alstr_append_range(outnames, pa_device, pa_device+sizeof(pa_device));
break;
}
}

View file

@ -1760,9 +1760,8 @@ typedef struct ALCpulseBackendFactory {
static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory *self);
static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory *self);
static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory *self, ALCbackend_Type type);
static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory *self, enum DevProbe type);
static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCpulseBackendFactory);
@ -1835,23 +1834,25 @@ static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory* UN
return ALC_FALSE;
}
static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
#define APPEND_OUTNAME(e) do { \
if(!alstr_empty((e)->name)) \
alstr_append_range(outnames, VECTOR_BEGIN((e)->name), \
VECTOR_END((e)->name)+1); \
} while(0)
case ALL_DEVICE_PROBE:
ALCpulsePlayback_probeDevices();
#define APPEND_ALL_DEVICES_LIST(e) AppendAllDevicesList(alstr_get_cstr((e)->name))
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_ALL_DEVICES_LIST);
#undef APPEND_ALL_DEVICES_LIST
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_OUTNAME);
break;
case CAPTURE_DEVICE_PROBE:
ALCpulseCapture_probeDevices();
#define APPEND_CAPTURE_DEVICE_LIST(e) AppendCaptureDeviceList(alstr_get_cstr((e)->name))
VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_CAPTURE_DEVICE_LIST);
#undef APPEND_CAPTURE_DEVICE_LIST
VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_OUTNAME);
break;
#undef APPEND_OUTNAME
}
}
@ -1899,7 +1900,7 @@ static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory* UN
return ALC_FALSE;
}
static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe UNUSED(type))
static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe UNUSED(type), al_string* UNUSED(outnames))
{
}

View file

@ -119,6 +119,9 @@ static void deviceList(int type, vector_DevMap *devmap)
if(max_cards < 0)
return;
#define FREE_NAME(iter) free((iter)->name)
VECTOR_FOR_EACH(DevMap, *devmap, FREE_NAME);
#undef FREE_NAME
VECTOR_RESIZE(*devmap, 0, max_cards+1);
entry.name = strdup(qsaDevice);
@ -989,7 +992,7 @@ typedef struct ALCqsaBackendFactory {
static ALCboolean ALCqsaBackendFactory_init(ALCqsaBackendFactory* UNUSED(self));
static void ALCqsaBackendFactory_deinit(ALCqsaBackendFactory* UNUSED(self));
static ALCboolean ALCqsaBackendFactory_querySupport(ALCqsaBackendFactory* UNUSED(self), ALCbackend_Type type);
static void ALCqsaBackendFactory_probe(ALCqsaBackendFactory* UNUSED(self), enum DevProbe type);
static void ALCqsaBackendFactory_probe(ALCqsaBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames);
static ALCbackend* ALCqsaBackendFactory_createBackend(ALCqsaBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCqsaBackendFactory);
@ -1016,33 +1019,25 @@ static ALCboolean ALCqsaBackendFactory_querySupport(ALCqsaBackendFactory* UNUSED
return ALC_FALSE;
}
static void ALCqsaBackendFactory_probe(ALCqsaBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCqsaBackendFactory_probe(ALCqsaBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch (type)
{
#define APPEND_OUTNAME(e) do { \
const char *n_ = (e)->name; \
if(n_ && n_[0]) \
alstr_append_range(outnames, n_, n_+strlen(n_)+1); \
} while(0)
case ALL_DEVICE_PROBE:
#define FREE_NAME(iter) free((iter)->name)
VECTOR_FOR_EACH(DevMap, DeviceNameMap, FREE_NAME);
VECTOR_RESIZE(DeviceNameMap, 0, 0);
#undef FREE_NAME
deviceList(SND_PCM_CHANNEL_PLAYBACK, &DeviceNameMap);
#define APPEND_DEVICE(iter) AppendAllDevicesList((iter)->name)
VECTOR_FOR_EACH(const DevMap, DeviceNameMap, APPEND_DEVICE);
#undef APPEND_DEVICE
VECTOR_FOR_EACH(const DevMap, DeviceNameMap, APPEND_OUTNAME);
break;
case CAPTURE_DEVICE_PROBE:
#define FREE_NAME(iter) free((iter)->name)
VECTOR_FOR_EACH(DevMap, CaptureNameMap, FREE_NAME);
VECTOR_RESIZE(CaptureNameMap, 0, 0);
#undef FREE_NAME
deviceList(SND_PCM_CHANNEL_CAPTURE, &CaptureNameMap);
#define APPEND_DEVICE(iter) AppendCaptureDeviceList((iter)->name)
VECTOR_FOR_EACH(const DevMap, CaptureNameMap, APPEND_DEVICE);
#undef APPEND_DEVICE
VECTOR_FOR_EACH(const DevMap, CaptureNameMap, APPEND_OUTNAME);
break;
#undef APPEND_OUTNAME
}
}

View file

@ -221,7 +221,7 @@ ALCbackendFactory *ALCsdl2BackendFactory_getFactory(void);
static ALCboolean ALCsdl2BackendFactory_init(ALCsdl2BackendFactory *self);
static void ALCsdl2BackendFactory_deinit(ALCsdl2BackendFactory *self);
static ALCboolean ALCsdl2BackendFactory_querySupport(ALCsdl2BackendFactory *self, ALCbackend_Type type);
static void ALCsdl2BackendFactory_probe(ALCsdl2BackendFactory *self, enum DevProbe type);
static void ALCsdl2BackendFactory_probe(ALCsdl2BackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCsdl2BackendFactory_createBackend(ALCsdl2BackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCsdl2BackendFactory);
@ -252,7 +252,7 @@ static ALCboolean ALCsdl2BackendFactory_querySupport(ALCsdl2BackendFactory* UNUS
return ALC_FALSE;
}
static void ALCsdl2BackendFactory_probe(ALCsdl2BackendFactory* UNUSED(self), enum DevProbe type)
static void ALCsdl2BackendFactory_probe(ALCsdl2BackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
int num_devices, i;
al_string name;
@ -263,12 +263,13 @@ static void ALCsdl2BackendFactory_probe(ALCsdl2BackendFactory* UNUSED(self), enu
AL_STRING_INIT(name);
num_devices = SDL_GetNumAudioDevices(SDL_FALSE);
AppendAllDevicesList(defaultDeviceName);
alstr_append_range(outnames, defaultDeviceName, defaultDeviceName+sizeof(defaultDeviceName));
for(i = 0;i < num_devices;++i)
{
alstr_copy_cstr(&name, DEVNAME_PREFIX);
alstr_append_cstr(&name, SDL_GetAudioDeviceName(i, SDL_FALSE));
AppendAllDevicesList(alstr_get_cstr(name));
if(!alstr_empty(name))
alstr_append_range(outnames, VECTOR_BEGIN(name), VECTOR_END(name)+1);
}
alstr_reset(&name);
}

View file

@ -27,15 +27,17 @@
#include "alMain.h"
#include "alu.h"
#include "threads.h"
#include "ringbuffer.h"
#include "backends/base.h"
#include <sndio.h>
static const ALCchar sndio_device[] = "SndIO Default";
typedef struct ALCsndioBackend {
typedef struct SndioPlayback {
DERIVE_FROM_TYPE(ALCbackend);
struct sio_hdl *sndHandle;
@ -45,40 +47,37 @@ typedef struct ALCsndioBackend {
ATOMIC(int) killNow;
althrd_t thread;
} ALCsndioBackend;
} SndioPlayback;
static int ALCsndioBackend_mixerProc(void *ptr);
static int SndioPlayback_mixerProc(void *ptr);
static void ALCsndioBackend_Construct(ALCsndioBackend *self, ALCdevice *device);
static void ALCsndioBackend_Destruct(ALCsndioBackend *self);
static ALCenum ALCsndioBackend_open(ALCsndioBackend *self, const ALCchar *name);
static ALCboolean ALCsndioBackend_reset(ALCsndioBackend *self);
static ALCboolean ALCsndioBackend_start(ALCsndioBackend *self);
static void ALCsndioBackend_stop(ALCsndioBackend *self);
static DECLARE_FORWARD2(ALCsndioBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, ALCuint, availableSamples)
static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, ClockLatency, getClockLatency)
static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, void, lock)
static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(ALCsndioBackend)
static void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device);
static void SndioPlayback_Destruct(SndioPlayback *self);
static ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name);
static ALCboolean SndioPlayback_reset(SndioPlayback *self);
static ALCboolean SndioPlayback_start(SndioPlayback *self);
static void SndioPlayback_stop(SndioPlayback *self);
static DECLARE_FORWARD2(SndioPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
static DECLARE_FORWARD(SndioPlayback, ALCbackend, ALCuint, availableSamples)
static DECLARE_FORWARD(SndioPlayback, ALCbackend, ClockLatency, getClockLatency)
static DECLARE_FORWARD(SndioPlayback, ALCbackend, void, lock)
static DECLARE_FORWARD(SndioPlayback, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(SndioPlayback)
DEFINE_ALCBACKEND_VTABLE(ALCsndioBackend);
DEFINE_ALCBACKEND_VTABLE(SndioPlayback);
static const ALCchar sndio_device[] = "SndIO Default";
static void ALCsndioBackend_Construct(ALCsndioBackend *self, ALCdevice *device)
static void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device)
{
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(ALCsndioBackend, ALCbackend, self);
SET_VTABLE2(SndioPlayback, ALCbackend, self);
self->sndHandle = NULL;
self->mix_data = NULL;
ATOMIC_INIT(&self->killNow, AL_TRUE);
}
static void ALCsndioBackend_Destruct(ALCsndioBackend *self)
static void SndioPlayback_Destruct(SndioPlayback *self)
{
if(self->sndHandle)
sio_close(self->sndHandle);
@ -91,9 +90,9 @@ static void ALCsndioBackend_Destruct(ALCsndioBackend *self)
}
static int ALCsndioBackend_mixerProc(void *ptr)
static int SndioPlayback_mixerProc(void *ptr)
{
ALCsndioBackend *self = (ALCsndioBackend*)ptr;
SndioPlayback *self = (SndioPlayback*)ptr;
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
ALsizei frameSize;
size_t wrote;
@ -109,9 +108,9 @@ static int ALCsndioBackend_mixerProc(void *ptr)
ALsizei len = self->data_size;
ALubyte *WritePtr = self->mix_data;
ALCsndioBackend_lock(self);
SndioPlayback_lock(self);
aluMixData(device, WritePtr, len/frameSize);
ALCsndioBackend_unlock(self);
SndioPlayback_unlock(self);
while(len > 0 && !ATOMIC_LOAD(&self->killNow, almemory_order_acquire))
{
wrote = sio_write(self->sndHandle, WritePtr, len);
@ -133,7 +132,7 @@ static int ALCsndioBackend_mixerProc(void *ptr)
}
static ALCenum ALCsndioBackend_open(ALCsndioBackend *self, const ALCchar *name)
static ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name)
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
@ -154,7 +153,7 @@ static ALCenum ALCsndioBackend_open(ALCsndioBackend *self, const ALCchar *name)
return ALC_NO_ERROR;
}
static ALCboolean ALCsndioBackend_reset(ALCsndioBackend *self)
static ALCboolean SndioPlayback_reset(SndioPlayback *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
struct sio_par par;
@ -239,7 +238,7 @@ static ALCboolean ALCsndioBackend_reset(ALCsndioBackend *self)
return ALC_TRUE;
}
static ALCboolean ALCsndioBackend_start(ALCsndioBackend *self)
static ALCboolean SndioPlayback_start(SndioPlayback *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
@ -256,7 +255,7 @@ static ALCboolean ALCsndioBackend_start(ALCsndioBackend *self)
}
ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
if(althrd_create(&self->thread, ALCsndioBackend_mixerProc, self) != althrd_success)
if(althrd_create(&self->thread, SndioPlayback_mixerProc, self) != althrd_success)
{
sio_stop(self->sndHandle);
return ALC_FALSE;
@ -265,7 +264,7 @@ static ALCboolean ALCsndioBackend_start(ALCsndioBackend *self)
return ALC_TRUE;
}
static void ALCsndioBackend_stop(ALCsndioBackend *self)
static void SndioPlayback_stop(SndioPlayback *self)
{
int res;
@ -281,59 +280,318 @@ static void ALCsndioBackend_stop(ALCsndioBackend *self)
}
typedef struct ALCsndioBackendFactory {
DERIVE_FROM_TYPE(ALCbackendFactory);
} ALCsndioBackendFactory;
#define ALCSNDIOBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCsndioBackendFactory, ALCbackendFactory) } }
typedef struct SndioCapture {
DERIVE_FROM_TYPE(ALCbackend);
ALCbackendFactory *ALCsndioBackendFactory_getFactory(void);
struct sio_hdl *sndHandle;
static ALCboolean ALCsndioBackendFactory_init(ALCsndioBackendFactory *self);
static DECLARE_FORWARD(ALCsndioBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCsndioBackendFactory_querySupport(ALCsndioBackendFactory *self, ALCbackend_Type type);
static void ALCsndioBackendFactory_probe(ALCsndioBackendFactory *self, enum DevProbe type);
static ALCbackend* ALCsndioBackendFactory_createBackend(ALCsndioBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCsndioBackendFactory);
ll_ringbuffer_t *ring;
ATOMIC(int) killNow;
althrd_t thread;
} SndioCapture;
static int SndioCapture_recordProc(void *ptr);
static void SndioCapture_Construct(SndioCapture *self, ALCdevice *device);
static void SndioCapture_Destruct(SndioCapture *self);
static ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name);
static DECLARE_FORWARD(SndioCapture, ALCbackend, ALCboolean, reset)
static ALCboolean SndioCapture_start(SndioCapture *self);
static void SndioCapture_stop(SndioCapture *self);
static ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples);
static ALCuint SndioCapture_availableSamples(SndioCapture *self);
static DECLARE_FORWARD(SndioCapture, ALCbackend, ClockLatency, getClockLatency)
static DECLARE_FORWARD(SndioCapture, ALCbackend, void, lock)
static DECLARE_FORWARD(SndioCapture, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(SndioCapture)
DEFINE_ALCBACKEND_VTABLE(SndioCapture);
ALCbackendFactory *ALCsndioBackendFactory_getFactory(void)
static void SndioCapture_Construct(SndioCapture *self, ALCdevice *device)
{
static ALCsndioBackendFactory factory = ALCSNDIOBACKENDFACTORY_INITIALIZER;
return STATIC_CAST(ALCbackendFactory, &factory);
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(SndioCapture, ALCbackend, self);
self->sndHandle = NULL;
self->ring = NULL;
ATOMIC_INIT(&self->killNow, AL_TRUE);
}
static void SndioCapture_Destruct(SndioCapture *self)
{
if(self->sndHandle)
sio_close(self->sndHandle);
self->sndHandle = NULL;
ll_ringbuffer_free(self->ring);
self->ring = NULL;
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
}
static ALCboolean ALCsndioBackendFactory_init(ALCsndioBackendFactory* UNUSED(self))
static int SndioCapture_recordProc(void* ptr)
{
SndioCapture *self = (SndioCapture*)ptr;
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
ALsizei frameSize;
SetRTPriority();
althrd_setname(althrd_current(), RECORD_THREAD_NAME);
frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) &&
ATOMIC_LOAD(&device->Connected, almemory_order_acquire))
{
ll_ringbuffer_data_t data[2];
size_t total, todo;
ll_ringbuffer_get_write_vector(self->ring, data);
todo = data[0].len + data[1].len;
if(todo == 0)
{
static char junk[4096];
sio_read(self->sndHandle, junk, minz(sizeof(junk)/frameSize, device->UpdateSize)*frameSize);
continue;
}
total = 0;
data[0].len *= frameSize;
data[1].len *= frameSize;
todo = minz(todo, device->UpdateSize) * frameSize;
while(total < todo)
{
size_t got;
if(!data[0].len)
data[0] = data[1];
got = sio_read(self->sndHandle, data[0].buf, minz(todo-total, data[0].len));
if(!got)
{
SndioCapture_lock(self);
aluHandleDisconnect(device, "Failed to read capture samples");
SndioCapture_unlock(self);
break;
}
data[0].buf += got;
data[0].len -= got;
total += got;
}
ll_ringbuffer_write_advance(self->ring, total / frameSize);
}
return 0;
}
static ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
struct sio_par par;
if(!name)
name = sndio_device;
else if(strcmp(name, sndio_device) != 0)
return ALC_INVALID_VALUE;
self->sndHandle = sio_open(NULL, SIO_REC, 0);
if(self->sndHandle == NULL)
{
ERR("Could not open device\n");
return ALC_INVALID_VALUE;
}
sio_initpar(&par);
switch(device->FmtType)
{
case DevFmtByte:
par.bps = 1;
par.sig = 1;
break;
case DevFmtUByte:
par.bps = 1;
par.sig = 0;
break;
case DevFmtShort:
par.bps = 2;
par.sig = 1;
break;
case DevFmtUShort:
par.bps = 2;
par.sig = 0;
break;
case DevFmtInt:
par.bps = 4;
par.sig = 1;
break;
case DevFmtUInt:
par.bps = 4;
par.sig = 0;
break;
case DevFmtFloat:
ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
return ALC_INVALID_VALUE;
}
par.bits = par.bps * 8;
par.le = SIO_LE_NATIVE;
par.msb = SIO_LE_NATIVE ? 0 : 1;
par.rchan = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
par.rate = device->Frequency;
par.appbufsz = maxu(device->UpdateSize*device->NumUpdates, (device->Frequency+9)/10);
par.round = clampu(par.appbufsz/device->NumUpdates, (device->Frequency+99)/100,
(device->Frequency+19)/20);
device->UpdateSize = par.round;
device->NumUpdates = maxu(par.appbufsz/par.round, 1);
if(!sio_setpar(self->sndHandle, &par) || !sio_getpar(self->sndHandle, &par))
{
ERR("Failed to set device parameters\n");
return ALC_INVALID_VALUE;
}
if(par.bits != par.bps*8)
{
ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8);
return ALC_INVALID_VALUE;
}
if(!((device->FmtType == DevFmtByte && par.bits == 8 && par.sig != 0) ||
(device->FmtType == DevFmtUByte && par.bits == 8 && par.sig == 0) ||
(device->FmtType == DevFmtShort && par.bits == 16 && par.sig != 0) ||
(device->FmtType == DevFmtUShort && par.bits == 16 && par.sig == 0) ||
(device->FmtType == DevFmtInt && par.bits == 32 && par.sig != 0) ||
(device->FmtType == DevFmtUInt && par.bits == 32 && par.sig == 0)) ||
ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder) != (ALsizei)par.rchan ||
device->Frequency != par.rate)
{
ERR("Failed to set format %s %s %uhz, got %c%u %u-channel %uhz instead\n",
DevFmtTypeString(device->FmtType), DevFmtChannelsString(device->FmtChans),
device->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate);
return ALC_INVALID_VALUE;
}
self->ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates, par.bps*par.rchan, 0);
if(!self->ring)
{
ERR("Failed to allocate %u-byte ringbuffer\n",
device->UpdateSize*device->NumUpdates*par.bps*par.rchan);
return ALC_OUT_OF_MEMORY;
}
SetDefaultChannelOrder(device);
alstr_copy_cstr(&device->DeviceName, name);
return ALC_NO_ERROR;
}
static ALCboolean SndioCapture_start(SndioCapture *self)
{
if(!sio_start(self->sndHandle))
{
ERR("Error starting playback\n");
return ALC_FALSE;
}
ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
if(althrd_create(&self->thread, SndioCapture_recordProc, self) != althrd_success)
{
sio_stop(self->sndHandle);
return ALC_FALSE;
}
return ALC_TRUE;
}
static void SndioCapture_stop(SndioCapture *self)
{
int res;
if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel))
return;
althrd_join(self->thread, &res);
if(!sio_stop(self->sndHandle))
ERR("Error stopping device\n");
}
static ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples)
{
ll_ringbuffer_read(self->ring, buffer, samples);
return ALC_NO_ERROR;
}
static ALCuint SndioCapture_availableSamples(SndioCapture *self)
{
return ll_ringbuffer_read_space(self->ring);
}
typedef struct SndioBackendFactory {
DERIVE_FROM_TYPE(ALCbackendFactory);
} SndioBackendFactory;
#define SNDIOBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(SndioBackendFactory, ALCbackendFactory) } }
ALCbackendFactory *SndioBackendFactory_getFactory(void);
static ALCboolean SndioBackendFactory_init(SndioBackendFactory *self);
static DECLARE_FORWARD(SndioBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean SndioBackendFactory_querySupport(SndioBackendFactory *self, ALCbackend_Type type);
static void SndioBackendFactory_probe(SndioBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* SndioBackendFactory_createBackend(SndioBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(SndioBackendFactory);
ALCbackendFactory *SndioBackendFactory_getFactory(void)
{
static SndioBackendFactory factory = SNDIOBACKENDFACTORY_INITIALIZER;
return STATIC_CAST(ALCbackendFactory, &factory);
}
static ALCboolean SndioBackendFactory_init(SndioBackendFactory* UNUSED(self))
{
/* No dynamic loading */
return ALC_TRUE;
}
static ALCboolean ALCsndioBackendFactory_querySupport(ALCsndioBackendFactory* UNUSED(self), ALCbackend_Type type)
static ALCboolean SndioBackendFactory_querySupport(SndioBackendFactory* UNUSED(self), ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
if(type == ALCbackend_Playback || type == ALCbackend_Capture)
return ALC_TRUE;
return ALC_FALSE;
}
static void ALCsndioBackendFactory_probe(ALCsndioBackendFactory* UNUSED(self), enum DevProbe type)
static void SndioBackendFactory_probe(SndioBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(sndio_device);
break;
case CAPTURE_DEVICE_PROBE:
alstr_append_range(outnames, sndio_device, sndio_device+sizeof(sndio_device));
break;
}
}
static ALCbackend* ALCsndioBackendFactory_createBackend(ALCsndioBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
static ALCbackend* SndioBackendFactory_createBackend(SndioBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
{
ALCsndioBackend *backend;
NEW_OBJ(backend, ALCsndioBackend)(device);
SndioPlayback *backend;
NEW_OBJ(backend, SndioPlayback)(device);
if(!backend) return NULL;
return STATIC_CAST(ALCbackend, backend);
}
if(type == ALCbackend_Capture)
{
SndioCapture *backend;
NEW_OBJ(backend, SndioCapture)(device);
if(!backend) return NULL;
return STATIC_CAST(ALCbackend, backend);
}

View file

@ -302,7 +302,7 @@ ALCbackendFactory *ALCsolarisBackendFactory_getFactory(void);
static ALCboolean ALCsolarisBackendFactory_init(ALCsolarisBackendFactory *self);
static DECLARE_FORWARD(ALCsolarisBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCsolarisBackendFactory_querySupport(ALCsolarisBackendFactory *self, ALCbackend_Type type);
static void ALCsolarisBackendFactory_probe(ALCsolarisBackendFactory *self, enum DevProbe type);
static void ALCsolarisBackendFactory_probe(ALCsolarisBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCsolarisBackendFactory_createBackend(ALCsolarisBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCsolarisBackendFactory);
@ -327,7 +327,7 @@ static ALCboolean ALCsolarisBackendFactory_querySupport(ALCsolarisBackendFactory
return ALC_FALSE;
}
static void ALCsolarisBackendFactory_probe(ALCsolarisBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCsolarisBackendFactory_probe(ALCsolarisBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
@ -337,7 +337,7 @@ static void ALCsolarisBackendFactory_probe(ALCsolarisBackendFactory* UNUSED(self
struct stat buf;
if(stat(solaris_driver, &buf) == 0)
#endif
AppendAllDevicesList(solaris_device);
alstr_append_range(outnames, solaris_device, solaris_device+sizeof(solaris_device));
}
break;

View file

@ -1919,11 +1919,6 @@ ALCenum ALCwasapiCapture_captureSamples(ALCwasapiCapture *self, ALCvoid *buffer,
}
static inline void AppendAllDevicesList2(const DevMap *entry)
{ AppendAllDevicesList(alstr_get_cstr(entry->name)); }
static inline void AppendCaptureDeviceList2(const DevMap *entry)
{ AppendCaptureDeviceList(alstr_get_cstr(entry->name)); }
typedef struct ALCwasapiBackendFactory {
DERIVE_FROM_TYPE(ALCbackendFactory);
} ALCwasapiBackendFactory;
@ -1932,7 +1927,7 @@ typedef struct ALCwasapiBackendFactory {
static ALCboolean ALCwasapiBackendFactory_init(ALCwasapiBackendFactory *self);
static void ALCwasapiBackendFactory_deinit(ALCwasapiBackendFactory *self);
static ALCboolean ALCwasapiBackendFactory_querySupport(ALCwasapiBackendFactory *self, ALCbackend_Type type);
static void ALCwasapiBackendFactory_probe(ALCwasapiBackendFactory *self, enum DevProbe type);
static void ALCwasapiBackendFactory_probe(ALCwasapiBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCwasapiBackendFactory_createBackend(ALCwasapiBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCwasapiBackendFactory);
@ -1989,7 +1984,7 @@ static ALCboolean ALCwasapiBackendFactory_querySupport(ALCwasapiBackendFactory*
return ALC_FALSE;
}
static void ALCwasapiBackendFactory_probe(ALCwasapiBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCwasapiBackendFactory_probe(ALCwasapiBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
ThreadRequest req = { NULL, 0 };
@ -2003,13 +1998,19 @@ static void ALCwasapiBackendFactory_probe(ALCwasapiBackendFactory* UNUSED(self),
hr = WaitForResponse(&req);
if(SUCCEEDED(hr)) switch(type)
{
#define APPEND_OUTNAME(e) do { \
if(!alstr_empty((e)->name)) \
alstr_append_range(outnames, VECTOR_BEGIN((e)->name), \
VECTOR_END((e)->name)+1); \
} while(0)
case ALL_DEVICE_PROBE:
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, AppendAllDevicesList2);
VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_OUTNAME);
break;
case CAPTURE_DEVICE_PROBE:
VECTOR_FOR_EACH(const DevMap, CaptureDevices, AppendCaptureDeviceList2);
VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_OUTNAME);
break;
#undef APPEND_OUTNAME
}
CloseHandle(req.FinishedEvt);
req.FinishedEvt = NULL;

View file

@ -403,7 +403,7 @@ ALCbackendFactory *ALCwaveBackendFactory_getFactory(void);
static ALCboolean ALCwaveBackendFactory_init(ALCwaveBackendFactory *self);
static DECLARE_FORWARD(ALCwaveBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCwaveBackendFactory_querySupport(ALCwaveBackendFactory *self, ALCbackend_Type type);
static void ALCwaveBackendFactory_probe(ALCwaveBackendFactory *self, enum DevProbe type);
static void ALCwaveBackendFactory_probe(ALCwaveBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCwaveBackendFactory_createBackend(ALCwaveBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCwaveBackendFactory);
@ -427,12 +427,12 @@ static ALCboolean ALCwaveBackendFactory_querySupport(ALCwaveBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCwaveBackendFactory_probe(ALCwaveBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCwaveBackendFactory_probe(ALCwaveBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(waveDevice);
alstr_append_range(outnames, waveDevice, waveDevice+sizeof(waveDevice));
break;
case CAPTURE_DEVICE_PROBE:
break;

View file

@ -700,17 +700,6 @@ static ALCuint ALCwinmmCapture_availableSamples(ALCwinmmCapture *self)
}
static inline void AppendAllDevicesList2(const al_string *name)
{
if(!alstr_empty(*name))
AppendAllDevicesList(alstr_get_cstr(*name));
}
static inline void AppendCaptureDeviceList2(const al_string *name)
{
if(!alstr_empty(*name))
AppendCaptureDeviceList(alstr_get_cstr(*name));
}
typedef struct ALCwinmmBackendFactory {
DERIVE_FROM_TYPE(ALCbackendFactory);
} ALCwinmmBackendFactory;
@ -719,7 +708,7 @@ typedef struct ALCwinmmBackendFactory {
static ALCboolean ALCwinmmBackendFactory_init(ALCwinmmBackendFactory *self);
static void ALCwinmmBackendFactory_deinit(ALCwinmmBackendFactory *self);
static ALCboolean ALCwinmmBackendFactory_querySupport(ALCwinmmBackendFactory *self, ALCbackend_Type type);
static void ALCwinmmBackendFactory_probe(ALCwinmmBackendFactory *self, enum DevProbe type);
static void ALCwinmmBackendFactory_probe(ALCwinmmBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCwinmmBackendFactory_createBackend(ALCwinmmBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCwinmmBackendFactory);
@ -749,19 +738,24 @@ static ALCboolean ALCwinmmBackendFactory_querySupport(ALCwinmmBackendFactory* UN
return ALC_FALSE;
}
static void ALCwinmmBackendFactory_probe(ALCwinmmBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCwinmmBackendFactory_probe(ALCwinmmBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
#define APPEND_OUTNAME(n) do { \
if(!alstr_empty(*(n))) \
alstr_append_range(outnames, VECTOR_BEGIN(*(n)), VECTOR_END(*(n))+1); \
} while(0)
case ALL_DEVICE_PROBE:
ProbePlaybackDevices();
VECTOR_FOR_EACH(const al_string, PlaybackDevices, AppendAllDevicesList2);
VECTOR_FOR_EACH(const al_string, PlaybackDevices, APPEND_OUTNAME);
break;
case CAPTURE_DEVICE_PROBE:
ProbeCaptureDevices();
VECTOR_FOR_EACH(const al_string, CaptureDevices, AppendCaptureDeviceList2);
VECTOR_FOR_EACH(const al_string, CaptureDevices, APPEND_OUTNAME);
break;
#undef APPEND_OUTNAME
}
}