16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 23:19:19 +02:00

build 171214. partial control variable normalization for combined engine sounds, conditional cab soundproofing

This commit is contained in:
tmj-fstate
2017-12-15 02:15:44 +01:00
parent b70c265a1e
commit c22390b4ff
8 changed files with 108 additions and 55 deletions

View File

@@ -3622,7 +3622,35 @@ void TDynamicObject::RenderSounds() {
|| ( MoverParameters->EngineType == Dumb ) ) { || ( MoverParameters->EngineType == Dumb ) ) {
// frequency calculation // frequency calculation
frequency = rsSilnik.m_frequencyfactor * std::fabs( MoverParameters->enrot ) + rsSilnik.m_frequencyoffset; auto normalizer { 1.f };
// for combined sounds normalize frequency to 0-1 range
switch( MoverParameters->EngineType ) {
case DieselElectric: {
if( true == sConverter.is_combined() ) {
normalizer = MoverParameters->DElist[ MoverParameters->MainCtrlPosNo ].RPM / 60;
}
break;
}
case DieselEngine: {
if( true == rsSilnik.is_combined() ) {
normalizer = MoverParameters->dizel_nmax;
}
break;
}
case ElectricInductionMotor: {
if( true == rsSilnik.is_combined() ) {
// TODO: implement normalization/a way to calculate max expected engine rpm
}
break;
}
default: {
if( true == rsSilnik.is_combined() ) {
normalizer = MoverParameters->nmax;
}
break;
}
}
frequency = rsSilnik.m_frequencyfactor * std::abs( MoverParameters->enrot ) / std::max( 1.f, normalizer ) + rsSilnik.m_frequencyoffset;
if( MoverParameters->EngineType == Dumb ) { if( MoverParameters->EngineType == Dumb ) {
frequency -= 0.2 * MoverParameters->EnginePower / ( 1 + MoverParameters->Power * 1000 ); frequency -= 0.2 * MoverParameters->EnginePower / ( 1 + MoverParameters->Power * 1000 );
} }

View File

@@ -40,6 +40,7 @@ float Global::FieldOfView = 45.0f;
GLFWwindow *Global::window; GLFWwindow *Global::window;
bool Global::shiftState; bool Global::shiftState;
bool Global::ctrlState; bool Global::ctrlState;
bool Global::CabWindowOpen { false };
int Global::iCameraLast = -1; int Global::iCameraLast = -1;
std::string Global::asVersion = "couldn't retrieve version string"; std::string Global::asVersion = "couldn't retrieve version string";
bool Global::ControlPicking = false; // indicates controls pick mode is enabled bool Global::ControlPicking = false; // indicates controls pick mode is enabled

View File

@@ -235,6 +235,7 @@ public:
static GLFWwindow *window; static GLFWwindow *window;
static bool shiftState; //m7todo: brzydko static bool shiftState; //m7todo: brzydko
static bool ctrlState; static bool ctrlState;
static bool CabWindowOpen; // controls sound attenuation between cab and outside
static int iCameraLast; static int iCameraLast;
static std::string asVersion; // z opisem static std::string asVersion; // z opisem
static bool ControlPicking; // indicates controls pick mode is active static bool ControlPicking; // indicates controls pick mode is active

View File

@@ -4746,21 +4746,27 @@ double TMoverParameters::TractionForce(double dt)
eimv[eimv_Uzsmax] = Min0R(Voltage - eimc[eimc_f_DU], tmp); eimv[eimv_Uzsmax] = Min0R(Voltage - eimc[eimc_f_DU], tmp);
eimv[eimv_fkr] = eimv[eimv_Uzsmax] / eimc[eimc_f_cfu]; eimv[eimv_fkr] = eimv[eimv_Uzsmax] / eimc[eimc_f_cfu];
if ((dizel_fill < 0)) if( ( dizel_fill < 0 ) ) {
eimv[ eimv_Pmax ] = eimc[ eimc_p_Ph ]; eimv[ eimv_Pmax ] = eimc[ eimc_p_Ph ];
else }
else {
eimv[ eimv_Pmax ] = eimv[ eimv_Pmax ] =
Min0R(eimc[eimc_p_Pmax], std::min(
0.001 * Voltage * (eimc[eimc_p_Imax] - eimc[eimc_f_I0]) * Pirazy2 * eimc[ eimc_p_Pmax ],
eimc[eimc_s_cim] / eimc[eimc_s_p] / eimc[eimc_s_cfu]); 0.001 * Voltage * ( eimc[ eimc_p_Imax ] - eimc[ eimc_f_I0 ] ) * Pirazy2 * eimc[ eimc_s_cim ] / eimc[ eimc_s_p ] / eimc[ eimc_s_cfu ] );
}
eimv[ eimv_FMAXMAX ] = eimv[ eimv_FMAXMAX ] =
0.001 * square(Min0R(eimv[eimv_fkr] / Max0R(abs(enrot) * eimc[eimc_s_p] + 0.001
eimc[eimc_s_dfmax] * eimv[eimv_ks], * square(
eimc[eimc_s_dfmax]), std::min(
1) * 1.0,
eimc[eimc_f_cfu] / eimc[eimc_s_cfu]) * eimv[ eimv_fkr ] / std::max(
(eimc[eimc_s_dfmax] * eimc[eimc_s_dfic] * eimc[eimc_s_cim]) * abs( enrot ) * eimc[ eimc_s_p ] + eimc[ eimc_s_dfmax ] * eimv[ eimv_ks ],
Transmision.Ratio * NPoweredAxles * 2.0 / WheelDiameter; eimc[ eimc_s_dfmax ] ) )
* eimc[ eimc_f_cfu ]
/ eimc[ eimc_s_cfu ] )
* ( eimc[ eimc_s_dfmax ] * eimc[ eimc_s_dfic ] * eimc[ eimc_s_cim ] )
* Transmision.Ratio * NPoweredAxles * 2.0 / WheelDiameter;
if ((dizel_fill < 0)) if ((dizel_fill < 0))
{ {
eimv[eimv_Fful] = std::min(eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001), eimv[eimv_Fful] = std::min(eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001),
@@ -4835,10 +4841,11 @@ double TMoverParameters::TractionForce(double dt)
i = 0; i = 0;
while ((i < RlistSize - 1) && (DElist[i + 1].RPM < abs(tmpV))) while ((i < RlistSize - 1) && (DElist[i + 1].RPM < abs(tmpV)))
i++; i++;
RventRot = (abs(tmpV) - DElist[i].RPM) / RventRot =
(DElist[i + 1].RPM - DElist[i].RPM) * ( std::abs( tmpV ) - DElist[ i ].RPM )
(DElist[i + 1].GenPower - DElist[i].GenPower) + / std::max( 1.0, ( DElist[ i + 1 ].RPM - DElist[ i ].RPM ) )
DElist[i].GenPower; * ( DElist[ i + 1 ].GenPower - DElist[ i ].GenPower )
+ DElist[ i ].GenPower;
} }
else else
RventRot = 0; RventRot = 0;

View File

@@ -1116,6 +1116,8 @@ TWorld::Update_Camera( double const Deltatime ) {
if( DebugCameraFlag ) { DebugCamera.Update(); } if( DebugCameraFlag ) { DebugCamera.Update(); }
else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami
// reset window state, it'll be set again if applicable in a check below
Global::CabWindowOpen = false;
if( ( Train != nullptr ) if( ( Train != nullptr )
&& ( Camera.Type == tp_Follow ) && ( Camera.Type == tp_Follow )
@@ -1128,6 +1130,8 @@ TWorld::Update_Camera( double const Deltatime ) {
&& ( (Console::Pressed( Global::Keys[ k_MechLeft ]) && ( (Console::Pressed( Global::Keys[ k_MechLeft ])
|| (Console::Pressed( Global::Keys[ k_MechRight ]))))) { || (Console::Pressed( Global::Keys[ k_MechRight ]))))) {
// jeśli lusterko lewe albo prawe (bez rzucania na razie) // jeśli lusterko lewe albo prawe (bez rzucania na razie)
Global::CabWindowOpen = true;
bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] ); bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] );
// Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu // Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu
Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka

View File

@@ -331,7 +331,7 @@ void
sound_source::play_combined() { sound_source::play_combined() {
// combined sound consists of table od samples, each sample associated with certain range of values of controlling variable // combined sound consists of table od samples, each sample associated with certain range of values of controlling variable
// current value of the controlling variable is passed to the source with pitch() call // current value of the controlling variable is passed to the source with pitch() call
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 100.f ) }; auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 99.f ) };
for( std::uint32_t idx = 0; idx < m_soundchunks.size(); ++idx ) { for( std::uint32_t idx = 0; idx < m_soundchunks.size(); ++idx ) {
auto const &soundchunk { m_soundchunks[ idx ] }; auto const &soundchunk { m_soundchunks[ idx ] };
@@ -520,7 +520,7 @@ sound_source::update_combined( audio::openal_source &Source ) {
if( ( soundhandle & sound_id::chunk ) != 0 ) { if( ( soundhandle & sound_id::chunk ) != 0 ) {
// for sound chunks, test whether the chunk should still be active given current value of the controlling variable // for sound chunks, test whether the chunk should still be active given current value of the controlling variable
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 100.f ) }; auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 99.f ) };
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] }; auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
if( ( soundpoint < soundchunk.second.fadein ) if( ( soundpoint < soundchunk.second.fadein )
|| ( soundpoint > soundchunk.second.fadeout ) ) { || ( soundpoint > soundchunk.second.fadeout ) ) {
@@ -598,7 +598,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
return; return;
} }
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 100.f ) }; auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 99.f ) };
// NOTE: direct access to implementation details ahead, kinda fugly // NOTE: direct access to implementation details ahead, kinda fugly
auto const chunkindex { Chunk ^ sound_id::chunk }; auto const chunkindex { Chunk ^ sound_id::chunk };
@@ -607,6 +607,8 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
// relative pitch adjustment // relative pitch adjustment
// pitch of each chunk is modified based on ratio of the chunk's pitch to that of its neighbour // pitch of each chunk is modified based on ratio of the chunk's pitch to that of its neighbour
if( soundpoint < chunkdata.threshold ) { if( soundpoint < chunkdata.threshold ) {
if( chunkindex > 0 ) {
// interpolate between the pitch of previous chunk and this chunk's base pitch, // interpolate between the pitch of previous chunk and this chunk's base pitch,
// based on how far the current soundpoint is in the range of previous chunk // based on how far the current soundpoint is in the range of previous chunk
auto const &previouschunkdata{ m_soundchunks[ chunkindex - 1 ].second }; auto const &previouschunkdata{ m_soundchunks[ chunkindex - 1 ].second };
@@ -618,6 +620,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
( soundpoint - previouschunkdata.threshold ) / ( chunkdata.threshold - previouschunkdata.threshold ), ( soundpoint - previouschunkdata.threshold ) / ( chunkdata.threshold - previouschunkdata.threshold ),
0.f, 1.f ) ); 0.f, 1.f ) );
} }
}
else { else {
if( chunkindex < ( m_soundchunks.size() - 1 ) ) { if( chunkindex < ( m_soundchunks.size() - 1 ) ) {
@@ -721,6 +724,13 @@ sound_source::is_playing( bool const Includesoundends ) const {
return isplaying; return isplaying;
} }
// returns true if the source uses sample table
bool
sound_source::is_combined() const {
return ( ( !m_soundchunks.empty() ) && ( sound( sound_id::main ).buffer == null_handle ) );
}
// returns location of the sound source in simulation region space // returns location of the sound source in simulation region space
glm::dvec3 const glm::dvec3 const
sound_source::location() const { sound_source::location() const {
@@ -756,12 +766,11 @@ float const EU07_SOUNDPROOFING_NONE { 1.f };
bool bool
sound_source::update_soundproofing() { sound_source::update_soundproofing() {
// NOTE, HACK: current cab id can vary from -1 to +1, and we use another higher priority value for open cab window
// NOTE, HACK: current cab id can vary from -1 to +1 // we use this as modifier to force re-calculations when moving between compartments or changing window state
// we use this as modifier to force re-calculations when moving between compartments
int const activecab = ( int const activecab = (
FreeFlyModeFlag ? Global::CabWindowOpen ? 2 :
0 : FreeFlyModeFlag ? 0 :
( Global::pWorld->train() ? ( Global::pWorld->train() ?
Global::pWorld->train()->Dynamic()->MoverParameters->ActiveCab : Global::pWorld->train()->Dynamic()->MoverParameters->ActiveCab :
0 ) ); 0 ) );
@@ -784,15 +793,15 @@ sound_source::update_soundproofing() {
} }
case sound_placement::external: { case sound_placement::external: {
m_properties.soundproofing = ( m_properties.soundproofing = (
soundproofingstamp == 0 ? ( ( soundproofingstamp == 0 ) || ( true == Global::CabWindowOpen ) ) ?
EU07_SOUNDPROOFING_NONE : // listener outside EU07_SOUNDPROOFING_NONE : // listener outside or has a window open
EU07_SOUNDPROOFING_STRONG ); // listener in a vehicle EU07_SOUNDPROOFING_STRONG ); // listener in a vehicle with windows shut
break; break;
} }
case sound_placement::internal: { case sound_placement::internal: {
m_properties.soundproofing = ( m_properties.soundproofing = (
soundproofingstamp == 0 ? soundproofingstamp == 0 ?
EU07_SOUNDPROOFING_STRONG : // listener outside EU07_SOUNDPROOFING_STRONG : // listener outside HACK: won't be true if active vehicle has open window
( Global::pWorld->train()->Dynamic() != m_owner ? ( Global::pWorld->train()->Dynamic() != m_owner ?
EU07_SOUNDPROOFING_STRONG : // in another vehicle EU07_SOUNDPROOFING_STRONG : // in another vehicle
( activecab == 0 ? ( activecab == 0 ?
@@ -802,8 +811,8 @@ sound_source::update_soundproofing() {
} }
case sound_placement::engine: { case sound_placement::engine: {
m_properties.soundproofing = ( m_properties.soundproofing = (
soundproofingstamp == 0 ? ( ( soundproofingstamp == 0 ) || ( true == Global::CabWindowOpen ) ) ?
EU07_SOUNDPROOFING_SOME : // listener outside EU07_SOUNDPROOFING_SOME : // listener outside or has a window open
( Global::pWorld->train()->Dynamic() != m_owner ? ( Global::pWorld->train()->Dynamic() != m_owner ?
EU07_SOUNDPROOFING_STRONG : // in another vehicle EU07_SOUNDPROOFING_STRONG : // in another vehicle
( activecab == 0 ? ( activecab == 0 ?

View File

@@ -97,6 +97,9 @@ public:
// returns true if the source is emitting any sound; by default doesn't take into account optional ending soudnds // returns true if the source is emitting any sound; by default doesn't take into account optional ending soudnds
bool bool
is_playing( bool const Includesoundends = false ) const; is_playing( bool const Includesoundends = false ) const;
// returns true if the source uses sample table
bool
is_combined() const;
// returns location of the sound source in simulation region space // returns location of the sound source in simulation region space
glm::dvec3 const glm::dvec3 const
location() const; location() const;

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 1205 #define VERSION_MINOR 1214
#define VERSION_REVISION 0 #define VERSION_REVISION 0