mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
sound transcripts, event-started sound persistence
This commit is contained in:
@@ -1039,12 +1039,12 @@ event_manager::CheckQuery() {
|
||||
static_cast<int>( m_workevent->Params[ 1 ].asdouble ) );
|
||||
}
|
||||
else {
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive );
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::event );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case -1: {
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::looping );
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::looping | sound_flags::event );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
23
Globals.cpp
23
Globals.cpp
@@ -1050,28 +1050,11 @@ void TTranscripts::AddLine(std::string const &txt, float show, float hide, bool
|
||||
}
|
||||
*/
|
||||
};
|
||||
void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
|
||||
void TTranscripts::Add(std::string const &txt, bool backgorund)
|
||||
{ // dodanie tekstów, długość dźwięku, czy istotne
|
||||
if (true == txt.empty())
|
||||
return; // pusty tekst
|
||||
/*
|
||||
int i = 0, j = int(0.5 + 10.0 * len); //[0.1s]
|
||||
if (*txt == '[')
|
||||
{ // powinny być dwa nawiasy
|
||||
while (*++txt ? *txt != ']' : false)
|
||||
if ((*txt >= '0') && (*txt <= '9'))
|
||||
i = 10 * i + int(*txt - '0'); // pierwsza liczba aż do ]
|
||||
if (*txt ? *++txt == '[' : false)
|
||||
{
|
||||
j = 0; // drugi nawias określa czas zakończenia wyświetlania
|
||||
while (*++txt ? *txt != ']' : false)
|
||||
if ((*txt >= '0') && (*txt <= '9'))
|
||||
j = 10 * j + int(*txt - '0'); // druga liczba aż do ]
|
||||
if (*txt)
|
||||
++txt; // pominięcie drugiego ]
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
std::string asciitext{ txt }; win1250_to_ascii( asciitext ); // TODO: launch relevant conversion table based on language
|
||||
cParser parser( asciitext );
|
||||
while( true == parser.getTokens( 3, false, "[]\n" ) ) {
|
||||
@@ -1088,7 +1071,7 @@ void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
|
||||
std::string transcript; parser >> transcript;
|
||||
while( false == transcript.empty() ) {
|
||||
|
||||
WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
|
||||
// WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
|
||||
AddLine( transcript, 0.0, 0.12 * transcript.size(), false );
|
||||
transcript = ""; parser >> transcript;
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
~TTranscripts();
|
||||
void AddLine(std::string const &txt, float show, float hide, bool it);
|
||||
// dodanie tekstów, długość dźwięku, czy istotne
|
||||
void Add(std::string const &txt, float len, bool background = false);
|
||||
void Add(std::string const &txt, bool background = false);
|
||||
// usuwanie niepotrzebnych (ok. 10 razy na sekundę)
|
||||
void Update();
|
||||
};
|
||||
|
||||
16
audio.cpp
16
audio.cpp
@@ -65,6 +65,8 @@ openal_buffer::openal_buffer( std::string const &Filename ) :
|
||||
// and get rid of the source, we shouldn't need it anymore
|
||||
// TBD, TODO: delay data fetching and transfers until the buffer is actually used?
|
||||
std::vector<std::int16_t>().swap( data );
|
||||
|
||||
fetch_caption();
|
||||
}
|
||||
|
||||
// mix specified number of interleaved multi-channel data, down to mono
|
||||
@@ -87,6 +89,20 @@ openal_buffer::narrow_to_mono( std::uint16_t const Channelcount ) {
|
||||
}
|
||||
}
|
||||
|
||||
// retrieves sound caption in currently set language
|
||||
void
|
||||
openal_buffer::fetch_caption() {
|
||||
|
||||
std::string captionfilename { name };
|
||||
captionfilename.erase( captionfilename.rfind( '.' ) ); // obcięcie rozszerzenia
|
||||
captionfilename += "-" + Global::asLang + ".txt"; // już może być w różnych językach
|
||||
if( true == FileExists( captionfilename ) ) {
|
||||
// wczytanie
|
||||
std::ifstream inputfile( captionfilename );
|
||||
caption.assign( std::istreambuf_iterator<char>( inputfile ), std::istreambuf_iterator<char>() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
buffer_manager::~buffer_manager() {
|
||||
|
||||
7
audio.h
7
audio.h
@@ -20,11 +20,16 @@ ALuint const null_resource{ ~( ALuint { 0 } ) };
|
||||
struct openal_buffer {
|
||||
// members
|
||||
ALuint id { null_resource }; // associated AL resource
|
||||
unsigned int rate { 0 }; // sample rate of the data
|
||||
unsigned int rate {}; // sample rate of the data
|
||||
std::string name;
|
||||
std::string caption;
|
||||
// constructors
|
||||
openal_buffer() = default;
|
||||
explicit openal_buffer( std::string const &Filename );
|
||||
// methods
|
||||
// retrieves sound caption in currently set language
|
||||
void
|
||||
fetch_caption();
|
||||
|
||||
private:
|
||||
// methods
|
||||
|
||||
@@ -162,8 +162,11 @@ openal_source::bind( sound_source *Controller, uint32_sequence Sounds, Iterator_
|
||||
std::vector<ALuint> buffers;
|
||||
std::for_each(
|
||||
First, Last,
|
||||
[&]( audio::buffer_handle const &buffer ) {
|
||||
buffers.emplace_back( audio::renderer.buffer( buffer ).id ); } );
|
||||
[&]( audio::buffer_handle const &bufferhandle ) {
|
||||
auto const &buffer { audio::renderer.buffer( bufferhandle ) };
|
||||
buffers.emplace_back( buffer.id );
|
||||
if( false == buffer.caption.empty() ) {
|
||||
Global::tranTexts.Add( buffer.caption ); } } );
|
||||
|
||||
if( id != audio::null_resource ) {
|
||||
::alSourceQueueBuffers( id, static_cast<ALsizei>( buffers.size() ), buffers.data() );
|
||||
|
||||
21
scene.cpp
21
scene.cpp
@@ -122,16 +122,9 @@ basic_cell::update_events() {
|
||||
void
|
||||
basic_cell::update_sounds() {
|
||||
|
||||
// sounds
|
||||
auto const deltatime = Timer::GetDeltaRenderTime();
|
||||
for( auto *sound : m_sounds ) {
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
if( ( sound->GetStatus() & DSBSTATUS_PLAYING ) == DSBPLAY_LOOPING ) {
|
||||
sound->Play( 1, DSBPLAY_LOOPING, true, sound->vSoundPosition );
|
||||
sound->AdjFreq( 1.0, deltatime );
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
sound->play_event();
|
||||
}
|
||||
// TBD, TODO: move to sound renderer
|
||||
for( auto *path : m_paths ) {
|
||||
@@ -350,11 +343,7 @@ basic_cell::insert( TAnimModel *Instance ) {
|
||||
|
||||
// adds provided sound instance to the cell
|
||||
void
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
basic_cell::insert( TTextSound *Sound ) {
|
||||
#else
|
||||
basic_cell::insert( sound_source *Sound ) {
|
||||
#endif
|
||||
|
||||
m_active = true;
|
||||
|
||||
@@ -1177,13 +1166,7 @@ basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad )
|
||||
|
||||
// inserts provided sound in the region
|
||||
void
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
basic_region::insert_sound( TTextSound *Sound, scratch_data &Scratchpad ) {
|
||||
#else
|
||||
basic_region::insert_sound( sound_source *Sound, scratch_data &Scratchpad ) {
|
||||
#endif
|
||||
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Sound->location();
|
||||
|
||||
@@ -1195,8 +1178,6 @@ basic_region::insert_sound( sound_source *Sound, scratch_data &Scratchpad ) {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: sound node \"" + Sound->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
// inserts provided event launcher in the region
|
||||
|
||||
8
scene.h
8
scene.h
@@ -149,11 +149,7 @@ private:
|
||||
using path_sequence = std::vector<TTrack *>;
|
||||
using traction_sequence = std::vector<TTraction *>;
|
||||
using instance_sequence = std::vector<TAnimModel *>;
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
using sound_sequence = std::vector<TTextSound *>;
|
||||
#else
|
||||
using sound_sequence = std::vector<sound_source *>;
|
||||
#endif
|
||||
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
||||
// methods
|
||||
void
|
||||
@@ -320,11 +316,7 @@ public:
|
||||
insert_instance( TAnimModel *Instance, scratch_data &Scratchpad );
|
||||
// inserts provided sound in the region
|
||||
void
|
||||
#ifdef EU07_USE_OLD_SOUNDCODE
|
||||
insert_sound( TTextSound *Sound, scratch_data &Scratchpad );
|
||||
#else
|
||||
insert_sound( sound_source *Sound, scratch_data &Scratchpad );
|
||||
#endif
|
||||
// inserts provided event launcher in the region
|
||||
void
|
||||
insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad );
|
||||
|
||||
20
sound.cpp
20
sound.cpp
@@ -289,6 +289,10 @@ sound_source::play( int const Flags ) {
|
||||
// if the sound is disabled altogether or nothing can be emitted from this source, no point wasting time
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: we cache the flags early, even if the sound is out of range, to mark activated event sounds
|
||||
m_flags = Flags;
|
||||
|
||||
if( m_range > 0 ) {
|
||||
auto const cutoffrange { m_range * 5 };
|
||||
if( glm::length2( location() - glm::dvec3 { Global::pCameraPosition } ) > std::min( 2750.f * 2750.f, cutoffrange * cutoffrange ) ) {
|
||||
@@ -304,8 +308,6 @@ sound_source::play( int const Flags ) {
|
||||
m_pitchvariation = 0.01f * static_cast<float>( Random( 97.5, 102.5 ) );
|
||||
}
|
||||
|
||||
m_flags = Flags;
|
||||
|
||||
if( sound( sound_id::main ).buffer != null_handle ) {
|
||||
// basic variant: single main sound, with optional bookends
|
||||
play_basic();
|
||||
@@ -401,12 +403,26 @@ sound_source::compute_combined_point() const {
|
||||
) * 100.f;
|
||||
}
|
||||
|
||||
// maintains playback of sounds started by event
|
||||
void
|
||||
sound_source::play_event() {
|
||||
|
||||
if( true == TestFlag( m_flags, ( sound_flags::event | sound_flags::looping ) ) ) {
|
||||
// events can potentially start scenery sounds out of the sound's audible range
|
||||
// such sounds are stopped on renderer side, but unless stopped by the simulation keep their activation flags
|
||||
// we use this to discern event-started sounds which should be re-activated if the listener gets close enough
|
||||
play( m_flags );
|
||||
}
|
||||
}
|
||||
|
||||
// stops currently active play commands controlled by this emitter
|
||||
void
|
||||
sound_source::stop( bool const Skipend ) {
|
||||
|
||||
// if the source was stopped on simulation side, we should play the opening bookend next time it's activated
|
||||
m_playbeginning = true;
|
||||
// clear the event flags to discern between manual stop and out-of-range/sound-end stop
|
||||
m_flags = 0;
|
||||
|
||||
if( false == is_playing() ) { return; }
|
||||
|
||||
|
||||
12
sound.h
12
sound.h
@@ -30,7 +30,8 @@ enum sound_parameters {
|
||||
|
||||
enum sound_flags {
|
||||
looping = 0x1, // the main sample will be looping; implied for multi-sounds
|
||||
exclusive = 0x2 // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
|
||||
exclusive = 0x2, // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
|
||||
event = 0x80 // sound was activated by an event; we should keep note of the activation state for the update() calls it may receive
|
||||
};
|
||||
|
||||
enum class sound_placement {
|
||||
@@ -64,6 +65,9 @@ public:
|
||||
// issues contextual play commands for the audio renderer
|
||||
void
|
||||
play( int const Flags = 0 );
|
||||
// maintains playback of sounds started by event
|
||||
void
|
||||
play_event();
|
||||
// stops currently active play commands controlled by this emitter
|
||||
void
|
||||
stop( bool const Skipend = false );
|
||||
@@ -194,15 +198,15 @@ private:
|
||||
sound_placement m_placement;
|
||||
float m_range { 50.f }; // audible range of the emitted sounds
|
||||
std::string m_name;
|
||||
int m_flags { 0 }; // requested playback parameters
|
||||
int m_flags {}; // requested playback parameters
|
||||
sound_properties m_properties; // current properties of the emitted sounds
|
||||
float m_pitchvariation { 0.f }; // emitter-specific shift in base pitch
|
||||
float m_pitchvariation {}; // emitter-specific shift in base pitch
|
||||
bool m_stop { false }; // indicates active sample instances should be terminated
|
||||
bool m_playbeginning { true }; // indicates started sounds should be preceeded by opening bookend if there's one
|
||||
std::array<sound_data, 3> m_sounds { {} }; // basic sounds emitted by the source, main and optional bookends
|
||||
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
|
||||
bool m_soundchunksempty { true }; // helper, cached check whether sample table is linked with any actual samples
|
||||
int m_crossfaderange {}; // range of transition from one chunk to another
|
||||
int m_crossfaderange {}; // range of transition from one chunk to another
|
||||
};
|
||||
|
||||
// owner setter/getter
|
||||
|
||||
Reference in New Issue
Block a user