Пример #1
0
/*
==============
SNDDMA_BeginPainting

Makes sure dma.buffer is valid
===============
*/
void SNDDMA_BeginPainting(void)
{
	int             reps;
	DWORD           dwSize2;
	DWORD          *pbuf, *pbuf2;
	HRESULT         hresult;
	DWORD           dwStatus;

	if(!pDSBuf)
	{
		return;
	}

	// if the buffer was lost or stopped, restore it and/or restart it
	if(pDSBuf->lpVtbl->GetStatus(pDSBuf, &dwStatus) != DS_OK)
	{
		Com_Printf("Couldn't get sound buffer status\n");
	}

	if(dwStatus & DSBSTATUS_BUFFERLOST)
	{
		pDSBuf->lpVtbl->Restore(pDSBuf);
	}

	if(!(dwStatus & DSBSTATUS_PLAYING))
	{
		pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
	}

	// lock the dsound buffer

	reps = 0;
	dma.buffer = NULL;

	while((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0)) != DS_OK)
	{
		if(hresult != DSERR_BUFFERLOST)
		{
			Com_Printf("SNDDMA_BeginPainting: Lock failed with error '%s'\n", DSoundError(hresult));
			S_Shutdown();
			return;
		}
		else
		{
			pDSBuf->lpVtbl->Restore(pDSBuf);
		}

		if(++reps > 2)
		{
			return;
		}
	}
	dma.buffer = (unsigned char *)pbuf;
}
Пример #2
0
void S_ClearBuffer (void)
{
	int clear;

#ifdef _WIN32
	if (!shm || (!shm->buffer && !pDSBuf))
#else
	if (!shm || !shm->buffer)
#endif
		return;

	clear = (shm->format.width == 2) ? 0x80 : 0;

#ifdef _WIN32
	if (pDSBuf) {
		DWORD dwSize;
		DWORD *pData;
		int reps;
		HRESULT hresult;

		reps = 0;

		while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize, NULL, NULL, 0)) != DS_OK) {
			if (hresult != DSERR_BUFFERLOST) {
				Com_Printf ("S_ClearBuffer: Lock failed with error '%s'\n", DSoundError(hresult));
				S_Shutdown ();
				return;
			} else {
				pDSBuf->lpVtbl->Restore (pDSBuf);
			}

			if (++reps > 2)
				return;
		}

		memset(pData, clear, shm->bufferlength);

		pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0);

	} else
#endif
	{
		memset(shm->buffer, clear, shm->bufferlength);
	}
}
Пример #3
0
/*
==============
SNDDMA_BeginPainting

Makes sure dma.buffer is valid
===============
*/
void SNDDMA_BeginPainting( void )
{
	int	reps;
	DWORD	dwSize2;
	DWORD	*pbuf, *pbuf2;
	HRESULT	hr;
	DWORD	dwStatus;

	if( !pDSBuf ) return;

	// if the buffer was lost or stopped, restore it and/or restart it
	if( pDSBuf->lpVtbl->GetStatus( pDSBuf, &dwStatus ) != DS_OK )
		MsgDev( D_WARN, "SNDDMA_BeginPainting: couldn't get sound buffer status\n" );
	
	if( dwStatus & DSBSTATUS_BUFFERLOST )
		pDSBuf->lpVtbl->Restore( pDSBuf );
	
	if( !( dwStatus & DSBSTATUS_PLAYING ))
		pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING );

	// lock the dsound buffer
	dma.buffer = NULL;
	reps = 0;

	while(( hr = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0 )) != DS_OK )
	{
		if( hr != DSERR_BUFFERLOST )
		{
			MsgDev( D_ERROR, "SNDDMA_BeginPainting: lock error '%s'\n", DSoundError( hr ));
			S_Shutdown ();
			return;
		}
		else pDSBuf->lpVtbl->Restore( pDSBuf );

		if( ++reps > 2 ) return;
	}

	dma.buffer = (byte *)pbuf;
}
Пример #4
0
void SNDDMA_BeginPainting (void)
{
	int		reps;
	DWORD	dwSize2;
	DWORD	*pbuf, *pbuf2;
	HRESULT	hresult;
	DWORD	dwStatus;

	// if the buffer was lost or stopped, restore it and/or restart it
	//if (!s_primary->value)
	//{
		if (!pDSBuf)
			return;

#ifdef QDSNDCOMPILERHACK
		if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK)
#else
		if (pDSBuf->GetStatus (&dwStatus) != DS_OK)
#endif
			Com_Printf ("Couldn't get sound buffer status\n");

		if (dwStatus & DSBSTATUS_BUFFERLOST)
#ifdef QDSNDCOMPILERHACK
			pDSBuf->lpVtbl->Restore (pDSBuf);
#else
			pDSBuf->Restore ();
#endif

		if (!(dwStatus & DSBSTATUS_PLAYING))
#ifdef QDSNDCOMPILERHACK
			pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
#else
			pDSBuf->Play(0, 0, DSBPLAY_LOOPING);
#endif
	/*}
	else
	{
		if (!pDSPBuf)
			return;

		if (pDSPBuf->lpVtbl->GetStatus (pDSPBuf, &dwStatus) != DS_OK)
			Com_Printf ("Couldn't get sound buffer status\n");

		if (dwStatus & DSBSTATUS_BUFFERLOST)
			pDSPBuf->lpVtbl->Restore (pDSPBuf);

		if (!(dwStatus & DSBSTATUS_PLAYING))
			pDSPBuf->lpVtbl->Play(pDSPBuf, 0, 0, DSBPLAY_LOOPING);
	}*/
	
	// lock the dsound buffer

	reps = 0;
	dma.buffer = NULL;
	//if (!s_primary->value)
	//{
#ifdef QDSNDCOMPILERHACK
		while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &locksize, 
			&pbuf2, &dwSize2, 0)) != DS_OK)
#else
		while ((hresult = pDSBuf->Lock(0, gSndBufSize, &pbuf, &locksize, 
			&pbuf2, &dwSize2, 0)) != DS_OK)
#endif
		{
			if (hresult != DSERR_BUFFERLOST)
			{
				Com_Printf( "S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) );
				S_Shutdown ();
				return;
			}
			else
			{
#ifdef QDSNDCOMPILERHACK
				pDSBuf->lpVtbl->Restore(pDSBuf);
#else
				pDSBuf->Restore();
#endif
			}

			if (++reps > 2)
				return;
		}
	/*}
	else
	{
		while ((hresult = pDSPBuf->lpVtbl->Lock(pDSPBuf, 0, gSndBufSize, &pbuf, &locksize, 
			&pbuf2, &dwSize2, 0)) != DS_OK)
		{
			if (hresult != DSERR_BUFFERLOST)
			{
				Com_Printf( "S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) );
				S_Shutdown ();
				return;
			}
			else
			{
				pDSPBuf->lpVtbl->Restore(pDSPBuf);
			}

			if (++reps > 2)
				return;
		}
	}*/
	dma.buffer = (unsigned char *)pbuf;
}
Пример #5
0
static int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	qboolean		pauseTried;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;

	Com_Printf( "Initializing DirectSound\n");

	if ( !hInstDS ) {
		Com_DPrintf( "...loading dsound.dll: " );

		hInstDS = LoadLibrary("dsound.dll");
		
		if ( hInstDS == NULL ) {
			Com_Printf ("failed\n");
			return 0;
		}

		Com_DPrintf ("ok\n");
		pDirectSoundCreate = (long (__stdcall *)(struct _GUID *,struct IDirectSound ** ,struct IUnknown *))
			GetProcAddress(hInstDS,"DirectSoundCreate");

		if ( !pDirectSoundCreate ) {
			Com_Printf ("*** couldn't get DS proc addr ***\n");
			return 0;
		}
	}

	Com_DPrintf( "...creating DS object: " );
	pauseTried = qfalse;
	while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) {
		if ( hresult != DSERR_ALLOCATED ) {
			Com_Printf( "failed\n" );
			return 0;
		}

		if ( pauseTried ) {
			Com_Printf ("failed, hardware already in use\n" );
			return 0;
		}
		// first try just waiting five seconds and trying again
		// this will handle the case of a sysyem beep playing when the
		// game starts
		Com_DPrintf ("retrying...\n");
		Sleep( 3000 );
		pauseTried = qtrue;
	}
	Com_DPrintf( "ok\n" );

	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );

	if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) )	{
		Com_Printf ("failed\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	Com_DPrintf("ok\n" );


	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer == 44)
		dma.speed = 44100;
	else if (s_khz->integer == 22)
		dma.speed = 22050;
	else
		dma.speed = 11025;

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);

#define idDSBCAPS_GETCURRENTPOSITION2 0x00010000

	dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE | idDSBCAPS_GETCURRENTPOSITION2;
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;
	
	Com_DPrintf( "...creating secondary buffer: " );
	if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY;
		hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL);
		if (hresult != DS_OK) {			
			Com_Printf( "failed to create secondary buffer - %s\n", DSoundError( hresult ) );
			SNDDMA_Shutdown ();
			return qfalse;
		}
	}
	Com_Printf( "locked hardware.  ok\n" );
		
	// Make sure mixer is active
	if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) {
		Com_Printf ("*** Looped sound play failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}

	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	// get the returned buffer size
	if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.submission_chunk = 1;
	dma.buffer = NULL;			// must be locked first

	sample16 = (dma.samplebits/8) - 1;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
	return 1;
}
Пример #6
0
/*
** DS_CreateBuffers
*/
static qboolean DS_CreateBuffers( void )
{
	int ret;

	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	pformat, format;
	DWORD			dwWrite;

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = sizeof(WAVEFORMATEX);
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	Com_DPrintf( "Creating DS buffers\n");

	Com_DPrintf("...setting EXCLUSIVE coop level: " );

	ret = pDS->lpVtbl->SetCooperativeLevel(pDS, cl_hwnd, DSSCL_EXCLUSIVE);
	if (ret != DS_OK)
	{
		Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
		FreeSound ();
		return false;
	}
	Com_DPrintf("ok\n" );

// get access to the primary buffer, if possible, so we can set the
// sound hardware format
	memset (&dsbuf, 0, sizeof(dsbuf));

	dsbuf.dwSize = sizeof(DSBUFFERDESC);
	dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
	dsbuf.dwBufferBytes = 0;
	dsbuf.lpwfxFormat = NULL;

	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	primary_format_set = false;

	Com_DPrintf( "...creating primary buffer: " );
	ret = pDS->lpVtbl->CreateSoundBuffer (pDS, &dsbuf, &pDSPBuf, NULL);
	if (DS_OK == ret)
	{
		pformat = format;

		Com_DPrintf( "ok\n" );

		ret = pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat);
		if (DS_OK != ret)
		{
			if (snd_firsttime)
			{
				Com_DPrintf ("...setting primary sound format: ");
				Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
			}
		}
		else
		{
			if (snd_firsttime)
				Com_DPrintf ("...setting primary sound format: ok\n");

			primary_format_set = true;
		}
	}
	else
	{
		Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
	}

	if ( !primary_format_set || !s_primary->intvalue)
	{
		// create the secondary buffer we'll actually work with
		memset (&dsbuf, 0, sizeof(dsbuf));
		dsbuf.dwSize = sizeof(DSBUFFERDESC);
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
		dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
		dsbuf.lpwfxFormat = &format;

		memset(&dsbcaps, 0, sizeof(dsbcaps));
		dsbcaps.dwSize = sizeof(dsbcaps);

		Com_DPrintf( "...creating secondary buffer: " );
		ret = pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL);
		if (DS_OK != ret)
		{
			Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
			FreeSound ();
			return false;
		}
		Com_DPrintf( "ok\n" );

		dma.channels = format.nChannels;
		dma.samplebits = format.wBitsPerSample;
		dma.speed = format.nSamplesPerSec;

		if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps))
		{
			Com_Printf ("*** GetCaps failed ***\n", LOG_CLIENT|LOG_ERROR);
			FreeSound ();
			return false;
		}

		Com_DPrintf ("...using secondary sound buffer\n");
	}
	else
	{
		Com_DPrintf( "...using primary buffer\n" );

		Com_DPrintf( "...setting WRITEPRIMARY coop level: " );
		pDS->lpVtbl->SetCooperativeLevel (pDS, cl_hwnd, DSSCL_WRITEPRIMARY);
		if (DS_OK != ret)
		{
			Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
			FreeSound ();
			return false;
		}
		Com_DPrintf( "ok\n" );

		if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps))
		{
			Com_Printf ("*** GetCaps failed ***\n", LOG_CLIENT|LOG_ERROR);
			return false;
		}

		pDSBuf = pDSPBuf;
	}

	// Make sure mixer is active
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	if (snd_firsttime)
		if (!cl_quietstartup->intvalue || developer->intvalue)
			Com_Printf("   %d channel(s)\n"
		               "   %d bits/sample\n"
					   "   %d bytes/sec\n", LOG_CLIENT|LOG_NOTICE,
					   dma.channels, dma.samplebits, dma.speed);
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	/* we don't want anyone to access the buffer directly w/o locking it first. */
	lpData = NULL; 

	pDSBuf->lpVtbl->Stop(pDSBuf);
	pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.samplepos = 0;
	dma.submission_chunk = 1;
	dma.buffer = (unsigned char *) lpData;
	sample16 = (dma.samplebits/8) - 1;

	return true;
}