From: curt Date: Fri, 2 Mar 2001 22:37:01 +0000 (+0000) Subject: Added a first pass at a C++ sound manager class. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=e9591422f3b5efadd7abe1a6fc4e7f6d7a713894;p=flightgear.git Added a first pass at a C++ sound manager class. --- diff --git a/src/Controls/controls.hxx b/src/Controls/controls.hxx index 91e27738c..7f0019dec 100644 --- a/src/Controls/controls.hxx +++ b/src/Controls/controls.hxx @@ -25,7 +25,9 @@ #define _CONTROLS_HXX #include + #include
+#include
#ifndef __cplusplus # error This library requires C++ @@ -144,10 +146,16 @@ public: 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 ); } diff --git a/src/FDM/LaRCsim/c172_gear.c b/src/FDM/LaRCsim/c172_gear.c index 353a5683c..180c26776 100644 --- a/src/FDM/LaRCsim/c172_gear.c +++ b/src/FDM/LaRCsim/c172_gear.c @@ -36,6 +36,9 @@ $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) @@ -374,7 +377,7 @@ char gear_strings[NUM_WHEELS][12]={"nose","right main", "left main", "tail skid" add3( tempM, M_gear_v, M_gear_v ); - } + } diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am index fd7d07797..f43dc25d3 100644 --- a/src/Main/Makefile.am +++ b/src/Main/Makefile.am @@ -43,6 +43,7 @@ fgfs_SOURCES = \ 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 \ diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index fc1c52184..62dac4b24 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -36,6 +36,7 @@ #include #include +#include "soundmgr.hxx" #include "viewmgr.hxx" FG_USING_STD( vector ); @@ -77,6 +78,9 @@ private: // Global autopilot "route" SGRoute *route; + // sound manager + FGSoundMgr *soundmgr; + // viewer maneger FGViewMgr *viewmgr; FGViewer *current_view; @@ -124,6 +128,9 @@ public: 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; } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 419614ed3..092e97d16 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -56,11 +56,6 @@ #include #include -#ifdef ENABLE_AUDIO_SUPPORT -# include -# include -#endif - #include // for VERSION #include #include @@ -124,6 +119,10 @@ int objc=0; #include "keyboard.hxx" #include "splash.hxx" +#ifdef ENABLE_AUDIO_SUPPORT +# include "soundmgr.hxx" +#endif + #ifdef macintosh # include // -dw- for command line dialog #endif @@ -146,12 +145,8 @@ void fgReshape( int width, int height ); // 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 @@ -1037,12 +1032,14 @@ static void fgMainLoop( void ) { // 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; @@ -1058,7 +1055,6 @@ static void fgMainLoop( void ) { // 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 ) { @@ -1077,15 +1073,15 @@ static void fgMainLoop( void ) { 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 @@ -1185,40 +1181,19 @@ static void fgIdleFunction ( void ) { #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 @@ -1404,6 +1379,11 @@ int main( int argc, char **argv ) { 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 ); diff --git a/src/Main/soundmgr.cxx b/src/Main/soundmgr.cxx new file mode 100644 index 000000000..a0abaa6a6 --- /dev/null +++ b/src/Main/soundmgr.cxx @@ -0,0 +1,149 @@ +// 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 + +#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; + } +} diff --git a/src/Main/soundmgr.hxx b/src/Main/soundmgr.hxx new file mode 100644 index 000000000..986acd7e8 --- /dev/null +++ b/src/Main/soundmgr.hxx @@ -0,0 +1,113 @@ +// 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 +#endif + +#include + +#include STL_STRING +#include + +#include +#include + +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 + +