]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Sound.cc
dispatcher alias methods
[chaz/yoink] / src / Moof / Sound.cc
index 9a632ebf3ace404b31787b16f227c70fecba4d60..368e9388bca4aee4f3665ae40b1abf1afa71f6cd 100644 (file)
 
 *******************************************************************************/
 
-#include <iostream>
 #include <string>
 
 #include <SDL/SDL.h>
 #include <SDL/SDL_sound.h>
 #include <AL/al.h>
 
+#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>
        {
                Buffer(const std::string& name) :
-                       Mippleton<Buffer>(name),
-                       object(0)
-               {}
+                       Mippleton<Buffer>(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>       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);
 }
 
 
This page took 0.022662 seconds and 4 git commands to generate.