📄 snd_dev_direct.cpp
字号:
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 + -