16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 03:09:18 +02:00

audio source reinitialization fix, sound volume level tweaks

This commit is contained in:
tmj-fstate
2017-11-30 16:37:25 +01:00
parent ef2195fbcc
commit 34f96595fd
9 changed files with 222 additions and 160 deletions

View File

@@ -2987,7 +2987,8 @@ void TController::Doors(bool what)
if (mvOccupied->DoorOpenCtrl == 1)
{ // jeśli drzwi sterowane z kabiny
if( AIControllFlag ) {
if( mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened ) { // AI zamyka drzwi przed odjazdem
if( mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened ) {
// AI zamyka drzwi przed odjazdem
if( ( true == mvOccupied->DoorClosureWarning )
&& ( false == mvOccupied->DepartureSignal )
&& ( true == TestFlag( iDrivigFlags, moveDoorOpened ) ) ) {
@@ -3092,8 +3093,8 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
asNextStop = TrainParams->NextStop();
iDrivigFlags |= movePrimary; // skoro dostał rozkład, to jest teraz głównym
NewCommand = Global::asCurrentSceneryPath + NewCommand + ".wav"; // na razie jeden
if (FileExists(NewCommand))
{ // wczytanie dźwięku odjazdu podawanego bezpośrenido
if (FileExists(NewCommand)) {
// wczytanie dźwięku odjazdu podawanego bezpośrenido
#ifdef EU07_USE_OLD_SOUNDCODE
tsGuardSignal =
new TTextSound(
@@ -3101,19 +3102,15 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
pVehicle->GetPosition().x, pVehicle->GetPosition().y, pVehicle->GetPosition().z,
false);
#else
tsGuardSignal = new sound_source( sound_placement::external );
tsGuardSignal = new sound_source( sound_placement::external, 75.f );
tsGuardSignal->deserialize( NewCommand, sound_type::single );
tsGuardSignal->owner( pVehicle );
// place virtual conductor some distance away
tsGuardSignal->offset( { pVehicle->MoverParameters->Dim.W * -0.75f, 1.7f, fLength * -0.25f } );
#endif
iGuardRadio = 0; // nie przez radio
}
else
{
else {
NewCommand = NewCommand.insert(NewCommand.find_last_of("."),"radio"); // wstawienie przed kropkč
if (FileExists(NewCommand))
{ // wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
if (FileExists(NewCommand)) {
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
#ifdef EU07_USE_OLD_SOUNDCODE
tsGuardSignal =
new TTextSound(
@@ -3121,12 +3118,8 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
pVehicle->GetPosition().x, pVehicle->GetPosition().y, pVehicle->GetPosition().z,
false);
#else
tsGuardSignal = new sound_source( sound_placement::external );
tsGuardSignal = new sound_source( sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE );
tsGuardSignal->deserialize( NewCommand, sound_type::single );
tsGuardSignal->owner( pVehicle );
// command will be transmitted by radio
// TODO: put the exact location in the proper cab
tsGuardSignal->offset( { 0.f, 1.f, pVehicle->MoverParameters->Dim.L * 0.75f } );
#endif
iGuardRadio = iRadioChannel;
}
@@ -4487,20 +4480,21 @@ TController::UpdateSituation(double dt) {
}
if (VelDesired > 0.0)
if( ( ( iDrivigFlags & moveStopHere ) == 0 )
|| ( ( SemNextIndex != -1 )
&& ( SemNextIndex < sSpeedTable.size() ) // BUG: index can point at non-existing slot. investigate reason(s)
&& ( sSpeedTable[SemNextIndex].fVelNext != 0.0 ) ) ) {
|| ( ( SemNextIndex != -1 )
&& ( SemNextIndex < sSpeedTable.size() ) // BUG: index can point at non-existing slot. investigate reason(s)
&& ( sSpeedTable[SemNextIndex].fVelNext != 0.0 ) ) ) {
// jeśli można jechać, to odpalić dźwięk kierownika oraz zamknąć drzwi w
// składzie, jeśli nie mamy czekać na sygnał też trzeba odpalić
if (iDrivigFlags & moveGuardSignal)
{ // komunikat od kierownika tu, bo musi być wolna droga i odczekany czas stania
iDrivigFlags &= ~moveGuardSignal; // tylko raz nadać
/*
if( ( iDrivigFlags & moveDoorOpened )
&& ( false == mvOccupied->DoorOpenCtrl ) ) {
// jeśli drzwi otwarte, niesterowane przez maszynistę
Doors( false ); // a EZT zamknie dopiero po odegraniu komunikatu kierownika
}
*/
if( tsGuardSignal != nullptr ) {
#ifdef EU07_USE_OLD_SOUNDCODE
tsGuardSignal->Stop();
@@ -4513,11 +4507,14 @@ TController::UpdateSituation(double dt) {
// pobliżu, a drugi radiowy, słyszalny w innych lokomotywach
// na razie zakładam, że to nie jest dźwięk radiowy, bo trzeba by zrobić
// obsługę kanałów radiowych itd.
if( !iGuardRadio ) {
if( iGuardRadio == 0 ) {
// jeśli nie przez radio
#ifdef EU07_USE_OLD_SOUNDCODE
tsGuardSignal->Play( 1.0, 0, !FreeFlyModeFlag, pVehicle->GetPosition() ); // dla true jest głośniej
#else
tsGuardSignal->owner( pVehicle );
// place virtual conductor some distance away
tsGuardSignal->offset( { pVehicle->MoverParameters->Dim.W * -0.75f, 1.7f, std::min( -20.0, -0.2 * fLength ) } );
tsGuardSignal->play( sound_flags::exclusive );
#endif
}
@@ -4526,15 +4523,18 @@ TController::UpdateSituation(double dt) {
// if (!FreeFlyModeFlag) //obserwator musi być w środku pojazdu
// (albo może mieć radio przenośne) - kierownik mógłby powtarzać
// przy braku reakcji
#ifdef EU07_USE_OLD_SOUNDCODE
if( SquareMagnitude( pVehicle->GetPosition() - Global::pCameraPosition ) < 2000 * 2000 ) {
// w odległości mniejszej niż 2km
#ifdef EU07_USE_OLD_SOUNDCODE
tsGuardSignal->Play( 1.0, 0, true, pVehicle->GetPosition() ); // dźwięk niby przez radio
#else
// TODO: proper system for sending/receiving radio messages
tsGuardSignal->play( sound_flags::exclusive );
#endif
}
#else
// TODO: proper system for sending/receiving radio messages
// place the sound in appropriate cab of the manned vehicle
tsGuardSignal->owner( pVehicle );
tsGuardSignal->offset( { 0.f, 2.f, pVehicle->MoverParameters->Dim.L * 0.4f * ( pVehicle->MoverParameters->ActiveCab < 0 ? -1 : 1 ) } );
tsGuardSignal->play( sound_flags::exclusive );
#endif
}
}
}

View File

@@ -3605,6 +3605,8 @@ void TDynamicObject::RenderSounds() {
double volume { 1.0 };
double const dt { Timer::GetDeltaRenderTime() };
if( dt == 0.0 ) { return; }
// engine sounds
if( MoverParameters->Power > 0 ) {
@@ -3889,7 +3891,7 @@ void TDynamicObject::RenderSounds() {
}
else {
eng_turbo = std::max( goalpitch, eng_turbo - changerate * 0.5 );
volume = std::max( 0.0, sTurbo.gain() - 10.0 * dt );
volume = std::max( 0.0, sTurbo.gain() - 2.0 * dt );
if( volume > 0.05 ) {
sTurbo
.pitch( 0.4 + eng_turbo * 0.4 )
@@ -3943,7 +3945,7 @@ void TDynamicObject::RenderSounds() {
// brake system and braking sounds:
if( m_lastbrakepressure != -1.f ) {
// calculate rate of pressure change 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 };
m_brakepressurechange = interpolate<float>( m_brakepressurechange, 10 * ( brakepressuredifference / dt ), 0.1f );
}
@@ -3951,7 +3953,7 @@ void TDynamicObject::RenderSounds() {
if( m_brakepressurechange > 0.05f ) {
// NOTE: can't use the leak rate directly due to irregular results produced by some brake type implementations
rsUnbrake
.gain( static_cast<float>( std::max( MoverParameters->BrakePress, 0.0 ) / MoverParameters->MaxBrakePress[ 3 ] ) )
.gain( static_cast<float>( 1.25 * std::max( MoverParameters->BrakePress, 0.0 ) / MoverParameters->MaxBrakePress[ 3 ] ) )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
@@ -4164,13 +4166,13 @@ void TDynamicObject::RenderSounds() {
}
// scale volume by track quality
volume *= ( 20.0 + MyTrack->iDamageFlag ) / 21;
// scale volume with curve radius and vehicle speed
// scale volume with vehicle speed
// TBD, TODO: disable the scaling for sounds combined from speed-based samples?
volume *=
interpolate(
0.0, 1.0,
clamp(
MoverParameters->Vel / 80.0,
MoverParameters->Vel / 60.0,
0.0, 1.0 ) );
rsRunningNoise
.pitch( clamp( frequency, 0.5, 1.15 ) ) // arbitrary limits to prevent the pitch going out of whack

214
Train.cpp
View File

@@ -5130,120 +5130,128 @@ bool TTrain::Update( double const Deltatime )
void
TTrain::update_sounds( double const Deltatime ) {
#ifdef EU07_USE_OLD_SOUNDCODE
double vol = 0;
// int freq=1;
double dfreq;
if( Deltatime == 0.0 ) { return; }
double volume { 0.0 };
double const brakevolumescale { 0.5 };
// McZapkie-280302 - syczenie
if( ( mvOccupied->BrakeHandle == FV4a ) || ( mvOccupied->BrakeHandle == FVel6 ) ) {
if( rsHiss.AM != 0 ) // upuszczanie z PG
{
fPPress = ( 1 * fPPress + mvOccupied->Handle->GetSound( s_fv4a_b ) ) / ( 2 );
if( fPPress > 0 ) {
vol = 2.0 * rsHiss.AM * fPPress;
}
if( vol > 0.001 ) {
rsHiss.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHiss.Stop();
}
// TODO: softer volume reduction than plain abrupt stop, perhaps as reusable wrapper?
if( ( mvOccupied->BrakeHandle == FV4a )
|| ( mvOccupied->BrakeHandle == FVel6 ) ) {
// upuszczanie z PG
fPPress = interpolate<float>( fPPress, mvOccupied->Handle->GetSound( s_fv4a_b ), 0.05 );
volume = (
fPPress > 0 ?
rsHiss.m_amplitudefactor * fPPress * 0.25 :
0 );
if( volume * brakevolumescale > 0.05 ) {
rsHiss
.gain( volume * brakevolumescale )
.play( sound_flags::exclusive | sound_flags::looping );
}
if( rsHissU.AM != 0 ) // upuszczanie z PG
{
fNPress = ( 1 * fNPress + mvOccupied->Handle->GetSound( s_fv4a_u ) ) / ( 2 );
if( fNPress > 0 ) {
vol = rsHissU.AM * fNPress;
}
if( vol > 0.001 ) {
rsHissU.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHissU.Stop();
}
else {
rsHiss.stop();
}
if( rsHissE.AM != 0 ) // upuszczanie przy naglym
{
vol = mvOccupied->Handle->GetSound( s_fv4a_e ) * rsHissE.AM;
if( vol > 0.001 ) {
rsHissE.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHissE.Stop();
}
// napelnianie PG
fNPress = interpolate<float>( fNPress, mvOccupied->Handle->GetSound( s_fv4a_u ), 0.25 );
volume = (
fNPress > 0 ?
rsHissU.m_amplitudefactor * fNPress :
0 );
if( volume * brakevolumescale > 0.05 ) {
rsHissU
.gain( volume * brakevolumescale )
.play( sound_flags::exclusive | sound_flags::looping );
}
if( rsHissX.AM != 0 ) // upuszczanie sterujacego fala
{
vol = mvOccupied->Handle->GetSound( s_fv4a_x ) * rsHissX.AM;
if( vol > 0.001 ) {
rsHissX.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHissX.Stop();
}
else {
rsHissU.stop();
}
if( rsHissT.AM != 0 ) // upuszczanie z czasowego
{
vol = mvOccupied->Handle->GetSound( s_fv4a_t ) * rsHissT.AM;
if( vol > 0.001 ) {
rsHissT.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHissT.Stop();
}
// upuszczanie przy naglym
volume = mvOccupied->Handle->GetSound( s_fv4a_e ) * rsHissE.m_amplitudefactor;
if( volume * brakevolumescale > 0.05 ) {
rsHissE
.gain( volume * brakevolumescale )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
rsHissE.stop();
}
// upuszczanie sterujacego fala
volume = mvOccupied->Handle->GetSound( s_fv4a_x ) * rsHissX.m_amplitudefactor;
if( volume * brakevolumescale > 0.05 ) {
rsHissX
.gain( volume * brakevolumescale )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
rsHissX.stop();
}
// upuszczanie z czasowego
volume = mvOccupied->Handle->GetSound( s_fv4a_t ) * rsHissT.m_amplitudefactor;
if( volume * brakevolumescale > 0.05 ) {
rsHissT
.gain( volume * brakevolumescale )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
rsHissT.stop();
}
} // koniec FV4a
else // jesli nie FV4a
{
if( rsHiss.AM != 0.0 ) // upuszczanie z PG
{
fPPress = ( 4.0f * fPPress + std::max( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
if( fPPress > 0.0f ) {
vol = 2.0 * rsHiss.AM * fPPress;
}
if( vol > 0.01 ) {
rsHiss.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHiss.Stop();
}
} else {
// jesli nie FV4a
// upuszczanie z PG
fPPress = ( 4.0f * fPPress + std::max( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
volume = (
fPPress > 0.0f ?
2.0 * rsHiss.m_amplitudefactor * fPPress :
0.0 );
if( volume > 0.05 ) {
rsHiss
.gain( volume )
.play( sound_flags::exclusive | sound_flags::looping );
}
if( rsHissU.AM != 0.0 ) // napelnianie PG
{
fNPress = ( 4.0f * fNPress + Min0R( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
if( fNPress < 0.0f ) {
vol = -1.0 * rsHissU.AM * fNPress;
}
if( vol > 0.01 ) {
rsHissU.Play( vol, DSBPLAY_LOOPING, true, DynamicObject->GetPosition() );
}
else {
rsHissU.Stop();
}
else {
rsHiss.stop();
}
// napelnianie PG
fNPress = ( 4.0f * fNPress + Min0R( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
volume = (
fNPress < 0.0f ?
-1.0 * rsHissU.m_amplitudefactor * fNPress :
0.0 );
if( volume > 0.01 ) {
rsHissU
.gain( volume )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
rsHissU.stop();
}
} // koniec nie FV4a
// Winger-160404 - syczenie pomocniczego (luzowanie)
/* if (rsSBHiss.AM!=0)
{
fSPPress=(mvOccupied->LocalBrakeRatio())-(mvOccupied->LocalBrakePos);
if (fSPPress>0)
{
vol=2*rsSBHiss.AM*fSPPress;
}
if (vol>0.1)
{
rsSBHiss.Play(vol,DSBPLAY_LOOPING,true,DynamicObject->GetPosition());
}
else
{
rsSBHiss.Stop();
}
}
*/
#endif
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
@@ -5400,6 +5408,10 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
// syk:
rsHiss.deserialize( parser, sound_type::single, sound_parameters::amplitude );
rsHiss.owner( DynamicObject );
if( true == rsSBHiss.empty() ) {
// fallback for vehicles without defined local brake hiss sound
rsSBHiss = rsHiss;
}
}
else if (token == "airsound2:")
{

View File

@@ -410,6 +410,8 @@ public: // reszta może by?publiczna
sound_source rsHissX { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // fala
sound_source rsHissT { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // czasowy
sound_source rsSBHiss { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // local
float m_lastlocalbrakepressure { -1.f }; // helper, cached level 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 dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
@@ -461,7 +463,7 @@ private:
bool bHeat[8]; // grzanie
// McZapkie: do syczenia
float fPPress, fNPress;
float fSPPress, fSNPress;
// float fSPPress, fSNPress;
int iSekunda; // Ra: sekunda aktualizacji pr?dko?ci
int iRadioChannel; // numer aktualnego kana?u radiowego
TPythonScreens pyScreens;

View File

@@ -128,7 +128,18 @@ buffer_manager::create( std::string const &Filename ) {
return emplace( filelookup );
}
}
// if dynamic-specific lookup finds nothing, try the default sound folder
if( filename.find( '/' ) != std::string::npos ) {
// if the filename includes path, try to use it directly
lookup = find_buffer( filename );
if( lookup != null_handle ) {
return lookup;
}
filelookup = find_file( filename );
if( false == filelookup.empty() ) {
return emplace( filelookup );
}
}
// if dynamic-specific and/or direct lookups find nothing, try the default sound folder
lookup = find_buffer( szSoundPath + filename );
if( lookup != null_handle ) {
return lookup;

View File

@@ -33,6 +33,12 @@ void
openal_source::stop() {
loop( false );
// NOTE: workaround for potential edge cases where ::alSourceStop() doesn't set source which wasn't yet started to AL_STOPPED
int state;
::alGetSourcei( id, AL_SOURCE_STATE, &state );
if( state == AL_INITIAL ) {
play();
}
::alSourceStop( id );
is_playing = false;
}
@@ -43,7 +49,6 @@ openal_source::update( double const Deltatime ) {
update_deltatime = Deltatime; // cached for time-based processing of data from the controller
// TODO: test whether the emitter was within range during the last tick, potentially update the counter and flag it for timeout
::alGetSourcei( id, AL_BUFFERS_PROCESSED, &buffer_index );
// for multipart sounds trim away processed sources until only one remains, the last one may be set to looping by the controller
ALuint bufferid;
@@ -53,9 +58,11 @@ openal_source::update( double const Deltatime ) {
buffers.erase( std::begin( buffers ) );
--buffer_index;
}
int state;
::alGetSourcei( id, AL_SOURCE_STATE, &state );
is_playing = ( state == AL_PLAYING );
// request instructions from the controller
controller->update( *this );
}
@@ -75,6 +82,7 @@ openal_source::sync_with( sound_properties const &State ) {
if( glm::length2( sourceoffset ) > std::max( ( sound_range * sound_range ), ( EU07_SOUND_CUTOFFRANGE * EU07_SOUND_CUTOFFRANGE ) ) ) {
// range cutoff check
stop();
is_synced = false; // flag sync failure for the controller
return;
}
if( sound_range >= 0 ) {
@@ -101,6 +109,7 @@ openal_source::sync_with( sound_properties const &State ) {
::alSourcef( id, AL_PITCH, properties.base_pitch * pitch_variation );
}
is_synced = true;
}
// sets max audible distance for sounds emitted by the source
@@ -145,20 +154,18 @@ openal_source::loop( bool const State ) {
// NOTE: doesn't release allocated implementation-side source
void
openal_source::clear() {
controller = nullptr;
// unqueue bound buffers:
// ensure no buffer is in use...
stop();
// ...prepare space for returned ids of unqueued buffers (not that we need that info)...
std::vector<ALuint> bufferids;
bufferids.resize( buffers.size() );
// ...release the buffers and update source data to match
// ...release the buffers...
::alSourceUnqueueBuffers( id, bufferids.size(), bufferids.data() );
buffers.clear();
buffer_index = 0;
// reset properties
properties = sound_properties();
// ...and reset reset the properties, except for the id of the allocated source
auto const sourceid { id };
*this = openal_source();
id = sourceid;
}

View File

@@ -36,9 +36,10 @@ struct openal_source {
ALuint id { audio::null_resource }; // associated AL resource
sound_source *controller { nullptr }; // source controller
buffer_sequence buffers; // sequence of samples the source will emit
int buffer_index; // currently queued sample from the buffer sequence
int buffer_index { 0 }; // currently queued sample from the buffer sequence
bool is_playing { false };
bool is_looping { false };
bool is_synced { true }; // set to false only if a sync attempt fails
sound_properties properties;
// methods

View File

@@ -108,10 +108,10 @@ sound_source::play( int const Flags ) {
// TODO: support for parameter-driven sound table
if( m_soundbegin.buffer != null_handle ) {
std::vector<audio::buffer_handle> bufferlist { m_soundbegin.buffer, m_soundmain.buffer };
audio::renderer.insert( this, std::begin( bufferlist ), std::end( bufferlist ) );
insert( std::begin( bufferlist ), std::end( bufferlist ) );
}
else {
audio::renderer.insert( this, m_soundmain.buffer );
insert( m_soundmain.buffer );
}
}
else {
@@ -119,7 +119,7 @@ sound_source::play( int const Flags ) {
if( ( m_soundbegin.buffer == null_handle )
&& ( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) == 0 ) ) {
// for single part non-looping samples we allow spawning multiple instances, if not prevented by set flags
audio::renderer.insert( this, m_soundmain.buffer );
insert( m_soundmain.buffer );
}
}
}
@@ -135,7 +135,7 @@ sound_source::stop() {
if( ( m_soundend.buffer != null_handle )
&& ( m_soundend.buffer != m_soundmain.buffer ) ) { // end == main can happen in malformed legacy cases
// spawn potentially defined sound end sample, if the emitter is currently active
audio::renderer.insert( this, m_soundend.buffer );
insert( m_soundend.buffer );
}
}
@@ -154,10 +154,6 @@ sound_source::update( audio::openal_source &Source ) {
}
return;
}
// check and update if needed current sound properties
update_location();
update_placement_gain();
Source.sync_with( m_properties );
if( m_soundbegin.buffer != null_handle ) {
// potentially a multipart sound
@@ -170,26 +166,41 @@ sound_source::update( audio::openal_source &Source ) {
++( m_soundmain.playing );
}
}
// check and update if needed current sound properties
update_location();
update_placement_gain();
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
update_counter( Source.buffers[ Source.buffer_index ], -1 );
}
}
else {
// if the emitter isn't playing it's either done or wasn't yet started
// we can determine this from number of processed buffers
if( Source.buffer_index != Source.buffers.size() ) {
auto const buffer { Source.buffers[ Source.buffer_index ] };
update_counter( buffer, 1 );
// emitter initialization
Source.range( m_range );
Source.pitch( m_pitchvariation );
update_location();
update_placement_gain();
Source.sync_with( m_properties );
if( ( buffer == m_soundmain.buffer )
&& ( true == TestFlag( m_flags, sound_flags::looping ) ) ) {
// main sample can be optionally set to loop
Source.loop( true );
}
// all set, start playback
Source.play();
Source.range( m_range );
Source.pitch( m_pitchvariation );
update_location();
update_placement_gain();
Source.sync_with( m_properties );
if( true == Source.is_synced ) {
// all set, start playback
Source.play();
}
else {
// if the initial sync went wrong we skip the activation so the renderer can clean the emitter on its end
update_counter( buffer, -1 );
}
}
else {
auto const buffer { Source.buffers[ Source.buffer_index - 1 ] };
@@ -339,4 +350,11 @@ sound_source::update_placement_gain() {
return true;
}
void
sound_source::insert( audio::buffer_handle Buffer ) {
std::vector<audio::buffer_handle> buffers { Buffer };
return insert( std::begin( buffers ), std::end( buffers ) );
}
//---------------------------------------------------------------------------

11
sound.h
View File

@@ -15,7 +15,7 @@ http://mozilla.org/MPL/2.0/.
float const EU07_SOUND_CABCONTROLSCUTOFFRANGE { 7.5f };
float const EU07_SOUND_BRAKINGCUTOFFRANGE { 100.f };
float const EU07_SOUND_RUNNINGNOISECUTOFFRANGE { 100.f };
float const EU07_SOUND_RUNNINGNOISECUTOFFRANGE { 200.f };
enum class sound_type {
single,
@@ -122,6 +122,15 @@ private:
// potentially updates area-based gain factor of the source. returns: true if location has changed
bool
update_placement_gain();
void
insert( audio::buffer_handle Buffer );
template <class Iterator_>
void
insert( Iterator_ First, Iterator_ Last ) {
audio::renderer.insert( this, First, Last );
update_counter( *First, 1 );
}
// members
TDynamicObject const * m_owner { nullptr }; // optional, the vehicle carrying this sound source