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[] ) { int main( int argc, char *argv[] ) {
SGSoundMgr sm; SGSoundMgr sm;
SGSoundSample sample1( ".", "jet.wav", true ); SGSoundSample sample1( ".", "jet.wav" );
sample1.set_volume(0.5); sample1.set_volume(0.5);
sample1.set_volume(0.2); sample1.set_volume(0.2);
sample1.play_looped(); sample1.play_looped();
sleep(1); sleep(1);
SGSoundSample sample2( ".", "jet.wav", true ); SGSoundSample sample2( ".", "jet.wav" );
sample2.set_volume(0.5); sample2.set_volume(0.5);
sample2.set_pitch(0.4); sample2.set_pitch(0.4);
sample2.play_looped(); sample2.play_looped();
sleep(1); sleep(1);
SGSoundSample sample3( ".", "jet.wav", true ); SGSoundSample sample3( ".", "jet.wav" );
sample3.set_volume(0.5); sample3.set_volume(0.5);
sample3.set_pitch(0.8); sample3.set_pitch(0.8);
sample3.play_looped(); sample3.play_looped();
sleep(1); sleep(1);
SGSoundSample sample4( ".", "jet.wav", true ); SGSoundSample sample4( ".", "jet.wav" );
sample4.set_volume(0.5); sample4.set_volume(0.5);
sample4.set_pitch(1.2); sample4.set_pitch(1.2);
sample4.play_looped(); sample4.play_looped();
sleep(1); sleep(1);
SGSoundSample sample5( ".", "jet.wav", true ); SGSoundSample sample5( ".", "jet.wav" );
sample5.set_volume(0.5); sample5.set_volume(0.5);
sample5.set_pitch(1.6); sample5.set_pitch(1.6);
sample5.play_looped(); sample5.play_looped();
sleep(1); sleep(1);
SGSoundSample sample6( ".", "jet.wav", true ); SGSoundSample sample6( ".", "jet.wav" );
sample6.set_volume(0.5); sample6.set_volume(0.5);
sample6.set_pitch(2.0); sample6.set_pitch(2.0);
sample6.play_looped(); sample6.play_looped();

View File

@ -63,11 +63,21 @@ static bool print_openal_error(const string &s = "unknown") {
return error; 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 // constructor
SGSoundSample::SGSoundSample( const char *path, const char *file, SGSoundSample::SGSoundSample( const char *path, const char *file) :
bool cleanup ) :
data(NULL),
buffer(0), buffer(0),
source(0), source(0),
pitch(1.0), pitch(1.0),
@ -81,7 +91,6 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
if ( strlen(file) ) { if ( strlen(file) ) {
samplepath.append( file ); samplepath.append( file );
} }
sample_name = samplepath.str(); sample_name = samplepath.str();
SG_LOG( SG_GENERAL, SG_DEBUG, "From file sounds sample = " 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 // pre 1.0 alut version
// //
# if defined (__APPLE__) ALvoid* data = load_file(path, file)
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.");
}
// Copy data to the internal OpenAL buffer // Copy data to the internal OpenAL buffer
alBufferData( buffer, format, data, size, freq ); 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."); throw sg_exception("Failed to buffer data.");
} }
if ( cleanup ) { alutUnloadWAV( format, data, size, freq );
alutUnloadWAV( format, data, size, freq );
data = NULL;
}
#endif #endif
print_openal_error("constructor return"); print_openal_error("constructor return");
} }
// constructor // constructor
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq, SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
bool cleanup) : bool cleanup) :
data(NULL),
buffer(0), buffer(0),
source(0), source(0),
pitch(1.0), pitch(1.0),
@ -178,17 +173,15 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
format = AL_FORMAT_MONO8; format = AL_FORMAT_MONO8;
size = len; size = len;
data = _data;
freq = _freq; freq = _freq;
alBufferData( buffer, format, data, size, freq ); alBufferData( buffer, format, _data, size, freq );
if ( print_openal_error("constructor (alBufferData)") ) { if ( print_openal_error("constructor (alBufferData)") ) {
throw sg_exception("Failed to buffer data."); throw sg_exception("Failed to buffer data.");
} }
if ( cleanup ) { if ( cleanup ) {
alutUnloadWAV( format, data, size, freq ); free(_data);
data = NULL;
} }
print_openal_error("constructor return"); print_openal_error("constructor return");
@ -198,7 +191,8 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
// destructor // destructor
SGSoundSample::~SGSoundSample() { SGSoundSample::~SGSoundSample() {
SG_LOG( SG_GENERAL, SG_INFO, "Deleting a sample" ); 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 ) { if ( playing ) {
return true; return true;
} }
if ( buffer == 0 ) {
return false;
}
// Bind buffer with a source. // Bind buffer with a source.
alGetError(); alGetError();
@ -376,3 +373,37 @@ SGSoundSample::set_max_dist( ALfloat dist ) {
alSourcef( source, AL_MAX_DISTANCE, max_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 // configuration values
ALenum format; ALenum format;
ALsizei size; ALsizei size;
ALvoid* data;
ALsizei freq; ALsizei freq;
double pitch; double pitch;
@ -98,15 +97,20 @@ private:
public: public:
/**
* Empty constructor, can be used to read data to the systems
* memory and not to the driver.
*/
SGSoundSample();
/** /**
* Constructor * Constructor
* @param path Path name to sound * @param path Path name to sound
* @param file File name of 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 should usually be true unless you want to manipulate the data
later.) later.)
*/ */
SGSoundSample( const char *path, const char *file, bool cleanup ); SGSoundSample( const char *path, const char *file );
/** /**
* Constructor. * Constructor.
@ -180,13 +184,6 @@ public:
return size; 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) * Set position of sound source (uses same coordinate system as opengl)
*/ */
@ -224,6 +221,11 @@ public:
* no longer audible. * no longer audible.
*/ */
void set_max_dist( ALfloat dist ); 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 // "alSource". The semantics of what is going on here seems
// confused and needs to be thought through more carefully. // confused and needs to be thought through more carefully.
_sample = new SGSoundSample( path.c_str(), _sample = new SGSoundSample( path.c_str(),
node->getStringValue("path", ""), node->getStringValue("path", "") );
true );
_mgr->add( _sample, _name ); _mgr->add( _sample, _name );
} }