X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FSound.cc;h=368e9388bca4aee4f3665ae40b1abf1afa71f6cd;hp=9a632ebf3ace404b31787b16f227c70fecba4d60;hb=f72400af4fa3e7b54dab154b5a2b6503a6f9af18;hpb=bfa6212d09d8735d8fd5e2638188e4a99f21ada4 diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc index 9a632eb..368e938 100644 --- a/src/Moof/Sound.cc +++ b/src/Moof/Sound.cc @@ -26,16 +26,17 @@ *******************************************************************************/ -#include #include #include #include #include +#include "Log.hh" #include "Mippleton.hh" #include "Sound.hh" +#define BUFFER_SIZE (8 * 4096) namespace Mf { @@ -60,46 +61,76 @@ struct Sound::Impl struct Buffer : public Mippleton { Buffer(const std::string& name) : - Mippleton(name), - object(0) - {} + Mippleton(name) + { + objects[0] = 0; + objects[1] = 0; + } ~Buffer() { - alDeleteBuffers(1, &object); + alDeleteBuffers(2, objects); + + if (sound) Sound_FreeSample(sound); } + + void loadFromFile(const std::string& filePath, bool stream) { - if (object != 0) return; + if (objects[0] != 0) return; - Sound_Sample* sound = Sound_NewSampleFromFile(filePath.c_str(), - NULL, 8096); + sound = Sound_NewSampleFromFile(filePath.c_str(), + NULL, BUFFER_SIZE); if (!sound) { - std::cerr << "could not load sound from file" << std::endl; - exit(1); + logWarning("audio not found: %s", getName().c_str()); + throw Exception(Exception::FILE_NOT_FOUND); } + if (!stream) + { unsigned decoded = Sound_DecodeAll(sound); if (decoded == 0) { - std::cout << "decoded no bytes" << std::endl; - exit(1); + logWarning("decoded not bytes from %s", getName().c_str()); + throw Exception(Exception::FILE_NOT_FOUND); } - std::cerr << "buffer size: " << sound->buffer_size << std::endl; - std::cerr << "channels: " << (int)sound->actual.channels << std::endl; - std::cerr << "format: " << sound->actual.format << std::endl; - std::cerr << "frequency: " << sound->actual.rate << std::endl; - alGenBuffers(1, &object); - alBufferData(object, getAudioFormat(sound->actual), sound->buffer, + alGenBuffers(2, objects); + alBufferData(objects[0], getAudioFormat(sound->actual), sound->buffer, sound->buffer_size, sound->actual.rate); + logDebug("buffer size: %d", sound->buffer_size); + logDebug(" channels: %d", sound->actual.channels); + logDebug(" format: %d", sound->actual.format); + logDebug(" frequency: %d", sound->actual.rate); Sound_FreeSample(sound); + sound = 0; + } + else + { + logDebug("buffer size: %d", sound->buffer_size); + logDebug(" channels: %d", sound->actual.channels); + logDebug(" format: %d", sound->actual.format); + logDebug(" frequency: %d", sound->actual.rate); + alGenBuffers(2, objects); + } } - ALuint object; + bool stream(ALuint buffer) + { + int bytes = Sound_Decode(sound); + + if (bytes < BUFFER_SIZE) return false; + + alBufferData(buffer, getAudioFormat(sound->actual), sound->buffer, + sound->buffer_size, sound->actual.rate); + return false; + } + + Sound_Sample* sound; + ALuint objects[2]; //ALfloat location[] = {0.0f, 0.0f, 0.0f}; //ALfloat location2[] = {0.0f, 0.0f, 0.0f}; @@ -112,7 +143,7 @@ struct Sound::Impl }; Impl(const std::string& name, bool stream = false) : - buffer_(Buffer::retain(name), Buffer::release) + buffer_(Buffer::getInstance(name)) { if (!stream) buffer_->loadFromFile(Sound::getPath(name), stream); else buffer_->loadFromFile(SoundStream::getPath(name), stream); @@ -120,12 +151,24 @@ struct Sound::Impl ALfloat location[] = {0.0f, 0.0f, 0.0f}; alGenSources(1, &source_); - alSourcei(source_, AL_BUFFER, buffer_->object); + alSourcef(source_, AL_PITCH, 1.0f); alSourcef(source_, AL_GAIN, 1.0f); alSourcefv(source_, AL_POSITION, location); alSourcefv(source_, AL_VELOCITY, location); alSourcei(source_, AL_LOOPING, AL_FALSE); + + if (!stream) + { + alSourcei(source_, AL_BUFFER, buffer_->objects[0]); + } + else + { + buffer_->stream(buffer_->objects[0]); + buffer_->stream(buffer_->objects[1]); + + alSourceQueueBuffers(source_, 2, buffer_->objects); + } } ~Impl() @@ -136,11 +179,24 @@ struct Sound::Impl void update() { + int finished = 0; + + alGetSourcei(source_, AL_BUFFERS_PROCESSED, &finished); + + while (finished-- > 0) + { + ALuint buffer; + + alSourceUnqueueBuffers(source_, 1, &buffer); + buffer_->stream(buffer); + alSourceQueueBuffers(source_, 1, &buffer); + } } boost::shared_ptr buffer_; ALuint source_; + bool playing; }; @@ -151,8 +207,26 @@ Sound::Sound(const std::string& name) : void Sound::play() { - alSourceRewind(impl_->source_); + //alSourceRewind(impl_->source_); alSourcePlay(impl_->source_); + impl_->playing = true; +} + +void Sound::pause() +{ + alSourcePause(impl_->source_); + impl_->playing = false; +} + +void Sound::togglePlayPause() +{ + if (impl_->playing) pause(); + else play(); +} + +void Sound::setGain(Scalar gain) +{ + alSourcef(impl_->source_, AL_GAIN, gain); }