1
0
Fork 0

Added a first pass at a C++ sound manager class.

This commit is contained in:
curt 2001-03-02 22:37:01 +00:00
parent 5d423a94b0
commit e9591422f3
7 changed files with 312 additions and 51 deletions

View file

@ -25,7 +25,9 @@
#define _CONTROLS_HXX
#include <simgear/misc/props.hxx>
#include <Main/fgfs.hxx>
#include <Main/globals.hxx>
#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 );
}

View file

@ -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)

View file

@ -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 \

View file

@ -36,6 +36,7 @@
#include <simgear/timing/sg_time.hxx>
#include <simgear/misc/props.hxx>
#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; }

View file

@ -56,11 +56,6 @@
#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>
@ -124,6 +119,10 @@ int objc=0;
#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
@ -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 );
"Rate = " << s1->get_sample()->getRate()
<< " Bps = " << s1->get_sample()->getBps()
<< " Stereo = " << s1->get_sample()->getStereo() );
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 );
}
// 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 );

149
src/Main/soundmgr.cxx Normal file
View file

@ -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 <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;
}
}

113
src/Main/soundmgr.hxx Normal file
View file

@ -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 <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