+ alSourcei( source, AL_BUFFER, 0 );
+ _free_sources.push_back( source );
+ _sources_in_use.erase( it );
+ }
+}
+
+unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample)
+{
+ ALuint buffer = NO_BUFFER;
+
+ if ( !sample->is_valid_buffer() ) {
+ // sample was not yet loaded or removed again
+ string sample_name = sample->get_sample_name();
+
+ // see if the sample name is already cached
+ buffer_map_iterator buffer_it = _buffers.find( sample_name );
+ if ( buffer_it != _buffers.end() ) {
+ buffer_it->second.refctr++;
+ buffer = buffer_it->second.id;
+ sample->set_buffer( buffer );
+ return buffer;
+ }
+
+ // sample name was not found in the buffer cache.
+ if ( sample->is_file() ) {
+ size_t size;
+ int freq, format;
+ void *data;
+
+ load(sample_name, &data, &format, &size, &freq);
+ sample->set_data( &data );
+ sample->set_frequency( freq );
+ sample->set_format( format );
+ sample->set_size( size );
+ }
+
+ // create an OpenAL buffer handle
+ alGenBuffers(1, &buffer);
+ if ( !testForALError("generate buffer") ) {
+ // Copy data to the internal OpenAL buffer
+
+ const ALvoid *data = sample->get_data();
+ ALenum format = sample->get_format();
+ ALsizei size = sample->get_size();
+ ALsizei freq = sample->get_frequency();
+ alBufferData( buffer, format, data, size, freq );
+
+ // If this sample was read from a file we have all the information
+ // needed to read it again. For data buffers provided by the
+ // program we don't; so don't delete it's data.
+ if ( sample->is_file() ) sample->free_data();
+
+ if ( !testForALError("buffer add data") ) {
+ sample->set_buffer(buffer);
+ _buffers[sample_name] = refUint(buffer);
+ }
+ }