Audio file loading backend libsndfile!
This commit is contained in:
@@ -70,6 +70,9 @@ MACRO(SETUP_LIBDIRS)
|
||||
IF(WITH_JACK)
|
||||
LINK_DIRECTORIES(${JACK_LIBPATH})
|
||||
ENDIF(WITH_JACK)
|
||||
IF(WITH_SNDFILE)
|
||||
LINK_DIRECTORIES(${SNDFILE_LIBPATH})
|
||||
ENDIF(WITH_SNDFILE)
|
||||
IF(WITH_FFTW3)
|
||||
LINK_DIRECTORIES(${FFTW3_LIBPATH})
|
||||
ENDIF(WITH_FFTW3)
|
||||
@@ -118,6 +121,9 @@ MACRO(SETUP_LIBLINKS
|
||||
IF(WITH_JACK)
|
||||
TARGET_LINK_LIBRARIES(${target} ${JACK_LIB})
|
||||
ENDIF(WITH_JACK)
|
||||
IF(WITH_SNDFILE)
|
||||
TARGET_LINK_LIBRARIES(${target} ${SNDFILE_LIB})
|
||||
ENDIF(WITH_SNDFILE)
|
||||
IF(WITH_SDL)
|
||||
TARGET_LINK_LIBRARIES(${target} ${SDL_LIBRARY})
|
||||
ENDIF(WITH_SDL)
|
||||
|
@@ -70,6 +70,7 @@ OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)"
|
||||
OPTION(WITH_WEBPLUGIN "Enable Web Plugin (Unix only)" OFF)
|
||||
OPTION(WITH_FFTW3 "Enable FFTW3 support" OFF)
|
||||
OPTION(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF)
|
||||
OPTION(WITH_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
|
||||
OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF)
|
||||
OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON)
|
||||
|
||||
@@ -109,6 +110,13 @@ IF(UNIX AND NOT APPLE)
|
||||
SET(JACK_LIBPATH ${JACK}/lib)
|
||||
ENDIF(WITH_JACK)
|
||||
|
||||
IF(WITH_SNDFILE)
|
||||
SET(SNDFILE /usr)
|
||||
SET(SNDFILE_INC ${SNDFILE}/include)
|
||||
SET(SNDFILE_LIB sndfile)
|
||||
SET(SNDFILE_LIBPATH ${SNDFILE}/lib)
|
||||
ENDIF(WITH_SNDFILE)
|
||||
|
||||
FIND_LIBRARY(INTL_LIBRARY
|
||||
NAMES intl
|
||||
PATHS
|
||||
@@ -247,6 +255,13 @@ IF(WIN32)
|
||||
SET(JACK_LIBPATH ${JACK}/lib)
|
||||
ENDIF(WITH_JACK)
|
||||
|
||||
IF(WITH_SNDFILE)
|
||||
SET(SNDFILE ${LIBDIR}/sndfile)
|
||||
SET(SNDFILE_INC ${SNDFILE}/include)
|
||||
SET(SNDFILE_LIB sndfile)
|
||||
SET(SNDFILE_LIBPATH ${SNDFILE}/lib)
|
||||
ENDIF(WITH_SNDFILE)
|
||||
|
||||
IF(CMAKE_CL_64)
|
||||
SET(PNG_LIBRARIES libpng)
|
||||
ELSE(CMAKE_CL_64)
|
||||
@@ -392,6 +407,13 @@ IF(APPLE)
|
||||
SET(JACK_LIBPATH ${JACK}/lib)
|
||||
ENDIF(WITH_JACK)
|
||||
|
||||
IF(WITH_SNDFILE)
|
||||
SET(SNDFILE /usr)
|
||||
SET(SNDFILE_INC ${SNDFILE}/include)
|
||||
SET(SNDFILE_LIB sndfile)
|
||||
SET(SNDFILE_LIBPATH ${SNDFILE}/lib)
|
||||
ENDIF(WITH_SNDFILE)
|
||||
|
||||
SET(PYTHON_VERSION 3.1)
|
||||
|
||||
IF(PYTHON_VERSION MATCHES 3.1)
|
||||
|
@@ -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}")
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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:
|
||||
/**
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
@@ -89,6 +91,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.
|
||||
@@ -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.
|
||||
|
@@ -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)
|
||||
|
95
intern/audaspace/intern/AUD_FileFactory.cpp
Normal file
95
intern/audaspace/intern/AUD_FileFactory.cpp
Normal file
@@ -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;
|
||||
}
|
71
intern/audaspace/intern/AUD_FileFactory.h
Normal file
71
intern/audaspace/intern/AUD_FileFactory.h
Normal file
@@ -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
|
67
intern/audaspace/sndfile/AUD_SndFileFactory.cpp
Normal file
67
intern/audaspace/sndfile/AUD_SndFileFactory.cpp
Normal file
@@ -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;
|
||||
}
|
71
intern/audaspace/sndfile/AUD_SndFileFactory.h
Normal file
71
intern/audaspace/sndfile/AUD_SndFileFactory.h
Normal file
@@ -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
|
233
intern/audaspace/sndfile/AUD_SndFileReader.cpp
Normal file
233
intern/audaspace/sndfile/AUD_SndFileReader.cpp
Normal file
@@ -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;
|
||||
}
|
131
intern/audaspace/sndfile/AUD_SndFileReader.h
Normal file
131
intern/audaspace/sndfile/AUD_SndFileReader.h
Normal file
@@ -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
|
Reference in New Issue
Block a user