forked from fte/fteqw
1
0
Fork 0

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:
Spoike 2013-04-07 08:59:05 +00:00
parent 694f36a615
commit a717b8ce22
3 changed files with 114 additions and 47 deletions

View File

@ -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

View File

@ -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");

View File

@ -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;