mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-20 15:59:18 +02:00
build 171204. separate vehicle movement noise for external and internal view, flexible parsing of wheel_clatter parameter, minor tweaks to air leak and wheel clatter playback
This commit is contained in:
132
DynObj.cpp
132
DynObj.cpp
@@ -559,7 +559,7 @@ TDynamicObject::toggle_lights() {
|
||||
( compartmentname.find( "compartment" ) != std::string::npos )
|
||||
|| ( compartmentname.find( "przedzial" ) != std::string::npos ) ) {
|
||||
// compartments are lit with 75% probability
|
||||
sectionlight.level = ( Random() < 0.75 ? 0.75f : 0.05f );
|
||||
sectionlight.level = ( Random() < 0.75 ? 0.75f : 0.15f );
|
||||
}
|
||||
}
|
||||
SectionLightsActive = true;
|
||||
@@ -1611,9 +1611,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance )
|
||||
}
|
||||
//----------ABu: koniec skanowania pojazdow
|
||||
|
||||
TDynamicObject::TDynamicObject() :
|
||||
rsStukot( MaxAxles, sound_source( sound_placement::external ) )
|
||||
{
|
||||
TDynamicObject::TDynamicObject() {
|
||||
modelShake = vector3(0, 0, 0);
|
||||
fTrackBlock = 10000.0; // brak przeszkody na drodze
|
||||
btnOn = false;
|
||||
@@ -1634,12 +1632,14 @@ TDynamicObject::TDynamicObject() :
|
||||
bEnabled = true;
|
||||
MyTrack = NULL;
|
||||
// McZapkie-260202
|
||||
/*
|
||||
dRailLength = 25.0;
|
||||
for (int i = 0; i < MaxAxles; i++)
|
||||
dRailPosition[i] = 0.0;
|
||||
for (int i = 0; i < MaxAxles; i++)
|
||||
dWheelsPosition[i] = 0.0; // będzie wczytane z MMD
|
||||
iAxles = 0;
|
||||
*/
|
||||
dWheelAngle[0] = 0.0;
|
||||
dWheelAngle[1] = 0.0;
|
||||
dWheelAngle[2] = 0.0;
|
||||
@@ -1985,8 +1985,9 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
create_controller( DriverType, !TrainName.empty() );
|
||||
|
||||
// McZapkie-250202
|
||||
/*
|
||||
iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi
|
||||
rsStukot.resize( iAxles, sound_source( sound_placement::external ) );
|
||||
*/
|
||||
// wczytywanie z pliku nazwatypu.mmd, w tym model
|
||||
LoadMMediaFile(asBaseDir, Type_Name, asReplacableSkin);
|
||||
// McZapkie-100402: wyszukiwanie submodeli sprzegów
|
||||
@@ -2093,12 +2094,12 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
smBuforPrawy[ i ]->WillBeAnimated();
|
||||
}
|
||||
}
|
||||
for( int i = 0; i < iAxles; i++ ) {
|
||||
for( auto &axle : m_axlesounds ) {
|
||||
// wyszukiwanie osi (0 jest na końcu, dlatego dodajemy długość?)
|
||||
dRailPosition[ i ] = (
|
||||
axle.distance = (
|
||||
Reversed ?
|
||||
-dWheelsPosition[ i ] :
|
||||
( dWheelsPosition[ i ] + MoverParameters->Dim.L ) ) + fDist;
|
||||
-axle.offset :
|
||||
( axle.offset + MoverParameters->Dim.L ) ) + fDist;
|
||||
}
|
||||
// McZapkie-250202 end.
|
||||
Track->AddDynamicObject(this); // wstawiamy do toru na pozycję 0, a potem przesuniemy
|
||||
@@ -3063,12 +3064,12 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
|
||||
if( MyTrack->fSoundDistance != dRailLength ) {
|
||||
dRailLength = MyTrack->fSoundDistance;
|
||||
for( int i = 0; i < iAxles; ++i ) {
|
||||
dRailPosition[ i ] = dWheelsPosition[ i ] + MoverParameters->Dim.L;
|
||||
for( auto &axle : m_axlesounds ) {
|
||||
axle.distance = axle.offset + MoverParameters->Dim.L;
|
||||
}
|
||||
}
|
||||
if( dRailLength != -1 ) {
|
||||
if( std::abs( MoverParameters->V ) > 0 ) {
|
||||
if( MoverParameters->Vel > 0 ) {
|
||||
|
||||
double volume = ( 20.0 + MyTrack->iDamageFlag ) / 21;
|
||||
switch( MyTrack->eEnvironment ) {
|
||||
@@ -3085,9 +3086,10 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < iAxles; ++i ) {
|
||||
dRailPosition[ i ] -= dDOMoveLen * Sign( dDOMoveLen );
|
||||
if( dRailPosition[ i ] < 0 ) {
|
||||
for( auto &axle : m_axlesounds ) {
|
||||
axle.distance -= dDOMoveLen * Sign( dDOMoveLen );
|
||||
if( axle.distance < 0 ) {
|
||||
axle.distance += dRailLength;
|
||||
/*
|
||||
// McZapkie-040302
|
||||
if( i == iAxles - 1 ) {
|
||||
@@ -3101,8 +3103,9 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
MoverParameters->AccV -= 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax );
|
||||
}
|
||||
*/
|
||||
rsStukot[ i ].gain( volume ).play();
|
||||
dRailPosition[ i ] += dRailLength;
|
||||
if( MoverParameters->Vel > 2.5 ) {
|
||||
axle.clatter.gain( volume ).play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3602,10 +3605,10 @@ void TDynamicObject::RenderSounds() {
|
||||
|
||||
// McZapkie-010302: ulepszony dzwiek silnika
|
||||
double frequency { 1.0 };
|
||||
double volume { 1.0 };
|
||||
double volume { 0.0 };
|
||||
double const dt { Timer::GetDeltaRenderTime() };
|
||||
|
||||
if( dt == 0.0 ) { return; }
|
||||
if( Global::iPause != 0 ) { return; }
|
||||
|
||||
// engine sounds
|
||||
if( MoverParameters->Power > 0 ) {
|
||||
@@ -3652,6 +3655,7 @@ void TDynamicObject::RenderSounds() {
|
||||
+ rsSilnik.m_amplitudeoffset;
|
||||
break;
|
||||
}
|
||||
// NOTE: default case also covers electric motors
|
||||
default: {
|
||||
volume =
|
||||
rsSilnik.m_amplitudefactor * ( MoverParameters->EnginePower / 1000 + std::fabs( MoverParameters->enrot ) * 60.0 )
|
||||
@@ -3950,13 +3954,14 @@ void TDynamicObject::RenderSounds() {
|
||||
if( m_lastbrakepressure != -1.f ) {
|
||||
// calculate rate of pressure drop in brake cylinder, once it's been initialized
|
||||
auto const brakepressuredifference { m_lastbrakepressure - MoverParameters->BrakePress };
|
||||
m_brakepressurechange = interpolate<float>( m_brakepressurechange, 10 * ( brakepressuredifference / dt ), 0.1f );
|
||||
m_brakepressurechange = interpolate<float>( m_brakepressurechange, brakepressuredifference / dt, 0.005f );
|
||||
}
|
||||
m_lastbrakepressure = MoverParameters->BrakePress;
|
||||
if( m_brakepressurechange > 0.05f ) {
|
||||
// NOTE: can't use the leak rate directly due to irregular results produced by some brake type implementations
|
||||
// ensure some basic level of volume and scale it up depending on pressure in the cylinder; scale this by the leak rate
|
||||
volume = 20 * m_brakepressurechange * ( 0.25 + 0.75 * ( std::max( MoverParameters->BrakePress, 0.0 ) / MoverParameters->MaxBrakePress[ 3 ] ) );
|
||||
if( volume > 0.075f ) {
|
||||
rsUnbrake
|
||||
.gain( static_cast<float>( 1.25 * std::max( MoverParameters->BrakePress, 0.0 ) / MoverParameters->MaxBrakePress[ 3 ] ) )
|
||||
.gain( volume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
@@ -4009,7 +4014,7 @@ void TDynamicObject::RenderSounds() {
|
||||
&& ( GetVelocity() > 0.05 ) ) {
|
||||
|
||||
rsBrake
|
||||
.pitch( clamp( rsBrake.m_frequencyfactor * GetVelocity() + rsBrake.m_frequencyoffset, 0.5, 1.15 ) ) // arbitrary limits
|
||||
.pitch( rsBrake.m_frequencyfactor * GetVelocity() + rsBrake.m_frequencyoffset )
|
||||
.gain( rsBrake.m_amplitudefactor * std::sqrt( ( GetVelocity() * MoverParameters->UnitBrakeForce ) ) + rsBrake.m_amplitudeoffset )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
@@ -4115,8 +4120,8 @@ void TDynamicObject::RenderSounds() {
|
||||
// szum w czasie jazdy
|
||||
if( GetVelocity() > 0.5 ) {
|
||||
|
||||
volume = rsRunningNoise.m_amplitudefactor * MoverParameters->Vel + rsRunningNoise.m_amplitudeoffset;
|
||||
frequency = rsRunningNoise.m_frequencyfactor * MoverParameters->Vel + rsRunningNoise.m_frequencyoffset;
|
||||
volume = rsOuterNoise.m_amplitudefactor * MoverParameters->Vel + rsOuterNoise.m_amplitudeoffset;
|
||||
frequency = rsOuterNoise.m_frequencyfactor * MoverParameters->Vel + rsOuterNoise.m_frequencyoffset;
|
||||
|
||||
if( false == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) {
|
||||
// McZpakie-221103: halas zalezny od kola
|
||||
@@ -4174,13 +4179,13 @@ void TDynamicObject::RenderSounds() {
|
||||
clamp(
|
||||
MoverParameters->Vel / 60.0,
|
||||
0.0, 1.0 ) );
|
||||
rsRunningNoise
|
||||
rsOuterNoise
|
||||
.pitch( clamp( frequency, 0.5, 1.15 ) ) // arbitrary limits to prevent the pitch going out of whack
|
||||
.gain( volume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
rsRunningNoise.stop();
|
||||
rsOuterNoise.stop();
|
||||
}
|
||||
|
||||
// youBy: dzwiek ostrych lukow i ciasnych zwrotek
|
||||
@@ -4200,7 +4205,7 @@ void TDynamicObject::RenderSounds() {
|
||||
}
|
||||
if( volume > 0.05 ) {
|
||||
rscurve
|
||||
.gain( 2.0 * volume )
|
||||
.gain( 2.5 * volume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
@@ -4274,17 +4279,17 @@ void TDynamicObject::RenderSounds() {
|
||||
// TODO: dedicated sound, played alongside regular noise
|
||||
if( true == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) {
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
if( rsRunningNoise.AM != 0 ) {
|
||||
rsRunningNoise.Stop();
|
||||
float am = rsRunningNoise.AM;
|
||||
float fa = rsRunningNoise.FA;
|
||||
float fm = rsRunningNoise.FM;
|
||||
rsRunningNoise.Init( "lomotpodkucia.wav", -1, 0, 0, 0, true ); // MC: zmiana szumu na lomot
|
||||
if( rsRunningNoise.AM == 1 )
|
||||
rsRunningNoise.AM = am;
|
||||
rsRunningNoise.AA = 0.7;
|
||||
rsRunningNoise.FA = fa;
|
||||
rsRunningNoise.FM = fm;
|
||||
if( rsOuterNoise.AM != 0 ) {
|
||||
rsOuterNoise.Stop();
|
||||
float am = rsOuterNoise.AM;
|
||||
float fa = rsOuterNoise.FA;
|
||||
float fm = rsOuterNoise.FM;
|
||||
rsOuterNoise.Init( "lomotpodkucia.wav", -1, 0, 0, 0, true ); // MC: zmiana szumu na lomot
|
||||
if( rsOuterNoise.AM == 1 )
|
||||
rsOuterNoise.AM = am;
|
||||
rsOuterNoise.AA = 0.7;
|
||||
rsOuterNoise.FA = fa;
|
||||
rsOuterNoise.FM = fm;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
@@ -5004,21 +5009,23 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
// polozenia osi w/m srodka pojazdu
|
||||
parser.getTokens( 1, false );
|
||||
parser >> dSDist;
|
||||
for( int i = 0; i < iAxles; ++i ) {
|
||||
parser.getTokens( 1, false );
|
||||
parser >> dWheelsPosition[ i ];
|
||||
parser.getTokens();
|
||||
parser >> token;
|
||||
if( token != "end" ) {
|
||||
rsStukot[ i ].deserialize( token + " " + std::to_string( dSDist ), sound_type::single, sound_parameters::range );
|
||||
rsStukot[ i ].owner( this );
|
||||
rsStukot[ i ].offset( { 0, 0, -dWheelsPosition[ i ] } );
|
||||
}
|
||||
while( ( ( token = parser.getToken<std::string>() ) != "" )
|
||||
&& ( token != "end" ) ) {
|
||||
// add another axle entry to the list
|
||||
axle_sounds axle {
|
||||
0,
|
||||
std::atof( token.c_str() ),
|
||||
{ sound_placement::external, static_cast<float>( dSDist ) } };
|
||||
axle.clatter.deserialize( parser, sound_type::single );
|
||||
axle.clatter.owner( this );
|
||||
axle.clatter.offset( { 0, 0, -axle.offset } );
|
||||
m_axlesounds.emplace_back( axle );
|
||||
}
|
||||
if( token != "end" ) {
|
||||
// TODO: check if this if() and/or retrieval makes sense here
|
||||
parser.getTokens( 1, false ); parser >> token;
|
||||
}
|
||||
// arrange the axles in case they're listed out of order
|
||||
std::sort(
|
||||
std::begin( m_axlesounds ), std::end( m_axlesounds ),
|
||||
[]( axle_sounds const &Left, axle_sounds const &Right ) {
|
||||
return ( Left.offset < Right.offset ); } );
|
||||
}
|
||||
|
||||
else if( ( token == "engine:" )
|
||||
@@ -5193,6 +5200,15 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
sReleaser.owner( this );
|
||||
}
|
||||
|
||||
else if( token == "outernoise:" ) {
|
||||
// szum podczas jazdy:
|
||||
rsOuterNoise.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency );
|
||||
rsOuterNoise.owner( this );
|
||||
|
||||
rsOuterNoise.m_amplitudefactor /= ( 1 + MoverParameters->Vmax );
|
||||
rsOuterNoise.m_frequencyfactor /= ( 1 + MoverParameters->Vmax );
|
||||
}
|
||||
|
||||
} while( ( token != "" )
|
||||
&& ( token != "endsounds" ) );
|
||||
|
||||
@@ -5301,14 +5317,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
couplersounds.dsbBufferClamp = bufferclash;
|
||||
}
|
||||
}
|
||||
else if( token == "runningnoise:" ) {
|
||||
// szum podczas jazdy:
|
||||
rsRunningNoise.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency );
|
||||
rsRunningNoise.owner( this );
|
||||
|
||||
rsRunningNoise.m_amplitudefactor /= ( 1 + MoverParameters->Vmax );
|
||||
rsRunningNoise.m_frequencyfactor /= ( 1 + MoverParameters->Vmax );
|
||||
}
|
||||
|
||||
} while( token != "" );
|
||||
|
||||
|
||||
21
DynObj.h
21
DynObj.h
@@ -273,8 +273,14 @@ private:
|
||||
};
|
||||
|
||||
struct door_sounds {
|
||||
sound_source rsDoorOpen{ sound_placement::general }; // Ra: przeniesione z kabiny
|
||||
sound_source rsDoorClose{ sound_placement::general };
|
||||
sound_source rsDoorOpen{ sound_placement::general, 25.f }; // Ra: przeniesione z kabiny
|
||||
sound_source rsDoorClose{ sound_placement::general, 25.f };
|
||||
};
|
||||
|
||||
struct axle_sounds {
|
||||
double distance; // distance to rail joint
|
||||
double offset; // axle offset from centre of the vehicle
|
||||
sound_source clatter; // clatter emitter
|
||||
};
|
||||
|
||||
// methods
|
||||
@@ -318,16 +324,19 @@ private:
|
||||
TButton btHeadSignals23;
|
||||
TButton btMechanik1;
|
||||
TButton btMechanik2;
|
||||
double enginevolume; // MC: pomocnicze zeby gladziej silnik buczal
|
||||
|
||||
int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles
|
||||
double dRailLength;
|
||||
// int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles
|
||||
double dRailLength { 0.0 };
|
||||
std::vector<axle_sounds> m_axlesounds;
|
||||
/*
|
||||
double dRailPosition[MaxAxles]; // licznik pozycji osi w/m szyny
|
||||
double dWheelsPosition[MaxAxles]; // pozycja osi w/m srodka pojazdu
|
||||
std::vector<sound_source> rsStukot; // dzwieki poszczegolnych osi //McZapkie-270202
|
||||
*/
|
||||
// engine sounds
|
||||
sound_source dsbDieselIgnition { sound_placement::engine }; // moved from cab
|
||||
sound_source rsSilnik { sound_placement::engine };
|
||||
double enginevolume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
|
||||
sound_source dsbRelay { sound_placement::engine };
|
||||
sound_source dsbWejscie_na_bezoporow { sound_placement::engine }; // moved from cab
|
||||
sound_source dsbWejscie_na_drugi_uklad { sound_placement::engine }; // moved from cab
|
||||
@@ -357,7 +366,7 @@ private:
|
||||
sound_source sDepartureSignal { sound_placement::general };
|
||||
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source rsRunningNoise { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source rsOuterNoise { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
|
||||
|
||||
double eng_vol_act;
|
||||
|
||||
83
Train.cpp
83
Train.cpp
@@ -5136,6 +5136,28 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
double volume { 0.0 };
|
||||
double const brakevolumescale { 0.5 };
|
||||
|
||||
// Winger-160404 - syczenie pomocniczego (luzowanie)
|
||||
if( m_lastlocalbrakepressure != -1.f ) {
|
||||
// calculate rate of pressure drop in local brake cylinder, once it's been initialized
|
||||
auto const brakepressuredifference{ m_lastlocalbrakepressure - mvOccupied->LocBrakePress };
|
||||
m_localbrakepressurechange = interpolate<float>( m_localbrakepressurechange, 10 * ( brakepressuredifference / Deltatime ), 0.1f );
|
||||
}
|
||||
m_lastlocalbrakepressure = mvOccupied->LocBrakePress;
|
||||
if( ( m_localbrakepressurechange > 0.05f )
|
||||
&& ( mvOccupied->LocBrakePress > mvOccupied->BrakePress - 0.05 ) ) {
|
||||
rsSBHiss
|
||||
.gain( clamp( 0.05 * m_localbrakepressurechange, 0.0, 1.5 ) )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
// don't stop the sound too abruptly
|
||||
volume = std::max( 0.0, rsSBHiss.gain() - 0.1 * Deltatime );
|
||||
rsSBHiss.gain( volume );
|
||||
if( volume < 0.05 ) {
|
||||
rsSBHiss.stop();
|
||||
}
|
||||
}
|
||||
|
||||
// McZapkie-280302 - syczenie
|
||||
// TODO: softer volume reduction than plain abrupt stop, perhaps as reusable wrapper?
|
||||
if( ( mvOccupied->BrakeHandle == FV4a )
|
||||
@@ -5231,28 +5253,6 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
}
|
||||
} // koniec nie FV4a
|
||||
|
||||
// Winger-160404 - syczenie pomocniczego (luzowanie)
|
||||
if( m_lastlocalbrakepressure != -1.f ) {
|
||||
// calculate rate of pressure drop in local brake cylinder, once it's been initialized
|
||||
auto const brakepressuredifference { m_lastlocalbrakepressure - mvOccupied->LocBrakePress };
|
||||
m_localbrakepressurechange = interpolate<float>( m_localbrakepressurechange, 10 * ( brakepressuredifference / Deltatime ), 0.1f );
|
||||
}
|
||||
m_lastlocalbrakepressure = mvOccupied->LocBrakePress;
|
||||
if( ( m_localbrakepressurechange > 0.05f )
|
||||
&& ( mvOccupied->LocBrakePress > mvOccupied->BrakePress - 0.05 ) ) {
|
||||
rsSBHiss
|
||||
.gain( clamp( 0.05 * m_localbrakepressurechange, 0.0, 1.5 ) )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
// don't stop the sound too abruptly
|
||||
volume = std::max( 0.0, rsSBHiss.gain() - 0.1 * Deltatime );
|
||||
rsSBHiss.gain( volume );
|
||||
if( volume < 0.05 ) {
|
||||
rsSBHiss.stop();
|
||||
}
|
||||
}
|
||||
|
||||
// ambient sound
|
||||
// since it's typically ticking of the clock we can center it on tachometer or on middle of compartment bounding area
|
||||
rsFadeSound.play( sound_flags::exclusive | sound_flags::looping );
|
||||
@@ -5268,6 +5268,35 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
}
|
||||
}
|
||||
|
||||
// szum w czasie jazdy
|
||||
if( DynamicObject->GetVelocity() > 0.5 ) {
|
||||
|
||||
volume = rsRunningNoise.m_amplitudefactor * mvOccupied->Vel + rsRunningNoise.m_amplitudeoffset;
|
||||
auto frequency { rsRunningNoise.m_frequencyfactor * mvOccupied->Vel + rsRunningNoise.m_frequencyoffset };
|
||||
|
||||
if( std::abs( mvOccupied->nrot ) > 0.01 ) {
|
||||
// hamulce wzmagaja halas
|
||||
volume *= 1 + 0.25 * ( mvOccupied->UnitBrakeForce / ( 1 + mvOccupied->MaxBrakeForce ) );
|
||||
}
|
||||
// scale volume by track quality
|
||||
volume *= ( 20.0 + DynamicObject->MyTrack->iDamageFlag ) / 21;
|
||||
// scale volume with vehicle speed
|
||||
// TBD, TODO: disable the scaling for sounds combined from speed-based samples?
|
||||
volume *=
|
||||
interpolate(
|
||||
0.0, 1.0,
|
||||
clamp(
|
||||
mvOccupied->Vel / 40.0,
|
||||
0.0, 1.0 ) );
|
||||
rsRunningNoise
|
||||
.pitch( clamp( frequency, 0.5, 1.15 ) ) // arbitrary limits to prevent the pitch going out of whack
|
||||
.gain( volume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
rsRunningNoise.stop();
|
||||
}
|
||||
|
||||
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
||||
if (mvOccupied->SecuritySystem.Status > 0) {
|
||||
// hunter-091012: rozdzielenie alarmow
|
||||
@@ -5449,6 +5478,14 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
||||
rsFadeSound.deserialize( parser, sound_type::single );
|
||||
rsFadeSound.owner( DynamicObject );
|
||||
}
|
||||
else if( token == "runningnoise:" ) {
|
||||
// szum podczas jazdy:
|
||||
rsRunningNoise.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency );
|
||||
rsRunningNoise.owner( DynamicObject );
|
||||
|
||||
rsRunningNoise.m_amplitudefactor /= ( 1 + mvOccupied->Vmax );
|
||||
rsRunningNoise.m_frequencyfactor /= ( 1 + mvOccupied->Vmax );
|
||||
}
|
||||
else if (token == "mechspring:")
|
||||
{
|
||||
// parametry bujania kamery:
|
||||
@@ -5500,7 +5537,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||
&dsbReverserKey, &dsbNastawnikJazdy, &dsbNastawnikBocz,
|
||||
&dsbSwitch, &dsbPneumaticSwitch,
|
||||
&rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss,
|
||||
&rsFadeSound,
|
||||
&rsFadeSound, &rsRunningNoise,
|
||||
&dsbHasler, &dsbBuzzer, &dsbSlipAlarm
|
||||
};
|
||||
for( auto sound : sounds ) {
|
||||
|
||||
2
Train.h
2
Train.h
@@ -414,6 +414,8 @@ public: // reszta może by?publiczna
|
||||
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
|
||||
|
||||
sound_source rsFadeSound { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
sound_source rsRunningNoise{ sound_placement::internal, 2.0 * EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
|
||||
sound_source dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
sound_source dsbBuzzer { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
sound_source dsbSlipAlarm { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // Bombardier 011010: alarm przy poslizgu dla 181/182
|
||||
|
||||
@@ -898,7 +898,7 @@ bool TWorld::Update() {
|
||||
Timer::UpdateTimers(Global::iPause != 0);
|
||||
Timer::subsystem.sim_total.start();
|
||||
|
||||
if( (Global::iPause == false)
|
||||
if( (Global::iPause == 0)
|
||||
|| (m_init == false) ) {
|
||||
// jak pauza, to nie ma po co tego przeliczać
|
||||
simulation::Time.update( Timer::GetDeltaTime() );
|
||||
|
||||
@@ -115,21 +115,21 @@ openal_source::sync_with( sound_properties const &State ) {
|
||||
::alSourcefv( id, AL_POSITION, glm::value_ptr( glm::vec3() ) );
|
||||
}
|
||||
// gain
|
||||
if( ( State.placement_stamp != properties.placement_stamp )
|
||||
|| ( State.base_gain != properties.base_gain ) ) {
|
||||
if( ( State.soundproofing_stamp != properties.soundproofing_stamp )
|
||||
|| ( State.gain != properties.gain ) ) {
|
||||
// gain value has changed
|
||||
properties.base_gain = State.base_gain;
|
||||
properties.placement_gain = State.placement_gain;
|
||||
properties.placement_stamp = State.placement_stamp;
|
||||
properties.gain = State.gain;
|
||||
properties.soundproofing = State.soundproofing;
|
||||
properties.soundproofing_stamp = State.soundproofing_stamp;
|
||||
|
||||
::alSourcef( id, AL_GAIN, properties.base_gain * properties.placement_gain * Global::AudioVolume );
|
||||
::alSourcef( id, AL_GAIN, properties.gain * properties.soundproofing * Global::AudioVolume );
|
||||
}
|
||||
// pitch
|
||||
if( State.base_pitch != properties.base_pitch ) {
|
||||
if( State.pitch != properties.pitch ) {
|
||||
// pitch value has changed
|
||||
properties.base_pitch = State.base_pitch;
|
||||
properties.pitch = State.pitch;
|
||||
|
||||
::alSourcef( id, AL_PITCH, properties.base_pitch * pitch_variation );
|
||||
::alSourcef( id, AL_PITCH, properties.pitch * pitch_variation );
|
||||
}
|
||||
is_synced = true;
|
||||
}
|
||||
@@ -157,7 +157,7 @@ openal_source::pitch( float const Pitch ) {
|
||||
|
||||
pitch_variation = Pitch;
|
||||
// invalidate current pitch value to enforce change of next syns
|
||||
properties.base_pitch = -1.f;
|
||||
properties.pitch = -1.f;
|
||||
}
|
||||
|
||||
// toggles looping of the sound emitted by the source
|
||||
|
||||
@@ -17,10 +17,10 @@ class sound_source;
|
||||
// sound emitter state sync item
|
||||
struct sound_properties {
|
||||
glm::dvec3 location;
|
||||
float base_gain { 1.f };
|
||||
float placement_gain { 1.f };
|
||||
std::uintptr_t placement_stamp { ~( std::uintptr_t{ 0 } ) };
|
||||
float base_pitch { 1.f };
|
||||
float gain { 1.f };
|
||||
float soundproofing { 1.f };
|
||||
std::uintptr_t soundproofing_stamp { ~( std::uintptr_t{ 0 } ) };
|
||||
float pitch { 1.f };
|
||||
};
|
||||
|
||||
namespace audio {
|
||||
|
||||
@@ -854,7 +854,7 @@ state_manager::deserialize_sound( cParser &Input, scene::scratch_data &Scratchpa
|
||||
auto *sound = new sound_source( sound_placement::external, Nodedata.range_max );
|
||||
sound->offset( location );
|
||||
sound->name( Nodedata.name );
|
||||
sound->deserialize( Input.getToken<std::string>(), sound_type::single );
|
||||
sound->deserialize( Input, sound_type::single );
|
||||
#endif
|
||||
|
||||
skip_until( Input, "endsound" );
|
||||
|
||||
62
sound.cpp
62
sound.cpp
@@ -168,7 +168,7 @@ sound_source::update( audio::openal_source &Source ) {
|
||||
|
||||
// check and update if needed current sound properties
|
||||
update_location();
|
||||
update_placement_gain();
|
||||
update_soundproofing();
|
||||
Source.sync_with( m_properties );
|
||||
if( false == Source.is_synced ) {
|
||||
// if the sync went wrong we let the renderer kill its part of the emitter, and update our playcounter(s) to match
|
||||
@@ -190,7 +190,7 @@ sound_source::update( audio::openal_source &Source ) {
|
||||
Source.range( m_range );
|
||||
Source.pitch( m_pitchvariation );
|
||||
update_location();
|
||||
update_placement_gain();
|
||||
update_soundproofing();
|
||||
Source.sync_with( m_properties );
|
||||
if( true == Source.is_synced ) {
|
||||
// all set, start playback
|
||||
@@ -216,7 +216,7 @@ sound_source::update( audio::openal_source &Source ) {
|
||||
sound_source &
|
||||
sound_source::gain( float const Gain ) {
|
||||
|
||||
m_properties.base_gain = clamp( Gain, 0.f, 2.f );
|
||||
m_properties.gain = clamp( Gain, 0.f, 2.f );
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -224,14 +224,14 @@ sound_source::gain( float const Gain ) {
|
||||
float
|
||||
sound_source::gain() const {
|
||||
|
||||
return m_properties.base_gain;
|
||||
return m_properties.gain;
|
||||
}
|
||||
|
||||
// sets base pitch of the emitter to specified value
|
||||
sound_source &
|
||||
sound_source::pitch( float const Pitch ) {
|
||||
|
||||
m_properties.base_pitch = clamp( Pitch, 0.1f, 10.f );
|
||||
m_properties.pitch = clamp( Pitch, 0.1f, 10.f );
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -275,18 +275,18 @@ sound_source::update_counter( audio::buffer_handle const Buffer, int const Value
|
||||
else if( Buffer == m_soundend.buffer ) { m_soundend.playing += Value; }
|
||||
}
|
||||
|
||||
float const EU07_SOUNDGAIN_LOW { 0.2f };
|
||||
float const EU07_SOUNDGAIN_MEDIUM { 0.65f };
|
||||
float const EU07_SOUNDGAIN_FULL { 1.f };
|
||||
|
||||
void
|
||||
sound_source::update_location() {
|
||||
|
||||
m_properties.location = location();
|
||||
}
|
||||
|
||||
float const EU07_SOUNDPROOFING_STRONG { 0.25f };
|
||||
float const EU07_SOUNDPROOFING_SOME { 0.65f };
|
||||
float const EU07_SOUNDPROOFING_NONE { 1.f };
|
||||
|
||||
bool
|
||||
sound_source::update_placement_gain() {
|
||||
sound_source::update_soundproofing() {
|
||||
|
||||
// NOTE, HACK: current cab id can vary from -1 to +1
|
||||
// we use this as modifier to force re-calculations when moving between compartments
|
||||
@@ -297,7 +297,7 @@ sound_source::update_placement_gain() {
|
||||
Global::pWorld->train()->Dynamic()->MoverParameters->ActiveCab :
|
||||
0 ) );
|
||||
// location-based gain factor:
|
||||
std::uintptr_t placementstamp = reinterpret_cast<std::uintptr_t>( (
|
||||
std::uintptr_t soundproofingstamp = reinterpret_cast<std::uintptr_t>( (
|
||||
FreeFlyModeFlag ?
|
||||
nullptr :
|
||||
( Global::pWorld->train() ?
|
||||
@@ -305,51 +305,51 @@ sound_source::update_placement_gain() {
|
||||
nullptr ) ) )
|
||||
+ activecab;
|
||||
|
||||
if( placementstamp == m_properties.placement_stamp ) { return false; }
|
||||
if( soundproofingstamp == m_properties.soundproofing_stamp ) { return false; }
|
||||
|
||||
// listener location has changed, calculate new location-based gain factor
|
||||
switch( m_placement ) {
|
||||
case sound_placement::general: {
|
||||
m_properties.placement_gain = EU07_SOUNDGAIN_FULL;
|
||||
m_properties.soundproofing = EU07_SOUNDPROOFING_NONE;
|
||||
break;
|
||||
}
|
||||
case sound_placement::external: {
|
||||
m_properties.placement_gain = (
|
||||
placementstamp == 0 ?
|
||||
EU07_SOUNDGAIN_FULL : // listener outside
|
||||
EU07_SOUNDGAIN_LOW ); // listener in a vehicle
|
||||
m_properties.soundproofing = (
|
||||
soundproofingstamp == 0 ?
|
||||
EU07_SOUNDPROOFING_NONE : // listener outside
|
||||
EU07_SOUNDPROOFING_STRONG ); // listener in a vehicle
|
||||
break;
|
||||
}
|
||||
case sound_placement::internal: {
|
||||
m_properties.placement_gain = (
|
||||
placementstamp == 0 ?
|
||||
EU07_SOUNDGAIN_LOW : // listener outside
|
||||
m_properties.soundproofing = (
|
||||
soundproofingstamp == 0 ?
|
||||
EU07_SOUNDPROOFING_STRONG : // listener outside
|
||||
( Global::pWorld->train()->Dynamic() != m_owner ?
|
||||
EU07_SOUNDGAIN_LOW : // in another vehicle
|
||||
EU07_SOUNDPROOFING_STRONG : // in another vehicle
|
||||
( activecab == 0 ?
|
||||
EU07_SOUNDGAIN_LOW : // listener in the engine compartment
|
||||
EU07_SOUNDGAIN_FULL ) ) ); // listener in the cab of the same vehicle
|
||||
EU07_SOUNDPROOFING_STRONG : // listener in the engine compartment
|
||||
EU07_SOUNDPROOFING_NONE ) ) ); // listener in the cab of the same vehicle
|
||||
break;
|
||||
}
|
||||
case sound_placement::engine: {
|
||||
m_properties.placement_gain = (
|
||||
placementstamp == 0 ?
|
||||
EU07_SOUNDGAIN_MEDIUM : // listener outside
|
||||
m_properties.soundproofing = (
|
||||
soundproofingstamp == 0 ?
|
||||
EU07_SOUNDPROOFING_SOME : // listener outside
|
||||
( Global::pWorld->train()->Dynamic() != m_owner ?
|
||||
EU07_SOUNDGAIN_LOW : // in another vehicle
|
||||
EU07_SOUNDPROOFING_STRONG : // in another vehicle
|
||||
( activecab == 0 ?
|
||||
EU07_SOUNDGAIN_FULL : // listener in the engine compartment
|
||||
EU07_SOUNDGAIN_LOW ) ) ); // listener in another compartment of the same vehicle
|
||||
EU07_SOUNDPROOFING_NONE : // listener in the engine compartment
|
||||
EU07_SOUNDPROOFING_STRONG ) ) ); // listener in another compartment of the same vehicle
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// shouldn't ever land here, but, eh
|
||||
m_properties.placement_gain = EU07_SOUNDGAIN_FULL;
|
||||
m_properties.soundproofing = EU07_SOUNDPROOFING_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_properties.placement_stamp = placementstamp;
|
||||
m_properties.soundproofing_stamp = soundproofingstamp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
2
sound.h
2
sound.h
@@ -121,7 +121,7 @@ private:
|
||||
update_location();
|
||||
// potentially updates area-based gain factor of the source. returns: true if location has changed
|
||||
bool
|
||||
update_placement_gain();
|
||||
update_soundproofing();
|
||||
void
|
||||
insert( audio::buffer_handle Buffer );
|
||||
template <class Iterator_>
|
||||
|
||||
Reference in New Issue
Block a user