ref: 3ed81805500b6497537fcab2dffe2b92e52cbed7
parent: bccea30192b10133583e2c658f434bba7169ecfa
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Jan 29 11:50:07 EST 2024
openal: store current device full name; don't try to reopen the same one
--- a/snd_openal.c
+++ b/snd_openal.c
@@ -48,6 +48,7 @@
static int num_sfx;
static int map;
static alchan_t *chans;
+static char *curdev = nil;
static cvar_t ambient_level = {"ambient_level", "0.3"};
static cvar_t ambient_fade = {"ambient_fade", "100"};
@@ -58,7 +59,6 @@
static ALchar *(*qalGetStringiSOFT)(ALenum, ALsizei);
static ALCchar *(*qalcGetStringiSOFT)(ALCdevice *, ALenum, ALsizei);
static ALCboolean (*qalcResetDeviceSOFT)(ALCdevice *, const ALCint *attr);
-static ALCboolean *(*qalcReopenDeviceSOFT)(ALCdevice *, const ALCchar *devname, const ALCint *attr);
typedef ALsizei (*qalBufferCallbackTypeSOFT)(ALvoid *, ALvoid *, ALsizei);
static void (*qalBufferCallbackSOFT)(ALuint buf, ALenum fmt, ALsizei freq, qalBufferCallbackTypeSOFT cb, ALvoid *aux);
@@ -536,9 +536,18 @@
ALCcontext *c;
int e;
+ if(devname == nil){
+ // ALC_DEFAULT_DEVICE_SPECIFIER would make more sense,
+ // but unfortunately it's not a _full_ name
+ devname = alcGetString(nil, ALC_ALL_DEVICES_SPECIFIER);
+ ALERR();
+ }
+
dev = alcOpenDevice(devname); ALERR();
if(dev == nil)
return -1;
+ free(curdev);
+ curdev = strdup(devname);
c = alcCreateContext(dev, nil); ALERR();
if(c == nil){
@@ -545,6 +554,8 @@
closedev:
alcCloseDevice(dev); ALERR();
dev = nil;
+ free(curdev);
+ curdev = nil;
return -1;
}
ctx = c;
@@ -598,38 +609,52 @@
return 0;
}
+static int
+alreopen(const char *new, ALCint *attr)
+{
+ ALCboolean *(*qalcReopenDeviceSOFT)(
+ ALCdevice *,
+ const ALCchar *devname,
+ const ALCint *attr
+ );
+ int r;
+
+ qalcReopenDeviceSOFT = nil;
+ if(alcIsExtensionPresent(dev, "ALC_SOFT_reopen_device"))
+ qalcReopenDeviceSOFT = alcGetProcAddress(dev, "alcReopenDeviceSOFT");
+ if(qalcReopenDeviceSOFT == nil){
+ Con_Printf("AL: can't change device settings on the fly\n");
+ return -1;
+ }
+ r = qalcReopenDeviceSOFT(dev, new, attr) ? 0 : -1;
+ ALERR();
+ return r;
+}
+
static void
alreinit(const char *def, const char *all)
{
- const char *s;
+ const char *newdev;
int i, n;
bool hrtf;
n = s_al_dev.value;
-
- if(qalcReopenDeviceSOFT == nil && alcIsExtensionPresent(nil, "ALC_SOFT_reopen_device"))
- qalcReopenDeviceSOFT = alGetProcAddress("alcReopenDeviceSOFT");
- if(qalcReopenDeviceSOFT == nil){
- Con_Printf("AL: can't change device settings on the fly\n");
- return;
- }
- for(i = 1, s = all; s != nil && *s; i++){
- if((n == 0 && def != nil && strcmp(s, def) == 0) || n == i){
- if(dev == nil)
- n = alinit(all);
- else{
- n = qalcReopenDeviceSOFT(dev, s, alcattr(false)) ? 0 : -1;
- ALERR();
- }
+ for(i = 1, newdev = all; newdev != nil && *newdev; i++){
+ if((n == 0 && def != nil && strcmp(newdev, def) == 0) || n == i){
+ if(curdev != nil && strcmp(newdev, curdev) == 0)
+ break;
+ n = dev == nil ? alinit(all) : alreopen(newdev, alcattr(false));
if(n != 0){
- Con_Printf("AL: failed to switch to %s\n", s);
+ Con_Printf("AL: failed to switch to %s\n", newdev);
return;
}
+ free(curdev);
+ curdev = strdup(newdev);
break;
}
- s += strlen(s)+1;
+ newdev += strlen(newdev)+1;
}
- if(s == nil || !*s){
+ if(newdev == nil || !*newdev){
Con_Printf("AL: no such device: %d\n", n);
return;
}