1
0
Fork 0
flightgear/src/Sound/soundmgr.cxx

167 lines
4.5 KiB
C++

// soundmgr.cxx -- Sound effect management class
//
// Sound manager initially written by David Findlay
// <david_j_findlay@yahoo.com.au> 2001
//
// C++-ified 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/debug/logstream.hxx>
#include <simgear/misc/fgpath.hxx>
#include <Main/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 );
}
FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len ) {
sample = new slSample ( buffer, len );
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;
FG_LOG( FG_GENERAL, FG_INFO,
"Rate = " << audio_sched->getRate()
<< " Bps = " << audio_sched->getBps()
<< " Stereo = " << audio_sched->getStereo() );
}
// 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;
}
}