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

📄 snd_dev_direct.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	Mix16MonoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, pData, inputOffset, rateScaleFix, outCount );

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

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

void CAudioDirectSound::Mix16Stereo( 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, 2 );

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

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

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


void CAudioDirectSound::ChannelReset( int entnum, int channelIndex, float distanceMod )
{
}


const char *CAudioDirectSound::DeviceName( void )
{ 
	if ( SURROUND_ON )
		return "4 Channel Surround";
	return "Direct Sound"; 
}

void *CAudioDirectSound::DeviceLockBuffer( void )
{
	int reps = 0;
	HRESULT hresult;
	void *pbuf = NULL, *pbuf2 = NULL;
	DWORD dwSize2;

 //////////////////////////////////////////////////////////////////////////////////////////////////
	if (pDSBuf)
	{
		while ((hresult = pDSBuf->Lock(0, m_bufferSize, (void**)&pbuf, &m_lockBufferSize, 
									   (void**)&pbuf2, &dwSize2, 0)) != DS_OK)
		{
			if (hresult != DSERR_BUFFERLOST)
			{
				Msg ("DS::Lock Sound Buffer Failed\n");
				S_Shutdown ();
				S_Startup ();
				return NULL;
			}

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

	return pbuf;
}



void CAudioDirectSound::DeviceUnlockBuffer( void *pbuf )
{
	if (pDSBuf)
		pDSBuf->Unlock(pbuf, m_lockBufferSize, NULL, 0);
}

void CAudioDirectSound::TransferSamples( int end )
{
	// When Surround is enabled, divert to 4 chan xfer scheme.
	if ( SURROUND_ON )
	{
		int		lpaintedtime;
		int		endtime;

		lpaintedtime = paintedtime; 
		endtime = end;				

		S_TransferStereo16Surround( PAINTBUFFER, REARPAINTBUFFER, lpaintedtime, endtime);
		return;
	}
	else
	{
		if ( DeviceChannels() == 2 && DeviceSampleBits() == 16 )
		{
			S_TransferStereo16( end );
		}
		else
		{
			S_TransferPaintBuffer( end );
		}
	}
}

// given unit vector from listener to sound source,
// determine proportion of volume for sound in FL, FR, RL, RR quadrants
// Scale this proportion by the distance scalar 'gain'
// NOTE: the sum of the quadrant volumes should be approximately 1.0!

void CAudioDirectSound::SpatializeChannel( int volume[4], int master_vol, const Vector& sourceDir, float gain, float dotRight, float dotFront )
{
	float scale, lscale, rscale;
	float rfscale, rrscale, lfscale, lrscale;
	float frontscale, rearscale;
	
	if (DeviceChannels() == 1)
	{
		rscale = 1.0;
		lscale = 1.0;
	}
	else
	{
		rscale = 1.0 + dotRight;			// 0.0->2.0,  2.0 is source fully right		
		lscale = 1.0 - dotRight;			// 2.0->0.0,  2.0 is source fully left
	}

	if ( SURROUND_ON )
	{
		
		frontscale = 1.0 + dotFront;		// 0.0->2.0, 2.0 is source fully front
		rearscale  = 1.0 - dotFront;		// 2.0->0.0, 2.0 is source fully rear

		rfscale = (rscale * frontscale)/2;	// 0.0->2.0, 2.0 is source fully right front
		rrscale = (rscale * rearscale )/2;	// 0.0->2.0, 2.0 is source fully right rear
		lfscale = (lscale * frontscale)/2;	// 0.0->2.0, 2.0 is source fully left front
		lrscale = (lscale * rearscale )/2;	// 0.0->2.0, 2.0 is source fully left rear

		//DevMsg("lfscale=%f rfscale=%f lrscale=%f rrscale=%f\n",lfscale,rfscale,lrscale,rrscale);

		rscale = rfscale;
		lscale = lfscale;
	}
	else
	{
		rrscale = lrscale = 0;	// Compiler warning..
	}

	// scale volumes in each quadrant by distance attenuation.

	// volumes are 0-255:
	// gain is 0.0->1.0, rscale is 0.0->2.0, so scale/2 is 0.0->1.0
	// master_vol is 0->255, so rightvol is 0->255

	scale = gain * rscale / 2.0;
	volume[IFRONT_RIGHT] = (int) (master_vol * scale);

	scale = gain * lscale / 2.0;
	volume[IFRONT_LEFT] = (int) (master_vol * scale);

	if ( SURROUND_ON )
	{
		scale = gain * rrscale / 2.0;
		volume[IREAR_RIGHT] = (int) (master_vol * scale);

		scale = gain * lrscale / 2.0;
		volume[IREAR_LEFT] = (int) (master_vol * scale);
	}
	
	volume[IFRONT_RIGHT] = clamp( volume[IFRONT_RIGHT], 0, 255 );
	volume[IFRONT_LEFT]  = clamp( volume[IFRONT_LEFT], 0, 255 );

	if ( SURROUND_ON )
	{
		volume[IREAR_RIGHT] = clamp( volume[IREAR_RIGHT], 0, 255 );
		volume[IREAR_LEFT] = clamp( volume[IREAR_LEFT], 0, 255 );
	}
}


void CAudioDirectSound::ApplyDSPEffects( int idsp, portable_samplepair_t *pbuffront, portable_samplepair_t *pbufrear, int samplecount)
{


#if 0
	
	// pDSPropSetFL is only valid if EAX is enabled. Use EAX reverbs instead and bypass
	// all the sw rendering.

	// EAX dsp fx currently disabled.
	float fMixLevel;
	int i;
	float roomType;
	HRESULT hResult;

	if ( pDSPropSetFL )
	{
		if ( g_pClientSidePrediction->GetWaterLevel() > 2 )
		{
			roomType = sxroom_type.GetFloat();
			fMixLevel = 1.0f;
		}
		else
		{
			roomType = sxroomwater_type.GetFloat();
			fMixLevel = 0.38f;
		}

		if (roomType != sxroom_typeprev) 
		{
			i = (int)(roomType);
			
			// set reverb params for all 4 mono EAX buffers FL, FR, RL, RR

			sxroom_typeprev = roomType;
			pDSPropSetFL->Set(DSPROPSETID_EAXBUFFER_ReverbPropertiesDef, 
								DSPROPERTY_EAXBUFFER_REVERBMIX, NULL, 0, &fMixLevel, sizeof(float));
			pDSPropSetFR->Set(DSPROPSETID_EAXBUFFER_ReverbPropertiesDef, 
								DSPROPERTY_EAXBUFFER_REVERBMIX, NULL, 0, &fMixLevel, sizeof(float));
			pDSPropSetRL->Set(DSPROPSETID_EAXBUFFER_ReverbPropertiesDef, 
								DSPROPERTY_EAXBUFFER_REVERBMIX, NULL, 0, &fMixLevel, sizeof(float));
			pDSPropSetRR->Set(DSPROPSETID_EAXBUFFER_ReverbPropertiesDef, 
								DSPROPERTY_EAXBUFFER_REVERBMIX, NULL, 0, &fMixLevel, sizeof(float));
			hResult = pDSPropSetFL->Set(DSPROPSETID_EAX_ReverbPropertiesDef, 
								DSPROPERTY_EAX_ALL, NULL, 0, &eax_preset[i], 
								sizeof(EAX_REVERBPROPERTIES));
			if ( hResult != DS_OK )
				DevMsg("Eax failed preset %d\n", i);
			else
				DevMsg("Eax preset %d\n", i);

			// Need to save this to restore preset in a restart.
			g_iEaxPreset = i;
		}
		return;
	}
#endif // 0

	//SX_RoomFX( endtime, filter, timefx );

	DEBUG_StartSoundMeasure( 1, samplecount );

	DSP_Process( idsp, pbuffront, pbufrear, samplecount );

	DEBUG_StopSoundMeasure( 1, samplecount );
}


//////////////////////////////////////////////////////////////////////////////////////////////////
// Given front and rear stereo paintbuffers, split samples into 4 mono directsound buffers (FL, FR, RL, RR)
//
void CAudioDirectSound::S_TransferStereo16Surround( portable_samplepair_t *pfront, portable_samplepair_t *prear, int lpaintedtime, int endtime )
{
	int		lpos;
	HRESULT hr;
	DWORD *pdwWriteFL, *pdwWriteFR, *pdwWriteRL, *pdwWriteRR;
	DWORD dwSizeFL, dwSizeFR, dwSizeRL, dwSizeRR;
	int reps;
	int i, val, *snd_p, *snd_rp, linearCount, volumeFactor;
	short	*snd_out_fleft, *snd_out_fright, *snd_out_rleft, *snd_out_rright;

	snd_p = (int *)pfront;
	volumeFactor = S_GetMasterVolume() * 256;

	// lock all 4 mono directsound buffers FL, FR, RL, RR

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

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

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

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

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

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

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

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

	// take stereo front and rear paintbuffers and copy samples into the 4
	// mono directsound buffers

	snd_rp = (int *)prear;

	int samplePairCount = (DeviceSampleCount()>>1);
	int sampleMask = samplePairCount - 1;
	while (lpaintedtime < endtime)
	{														
		lpos = lpaintedtime & sampleMask;

		linearCount = samplePairCount - lpos;		

		if (linearCount > endtime - lpaintedtime)		
		linearCount = endtime - lpaintedtime;		

		snd_out_fleft = (short *)pdwWriteFL + lpos;
		snd_out_fright = (short *)pdwWriteFR + lpos;
		snd_out_rleft = (short *)pdwWriteRL + lpos;
		snd_out_rright = (short *)pdwWriteRR + lpos;

		linearCount <<= 1;								

		// for 16 bit sample in the front and rear stereo paintbuffers, copy
		// into the 4 FR, FL, RL, RR directsound paintbuffers

		for (i=0 ; i<linearCount ; i+=2)
		{
			val = (snd_p[i]*volumeFactor)>>8;
			snd_out_fleft[i>>1] = CLIP(val);

			val = (snd_p[i + 1]*volumeFactor)>>8;
			snd_out_fright[i>>1] = CLIP(val);

			val = (snd_rp[i]*volumeFactor)>>8;
			snd_out_rleft[i>>1] = CLIP(val);

			val = (snd_rp[i + 1]*volumeFactor)>>8;
			snd_out_rright[i>>1] = CLIP(val);
		}

		snd_p += linearCount;
		snd_rp += linearCount;
		lpaintedtime += (linearCount>>1);
	}

	pDSBufFL->Unlock(pdwWriteFL, dwSizeFL, NULL, 0);
	pDSBufFR->Unlock(pdwWriteFR, dwSizeFR, NULL, 0);
	pDSBufRL->Unlock(pdwWriteRL, dwSizeRL, NULL, 0);
	pDSBufRR->Unlock(pdwWriteRR, dwSizeRR, NULL, 0);
}
//////////////////////////////////////////////////////////////////////////////////////////////////

/*
==================
LPDIRECTSOUND S_GetDSPointer

Returns a pointer to pDS, if it exists, NULL otherwise
==================
*/
void S_GetDSPointer(LPDIRECTSOUND *lpDS, LPDIRECTSOUNDBUFFER *lpDSBuf)
{
	*lpDS = pDS;
	*lpDSBuf = pDSBuf;
}

⌨️ 快捷键说明

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