diff --git a/sound/outputs/openal_out.cpp b/sound/outputs/openal_out.cpp index 649a56aef3..9106901563 100644 --- a/sound/outputs/openal_out.cpp +++ b/sound/outputs/openal_out.cpp @@ -108,10 +108,6 @@ void OpenAL_Sound::setRepeat(bool rep) alSourcei(Source, AL_LOOPING, rep?AL_TRUE:AL_FALSE); } -void OpenAL_Sound::setup() -{ -} - // Constructor used for cloned sounds OpenAL_Sound::OpenAL_Sound(ALuint buf, int *ref) : refCnt(ref), bufferID(buf) @@ -125,19 +121,31 @@ OpenAL_Sound::OpenAL_Sound(ALuint buf, int *ref) alSourcei(inst, AL_BUFFER, bufferID); } -OpenAL_Sound::OpenAL_Sound(SampleSource *input) +OpenAL_Sound::OpenAL_Sound(SampleSourcePtr input) { // Get the format int fmt, rate; getALFormat(inp, fmt, rate); - // Read the entire stream into a buffer - BufferStream buf(input); - - // Move the data into OpenAL + // Set up the OpenAL buffer alGenBuffers(1, &bufferID); assert(bufferID != 0); - alBufferData(bufferID, fmt, &buf.getPtr(), buf.size(), rate); + + // Does the stream support pointer operations? + if(input->hasPtr) + { + // If so, we can read the data directly from the stream + alBufferData(bufferID, fmt, &input.getPtr(), input.size(), rate); + } + else + { + // Read the entire stream into a temporary buffer first + BufferStream buf(input); + + // Then copy that into OpenAL + alBufferData(bufferID, fmt, &buf.getPtr(), buf.size(), rate); + } + checkALError("loading sound buffer"); // Create a source diff --git a/sound/outputs/openal_out.h b/sound/outputs/openal_out.h index a0b8ed4129..115c3c13e3 100644 --- a/sound/outputs/openal_out.h +++ b/sound/outputs/openal_out.h @@ -22,7 +22,7 @@ class OpenAL_Sound : public Sound int *refCnt; public: - OpenAL_Sound(SampleSource *input); + OpenAL_Sound(SampleSourcePtr input); OpenAL_Sound(ALuint buf, int *ref); // Used for cloning ~OpenAL_Sound(); @@ -83,10 +83,10 @@ class OpenAL_Factory : public SoundFactory } } - Sound *load(const std::string &file, bool stream=false) { assert(0); } - Sound *load(Stream::Stream *input, bool stream=false) { assert(0); } - Sound *load(SampleSource* input, bool stream=false) - { return new OpenAL_Sound(input); } + SoundPtr load(const std::string &file, bool stream=false) { assert(0); } + SoundPtr load(Stream::StreamPtr input, bool stream=false) { assert(0); } + SoundPtr load(SampleSourcePtr input, bool stream=false) + { return SoundPtr(new OpenAL_Sound(input)); } void update() {} setListenerPos(float x, float y, float z, diff --git a/sound/source.h b/sound/source.h index 0301f4bae8..f987dfe4ff 100644 --- a/sound/source.h +++ b/sound/source.h @@ -17,15 +17,7 @@ class SampleSource : public Stream::Stream bool isEof; public: - SampleSource() - { - // These are usually not needed for sound data - isSeekable = false; - hasPosition = false; - hasSize = false; - - isEof = false; - } + SampleSource() : isEof(false) {} /// Get the sample rate, number of channels, and bits per /// sample. NULL parameters are ignored. diff --git a/sound/sources/audiere_source.cpp b/sound/sources/audiere_source.cpp index d99c6c4ee6..1a0dfe8dc0 100644 --- a/sound/sources/audiere_source.cpp +++ b/sound/sources/audiere_source.cpp @@ -109,7 +109,7 @@ AudiereSource::AudiereSource(const std::string &file) setup(); } -AudiereSource::AudiereSource(Stream::Stream *input) +AudiereSource::AudiereSource(Stream::StreamPtr input) { // Use our Stream::AudiereFile implementation to convert a Mangle // 'Stream' to an Audiere 'File' diff --git a/sound/sources/audiere_source.h b/sound/sources/audiere_source.h index 1348e112c0..671595a1af 100644 --- a/sound/sources/audiere_source.h +++ b/sound/sources/audiere_source.h @@ -33,7 +33,7 @@ class AudiereSource : public SampleSource AudiereSource(const std::string &file); /// Decode the given sound stream - AudiereSource(Stream::Stream *src); + AudiereSource(Stream::StreamPtr src); /// Read directly from an existing audiere::SampleSource AudiereSource(audiere::SampleSourcePtr src); diff --git a/sound/sources/ffmpeg_source.h b/sound/sources/ffmpeg_source.h index 5317c11c02..d185098fdb 100644 --- a/sound/sources/ffmpeg_source.h +++ b/sound/sources/ffmpeg_source.h @@ -28,7 +28,7 @@ class FFMpegSource : public SampleSource FFMpegSource(const std::string &file); /// Decode the given sound stream (not supported by FFmpeg) - FFMpegSource(Stream::Stream *src) { assert(0); } + FFMpegSource(Stream::StreamPtr src) { assert(0); } ~FFMpegSource(); diff --git a/sound/sources/loadertemplate.h b/sound/sources/loadertemplate.h index 0b668fffa6..f1ebea2d56 100644 --- a/sound/sources/loadertemplate.h +++ b/sound/sources/loadertemplate.h @@ -16,7 +16,7 @@ class SSL_Template : public SampleSourceLoader return new SourceT(file); } - SampleSource *load(Stream::Stream *input) + SampleSource *load(Stream::StreamPtr input) { assert(canLoadStream); return new SourceT(input); diff --git a/sound/sources/memsource.h b/sound/sources/memsource.h index 1e38d90524..72624b899c 100644 --- a/sound/sources/memsource.h +++ b/sound/sources/memsource.h @@ -6,19 +6,21 @@ namespace Mangle { namespace Sound { -/// A sample source reading directly from a memory buffer -class MemorySource : public SampleSource +/// A class for reading raw samples directly from a stream. +class Stream2Samples : public SampleSource { - char *buf; - size_t len; - size_t pos; - int32_t rate, channels, bits; + Stream::StreamPtr inp; public: - MemorySource(void *_buf, size_t _len, int32_t _rate, int32_t _channels, int32_t _bits) - : len(_len), pos(0), rate(_rate), channels(_channels), bits(_bits) - { buf = (char*)_buf; } + Stream2Samples(Stream::StreamPtr _inp, int32_t _rate, int32_t _channels, int32_t _bits) + : inp(_inp), rate(_rate), channels(_channels), bits(_bits) + { + isSeekable = inp->isSeekable; + hasPosition = inp->hasPosition; + hasSize = inp->hasSize; + hasPtr = inp->hasPtr; + } /// Get the sample rate, number of channels, and bits per /// sample. NULL parameters are ignored. @@ -29,20 +31,16 @@ class MemorySource : public SampleSource if(_bits) *_bits = bits; } - bool eof() const { return pos == len; } - size_t read(void *out, size_t count) - { - assert(len >= pos); - - if(count > (len-pos)) - count = len-pos; - - if(count) memcpy(out, buf+pos, count); - pos += count; - - return count; - } + { return inp->read(out, count); } + + void seek(size_t pos) { inp->seek(pos); } + size_t tell() const { return inp->tell(); } + size_t size() const { return inp->size(); } + bool eof() const { return inp->eof(); } + void *getPtr() const { return inp->getPtr(); } + void *getPtr(size_t size) const { return inp->getPtr(size); } + void *getPtr(size_t pos, size_t size) const { return inp->getPtr(pos, size); } }; }} // namespaces