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

📄 snd_dev_direct.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		if (!(dwStatus & DSBSTATUS_PLAYING))
			pDSBufRR->Play(0, 0, DSBPLAY_LOOPING);
	}
	else if (pDSBuf)
	{
		if (pDSBuf->GetStatus (&dwStatus) != DS_OK)
			Msg ("Couldn't get sound buffer status\n");
		
		if (dwStatus & DSBSTATUS_BUFFERLOST)
			pDSBuf->Restore ();
		
		if (!(dwStatus & DSBSTATUS_PLAYING))
			pDSBuf->Play(0, 0, DSBPLAY_LOOPING);
	}

	return endtime;
}


void CAudioDirectSound::PaintEnd( void )
{
}


void CAudioDirectSound::ClearBuffer( void )
{
	int		clear;

////////////////////////////////////////////////////////////////////////////////////////////////////////////
	DWORD	dwSizeFL, dwSizeFR, dwSizeRL, dwSizeRR;
	char	*pDataFL, *pDataFR, *pDataRL, *pDataRR;
 
	if ( SURROUND_ON )
	{
		int		SURROUNDreps;
		HRESULT	SURROUNDhresult;
		SURROUNDreps = 0;

		if ( !pDSBufFL && !pDSBufFR && !pDSBufRL && !pDSBufRR )
			return;

		while ((SURROUNDhresult = pDSBufFL->Lock(0, m_bufferSize/2, (void**)&pDataFL, &dwSizeFL, NULL, NULL, 0)) != DS_OK)
		{
			if (SURROUNDhresult != DSERR_BUFFERLOST)
			{
				Msg ("S_ClearBuffer: DS::Lock FL Sound Buffer Failed\n");
				S_Shutdown ();
				return;
			}

			if (++SURROUNDreps > 10000)
			{
				Msg ("S_ClearBuffer: DS: couldn't restore FL buffer\n");
				S_Shutdown ();
				return;
			}
		}

		SURROUNDreps = 0;
		while ((SURROUNDhresult = pDSBufFR->Lock(0, m_bufferSize/2, (void**)&pDataFR, &dwSizeFR, NULL, NULL, 0)) != DS_OK)
		{
			if (SURROUNDhresult != DSERR_BUFFERLOST)
			{
				Msg ("S_ClearBuffer: DS::Lock FR Sound Buffer Failed\n");
				S_Shutdown ();
				return;
			}

			if (++SURROUNDreps > 10000)
			{
				Msg ("S_ClearBuffer: DS: couldn't restore FR buffer\n");
				S_Shutdown ();
				return;
			}
		}

		SURROUNDreps = 0;
		while ((SURROUNDhresult = pDSBufRL->Lock(0, m_bufferSize/2, (void**)&pDataRL, &dwSizeRL, NULL, NULL, 0)) != DS_OK)
		{
			if (SURROUNDhresult != DSERR_BUFFERLOST)
			{
				Msg ("S_ClearBuffer: DS::Lock RL Sound Buffer Failed\n");
				S_Shutdown ();
				return;
			}

			if (++SURROUNDreps > 10000)
			{
				Msg ("S_ClearBuffer: DS: couldn't restore RL buffer\n");
				S_Shutdown ();
				return;
			}
		}

		SURROUNDreps = 0;
		while ((SURROUNDhresult = pDSBufRR->Lock(0, m_bufferSize/2, (void**)&pDataRR, &dwSizeRR, NULL, NULL, 0)) != DS_OK)
		{
			if (SURROUNDhresult != DSERR_BUFFERLOST)
			{
				Msg ("S_ClearBuffer: DS::Lock RR Sound Buffer Failed\n");
				S_Shutdown ();
				return;
			}

			if (++SURROUNDreps > 10000)
			{
				Msg ("S_ClearBuffer: DS: couldn't restore RR buffer\n");
				S_Shutdown ();
				return;
			}
		}

		Q_memset(pDataFL, 0, m_bufferSize/2);
		Q_memset(pDataFR, 0, m_bufferSize/2);
		Q_memset(pDataRL, 0, m_bufferSize/2);
		Q_memset(pDataRR, 0, m_bufferSize/2);

		pDSBufFL->Unlock(pDataFL, dwSizeFL, NULL, 0);
		pDSBufFR->Unlock(pDataFR, dwSizeFR, NULL, 0);
		pDSBufRL->Unlock(pDataRL, dwSizeRL, NULL, 0);
		pDSBufRR->Unlock(pDataRR, dwSizeRR, NULL, 0);

		return;
	}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
	if ( !pDSBuf )
		return;

	if ( DeviceSampleBits() == 8)
		clear = 0x80;
	else
		clear = 0;

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

		reps = 0;

		while ((hresult = pDSBuf->Lock(0, m_bufferSize, (void**)&pData, &dwSize, NULL, NULL, 0)) != DS_OK)
		{
			if (hresult != DSERR_BUFFERLOST)
			{
				Msg ("S_ClearBuffer: DS::Lock Sound Buffer Failed\n");
				S_Shutdown ();
				return;
			}

			if (++reps > 10000)
			{
				Msg ("S_ClearBuffer: DS: couldn't restore buffer\n");
				S_Shutdown ();
				return;
			}
		}

		Q_memset(pData, clear, DeviceSampleCount() * DeviceSampleBytes());

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

	}
}

void CAudioDirectSound::StopAllSounds( void )
{
}

/*
==================
SNDDMA_InitDirect

Direct-Sound support
==================
*/
sndinitstat CAudioDirectSound::SNDDMA_InitDirect( void )
{
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	DWORD			dwSize, dwWrite;
	DSCAPS			dscaps;
	WAVEFORMATEX	format, pformat; 
	HRESULT			hresult;
	int				reps;
	void			*lpData = NULL;
	qboolean		primary_format_set;

	// BUGBUG: Making 8 bit mono/stereo output has weird latency problems.
	// UNDONE: Revisit and test this to make sure 8-bit devices will work.

	m_deviceChannels = 2;
	m_deviceSampleBits = 16;
	m_deviceDmaSpeed = SOUND_DMA_SPEED;	// 44k: hardware playback rate

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = m_deviceChannels;
    format.wBitsPerSample = m_deviceSampleBits;
    format.nSamplesPerSec = m_deviceDmaSpeed;
    format.nBlockAlign = format.nChannels
		*format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec
		*format.nBlockAlign; 

	if (!m_hInstDS)
	{
		m_hInstDS = LoadLibrary("dsound.dll");
		
		if (m_hInstDS == NULL)
		{
			g_pSoundServices->ConSafePrint ("Couldn't load dsound.dll\n");
			return SIS_FAILURE;
		}

		pDirectSoundCreate = (long (__stdcall *)(struct _GUID *,struct IDirectSound ** ,struct IUnknown *))GetProcAddress(m_hInstDS,"DirectSoundCreate");

		if (!pDirectSoundCreate)
		{
			g_pSoundServices->ConSafePrint ("Couldn't get DS proc addr\n");
			return SIS_FAILURE;
		}
	}

	while ((hresult = iDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK)
	{
		if (hresult != DSERR_ALLOCATED)
		{
			DevMsg ("DirectSound create failed\n");
			return SIS_FAILURE;
		}

#if 0
		if (MessageBox (NULL,
						"The sound hardware is in use by another app.\n\n"
					    "Select Retry to try to start sound again or Cancel to run Half-Life with no sound.",
						"Sound not available",
						MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
		{
			g_pSoundServices->ConSafePrint ("DirectSoundCreate failure\n"
							"  hardware already in use\n");
			return SIS_NOTAVAIL;
		}
#else
	return SIS_NOTAVAIL;
#endif

	}

	dscaps.dwSize = sizeof(dscaps);

	if (DS_OK != pDS->GetCaps (&dscaps))
	{
		g_pSoundServices->ConSafePrint ("Couldn't get DS caps\n");
	}

	if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
	{
		g_pSoundServices->ConSafePrint ("No DirectSound driver installed\n");
		Shutdown();
		return SIS_FAILURE;
	}

	if (DS_OK != pDS->SetCooperativeLevel (*pmainwindow, DSSCL_EXCLUSIVE))
	{
		g_pSoundServices->ConSafePrint ("Set coop level failed\n");
		Shutdown();
		return SIS_FAILURE;
	}

// 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|DSBCAPS_CTRL3D;
	dsbuf.dwBufferBytes = 0;
	dsbuf.lpwfxFormat = NULL;

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

	if (!g_pSoundServices->CheckParm ("-snoforceformat"))
	{
		if (DS_OK == pDS->CreateSoundBuffer(&dsbuf, &pDSPBuf, NULL))
		{
			pformat = format;

			if (DS_OK != pDSPBuf->SetFormat (&pformat))
			{
				if (snd_firsttime)
					DevMsg ("Set primary sound buffer format: no\n");
			}
			else
			{
				if (snd_firsttime)
					DevMsg ("Set primary sound buffer format: yes\n");

				primary_format_set = true;
			}
		}
	}


	SURROUND_ON = FALSE;

	if (s_surround.GetInt()) 
		SURROUND_ON = SNDDMA_InitSurround(pDS, &format, &dsbcaps);

	if ( !SURROUND_ON )
	{
		s_surround.SetValue( 0 );

		if (!primary_format_set || !g_pSoundServices->CheckParm ("-primarysound"))
		{
		// 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);

			if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL))
			{
				g_pSoundServices->ConSafePrint ("DS:CreateSoundBuffer Failed");
				Shutdown();
				return SIS_FAILURE;
			}

			m_deviceChannels = format.nChannels;
			m_deviceSampleBits = format.wBitsPerSample;
			m_deviceDmaSpeed = format.nSamplesPerSec;

			if (DS_OK != pDSBuf->GetCaps (&dsbcaps))
			{
				g_pSoundServices->ConSafePrint ("DS:GetCaps failed\n");
				Shutdown();
				return SIS_FAILURE;
			}

			if (snd_firsttime)
				DevMsg ("Using secondary sound buffer\n");
		}
		else
		{
			if (DS_OK != pDS->SetCooperativeLevel (*pmainwindow, DSSCL_WRITEPRIMARY))
			{
				g_pSoundServices->ConSafePrint ("Set coop level failed\n");
				Shutdown();
				return SIS_FAILURE;
			}

			if (DS_OK != pDSPBuf->GetCaps (&dsbcaps))
			{
				Msg ("DS:GetCaps failed\n");
				return SIS_FAILURE;
			}

			pDSBuf = pDSPBuf;
			DevMsg ("Using primary sound buffer\n");
		}

		// Make sure mixer is active
		pDSBuf->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 = dsbcaps.dwBufferBytes;

	// initialize the buffer
		reps = 0;

		while ((hresult = pDSBuf->Lock(0, m_bufferSize, (void**)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
		{
			if (hresult != DSERR_BUFFERLOST)
			{
				g_pSoundServices->ConSafePrint ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
				Shutdown();
				return SIS_FAILURE;
			}

			if (++reps > 10000)
			{
				g_pSoundServices->ConSafePrint ("SNDDMA_InitDirect: DS: couldn't restore buffer\n");
				Shutdown();
				return SIS_FAILURE;
			}

		}

		memset(lpData, 0, dwSize);
	//		lpData[4] = lpData[5] = 0x7f;	// force a pop for debugging

		pDSBuf->Unlock(lpData, dwSize, NULL, 0);

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

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

	m_deviceSampleCount = m_bufferSize/(DeviceSampleBytes());
	// UNDONE: Do I need this?
	//shm->buffer = (unsigned char *) lpData;

	return SIS_SUCCESS;
}


/*
  This routine is used to intercept SNDDMA_GetDMAPos. We need to return the total

⌨️ 快捷键说明

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