diff options
author | Joerg Mueller <nexyon@gmail.com> | 2009-07-11 19:07:36 +0400 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2009-07-11 19:07:36 +0400 |
commit | 28f5c0074f43abab85137213548e8dd349281955 (patch) | |
tree | fc56d4c4ebfe6021f334c62707fa79404055b150 /intern | |
parent | f759f48ae0a1b3feeafd86a684f6eb651bf23280 (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.h | 32 | ||||
-rw-r--r-- | intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp | 31 | ||||
-rw-r--r-- | intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h | 24 | ||||
-rw-r--r-- | intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp | 79 | ||||
-rw-r--r-- | intern/audaspace/ffmpeg/AUD_FFMPEGReader.h | 18 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.cpp | 23 |
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); |