1 // voiceplayer.cxx -- voice/sound sample player
3 // Written by Jean-Yves Lefort, started September 2005.
5 // Copyright (C) 2005, 2006 Jean-Yves Lefort - jylefort@FreeBSD.org
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 ///////////////////////////////////////////////////////////////////////////////
24 # pragma warning( disable: 4355 )
39 #include <simgear/debug/logstream.hxx>
40 #include <simgear/sound/soundmgr_openal.hxx>
41 #include <simgear/structure/exception.hxx>
45 #if defined( HAVE_VERSION_H ) && HAVE_VERSION_H
46 # include <Include/version.h>
48 # include <Include/no_version.h>
51 #include "voiceplayer.hxx"
53 ///////////////////////////////////////////////////////////////////////////////
54 // constants //////////////////////////////////////////////////////////////////
55 ///////////////////////////////////////////////////////////////////////////////
58 ///////////////////////////////////////////////////////////////////////////////
59 // helpers ////////////////////////////////////////////////////////////////////
60 ///////////////////////////////////////////////////////////////////////////////
61 #define ADD_VOICE(Var,Sample,Twice) \
62 { make_voice(&Var);append(Var,Sample);\
63 if (Twice) append(Var,Sample); }
65 #define test_bits(_bits, _test) (((_bits) & (_test)) != 0)
67 ///////////////////////////////////////////////////////////////////////////////
68 // FGVoicePlayer //////////////////////////////////////////////////////////////
69 ///////////////////////////////////////////////////////////////////////////////
72 FGVoicePlayer::Speaker::bind (SGPropertyNode *node)
74 // uses xmlsound property names
75 tie(node, "volume", &volume);
76 tie(node, "pitch", &pitch);
80 FGVoicePlayer::Speaker::update_configuration ()
82 map< string, SGSharedPtr<SGSoundSample> >::iterator iter;
83 for (iter = player->samples.begin(); iter != player->samples.end(); iter++)
85 SGSoundSample *sample = (*iter).second;
87 sample->set_pitch(pitch);
91 player->voice->volume_changed();
94 FGVoicePlayer::Voice::~Voice ()
96 for (iter = elements.begin(); iter != elements.end(); iter++)
97 delete *iter; // we owned the element
102 FGVoicePlayer::Voice::play ()
104 iter = elements.begin();
107 element->play(get_volume());
111 FGVoicePlayer::Voice::stop (bool now)
115 if (now || element->silence)
121 iter = elements.end() - 1; // stop after the current element finishes
126 FGVoicePlayer::Voice::set_volume (float _volume)
133 FGVoicePlayer::Voice::volume_changed ()
136 element->set_volume(get_volume());
140 FGVoicePlayer::Voice::update ()
144 if (! element->is_playing())
146 if (++iter == elements.end())
151 element->play(get_volume());
157 FGVoicePlayer::~FGVoicePlayer ()
159 vector<Voice *>::iterator iter1;
160 for (iter1 = _voices.begin(); iter1 != _voices.end(); iter1++)
167 FGVoicePlayer::bind (SGPropertyNode *node, const char* default_dir_prefix)
169 dir_prefix = node->getStringValue("voice/file-prefix", default_dir_prefix);
174 FGVoicePlayer::init ()
176 SGSoundMgr *smgr = globals->get_soundmgr();
177 _sgr = smgr->find("avionics", true);
178 _sgr->tie_to_listener();
179 speaker.update_configuration();
183 FGVoicePlayer::pause()
196 FGVoicePlayer::resume()
208 FGVoicePlayer::get_sample (const char *name)
211 refname = dev_name + "/" + dir_prefix + name;
213 SGSoundSample *sample = _sgr->find(refname);
216 string filename = dir_prefix + string(name) + ".wav";
219 sample = new SGSoundSample(filename.c_str(), SGPath());
221 catch (const sg_exception &e)
223 SG_LOG(SG_INSTR, SG_ALERT, "Error loading sound sample \"" + filename + "\": " + e.getFormattedMessage());
227 _sgr->add(sample, refname);
228 samples[refname] = sample;
235 FGVoicePlayer::play (Voice *_voice, unsigned int flags)
239 if (test_bits(flags, PLAY_NOW) || ! voice ||
240 (voice->element && voice->element->silence))
246 looped = test_bits(flags, PLAY_LOOPED);
257 next_looped = test_bits(flags, PLAY_LOOPED);
262 FGVoicePlayer::stop (unsigned int flags)
266 voice->stop(test_bits(flags, STOP_NOW));
276 FGVoicePlayer::set_volume (float _volume)
280 voice->volume_changed();
284 FGVoicePlayer::update ()
292 if (! voice->element || voice->element->silence)
295 looped = next_looped;
305 if (! voice->element)