mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
engine: client: voice api
This commit is contained in:
@@ -159,11 +159,22 @@ typedef struct snd_globals_s
|
||||
qboolean have_ambient_sfx;
|
||||
} snd_globals_t;
|
||||
|
||||
typedef struct voice_audio_info_s
|
||||
{
|
||||
uint width;
|
||||
uint samplerate;
|
||||
uint frame_size; // in samples
|
||||
} voice_audio_info_t;
|
||||
|
||||
// API from engine to client (client calls these)
|
||||
typedef struct sound_api_s
|
||||
{
|
||||
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
|
||||
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
|
||||
// Voice extensions
|
||||
void (*pfnS_RawEntSamples)( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
|
||||
void (*pfnSND_ForceInitMouth)( int entnum );
|
||||
voice_audio_info_t (*pfnVoice_GetAudioInfo)( void );
|
||||
} sound_api_t;
|
||||
|
||||
// Callbacks from client to engine (engine calls these when custom sound is active)
|
||||
|
||||
@@ -82,6 +82,7 @@ typedef struct cldll_func_s
|
||||
void (*pfnLookEvent)( float relyaw, float relpitch );
|
||||
// Sound API
|
||||
int (*pfnGetSoundInterface)( int version, const sound_api_t *api, sound_interface_t *callback );
|
||||
int (*pfnVoice_StartChannel)( int samples, byte *data, int entnum );
|
||||
} cldll_func_t;
|
||||
|
||||
#endif//CDLL_EXP_H
|
||||
|
||||
@@ -105,7 +105,8 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
|
||||
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D ext
|
||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D FWGS ext
|
||||
{ "Voice_StartChannel", (void **)&clgame.dllFuncs.pfnVoice_StartChannel }, // Xash3D FWGS ext
|
||||
};
|
||||
|
||||
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
||||
|
||||
@@ -1287,7 +1287,7 @@ uint S_RawSamplesStereo( portable_samplepair_t *rawsamples, uint rawend, uint ma
|
||||
S_RawEntSamples
|
||||
===================
|
||||
*/
|
||||
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol )
|
||||
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn )
|
||||
{
|
||||
rawchan_t *ch;
|
||||
|
||||
@@ -1298,7 +1298,7 @@ void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word chan
|
||||
return;
|
||||
|
||||
ch->master_vol = snd_vol;
|
||||
ch->dist_mult = (ATTN_NONE / SND_CLIP_DISTANCE);
|
||||
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
|
||||
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples, samples, rate, width, channels, data );
|
||||
ch->leftvol = ch->rightvol = snd_vol;
|
||||
}
|
||||
@@ -1938,6 +1938,9 @@ static void S_VoiceRecordStop_f( void )
|
||||
static const sound_api_t gSoundAPI = {
|
||||
CL_GetEntitySpatialization,
|
||||
S_GetSfxByHandle,
|
||||
S_RawEntSamples,
|
||||
SND_ForceInitMouth,
|
||||
Voice_GetAudioInfo,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -253,7 +253,7 @@ void S_StreamBackgroundTrack( void )
|
||||
{
|
||||
// add to raw buffer
|
||||
int music_vol = (int)(255.0f * S_GetMusicVolume());
|
||||
S_RawEntSamples( S_RAW_SOUND_BACKGROUNDTRACK, fileSamples, info->rate, info->width, info->channels, raw, music_vol );
|
||||
S_RawEntSamples( S_RAW_SOUND_BACKGROUNDTRACK, fileSamples, info->rate, info->width, info->channels, raw, music_vol, ATTN_NONE );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -111,7 +111,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size );
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle );
|
||||
rawchan_t *S_FindRawChannel( int entnum, qboolean create );
|
||||
uint S_RawSamplesStereo( portable_samplepair_t *rawsamples, uint rawend, uint max_samples, uint samples, uint rate, word width, word channels, const byte *data );
|
||||
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol );
|
||||
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
|
||||
void S_StopSound( int entnum, int channel, const char *soundname );
|
||||
void S_UpdateFrame( struct ref_viewpass_s *rvp );
|
||||
void S_StopAllSounds( qboolean ambient );
|
||||
|
||||
@@ -939,8 +939,14 @@ Feed the decoded data to engine sound subsystem
|
||||
*/
|
||||
static void Voice_StartChannel( uint samples, byte *data, int entnum )
|
||||
{
|
||||
if( clgame.dllFuncs.pfnVoice_StartChannel != NULL )
|
||||
{
|
||||
if( clgame.dllFuncs.pfnVoice_StartChannel( samples, data, entnum ))
|
||||
return;
|
||||
}
|
||||
|
||||
SND_ForceInitMouth( entnum );
|
||||
S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, bound( 0, 255 * voice_scale.value, 255 ));
|
||||
S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, bound( 0, 255 * voice_scale.value, 255 ), ATTN_NONE );
|
||||
Voice_Status( entnum, true );
|
||||
}
|
||||
|
||||
@@ -1194,3 +1200,13 @@ qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit )
|
||||
voice.initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
voice_audio_info_t Voice_GetAudioInfo( void )
|
||||
{
|
||||
voice_audio_info_t info;
|
||||
|
||||
info.width = voice.width;
|
||||
info.samplerate = voice.samplerate;
|
||||
info.frame_size = voice.frame_size;
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -131,5 +131,6 @@ void Voice_Disconnect( void );
|
||||
void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames );
|
||||
void Voice_StopChannel( int entnum );
|
||||
void Voice_LoopbackAck( void ); // sends VOICE_LOOPBACK_INDEX to client, gets disabled on timeout
|
||||
voice_audio_info_t Voice_GetAudioInfo( void );
|
||||
|
||||
#endif // VOICE_H
|
||||
|
||||
@@ -168,6 +168,8 @@ typedef struct physics_interface_s
|
||||
void *(*SV_HullForBsp)( edict_t *ent, const float *mins, const float *maxs, float *offset );
|
||||
// handle player custom think function
|
||||
int (*SV_PlayerThink)( edict_t *ent, float frametime, double time );
|
||||
// voice data
|
||||
qboolean (*pfnVoiceData)( int client, uint frames, uint size, qboolean loopback, const char *received );
|
||||
} physics_interface_t;
|
||||
|
||||
#endif//PHYSINT_H
|
||||
|
||||
@@ -406,6 +406,7 @@ extern convar_t sv_wateralpha;
|
||||
extern convar_t sv_wateramp;
|
||||
extern convar_t sv_voiceenable;
|
||||
extern convar_t sv_voicequality;
|
||||
extern convar_t sv_voice_singleplayer;
|
||||
extern convar_t sv_maxvelocity;
|
||||
extern convar_t sv_stepsize;
|
||||
extern convar_t sv_skyname;
|
||||
|
||||
@@ -3571,7 +3571,16 @@ static void SV_ParseVoiceData( sv_client_t *cl, sizebuf_t *msg )
|
||||
|
||||
MSG_ReadBytes( msg, received, size );
|
||||
|
||||
if( !sv_voiceenable.value || svs.maxclients <= 1 || cl->state != cs_spawned )
|
||||
if( !sv_voiceenable.value || cl->state != cs_spawned )
|
||||
return;
|
||||
|
||||
if( svgame.physFuncs.pfnVoiceData != NULL )
|
||||
{
|
||||
if( svgame.physFuncs.pfnVoiceData( client, frames, size, loopback, received ))
|
||||
return;
|
||||
}
|
||||
|
||||
if( svs.maxclients <= 1 && sv_voice_singleplayer.value == 0.0f )
|
||||
return;
|
||||
|
||||
for( i = 0; i < svs.maxclients; i++ )
|
||||
|
||||
@@ -463,7 +463,7 @@ static void SV_CreateBaseline( void )
|
||||
int delta_type;
|
||||
int entnum;
|
||||
|
||||
if( svs.maxclients > 1 )
|
||||
if( svs.maxclients > 1 || sv_voice_singleplayer.value )
|
||||
SV_WriteVoiceCodec( &sv.signon );
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
|
||||
@@ -124,6 +124,7 @@ static CVAR_DEFINE_AUTO( violence_agibs, "1", 0, "show alien gib entities" );
|
||||
// voice chat
|
||||
CVAR_DEFINE_AUTO( sv_voiceenable, "1", FCVAR_ARCHIVE|FCVAR_SERVER, "enable voice support" );
|
||||
CVAR_DEFINE_AUTO( sv_voicequality, "3", FCVAR_ARCHIVE, "voice chat quality level, from 0 to 5, higher is better" );
|
||||
CVAR_DEFINE_AUTO( sv_voice_singleplayer, "0", FCVAR_ARCHIVE, "enable voice subsystem in singleplayer games (maxclients == 1)" );
|
||||
|
||||
// enttools
|
||||
CVAR_DEFINE_AUTO( sv_enttools_enable, "0", FCVAR_ARCHIVE|FCVAR_PROTECTED, "enable powerful and dangerous entity tools" );
|
||||
@@ -975,6 +976,7 @@ void SV_Init( void )
|
||||
|
||||
Cvar_RegisterVariable( &sv_voiceenable );
|
||||
Cvar_RegisterVariable( &sv_voicequality );
|
||||
Cvar_RegisterVariable( &sv_voice_singleplayer );
|
||||
Cvar_RegisterVariable( &sv_trace_messages );
|
||||
Cvar_RegisterVariable( &sv_enttools_enable );
|
||||
Cvar_RegisterVariable( &sv_enttools_maxfire );
|
||||
|
||||
Reference in New Issue
Block a user