We have now better angle update

Since it was previously based on old frametime,
you would see your angle changes from previous frametime,
not the current one...
It's now fixed.
This commit is contained in:
unknown 2024-09-12 22:33:24 +02:00
parent db3027fa29
commit d03c92b6f0
12 changed files with 200 additions and 200 deletions

View file

@ -699,7 +699,7 @@ typedef enum _DXVA_SampleFormat {
DXVA_SampleSubStream = 7
} DXVA_SampleFormat;
#define DXVA_ExtractSampleFormat(_sf) ((_sf) & (DXVA_SampleFormatMask))
#define DXVA_ExtraMovementSampleFormatMask))
#define DXVA_ExtractExtColorData(_sf, _Mask, _Shift) \
(((_sf) >> (_Shift)) & (_Mask))

View file

@ -10,6 +10,7 @@
#include "client.h"
#include "client_pch.h"
#include "clockdriftmgr.h"
#include "host.h"
#include "sound.h"
#include <inetchannel.h>
#include "checksum_engine.h"
@ -593,7 +594,7 @@ void CL_ReadPackets ( bool bFinalTick )
// While clock correction is off, we have the old behavior of matching the client and server clocks.
if (CClockDriftMgr::IsClockCorrectionEnabled())
{
cl.m_ClockDriftMgr.IncrementCachedTickCount(bFinalTick);
cl.GetClockDriftMgr().IncrementCachedTickCount(bFinalTick);
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
g_ClientGlobalVariables.curtime = cl.GetTime();
}
@ -2081,7 +2082,7 @@ void CL_DecayLights (void)
}
void CL_ExtraMouseUpdate( float frametime )
void CL_ExtraMovementUpdate( float frametime )
{
// Not ready for commands yet.
if ( !cl.IsActive() )
@ -2102,7 +2103,7 @@ void CL_ExtraMouseUpdate( float frametime )
int nextcommandnr = cl.lastoutgoingcommand + cl.chokedcommands + 1;
// Have client .dll create and store usercmd structure
g_ClientDLL->ExtraMouseSample( nextcommandnr, frametime, !cl.m_bPaused );
g_ClientDLL->ExtraMovementSample( cl.GetClockDriftMgr().m_nNumberOfTicks, nextcommandnr, frametime, !cl.m_bPaused );
}
/*
@ -2159,7 +2160,7 @@ void CL_SendMove( void )
}
}
void CL_Move(float accumulated_extra_samples, bool bFinalTick )
void CL_Move(float frametime, bool bFinalTick )
{
if ( !cl.IsConnected() )
return;
@ -2205,10 +2206,20 @@ void CL_Move(float accumulated_extra_samples, bool bFinalTick )
int nextcommandnr = cl.lastoutgoingcommand + cl.chokedcommands + 1;
// Have client .dll create and store usercmd structure
// TODO_ENHANCED:
// Sooo why do we ignore interval per tick overlap here?
// Because the mouse accumulators even in low fps are always reset to zero anyway after the first tick.
// Movements will be instead calculate inside CL_ExtraMovementSample with the correct frametime.
// Doing host_state.interval_per_tick - frametime was just to calculate the previous frametime, but it has issues:
// Before even if you had low fps, the mouse will only be updated only once even if CreateMove is called multiple times.
// So basically, no matter the frametime you had, the mouse will never update its angles anyway with the correct amount (multiple interval per ticks.);
// Because GetRawMouseAccumulators will always be zero, except with old behavior with GetCursorPos.
// So, instead the frametime has been divided by the number ticks been ran, so we get the right amount to adjust everytime.
// Technically it's even safe to remove now the calculation for movements since they'll calculated inside CL_ExtraMovementSample now.
g_ClientDLL->CreateMove(
nextcommandnr,
host_state.interval_per_tick - accumulated_extra_samples,
frametime,
!cl.IsPaused() );
// Store new usercmd to dem file

View file

@ -158,7 +158,7 @@ void CL_RegisterResources ( void );
// cl_input
//
void CL_Move( float accumulated_extra_samples, bool bFinalTick );
void CL_ExtraMouseUpdate( float remainder );
void CL_ExtraMovementUpdate( float remainder );
void CL_ClearState (void);
void CL_ReadPackets ( bool framefinished ); // Read packets from server and other sources (ping requests, etc.)

View file

@ -2623,7 +2623,7 @@ Runs all active servers
==================
*/
void _Host_RunFrame_Input( float accumulated_extra_samples, bool bFinalTick )
void _Host_RunFrame_Input( float frametime, bool bFinalTick )
{
VPROF_BUDGET( "_Host_RunFrame_Input", _T("Input") );
@ -2656,7 +2656,7 @@ void _Host_RunFrame_Input( float accumulated_extra_samples, bool bFinalTick )
g_HostTimes.EndFrameSegment( FRAME_SEGMENT_CMD_EXECUTE );
// Send any current movement commands to server and flush reliable buffer even if not moving yet.
CL_Move( accumulated_extra_samples, bFinalTick );
CL_Move( frametime, bFinalTick );
#endif
@ -3054,7 +3054,6 @@ void _Host_RunFrame (float time)
{
MDLCACHE_COARSE_LOCK_(g_pMDLCache);
static double host_remainder = 0.0f;
double prevremainder;
bool shouldrender;
#if defined( RAD_TELEMETRY_ENABLED )
@ -3104,11 +3103,6 @@ void _Host_RunFrame (float time)
shouldrender = !sv.IsDedicated();
// FIXME: Could track remainder as fractional ticks instead of msec
prevremainder = host_remainder;
if ( prevremainder < 0 )
prevremainder = 0;
#if !defined(SWDS)
if ( !demoplayer->IsPlaybackPaused() )
#endif
@ -3136,7 +3130,7 @@ void _Host_RunFrame (float time)
host_remainder -= numticks * host_state.interval_per_tick;
}
cl.m_ClockDriftMgr.m_nNumberOfTicks = numticks;
cl.GetClockDriftMgr().m_nNumberOfTicks = numticks;
host_nexttick = host_state.interval_per_tick - host_remainder;
@ -3240,14 +3234,14 @@ void _Host_RunFrame (float time)
g_ClientGlobalVariables.next_interpolation_amount = cl.m_tickRemainder / host_state.interval_per_tick;
// TODO_ENHANCED:
// Update the mouse as last so we can get the right viewangles while taking screenshot.
// Update the mouse as first so we can get the right viewangles while rendering.
// The mouse is always simulated for the current frame's time
// This makes updates smooth in every case
// continuous controllers affecting the view are also simulated this way
// but they have a cap applied by IN_SetSampleTime() so they are not also
// simulated during input gathering
g_ClientGlobalVariables.frametime = host_frametime;
CL_ExtraMouseUpdate( host_frametime );
CL_ExtraMovementUpdate( host_frametime );
#endif
for ( int tick = 0; tick < numticks; tick++ )
{
@ -3300,8 +3294,7 @@ void _Host_RunFrame (float time)
//---------------------------------------------------------
// CL_RunPrediction( PREDICTION_NORMAL );
_Host_RunFrame_Input( prevremainder, bFinalTick );
prevremainder = 0;
_Host_RunFrame_Input( host_frametime, bFinalTick );
//-------------------
//
@ -3436,14 +3429,14 @@ void _Host_RunFrame (float time)
g_ServerGlobalVariables.tickcount = sv.m_nTickCount;
// TODO_ENHANCED:
// Update the mouse as last so we can get the right viewangles while taking screenshot.
// Update the mouse as first so we can get the right viewangles while rendering.
// The mouse is always simulated for the current frame's time
// This makes updates smooth in every case
// continuous controllers affecting the view are also simulated this way
// but they have a cap applied by IN_SetSampleTime() so they are not also
// simulated during input gathering
g_ClientGlobalVariables.frametime = host_frametime;
CL_ExtraMouseUpdate( host_frametime );
CL_ExtraMovementUpdate( host_frametime );
// THREADED: Run Client
// -------------------
@ -3518,8 +3511,7 @@ void _Host_RunFrame (float time)
bool bFinalTick = tick==(serverticks-1) ? true : false;
// Run prediction before inputs if fps is lower than tickrate
// CL_RunPrediction( PREDICTION_NORMAL );
_Host_RunFrame_Input( prevremainder, bFinalTick );
prevremainder = 0;
_Host_RunFrame_Input( host_frametime, bFinalTick );
// process any asynchronous network traffic (TCP), set net_time
NET_RunFrame( Plat_FloatTime() );
}

View file

@ -630,7 +630,7 @@ public:
virtual void IN_SetSampleTime( float frametime );
// Create movement command
virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active );
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active );
virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active );
virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand );
virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot );
virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot );
@ -1419,7 +1419,7 @@ int CHLClient::IN_KeyEvent( int eventcode, ButtonCode_t keynum, const char *pszC
return input->KeyEvent( eventcode, keynum, pszCurrentBinding );
}
void CHLClient::ExtraMouseSample( int sequence_number, float frametime, bool active )
void CHLClient::ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active )
{
Assert( C_BaseEntity::IsAbsRecomputationsEnabled() );
Assert( C_BaseEntity::IsAbsQueriesValid() );
@ -1427,7 +1427,7 @@ void CHLClient::ExtraMouseSample( int sequence_number, float frametime, bool act
C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, false );
MDLCACHE_CRITICAL_SECTION();
input->ExtraMouseSample( sequence_number, frametime, active );
input->ExtraMovementSample( number_of_ticks_this_frame, current_command, frametime, active );
}
void CHLClient::IN_SetSampleTime( float frametime )

View file

@ -37,7 +37,7 @@ public:
virtual int GetButtonBits( int ) = 0;
// Create movement command
virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active ) = 0;
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active ) = 0;
virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active ) = 0;
virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand ) = 0;
virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot ) = 0;
virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot ) = 0;

View file

@ -1016,124 +1016,155 @@ if active == 1 then we are 1) not playing back demos ( where our commands are ig
================
*/
void CInput::ExtraMouseSample( int sequence_number, float frametime, bool active )
void CInput::ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active )
{
VPROF( "CInput::ExtraMouseSample" );
VPROF( "CInput::ExtraMovementSample" );
CUserCmd dummy;
CUserCmd* cmd;
static int old_sequence_number = 0;
// Be sure to call this only once per tick.
if ( old_sequence_number != sequence_number )
auto UpdateMovements = [&]()
{
cmd = &m_pCommands[sequence_number % MULTIPLAYER_BACKUP];
old_sequence_number = sequence_number;
cmd->Reset();
QAngle viewangles;
engine->GetViewAngles( viewangles );
QAngle originalViewangles = viewangles;
if ( active )
{
// Determine view angles
AdjustAngles ( frametime );
// Determine sideways movement
ComputeSideMove( cmd );
// Determine vertical movement
ComputeUpwardMove( cmd );
// Determine forward movement
ComputeForwardMove( cmd );
// Scale based on holding speed key or having too fast of a velocity based on client maximum
// speed.
ScaleMovements( cmd );
// Allow mice and other controllers to add their inputs
ControllerMove( frametime, cmd );
#ifdef SIXENSE
g_pSixenseInput->SixenseFrame( frametime, cmd );
if( g_pSixenseInput->IsEnabled() )
{
g_pSixenseInput->SetView( frametime, cmd );
}
#endif
}
else
{
// need to run and reset mouse input so that there is no view pop when unpausing
if ( !m_fCameraInterceptingMouse && m_fMouseActive )
{
float mx, my;
GetAccumulatedMouseDeltasAndResetAccumulators( &mx, &my );
ResetMouse();
}
}
// Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
engine->GetViewAngles( viewangles );
// Set button and flag bits, don't blow away state
#ifdef SIXENSE
if( g_pSixenseInput->IsEnabled() )
{
// Some buttons were set in SixenseUpdateKeys, so or in any real keypresses
cmd->buttons |= GetButtonBits( 0 );
}
else
{
cmd->buttons = GetButtonBits( 0 );
}
#else
cmd->buttons = GetButtonBits( 0 );
#endif
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
// Let the move manager override anything it wants to.
if ( g_pClientMode->CreateMove( frametime, cmd ) )
{
// Get current view angles after the client mode tweaks with it
engine->SetViewAngles( cmd->viewangles );
prediction->SetLocalViewAngles( cmd->viewangles );
}
// Let the headtracker override the view at the very end of the process so
// that vehicles and other stuff in g_pClientMode->CreateMove can override
// first
if ( active && UseVR() )
{
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if( pPlayer && !pPlayer->GetVehicle() )
{
QAngle curViewangles, newViewangles;
Vector curMotion, newMotion;
engine->GetViewAngles( curViewangles );
curMotion.Init (
cmd->forwardmove,
cmd->sidemove,
cmd->upmove );
g_ClientVirtualReality.OverridePlayerMotion ( frametime, originalViewangles, curViewangles, curMotion, &newViewangles, &newMotion );
engine->SetViewAngles( newViewangles );
cmd->forwardmove = newMotion[0];
cmd->sidemove = newMotion[1];
cmd->upmove = newMotion[2];
cmd->viewangles = newViewangles;
prediction->SetLocalViewAngles( cmd->viewangles );
}
}
};
// TODO_ENHANCED:
//
// Be sure to set the usercmd once
// because CreateMove won't be able to adjust angles anyway since accumulators will be reset to zero.
// How ever when fps is lower than tickrate, this function is actually never called into the engine
// In order to use interval per tick instead of frametime.
if ( number_of_ticks_this_frame > 0 )
{
// Sometimes, when fps is too low or framerate suddently dropped,
// We need to do this to prevent CreateMove using old commands.
// TODO_ENHANCED:
// We will need this eventually,
// but since accumulators gets reset to zero, its actually better to let it like this.
// Maybe if the accumulators aren't zeros per number_of_ticks_this_frame,
// we could get more accurate viewangles changes.
// frametime /= number_of_ticks_this_frame;
for (int i = 0; i < number_of_ticks_this_frame; i++)
{
cmd = &m_pCommands[(current_command + i) % MULTIPLAYER_BACKUP];
UpdateMovements();
}
}
else
{
cmd = &dummy;
}
cmd->Reset();
QAngle viewangles;
engine->GetViewAngles( viewangles );
QAngle originalViewangles = viewangles;
if ( active )
{
// Determine view angles
AdjustAngles ( frametime );
// Determine sideways movement
ComputeSideMove( cmd );
// Determine vertical movement
ComputeUpwardMove( cmd );
// Determine forward movement
ComputeForwardMove( cmd );
// Scale based on holding speed key or having too fast of a velocity based on client maximum
// speed.
ScaleMovements( cmd );
// Allow mice and other controllers to add their inputs
ControllerMove( frametime, cmd );
#ifdef SIXENSE
g_pSixenseInput->SixenseFrame( frametime, cmd );
if( g_pSixenseInput->IsEnabled() )
{
g_pSixenseInput->SetView( frametime, cmd );
}
#endif
}
// Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
engine->GetViewAngles( viewangles );
// Set button and flag bits, don't blow away state
#ifdef SIXENSE
if( g_pSixenseInput->IsEnabled() )
{
// Some buttons were set in SixenseUpdateKeys, so or in any real keypresses
cmd->buttons |= GetButtonBits( 0 );
}
else
{
cmd->buttons = GetButtonBits( 0 );
}
#else
cmd->buttons = GetButtonBits( 0 );
#endif
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
// Let the move manager override anything it wants to.
if ( g_pClientMode->CreateMove( frametime, cmd ) )
{
// Get current view angles after the client mode tweaks with it
engine->SetViewAngles( cmd->viewangles );
prediction->SetLocalViewAngles( cmd->viewangles );
}
// Let the headtracker override the view at the very end of the process so
// that vehicles and other stuff in g_pClientMode->CreateMove can override
// first
if ( active && UseVR() )
{
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if( pPlayer && !pPlayer->GetVehicle() )
{
QAngle curViewangles, newViewangles;
Vector curMotion, newMotion;
engine->GetViewAngles( curViewangles );
curMotion.Init (
cmd->forwardmove,
cmd->sidemove,
cmd->upmove );
g_ClientVirtualReality.OverridePlayerMotion ( frametime, originalViewangles, curViewangles, curMotion, &newViewangles, &newMotion );
engine->SetViewAngles( newViewangles );
cmd->forwardmove = newMotion[0];
cmd->sidemove = newMotion[1];
cmd->upmove = newMotion[2];
cmd->viewangles = newViewangles;
prediction->SetLocalViewAngles( cmd->viewangles );
}
UpdateMovements();
}
}
@ -1149,49 +1180,6 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
QAngle viewangles;
engine->GetViewAngles( viewangles );
QAngle originalViewangles = viewangles;
if ( active || sv_noclipduringpause.GetInt() )
{
// Determine view angles
AdjustAngles ( input_sample_frametime );
// Determine sideways movement
ComputeSideMove( cmd );
// Determine vertical movement
ComputeUpwardMove( cmd );
// Determine forward movement
ComputeForwardMove( cmd );
// Scale based on holding speed key or having too fast of a velocity based on client maximum
// speed.
ScaleMovements( cmd );
// Allow mice and other controllers to add their inputs
ControllerMove( input_sample_frametime, cmd );
#ifdef SIXENSE
g_pSixenseInput->SixenseFrame( input_sample_frametime, cmd );
if( g_pSixenseInput->IsEnabled() )
{
g_pSixenseInput->SetView( input_sample_frametime, cmd );
}
#endif
}
else
{
// need to run and reset mouse input so that there is no view pop when unpausing
if ( !m_fCameraInterceptingMouse && m_fMouseActive )
{
float mx, my;
GetAccumulatedMouseDeltasAndResetAccumulators( &mx, &my );
ResetMouse();
}
}
// Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
engine->GetViewAngles( viewangles );
// Latch and clear impulse
cmd->impulse = in_impulse;
@ -1242,17 +1230,6 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
}
}
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
// Let the move manager override anything it wants to.
if ( g_pClientMode->CreateMove( input_sample_frametime, cmd ) )
{
@ -1280,7 +1257,7 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
cmd->forwardmove,
cmd->sidemove,
cmd->upmove );
g_ClientVirtualReality.OverridePlayerMotion ( input_sample_frametime, originalViewangles, curViewangles, curMotion, &newViewangles, &newMotion );
g_ClientVirtualReality.OverridePlayerMotion ( input_sample_frametime, viewangles, curViewangles, curMotion, &newViewangles, &newMotion );
engine->SetViewAngles( newViewangles );
cmd->forwardmove = newMotion[0];
cmd->sidemove = newMotion[1];
@ -1296,6 +1273,17 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
}
}
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
m_flLastForwardMove = cmd->forwardmove;
cmd->random_seed = MD5_PseudoRandom( sequence_number ) & 0x7fffffff;

View file

@ -47,7 +47,7 @@ public:
virtual void Shutdown_All( void );
virtual int GetButtonBits( int );
virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active );
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active );
virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active );
virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand );
virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot );
virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot );

View file

@ -6,6 +6,8 @@
#include "cbase.h"
#include "view.h"
#include "cdll_client_int.h"
#include "gamerules.h"
#include "iviewrender.h"
#include "iviewrender_beams.h"
#include "view_shared.h"
@ -150,7 +152,14 @@ static void CalcDemoViewOverride( Vector &origin, QAngle &angles )
{
engine->SetViewAngles( s_DemoAngle );
input->ExtraMouseSample( 0, gpGlobals->absoluteframetime, true );
input->ExtraMovementSample( gpGlobals->tickcount, 0, gpGlobals->absoluteframetime, true );
static int iOldTickCount = 0;
if (iOldTickCount != gpGlobals->tickcount)
{
iOldTickCount = gpGlobals->tickcount;
}
engine->GetViewAngles( s_DemoAngle );

View file

@ -653,7 +653,7 @@ public:
// If the game is running faster than the tick_interval framerate, then we do extra mouse sampling to avoid jittery input
// This code path is much like the normal move creation code, except no move is created
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active ) = 0;
virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active ) = 0;
// Encode the delta (changes) between the CUserCmd in slot from vs the one in slot to. The game code will have
// matching logic to read the delta.

View file

@ -10633,7 +10633,7 @@ enum DISPID_SpeechWaveFormatEx
DISPID_SWFEAvgBytesPerSec = DISPID_SWFESamplesPerSec + 1,
DISPID_SWFEBlockAlign = DISPID_SWFEAvgBytesPerSec + 1,
DISPID_SWFEBitsPerSample = DISPID_SWFEBlockAlign + 1,
DISPID_SWFEExtraData = DISPID_SWFEBitsPerSample + 1
DISPID_SWFEExtraMovementSample + 1
} DISPID_SpeechWaveFormatEx;
typedef /* [hidden] */

View file

@ -50,7 +50,7 @@ inline float DecimateSamplePair(float input0, float input1, const float pCoeffic
return (input0 + input1);
}
static void ExtractFloatSamples( float *pOut, const short *pInputBuffer, int sampleCount, int stride )
static void ExtraMovementSamples( float *pOut, const short *pInputBuffer, int sampleCount, int stride )
{
for ( int i = 0; i < sampleCount; i++ )
{
@ -59,7 +59,7 @@ static void ExtractFloatSamples( float *pOut, const short *pInputBuffer, int sam
}
}
static void ExtractShortSamples( short *pOut, const float *pInputBuffer, float scale, int sampleCount, int stride )
static void ExtraMovementSamples( short *pOut, const float *pInputBuffer, float scale, int sampleCount, int stride )
{
for ( int i = 0; i < sampleCount; i++ )
{
@ -96,9 +96,9 @@ void DecimateSampleRateBy2_16( const short *pInputBuffer, short *pOutputBuffer,
float *pTmpBuf = new float[sampleCount];
for ( int i = 0; i < channelCount; i++ )
{
ExtractFloatSamples( pTmpBuf, pInputBuffer+i, sampleCount, channelCount );
ExtraMovementSamples( pTmpBuf, pInputBuffer+i, sampleCount, channelCount );
DecimateSampleBlock( pTmpBuf, sampleCount );
ExtractShortSamples( pOutputBuffer+i, pTmpBuf, 0.5f * 32768.0f, sampleCount>>1, channelCount );
ExtraMovementSamples( pOutputBuffer+i, pTmpBuf, 0.5f * 32768.0f, sampleCount>>1, channelCount );
}
delete [] pTmpBuf;
}