Move all OpenAL function calls from SampleMgr to soundMgr

This commit is contained in:
Erik Hofman
2016-05-27 14:40:49 +02:00
parent c5a94e8899
commit ef5b9ee66b
12 changed files with 237 additions and 143 deletions

View File

@@ -1,16 +1,16 @@
include (SimGearComponent)
set(HEADERS
sample.hxx
sample_group.hxx
sample_openal.hxx
soundmgr_openal.hxx
xmlsound.hxx
readwav.hxx
)
set(SOURCES
sample.cxx
sample_group.cxx
sample_openal.cxx
soundmgr_openal.cxx
xmlsound.cxx
readwav.cxx

View File

@@ -12,7 +12,7 @@
#include "soundmgr_openal.hxx"
#include "sample_group.hxx"
#include "sample_openal.hxx"
#include "sample.hxx"
int main( int argc, char *argv[] ) {

View File

@@ -11,7 +11,7 @@
#include "soundmgr_openal.hxx"
#include "sample_group.hxx"
#include "sample_openal.hxx"
#include "sample.hxx"
int main( int argc, char *argv[] ) {
SGSampleGroup *sgr;

View File

@@ -30,7 +30,7 @@
#include <simgear/misc/stdint.hxx>
#include <simgear/structure/exception.hxx>
#include "sample_openal.hxx"
#include "sample.hxx"
namespace
{

View File

@@ -1,4 +1,4 @@
// sample_openal.cxx -- Audio sample encapsulation class
// sample.cxx -- Audio sample encapsulation class
//
// Written by Curtis Olson, started April 2004.
// Modified to match the new SoundSystem by Erik Hofman, October 2009
@@ -35,9 +35,9 @@
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/ResourceManager.hxx>
#include "soundmgr_openal.hxx"
#include "sample_openal.hxx"
#include "soundmgr_openal_private.hxx"
#include "soundmgr_openal.hxx"
#include "sample.hxx"
#define AL_FALSE 0

View File

@@ -1,4 +1,4 @@
// sample_openal.hxx -- Audio sample encapsulation class
// sample.hxx -- Audio sample encapsulation class
//
// Written by Curtis Olson, started April 2004.
// Modified to match the new SoundSystem by Erik Hofman, October 2009

View File

@@ -24,7 +24,6 @@
# include <simgear_config.h>
#endif
#include <cassert>
#include <simgear/compiler.h>
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
@@ -78,42 +77,15 @@ SGSampleGroup::~SGSampleGroup ()
_smgr = 0;
}
static bool is_sample_stopped(SGSoundSample *sample)
{
#ifdef ENABLE_SOUND
assert(sample->is_valid_source());
unsigned int source = sample->get_source();
int result;
alGetSourcei( source, AL_SOURCE_STATE, &result );
return (result == AL_STOPPED);
#else
return true;
#endif
}
void SGSampleGroup::cleanup_removed_samples()
{
// Delete any OpenAL buffers that might still be in use.
unsigned int size = _removed_samples.size();
for (unsigned int i=0; i<size; ) {
SGSoundSample *sample = _removed_samples[i];
bool stopped = is_sample_stopped(sample);
if ( sample->is_valid_source() ) {
int source = sample->get_source();
if ( sample->is_looping() && !stopped) {
#ifdef ENABLE_SOUND
alSourceStop( source );
#endif
stopped = is_sample_stopped(sample);
}
if ( stopped ) {
sample->no_valid_source();
_smgr->release_source( source );
}
}
_smgr->sample_stop(sample);
bool stopped = _smgr->is_sample_stopped(sample);
if ( stopped ) {
sample->stop();
@@ -132,52 +104,16 @@ void SGSampleGroup::cleanup_removed_samples()
void SGSampleGroup::start_playing_sample(SGSoundSample *sample)
{
#ifdef ENABLE_SOUND
//
// a request to start playing a sound has been filed.
//
ALuint source = _smgr->request_source();
if (alIsSource(source) == AL_FALSE ) {
return;
}
sample->set_source( source );
_smgr->sample_init( sample );
update_sample_config( sample );
ALboolean looping = sample->is_looping() ? AL_TRUE : AL_FALSE;
if ( !sample->is_queue() )
{
ALuint buffer = _smgr->request_buffer(sample);
if (buffer == SGSoundMgr::FAILED_BUFFER ||
buffer == SGSoundMgr::NO_BUFFER)
{
_smgr->release_source(source);
return;
}
// start playing the sample
buffer = sample->get_buffer();
if ( alIsBuffer(buffer) == AL_TRUE )
{
alSourcei( source, AL_BUFFER, buffer );
testForALError("assign buffer to source");
} else
SG_LOG( SG_SOUND, SG_ALERT, "No such buffer!");
}
alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 );
alSourcei( source, AL_LOOPING, looping );
alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
alSourcePlay( source );
testForALError("sample play");
#endif
_smgr->sample_play( sample );
}
void SGSampleGroup::check_playing_sample(SGSoundSample *sample)
{
// check if the sound has stopped by itself
if (is_sample_stopped(sample)) {
if (_smgr->is_sample_stopped(sample)) {
// sample is stopped because it wasn't looping
sample->stop();
sample->no_valid_source();
@@ -291,23 +227,7 @@ SGSampleGroup::stop ()
sample_map_iterator sample_end = _samples.end();
for ( ; sample_current != sample_end; ++sample_current ) {
SGSoundSample *sample = sample_current->second;
if ( sample->is_valid_source() ) {
#ifdef ENABLE_SOUND
ALint source = sample->get_source();
if ( sample->is_playing() ) {
alSourceStop( source );
testForALError("stop");
}
_smgr->release_source( source );
#endif
sample->no_valid_source();
}
if ( sample->is_valid_buffer() ) {
_smgr->release_buffer( sample );
sample->no_valid_buffer();
}
_smgr->sample_destroy( sample );
}
}
@@ -322,9 +242,7 @@ SGSampleGroup::suspend ()
for ( ; sample_current != sample_end; ++sample_current ) {
#ifdef ENABLE_SOUND
SGSoundSample *sample = sample_current->second;
if ( sample->is_valid_source() && sample->is_playing() ) {
alSourcePause( sample->get_source() );
}
_smgr->sample_suspend( sample );
#endif
}
testForALError("suspend");
@@ -341,9 +259,7 @@ SGSampleGroup::resume ()
sample_map_iterator sample_end = _samples.end();
for ( ; sample_current != sample_end; ++sample_current ) {
SGSoundSample *sample = sample_current->second;
if ( sample->is_valid_source() && sample->is_playing() ) {
alSourcePlay( sample->get_source() );
}
_smgr->sample_resume( sample );
}
testForALError("resume");
#endif
@@ -469,27 +385,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample )
if (isNaN(velocity.data())) printf("NaN in source velocity\n");
#endif
unsigned int source = sample->get_source();
alSourcefv( source, AL_POSITION, toVec3f(position).data() );
alSourcefv( source, AL_VELOCITY, velocity.data() );
alSourcefv( source, AL_DIRECTION, orientation.data() );
testForALError("position and orientation");
alSourcef( source, AL_PITCH, sample->get_pitch() );
alSourcef( source, AL_GAIN, sample->get_volume() );
testForALError("pitch and gain");
if ( sample->has_static_data_changed() ) {
alSourcef( source, AL_CONE_INNER_ANGLE, sample->get_innerangle() );
alSourcef( source, AL_CONE_OUTER_ANGLE, sample->get_outerangle() );
alSourcef( source, AL_CONE_OUTER_GAIN, sample->get_outergain() );
testForALError("audio cone");
alSourcef( source, AL_MAX_DISTANCE, sample->get_max_dist() );
alSourcef( source, AL_REFERENCE_DISTANCE,
sample->get_reference_dist() );
testForALError("distance rolloff");
}
_smgr->update_sample_config( sample, position, orientation, velocity );
#endif
}
@@ -504,14 +400,7 @@ bool SGSampleGroup::testForError(void *p, std::string s)
bool SGSampleGroup::testForALError(std::string s)
{
#ifdef SG_C
ALenum error = alGetError();
if (error != AL_NO_ERROR) {
SG_LOG( SG_SOUND, SG_ALERT, "AL Error (" << _refname << "): "
<< alGetString(error) << " at " << s);
return true;
}
#endif
_smgr->testForError(s, _refname);
return false;
}

View File

@@ -36,7 +36,7 @@
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/exception.hxx>
#include "sample_openal.hxx"
#include "sample.hxx"
typedef std::map < std::string, SGSharedPtr<SGSoundSample> > sample_map;

View File

@@ -32,6 +32,7 @@
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cassert>
#include <boost/foreach.hpp>
@@ -215,7 +216,7 @@ void SGSoundMgr::init()
// AL_ROLLOFF_FACTOR * (distance - AL_REFERENCE_DISTANCE));
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
testForALError("listener initialization");
testForError("listener initialization");
// get a free source one at a time
// if an error is returned no more (hardware) sources are available
@@ -296,7 +297,7 @@ void SGSoundMgr::stop()
// clear all OpenAL sources
BOOST_FOREACH(ALuint source, d->_free_sources) {
alDeleteSources( 1 , &source );
testForALError("SGSoundMgr::stop: delete sources");
testForError("SGSoundMgr::stop: delete sources");
}
d->_free_sources.clear();
@@ -307,7 +308,7 @@ void SGSoundMgr::stop()
refUint ref = buffers_current->second;
ALuint buffer = ref.id;
alDeleteBuffers(1, &buffer);
testForALError("SGSoundMgr::stop: delete buffers");
testForError("SGSoundMgr::stop: delete buffers");
}
d->_buffers.clear();
@@ -396,7 +397,7 @@ if (isNaN(_velocity.data())) printf("NaN in listener velocity\n");
alListenerfv( AL_VELOCITY, toVec3f(velocity).data() );
// alDopplerVelocity(340.3); // TODO: altitude dependent
testForALError("update");
testForError("update");
_changed = false;
}
@@ -509,7 +510,7 @@ void SGSoundMgr::release_source( unsigned int source )
}
alSourcei( source, AL_BUFFER, 0 ); // detach the associated buffer
testForALError("release_source");
testForError("release_source");
#endif
d->_free_sources.push_back( source );
d->_sources_in_use.erase( it );
@@ -559,7 +560,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample)
// create an OpenAL buffer handle
alGenBuffers(1, &buffer);
if ( !testForALError("generate buffer") ) {
if ( !testForError("generate buffer") ) {
// Copy data to the internal OpenAL buffer
ALenum format = AL_NONE;
@@ -571,7 +572,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample)
ALsizei freq = sample->get_frequency();
alBufferData( buffer, format, sample_data, size, freq );
if ( !testForALError("buffer add data") ) {
if ( !testForError("buffer add data") ) {
sample->set_buffer(buffer);
d->_buffers[sample_name] = refUint(buffer);
}
@@ -605,11 +606,153 @@ void SGSoundMgr::release_buffer(SGSoundSample *sample)
alDeleteBuffers(1, &buffer);
#endif
d->_buffers.erase( buffer_it );
testForALError("release buffer");
testForError("release buffer");
}
}
}
void SGSoundMgr::sample_suspend( SGSoundSample *sample )
{
if ( sample->is_valid_source() && sample->is_playing() ) {
alSourcePause( sample->get_source() );
}
}
void SGSoundMgr::sample_resume( SGSoundSample *sample )
{
if ( sample->is_valid_source() && sample->is_playing() ) {
alSourcePlay( sample->get_source() );
}
}
void SGSoundMgr::sample_init( SGSoundSample *sample )
{
#ifdef ENABLE_SOUND
//
// a request to start playing a sound has been filed.
//
ALuint source = request_source();
if (alIsSource(source) == AL_FALSE ) {
return;
}
sample->set_source( source );
#endif
}
void SGSoundMgr::sample_play( SGSoundSample *sample )
{
#ifdef ENABLE_SOUND
ALboolean looping = sample->is_looping() ? AL_TRUE : AL_FALSE;
ALint source = sample->get_source();
if ( !sample->is_queue() )
{
ALuint buffer = request_buffer(sample);
if (buffer == SGSoundMgr::FAILED_BUFFER ||
buffer == SGSoundMgr::NO_BUFFER)
{
release_source(source);
return;
}
// start playing the sample
buffer = sample->get_buffer();
if ( alIsBuffer(buffer) == AL_TRUE )
{
alSourcei( source, AL_BUFFER, buffer );
testForError("assign buffer to source");
} else
SG_LOG( SG_SOUND, SG_ALERT, "No such buffer!");
}
alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 );
alSourcei( source, AL_LOOPING, looping );
alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
alSourcePlay( source );
testForError("sample play");
#endif
}
void SGSoundMgr::sample_stop( SGSoundSample *sample )
{
if ( sample->is_valid_source() ) {
int source = sample->get_source();
bool stopped = is_sample_stopped(sample);
if ( sample->is_looping() && !stopped) {
#ifdef ENABLE_SOUND
alSourceStop( source );
#endif
stopped = is_sample_stopped(sample);
}
if ( stopped ) {
sample->no_valid_source();
release_source( source );
}
}
}
void SGSoundMgr::sample_destroy( SGSoundSample *sample )
{
if ( sample->is_valid_source() ) {
#ifdef ENABLE_SOUND
ALint source = sample->get_source();
if ( sample->is_playing() ) {
alSourceStop( source );
testForError("stop");
}
release_source( source );
#endif
sample->no_valid_source();
}
if ( sample->is_valid_buffer() ) {
release_buffer( sample );
sample->no_valid_buffer();
}
}
bool SGSoundMgr::is_sample_stopped(SGSoundSample *sample)
{
#ifdef ENABLE_SOUND
assert(sample->is_valid_source());
unsigned int source = sample->get_source();
int result;
alGetSourcei( source, AL_SOURCE_STATE, &result );
return (result == AL_STOPPED);
#else
return true;
#endif
}
void SGSoundMgr::update_sample_config( SGSoundSample *sample, SGVec3d& position, SGVec3f& orientation, SGVec3f& velocity )
{
unsigned int source = sample->get_source();
alSourcefv( source, AL_POSITION, toVec3f(position).data() );
alSourcefv( source, AL_VELOCITY, velocity.data() );
alSourcefv( source, AL_DIRECTION, orientation.data() );
testForError("position and orientation");
alSourcef( source, AL_PITCH, sample->get_pitch() );
alSourcef( source, AL_GAIN, sample->get_volume() );
testForError("pitch and gain");
if ( sample->has_static_data_changed() ) {
alSourcef( source, AL_CONE_INNER_ANGLE, sample->get_innerangle() );
alSourcef( source, AL_CONE_OUTER_ANGLE, sample->get_outerangle() );
alSourcef( source, AL_CONE_OUTER_GAIN, sample->get_outergain() );
testForError("audio cone");
alSourcef( source, AL_MAX_DISTANCE, sample->get_max_dist() );
alSourcef( source, AL_REFERENCE_DISTANCE,
sample->get_reference_dist() );
testForError("distance rolloff");
}
}
bool SGSoundMgr::load( const std::string &samplepath,
void **dbuf,
int *fmt,
@@ -683,12 +826,12 @@ bool SGSoundMgr::testForError(void *p, std::string s)
}
bool SGSoundMgr::testForALError(std::string s)
bool SGSoundMgr::testForError(std::string s, std::string name)
{
#ifdef ENABLE_SOUND
ALenum error = alGetError();
if (error != AL_NO_ERROR) {
SG_LOG( SG_SOUND, SG_ALERT, "AL Error (sound manager): "
SG_LOG( SG_SOUND, SG_ALERT, "AL Error (" << name << "): "
<< alGetString(error) << " at " << s);
return true;
}

View File

@@ -225,6 +225,63 @@ public:
*/
void release_buffer( SGSoundSample *sample );
/**
* Initialize sample for playback.
*
* @param sample Pointer to an audio sample to initialize.
*/
void sample_init( SGSoundSample *sample );
/**
* Stop and destroy a sample
*
* @param sample Pointer to an audio sample to destroy.
*/
void sample_destroy( SGSoundSample *sample );
/**
* Start playback of a sample
*
* @param sample Pointer to an audio sample to start playing.
*/
void sample_play( SGSoundSample *sample );
/**
* Stop a sample
*
* @param sample Pointer to an audio sample to stop.
*/
void sample_stop( SGSoundSample *sample );
/**
* Suspend playback of a sample
*
* @param sample Pointer to an audio sample to suspend.
*/
void sample_suspend( SGSoundSample *sample );
/**
* Resume playback of a sample
*
* @param sample Pointer to an audio sample to resume.
*/
void sample_resume( SGSoundSample *sample );
/**
* Check if a sample is stopped, or still playing
*
* @param sample Pointer to an audio sample to test.
* @return true if the sample is stopped.
*/
bool is_sample_stopped( SGSoundSample *sample );
/**
* Update all status and 3d parameters of a sample.
*
* @param sample Pointer to an audio sample to update.
*/
void update_sample_config( SGSoundSample *sample, SGVec3d& position, SGVec3f& orientation, SGVec3f& velocity );
/**
* Test if the position of the sound manager has changed.
* The value will be set to false upon the next call to update_late()
@@ -268,6 +325,8 @@ public:
const std::string& get_vendor() { return _vendor; }
const std::string& get_renderer() { return _renderer; }
bool testForError(std::string s, std::string name = "sound manager");
static const char* subsystemName() { return "sound"; };
private:
class SoundManagerPrivate;
@@ -290,7 +349,6 @@ private:
std::string _vendor;
std::string _device_name;
bool testForALError(std::string s);
bool testForALCError(std::string s);
bool testForError(void *p, std::string s);

View File

@@ -47,6 +47,10 @@
# include <AL/alext.h>
#endif
#include <simgear/structure/SGSharedPtr.hxx>
class SGSampleGroup;
struct refUint {
unsigned int refctr;
ALuint id;

View File

@@ -40,7 +40,7 @@
#include <simgear/misc/sg_path.hxx>
#include "sample_group.hxx"
#include "sample_openal.hxx"
#include "sample.hxx"
using std::string;