From 25ec32d0e691b8a1f1a04a127a9616653a057842 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Wed, 8 Jan 2020 18:57:44 +0100 Subject: [PATCH] build 200108. sound start offset support, default coupler sound naming cleanup, minor bug fixes --- DynObj.cpp | 55 ++++++++++++++++++++++++++++------------------ DynObj.h | 2 ++ McZapkie/Mover.cpp | 2 +- audiorenderer.h | 17 +++++++++++++- drivermode.cpp | 10 ++++++++- driveruipanels.cpp | 2 +- sound.cpp | 6 +++++ sound.h | 11 +++++++++- version.h | 2 +- 9 files changed, 80 insertions(+), 27 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index e35b3a4a..6b20af95 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -4206,8 +4206,9 @@ void TDynamicObject::RenderSounds() { } // youBy: dzwiek ostrych lukow i ciasnych zwrotek - if( ( ts.R * ts.R > 1 ) - && ( MoverParameters->Vel > 5.0 ) ) { + if( ( MoverParameters->Vel > 5.0 ) + && ( ts.R * ts.R > 1.0 ) + && ( std::abs( ts.R ) < 15000.0 ) ) { // scale volume with curve radius and vehicle speed volume = std::abs( MoverParameters->AccN ) // * MoverParameters->AccN @@ -5440,16 +5441,13 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co else if( token == "outernoise:" ) { // szum podczas jazdy: - sound_source noisetemplate { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; + sound_source noisetemplate{ sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; noisetemplate.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency, MoverParameters->Vmax ); noisetemplate.owner( this ); noisetemplate.m_amplitudefactor /= ( 1 + MoverParameters->Vmax ); noisetemplate.m_frequencyfactor /= ( 1 + MoverParameters->Vmax ); - - m_outernoise = noisetemplate; -/* -// disabled until we can resolve sound interferences +#ifdef EU07_SOUND_BOGIESOUNDS if( true == m_bogiesounds.empty() ) { // fallback for cases without specified noise locations, convert sound template to a single sound source m_bogiesounds.emplace_back( noisetemplate ); @@ -5458,13 +5456,27 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co // apply configuration to all defined bogies for( auto &bogie : m_bogiesounds ) { // combine potential x- and y-axis offsets of the sound template with z-axis offsets of individual motors - auto bogieoffset { noisetemplate.offset() }; + auto bogieoffset{ noisetemplate.offset() }; bogieoffset.z = bogie.offset().z; bogie = noisetemplate; bogie.offset( bogieoffset ); } } -*/ + // apply randomized playback start offset for each bogie, to reduce potential reverb with identical nearby sources + auto bogieidx( 0 ); + for( auto &bogie : m_bogiesounds ) { + bogie.start( ( + bogieidx % 2 ? + Random( 0.0, 30.0 ) : + Random( 50.0, 80.0 ) ) + * 0.01 ); + ++bogieidx; + } +#else + m_outernoise = noisetemplate; + // apply randomized playback start offset, to reduce potential reverb with identical nearby sources + m_outernoise.start( Random( 0.0, 80.0 ) * 0.01 ); +#endif } else if( token == "wheelflat:" ) { @@ -5791,46 +5803,46 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co if( MoverParameters->Power > 0 ) { if( true == m_powertrainsounds.dsbWejscie_na_bezoporow.empty() ) { // hunter-111211: domyslne, gdy brak - m_powertrainsounds.dsbWejscie_na_bezoporow.deserialize( "wejscie_na_bezoporow.wav", sound_type::single ); + m_powertrainsounds.dsbWejscie_na_bezoporow.deserialize( "wejscie_na_bezoporow", sound_type::single ); m_powertrainsounds.dsbWejscie_na_bezoporow.owner( this ); } if( true == m_powertrainsounds.motor_parallel.empty() ) { - m_powertrainsounds.motor_parallel.deserialize( "wescie_na_drugi_uklad.wav", sound_type::single ); + m_powertrainsounds.motor_parallel.deserialize( "wescie_na_drugi_uklad", sound_type::single ); m_powertrainsounds.motor_parallel.owner( this ); } } // braking sounds if( true == rsUnbrake.empty() ) { - rsUnbrake.deserialize( "[1007]estluz.wav", sound_type::single ); + rsUnbrake.deserialize( "[1007]estluz", sound_type::single ); rsUnbrake.owner( this ); } // couplers for( auto &couplersounds : m_couplersounds ) { if( true == couplersounds.dsbCouplerAttach.empty() ) { - couplersounds.dsbCouplerAttach.deserialize( "couplerattach.wav", sound_type::single ); + couplersounds.dsbCouplerAttach.deserialize( "couplerattach_default", sound_type::single ); couplersounds.dsbCouplerAttach.owner( this ); } if( true == couplersounds.dsbCouplerDetach.empty() ) { - couplersounds.dsbCouplerDetach.deserialize( "couplerdetach.wav", sound_type::single ); + couplersounds.dsbCouplerDetach.deserialize( "couplerdetach_default", sound_type::single ); couplersounds.dsbCouplerDetach.owner( this ); } if( true == couplersounds.dsbCouplerStretch.empty() ) { - couplersounds.dsbCouplerStretch.deserialize( "en57_couplerstretch.wav", sound_type::single ); + couplersounds.dsbCouplerStretch.deserialize( "couplerstretch_default", sound_type::single ); couplersounds.dsbCouplerStretch.owner( this ); } if( true == couplersounds.dsbBufferClamp.empty() ) { - couplersounds.dsbBufferClamp.deserialize( "en57_bufferclamp.wav", sound_type::single ); + couplersounds.dsbBufferClamp.deserialize( "bufferclamp_default", sound_type::single ); couplersounds.dsbBufferClamp.owner( this ); } } // other sounds if( true == m_wheelflat.empty() ) { - m_wheelflat.deserialize( "lomotpodkucia.wav 0.23 0.0", sound_type::single, sound_parameters::frequency ); + m_wheelflat.deserialize( "lomotpodkucia 0.23 0.0", sound_type::single, sound_parameters::frequency ); m_wheelflat.owner( this ); } if( true == rscurve.empty() ) { // hunter-111211: domyslne, gdy brak - rscurve.deserialize( "curve.wav", sound_type::single ); + rscurve.deserialize( "curve", sound_type::single ); rscurve.owner( this ); } } @@ -6402,15 +6414,16 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer) { std::string signrequest { "make:" - + DestinationSign.script + "?" + + DestinationSign.script + + "?" // timetable include + "$timetable=" + ( ctOwner == nullptr ? MoverParameters->Name : // leading vehicle, can point to it directly - ctOwner->Vehicle()->MoverParameters->Name ) + "&" // owned vehicle, safer to point to owner as carriages can have identical names + ctOwner->Vehicle()->MoverParameters->Name ) // owned vehicle, safer to point to owner as carriages can have identical names // basic instancing string // NOTE: underscore doesn't have any magic meaning for the time being, it's just less likely to conflict with regular dictionary keys - + "_id1=" + ( + + "&_id1=" + ( ctOwner != nullptr ? ctOwner->TrainName() : Mechanik != nullptr ? Mechanik->TrainName() : "none" ) }; // shouldn't get here but, eh diff --git a/DynObj.h b/DynObj.h index 094bc2af..602d0b42 100644 --- a/DynObj.h +++ b/DynObj.h @@ -21,6 +21,8 @@ http://mozilla.org/MPL/2.0/. #include "sound.h" #include "Spring.h" +#define EU07_SOUND_BOGIESOUNDS + //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index a7b989c6..9a3a5d18 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4704,7 +4704,7 @@ double TMoverParameters::CouplerForce( int const End, double dt ) { // potentially generate sounds on clash or stretch if( ( newdistance < 0.0 ) && ( coupler.Dist > newdistance ) - && ( dV < -0.5 ) ) { + && ( dV < -0.1 ) ) { // 090503: dzwieki pracy zderzakow SetFlag( coupler.sounds, diff --git a/audiorenderer.h b/audiorenderer.h index 5cdb96d3..3d2de107 100644 --- a/audiorenderer.h +++ b/audiorenderer.h @@ -180,11 +180,26 @@ openal_source::bind( sound_source *Controller, uint32_sequence Sounds, Iterator_ auto const &buffer { audio::renderer.buffer( bufferhandle ) }; buffers.emplace_back( buffer.id ); } ); + is_multipart = ( buffers.size() > 1 ); + if( id != audio::null_resource ) { ::alSourceQueueBuffers( id, static_cast( buffers.size() ), buffers.data() ); ::alSourceRewind( id ); + // sound controller can potentially request playback to start from certain buffer point + if( controller->start() == 0.f ) { + // regular case with no offset, reset bound source just in case + ::alSourcei( id, AL_SAMPLE_OFFSET, 0 ); + } + else { + // move playback start to specified point in 0-1 range + ALint buffersize; + ::alGetBufferi( buffers.front(), AL_SIZE, &buffersize ); + ::alSourcei( + id, + AL_SAMPLE_OFFSET, + static_cast( controller->start() * ( buffersize / sizeof( std::int16_t ) ) ) ); + } } - is_multipart = ( buffers.size() > 1 ); return *this; } diff --git a/drivermode.cpp b/drivermode.cpp index 15d87e43..1ec7c49e 100644 --- a/drivermode.cpp +++ b/drivermode.cpp @@ -743,12 +743,20 @@ driver_mode::OnKeyDown(int cKey) { // jeśli mielismy pojazd if( simulation::Train->Dynamic()->Mechanik ) { // na skutek jakiegoś błędu może czasem zniknąć auto const *currentvehicle { simulation::Train->Dynamic() }; + auto const samevehicle { currentvehicle == targetvehicle }; + + if( samevehicle ) { + // we already control desired vehicle so don't overcomplicate things + InOutKey(); // do kabiny + break; + } + auto const sameconsist { ( targetvehicle->ctOwner == currentvehicle->Mechanik ) || ( targetvehicle->ctOwner == currentvehicle->ctOwner ) }; auto const isincharge { currentvehicle->Mechanik->primary() }; auto const aidriveractive { currentvehicle->Mechanik->AIControllFlag }; - + if( !sameconsist && isincharge ) { // oddajemy dotychczasowy AI simulation::Train->Dynamic()->Mechanik->TakeControl( true ); diff --git a/driveruipanels.cpp b/driveruipanels.cpp index e6112630..0f3d133d 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -696,7 +696,7 @@ debug_panel::update_section_vehicle( std::vector &Output ) { // acceleration Acc, mover.AccN + 0.001f, - std::string( std::abs( mover.RunningShape.R ) > 10000.0 ? "~0" : to_string( mover.RunningShape.R, 0 ) ).c_str(), + std::string( std::abs( mover.RunningShape.R ) > 15000.0 ? "~0" : to_string( mover.RunningShape.R, 0 ) ).c_str(), // velocity vehicle.GetVelocity(), mover.DistCounter, diff --git a/sound.cpp b/sound.cpp index 1d7418cc..f3bd17ba 100644 --- a/sound.cpp +++ b/sound.cpp @@ -193,6 +193,12 @@ sound_source::deserialize_mapping( cParser &Input ) { 1.0f : 0.01f * static_cast( Random( 100.0 - variation, 100.0 + variation ) ) ); } + else if( key == "startoffset:" ) { + m_startoffset = + clamp( + Input.getToken( false, "\n\r\t ,;" ), + 0.0f, 1.0f ); + } else if( key.compare( 0, std::min( key.size(), 5 ), "pitch" ) == 0 ) { // sound chunk pitch, defined with key pitchX where X = activation threshold auto const indexstart { key.find_first_of( "1234567890" ) }; diff --git a/sound.h b/sound.h index 455d6d7c..d810fee0 100644 --- a/sound.h +++ b/sound.h @@ -102,6 +102,11 @@ public: name( std::string Name ); std::string const & name() const; + // playback starting point shift setter/getter + void + start( float const Offset ); + float const & + start() const; // returns true if there isn't any sound buffer associated with the object, false otherwise bool empty() const; @@ -204,7 +209,8 @@ private: std::string m_name; int m_flags {}; // requested playback parameters sound_properties m_properties; // current properties of the emitted sounds - float m_pitchvariation {}; // emitter-specific shift in base pitch + float m_pitchvariation {}; // emitter-specific shift for base pitch + float m_startoffset {}; // emitter-specific shift for playback starting point bool m_stop { false }; // indicates active sample instances should be terminated /* bool m_stopend { false }; // indicates active instances of optional ending sound should be terminated @@ -225,6 +231,9 @@ inline glm::vec3 const & sound_source::offset() const { return m_offset; } // sound source name setter/getter inline void sound_source::name( std::string Name ) { m_name = Name; } inline std::string const & sound_source::name() const { return m_name; } +// playback starting point shift setter/getter +inline void sound_source::start( float const Offset ) { m_startoffset = Offset; } +inline float const & sound_source::start() const { return m_startoffset; } // collection of sound sources present in the scene class sound_table : public basic_table { diff --git a/version.h b/version.h index 525cd064..4fdd6647 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 20 -#define VERSION_MINOR 106 +#define VERSION_MINOR 108 #define VERSION_REVISION 0