From 4ee198d66c8b54527fa35e1eb55e127f33c1a8a4 Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Tue, 29 Dec 2009 11:56:14 +0100 Subject: [PATCH] Added SampleBuffer (experimental) --- sound/buffer.h | 57 ++++++++++++++++++++++++++++++++++ sound/sources/loadertemplate.h | 6 ++-- sound/sources/memsource.h | 49 +++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 sound/buffer.h create mode 100644 sound/sources/memsource.h diff --git a/sound/buffer.h b/sound/buffer.h new file mode 100644 index 000000000..9cb27bd9c --- /dev/null +++ b/sound/buffer.h @@ -0,0 +1,57 @@ +#ifndef MANGLE_SOUND_BUFFER_H +#define MANGLE_SOUND_BUFFER_H + +#include "source.h" +#include "sources/memsource.h" +#include +#include + +namespace Mangle { +namespace Sound { + +/** A sample buffer is a factory that creates SampleSources from one + single sound source. It is helpful when you have many instances of + one sound and want to use one shared memory buffer. + + This is just a helper class - you don't have to include it in your + program if you don't need it. +*/ +class SampleBuffer +{ + std::vector buffer; + + public: + /// Reads the source into a memory buffer. Not heavily optimized. + SampleBuffer(SampleSource *source) + { + size_t final = 0; + + while(!source->eof()) + { + const int add = 16*1024; + + // Allocate more memory + size_t newSize = final + add; + buffer.resize(newSize); + + // Fill in data + size_t read = source->read(&buffer[final], add); + + // If we couldn't read enough data, we should be at the end + // of the stream + assert(read == add || source->eof()); + + final += read; + } + + // Downsize the buffer to the actual length + buffer.resize(final); + } + + /// Get a new source + SampleSource *get() + { return new MemorySource(&buffer[0], buffer.size()); } +}; + +}} +#endif diff --git a/sound/sources/loadertemplate.h b/sound/sources/loadertemplate.h index 95d0e798c..0b668fffa 100644 --- a/sound/sources/loadertemplate.h +++ b/sound/sources/loadertemplate.h @@ -1,7 +1,7 @@ #ifndef SSL_TEMPL_H #define SSL_TEMPL_H -template +template class SSL_Template : public SampleSourceLoader { SSL_Template() @@ -13,13 +13,13 @@ class SSL_Template : public SampleSourceLoader SampleSource *load(const std::string &file) { assert(canLoadFile); - return new X(file); + return new SourceT(file); } SampleSource *load(Stream::Stream *input) { assert(canLoadStream); - return new X(input); + return new SourceT(input); } }; diff --git a/sound/sources/memsource.h b/sound/sources/memsource.h new file mode 100644 index 000000000..1e38d9052 --- /dev/null +++ b/sound/sources/memsource.h @@ -0,0 +1,49 @@ +#ifndef MANGLE_SOUND_MEMSOURCE_H +#define MANGLE_SOUND_MEMSOURCE_H + +#include "../source.h" + +namespace Mangle { +namespace Sound { + +/// A sample source reading directly from a memory buffer +class MemorySource : public SampleSource +{ + char *buf; + size_t len; + size_t pos; + + int32_t rate, channels, bits; + + 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; } + + /// Get the sample rate, number of channels, and bits per + /// sample. NULL parameters are ignored. + void getInfo(int32_t *_rate, int32_t *_channels, int32_t *_bits) const + { + if(_rate) *_rate = rate; + if(_channels) *_channels = channels; + 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; + } +}; + +}} // namespaces +#endif