]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Sound.cc
improved new vorbisfile compatibility
[chaz/yoink] / src / Moof / Sound.cc
index 110dc4ba0416e03c268147097bd8e4c7f44821ee..f912b318d153c2dfa13ecf1b991169f4e87751ee 100644 (file)
 
 *******************************************************************************/
 
+#include <cstdio>
 #include <string>
 #include <queue>
 #include <vector>
 
-#include <SDL/SDL.h>
-#include <SDL/SDL_sound.h>
 #include <AL/al.h>
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
 
 #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,15 +59,17 @@ struct Sound::Impl
        
        class Buffer : public Mippleton<Buffer>
        {
-               Sound_Sample*                   sound;
+               OggVorbis_File                  oggStream;
+               ALenum                                  audioFormat;
+               ALsizei                                 audioFreq;
                std::vector<ALuint>             objects;
 
        public:
 
                Buffer(const std::string& name) :
-                       Mippleton<Buffer>(name),
-                       sound(0)
+                       Mippleton<Buffer>(name)
                {
+                       oggStream.datasource = 0;
                        openFile();
                }
 
@@ -86,38 +81,65 @@ struct Sound::Impl
                                objects.pop_back();
                        }
 
-                       if (sound) Sound_FreeSample(sound);
+                       if (oggStream.datasource)
+                       {
+                               ov_clear(&oggStream);
+                       }
                }
 
 
                void openFile()
                {
-                       if (sound) Sound_FreeSample(sound);
+                       if (oggStream.datasource)
+                       {
+                               ov_clear(&oggStream);
+                               oggStream.datasource = 0;
+                       }
 
-                       sound = Sound_NewSampleFromFile(Sound::getPath(getName()).c_str(),
-                                       0, BUFFER_SIZE);
+                       std::string filePath = Sound::getPath(getName());
+                       int result = ov_fopen((char*)filePath.c_str(), &oggStream);
 
-                       if (!sound)
+                       if (result < 0)
                        {
-                               logWarning("error while loading sound %s: %s",
-                                               getName().c_str(), Sound_GetError());
-                               throw Exception(Exception::FILE_NOT_FOUND);
+                               logWarning("error while loading sound %s",
+                                               getName().c_str());
+                               throw Exception(Exception::BAD_AUDIO_FORMAT);
                        }
 
-                       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);
+                       vorbis_info* vorbisInfo = ov_info(&oggStream, -1);
+                       audioFormat = getAudioFormat(vorbisInfo);
+                       audioFreq = vorbisInfo->rate;
+
+                       logDebug("   channels: %d", vorbisInfo->channels);
+                       logDebug("  frequency: %d", vorbisInfo->rate);
                }
 
 
                void loadAll(ALuint source)
                {
-                       if (!sound) openFile();
-                       if (!sound) return;
+                       if (!oggStream.datasource) openFile();
+                       if (!oggStream.datasource) return;
+
+                       char data[BUFFER_SIZE];
+                       int size = 0;
+
+                       for (;;)
+                       {
+                               int section;
+                               int result = ov_read(&oggStream, data + size,
+                                               BUFFER_SIZE - size, 0, 2, 1, &section);
 
-                       unsigned decoded = Sound_DecodeAll(sound);
-                       if (decoded == 0)
+                               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 +149,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);
+                       oggStream.datasource = 0;
                }
 
 
                void beginStream(ALuint source, int nBuffers = 4)
                {
-                       if (!sound) openFile();
-                       if (!sound) return;
+                       if (!oggStream.datasource) openFile();
+                       if (!oggStream.datasource) return;
 
                        ALuint objs[nBuffers];
                        alGenBuffers(nBuffers, objs);
@@ -172,20 +193,37 @@ 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;
+
+                       while (size < BUFFER_SIZE)
+                       {
+                               int section;
+                               int result = ov_read(&oggStream, data + size,
+                                               BUFFER_SIZE - size, 0, 2, 1, &section);
+
+                               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 (!oggStream.datasource) openFile();
+                       else ov_raw_seek(&oggStream, 0);
                }
 
 
This page took 0.023515 seconds and 4 git commands to generate.