Merge commit '3a7f96fd99528968c39b5be81db067ca018d432b' into dev
This commit is contained in:
80
external/SDL/src/audio/SDL_audio.c
vendored
80
external/SDL/src/audio/SDL_audio.c
vendored
@@ -280,7 +280,7 @@ bool SDL_AudioSpecsEqual(const SDL_AudioSpec *a, const SDL_AudioSpec *b, const i
|
||||
// consumed and apps relying on audio callbacks don't stop making progress.
|
||||
static bool ZombieWaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
if (!SDL_AtomicGet(&device->shutdown)) {
|
||||
if (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
const int frames = device->buffer_size / SDL_AUDIO_FRAMESIZE(device->spec);
|
||||
SDL_Delay((frames * 1000) / device->spec.freq);
|
||||
}
|
||||
@@ -390,7 +390,7 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid,
|
||||
// to make sure the correct physical device gets locked, in case we're in a race with the default changing.
|
||||
while (true) {
|
||||
SDL_LockMutex(device->lock);
|
||||
SDL_AudioDevice *recheck_device = (SDL_AudioDevice *) SDL_AtomicGetPointer((void **) &logdev->physical_device);
|
||||
SDL_AudioDevice *recheck_device = (SDL_AudioDevice *) SDL_GetAtomicPointer((void **) &logdev->physical_device);
|
||||
if (device == recheck_device) {
|
||||
break;
|
||||
}
|
||||
@@ -559,7 +559,7 @@ void UnrefPhysicalAudioDevice(SDL_AudioDevice *device)
|
||||
// take it out of the device list.
|
||||
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
|
||||
if (SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) device->instance_id)) {
|
||||
SDL_AtomicAdd(device->recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count, -1);
|
||||
SDL_AddAtomicInt(device->recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count, -1);
|
||||
}
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
DestroyPhysicalAudioDevice(device); // ...and nuke it.
|
||||
@@ -576,7 +576,7 @@ static SDL_AudioDevice *CreatePhysicalAudioDevice(const char *name, bool recordi
|
||||
SDL_assert(name != NULL);
|
||||
|
||||
SDL_LockRWLockForReading(current_audio.device_hash_lock);
|
||||
const int shutting_down = SDL_AtomicGet(¤t_audio.shutting_down);
|
||||
const int shutting_down = SDL_GetAtomicInt(¤t_audio.shutting_down);
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
if (shutting_down) {
|
||||
return NULL; // we're shutting down, don't add any devices that are hotplugged at the last possible moment.
|
||||
@@ -608,8 +608,8 @@ static SDL_AudioDevice *CreatePhysicalAudioDevice(const char *name, bool recordi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_AtomicSet(&device->shutdown, 0);
|
||||
SDL_AtomicSet(&device->zombie, 0);
|
||||
SDL_SetAtomicInt(&device->shutdown, 0);
|
||||
SDL_SetAtomicInt(&device->zombie, 0);
|
||||
device->recording = recording;
|
||||
SDL_copyp(&device->spec, spec);
|
||||
SDL_copyp(&device->default_spec, spec);
|
||||
@@ -621,7 +621,7 @@ static SDL_AudioDevice *CreatePhysicalAudioDevice(const char *name, bool recordi
|
||||
|
||||
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
|
||||
if (SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) device->instance_id, device)) {
|
||||
SDL_AtomicAdd(device_count, 1);
|
||||
SDL_AddAtomicInt(device_count, 1);
|
||||
} else {
|
||||
SDL_DestroyCondition(device->close_cond);
|
||||
SDL_DestroyMutex(device->lock);
|
||||
@@ -711,7 +711,7 @@ void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
const bool is_default_device = ((devid == current_audio.default_playback_device_id) || (devid == current_audio.default_recording_device_id));
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
||||
const bool first_disconnect = SDL_AtomicCompareAndSwap(&device->zombie, 0, 1);
|
||||
const bool first_disconnect = SDL_CompareAndSwapAtomicInt(&device->zombie, 0, 1);
|
||||
if (first_disconnect) { // if already disconnected this device, don't do it twice.
|
||||
// Swap in "Zombie" versions of the usual platform interfaces, so the device will keep
|
||||
// making progress until the app closes it. Otherwise, streams might continue to
|
||||
@@ -886,7 +886,7 @@ bool SDL_InitAudio(const char *driver_name)
|
||||
}
|
||||
|
||||
// make sure device IDs start at 2 (because of SDL2 legacy interface), but don't reset the counter on each init, in case the app is holding an old device ID somewhere.
|
||||
SDL_AtomicCompareAndSwap(&last_device_instance_id, 0, 2);
|
||||
SDL_CompareAndSwapAtomicInt(&last_device_instance_id, 0, 2);
|
||||
|
||||
SDL_ChooseAudioConverters();
|
||||
SDL_SetupAudioResampler();
|
||||
@@ -1031,13 +1031,13 @@ void SDL_QuitAudio(void)
|
||||
}
|
||||
|
||||
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
|
||||
SDL_AtomicSet(¤t_audio.shutting_down, 1);
|
||||
SDL_SetAtomicInt(¤t_audio.shutting_down, 1);
|
||||
SDL_HashTable *device_hash = current_audio.device_hash;
|
||||
current_audio.device_hash = NULL;
|
||||
SDL_PendingAudioDeviceEvent *pending_events = current_audio.pending_events.next;
|
||||
current_audio.pending_events.next = NULL;
|
||||
SDL_AtomicSet(¤t_audio.playback_device_count, 0);
|
||||
SDL_AtomicSet(¤t_audio.recording_device_count, 0);
|
||||
SDL_SetAtomicInt(¤t_audio.playback_device_count, 0);
|
||||
SDL_SetAtomicInt(¤t_audio.recording_device_count, 0);
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
||||
SDL_PendingAudioDeviceEvent *pending_next = NULL;
|
||||
@@ -1094,7 +1094,7 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
|
||||
SDL_LockMutex(device->lock);
|
||||
|
||||
if (SDL_AtomicGet(&device->shutdown)) {
|
||||
if (SDL_GetAtomicInt(&device->shutdown)) {
|
||||
SDL_UnlockMutex(device->lock);
|
||||
return false; // we're done, shut it down.
|
||||
}
|
||||
@@ -1118,7 +1118,7 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
// We should have updated this elsewhere if the format changed!
|
||||
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &device->spec, stream->dst_chmap, device->chmap));
|
||||
|
||||
const int br = SDL_AtomicGet(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain);
|
||||
const int br = SDL_GetAtomicInt(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain);
|
||||
if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
|
||||
failed = true;
|
||||
SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die.
|
||||
@@ -1139,7 +1139,7 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
SDL_memset(final_mix_buffer, '\0', work_buffer_size); // start with silence.
|
||||
|
||||
for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev; logdev = logdev->next) {
|
||||
if (SDL_AtomicGet(&logdev->paused)) {
|
||||
if (SDL_GetAtomicInt(&logdev->paused)) {
|
||||
continue; // paused? Skip this logical device.
|
||||
}
|
||||
|
||||
@@ -1202,7 +1202,7 @@ void SDL_PlaybackAudioThreadShutdown(SDL_AudioDevice *device)
|
||||
SDL_assert(!device->recording);
|
||||
const int frames = device->buffer_size / SDL_AUDIO_FRAMESIZE(device->spec);
|
||||
// Wait for the audio to drain if device didn't die.
|
||||
if (!SDL_AtomicGet(&device->zombie)) {
|
||||
if (!SDL_GetAtomicInt(&device->zombie)) {
|
||||
SDL_Delay(((frames * 1000) / device->spec.freq) * 2);
|
||||
}
|
||||
current_audio.impl.ThreadDeinit(device);
|
||||
@@ -1242,7 +1242,7 @@ bool SDL_RecordingAudioThreadIterate(SDL_AudioDevice *device)
|
||||
|
||||
SDL_LockMutex(device->lock);
|
||||
|
||||
if (SDL_AtomicGet(&device->shutdown)) {
|
||||
if (SDL_GetAtomicInt(&device->shutdown)) {
|
||||
SDL_UnlockMutex(device->lock);
|
||||
return false; // we're done, shut it down.
|
||||
}
|
||||
@@ -1258,7 +1258,7 @@ bool SDL_RecordingAudioThreadIterate(SDL_AudioDevice *device)
|
||||
failed = true;
|
||||
} else if (br > 0) { // queue the new data to each bound stream.
|
||||
for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev; logdev = logdev->next) {
|
||||
if (SDL_AtomicGet(&logdev->paused)) {
|
||||
if (SDL_GetAtomicInt(&logdev->paused)) {
|
||||
continue; // paused? Skip this logical device.
|
||||
}
|
||||
|
||||
@@ -1342,7 +1342,7 @@ static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
|
||||
if (SDL_GetCurrentAudioDriver()) {
|
||||
SDL_LockRWLockForReading(current_audio.device_hash_lock);
|
||||
{
|
||||
num_devices = SDL_AtomicGet(recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count);
|
||||
num_devices = SDL_GetAtomicInt(recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count);
|
||||
result = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
|
||||
if (result) {
|
||||
int devs_seen = 0;
|
||||
@@ -1443,7 +1443,7 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *sample_frames)
|
||||
bool SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *sample_frames)
|
||||
{
|
||||
if (!spec) {
|
||||
return SDL_InvalidParamError("spec");
|
||||
@@ -1490,7 +1490,7 @@ int *SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count)
|
||||
// BE CAREFUL WITH THIS.
|
||||
static void SerializePhysicalDeviceClose(SDL_AudioDevice *device)
|
||||
{
|
||||
while (SDL_AtomicGet(&device->shutdown)) {
|
||||
while (SDL_GetAtomicInt(&device->shutdown)) {
|
||||
SDL_WaitCondition(device->close_cond, device->lock);
|
||||
}
|
||||
}
|
||||
@@ -1500,7 +1500,7 @@ static void ClosePhysicalAudioDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
SerializePhysicalDeviceClose(device);
|
||||
|
||||
SDL_AtomicSet(&device->shutdown, 1);
|
||||
SDL_SetAtomicInt(&device->shutdown, 1);
|
||||
|
||||
// YOU MUST PROTECT KEY POINTS WITH SerializePhysicalDeviceClose() WHILE THE THREAD JOINS
|
||||
SDL_UnlockMutex(device->lock);
|
||||
@@ -1517,7 +1517,7 @@ static void ClosePhysicalAudioDevice(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
SDL_LockMutex(device->lock);
|
||||
SDL_AtomicSet(&device->shutdown, 0); // ready to go again.
|
||||
SDL_SetAtomicInt(&device->shutdown, 0); // ready to go again.
|
||||
SDL_BroadcastCondition(device->close_cond); // release anyone waiting in SerializePhysicalDeviceClose; they'll still block until we release device->lock, though.
|
||||
|
||||
SDL_aligned_free(device->work_buffer);
|
||||
@@ -1630,7 +1630,7 @@ static bool OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec
|
||||
}
|
||||
|
||||
// Just pretend to open a zombie device. It can still collect logical devices on a default device under the assumption they will all migrate when the default device is officially changed.
|
||||
if (SDL_AtomicGet(&device->zombie)) {
|
||||
if (SDL_GetAtomicInt(&device->zombie)) {
|
||||
return true; // Braaaaaaaaains.
|
||||
}
|
||||
|
||||
@@ -1719,7 +1719,7 @@ SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSp
|
||||
|
||||
if (device) {
|
||||
SDL_LogicalAudioDevice *logdev = NULL;
|
||||
if (!wants_default && SDL_AtomicGet(&device->zombie)) {
|
||||
if (!wants_default && SDL_GetAtomicInt(&device->zombie)) {
|
||||
// uhoh, this device is undead, and just waiting to be cleaned up. Refuse explicit opens.
|
||||
SDL_SetError("Device was already lost and can't accept new opens");
|
||||
} else if ((logdev = (SDL_LogicalAudioDevice *) SDL_calloc(1, sizeof (SDL_LogicalAudioDevice))) == NULL) {
|
||||
@@ -1728,7 +1728,7 @@ SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSp
|
||||
SDL_free(logdev);
|
||||
} else {
|
||||
RefPhysicalAudioDevice(device); // unref'd on successful SDL_CloseAudioDevice
|
||||
SDL_AtomicSet(&logdev->paused, 0);
|
||||
SDL_SetAtomicInt(&logdev->paused, 0);
|
||||
result = logdev->instance_id = AssignAudioDeviceInstanceId(device->recording, /*islogical=*/true);
|
||||
logdev->physical_device = device;
|
||||
logdev->gain = 1.0f;
|
||||
@@ -1761,28 +1761,28 @@ static bool SetLogicalAudioDevicePauseState(SDL_AudioDeviceID devid, int value)
|
||||
SDL_AudioDevice *device = NULL;
|
||||
SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid, &device);
|
||||
if (logdev) {
|
||||
SDL_AtomicSet(&logdev->paused, value);
|
||||
SDL_SetAtomicInt(&logdev->paused, value);
|
||||
}
|
||||
ReleaseAudioDevice(device);
|
||||
return logdev ? true : false; // ObtainLogicalAudioDevice will have set an error.
|
||||
}
|
||||
|
||||
SDL_bool SDL_PauseAudioDevice(SDL_AudioDeviceID devid)
|
||||
bool SDL_PauseAudioDevice(SDL_AudioDeviceID devid)
|
||||
{
|
||||
return SetLogicalAudioDevicePauseState(devid, 1);
|
||||
}
|
||||
|
||||
SDL_bool SDLCALL SDL_ResumeAudioDevice(SDL_AudioDeviceID devid)
|
||||
bool SDLCALL SDL_ResumeAudioDevice(SDL_AudioDeviceID devid)
|
||||
{
|
||||
return SetLogicalAudioDevicePauseState(devid, 0);
|
||||
}
|
||||
|
||||
SDL_bool SDL_AudioDevicePaused(SDL_AudioDeviceID devid)
|
||||
bool SDL_AudioDevicePaused(SDL_AudioDeviceID devid)
|
||||
{
|
||||
SDL_AudioDevice *device = NULL;
|
||||
SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid, &device);
|
||||
bool result = false;
|
||||
if (logdev && SDL_AtomicGet(&logdev->paused)) {
|
||||
if (logdev && SDL_GetAtomicInt(&logdev->paused)) {
|
||||
result = true;
|
||||
}
|
||||
ReleaseAudioDevice(device);
|
||||
@@ -1798,7 +1798,7 @@ float SDL_GetAudioDeviceGain(SDL_AudioDeviceID devid)
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioDeviceGain(SDL_AudioDeviceID devid, float gain)
|
||||
bool SDL_SetAudioDeviceGain(SDL_AudioDeviceID devid, float gain)
|
||||
{
|
||||
if (gain < 0.0f) {
|
||||
return SDL_InvalidParamError("gain");
|
||||
@@ -1827,7 +1827,7 @@ SDL_bool SDL_SetAudioDeviceGain(SDL_AudioDeviceID devid, float gain)
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid, SDL_AudioPostmixCallback callback, void *userdata)
|
||||
bool SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid, SDL_AudioPostmixCallback callback, void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = NULL;
|
||||
SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid, &device);
|
||||
@@ -1862,7 +1862,7 @@ SDL_bool SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid, SDL_AudioPostmixCa
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int num_streams)
|
||||
bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int num_streams)
|
||||
{
|
||||
const bool islogical = !(devid & (1<<1));
|
||||
SDL_AudioDevice *device = NULL;
|
||||
@@ -1955,7 +1955,7 @@ SDL_bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream)
|
||||
bool SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream)
|
||||
{
|
||||
return SDL_BindAudioStreams(devid, &stream, 1);
|
||||
}
|
||||
@@ -2067,7 +2067,7 @@ SDL_AudioStream *SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_Au
|
||||
if (!logdev) { // this shouldn't happen, but just in case.
|
||||
failed = true;
|
||||
} else {
|
||||
SDL_AtomicSet(&logdev->paused, 1); // start the device paused, to match SDL2.
|
||||
SDL_SetAtomicInt(&logdev->paused, 1); // start the device paused, to match SDL2.
|
||||
|
||||
SDL_assert(device != NULL);
|
||||
const bool recording = device->recording;
|
||||
@@ -2120,7 +2120,7 @@ SDL_AudioStream *SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_Au
|
||||
return stream;
|
||||
}
|
||||
|
||||
SDL_bool SDL_PauseAudioStreamDevice(SDL_AudioStream *stream)
|
||||
bool SDL_PauseAudioStreamDevice(SDL_AudioStream *stream)
|
||||
{
|
||||
SDL_AudioDeviceID devid = SDL_GetAudioStreamDevice(stream);
|
||||
if (!devid) {
|
||||
@@ -2130,7 +2130,7 @@ SDL_bool SDL_PauseAudioStreamDevice(SDL_AudioStream *stream)
|
||||
return SDL_PauseAudioDevice(devid);
|
||||
}
|
||||
|
||||
SDL_bool SDL_ResumeAudioStreamDevice(SDL_AudioStream *stream)
|
||||
bool SDL_ResumeAudioStreamDevice(SDL_AudioStream *stream)
|
||||
{
|
||||
SDL_AudioDeviceID devid = SDL_GetAudioStreamDevice(stream);
|
||||
if (!devid) {
|
||||
@@ -2302,7 +2302,7 @@ void SDL_DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device)
|
||||
new_default_device->logical_devices = logdev;
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
||||
SDL_assert(SDL_AtomicGet(¤t_default_device->refcount) > 1); // we should hold at least one extra reference to this device, beyond logical devices, during this phase...
|
||||
SDL_assert(SDL_GetAtomicInt(¤t_default_device->refcount) > 1); // we should hold at least one extra reference to this device, beyond logical devices, during this phase...
|
||||
RefPhysicalAudioDevice(new_default_device);
|
||||
UnrefPhysicalAudioDevice(current_default_device);
|
||||
|
||||
@@ -2474,7 +2474,7 @@ void SDL_UpdateAudio(void)
|
||||
SDL_zero(event);
|
||||
event.type = i->type;
|
||||
event.adevice.which = (Uint32) i->devid;
|
||||
event.adevice.recording = (i->devid & (1<<0)) ? 0 : 1; // bit #0 of devid is set for playback devices and unset for recording.
|
||||
event.adevice.recording = ((i->devid & (1<<0)) == 0); // bit #0 of devid is set for playback devices and unset for recording.
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
SDL_free(i);
|
||||
|
||||
30
external/SDL/src/audio/SDL_audiocvt.c
vendored
30
external/SDL/src/audio/SDL_audiocvt.c
vendored
@@ -448,7 +448,7 @@ SDL_PropertiesID SDL_GetAudioStreamProperties(SDL_AudioStream *stream)
|
||||
return stream->props;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata)
|
||||
bool SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -460,7 +460,7 @@ SDL_bool SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamC
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata)
|
||||
bool SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -472,7 +472,7 @@ SDL_bool SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamC
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_bool SDL_LockAudioStream(SDL_AudioStream *stream)
|
||||
bool SDL_LockAudioStream(SDL_AudioStream *stream)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -481,7 +481,7 @@ SDL_bool SDL_LockAudioStream(SDL_AudioStream *stream)
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_bool SDL_UnlockAudioStream(SDL_AudioStream *stream)
|
||||
bool SDL_UnlockAudioStream(SDL_AudioStream *stream)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -490,7 +490,7 @@ SDL_bool SDL_UnlockAudioStream(SDL_AudioStream *stream)
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_bool SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_spec, SDL_AudioSpec *dst_spec)
|
||||
bool SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_spec, SDL_AudioSpec *dst_spec)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -514,7 +514,7 @@ SDL_bool SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_sp
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec)
|
||||
bool SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -626,12 +626,12 @@ bool SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec *spec
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamInputChannelMap(SDL_AudioStream *stream, const int *chmap, int channels)
|
||||
bool SDL_SetAudioStreamInputChannelMap(SDL_AudioStream *stream, const int *chmap, int channels)
|
||||
{
|
||||
return SetAudioStreamChannelMap(stream, &stream->src_spec, &stream->src_chmap, chmap, channels, true);
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamOutputChannelMap(SDL_AudioStream *stream, const int *chmap, int channels)
|
||||
bool SDL_SetAudioStreamOutputChannelMap(SDL_AudioStream *stream, const int *chmap, int channels)
|
||||
{
|
||||
return SetAudioStreamChannelMap(stream, &stream->dst_spec, &stream->dst_chmap, chmap, channels, false);
|
||||
}
|
||||
@@ -686,7 +686,7 @@ float SDL_GetAudioStreamFrequencyRatio(SDL_AudioStream *stream)
|
||||
return freq_ratio;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamFrequencyRatio(SDL_AudioStream *stream, float freq_ratio)
|
||||
bool SDL_SetAudioStreamFrequencyRatio(SDL_AudioStream *stream, float freq_ratio)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -723,7 +723,7 @@ float SDL_GetAudioStreamGain(SDL_AudioStream *stream)
|
||||
return gain;
|
||||
}
|
||||
|
||||
SDL_bool SDL_SetAudioStreamGain(SDL_AudioStream *stream, float gain)
|
||||
bool SDL_SetAudioStreamGain(SDL_AudioStream *stream, float gain)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -805,7 +805,7 @@ static void SDLCALL FreeAllocatedAudioBuffer(void *userdata, const void *buf, in
|
||||
SDL_free((void*) buf);
|
||||
}
|
||||
|
||||
SDL_bool SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len)
|
||||
bool SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -841,7 +841,7 @@ SDL_bool SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int le
|
||||
return PutAudioStreamBuffer(stream, buf, len, NULL, NULL);
|
||||
}
|
||||
|
||||
SDL_bool SDL_FlushAudioStream(SDL_AudioStream *stream)
|
||||
bool SDL_FlushAudioStream(SDL_AudioStream *stream)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -1013,7 +1013,7 @@ static bool GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int o
|
||||
// Calculate the number of input frames necessary for this request.
|
||||
// Because resampling happens "between" frames, The same number of output_frames
|
||||
// can require a different number of input_frames, depending on the resample_offset.
|
||||
// Infact, input_frames can sometimes even be zero when upsampling.
|
||||
// In fact, input_frames can sometimes even be zero when upsampling.
|
||||
const int input_frames = (int) SDL_GetResamplerInputFrames(output_frames, resample_rate, stream->resample_offset);
|
||||
|
||||
const int padding_frames = SDL_GetResamplerPaddingFrames(resample_rate);
|
||||
@@ -1254,7 +1254,7 @@ int SDL_GetAudioStreamQueued(SDL_AudioStream *stream)
|
||||
return (int) SDL_min(total, SDL_INT_MAX);
|
||||
}
|
||||
|
||||
SDL_bool SDL_ClearAudioStream(SDL_AudioStream *stream)
|
||||
bool SDL_ClearAudioStream(SDL_AudioStream *stream)
|
||||
{
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
@@ -1303,7 +1303,7 @@ static void SDLCALL DontFreeThisAudioBuffer(void *userdata, const void *buf, int
|
||||
// We don't own the buffer, but know it will outlive the stream
|
||||
}
|
||||
|
||||
SDL_bool SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len)
|
||||
bool SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len)
|
||||
{
|
||||
if (dst_data) {
|
||||
*dst_data = NULL;
|
||||
|
||||
13
external/SDL/src/audio/SDL_audioresample.c
vendored
13
external/SDL/src/audio/SDL_audioresample.c
vendored
@@ -574,16 +574,11 @@ static void SetupAudioResampler(void)
|
||||
|
||||
void SDL_SetupAudioResampler(void)
|
||||
{
|
||||
static SDL_SpinLock running = 0;
|
||||
static SDL_InitState init;
|
||||
|
||||
if (!ResampleFrame[0]) {
|
||||
SDL_LockSpinlock(&running);
|
||||
|
||||
if (!ResampleFrame[0]) {
|
||||
SetupAudioResampler();
|
||||
}
|
||||
|
||||
SDL_UnlockSpinlock(&running);
|
||||
if (SDL_ShouldInit(&init)) {
|
||||
SetupAudioResampler();
|
||||
SDL_SetInitialized(&init, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
external/SDL/src/audio/SDL_mixer.c
vendored
2
external/SDL/src/audio/SDL_mixer.c
vendored
@@ -86,7 +86,7 @@ static const Uint8 mix8[] = {
|
||||
// !!! FIXME: Add fast-path for volume = 1
|
||||
// !!! FIXME: Use larger scales for 16-bit/32-bit integers
|
||||
|
||||
SDL_bool SDL_MixAudio(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, Uint32 len, float fvolume)
|
||||
bool SDL_MixAudio(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, Uint32 len, float fvolume)
|
||||
{
|
||||
int volume = (int)SDL_roundf(fvolume * MIX_MAXVOLUME);
|
||||
|
||||
|
||||
6
external/SDL/src/audio/SDL_wave.c
vendored
6
external/SDL/src/audio/SDL_wave.c
vendored
@@ -24,7 +24,7 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifndef INT_MAX
|
||||
// Make a lucky guess.
|
||||
SDL_COMPILE_TIME_ASSERT(int_size, sizeof(int) == sizeof(Sint32));
|
||||
#define INT_MAX SDL_MAX_SINT32
|
||||
#endif
|
||||
#ifndef SIZE_MAX
|
||||
@@ -2076,7 +2076,7 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_bool SDL_LoadWAV_IO(SDL_IOStream *src, SDL_bool closeio, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
bool result = false;
|
||||
WaveFile file;
|
||||
@@ -2130,7 +2130,7 @@ done:
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool SDL_LoadWAV(const char *path, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
bool SDL_LoadWAV(const char *path, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
return SDL_LoadWAV_IO(SDL_IOFromFile(path, "rb"), 1, spec, audio_buf, audio_len);
|
||||
}
|
||||
|
||||
28
external/SDL/src/audio/aaudio/SDL_aaudio.c
vendored
28
external/SDL/src/audio/aaudio/SDL_aaudio.c
vendored
@@ -82,7 +82,7 @@ static void AAUDIO_errorCallback(AAudioStream *stream, void *userData, aaudio_re
|
||||
// You MUST NOT close the audio stream from this callback, so we cannot call SDL_AudioDeviceDisconnected here.
|
||||
// Just flag the device so we can kill it in PlayDevice instead.
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userData;
|
||||
SDL_AtomicSet(&device->hidden->error_callback_triggered, (int) error); // AAUDIO_OK is zero, so !triggered means no error.
|
||||
SDL_SetAtomicInt(&device->hidden->error_callback_triggered, (int) error); // AAUDIO_OK is zero, so !triggered means no error.
|
||||
SDL_SignalSemaphore(device->hidden->semaphore); // in case we're blocking in WaitDevice.
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize)
|
||||
|
||||
static bool AAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
// this semaphore won't fire when the app is in the background (AAUDIO_PauseDevices was called).
|
||||
if (SDL_WaitSemaphoreTimeout(device->hidden->semaphore, 100)) {
|
||||
return true; // semaphore was signaled, let's go!
|
||||
@@ -218,7 +218,7 @@ static bool AAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int
|
||||
struct SDL_PrivateAudioData *hidden = device->hidden;
|
||||
|
||||
// AAUDIO_dataCallback picks up our work and unblocks AAUDIO_WaitDevice. But make sure we didn't fail here.
|
||||
const aaudio_result_t err = (aaudio_result_t) SDL_AtomicGet(&hidden->error_callback_triggered);
|
||||
const aaudio_result_t err = (aaudio_result_t) SDL_GetAtomicInt(&hidden->error_callback_triggered);
|
||||
if (err) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "aaudio: Audio device triggered error %d (%s)", (int) err, ctx.AAudio_convertResultToText(err));
|
||||
|
||||
@@ -237,8 +237,8 @@ static int AAUDIO_RecordDevice(SDL_AudioDevice *device, void *buffer, int buflen
|
||||
struct SDL_PrivateAudioData *hidden = device->hidden;
|
||||
|
||||
// AAUDIO_dataCallback picks up our work and unblocks AAUDIO_WaitDevice. But make sure we didn't fail here.
|
||||
if (SDL_AtomicGet(&hidden->error_callback_triggered)) {
|
||||
SDL_AtomicSet(&hidden->error_callback_triggered, 0);
|
||||
if (SDL_GetAtomicInt(&hidden->error_callback_triggered)) {
|
||||
SDL_SetAtomicInt(&hidden->error_callback_triggered, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
|
||||
const bool recording = device->recording;
|
||||
aaudio_result_t res;
|
||||
|
||||
SDL_AtomicSet(&hidden->error_callback_triggered, 0);
|
||||
SDL_SetAtomicInt(&hidden->error_callback_triggered, 0);
|
||||
|
||||
AAudioStreamBuilder *builder = NULL;
|
||||
res = ctx.AAudio_createStreamBuilder(&builder);
|
||||
@@ -308,8 +308,8 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
|
||||
}
|
||||
ctx.AAudioStreamBuilder_setFormat(builder, format);
|
||||
ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq);
|
||||
ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels);
|
||||
#endif
|
||||
ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels);
|
||||
|
||||
const aaudio_direction_t direction = (recording ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT);
|
||||
ctx.AAudioStreamBuilder_setDirection(builder, direction);
|
||||
@@ -320,7 +320,7 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
|
||||
ctx.AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
|
||||
}
|
||||
|
||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||
LOGI("AAudio Try to open %u hz %u bit %u channels %s samples %u",
|
||||
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
||||
device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames);
|
||||
|
||||
@@ -370,7 +370,7 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGI("AAudio Actually opened %u hz %u bit chan %u %s samples %u, buffers %d",
|
||||
LOGI("AAudio Actually opened %u hz %u bit %u channels %s samples %u, buffers %d",
|
||||
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
||||
device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames, hidden->num_buffers);
|
||||
|
||||
@@ -386,9 +386,9 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
// !!! FIXME: make this non-blocking!
|
||||
static void SDLCALL RequestAndroidPermissionBlockingCallback(void *userdata, const char *permission, SDL_bool granted)
|
||||
static void SDLCALL RequestAndroidPermissionBlockingCallback(void *userdata, const char *permission, bool granted)
|
||||
{
|
||||
SDL_AtomicSet((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
||||
SDL_SetAtomicInt((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
||||
}
|
||||
|
||||
static bool AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
@@ -402,16 +402,16 @@ static bool AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
if (device->recording) {
|
||||
// !!! FIXME: make this non-blocking!
|
||||
SDL_AtomicInt permission_response;
|
||||
SDL_AtomicSet(&permission_response, 0);
|
||||
SDL_SetAtomicInt(&permission_response, 0);
|
||||
if (!SDL_RequestAndroidPermission("android.permission.RECORD_AUDIO", RequestAndroidPermissionBlockingCallback, &permission_response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (SDL_AtomicGet(&permission_response) == 0) {
|
||||
while (SDL_GetAtomicInt(&permission_response) == 0) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&permission_response) < 0) {
|
||||
if (SDL_GetAtomicInt(&permission_response) < 0) {
|
||||
LOGI("This app doesn't have RECORD_AUDIO permission");
|
||||
return SDL_SetError("This app doesn't have RECORD_AUDIO permission");
|
||||
}
|
||||
|
||||
12
external/SDL/src/audio/alsa/SDL_alsa_audio.c
vendored
12
external/SDL/src/audio/alsa/SDL_alsa_audio.c
vendored
@@ -265,7 +265,7 @@ static bool ALSA_WaitDevice(SDL_AudioDevice *device)
|
||||
const int fulldelay = (int) ((((Uint64) device->sample_frames) * 1000) / device->spec.freq);
|
||||
const int delay = SDL_max(fulldelay, 10);
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
const int rc = ALSA_snd_pcm_wait(device->hidden->pcm_handle, delay);
|
||||
if (rc < 0 && (rc != -EAGAIN)) {
|
||||
const int status = ALSA_snd_pcm_recover(device->hidden->pcm_handle, rc, 0);
|
||||
@@ -294,7 +294,7 @@ static bool ALSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int bu
|
||||
const int frame_size = SDL_AUDIO_FRAMESIZE(device->spec);
|
||||
snd_pcm_uframes_t frames_left = (snd_pcm_uframes_t) (buflen / frame_size);
|
||||
|
||||
while ((frames_left > 0) && !SDL_AtomicGet(&device->shutdown)) {
|
||||
while ((frames_left > 0) && !SDL_GetAtomicInt(&device->shutdown)) {
|
||||
const int rc = ALSA_snd_pcm_writei(device->hidden->pcm_handle, sample_buf, frames_left);
|
||||
//SDL_LogInfo(SDL_LOG_CATEGORY_AUDIO, "ALSA PLAYDEVICE: WROTE %d of %d bytes", (rc >= 0) ? ((int) (rc * frame_size)) : rc, (int) (frames_left * frame_size));
|
||||
SDL_assert(rc != 0); // assuming this can't happen if we used snd_pcm_wait and queried for available space.
|
||||
@@ -825,10 +825,10 @@ static int SDLCALL ALSA_HotplugThread(void *arg)
|
||||
{
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
|
||||
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&ALSA_hotplug_shutdown)) {
|
||||
// Block awhile before checking again, unless we're told to stop.
|
||||
const Uint64 ticks = SDL_GetTicks() + 5000;
|
||||
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && SDL_GetTicks() < ticks) {
|
||||
while (!SDL_GetAtomicInt(&ALSA_hotplug_shutdown) && SDL_GetTicks() < ticks) {
|
||||
SDL_Delay(100);
|
||||
}
|
||||
|
||||
@@ -853,7 +853,7 @@ static void ALSA_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDevi
|
||||
}
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 0);
|
||||
SDL_SetAtomicInt(&ALSA_hotplug_shutdown, 0);
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL);
|
||||
// if the thread doesn't spin, oh well, you just don't get further hotplug events.
|
||||
#endif
|
||||
@@ -866,7 +866,7 @@ static void ALSA_DeinitializeStart(void)
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
if (ALSA_hotplug_thread) {
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 1);
|
||||
SDL_SetAtomicInt(&ALSA_hotplug_shutdown, 1);
|
||||
SDL_WaitThread(ALSA_hotplug_thread, NULL);
|
||||
ALSA_hotplug_thread = NULL;
|
||||
}
|
||||
|
||||
@@ -622,7 +622,7 @@ static void RecordingBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, A
|
||||
|
||||
// buffer is unexpectedly here? We're probably dying, but try to requeue this buffer anyhow.
|
||||
if (device->hidden->current_buffer != NULL) {
|
||||
SDL_assert(SDL_AtomicGet(&device->shutdown) != 0);
|
||||
SDL_assert(SDL_GetAtomicInt(&device->shutdown) != 0);
|
||||
COREAUDIO_FlushRecording(device); // just flush it manually, which will requeue it.
|
||||
}
|
||||
}
|
||||
@@ -641,7 +641,7 @@ static void COREAUDIO_CloseDevice(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
if (device->hidden->thread) {
|
||||
SDL_assert(SDL_AtomicGet(&device->shutdown) != 0); // should have been set by SDL_audio.c
|
||||
SDL_assert(SDL_GetAtomicInt(&device->shutdown) != 0); // should have been set by SDL_audio.c
|
||||
SDL_WaitThread(device->hidden->thread, NULL);
|
||||
}
|
||||
|
||||
@@ -839,7 +839,7 @@ static int AudioQueueThreadEntry(void *arg)
|
||||
SDL_SignalSemaphore(device->hidden->ready_semaphore);
|
||||
|
||||
// This would be WaitDevice/WaitRecordingDevice in the normal SDL audio thread, but we get *BufferReadyCallback calls here to know when to iterate.
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ static bool DSOUND_WaitDevice(SDL_AudioDevice *device)
|
||||
/* Semi-busy wait, since we have no way of getting play notification
|
||||
on a primary mixing buffer located in hardware (DirectX 5.0)
|
||||
*/
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
DWORD status = 0;
|
||||
DWORD cursor = 0;
|
||||
DWORD junk = 0;
|
||||
@@ -336,7 +336,7 @@ static Uint8 *DSOUND_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||
static bool DSOUND_WaitRecordingDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = device->hidden;
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
DWORD junk, cursor;
|
||||
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
|
||||
return false;
|
||||
|
||||
2
external/SDL/src/audio/dsp/SDL_dspaudio.c
vendored
2
external/SDL/src/audio/dsp/SDL_dspaudio.c
vendored
@@ -204,7 +204,7 @@ static bool DSP_WaitDevice(SDL_AudioDevice *device)
|
||||
const unsigned long ioctlreq = device->recording ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE;
|
||||
struct SDL_PrivateAudioData *h = device->hidden;
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
audio_buf_info info;
|
||||
const int rc = ioctl(h->audio_fd, ioctlreq, &info);
|
||||
if (rc < 0) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
Uint8 *mixbuf; // The file descriptor for the audio device
|
||||
Uint32 io_delay; // miliseconds to sleep in WaitDevice.
|
||||
Uint32 io_delay; // milliseconds to sleep in WaitDevice.
|
||||
};
|
||||
|
||||
#endif // SDL_dummyaudio_h_
|
||||
|
||||
2
external/SDL/src/audio/n3ds/SDL_n3dsaudio.c
vendored
2
external/SDL/src/audio/n3ds/SDL_n3dsaudio.c
vendored
@@ -203,7 +203,7 @@ static bool N3DSAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, i
|
||||
static bool N3DSAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
contextLock(device);
|
||||
while (!device->hidden->isCancelled && !SDL_AtomicGet(&device->shutdown) &&
|
||||
while (!device->hidden->isCancelled && !SDL_GetAtomicInt(&device->shutdown) &&
|
||||
device->hidden->waveBuf[device->hidden->nextbuf].status != NDSP_WBUF_FREE) {
|
||||
CondVar_Wait(&device->hidden->cv, &device->hidden->lock);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ static void NETBSDAUDIO_Status(SDL_AudioDevice *device)
|
||||
static bool NETBSDAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
const bool recording = device->recording;
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
audio_info_t info;
|
||||
const int rc = ioctl(device->hidden->audio_fd, AUDIO_GETINFO, &info);
|
||||
if (rc < 0) {
|
||||
|
||||
16
external/SDL/src/audio/openslES/SDL_openslES.c
vendored
16
external/SDL/src/audio/openslES/SDL_openslES.c
vendored
@@ -229,9 +229,9 @@ static void OPENSLES_DestroyPCMRecorder(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
// !!! FIXME: make this non-blocking!
|
||||
static void SDLCALL RequestAndroidPermissionBlockingCallback(void *userdata, const char *permission, SDL_bool granted)
|
||||
static void SDLCALL RequestAndroidPermissionBlockingCallback(void *userdata, const char *permission, bool granted)
|
||||
{
|
||||
SDL_AtomicSet((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
||||
SDL_SetAtomicInt((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
||||
}
|
||||
|
||||
static bool OPENSLES_CreatePCMRecorder(SDL_AudioDevice *device)
|
||||
@@ -250,16 +250,16 @@ static bool OPENSLES_CreatePCMRecorder(SDL_AudioDevice *device)
|
||||
// !!! FIXME: make this non-blocking!
|
||||
{
|
||||
SDL_AtomicInt permission_response;
|
||||
SDL_AtomicSet(&permission_response, 0);
|
||||
SDL_SetAtomicInt(&permission_response, 0);
|
||||
if (!SDL_RequestAndroidPermission("android.permission.RECORD_AUDIO", RequestAndroidPermissionBlockingCallback, &permission_response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (SDL_AtomicGet(&permission_response) == 0) {
|
||||
while (SDL_GetAtomicInt(&permission_response) == 0) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&permission_response) < 0) {
|
||||
if (SDL_GetAtomicInt(&permission_response) < 0) {
|
||||
LOGE("This app doesn't have RECORD_AUDIO permission");
|
||||
return SDL_SetError("This app doesn't have RECORD_AUDIO permission");
|
||||
}
|
||||
@@ -273,7 +273,7 @@ static bool OPENSLES_CreatePCMRecorder(SDL_AudioDevice *device)
|
||||
// Update the fragment size as size in bytes
|
||||
SDL_UpdatedAudioDeviceFormat(device);
|
||||
|
||||
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
|
||||
LOGI("Try to open %u hz %u bit %u channels %s samples %u",
|
||||
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
||||
device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->sample_frames);
|
||||
|
||||
@@ -453,7 +453,7 @@ static bool OPENSLES_CreatePCMPlayer(SDL_AudioDevice *device)
|
||||
// Update the fragment size as size in bytes
|
||||
SDL_UpdatedAudioDeviceFormat(device);
|
||||
|
||||
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
|
||||
LOGI("Try to open %u hz %s %u bit %u channels %s samples %u",
|
||||
device->spec.freq, SDL_AUDIO_ISFLOAT(device->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(device->spec.format),
|
||||
device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->sample_frames);
|
||||
|
||||
@@ -652,7 +652,7 @@ static bool OPENSLES_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
LOGV("OPENSLES_WaitDevice()");
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
// this semaphore won't fire when the app is in the background (OPENSLES_PauseDevices was called).
|
||||
if (SDL_WaitSemaphoreTimeout(audiodata->playsem, 100)) {
|
||||
return true; // semaphore was signaled, let's go!
|
||||
|
||||
@@ -711,7 +711,7 @@ static bool hotplug_loop_init(void)
|
||||
spa_list_init(&hotplug_pending_list);
|
||||
spa_list_init(&hotplug_io_list);
|
||||
|
||||
hotplug_loop = PIPEWIRE_pw_thread_loop_new("SDLAudioHotplug", NULL);
|
||||
hotplug_loop = PIPEWIRE_pw_thread_loop_new("SDLPwAudioPlug", NULL);
|
||||
if (!hotplug_loop) {
|
||||
return SDL_SetError("Pipewire: Failed to create hotplug detection loop (%i)", errno);
|
||||
}
|
||||
@@ -1215,6 +1215,7 @@ static void PIPEWIRE_DeinitializeStart(void)
|
||||
static void PIPEWIRE_Deinitialize(void)
|
||||
{
|
||||
if (pipewire_initialized) {
|
||||
hotplug_loop_destroy();
|
||||
deinit_pipewire_library();
|
||||
pipewire_initialized = false;
|
||||
}
|
||||
@@ -1270,7 +1271,6 @@ static bool PIPEWIRE_PREFERRED_Init(SDL_AudioDriverImpl *impl)
|
||||
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
|
||||
|
||||
if (no_devices || !pipewire_core_version_at_least(1, 0, 0)) {
|
||||
hotplug_loop_destroy();
|
||||
PIPEWIRE_Deinitialize();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ static bool PULSEAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown) && (h->bytes_requested == 0)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && (h->bytes_requested == 0)) {
|
||||
//SDL_Log("PULSEAUDIO WAIT IN WAITDEVICE!");
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
|
||||
@@ -486,7 +486,7 @@ static bool PULSEAUDIO_WaitRecordingDevice(SDL_AudioDevice *device)
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||
//SDL_Log("PULSEAUDIO DEVICE FAILURE IN WAITRECORDINGDEVICE!");
|
||||
@@ -553,7 +553,7 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
|
||||
h->recordinglen = 0;
|
||||
}
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown) && (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||
//SDL_Log("PULSEAUDIO DEVICE FAILURE IN FLUSHRECORDING!");
|
||||
@@ -901,7 +901,7 @@ static int SDLCALL HotplugThread(void *data)
|
||||
|
||||
SDL_SignalSemaphore((SDL_Semaphore *) data);
|
||||
|
||||
while (SDL_AtomicGet(&pulseaudio_hotplug_thread_active)) {
|
||||
while (SDL_GetAtomicInt(&pulseaudio_hotplug_thread_active)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if (op && PULSEAUDIO_pa_operation_get_state(op) != PA_OPERATION_RUNNING) {
|
||||
PULSEAUDIO_pa_operation_unref(op);
|
||||
@@ -956,9 +956,14 @@ static void PULSEAUDIO_DetectDevices(SDL_AudioDevice **default_playback, SDL_Aud
|
||||
}
|
||||
|
||||
// ok, we have a sane list, let's set up hotplug notifications now...
|
||||
SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 1);
|
||||
pulseaudio_hotplug_thread = SDL_CreateThreadWithStackSize(HotplugThread, "PulseHotplug", 256 * 1024, ready_sem); // !!! FIXME: this can probably survive in significantly less stack space.
|
||||
SDL_WaitSemaphore(ready_sem);
|
||||
SDL_SetAtomicInt(&pulseaudio_hotplug_thread_active, 1);
|
||||
pulseaudio_hotplug_thread = SDL_CreateThread(HotplugThread, "PulseHotplug", ready_sem);
|
||||
if (pulseaudio_hotplug_thread) {
|
||||
SDL_WaitSemaphore(ready_sem); // wait until the thread hits it's main loop.
|
||||
} else {
|
||||
SDL_SetAtomicInt(&pulseaudio_hotplug_thread_active, 0); // thread failed to start, we'll go on without hotplug.
|
||||
}
|
||||
|
||||
SDL_DestroySemaphore(ready_sem);
|
||||
}
|
||||
|
||||
@@ -973,7 +978,7 @@ static void PULSEAUDIO_DeinitializeStart(void)
|
||||
{
|
||||
if (pulseaudio_hotplug_thread) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 0);
|
||||
SDL_SetAtomicInt(&pulseaudio_hotplug_thread_active, 0);
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
SDL_WaitThread(pulseaudio_hotplug_thread, NULL);
|
||||
|
||||
4
external/SDL/src/audio/qnx/SDL_qsa_audio.c
vendored
4
external/SDL/src/audio/qnx/SDL_qsa_audio.c
vendored
@@ -112,14 +112,14 @@ static bool QSA_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
static bool QSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||
{
|
||||
if (SDL_AtomicGet(&device->shutdown) || !device->hidden) {
|
||||
if (SDL_GetAtomicInt(&device->shutdown) || !device->hidden) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int towrite = buflen;
|
||||
|
||||
// Write the audio data, checking for EAGAIN (buffer full) and underrun
|
||||
while ((towrite > 0) && !SDL_AtomicGet(&device->shutdown));
|
||||
while ((towrite > 0) && !SDL_GetAtomicInt(&device->shutdown));
|
||||
const int bw = snd_pcm_plugin_write(device->hidden->audio_handle, buffer, towrite);
|
||||
if (bw != towrite) {
|
||||
// Check if samples playback got stuck somewhere in hardware or in the audio device driver
|
||||
|
||||
@@ -151,7 +151,7 @@ static bool SNDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
const bool recording = device->recording;
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
if (SNDIO_sio_eof(device->hidden->dev)) {
|
||||
return false;
|
||||
}
|
||||
@@ -200,7 +200,7 @@ static int SNDIO_RecordDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
||||
static void SNDIO_FlushRecording(SDL_AudioDevice *device)
|
||||
{
|
||||
char buf[512];
|
||||
while (!SDL_AtomicGet(&device->shutdown) && (SNDIO_sio_read(device->hidden->dev, buf, sizeof(buf)) > 0)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && (SNDIO_sio_read(device->hidden->dev, buf, sizeof(buf)) > 0)) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
4
external/SDL/src/audio/vita/SDL_vitaaudio.c
vendored
4
external/SDL/src/audio/vita/SDL_vitaaudio.c
vendored
@@ -137,7 +137,7 @@ static bool VITAAUD_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int
|
||||
static bool VITAAUD_WaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
// !!! FIXME: we might just need to sleep roughly as long as playback buffers take to process, based on sample rate, etc.
|
||||
while (!SDL_AtomicGet(&device->shutdown) && (sceAudioOutGetRestSample(device->hidden->port) >= device->buffer_size)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && (sceAudioOutGetRestSample(device->hidden->port) >= device->buffer_size)) {
|
||||
SDL_Delay(1);
|
||||
}
|
||||
return true;
|
||||
@@ -176,7 +176,7 @@ static bool VITAAUD_WaitRecordingDevice(SDL_AudioDevice *device)
|
||||
// there's only a blocking call to obtain more data, so we'll just sleep as
|
||||
// long as a buffer would run.
|
||||
const Uint64 endticks = SDL_GetTicks() + ((device->sample_frames * 1000) / device->spec.freq);
|
||||
while (!SDL_AtomicGet(&device->shutdown) && (SDL_GetTicks() < endticks)) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && (SDL_GetTicks() < endticks)) {
|
||||
SDL_Delay(1);
|
||||
}
|
||||
return true;
|
||||
|
||||
42
external/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
42
external/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
@@ -74,11 +74,11 @@ static void ManagementThreadMainloop(void)
|
||||
{
|
||||
SDL_LockMutex(ManagementThreadLock);
|
||||
ManagementThreadPendingTask *task;
|
||||
while (((task = (ManagementThreadPendingTask *)SDL_AtomicGetPointer((void **)&ManagementThreadPendingTasks)) != NULL) || !SDL_AtomicGet(&ManagementThreadShutdown)) {
|
||||
while (((task = (ManagementThreadPendingTask *)SDL_GetAtomicPointer((void **)&ManagementThreadPendingTasks)) != NULL) || !SDL_GetAtomicInt(&ManagementThreadShutdown)) {
|
||||
if (!task) {
|
||||
SDL_WaitCondition(ManagementThreadCondition, ManagementThreadLock); // block until there's something to do.
|
||||
} else {
|
||||
SDL_AtomicSetPointer((void **) &ManagementThreadPendingTasks, task->next); // take task off the pending list.
|
||||
SDL_SetAtomicPointer((void **) &ManagementThreadPendingTasks, task->next); // take task off the pending list.
|
||||
SDL_UnlockMutex(ManagementThreadLock); // let other things add to the list while we chew on this task.
|
||||
task->result = task->fn(task->userdata); // run this task.
|
||||
if (task->task_complete_sem) { // something waiting on result?
|
||||
@@ -101,7 +101,7 @@ bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, b
|
||||
return true; // completed!
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&ManagementThreadShutdown)) {
|
||||
if (SDL_GetAtomicInt(&ManagementThreadShutdown)) {
|
||||
return SDL_SetError("Can't add task, we're shutting down");
|
||||
}
|
||||
|
||||
@@ -127,14 +127,14 @@ bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, b
|
||||
|
||||
// add to end of task list.
|
||||
ManagementThreadPendingTask *prev = NULL;
|
||||
for (ManagementThreadPendingTask *i = (ManagementThreadPendingTask *)SDL_AtomicGetPointer((void **)&ManagementThreadPendingTasks); i; i = i->next) {
|
||||
for (ManagementThreadPendingTask *i = (ManagementThreadPendingTask *)SDL_GetAtomicPointer((void **)&ManagementThreadPendingTasks); i; i = i->next) {
|
||||
prev = i;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
prev->next = pending;
|
||||
} else {
|
||||
SDL_AtomicSetPointer((void **) &ManagementThreadPendingTasks, pending);
|
||||
SDL_SetAtomicPointer((void **) &ManagementThreadPendingTasks, pending);
|
||||
}
|
||||
|
||||
// task is added to the end of the pending list, let management thread rip!
|
||||
@@ -210,8 +210,8 @@ static bool InitManagementThread(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_AtomicSetPointer((void **) &ManagementThreadPendingTasks, NULL);
|
||||
SDL_AtomicSet(&ManagementThreadShutdown, 0);
|
||||
SDL_SetAtomicPointer((void **) &ManagementThreadPendingTasks, NULL);
|
||||
SDL_SetAtomicInt(&ManagementThreadShutdown, 0);
|
||||
ManagementThread = SDL_CreateThreadWithStackSize(ManagementThreadEntry, "SDLWASAPIMgmt", 256 * 1024, &mgmtdata); // !!! FIXME: maybe even smaller stack size?
|
||||
if (!ManagementThread) {
|
||||
return false;
|
||||
@@ -234,7 +234,7 @@ static bool InitManagementThread(void)
|
||||
static void DeinitManagementThread(void)
|
||||
{
|
||||
if (ManagementThread) {
|
||||
SDL_AtomicSet(&ManagementThreadShutdown, 1);
|
||||
SDL_SetAtomicInt(&ManagementThreadShutdown, 1);
|
||||
SDL_LockMutex(ManagementThreadLock);
|
||||
SDL_SignalCondition(ManagementThreadCondition);
|
||||
SDL_UnlockMutex(ManagementThreadLock);
|
||||
@@ -242,13 +242,13 @@ static void DeinitManagementThread(void)
|
||||
ManagementThread = NULL;
|
||||
}
|
||||
|
||||
SDL_assert(SDL_AtomicGetPointer((void **) &ManagementThreadPendingTasks) == NULL);
|
||||
SDL_assert(SDL_GetAtomicPointer((void **) &ManagementThreadPendingTasks) == NULL);
|
||||
|
||||
SDL_DestroyCondition(ManagementThreadCondition);
|
||||
SDL_DestroyMutex(ManagementThreadLock);
|
||||
ManagementThreadCondition = NULL;
|
||||
ManagementThreadLock = NULL;
|
||||
SDL_AtomicSet(&ManagementThreadShutdown, 0);
|
||||
SDL_SetAtomicInt(&ManagementThreadShutdown, 0);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@@ -325,12 +325,6 @@ static bool mgmtthrtask_CoTaskMemFree(void *userdata)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_PlatformDeleteActivationHandler(void *userdata)
|
||||
{
|
||||
WASAPI_PlatformDeleteActivationHandler(userdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_CloseHandle(void *userdata)
|
||||
{
|
||||
CloseHandle((HANDLE) userdata);
|
||||
@@ -370,12 +364,6 @@ static void ResetWasapiDevice(SDL_AudioDevice *device)
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_CoTaskMemFree, ptr, NULL);
|
||||
}
|
||||
|
||||
if (device->hidden->activation_handler) {
|
||||
void *activation_handler = device->hidden->activation_handler;
|
||||
device->hidden->activation_handler = NULL;
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_PlatformDeleteActivationHandler, activation_handler, NULL);
|
||||
}
|
||||
|
||||
if (device->hidden->event) {
|
||||
HANDLE event = device->hidden->event;
|
||||
device->hidden->event = NULL;
|
||||
@@ -415,14 +403,14 @@ static bool RecoverWasapiDevice(SDL_AudioDevice *device)
|
||||
// do not call when holding the device lock!
|
||||
static bool RecoverWasapiIfLost(SDL_AudioDevice *device)
|
||||
{
|
||||
if (SDL_AtomicGet(&device->shutdown)) {
|
||||
if (SDL_GetAtomicInt(&device->shutdown)) {
|
||||
return false; // already failed.
|
||||
} else if (device->hidden->device_dead) { // had a fatal error elsewhere, clean up and quit
|
||||
IAudioClient_Stop(device->hidden->client);
|
||||
WASAPI_DisconnectDevice(device);
|
||||
SDL_assert(SDL_AtomicGet(&device->shutdown)); // so we don't come back through here.
|
||||
SDL_assert(SDL_GetAtomicInt(&device->shutdown)); // so we don't come back through here.
|
||||
return false; // already failed.
|
||||
} else if (SDL_AtomicGet(&device->zombie)) {
|
||||
} else if (SDL_GetAtomicInt(&device->zombie)) {
|
||||
return false; // we're already dead, so just leave and let the Zombie implementations take over.
|
||||
} else if (!device->hidden->client) {
|
||||
return true; // still waiting for activation.
|
||||
@@ -550,7 +538,7 @@ static void WASAPI_FlushRecording(SDL_AudioDevice *device)
|
||||
DWORD flags = 0;
|
||||
|
||||
// just read until we stop getting packets, throwing them away.
|
||||
while (!SDL_AtomicGet(&device->shutdown) && device->hidden->capture) {
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && device->hidden->capture) {
|
||||
const HRESULT ret = IAudioCaptureClient_GetBuffer(device->hidden->capture, &ptr, &frames, &flags, NULL, NULL);
|
||||
if (ret == AUDCLNT_S_BUFFER_EMPTY) {
|
||||
break; // no more buffered data; we're done.
|
||||
@@ -592,7 +580,7 @@ static bool mgmtthrtask_PrepDevice(void *userdata)
|
||||
IAudioClient *client = device->hidden->client;
|
||||
SDL_assert(client != NULL);
|
||||
|
||||
#if defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK) // CreateEventEx() arrived in Vista, so we need an #ifdef for XP.
|
||||
#if defined(SDL_PLATFORM_GDK) // CreateEventEx() arrived in Vista, so we need an #ifdef for XP.
|
||||
device->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
|
||||
#else
|
||||
device->hidden->event = CreateEventW(NULL, 0, 0, NULL);
|
||||
|
||||
6
external/SDL/src/audio/wasapi/SDL_wasapi.h
vendored
6
external/SDL/src/audio/wasapi/SDL_wasapi.h
vendored
@@ -42,10 +42,9 @@ struct SDL_PrivateAudioData
|
||||
int framesize;
|
||||
bool device_lost;
|
||||
bool device_dead;
|
||||
void *activation_handler;
|
||||
};
|
||||
|
||||
// win32 and winrt implementations call into these.
|
||||
// win32 implementation calls into these.
|
||||
bool WASAPI_PrepDevice(SDL_AudioDevice *device);
|
||||
void WASAPI_DisconnectDevice(SDL_AudioDevice *device); // don't hold the device lock when calling this!
|
||||
|
||||
@@ -54,7 +53,7 @@ void WASAPI_DisconnectDevice(SDL_AudioDevice *device); // don't hold the device
|
||||
typedef bool (*ManagementThreadTask)(void *userdata);
|
||||
bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, bool *wait_until_complete);
|
||||
|
||||
// These are functions that are implemented differently for Windows vs WinRT.
|
||||
// These are functions that are (were...?) implemented differently for various Windows versions.
|
||||
// UNLESS OTHERWISE NOTED THESE ALL HAPPEN ON THE MANAGEMENT THREAD.
|
||||
bool WASAPI_PlatformInit(void);
|
||||
void WASAPI_PlatformDeinit(void);
|
||||
@@ -63,7 +62,6 @@ void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevi
|
||||
bool WASAPI_ActivateDevice(SDL_AudioDevice *device);
|
||||
void WASAPI_PlatformThreadInit(SDL_AudioDevice *device); // this happens on the audio device thread, not the management thread.
|
||||
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device); // this happens on the audio device thread, not the management thread.
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler);
|
||||
void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
13
external/SDL/src/audio/wasapi/SDL_wasapi_win32.c
vendored
13
external/SDL/src/audio/wasapi/SDL_wasapi_win32.c
vendored
@@ -20,13 +20,14 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* This is code that Windows uses to talk to WASAPI-related system APIs.
|
||||
/* !!! FIXME: merge this all into SDL_wasapi.c, now that WinRT is gone.
|
||||
This is code that Windows uses to talk to WASAPI-related system APIs.
|
||||
This is for non-WinRT desktop apps. The C++/CX implementation of these
|
||||
functions, exclusive to WinRT, are in SDL_wasapi_winrt.cpp.
|
||||
The code in SDL_wasapi.c is used by both standard Windows and WinRT builds
|
||||
to deal with audio and calls into these functions. */
|
||||
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && !defined(SDL_PLATFORM_WINRT)
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI)
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
@@ -191,15 +192,9 @@ void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevi
|
||||
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording);
|
||||
}
|
||||
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
{
|
||||
// not asynchronous.
|
||||
SDL_assert(!"This function should have only been called on WinRT.");
|
||||
}
|
||||
|
||||
void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device)
|
||||
{
|
||||
SDL_IMMDevice_FreeDeviceHandle(device);
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && !defined(SDL_PLATFORM_WINRT)
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI
|
||||
|
||||
360
external/SDL/src/audio/wasapi/SDL_wasapi_winrt.cpp
vendored
360
external/SDL/src/audio/wasapi/SDL_wasapi_winrt.cpp
vendored
@@ -1,360 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
// This is C++/CX code that the WinRT port uses to talk to WASAPI-related
|
||||
// system APIs. The C implementation of these functions, for non-WinRT apps,
|
||||
// is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard
|
||||
// Windows and WinRT builds to deal with audio and calls into these functions.
|
||||
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && defined(SDL_PLATFORM_WINRT)
|
||||
|
||||
#include <Windows.h>
|
||||
#include <windows.ui.core.h>
|
||||
#include <windows.devices.enumeration.h>
|
||||
#include <windows.media.devices.h>
|
||||
#include <wrl/implements.h>
|
||||
#include <collection.h>
|
||||
|
||||
extern "C" {
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
}
|
||||
|
||||
#define COBJMACROS
|
||||
#include <mmdeviceapi.h>
|
||||
#include <audioclient.h>
|
||||
|
||||
#include "SDL_wasapi.h"
|
||||
|
||||
using namespace Windows::Devices::Enumeration;
|
||||
using namespace Windows::Media::Devices;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
static Platform::String ^ SDL_PKEY_AudioEngine_DeviceFormat = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c} 0";
|
||||
|
||||
|
||||
static bool FindWinRTAudioDeviceCallback(SDL_AudioDevice *device, void *userdata)
|
||||
{
|
||||
return (SDL_wcscmp((LPCWSTR) device->handle, (LPCWSTR) userdata) == 0);
|
||||
}
|
||||
|
||||
static SDL_AudioDevice *FindWinRTAudioDevice(LPCWSTR devid)
|
||||
{
|
||||
return SDL_FindPhysicalAudioDeviceByCallback(FindWinRTAudioDeviceCallback, (void *) devid);
|
||||
}
|
||||
|
||||
class SDL_WasapiDeviceEventHandler
|
||||
{
|
||||
public:
|
||||
SDL_WasapiDeviceEventHandler(const bool _recording);
|
||||
~SDL_WasapiDeviceEventHandler();
|
||||
void OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ args);
|
||||
void OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args);
|
||||
void OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args);
|
||||
void OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args);
|
||||
void OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args);
|
||||
void OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args);
|
||||
void WaitForCompletion();
|
||||
|
||||
private:
|
||||
SDL_Semaphore *completed_semaphore;
|
||||
const bool recording;
|
||||
DeviceWatcher ^ watcher;
|
||||
Windows::Foundation::EventRegistrationToken added_handler;
|
||||
Windows::Foundation::EventRegistrationToken removed_handler;
|
||||
Windows::Foundation::EventRegistrationToken updated_handler;
|
||||
Windows::Foundation::EventRegistrationToken completed_handler;
|
||||
Windows::Foundation::EventRegistrationToken default_changed_handler;
|
||||
};
|
||||
|
||||
SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const bool _recording)
|
||||
: recording(_recording), completed_semaphore(SDL_CreateSemaphore(0))
|
||||
{
|
||||
if (!completed_semaphore) {
|
||||
return; // uhoh.
|
||||
}
|
||||
|
||||
Platform::String ^ selector = _recording ? MediaDevice::GetAudioCaptureSelector() : MediaDevice::GetAudioRenderSelector();
|
||||
Platform::Collections::Vector<Platform::String ^> properties;
|
||||
properties.Append(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
watcher = DeviceInformation::CreateWatcher(selector, properties.GetView());
|
||||
if (!watcher)
|
||||
return; // uhoh.
|
||||
|
||||
// !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan.
|
||||
added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher ^, DeviceInformation ^>([this](DeviceWatcher ^ sender, DeviceInformation ^ args) { OnDeviceAdded(sender, args); });
|
||||
removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher ^, DeviceInformationUpdate ^>([this](DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) { OnDeviceRemoved(sender, args); });
|
||||
updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher ^, DeviceInformationUpdate ^>([this](DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) { OnDeviceUpdated(sender, args); });
|
||||
completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler<DeviceWatcher ^, Platform::Object ^>([this](DeviceWatcher ^ sender, Platform::Object ^ args) { OnEnumerationCompleted(sender, args); });
|
||||
if (recording) {
|
||||
default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object ^, DefaultAudioCaptureDeviceChangedEventArgs ^>([this](Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args) { OnDefaultCaptureDeviceChanged(sender, args); });
|
||||
} else {
|
||||
default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object ^, DefaultAudioRenderDeviceChangedEventArgs ^>([this](Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args) { OnDefaultRenderDeviceChanged(sender, args); });
|
||||
}
|
||||
watcher->Start();
|
||||
}
|
||||
|
||||
SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler()
|
||||
{
|
||||
if (watcher) {
|
||||
watcher->Added -= added_handler;
|
||||
watcher->Removed -= removed_handler;
|
||||
watcher->Updated -= updated_handler;
|
||||
watcher->EnumerationCompleted -= completed_handler;
|
||||
watcher->Stop();
|
||||
watcher = nullptr;
|
||||
}
|
||||
|
||||
if (completed_semaphore) {
|
||||
SDL_DestroySemaphore(completed_semaphore);
|
||||
completed_semaphore = nullptr;
|
||||
}
|
||||
|
||||
if (recording) {
|
||||
MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler;
|
||||
} else {
|
||||
MediaDevice::DefaultAudioRenderDeviceChanged -= default_changed_handler;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ info)
|
||||
{
|
||||
/* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
|
||||
In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
|
||||
phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be
|
||||
available and switch automatically. (!!! FIXME...?) */
|
||||
|
||||
SDL_assert(sender == this->watcher);
|
||||
char *utf8dev = WIN_StringToUTF8W(info->Name->Data());
|
||||
if (utf8dev) {
|
||||
SDL_AudioSpec spec;
|
||||
SDL_zero(spec);
|
||||
|
||||
Platform::Object ^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
if (obj) {
|
||||
IPropertyValue ^ property = (IPropertyValue ^) obj;
|
||||
Platform::Array<unsigned char> ^ data;
|
||||
property->GetUInt8Array(&data);
|
||||
WAVEFORMATEXTENSIBLE fmt;
|
||||
SDL_zero(fmt);
|
||||
SDL_memcpy(&fmt, data->Data, SDL_min(data->Length, sizeof(WAVEFORMATEXTENSIBLE)));
|
||||
spec.channels = (Uint8)fmt.Format.nChannels;
|
||||
spec.freq = fmt.Format.nSamplesPerSec;
|
||||
spec.format = SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)&fmt);
|
||||
}
|
||||
|
||||
LPWSTR devid = SDL_wcsdup(info->Id->Data());
|
||||
if (devid) {
|
||||
SDL_AddAudioDevice(this->recording, utf8dev, spec.channels ? &spec : NULL, devid);
|
||||
}
|
||||
SDL_free(utf8dev);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ info)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
WASAPI_DisconnectDevice(FindWinRTAudioDevice(info->Id->Data()));
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
if (this->completed_semaphore) {
|
||||
SDL_SignalSemaphore(this->completed_semaphore);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args)
|
||||
{
|
||||
SDL_assert(!this->recording);
|
||||
SDL_DefaultAudioDeviceChanged(FindWinRTAudioDevice(args->Id->Data()));
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args)
|
||||
{
|
||||
SDL_assert(this->recording);
|
||||
SDL_DefaultAudioDeviceChanged(FindWinRTAudioDevice(args->Id->Data()));
|
||||
}
|
||||
|
||||
void SDL_WasapiDeviceEventHandler::WaitForCompletion()
|
||||
{
|
||||
if (this->completed_semaphore) {
|
||||
SDL_WaitSemaphore(this->completed_semaphore);
|
||||
SDL_DestroySemaphore(this->completed_semaphore);
|
||||
this->completed_semaphore = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_WasapiDeviceEventHandler *playback_device_event_handler;
|
||||
static SDL_WasapiDeviceEventHandler *recording_device_event_handler;
|
||||
|
||||
bool WASAPI_PlatformInit(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void StopWasapiHotplug(void)
|
||||
{
|
||||
delete playback_device_event_handler;
|
||||
playback_device_event_handler = nullptr;
|
||||
delete recording_device_event_handler;
|
||||
recording_device_event_handler = nullptr;
|
||||
}
|
||||
|
||||
void WASAPI_PlatformDeinit(void)
|
||||
{
|
||||
StopWasapiHotplug();
|
||||
}
|
||||
|
||||
void WASAPI_PlatformDeinitializeStart(void)
|
||||
{
|
||||
StopWasapiHotplug();
|
||||
}
|
||||
|
||||
|
||||
void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
|
||||
{
|
||||
Platform::String ^ defdevid;
|
||||
|
||||
// DeviceWatchers will fire an Added event for each existing device at
|
||||
// startup, so we don't need to enumerate them separately before
|
||||
// listening for updates.
|
||||
playback_device_event_handler = new SDL_WasapiDeviceEventHandler(false);
|
||||
playback_device_event_handler->WaitForCompletion();
|
||||
defdevid = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
|
||||
if (defdevid) {
|
||||
*default_playback = FindWinRTAudioDevice(defdevid->Data());
|
||||
}
|
||||
|
||||
recording_device_event_handler = new SDL_WasapiDeviceEventHandler(true);
|
||||
recording_device_event_handler->WaitForCompletion();
|
||||
defdevid = MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default);
|
||||
if (defdevid) {
|
||||
*default_recording = FindWinRTAudioDevice(defdevid->Data());
|
||||
}
|
||||
}
|
||||
|
||||
class SDL_WasapiActivationHandler : public RuntimeClass<RuntimeClassFlags<ClassicCom>, FtmBase, IActivateAudioInterfaceCompletionHandler>
|
||||
{
|
||||
public:
|
||||
SDL_WasapiActivationHandler() : completion_semaphore(SDL_CreateSemaphore(0)) { SDL_assert(completion_semaphore != NULL); }
|
||||
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation);
|
||||
void WaitForCompletion();
|
||||
private:
|
||||
SDL_Semaphore *completion_semaphore;
|
||||
};
|
||||
|
||||
void SDL_WasapiActivationHandler::WaitForCompletion()
|
||||
{
|
||||
if (completion_semaphore) {
|
||||
SDL_WaitSemaphore(completion_semaphore);
|
||||
SDL_DestroySemaphore(completion_semaphore);
|
||||
completion_semaphore = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
|
||||
{
|
||||
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
|
||||
SDL_SignalSemaphore(completion_semaphore);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
{
|
||||
((SDL_WasapiActivationHandler *)handler)->Release();
|
||||
}
|
||||
|
||||
bool WASAPI_ActivateDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
LPCWSTR devid = (LPCWSTR) device->handle;
|
||||
SDL_assert(devid != NULL);
|
||||
|
||||
ComPtr<SDL_WasapiActivationHandler> handler = Make<SDL_WasapiActivationHandler>();
|
||||
if (handler == nullptr) {
|
||||
return SDL_SetError("Failed to allocate WASAPI activation handler");
|
||||
}
|
||||
|
||||
handler.Get()->AddRef(); // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc.
|
||||
device->hidden->activation_handler = handler.Get();
|
||||
|
||||
IActivateAudioInterfaceAsyncOperation *async = nullptr;
|
||||
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
|
||||
|
||||
if (FAILED(ret) || async == nullptr) {
|
||||
if (async != nullptr) {
|
||||
async->Release();
|
||||
}
|
||||
handler.Get()->Release();
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
|
||||
}
|
||||
|
||||
// !!! FIXME: the problems in SDL2 that needed this to be synchronous are _probably_ solved by SDL3, and this can block indefinitely if a user prompt is shown to get permission to use a microphone.
|
||||
handler.Get()->WaitForCompletion(); // block here until we have an answer, so this is synchronous to us after all.
|
||||
|
||||
HRESULT activateRes = S_OK;
|
||||
IUnknown *iunknown = nullptr;
|
||||
const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
|
||||
async->Release();
|
||||
if (FAILED(getActivateRes)) {
|
||||
return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
|
||||
} else if (FAILED(activateRes)) {
|
||||
return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
|
||||
}
|
||||
|
||||
iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client));
|
||||
if (!device->hidden->client) {
|
||||
return SDL_SetError("Failed to query WASAPI client interface");
|
||||
}
|
||||
|
||||
if (!WASAPI_PrepDevice(device)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WASAPI_PlatformThreadInit(SDL_AudioDevice *device)
|
||||
{
|
||||
// !!! FIXME: set this thread to "Pro Audio" priority.
|
||||
SDL_SetThreadPriority(device->recording ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL);
|
||||
}
|
||||
|
||||
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device)
|
||||
{
|
||||
// !!! FIXME: set this thread to "Pro Audio" priority.
|
||||
}
|
||||
|
||||
void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device)
|
||||
{
|
||||
SDL_free(device->handle);
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && defined(SDL_PLATFORM_WINRT)
|
||||
Reference in New Issue
Block a user