mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-09 21:52:05 +08:00
Merge remote-tracking branch 'pwd491/gsvoice'
This commit is contained in:
@@ -1029,6 +1029,10 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
|
||||
crc = CRC32_Final( crc );
|
||||
i = GenerateRevEmu2013( buf, s, crc );
|
||||
MSG_WriteBytes( send, buf, i );
|
||||
|
||||
// RevEmu2013: pTicket[1] = revHash (low), pTicket[5] = 0x01100001 (high)
|
||||
*(uint32_t*)cls.steamid = LittleLong( ((uint32_t*)buf)[1] );
|
||||
*(uint32_t*)(cls.steamid + 4) = LittleLong( ((uint32_t*)buf)[5] );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+24
-27
@@ -2010,44 +2010,41 @@ CL_ParseVoiceData
|
||||
*/
|
||||
void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
int size, idx, frames;
|
||||
byte received[8192];
|
||||
int size, idx, frames = 0;
|
||||
byte received[VOICE_MAX_DATA_SIZE];
|
||||
|
||||
idx = MSG_ReadByte( msg ) + 1;
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
size = MSG_ReadShort( msg );
|
||||
MSG_SeekToBit( msg, size << 3, SEEK_CUR ); // skip the entire buf, not supported yet
|
||||
|
||||
#if 0 // shall we notify client.dll if nothing can be heard?
|
||||
// must notify through as both local player and normal client
|
||||
if( idx == cl.playernum + 1 )
|
||||
Voice_StatusAck( &voice.local, VOICE_LOOPBACK_INDEX );
|
||||
|
||||
Voice_StatusAck( &voice.players_status[idx], idx );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
frames = MSG_ReadByte( msg );
|
||||
size = MSG_ReadShort( msg );
|
||||
size = Q_min( size, sizeof( received ));
|
||||
|
||||
MSG_ReadBytes( msg, received, size );
|
||||
|
||||
if ( idx <= 0 || idx > cl.maxclients )
|
||||
return;
|
||||
|
||||
// must notify through as both local player and normal client
|
||||
if( idx == cl.playernum + 1 )
|
||||
Voice_StatusAck( &voice.local, VOICE_LOOPBACK_INDEX );
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
size = MSG_ReadShort( msg );
|
||||
if ( size > VOICE_MAX_GS_DATA_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "Voice data size is too large: %d bytes (max: %d)\n", size, VOICE_MAX_GS_DATA_SIZE );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frames = MSG_ReadByte( msg );
|
||||
size = MSG_ReadShort( msg );
|
||||
if (size > VOICE_MAX_DATA_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "Voice data size is too large: %d bytes (max: %d)\n", size, VOICE_MAX_DATA_SIZE );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Voice_StatusAck( &voice.players_status[idx], idx );
|
||||
size = Q_min( size, sizeof( received ));
|
||||
|
||||
if ( !size )
|
||||
return;
|
||||
|
||||
MSG_ReadBytes( msg, received, size );
|
||||
|
||||
Voice_AddIncomingData( idx, received, size, frames );
|
||||
}
|
||||
|
||||
|
||||
@@ -638,6 +638,7 @@ typedef struct
|
||||
|
||||
// server's build number (might be zero)
|
||||
int build_num;
|
||||
uint8_t steamid[8];
|
||||
} client_static_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+21
-3
@@ -22,6 +22,7 @@ enum
|
||||
IPAINTBUFFER = 0,
|
||||
IROOMBUFFER,
|
||||
ISTREAMBUFFER,
|
||||
IVOICEBUFFER,
|
||||
CPAINTBUFFERS,
|
||||
};
|
||||
|
||||
@@ -63,6 +64,7 @@ static portable_samplepair_t *g_curpaintbuffer;
|
||||
static portable_samplepair_t streambuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t paintbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t roombuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t voicebuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t temppaintbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static paintbuffer_t paintbuffers[CPAINTBUFFERS];
|
||||
|
||||
@@ -216,6 +218,7 @@ void MIX_InitAllPaintbuffers( void )
|
||||
paintbuffers[IPAINTBUFFER].pbuf = paintbuffer;
|
||||
paintbuffers[IROOMBUFFER].pbuf = roombuffer;
|
||||
paintbuffers[ISTREAMBUFFER].pbuf = streambuffer;
|
||||
paintbuffers[IVOICEBUFFER].pbuf = voicebuffer;
|
||||
|
||||
MIX_SetCurrentPaintbuffer( IPAINTBUFFER );
|
||||
}
|
||||
@@ -921,11 +924,12 @@ static void S_MixUpsample( int sampleCount, int filtertype )
|
||||
|
||||
static void MIX_MixRawSamplesBuffer( int end )
|
||||
{
|
||||
portable_samplepair_t *pbuf, *roombuf, *streambuf;
|
||||
portable_samplepair_t *pbuf, *roombuf, *streambuf, *voicebuf;
|
||||
uint i, j, stop;
|
||||
|
||||
roombuf = MIX_GetPFrontFromIPaint( IROOMBUFFER );
|
||||
streambuf = MIX_GetPFrontFromIPaint( ISTREAMBUFFER );
|
||||
voicebuf = MIX_GetPFrontFromIPaint( IVOICEBUFFER );
|
||||
|
||||
if( s_listener.paused ) return;
|
||||
|
||||
@@ -935,6 +939,7 @@ static void MIX_MixRawSamplesBuffer( int end )
|
||||
// copy from the streaming sound source
|
||||
rawchan_t *ch = raw_channels[i];
|
||||
qboolean stream;
|
||||
qboolean is_voice;
|
||||
|
||||
if( !ch )
|
||||
continue;
|
||||
@@ -943,8 +948,18 @@ static void MIX_MixRawSamplesBuffer( int end )
|
||||
if( !ch->leftvol && !ch->rightvol )
|
||||
continue;
|
||||
|
||||
is_voice = (ch->entnum > 0 && ch->entnum <= MAX_CLIENTS) ||
|
||||
(ch->entnum == VOICE_LOOPBACK_INDEX) ||
|
||||
(ch->entnum == VOICE_LOCALCLIENT_INDEX);
|
||||
|
||||
stream = ch->entnum == S_RAW_SOUND_BACKGROUNDTRACK || CL_IsPlayerIndex( ch->entnum );
|
||||
pbuf = stream ? streambuf : roombuf;
|
||||
|
||||
if( is_voice )
|
||||
pbuf = voicebuf;
|
||||
else if( stream )
|
||||
pbuf = streambuf;
|
||||
else
|
||||
pbuf = roombuf;
|
||||
|
||||
stop = (end < ch->s_rawend) ? end : ch->s_rawend;
|
||||
|
||||
@@ -1045,7 +1060,10 @@ void MIX_PaintChannels( int endtime )
|
||||
MIX_MixPaintbuffers( IPAINTBUFFER, IROOMBUFFER, IPAINTBUFFER, count, S_GetMasterVolume() );
|
||||
|
||||
// add music or soundtrack from movie (no dsp)
|
||||
MIX_MixPaintbuffers( IPAINTBUFFER, ISTREAMBUFFER, IPAINTBUFFER, count, S_GetMusicVolume() );
|
||||
MIX_MixPaintbuffers( IPAINTBUFFER, ISTREAMBUFFER, IPAINTBUFFER, count, 1.0f );
|
||||
|
||||
// voice chat
|
||||
MIX_MixPaintbuffers( IPAINTBUFFER, IVOICEBUFFER, IPAINTBUFFER, count, 1.0f );
|
||||
|
||||
// clip all values > 16 bit down to 16 bit
|
||||
MIX_CompressPaintbuffer( IPAINTBUFFER, count );
|
||||
|
||||
@@ -242,7 +242,8 @@ void S_StreamBackgroundTrack( void )
|
||||
if( r > 0 )
|
||||
{
|
||||
// add to raw buffer
|
||||
S_RawEntSamples( S_RAW_SOUND_BACKGROUNDTRACK, fileSamples, info->rate, info->width, info->channels, raw, 255 );
|
||||
int music_vol = (int)(255.0f * S_GetMusicVolume());
|
||||
S_RawEntSamples( S_RAW_SOUND_BACKGROUNDTRACK, fileSamples, info->rate, info->width, info->channels, raw, music_vol );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+729
-200
File diff suppressed because it is too large
Load Diff
+51
-22
@@ -24,46 +24,81 @@ GNU General Public License for more details.
|
||||
typedef struct OpusCustomEncoder OpusCustomEncoder;
|
||||
typedef struct OpusCustomDecoder OpusCustomDecoder;
|
||||
typedef struct OpusCustomMode OpusCustomMode;
|
||||
typedef struct OpusEncoder OpusEncoder;
|
||||
typedef struct OpusDecoder OpusDecoder;
|
||||
|
||||
#define VOICE_LOOPBACK_INDEX (-2)
|
||||
#define VOICE_LOCALCLIENT_INDEX (-1)
|
||||
#define VOICE_LOOPBACK_INDEX ( -2 )
|
||||
#define VOICE_LOCALCLIENT_INDEX ( -1 )
|
||||
|
||||
#define VOICE_PCM_CHANNELS 1 // always mono
|
||||
#define VOICE_PCM_CHANNELS 1 // always mono
|
||||
#define VOICE_MAX_DATA_SIZE 8192
|
||||
#define VOICE_MAX_GS_DATA_SIZE 4096
|
||||
|
||||
// never change these parameters when using opuscustom
|
||||
#define VOICE_OPUS_CUSTOM_SAMPLERATE 44100
|
||||
// must follow opus custom requirements
|
||||
// also be divisible with MAX_RAW_SAMPLES
|
||||
#define VOICE_OPUS_CUSTOM_FRAME_SIZE 1024
|
||||
#define VOICE_OPUS_CUSTOM_CODEC "opus_custom_44k_512"
|
||||
#define VOICE_OPUS_CUSTOM_CODEC "opus_custom_44k_512"
|
||||
|
||||
// a1ba: do not change, we don't have any re-encoding support now
|
||||
#define VOICE_DEFAULT_CODEC VOICE_OPUS_CUSTOM_CODEC
|
||||
#define VOICE_DEFAULT_CODEC VOICE_OPUS_CUSTOM_CODEC
|
||||
#define VOICE_DEFAULT_SILENCE_FRAME_SIZE 160
|
||||
|
||||
// GoldSrc voice configuration
|
||||
#define GS_MAX_DECOMPRESSED_SAMPLES 32768
|
||||
#define GS_DEFAULT_SAMPLE_RATE 24000
|
||||
#define GS_DEFAULT_FRAME_SIZE 480
|
||||
|
||||
// VPC (Voice Packet Control) types
|
||||
enum gs_vpc_type
|
||||
{
|
||||
GS_VPC_VDATA_SILENCE = 0,
|
||||
GS_VPC_VDATA_MILES = 1,
|
||||
GS_VPC_VDATA_SPEEX = 2,
|
||||
GS_VPC_VDATA_RAW = 3,
|
||||
GS_VPC_VDATA_SILK = 4,
|
||||
GS_VPC_VDATA_OPUS_PLC = 6,
|
||||
GS_VPC_SETSAMPLERATE = 11,
|
||||
GS_VPC_UNKNOWN = 10
|
||||
};
|
||||
|
||||
typedef struct voice_status_s
|
||||
{
|
||||
qboolean talking_ack;
|
||||
double talking_timeout;
|
||||
double talking_timeout;
|
||||
} voice_status_t;
|
||||
|
||||
typedef struct voice_autogain_s
|
||||
{
|
||||
int block_size;
|
||||
float current_gain;
|
||||
float next_gain;
|
||||
float gain_multiplier;
|
||||
} voice_autogain_t;
|
||||
|
||||
typedef struct voice_state_s
|
||||
{
|
||||
string codec;
|
||||
int quality;
|
||||
string codec;
|
||||
int quality;
|
||||
qboolean goldsrc;
|
||||
|
||||
qboolean initialized;
|
||||
qboolean is_recording;
|
||||
qboolean device_opened;
|
||||
double start_time;
|
||||
double start_time;
|
||||
|
||||
voice_status_t local;
|
||||
voice_status_t players_status[MAX_CLIENTS];
|
||||
voice_status_t local;
|
||||
voice_status_t players_status[MAX_CLIENTS];
|
||||
|
||||
// opus stuff
|
||||
OpusCustomMode *custom_mode;
|
||||
OpusCustomEncoder *encoder;
|
||||
OpusCustomDecoder *decoders[MAX_CLIENTS];
|
||||
|
||||
OpusEncoder *gs_encoder;
|
||||
OpusDecoder *gs_decoders[MAX_CLIENTS];
|
||||
|
||||
// audio info
|
||||
uint width;
|
||||
uint samplerate;
|
||||
@@ -73,25 +108,18 @@ typedef struct voice_state_s
|
||||
byte input_buffer[MAX_RAW_SAMPLES];
|
||||
byte compress_buffer[MAX_RAW_SAMPLES];
|
||||
byte decompress_buffer[MAX_RAW_SAMPLES];
|
||||
fs_offset_t input_buffer_pos; // in bytes
|
||||
fs_offset_t input_buffer_pos; // in bytes
|
||||
|
||||
// input from file
|
||||
wavdata_t *input_file;
|
||||
fs_offset_t input_file_pos; // in bytes
|
||||
wavdata_t *input_file;
|
||||
fs_offset_t input_file_pos; // in bytes
|
||||
|
||||
// automatic gain control
|
||||
struct {
|
||||
int block_size;
|
||||
float current_gain;
|
||||
float next_gain;
|
||||
float gain_multiplier;
|
||||
} autogain;
|
||||
voice_autogain_t autogain;
|
||||
} voice_state_t;
|
||||
|
||||
extern voice_state_t voice;
|
||||
|
||||
void CL_AddVoiceToDatagram( void );
|
||||
|
||||
void Voice_RegisterCvars( void );
|
||||
qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit );
|
||||
void Voice_Idle( double frametime );
|
||||
@@ -101,5 +129,6 @@ void Voice_RecordStart( void );
|
||||
void Voice_Disconnect( void );
|
||||
void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames );
|
||||
void Voice_StatusAck( voice_status_t *status, int playerIndex );
|
||||
void Voice_StartChannel( uint samples, byte *data, int entnum );
|
||||
|
||||
#endif // VOICE_H
|
||||
|
||||
@@ -342,6 +342,7 @@ void VoiceCapture_Shutdown( void )
|
||||
return;
|
||||
|
||||
SDL_CloseAudioDevice( in_dev );
|
||||
in_dev = 0;
|
||||
}
|
||||
|
||||
#endif // XASH_SOUND == SOUND_SDL
|
||||
|
||||
Reference in New Issue
Block a user