#define _CONTROLS_HXX
#include <simgear/misc/props.hxx>
+
#include <Main/fgfs.hxx>
+#include <Main/globals.hxx>
#ifndef __cplusplus
# error This library requires C++
CLAMP( &rudder, -1.0, 1.0 );
}
inline void set_flaps( double pos ) {
+ if ( flaps != pos ) {
+ globals->get_soundmgr()->play_once( "flaps" );
+ }
flaps = pos;
CLAMP( &flaps, 0.0, 1.0 );
}
inline void move_flaps( double amt ) {
+ if ( fabs(amt) > 0.0 ) {
+ globals->get_soundmgr()->play_once( "flaps" );
+ }
flaps += amt;
CLAMP( &flaps, 0.0, 1.0 );
}
$Header$
$Log$
+Revision 1.19 2001/03/02 21:37:01 curt
+Added a first pass at a C++ sound manager class.
+
Revision 1.18 2000/12/13 22:02:02 curt
MacOS changes contributed by Darrell Walisser (12/13/2000)
add3( tempM, M_gear_v, M_gear_v );
- }
+ }
globals.cxx globals.hxx \
keyboard.cxx keyboard.hxx \
options.cxx options.hxx \
+ soundmgr.cxx soundmgr.hxx \
splash.cxx splash.hxx \
viewer.cxx viewer.hxx \
viewer_lookat.cxx viewer_lookat.hxx \
#include <simgear/timing/sg_time.hxx>
#include <simgear/misc/props.hxx>
+#include "soundmgr.hxx"
#include "viewmgr.hxx"
FG_USING_STD( vector );
// Global autopilot "route"
SGRoute *route;
+ // sound manager
+ FGSoundMgr *soundmgr;
+
// viewer maneger
FGViewMgr *viewmgr;
FGViewer *current_view;
inline SGRoute *get_route() const { return route; }
inline void set_route( SGRoute *r ) { route = r; }
+ inline FGSoundMgr *get_soundmgr() const { return soundmgr; }
+ inline void set_soundmgr( FGSoundMgr *sm ) { soundmgr = sm; }
+
inline FGViewMgr *get_viewmgr() const { return viewmgr; }
inline void set_viewmgr( FGViewMgr *vm ) { viewmgr = vm; }
inline FGViewer *get_current_view() const { return current_view; }
#include <plib/pu.h>
#include <plib/ssg.h>
-#ifdef ENABLE_AUDIO_SUPPORT
-# include <plib/sl.h>
-# include <plib/sm.h>
-#endif
-
#include <simgear/constants.h> // for VERSION
#include <simgear/debug/logstream.hxx>
#include <simgear/math/polar3d.hxx>
#include "keyboard.hxx"
#include "splash.hxx"
+#ifdef ENABLE_AUDIO_SUPPORT
+# include "soundmgr.hxx"
+#endif
+
#ifdef macintosh
# include <console.h> // -dw- for command line dialog
#endif
// Global structures for the Audio library
#ifdef ENABLE_AUDIO_SUPPORT
-slEnvelope pitch_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
-slEnvelope volume_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
-slScheduler *audio_sched;
-smMixer *audio_mixer;
-slSample *s1;
-slSample *s2;
+ static FGSimpleSound *s1;
+ static FGSimpleSound *s2;
#endif
// Run audio scheduler
#ifdef ENABLE_AUDIO_SUPPORT
- if ( fgGetBool("/sim/sound") && !audio_sched->not_working() ) {
-
+ if ( fgGetBool("/sim/sound") && globals->get_soundmgr()->is_working() ) {
if ( fgGetString("/sim/aircraft") == "c172" ) {
// pitch corresponds to rpm
// volume corresponds to manifold pressure
+ // cout << "AUDIO working = "
+ // << globals->get_soundmgr()->is_working() << endl;
+
double rpm_factor;
if ( cur_fdm_state->get_engine(0) != NULL ) {
rpm_factor = cur_fdm_state->get_engine(0)->get_RPM() / 2500.0;
// and sounds bad to boot. :-)
if (pitch < 0.7) { pitch = 0.7; }
if (pitch > 5.0) { pitch = 5.0; }
- // cout << "pitch = " << pitch << endl;
double mp_factor;
if ( cur_fdm_state->get_engine(0) != NULL ) {
if ( volume > 1.0 ) { volume = 1.0; }
// cout << "volume = " << volume << endl;
- pitch_envelope.setStep ( 0, 0.01, pitch );
- volume_envelope.setStep ( 0, 0.01, volume );
+ s1->set_pitch( pitch );
+ s1->set_volume( volume );
} else {
double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
- pitch_envelope.setStep ( 0, 0.01, param );
- volume_envelope.setStep ( 0, 0.01, param );
+ s1->set_pitch( param );
+ s1->set_volume( param );
}
- audio_sched -> update();
+ globals->get_soundmgr()->update();
}
#endif
#endif // WIN32
if ( fgGetBool("/sim/sound") ) {
- audio_sched = new slScheduler ( 8000 );
- audio_mixer = new smMixer;
- audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */
- audio_sched -> setSafetyMargin ( 1.0 ) ;
+ globals->get_soundmgr()->init();
- FGPath slfile( globals->get_fg_root() );
- slfile.append( "Sounds/wasp.wav" );
-
- s1 = new slSample ( (char *)slfile.c_str() );
+ s1 = new FGSimpleSound( "Sounds/wasp.wav" );
+ globals->get_soundmgr()->add( s1, "engine loop" );
+ globals->get_soundmgr()->play_looped( "engine loop" );
FG_LOG( FG_GENERAL, FG_INFO,
- "Rate = " << s1 -> getRate()
- << " Bps = " << s1 -> getBps()
- << " Stereo = " << s1 -> getStereo() );
- audio_sched -> loopSample ( s1 );
-
- if ( audio_sched->not_working() ) {
- // skip
- } else {
- pitch_envelope.setStep ( 0, 0.01, 0.6 );
- volume_envelope.setStep ( 0, 0.01, 0.6 );
-
- audio_sched -> addSampleEnvelope( s1, 0, 0,
- &pitch_envelope,
- SL_PITCH_ENVELOPE );
- audio_sched -> addSampleEnvelope( s1, 0, 1,
- &volume_envelope,
- SL_VOLUME_ENVELOPE );
- }
+ "Rate = " << s1->get_sample()->getRate()
+ << " Bps = " << s1->get_sample()->getBps()
+ << " Stereo = " << s1->get_sample()->getStereo() );
- // strcpy(slfile, path);
- // strcat(slfile, "thunder.wav");
- // s2 -> loadFile ( slfile );
- // s2 -> adjustVolume(0.5);
- // audio_sched -> playSample ( s2 );
+ s2 = new FGSimpleSound( "Sounds/corflaps.wav" );
+ s2->set_volume( 2.0 );
+ globals->get_soundmgr()->add( s2, "flaps" );
}
#endif
SGRoute *route = new SGRoute;
globals->set_route( route );
+#ifdef ENABLE_AUDIO_SUPPORT
+ FGSoundMgr *soundmgr = new FGSoundMgr;
+ globals->set_soundmgr( soundmgr );
+#endif
+
FGViewMgr *viewmgr = new FGViewMgr;
globals->set_viewmgr( viewmgr );
--- /dev/null
+// soundmgr.cxx -- Sound effect management class
+//
+// Written by Curtis Olson, started March 2001.
+//
+// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// 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.
+//
+// $Id$
+
+
+#include <simgear/misc/fgpath.hxx>
+
+#include "globals.hxx"
+#include "soundmgr.hxx"
+
+
+// constructor
+FGSimpleSound::FGSimpleSound( string file ) {
+ FGPath slfile( globals->get_fg_root() );
+ slfile.append( file );
+ sample = new slSample ( (char *)slfile.c_str() );
+ pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
+ volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
+ pitch_envelope->setStep ( 0, 0.01, 1.0 );
+ volume_envelope->setStep ( 0, 0.01, 1.0 );
+}
+
+// destructor
+FGSimpleSound::~FGSimpleSound() {
+ delete pitch_envelope;
+ delete volume_envelope;
+ delete sample;
+}
+
+
+// constructor
+FGSoundMgr::FGSoundMgr() {
+ audio_sched = new slScheduler( 8000 );
+ audio_mixer = new smMixer;
+}
+
+// destructor
+FGSoundMgr::~FGSoundMgr() {
+ sound_map_iterator current = sounds.begin();
+ sound_map_iterator end = sounds.end();
+ for ( ; current != end; ++current ) {
+ FGSimpleSound *s = current->second;
+ delete s->get_sample();
+ delete s;
+ }
+
+ delete audio_sched;
+ delete audio_mixer;
+}
+
+
+// initialize the sound manager
+bool FGSoundMgr::init() {
+ audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */
+ audio_sched -> setSafetyMargin ( 1.0 ) ;
+
+ sound_map_iterator current = sounds.begin();
+ sound_map_iterator end = sounds.end();
+ for ( ; current != end; ++current ) {
+ FGSimpleSound *s = current->second;
+ delete s->get_sample();
+ delete s;
+ }
+ sounds.clear();
+
+ if ( audio_sched->not_working() ) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+// run the audio scheduler
+bool FGSoundMgr::update() {
+ if ( !audio_sched->not_working() ) {
+ audio_sched -> update();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+// add a sound effect
+bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname ) {
+ sounds[refname] = sound;
+
+ return true;
+}
+
+
+// tell the scheduler to play the indexed sample in a continuous
+// loop
+bool FGSoundMgr::play_looped( const string& refname ) {
+ sound_map_iterator it = sounds.find( refname );
+ if ( it != sounds.end() ) {
+ FGSimpleSound *sample = it->second;
+ audio_sched->loopSample( sample->get_sample() );
+ audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0,
+ sample->get_pitch_envelope(),
+ SL_PITCH_ENVELOPE );
+ audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1,
+ sample->get_volume_envelope(),
+ SL_VOLUME_ENVELOPE );
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+// tell the scheduler to play the indexed sample once
+bool FGSoundMgr::FGSoundMgr::play_once( const string& refname ) {
+ sound_map_iterator it = sounds.find( refname );
+ if ( it != sounds.end() ) {
+ FGSimpleSound *sample = it->second;
+ audio_sched->playSample( sample->get_sample() );
+ audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0,
+ sample->get_pitch_envelope(),
+ SL_PITCH_ENVELOPE );
+ audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1,
+ sample->get_volume_envelope(),
+ SL_VOLUME_ENVELOPE );
+
+ return true;
+ } else {
+ return false;
+ }
+}
--- /dev/null
+// soundmgr.hxx -- Sound effect management class
+//
+// Written by Curtis Olson, started March 2001.
+//
+// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// 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.
+//
+// $Id$
+
+
+#ifndef _SOUNDMGR_HXX
+#define _SOUNDMGR_HXX
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include STL_STRING
+#include <map>
+
+#include <plib/sl.h>
+#include <plib/sm.h>
+
+FG_USING_STD(map);
+FG_USING_STD(string);
+
+
+// manages everything we need to know for an individual sound sample
+class FGSimpleSound {
+
+ slSample *sample;
+ slEnvelope *pitch_envelope;
+ slEnvelope *volume_envelope;
+ double pitch;
+ double volume;
+
+public:
+
+ FGSimpleSound( string file );
+ ~FGSimpleSound();
+
+ inline double get_pitch() const { return pitch; }
+ inline void set_pitch( double p ) {
+ pitch = p;
+ pitch_envelope->setStep( 0, 0.01, pitch );
+ }
+ inline double get_volume() const { return volume; }
+ inline void set_volume( double v ) {
+ volume = v;
+ volume_envelope->setStep( 0, 0.01, volume );
+ }
+
+ inline slSample *get_sample() { return sample; }
+ inline slEnvelope *get_pitch_envelope() { return pitch_envelope; }
+ inline slEnvelope *get_volume_envelope() { return volume_envelope; }
+};
+
+
+typedef map < string, FGSimpleSound * > sound_map;
+typedef sound_map::iterator sound_map_iterator;
+typedef sound_map::const_iterator const_sound_map_iterator;
+
+
+class FGSoundMgr {
+
+ slScheduler *audio_sched;
+ smMixer *audio_mixer;
+ sound_map sounds;
+
+public:
+
+ FGSoundMgr();
+ ~FGSoundMgr();
+
+ // initialize the sound manager
+ bool init();
+
+ // run the audio scheduler
+ bool update();
+
+ // is audio working?
+ inline bool is_working() const { return !audio_sched->not_working(); }
+
+ // add a sound effect, return the index of the sound
+ bool add( FGSimpleSound *sound, const string& refname );
+
+ // tell the scheduler to play the indexed sample in a continuous
+ // loop
+ bool play_looped( const string& refname );
+
+ // tell the scheduler to play the indexed sample once
+ bool play_once( const string& refname );
+};
+
+
+#endif // _SOUNDMGR_HXX
+
+