⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snd_dev_direct.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  number based on both buffers so the rest of the framework behaves the same.
*/
int CAudioDirectSound::GetOutputPositionSurround()
{
	DWORD dwPos;
	DWORD dwRtn;

	pDSBufFL->GetCurrentPosition(&dwPos, NULL);
	// Causing problems on some EAX cards
#if 0
	pDSBufFR->SetCurrentPosition(dwPos);
	pDSBufRL->SetCurrentPosition(dwPos);
	pDSBufRR->SetCurrentPosition(dwPos);
#endif

	dwPos -= dwSurroundStart;
	dwRtn = dwPos << 1;
	dwRtn >>= SAMPLE_16BIT_SHIFT;
	dwRtn &= DeviceSampleCount() - 1;
	return (int)dwRtn;
}

/*
 Release all Surround buffer pointers
*/
void ReleaseSurround(void)
{
	if ( pDSPropSetFL != NULL ) pDSPropSetFL->Release();
	pDSPropSetFL = NULL;

	if ( pDSPropSetFR != NULL ) pDSPropSetFR->Release();
	pDSPropSetFR = NULL;

	if ( pDSPropSetRL != NULL ) pDSPropSetRL->Release();
	pDSPropSetRL = NULL;

	if ( pDSPropSetRR != NULL ) pDSPropSetRR->Release();
	pDSPropSetRR = NULL;

	if ( pDSBuf3DFL != NULL ) pDSBuf3DFL->Release();
	pDSBuf3DFL = NULL;

	if ( pDSBuf3DFR != NULL ) pDSBuf3DFR->Release();
	pDSBuf3DFR = NULL;

	if ( pDSBuf3DRL != NULL ) pDSBuf3DRL->Release();
	pDSBuf3DRL = NULL;

	if ( pDSBuf3DRR != NULL ) pDSBuf3DRR->Release();
	pDSBuf3DRR = NULL;

	if ( pDSBufFL != NULL ) pDSBufFL->Release();
	pDSBufFL = NULL;

	if ( pDSBufFR != NULL ) pDSBufFR->Release();
	pDSBufFR = NULL;

	if ( pDSBufRL != NULL ) pDSBufRL->Release();
	pDSBufRL = NULL;

	if ( pDSBufRR != NULL ) pDSBufRR->Release();
	pDSBufRR = NULL;
}


// Initialization for Surround sound support (4 channel). 
// Creates 4 mono 3D buffers to be used as Front Left, Front Right, Rear Left, Rear Right
 
bool CAudioDirectSound::SNDDMA_InitSurround(LPDIRECTSOUND lpDS, WAVEFORMATEX* lpFormat, DSBCAPS* lpdsbc)
{
	DSBUFFERDESC	dsbuf;
	WAVEFORMATEX wvex;
	DWORD dwSize, dwWrite;
	int reps;
	HRESULT hresult;
	void			*lpData = NULL;

	if ( lpDS == NULL ) return FALSE;
 
	// Force format to mono channel

	memcpy(&wvex, lpFormat, sizeof(WAVEFORMATEX));
	wvex.nChannels = 1;
	wvex.nBlockAlign = wvex.nChannels * wvex.wBitsPerSample / 8;
	wvex.nAvgBytesPerSec = wvex.nSamplesPerSec	* wvex.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);
														// LOCHARDWARE causes SB AWE64 to crash in it's DSOUND driver
	dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRL3D;//|DSBCAPS_LOCHARDWARE;
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE/2;
	dsbuf.lpwfxFormat = &wvex;

	// create 4 mono buffers FL, FR, RL, RR

	if (DS_OK != lpDS->CreateSoundBuffer(&dsbuf, &pDSBufFL, NULL))
	{
		g_pSoundServices->ConSafePrint ("DS:CreateSoundBuffer for 3d front left failed");
		ReleaseSurround();
		return FALSE;
	}

	if (DS_OK != lpDS->CreateSoundBuffer(&dsbuf, &pDSBufFR, NULL))
	{
		g_pSoundServices->ConSafePrint ("DS:CreateSoundBuffer for 3d front right failed");
		ReleaseSurround();
		return FALSE;
	}

	if (DS_OK != lpDS->CreateSoundBuffer(&dsbuf, &pDSBufRL, NULL))
	{
		g_pSoundServices->ConSafePrint ("DS:CreateSoundBuffer for 3d rear left failed");
		ReleaseSurround();
		return FALSE;
	}

	if (DS_OK != lpDS->CreateSoundBuffer(&dsbuf, &pDSBufRR, NULL))
	{
		g_pSoundServices->ConSafePrint ("DS:CreateSoundBuffer for 3d rear right failed");
		ReleaseSurround();
		return FALSE;
	}

	// Try to get 4 3D buffers from the mono DS buffers

	if (DS_OK != pDSBufFL->QueryInterface(IID_IDirectSound3DBufferDef, (void**)&pDSBuf3DFL))
	{
		g_pSoundServices->ConSafePrint ("DS:Query 3DBuffer for 3d front left failed");
		ReleaseSurround();
		return FALSE;
	}

	if (DS_OK != pDSBufFR->QueryInterface(IID_IDirectSound3DBufferDef, (void**)&pDSBuf3DFR))
	{
		g_pSoundServices->ConSafePrint ("DS:Query 3DBuffer for 3d front right failed");
		ReleaseSurround();
		return FALSE;
	}

	if (DS_OK != pDSBufRL->QueryInterface(IID_IDirectSound3DBufferDef, (void**)&pDSBuf3DRL))
	{
		g_pSoundServices->ConSafePrint ("DS:Query 3DBuffer for 3d rear left failed");
		ReleaseSurround();
		return FALSE;
	}

	if (DS_OK != pDSBufRR->QueryInterface(IID_IDirectSound3DBufferDef, (void**)&pDSBuf3DRR))
	{
		g_pSoundServices->ConSafePrint ("DS:Query 3DBuffer for 3d rear right failed");
		ReleaseSurround();
		return FALSE;
	}

	// UNDONE: set speaker configuration to 2, 4 or headphone
	//lpDS->lpVtbl->SetSpeakerConfig(lpDS, DSSPEAKER_QUAD);

	// Position the 4 3D buffers to FL, FR, RL, RR

	pDSBuf3DFL->SetPosition(-1.0f, 0.0f, 1.0f, DS3D_IMMEDIATE);
	pDSBuf3DFR->SetPosition(1.0f, 0.0f, 1.0f, DS3D_IMMEDIATE);
	pDSBuf3DRL->SetPosition(-1.0f, 0.0f, -1.0f, DS3D_IMMEDIATE);
	pDSBuf3DRR->SetPosition(1.0f, 0.0f, -1.0f, DS3D_IMMEDIATE);

#if 0 
	// try to get EAX fx on the 4 buffers (unused)
	ULONG ulAnswer;
	
	ulAnswer = 0;
	if ( (pDSBufFL->QueryInterface(IID_IKsPropertySetDef, (LPVOID *)&pDSPropSetFL)) == DS_OK )
	{
		if ( (pDSPropSetFL->QuerySupport(DSPROPSETID_EAX_ReverbPropertiesDef, DSPROPERTY_EAX_ALL, &ulAnswer)) == DS_OK )
		{
			if ( (ulAnswer & KSPROPERTY_SUPPORT_SET|KSPROPERTY_SUPPORT_GET) != (KSPROPERTY_SUPPORT_SET|KSPROPERTY_SUPPORT_GET) )
			{
				g_pSoundServices->ConSafePrint ("The current device is not EAX capable.");
				ReleaseSurround();
				return FALSE;
			}
		}
		else
		{
			g_pSoundServices->ConSafePrint ("EAX:QuerySupport for DSPROPSETID_EAX_ReverbProperties Failed\n");
			ReleaseSurround();
			return FALSE;
		}
	}
	else
	{
		g_pSoundServices->ConSafePrint ("EAX:QueryInterface for IID_IKsPropertySet FL Failed");
		ReleaseSurround();
		return FALSE;
	}

	if ( (pDSBufFR->QueryInterface(IID_IKsPropertySetDef, (LPVOID *)&pDSPropSetFR)) != DS_OK )
	{
		g_pSoundServices->ConSafePrint ("EAX:QueryInterface for IID_IKsPropertySet FR Failed");
		ReleaseSurround();
		return FALSE;
	}

	if ( (pDSBufRL->QueryInterface(IID_IKsPropertySetDef, (LPVOID *)&pDSPropSetRL)) != DS_OK )
	{
		g_pSoundServices->ConSafePrint ("EAX:QueryInterface for IID_IKsPropertySet RL Failed");
		ReleaseSurround();
		return FALSE;
	}

	if ( (pDSBufRR->QueryInterface(IID_IKsPropertySetDef, (LPVOID *)&pDSPropSetRR)) != DS_OK )
	{
		g_pSoundServices->ConSafePrint ("EAX:QueryInterface for IID_IKsPropertySet RR Failed");
		ReleaseSurround();
		return FALSE;
	}

#endif // 0

	m_deviceChannels = lpFormat->nChannels;
	m_deviceSampleBits = lpFormat->wBitsPerSample;
	m_deviceDmaSpeed = lpFormat->nSamplesPerSec;

	memset(lpdsbc, 0, sizeof(DSBCAPS));
	lpdsbc->dwSize = sizeof(DSBCAPS);

	if (DS_OK != pDSBufFL->GetCaps (lpdsbc))
	{
		g_pSoundServices->ConSafePrint ("DS:GetCaps failed for 3d sound buffer\n");
		ReleaseSurround();
		return FALSE;
	}

	pDSBufFL->Play(0, 0, DSBPLAY_LOOPING);
	pDSBufFR->Play(0, 0, DSBPLAY_LOOPING);

	if (snd_firsttime)
		DevMsg("   %d channel(s)\n"
					"   %d bits/sample\n"
					"   %d samples/sec\n",
					DeviceChannels(), DeviceSampleBits(), DeviceDmaSpeed());

	m_bufferSize = lpdsbc->dwBufferBytes*2;

	// Test everything just like in the normal initialization.
	reps = 0;
	while ((hresult = pDSBufFL->Lock(0, lpdsbc->dwBufferBytes, (void**)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
	{
		if (hresult != DSERR_BUFFERLOST)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitSurround: DS::Lock Sound Buffer Failed for 3d FL\n");
			ReleaseSurround();
			return FALSE;
		}

		if (++reps > 10000)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitSurround: DS: couldn't restore buffer for 3d FL\n");
			ReleaseSurround();
			return FALSE;
		}
	}
	memset(lpData, 0, dwSize);
	pDSBufFL->Unlock(lpData, dwSize, NULL, 0);

	reps = 0;
	while ((hresult = pDSBufFR->Lock(0, lpdsbc->dwBufferBytes, (void**)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
	{
		if (hresult != DSERR_BUFFERLOST)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitSurround: DS::Lock Sound Buffer Failed for 3d FR\n");
			ReleaseSurround();
			return FALSE;
		}

		if (++reps > 10000)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitSurround: DS: couldn't restore buffer for FR\n");
			ReleaseSurround();
			return FALSE;
		}
	}
	memset(lpData, 0, dwSize);
	pDSBufFR->Unlock(lpData, dwSize, NULL, 0);

	reps = 0;
	while ((hresult = pDSBufRL->Lock(0, lpdsbc->dwBufferBytes, (void**)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
	{
		if (hresult != DSERR_BUFFERLOST)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed for RL\n");
			ReleaseSurround();
			return FALSE;
		}

		if (++reps > 10000)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitDirect: DS: couldn't restore buffer for RL\n");
			ReleaseSurround();
			return FALSE;
		}
	}
	memset(lpData, 0, dwSize);
	pDSBufRL->Unlock(lpData, dwSize, NULL, 0);

	reps = 0;
	while ((hresult = pDSBufRR->Lock(0, lpdsbc->dwBufferBytes, (void**)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
	{
		if (hresult != DSERR_BUFFERLOST)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed for RR\n");
			ReleaseSurround();
			return FALSE;
		}

		if (++reps > 10000)
		{
			g_pSoundServices->ConSafePrint ("SNDDMA_InitDirect: DS: couldn't restore buffer for RR\n");
			ReleaseSurround();
			return FALSE;
		}
	}
	memset(lpData, 0, dwSize);
	pDSBufRR->Unlock(lpData, dwSize, NULL, 0);
	lpData = NULL; // this is invalid now

	// OK Stop and get our positions and were good to go.
	pDSBufFL->Stop();
	pDSBufFR->Stop();
	pDSBufRL->Stop();
	pDSBufRR->Stop();
	pDSBufFL->GetCurrentPosition(&dwSurroundStart, &dwWrite);
	pDSBufFR->SetCurrentPosition(dwSurroundStart);
	pDSBufRL->SetCurrentPosition(dwSurroundStart);
	pDSBufRR->SetCurrentPosition(dwSurroundStart);
	pDSBufFL->Play(0, 0, DSBPLAY_LOOPING);
	pDSBufFR->Play(0, 0, DSBPLAY_LOOPING);
	pDSBufRL->Play(0, 0, DSBPLAY_LOOPING);
	pDSBufRR->Play(0, 0, DSBPLAY_LOOPING);

	if (snd_firsttime)
		g_pSoundServices->ConSafePrint ("3d surround sound initialization successful\n");

	return TRUE;
}

void CAudioDirectSound::UpdateListener( const Vector& position, const Vector& forward, const Vector& right, const Vector& up )
{
	VectorCopy( forward, m_listenerForward );
}

void CAudioDirectSound::MixBegin( int sampleCount )
{
	MIX_ClearAllPaintBuffers( sampleCount, false );
}

void CAudioDirectSound::MixUpsample( int sampleCount, int filtertype )
{
	
	paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
	int ifilter = ppaint->ifilter;

	Assert (ifilter < CPAINTFILTERS);

	S_MixBufferUpsample2x( sampleCount, ppaint->pbuf, &(ppaint->fltmem[ifilter][0]), CPAINTFILTERMEM, filtertype );

	if ( ppaint->fsurround )
	{
		Assert( ppaint->pbufrear );
		S_MixBufferUpsample2x( sampleCount, ppaint->pbufrear, &(ppaint->fltmemrear[ifilter][0]), CPAINTFILTERMEM, filtertype );
	}

	// make sure on next upsample pass for this paintbuffer, new filter memory is used

	ppaint->ifilter++;
}



// UNDONE: Implement fast 3D mixing routines instead of doing 2D mix times 2 ??
void CAudioDirectSound::Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress )
{
	int volume[CCHANVOLUMES];		// fl, fr, rl, rr

	paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();

	MIX_ScaleChannelVolume( ppaint, pChannel, volume, 1);
	
	Mix8MonoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, (byte *)pData, inputOffset, rateScaleFix, outCount);

	if ( ppaint->fsurround )
	{
		Assert( ppaint->pbufrear );

		Mix8MonoWavtype( pChannel, ppaint->pbufrear + outputOffset, &volume[IREAR_LEFT], (byte *)pData, inputOffset, rateScaleFix, outCount  );
	}
}


void CAudioDirectSound::Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress )
{
	int volume[CCHANVOLUMES];
	paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();

	MIX_ScaleChannelVolume( ppaint, pChannel, volume, 2 );

	Mix8StereoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, (byte *)pData, inputOffset, rateScaleFix, outCount );


	if ( ppaint->fsurround )
	{
		Assert( ppaint->pbufrear );

		Mix8StereoWavtype( pChannel, ppaint->pbufrear + outputOffset, &volume[IREAR_LEFT], (byte *)pData, inputOffset, rateScaleFix, outCount );
	}
}



void CAudioDirectSound::Mix16Mono( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, fixedint rateScaleFix, int outCount, int timecompress )
{
	int volume[CCHANVOLUMES];
	paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();

	MIX_ScaleChannelVolume( ppaint, pChannel, volume, 1 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -