FlightGear next
voiceplayer.hxx
Go to the documentation of this file.
1// voiceplayer.hxx -- voice/sound sample player
2//
3// Written by Jean-Yves Lefort, started September 2005.
4//
5// Copyright (C) 2005, 2006 Jean-Yves Lefort - jylefort@FreeBSD.org
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 St, Fifth Floor, Boston, MA 02110-1301, USA.
20
21
22#ifndef __SOUND_VOICEPLAYER_HXX
23#define __SOUND_VOICEPLAYER_HXX
24
25#include <assert.h>
26
27#include <vector>
28#include <deque>
29#include <map>
30
31#include <simgear/props/props.hxx>
32#include <simgear/props/tiedpropertylist.hxx>
33
34class SGSampleGroup;
35class SGSoundSample;
36
37#include <Main/globals.hxx>
38
39#ifdef _MSC_VER
40# pragma warning( push )
41# pragma warning( disable: 4355 )
42#endif
43
45// FGVoicePlayer /////////////////////////////////////////////////////
47
49{
50public:
51
53 // MK::RawValueMethodsData /////////////////////////////////////////////
55
56 template <class C, class VT, class DT>
57 class RawValueMethodsData : public SGRawValue<VT>
58 {
59 public:
60 typedef VT (C::*getter_t) (DT) const;
61 typedef void (C::*setter_t) (DT, VT);
62
63 RawValueMethodsData (C &obj, DT data, getter_t getter = 0, setter_t setter = 0)
64 : _obj(obj), _data(data), _getter(getter), _setter(setter) {}
65
66 virtual VT getValue () const
67 {
68 if (_getter)
69 return (_obj.*_getter)(_data);
70 else
71 return SGRawValue<VT>::DefaultValue();
72 }
73 virtual bool setValue (VT value)
74 {
75 if (_setter)
76 {
77 (_obj.*_setter)(_data, value);
78 return true;
79 }
80 else
81 return false;
82 }
83 virtual SGRawValue<VT> *clone () const
84 {
85 return new RawValueMethodsData<C,VT,DT>(_obj, _data, _getter, _setter);
86 }
87
88 private:
89 C &_obj;
90 DT _data;
91 getter_t _getter;
92 setter_t _setter;
93 };
94
95 class PropertiesHandler : public simgear::TiedPropertyList
96 {
97 public:
98
99 template <class T>
100 inline void tie (SGPropertyNode *node, const SGRawValue<T> &raw_value)
101 {
102 Tie(node,raw_value);
103 }
104
105 template <class T>
106 inline void tie (SGPropertyNode *node,
107 const char *relative_path,
108 const SGRawValue<T> &raw_value)
109 {
110 Tie(node->getNode(relative_path, true),raw_value);
111 }
112
114
115 void unbind () {Untie();}
116 };
117
119 // FGVoicePlayer::Voice ////////////////////////////////////////////
121
122 class Voice
123 {
124 public:
125
127 // FGVoicePlayer::Voice::Element ////////////////////////////////////////
129
131 {
132 public:
134
135 virtual ~Element() {}
136 virtual inline void play (float volume) {}
137 virtual inline void stop () {}
138 virtual bool is_playing () = 0;
139 virtual inline void set_volume (float volume) {}
140 };
141
143 // FGVoicePlayer::Voice::SampleElement ///////////////////////////
145
146 class SampleElement : public Element
147 {
148 SGSharedPtr<SGSoundSample> _sample;
149 float _volume;
150
151 public:
152 SampleElement (SGSharedPtr<SGSoundSample> sample, float volume = 1.0);
153
154 virtual void play (float volume);
155 virtual void stop ();
156 virtual bool is_playing ();
157 virtual void set_volume (float volume);
158 };
159
161 // FGVoicePlayer::Voice::SilenceElement //////////////////////////
163
164 class SilenceElement : public Element
165 {
166 double _duration;
167 double start_time;
168
169 public:
170 inline SilenceElement (double duration)
171 : _duration(duration) { silence = true; }
172
173 virtual inline void play (float volume) { start_time = globals->get_sim_time_sec(); }
174 virtual inline bool is_playing () { return globals->get_sim_time_sec() - start_time < _duration; }
175 };
176
178 // FGVoicePlayer::Voice (continued) //////////////////////////////
180
182
183 inline Voice (FGVoicePlayer *_player)
184 : element(NULL), player(_player), volume(1.0) {}
185
186 virtual ~Voice ();
187
188 inline void append (Element *_element) { elements.push_back(_element); }
189
190 void play ();
191 void stop (bool now);
192 void set_volume (float _volume);
193 void volume_changed ();
194 void update ();
195
196 private:
197 FGVoicePlayer *player;
198
199 float volume;
200
201 std::vector<Element *> elements;
202 std::vector<Element *>::iterator iter;
203
204 inline float get_volume () const { return player->volume * player->speaker.volume * volume; }
205 };
206
208 // FGVoicePlayer (continued) ///////////////////////////////////////
210
211 struct
212 {
213 float volume;
215
216 float volume;
217
220 bool paused;
221 std::string dev_name;
222 std::string dir_prefix;
223
224 FGVoicePlayer (PropertiesHandler* properties_handler, std::string _dev_name);
225
226 virtual ~FGVoicePlayer ();
227
228 void init ();
229 void pause();
230 void resume();
231 bool is_playing() { return (voice!=NULL);}
232
233 enum
234 {
235 PLAY_NOW = 1 << 0,
236 PLAY_LOOPED = 1 << 1
237 };
238 void play (Voice *_voice, unsigned int flags = 0);
239
240 enum
241 {
242 STOP_NOW = 1 << 0
243 };
244 void stop (unsigned int flags = 0);
245
246 void set_volume (float _volume);
247 void update ();
248
249 void bind (SGPropertyNode *node, const char* default_dir_prefix);
250
251public:
252
254 // FGVoicePlayer::Speaker //////////////////////////////////////////
256
258 {
259 FGVoicePlayer *player;
260 PropertiesHandler* properties_handler;
261
262 double pitch;
263
264 template <class T>
265 inline void tie (SGPropertyNode *node, const char *name, T *ptr)
266 {
267 properties_handler->tie
268 (node, (std::string("speaker/") + name).c_str(),
270 (*this, ptr,
273 }
274
275 public:
276 template <class T>
277 inline void set_property (T *ptr, T value) { *ptr = value; update_configuration(); }
278
279 template <class T>
280 inline T get_property (T *ptr) const { return *ptr; }
281
282 float volume;
283
284 inline Speaker (FGVoicePlayer *_player,PropertiesHandler* _properties_handler)
285 : player(_player),
286 properties_handler(_properties_handler),
287 pitch(1),
288 volume(1)
289 {
290 }
291
292 void bind (SGPropertyNode *node);
293 void update_configuration ();
294 };
295
296protected:
298 // FGVoicePlayer (continued) ///////////////////////////////////////
300
301 SGSharedPtr<SGSampleGroup> _sgr;
303
304 std::map< std::string, SGSharedPtr<SGSoundSample> > samples;
305 std::vector<Voice *> _voices;
306
307 bool looped;
309
310 SGSoundSample *get_sample (const char *name);
311
312 inline void append (Voice *voice, Voice::Element *element) { voice->append(element); }
313 void append (Voice *voice, const char *sample_name);
314 inline void append (Voice *voice, double silence) { voice->append(new Voice::SilenceElement(silence)); }
315
316 inline void make_voice (Voice **voice) { *voice = new Voice(this); _voices.push_back(*voice); }
317
318 template <class T1>
319 inline void make_voice (Voice **voice, T1 e1) { make_voice(voice); append(*voice, e1); }
320 template <class T1, class T2>
321 inline void make_voice (Voice **voice, T1 e1, T2 e2) { make_voice(voice, e1); append(*voice, e2); }
322 template <class T1, class T2, class T3>
323 inline void make_voice (Voice **voice, T1 e1, T2 e2, T3 e3) { make_voice(voice, e1, e2); append(*voice, e3); }
324 template <class T1, class T2, class T3, class T4>
325 inline void make_voice (Voice **voice, T1 e1, T2 e2, T3 e3, T4 e4) { make_voice(voice, e1, e2, e3); append(*voice, e4); }
326};
327
328#endif // __SOUND_VOICEPLAYER_HXX
void tie(SGPropertyNode *node, const char *relative_path, const SGRawValue< T > &raw_value)
void tie(SGPropertyNode *node, const SGRawValue< T > &raw_value)
virtual bool setValue(VT value)
virtual SGRawValue< VT > * clone() const
RawValueMethodsData(C &obj, DT data, getter_t getter=0, setter_t setter=0)
T get_property(T *ptr) const
Speaker(FGVoicePlayer *_player, PropertiesHandler *_properties_handler)
void set_property(T *ptr, T value)
void bind(SGPropertyNode *node)
virtual void play(float volume)
virtual void set_volume(float volume)
SampleElement(SGSharedPtr< SGSoundSample > sample, float volume=1.0)
virtual void set_volume(float volume)
virtual void play(float volume)
void set_volume(float _volume)
void append(Element *_element)
void stop(bool now)
Voice(FGVoicePlayer *_player)
virtual ~FGVoicePlayer()
SGSharedPtr< SGSampleGroup > _sgr
void make_voice(Voice **voice, T1 e1, T2 e2)
void make_voice(Voice **voice)
struct FGVoicePlayer::@054217056221357017171266312225347342161325347250 conf
void make_voice(Voice **voice, T1 e1, T2 e2, T3 e3, T4 e4)
void set_volume(float _volume)
void bind(SGPropertyNode *node, const char *default_dir_prefix)
SGSoundSample * get_sample(const char *name)
void append(Voice *voice, double silence)
void make_voice(Voice **voice, T1 e1)
void append(Voice *voice, Voice::Element *element)
std::string dev_name
void play(Voice *_voice, unsigned int flags=0)
std::map< std::string, SGSharedPtr< SGSoundSample > > samples
void make_voice(Voice **voice, T1 e1, T2 e2, T3 e3)
std::vector< Voice * > _voices
FGVoicePlayer(PropertiesHandler *properties_handler, std::string _dev_name)
std::string dir_prefix
void stop(unsigned int flags=0)
const char * name
FGGlobals * globals
Definition globals.cxx:142
#define C