Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2009-08-21 23:39:28 +0400
committerJoerg Mueller <nexyon@gmail.com>2009-08-21 23:39:28 +0400
commitf248b25152db25c03c9e296ed965b6925924829a (patch)
tree6827d9d24d0d570b14f355ba9128f8c8adefa936 /intern/audaspace
parent647fd95c7fc25170ec2f1c75137f4e6f39c66651 (diff)
Audio file loading backend libsndfile!
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/CMakeLists.txt8
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp49
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h9
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp9
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h10
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp14
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp95
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h71
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp67
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h71
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp233
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h131
12 files changed, 707 insertions, 60 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 940a4b2bedc..1b48de3190b 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -53,6 +53,12 @@ IF(WITH_JACK)
ADD_DEFINITIONS(-DWITH_JACK)
ENDIF(WITH_JACK)
-SET(SRC ${SRC} ${FFMPEGSRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
+IF(WITH_SNDFILE)
+ SET(INC ${INC} sndfile ${SNDFILE_INC})
+ FILE(GLOB SNDFILESRC sndfile/*.cpp)
+ ADD_DEFINITIONS(-DWITH_SNDFILE)
+ENDIF(WITH_SNDFILE)
+
+SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
index 5f9006b0ec0..f67c819ff10 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
@@ -25,31 +25,24 @@
#include "AUD_FFMPEGFactory.h"
#include "AUD_FFMPEGReader.h"
-#include "AUD_Space.h"
-
-extern "C" {
-#include <libavformat/avformat.h>
-}
+#include "AUD_Buffer.h"
AUD_FFMPEGFactory::AUD_FFMPEGFactory(const char* filename)
{
- if(filename != 0)
+ if(filename != NULL)
{
m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
strcpy(m_filename, filename);
}
else
- m_filename = 0;
- m_buffer = 0;
- m_size = 0;
+ m_filename = NULL;
}
AUD_FFMPEGFactory::AUD_FFMPEGFactory(unsigned char* buffer, int size)
{
- m_filename = 0;
- m_buffer = (unsigned char*)av_malloc(size); AUD_NEW("buffer")
- m_size = size;
- memcpy(m_buffer, buffer, size);
+ m_filename = NULL;
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer(size));
+ memcpy(m_buffer.get()->getBuffer(), buffer, size);
}
AUD_FFMPEGFactory::~AUD_FFMPEGFactory()
@@ -58,31 +51,15 @@ AUD_FFMPEGFactory::~AUD_FFMPEGFactory()
{
delete[] m_filename; AUD_DELETE("string")
}
- if(m_buffer)
- {
- av_free(m_buffer); AUD_DELETE("buffer")
- }
}
AUD_IReader* AUD_FFMPEGFactory::createReader()
{
- try
- {
- AUD_IReader* reader;
- if(m_filename)
- reader = new AUD_FFMPEGReader(m_filename);
- else
- reader = new AUD_FFMPEGReader(m_buffer, m_size);
- AUD_NEW("reader")
- return reader;
- }
- catch(AUD_Exception e)
- {
- // return 0 if ffmpeg cannot read the file
- if(e.error == AUD_ERROR_FFMPEG)
- return 0;
- // but throw an exception if the file doesn't exist
- else
- throw;
- }
+ AUD_IReader* reader;
+ if(m_filename)
+ reader = new AUD_FFMPEGReader(m_filename);
+ else
+ reader = new AUD_FFMPEGReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
index 0a9fcc22c8b..22560303a73 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
@@ -27,6 +27,8 @@
#define AUD_FFMPEGFACTORY
#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
/**
* This factory reads a sound file via ffmpeg.
@@ -44,12 +46,7 @@ private:
/**
* The buffer to read from.
*/
- unsigned char* m_buffer;
-
- /**
- * The size of the buffer.
- */
- int m_size;
+ AUD_Reference<AUD_Buffer> m_buffer;
public:
/**
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index b79375c2dc5..de0e47300f8 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -158,21 +158,22 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
AUD_NEW("buffer")
}
-AUD_FFMPEGReader::AUD_FFMPEGReader(unsigned char* buffer, int size)
+AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
{
m_position = 0;
m_pkgbuf_left = 0;
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
AUD_NEW("byteiocontext")
+ m_membuffer = buffer;
- if(init_put_byte(m_byteiocontext, buffer, size, 0,
+ if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
NULL, NULL, NULL, NULL) != 0)
AUD_THROW(AUD_ERROR_FILE);
AVProbeData probe_data;
probe_data.filename = "";
- probe_data.buf = buffer;
- probe_data.buf_size = size;
+ probe_data.buf = buffer.get()->getBuffer();
+ probe_data.buf_size = buffer.get()->getSize();
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
// open stream
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 645f5f356f0..6e303934f36 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -27,7 +27,9 @@
#define AUD_FFMPEGREADER
#include "AUD_IReader.h"
+#include "AUD_Reference.h"
class AUD_Buffer;
+
struct AVCodecContext;
extern "C" {
#include <libavformat/avformat.h>
@@ -90,6 +92,11 @@ private:
int m_stream;
/**
+ * The memory file to read from, only saved to keep the buffer alive.
+ */
+ AUD_Reference<AUD_Buffer> m_membuffer;
+
+ /**
* Decodes a packet into the given buffer.
* \param packet The AVPacket to decode.
* \param buffer The target buffer.
@@ -109,11 +116,10 @@ public:
/**
* Creates a new reader.
* \param buffer The buffer to read from.
- * \param size The size of the buffer.
* \exception AUD_Exception Thrown if the buffer specified cannot be read
* with ffmpeg.
*/
- AUD_FFMPEGReader(unsigned char* buffer, int size);
+ AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer);
/**
* Destroys the reader and closes the file.
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index d2c8e94c949..9481e2139e8 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -25,6 +25,7 @@
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
+#include "AUD_FileFactory.h"
#include "AUD_StreamBufferFactory.h"
#include "AUD_DelayFactory.h"
#include "AUD_LimiterFactory.h"
@@ -48,7 +49,6 @@
#endif
#ifdef WITH_FFMPEG
-#include "AUD_FFMPEGFactory.h"
extern "C" {
#include <libavformat/avformat.h>
}
@@ -187,21 +187,13 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
AUD_Sound* AUD_load(const char* filename)
{
assert(filename);
-#ifdef WITH_FFMPEG
- return new AUD_FFMPEGFactory(filename);
-#else
- return NULL;
-#endif
+ return new AUD_FileFactory(filename);
}
AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
{
assert(buffer);
-#ifdef WITH_FFMPEG
- return new AUD_FFMPEGFactory(buffer, size);
-#else
- return NULL;
-#endif
+ return new AUD_FileFactory(buffer, size);
}
AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
new file mode 100644
index 00000000000..a1f81f49061
--- /dev/null
+++ b/intern/audaspace/intern/AUD_FileFactory.cpp
@@ -0,0 +1,95 @@
+/*
+ * $Id: AUD_FFMPEGFactory.cpp 22328 2009-08-09 23:23:19Z gsrb3d $
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FileFactory.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+#ifdef WITH_FFMPEG
+#include "AUD_FFMPEGReader.h"
+#endif
+#ifdef WITH_SNDFILE
+#include "AUD_SndFileReader.h"
+#endif
+
+AUD_FileFactory::AUD_FileFactory(const char* filename)
+{
+ if(filename != NULL)
+ {
+ m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
+ strcpy(m_filename, filename);
+ }
+ else
+ m_filename = NULL;
+}
+
+AUD_FileFactory::AUD_FileFactory(unsigned char* buffer, int size)
+{
+ m_filename = NULL;
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer(size));
+ memcpy(m_buffer.get()->getBuffer(), buffer, size);
+}
+
+AUD_FileFactory::~AUD_FileFactory()
+{
+ if(m_filename)
+ {
+ delete[] m_filename; AUD_DELETE("string")
+ }
+}
+
+AUD_IReader* AUD_FileFactory::createReader()
+{
+ AUD_IReader* reader = 0;
+
+#ifdef WITH_SNDFILE
+ try
+ {
+ if(m_filename)
+ reader = new AUD_SndFileReader(m_filename);
+ else
+ reader = new AUD_SndFileReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+ }
+ catch(AUD_Exception e) {}
+#endif
+
+#ifdef WITH_FFMPEG
+ try
+ {
+ if(m_filename)
+ reader = new AUD_FFMPEGReader(m_filename);
+ else
+ reader = new AUD_FFMPEGReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+ }
+ catch(AUD_Exception e) {}
+#endif
+
+ return reader;
+}
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
new file mode 100644
index 00000000000..8badb4429df
--- /dev/null
+++ b/intern/audaspace/intern/AUD_FileFactory.h
@@ -0,0 +1,71 @@
+/*
+ * $Id: AUD_FFMPEGFactory.h 22328 2009-08-09 23:23:19Z gsrb3d $
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FILEFACTORY
+#define AUD_FILEFACTORY
+
+#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * This factory tries to read a sound file via all available file readers.
+ */
+class AUD_FileFactory : public AUD_IFactory
+{
+private:
+ /**
+ * The filename of the sound source file.
+ */
+ char* m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+public:
+ /**
+ * Creates a new factory.
+ * \param filename The sound file path.
+ */
+ AUD_FileFactory(const char* filename);
+
+ /**
+ * Creates a new factory.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ AUD_FileFactory(unsigned char* buffer, int size);
+
+ /**
+ * Destroys the factory.
+ */
+ ~AUD_FileFactory();
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_FILEFACTORY
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
new file mode 100644
index 00000000000..d3c5ea8a273
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * $Id: AUD_FFMPEGFactory.cpp 22328 2009-08-09 23:23:19Z gsrb3d $
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SndFileFactory.h"
+#include "AUD_SndFileReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_SndFileFactory::AUD_SndFileFactory(const char* filename)
+{
+ if(filename != NULL)
+ {
+ m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
+ strcpy(m_filename, filename);
+ }
+ else
+ m_filename = NULL;
+}
+
+AUD_SndFileFactory::AUD_SndFileFactory(unsigned char* buffer, int size)
+{
+ m_filename = NULL;
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer(size));
+ memcpy(m_buffer.get()->getBuffer(), buffer, size);
+}
+
+AUD_SndFileFactory::~AUD_SndFileFactory()
+{
+ if(m_filename)
+ {
+ delete[] m_filename; AUD_DELETE("string")
+ }
+}
+
+AUD_IReader* AUD_SndFileFactory::createReader()
+{
+ AUD_IReader* reader;
+ if(m_filename)
+ reader = new AUD_SndFileReader(m_filename);
+ else
+ reader = new AUD_SndFileReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+}
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.h b/intern/audaspace/sndfile/AUD_SndFileFactory.h
new file mode 100644
index 00000000000..6e265a63abe
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.h
@@ -0,0 +1,71 @@
+/*
+ * $Id: AUD_FFMPEGFactory.h 22328 2009-08-09 23:23:19Z gsrb3d $
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SNDFILEFACTORY
+#define AUD_SNDFILEFACTORY
+
+#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * This factory reads a sound file via libsndfile.
+ */
+class AUD_SndFileFactory : public AUD_IFactory
+{
+private:
+ /**
+ * The filename of the sound source file.
+ */
+ char* m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+public:
+ /**
+ * Creates a new factory.
+ * \param filename The sound file path.
+ */
+ AUD_SndFileFactory(const char* filename);
+
+ /**
+ * Creates a new factory.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ AUD_SndFileFactory(unsigned char* buffer, int size);
+
+ /**
+ * Destroys the factory.
+ */
+ ~AUD_SndFileFactory();
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_SNDFILEFACTORY
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
new file mode 100644
index 00000000000..8daef573d37
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -0,0 +1,233 @@
+/*
+ * $Id: AUD_FFMPEGReader.cpp 22328 2009-08-09 23:23:19Z gsrb3d $
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SndFileReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+// This function transforms a SampleFormat to our own sample format
+static inline AUD_SampleFormat SNDFILE_TO_AUD(int fmt)
+{
+ switch(fmt & SF_FORMAT_SUBMASK)
+ {
+ // only read s16, s32 and double as they are
+ case SF_FORMAT_PCM_16:
+ return AUD_FORMAT_S16;
+ case SF_FORMAT_PCM_32:
+ return AUD_FORMAT_S32;
+ case SF_FORMAT_DOUBLE:
+ return AUD_FORMAT_FLOAT64;
+ // read all other formats as floats
+ default:
+ return AUD_FORMAT_FLOAT32;
+ }
+}
+
+sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
+{
+ AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
+ return reader->m_membuffer.get()->getSize();
+}
+
+sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user_data)
+{
+ AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ reader->m_memoffset = offset;
+ break;
+ case SEEK_CUR:
+ reader->m_memoffset = reader->m_memoffset + offset;
+ break;
+ case SEEK_END:
+ reader->m_memoffset = reader->m_membuffer.get()->getSize() + offset;
+ break;
+ }
+
+ return reader->m_memoffset;
+}
+
+sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count, void *user_data)
+{
+ AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
+
+ if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
+ count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
+
+ memcpy(ptr, reader->m_membuffer.get()->getBuffer() + reader->m_memoffset, count);
+ reader->m_memoffset += count;
+
+ return count;
+}
+
+sf_count_t AUD_SndFileReader::vio_tell(void *user_data)
+{
+ AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
+
+ return reader->m_memoffset;
+}
+
+AUD_SndFileReader::AUD_SndFileReader(const char* filename)
+{
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open(filename, SFM_READ, &sfinfo);
+
+ if(!m_sndfile)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ m_specs.channels = (AUD_Channels) sfinfo.channels;
+ m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
+ m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+ m_position = 0;
+
+ switch(m_specs.format)
+ {
+ case AUD_FORMAT_S16:
+ m_read = (sf_read_f) sf_readf_short;
+ break;
+ case AUD_FORMAT_S32:
+ m_read = (sf_read_f) sf_readf_int;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_read = (sf_read_f) sf_readf_double;
+ break;
+ default:
+ m_read = (sf_read_f) sf_readf_float;
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
+{
+ m_membuffer = buffer;
+ m_memoffset = 0;
+
+ m_vio.get_filelen = vio_get_filelen;
+ m_vio.read = vio_read;
+ m_vio.seek = vio_seek;
+ m_vio.tell = vio_tell;
+ m_vio.write = NULL;
+
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this);
+
+ if(!m_sndfile)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ m_specs.channels = (AUD_Channels) sfinfo.channels;
+ m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
+ m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+ m_position = 0;
+
+ switch(m_specs.format)
+ {
+ case AUD_FORMAT_S16:
+ m_read = (sf_read_f) sf_readf_short;
+ break;
+ case AUD_FORMAT_S32:
+ m_read = (sf_read_f) sf_readf_int;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_read = (sf_read_f) sf_readf_double;
+ break;
+ default:
+ m_read = (sf_read_f) sf_readf_float;
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SndFileReader::~AUD_SndFileReader()
+{
+ sf_close(m_sndfile);
+
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_SndFileReader::isSeekable()
+{
+ return m_seekable;
+}
+
+void AUD_SndFileReader::seek(int position)
+{
+ if(m_seekable)
+ {
+ position = sf_seek(m_sndfile, position, SEEK_SET);
+ m_position = position;
+ }
+}
+
+int AUD_SndFileReader::getLength()
+{
+ return m_length;
+}
+
+int AUD_SndFileReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_SndFileReader::getSpecs()
+{
+ return m_specs;
+}
+
+AUD_ReaderType AUD_SndFileReader::getType()
+{
+ return AUD_TYPE_STREAM;
+}
+
+bool AUD_SndFileReader::notify(AUD_Message &message)
+{
+ return false;
+}
+
+void AUD_SndFileReader::read(int & length, sample_t* & buffer)
+{
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+
+ // resize output buffer if necessary
+ if(m_buffer->getSize() < length*sample_size)
+ m_buffer->resize(length*sample_size);
+
+ buffer = m_buffer->getBuffer();
+
+ length = m_read(m_sndfile, buffer, length);
+
+ m_position += length;
+}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
new file mode 100644
index 00000000000..f55c36b47e8
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.h
@@ -0,0 +1,131 @@
+/*
+ * $Id: AUD_FFMPEGReader.h 22328 2009-08-09 23:23:19Z gsrb3d $
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SNDFILEREADER
+#define AUD_SNDFILEREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+#include <sndfile.h>
+
+typedef sf_count_t (*sf_read_f)(SNDFILE *sndfile, void *ptr, sf_count_t frames);
+
+/**
+ * This class reads a sound file via libsndfile.
+ */
+class AUD_SndFileReader : public AUD_IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The sample count in the file.
+ */
+ int m_length;
+
+ /**
+ * Whether the file is seekable.
+ */
+ bool m_seekable;
+
+ /**
+ * The specification of the audio data.
+ */
+ AUD_Specs m_specs;
+
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * The sndfile.
+ */
+ SNDFILE* m_sndfile;
+
+ /**
+ * The reading function.
+ */
+ sf_read_f m_read;
+
+ /**
+ * The virtual IO structure for memory file reading.
+ */
+ SF_VIRTUAL_IO m_vio;
+
+ /**
+ * The pointer to the memory file.
+ */
+ AUD_Reference<AUD_Buffer> m_membuffer;
+
+ /**
+ * The current reading pointer of the memory file.
+ */
+ int m_memoffset;
+
+ // Functions for libsndfile virtual IO functionality
+ static sf_count_t vio_get_filelen(void *user_data);
+ static sf_count_t vio_seek(sf_count_t offset, int whence, void *user_data);
+ static sf_count_t vio_read(void *ptr, sf_count_t count, void *user_data);
+ static sf_count_t vio_tell(void *user_data);
+
+public:
+ /**
+ * Creates a new reader.
+ * \param filename The path to the file to be read.
+ * \exception AUD_Exception Thrown if the file specified does not exist or
+ * cannot be read with libsndfile.
+ */
+ AUD_SndFileReader(const char* filename);
+
+ /**
+ * Creates a new reader.
+ * \param buffer The buffer to read from.
+ * \exception AUD_Exception Thrown if the buffer specified cannot be read
+ * with libsndfile.
+ */
+ AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~AUD_SndFileReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SNDFILEREADER