Make a clear separation between loading a sound file into main memroy and sending it to the driver. This prevents data to be loaded into the main memory (or onto the soundcard's memory) when it's not needed.

This commit is contained in:
ehofman 2005-11-12 10:26:21 +00:00
parent 694cf6e958
commit 1cff7fcfea
4 changed files with 75 additions and 43 deletions

View File

@ -14,37 +14,37 @@ static unsigned int sleep(unsigned int secs) { return 0; }
int main( int argc, char *argv[] ) {
SGSoundMgr sm;
SGSoundSample sample1( ".", "jet.wav", true );
SGSoundSample sample1( ".", "jet.wav" );
sample1.set_volume(0.5);
sample1.set_volume(0.2);
sample1.play_looped();
sleep(1);
SGSoundSample sample2( ".", "jet.wav", true );
SGSoundSample sample2( ".", "jet.wav" );
sample2.set_volume(0.5);
sample2.set_pitch(0.4);
sample2.play_looped();
sleep(1);
SGSoundSample sample3( ".", "jet.wav", true );
SGSoundSample sample3( ".", "jet.wav" );
sample3.set_volume(0.5);
sample3.set_pitch(0.8);
sample3.play_looped();
sleep(1);
SGSoundSample sample4( ".", "jet.wav", true );
SGSoundSample sample4( ".", "jet.wav" );
sample4.set_volume(0.5);
sample4.set_pitch(1.2);
sample4.play_looped();
sleep(1);
SGSoundSample sample5( ".", "jet.wav", true );
SGSoundSample sample5( ".", "jet.wav" );
sample5.set_volume(0.5);
sample5.set_pitch(1.6);
sample5.play_looped();
sleep(1);
SGSoundSample sample6( ".", "jet.wav", true );
SGSoundSample sample6( ".", "jet.wav" );
sample6.set_volume(0.5);
sample6.set_pitch(2.0);
sample6.play_looped();

View File

@ -63,11 +63,21 @@ static bool print_openal_error(const string &s = "unknown") {
return error;
}
// empry constructor
SGSoundSample::SGSoundSample() :
buffer(0),
source(0),
pitch(1.0),
volume(1.0),
reference_dist(500.0),
max_dist(3000.),
loop(AL_FALSE),
playing(false)
{
}
// constructor
SGSoundSample::SGSoundSample( const char *path, const char *file,
bool cleanup ) :
data(NULL),
SGSoundSample::SGSoundSample( const char *path, const char *file) :
buffer(0),
source(0),
pitch(1.0),
@ -81,7 +91,6 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
if ( strlen(file) ) {
samplepath.append( file );
}
sample_name = samplepath.str();
SG_LOG( SG_GENERAL, SG_DEBUG, "From file sounds sample = "
@ -116,16 +125,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
//
// pre 1.0 alut version
//
# if defined (__APPLE__)
alutLoadWAVFile( (ALbyte *)samplepath.c_str(),
&format, &data, &size, &freq );
# else
alutLoadWAVFile( (ALbyte *)samplepath.c_str(),
&format, &data, &size, &freq, &loop );
# endif
if ( print_openal_error("constructor (alutLoadWAVFile)") ) {
throw sg_exception("Failed to load wav file.");
}
ALvoid* data = load_file(path, file)
// Copy data to the internal OpenAL buffer
alBufferData( buffer, format, data, size, freq );
@ -134,20 +134,15 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
throw sg_exception("Failed to buffer data.");
}
if ( cleanup ) {
alutUnloadWAV( format, data, size, freq );
data = NULL;
}
alutUnloadWAV( format, data, size, freq );
#endif
print_openal_error("constructor return");
}
// constructor
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
bool cleanup) :
data(NULL),
buffer(0),
source(0),
pitch(1.0),
@ -178,17 +173,15 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
format = AL_FORMAT_MONO8;
size = len;
data = _data;
freq = _freq;
alBufferData( buffer, format, data, size, freq );
alBufferData( buffer, format, _data, size, freq );
if ( print_openal_error("constructor (alBufferData)") ) {
throw sg_exception("Failed to buffer data.");
}
if ( cleanup ) {
alutUnloadWAV( format, data, size, freq );
data = NULL;
free(_data);
}
print_openal_error("constructor return");
@ -198,7 +191,8 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
// destructor
SGSoundSample::~SGSoundSample() {
SG_LOG( SG_GENERAL, SG_INFO, "Deleting a sample" );
alDeleteBuffers(1, &buffer);
if (buffer)
alDeleteBuffers(1, &buffer);
}
@ -239,6 +233,9 @@ SGSoundSample::bind_source() {
if ( playing ) {
return true;
}
if ( buffer == 0 ) {
return false;
}
// Bind buffer with a source.
alGetError();
@ -376,3 +373,37 @@ SGSoundSample::set_max_dist( ALfloat dist ) {
alSourcef( source, AL_MAX_DISTANCE, max_dist );
}
}
ALvoid *
SGSoundSample::load_file(const char *path, const char *file)
{
ALvoid* data = 0;
SGPath samplepath( path );
if ( strlen(file) ) {
samplepath.append( file );
}
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
ALfloat freqf;
data = alutLoadMemoryFromFile(samplepath.c_str(), &format, &size, &freqf );
if (data == NULL) {
throw sg_exception("Failed to load wav file.");
}
freq = (ALsizei)freqf;
#else
# if defined (__APPLE__)
alutLoadWAVFile( (ALbyte *)samplepath.c_str(),
&format, &data, &size, &freq );
# else
alutLoadWAVFile( (ALbyte *)samplepath.c_str(),
&format, &data, &size, &freq, &loop );
# endif
if ( print_openal_error("constructor (alutLoadWAVFile)") ) {
throw sg_exception("Failed to load wav file.");
}
#endif
return data;
}

View File

@ -84,7 +84,6 @@ private:
// configuration values
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
double pitch;
@ -98,15 +97,20 @@ private:
public:
/**
* Empty constructor, can be used to read data to the systems
* memory and not to the driver.
*/
SGSoundSample();
/**
* Constructor
* @param path Path name to sound
* @param file File name of sound
* @param cleanup Request clean up the intermediate data (this
should usually be true unless you want to manipulate the data
later.)
*/
SGSoundSample( const char *path, const char *file, bool cleanup );
SGSoundSample( const char *path, const char *file );
/**
* Constructor.
@ -180,13 +184,6 @@ public:
return size;
}
/**
* Return a pointer to the raw data
*/
inline char *get_data() {
return (char *)data;
}
/**
* Set position of sound source (uses same coordinate system as opengl)
*/
@ -224,6 +221,11 @@ public:
* no longer audible.
*/
void set_max_dist( ALfloat dist );
/**
* Load a sound file into a memory buffer only.
*/
ALvoid* load_file(const char *path, const char *file);
};

View File

@ -275,8 +275,7 @@ SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node, SGSoundMgr *sndmgr,
// "alSource". The semantics of what is going on here seems
// confused and needs to be thought through more carefully.
_sample = new SGSoundSample( path.c_str(),
node->getStringValue("path", ""),
true );
node->getStringValue("path", "") );
_mgr->add( _sample, _name );
}