X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FSound.cc;fp=src%2FMoof%2FSound.cc;h=43714fe04872a93e968c0e44d0c7724f78b2d966;hp=110dc4ba0416e03c268147097bd8e4c7f44821ee;hb=5250c138b1a692e4e893a8f424d2856e519fd652;hpb=25aefe01ef7dbdb603c51411e04b0d6a6107684f diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc index 110dc4b..43714fe 100644 --- a/src/Moof/Sound.cc +++ b/src/Moof/Sound.cc @@ -26,13 +26,14 @@ *******************************************************************************/ +#include #include #include #include -#include -#include #include +#include +#include #include "Log.hh" #include "Mippleton.hh" @@ -47,18 +48,10 @@ namespace Mf { struct Sound::Impl { - static ALenum getAudioFormat(const Sound_AudioInfo& audioInfo) + static ALenum getAudioFormat(const vorbis_info* audioInfo) { - if (audioInfo.format == AUDIO_U8 || audioInfo.format == AUDIO_S8) - { - if (audioInfo.channels == 1) return AL_FORMAT_MONO8; - else return AL_FORMAT_STEREO8; - } - else - { - if (audioInfo.channels == 1) return AL_FORMAT_MONO16; - else return AL_FORMAT_STEREO16; - } + if (audioInfo->channels == 1) return AL_FORMAT_MONO16; + else return AL_FORMAT_STEREO16; } class Buffer; @@ -66,14 +59,17 @@ struct Sound::Impl class Buffer : public Mippleton { - Sound_Sample* sound; + FILE* soundFile; + OggVorbis_File oggStream; + ALenum audioFormat; + ALsizei audioFreq; std::vector objects; public: Buffer(const std::string& name) : Mippleton(name), - sound(0) + soundFile(0) { openFile(); } @@ -86,38 +82,79 @@ struct Sound::Impl objects.pop_back(); } - if (sound) Sound_FreeSample(sound); + if (soundFile) + { + ov_clear(&oggStream); + } } void openFile() { - if (sound) Sound_FreeSample(sound); + if (soundFile) + { + ov_clear(&oggStream); + soundFile = 0; + } - sound = Sound_NewSampleFromFile(Sound::getPath(getName()).c_str(), - 0, BUFFER_SIZE); + //soundFile = Sound_NewSampleFromFile(soundFile::getPath(getName()).c_str(), + //0, BUFFER_SIZE); + soundFile = fopen(Sound::getPath(getName()).c_str(), "rb"); - if (!sound) + if (!soundFile) { - logWarning("error while loading sound %s: %s", - getName().c_str(), Sound_GetError()); + logWarning("error while loading sound %s", getName().c_str()); throw Exception(Exception::FILE_NOT_FOUND); } - 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); + int result = ov_open(soundFile, &oggStream, NULL, 0); + + if (result < 0) + { + fclose(soundFile); + soundFile = 0; + + logWarning("error while loading oggvorbis stream %s", + getName().c_str()); + throw Exception(Exception::BAD_AUDIO_FORMAT); + } + + vorbis_info* vorbisInfo = ov_info(&oggStream, -1); + audioFormat = getAudioFormat(vorbisInfo); + audioFreq = vorbisInfo->rate; + + logDebug(" version: %d", vorbisInfo->version); + logDebug(" channels: %d", vorbisInfo->channels); + logDebug(" frequency: %d", vorbisInfo->rate); } void loadAll(ALuint source) { - if (!sound) openFile(); - if (!sound) return; + if (!soundFile) openFile(); + if (!soundFile) return; + + char data[BUFFER_SIZE]; + int size = 0; - unsigned decoded = Sound_DecodeAll(sound); - if (decoded == 0) + //unsigned decoded = Sound_DecodeAll(soundFile); + for (;;) + { + int section; + int result = ov_read(&oggStream, data + size, + BUFFER_SIZE - size, 0, 2, 1, §ion); + + if (result > 0) + { + size += result; + } + else + { + if (result < 0) logWarning("vorbis playback error"); + break; + } + } + if (size == 0) { logWarning("decoded no bytes from %s", getName().c_str()); //throw Exception(Exception::FILE_NOT_FOUND); @@ -127,23 +164,22 @@ struct Sound::Impl ALuint obj; alGenBuffers(1, &obj); - alBufferData(obj, getAudioFormat(sound->actual), sound->buffer, - sound->buffer_size, sound->actual.rate); + alBufferData(obj, audioFormat, data, size, audioFreq); objects.push_back(obj); alSourcei(source, AL_BUFFER, obj); - // don't need t his anymore - Sound_FreeSample(sound); - sound = 0; + // don't need this anymore + ov_clear(&oggStream); + soundFile = 0; } void beginStream(ALuint source, int nBuffers = 4) { - if (!sound) openFile(); - if (!sound) return; + if (!soundFile) openFile(); + if (!soundFile) return; ALuint objs[nBuffers]; alGenBuffers(nBuffers, objs); @@ -172,20 +208,38 @@ struct Sound::Impl // that buffer doesn't belong to us if (it == objects.end()) return STREAM_WRONG; - unsigned bytes = Sound_Decode(sound); + char data[BUFFER_SIZE]; + int size = 0; + + //unsigned bytes = Sound_Decode(soundFile); + while (size < BUFFER_SIZE) + { + int section; + int result = ov_read(&oggStream, data + size, + BUFFER_SIZE - size, 0, 2, 1, §ion); + + if (result > 0) + { + size += result; + } + else + { + if (result < 0) logWarning("vorbis playback error"); + break; + } + } - if (bytes == 0) return STREAM_EOF; + if (size == 0) return STREAM_EOF; - alBufferData(buffer, getAudioFormat(sound->actual), sound->buffer, - bytes, sound->actual.rate); + alBufferData(buffer, audioFormat, data, size, audioFreq); return STREAM_OK; } inline void rewind() { - if (!sound) openFile(); - else Sound_Rewind(sound); + if (!soundFile) openFile(); + else ov_raw_seek(&oggStream, 0); }