From 1df53cfc6c47d85a63ae7c795ca8b50a3e4db8de Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 25 Aug 2018 22:44:09 +0200 Subject: [PATCH] build 180825. radio message playback enhancements and fixes --- Train.cpp | 73 +++++++++++++++++++++++++++++++++++-------------------- Train.h | 3 ++- sound.cpp | 9 +++++-- version.h | 2 +- 4 files changed, 56 insertions(+), 31 deletions(-) diff --git a/Train.cpp b/Train.cpp index f059b765..d1a73140 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5703,16 +5703,6 @@ bool TTrain::Update( double const Deltatime ) // sounds update_sounds( Deltatime ); - if( false == m_radiomessages.empty() ) { - // erase completed radio messages from the list - m_radiomessages.erase( - std::remove_if( - std::begin( m_radiomessages ), std::end( m_radiomessages ), - []( sound_source const &source ) { - return ( false == source.is_playing() ); } ), - std::end( m_radiomessages ) ); - } - return true; //(DynamicObject->Update(dt)); } // koniec update @@ -5921,14 +5911,7 @@ TTrain::update_sounds( double const Deltatime ) { } } - // radiostop - if( ( true == mvOccupied->Radio ) - && ( true == mvOccupied->RadioStopFlag ) ) { - m_radiostop.play( sound_flags::exclusive | sound_flags::looping ); - } - else { - m_radiostop.stop(); - } + update_sounds_radio(); if( fTachoCount >= 3.f ) { auto const frequency { ( @@ -5996,6 +5979,37 @@ void TTrain::update_sounds_runningnoise( sound_source &Sound ) { } } +void TTrain::update_sounds_radio() { + + if( false == m_radiomessages.empty() ) { + // erase completed radio messages from the list + m_radiomessages.erase( + std::remove_if( + std::begin( m_radiomessages ), std::end( m_radiomessages ), + []( auto const &source ) { + return ( false == source.second->is_playing() ); } ), + std::end( m_radiomessages ) ); + } + // adjust audibility of remaining messages based on current radio conditions + auto const radioenabled { ( true == mvOccupied->Radio ) && ( mvControlled->Battery || mvControlled->ConverterFlag ) }; + for( auto &message : m_radiomessages ) { + auto const volume { + ( true == radioenabled ) + && ( message.first == iRadioChannel ) ? + 1.0 : + 0.0 }; + message.second->gain( volume ); + } + // radiostop + if( ( true == radioenabled ) + && ( true == mvOccupied->RadioStopFlag ) ) { + m_radiostop.play( sound_flags::exclusive | sound_flags::looping ); + } + else { + m_radiostop.stop(); + } +} + bool TTrain::CabChange(int iDirection) { // McZapkie-090902: zmiana kabiny 1->0->2 i z powrotem if( ( DynamicObject->Mechanik == nullptr ) @@ -6613,23 +6627,28 @@ void TTrain::DynamicSet(TDynamicObject *d) void TTrain::radio_message( sound_source *Message, int const Channel ) { - if( ( false == mvOccupied->Radio ) - || ( iRadioChannel != Channel ) ) { - // skip message playback if the radio isn't able to receive it - return; - } auto const soundrange { Message->range() }; if( ( soundrange > 0 ) && ( glm::length2( Message->location() - glm::dvec3 { DynamicObject->GetPosition() } ) > ( soundrange * soundrange ) ) ) { // skip message playback if the receiver is outside of the emitter's range return; } - - m_radiomessages.emplace_back( m_radiosound ); + // NOTE: we initiate playback of all sounds in range, in case the user switches on the radio or tunes to the right channel mid-play + m_radiomessages.emplace_back( + Channel, + std::make_shared( m_radiosound ) ); // assign sound to the template and play it - m_radiomessages.back() + auto &message = *( m_radiomessages.back().second.get() ); + auto const radioenabled { ( true == mvOccupied->Radio ) && ( mvControlled->Battery || mvControlled->ConverterFlag ) }; + auto const volume { + ( true == radioenabled ) + && ( Channel == iRadioChannel ) ? + 1.0 : + 0.0 }; + message .copy_sounds( *Message ) - .play( sound_flags::exclusive ); + .gain( volume ) + .play(); } void TTrain::SetLights() diff --git a/Train.h b/Train.h index f2c57078..d365f4c0 100644 --- a/Train.h +++ b/Train.h @@ -143,6 +143,7 @@ class TTrain // update function subroutines void update_sounds( double const Deltatime ); void update_sounds_runningnoise( sound_source &Sound ); + void update_sounds_radio(); // command handlers // NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis @@ -599,7 +600,7 @@ public: // reszta może by?publiczna 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 m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages - std::vector m_radiomessages; // list of currently played radio messages + std::vector>> m_radiomessages; // list of currently played radio messages sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) diff --git a/sound.cpp b/sound.cpp index 0189721c..aceec296 100644 --- a/sound.cpp +++ b/sound.cpp @@ -338,8 +338,13 @@ sound_source::copy_sounds( sound_source const &Source ) { m_sounds = Source.m_sounds; m_soundchunks = Source.m_soundchunks; m_soundchunksempty = Source.m_soundchunksempty; - // NOTE: should probably zero the .playing fields here as precaution - // TODO: add this if we ever start copying sounds from active sources + // reset source's playback counters + for( auto &sound : m_sounds ) { + sound.playing = 0; + } + for( auto &sound : m_soundchunks ) { + sound.first.playing = 0; + } return *this; } diff --git a/version.h b/version.h index c945cd61..3b5b4521 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 18 -#define VERSION_MINOR 809 +#define VERSION_MINOR 825 #define VERSION_REVISION 0