FlightGear next
audioident.cxx
Go to the documentation of this file.
1// audioident.cxx -- audible station identifiers
2//
3// Written by Torsten Dreyer, September 2011
4//
5// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21
22#include "audioident.hxx"
23#include <simgear/sg_inlines.h>
24#include <simgear/sound/sample_group.hxx>
25
26#include <Main/globals.hxx>
27#include <Sound/morse.hxx>
28
29AudioIdent::AudioIdent( const std::string & fx_name, const double interval_secs, const int frequency_hz ) :
30 _fx_name(fx_name),
31 _frequency(frequency_hz),
32 _timer(0.0),
33 _interval(interval_secs),
34 _running(false)
35{
36}
37
39{
40 auto soundManager = globals->get_subsystem<SGSoundMgr>();
41 if (!soundManager)
42 return; // sound disabled
43
44 _timer = 0.0;
45 _ident = "";
46 _running = false;
47 _sgr = globals->get_subsystem<SGSoundMgr>()->find("avionics", true);
48 _sgr->tie_to_listener();
49}
50
51void AudioIdent::stop()
52{
53 if (_sgr && _sgr->exists( _fx_name ) )
54 _sgr->stop( _fx_name );
55 _running = false;
56}
57
58void AudioIdent::start()
59{
60 if (!_sgr)
61 return;
62
63 _timer = _interval;
64 _sgr->play_once(_fx_name);
65 _running = true;
66}
67
68void AudioIdent::setVolumeNorm( double volumeNorm )
69{
70 if (!_sgr)
71 return;
72
73 SG_CLAMP_RANGE(volumeNorm, 0.0, 1.0);
74 SGSoundSample *sound = _sgr->find( _fx_name );
75 if ( sound != NULL ) {
76 sound->set_volume( volumeNorm );
77 }
78}
79
80void AudioIdent::setIdent( const std::string & ident, double volumeNorm )
81{
82 if (!_sgr)
83 return;
84
85 // Signal may flicker very frequently (due to our realistic newnavradio...).
86 // Avoid recreating identical sound samples all the time, instead turn off
87 // volume when signal is lost, and save the most recent sample.
88 if (ident.empty())
89 volumeNorm = 0;
90
91 // don't bother with sounds when volume is OFF anyway...
92 if ((_ident == ident ) || (volumeNorm == 0))
93 {
94 if (!_ident.empty())
95 setVolumeNorm(volumeNorm);
96 return;
97 }
98
99 try {
100 stop();
101
102 if ( _sgr->exists( _fx_name ) )
103 _sgr->remove( _fx_name );
104
105 if (!ident.empty()) {
106 SGSoundSample* sound = FGMorse::instance()->make_ident(ident, _frequency );
107 sound->set_volume( volumeNorm );
108 if (!_sgr->add( sound, _fx_name )) {
109 SG_LOG(SG_SOUND, SG_WARN, "Failed to add sound '" << _fx_name << "' for ident '" << ident << "'" );
110 delete sound;
111 return;
112 }
113
114 start();
115 }
116 _ident = ident;
117
118 } catch (sg_io_exception& e) {
119 SG_LOG(SG_SOUND, SG_ALERT, e.getFormattedMessage());
120 }
121
122}
123
124void AudioIdent::update( double dt )
125{
126 // single-shot
127 if( !_running || _interval < SGLimitsd::min() )
128 return;
129
130 _timer -= dt;
131
132 if( _timer < SGLimitsd::min() ) {
133 _timer = _interval;
134 stop();
135 start();
136 }
137}
138
139// FIXME: shall transmit at least 6 wpm (ICAO Annex 10 - 3.5.3.6.3)
140DMEAudioIdent::DMEAudioIdent( const std::string & fx_name )
141: AudioIdent( fx_name, 40, FGMorse::HI_FREQUENCY )
142{
143}
144
145
146//FIXME: for co-located VOR/DME or ILS/DME, assign four time-slots
147// 3xVOR/ILS ident, 1xDME ident
148
149// FIXME: shall transmit at approx. 7 wpm (ICAO Annex 10 - 3.3.6.5.1)
150VORAudioIdent::VORAudioIdent( const std::string & fx_name )
151: AudioIdent( fx_name, 10, FGMorse::LO_FREQUENCY )
152{
153}
154
155//FIXME: LOCAudioIdent at approx 7wpm (ICAO Annex 10 - 3.1.3.9.4)
156// not less than six times per minute at approx equal intervals
157// frequency 1020+/-50Hz (3.1.3.9.2)
158LOCAudioIdent::LOCAudioIdent( const std::string & fx_name )
159: AudioIdent( fx_name, 10, FGMorse::LO_FREQUENCY )
160{
161}
162
163
164// FIXME: NDBAudioIdent at approx 7 wpm (ICAO ANNEX 10 - 3.4.5.1)
165// at least once every 10s (3.4.5.2.1)
166// frequency 1020+/-50Hz or 400+/-25Hz (3.4.5.4)
void init()
void setIdent(const std::string &ident, double volumeNorm)
void setVolumeNorm(double volumeNorm)
void update(double dt)
AudioIdent(const std::string &fx_name, const double interval_secs, const int frequency)
DMEAudioIdent(const std::string &fx_name)
SGSoundSample * make_ident(const std::string &id, const int freq=LO_FREQUENCY)
Definition morse.cxx:141
static FGMorse * instance()
Definition morse.cxx:250
LOCAudioIdent(const std::string &fx_name)
VORAudioIdent(const std::string &fx_name)
FGGlobals * globals
Definition globals.cxx:142