16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 19:49:19 +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:
tmj-fstate
2017-12-04 15:39:15 +01:00
parent 5645c13362
commit 4f9464499c
11 changed files with 196 additions and 140 deletions

View File

@@ -559,7 +559,7 @@ TDynamicObject::toggle_lights() {
( compartmentname.find( "compartment" ) != std::string::npos ) ( compartmentname.find( "compartment" ) != std::string::npos )
|| ( compartmentname.find( "przedzial" ) != std::string::npos ) ) { || ( compartmentname.find( "przedzial" ) != std::string::npos ) ) {
// compartments are lit with 75% probability // 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; SectionLightsActive = true;
@@ -1611,9 +1611,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance )
} }
//----------ABu: koniec skanowania pojazdow //----------ABu: koniec skanowania pojazdow
TDynamicObject::TDynamicObject() : TDynamicObject::TDynamicObject() {
rsStukot( MaxAxles, sound_source( sound_placement::external ) )
{
modelShake = vector3(0, 0, 0); modelShake = vector3(0, 0, 0);
fTrackBlock = 10000.0; // brak przeszkody na drodze fTrackBlock = 10000.0; // brak przeszkody na drodze
btnOn = false; btnOn = false;
@@ -1634,12 +1632,14 @@ TDynamicObject::TDynamicObject() :
bEnabled = true; bEnabled = true;
MyTrack = NULL; MyTrack = NULL;
// McZapkie-260202 // McZapkie-260202
/*
dRailLength = 25.0; dRailLength = 25.0;
for (int i = 0; i < MaxAxles; i++) for (int i = 0; i < MaxAxles; i++)
dRailPosition[i] = 0.0; dRailPosition[i] = 0.0;
for (int i = 0; i < MaxAxles; i++) for (int i = 0; i < MaxAxles; i++)
dWheelsPosition[i] = 0.0; // będzie wczytane z MMD dWheelsPosition[i] = 0.0; // będzie wczytane z MMD
iAxles = 0; iAxles = 0;
*/
dWheelAngle[0] = 0.0; dWheelAngle[0] = 0.0;
dWheelAngle[1] = 0.0; dWheelAngle[1] = 0.0;
dWheelAngle[2] = 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() ); create_controller( DriverType, !TrainName.empty() );
// McZapkie-250202 // McZapkie-250202
/*
iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi
rsStukot.resize( iAxles, sound_source( sound_placement::external ) ); */
// wczytywanie z pliku nazwatypu.mmd, w tym model // wczytywanie z pliku nazwatypu.mmd, w tym model
LoadMMediaFile(asBaseDir, Type_Name, asReplacableSkin); LoadMMediaFile(asBaseDir, Type_Name, asReplacableSkin);
// McZapkie-100402: wyszukiwanie submodeli sprzegów // McZapkie-100402: wyszukiwanie submodeli sprzegów
@@ -2093,12 +2094,12 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
smBuforPrawy[ i ]->WillBeAnimated(); 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ść?) // wyszukiwanie osi (0 jest na końcu, dlatego dodajemy długość?)
dRailPosition[ i ] = ( axle.distance = (
Reversed ? Reversed ?
-dWheelsPosition[ i ] : -axle.offset :
( dWheelsPosition[ i ] + MoverParameters->Dim.L ) ) + fDist; ( axle.offset + MoverParameters->Dim.L ) ) + fDist;
} }
// McZapkie-250202 end. // McZapkie-250202 end.
Track->AddDynamicObject(this); // wstawiamy do toru na pozycję 0, a potem przesuniemy 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 ) { if( MyTrack->fSoundDistance != dRailLength ) {
dRailLength = MyTrack->fSoundDistance; dRailLength = MyTrack->fSoundDistance;
for( int i = 0; i < iAxles; ++i ) { for( auto &axle : m_axlesounds ) {
dRailPosition[ i ] = dWheelsPosition[ i ] + MoverParameters->Dim.L; axle.distance = axle.offset + MoverParameters->Dim.L;
} }
} }
if( dRailLength != -1 ) { if( dRailLength != -1 ) {
if( std::abs( MoverParameters->V ) > 0 ) { if( MoverParameters->Vel > 0 ) {
double volume = ( 20.0 + MyTrack->iDamageFlag ) / 21; double volume = ( 20.0 + MyTrack->iDamageFlag ) / 21;
switch( MyTrack->eEnvironment ) { switch( MyTrack->eEnvironment ) {
@@ -3085,9 +3086,10 @@ bool TDynamicObject::Update(double dt, double dt1)
} }
} }
for( int i = 0; i < iAxles; ++i ) { for( auto &axle : m_axlesounds ) {
dRailPosition[ i ] -= dDOMoveLen * Sign( dDOMoveLen ); axle.distance -= dDOMoveLen * Sign( dDOMoveLen );
if( dRailPosition[ i ] < 0 ) { if( axle.distance < 0 ) {
axle.distance += dRailLength;
/* /*
// McZapkie-040302 // McZapkie-040302
if( i == iAxles - 1 ) { if( i == iAxles - 1 ) {
@@ -3101,8 +3103,9 @@ bool TDynamicObject::Update(double dt, double dt1)
MoverParameters->AccV -= 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax ); MoverParameters->AccV -= 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax );
} }
*/ */
rsStukot[ i ].gain( volume ).play(); if( MoverParameters->Vel > 2.5 ) {
dRailPosition[ i ] += dRailLength; axle.clatter.gain( volume ).play();
}
} }
} }
} }
@@ -3602,10 +3605,10 @@ void TDynamicObject::RenderSounds() {
// McZapkie-010302: ulepszony dzwiek silnika // McZapkie-010302: ulepszony dzwiek silnika
double frequency { 1.0 }; double frequency { 1.0 };
double volume { 1.0 }; double volume { 0.0 };
double const dt { Timer::GetDeltaRenderTime() }; double const dt { Timer::GetDeltaRenderTime() };
if( dt == 0.0 ) { return; } if( Global::iPause != 0 ) { return; }
// engine sounds // engine sounds
if( MoverParameters->Power > 0 ) { if( MoverParameters->Power > 0 ) {
@@ -3652,6 +3655,7 @@ void TDynamicObject::RenderSounds() {
+ rsSilnik.m_amplitudeoffset; + rsSilnik.m_amplitudeoffset;
break; break;
} }
// NOTE: default case also covers electric motors
default: { default: {
volume = volume =
rsSilnik.m_amplitudefactor * ( MoverParameters->EnginePower / 1000 + std::fabs( MoverParameters->enrot ) * 60.0 ) rsSilnik.m_amplitudefactor * ( MoverParameters->EnginePower / 1000 + std::fabs( MoverParameters->enrot ) * 60.0 )
@@ -3950,13 +3954,14 @@ void TDynamicObject::RenderSounds() {
if( m_lastbrakepressure != -1.f ) { if( m_lastbrakepressure != -1.f ) {
// calculate rate of pressure drop in brake cylinder, once it's been initialized // calculate rate of pressure drop in brake cylinder, once it's been initialized
auto const brakepressuredifference { m_lastbrakepressure - MoverParameters->BrakePress }; 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; m_lastbrakepressure = MoverParameters->BrakePress;
if( m_brakepressurechange > 0.05f ) { // ensure some basic level of volume and scale it up depending on pressure in the cylinder; scale this by the leak rate
// NOTE: can't use the leak rate directly due to irregular results produced by some brake type implementations volume = 20 * m_brakepressurechange * ( 0.25 + 0.75 * ( std::max( MoverParameters->BrakePress, 0.0 ) / MoverParameters->MaxBrakePress[ 3 ] ) );
if( volume > 0.075f ) {
rsUnbrake 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 ); .play( sound_flags::exclusive | sound_flags::looping );
} }
else { else {
@@ -4009,7 +4014,7 @@ void TDynamicObject::RenderSounds() {
&& ( GetVelocity() > 0.05 ) ) { && ( GetVelocity() > 0.05 ) ) {
rsBrake 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 ) .gain( rsBrake.m_amplitudefactor * std::sqrt( ( GetVelocity() * MoverParameters->UnitBrakeForce ) ) + rsBrake.m_amplitudeoffset )
.play( sound_flags::exclusive | sound_flags::looping ); .play( sound_flags::exclusive | sound_flags::looping );
} }
@@ -4115,8 +4120,8 @@ void TDynamicObject::RenderSounds() {
// szum w czasie jazdy // szum w czasie jazdy
if( GetVelocity() > 0.5 ) { if( GetVelocity() > 0.5 ) {
volume = rsRunningNoise.m_amplitudefactor * MoverParameters->Vel + rsRunningNoise.m_amplitudeoffset; volume = rsOuterNoise.m_amplitudefactor * MoverParameters->Vel + rsOuterNoise.m_amplitudeoffset;
frequency = rsRunningNoise.m_frequencyfactor * MoverParameters->Vel + rsRunningNoise.m_frequencyoffset; frequency = rsOuterNoise.m_frequencyfactor * MoverParameters->Vel + rsOuterNoise.m_frequencyoffset;
if( false == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) { if( false == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) {
// McZpakie-221103: halas zalezny od kola // McZpakie-221103: halas zalezny od kola
@@ -4174,13 +4179,13 @@ void TDynamicObject::RenderSounds() {
clamp( clamp(
MoverParameters->Vel / 60.0, MoverParameters->Vel / 60.0,
0.0, 1.0 ) ); 0.0, 1.0 ) );
rsRunningNoise rsOuterNoise
.pitch( clamp( frequency, 0.5, 1.15 ) ) // arbitrary limits to prevent the pitch going out of whack .pitch( clamp( frequency, 0.5, 1.15 ) ) // arbitrary limits to prevent the pitch going out of whack
.gain( volume ) .gain( volume )
.play( sound_flags::exclusive | sound_flags::looping ); .play( sound_flags::exclusive | sound_flags::looping );
} }
else { else {
rsRunningNoise.stop(); rsOuterNoise.stop();
} }
// youBy: dzwiek ostrych lukow i ciasnych zwrotek // youBy: dzwiek ostrych lukow i ciasnych zwrotek
@@ -4200,7 +4205,7 @@ void TDynamicObject::RenderSounds() {
} }
if( volume > 0.05 ) { if( volume > 0.05 ) {
rscurve rscurve
.gain( 2.0 * volume ) .gain( 2.5 * volume )
.play( sound_flags::exclusive | sound_flags::looping ); .play( sound_flags::exclusive | sound_flags::looping );
} }
else { else {
@@ -4274,17 +4279,17 @@ void TDynamicObject::RenderSounds() {
// TODO: dedicated sound, played alongside regular noise // TODO: dedicated sound, played alongside regular noise
if( true == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) { if( true == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) {
#ifdef EU07_USE_OLD_SOUNDCODE #ifdef EU07_USE_OLD_SOUNDCODE
if( rsRunningNoise.AM != 0 ) { if( rsOuterNoise.AM != 0 ) {
rsRunningNoise.Stop(); rsOuterNoise.Stop();
float am = rsRunningNoise.AM; float am = rsOuterNoise.AM;
float fa = rsRunningNoise.FA; float fa = rsOuterNoise.FA;
float fm = rsRunningNoise.FM; float fm = rsOuterNoise.FM;
rsRunningNoise.Init( "lomotpodkucia.wav", -1, 0, 0, 0, true ); // MC: zmiana szumu na lomot rsOuterNoise.Init( "lomotpodkucia.wav", -1, 0, 0, 0, true ); // MC: zmiana szumu na lomot
if( rsRunningNoise.AM == 1 ) if( rsOuterNoise.AM == 1 )
rsRunningNoise.AM = am; rsOuterNoise.AM = am;
rsRunningNoise.AA = 0.7; rsOuterNoise.AA = 0.7;
rsRunningNoise.FA = fa; rsOuterNoise.FA = fa;
rsRunningNoise.FM = fm; rsOuterNoise.FM = fm;
} }
#else #else
#endif #endif
@@ -5004,21 +5009,23 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
// polozenia osi w/m srodka pojazdu // polozenia osi w/m srodka pojazdu
parser.getTokens( 1, false ); parser.getTokens( 1, false );
parser >> dSDist; parser >> dSDist;
for( int i = 0; i < iAxles; ++i ) { while( ( ( token = parser.getToken<std::string>() ) != "" )
parser.getTokens( 1, false ); && ( token != "end" ) ) {
parser >> dWheelsPosition[ i ]; // add another axle entry to the list
parser.getTokens(); axle_sounds axle {
parser >> token; 0,
if( token != "end" ) { std::atof( token.c_str() ),
rsStukot[ i ].deserialize( token + " " + std::to_string( dSDist ), sound_type::single, sound_parameters::range ); { sound_placement::external, static_cast<float>( dSDist ) } };
rsStukot[ i ].owner( this ); axle.clatter.deserialize( parser, sound_type::single );
rsStukot[ i ].offset( { 0, 0, -dWheelsPosition[ i ] } ); 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:" ) else if( ( token == "engine:" )
@@ -5193,6 +5200,15 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
sReleaser.owner( this ); 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 != "" ) } while( ( token != "" )
&& ( token != "endsounds" ) ); && ( token != "endsounds" ) );
@@ -5301,14 +5317,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
couplersounds.dsbBufferClamp = bufferclash; 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 != "" ); } while( token != "" );

View File

@@ -273,8 +273,14 @@ private:
}; };
struct door_sounds { struct door_sounds {
sound_source rsDoorOpen{ sound_placement::general }; // Ra: przeniesione z kabiny sound_source rsDoorOpen{ sound_placement::general, 25.f }; // Ra: przeniesione z kabiny
sound_source rsDoorClose{ sound_placement::general }; 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 // methods
@@ -318,16 +324,19 @@ private:
TButton btHeadSignals23; TButton btHeadSignals23;
TButton btMechanik1; TButton btMechanik1;
TButton btMechanik2; TButton btMechanik2;
double enginevolume; // MC: pomocnicze zeby gladziej silnik buczal
int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles // int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles
double dRailLength; double dRailLength { 0.0 };
std::vector<axle_sounds> m_axlesounds;
/*
double dRailPosition[MaxAxles]; // licznik pozycji osi w/m szyny double dRailPosition[MaxAxles]; // licznik pozycji osi w/m szyny
double dWheelsPosition[MaxAxles]; // pozycja osi w/m srodka pojazdu double dWheelsPosition[MaxAxles]; // pozycja osi w/m srodka pojazdu
std::vector<sound_source> rsStukot; // dzwieki poszczegolnych osi //McZapkie-270202 std::vector<sound_source> rsStukot; // dzwieki poszczegolnych osi //McZapkie-270202
*/
// engine sounds // engine sounds
sound_source dsbDieselIgnition { sound_placement::engine }; // moved from cab sound_source dsbDieselIgnition { sound_placement::engine }; // moved from cab
sound_source rsSilnik { sound_placement::engine }; sound_source rsSilnik { sound_placement::engine };
double enginevolume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
sound_source dsbRelay { sound_placement::engine }; sound_source dsbRelay { sound_placement::engine };
sound_source dsbWejscie_na_bezoporow { sound_placement::engine }; // moved from cab sound_source dsbWejscie_na_bezoporow { sound_placement::engine }; // moved from cab
sound_source dsbWejscie_na_drugi_uklad { 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 sDepartureSignal { sound_placement::general };
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
sound_source sHorn2 { 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 sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
double eng_vol_act; double eng_vol_act;

View File

@@ -5136,6 +5136,28 @@ TTrain::update_sounds( double const Deltatime ) {
double volume { 0.0 }; double volume { 0.0 };
double const brakevolumescale { 0.5 }; 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 // McZapkie-280302 - syczenie
// TODO: softer volume reduction than plain abrupt stop, perhaps as reusable wrapper? // TODO: softer volume reduction than plain abrupt stop, perhaps as reusable wrapper?
if( ( mvOccupied->BrakeHandle == FV4a ) if( ( mvOccupied->BrakeHandle == FV4a )
@@ -5231,28 +5253,6 @@ TTrain::update_sounds( double const Deltatime ) {
} }
} // koniec nie FV4a } // 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 // ambient sound
// since it's typically ticking of the clock we can center it on tachometer or on middle of compartment bounding area // 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 ); 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 // McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
if (mvOccupied->SecuritySystem.Status > 0) { if (mvOccupied->SecuritySystem.Status > 0) {
// hunter-091012: rozdzielenie alarmow // hunter-091012: rozdzielenie alarmow
@@ -5449,6 +5478,14 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
rsFadeSound.deserialize( parser, sound_type::single ); rsFadeSound.deserialize( parser, sound_type::single );
rsFadeSound.owner( DynamicObject ); 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:") else if (token == "mechspring:")
{ {
// parametry bujania kamery: // parametry bujania kamery:
@@ -5500,7 +5537,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
&dsbReverserKey, &dsbNastawnikJazdy, &dsbNastawnikBocz, &dsbReverserKey, &dsbNastawnikJazdy, &dsbNastawnikBocz,
&dsbSwitch, &dsbPneumaticSwitch, &dsbSwitch, &dsbPneumaticSwitch,
&rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss, &rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss,
&rsFadeSound, &rsFadeSound, &rsRunningNoise,
&dsbHasler, &dsbBuzzer, &dsbSlipAlarm &dsbHasler, &dsbBuzzer, &dsbSlipAlarm
}; };
for( auto sound : sounds ) { for( auto sound : sounds ) {

View File

@@ -414,6 +414,8 @@ public: // reszta może by?publiczna
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
sound_source rsFadeSound { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; 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 dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
sound_source dsbBuzzer { 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 sound_source dsbSlipAlarm { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // Bombardier 011010: alarm przy poslizgu dla 181/182

View File

@@ -898,7 +898,7 @@ bool TWorld::Update() {
Timer::UpdateTimers(Global::iPause != 0); Timer::UpdateTimers(Global::iPause != 0);
Timer::subsystem.sim_total.start(); Timer::subsystem.sim_total.start();
if( (Global::iPause == false) if( (Global::iPause == 0)
|| (m_init == false) ) { || (m_init == false) ) {
// jak pauza, to nie ma po co tego przeliczać // jak pauza, to nie ma po co tego przeliczać
simulation::Time.update( Timer::GetDeltaTime() ); simulation::Time.update( Timer::GetDeltaTime() );

View File

@@ -115,21 +115,21 @@ openal_source::sync_with( sound_properties const &State ) {
::alSourcefv( id, AL_POSITION, glm::value_ptr( glm::vec3() ) ); ::alSourcefv( id, AL_POSITION, glm::value_ptr( glm::vec3() ) );
} }
// gain // gain
if( ( State.placement_stamp != properties.placement_stamp ) if( ( State.soundproofing_stamp != properties.soundproofing_stamp )
|| ( State.base_gain != properties.base_gain ) ) { || ( State.gain != properties.gain ) ) {
// gain value has changed // gain value has changed
properties.base_gain = State.base_gain; properties.gain = State.gain;
properties.placement_gain = State.placement_gain; properties.soundproofing = State.soundproofing;
properties.placement_stamp = State.placement_stamp; 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 // pitch
if( State.base_pitch != properties.base_pitch ) { if( State.pitch != properties.pitch ) {
// pitch value has changed // 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; is_synced = true;
} }
@@ -157,7 +157,7 @@ openal_source::pitch( float const Pitch ) {
pitch_variation = Pitch; pitch_variation = Pitch;
// invalidate current pitch value to enforce change of next syns // 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 // toggles looping of the sound emitted by the source

View File

@@ -17,10 +17,10 @@ class sound_source;
// sound emitter state sync item // sound emitter state sync item
struct sound_properties { struct sound_properties {
glm::dvec3 location; glm::dvec3 location;
float base_gain { 1.f }; float gain { 1.f };
float placement_gain { 1.f }; float soundproofing { 1.f };
std::uintptr_t placement_stamp { ~( std::uintptr_t{ 0 } ) }; std::uintptr_t soundproofing_stamp { ~( std::uintptr_t{ 0 } ) };
float base_pitch { 1.f }; float pitch { 1.f };
}; };
namespace audio { namespace audio {

View File

@@ -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 ); auto *sound = new sound_source( sound_placement::external, Nodedata.range_max );
sound->offset( location ); sound->offset( location );
sound->name( Nodedata.name ); sound->name( Nodedata.name );
sound->deserialize( Input.getToken<std::string>(), sound_type::single ); sound->deserialize( Input, sound_type::single );
#endif #endif
skip_until( Input, "endsound" ); skip_until( Input, "endsound" );

View File

@@ -168,7 +168,7 @@ sound_source::update( audio::openal_source &Source ) {
// check and update if needed current sound properties // check and update if needed current sound properties
update_location(); update_location();
update_placement_gain(); update_soundproofing();
Source.sync_with( m_properties ); Source.sync_with( m_properties );
if( false == Source.is_synced ) { 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 // 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.range( m_range );
Source.pitch( m_pitchvariation ); Source.pitch( m_pitchvariation );
update_location(); update_location();
update_placement_gain(); update_soundproofing();
Source.sync_with( m_properties ); Source.sync_with( m_properties );
if( true == Source.is_synced ) { if( true == Source.is_synced ) {
// all set, start playback // all set, start playback
@@ -216,7 +216,7 @@ sound_source::update( audio::openal_source &Source ) {
sound_source & sound_source &
sound_source::gain( float const Gain ) { 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; return *this;
} }
@@ -224,14 +224,14 @@ sound_source::gain( float const Gain ) {
float float
sound_source::gain() const { sound_source::gain() const {
return m_properties.base_gain; return m_properties.gain;
} }
// sets base pitch of the emitter to specified value // sets base pitch of the emitter to specified value
sound_source & sound_source &
sound_source::pitch( float const Pitch ) { 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; 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; } 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 void
sound_source::update_location() { sound_source::update_location() {
m_properties.location = 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 bool
sound_source::update_placement_gain() { sound_source::update_soundproofing() {
// NOTE, HACK: current cab id can vary from -1 to +1 // NOTE, HACK: current cab id can vary from -1 to +1
// we use this as modifier to force re-calculations when moving between compartments // 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 : Global::pWorld->train()->Dynamic()->MoverParameters->ActiveCab :
0 ) ); 0 ) );
// location-based gain factor: // location-based gain factor:
std::uintptr_t placementstamp = reinterpret_cast<std::uintptr_t>( ( std::uintptr_t soundproofingstamp = reinterpret_cast<std::uintptr_t>( (
FreeFlyModeFlag ? FreeFlyModeFlag ?
nullptr : nullptr :
( Global::pWorld->train() ? ( Global::pWorld->train() ?
@@ -305,51 +305,51 @@ sound_source::update_placement_gain() {
nullptr ) ) ) nullptr ) ) )
+ activecab; + 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 // listener location has changed, calculate new location-based gain factor
switch( m_placement ) { switch( m_placement ) {
case sound_placement::general: { case sound_placement::general: {
m_properties.placement_gain = EU07_SOUNDGAIN_FULL; m_properties.soundproofing = EU07_SOUNDPROOFING_NONE;
break; break;
} }
case sound_placement::external: { case sound_placement::external: {
m_properties.placement_gain = ( m_properties.soundproofing = (
placementstamp == 0 ? soundproofingstamp == 0 ?
EU07_SOUNDGAIN_FULL : // listener outside EU07_SOUNDPROOFING_NONE : // listener outside
EU07_SOUNDGAIN_LOW ); // listener in a vehicle EU07_SOUNDPROOFING_STRONG ); // listener in a vehicle
break; break;
} }
case sound_placement::internal: { case sound_placement::internal: {
m_properties.placement_gain = ( m_properties.soundproofing = (
placementstamp == 0 ? soundproofingstamp == 0 ?
EU07_SOUNDGAIN_LOW : // listener outside EU07_SOUNDPROOFING_STRONG : // listener outside
( Global::pWorld->train()->Dynamic() != m_owner ? ( Global::pWorld->train()->Dynamic() != m_owner ?
EU07_SOUNDGAIN_LOW : // in another vehicle EU07_SOUNDPROOFING_STRONG : // in another vehicle
( activecab == 0 ? ( activecab == 0 ?
EU07_SOUNDGAIN_LOW : // listener in the engine compartment EU07_SOUNDPROOFING_STRONG : // listener in the engine compartment
EU07_SOUNDGAIN_FULL ) ) ); // listener in the cab of the same vehicle EU07_SOUNDPROOFING_NONE ) ) ); // listener in the cab of the same vehicle
break; break;
} }
case sound_placement::engine: { case sound_placement::engine: {
m_properties.placement_gain = ( m_properties.soundproofing = (
placementstamp == 0 ? soundproofingstamp == 0 ?
EU07_SOUNDGAIN_MEDIUM : // listener outside EU07_SOUNDPROOFING_SOME : // listener outside
( Global::pWorld->train()->Dynamic() != m_owner ? ( Global::pWorld->train()->Dynamic() != m_owner ?
EU07_SOUNDGAIN_LOW : // in another vehicle EU07_SOUNDPROOFING_STRONG : // in another vehicle
( activecab == 0 ? ( activecab == 0 ?
EU07_SOUNDGAIN_FULL : // listener in the engine compartment EU07_SOUNDPROOFING_NONE : // listener in the engine compartment
EU07_SOUNDGAIN_LOW ) ) ); // listener in another compartment of the same vehicle EU07_SOUNDPROOFING_STRONG ) ) ); // listener in another compartment of the same vehicle
break; break;
} }
default: { default: {
// shouldn't ever land here, but, eh // shouldn't ever land here, but, eh
m_properties.placement_gain = EU07_SOUNDGAIN_FULL; m_properties.soundproofing = EU07_SOUNDPROOFING_NONE;
break; break;
} }
} }
m_properties.placement_stamp = placementstamp; m_properties.soundproofing_stamp = soundproofingstamp;
return true; return true;
} }

View File

@@ -121,7 +121,7 @@ private:
update_location(); update_location();
// potentially updates area-based gain factor of the source. returns: true if location has changed // potentially updates area-based gain factor of the source. returns: true if location has changed
bool bool
update_placement_gain(); update_soundproofing();
void void
insert( audio::buffer_handle Buffer ); insert( audio::buffer_handle Buffer );
template <class Iterator_> template <class Iterator_>

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 1202 #define VERSION_MINOR 1204
#define VERSION_REVISION 0 #define VERSION_REVISION 0