-// mk_viii.cxx -- Honeywell MK VIII EGPWS emulation
+// mk_viii.hxx -- Honeywell MK VIII EGPWS emulation
//
// Written by Jean-Yves Lefort, started September 2005.
//
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __INSTRUMENTS_MK_VIII_HXX
#include <map>
#include <simgear/props/props.hxx>
-#include <simgear/sound/sample_openal.hxx>
+#include <simgear/props/tiedpropertylist.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
-
using std::vector;
using std::deque;
using std::map;
#include <Airports/runways.hxx>
#include <Airports/simple.hxx>
#include <Main/globals.hxx>
+#include <Sound/voiceplayer.hxx>
#ifdef _MSC_VER
# pragma warning( push )
# pragma warning( disable: 4355 )
#endif
+
///////////////////////////////////////////////////////////////////////////////
// MK_VIII ////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// keep in sync with Mode6Handler::altitude_callout_definitions[]
static const unsigned n_altitude_callouts = 11;
- /////////////////////////////////////////////////////////////////////////////
- // MK_VIII::RawValueMethodsData /////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
-
- template <class C, class VT, class DT>
- class RawValueMethodsData : public SGRawValue<VT>
- {
- public:
- typedef VT (C::*getter_t) (DT) const;
- typedef void (C::*setter_t) (DT, VT);
-
- RawValueMethodsData (C &obj, DT data, getter_t getter = 0, setter_t setter = 0)
- : _obj(obj), _data(data), _getter(getter), _setter(setter) {}
-
- virtual VT getValue () const
- {
- if (_getter)
- return (_obj.*_getter)(_data);
- else
- return SGRawValue<VT>::DefaultValue();
- }
- virtual bool setValue (VT value)
- {
- if (_setter)
- {
- (_obj.*_setter)(_data, value);
- return true;
- }
- else
- return false;
- }
- virtual SGRawValue<VT> *clone () const
- {
- return new RawValueMethodsData<C,VT,DT>(_obj, _data, _getter, _setter);
- }
-
- private:
- C &_obj;
- DT _data;
- getter_t _getter;
- setter_t _setter;
- };
-
/////////////////////////////////////////////////////////////////////////////
// MK_VIII::Parameter ///////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// MK_VIII::PropertiesHandler ///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
- class PropertiesHandler
+ class PropertiesHandler : public FGVoicePlayer::PropertiesHandler
{
MK_VIII *mk;
- vector<SGPropertyNode_ptr> tied_properties;
-
public:
struct
{
SGPropertyNode_ptr altitude;
SGPropertyNode_ptr altitude_agl;
SGPropertyNode_ptr altitude_gear_agl;
+ SGPropertyNode_ptr altitude_radar_agl;
SGPropertyNode_ptr orientation_roll;
SGPropertyNode_ptr asi_serviceable;
SGPropertyNode_ptr asi_speed;
} external_properties;
inline PropertiesHandler (MK_VIII *device)
- : mk(device) {}
+ : FGVoicePlayer::PropertiesHandler(), mk(device) {}
- template <class T>
- inline void tie (SGPropertyNode *node, const SGRawValue<T> &raw_value)
- {
- node->tie(raw_value);
- tied_properties.push_back(node);
- }
-
- template <class T>
- inline void tie (SGPropertyNode *node,
- const char *relative_path,
- const SGRawValue<T> &raw_value)
- {
- tie(node->getNode(relative_path, true), raw_value);
- }
-
- PropertiesHandler() {};
+ PropertiesHandler() : FGVoicePlayer::PropertiesHandler() {}
void init ();
- void unbind ();
};
public:
bool alternate_steep_approach;
bool use_internal_gps;
bool localizer_enabled;
- bool use_gear_altitude;
+ int altitude_source;
bool use_attitude_indicator;
} conf;
void update_egpws_alert_discrete_2 ();
void update_egpwc_alert_discrete_3 ();
void update_outputs ();
+ void reposition ();
void update_lamps ();
void set_lamp (Lamp lamp);
typedef deque< Sample<double> > samples_type;
samples_type samples;
double value;
+ double last_update;
public:
inline TerrainClearanceFilter ()
- : value(0) {}
+ : value(0.0), last_update(-1.0) {}
double update (double agl);
void reset ();
bool *get_lamp_output (Lamp lamp);
};
-
- /////////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer /////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
-
- class VoicePlayer
+
+ class VoicePlayer : public FGVoicePlayer
{
public:
+ VoicePlayer (MK_VIII *device) :
+ FGVoicePlayer(&device->properties_handler, "mk-viii")
+ {}
- ///////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer::Voice ////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
-
- class Voice
- {
- public:
-
- /////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer::Voice::Element ////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
-
- class Element
- {
- public:
- bool silence;
-
- virtual inline void play (float volume) {}
- virtual inline void stop () {}
- virtual bool is_playing () = 0;
- virtual inline void set_volume (float volume) {}
- };
-
- /////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer::Voice::SampleElement ///////////////////////////
- /////////////////////////////////////////////////////////////////////////
-
- class SampleElement : public Element
- {
- SGSharedPtr<SGSoundSample> _sample;
- float _volume;
-
- public:
- inline SampleElement (SGSharedPtr<SGSoundSample> sample, float volume = 1.0)
- : _sample(sample), _volume(volume) { silence = false; }
-
- virtual inline void play (float volume) { if (_sample && (volume > 0.05)) { set_volume(volume); _sample->play_once(); } }
- virtual inline void stop () { if (_sample) _sample->stop(); }
- virtual inline bool is_playing () { return _sample ? _sample->is_playing() : false; }
- virtual inline void set_volume (float volume) { if (_sample) _sample->set_volume(volume * _volume); }
- };
-
- /////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer::Voice::SilenceElement //////////////////////////
- /////////////////////////////////////////////////////////////////////////
-
- class SilenceElement : public Element
- {
- double _duration;
- double start_time;
-
- public:
- inline SilenceElement (double duration)
- : _duration(duration) { silence = true; }
-
- virtual inline void play (float volume) { start_time = globals->get_sim_time_sec(); }
- virtual inline bool is_playing () { return globals->get_sim_time_sec() - start_time < _duration; }
- };
-
- /////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer::Voice (continued) //////////////////////////////
- /////////////////////////////////////////////////////////////////////////
-
- Element *element;
-
- inline Voice (VoicePlayer *_player)
- : element(NULL), player(_player), volume(1.0) {}
-
- ~Voice ();
-
- inline void append (Element *_element) { elements.push_back(_element); }
-
- void play ();
- void stop (bool now);
- void set_volume (float _volume);
- void volume_changed ();
- void update ();
-
- private:
- VoicePlayer *player;
-
- float volume;
-
- vector<Element *> elements;
- vector<Element *>::iterator iter;
-
- inline float get_volume () const { return player->volume * player->speaker.volume * volume; }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer (continued) ///////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
-
- struct
- {
- float volume;
- } conf;
-
- float volume;
-
- Voice *voice;
- Voice *next_voice;
-
- struct
- {
- Voice *application_data_base_failed;
- Voice *bank_angle;
- Voice *bank_angle_bank_angle;
- Voice *bank_angle_bank_angle_3;
- Voice *bank_angle_inop;
- Voice *bank_angle_pause_bank_angle;
- Voice *bank_angle_pause_bank_angle_3;
- Voice *callouts_inop;
- Voice *configuration_type_invalid;
- Voice *dont_sink;
- Voice *dont_sink_pause_dont_sink;
- Voice *five_hundred_above;
- Voice *glideslope;
- Voice *glideslope_inop;
- Voice *gpws_inop;
- Voice *hard_glideslope;
- Voice *minimums;
- Voice *minimums_minimums;
- Voice *pull_up;
- Voice *sink_rate;
- Voice *sink_rate_pause_sink_rate;
- Voice *soft_glideslope;
- Voice *terrain;
- Voice *terrain_pause_terrain;
- Voice *too_low_flaps;
- Voice *too_low_gear;
- Voice *too_low_terrain;
- Voice *altitude_callouts[n_altitude_callouts];
- } voices;
-
- inline VoicePlayer (MK_VIII *device)
- : voice(NULL), next_voice(NULL), mk(device), speaker(this) {}
-
- ~VoicePlayer ();
-
- void init ();
-
- enum
- {
- PLAY_NOW = 1 << 0,
- PLAY_LOOPED = 1 << 1
- };
- void play (Voice *_voice, unsigned int flags = 0);
-
- enum
- {
- STOP_NOW = 1 << 0
- };
- void stop (unsigned int flags = 0);
-
- void set_volume (float _volume);
- void update ();
-
- inline void bind (SGPropertyNode *node) { speaker.bind(node); }
-
- public:
-
- ///////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer::Speaker //////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
-
- class Speaker
- {
- VoicePlayer *player;
-
- double pitch;
-
- template <class T>
- inline void tie (SGPropertyNode *node, const char *name, T *ptr)
- {
- player->mk->properties_handler.tie
- (node, (string("speaker/") + name).c_str(),
- RawValueMethodsData<MK_VIII::VoicePlayer::Speaker,T,T*>
- (*this, ptr,
- &MK_VIII::VoicePlayer::Speaker::get_property,
- &MK_VIII::VoicePlayer::Speaker::set_property));
- }
-
- public:
- template <class T>
- inline void set_property (T *ptr, T value) { *ptr = value; update_configuration(); }
-
- template <class T>
- inline T get_property (T *ptr) const { return *ptr; }
-
- float volume;
+ ~VoicePlayer() {}
+ void init ();
- inline Speaker (VoicePlayer *_player)
- : player(_player),
- pitch(1),
- volume(1)
+ struct
{
- }
-
- void bind (SGPropertyNode *node);
- void update_configuration ();
- };
-
- private:
- ///////////////////////////////////////////////////////////////////////////
- // MK_VIII::VoicePlayer (continued) ///////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
-
- MK_VIII *mk;
-
- SGSharedPtr<SGSampleGroup> _sgr;
- Speaker speaker;
-
- map< string, SGSharedPtr<SGSoundSample> > samples;
- vector<Voice *> _voices;
-
- bool looped;
- bool next_looped;
-
- SGSoundSample *get_sample (const char *name);
-
- inline void append (Voice *voice, Voice::Element *element) { voice->append(element); }
- inline void append (Voice *voice, const char *sample_name) { voice->append(new Voice::SampleElement(get_sample(sample_name))); }
- inline void append (Voice *voice, double silence) { voice->append(new Voice::SilenceElement(silence)); }
-
- inline void make_voice (Voice **voice) { *voice = new Voice(this); _voices.push_back(*voice); }
-
- template <class T1>
- inline void make_voice (Voice **voice, T1 e1) { make_voice(voice); append(*voice, e1); }
- template <class T1, class T2>
- inline void make_voice (Voice **voice, T1 e1, T2 e2) { make_voice(voice, e1); append(*voice, e2); }
- template <class T1, class T2, class T3>
- inline void make_voice (Voice **voice, T1 e1, T2 e2, T3 e3) { make_voice(voice, e1, e2); append(*voice, e3); }
- template <class T1, class T2, class T3, class T4>
- inline void make_voice (Voice **voice, T1 e1, T2 e2, T3 e3, T4 e4) { make_voice(voice, e1, e2, e3); append(*voice, e4); }
+ Voice *application_data_base_failed;
+ Voice *bank_angle;
+ Voice *bank_angle_bank_angle;
+ Voice *bank_angle_bank_angle_3;
+ Voice *bank_angle_inop;
+ Voice *bank_angle_pause_bank_angle;
+ Voice *bank_angle_pause_bank_angle_3;
+ Voice *callouts_inop;
+ Voice *configuration_type_invalid;
+ Voice *dont_sink;
+ Voice *dont_sink_pause_dont_sink;
+ Voice *five_hundred_above;
+ Voice *glideslope;
+ Voice *glideslope_inop;
+ Voice *gpws_inop;
+ Voice *hard_glideslope;
+ Voice *minimums;
+ Voice *minimums_minimums;
+ Voice *pull_up;
+ Voice *sink_rate;
+ Voice *sink_rate_pause_sink_rate;
+ Voice *soft_glideslope;
+ Voice *terrain;
+ Voice *terrain_pause_terrain;
+ Voice *too_low_flaps;
+ Voice *too_low_gear;
+ Voice *too_low_terrain;
+ Voice *altitude_callouts[n_altitude_callouts];
+ } voices;
+
};
private: