Moved directsound audio initialisation onto the mixer thread, also added a cvar to disable threaded audio mixing. This should hopefully fix compat issues a couple of people had with not having audio in win32 (when it worked in win64 builds).
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4295 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
694f36a615
commit
a717b8ce22
3 changed files with 114 additions and 47 deletions
|
@ -134,21 +134,12 @@ FreeSound
|
|||
==================
|
||||
*/
|
||||
//per device
|
||||
static void DSOUND_Shutdown (soundcardinfo_t *sc)
|
||||
static void DSOUND_Shutdown_Internal (soundcardinfo_t *sc)
|
||||
{
|
||||
dshandle_t *dh = sc->handle;
|
||||
if (!dh)
|
||||
return;
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
if (sc->thread)
|
||||
{
|
||||
sc->selfpainting = false;
|
||||
Sys_WaitOnThread(sc->thread);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
sc->handle = NULL;
|
||||
#ifdef _IKsPropertySet_
|
||||
if (dh->EaxKsPropertiesSet)
|
||||
|
@ -184,6 +175,21 @@ static void DSOUND_Shutdown (soundcardinfo_t *sc)
|
|||
Z_Free(dh);
|
||||
}
|
||||
|
||||
static void DSOUND_Shutdown (soundcardinfo_t *sc)
|
||||
{
|
||||
#ifdef MULTITHREAD
|
||||
if (sc->thread)
|
||||
{
|
||||
//thread does the actual closing.
|
||||
sc->selfpainting = false;
|
||||
Sys_WaitOnThread(sc->thread);
|
||||
sc->thread = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
DSOUND_Shutdown_Internal(sc);
|
||||
}
|
||||
|
||||
|
||||
const char *dsndcard;
|
||||
GUID FAR *dsndguid;
|
||||
|
@ -526,24 +532,6 @@ static void DSOUND_Submit(soundcardinfo_t *sc, int start, int end)
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
int GetSoundtime(soundcardinfo_t *sc);
|
||||
static int DSOUND_Thread(void *arg)
|
||||
{
|
||||
soundcardinfo_t *sc = arg;
|
||||
while(sc->selfpainting)
|
||||
{
|
||||
S_MixerThread(sc);
|
||||
/* Quote:
|
||||
On NT (Win2K and XP) the cursors in SW buffers (and HW buffers on some devices) move in 10ms increments, so calling GetCurrentPosition() every 10ms is ideal.
|
||||
Calling it more often than every 5ms will cause some perf degradation.
|
||||
*/
|
||||
Sleep(9);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_InitDirect
|
||||
|
@ -551,7 +539,7 @@ SNDDMA_InitDirect
|
|||
Direct-Sound support
|
||||
==================
|
||||
*/
|
||||
int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
||||
static int DSOUND_InitCard_Internal (soundcardinfo_t *sc, int cardnum)
|
||||
{
|
||||
extern cvar_t snd_inactive, snd_eax;
|
||||
DSBUFFERDESC dsbuf;
|
||||
|
@ -565,9 +553,6 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
dshandle_t *dh;
|
||||
char *buffer;
|
||||
|
||||
if (COM_CheckParm("-wavonly"))
|
||||
return SND_NOMORE;
|
||||
|
||||
memset (&format, 0, sizeof(format));
|
||||
|
||||
if (sc->sn.numchannels >= 8) // 7.1 surround
|
||||
|
@ -707,14 +692,14 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
|
||||
{
|
||||
Con_SafePrintf ("No DirectSound driver installed\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
if (DS_OK != dh->pDS->lpVtbl->SetCooperativeLevel (dh->pDS, mainwindow, DSSCL_EXCLUSIVE))
|
||||
{
|
||||
Con_SafePrintf ("Set coop level failed\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
|
@ -790,7 +775,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
if (DS_OK != dh->pDS->lpVtbl->CreateSoundBuffer(dh->pDS, &dsbuf, &dh->pDSBuf, NULL))
|
||||
{
|
||||
Con_SafePrintf ("DS:CreateSoundBuffer Failed");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
|
@ -801,7 +786,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
if (DS_OK != dh->pDSBuf->lpVtbl->GetCaps (dh->pDSBuf, &dsbcaps))
|
||||
{
|
||||
Con_SafePrintf ("DS:GetCaps failed\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
|
@ -813,14 +798,14 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
if (DS_OK != dh->pDS->lpVtbl->SetCooperativeLevel (dh->pDS, mainwindow, DSSCL_WRITEPRIMARY))
|
||||
{
|
||||
Con_SafePrintf ("Set coop level failed\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
if (DS_OK != dh->pDSPBuf->lpVtbl->GetCaps (dh->pDSPBuf, &dsbcaps))
|
||||
{
|
||||
Con_Printf ("DS:GetCaps failed\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
|
@ -849,14 +834,14 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
if (hresult != DSERR_BUFFERLOST)
|
||||
{
|
||||
Con_SafePrintf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
if (++reps > 10000)
|
||||
{
|
||||
Con_SafePrintf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n");
|
||||
DSOUND_Shutdown (sc);
|
||||
DSOUND_Shutdown_Internal (sc);
|
||||
return SND_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -918,15 +903,91 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
sc->selfpainting = true;
|
||||
sc->thread = Sys_CreateThread("dsoundmixer", DSOUND_Thread, sc, THREADP_HIGHEST, 0);
|
||||
if (!sc->thread)
|
||||
sc->selfpainting = false; /*oh well*/
|
||||
#endif
|
||||
|
||||
return SND_LOADED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
int GetSoundtime(soundcardinfo_t *sc);
|
||||
static int DSOUND_Thread(void *arg)
|
||||
{
|
||||
soundcardinfo_t *sc = arg;
|
||||
void *cond = sc->handle;
|
||||
int cardnum = sc->audio_fd;
|
||||
sc->handle = NULL;
|
||||
|
||||
//once creating the thread, the main thread will wait for us to signal that we have inited the dsound device.
|
||||
switch(DSOUND_InitCard_Internal(sc, cardnum))
|
||||
{
|
||||
case SND_LOADED:
|
||||
break;
|
||||
case SND_NOMORE:
|
||||
sc->audio_fd = -1;
|
||||
sc->selfpainting = false;
|
||||
break;
|
||||
default:
|
||||
case SND_ERROR:
|
||||
sc->selfpainting = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//wake up the main thread.
|
||||
Sys_ConditionSignal(cond);
|
||||
|
||||
while(sc->selfpainting)
|
||||
{
|
||||
S_MixerThread(sc);
|
||||
/* Quote:
|
||||
On NT (Win2K and XP) the cursors in SW buffers (and HW buffers on some devices) move in 10ms increments, so calling GetCurrentPosition() every 10ms is ideal.
|
||||
Calling it more often than every 5ms will cause some perf degradation.
|
||||
*/
|
||||
Sleep(9);
|
||||
}
|
||||
|
||||
//we created the device, we need to kill it.
|
||||
DSOUND_Shutdown_Internal(sc);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
|
||||
{
|
||||
if (COM_CheckParm("-wavonly"))
|
||||
return SND_NOMORE;
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
if (snd_mixerthread.ival)
|
||||
{
|
||||
void *cond;
|
||||
sc->audio_fd = cardnum;
|
||||
sc->selfpainting = true;
|
||||
sc->handle = cond = Sys_CreateConditional();
|
||||
sc->thread = Sys_CreateThread("dsoundmixer", DSOUND_Thread, sc, THREADP_HIGHEST, 0);
|
||||
if (!sc->thread)
|
||||
{
|
||||
Con_SafePrintf ("Unable to create sound mixing thread\n");
|
||||
return SND_ERROR;
|
||||
}
|
||||
|
||||
//wait for the thread to finish (along with all its error con printfs etc
|
||||
Sys_ConditionWait(cond);
|
||||
Sys_DestroyConditional(cond);
|
||||
|
||||
if (!sc->selfpainting)
|
||||
{
|
||||
Sys_WaitOnThread(sc->thread);
|
||||
sc->thread = NULL;
|
||||
return (sc->audio_fd==-1)?SND_NOMORE:SND_ERROR;
|
||||
}
|
||||
return SND_LOADED;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return DSOUND_InitCard_Internal(sc, cardnum);
|
||||
}
|
||||
|
||||
int (*pDSOUND_InitCard) (soundcardinfo_t *sc, int cardnum) = &DSOUND_InitCard;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -110,6 +110,8 @@ cvar_t snd_linearresample = CVARAF( "s_linearresample", "1",
|
|||
cvar_t snd_linearresample_stream = CVARAF( "s_linearresample_stream", "0",
|
||||
"snd_linearresample_stream", 0);
|
||||
|
||||
cvar_t snd_mixerthread = CVARAD( "s_mixerthread", "1",
|
||||
"snd_mixerthread", "When enabled sound mixing will be run on a separate thread. Currently supported only by directsound. Other drivers may unconditionally thread audio. Set to 0 only if you have issues.");
|
||||
cvar_t snd_usemultipledevices = CVARAFD( "s_multipledevices", "0",
|
||||
"snd_multipledevices", 0, "If enabled, all output sound devices in your computer will be initialised for playback, not just the default device.");
|
||||
cvar_t snd_driver = CVARAF( "s_driver", "",
|
||||
|
@ -1122,6 +1124,9 @@ void S_Init (void)
|
|||
|
||||
Cvar_Register(&snd_inactive, "Sound controls");
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
Cvar_Register(&snd_mixerthread, "Sound controls");
|
||||
#endif
|
||||
Cvar_Register(&snd_playersoundvolume, "Sound controls");
|
||||
Cvar_Register(&snd_usemultipledevices, "Sound controls");
|
||||
Cvar_Register(&snd_driver, "Sound controls");
|
||||
|
|
|
@ -236,6 +236,7 @@ extern float voicevolumemod;
|
|||
|
||||
extern qboolean snd_initialized;
|
||||
extern cvar_t snd_usemultipledevices;
|
||||
extern cvar_t snd_mixerthread;
|
||||
|
||||
extern int snd_blocked;
|
||||
|
||||
|
|
Loading…
Reference in a new issue