X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FSound%2Ffg_fx.cxx;h=5537bb1195b80743a59005658aa6499ed1829383;hb=db89cf202adc795b27e1bbf85162e8ec137a760d;hp=53c0ceda57d709da259e5147305caa953db7b09f;hpb=bc20e9b4905cb1464316417fe29d611511d3a364;p=flightgear.git diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 53c0ceda5..5537bb119 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -1,9 +1,9 @@ -// fgfx.cxx -- Sound effect management class implementation +// fg_fx.cxx -- Sound effect management class implementation // // Started by David Megginson, October 2001 // (Reuses some code from main.cxx, probably by Curtis Olson) // -// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -21,122 +21,99 @@ // // $Id$ -#include "fg_fx.hxx" +#ifdef _MSC_VER +#pragma warning (disable: 4786) +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#ifdef __BORLANDC__ +# define exception c_exception +#endif +#include +#include +#include + #include
-// FIXME: remove direct dependencies -#include +#include "fg_fx.hxx" -FGFX::FGFX () - : _old_flap_position(0), - _engine(0), - _crank(0), - _wind(0), - _stall(0), - _rumble(0), - _flaps(0), - _squeal(0), - _click(0), - _engine_running_prop(0), - _engine_cranking_prop(0), - _stall_warning_prop(0), - _flaps_prop(0) +FGFX::FGFX () : + last_pause( true ), + last_volume( 0.0 ), + _pause( fgGetNode("/sim/sound/pause") ), + _volume( fgGetNode("/sim/sound/volume") ) { } FGFX::~FGFX () { - // FIXME: is this right, or does the - // sound manager assume pointer ownership? - delete _engine; - delete _crank; - delete _wind; - delete _stall; - delete _rumble; + unsigned int i; + for ( i = 0; i < _sound.size(); i++ ) { + delete _sound[i]; + } + _sound.clear(); - delete _flaps; - delete _squeal; - delete _click; + while ( _samplequeue.size() > 0 ) { + delete _samplequeue.front(); + _samplequeue.pop(); + } } - void -FGFX::init () +FGFX::init() { - FGSoundMgr * mgr = globals->get_soundmgr(); - - // - // Create and add the engine sound - // - _engine = - new FGSimpleSound(fgGetString("/sim/sounds/engine", "Sounds/wasp.wav")); - mgr->add(_engine, "engine"); - - // - // Create and add the cranking sound. - // - _crank = new FGSimpleSound(fgGetString("/sim/sounds/cranking", - "Sounds/cranking.wav")); - _crank->set_pitch(1.5); - _crank->set_volume(0.25); - mgr->add(_crank, "crank"); - - - // - // Create and add the wind noise. - // - _wind = new FGSimpleSound(fgGetString("/sim/sounds/wind", - "Sounds/wind.wav")); - mgr->add(_wind, "wind"); - - - // - // Create and add the stall noise. - // - _stall = new FGSimpleSound(fgGetString("/sim/sounds/stall", - "Sounds/stall.wav")); - mgr->add(_stall, "stall"); - - // - // Create and add the rumble noise. - // - _rumble = new FGSimpleSound(fgGetString("/sim/sounds/rumble", - "Sounds/rumble.wav")); - mgr->add(_rumble, "rumble"); - - - // - // Create and add the flaps noise - // - _flaps = new FGSimpleSound(fgGetString("/sim/sounds/flaps", - "Sounds/flaps.wav")); - mgr->add(_flaps, "flaps"); - - // - // Create and add the squeal noise. - // - _squeal = new FGSimpleSound(fgGetString("/sim/sounds/squeal", - "Sounds/squeal.wav")); - mgr->add(_squeal, "squeal"); - - // - // Create and add the click noise. - _click = new FGSimpleSound(fgGetString("/sim/sounds/click", - "Sounds/click.wav")); - mgr->add(_click, "click"); - - - //////////////////////////////////////////////////////////////////// - // Grab some properties. - //////////////////////////////////////////////////////////////////// - - _engine_running_prop = fgGetNode("/engines/engine[0]/running", true); - _engine_cranking_prop = fgGetNode("/engines/engine[0]/cranking", true); - _stall_warning_prop = fgGetNode("/sim/aircraft/alarms/stall-warning", true); - _flaps_prop = fgGetNode("/controls/flaps", true); + SGPropertyNode *node = fgGetNode("/sim/sound", true); + int i; + + string path_str = node->getStringValue("path"); + SGPath path( globals->get_fg_root() ); + if (path_str.empty()) { + SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file."); + return; + } + + path.append(path_str.c_str()); + SG_LOG(SG_GENERAL, SG_INFO, "Reading sound " << node->getName() + << " from " << path.str()); + + SGPropertyNode root; + try { + readProperties(path.str(), &root); + } catch (const sg_exception &) { + SG_LOG(SG_GENERAL, SG_ALERT, + "Incorrect path specified in configuration file"); + return; + } + + node = root.getNode("fx"); + for (i = 0; i < node->nChildren(); i++) { + SGXmlSound *sound = new SGXmlSound(); + + try { + sound->init(globals->get_props(), node->getChild(i), + globals->get_soundmgr(), globals->get_fg_root()); + + _sound.push_back(sound); + } catch ( sg_io_exception &e ) { + SG_LOG(SG_GENERAL, SG_ALERT, e.getFormattedMessage()); + delete sound; + } + } } +void +FGFX::reinit() +{ + _sound.clear(); + init(); +}; + void FGFX::bind () { @@ -148,163 +125,74 @@ FGFX::unbind () } void -FGFX::update () +FGFX::update (double dt) { - FGSoundMgr * mgr = globals->get_soundmgr(); - - - //////////////////////////////////////////////////////////////////// - // Update the engine sound. - //////////////////////////////////////////////////////////////////// - - if (_engine_running_prop->getBoolValue()) { - // pitch corresponds to rpm - // volume corresponds to manifold pressure - - double rpm_factor; - if ( cur_fdm_state->get_num_engines() > 0 ) - rpm_factor = cur_fdm_state->get_engine(0)->get_RPM() / 2500.0; - else - rpm_factor = 1.0; - - double pitch = 0.3 + rpm_factor * 3.0; - - // don't run at absurdly slow rates -- not realistic - // and sounds bad to boot. :-) - if (pitch < 0.7) - pitch = 0.7; - if (pitch > 5.0) - pitch = 5.0; - - double mp_factor; - if ( cur_fdm_state->get_num_engines() > 0 ) - mp_factor = cur_fdm_state->get_engine(0)->get_Manifold_Pressure() / 100; - else - mp_factor = 0.3; - - double volume = 0.15 + mp_factor / 2.0; - - if (volume < 0.15) - volume = 0.15; - if (volume > 0.5) - volume = 0.5; - - _engine->set_pitch( pitch ); - _engine->set_volume( volume ); - set_playing("engine", true); - } else { - set_playing("engine", false); - } - - - //////////////////////////////////////////////////////////////////// - // Update the cranking sound. - //////////////////////////////////////////////////////////////////// - - // FIXME - set_playing("crank", _engine_cranking_prop->getBoolValue()); - - - //////////////////////////////////////////////////////////////////// - // Update the wind noise. - //////////////////////////////////////////////////////////////////// - - float rel_wind = cur_fdm_state->get_V_rel_wind(); // FPS - if (rel_wind > 60.0) { // a little off 30kt - float volume = rel_wind/1200.0; // FIXME!!! - _wind->set_volume(volume); - set_playing("wind", true); - } else { - set_playing("wind", false); - } - - - //////////////////////////////////////////////////////////////////// - // Update the stall horn. - //////////////////////////////////////////////////////////////////// - - double stall = _stall_warning_prop->getDoubleValue(); - if (stall > 0.0) { - _stall->set_volume(stall); - set_playing("stall", true); - } else { - set_playing("stall", false); - } - - - //////////////////////////////////////////////////////////////////// - // Update the rumble. - //////////////////////////////////////////////////////////////////// - - float totalGear = min(cur_fdm_state->get_num_gear(), MAX_GEAR); - float gearOnGround = 0; - - - // Calculate whether a squeal is - // required, and set the volume. - // Currently, the squeal volume is the - // current local down velocity in feet - // per second divided by 10.0, and - // will not be played if under 0.1. - - // FIXME: take rotational velocities - // into account as well. - for (int i = 0; i < totalGear; i++) { - if (cur_fdm_state->get_gear_unit(i)->GetWoW()) { - gearOnGround++; - if (!_gear_on_ground[i]) { - double squeal_volume = cur_fdm_state->get_V_down() / 5.0; - if (squeal_volume > 0.1) { - _squeal->set_volume(squeal_volume); - mgr->play_once("squeal"); - } - _gear_on_ground[i] = true; - } - } else { - _gear_on_ground[i] = false; + SGSoundMgr *smgr = globals->get_soundmgr(); + + // command sound manger + bool pause = _pause->getBoolValue(); + if ( pause != last_pause ) { + if ( pause ) { + smgr->pause(); + } else { + smgr->resume(); + } + last_pause = pause; } - } - // Now, if any of the gear is in - // contact with the ground play the - // rumble sound. The volume is the - // absolute velocity in knots divided - // by 120.0. No rumble will be played - // if the velocity is under 6kt. - double speed = cur_fdm_state->get_V_equiv_kts(); - if (gearOnGround > 0 && speed >= 6.0) { - double volume = (gearOnGround/totalGear) * (speed/60.0); - _rumble->set_volume(volume); - set_playing("rumble", true); - } else { - set_playing("rumble", false); - } - - - //////////////////////////////////////////////////////////////////////// - // Check for flap movement. - //////////////////////////////////////////////////////////////////// - - double flap_position = _flaps_prop->getDoubleValue(); - if (fabs(flap_position - _old_flap_position) > 0.1) { - mgr->play_once("flaps"); - _old_flap_position = flap_position; - } + // process mesage queue + const string msgid = "Sequential Audio Message"; + bool is_playing = false; + if ( smgr->exists( msgid ) ) { + if ( smgr->is_playing( msgid ) ) { + // still playing, do nothing + is_playing = true; + } else { + // current message finished, stop and remove + smgr->stop( msgid ); // removes source + smgr->remove( msgid ); // removes buffer + } + } + if ( !is_playing ) { + // message queue idle, add next sound if we have one + if ( _samplequeue.size() > 0 ) { + smgr->add( _samplequeue.front(), msgid ); + _samplequeue.pop(); + smgr->play_once( msgid ); + } + } - // TODO: click + double volume = _volume->getDoubleValue(); + if ( volume != last_volume ) { + smgr->set_volume( volume ); + last_volume = volume; + } + if ( !pause ) { + // update sound effects if not paused + for ( unsigned int i = 0; i < _sound.size(); i++ ) { + _sound[i]->update(dt); + } + } } - +/** + * add a sound sample to the message queue which is played sequentially + * in order. + */ void -FGFX::set_playing (const char * soundName, bool state) +FGFX::play_message( SGSoundSample *_sample ) { - FGSoundMgr * mgr = globals->get_soundmgr(); - bool playing = mgr->is_playing(soundName); - if (state && !playing) - mgr->play_looped(soundName); - else if (!state && playing) - mgr->stop(soundName); + _sample->set_volume( 1.0 ); + _samplequeue.push( _sample ); } +void +FGFX::play_message( const string path, const string fname ) +{ + SGSoundSample *sample; + sample = new SGSoundSample( path.c_str(), fname.c_str() ); + play_message( sample ); +} + // end of fg_fx.cxx