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
path: root/intern
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2009-07-11 19:07:36 +0400
committerJoerg Mueller <nexyon@gmail.com>2009-07-11 19:07:36 +0400
commit28f5c0074f43abab85137213548e8dd349281955 (patch)
treefc56d4c4ebfe6021f334c62707fa79404055b150 /intern
parentf759f48ae0a1b3feeafd86a684f6eb651bf23280 (diff)
BGE now uses the audaspace library for sound output. 3D sound and several settings have been lost for the moment.
Diffstat (limited to 'intern')
-rw-r--r--intern/audaspace/AUD_C-API.h32
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp31
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h24
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp79
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h18
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp23
6 files changed, 181 insertions, 26 deletions
diff --git a/intern/audaspace/AUD_C-API.h b/intern/audaspace/AUD_C-API.h
index a6423b78f53..4ddc60d7cf0 100644
--- a/intern/audaspace/AUD_C-API.h
+++ b/intern/audaspace/AUD_C-API.h
@@ -30,17 +30,17 @@
extern "C" {
#endif
-#include "AUD_Space.h"
+#include "intern/AUD_Space.h"
-//#ifndef AUD_CAPI_IMPLEMENTATION
-typedef struct AUD_Sound;
-//#endif
+#ifndef AUD_CAPI_IMPLEMENTATION
+ typedef struct {} AUD_Sound;
+#endif
/**
* Initializes an audio device.
* \return Whether the device has been initialized.
*/
-extern bool AUD_init();
+extern int AUD_init();
/**
* Unitinitializes an audio device.
@@ -55,6 +55,14 @@ extern void AUD_exit();
extern AUD_Sound* AUD_load(const char* filename);
/**
+ * Loads a sound file.
+ * \param buffer The buffer which contains the sound file.
+ * \param size The size of the buffer.
+ * \return A handle of the sound file.
+ */
+extern AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size);
+
+/**
* Unloads a sound file.
* \param sound The handle of the sound file.
*/
@@ -71,29 +79,29 @@ extern void AUD_unload(AUD_Sound* sound);
* \return A handle to the played back sound.
*/
extern AUD_Handle* AUD_play(AUD_Sound* sound,
- AUD_EndBehaviour endBehaviour = AUD_BEHAVIOUR_STOP,
- double seekTo = 0);
+ AUD_EndBehaviour endBehaviour,
+ double seekTo);
/**
* Pauses a played back sound.
* \param handle The handle to the sound.
* \return Whether the handle has been playing or not.
*/
-extern bool AUD_pause(AUD_Handle* handle);
+extern int AUD_pause(AUD_Handle* handle);
/**
* Resumes a paused sound.
* \param handle The handle to the sound.
* \return Whether the handle has been paused or not.
*/
-extern bool AUD_resume(AUD_Handle* handle);
+extern int AUD_resume(AUD_Handle* handle);
/**
* Stops a playing or paused sound.
* \param handle The handle to the sound.
* \return Whether the handle has been valid or not.
*/
-extern bool AUD_stop(AUD_Handle* handle);
+extern int AUD_stop(AUD_Handle* handle);
/**
* Sets the end behaviour of a playing or paused sound.
@@ -101,7 +109,7 @@ extern bool AUD_stop(AUD_Handle* handle);
* \param endBehaviour The behaviour after the end of the file has been reached.
* \return Whether the handle has been valid or not.
*/
-extern bool AUD_setEndBehaviour(AUD_Handle* handle,
+extern int AUD_setEndBehaviour(AUD_Handle* handle,
AUD_EndBehaviour endBehaviour);
/**
@@ -112,7 +120,7 @@ extern bool AUD_setEndBehaviour(AUD_Handle* handle,
* before playback starts.
* \return Whether the handle has been valid or not.
*/
-extern bool AUD_seek(AUD_Handle* handle, int seekTo);
+extern int AUD_seek(AUD_Handle* handle, int seekTo);
/**
* Returns the status of a playing, paused or stopped sound.
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
index 4da80c7d0e5..2a1cfa90227 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
@@ -27,16 +27,43 @@
#include "AUD_FFMPEGReader.h"
#include "AUD_Space.h"
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
AUD_FFMPEGFactory::AUD_FFMPEGFactory(const char* filename)
{
- m_filename = filename;
+ m_filename = new char[strlen(filename)+1];
+ strcpy(m_filename, filename);
+ m_buffer = 0;
+ m_size = 0;
+}
+
+AUD_FFMPEGFactory::AUD_FFMPEGFactory(unsigned char* buffer, int size)
+{
+ m_filename = 0;
+ m_buffer = (unsigned char*)av_malloc(size);
+ m_size = size;
+ memcpy(m_buffer, buffer, size);
+}
+
+AUD_FFMPEGFactory::~AUD_FFMPEGFactory()
+{
+ if(m_filename)
+ delete[] m_filename;
+ if(m_buffer)
+ av_free(m_buffer);
}
AUD_IReader* AUD_FFMPEGFactory::createReader()
{
try
{
- AUD_IReader* reader = new AUD_FFMPEGReader(m_filename);
+ 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;
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
index 2fa1e7ec26b..0a9fcc22c8b 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
@@ -39,7 +39,17 @@ private:
/**
* The filename of the sound source file.
*/
- const char* m_filename;
+ char* m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ unsigned char* m_buffer;
+
+ /**
+ * The size of the buffer.
+ */
+ int m_size;
public:
/**
@@ -48,6 +58,18 @@ public:
*/
AUD_FFMPEGFactory(const char* filename);
+ /**
+ * Creates a new factory.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ AUD_FFMPEGFactory(unsigned char* buffer, int size);
+
+ /**
+ * Destroys the factory.
+ */
+ ~AUD_FFMPEGFactory();
+
virtual AUD_IReader* createReader();
};
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 25e4f53770b..01898a884d4 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -55,6 +55,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
{
m_position = 0;
m_pkgbuf_left = 0;
+ m_byteiocontext = NULL;
// open file
if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
@@ -106,11 +107,85 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
}
+AUD_FFMPEGReader::AUD_FFMPEGReader(unsigned char* buffer, int size)
+{
+ m_position = 0;
+ m_pkgbuf_left = 0;
+ m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
+
+ if(init_put_byte(m_byteiocontext, buffer, size, 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;
+ AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
+
+ // open stream
+ if(av_open_input_stream(&m_formatCtx, m_byteiocontext, "", fmt, NULL)!=0)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ try
+ {
+ if(av_find_stream_info(m_formatCtx)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ // XXX this prints stream information to stdout:
+ //dump_format(m_formatCtx, 0, NULL, 0);
+
+ // find audio stream and codec
+ m_stream = -1;
+
+ for(int i = 0; i < m_formatCtx->nb_streams; i++)
+ if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ if(m_stream == -1)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+
+ m_specs.channels = (AUD_Channels) m_codecCtx->channels;
+ m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
+ m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+
+ // get a decoder and open it
+ AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+ if(!aCodec)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ if(avcodec_open(m_codecCtx, aCodec)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+ }
+ catch(AUD_Exception e)
+ {
+ av_close_input_stream(m_formatCtx);
+ delete m_byteiocontext;
+ throw;
+ }
+
+ // last but not least if there hasn't been any error, create the buffers
+ m_buffer = new AUD_Buffer(0); AUD_NEW("buffer")
+ m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
+}
+
AUD_FFMPEGReader::~AUD_FFMPEGReader()
{
- // close the file
avcodec_close(m_codecCtx);
- av_close_input_file(m_formatCtx);
+
+ if(m_byteiocontext)
+ {
+ av_close_input_stream(m_formatCtx);
+ av_free(m_byteiocontext);
+ }
+ else
+ av_close_input_file(m_formatCtx);
+
delete m_buffer; AUD_DELETE("buffer")
delete m_pkgbuf;
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 795c2ecf8e5..8a3728878a6 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -28,8 +28,10 @@
#include "AUD_IReader.h"
class AUD_Buffer;
-struct AVFormatContext;
struct AVCodecContext;
+extern "C" {
+#include <libavformat/avformat.h>
+}
/**
* This class reads a sound file via ffmpeg.
@@ -80,6 +82,11 @@ private:
AVCodecContext* m_codecCtx;
/**
+ * The ByteIOContext to read the data from.
+ */
+ ByteIOContext* m_byteiocontext;
+
+ /**
* The stream ID in the file.
*/
int m_stream;
@@ -94,6 +101,15 @@ public:
AUD_FFMPEGReader(const char* filename);
/**
+ * 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);
+
+ /**
* Destroys the reader and closes the file.
*/
virtual ~AUD_FFMPEGReader();
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 609dd5ededa..0c561a21e16 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -23,8 +23,6 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-//#define AUD_CAPI_IMPLEMENTATION
-//#include "AUD_C-API.h"
#include "AUD_FFMPEGFactory.h"
#include "AUD_SDLDevice.h"
@@ -35,9 +33,12 @@ extern "C" {
typedef AUD_IFactory AUD_Sound;
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_C-API.h"
+
static AUD_IDevice* AUD_device = NULL;
-bool AUD_init()
+int AUD_init()
{
av_register_all();
try
@@ -63,6 +64,12 @@ AUD_Sound* AUD_load(const char* filename)
return new AUD_FFMPEGFactory(filename);
}
+AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
+{
+ assert(buffer);
+ return new AUD_FFMPEGFactory(buffer, size);
+}
+
void AUD_unload(AUD_Sound* sound)
{
assert(sound);
@@ -86,32 +93,32 @@ AUD_Handle* AUD_play(AUD_Sound* sound,
}
}
-bool AUD_pause(AUD_Handle* handle)
+int AUD_pause(AUD_Handle* handle)
{
assert(AUD_device);
return AUD_device->pause(handle);
}
-bool AUD_resume(AUD_Handle* handle)
+int AUD_resume(AUD_Handle* handle)
{
assert(AUD_device);
return AUD_device->resume(handle);
}
-bool AUD_stop(AUD_Handle* handle)
+int AUD_stop(AUD_Handle* handle)
{
assert(AUD_device);
return AUD_device->stop(handle);
}
-bool AUD_setEndBehaviour(AUD_Handle* handle,
+int AUD_setEndBehaviour(AUD_Handle* handle,
AUD_EndBehaviour endBehaviour)
{
assert(AUD_device);
return AUD_device->setEndBehaviour(handle, endBehaviour);
}
-bool AUD_seek(AUD_Handle* handle, double seekTo)
+int AUD_seek(AUD_Handle* handle, double seekTo)
{
assert(AUD_device);
int position = (int)(seekTo * AUD_device->getSpecs().rate);