#include "Mippleton.hh"
#include "Sound.hh"
+#define BUFFER_SIZE (8 * 4096)
namespace Mf {
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)
{
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};
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()
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;
};
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);
}