X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FMoof%2FSound.cc;h=59acfaa9af269886ec0cc34a8286671751f75505;hb=a5f0d391406a68275b41448fc3f49e8d8396c497;hp=9a632ebf3ace404b31787b16f227c70fecba4d60;hpb=bfa6212d09d8735d8fd5e2638188e4a99f21ada4;p=chaz%2Fyoink diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc index 9a632eb..59acfaa 100644 --- a/src/Moof/Sound.cc +++ b/src/Moof/Sound.cc @@ -36,6 +36,7 @@ #include "Mippleton.hh" #include "Sound.hh" +#define BUFFER_SIZE (8 * 4096) namespace Mf { @@ -60,20 +61,26 @@ 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) { @@ -81,25 +88,49 @@ struct Sound::Impl exit(1); } + if (!stream) + { unsigned decoded = Sound_DecodeAll(sound); if (decoded == 0) { std::cout << "decoded no bytes" << std::endl; exit(1); } + + alGenBuffers(2, objects); + alBufferData(objects[0], getAudioFormat(sound->actual), sound->buffer, + sound->buffer_size, sound->actual.rate); 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, - sound->buffer_size, sound->actual.rate); - Sound_FreeSample(sound); + sound = 0; + } + else + { + 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(2, objects); + } + } + + 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; } - ALuint object; + Sound_Sample* sound; + ALuint objects[2]; //ALfloat location[] = {0.0f, 0.0f, 0.0f}; //ALfloat location2[] = {0.0f, 0.0f, 0.0f}; @@ -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); }