// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#include "audio/dummy_sound_source.hpp"
+
+#include <memory>
+
#include "audio/sound_source.hpp"
class DummySoundSource : public SoundSource
private:
bool is_playing;
+
+private:
+ DummySoundSource(const DummySoundSource&) = delete;
+ DummySoundSource& operator=(const DummySoundSource&) = delete;
};
-SoundSource* create_dummy_sound_source()
+std::unique_ptr<SoundSource> create_dummy_sound_source()
{
- return new DummySoundSource();
+ return std::unique_ptr<SoundSource>(new DummySoundSource);
}
/* EOF */
#ifndef HEADER_SUPERTUX_AUDIO_DUMMY_SOUND_SOURCE_HPP
#define HEADER_SUPERTUX_AUDIO_DUMMY_SOUND_SOURCE_HPP
+#include <memory>
+
class SoundSource;
-SoundSource* create_dummy_sound_source();
+std::unique_ptr<SoundSource> create_dummy_sound_source();
#endif
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "audio/openal_sound_source.hpp"
+
#include "audio/sound_manager.hpp"
OpenALSoundSource::OpenALSoundSource() :
friend class SoundManager;
ALuint source;
+
+private:
+ OpenALSoundSource(const OpenALSoundSource&) = delete;
+ OpenALSoundSource& operator=(const OpenALSoundSource&) = delete;
};
#endif
#include "util/file_system.hpp"
#include "util/log.hpp"
-SoundFile* load_music_file(const std::string& filename)
+std::unique_ptr<SoundFile> load_music_file(const std::string& filename)
{
lisp::Parser parser(false);
const lisp::Lisp* root = parser.parse(filename);
throw SoundError(msg.str());
}
- return new OggSoundFile(file, loop_begin, loop_at);
+ return std::unique_ptr<SoundFile>(new OggSoundFile(file, loop_begin, loop_at));
}
-SoundFile* load_sound_file(const std::string& filename)
+std::unique_ptr<SoundFile> load_sound_file(const std::string& filename)
{
if(filename.length() > 6
&& filename.compare(filename.length()-6, 6, ".music") == 0) {
throw SoundError("Couldn't read magic, file too short");
PHYSFS_seek(file, 0);
if(strncmp(magic, "RIFF", 4) == 0)
- return new WavSoundFile(file);
+ return std::unique_ptr<SoundFile>(new WavSoundFile(file));
else if(strncmp(magic, "OggS", 4) == 0)
- return new OggSoundFile(file, 0, -1);
+ return std::unique_ptr<SoundFile>(new OggSoundFile(file, 0, -1));
else
throw SoundError("Unknown file format");
} catch(std::exception& e) {
#define HEADER_SUPERTUX_AUDIO_SOUND_FILE_HPP
#include <iostream>
+#include <memory>
class SoundFile
{
int bits_per_sample;
/// size in bytes
size_t size;
+
+private:
+ SoundFile(const SoundFile&) = delete;
+ SoundFile& operator=(const SoundFile&) = delete;
};
-SoundFile* load_sound_file(const std::string& filename);
+std::unique_ptr<SoundFile> load_sound_file(const std::string& filename);
#endif
buffers(),
sources(),
update_list(),
- music_source(0),
+ music_source(),
music_enabled(false),
current_music()
{
SoundManager::~SoundManager()
{
- delete music_source;
-
- for(SoundSources::iterator i = sources.begin(); i != sources.end(); ++i) {
- delete *i;
- }
+ music_source.reset();
+ sources.clear();
for(SoundBuffers::iterator i = buffers.begin(); i != buffers.end(); ++i) {
ALuint buffer = i->second;
}
ALuint
-SoundManager::load_file_into_buffer(SoundFile* file)
+SoundManager::load_file_into_buffer(SoundFile& file)
{
ALenum format = get_sample_format(file);
ALuint buffer;
alGenBuffers(1, &buffer);
check_al_error("Couldn't create audio buffer: ");
- char* samples = new char[file->size];
- try {
- file->read(samples, file->size);
- alBufferData(buffer, format, samples,
- static_cast<ALsizei> (file->size),
- static_cast<ALsizei> (file->rate));
- check_al_error("Couldn't fill audio buffer: ");
- } catch(...) {
- delete[] samples;
- throw;
- }
- delete[] samples;
+ std::unique_ptr<char[]> samples(new char[file.size]);
+ file.read(samples.get(), file.size);
+ alBufferData(buffer, format, samples.get(),
+ static_cast<ALsizei>(file.size),
+ static_cast<ALsizei>(file.rate));
+ check_al_error("Couldn't fill audio buffer: ");
return buffer;
}
-OpenALSoundSource*
+std::unique_ptr<OpenALSoundSource>
SoundManager::intern_create_sound_source(const std::string& filename)
{
assert(sound_enabled);
- std::unique_ptr<OpenALSoundSource> source (new OpenALSoundSource());
+ std::unique_ptr<OpenALSoundSource> source(new OpenALSoundSource);
ALuint buffer;
buffer = i->second;
} else {
// Load sound file
- std::unique_ptr<SoundFile> file (load_sound_file(filename));
+ std::unique_ptr<SoundFile> file(load_sound_file(filename));
if(file->size < 100000) {
- buffer = load_file_into_buffer(file.get());
+ buffer = load_file_into_buffer(*file);
buffers.insert(std::make_pair(filename, buffer));
} else {
- StreamSoundSource* source = new StreamSoundSource();
- source->set_sound_file(file.release());
- return source;
+ std::unique_ptr<StreamSoundSource> source(new StreamSoundSource);
+ source->set_sound_file(std::move(file));
+ return std::move(source);
}
log_debug << "Uncached sound \"" << filename << "\" requested to be played" << std::endl;
}
alSourcei(source->source, AL_BUFFER, buffer);
- return source.release();
+ return std::move(source);
}
-SoundSource*
+std::unique_ptr<SoundSource>
SoundManager::create_sound_source(const std::string& filename)
{
if(!sound_enabled)
if(file->size >= 100000)
return;
- ALuint buffer = load_file_into_buffer(file.get());
+ ALuint buffer = load_file_into_buffer(*file);
buffers.insert(std::make_pair(filename, buffer));
} catch(std::exception& e) {
log_warning << "Error while preloading sound file: " << e.what() << std::endl;
return;
try {
- std::unique_ptr<OpenALSoundSource> source
- (intern_create_sound_source(filename));
+ std::unique_ptr<OpenALSoundSource> source(intern_create_sound_source(filename));
if(pos.x < 0 || pos.y < 0) {
source->set_relative(true);
source->set_position(pos);
}
source->play();
- sources.push_back(source.release());
+ sources.push_back(std::move(source));
} catch(std::exception& e) {
log_warning << "Couldn't play sound " << filename << ": " << e.what() << std::endl;
}
}
void
-SoundManager::manage_source(SoundSource* source)
+SoundManager::manage_source(std::unique_ptr<SoundSource> source)
{
- assert(source != NULL);
-
- OpenALSoundSource* openal_source = dynamic_cast<OpenALSoundSource*> (source);
- if(openal_source != NULL) {
- sources.push_back(openal_source);
+ assert(source);
+ if (dynamic_cast<OpenALSoundSource*>(source.get()))
+ {
+ std::unique_ptr<OpenALSoundSource> openal_source(dynamic_cast<OpenALSoundSource*>(source.release()));
+ sources.push_back(std::move(openal_source));
}
}
void
-SoundManager::register_for_update( StreamSoundSource* sss ){
- if( sss != NULL ){
- update_list.push_back( sss );
+SoundManager::register_for_update(StreamSoundSource* sss)
+{
+ if (sss)
+ {
+ update_list.push_back(sss);
}
}
void
-SoundManager::remove_from_update( StreamSoundSource* sss ){
- if( sss != NULL ){
+SoundManager::remove_from_update(StreamSoundSource* sss)
+{
+ if (sss)
+ {
StreamSoundSources::iterator i = update_list.begin();
while( i != update_list.end() ){
if( *i == sss ){
play_music(current_music);
} else {
if(music_source) {
- delete music_source;
- music_source = NULL;
+ music_source.reset();
}
}
}
&& music_source->get_fade_state() != StreamSoundSource::FadingOff)
music_source->set_fading(StreamSoundSource::FadingOff, fadetime);
} else {
- delete music_source;
- music_source = NULL;
+ music_source.reset();
}
current_music = "";
}
return;
if(filename == "") {
- delete music_source;
- music_source = NULL;
+ music_source.reset();
return;
}
newmusic->set_fading(StreamSoundSource::FadingOn, .5f);
newmusic->play();
- delete music_source;
- music_source = newmusic.release();
+ music_source = std::move(newmusic);
} catch(std::exception& e) {
log_warning << "Couldn't play music file '" << filename << "': " << e.what() << std::endl;
// When this happens, previous music continued playing, stop it, just in case.
// update and check for finished sound sources
for(SoundSources::iterator i = sources.begin(); i != sources.end(); ) {
- OpenALSoundSource* source = *i;
+ auto& source = *i;
source->update();
if(!source->playing()) {
- delete source;
i = sources.erase(i);
} else {
++i;
}
ALenum
-SoundManager::get_sample_format(SoundFile* file)
+SoundManager::get_sample_format(const SoundFile& file)
{
- if(file->channels == 2) {
- if(file->bits_per_sample == 16) {
+ if(file.channels == 2) {
+ if(file.bits_per_sample == 16) {
return AL_FORMAT_STEREO16;
- } else if(file->bits_per_sample == 8) {
+ } else if(file.bits_per_sample == 8) {
return AL_FORMAT_STEREO8;
} else {
throw std::runtime_error("Only 16 and 8 bit samples supported");
}
- } else if(file->channels == 1) {
- if(file->bits_per_sample == 16) {
+ } else if(file.channels == 1) {
+ if(file.bits_per_sample == 16) {
return AL_FORMAT_MONO16;
- } else if(file->bits_per_sample == 8) {
+ } else if(file.bits_per_sample == 8) {
return AL_FORMAT_MONO8;
} else {
throw std::runtime_error("Only 16 and 8 bit samples supported");
#define HEADER_SUPERTUX_AUDIO_SOUND_MANAGER_HPP
#include <map>
+#include <memory>
#include <string>
#include <vector>
* sound).
* This function never throws exceptions, but might return a DummySoundSource
*/
- SoundSource* create_sound_source(const std::string& filename);
+ std::unique_ptr<SoundSource> create_sound_source(const std::string& filename);
/**
* Convenience function to simply play a sound at a given position.
*/
* Adds the source to the list of managed sources (= the source gets deleted
* when it finished playing)
*/
- void manage_source(SoundSource* source);
+ void manage_source(std::unique_ptr<SoundSource> source);
/// preloads a sound, so that you don't get a lag later when playing it
void preload(const std::string& name);
friend class StreamSoundSource;
/** creates a new sound source, might throw exceptions, never returns NULL */
- OpenALSoundSource* intern_create_sound_source(const std::string& filename);
- static ALuint load_file_into_buffer(SoundFile* file);
- static ALenum get_sample_format(SoundFile* file);
+ std::unique_ptr<OpenALSoundSource> intern_create_sound_source(const std::string& filename);
+ static ALuint load_file_into_buffer(SoundFile& file);
+ static ALenum get_sample_format(const SoundFile& file);
void print_openal_version();
void check_alc_error(const char* message);
typedef std::map<std::string, ALuint> SoundBuffers;
SoundBuffers buffers;
- typedef std::vector<OpenALSoundSource*> SoundSources;
+ typedef std::vector<std::unique_ptr<OpenALSoundSource> > SoundSources;
SoundSources sources;
typedef std::vector<StreamSoundSource*> StreamSoundSources;
StreamSoundSources update_list;
- StreamSoundSource* music_source;
+ std::unique_ptr<StreamSoundSource> music_source;
bool music_enabled;
std::string current_music;
class SoundSource
{
public:
- virtual ~SoundSource()
- { }
+ SoundSource() {}
+ virtual ~SoundSource() {}
virtual void play() = 0;
virtual void stop() = 0;
virtual void set_position(const Vector& position) = 0;
virtual void set_velocity(const Vector& velocity) = 0;
virtual void set_reference_distance(float distance) = 0;
+
+private:
+ SoundSource(const SoundSource&) = delete;
+ SoundSource& operator=(const SoundSource&) = delete;
};
#endif
#include "util/log.hpp"
StreamSoundSource::StreamSoundSource() :
- file(0),
+ file(),
fade_state(NoFading),
fade_start_time(),
fade_time(),
{
//don't update me any longer
sound_manager->remove_from_update( this );
- delete file;
+ file.reset();
stop();
alDeleteBuffers(STREAMFRAGMENTS, buffers);
SoundManager::check_al_error("Couldn't delete audio buffers: ");
}
void
-StreamSoundSource::set_sound_file(SoundFile* newfile)
+StreamSoundSource::set_sound_file(std::unique_ptr<SoundFile> newfile)
{
- delete file;
- file = newfile;
+ file = std::move(newfile);
ALint queued;
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
StreamSoundSource::fillBufferAndQueue(ALuint buffer)
{
// fill buffer
- char* bufferdata = new char[STREAMFRAGMENTSIZE];
+ std::unique_ptr<char[]> bufferdata(new char[STREAMFRAGMENTSIZE]);
size_t bytesread = 0;
do {
- bytesread += file->read(bufferdata + bytesread,
+ bytesread += file->read(bufferdata.get() + bytesread,
STREAMFRAGMENTSIZE - bytesread);
// end of sound file
if(bytesread < STREAMFRAGMENTSIZE) {
} while(bytesread < STREAMFRAGMENTSIZE);
if(bytesread > 0) {
- ALenum format = SoundManager::get_sample_format(file);
- alBufferData(buffer, format, bufferdata, bytesread, file->rate);
+ ALenum format = SoundManager::get_sample_format(*file);
+ alBufferData(buffer, format, bufferdata.get(), bytesread, file->rate);
SoundManager::check_al_error("Couldn't refill audio buffer: ");
alSourceQueueBuffers(source, 1, &buffer);
SoundManager::check_al_error("Couldn't queue audio buffer: ");
}
- delete[] bufferdata;
// return false if there aren't more buffers to fill
return bytesread >= STREAMFRAGMENTSIZE;
StreamSoundSource();
virtual ~StreamSoundSource();
- void set_sound_file(SoundFile* file);
+ void set_sound_file(std::unique_ptr<SoundFile> newfile);
enum FadeState { NoFading, FadingOn, FadingOff };
= STREAMBUFFERSIZE / STREAMFRAGMENTS;
bool fillBufferAndQueue(ALuint buffer);
- SoundFile* file;
+ std::unique_ptr<SoundFile> file;
ALuint buffers[STREAMFRAGMENTS];
FadeState fade_state;
set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1);
countMe = false;
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
+ ticking = sound_manager->create_sound_source("sounds/fizz.wav");
ticking->set_position(get_pos());
ticking->set_looping(true);
ticking->set_gain(2.0);
void
Dart::activate()
{
- sound_source.reset(sound_manager->create_sound_source(DART_SOUND));
+ sound_source = sound_manager->create_sound_source(DART_SOUND);
sound_source->set_position(get_pos());
sound_source->set_looping(true);
sound_source->set_gain(1.0);
void
Flame::activate()
{
- sound_source.reset(sound_manager->create_sound_source(FLAME_SOUND));
+ sound_source = sound_manager->create_sound_source(FLAME_SOUND);
sound_source->set_position(get_pos());
sound_source->set_looping(true);
sound_source->set_gain(2.0);
if (player)
player->bounce(*this);
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
+ ticking = sound_manager->create_sound_source("sounds/fizz.wav");
ticking->set_position(get_pos());
ticking->set_looping(true);
ticking->set_gain(2.0);
time_until_explosion = TIME_EXPLOSION;
is_exploding = true;
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
+ ticking = sound_manager->create_sound_source("sounds/fizz.wav");
ticking->set_position(get_pos());
ticking->set_looping(true);
ticking->set_reference_distance(32);
ticking->play();
- grunting.reset(sound_manager->create_sound_source("sounds/grunts.ogg"));
+ grunting = sound_manager->create_sound_source("sounds/grunts.ogg");
grunting->set_position(get_pos());
grunting->set_looping(true);
grunting->set_reference_distance(32);
void
TreeWillOWisp::activate()
{
- sound_source.reset(sound_manager->create_sound_source(TREEWILLOSOUND));
+ sound_source = sound_manager->create_sound_source(TREEWILLOSOUND);
sound_source->set_position(get_pos());
sound_source->set_looping(true);
sound_source->set_gain(2.0);
void
WillOWisp::activate()
{
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
+ sound_source = sound_manager->create_sound_source(SOUNDFILE);
sound_source->set_position(get_pos());
sound_source->set_looping(true);
sound_source->set_gain(2.0);
lisp.get("silence_distance",silence_distance);
- sound_source = 0; // not playing at the beginning
+ sound_source.reset(); // not playing at the beginning
sound_manager->preload(sample);
latency=0;
}
void
AmbientSound::stop_playing()
{
- delete sound_source;
- sound_source = 0;
+ sound_source.reset();
}
void
sound_source->play();
} catch(std::exception& e) {
log_warning << "Couldn't play '" << sample << "': " << e.what() << "" << std::endl;
- delete sound_source;
- sound_source = 0;
+ sound_source.reset();
remove_me();
}
}
Vector dimension;
std::string sample;
- SoundSource* sound_source;
+ std::unique_ptr<SoundSource> sound_source;
int latency;
float distance_factor; /// distance scaling