2.5: Sound branch merge!
See mailing list for additional information.
This commit is contained in:
@@ -43,7 +43,7 @@ MACRO(SETUP_LIBDIRS)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
endif(COMMAND cmake_policy)
|
||||
LINK_DIRECTORIES(${PYTHON_LIBPATH} ${SDL_LIBPATH} ${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${ICONV_LIBPATH} ${OPENEXR_LIBPATH} ${QUICKTIME_LIBPATH} ${FFMPEG_LIBPATH})
|
||||
LINK_DIRECTORIES(${FREETYPE_LIBPATH})
|
||||
LINK_DIRECTORIES(${FREETYPE_LIBPATH} ${LIBSAMPLERATE_LIBPATH})
|
||||
IF(WITH_INTERNATIONAL)
|
||||
LINK_DIRECTORIES(${GETTEXT_LIBPATH})
|
||||
ENDIF(WITH_INTERNATIONAL)
|
||||
@@ -82,7 +82,7 @@ MACRO(SETUP_LIBLINKS
|
||||
|
||||
|
||||
TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS})
|
||||
TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIB})
|
||||
TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIB} ${LIBSAMPLERATE_LIB})
|
||||
|
||||
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
|
||||
|
||||
|
||||
@@ -165,6 +165,11 @@ IF(UNIX AND NOT APPLE)
|
||||
SET(FFTW3_LIBPATH ${FFTW3}/lib)
|
||||
ENDIF(WITH_FFTW3)
|
||||
|
||||
SET(LIBSAMPLERATE /usr)
|
||||
SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include)
|
||||
SET(LIBSAMPLERATE_LIB samplerate)
|
||||
SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib)
|
||||
|
||||
FIND_PACKAGE(JPEG REQUIRED)
|
||||
|
||||
FIND_PACKAGE(PNG REQUIRED)
|
||||
@@ -213,11 +218,11 @@ IF(WIN32)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(WITH_OPENAL OFF)
|
||||
ELSE(CMAKE_CL_64)
|
||||
#SET(WITH_OPENAL ON)
|
||||
SET(OPENAL ${LIBDIR}/openal)
|
||||
SET(OPENAL_INC ${OPENAL}/include ${OPENAL}/include/AL)
|
||||
SET(OPENAL_LIB openal_static)
|
||||
SET(OPENAL_LIBPATH ${OPENAL}/lib)
|
||||
#SET(WITH_OPENAL ON)
|
||||
SET(OPENAL ${LIBDIR}/openal)
|
||||
SET(OPENAL_INC ${OPENAL}/include)
|
||||
SET(OPENAL_LIB wrap_oal)
|
||||
SET(OPENAL_LIBPATH ${OPENAL}/lib)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
IF(CMAKE_CL_64)
|
||||
@@ -286,15 +291,16 @@ IF(WIN32)
|
||||
SET(FFMPEG_LIB avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0)
|
||||
SET(FFMPEG_LIBPATH ${FFMPEG}/lib)
|
||||
|
||||
SET(LIBSAMPLERATE ${LIBDIR}/samplerate)
|
||||
SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include)
|
||||
SET(LIBSAMPLERATE_LIB libsamplerate)
|
||||
SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib)
|
||||
|
||||
IF(CMAKE_CL_64)
|
||||
SET(LLIBS kernel32 user32 vfw32 winmm ws2_32 )
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(LLIBS kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid ws2_32 vfw32 winmm)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
IF(WITH_OPENAL)
|
||||
SET(LLIBS ${LLIBS} dxguid)
|
||||
ENDIF(WITH_OPENAL)
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
|
||||
@@ -86,11 +86,6 @@ else:
|
||||
BF_QUIET = '1'
|
||||
WITH_BF_OPENMP = '0'
|
||||
|
||||
# Note : should be true, but openal simply dont work on intel
|
||||
if MAC_PROC == 'i386':
|
||||
WITH_BF_OPENAL = False
|
||||
else:
|
||||
WITH_BF_OPENAL = True
|
||||
#different lib must be used following version of gcc
|
||||
# for gcc 3.3
|
||||
#BF_OPENAL = LIBDIR + '/openal'
|
||||
@@ -112,7 +107,7 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/SRC'
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
@@ -206,11 +201,6 @@ BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
#BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
# Mesa Libs should go here if your using them as well....
|
||||
WITH_BF_STATICOPENGL = True
|
||||
BF_OPENGL_LIB = 'GL GLU'
|
||||
|
||||
@@ -24,6 +24,11 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = 'false'
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
BF_LIBSAMPLERATE = LCGDIR+'/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = 'true'
|
||||
BF_SDL = LCGDIR+'/sdl' #$(shell sdl-config --prefix)
|
||||
BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
|
||||
@@ -22,6 +22,11 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
BF_LIBSAMPLERATE = '/usr'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = '/usr' #$(shell sdl-config --prefix)
|
||||
BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
|
||||
@@ -22,6 +22,11 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = LIBDIR + '/sdl'
|
||||
BF_SDL_INC = '${BF_SDL}/include'
|
||||
|
||||
@@ -16,6 +16,11 @@ WITH_BF_OPENAL = False
|
||||
#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
|
||||
|
||||
BF_LIBSAMPLERATE = '/usr/local'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
|
||||
BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
|
||||
@@ -22,6 +22,11 @@ BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
BF_LIBSAMPLERATE = '/usr/local'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'samplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
|
||||
BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
@@ -109,7 +114,7 @@ BF_ICONV_LIB = 'iconv'
|
||||
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
# enable ffmpeg support
|
||||
WITH_BF_FFMPEG = False # -DWITH_FFMPEG
|
||||
WITH_BF_FFMPEG = True # -DWITH_FFMPEG
|
||||
BF_FFMPEG = '/usr/local'
|
||||
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
|
||||
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
||||
|
||||
@@ -18,7 +18,7 @@ BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PY
|
||||
WITH_BF_OPENAL = True
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include'
|
||||
BF_OPENAL_LIB = 'OpenAL32 wrap_oal'
|
||||
BF_OPENAL_LIB = 'wrap_oal'
|
||||
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
|
||||
WITH_BF_FFMPEG = False
|
||||
@@ -26,6 +26,11 @@ BF_FFMPEG_LIB = 'avformat swscale avcodec avutil avdevice xvidcore x264'
|
||||
BF_FFMPEG_LIBPATH = LIBDIR + '/gcc/ffmpeg/lib'
|
||||
BF_FFMPEG_INC = LIBDIR + '/gcc/ffmpeg/include'
|
||||
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'libsamplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = LIBDIR + '/sdl'
|
||||
BF_SDL_INC = '${BF_SDL}/include'
|
||||
|
||||
@@ -17,8 +17,8 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
||||
|
||||
WITH_BF_OPENAL = True
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include ${BF_OPENAL}/include/AL '
|
||||
BF_OPENAL_LIB = 'OpenAL32 wrap_oal'
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include '
|
||||
BF_OPENAL_LIB = 'wrap_oal'
|
||||
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
|
||||
# TODO - are these useful on win32?
|
||||
@@ -32,6 +32,11 @@ BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'libsamplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = LIBDIR + '/sdl'
|
||||
BF_SDL_INC = '${BF_SDL}/include'
|
||||
|
||||
@@ -17,8 +17,8 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
||||
|
||||
WITH_BF_OPENAL = False
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include ${BF_OPENAL}/include/AL '
|
||||
BF_OPENAL_LIB = 'OpenAL32 wrap_oal'
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include '
|
||||
BF_OPENAL_LIB = 'wrap_oal'
|
||||
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
|
||||
# TODO - are these useful on win32?
|
||||
@@ -32,6 +32,11 @@ BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
|
||||
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
|
||||
BF_LIBSAMPLERATE_LIB = 'libsamplerate'
|
||||
BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = LIBDIR + '/sdl'
|
||||
BF_SDL_INC = '${BF_SDL}/include'
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
ADD_SUBDIRECTORY(audaspace)
|
||||
ADD_SUBDIRECTORY(SoundSystem)
|
||||
ADD_SUBDIRECTORY(string)
|
||||
ADD_SUBDIRECTORY(ghost)
|
||||
|
||||
@@ -32,7 +32,7 @@ SOURCEDIR = intern
|
||||
# include nan_subdirs.mk
|
||||
|
||||
ALLDIRS = string ghost guardedalloc moto container memutil
|
||||
ALLDIRS += decimation iksolver bsp SoundSystem opennl elbeem boolop smoke
|
||||
ALLDIRS += decimation iksolver bsp SoundSystem opennl elbeem boolop smoke audaspace
|
||||
|
||||
all::
|
||||
@for i in $(ALLDIRS); do \
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
SConscript(['SoundSystem/SConscript',
|
||||
SConscript(['audaspace/SConscript',
|
||||
'SoundSystem/SConscript',
|
||||
'string/SConscript',
|
||||
'ghost/SConscript',
|
||||
'guardedalloc/SConscript',
|
||||
|
||||
330
intern/audaspace/AUD_C-API.h
Normal file
330
intern/audaspace/AUD_C-API.h
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_CAPI
|
||||
#define AUD_CAPI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "intern/AUD_Space.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUD_NULL_DEVICE = 0,
|
||||
AUD_SDL_DEVICE,
|
||||
AUD_OPENAL_DEVICE
|
||||
} AUD_DeviceType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AUD_Specs specs;
|
||||
float length;
|
||||
} AUD_SoundInfo;
|
||||
|
||||
#ifndef AUD_CAPI_IMPLEMENTATION
|
||||
typedef void AUD_Sound;
|
||||
typedef void AUD_Handle;
|
||||
typedef void AUD_Device;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes an audio device.
|
||||
* \param device The device type that should be used.
|
||||
* \param specs The audio specification to be used.
|
||||
* \param buffersize The buffersize for the device.
|
||||
* \return Whether the device has been initialized.
|
||||
*/
|
||||
extern int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize);
|
||||
|
||||
/**
|
||||
* Returns a integer list with available sound devices. The last one is always
|
||||
* AUD_NULL_DEVICE.
|
||||
*/
|
||||
extern int* AUD_enumDevices();
|
||||
|
||||
/**
|
||||
* Unitinitializes an audio device.
|
||||
*/
|
||||
extern void AUD_exit();
|
||||
|
||||
/**
|
||||
* Locks the playback device.
|
||||
*/
|
||||
extern void AUD_lock();
|
||||
|
||||
/**
|
||||
* Unlocks the device.
|
||||
*/
|
||||
extern void AUD_unlock();
|
||||
|
||||
/**
|
||||
* Returns information about a sound.
|
||||
* \param sound The sound to get the info about.
|
||||
* \return The AUD_SoundInfo structure with filled in data.
|
||||
*/
|
||||
extern AUD_SoundInfo AUD_getInfo(AUD_Sound* sound);
|
||||
|
||||
/**
|
||||
* Loads a sound file.
|
||||
* \param filename The filename of the sound file.
|
||||
* \return A handle of the sound file.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Buffers a sound.
|
||||
* \param sound The sound to buffer.
|
||||
* \return A handle of the sound buffer.
|
||||
*/
|
||||
extern AUD_Sound* AUD_bufferSound(AUD_Sound* sound);
|
||||
|
||||
/**
|
||||
* Delays a sound.
|
||||
* \param sound The sound to dealy.
|
||||
* \param delay The delay in seconds.
|
||||
* \return A handle of the delayed sound.
|
||||
*/
|
||||
extern AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay);
|
||||
|
||||
/**
|
||||
* Limits a sound.
|
||||
* \param sound The sound to limit.
|
||||
* \param start The start time in seconds.
|
||||
* \param end The stop time in seconds.
|
||||
* \return A handle of the limited sound.
|
||||
*/
|
||||
extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end);
|
||||
|
||||
/**
|
||||
* Ping pongs a sound.
|
||||
* \param sound The sound to ping pong.
|
||||
* \return A handle of the ping pong sound.
|
||||
*/
|
||||
extern AUD_Sound* AUD_pingpongSound(AUD_Sound* sound);
|
||||
|
||||
/**
|
||||
* Loops a sound.
|
||||
* \param sound The sound to loop.
|
||||
* \return A handle of the looped sound.
|
||||
*/
|
||||
extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
|
||||
|
||||
/**
|
||||
* Stops a looping sound when the current playback finishes.
|
||||
* \param handle The playback handle.
|
||||
* \return Whether the handle is valid.
|
||||
*/
|
||||
extern int AUD_stopLoop(AUD_Handle* handle);
|
||||
|
||||
/**
|
||||
* Unloads a sound of any type.
|
||||
* \param sound The handle of the sound.
|
||||
*/
|
||||
extern void AUD_unload(AUD_Sound* sound);
|
||||
|
||||
/**
|
||||
* Plays back a sound file.
|
||||
* \param sound The handle of the sound file.
|
||||
* \param keep When keep is true the sound source will not be deleted but set to
|
||||
* paused when its end has been reached.
|
||||
* \return A handle to the played back sound.
|
||||
*/
|
||||
extern AUD_Handle* AUD_play(AUD_Sound* sound, int keep);
|
||||
|
||||
/**
|
||||
* Pauses a played back sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \return Whether the handle has been playing or not.
|
||||
*/
|
||||
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 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 int AUD_stop(AUD_Handle* handle);
|
||||
|
||||
/**
|
||||
* Sets the end behaviour of a playing or paused sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \param keep When keep is true the sound source will not be deleted but set to
|
||||
* paused when its end has been reached.
|
||||
* \return Whether the handle has been valid or not.
|
||||
*/
|
||||
extern int AUD_setKeep(AUD_Handle* handle, int keep);
|
||||
|
||||
/**
|
||||
* Seeks a playing or paused sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \param seekTo From where the sound file should be played back in seconds.
|
||||
* \return Whether the handle has been valid or not.
|
||||
*/
|
||||
extern int AUD_seek(AUD_Handle* handle, float seekTo);
|
||||
|
||||
/**
|
||||
* Retrieves the playback position of a handle.
|
||||
* \return The current playback position in seconds or 0.0 if the handle is
|
||||
* invalid.
|
||||
*/
|
||||
extern float AUD_getPosition(AUD_Handle* handle);
|
||||
|
||||
/**
|
||||
* Returns the status of a playing, paused or stopped sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \return The status of the sound behind the handle.
|
||||
*/
|
||||
extern AUD_Status AUD_getStatus(AUD_Handle* handle);
|
||||
|
||||
/**
|
||||
* Plays a 3D sound.
|
||||
* \param sound The handle of the sound file.
|
||||
* \param keep When keep is true the sound source will not be deleted but set to
|
||||
* paused when its end has been reached.
|
||||
* \return A handle to the played back sound.
|
||||
* \note The factory must provide a mono (single channel) source and the device
|
||||
* must support 3D audio, otherwise the sound is played back normally.
|
||||
*/
|
||||
extern AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep);
|
||||
|
||||
/**
|
||||
* Updates the listener 3D data.
|
||||
* \param data The 3D data.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_updateListener(AUD_3DData* data);
|
||||
|
||||
/**
|
||||
* Sets a 3D device setting.
|
||||
* \param setting The setting type.
|
||||
* \param value The new setting value.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_set3DSetting(AUD_3DSetting setting, float value);
|
||||
|
||||
/**
|
||||
* Retrieves a 3D device setting.
|
||||
* \param setting The setting type.
|
||||
* \return The setting value.
|
||||
*/
|
||||
extern float AUD_get3DSetting(AUD_3DSetting setting);
|
||||
|
||||
/**
|
||||
* Updates a listeners 3D data.
|
||||
* \param handle The source handle.
|
||||
* \param data The 3D data.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data);
|
||||
|
||||
/**
|
||||
* Sets a 3D source setting.
|
||||
* \param handle The source handle.
|
||||
* \param setting The setting type.
|
||||
* \param value The new setting value.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_set3DSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting, float value);
|
||||
|
||||
/**
|
||||
* Retrieves a 3D source setting.
|
||||
* \param handle The source handle.
|
||||
* \param setting The setting type.
|
||||
* \return The setting value.
|
||||
*/
|
||||
extern float AUD_get3DSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting);
|
||||
|
||||
/**
|
||||
* Sets the volume of a played back sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \param volume The new volume, must be between 0.0 and 1.0.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSoundVolume(AUD_Handle* handle, float volume);
|
||||
|
||||
/**
|
||||
* Sets the pitch of a played back sound.
|
||||
* \param handle The handle to the sound.
|
||||
* \param pitch The new pitch.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
|
||||
|
||||
/**
|
||||
* Opens a read device, with which audio data can be read.
|
||||
* \param specs The specification of the audio data.
|
||||
* \return A device handle.
|
||||
*/
|
||||
extern AUD_Device* AUD_openReadDevice(AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Plays back a sound file through a read device.
|
||||
* \param device The read device.
|
||||
* \param sound The handle of the sound file.
|
||||
* \return Whether the sound could be played back.
|
||||
*/
|
||||
extern int AUD_playDevice(AUD_Device* device, AUD_Sound* sound);
|
||||
|
||||
/**
|
||||
* Reads the next samples into the supplied buffer.
|
||||
* \param device The read device.
|
||||
* \param buffer The target buffer.
|
||||
* \param length The length in samples to be filled.
|
||||
* \return True if the reading succeeded, false if there are no sounds
|
||||
* played back currently, in that case the buffer is filled with
|
||||
* silence.
|
||||
*/
|
||||
extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
|
||||
|
||||
/**
|
||||
* Closes a read device.
|
||||
* \param device The read device.
|
||||
*/
|
||||
extern void AUD_closeReadDevice(AUD_Device* device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //AUD_CAPI
|
||||
52
intern/audaspace/CMakeLists.txt
Normal file
52
intern/audaspace/CMakeLists.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
# $Id$
|
||||
# ***** 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 *****
|
||||
|
||||
SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC})
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp)
|
||||
|
||||
IF(WITH_FFMPEG)
|
||||
SET(INC ${INC} ffmpeg ${FFMPEG_INC})
|
||||
FILE(GLOB FFMPEGSRC ffmpeg/*.cpp)
|
||||
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
||||
ENDIF(WITH_FFMPEG)
|
||||
|
||||
IF(WITH_SDL)
|
||||
SET(INC ${INC} SDL ${SDL_INC})
|
||||
FILE(GLOB SDLSRC SDL/*.cpp)
|
||||
ADD_DEFINITIONS(-DWITH_SDL)
|
||||
ENDIF(WITH_SDL)
|
||||
|
||||
IF(WITH_OPENAL)
|
||||
SET(INC ${INC} OpenAL ${OPENAL_INC})
|
||||
FILE(GLOB OPENALSRC OpenAL/*.cpp)
|
||||
ADD_DEFINITIONS(-DWITH_OPENAL)
|
||||
|
||||
STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INC})
|
||||
IF(FRAMEWORK)
|
||||
ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX)
|
||||
ENDIF(FRAMEWORK)
|
||||
ENDIF(WITH_OPENAL)
|
||||
|
||||
SET(SRC ${SRC} ${FFMPEGSRC} ${SDLSRC} ${OPENALSRC})
|
||||
|
||||
BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
|
||||
674
intern/audaspace/COPYING
Normal file
674
intern/audaspace/COPYING
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
165
intern/audaspace/COPYING.LESSER
Normal file
165
intern/audaspace/COPYING.LESSER
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
58
intern/audaspace/FX/AUD_DelayFactory.cpp
Normal file
58
intern/audaspace/FX/AUD_DelayFactory.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_DelayFactory.h"
|
||||
#include "AUD_DelayReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_delay(delay) {}
|
||||
|
||||
AUD_DelayFactory::AUD_DelayFactory(float delay) :
|
||||
AUD_EffectFactory(0),
|
||||
m_delay(delay) {}
|
||||
|
||||
float AUD_DelayFactory::getDelay()
|
||||
{
|
||||
return m_delay;
|
||||
}
|
||||
|
||||
void AUD_DelayFactory::setDelay(float delay)
|
||||
{
|
||||
m_delay = delay;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_DelayFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_DelayReader(reader, m_delay); AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
70
intern/audaspace/FX/AUD_DelayFactory.h
Normal file
70
intern/audaspace/FX/AUD_DelayFactory.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_DELAYFACTORY
|
||||
#define AUD_DELAYFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory plays another factory delayed.
|
||||
*/
|
||||
class AUD_DelayFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The delay in samples.
|
||||
*/
|
||||
float m_delay;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new delay factory.
|
||||
* \param factory The input factory.
|
||||
* \param delay The desired delay in seconds.
|
||||
*/
|
||||
AUD_DelayFactory(AUD_IFactory* factory = 0, float delay = 0);
|
||||
|
||||
/**
|
||||
* Creates a new delay factory.
|
||||
* \param delay The desired delay in seconds.
|
||||
*/
|
||||
AUD_DelayFactory(float delay);
|
||||
|
||||
/**
|
||||
* Returns the delay in seconds.
|
||||
*/
|
||||
float getDelay();
|
||||
|
||||
/**
|
||||
* Sets the delay.
|
||||
* \param delay The new delay value in seconds.
|
||||
*/
|
||||
void setDelay(float delay);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_DELAYFACTORY
|
||||
111
intern/audaspace/FX/AUD_DelayReader.cpp
Normal file
111
intern/audaspace/FX/AUD_DelayReader.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_DelayReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
m_delay = (int)(delay * reader->getSpecs().rate);
|
||||
m_remdelay = m_delay;
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_DelayReader::~AUD_DelayReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
void AUD_DelayReader::seek(int position)
|
||||
{
|
||||
if(position < 0)
|
||||
return;
|
||||
|
||||
if(position < m_delay)
|
||||
{
|
||||
m_remdelay = m_delay - position;
|
||||
m_reader->seek(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_remdelay = 0;
|
||||
m_reader->seek(position - m_delay);
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_DelayReader::getLength()
|
||||
{
|
||||
int len = m_reader->getLength();
|
||||
if(len < 0)
|
||||
return len;
|
||||
return len+m_delay;
|
||||
}
|
||||
|
||||
int AUD_DelayReader::getPosition()
|
||||
{
|
||||
if(m_remdelay > 0)
|
||||
return m_delay-m_remdelay;
|
||||
return m_reader->getPosition() + m_delay;
|
||||
}
|
||||
|
||||
void AUD_DelayReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
if(m_remdelay > 0)
|
||||
{
|
||||
int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
|
||||
|
||||
if(m_buffer->getSize() < length*samplesize)
|
||||
m_buffer->resize(length*samplesize);
|
||||
|
||||
if(length > m_remdelay)
|
||||
{
|
||||
if(getSpecs().format == AUD_FORMAT_U8)
|
||||
memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize);
|
||||
else
|
||||
memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize);
|
||||
int len = length - m_remdelay;
|
||||
m_reader->read(len, buffer);
|
||||
memcpy(m_buffer->getBuffer()+m_remdelay*samplesize,
|
||||
buffer, len*samplesize);
|
||||
if(len < length-m_remdelay)
|
||||
length = m_remdelay + len;
|
||||
m_remdelay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(getSpecs().format == AUD_FORMAT_U8)
|
||||
memset(m_buffer->getBuffer(), 0x80, length*samplesize);
|
||||
else
|
||||
memset(m_buffer->getBuffer(), 0, length*samplesize);
|
||||
m_remdelay -= length;
|
||||
}
|
||||
buffer = m_buffer->getBuffer();
|
||||
}
|
||||
else
|
||||
m_reader->read(length, buffer);
|
||||
}
|
||||
73
intern/audaspace/FX/AUD_DelayReader.h
Normal file
73
intern/audaspace/FX/AUD_DelayReader.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_DELAYREADER
|
||||
#define AUD_DELAYREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class reads another reader and changes it's delay.
|
||||
*/
|
||||
class AUD_DelayReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The delay level.
|
||||
*/
|
||||
int m_delay;
|
||||
|
||||
/**
|
||||
* The remaining delay for playback.
|
||||
*/
|
||||
int m_remdelay;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new delay reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param delay The delay in seconds.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_DelayReader(AUD_IReader* reader, float delay);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_DelayReader();
|
||||
|
||||
virtual void seek(int position);
|
||||
virtual int getLength();
|
||||
virtual int getPosition();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_DELAYREADER
|
||||
158
intern/audaspace/FX/AUD_DoubleReader.cpp
Normal file
158
intern/audaspace/FX/AUD_DoubleReader.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_DoubleReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
|
||||
AUD_IReader* reader2) :
|
||||
m_reader1(reader1), m_reader2(reader2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!reader1)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
if(!reader2)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
AUD_Specs s1, s2;
|
||||
s1 = reader1->getSpecs();
|
||||
s2 = reader2->getSpecs();
|
||||
if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
}
|
||||
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
if(reader1)
|
||||
{
|
||||
delete reader1; AUD_DELETE("reader")
|
||||
}
|
||||
if(reader2)
|
||||
{
|
||||
delete reader2; AUD_DELETE("reader")
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_finished1 = false;
|
||||
}
|
||||
|
||||
AUD_DoubleReader::~AUD_DoubleReader()
|
||||
{
|
||||
delete m_reader1; AUD_DELETE("reader")
|
||||
delete m_reader2; AUD_DELETE("reader")
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
bool AUD_DoubleReader::isSeekable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_DoubleReader::seek(int position)
|
||||
{
|
||||
int length1 = m_reader1->getLength();
|
||||
|
||||
if(position < 0)
|
||||
position = 0;
|
||||
|
||||
if(position < length1)
|
||||
{
|
||||
m_reader1->seek(position);
|
||||
m_reader2->seek(0);
|
||||
m_finished1 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_reader2->seek(position-length1);
|
||||
m_finished1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_DoubleReader::getLength()
|
||||
{
|
||||
int len1 = m_reader1->getLength();
|
||||
int len2 = m_reader2->getLength();
|
||||
if(len1 < 0 || len2 < 0)
|
||||
return -1;
|
||||
return len1 + len2;
|
||||
}
|
||||
|
||||
int AUD_DoubleReader::getPosition()
|
||||
{
|
||||
return m_reader1->getPosition() + m_reader2->getPosition();
|
||||
}
|
||||
|
||||
AUD_Specs AUD_DoubleReader::getSpecs()
|
||||
{
|
||||
return m_reader1->getSpecs();
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_DoubleReader::getType()
|
||||
{
|
||||
if(m_reader1->getType() == AUD_TYPE_BUFFER &&
|
||||
m_reader2->getType() == AUD_TYPE_BUFFER)
|
||||
return AUD_TYPE_BUFFER;
|
||||
return AUD_TYPE_STREAM;
|
||||
}
|
||||
|
||||
bool AUD_DoubleReader::notify(AUD_Message &message)
|
||||
{
|
||||
return m_reader1->notify(message) | m_reader2->notify(message);
|
||||
}
|
||||
|
||||
void AUD_DoubleReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
if(!m_finished1)
|
||||
{
|
||||
int len = length;
|
||||
m_reader1->read(len, buffer);
|
||||
if(len < length)
|
||||
{
|
||||
int samplesize = AUD_SAMPLE_SIZE(m_reader1->getSpecs());
|
||||
if(m_buffer->getSize() < length * samplesize)
|
||||
m_buffer->resize(length * samplesize);
|
||||
memcpy(m_buffer->getBuffer(), buffer, len*samplesize);
|
||||
len = length - len;
|
||||
length -= len;
|
||||
m_reader2->read(len, buffer);
|
||||
memcpy(m_buffer->getBuffer() + length*samplesize,
|
||||
buffer, len*samplesize);
|
||||
length += len;
|
||||
buffer = m_buffer->getBuffer();
|
||||
m_finished1 = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_reader2->read(length, buffer);
|
||||
}
|
||||
}
|
||||
83
intern/audaspace/FX/AUD_DoubleReader.h
Normal file
83
intern/audaspace/FX/AUD_DoubleReader.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_DOUBLEREADER
|
||||
#define AUD_DOUBLEREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This reader plays two readers with the same specs sequently.
|
||||
*/
|
||||
class AUD_DoubleReader : public AUD_IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The first reader.
|
||||
*/
|
||||
AUD_IReader* m_reader1;
|
||||
|
||||
/**
|
||||
* The second reader.
|
||||
*/
|
||||
AUD_IReader* m_reader2;
|
||||
|
||||
/**
|
||||
* Whether we've reached the end of the first reader.
|
||||
*/
|
||||
bool m_finished1;
|
||||
|
||||
/**
|
||||
* The playback buffer for the intersecting part.
|
||||
*/
|
||||
AUD_Buffer* m_buffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new ping pong reader.
|
||||
* \param reader1 The first reader to read from.
|
||||
* \param reader2 The second reader to read from.
|
||||
* \exception AUD_Exception Thrown if one of the reader specified is NULL
|
||||
* or the specs from the readers differ.
|
||||
*/
|
||||
AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_DoubleReader();
|
||||
|
||||
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_DOUBLEREADER
|
||||
50
intern/audaspace/FX/AUD_EffectFactory.cpp
Normal file
50
intern/audaspace/FX/AUD_EffectFactory.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_EffectFactory.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
AUD_IReader* AUD_EffectFactory::getReader()
|
||||
{
|
||||
if(m_factory != 0)
|
||||
return m_factory->createReader();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
|
||||
{
|
||||
m_factory = factory;
|
||||
}
|
||||
|
||||
void AUD_EffectFactory::setFactory(AUD_IFactory* factory)
|
||||
{
|
||||
m_factory = factory;
|
||||
}
|
||||
|
||||
AUD_IFactory* AUD_EffectFactory::getFactory()
|
||||
{
|
||||
return m_factory;
|
||||
}
|
||||
76
intern/audaspace/FX/AUD_EffectFactory.h
Normal file
76
intern/audaspace/FX/AUD_EffectFactory.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_EFFECTFACTORY
|
||||
#define AUD_EFFECTFACTORY
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
|
||||
/**
|
||||
* This factory is a base class for all effect factories that take one other
|
||||
* factory as input.
|
||||
*/
|
||||
class AUD_EffectFactory : public AUD_IFactory
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* If there is no reader it is created out of this factory.
|
||||
*/
|
||||
AUD_IFactory* m_factory;
|
||||
|
||||
/**
|
||||
* Returns the reader created out of the factory.
|
||||
* This method can be used for the createReader function of the implementing
|
||||
* classes.
|
||||
* \return The reader created out of the factory or NULL if there is none.
|
||||
*/
|
||||
AUD_IReader* getReader();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new factory.
|
||||
* \param factory The input factory.
|
||||
*/
|
||||
AUD_EffectFactory(AUD_IFactory* factory);
|
||||
|
||||
/**
|
||||
* Destroys the factory.
|
||||
*/
|
||||
virtual ~AUD_EffectFactory() {}
|
||||
|
||||
/**
|
||||
* Sets the input factory.
|
||||
* \param factory The input factory.
|
||||
*/
|
||||
void setFactory(AUD_IFactory* factory);
|
||||
|
||||
/**
|
||||
* Returns the saved factory.
|
||||
* \return The factory or NULL if there has no factory been saved.
|
||||
*/
|
||||
AUD_IFactory* getFactory();
|
||||
};
|
||||
|
||||
#endif //AUD_EFFECTFACTORY
|
||||
78
intern/audaspace/FX/AUD_EffectReader.cpp
Normal file
78
intern/audaspace/FX/AUD_EffectReader.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_EffectReader.h"
|
||||
|
||||
AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
|
||||
{
|
||||
if(!reader)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
m_reader = reader;
|
||||
}
|
||||
|
||||
AUD_EffectReader::~AUD_EffectReader()
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
}
|
||||
|
||||
bool AUD_EffectReader::isSeekable()
|
||||
{
|
||||
return m_reader->isSeekable();
|
||||
}
|
||||
|
||||
void AUD_EffectReader::seek(int position)
|
||||
{
|
||||
m_reader->seek(position);
|
||||
}
|
||||
|
||||
int AUD_EffectReader::getLength()
|
||||
{
|
||||
return m_reader->getLength();
|
||||
}
|
||||
|
||||
int AUD_EffectReader::getPosition()
|
||||
{
|
||||
return m_reader->getPosition();
|
||||
}
|
||||
|
||||
AUD_Specs AUD_EffectReader::getSpecs()
|
||||
{
|
||||
return m_reader->getSpecs();
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_EffectReader::getType()
|
||||
{
|
||||
return m_reader->getType();
|
||||
}
|
||||
|
||||
bool AUD_EffectReader::notify(AUD_Message &message)
|
||||
{
|
||||
return m_reader->notify(message);
|
||||
}
|
||||
|
||||
void AUD_EffectReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
m_reader->read(length, buffer);
|
||||
}
|
||||
66
intern/audaspace/FX/AUD_EffectReader.h
Normal file
66
intern/audaspace/FX/AUD_EffectReader.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_EFFECTREADER
|
||||
#define AUD_EFFECTREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
/**
|
||||
* This reader is a base class for all effect readers that take one other reader
|
||||
* as input.
|
||||
*/
|
||||
class AUD_EffectReader : public AUD_IReader
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* The reader to read from.
|
||||
*/
|
||||
AUD_IReader* m_reader;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new effect reader.
|
||||
* \param reader The reader to read from.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_EffectReader(AUD_IReader* reader);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_EffectReader();
|
||||
|
||||
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_EFFECTREADER
|
||||
84
intern/audaspace/FX/AUD_FaderFactory.cpp
Normal file
84
intern/audaspace/FX/AUD_FaderFactory.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FaderFactory.h"
|
||||
#include "AUD_FaderReader.h"
|
||||
|
||||
AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
|
||||
float start, float length) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_type(type),
|
||||
m_start(start),
|
||||
m_length(length) {}
|
||||
|
||||
AUD_FaderFactory::AUD_FaderFactory(AUD_FadeType type,
|
||||
float start, float length) :
|
||||
AUD_EffectFactory(0),
|
||||
m_type(type),
|
||||
m_start(start),
|
||||
m_length(length) {}
|
||||
|
||||
AUD_FadeType AUD_FaderFactory::getType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void AUD_FaderFactory::setType(AUD_FadeType type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
float AUD_FaderFactory::getStart()
|
||||
{
|
||||
return m_start;
|
||||
}
|
||||
|
||||
void AUD_FaderFactory::setStart(float start)
|
||||
{
|
||||
m_start = start;
|
||||
}
|
||||
|
||||
float AUD_FaderFactory::getLength()
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void AUD_FaderFactory::setLength(float length)
|
||||
{
|
||||
m_length = length;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_FaderFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_FaderReader(reader, m_type, m_start, m_length);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
111
intern/audaspace/FX/AUD_FaderFactory.h
Normal file
111
intern/audaspace/FX/AUD_FaderFactory.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FADERFACTORY
|
||||
#define AUD_FADERFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory fades another factory.
|
||||
* If the fading type is AUD_FADE_IN, everything before the fading start will be
|
||||
* silenced, for AUD_FADE_OUT that's true for everything after fading ends.
|
||||
*/
|
||||
class AUD_FaderFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The fading type.
|
||||
*/
|
||||
AUD_FadeType m_type;
|
||||
|
||||
/**
|
||||
* The fading start.
|
||||
*/
|
||||
float m_start;
|
||||
|
||||
/**
|
||||
* The fading length.
|
||||
*/
|
||||
float m_length;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new fader factory.
|
||||
* \param factory The input factory.
|
||||
* \param type The fading type.
|
||||
* \param start The time where fading should start in seconds.
|
||||
* \param length How long fading should last in seconds.
|
||||
*/
|
||||
AUD_FaderFactory(AUD_IFactory* factory = 0,
|
||||
AUD_FadeType type = AUD_FADE_IN,
|
||||
float start = 0.0f, float length = 1.0f);
|
||||
|
||||
/**
|
||||
* Creates a new fader factory.
|
||||
* \param type The fading type.
|
||||
* \param start The time where fading should start in seconds.
|
||||
* \param length How long fading should last in seconds.
|
||||
*/
|
||||
AUD_FaderFactory(AUD_FadeType type = AUD_FADE_IN,
|
||||
float start = 0.0f, float length = 1.0f);
|
||||
|
||||
/**
|
||||
* Returns the fading type.
|
||||
*/
|
||||
AUD_FadeType getType();
|
||||
|
||||
/**
|
||||
* Sets the fading type.
|
||||
* \param type The new fading type: AUD_FADE_IN or AUD_FADE_OUT.
|
||||
*/
|
||||
void setType(AUD_FadeType type);
|
||||
|
||||
/**
|
||||
* Returns the fading start.
|
||||
*/
|
||||
float getStart();
|
||||
|
||||
/**
|
||||
* Sets the fading start.
|
||||
* \param start The new fading start.
|
||||
*/
|
||||
void setStart(float start);
|
||||
|
||||
/**
|
||||
* Returns the fading length.
|
||||
*/
|
||||
float getLength();
|
||||
|
||||
/**
|
||||
* Sets the fading length.
|
||||
* \param start The new fading length.
|
||||
*/
|
||||
void setLength(float length);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_FADERFACTORY
|
||||
133
intern/audaspace/FX/AUD_FaderReader.cpp
Normal file
133
intern/audaspace/FX/AUD_FaderReader.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FaderReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
|
||||
float start,float length) :
|
||||
AUD_EffectReader(reader),
|
||||
m_type(type),
|
||||
m_start(start),
|
||||
m_length(length)
|
||||
{
|
||||
int bigendian = 1;
|
||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||
|
||||
switch(m_reader->getSpecs().format)
|
||||
{
|
||||
case AUD_FORMAT_S16:
|
||||
m_adjust = AUD_volume_adjust<int16_t>;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_adjust = AUD_volume_adjust<int32_t>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_adjust = AUD_volume_adjust<float>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_adjust = AUD_volume_adjust<double>;
|
||||
break;
|
||||
case AUD_FORMAT_U8:
|
||||
m_adjust = AUD_volume_adjust_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
m_adjust = bigendian ? AUD_volume_adjust_s24_be :
|
||||
AUD_volume_adjust_s24_le;
|
||||
break;
|
||||
default:
|
||||
delete m_reader;
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
}
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_FaderReader::~AUD_FaderReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
bool AUD_FaderReader::notify(AUD_Message &message)
|
||||
{
|
||||
return m_reader->notify(message);
|
||||
}
|
||||
|
||||
void AUD_FaderReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
int position = m_reader->getPosition();
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||
|
||||
m_reader->read(length, buffer);
|
||||
|
||||
if(m_buffer->getSize() < length * samplesize)
|
||||
m_buffer->resize(length * samplesize);
|
||||
|
||||
if((position + length) / (float)specs.rate <= m_start)
|
||||
{
|
||||
if(m_type != AUD_FADE_OUT)
|
||||
{
|
||||
buffer = m_buffer->getBuffer();
|
||||
memset(buffer,
|
||||
specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
|
||||
length * samplesize);
|
||||
}
|
||||
}
|
||||
else if(position / (float)specs.rate >= m_start+m_length)
|
||||
{
|
||||
if(m_type == AUD_FADE_OUT)
|
||||
{
|
||||
buffer = m_buffer->getBuffer();
|
||||
memset(buffer,
|
||||
specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
|
||||
length * samplesize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sample_t* buf = m_buffer->getBuffer();
|
||||
float volume;
|
||||
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
|
||||
if(volume > 1.0f)
|
||||
volume = 1.0f;
|
||||
else if(volume < 0.0f)
|
||||
volume = 0.0f;
|
||||
|
||||
if(m_type == AUD_FADE_OUT)
|
||||
volume = 1.0f - volume;
|
||||
|
||||
m_adjust(buf + i * samplesize, buffer + i * samplesize,
|
||||
specs.channels, volume);
|
||||
}
|
||||
|
||||
buffer = buf;
|
||||
}
|
||||
}
|
||||
86
intern/audaspace/FX/AUD_FaderReader.h
Normal file
86
intern/audaspace/FX/AUD_FaderReader.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FADERREADER
|
||||
#define AUD_FADERREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class fades another reader.
|
||||
* If the fading type is AUD_FADE_IN, everything before the fading start will be
|
||||
* silenced, for AUD_FADE_OUT that's true for everything after fading ends.
|
||||
*/
|
||||
class AUD_FaderReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The fading type.
|
||||
*/
|
||||
AUD_FadeType m_type;
|
||||
|
||||
/**
|
||||
* The fading start.
|
||||
*/
|
||||
float m_start;
|
||||
|
||||
/**
|
||||
* The fading length.
|
||||
*/
|
||||
float m_length;
|
||||
|
||||
/**
|
||||
* Volume adjustment function.
|
||||
*/
|
||||
AUD_volume_adjust_f m_adjust;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new fader reader.
|
||||
* \param type The fading type.
|
||||
* \param start The time where fading should start in seconds.
|
||||
* \param length How long fading should last in seconds.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
|
||||
float start,float length);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_FaderReader();
|
||||
|
||||
virtual bool notify(AUD_Message &message);
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_FADERREADER
|
||||
67
intern/audaspace/FX/AUD_LimiterFactory.cpp
Normal file
67
intern/audaspace/FX/AUD_LimiterFactory.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LimiterFactory.h"
|
||||
#include "AUD_LimiterReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
|
||||
float start, float end) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_start(start),
|
||||
m_end(end) {}
|
||||
|
||||
float AUD_LimiterFactory::getStart()
|
||||
{
|
||||
return m_start;
|
||||
}
|
||||
|
||||
void AUD_LimiterFactory::setStart(float start)
|
||||
{
|
||||
m_start = start;
|
||||
}
|
||||
|
||||
float AUD_LimiterFactory::getEnd()
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
void AUD_LimiterFactory::setEnd(float end)
|
||||
{
|
||||
m_end = end;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_LimiterFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_LimiterReader(reader, m_start, m_end);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
84
intern/audaspace/FX/AUD_LimiterFactory.h
Normal file
84
intern/audaspace/FX/AUD_LimiterFactory.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LIMITERFACTORY
|
||||
#define AUD_LIMITERFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory limits another factory in start and end time.
|
||||
*/
|
||||
class AUD_LimiterFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The start time.
|
||||
*/
|
||||
float m_start;
|
||||
|
||||
/**
|
||||
* The end time.
|
||||
*/
|
||||
float m_end;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new limiter factory.
|
||||
* \param factory The input factory.
|
||||
* \param start The desired start time.
|
||||
* \param end The desired end time, a negative value signals that it should
|
||||
* play to the end.
|
||||
*/
|
||||
AUD_LimiterFactory(AUD_IFactory* factory = 0,
|
||||
float start = 0, float end = -1);
|
||||
|
||||
/**
|
||||
* Returns the start time.
|
||||
*/
|
||||
float getStart();
|
||||
|
||||
/**
|
||||
* Sets the start time.
|
||||
* \param start The new start time.
|
||||
*/
|
||||
void setStart(float start);
|
||||
|
||||
/**
|
||||
* Returns the end time.
|
||||
*/
|
||||
float getEnd();
|
||||
|
||||
/**
|
||||
* Sets the end time.
|
||||
* \param end The new end time, a negative value signals that it should play
|
||||
* to the end.
|
||||
*/
|
||||
void setEnd(float end);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_LIMITERFACTORY
|
||||
95
intern/audaspace/FX/AUD_LimiterReader.cpp
Normal file
95
intern/audaspace/FX/AUD_LimiterReader.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LimiterReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
|
||||
float start, float end) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
m_end = (int)(end * reader->getSpecs().rate);
|
||||
|
||||
if(start <= 0)
|
||||
m_start = 0;
|
||||
else
|
||||
{
|
||||
m_start = (int)(start * reader->getSpecs().rate);
|
||||
if(m_reader->isSeekable())
|
||||
m_reader->seek(m_start);
|
||||
else
|
||||
{
|
||||
// skip first m_start samples by reading them
|
||||
int length;
|
||||
sample_t* buffer;
|
||||
for(int i = m_start;
|
||||
i >= AUD_DEFAULT_BUFFER_SIZE;
|
||||
i -= AUD_DEFAULT_BUFFER_SIZE)
|
||||
{
|
||||
length = AUD_DEFAULT_BUFFER_SIZE;
|
||||
m_reader->read(length, buffer);
|
||||
length = i;
|
||||
}
|
||||
m_reader->read(length, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_LimiterReader::seek(int position)
|
||||
{
|
||||
m_reader->seek(position + m_start);
|
||||
}
|
||||
|
||||
int AUD_LimiterReader::getLength()
|
||||
{
|
||||
int len = m_reader->getLength();
|
||||
if(m_reader->getType() != AUD_TYPE_BUFFER || len < 0 ||
|
||||
(len > m_end && m_end >= 0))
|
||||
len = m_end;
|
||||
return len - m_start;
|
||||
}
|
||||
|
||||
int AUD_LimiterReader::getPosition()
|
||||
{
|
||||
return m_reader->getPosition() - m_start;
|
||||
}
|
||||
|
||||
void AUD_LimiterReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
if(m_end >= 0)
|
||||
{
|
||||
int position = m_reader->getPosition();
|
||||
if(position+length > m_end)
|
||||
length = m_end - position;
|
||||
if(length < 0)
|
||||
{
|
||||
length = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_reader->read(length, buffer);
|
||||
}
|
||||
64
intern/audaspace/FX/AUD_LimiterReader.h
Normal file
64
intern/audaspace/FX/AUD_LimiterReader.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LIMITERREADER
|
||||
#define AUD_LIMITERREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
|
||||
/**
|
||||
* This reader limits another reader in start and end sample.
|
||||
*/
|
||||
class AUD_LimiterReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The start sample: inclusive.
|
||||
*/
|
||||
int m_start;
|
||||
|
||||
/**
|
||||
* The end sample: exlusive.
|
||||
*/
|
||||
int m_end;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new limiter reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param start The desired start sample (inclusive).
|
||||
* \param end The desired end sample (exklusive), a negative value signals
|
||||
* that it should play to the end.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
|
||||
|
||||
virtual void seek(int position);
|
||||
virtual int getLength();
|
||||
virtual int getPosition();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_LIMITERREADER
|
||||
57
intern/audaspace/FX/AUD_LoopFactory.cpp
Normal file
57
intern/audaspace/FX/AUD_LoopFactory.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LoopFactory.h"
|
||||
#include "AUD_LoopReader.h"
|
||||
|
||||
AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_loop(loop) {}
|
||||
|
||||
AUD_LoopFactory::AUD_LoopFactory(int loop) :
|
||||
AUD_EffectFactory(0),
|
||||
m_loop(loop) {}
|
||||
|
||||
int AUD_LoopFactory::getLoop()
|
||||
{
|
||||
return m_loop;
|
||||
}
|
||||
|
||||
void AUD_LoopFactory::setLoop(int loop)
|
||||
{
|
||||
m_loop = loop;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_LoopFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_LoopReader(reader, m_loop); AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
74
intern/audaspace/FX/AUD_LoopFactory.h
Normal file
74
intern/audaspace/FX/AUD_LoopFactory.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LOOPFACTORY
|
||||
#define AUD_LOOPFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory loops another factory.
|
||||
* \note The reader has to be seekable.
|
||||
*/
|
||||
class AUD_LoopFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The loop count.
|
||||
*/
|
||||
float m_loop;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new loop factory.
|
||||
* \param factory The input factory.
|
||||
* \param loop The desired loop count, negative values result in endless
|
||||
* looping.
|
||||
*/
|
||||
AUD_LoopFactory(AUD_IFactory* factory = 0, int loop = -1);
|
||||
|
||||
/**
|
||||
* Creates a new loop factory.
|
||||
* \param loop The desired loop count, negative values result in endless
|
||||
* looping.
|
||||
*/
|
||||
AUD_LoopFactory(int loop);
|
||||
|
||||
/**
|
||||
* Returns the loop count.
|
||||
*/
|
||||
int getLoop();
|
||||
|
||||
/**
|
||||
* Sets the loop count.
|
||||
* \param loop The desired loop count, negative values result in endless
|
||||
* looping.
|
||||
*/
|
||||
void setLoop(int loop);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_LOOPFACTORY
|
||||
107
intern/audaspace/FX/AUD_LoopReader.cpp
Normal file
107
intern/audaspace/FX/AUD_LoopReader.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LoopReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
|
||||
AUD_EffectReader(reader), m_loop(loop)
|
||||
{
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_LoopReader::~AUD_LoopReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_LoopReader::getType()
|
||||
{
|
||||
if(m_loop < 0)
|
||||
return AUD_TYPE_STREAM;
|
||||
return m_reader->getType();
|
||||
}
|
||||
|
||||
bool AUD_LoopReader::notify(AUD_Message &message)
|
||||
{
|
||||
if(message.type == AUD_MSG_LOOP)
|
||||
{
|
||||
m_loop = message.loopcount;
|
||||
|
||||
m_reader->notify(message);
|
||||
|
||||
return true;
|
||||
}
|
||||
return m_reader->notify(message);
|
||||
}
|
||||
|
||||
void AUD_LoopReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
|
||||
|
||||
int len = length;
|
||||
|
||||
m_reader->read(len, buffer);
|
||||
|
||||
if(len < length && m_loop != 0)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
if(m_buffer->getSize() < length*samplesize)
|
||||
m_buffer->resize(length*samplesize);
|
||||
|
||||
memcpy(m_buffer->getBuffer() + pos * samplesize,
|
||||
buffer, len * samplesize);
|
||||
|
||||
pos += len;
|
||||
|
||||
while(pos < length && m_loop != 0)
|
||||
{
|
||||
if(m_loop > 0)
|
||||
m_loop--;
|
||||
|
||||
m_reader->seek(0);
|
||||
|
||||
len = length - pos;
|
||||
m_reader->read(len, buffer);
|
||||
// prevent endless loop
|
||||
if(!len)
|
||||
break;
|
||||
|
||||
memcpy(m_buffer->getBuffer() + pos * samplesize,
|
||||
buffer, len * samplesize);
|
||||
|
||||
pos += len;
|
||||
}
|
||||
|
||||
length = pos;
|
||||
buffer = m_buffer->getBuffer();
|
||||
}
|
||||
else
|
||||
length = len;
|
||||
}
|
||||
69
intern/audaspace/FX/AUD_LoopReader.h
Normal file
69
intern/audaspace/FX/AUD_LoopReader.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_LOOPREADER
|
||||
#define AUD_LOOPREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class reads another reader and loops it.
|
||||
* \note The other reader must be seekable.
|
||||
*/
|
||||
class AUD_LoopReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The left loop count.
|
||||
*/
|
||||
int m_loop;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new loop reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param loop The desired loop count, negative values result in endless
|
||||
* looping.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_LoopReader(AUD_IReader* reader, int loop);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_LoopReader();
|
||||
|
||||
virtual AUD_ReaderType getType();
|
||||
virtual bool notify(AUD_Message &message);
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_LOOPREADER
|
||||
67
intern/audaspace/FX/AUD_PingPongFactory.cpp
Normal file
67
intern/audaspace/FX/AUD_PingPongFactory.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_PingPongFactory.h"
|
||||
#include "AUD_DoubleReader.h"
|
||||
#include "AUD_ReverseFactory.h"
|
||||
|
||||
AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
|
||||
AUD_EffectFactory(factory) {}
|
||||
|
||||
AUD_IReader* AUD_PingPongFactory::createReader()
|
||||
{
|
||||
if(m_factory == 0)
|
||||
return 0;
|
||||
|
||||
AUD_IReader* reader = m_factory->createReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
AUD_IReader* reader2;
|
||||
AUD_ReverseFactory factory(m_factory);
|
||||
|
||||
try
|
||||
{
|
||||
reader2 = factory.createReader();
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
reader2 = 0;
|
||||
}
|
||||
|
||||
if(reader2 != 0)
|
||||
{
|
||||
reader = new AUD_DoubleReader(reader, reader2);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
else
|
||||
{
|
||||
delete reader; AUD_DELETE("reader")
|
||||
reader = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
51
intern/audaspace/FX/AUD_PingPongFactory.h
Normal file
51
intern/audaspace/FX/AUD_PingPongFactory.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_PINGPONGFACTORY
|
||||
#define AUD_PINGPONGFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory plays another factory first normal, then reversed.
|
||||
* \note Readers from the underlying factory must be from the buffer type.
|
||||
*/
|
||||
class AUD_PingPongFactory : public AUD_EffectFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new ping pong factory.
|
||||
* \param factory The input factory.
|
||||
*/
|
||||
AUD_PingPongFactory(AUD_IFactory* factory = 0);
|
||||
|
||||
/**
|
||||
* Destroys the factory.
|
||||
*/
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_PINGPONGFACTORY
|
||||
48
intern/audaspace/FX/AUD_PitchFactory.cpp
Normal file
48
intern/audaspace/FX/AUD_PitchFactory.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_PitchFactory.h"
|
||||
#include "AUD_PitchReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_pitch(pitch) {}
|
||||
|
||||
AUD_PitchFactory::AUD_PitchFactory(float pitch) :
|
||||
AUD_EffectFactory(0),
|
||||
m_pitch(pitch) {}
|
||||
|
||||
AUD_IReader* AUD_PitchFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_PitchReader(reader, m_pitch); AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
70
intern/audaspace/FX/AUD_PitchFactory.h
Normal file
70
intern/audaspace/FX/AUD_PitchFactory.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_PITCHFACTORY
|
||||
#define AUD_PITCHFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory changes the pitch of another factory.
|
||||
*/
|
||||
class AUD_PitchFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The pitch.
|
||||
*/
|
||||
float m_pitch;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new pitch factory.
|
||||
* \param factory The input factory.
|
||||
* \param pitch The desired pitch.
|
||||
*/
|
||||
AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0);
|
||||
|
||||
/**
|
||||
* Creates a new pitch factory.
|
||||
* \param pitch The desired pitch.
|
||||
*/
|
||||
AUD_PitchFactory(float pitch);
|
||||
|
||||
/**
|
||||
* Returns the pitch.
|
||||
*/
|
||||
float getPitch();
|
||||
|
||||
/**
|
||||
* Sets the pitch.
|
||||
* \param pitch The new pitch value. Should be between 0.0 and 1.0.
|
||||
*/
|
||||
void setPitch(float pitch);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_PITCHFACTORY
|
||||
39
intern/audaspace/FX/AUD_PitchReader.cpp
Normal file
39
intern/audaspace/FX/AUD_PitchReader.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_PitchReader.h"
|
||||
|
||||
AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
m_pitch = pitch;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_PitchReader::getSpecs()
|
||||
{
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
|
||||
return specs;
|
||||
}
|
||||
54
intern/audaspace/FX/AUD_PitchReader.h
Normal file
54
intern/audaspace/FX/AUD_PitchReader.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_PITCHREADER
|
||||
#define AUD_PITCHREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
|
||||
/**
|
||||
* This class reads another reader and changes it's pitch.
|
||||
*/
|
||||
class AUD_PitchReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The pitch level.
|
||||
*/
|
||||
float m_pitch;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new pitch reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param pitch The size of the buffer.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_PitchReader(AUD_IReader* reader, float pitch);
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
};
|
||||
|
||||
#endif //AUD_PITCHREADER
|
||||
43
intern/audaspace/FX/AUD_ReverseFactory.cpp
Normal file
43
intern/audaspace/FX/AUD_ReverseFactory.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ReverseFactory.h"
|
||||
#include "AUD_ReverseReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
|
||||
AUD_EffectFactory(factory) {}
|
||||
|
||||
AUD_IReader* AUD_ReverseFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_ReverseReader(reader); AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
50
intern/audaspace/FX/AUD_ReverseFactory.h
Normal file
50
intern/audaspace/FX/AUD_ReverseFactory.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_REVERSEFACTORY
|
||||
#define AUD_REVERSEFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory reads another factory reverted.
|
||||
* \note Readers from the underlying factory must be from the buffer type.
|
||||
*/
|
||||
class AUD_ReverseFactory : public AUD_EffectFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new reverse factory.
|
||||
* \param factory The input factory.
|
||||
*/
|
||||
AUD_ReverseFactory(AUD_IFactory* factory = 0);
|
||||
|
||||
/**
|
||||
* Destroys the factory.
|
||||
*/
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_REVERSEFACTORY
|
||||
111
intern/audaspace/FX/AUD_ReverseReader.cpp
Normal file
111
intern/audaspace/FX/AUD_ReverseReader.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ReverseReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
if(reader->getType() != AUD_TYPE_BUFFER)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
m_length = reader->getLength();
|
||||
if(m_length < 0)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
m_position = 0;
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_ReverseReader::~AUD_ReverseReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
void AUD_ReverseReader::seek(int position)
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
int AUD_ReverseReader::getLength()
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
int AUD_ReverseReader::getPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void AUD_ReverseReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// first correct the length
|
||||
if(m_position+length > m_length)
|
||||
length = m_length-m_position;
|
||||
|
||||
if(length <= 0)
|
||||
{
|
||||
length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int samplesize = AUD_SAMPLE_SIZE(getSpecs());
|
||||
|
||||
// resize buffer if needed
|
||||
if(m_buffer->getSize() < length * samplesize)
|
||||
m_buffer->resize(length * samplesize);
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
|
||||
sample_t* buf;
|
||||
int len = length;
|
||||
|
||||
// read from reader
|
||||
m_reader->seek(m_length-m_position-len);
|
||||
m_reader->read(len, buf);
|
||||
|
||||
// set null if reader didn't give enough data
|
||||
if(len < length)
|
||||
{
|
||||
if(getSpecs().format == AUD_FORMAT_U8)
|
||||
memset(buffer, 0x80, (length-len)*samplesize);
|
||||
else
|
||||
memset(buffer, 0, (length-len)*samplesize);
|
||||
buffer += length-len;
|
||||
}
|
||||
|
||||
// copy the samples reverted
|
||||
for(int i = 0; i < len; i++)
|
||||
memcpy(buffer + i * samplesize,
|
||||
buf + (len - 1 - i) * samplesize,
|
||||
samplesize);
|
||||
|
||||
m_position += length;
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
}
|
||||
74
intern/audaspace/FX/AUD_ReverseReader.h
Normal file
74
intern/audaspace/FX/AUD_ReverseReader.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_REVERSEREADER
|
||||
#define AUD_REVERSEREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class reads another reader from back to front.
|
||||
* \note The underlying reader must be a buffer.
|
||||
*/
|
||||
class AUD_ReverseReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The current position.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* The sample count.
|
||||
*/
|
||||
int m_length;
|
||||
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer* m_buffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new reverse reader.
|
||||
* \param reader The reader to read from.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL or not
|
||||
* a buffer.
|
||||
*/
|
||||
AUD_ReverseReader(AUD_IReader* reader);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_ReverseReader();
|
||||
|
||||
virtual void seek(int position);
|
||||
virtual int getLength();
|
||||
virtual int getPosition();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_REVERSEREADER
|
||||
57
intern/audaspace/FX/AUD_VolumeFactory.cpp
Normal file
57
intern/audaspace/FX/AUD_VolumeFactory.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_VolumeFactory.h"
|
||||
#include "AUD_VolumeReader.h"
|
||||
|
||||
AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
|
||||
AUD_EffectFactory(factory),
|
||||
m_volume(volume) {}
|
||||
|
||||
AUD_VolumeFactory::AUD_VolumeFactory(float volume) :
|
||||
AUD_EffectFactory(0),
|
||||
m_volume(volume) {}
|
||||
|
||||
float AUD_VolumeFactory::getVolume()
|
||||
{
|
||||
return m_volume;
|
||||
}
|
||||
|
||||
void AUD_VolumeFactory::setVolume(float volume)
|
||||
{
|
||||
m_volume = volume;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_VolumeFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
reader = new AUD_VolumeReader(reader, m_volume); AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
72
intern/audaspace/FX/AUD_VolumeFactory.h
Normal file
72
intern/audaspace/FX/AUD_VolumeFactory.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_VOLUMEFACTORY
|
||||
#define AUD_VOLUMEFACTORY
|
||||
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
/**
|
||||
* This factory changes the volume of another factory.
|
||||
* The set volume should be a value between 0.0 and 1.0, higher values at your
|
||||
* own risk!
|
||||
*/
|
||||
class AUD_VolumeFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The volume.
|
||||
*/
|
||||
float m_volume;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new volume factory.
|
||||
* \param factory The input factory.
|
||||
* \param volume The desired volume.
|
||||
*/
|
||||
AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0);
|
||||
|
||||
/**
|
||||
* Creates a new volume factory.
|
||||
* \param volume The desired volume.
|
||||
*/
|
||||
AUD_VolumeFactory(float volume);
|
||||
|
||||
/**
|
||||
* Returns the volume.
|
||||
*/
|
||||
float getVolume();
|
||||
|
||||
/**
|
||||
* Sets the volume.
|
||||
* \param volume The new volume value. Should be between 0.0 and 1.0.
|
||||
*/
|
||||
void setVolume(float volume);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_VOLUMEFACTORY
|
||||
97
intern/audaspace/FX/AUD_VolumeReader.cpp
Normal file
97
intern/audaspace/FX/AUD_VolumeReader.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_VolumeReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
|
||||
AUD_EffectReader(reader),
|
||||
m_volume(volume)
|
||||
{
|
||||
int bigendian = 1;
|
||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||
|
||||
switch(m_reader->getSpecs().format)
|
||||
{
|
||||
case AUD_FORMAT_S16:
|
||||
m_adjust = AUD_volume_adjust<int16_t>;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_adjust = AUD_volume_adjust<int32_t>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_adjust = AUD_volume_adjust<float>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_adjust = AUD_volume_adjust<double>;
|
||||
break;
|
||||
case AUD_FORMAT_U8:
|
||||
m_adjust = AUD_volume_adjust_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
m_adjust = bigendian ? AUD_volume_adjust_s24_be :
|
||||
AUD_volume_adjust_s24_le;
|
||||
break;
|
||||
default:
|
||||
delete m_reader;
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
}
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_VolumeReader::~AUD_VolumeReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
bool AUD_VolumeReader::notify(AUD_Message &message)
|
||||
{
|
||||
if(message.type == AUD_MSG_VOLUME)
|
||||
{
|
||||
m_volume = message.volume;
|
||||
|
||||
m_reader->notify(message);
|
||||
|
||||
return true;
|
||||
}
|
||||
return m_reader->notify(message);
|
||||
}
|
||||
|
||||
void AUD_VolumeReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer->resize(length*AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
|
||||
m_adjust(buffer, buf, length * specs.channels, m_volume);
|
||||
}
|
||||
72
intern/audaspace/FX/AUD_VolumeReader.h
Normal file
72
intern/audaspace/FX/AUD_VolumeReader.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_VOLUMEREADER
|
||||
#define AUD_VOLUMEREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class reads another reader and changes it's volume.
|
||||
*/
|
||||
class AUD_VolumeReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The volume level.
|
||||
*/
|
||||
float m_volume;
|
||||
|
||||
/**
|
||||
* Volume adjustment function.
|
||||
*/
|
||||
AUD_volume_adjust_f m_adjust;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new volume reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param volume The size of the buffer.
|
||||
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||
*/
|
||||
AUD_VolumeReader(AUD_IReader* reader, float volume);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_VolumeReader();
|
||||
|
||||
virtual bool notify(AUD_Message &message);
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_VOLUMEREADER
|
||||
57
intern/audaspace/Makefile
Normal file
57
intern/audaspace/Makefile
Normal file
@@ -0,0 +1,57 @@
|
||||
# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
|
||||
# vim: tabstop=8
|
||||
#
|
||||
# $Id: Makefile 19820 2009-04-20 15:06:46Z blendix $
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): GSR
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
include nan_definitions.mk
|
||||
|
||||
LIBNAME = audaspace
|
||||
SOURCEDIR = intern/audaspace
|
||||
DIR = $(OCGDIR)/$(SOURCEDIR)
|
||||
DIRS = intern
|
||||
DIRS += SDL
|
||||
|
||||
ifeq ($(WITH_FFMPEG),true)
|
||||
DIRS += ffmpeg
|
||||
endif
|
||||
|
||||
include nan_subdirs.mk
|
||||
|
||||
install: $(ALL_OR_DEBUG)
|
||||
@[ -d $(NAN_AUDASPACE) ] || mkdir $(NAN_AUDASPACE)
|
||||
@[ -d $(NAN_AUDASPACE)/include ] || mkdir $(NAN_AUDASPACE)/include
|
||||
@[ -d $(NAN_AUDASPACE)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
||||
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaudaspace.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
||||
ifeq ($(OS),darwin)
|
||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaudaspace.a
|
||||
endif
|
||||
@../tools/cpifdiff.sh *.h $(NAN_AUDASPACE)/include/
|
||||
|
||||
|
||||
1362
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
Normal file
1362
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
Normal file
@@ -0,0 +1,1362 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_OpenALDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_IMixer.h"
|
||||
#include "AUD_ConverterFactory.h"
|
||||
#include "AUD_SourceCaps.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define AUD_OPENAL_CYCLE_BUFFERS 3
|
||||
|
||||
/// Saves the data for playback.
|
||||
struct AUD_OpenALHandle : AUD_Handle
|
||||
{
|
||||
/// Whether it's a buffered or a streamed source.
|
||||
bool isBuffered;
|
||||
|
||||
/// The reader source.
|
||||
AUD_IReader* reader;
|
||||
|
||||
/// Whether to keep the source if end of it is reached.
|
||||
bool keep;
|
||||
|
||||
/// OpenAL sample format.
|
||||
ALenum format;
|
||||
|
||||
/// OpenAL source.
|
||||
ALuint source;
|
||||
|
||||
/// OpenAL buffers.
|
||||
ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
|
||||
|
||||
/// The first buffer to be read next.
|
||||
int current;
|
||||
|
||||
/// Whether the stream doesn't return any more data.
|
||||
bool data_end;
|
||||
};
|
||||
|
||||
struct AUD_OpenALBufferedFactory
|
||||
{
|
||||
/// The factory.
|
||||
AUD_IFactory* factory;
|
||||
|
||||
/// The OpenAL buffer.
|
||||
ALuint buffer;
|
||||
};
|
||||
|
||||
typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
|
||||
typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** Threading Code **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
void* AUD_openalRunThread(void* device)
|
||||
{
|
||||
AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
|
||||
dev->updateStreams();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AUD_OpenALDevice::start()
|
||||
{
|
||||
lock();
|
||||
|
||||
if(!m_playing)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
pthread_create(&m_thread, &attr, AUD_openalRunThread, this);
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
m_playing = true;
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
void AUD_OpenALDevice::updateStreams()
|
||||
{
|
||||
AUD_OpenALHandle* sound;
|
||||
|
||||
int length;
|
||||
sample_t* buffer;
|
||||
|
||||
ALint info;
|
||||
AUD_Specs specs;
|
||||
|
||||
while(1)
|
||||
{
|
||||
lock();
|
||||
|
||||
alcSuspendContext(m_context);
|
||||
|
||||
// for all sounds
|
||||
AUD_HandleIterator it = m_playingSounds->begin();
|
||||
while(it != m_playingSounds->end())
|
||||
{
|
||||
sound = *it;
|
||||
// increment the iterator to make sure it's valid,
|
||||
// in case the sound gets deleted after stopping
|
||||
++it;
|
||||
|
||||
// is it a streamed sound?
|
||||
if(!sound->isBuffered)
|
||||
{
|
||||
// check for buffer refilling
|
||||
alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
|
||||
|
||||
if(info)
|
||||
{
|
||||
specs = sound->reader->getSpecs();
|
||||
|
||||
// for all empty buffers
|
||||
while(info--)
|
||||
{
|
||||
// if there's still data to play back
|
||||
if(!sound->data_end)
|
||||
{
|
||||
// read data
|
||||
length = m_buffersize;
|
||||
sound->reader->read(length, buffer);
|
||||
|
||||
// read nothing?
|
||||
if(length == 0)
|
||||
{
|
||||
sound->data_end = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// unqueue buffer
|
||||
alSourceUnqueueBuffers(sound->source, 1,
|
||||
&sound->buffers[sound->current]);
|
||||
ALenum err;
|
||||
if((err = alGetError()) != AL_NO_ERROR)
|
||||
{
|
||||
sound->data_end = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// fill with new data
|
||||
alBufferData(sound->buffers[sound->current],
|
||||
sound->format,
|
||||
buffer,
|
||||
length * AUD_SAMPLE_SIZE(specs),
|
||||
specs.rate);
|
||||
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
sound->data_end = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// and queue again
|
||||
alSourceQueueBuffers(sound->source, 1,
|
||||
&sound->buffers[sound->current]);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
sound->data_end = true;
|
||||
break;
|
||||
}
|
||||
|
||||
sound->current = (sound->current+1) %
|
||||
AUD_OPENAL_CYCLE_BUFFERS;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if the sound has been stopped
|
||||
alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
|
||||
|
||||
if(info != AL_PLAYING)
|
||||
{
|
||||
// if it really stopped
|
||||
if(sound->data_end)
|
||||
{
|
||||
// pause or
|
||||
if(sound->keep)
|
||||
pause(sound);
|
||||
// stop
|
||||
else
|
||||
stop(sound);
|
||||
}
|
||||
// continue playing
|
||||
else
|
||||
alSourcePlay(sound->source);
|
||||
}
|
||||
}
|
||||
|
||||
alcProcessContext(m_context);
|
||||
|
||||
// stop thread
|
||||
if(m_playingSounds->empty())
|
||||
{
|
||||
unlock();
|
||||
m_playing = false;
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
unlock();
|
||||
|
||||
#ifdef WIN32
|
||||
Sleep(20);
|
||||
#else
|
||||
usleep(20000);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** IDevice Code ************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
|
||||
{
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
if(*i == handle)
|
||||
return true;
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
if(*i == handle)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
|
||||
{
|
||||
// cannot determine how many channels or which format OpenAL uses, but
|
||||
// it at least is able to play 16 bit stereo audio
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
|
||||
m_device = alcOpenDevice(NULL);
|
||||
|
||||
if(!m_device)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
|
||||
// at least try to set the frequency
|
||||
ALCint attribs[] = { ALC_FREQUENCY, specs.rate, 0 };
|
||||
ALCint* attributes = attribs;
|
||||
if(specs.rate == AUD_RATE_INVALID)
|
||||
attributes = NULL;
|
||||
|
||||
m_context = alcCreateContext(m_device, attributes);
|
||||
alcMakeContextCurrent(m_context);
|
||||
|
||||
alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
|
||||
|
||||
// check for specific formats and channel counts to be played back
|
||||
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
|
||||
specs.format = AUD_FORMAT_FLOAT32;
|
||||
|
||||
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
|
||||
|
||||
alGetError();
|
||||
|
||||
m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
|
||||
|
||||
m_specs = specs;
|
||||
m_buffersize = buffersize;
|
||||
m_playing = false;
|
||||
|
||||
m_playingSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list")
|
||||
m_pausedSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list")
|
||||
m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
|
||||
AUD_NEW("list")
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
pthread_mutex_init(&m_mutex, &attr);
|
||||
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
AUD_OpenALDevice::~AUD_OpenALDevice()
|
||||
{
|
||||
AUD_OpenALHandle* sound;
|
||||
|
||||
lock();
|
||||
alcSuspendContext(m_context);
|
||||
|
||||
// delete all playing sounds
|
||||
while(!m_playingSounds->empty())
|
||||
{
|
||||
sound = *(m_playingSounds->begin());
|
||||
alDeleteSources(1, &sound->source);
|
||||
if(!sound->isBuffered)
|
||||
{
|
||||
delete sound->reader; AUD_DELETE("reader")
|
||||
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
|
||||
}
|
||||
delete sound; AUD_DELETE("handle")
|
||||
m_playingSounds->erase(m_playingSounds->begin());
|
||||
}
|
||||
|
||||
// delete all paused sounds
|
||||
while(!m_pausedSounds->empty())
|
||||
{
|
||||
sound = *(m_pausedSounds->begin());
|
||||
alDeleteSources(1, &sound->source);
|
||||
if(!sound->isBuffered)
|
||||
{
|
||||
delete sound->reader; AUD_DELETE("reader")
|
||||
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
|
||||
}
|
||||
delete sound; AUD_DELETE("handle")
|
||||
m_pausedSounds->erase(m_pausedSounds->begin());
|
||||
}
|
||||
|
||||
// delete all buffered factories
|
||||
while(!m_bufferedFactories->empty())
|
||||
{
|
||||
alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
|
||||
delete *m_bufferedFactories->begin(); AUD_DELETE("bufferedfactory");
|
||||
m_bufferedFactories->erase(m_bufferedFactories->begin());
|
||||
}
|
||||
|
||||
alcProcessContext(m_context);
|
||||
|
||||
// wait for the thread to stop
|
||||
if(m_playing)
|
||||
{
|
||||
unlock();
|
||||
pthread_join(m_thread, NULL);
|
||||
}
|
||||
else
|
||||
unlock();
|
||||
|
||||
delete m_playingSounds; AUD_DELETE("list")
|
||||
delete m_pausedSounds; AUD_DELETE("list")
|
||||
delete m_bufferedFactories; AUD_DELETE("list")
|
||||
|
||||
// quit OpenAL
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(m_context);
|
||||
alcCloseDevice(m_device);
|
||||
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
|
||||
AUD_Specs AUD_OpenALDevice::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
|
||||
{
|
||||
bool valid = true;
|
||||
format = 0;
|
||||
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
switch(specs.channels)
|
||||
{
|
||||
case AUD_CHANNELS_MONO:
|
||||
format = AL_FORMAT_MONO8;
|
||||
break;
|
||||
case AUD_CHANNELS_STEREO:
|
||||
format = AL_FORMAT_STEREO8;
|
||||
break;
|
||||
case AUD_CHANNELS_SURROUND4:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_QUAD8");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND51:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_51CHN8");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND61:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_61CHN8");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND71:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_71CHN8");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
switch(specs.channels)
|
||||
{
|
||||
case AUD_CHANNELS_MONO:
|
||||
format = AL_FORMAT_MONO16;
|
||||
break;
|
||||
case AUD_CHANNELS_STEREO:
|
||||
format = AL_FORMAT_STEREO16;
|
||||
break;
|
||||
case AUD_CHANNELS_SURROUND4:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_QUAD16");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND51:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_51CHN16");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND61:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_61CHN16");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND71:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_71CHN16");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
switch(specs.channels)
|
||||
{
|
||||
case AUD_CHANNELS_MONO:
|
||||
format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
|
||||
break;
|
||||
case AUD_CHANNELS_STEREO:
|
||||
format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
|
||||
break;
|
||||
case AUD_CHANNELS_SURROUND4:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_QUAD32");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND51:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_51CHN32");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND61:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_61CHN32");
|
||||
break;
|
||||
}
|
||||
case AUD_CHANNELS_SURROUND71:
|
||||
if(m_useMC)
|
||||
{
|
||||
format = alGetEnumValue("AL_FORMAT_71CHN32");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if(!format)
|
||||
valid = false;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
|
||||
{
|
||||
// check if it is a buffered factory
|
||||
for(AUD_BFIterator i = m_bufferedFactories->begin();
|
||||
i != m_bufferedFactories->end(); i++)
|
||||
{
|
||||
if((*i)->factory == factory)
|
||||
{
|
||||
// create the handle
|
||||
AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle")
|
||||
sound->keep = keep;
|
||||
sound->current = -1;
|
||||
sound->isBuffered = true;
|
||||
sound->data_end = true;
|
||||
|
||||
alcSuspendContext(m_context);
|
||||
|
||||
// OpenAL playback code
|
||||
try
|
||||
{
|
||||
alGenSources(1, &sound->source);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
|
||||
try
|
||||
{
|
||||
alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
alDeleteSources(1, &sound->source);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
delete sound; AUD_DELETE("handle")
|
||||
alcProcessContext(m_context);
|
||||
unlock();
|
||||
throw;
|
||||
}
|
||||
|
||||
// play sound
|
||||
m_playingSounds->push_back(sound);
|
||||
|
||||
alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
|
||||
start();
|
||||
|
||||
alcProcessContext(m_context);
|
||||
unlock();
|
||||
|
||||
return sound;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_IReader* reader = factory->createReader();
|
||||
|
||||
if(reader == NULL)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
AUD_Specs specs;
|
||||
|
||||
specs = reader->getSpecs();
|
||||
|
||||
// check format
|
||||
bool valid = true;
|
||||
|
||||
if(specs.format == AUD_FORMAT_INVALID)
|
||||
valid = false;
|
||||
else if(specs.format == AUD_FORMAT_S24 ||
|
||||
specs.format == AUD_FORMAT_S32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT64)
|
||||
{
|
||||
m_converter->setReader(reader);
|
||||
reader = m_converter->createReader();
|
||||
specs = reader->getSpecs();
|
||||
}
|
||||
|
||||
// create the handle
|
||||
AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle")
|
||||
sound->keep = keep;
|
||||
sound->reader = reader;
|
||||
sound->current = 0;
|
||||
sound->isBuffered = false;
|
||||
sound->data_end = false;
|
||||
|
||||
valid &= getFormat(sound->format, specs);
|
||||
|
||||
if(!valid)
|
||||
{
|
||||
delete sound; AUD_DELETE("handle")
|
||||
delete reader; AUD_DELETE("reader")
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lock();
|
||||
alcSuspendContext(m_context);
|
||||
|
||||
// OpenAL playback code
|
||||
try
|
||||
{
|
||||
alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
|
||||
try
|
||||
{
|
||||
sample_t* buf;
|
||||
int length;
|
||||
|
||||
for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
|
||||
{
|
||||
length = m_buffersize;
|
||||
reader->read(length, buf);
|
||||
alBufferData(sound->buffers[i], sound->format, buf,
|
||||
length * AUD_SAMPLE_SIZE(specs), specs.rate);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
}
|
||||
|
||||
alGenSources(1, &sound->source);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
|
||||
try
|
||||
{
|
||||
alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
|
||||
sound->buffers);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
alDeleteSources(1, &sound->source);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
delete sound; AUD_DELETE("handle")
|
||||
delete reader; AUD_DELETE("reader")
|
||||
alcProcessContext(m_context);
|
||||
unlock();
|
||||
throw;
|
||||
}
|
||||
|
||||
// play sound
|
||||
m_playingSounds->push_back(sound);
|
||||
alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
|
||||
|
||||
start();
|
||||
|
||||
alcProcessContext(m_context);
|
||||
unlock();
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::pause(AUD_Handle* handle)
|
||||
{
|
||||
// only songs that are played can be paused
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
m_pausedSounds->push_back(*i);
|
||||
alSourcePause((*i)->source);
|
||||
m_playingSounds->erase(i);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::resume(AUD_Handle* handle)
|
||||
{
|
||||
lock();
|
||||
|
||||
// only songs that are paused can be resumed
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
m_playingSounds->push_back(*i);
|
||||
start();
|
||||
m_pausedSounds->erase(i);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::stop(AUD_Handle* handle)
|
||||
{
|
||||
AUD_OpenALHandle* sound;
|
||||
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
sound = *i;
|
||||
alDeleteSources(1, &sound->source);
|
||||
if(!sound->isBuffered)
|
||||
{
|
||||
delete sound->reader; AUD_DELETE("reader")
|
||||
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
|
||||
}
|
||||
delete *i; AUD_DELETE("handle")
|
||||
m_playingSounds->erase(i);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
sound = *i;
|
||||
alDeleteSources(1, &sound->source);
|
||||
if(!sound->isBuffered)
|
||||
{
|
||||
delete sound->reader; AUD_DELETE("reader")
|
||||
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
|
||||
}
|
||||
delete *i; AUD_DELETE("handle")
|
||||
m_pausedSounds->erase(i);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
|
||||
{
|
||||
lock();
|
||||
if(isValid(handle))
|
||||
{
|
||||
((AUD_OpenALHandle*)handle)->keep = keep;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
|
||||
{
|
||||
lock();
|
||||
|
||||
bool result = false;
|
||||
|
||||
if(handle == 0)
|
||||
{
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
if(!(*i)->isBuffered)
|
||||
result |= (*i)->reader->notify(message);
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
if(!(*i)->isBuffered)
|
||||
result |= (*i)->reader->notify(message);
|
||||
}
|
||||
else if(isValid(handle))
|
||||
if(!((AUD_OpenALHandle*)handle)->isBuffered)
|
||||
result = ((AUD_OpenALHandle*)handle)->reader->notify(message);
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
|
||||
{
|
||||
lock();
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
|
||||
if(alhandle->isBuffered)
|
||||
alSourcef(alhandle->source, AL_SEC_OFFSET, position);
|
||||
else
|
||||
{
|
||||
alhandle->reader->seek((int)(position *
|
||||
alhandle->reader->getSpecs().rate));
|
||||
alhandle->data_end = false;
|
||||
|
||||
ALint info;
|
||||
|
||||
alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
|
||||
|
||||
if(info != AL_PLAYING)
|
||||
{
|
||||
if(info != AL_STOPPED)
|
||||
alSourceStop(alhandle->source);
|
||||
|
||||
alSourceUnqueueBuffers(alhandle->source,
|
||||
AUD_OPENAL_CYCLE_BUFFERS,
|
||||
alhandle->buffers);
|
||||
if(alGetError() == AL_NO_ERROR)
|
||||
{
|
||||
sample_t* buf;
|
||||
int length;
|
||||
AUD_Specs specs = alhandle->reader->getSpecs();
|
||||
|
||||
for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
|
||||
{
|
||||
length = m_buffersize;
|
||||
alhandle->reader->read(length, buf);
|
||||
alBufferData(alhandle->buffers[i], alhandle->format,
|
||||
buf, length * AUD_SAMPLE_SIZE(specs),
|
||||
specs.rate);
|
||||
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
alSourceQueueBuffers(alhandle->source,
|
||||
AUD_OPENAL_CYCLE_BUFFERS,
|
||||
alhandle->buffers);
|
||||
}
|
||||
|
||||
alSourceRewind(alhandle->source);
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
|
||||
{
|
||||
lock();
|
||||
|
||||
float position = 0.0;
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
|
||||
if(h->isBuffered)
|
||||
alGetSourcef(h->source, AL_SEC_OFFSET, &position);
|
||||
else
|
||||
position = h->reader->getPosition() /
|
||||
(float)h->reader->getSpecs().rate;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return position;
|
||||
}
|
||||
|
||||
AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
|
||||
{
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
unlock();
|
||||
return AUD_STATUS_PLAYING;
|
||||
}
|
||||
}
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
unlock();
|
||||
return AUD_STATUS_PAUSED;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return AUD_STATUS_INVALID;
|
||||
}
|
||||
|
||||
void AUD_OpenALDevice::lock()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
}
|
||||
|
||||
void AUD_OpenALDevice::unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** Capabilities Code *******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
bool AUD_OpenALDevice::checkCapability(int capability)
|
||||
{
|
||||
return capability == AUD_CAPS_3D_DEVICE ||
|
||||
capability == AUD_CAPS_VOLUME ||
|
||||
capability == AUD_CAPS_SOURCE_VOLUME ||
|
||||
capability == AUD_CAPS_SOURCE_PITCH ||
|
||||
capability == AUD_CAPS_BUFFERED_FACTORY;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::setCapability(int capability, void *value)
|
||||
{
|
||||
switch(capability)
|
||||
{
|
||||
case AUD_CAPS_VOLUME:
|
||||
alListenerf(AL_GAIN, *((float*)value));
|
||||
return true;
|
||||
case AUD_CAPS_SOURCE_VOLUME:
|
||||
{
|
||||
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
|
||||
lock();
|
||||
if(isValid(caps->handle))
|
||||
{
|
||||
alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
|
||||
AL_GAIN, caps->value);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
case AUD_CAPS_SOURCE_PITCH:
|
||||
{
|
||||
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
|
||||
lock();
|
||||
if(isValid(caps->handle))
|
||||
{
|
||||
alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
|
||||
AL_PITCH, caps->value);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
case AUD_CAPS_BUFFERED_FACTORY:
|
||||
{
|
||||
AUD_IFactory* factory = (AUD_IFactory*) value;
|
||||
|
||||
// load the factory into an OpenAL buffer
|
||||
if(factory)
|
||||
{
|
||||
lock();
|
||||
for(AUD_BFIterator i = m_bufferedFactories->begin();
|
||||
i != m_bufferedFactories->end(); i++)
|
||||
{
|
||||
if((*i)->factory == factory)
|
||||
{
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
|
||||
AUD_IReader* reader = factory->createReader();
|
||||
|
||||
if(reader == NULL)
|
||||
return false;
|
||||
|
||||
AUD_Specs specs;
|
||||
|
||||
specs = reader->getSpecs();
|
||||
|
||||
// determine format
|
||||
bool valid = reader->getType() == AUD_TYPE_BUFFER;
|
||||
|
||||
if(valid)
|
||||
{
|
||||
if(specs.format == AUD_FORMAT_INVALID)
|
||||
valid = false;
|
||||
else if(specs.format == AUD_FORMAT_S24 ||
|
||||
specs.format == AUD_FORMAT_S32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT32 ||
|
||||
specs.format == AUD_FORMAT_FLOAT64)
|
||||
{
|
||||
m_converter->setReader(reader);
|
||||
reader = m_converter->createReader();
|
||||
specs = reader->getSpecs();
|
||||
}
|
||||
}
|
||||
|
||||
ALenum format;
|
||||
|
||||
if(valid)
|
||||
valid = getFormat(format, specs);
|
||||
|
||||
if(!valid)
|
||||
{
|
||||
delete reader; AUD_DELETE("reader")
|
||||
return false;
|
||||
}
|
||||
|
||||
// load into a buffer
|
||||
lock();
|
||||
alcSuspendContext(m_context);
|
||||
|
||||
AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
|
||||
AUD_NEW("bufferedfactory");
|
||||
bf->factory = factory;
|
||||
|
||||
try
|
||||
{
|
||||
alGenBuffers(1, &bf->buffer);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
|
||||
try
|
||||
{
|
||||
sample_t* buf;
|
||||
int length = reader->getLength();
|
||||
|
||||
reader->read(length, buf);
|
||||
alBufferData(bf->buffer, format, buf,
|
||||
length * AUD_SAMPLE_SIZE(specs),
|
||||
specs.rate);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
AUD_THROW(AUD_ERROR_OPENAL);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
alDeleteBuffers(1, &bf->buffer);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
delete bf; AUD_DELETE("bufferedfactory")
|
||||
delete reader; AUD_DELETE("reader")
|
||||
alcProcessContext(m_context);
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bufferedFactories->push_back(bf);
|
||||
|
||||
alcProcessContext(m_context);
|
||||
unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// stop all playing and paused buffered sources
|
||||
lock();
|
||||
alcSuspendContext(m_context);
|
||||
|
||||
AUD_OpenALHandle* sound;
|
||||
AUD_HandleIterator it = m_playingSounds->begin();
|
||||
while(it != m_playingSounds->end())
|
||||
{
|
||||
sound = *it;
|
||||
++it;
|
||||
|
||||
if(sound->isBuffered)
|
||||
stop(sound);
|
||||
}
|
||||
alcProcessContext(m_context);
|
||||
|
||||
while(!m_bufferedFactories->empty())
|
||||
{
|
||||
alDeleteBuffers(1,
|
||||
&(*(m_bufferedFactories->begin()))->buffer);
|
||||
delete *m_bufferedFactories->begin();
|
||||
AUD_DELETE("bufferedfactory");
|
||||
m_bufferedFactories->erase(m_bufferedFactories->begin());
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::getCapability(int capability, void *value)
|
||||
{
|
||||
switch(capability)
|
||||
{
|
||||
case AUD_CAPS_VOLUME:
|
||||
alGetListenerf(AL_GAIN, (float*)value);
|
||||
return true;
|
||||
case AUD_CAPS_SOURCE_VOLUME:
|
||||
{
|
||||
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
|
||||
lock();
|
||||
if(isValid(caps->handle))
|
||||
{
|
||||
alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
|
||||
AL_GAIN, &caps->value);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
case AUD_CAPS_SOURCE_PITCH:
|
||||
{
|
||||
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
|
||||
lock();
|
||||
if(isValid(caps->handle))
|
||||
{
|
||||
alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
|
||||
AL_PITCH, &caps->value);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**************************** 3D Device Code **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
AUD_Handle* AUD_OpenALDevice::play3D(AUD_IFactory* factory, bool keep)
|
||||
{
|
||||
AUD_OpenALHandle* handle = (AUD_OpenALHandle*)play(factory, keep);
|
||||
if(handle)
|
||||
alSourcei(handle->source, AL_SOURCE_RELATIVE, 0);
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::updateListener(AUD_3DData &data)
|
||||
{
|
||||
alListenerfv(AL_POSITION, (ALfloat*)data.position);
|
||||
alListenerfv(AL_VELOCITY, (ALfloat*)data.velocity);
|
||||
alListenerfv(AL_ORIENTATION, (ALfloat*)&(data.orientation[3]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::setSetting(AUD_3DSetting setting, float value)
|
||||
{
|
||||
switch(setting)
|
||||
{
|
||||
case AUD_3DS_DISTANCE_MODEL:
|
||||
if(value == AUD_DISTANCE_MODEL_NONE)
|
||||
alDistanceModel(AL_NONE);
|
||||
else if(value == AUD_DISTANCE_MODEL_INVERSE)
|
||||
alDistanceModel(AL_INVERSE_DISTANCE);
|
||||
else if(value == AUD_DISTANCE_MODEL_INVERSE_CLAMPED)
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
else if(value == AUD_DISTANCE_MODEL_LINEAR)
|
||||
alDistanceModel(AL_LINEAR_DISTANCE);
|
||||
else if(value == AUD_DISTANCE_MODEL_LINEAR_CLAMPED)
|
||||
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
||||
else if(value == AUD_DISTANCE_MODEL_EXPONENT)
|
||||
alDistanceModel(AL_EXPONENT_DISTANCE);
|
||||
else if(value == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
|
||||
alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
case AUD_3DS_DOPPLER_FACTOR:
|
||||
alDopplerFactor(value);
|
||||
return true;
|
||||
case AUD_3DS_SPEED_OF_SOUND:
|
||||
alSpeedOfSound(value);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float AUD_OpenALDevice::getSetting(AUD_3DSetting setting)
|
||||
{
|
||||
switch(setting)
|
||||
{
|
||||
case AUD_3DS_DISTANCE_MODEL:
|
||||
switch(alGetInteger(AL_DISTANCE_MODEL))
|
||||
{
|
||||
case AL_NONE:
|
||||
return AUD_DISTANCE_MODEL_NONE;
|
||||
case AL_INVERSE_DISTANCE:
|
||||
return AUD_DISTANCE_MODEL_INVERSE;
|
||||
case AL_INVERSE_DISTANCE_CLAMPED:
|
||||
return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
|
||||
case AL_LINEAR_DISTANCE:
|
||||
return AUD_DISTANCE_MODEL_LINEAR;
|
||||
case AL_LINEAR_DISTANCE_CLAMPED:
|
||||
return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
|
||||
case AL_EXPONENT_DISTANCE:
|
||||
return AUD_DISTANCE_MODEL_EXPONENT;
|
||||
case AL_EXPONENT_DISTANCE_CLAMPED:
|
||||
return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
|
||||
}
|
||||
case AUD_3DS_DOPPLER_FACTOR:
|
||||
return alGetFloat(AL_DOPPLER_FACTOR);
|
||||
case AUD_3DS_SPEED_OF_SOUND:
|
||||
return alGetFloat(AL_SPEED_OF_SOUND);
|
||||
default:
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data)
|
||||
{
|
||||
lock();
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
int source = ((AUD_OpenALHandle*)handle)->source;
|
||||
alSourcefv(source, AL_POSITION, (ALfloat*)data.position);
|
||||
alSourcefv(source, AL_VELOCITY, (ALfloat*)data.velocity);
|
||||
alSourcefv(source, AL_DIRECTION, (ALfloat*)&(data.orientation[3]));
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting,
|
||||
float value)
|
||||
{
|
||||
lock();
|
||||
|
||||
bool result = false;
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
int source = ((AUD_OpenALHandle*)handle)->source;
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case AUD_3DSS_CONE_INNER_ANGLE:
|
||||
alSourcef(source, AL_CONE_INNER_ANGLE, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_CONE_OUTER_ANGLE:
|
||||
alSourcef(source, AL_CONE_OUTER_ANGLE, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_CONE_OUTER_GAIN:
|
||||
alSourcef(source, AL_CONE_OUTER_GAIN, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_IS_RELATIVE:
|
||||
alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_MAX_DISTANCE:
|
||||
alSourcef(source, AL_MAX_DISTANCE, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_MAX_GAIN:
|
||||
alSourcef(source, AL_MAX_GAIN, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_MIN_GAIN:
|
||||
alSourcef(source, AL_MIN_GAIN, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_REFERENCE_DISTANCE:
|
||||
alSourcef(source, AL_REFERENCE_DISTANCE, value);
|
||||
result = true;
|
||||
break;
|
||||
case AUD_3DSS_ROLLOFF_FACTOR:
|
||||
alSourcef(source, AL_ROLLOFF_FACTOR, value);
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting)
|
||||
{
|
||||
float result = std::numeric_limits<float>::quiet_NaN();;
|
||||
|
||||
lock();
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
int source = ((AUD_OpenALHandle*)handle)->source;
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case AUD_3DSS_CONE_INNER_ANGLE:
|
||||
alGetSourcef(source, AL_CONE_INNER_ANGLE, &result);
|
||||
break;
|
||||
case AUD_3DSS_CONE_OUTER_ANGLE:
|
||||
alGetSourcef(source, AL_CONE_OUTER_ANGLE, &result);
|
||||
break;
|
||||
case AUD_3DSS_CONE_OUTER_GAIN:
|
||||
alGetSourcef(source, AL_CONE_OUTER_GAIN, &result);
|
||||
break;
|
||||
case AUD_3DSS_IS_RELATIVE:
|
||||
{
|
||||
ALint i;
|
||||
alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
|
||||
result = i ? 1.0 : 0.0;
|
||||
break;
|
||||
}
|
||||
case AUD_3DSS_MAX_DISTANCE:
|
||||
alGetSourcef(source, AL_MAX_DISTANCE, &result);
|
||||
break;
|
||||
case AUD_3DSS_MAX_GAIN:
|
||||
alGetSourcef(source, AL_MAX_GAIN, &result);
|
||||
break;
|
||||
case AUD_3DSS_MIN_GAIN:
|
||||
alGetSourcef(source, AL_MIN_GAIN, &result);
|
||||
break;
|
||||
case AUD_3DSS_REFERENCE_DISTANCE:
|
||||
alGetSourcef(source, AL_REFERENCE_DISTANCE, &result);
|
||||
break;
|
||||
case AUD_3DSS_ROLLOFF_FACTOR:
|
||||
alGetSourcef(source, AL_ROLLOFF_FACTOR, &result);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
171
intern/audaspace/OpenAL/AUD_OpenALDevice.h
Normal file
171
intern/audaspace/OpenAL/AUD_OpenALDevice.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_OPENALDEVICE
|
||||
#define AUD_OPENALDEVICE
|
||||
|
||||
#include "AUD_IDevice.h"
|
||||
#include "AUD_I3DDevice.h"
|
||||
struct AUD_OpenALHandle;
|
||||
struct AUD_OpenALBufferedFactory;
|
||||
class AUD_ConverterFactory;
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* This device plays through OpenAL.
|
||||
*/
|
||||
class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The OpenAL device handle.
|
||||
*/
|
||||
ALCdevice* m_device;
|
||||
|
||||
/**
|
||||
* The OpenAL context.
|
||||
*/
|
||||
ALCcontext* m_context;
|
||||
|
||||
/**
|
||||
* The specification of the device.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* Whether the device has the AL_EXT_MCFORMATS extension.
|
||||
*/
|
||||
bool m_useMC;
|
||||
|
||||
/**
|
||||
* The converter factory for readers with wrong input format.
|
||||
*/
|
||||
AUD_ConverterFactory* m_converter;
|
||||
|
||||
/**
|
||||
* The list of sounds that are currently playing.
|
||||
*/
|
||||
std::list<AUD_OpenALHandle*>* m_playingSounds;
|
||||
|
||||
/**
|
||||
* The list of sounds that are currently paused.
|
||||
*/
|
||||
std::list<AUD_OpenALHandle*>* m_pausedSounds;
|
||||
|
||||
/**
|
||||
* The list of buffered factories.
|
||||
*/
|
||||
std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
|
||||
|
||||
/**
|
||||
* The mutex for locking.
|
||||
*/
|
||||
pthread_mutex_t m_mutex;
|
||||
|
||||
/**
|
||||
* The streaming thread.
|
||||
*/
|
||||
pthread_t m_thread;
|
||||
|
||||
/**
|
||||
* The condition for streaming thread wakeup.
|
||||
*/
|
||||
bool m_playing;
|
||||
|
||||
/**
|
||||
* Buffer size.
|
||||
*/
|
||||
int m_buffersize;
|
||||
|
||||
/**
|
||||
* Starts the streaming thread.
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Checks if a handle is valid.
|
||||
* \param handle The handle to check.
|
||||
* \return Whether the handle is valid.
|
||||
*/
|
||||
bool isValid(AUD_Handle* handle);
|
||||
|
||||
/**
|
||||
* Gets the format according to the specs.
|
||||
* \param format The variable to put the format into.
|
||||
* \param specs The specs to read the format from.
|
||||
* \return Whether the format is valid or not.
|
||||
*/
|
||||
bool getFormat(ALenum &format, AUD_Specs specs);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Opens the OpenAL audio device for playback.
|
||||
* \param specs The wanted audio specification.
|
||||
* \param buffersize The size of the internal buffer.
|
||||
* \note The specification really used for opening the device may differ.
|
||||
* \note The buffersize will be multiplicated by three for this device.
|
||||
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
||||
*/
|
||||
AUD_OpenALDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
/**
|
||||
* Streaming thread main function.
|
||||
*/
|
||||
void updateStreams();
|
||||
|
||||
virtual ~AUD_OpenALDevice();
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool pause(AUD_Handle* handle);
|
||||
virtual bool resume(AUD_Handle* handle);
|
||||
virtual bool stop(AUD_Handle* handle);
|
||||
virtual bool setKeep(AUD_Handle* handle, bool keep);
|
||||
virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
|
||||
virtual bool seek(AUD_Handle* handle, float position);
|
||||
virtual float getPosition(AUD_Handle* handle);
|
||||
virtual AUD_Status getStatus(AUD_Handle* handle);
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
virtual bool checkCapability(int capability);
|
||||
virtual bool setCapability(int capability, void *value);
|
||||
virtual bool getCapability(int capability, void *value);
|
||||
|
||||
virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool updateListener(AUD_3DData &data);
|
||||
virtual bool setSetting(AUD_3DSetting setting, float value);
|
||||
virtual float getSetting(AUD_3DSetting setting);
|
||||
virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data);
|
||||
virtual bool setSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting, float value);
|
||||
virtual float getSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting);
|
||||
};
|
||||
|
||||
#endif //AUD_OPENALDEVICE
|
||||
24
intern/audaspace/SConscript
Normal file
24
intern/audaspace/SConscript
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('intern/*.cpp') + env.Glob('FX/*.cpp') + env.Glob('SRC/*.cpp')
|
||||
incs = '. intern FX SRC ' + env['BF_PTHREADS_INC'] + ' ' + env['BF_LIBSAMPLERATE_INC']
|
||||
defs = []
|
||||
|
||||
if env['WITH_BF_FFMPEG']:
|
||||
sources += env.Glob('ffmpeg/*.cpp')
|
||||
incs += ' ffmpeg ' + env['BF_FFMPEG_INC']
|
||||
defs.append('WITH_FFMPEG')
|
||||
|
||||
if env['WITH_BF_SDL']:
|
||||
sources += env.Glob('SDL/*.cpp')
|
||||
incs += ' SDL ' + env['BF_SDL_INC']
|
||||
defs.append('WITH_SDL')
|
||||
|
||||
if env['WITH_BF_OPENAL']:
|
||||
sources += env.Glob('OpenAL/*.cpp')
|
||||
incs += ' OpenAL ' + env['BF_OPENAL_INC']
|
||||
defs.append('WITH_OPENAL')
|
||||
|
||||
env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern'], priority = [25] )
|
||||
97
intern/audaspace/SDL/AUD_SDLDevice.cpp
Normal file
97
intern/audaspace/SDL/AUD_SDLDevice.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMixer.h"
|
||||
#include "AUD_SDLDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
// this is the callback function for SDL, it only calls the class
|
||||
void mixAudio(void *data, Uint8* buffer, int length)
|
||||
{
|
||||
AUD_SDLDevice* device = (AUD_SDLDevice*)data;
|
||||
device->SDLmix((sample_t *)buffer, length);
|
||||
}
|
||||
|
||||
AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
|
||||
{
|
||||
if(specs.channels == AUD_CHANNELS_INVALID)
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
if(specs.format == AUD_FORMAT_INVALID)
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
if(specs.rate == AUD_RATE_INVALID)
|
||||
specs.rate = AUD_RATE_44100;
|
||||
|
||||
m_specs = specs;
|
||||
|
||||
SDL_AudioSpec format, obtained;
|
||||
|
||||
format.freq = m_specs.rate;
|
||||
if(m_specs.format == AUD_FORMAT_U8)
|
||||
format.format = AUDIO_U8;
|
||||
else
|
||||
format.format = AUDIO_S16SYS;
|
||||
format.channels = m_specs.channels;
|
||||
format.samples = buffersize;
|
||||
format.callback = &mixAudio;
|
||||
format.userdata = this;
|
||||
|
||||
if(SDL_OpenAudio(&format, &obtained) != 0)
|
||||
AUD_THROW(AUD_ERROR_SDL);
|
||||
|
||||
m_specs.rate = (AUD_SampleRate)obtained.freq;
|
||||
m_specs.channels = (AUD_Channels)obtained.channels;
|
||||
if(obtained.format == AUDIO_U8)
|
||||
m_specs.format = AUD_FORMAT_U8;
|
||||
else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
|
||||
m_specs.format = AUD_FORMAT_S16;
|
||||
else
|
||||
AUD_THROW(AUD_ERROR_SDL);
|
||||
|
||||
m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
|
||||
m_mixer->setSpecs(m_specs);
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
AUD_SDLDevice::~AUD_SDLDevice()
|
||||
{
|
||||
lock();
|
||||
SDL_CloseAudio();
|
||||
unlock();
|
||||
|
||||
destroy();
|
||||
}
|
||||
|
||||
void AUD_SDLDevice::SDLmix(sample_t* buffer, int length)
|
||||
{
|
||||
mix(buffer, length/AUD_SAMPLE_SIZE(m_specs));
|
||||
}
|
||||
|
||||
void AUD_SDLDevice::playing(bool playing)
|
||||
{
|
||||
SDL_PauseAudio(playing ? 0 : 1);
|
||||
}
|
||||
63
intern/audaspace/SDL/AUD_SDLDevice.h
Normal file
63
intern/audaspace/SDL/AUD_SDLDevice.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLDEVICE
|
||||
#define AUD_SDLDEVICE
|
||||
|
||||
#include "AUD_SoftwareDevice.h"
|
||||
|
||||
/**
|
||||
* This device plays back through SDL, the simple direct media layer.
|
||||
*/
|
||||
class AUD_SDLDevice : public AUD_SoftwareDevice
|
||||
{
|
||||
protected:
|
||||
virtual void playing(bool playing);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Opens the SDL audio device for playback.
|
||||
* \param specs The wanted audio specification.
|
||||
* \param buffersize The size of the internal buffer.
|
||||
* \note The specification really used for opening the device may differ.
|
||||
* \exception AUD_Exception Thrown if the audio device cannot be opened.
|
||||
*/
|
||||
AUD_SDLDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
/**
|
||||
* Closes the SDL audio device.
|
||||
*/
|
||||
virtual ~AUD_SDLDevice();
|
||||
|
||||
/**
|
||||
* Mixes the next bytes into the buffer.
|
||||
* \param buffer The target buffer.
|
||||
* \param length The length in bytes to be filled.
|
||||
* \warning This function shall not be called from outside!
|
||||
*/
|
||||
void SDLmix(sample_t* buffer, int length);
|
||||
};
|
||||
|
||||
#endif //AUD_SDLDEVICE
|
||||
83
intern/audaspace/SDL/AUD_SDLMixer.cpp
Normal file
83
intern/audaspace/SDL/AUD_SDLMixer.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMixer.h"
|
||||
#include "AUD_SDLMixerFactory.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
AUD_SDLMixer::AUD_SDLMixer()
|
||||
{
|
||||
m_factory = NULL;
|
||||
}
|
||||
|
||||
AUD_SDLMixer::~AUD_SDLMixer()
|
||||
{
|
||||
if(m_factory)
|
||||
{
|
||||
delete m_factory; AUD_DELETE("factory")
|
||||
}
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader)
|
||||
{
|
||||
m_factory->setReader(reader);
|
||||
return m_factory->createReader();
|
||||
}
|
||||
|
||||
void AUD_SDLMixer::setSpecs(AUD_Specs specs)
|
||||
{
|
||||
m_samplesize = AUD_SAMPLE_SIZE(specs);
|
||||
if(m_factory)
|
||||
{
|
||||
delete m_factory; AUD_DELETE("factory")
|
||||
}
|
||||
m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory")
|
||||
}
|
||||
|
||||
void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length,
|
||||
float volume)
|
||||
{
|
||||
AUD_SDLMixerBuffer buf;
|
||||
buf.buffer = buffer;
|
||||
buf.length = length;
|
||||
buf.volume = volume;
|
||||
m_buffers.push_back(buf);
|
||||
}
|
||||
|
||||
void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume)
|
||||
{
|
||||
AUD_SDLMixerBuffer buf;
|
||||
|
||||
while(!m_buffers.empty())
|
||||
{
|
||||
buf = m_buffers.front();
|
||||
m_buffers.pop_front();
|
||||
SDL_MixAudio((Uint8*)buffer,
|
||||
(Uint8*)buf.buffer,
|
||||
buf.length * m_samplesize,
|
||||
(int)(SDL_MIX_MAXVOLUME * volume * buf.volume));
|
||||
}
|
||||
}
|
||||
76
intern/audaspace/SDL/AUD_SDLMixer.h
Normal file
76
intern/audaspace/SDL/AUD_SDLMixer.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMIXER
|
||||
#define AUD_SDLMIXER
|
||||
|
||||
#include "AUD_IMixer.h"
|
||||
class AUD_SDLMixerFactory;
|
||||
#include <list>
|
||||
|
||||
struct AUD_SDLMixerBuffer
|
||||
{
|
||||
sample_t* buffer;
|
||||
int length;
|
||||
float volume;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is able to mix audiosignals with the help of SDL.
|
||||
*/
|
||||
class AUD_SDLMixer : public AUD_IMixer
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The mixer factory that prepares all readers for superposition.
|
||||
*/
|
||||
AUD_SDLMixerFactory* m_factory;
|
||||
|
||||
/**
|
||||
* The list of buffers to superpose.
|
||||
*/
|
||||
std::list<AUD_SDLMixerBuffer> m_buffers;
|
||||
|
||||
/**
|
||||
* The size of an output sample.
|
||||
*/
|
||||
int m_samplesize;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates the mixer.
|
||||
*/
|
||||
AUD_SDLMixer();
|
||||
|
||||
virtual ~AUD_SDLMixer();
|
||||
|
||||
virtual AUD_IReader* prepare(AUD_IReader* reader);
|
||||
virtual void setSpecs(AUD_Specs specs);
|
||||
virtual void add(sample_t* buffer, AUD_Specs specs, int length,
|
||||
float volume);
|
||||
virtual void superpose(sample_t* buffer, int length, float volume);
|
||||
};
|
||||
|
||||
#endif //AUD_SDLMIXER
|
||||
63
intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
Normal file
63
intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMixerFactory.h"
|
||||
#include "AUD_SDLMixerReader.h"
|
||||
|
||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
|
||||
AUD_MixerFactory(reader, specs) {}
|
||||
|
||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
|
||||
AUD_MixerFactory(factory, specs) {}
|
||||
|
||||
AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
|
||||
AUD_MixerFactory(specs) {}
|
||||
|
||||
AUD_IReader* AUD_SDLMixerFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
AUD_Specs specs = reader->getSpecs();
|
||||
if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader = new AUD_SDLMixerReader(reader, m_specs);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
// return 0 in case SDL cannot mix the source
|
||||
if(e.error != AUD_ERROR_SDL)
|
||||
throw;
|
||||
else
|
||||
reader = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
45
intern/audaspace/SDL/AUD_SDLMixerFactory.h
Normal file
45
intern/audaspace/SDL/AUD_SDLMixerFactory.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMIXERFACTORY
|
||||
#define AUD_SDLMIXERFACTORY
|
||||
|
||||
#include "AUD_MixerFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a resampling reader that uses SDL's resampling
|
||||
* functionality which unfortunately is very very very limited.
|
||||
*/
|
||||
class AUD_SDLMixerFactory : public AUD_MixerFactory
|
||||
{
|
||||
public:
|
||||
AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_SDLMixerFactory(AUD_Specs specs);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_SDLMIXERFACTORY
|
||||
214
intern/audaspace/SDL/AUD_SDLMixerReader.cpp
Normal file
214
intern/audaspace/SDL/AUD_SDLMixerReader.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMixerReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
inline Uint16 AUD_TO_SDL(AUD_SampleFormat format)
|
||||
{
|
||||
// SDL only supports 8 and 16 bit audio
|
||||
switch(format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
return AUDIO_U8;
|
||||
case AUD_FORMAT_S16:
|
||||
return AUDIO_S16SYS;
|
||||
default:
|
||||
AUD_THROW(AUD_ERROR_SDL);
|
||||
}
|
||||
}
|
||||
|
||||
// greatest common divisor
|
||||
inline int gcd(int a, int b)
|
||||
{
|
||||
int c;
|
||||
|
||||
// make sure a is the bigger
|
||||
if(b > a)
|
||||
{
|
||||
c = b;
|
||||
b = a;
|
||||
a = c;
|
||||
}
|
||||
|
||||
// greetings from Euclides
|
||||
while(b != 0)
|
||||
{
|
||||
c = a % b;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader,
|
||||
AUD_Specs specs)
|
||||
{
|
||||
if(reader == NULL)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
m_reader = reader;
|
||||
m_tspecs = specs;
|
||||
m_sspecs = reader->getSpecs();
|
||||
|
||||
try
|
||||
{
|
||||
// SDL only supports 8 and 16 bit sample formats
|
||||
if(SDL_BuildAudioCVT(&m_cvt,
|
||||
AUD_TO_SDL(m_sspecs.format),
|
||||
m_sspecs.channels,
|
||||
m_sspecs.rate,
|
||||
AUD_TO_SDL(specs.format),
|
||||
specs.channels,
|
||||
specs.rate) == -1)
|
||||
AUD_THROW(AUD_ERROR_SDL);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
throw;
|
||||
}
|
||||
|
||||
m_eor = false;
|
||||
m_rsposition = 0;
|
||||
m_rssize = 0;
|
||||
m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate);
|
||||
m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate;
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_SDLMixerReader::~AUD_SDLMixerReader()
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
delete m_rsbuffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
bool AUD_SDLMixerReader::isSeekable()
|
||||
{
|
||||
return m_reader->isSeekable();
|
||||
}
|
||||
|
||||
void AUD_SDLMixerReader::seek(int position)
|
||||
{
|
||||
m_reader->seek(position * m_ssize / m_tsize);
|
||||
m_eor = false;
|
||||
}
|
||||
|
||||
int AUD_SDLMixerReader::getLength()
|
||||
{
|
||||
return m_reader->getLength() * m_tsize / m_ssize;
|
||||
}
|
||||
|
||||
int AUD_SDLMixerReader::getPosition()
|
||||
{
|
||||
return m_reader->getPosition() * m_tsize / m_ssize;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_SDLMixerReader::getSpecs()
|
||||
{
|
||||
return m_tspecs;
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_SDLMixerReader::getType()
|
||||
{
|
||||
return m_reader->getType();
|
||||
}
|
||||
|
||||
bool AUD_SDLMixerReader::notify(AUD_Message &message)
|
||||
{
|
||||
return m_reader->notify(message);
|
||||
}
|
||||
|
||||
void AUD_SDLMixerReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// sample count for the target buffer without getting a shift
|
||||
int tns = length + m_tsize - length % m_tsize;
|
||||
// sample count for the source buffer without getting a shift
|
||||
int sns = tns * m_ssize / m_tsize;
|
||||
// target sample size
|
||||
int tss = AUD_SAMPLE_SIZE(m_tspecs);
|
||||
// source sample size
|
||||
int sss = AUD_SAMPLE_SIZE(m_sspecs);
|
||||
|
||||
// input is output buffer
|
||||
int buf_size = AUD_MAX(tns*tss, sns*sss);
|
||||
|
||||
// resize if necessary
|
||||
if(m_rsbuffer->getSize() < buf_size)
|
||||
m_rsbuffer->resize(buf_size, true);
|
||||
|
||||
if(m_buffer->getSize() < length*tss)
|
||||
m_buffer->resize(length*tss);
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
int size;
|
||||
int index = 0;
|
||||
sample_t* buf;
|
||||
|
||||
while(index < length)
|
||||
{
|
||||
if(m_rsposition == m_rssize)
|
||||
{
|
||||
// no more data
|
||||
if(m_eor)
|
||||
length = index;
|
||||
// mix
|
||||
else
|
||||
{
|
||||
// read from source
|
||||
size = sns;
|
||||
m_reader->read(size, buf);
|
||||
|
||||
// prepare
|
||||
m_cvt.buf = m_rsbuffer->getBuffer();
|
||||
m_cvt.len = size*sss;
|
||||
memcpy(m_cvt.buf, buf, size*sss);
|
||||
|
||||
// convert
|
||||
SDL_ConvertAudio(&m_cvt);
|
||||
|
||||
// end of reader
|
||||
if(size < sns)
|
||||
m_eor = true;
|
||||
|
||||
m_rsposition = 0;
|
||||
m_rssize = size * m_tsize / m_ssize;
|
||||
}
|
||||
}
|
||||
|
||||
// size to copy
|
||||
size = AUD_MIN(m_rssize-m_rsposition, length-index);
|
||||
|
||||
// copy
|
||||
memcpy(m_buffer->getBuffer() + index * tss,
|
||||
m_rsbuffer->getBuffer() + m_rsposition * tss,
|
||||
size*tss);
|
||||
m_rsposition += size;
|
||||
index += size;
|
||||
}
|
||||
}
|
||||
128
intern/audaspace/SDL/AUD_SDLMixerReader.h
Normal file
128
intern/audaspace/SDL/AUD_SDLMixerReader.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SDLMIXERREADER
|
||||
#define AUD_SDLMIXERREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
/**
|
||||
* This class mixes a sound source with help of the SDL library.
|
||||
* Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
|
||||
* well as resampling only 2^n sample rate relationships where n is a natural
|
||||
* number.
|
||||
* \warning Although SDL can only resample 2^n sample rate relationships, this
|
||||
* class doesn't check for compliance, so in case of other factors,
|
||||
* the behaviour is undefined.
|
||||
*/
|
||||
class AUD_SDLMixerReader : public AUD_IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The reader that is being mixed.
|
||||
*/
|
||||
AUD_IReader* m_reader;
|
||||
|
||||
/**
|
||||
* The current reading position in the resampling buffer.
|
||||
*/
|
||||
int m_rsposition;
|
||||
|
||||
/**
|
||||
* The count of mixed samples in the resampling buffer.
|
||||
*/
|
||||
int m_rssize;
|
||||
|
||||
/**
|
||||
* The smallest count of source samples to get a fractionless resampling
|
||||
* factor.
|
||||
*/
|
||||
int m_ssize;
|
||||
|
||||
/**
|
||||
* The smallest count of target samples to get a fractionless resampling
|
||||
* factor.
|
||||
*/
|
||||
int m_tsize;
|
||||
|
||||
/**
|
||||
* The sound output buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The resampling buffer.
|
||||
*/
|
||||
AUD_Buffer *m_rsbuffer;
|
||||
|
||||
/**
|
||||
* The target specification.
|
||||
*/
|
||||
AUD_Specs m_tspecs;
|
||||
|
||||
/**
|
||||
* The sample specification of the source.
|
||||
*/
|
||||
AUD_Specs m_sspecs;
|
||||
|
||||
/**
|
||||
* Saves whether the end of the source has been reached.
|
||||
*/
|
||||
bool m_eor;
|
||||
|
||||
/**
|
||||
* The SDL_AudioCVT structure used for resampling.
|
||||
*/
|
||||
SDL_AudioCVT m_cvt;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a resampling reader.
|
||||
* \param reader The reader to mix.
|
||||
* \param specs The target specification.
|
||||
* \exception AUD_Exception Thrown if the source specification cannot be
|
||||
* mixed to the target specification or if the reader is
|
||||
* NULL.
|
||||
*/
|
||||
AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs);
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
~AUD_SDLMixerReader();
|
||||
|
||||
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_SDLMIXERREADER
|
||||
41
intern/audaspace/SDL/Makefile
Normal file
41
intern/audaspace/SDL/Makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# $Id: Makefile 13161 2008-01-07 19:13:47Z hos $
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = SDLaudaspace
|
||||
DIR = $(OCGDIR)/intern/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += $(NAN_SDLCFLAGS)
|
||||
CPPFLAGS += -I../intern
|
||||
CPPFLAGS += -I..
|
||||
CPPFLAGS += -I.
|
||||
53
intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
Normal file
53
intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SRCResampleFactory.h"
|
||||
#include "AUD_SRCResampleReader.h"
|
||||
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_ResampleFactory(reader, specs) {}
|
||||
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs) :
|
||||
AUD_ResampleFactory(factory, specs) {}
|
||||
|
||||
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
|
||||
AUD_ResampleFactory(specs) {}
|
||||
|
||||
AUD_IReader* AUD_SRCResampleFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
if(reader->getSpecs().rate != m_specs.rate)
|
||||
{
|
||||
reader = new AUD_SRCResampleReader(reader, m_specs);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
46
intern/audaspace/SRC/AUD_SRCResampleFactory.h
Normal file
46
intern/audaspace/SRC/AUD_SRCResampleFactory.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SRCRESAMPLEFACTORY
|
||||
#define AUD_SRCRESAMPLEFACTORY
|
||||
|
||||
#include "AUD_ResampleFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a resampling reader that uses libsamplerate for
|
||||
* resampling.
|
||||
* \note The format of the input must be float.
|
||||
*/
|
||||
class AUD_SRCResampleFactory : public AUD_ResampleFactory
|
||||
{
|
||||
public:
|
||||
AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_SRCResampleFactory(AUD_Specs specs);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_SRCRESAMPLEFACTORY
|
||||
119
intern/audaspace/SRC/AUD_SRCResampleReader.cpp
Normal file
119
intern/audaspace/SRC/AUD_SRCResampleReader.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SRCResampleReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
static long src_callback(void *cb_data, float **data)
|
||||
{
|
||||
return ((AUD_SRCResampleReader*)cb_data)->doCallback(data);
|
||||
}
|
||||
|
||||
AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
m_sspecs = reader->getSpecs();
|
||||
|
||||
if(m_sspecs.format != AUD_FORMAT_FLOAT32)
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
}
|
||||
|
||||
m_tspecs = specs;
|
||||
m_tspecs.channels = m_sspecs.channels;
|
||||
m_tspecs.format = m_sspecs.format;
|
||||
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
|
||||
|
||||
int error;
|
||||
m_src = src_callback_new(src_callback,
|
||||
SRC_SINC_MEDIUM_QUALITY,
|
||||
m_sspecs.channels,
|
||||
&error,
|
||||
this);
|
||||
|
||||
if(!m_src)
|
||||
{
|
||||
// XXX printf("%s\n", src_strerror(error));
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
}
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_SRCResampleReader::~AUD_SRCResampleReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
|
||||
src_delete(m_src);
|
||||
}
|
||||
|
||||
long AUD_SRCResampleReader::doCallback(float** data)
|
||||
{
|
||||
int length = m_buffer->getSize() / 4 / m_tspecs.channels;
|
||||
sample_t* buffer;
|
||||
|
||||
m_reader->read(length, buffer);
|
||||
|
||||
*data = (float*)buffer;
|
||||
return length;
|
||||
}
|
||||
|
||||
void AUD_SRCResampleReader::seek(int position)
|
||||
{
|
||||
m_reader->seek(position / m_factor);
|
||||
src_reset(m_src);
|
||||
}
|
||||
|
||||
int AUD_SRCResampleReader::getLength()
|
||||
{
|
||||
return m_reader->getLength() * m_factor;
|
||||
}
|
||||
|
||||
int AUD_SRCResampleReader::getPosition()
|
||||
{
|
||||
return m_reader->getPosition() * m_factor;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_SRCResampleReader::getSpecs()
|
||||
{
|
||||
return m_tspecs;
|
||||
}
|
||||
|
||||
void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
if(m_buffer->getSize() < length * m_tspecs.channels * 4)
|
||||
m_buffer->resize(length * m_tspecs.channels * 4);
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
|
||||
length = src_callback_read(m_src, m_factor, length, (float*)buffer);
|
||||
}
|
||||
102
intern/audaspace/SRC/AUD_SRCResampleReader.h
Normal file
102
intern/audaspace/SRC/AUD_SRCResampleReader.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SRCRESAMPLEREADER
|
||||
#define AUD_SRCRESAMPLEREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
/**
|
||||
* This class mixes a sound source with help of the SDL library.
|
||||
* Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
|
||||
* well as resampling only 2^n sample rate relationships where n is a natural
|
||||
* number.
|
||||
* \warning Although SDL can only resample 2^n sample rate relationships, this
|
||||
* class doesn't check for compliance, so in case of other factors,
|
||||
* the behaviour is undefined.
|
||||
*/
|
||||
class AUD_SRCResampleReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The resampling factor.
|
||||
*/
|
||||
double m_factor;
|
||||
|
||||
/**
|
||||
* The sound output buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The target specification.
|
||||
*/
|
||||
AUD_Specs m_tspecs;
|
||||
|
||||
/**
|
||||
* The sample specification of the source.
|
||||
*/
|
||||
AUD_Specs m_sspecs;
|
||||
|
||||
/**
|
||||
* The src state structure.
|
||||
*/
|
||||
SRC_STATE* m_src;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a resampling reader.
|
||||
* \param reader The reader to mix.
|
||||
* \param specs The target specification.
|
||||
* \exception AUD_Exception Thrown if the source specification cannot be
|
||||
* mixed to the target specification or if the reader is
|
||||
* NULL.
|
||||
*/
|
||||
AUD_SRCResampleReader(AUD_IReader* reader, AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
~AUD_SRCResampleReader();
|
||||
|
||||
/**
|
||||
* The callback function for SRC.
|
||||
* \warning Do not call!
|
||||
* \param data The pointer to the float data.
|
||||
* \return The count of samples in the float data.
|
||||
*/
|
||||
long doCallback(float** data);
|
||||
|
||||
virtual void seek(int position);
|
||||
virtual int getLength();
|
||||
virtual int getPosition();
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_SRCRESAMPLEREADER
|
||||
88
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
Normal file
88
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FFMPEGFactory.h"
|
||||
#include "AUD_FFMPEGReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
AUD_FFMPEGFactory::AUD_FFMPEGFactory(const char* filename)
|
||||
{
|
||||
if(filename != 0)
|
||||
{
|
||||
m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
|
||||
strcpy(m_filename, filename);
|
||||
}
|
||||
else
|
||||
m_filename = 0;
|
||||
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); AUD_NEW("buffer")
|
||||
m_size = size;
|
||||
memcpy(m_buffer, buffer, size);
|
||||
}
|
||||
|
||||
AUD_FFMPEGFactory::~AUD_FFMPEGFactory()
|
||||
{
|
||||
if(m_filename)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
76
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
Normal file
76
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FFMPEGFACTORY
|
||||
#define AUD_FFMPEGFACTORY
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
|
||||
/**
|
||||
* This factory reads a sound file via ffmpeg.
|
||||
* \warning Notice that the needed formats and codecs have to be registered
|
||||
* for ffmpeg before this class can be used.
|
||||
*/
|
||||
class AUD_FFMPEGFactory : public AUD_IFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The filename of the sound source file.
|
||||
*/
|
||||
char* m_filename;
|
||||
|
||||
/**
|
||||
* The buffer to read from.
|
||||
*/
|
||||
unsigned char* m_buffer;
|
||||
|
||||
/**
|
||||
* The size of the buffer.
|
||||
*/
|
||||
int m_size;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new factory.
|
||||
* \param filename The sound file path.
|
||||
*/
|
||||
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();
|
||||
};
|
||||
|
||||
#endif //AUD_FFMPEGFACTORY
|
||||
388
intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
Normal file
388
intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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 *****
|
||||
*/
|
||||
|
||||
// needed for INT64_C
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
|
||||
#include "AUD_FFMPEGReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
// This function transforms a FFMPEG SampleFormat to or own sample format
|
||||
static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
|
||||
{
|
||||
switch(fmt)
|
||||
{
|
||||
case SAMPLE_FMT_U8:
|
||||
return AUD_FORMAT_U8;
|
||||
case SAMPLE_FMT_S16:
|
||||
return AUD_FORMAT_S16;
|
||||
case SAMPLE_FMT_S32:
|
||||
return AUD_FORMAT_S32;
|
||||
case SAMPLE_FMT_FLT:
|
||||
return AUD_FORMAT_FLOAT32;
|
||||
case SAMPLE_FMT_DBL:
|
||||
return AUD_FORMAT_FLOAT64;
|
||||
default:
|
||||
return AUD_FORMAT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
|
||||
{
|
||||
// save packet parameters
|
||||
uint8_t *audio_pkg_data = packet->data;
|
||||
int audio_pkg_size = packet->size;
|
||||
|
||||
int buf_size = buffer->getSize();
|
||||
int buf_pos = 0;
|
||||
|
||||
int read_length, data_size;
|
||||
|
||||
// as long as there is still data in the package
|
||||
while(audio_pkg_size > 0)
|
||||
{
|
||||
// resize buffer if needed
|
||||
if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
|
||||
{
|
||||
buffer->resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
|
||||
buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
}
|
||||
|
||||
// read samples from the packet
|
||||
data_size = buf_size - buf_pos;
|
||||
/*read_length = avcodec_decode_audio3(m_codecCtx,
|
||||
(int16_t*)(buffer->getBuffer()+buf_pos),
|
||||
&data_size,
|
||||
packet);*/
|
||||
read_length = avcodec_decode_audio2(m_codecCtx,
|
||||
(int16_t*)(buffer->getBuffer()+buf_pos),
|
||||
&data_size,
|
||||
audio_pkg_data,
|
||||
audio_pkg_size);
|
||||
|
||||
buf_pos += data_size;
|
||||
|
||||
// read error, next packet!
|
||||
if(read_length < 0)
|
||||
break;
|
||||
|
||||
// move packet parameters
|
||||
audio_pkg_data += read_length;
|
||||
audio_pkg_size -= read_length;
|
||||
}
|
||||
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
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)
|
||||
AUD_THROW(AUD_ERROR_FILE);
|
||||
|
||||
try
|
||||
{
|
||||
if(av_find_stream_info(m_formatCtx)<0)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG);
|
||||
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
||||
// XXX this prints file information to stdout:
|
||||
//dump_format(m_formatCtx, 0, filename, 0);
|
||||
|
||||
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;
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
av_close_input_file(m_formatCtx);
|
||||
throw;
|
||||
}
|
||||
|
||||
// last but not least if there hasn't been any error, create the buffers
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
|
||||
AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_FFMPEGReader::AUD_FFMPEGReader(unsigned char* buffer, int size)
|
||||
{
|
||||
m_position = 0;
|
||||
m_pkgbuf_left = 0;
|
||||
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
|
||||
AUD_NEW("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);
|
||||
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
||||
// XXX this prints stream information to stdout:
|
||||
//dump_format(m_formatCtx, 0, NULL, 0);
|
||||
|
||||
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;
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
av_close_input_stream(m_formatCtx);
|
||||
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
|
||||
throw;
|
||||
}
|
||||
|
||||
// last but not least if there hasn't been any error, create the buffers
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
|
||||
AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_FFMPEGReader::~AUD_FFMPEGReader()
|
||||
{
|
||||
avcodec_close(m_codecCtx);
|
||||
|
||||
if(m_byteiocontext)
|
||||
{
|
||||
av_close_input_stream(m_formatCtx);
|
||||
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
|
||||
}
|
||||
else
|
||||
av_close_input_file(m_formatCtx);
|
||||
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
delete m_pkgbuf; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
bool AUD_FFMPEGReader::isSeekable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AUD_FFMPEGReader::seek(int position)
|
||||
{
|
||||
if(position >= 0)
|
||||
{
|
||||
// a value < 0 tells us that seeking failed
|
||||
if(av_seek_frame(m_formatCtx,
|
||||
-1,
|
||||
(uint64_t)(((uint64_t)position *
|
||||
(uint64_t)AV_TIME_BASE) /
|
||||
(uint64_t)m_specs.rate),
|
||||
AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
|
||||
{
|
||||
avcodec_flush_buffers(m_codecCtx);
|
||||
m_position = position;
|
||||
|
||||
AVPacket packet;
|
||||
bool search = true;
|
||||
|
||||
while(search && av_read_frame(m_formatCtx, &packet) >= 0)
|
||||
{
|
||||
// is it a frame from the audio stream?
|
||||
if(packet.stream_index == m_stream)
|
||||
{
|
||||
// decode the package
|
||||
m_pkgbuf_left = decode(&packet, m_pkgbuf);
|
||||
search = false;
|
||||
|
||||
// check position
|
||||
if(packet.pts != AV_NOPTS_VALUE)
|
||||
{
|
||||
// calculate real position, and read to frame!
|
||||
m_position = packet.pts *
|
||||
av_q2d(m_formatCtx->streams[m_stream]->time_base) *
|
||||
m_specs.rate;
|
||||
|
||||
if(m_position < position)
|
||||
{
|
||||
sample_t* buf;
|
||||
int length = position - m_position;
|
||||
read(length, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Seeking failed, do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_FFMPEGReader::getLength()
|
||||
{
|
||||
// return approximated remaning size
|
||||
return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
|
||||
/ AV_TIME_BASE)-m_position;
|
||||
}
|
||||
|
||||
int AUD_FFMPEGReader::getPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_FFMPEGReader::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_FFMPEGReader::getType()
|
||||
{
|
||||
return AUD_TYPE_STREAM;
|
||||
}
|
||||
|
||||
bool AUD_FFMPEGReader::notify(AUD_Message &message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// read packages and decode them
|
||||
AVPacket packet;
|
||||
int data_size = 0;
|
||||
int pkgbuf_size = m_pkgbuf->getSize();
|
||||
int pkgbuf_pos;
|
||||
int left = length;
|
||||
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();
|
||||
pkgbuf_pos = m_pkgbuf_left;
|
||||
m_pkgbuf_left = 0;
|
||||
|
||||
// there may still be data in the buffer from the last call
|
||||
if(pkgbuf_pos > 0)
|
||||
{
|
||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||
memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
|
||||
buffer += data_size;
|
||||
left -= data_size/sample_size;
|
||||
}
|
||||
|
||||
// for each frame read as long as there isn't enough data already
|
||||
while((left > 0) && (av_read_frame(m_formatCtx, &packet) >= 0))
|
||||
{
|
||||
// is it a frame from the audio stream?
|
||||
if(packet.stream_index == m_stream)
|
||||
{
|
||||
// decode the package
|
||||
pkgbuf_pos = decode(&packet, m_pkgbuf);
|
||||
|
||||
// copy to output buffer
|
||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||
memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
|
||||
buffer += data_size;
|
||||
left -= data_size/sample_size;
|
||||
}
|
||||
av_free_packet(&packet);
|
||||
}
|
||||
// read more data than necessary?
|
||||
if(pkgbuf_pos > data_size)
|
||||
{
|
||||
m_pkgbuf_left = pkgbuf_pos-data_size;
|
||||
memmove(m_pkgbuf->getBuffer(), m_pkgbuf->getBuffer()+data_size,
|
||||
pkgbuf_pos-data_size);
|
||||
}
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
|
||||
if(left > 0)
|
||||
length -= left;
|
||||
m_position += length;
|
||||
}
|
||||
133
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
Normal file
133
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FFMPEGREADER
|
||||
#define AUD_FFMPEGREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
class AUD_Buffer;
|
||||
struct AVCodecContext;
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
/**
|
||||
* This class reads a sound file via ffmpeg.
|
||||
* \warning Seeking may not be accurate! Moreover the position is updated after
|
||||
* a buffer reading call. So calling getPosition right after seek
|
||||
* normally results in a wrong value.
|
||||
* \warning Playback of an ogg with some outdated ffmpeg versions results in a
|
||||
* segfault on windows.
|
||||
*/
|
||||
class AUD_FFMPEGReader : public AUD_IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The current position in samples.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The specification of the audio data.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* The buffer for package reading.
|
||||
*/
|
||||
AUD_Buffer *m_pkgbuf;
|
||||
|
||||
/**
|
||||
* The count of samples still available from the last read package.
|
||||
*/
|
||||
int m_pkgbuf_left;
|
||||
|
||||
/**
|
||||
* The AVFormatContext structure for using ffmpeg.
|
||||
*/
|
||||
AVFormatContext* m_formatCtx;
|
||||
|
||||
/**
|
||||
* The AVCodecContext structure for using ffmpeg.
|
||||
*/
|
||||
AVCodecContext* m_codecCtx;
|
||||
|
||||
/**
|
||||
* The ByteIOContext to read the data from.
|
||||
*/
|
||||
ByteIOContext* m_byteiocontext;
|
||||
|
||||
/**
|
||||
* The stream ID in the file.
|
||||
*/
|
||||
int m_stream;
|
||||
|
||||
/**
|
||||
* Decodes a packet into the given buffer.
|
||||
* \param packet The AVPacket to decode.
|
||||
* \param buffer The target buffer.
|
||||
* \return The count of read bytes.
|
||||
*/
|
||||
int decode(AVPacket* packet, AUD_Buffer* buffer);
|
||||
|
||||
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 ffmpeg.
|
||||
*/
|
||||
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();
|
||||
|
||||
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_FFMPEGREADER
|
||||
41
intern/audaspace/ffmpeg/Makefile
Normal file
41
intern/audaspace/ffmpeg/Makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# $Id: Makefile 13161 2008-01-07 19:13:47Z hos $
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = ffmpegaudaspace
|
||||
DIR = $(OCGDIR)/intern/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += $(NAN_FFMPEGCFLAGS)
|
||||
CPPFLAGS += -I../intern
|
||||
CPPFLAGS += -I..
|
||||
CPPFLAGS += -I.
|
||||
67
intern/audaspace/intern/AUD_Buffer.cpp
Normal file
67
intern/audaspace/intern/AUD_Buffer.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_Buffer.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
|
||||
|
||||
AUD_Buffer::AUD_Buffer(int size)
|
||||
{
|
||||
m_size = size;
|
||||
m_buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_Buffer::~AUD_Buffer()
|
||||
{
|
||||
free(m_buffer); AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
sample_t* AUD_Buffer::getBuffer()
|
||||
{
|
||||
return AUD_ALIGN(m_buffer);
|
||||
}
|
||||
|
||||
int AUD_Buffer::getSize()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void AUD_Buffer::resize(int size, bool keep)
|
||||
{
|
||||
sample_t* buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
|
||||
|
||||
// copy old data over if wanted
|
||||
if(keep)
|
||||
memcpy(AUD_ALIGN(buffer), AUD_ALIGN(m_buffer), AUD_MIN(size, m_size));
|
||||
|
||||
free(m_buffer); AUD_DELETE("buffer")
|
||||
|
||||
m_buffer = buffer;
|
||||
m_size = size;
|
||||
}
|
||||
75
intern/audaspace/intern/AUD_Buffer.h
Normal file
75
intern/audaspace/intern/AUD_Buffer.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_BUFFER
|
||||
#define AUD_BUFFER
|
||||
|
||||
#include "AUD_Space.h"
|
||||
|
||||
/**
|
||||
* This class is a simple buffer in RAM which is 16 Byte aligned and provides
|
||||
* resize functionality.
|
||||
*/
|
||||
class AUD_Buffer
|
||||
{
|
||||
private:
|
||||
/// The size of the buffer in bytes.
|
||||
int m_size;
|
||||
|
||||
/// The pointer to the buffer memory.
|
||||
sample_t* m_buffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new buffer.
|
||||
* \param size The size of the buffer in bytes.
|
||||
*/
|
||||
AUD_Buffer(int size = 0);
|
||||
|
||||
/**
|
||||
* Destroys the buffer.
|
||||
*/
|
||||
~AUD_Buffer();
|
||||
|
||||
/**
|
||||
* Returns the pointer to the buffer in memory.
|
||||
*/
|
||||
sample_t* getBuffer();
|
||||
|
||||
/**
|
||||
* Returns the size of the buffer in bytes.
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
/**
|
||||
* Resizes the buffer.
|
||||
* \param size The new size of the buffer, measured in bytes.
|
||||
* \param keep Whether to keep the old data. If the new buffer is smaller,
|
||||
* the data at the end will be lost.
|
||||
*/
|
||||
void resize(int size, bool keep = false);
|
||||
};
|
||||
|
||||
#endif //AUD_BUFFER
|
||||
91
intern/audaspace/intern/AUD_BufferReader.cpp
Normal file
91
intern/audaspace/intern/AUD_BufferReader.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_BufferReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_BufferReader::AUD_BufferReader(AUD_Reference<AUD_Buffer> buffer,
|
||||
AUD_Specs specs)
|
||||
{
|
||||
m_position = 0;
|
||||
m_buffer = buffer;
|
||||
m_specs = specs;
|
||||
}
|
||||
|
||||
bool AUD_BufferReader::isSeekable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AUD_BufferReader::seek(int position)
|
||||
{
|
||||
if(position < 0)
|
||||
m_position = 0;
|
||||
else if(position > m_buffer.get()->getSize() / AUD_SAMPLE_SIZE(m_specs))
|
||||
m_position = m_buffer.get()->getSize() / AUD_SAMPLE_SIZE(m_specs);
|
||||
else
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
int AUD_BufferReader::getLength()
|
||||
{
|
||||
return m_buffer.get()->getSize()/AUD_SAMPLE_SIZE(m_specs);
|
||||
}
|
||||
|
||||
int AUD_BufferReader::getPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_BufferReader::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_BufferReader::getType()
|
||||
{
|
||||
return AUD_TYPE_BUFFER;
|
||||
}
|
||||
|
||||
bool AUD_BufferReader::notify(AUD_Message &message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_BufferReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
||||
|
||||
buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
|
||||
|
||||
// in case the end of the buffer is reach
|
||||
if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
|
||||
length = m_buffer.get()->getSize()/sample_size-m_position;
|
||||
|
||||
if(length < 0)
|
||||
length = 0;
|
||||
m_position += length;
|
||||
}
|
||||
74
intern/audaspace/intern/AUD_BufferReader.h
Normal file
74
intern/audaspace/intern/AUD_BufferReader.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_BUFFERREADER
|
||||
#define AUD_BUFFERREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_Reference.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class represents a simple reader from a buffer that exists in memory.
|
||||
* \warning Notice that the buffer used for creating the reader must exist as
|
||||
* long as the reader exists.
|
||||
*/
|
||||
class AUD_BufferReader : public AUD_IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The current position in the buffer.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* The buffer that is read.
|
||||
*/
|
||||
AUD_Reference<AUD_Buffer> m_buffer;
|
||||
|
||||
/**
|
||||
* The specification of the sample data in the buffer.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new buffer reader.
|
||||
* \param buffer The buffer to read from.
|
||||
* \param specs The specification of the sample data in the buffer.
|
||||
*/
|
||||
AUD_BufferReader(AUD_Reference<AUD_Buffer> buffer, AUD_Specs specs);
|
||||
|
||||
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_BUFFERREADER
|
||||
558
intern/audaspace/intern/AUD_C-API.cpp
Normal file
558
intern/audaspace/intern/AUD_C-API.cpp
Normal file
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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 *****
|
||||
*/
|
||||
|
||||
/*#define WITH_SDL
|
||||
#define WITH_FFMPEG
|
||||
#define WITH_OPENAL*/
|
||||
|
||||
#include "AUD_NULLDevice.h"
|
||||
#include "AUD_I3DDevice.h"
|
||||
#include "AUD_StreamBufferFactory.h"
|
||||
#include "AUD_DelayFactory.h"
|
||||
#include "AUD_LimiterFactory.h"
|
||||
#include "AUD_PingPongFactory.h"
|
||||
#include "AUD_LoopFactory.h"
|
||||
#include "AUD_ReadDevice.h"
|
||||
#include "AUD_SourceCaps.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
#ifdef WITH_SDL
|
||||
#include "AUD_SDLDevice.h"
|
||||
#include "AUD_FloatMixer.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENAL
|
||||
#include "AUD_OpenALDevice.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FFMPEG
|
||||
#include "AUD_FFMPEGFactory.h"
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
typedef AUD_IFactory AUD_Sound;
|
||||
typedef AUD_ReadDevice AUD_Device;
|
||||
|
||||
#define AUD_CAPI_IMPLEMENTATION
|
||||
#include "AUD_C-API.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
static AUD_IDevice* AUD_device = NULL;
|
||||
static int AUD_available_devices[3];
|
||||
static AUD_I3DDevice* AUD_3ddevice = NULL;
|
||||
|
||||
int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
|
||||
{
|
||||
#ifdef WITH_FFMPEG
|
||||
av_register_all();
|
||||
#endif
|
||||
AUD_IDevice* dev = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
switch(device)
|
||||
{
|
||||
case AUD_NULL_DEVICE:
|
||||
dev = new AUD_NULLDevice();
|
||||
break;
|
||||
#ifdef WITH_SDL
|
||||
case AUD_SDL_DEVICE:
|
||||
{
|
||||
dev = new AUD_SDLDevice(specs, buffersize);
|
||||
AUD_FloatMixer* mixer = new AUD_FloatMixer();
|
||||
((AUD_SDLDevice*)dev)->setMixer(mixer);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
case AUD_OPENAL_DEVICE:
|
||||
dev = new AUD_OpenALDevice(specs, buffersize);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if(AUD_device)
|
||||
AUD_exit();
|
||||
|
||||
AUD_device = dev;
|
||||
if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE))
|
||||
AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int* AUD_enumDevices()
|
||||
{
|
||||
int i = 0;
|
||||
#ifdef WITH_SDL
|
||||
AUD_available_devices[i++] = AUD_SDL_DEVICE;
|
||||
#endif
|
||||
#ifdef WITH_OPENAL
|
||||
AUD_available_devices[i++] = AUD_OPENAL_DEVICE;
|
||||
#endif
|
||||
AUD_available_devices[i++] = AUD_NULL_DEVICE;
|
||||
return AUD_available_devices;
|
||||
}
|
||||
|
||||
void AUD_exit()
|
||||
{
|
||||
assert(AUD_device);
|
||||
delete AUD_device;
|
||||
AUD_device = NULL;
|
||||
AUD_3ddevice = NULL;
|
||||
}
|
||||
|
||||
void AUD_lock()
|
||||
{
|
||||
assert(AUD_device);
|
||||
AUD_device->lock();
|
||||
}
|
||||
|
||||
void AUD_unlock()
|
||||
{
|
||||
assert(AUD_device);
|
||||
AUD_device->unlock();
|
||||
}
|
||||
|
||||
AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
AUD_IReader* reader = sound->createReader();
|
||||
|
||||
AUD_SoundInfo info;
|
||||
|
||||
if(reader)
|
||||
{
|
||||
info.specs = reader->getSpecs();
|
||||
info.length = reader->getLength() / (float) info.specs.rate;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.specs.channels = AUD_CHANNELS_INVALID;
|
||||
info.specs.format = AUD_FORMAT_INVALID;
|
||||
info.specs.rate = AUD_RATE_INVALID;
|
||||
info.length = 0.0;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_load(const char* filename)
|
||||
{
|
||||
assert(filename);
|
||||
#ifdef WITH_FFMPEG
|
||||
return new AUD_FFMPEGFactory(filename);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
|
||||
{
|
||||
assert(buffer);
|
||||
#ifdef WITH_FFMPEG
|
||||
return new AUD_FFMPEGFactory(buffer, size);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
return new AUD_StreamBufferFactory(sound);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
return new AUD_DelayFactory(sound, delay);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
return new AUD_LimiterFactory(sound, start, end);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
return new AUD_PingPongFactory(sound);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_loopSound(AUD_Sound* sound)
|
||||
{
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
return new AUD_LoopFactory(sound);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_stopLoop(AUD_Handle* handle)
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
AUD_Message message;
|
||||
message.type = AUD_MSG_LOOP;
|
||||
message.loopcount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
return AUD_device->sendMessage(handle, message);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_unload(AUD_Sound* sound)
|
||||
{
|
||||
assert(sound);
|
||||
delete sound;
|
||||
}
|
||||
|
||||
AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
|
||||
{
|
||||
assert(AUD_device);
|
||||
assert(sound);
|
||||
try
|
||||
{
|
||||
return AUD_device->play(sound, keep);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_pause(AUD_Handle* handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
return AUD_device->pause(handle);
|
||||
}
|
||||
|
||||
int AUD_resume(AUD_Handle* handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
return AUD_device->resume(handle);
|
||||
}
|
||||
|
||||
int AUD_stop(AUD_Handle* handle)
|
||||
{
|
||||
if(AUD_device)
|
||||
return AUD_device->stop(handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setKeep(AUD_Handle* handle, int keep)
|
||||
{
|
||||
assert(AUD_device);
|
||||
return AUD_device->setKeep(handle, keep);
|
||||
}
|
||||
|
||||
int AUD_seek(AUD_Handle* handle, float seekTo)
|
||||
{
|
||||
assert(AUD_device);
|
||||
return AUD_device->seek(handle, seekTo);
|
||||
}
|
||||
|
||||
float AUD_getPosition(AUD_Handle* handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
return AUD_device->getPosition(handle);
|
||||
}
|
||||
|
||||
AUD_Status AUD_getStatus(AUD_Handle* handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
return AUD_device->getStatus(handle);
|
||||
}
|
||||
|
||||
AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep)
|
||||
{
|
||||
assert(AUD_device);
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->play3D(sound, keep);
|
||||
else
|
||||
return AUD_device->play(sound, keep);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_updateListener(AUD_3DData* data)
|
||||
{
|
||||
assert(AUD_device);
|
||||
assert(data);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->updateListener(*data);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_set3DSetting(AUD_3DSetting setting, float value)
|
||||
{
|
||||
assert(AUD_device);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->setSetting(setting, value);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float AUD_get3DSetting(AUD_3DSetting setting)
|
||||
{
|
||||
assert(AUD_device);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->getSetting(setting);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
assert(data);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->updateSource(handle, *data);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_set3DSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting, float value)
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->setSourceSetting(handle, setting, value);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
|
||||
try
|
||||
{
|
||||
if(AUD_3ddevice)
|
||||
return AUD_3ddevice->getSourceSetting(handle, setting);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int AUD_setSoundVolume(AUD_Handle* handle, float volume)
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
AUD_SourceCaps caps;
|
||||
caps.handle = handle;
|
||||
caps.value = volume;
|
||||
|
||||
try
|
||||
{
|
||||
return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
|
||||
}
|
||||
catch(AUD_Exception e) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
AUD_SourceCaps caps;
|
||||
caps.handle = handle;
|
||||
caps.value = pitch;
|
||||
|
||||
try
|
||||
{
|
||||
return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps);
|
||||
}
|
||||
catch(AUD_Exception e) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AUD_Device* AUD_openReadDevice(AUD_Specs specs)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new AUD_ReadDevice(specs);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
|
||||
{
|
||||
assert(device);
|
||||
assert(sound);
|
||||
|
||||
try
|
||||
{
|
||||
return device->play(sound) != NULL;
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
|
||||
{
|
||||
assert(device);
|
||||
assert(buffer);
|
||||
|
||||
try
|
||||
{
|
||||
return device->read(buffer, length);
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_closeReadDevice(AUD_Device* device)
|
||||
{
|
||||
assert(device);
|
||||
|
||||
try
|
||||
{
|
||||
delete device;
|
||||
}
|
||||
catch(AUD_Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
125
intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
Normal file
125
intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ChannelMapperFactory.h"
|
||||
#include "AUD_ChannelMapperReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_MixerFactory(reader, specs)
|
||||
{
|
||||
memset(m_mapping, 0, sizeof(m_mapping));
|
||||
}
|
||||
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs) :
|
||||
AUD_MixerFactory(factory, specs)
|
||||
{
|
||||
memset(m_mapping, 0, sizeof(m_mapping));
|
||||
}
|
||||
|
||||
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
|
||||
AUD_MixerFactory(specs)
|
||||
{
|
||||
memset(m_mapping, 0, sizeof(m_mapping));
|
||||
}
|
||||
|
||||
AUD_ChannelMapperFactory::~AUD_ChannelMapperFactory()
|
||||
{
|
||||
for(int i = 1; i < 10; i++)
|
||||
deleteMapping(i);
|
||||
}
|
||||
|
||||
float** AUD_ChannelMapperFactory::getMapping(int ic)
|
||||
{
|
||||
ic--;
|
||||
if(ic > 8 || ic < 0)
|
||||
return 0;
|
||||
|
||||
if(m_mapping[ic])
|
||||
{
|
||||
int channels = -1;
|
||||
while(m_mapping[ic][++channels] != 0);
|
||||
if(channels != m_specs.channels)
|
||||
deleteMapping(ic+1);
|
||||
}
|
||||
|
||||
if(!m_mapping[ic])
|
||||
{
|
||||
int channels = m_specs.channels;
|
||||
|
||||
m_mapping[ic] = new float*[channels+1]; AUD_NEW("mapping")
|
||||
m_mapping[ic][channels] = 0;
|
||||
|
||||
for(int i = 0; i < channels; i++)
|
||||
{
|
||||
m_mapping[ic][i] = new float[ic+1]; AUD_NEW("mapping")
|
||||
for(int j = 0; j <= ic; j++)
|
||||
m_mapping[ic][i][j] = ((i == j) || (channels == 1) ||
|
||||
(ic == 0)) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return m_mapping[ic];
|
||||
}
|
||||
|
||||
void AUD_ChannelMapperFactory::deleteMapping(int ic)
|
||||
{
|
||||
ic--;
|
||||
if(ic > 8 || ic < 0)
|
||||
return;
|
||||
|
||||
if(m_mapping[ic])
|
||||
{
|
||||
for(int i = 0; 1; i++)
|
||||
{
|
||||
if(m_mapping[ic][i] != 0)
|
||||
{
|
||||
delete[] m_mapping[ic][i]; AUD_DELETE("mapping")
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
delete[] m_mapping[ic]; AUD_DELETE("mapping")
|
||||
m_mapping[ic] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_ChannelMapperFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
int ic = reader->getSpecs().channels;
|
||||
|
||||
reader = new AUD_ChannelMapperReader(reader, getMapping(ic));
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
65
intern/audaspace/intern/AUD_ChannelMapperFactory.h
Normal file
65
intern/audaspace/intern/AUD_ChannelMapperFactory.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_CHANNELMAPPERFACTORY
|
||||
#define AUD_CHANNELMAPPERFACTORY
|
||||
|
||||
#include "AUD_MixerFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a reader that maps a sound source's channels to a
|
||||
* specific output channel count.
|
||||
*/
|
||||
class AUD_ChannelMapperFactory : public AUD_MixerFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The mapping specification.
|
||||
*/
|
||||
float **m_mapping[9];
|
||||
|
||||
public:
|
||||
AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_ChannelMapperFactory(AUD_Specs specs);
|
||||
|
||||
virtual ~AUD_ChannelMapperFactory();
|
||||
|
||||
/**
|
||||
* Returns the mapping array for editing.
|
||||
* \param ic The count of input channels the array should have.
|
||||
* \note The count of output channels is read of the desired output specs.
|
||||
*/
|
||||
float** getMapping(int ic);
|
||||
|
||||
/**
|
||||
* Deletes the current channel mapping.
|
||||
*/
|
||||
void deleteMapping(int ic);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_CHANNELMAPPERFACTORY
|
||||
108
intern/audaspace/intern/AUD_ChannelMapperReader.cpp
Normal file
108
intern/audaspace/intern/AUD_ChannelMapperReader.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ChannelMapperReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
|
||||
float **mapping) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
m_specs = reader->getSpecs();
|
||||
|
||||
if(m_specs.format != AUD_FORMAT_FLOAT32)
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
}
|
||||
|
||||
int channels = -1;
|
||||
m_rch = m_specs.channels;
|
||||
while(mapping[++channels] != 0);
|
||||
|
||||
m_mapping = new float*[channels]; AUD_NEW("mapping")
|
||||
m_specs.channels = (AUD_Channels)channels;
|
||||
|
||||
float sum;
|
||||
int i;
|
||||
|
||||
while(channels--)
|
||||
{
|
||||
m_mapping[channels] = new float[m_rch]; AUD_NEW("mapping")
|
||||
sum = 0.0f;
|
||||
for(i=0; i < m_rch; i++)
|
||||
sum += mapping[channels][i];
|
||||
for(i=0; i < m_rch; i++)
|
||||
m_mapping[channels][i] = sum > 0.0 ? mapping[channels][i]/sum : 0.0;
|
||||
}
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
|
||||
{
|
||||
int channels = m_specs.channels;
|
||||
|
||||
while(channels--)
|
||||
{
|
||||
delete[] m_mapping[channels]; AUD_DELETE("mapping")
|
||||
}
|
||||
|
||||
delete[] m_mapping; AUD_DELETE("mapping")
|
||||
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
AUD_Specs AUD_ChannelMapperReader::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
m_reader->read(length, buffer);
|
||||
|
||||
int channels = m_specs.channels;
|
||||
|
||||
if(m_buffer->getSize() < length * 4 * channels)
|
||||
m_buffer->resize(length * 4 * channels);
|
||||
|
||||
float* in = (float*)buffer;
|
||||
float* out = (float*)m_buffer->getBuffer();
|
||||
float sum;
|
||||
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
for(int j = 0; j < channels; j++)
|
||||
{
|
||||
sum = 0;
|
||||
for(int k = 0; k < m_rch; k++)
|
||||
sum += m_mapping[j][k] * in[i * m_rch + k];
|
||||
out[i * channels + j] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
}
|
||||
76
intern/audaspace/intern/AUD_ChannelMapperReader.h
Normal file
76
intern/audaspace/intern/AUD_ChannelMapperReader.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_CHANNELMAPPERREADER
|
||||
#define AUD_CHANNELMAPPERREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class maps a sound source's channels to a specific output channel count.
|
||||
* \note The input sample format must be float.
|
||||
*/
|
||||
class AUD_ChannelMapperReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The sound output buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The output specification.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* The channel count of the reader.
|
||||
*/
|
||||
int m_rch;
|
||||
|
||||
/**
|
||||
* The mapping specification.
|
||||
*/
|
||||
float **m_mapping;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a channel mapper reader.
|
||||
* \param reader The reader to map.
|
||||
* \param mapping The mapping specification as two dimensional float array.
|
||||
* \exception AUD_Exception Thrown if the reader is NULL.
|
||||
*/
|
||||
AUD_ChannelMapperReader(AUD_IReader* reader, float **mapping);
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
~AUD_ChannelMapperReader();
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_CHANNELMAPPERREADER
|
||||
54
intern/audaspace/intern/AUD_ConverterFactory.cpp
Normal file
54
intern/audaspace/intern/AUD_ConverterFactory.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ConverterFactory.h"
|
||||
#include "AUD_ConverterReader.h"
|
||||
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs) :
|
||||
AUD_MixerFactory(reader, specs) {}
|
||||
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs) :
|
||||
AUD_MixerFactory(factory, specs) {}
|
||||
|
||||
AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
|
||||
AUD_MixerFactory(specs) {}
|
||||
|
||||
AUD_IReader* AUD_ConverterFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
if(reader != 0)
|
||||
{
|
||||
if(reader->getSpecs().format != m_specs.format)
|
||||
{
|
||||
reader = new AUD_ConverterReader(reader, m_specs);
|
||||
AUD_NEW("reader")
|
||||
}
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
45
intern/audaspace/intern/AUD_ConverterFactory.h
Normal file
45
intern/audaspace/intern/AUD_ConverterFactory.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_CONVERTERFACTORY
|
||||
#define AUD_CONVERTERFACTORY
|
||||
|
||||
#include "AUD_MixerFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a converter reader that is able to convert from one
|
||||
* audio format to another.
|
||||
*/
|
||||
class AUD_ConverterFactory : public AUD_MixerFactory
|
||||
{
|
||||
public:
|
||||
AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
AUD_ConverterFactory(AUD_Specs specs);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_CONVERTERFACTORY
|
||||
502
intern/audaspace/intern/AUD_ConverterFunctions.cpp
Normal file
502
intern/audaspace/intern/AUD_ConverterFunctions.cpp
Normal file
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ConverterFunctions.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#define AUD_U8_0 0x80
|
||||
#define AUD_S16_MAX 0x7FFF
|
||||
#define AUD_S16_MIN 0x8000
|
||||
#define AUD_S16_FLT 32768.0
|
||||
#define AUD_S32_MAX 0x7FFFFFFF
|
||||
#define AUD_S32_MIN 0x80000000
|
||||
#define AUD_S32_FLT 2147483648.0
|
||||
#define AUD_FLT_MAX 1.0
|
||||
#define AUD_FLT_MIN -1.0
|
||||
|
||||
void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* t = (int16_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
|
||||
}
|
||||
|
||||
void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
target[i*3] = source[i] - AUD_U8_0;
|
||||
target[i*3+1] = 0;
|
||||
target[i*3+2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
target[i*3+2] = source[i] - AUD_U8_0;
|
||||
target[i*3+1] = 0;
|
||||
target[i*3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* t = (int32_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
|
||||
}
|
||||
|
||||
void AUD_convert_u8_float(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
float* t = (float*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
|
||||
}
|
||||
|
||||
void AUD_convert_u8_double(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
double* t = (double*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
|
||||
}
|
||||
|
||||
void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
|
||||
}
|
||||
|
||||
void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
target[i*3] = s[i] >> 8 & 0xFF;
|
||||
target[i*3+1] = s[i] & 0xFF;
|
||||
target[i*3+2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
target[i*3+2] = s[i] >> 8 & 0xFF;
|
||||
target[i*3+1] = s[i] & 0xFF;
|
||||
target[i*3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
int32_t* t = (int32_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = ((int32_t)s[i]) << 16;
|
||||
}
|
||||
|
||||
void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
float* t = (float*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i] / AUD_S16_FLT;
|
||||
}
|
||||
|
||||
void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
double* t = (double*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i] / AUD_S16_FLT;
|
||||
}
|
||||
|
||||
void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
target[i] = source[i*3] ^ AUD_U8_0;
|
||||
}
|
||||
|
||||
void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
target[i] = source[i*3+2] ^ AUD_U8_0;
|
||||
}
|
||||
|
||||
void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* t = (int16_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = source[i*3] << 8 | source[i*3+1];
|
||||
}
|
||||
|
||||
void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* t = (int16_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = source[i*3+2] << 8 | source[i*3+1];
|
||||
}
|
||||
|
||||
void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
memcpy(target, source, length * 3);
|
||||
}
|
||||
|
||||
void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* t = (int32_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
|
||||
}
|
||||
|
||||
void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* t = (int32_t*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
|
||||
}
|
||||
|
||||
void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
float* t = (float*) target;
|
||||
int32_t s;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
|
||||
t[i] = s / AUD_S32_FLT;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
float* t = (float*) target;
|
||||
int32_t s;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
|
||||
t[i] = s / AUD_S32_FLT;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
double* t = (double*) target;
|
||||
int32_t s;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
|
||||
t[i] = s / AUD_S32_FLT;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
double* t = (double*) target;
|
||||
int32_t s;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
|
||||
t[i] = s / AUD_S32_FLT;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
|
||||
}
|
||||
|
||||
void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* t = (int16_t*) target;
|
||||
int32_t* s = (int32_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i] >> 16;
|
||||
}
|
||||
|
||||
void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* s = (int32_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
target[i*3] = s[i] >> 24 & 0xFF;
|
||||
target[i*3+1] = s[i] >> 16 & 0xFF;
|
||||
target[i*3+2] = s[i] >> 8 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* s = (int16_t*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
target[i*3+2] = s[i] >> 24 & 0xFF;
|
||||
target[i*3+1] = s[i] >> 16 & 0xFF;
|
||||
target[i*3] = s[i] >> 8 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* s = (int32_t*) source;
|
||||
float* t = (float*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i] / AUD_S32_FLT;
|
||||
}
|
||||
|
||||
void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* s = (int32_t*) source;
|
||||
double* t = (double*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i] / AUD_S32_FLT;
|
||||
}
|
||||
|
||||
void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
float* s = (float*) source;
|
||||
float t;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
t = s[i] + AUD_FLT_MAX;
|
||||
if(t <= 0.0f)
|
||||
target[i] = 0;
|
||||
else if(t >= 2.0f)
|
||||
target[i] = 255;
|
||||
else
|
||||
target[i] = (unsigned char)(t*127);
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* t = (int16_t*) target;
|
||||
float* s = (float*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t[i] = AUD_S16_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t[i] = AUD_S16_MAX;
|
||||
else
|
||||
t[i] = (int16_t)(s[i] * AUD_S16_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t t;
|
||||
float* s = (float*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t = AUD_S32_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t = AUD_S32_MAX;
|
||||
else
|
||||
t = (int32_t)(s[i]*AUD_S32_MAX);
|
||||
target[i*3] = t >> 24 & 0xFF;
|
||||
target[i*3+1] = t >> 16 & 0xFF;
|
||||
target[i*3+2] = t >> 8 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t t;
|
||||
float* s = (float*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t = AUD_S32_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t = AUD_S32_MAX;
|
||||
else
|
||||
t = (int32_t)(s[i]*AUD_S32_MAX);
|
||||
target[i*3+2] = t >> 24 & 0xFF;
|
||||
target[i*3+1] = t >> 16 & 0xFF;
|
||||
target[i*3] = t >> 8 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* t = (int32_t*) target;
|
||||
float* s = (float*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t[i] = AUD_S32_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t[i] = AUD_S32_MAX;
|
||||
else
|
||||
t[i] = (int32_t)(s[i]*AUD_S32_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
float* s = (float*) source;
|
||||
double* t = (double*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i];
|
||||
}
|
||||
|
||||
void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
double* s = (double*) source;
|
||||
double t;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
t = s[i] + AUD_FLT_MAX;
|
||||
if(t <= 0.0)
|
||||
target[i] = 0;
|
||||
else if(t >= 2.0)
|
||||
target[i] = 255;
|
||||
else
|
||||
target[i] = (unsigned char)(t*127);
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int16_t* t = (int16_t*) target;
|
||||
double* s = (double*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t[i] = AUD_S16_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t[i] = AUD_S16_MAX;
|
||||
else
|
||||
t[i] = (int16_t)(s[i]*AUD_S16_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t t;
|
||||
double* s = (double*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t = AUD_S32_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t = AUD_S32_MAX;
|
||||
else
|
||||
t = (int32_t)(s[i]*AUD_S32_MAX);
|
||||
target[i*3] = t >> 24 & 0xFF;
|
||||
target[i*3+1] = t >> 16 & 0xFF;
|
||||
target[i*3+2] = t >> 8 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t t;
|
||||
double* s = (double*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t = AUD_S32_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t = AUD_S32_MAX;
|
||||
else
|
||||
t = (int32_t)(s[i]*AUD_S32_MAX);
|
||||
target[i*3+2] = t >> 24 & 0xFF;
|
||||
target[i*3+1] = t >> 16 & 0xFF;
|
||||
target[i*3] = t >> 8 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
int32_t* t = (int32_t*) target;
|
||||
double* s = (double*) source;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(s[i] <= AUD_FLT_MIN)
|
||||
t[i] = AUD_S32_MIN;
|
||||
else if(s[i] >= AUD_FLT_MAX)
|
||||
t[i] = AUD_S32_MAX;
|
||||
else
|
||||
t[i] = (int32_t)(s[i]*AUD_S32_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_convert_double_float(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
double* s = (double*) source;
|
||||
float* t = (float*) target;
|
||||
for(int i = 0; i < length; i++)
|
||||
t[i] = s[i];
|
||||
}
|
||||
|
||||
void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
|
||||
int count, float volume)
|
||||
{
|
||||
for(int i=0; i<count; i++)
|
||||
target[i] = (unsigned char)((source[i]-0x0080) * volume + 0x80);
|
||||
}
|
||||
|
||||
void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
|
||||
int count, float volume)
|
||||
{
|
||||
count *= 3;
|
||||
int value;
|
||||
|
||||
for(int i=0; i<count; i+=3)
|
||||
{
|
||||
value = source[i+2] << 16 | source[i+1] << 8 | source[i];
|
||||
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
||||
value *= volume;
|
||||
target[i+2] = value >> 16;
|
||||
target[i+1] = value >> 8;
|
||||
target[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
||||
int count, float volume)
|
||||
{
|
||||
count *= 3;
|
||||
int value;
|
||||
|
||||
for(int i=0; i < count; i+=3)
|
||||
{
|
||||
value = source[i] << 16 | source[i+1] << 8 | source[i+2];
|
||||
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
||||
value *= volume;
|
||||
target[i] = value >> 16;
|
||||
target[i+1] = value >> 8;
|
||||
target[i+2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
156
intern/audaspace/intern/AUD_ConverterFunctions.h
Normal file
156
intern/audaspace/intern/AUD_ConverterFunctions.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_CONVERTERFUNCTIONS
|
||||
#define AUD_CONVERTERFUNCTIONS
|
||||
|
||||
#include "AUD_Space.h"
|
||||
|
||||
#include <cstring>
|
||||
#ifdef _MSC_VER
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef short int16_t;
|
||||
typedef int int32_t;
|
||||
#else
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
|
||||
|
||||
typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
|
||||
int count, float volume);
|
||||
|
||||
template <class T>
|
||||
void AUD_convert_copy(sample_t* target, sample_t* source, int length)
|
||||
{
|
||||
memcpy(target, source, length*sizeof(T));
|
||||
}
|
||||
|
||||
void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_u8_float(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_u8_double(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s16_float(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s16_double(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s32_float(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_s32_double(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_float_u8(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_float_s16(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_float_s32(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_float_double(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_double_u8(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_double_s16(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_double_s32(sample_t* target, sample_t* source, int length);
|
||||
|
||||
void AUD_convert_double_float(sample_t* target, sample_t* source, int length);
|
||||
|
||||
template <class T>
|
||||
void AUD_volume_adjust(sample_t* target, sample_t* source,
|
||||
int count, float volume)
|
||||
{
|
||||
T* t = (T*)target;
|
||||
T* s = (T*)source;
|
||||
for(int i=0; i < count; i++)
|
||||
t[i] = (T)(s[i] * volume);
|
||||
}
|
||||
|
||||
void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
|
||||
int count, float volume);
|
||||
|
||||
void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
|
||||
int count, float volume);
|
||||
|
||||
void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
||||
int count, float volume);
|
||||
|
||||
#endif //AUD_CONVERTERFUNCTIONS
|
||||
244
intern/audaspace/intern/AUD_ConverterReader.cpp
Normal file
244
intern/audaspace/intern/AUD_ConverterReader.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_ConverterReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs) :
|
||||
AUD_EffectReader(reader)
|
||||
{
|
||||
m_specs = reader->getSpecs();
|
||||
|
||||
int bigendian = 1;
|
||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||
|
||||
switch(m_specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_copy<unsigned char>;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_u8_s16;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
m_convert = AUD_convert_u8_s24_be;
|
||||
else
|
||||
m_convert = AUD_convert_u8_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_u8_s32;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_u8_float;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_u8_double;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_s16_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_copy<int16_t>;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
m_convert = AUD_convert_s16_s24_be;
|
||||
else
|
||||
m_convert = AUD_convert_s16_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_s16_s32;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_s16_float;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_s16_double;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_u8_s24_be;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_s16_s24_be;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
m_convert = AUD_convert_s24_s24;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_s32_s24_be;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_float_s24_be;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_double_s24_be;
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_u8_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_s16_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
m_convert = AUD_convert_s24_s24;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_s32_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_float_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_double_s24_le;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_s32_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_s32_s16;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
m_convert = AUD_convert_s32_s24_be;
|
||||
else
|
||||
m_convert = AUD_convert_s32_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_copy<int32_t>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_s32_float;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_s32_double;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_float_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_float_s16;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
m_convert = AUD_convert_float_s24_be;
|
||||
else
|
||||
m_convert = AUD_convert_float_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_float_s32;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_copy<float>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_float_double;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
switch(specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_double_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_double_s16;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
m_convert = AUD_convert_double_s24_be;
|
||||
else
|
||||
m_convert = AUD_convert_double_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_double_s32;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_double_float;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_copy<double>;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_specs.format = specs.format;
|
||||
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
}
|
||||
|
||||
AUD_ConverterReader::~AUD_ConverterReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
AUD_Specs AUD_ConverterReader::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
void AUD_ConverterReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
m_reader->read(length, buffer);
|
||||
|
||||
int samplesize = AUD_SAMPLE_SIZE(m_specs);
|
||||
|
||||
if(m_buffer->getSize() < length*samplesize)
|
||||
m_buffer->resize(length*samplesize);
|
||||
|
||||
m_convert(m_buffer->getBuffer(), buffer, length*m_specs.channels);
|
||||
|
||||
buffer = m_buffer->getBuffer();
|
||||
}
|
||||
71
intern/audaspace/intern/AUD_ConverterReader.h
Normal file
71
intern/audaspace/intern/AUD_ConverterReader.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_CONVERTERREADER
|
||||
#define AUD_CONVERTERREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class converts a sound source from one to another format.
|
||||
*/
|
||||
class AUD_ConverterReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The sound output buffer.
|
||||
*/
|
||||
AUD_Buffer *m_buffer;
|
||||
|
||||
/**
|
||||
* The target specification.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* Converter function.
|
||||
*/
|
||||
AUD_convert_f m_convert;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a converter reader.
|
||||
* \param reader The reader to convert.
|
||||
* \param specs The target specification.
|
||||
* \exception AUD_Exception Thrown if the reader is NULL.
|
||||
*/
|
||||
AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs);
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
~AUD_ConverterReader();
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_CONVERTERREADER
|
||||
170
intern/audaspace/intern/AUD_FloatMixer.cpp
Normal file
170
intern/audaspace/intern/AUD_FloatMixer.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FloatMixer.h"
|
||||
#include "AUD_ConverterFactory.h"
|
||||
#include "AUD_SRCResampleFactory.h"
|
||||
#include "AUD_ChannelMapperFactory.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_FloatMixer::AUD_FloatMixer()
|
||||
{
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
|
||||
m_converter = NULL;
|
||||
m_resampler = NULL;
|
||||
m_mapper = NULL;
|
||||
}
|
||||
|
||||
AUD_FloatMixer::~AUD_FloatMixer()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
|
||||
if(m_converter)
|
||||
{
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_resampler)
|
||||
{
|
||||
delete m_resampler; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_mapper)
|
||||
{
|
||||
delete m_mapper; AUD_DELETE("factory")
|
||||
}
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
|
||||
{
|
||||
m_converter->setReader(reader);
|
||||
reader = m_converter->createReader();
|
||||
|
||||
m_resampler->setReader(reader);
|
||||
reader = m_resampler->createReader();
|
||||
|
||||
if(reader->getSpecs().channels != m_specs.channels)
|
||||
{
|
||||
m_mapper->setReader(reader);
|
||||
reader = m_mapper->createReader();
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
void AUD_FloatMixer::setSpecs(AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
|
||||
if(m_converter)
|
||||
{
|
||||
delete m_converter; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_resampler)
|
||||
{
|
||||
delete m_resampler; AUD_DELETE("factory")
|
||||
}
|
||||
if(m_mapper)
|
||||
{
|
||||
delete m_mapper; AUD_DELETE("factory")
|
||||
}
|
||||
|
||||
specs.format = AUD_FORMAT_FLOAT32;
|
||||
|
||||
m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
|
||||
m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
|
||||
m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
|
||||
|
||||
int bigendian = 1;
|
||||
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||
|
||||
switch(m_specs.format)
|
||||
{
|
||||
case AUD_FORMAT_U8:
|
||||
m_convert = AUD_convert_float_u8;
|
||||
break;
|
||||
case AUD_FORMAT_S16:
|
||||
m_convert = AUD_convert_float_s16;
|
||||
break;
|
||||
case AUD_FORMAT_S24:
|
||||
if(bigendian)
|
||||
m_convert = AUD_convert_float_s24_be;
|
||||
else
|
||||
m_convert = AUD_convert_float_s24_le;
|
||||
break;
|
||||
case AUD_FORMAT_S32:
|
||||
m_convert = AUD_convert_float_s32;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT32:
|
||||
m_convert = AUD_convert_copy<float>;
|
||||
break;
|
||||
case AUD_FORMAT_FLOAT64:
|
||||
m_convert = AUD_convert_float_double;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
|
||||
float volume)
|
||||
{
|
||||
AUD_FloatMixerBuffer buf;
|
||||
buf.buffer = buffer;
|
||||
buf.length = length;
|
||||
buf.volume = volume;
|
||||
m_buffers.push_back(buf);
|
||||
}
|
||||
|
||||
void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
|
||||
{
|
||||
AUD_FloatMixerBuffer buf;
|
||||
|
||||
int channels = m_specs.channels;
|
||||
|
||||
if(m_buffer->getSize() < length * channels * 4)
|
||||
m_buffer->resize(length * channels * 4);
|
||||
|
||||
float* out = (float*)m_buffer->getBuffer();
|
||||
float* in;
|
||||
|
||||
memset(out, 0, length * channels * 4);
|
||||
|
||||
int end;
|
||||
|
||||
while(!m_buffers.empty())
|
||||
{
|
||||
buf = m_buffers.front();
|
||||
m_buffers.pop_front();
|
||||
|
||||
end = buf.length*channels;
|
||||
in = (float*) buf.buffer;
|
||||
|
||||
for(int i = 0; i < end; i++)
|
||||
out[i] += in[i]*buf.volume * volume;
|
||||
}
|
||||
|
||||
m_convert(buffer, (sample_t*) out, length * channels);
|
||||
}
|
||||
100
intern/audaspace/intern/AUD_FloatMixer.h
Normal file
100
intern/audaspace/intern/AUD_FloatMixer.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FLOATMIXER
|
||||
#define AUD_FLOATMIXER
|
||||
|
||||
#include "AUD_IMixer.h"
|
||||
#include "AUD_ConverterFunctions.h"
|
||||
class AUD_ConverterFactory;
|
||||
class AUD_SRCResampleFactory;
|
||||
class AUD_ChannelMapperFactory;
|
||||
class AUD_Buffer;
|
||||
#include <list>
|
||||
|
||||
struct AUD_FloatMixerBuffer
|
||||
{
|
||||
sample_t* buffer;
|
||||
int length;
|
||||
float volume;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is able to mix two audiosignals with floats.
|
||||
*/
|
||||
class AUD_FloatMixer : public AUD_IMixer
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The converter factory that converts all readers for superposition.
|
||||
*/
|
||||
AUD_ConverterFactory* m_converter;
|
||||
|
||||
/**
|
||||
* The resampling factory that resamples all readers for superposition.
|
||||
*/
|
||||
AUD_SRCResampleFactory* m_resampler;
|
||||
|
||||
/**
|
||||
* The channel mapper factory that maps all readers for superposition.
|
||||
*/
|
||||
AUD_ChannelMapperFactory* m_mapper;
|
||||
|
||||
/**
|
||||
* The list of buffers to superpose.
|
||||
*/
|
||||
std::list<AUD_FloatMixerBuffer> m_buffers;
|
||||
|
||||
/**
|
||||
* The output specification.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* The temporary mixing buffer.
|
||||
*/
|
||||
AUD_Buffer* m_buffer;
|
||||
|
||||
/**
|
||||
* Converter function.
|
||||
*/
|
||||
AUD_convert_f m_convert;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates the mixer.
|
||||
*/
|
||||
AUD_FloatMixer();
|
||||
|
||||
virtual ~AUD_FloatMixer();
|
||||
|
||||
virtual AUD_IReader* prepare(AUD_IReader* reader);
|
||||
virtual void setSpecs(AUD_Specs specs);
|
||||
virtual void add(sample_t* buffer, AUD_Specs specs, int length,
|
||||
float volume);
|
||||
virtual void superpose(sample_t* buffer, int length, float volume);
|
||||
};
|
||||
|
||||
#endif //AUD_FLOATMIXER
|
||||
103
intern/audaspace/intern/AUD_I3DDevice.h
Normal file
103
intern/audaspace/intern/AUD_I3DDevice.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_I3DDEVICE
|
||||
#define AUD_I3DDEVICE
|
||||
|
||||
#include "AUD_Space.h"
|
||||
|
||||
/**
|
||||
* This class represents an output device for 3D sound.
|
||||
* Whether a normal device supports this or not can be checked with the
|
||||
* AUD_CAPS_3D_DEVICE capability.
|
||||
*/
|
||||
class AUD_I3DDevice
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Plays a 3D sound source.
|
||||
* \param factory The factory to create the reader for the sound source.
|
||||
* \param keep When keep is true the sound source will not be deleted but
|
||||
* set to paused when its end has been reached.
|
||||
* \return Returns a handle with which the playback can be controlled.
|
||||
* This is NULL if the sound couldn't be played back.
|
||||
* \exception AUD_Exception Thrown if there's an unexpected (from the
|
||||
* device side) error during creation of the reader.
|
||||
* \note The factory must provide a mono (single channel) source otherwise
|
||||
* the sound is played back normally.
|
||||
*/
|
||||
virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false)=0;
|
||||
|
||||
/**
|
||||
* Updates a listeners 3D data.
|
||||
* \param data The 3D data.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
virtual bool updateListener(AUD_3DData &data)=0;
|
||||
|
||||
/**
|
||||
* Sets a 3D device setting.
|
||||
* \param setting The setting type.
|
||||
* \param value The new setting value.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
virtual bool setSetting(AUD_3DSetting setting, float value)=0;
|
||||
|
||||
/**
|
||||
* Retrieves a 3D device setting.
|
||||
* \param setting The setting type.
|
||||
* \return The setting value.
|
||||
*/
|
||||
virtual float getSetting(AUD_3DSetting setting)=0;
|
||||
|
||||
/**
|
||||
* Updates a listeners 3D data.
|
||||
* \param handle The source handle.
|
||||
* \param data The 3D data.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data)=0;
|
||||
|
||||
/**
|
||||
* Sets a 3D source setting.
|
||||
* \param handle The source handle.
|
||||
* \param setting The setting type.
|
||||
* \param value The new setting value.
|
||||
* \return Whether the action succeeded.
|
||||
*/
|
||||
virtual bool setSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting, float value)=0;
|
||||
|
||||
/**
|
||||
* Retrieves a 3D source setting.
|
||||
* \param handle The source handle.
|
||||
* \param setting The setting type.
|
||||
* \return The setting value.
|
||||
*/
|
||||
virtual float getSourceSetting(AUD_Handle* handle,
|
||||
AUD_3DSourceSetting setting)=0;
|
||||
};
|
||||
|
||||
#endif //AUD_I3DDEVICE
|
||||
191
intern/audaspace/intern/AUD_IDevice.h
Normal file
191
intern/audaspace/intern/AUD_IDevice.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_IDEVICE
|
||||
#define AUD_IDEVICE
|
||||
|
||||
#include "AUD_Space.h"
|
||||
class AUD_IFactory;
|
||||
|
||||
/// Handle structure, for inherition.
|
||||
typedef struct
|
||||
{
|
||||
} AUD_Handle;
|
||||
|
||||
/**
|
||||
* This class represents an output device for sound sources.
|
||||
* Output devices may be several backends such as plattform independand like
|
||||
* SDL or OpenAL or plattform specific like DirectSound, but they may also be
|
||||
* files, RAM buffers or other types of streams.
|
||||
* \warning Thread safety must be insured so that no reader is beeing called
|
||||
* twice at the same time.
|
||||
*/
|
||||
class AUD_IDevice
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destroys the device.
|
||||
*/
|
||||
virtual ~AUD_IDevice() {}
|
||||
|
||||
/**
|
||||
* Returns the specification of the device.
|
||||
*/
|
||||
virtual AUD_Specs getSpecs()=0;
|
||||
|
||||
/**
|
||||
* Plays a sound source.
|
||||
* \param factory The factory to create the reader for the sound source.
|
||||
* \param keep When keep is true the sound source will not be deleted but
|
||||
* set to paused when its end has been reached.
|
||||
* \return Returns a handle with which the playback can be controlled.
|
||||
* This is NULL if the sound couldn't be played back.
|
||||
* \exception AUD_Exception Thrown if there's an unexpected (from the
|
||||
* device side) error during creation of the reader.
|
||||
*/
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false)=0;
|
||||
|
||||
/**
|
||||
* Pauses a played back sound.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \return
|
||||
* - true if the sound has been paused.
|
||||
* - false if the sound isn't playing back or the handle is invalid.
|
||||
*/
|
||||
virtual bool pause(AUD_Handle* handle)=0;
|
||||
|
||||
/**
|
||||
* Resumes a paused sound.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \return
|
||||
* - true if the sound has been resumed.
|
||||
* - false if the sound isn't paused or the handle is invalid.
|
||||
*/
|
||||
virtual bool resume(AUD_Handle* handle)=0;
|
||||
|
||||
/**
|
||||
* Stops a played back or paused sound. The handle is definitely invalid
|
||||
* afterwards.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \return
|
||||
* - true if the sound has been stopped.
|
||||
* - false if the handle is invalid.
|
||||
*/
|
||||
virtual bool stop(AUD_Handle* handle)=0;
|
||||
|
||||
/**
|
||||
* Sets the behaviour of the device for a played back sound when the sound
|
||||
* doesn't return any more samples.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \param keep True when the source should be paused and not deleted.
|
||||
* \return
|
||||
* - true if the behaviour has been changed.
|
||||
* - false if the handle is invalid.
|
||||
*/
|
||||
virtual bool setKeep(AUD_Handle* handle, bool keep)=0;
|
||||
|
||||
/**
|
||||
* Sends a message to a sound or all sounds that are currently played or
|
||||
* paused.
|
||||
* \param handle The sound that should receive the message or NULL if all
|
||||
* sounds should receive it.
|
||||
* \param message The message.
|
||||
* \return True if the message has been read by at least one sound.
|
||||
*/
|
||||
virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message)=0;
|
||||
|
||||
/**
|
||||
* Seeks in a played back sound.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \param position The new position from where to play back, in seconds.
|
||||
* \return
|
||||
* - true if the handle is valid.
|
||||
* - false if the handle is invalid.
|
||||
* \warning Whether the seek works or not depends on the sound source.
|
||||
*/
|
||||
virtual bool seek(AUD_Handle* handle, float position)=0;
|
||||
|
||||
/**
|
||||
* Retrieves the current playback position of a sound.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \return The playback position in seconds, or 0.0 if the handle is
|
||||
* invalid.
|
||||
*/
|
||||
virtual float getPosition(AUD_Handle* handle)=0;
|
||||
|
||||
/**
|
||||
* Returns the status of a played back sound.
|
||||
* \param handle The handle returned by the play function.
|
||||
* \return
|
||||
* - AUD_STATUS_INVALID if the sound has stopped or the handle is
|
||||
*. invalid
|
||||
* - AUD_STATUS_PLAYING if the sound is currently played back.
|
||||
* - AUD_STATUS_PAUSED if the sound is currently paused.
|
||||
* \see AUD_Status
|
||||
*/
|
||||
virtual AUD_Status getStatus(AUD_Handle* handle)=0;
|
||||
|
||||
/**
|
||||
* Locks the device.
|
||||
* Used to make sure that between lock and unlock, no buffers are read, so
|
||||
* that it is possible to start, resume, pause, stop or seek several
|
||||
* playback handles simultaneously.
|
||||
* \warning Make sure the locking time is as small as possible to avoid
|
||||
* playback delays that result in unexpected noise and cracks.
|
||||
*/
|
||||
virtual void lock()=0;
|
||||
|
||||
/**
|
||||
* Unlocks the previously locked device.
|
||||
*/
|
||||
virtual void unlock()=0;
|
||||
|
||||
/**
|
||||
* Checks if a specific capability as available on a device.
|
||||
* \param capability The capability.
|
||||
* \return Whether it is available or not.
|
||||
*/
|
||||
virtual bool checkCapability(int capability)=0;
|
||||
|
||||
/**
|
||||
* Set a value of a capability. The data behind the pointer depends on the
|
||||
* capability.
|
||||
* \param capability The capability.
|
||||
* \param value The value.
|
||||
* \return Whether the action succeeded or not.
|
||||
*/
|
||||
virtual bool setCapability(int capability, void *value)=0;
|
||||
|
||||
/**
|
||||
* Retrieves a value of a capability. The data behind the pointer depends on
|
||||
* the capability.
|
||||
* \param capability The capability.
|
||||
* \param value The value.
|
||||
* \return Whether the action succeeded or not.
|
||||
*/
|
||||
virtual bool getCapability(int capability, void *value)=0;
|
||||
};
|
||||
|
||||
#endif //AUD_IDevice
|
||||
55
intern/audaspace/intern/AUD_IFactory.h
Normal file
55
intern/audaspace/intern/AUD_IFactory.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_IFACTORY
|
||||
#define AUD_IFACTORY
|
||||
|
||||
#include "AUD_Space.h"
|
||||
class AUD_IReader;
|
||||
|
||||
/**
|
||||
* This class represents a type of sound source and saves the necessary values
|
||||
* for it. It is able to create a reader that is actually usable for playback
|
||||
* of the respective sound source through the factory method createReader.
|
||||
*/
|
||||
class AUD_IFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destroys the factory.
|
||||
*/
|
||||
virtual ~AUD_IFactory(){}
|
||||
|
||||
/**
|
||||
* Creates a reader for playback of the sound source.
|
||||
* \return A pointer to an AUD_IReader object or NULL if there has been an
|
||||
* error.
|
||||
* \exception AUD_Exception An exception may be thrown if there has been
|
||||
* a more unexpected error during reader creation.
|
||||
*/
|
||||
virtual AUD_IReader* createReader()=0;
|
||||
};
|
||||
|
||||
#endif //AUD_IFACTORY
|
||||
77
intern/audaspace/intern/AUD_IMixer.h
Normal file
77
intern/audaspace/intern/AUD_IMixer.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_IMIXER
|
||||
#define AUD_IMIXER
|
||||
|
||||
#include "AUD_Space.h"
|
||||
class AUD_IReader;
|
||||
|
||||
/**
|
||||
* This class is able to mix audiosignals of different format and channel count.
|
||||
* \note This class doesn't do resampling!
|
||||
*/
|
||||
class AUD_IMixer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destroys the mixer.
|
||||
*/
|
||||
virtual ~AUD_IMixer(){}
|
||||
|
||||
/**
|
||||
* This funuction prepares a reader for playback.
|
||||
* \param reader The reader to prepare.
|
||||
* \return The reader that should be used for playback.
|
||||
*/
|
||||
virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
|
||||
|
||||
/**
|
||||
* Sets the target specification for superposing.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
virtual void setSpecs(AUD_Specs specs)=0;
|
||||
|
||||
/**
|
||||
* Adds a buffer for superposition.
|
||||
* \param buffer The buffer to superpose.
|
||||
* \param specs The specification of the buffer.
|
||||
* \param start The start sample of the buffer.
|
||||
* \param length The length of the buffer in samples.
|
||||
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
||||
*/
|
||||
virtual void add(sample_t* buffer, AUD_Specs specs, int length,
|
||||
float volume)=0;
|
||||
|
||||
/**
|
||||
* Superposes all added buffers into an output buffer.
|
||||
* \param buffer The target buffer for superposing.
|
||||
* \param length The length of the buffer in samples.
|
||||
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
||||
*/
|
||||
virtual void superpose(sample_t* buffer, int length, float volume)=0;
|
||||
};
|
||||
|
||||
#endif //AUD_IMIXER
|
||||
117
intern/audaspace/intern/AUD_IReader.h
Normal file
117
intern/audaspace/intern/AUD_IReader.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_IREADER
|
||||
#define AUD_IREADER
|
||||
|
||||
#include "AUD_Space.h"
|
||||
|
||||
/**
|
||||
* This class represents a sound source as stream or as buffer which can be read
|
||||
* for example by another reader, a device or whatever.
|
||||
*/
|
||||
class AUD_IReader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_IReader(){}
|
||||
|
||||
/**
|
||||
* Tells whether the source provides seeking functionality or not.
|
||||
* \warning This doesn't mean that the seeking always has to succeed.
|
||||
* \return Always returns true for readers of the buffer type.
|
||||
* \see getType
|
||||
*/
|
||||
virtual bool isSeekable()=0;
|
||||
|
||||
/**
|
||||
* Seeks to a specific position in the source.
|
||||
* This function must work for buffer type readers.
|
||||
* \param position The position to seek for measured in samples. To get
|
||||
* from a given time to the samples you simply have to multiply the
|
||||
* time value in seconds with the sample rate of the reader.
|
||||
* \warning This may work or not, depending on the actual reader.
|
||||
* \see getType
|
||||
*/
|
||||
virtual void seek(int position)=0;
|
||||
|
||||
/**
|
||||
* Returns an aproximated length of the source in samples.
|
||||
* For readers of the type buffer this has to return a correct value!
|
||||
* \return The length as sample count. May be negative if unknown.
|
||||
* \see getType
|
||||
*/
|
||||
virtual int getLength()=0;
|
||||
|
||||
/**
|
||||
* Returns the position of the source as a sample count value.
|
||||
* \return The current position in the source. A negative value indicates
|
||||
* that the position is unknown.
|
||||
* \warning The value returned doesn't always have to be correct for readers
|
||||
* of the stream type, especially after seeking, it must though for
|
||||
* the buffer ones.
|
||||
* \see getType
|
||||
*/
|
||||
virtual int getPosition()=0;
|
||||
|
||||
/**
|
||||
* Returns the specification of the reader.
|
||||
* \return The AUD_Specs structure.
|
||||
*/
|
||||
virtual AUD_Specs getSpecs()=0;
|
||||
|
||||
/**
|
||||
* Returns the type of the reader. There are special conditions for the
|
||||
* readers of the buffer type. Those have to return correct position and
|
||||
* length values as well as they must be seekable.
|
||||
* \return AUD_TYPE_BUFFER or AUD_TYPE_STREAM.
|
||||
*/
|
||||
virtual AUD_ReaderType getType()=0;
|
||||
|
||||
/**
|
||||
* Sends a message to this reader and if it has subreaders it broadcasts
|
||||
* the message to them.
|
||||
* \param message The message.
|
||||
* \return Whether the message has been read by the reader or one of his
|
||||
* subreaders.
|
||||
*/
|
||||
virtual bool notify(AUD_Message &message)=0;
|
||||
|
||||
/**
|
||||
* Request to read the next length samples out of the source.
|
||||
* The buffer for reading has to stay valid until the next call of this
|
||||
* method or until the reader is deleted.
|
||||
* \param[in,out] length The count of samples that should be read. Shall
|
||||
* contain the real count of samples after reading, in case
|
||||
* there were only fewer samples available.
|
||||
* A smaller value also indicates the end of the reader.
|
||||
* \param[out] buffer The pointer to the buffer with the samples.
|
||||
*/
|
||||
virtual void read(int & length, sample_t* & buffer)=0;
|
||||
};
|
||||
|
||||
#endif //AUD_IREADER
|
||||
109
intern/audaspace/intern/AUD_MixerFactory.cpp
Normal file
109
intern/audaspace/intern/AUD_MixerFactory.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_MixerFactory.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
AUD_IReader* AUD_MixerFactory::getReader()
|
||||
{
|
||||
AUD_IReader* reader;
|
||||
|
||||
// first check for an existing reader
|
||||
if(m_reader != 0)
|
||||
{
|
||||
reader = m_reader;
|
||||
m_reader = 0;
|
||||
return reader;
|
||||
}
|
||||
|
||||
// otherwise create a reader if there is a factory
|
||||
if(m_factory != 0)
|
||||
{
|
||||
reader = m_factory->createReader();
|
||||
return reader;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
|
||||
AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
m_reader = reader;
|
||||
m_factory = 0;
|
||||
}
|
||||
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
|
||||
AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
m_reader = 0;
|
||||
m_factory = factory;
|
||||
}
|
||||
|
||||
AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
m_reader = 0;
|
||||
m_factory = 0;
|
||||
}
|
||||
|
||||
AUD_MixerFactory::~AUD_MixerFactory()
|
||||
{
|
||||
if(m_reader != 0)
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Specs AUD_MixerFactory::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
void AUD_MixerFactory::setSpecs(AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
}
|
||||
|
||||
void AUD_MixerFactory::setReader(AUD_IReader* reader)
|
||||
{
|
||||
if(m_reader != 0)
|
||||
{
|
||||
delete m_reader; AUD_DELETE("reader")
|
||||
}
|
||||
m_reader = reader;
|
||||
}
|
||||
|
||||
void AUD_MixerFactory::setFactory(AUD_IFactory* factory)
|
||||
{
|
||||
m_factory = factory;
|
||||
}
|
||||
|
||||
AUD_IFactory* AUD_MixerFactory::getFactory()
|
||||
{
|
||||
return m_factory;
|
||||
}
|
||||
117
intern/audaspace/intern/AUD_MixerFactory.h
Normal file
117
intern/audaspace/intern/AUD_MixerFactory.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_MIXERFACTORY
|
||||
#define AUD_MIXERFACTORY
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
|
||||
/**
|
||||
* This factory is a base class for all mixer factories.
|
||||
*/
|
||||
class AUD_MixerFactory : public AUD_IFactory
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* The reader that should be mixed later.
|
||||
*/
|
||||
AUD_IReader* m_reader;
|
||||
|
||||
/**
|
||||
* If there is no reader it is created out of this factory.
|
||||
*/
|
||||
AUD_IFactory* m_factory;
|
||||
|
||||
/**
|
||||
* The target specification for resampling.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* Returns the reader created out of the factory or taken from m_reader.
|
||||
* This method can be used for the createReader function of the implementing
|
||||
* classes.
|
||||
* \return The reader to mix, or NULL if there is no reader or factory.
|
||||
*/
|
||||
AUD_IReader* getReader();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new factory.
|
||||
* \param reader The reader to mix.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
AUD_MixerFactory(AUD_IReader* reader, AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Creates a new factory.
|
||||
* \param factory The factory to create the readers to mix out of.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
AUD_MixerFactory(AUD_IFactory* factory, AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Creates a new factory.
|
||||
* \param specs The target specification.
|
||||
*/
|
||||
AUD_MixerFactory(AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Destroys the resampling factory.
|
||||
*/
|
||||
virtual ~AUD_MixerFactory();
|
||||
|
||||
/**
|
||||
* Returns the target specification for resampling.
|
||||
*/
|
||||
AUD_Specs getSpecs();
|
||||
|
||||
/**
|
||||
* Sets the target specification for resampling.
|
||||
* \param specs The specification.
|
||||
*/
|
||||
void setSpecs(AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Sets the reader for resampling.
|
||||
* If there has already been a reader, it will be deleted.
|
||||
* \param reader The reader that should be used as source for resampling.
|
||||
*/
|
||||
void setReader(AUD_IReader* reader);
|
||||
|
||||
/**
|
||||
* Sets the factory for resampling.
|
||||
* \param factory The factory that should be used as source for resampling.
|
||||
*/
|
||||
void setFactory(AUD_IFactory* factory);
|
||||
|
||||
/**
|
||||
* Returns the saved factory.
|
||||
* \return The factory or NULL if there has no factory been saved.
|
||||
*/
|
||||
AUD_IFactory* getFactory();
|
||||
};
|
||||
|
||||
#endif //AUD_MIXERFACTORY
|
||||
108
intern/audaspace/intern/AUD_NULLDevice.cpp
Normal file
108
intern/audaspace/intern/AUD_NULLDevice.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_NULLDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_IFactory.h"
|
||||
|
||||
AUD_NULLDevice::AUD_NULLDevice()
|
||||
{
|
||||
m_specs.channels = AUD_CHANNELS_INVALID;
|
||||
m_specs.format = AUD_FORMAT_INVALID;
|
||||
m_specs.rate = AUD_RATE_INVALID;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_NULLDevice::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
AUD_Handle* AUD_NULLDevice::play(AUD_IFactory* factory, bool keep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::pause(AUD_Handle* handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::resume(AUD_Handle* handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::stop(AUD_Handle* handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::setKeep(AUD_Handle* handle, bool keep)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::seek(AUD_Handle* handle, float position)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float AUD_NULLDevice::getPosition(AUD_Handle* handle)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
AUD_Status AUD_NULLDevice::getStatus(AUD_Handle* handle)
|
||||
{
|
||||
return AUD_STATUS_INVALID;
|
||||
}
|
||||
|
||||
void AUD_NULLDevice::lock()
|
||||
{
|
||||
}
|
||||
|
||||
void AUD_NULLDevice::unlock()
|
||||
{
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::checkCapability(int capability)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::setCapability(int capability, void *value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::getCapability(int capability, void *value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
65
intern/audaspace/intern/AUD_NULLDevice.h
Normal file
65
intern/audaspace/intern/AUD_NULLDevice.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_NULLDEVICE
|
||||
#define AUD_NULLDEVICE
|
||||
|
||||
#include "AUD_IDevice.h"
|
||||
|
||||
/**
|
||||
* This device plays nothing.
|
||||
*/
|
||||
class AUD_NULLDevice : public AUD_IDevice
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The specs of the device.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new NULL device.
|
||||
*/
|
||||
AUD_NULLDevice();
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool pause(AUD_Handle* handle);
|
||||
virtual bool resume(AUD_Handle* handle);
|
||||
virtual bool stop(AUD_Handle* handle);
|
||||
virtual bool setKeep(AUD_Handle* handle, bool keep);
|
||||
virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
|
||||
virtual bool seek(AUD_Handle* handle, float position);
|
||||
virtual float getPosition(AUD_Handle* handle);
|
||||
virtual AUD_Status getStatus(AUD_Handle* handle);
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
virtual bool checkCapability(int capability);
|
||||
virtual bool setCapability(int capability, void *value);
|
||||
virtual bool getCapability(int capability, void *value);
|
||||
};
|
||||
|
||||
#endif //AUD_NULLDEVICE
|
||||
64
intern/audaspace/intern/AUD_ReadDevice.cpp
Normal file
64
intern/audaspace/intern/AUD_ReadDevice.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_FloatMixer.h"
|
||||
#include "AUD_ReadDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
|
||||
{
|
||||
m_specs = specs;
|
||||
|
||||
m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
|
||||
m_mixer->setSpecs(m_specs);
|
||||
|
||||
m_playing = false;
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
AUD_ReadDevice::~AUD_ReadDevice()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool AUD_ReadDevice::read(sample_t* buffer, int length)
|
||||
{
|
||||
if(m_playing)
|
||||
mix(buffer, length);
|
||||
else
|
||||
if(m_specs.format == AUD_FORMAT_U8)
|
||||
memset(buffer, 0x80, length * AUD_SAMPLE_SIZE(m_specs));
|
||||
else
|
||||
memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
|
||||
return m_playing;
|
||||
}
|
||||
|
||||
void AUD_ReadDevice::playing(bool playing)
|
||||
{
|
||||
m_playing = playing;
|
||||
}
|
||||
68
intern/audaspace/intern/AUD_ReadDevice.h
Normal file
68
intern/audaspace/intern/AUD_ReadDevice.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_READDEVICE
|
||||
#define AUD_READDEVICE
|
||||
|
||||
#include "AUD_SoftwareDevice.h"
|
||||
|
||||
/**
|
||||
* This device enables to let the user read raw data out of it.
|
||||
*/
|
||||
class AUD_ReadDevice : public AUD_SoftwareDevice
|
||||
{
|
||||
protected:
|
||||
virtual void playing(bool playing);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Whether the device currently.
|
||||
*/
|
||||
bool m_playing;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new read device.
|
||||
* \param specs The wanted audio specification.
|
||||
*/
|
||||
AUD_ReadDevice(AUD_Specs specs);
|
||||
|
||||
/**
|
||||
* Closes the device.
|
||||
*/
|
||||
virtual ~AUD_ReadDevice();
|
||||
|
||||
/**
|
||||
* Reads the next bytes into the supplied buffer.
|
||||
* \param buffer The target buffer.
|
||||
* \param length The length in samples to be filled.
|
||||
* \return True if the reading succeeded, false if there are no sounds
|
||||
* played back currently, in that case the buffer is filled with
|
||||
* silence.
|
||||
*/
|
||||
bool read(sample_t* buffer, int length);
|
||||
};
|
||||
|
||||
#endif //AUD_READDEVICE
|
||||
115
intern/audaspace/intern/AUD_Reference.h
Normal file
115
intern/audaspace/intern/AUD_Reference.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_REFERENCE
|
||||
#define AUD_REFERENCE
|
||||
|
||||
template <class T>
|
||||
/**
|
||||
* This class provides reference counting functionality.
|
||||
*/
|
||||
class AUD_Reference
|
||||
{
|
||||
private:
|
||||
/// The reference.
|
||||
T* m_reference;
|
||||
/// The reference counter.
|
||||
int* m_refcount;
|
||||
public:
|
||||
/**
|
||||
* Creates a new reference counter.
|
||||
* \param reference The reference.
|
||||
*/
|
||||
AUD_Reference(T* reference = 0)
|
||||
{
|
||||
m_reference = reference;
|
||||
m_refcount = new int; AUD_NEW("int")
|
||||
*m_refcount = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a AUD_Reference object.
|
||||
* \param ref The AUD_Reference object to copy.
|
||||
*/
|
||||
AUD_Reference(const AUD_Reference& ref)
|
||||
{
|
||||
m_reference = ref.m_reference;
|
||||
m_refcount = ref.m_refcount;
|
||||
(*m_refcount)++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a AUD_Reference object, if there's no furthere reference on the
|
||||
* reference, it is destroyed as well.
|
||||
*/
|
||||
~AUD_Reference()
|
||||
{
|
||||
(*m_refcount)--;
|
||||
if(*m_refcount == 0)
|
||||
{
|
||||
if(m_reference != 0)
|
||||
{
|
||||
delete m_reference; AUD_DELETE("buffer")
|
||||
}
|
||||
delete m_refcount; AUD_DELETE("int")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a AUD_Reference object.
|
||||
* \param ref The AUD_Reference object to copy.
|
||||
*/
|
||||
AUD_Reference& operator=(const AUD_Reference& ref)
|
||||
{
|
||||
if(&ref == this)
|
||||
return *this;
|
||||
|
||||
(*m_refcount)--;
|
||||
if(*m_refcount == 0)
|
||||
{
|
||||
if(m_reference != 0)
|
||||
{
|
||||
delete m_reference; AUD_DELETE("buffer")
|
||||
}
|
||||
delete m_refcount; AUD_DELETE("int")
|
||||
}
|
||||
|
||||
m_reference = ref.m_reference;
|
||||
m_refcount = ref.m_refcount;
|
||||
(*m_refcount)++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reference.
|
||||
*/
|
||||
T* get()
|
||||
{
|
||||
return m_reference;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // AUD_REFERENCE
|
||||
33
intern/audaspace/intern/AUD_ResampleFactory.h
Normal file
33
intern/audaspace/intern/AUD_ResampleFactory.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_RESAMPLEFACTORY
|
||||
#define AUD_RESAMPLEFACTORY
|
||||
|
||||
#include "AUD_MixerFactory.h"
|
||||
|
||||
typedef AUD_MixerFactory AUD_ResampleFactory;
|
||||
|
||||
#endif //AUD_RESAMPLEFACTORY
|
||||
51
intern/audaspace/intern/AUD_SinusFactory.cpp
Normal file
51
intern/audaspace/intern/AUD_SinusFactory.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SinusFactory.h"
|
||||
#include "AUD_SinusReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_SinusFactory::AUD_SinusFactory(double frequency, AUD_SampleRate sampleRate)
|
||||
{
|
||||
m_frequency = frequency;
|
||||
m_sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_SinusFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = new AUD_SinusReader(m_frequency, m_sampleRate);
|
||||
AUD_NEW("reader")
|
||||
return reader;
|
||||
}
|
||||
|
||||
double AUD_SinusFactory::getFrequency()
|
||||
{
|
||||
return m_frequency;
|
||||
}
|
||||
|
||||
void AUD_SinusFactory::setFrequency(double frequency)
|
||||
{
|
||||
m_frequency = frequency;
|
||||
}
|
||||
70
intern/audaspace/intern/AUD_SinusFactory.h
Normal file
70
intern/audaspace/intern/AUD_SinusFactory.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SINUSFACTORY
|
||||
#define AUD_SINUSFACTORY
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a reader that plays a sine tone.
|
||||
*/
|
||||
class AUD_SinusFactory : public AUD_IFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The frequence of the sine wave.
|
||||
*/
|
||||
double m_frequency;
|
||||
|
||||
/**
|
||||
* The target sample rate for output.
|
||||
*/
|
||||
AUD_SampleRate m_sampleRate;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new sine factory.
|
||||
* \param frequency The desired frequency.
|
||||
* \param sampleRate The target sample rate for playback.
|
||||
*/
|
||||
AUD_SinusFactory(double frequency,
|
||||
AUD_SampleRate sampleRate = AUD_RATE_44100);
|
||||
|
||||
/**
|
||||
* Returns the frequency of the sine wave.
|
||||
*/
|
||||
double getFrequency();
|
||||
|
||||
/**
|
||||
* Sets the frequency.
|
||||
* \param frequency The new frequency.
|
||||
*/
|
||||
void setFrequency(double frequency);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_SINUSFACTORY
|
||||
104
intern/audaspace/intern/AUD_SinusReader.cpp
Normal file
104
intern/audaspace/intern/AUD_SinusReader.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SinusReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
AUD_SinusReader::AUD_SinusReader(double frequency, AUD_SampleRate sampleRate)
|
||||
{
|
||||
m_frequency = frequency;
|
||||
m_position = 0;
|
||||
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||
m_sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
AUD_SinusReader::~AUD_SinusReader()
|
||||
{
|
||||
delete m_buffer; AUD_DELETE("buffer")
|
||||
}
|
||||
|
||||
bool AUD_SinusReader::isSeekable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AUD_SinusReader::seek(int position)
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
int AUD_SinusReader::getLength()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AUD_SinusReader::getPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_SinusReader::getSpecs()
|
||||
{
|
||||
AUD_Specs specs;
|
||||
specs.rate = m_sampleRate;
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
return specs;
|
||||
}
|
||||
|
||||
AUD_ReaderType AUD_SinusReader::getType()
|
||||
{
|
||||
return AUD_TYPE_STREAM;
|
||||
}
|
||||
|
||||
bool AUD_SinusReader::notify(AUD_Message &message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_SinusReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// resize if necessary
|
||||
if(m_buffer->getSize() < length*4)
|
||||
m_buffer->resize(length*4);
|
||||
|
||||
// fill with sine data
|
||||
short* buf = (short*) m_buffer->getBuffer();
|
||||
for(int i=0; i < length; i++)
|
||||
{
|
||||
buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
|
||||
(float)m_sampleRate) * 32700;
|
||||
buf[i*2+1] = buf[i*2];
|
||||
}
|
||||
|
||||
buffer = (sample_t*)buf;
|
||||
m_position += length;
|
||||
}
|
||||
86
intern/audaspace/intern/AUD_SinusReader.h
Normal file
86
intern/audaspace/intern/AUD_SinusReader.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SINUSREADER
|
||||
#define AUD_SINUSREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This class is used for sine tone playback.
|
||||
* The output format is in the 16 bit format and stereo, the sample rate can be
|
||||
* specified.
|
||||
* As the two channels both play the same the output could also be mono, but
|
||||
* in most cases this will result in having to resample for output, so stereo
|
||||
* sound is created directly.
|
||||
*/
|
||||
class AUD_SinusReader : public AUD_IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The frequency of the sine wave.
|
||||
*/
|
||||
double m_frequency;
|
||||
|
||||
/**
|
||||
* The current position in samples.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer* m_buffer;
|
||||
|
||||
/**
|
||||
* The sample rate for the output.
|
||||
*/
|
||||
AUD_SampleRate m_sampleRate;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new reader.
|
||||
* \param frequency The frequency of the sine wave.
|
||||
* \param sampleRate The output sample rate.
|
||||
*/
|
||||
AUD_SinusReader(double frequency, AUD_SampleRate sampleRate);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~AUD_SinusReader();
|
||||
|
||||
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_SINUSREADER
|
||||
444
intern/audaspace/intern/AUD_SoftwareDevice.cpp
Normal file
444
intern/audaspace/intern/AUD_SoftwareDevice.cpp
Normal file
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SoftwareDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_IMixer.h"
|
||||
#include "AUD_IFactory.h"
|
||||
#include "AUD_SourceCaps.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
/// Saves the data for playback.
|
||||
struct AUD_SoftwareHandle : AUD_Handle
|
||||
{
|
||||
/// The reader source.
|
||||
AUD_IReader* reader;
|
||||
|
||||
/// Whether to keep the source if end of it is reached.
|
||||
bool keep;
|
||||
|
||||
/// The volume of the source.
|
||||
float volume;
|
||||
};
|
||||
|
||||
typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
|
||||
|
||||
void AUD_SoftwareDevice::create()
|
||||
{
|
||||
m_playingSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
||||
m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
|
||||
m_playback = false;
|
||||
m_volume = 1.0;
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
pthread_mutex_init(&m_mutex, &attr);
|
||||
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::destroy()
|
||||
{
|
||||
if(m_playback)
|
||||
playing(m_playback = false);
|
||||
|
||||
delete m_mixer; AUD_DELETE("mixer")
|
||||
|
||||
// delete all playing sounds
|
||||
while(m_playingSounds->begin() != m_playingSounds->end())
|
||||
{
|
||||
delete (*(m_playingSounds->begin()))->reader; AUD_DELETE("reader")
|
||||
delete *(m_playingSounds->begin()); AUD_DELETE("handle")
|
||||
m_playingSounds->erase(m_playingSounds->begin());
|
||||
}
|
||||
delete m_playingSounds; AUD_DELETE("list")
|
||||
|
||||
// delete all paused sounds
|
||||
while(m_pausedSounds->begin() != m_pausedSounds->end())
|
||||
{
|
||||
delete (*(m_pausedSounds->begin()))->reader; AUD_DELETE("reader")
|
||||
delete *(m_pausedSounds->begin()); AUD_DELETE("handle")
|
||||
m_pausedSounds->erase(m_pausedSounds->begin());
|
||||
}
|
||||
delete m_pausedSounds; AUD_DELETE("list")
|
||||
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
|
||||
{
|
||||
lock();
|
||||
|
||||
AUD_SoftwareHandle* sound;
|
||||
int len;
|
||||
sample_t* buf;
|
||||
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
||||
std::list<AUD_SoftwareHandle*> stopSounds;
|
||||
|
||||
// for all sounds
|
||||
AUD_HandleIterator it = m_playingSounds->begin();
|
||||
while(it != m_playingSounds->end())
|
||||
{
|
||||
sound = *it;
|
||||
// increment the iterator to make sure it's valid,
|
||||
// in case the sound gets deleted after stopping
|
||||
++it;
|
||||
|
||||
// get the buffer from the source
|
||||
len = length;
|
||||
sound->reader->read(len, buf);
|
||||
|
||||
m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
|
||||
|
||||
// in case the end of the sound is reached
|
||||
if(len < length)
|
||||
{
|
||||
if(sound->keep)
|
||||
pause(sound);
|
||||
else
|
||||
stopSounds.push_back(sound);
|
||||
}
|
||||
}
|
||||
|
||||
// fill with silence
|
||||
if(m_specs.format == AUD_FORMAT_U8)
|
||||
memset(buffer, 0x80, length * sample_size);
|
||||
else
|
||||
memset(buffer, 0, length * sample_size);
|
||||
|
||||
// superpose
|
||||
m_mixer->superpose(buffer, length, m_volume);
|
||||
|
||||
while(!stopSounds.empty())
|
||||
{
|
||||
sound = stopSounds.front();
|
||||
stopSounds.pop_front();
|
||||
stop(sound);
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
|
||||
{
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
if(*i == handle)
|
||||
return true;
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
if(*i == handle)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
|
||||
{
|
||||
delete m_mixer; AUD_DELETE("mixer")
|
||||
m_mixer = mixer;
|
||||
mixer->setSpecs(m_specs);
|
||||
}
|
||||
|
||||
AUD_Specs AUD_SoftwareDevice::getSpecs()
|
||||
{
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
|
||||
{
|
||||
AUD_IReader* reader = factory->createReader();
|
||||
|
||||
if(reader == NULL)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
// prepare the reader
|
||||
reader = m_mixer->prepare(reader);
|
||||
if(reader == NULL)
|
||||
return NULL;
|
||||
|
||||
AUD_Specs rs = reader->getSpecs();
|
||||
|
||||
// play sound
|
||||
AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; AUD_NEW("handle")
|
||||
sound->keep = keep;
|
||||
sound->reader = reader;
|
||||
sound->volume = 1.0;
|
||||
|
||||
lock();
|
||||
m_playingSounds->push_back(sound);
|
||||
|
||||
if(!m_playback)
|
||||
playing(m_playback = true);
|
||||
unlock();
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
|
||||
{
|
||||
// only songs that are played can be paused
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
m_pausedSounds->push_back(*i);
|
||||
m_playingSounds->erase(i);
|
||||
if(m_playingSounds->empty())
|
||||
playing(m_playback = false);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
|
||||
{
|
||||
// only songs that are paused can be resumed
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
m_playingSounds->push_back(*i);
|
||||
m_pausedSounds->erase(i);
|
||||
if(!m_playback)
|
||||
playing(m_playback = true);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
|
||||
{
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
delete (*i)->reader; AUD_DELETE("reader")
|
||||
delete *i; AUD_DELETE("handle")
|
||||
m_playingSounds->erase(i);
|
||||
if(m_playingSounds->empty())
|
||||
playing(m_playback = false);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
delete (*i)->reader; AUD_DELETE("reader")
|
||||
delete *i; AUD_DELETE("handle")
|
||||
m_pausedSounds->erase(i);
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep)
|
||||
{
|
||||
lock();
|
||||
if(isValid(handle))
|
||||
{
|
||||
((AUD_SoftwareHandle*)handle)->keep = keep;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
|
||||
{
|
||||
lock();
|
||||
|
||||
bool result = false;
|
||||
|
||||
if(handle == 0)
|
||||
{
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
result |= (*i)->reader->notify(message);
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
result |= (*i)->reader->notify(message);
|
||||
}
|
||||
else if(isValid(handle))
|
||||
result = ((AUD_SoftwareHandle*)handle)->reader->notify(message);
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
|
||||
{
|
||||
lock();
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
AUD_IReader* reader = ((AUD_SoftwareHandle*)handle)->reader;
|
||||
reader->seek((int)(position * reader->getSpecs().rate));
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
|
||||
{
|
||||
lock();
|
||||
|
||||
float position = 0.0f;
|
||||
|
||||
if(isValid(handle))
|
||||
{
|
||||
AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
|
||||
position = h->reader->getPosition() / (float)m_specs.rate;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return position;
|
||||
}
|
||||
|
||||
AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
|
||||
{
|
||||
lock();
|
||||
for(AUD_HandleIterator i = m_playingSounds->begin();
|
||||
i != m_playingSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
unlock();
|
||||
return AUD_STATUS_PLAYING;
|
||||
}
|
||||
}
|
||||
for(AUD_HandleIterator i = m_pausedSounds->begin();
|
||||
i != m_pausedSounds->end(); i++)
|
||||
{
|
||||
if(*i == handle)
|
||||
{
|
||||
unlock();
|
||||
return AUD_STATUS_PAUSED;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return AUD_STATUS_INVALID;
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::lock()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
}
|
||||
|
||||
void AUD_SoftwareDevice::unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::checkCapability(int capability)
|
||||
{
|
||||
return capability == AUD_CAPS_SOFTWARE_DEVICE ||
|
||||
capability == AUD_CAPS_VOLUME ||
|
||||
capability == AUD_CAPS_SOURCE_VOLUME;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::setCapability(int capability, void *value)
|
||||
{
|
||||
switch(capability)
|
||||
{
|
||||
case AUD_CAPS_VOLUME:
|
||||
lock();
|
||||
m_volume = *((float*)value);
|
||||
if(m_volume > 1.0)
|
||||
m_volume = 1.0;
|
||||
else if(m_volume < 0.0)
|
||||
m_volume = 0.0;
|
||||
unlock();
|
||||
return true;
|
||||
case AUD_CAPS_SOURCE_VOLUME:
|
||||
{
|
||||
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
|
||||
lock();
|
||||
if(isValid(caps->handle))
|
||||
{
|
||||
AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
|
||||
handle->volume = caps->value;
|
||||
if(handle->volume > 1.0)
|
||||
handle->volume = 1.0;
|
||||
else if(handle->volume < 0.0)
|
||||
handle->volume = 0.0;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::getCapability(int capability, void *value)
|
||||
{
|
||||
switch(capability)
|
||||
{
|
||||
case AUD_CAPS_VOLUME:
|
||||
lock();
|
||||
*((float*)value) = m_volume;
|
||||
unlock();
|
||||
return true;
|
||||
case AUD_CAPS_SOURCE_VOLUME:
|
||||
{
|
||||
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
|
||||
lock();
|
||||
if(isValid(caps->handle))
|
||||
{
|
||||
caps->value = ((AUD_SoftwareHandle*)caps->handle)->volume;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
137
intern/audaspace/intern/AUD_SoftwareDevice.h
Normal file
137
intern/audaspace/intern/AUD_SoftwareDevice.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SOFTWAREDEVICE
|
||||
#define AUD_SOFTWAREDEVICE
|
||||
|
||||
#include "AUD_IDevice.h"
|
||||
struct AUD_SoftwareHandle;
|
||||
class AUD_IMixer;
|
||||
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* This device plays is a generic device with software mixing.
|
||||
* Classes implementing this have to:
|
||||
* - Implement the playing function.
|
||||
* - Prepare the m_specs, m_mixer variables.
|
||||
* - Call the create and destroy functions.
|
||||
* - Call the mix function to retrieve their audio data.
|
||||
*/
|
||||
class AUD_SoftwareDevice : public AUD_IDevice
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* The specification of the device.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
/**
|
||||
* The mixer. Will be deleted by the destroy function.
|
||||
*/
|
||||
AUD_IMixer* m_mixer;
|
||||
|
||||
/**
|
||||
* Initializes member variables.
|
||||
*/
|
||||
void create();
|
||||
|
||||
/**
|
||||
* Uninitializes member variables.
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
/**
|
||||
* Mixes the next samples into the buffer.
|
||||
* \param buffer The target buffer.
|
||||
* \param length The length in samples to be filled.
|
||||
*/
|
||||
void mix(sample_t* buffer, int length);
|
||||
|
||||
/**
|
||||
* This function tells the device, to start or pause playback.
|
||||
* \param playing True if device should playback.
|
||||
*/
|
||||
virtual void playing(bool playing)=0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The list of sounds that are currently playing.
|
||||
*/
|
||||
std::list<AUD_SoftwareHandle*>* m_playingSounds;
|
||||
|
||||
/**
|
||||
* The list of sounds that are currently paused.
|
||||
*/
|
||||
std::list<AUD_SoftwareHandle*>* m_pausedSounds;
|
||||
|
||||
/**
|
||||
* Whether there is currently playback.
|
||||
*/
|
||||
bool m_playback;
|
||||
|
||||
/**
|
||||
* The mutex for locking.
|
||||
*/
|
||||
pthread_mutex_t m_mutex;
|
||||
|
||||
/**
|
||||
* The overall volume of the device.
|
||||
*/
|
||||
float m_volume;
|
||||
|
||||
/**
|
||||
* Checks if a handle is valid.
|
||||
* \param handle The handle to check.
|
||||
* \return Whether the handle is valid.
|
||||
*/
|
||||
bool isValid(AUD_Handle* handle);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Sets a new mixer.
|
||||
* \param mixer The new mixer.
|
||||
*/
|
||||
void setMixer(AUD_IMixer* mixer);
|
||||
|
||||
virtual AUD_Specs getSpecs();
|
||||
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
|
||||
virtual bool pause(AUD_Handle* handle);
|
||||
virtual bool resume(AUD_Handle* handle);
|
||||
virtual bool stop(AUD_Handle* handle);
|
||||
virtual bool setKeep(AUD_Handle* handle, bool keep);
|
||||
virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
|
||||
virtual bool seek(AUD_Handle* handle, float position);
|
||||
virtual float getPosition(AUD_Handle* handle);
|
||||
virtual AUD_Status getStatus(AUD_Handle* handle);
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
virtual bool checkCapability(int capability);
|
||||
virtual bool setCapability(int capability, void *value);
|
||||
virtual bool getCapability(int capability, void *value);
|
||||
};
|
||||
|
||||
#endif //AUD_SOFTWAREDEVICE
|
||||
41
intern/audaspace/intern/AUD_SourceCaps.h
Normal file
41
intern/audaspace/intern/AUD_SourceCaps.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SOURCECAPS
|
||||
#define AUD_SOURCECAPS
|
||||
|
||||
#include "AUD_IDevice.h"
|
||||
|
||||
/// The structure for source capabilities.
|
||||
typedef struct
|
||||
{
|
||||
/// The source to apply the capability on.
|
||||
AUD_Handle* handle;
|
||||
|
||||
/// The value for the capability.
|
||||
float value;
|
||||
} AUD_SourceCaps;
|
||||
|
||||
#endif //AUD_SOURCECAPS
|
||||
294
intern/audaspace/intern/AUD_Space.h
Normal file
294
intern/audaspace/intern/AUD_Space.h
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_SPACE
|
||||
#define AUD_SPACE
|
||||
|
||||
/// The size of a format in bytes.
|
||||
#define AUD_FORMAT_SIZE(format) (format & 0x0F)
|
||||
/// The size of a sample in the specified format in bytes.
|
||||
#define AUD_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
|
||||
/// Throws a AUD_Exception with the provided error code.
|
||||
#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
|
||||
|
||||
/// Returns the smaller of the two values.
|
||||
#define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
/// Returns the bigger of the two values.
|
||||
#define AUD_MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
// 5 sec * 44100 samples/sec * 4 bytes/sample * 6 channels
|
||||
/// The size by which a buffer should be resized if the final extent is unknown.
|
||||
#define AUD_BUFFER_RESIZE_BYTES 5292000
|
||||
|
||||
/// The default playback buffer size of a device.
|
||||
#define AUD_DEFAULT_BUFFER_SIZE 1024
|
||||
|
||||
// Capability defines
|
||||
|
||||
/// This capability checks whether a device is a 3D device. See AUD_I3DDevice.h.
|
||||
#define AUD_CAPS_3D_DEVICE 0x0001
|
||||
|
||||
/**
|
||||
* This capability checks whether a device is a software device. See
|
||||
* AUD_SoftwareDevice.
|
||||
*/
|
||||
#define AUD_CAPS_SOFTWARE_DEVICE 0x0002
|
||||
|
||||
/**
|
||||
* This capability enables the user to set the overall volume of the device.
|
||||
* You can set and get it with the pointer pointing to a float value between
|
||||
* 0.0 (muted) and 1.0 (maximum volume).
|
||||
*/
|
||||
#define AUD_CAPS_VOLUME 0x0101
|
||||
|
||||
/**
|
||||
* This capability enables the user to set the volume of a source.
|
||||
* You can set and get it with the pointer pointing to a AUD_SourceValue
|
||||
* structure defined in AUD_SourceCaps.h.
|
||||
*/
|
||||
#define AUD_CAPS_SOURCE_VOLUME 0x1001
|
||||
|
||||
/**
|
||||
* This capability enables the user to set the pitch of a source.
|
||||
* You can set and get it with the pointer pointing to a AUD_SourceValue
|
||||
* structure defined in AUD_SourceCaps.h.
|
||||
*/
|
||||
#define AUD_CAPS_SOURCE_PITCH 0x1002
|
||||
|
||||
/**
|
||||
* This capability enables the user to buffer a factory into the device.
|
||||
* Setting with the factory as pointer loads the factory into a device internal
|
||||
* buffer. Play function calls with the buffered factory as argument result in
|
||||
* the internal buffer being played back, so there's no reader created, what
|
||||
* also results in not being able to send messages to that handle.
|
||||
* A repeated call with the same factory doesn't do anything.
|
||||
* A set call with a NULL pointer results in all buffered factories being
|
||||
* deleted.
|
||||
* \note This is only possible with factories that create readers of the buffer
|
||||
* type.
|
||||
*/
|
||||
#define AUD_CAPS_BUFFERED_FACTORY 0x2001
|
||||
|
||||
// Used for debugging memory leaks.
|
||||
//#define AUD_DEBUG_MEMORY
|
||||
|
||||
#ifdef AUD_DEBUG_MEMORY
|
||||
int AUD_References(int count = 0, const char* text = "");
|
||||
#define AUD_NEW(text) AUD_References(1, text);
|
||||
#define AUD_DELETE(text) AUD_References(-1, text);
|
||||
#else
|
||||
#define AUD_NEW(text)
|
||||
#define AUD_DELETE(text)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The format of a sample.
|
||||
* The last 4 bit save the byte count of the format.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUD_FORMAT_INVALID = 0x00, /// Invalid sample format.
|
||||
AUD_FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
|
||||
AUD_FORMAT_S16 = 0x12, /// 2 byte signed integer.
|
||||
AUD_FORMAT_S24 = 0x13, /// 3 byte signed integer.
|
||||
AUD_FORMAT_S32 = 0x14, /// 4 byte signed integer.
|
||||
AUD_FORMAT_FLOAT32 = 0x24, /// 4 byte float.
|
||||
AUD_FORMAT_FLOAT64 = 0x28 /// 8 byte float.
|
||||
} AUD_SampleFormat;
|
||||
|
||||
/// The channel count.
|
||||
typedef enum
|
||||
{
|
||||
AUD_CHANNELS_INVALID = 0, /// Invalid channel count.
|
||||
AUD_CHANNELS_MONO = 1, /// Mono.
|
||||
AUD_CHANNELS_STEREO = 2, /// Stereo.
|
||||
AUD_CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
|
||||
AUD_CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
|
||||
AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
|
||||
AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
|
||||
AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
|
||||
AUD_CHANNELS_SURROUND71 = 8, /// 7.1 surround sound.
|
||||
AUD_CHANNELS_SURROUND72 = 9 /// 7.2 surround sound.
|
||||
} AUD_Channels;
|
||||
|
||||
/**
|
||||
* The sample rate tells how many samples are played back within one second.
|
||||
* Some exotic formats may use other sample rates than provided here.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUD_RATE_INVALID = 0, /// Invalid sample rate.
|
||||
AUD_RATE_8000 = 8000, /// 8000 Hz.
|
||||
AUD_RATE_16000 = 16000, /// 16000 Hz.
|
||||
AUD_RATE_11025 = 11025, /// 11025 Hz.
|
||||
AUD_RATE_22050 = 22050, /// 22050 Hz.
|
||||
AUD_RATE_32000 = 32000, /// 32000 Hz.
|
||||
AUD_RATE_44100 = 44100, /// 44100 Hz.
|
||||
AUD_RATE_48000 = 48000, /// 48000 Hz.
|
||||
AUD_RATE_88200 = 88200, /// 88200 Hz.
|
||||
AUD_RATE_96000 = 96000, /// 96000 Hz.
|
||||
AUD_RATE_192000 = 192000 /// 192000 Hz.
|
||||
} AUD_SampleRate;
|
||||
|
||||
/**
|
||||
* Type of a reader.
|
||||
* @see AUD_IReader for details.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUD_TYPE_INVALID = 0, /// Invalid reader type.
|
||||
AUD_TYPE_BUFFER, /// Reader reads from a buffer.
|
||||
AUD_TYPE_STREAM /// Reader reads from a stream.
|
||||
} AUD_ReaderType;
|
||||
|
||||
/// Status of a playback handle.
|
||||
typedef enum
|
||||
{
|
||||
AUD_STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
|
||||
AUD_STATUS_PLAYING, /// Sound is playing.
|
||||
AUD_STATUS_PAUSED /// Sound is being paused.
|
||||
} AUD_Status;
|
||||
|
||||
/// Error codes for exceptions (C++ library) or for return values (C API).
|
||||
typedef enum
|
||||
{
|
||||
AUD_NO_ERROR = 0,
|
||||
AUD_ERROR_READER,
|
||||
AUD_ERROR_FACTORY,
|
||||
AUD_ERROR_FILE,
|
||||
AUD_ERROR_FFMPEG,
|
||||
AUD_ERROR_SDL,
|
||||
AUD_ERROR_OPENAL
|
||||
} AUD_Error;
|
||||
|
||||
/// Message codes.
|
||||
typedef enum
|
||||
{
|
||||
AUD_MSG_INVALID = 0, /// Invalid message.
|
||||
AUD_MSG_LOOP, /// Loop reader message.
|
||||
AUD_MSG_VOLUME /// Volume reader message.
|
||||
} AUD_MessageType;
|
||||
|
||||
/// Fading types.
|
||||
typedef enum
|
||||
{
|
||||
AUD_FADE_IN,
|
||||
AUD_FADE_OUT
|
||||
} AUD_FadeType;
|
||||
|
||||
/// 3D device settings.
|
||||
typedef enum
|
||||
{
|
||||
AUD_3DS_NONE, /// No setting.
|
||||
AUD_3DS_SPEED_OF_SOUND, /// Speed of sound.
|
||||
AUD_3DS_DOPPLER_FACTOR, /// Doppler factor.
|
||||
AUD_3DS_DISTANCE_MODEL /// Distance model.
|
||||
} AUD_3DSetting;
|
||||
|
||||
/// Possible distance models for the 3D device.
|
||||
#define AUD_DISTANCE_MODEL_NONE 0.0f
|
||||
#define AUD_DISTANCE_MODEL_INVERSE 1.0f
|
||||
#define AUD_DISTANCE_MODEL_INVERSE_CLAMPED 2.0f
|
||||
#define AUD_DISTANCE_MODEL_LINEAR 3.0f
|
||||
#define AUD_DISTANCE_MODEL_LINEAR_CLAMPED 4.0f
|
||||
#define AUD_DISTANCE_MODEL_EXPONENT 5.0f
|
||||
#define AUD_DISTANCE_MODEL_EXPONENT_CLAMPED 6.0f
|
||||
|
||||
/// 3D source settings.
|
||||
typedef enum
|
||||
{
|
||||
AUD_3DSS_NONE, /// No setting.
|
||||
AUD_3DSS_IS_RELATIVE, /// > 0 tells that the sound source is
|
||||
/// relative to the listener
|
||||
AUD_3DSS_MIN_GAIN, /// Minimum gain.
|
||||
AUD_3DSS_MAX_GAIN, /// Maximum gain.
|
||||
AUD_3DSS_REFERENCE_DISTANCE, /// Reference distance.
|
||||
AUD_3DSS_MAX_DISTANCE, /// Maximum distance.
|
||||
AUD_3DSS_ROLLOFF_FACTOR, /// Rolloff factor.
|
||||
AUD_3DSS_CONE_INNER_ANGLE, /// Cone inner angle.
|
||||
AUD_3DSS_CONE_OUTER_ANGLE, /// Cone outer angle.
|
||||
AUD_3DSS_CONE_OUTER_GAIN /// Cone outer gain.
|
||||
} AUD_3DSourceSetting;
|
||||
|
||||
/// Sample pointer type.
|
||||
typedef unsigned char sample_t;
|
||||
|
||||
/// Specification of a sound source or device.
|
||||
typedef struct
|
||||
{
|
||||
/// Sample rate in Hz.
|
||||
AUD_SampleRate rate;
|
||||
|
||||
/// Sample format.
|
||||
AUD_SampleFormat format;
|
||||
|
||||
/// Channel count.
|
||||
AUD_Channels channels;
|
||||
} AUD_Specs;
|
||||
|
||||
/// Exception structure.
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Error code.
|
||||
* \see AUD_Error
|
||||
*/
|
||||
AUD_Error error;
|
||||
|
||||
// void* userData; - for the case it is needed someday
|
||||
} AUD_Exception;
|
||||
|
||||
/// Message structure.
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* The message type.
|
||||
*/
|
||||
AUD_MessageType type;
|
||||
|
||||
union
|
||||
{
|
||||
// loop reader
|
||||
int loopcount;
|
||||
|
||||
// volume reader
|
||||
float volume;
|
||||
};
|
||||
} AUD_Message;
|
||||
|
||||
/// Handle structure, for inherition.
|
||||
typedef struct
|
||||
{
|
||||
/// x, y and z coordinates of the object.
|
||||
float position[3];
|
||||
|
||||
/// x, y and z coordinates telling the velocity and direction of the object.
|
||||
float velocity[3];
|
||||
|
||||
/// 3x3 matrix telling the orientation of the object.
|
||||
float orientation[9];
|
||||
} AUD_3DData;
|
||||
|
||||
#endif //AUD_SPACE
|
||||
80
intern/audaspace/intern/AUD_StreamBufferFactory.cpp
Normal file
80
intern/audaspace/intern/AUD_StreamBufferFactory.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_StreamBufferFactory.h"
|
||||
#include "AUD_BufferReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
|
||||
{
|
||||
AUD_IReader* reader = factory->createReader();
|
||||
|
||||
if(reader == NULL)
|
||||
AUD_THROW(AUD_ERROR_READER);
|
||||
|
||||
m_specs = reader->getSpecs();
|
||||
m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer()); AUD_NEW("buffer")
|
||||
|
||||
int sample_size = AUD_SAMPLE_SIZE(m_specs);
|
||||
int length;
|
||||
int index = 0;
|
||||
sample_t* buffer;
|
||||
|
||||
// get an aproximated size if possible
|
||||
int size = reader->getLength();
|
||||
|
||||
if(size <= 0)
|
||||
size = AUD_BUFFER_RESIZE_BYTES / sample_size;
|
||||
else
|
||||
size += m_specs.rate;
|
||||
|
||||
// as long as we fill our buffer to the end
|
||||
while(index == m_buffer.get()->getSize() / sample_size)
|
||||
{
|
||||
// increase
|
||||
m_buffer.get()->resize(size*sample_size, true);
|
||||
|
||||
// read more
|
||||
length = size-index;
|
||||
reader->read(length, buffer);
|
||||
memcpy(m_buffer.get()->getBuffer()+index*sample_size,
|
||||
buffer,
|
||||
length*sample_size);
|
||||
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
|
||||
index += length;
|
||||
}
|
||||
|
||||
m_buffer.get()->resize(index*sample_size, true);
|
||||
delete reader; AUD_DELETE("reader")
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_StreamBufferFactory::createReader()
|
||||
{
|
||||
AUD_IReader* reader = new AUD_BufferReader(m_buffer, m_specs);
|
||||
AUD_NEW("reader")
|
||||
return reader;
|
||||
}
|
||||
62
intern/audaspace/intern/AUD_StreamBufferFactory.h
Normal file
62
intern/audaspace/intern/AUD_StreamBufferFactory.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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_STREAMBUFFERFACTORY
|
||||
#define AUD_STREAMBUFFERFACTORY
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
#include "AUD_Reference.h"
|
||||
class AUD_Buffer;
|
||||
|
||||
/**
|
||||
* This factory creates a buffer out of a reader. This way normally streamed
|
||||
* sound sources can be loaded into memory for buffered playback.
|
||||
*/
|
||||
class AUD_StreamBufferFactory : public AUD_IFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The buffer that holds the audio data.
|
||||
*/
|
||||
AUD_Reference<AUD_Buffer> m_buffer;
|
||||
|
||||
/**
|
||||
* The specification of the samples.
|
||||
*/
|
||||
AUD_Specs m_specs;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates the factory and reads the reader created by the factory supplied
|
||||
* to the buffer.
|
||||
* \param factory The factory that creates the reader for buffering.
|
||||
* \exception AUD_Exception Thrown if the reader cannot be created.
|
||||
*/
|
||||
AUD_StreamBufferFactory(AUD_IFactory* factory);
|
||||
|
||||
virtual AUD_IReader* createReader();
|
||||
};
|
||||
|
||||
#endif //AUD_STREAMBUFFERFACTORY
|
||||
41
intern/audaspace/intern/Makefile
Normal file
41
intern/audaspace/intern/Makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# $Id: Makefile 19820 2009-04-20 15:06:46Z blendix $
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
#
|
||||
|
||||
LIBNAME = audaspace
|
||||
DIR = $(OCGDIR)/intern/audaspace
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I../ffmpeg
|
||||
CPPFLAGS += -I../SDL
|
||||
CPPFLAGS += -I..
|
||||
CPPFLAGS += -I.
|
||||
@@ -34,7 +34,6 @@
|
||||
#define RET_OK 0
|
||||
#define RET_ERROR 1
|
||||
|
||||
struct bSample;
|
||||
struct bSound;
|
||||
struct Image;
|
||||
struct Main;
|
||||
@@ -51,7 +50,7 @@ void packAll(struct Main *bmain, struct ReportList *reports);
|
||||
/* unpack */
|
||||
char *unpackFile(struct ReportList *reports, char *abs_name, char *local_name, struct PackedFile *pf, int how);
|
||||
int unpackVFont(struct ReportList *reports, struct VFont *vfont, int how);
|
||||
int unpackSample(struct ReportList *reports, struct bSample *sample, int how);
|
||||
int unpackSound(struct ReportList *reports, struct bSound *sound, int how);
|
||||
int unpackImage(struct ReportList *reports, struct Image *ima, int how);
|
||||
void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ struct Strip;
|
||||
struct StripElem;
|
||||
struct ImBuf;
|
||||
struct Scene;
|
||||
struct bContext;
|
||||
|
||||
#define MAXSEQ 32
|
||||
|
||||
@@ -44,7 +45,6 @@ struct Scene;
|
||||
#define BUILD_SEQAR_COUNT_CURRENT 1
|
||||
#define BUILD_SEQAR_COUNT_CHILDREN 2
|
||||
|
||||
|
||||
/* sequence iterator */
|
||||
|
||||
typedef struct SeqIterator {
|
||||
@@ -137,9 +137,9 @@ struct SeqEffectHandle {
|
||||
/* sequence.c */
|
||||
|
||||
// extern
|
||||
void seq_free_sequence(struct Editing *ed, struct Sequence *seq);
|
||||
void seq_free_sequence(struct Scene *scene, struct Sequence *seq);
|
||||
void seq_free_strip(struct Strip *strip);
|
||||
void seq_free_editing(struct Editing *ed);
|
||||
void seq_free_editing(struct Scene *scene);
|
||||
struct Editing *seq_give_editing(struct Scene *scene, int alloc);
|
||||
char *give_seqname(struct Sequence *seq);
|
||||
struct ImBuf *give_ibuf_seq(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size);
|
||||
@@ -183,3 +183,4 @@ int seq_test_overlap(struct ListBase * seqbasep, struct Sequence *test);
|
||||
int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test);
|
||||
void free_imbuf_seq(struct ListBase * seqbasep, int check_mem_usage);
|
||||
|
||||
void seq_update_sound(struct Sequence *seq);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* sound.h (mar-2001 nzc)
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -33,20 +33,47 @@
|
||||
|
||||
struct PackedFile;
|
||||
struct bSound;
|
||||
struct bSample;
|
||||
struct bContext;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
|
||||
/* bad bad global... */
|
||||
extern struct ListBase *samples;
|
||||
void sound_init();
|
||||
|
||||
void sound_free_all_samples(void);
|
||||
void sound_reinit(struct bContext *C);
|
||||
|
||||
/* void *sound_get_listener(void); implemented in src!also declared there now */
|
||||
void sound_exit();
|
||||
|
||||
void sound_set_packedfile(struct bSample* sample, struct PackedFile* pf);
|
||||
struct PackedFile* sound_find_packedfile(struct bSound* sound);
|
||||
void sound_free_sample(struct bSample* sample);
|
||||
void sound_free_sound(struct bSound* sound);
|
||||
struct bSound* sound_new_file(struct Main *main, char* filename);
|
||||
|
||||
// XXX unused currently
|
||||
#if 0
|
||||
struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source);
|
||||
|
||||
struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, float start, float end);
|
||||
#endif
|
||||
|
||||
void sound_delete(struct bContext *C, struct bSound* sound);
|
||||
|
||||
void sound_cache(struct bSound* sound, int ignore);
|
||||
|
||||
void sound_load(struct bSound* sound);
|
||||
|
||||
void sound_free(struct bSound* sound);
|
||||
|
||||
void sound_unlink(struct bContext *C, struct bSound* sound);
|
||||
|
||||
struct SoundHandle* sound_new_handle(struct Scene *scene, struct bSound* sound, int startframe, int endframe, int frameskip);
|
||||
|
||||
void sound_delete_handle(struct Scene *scene, struct SoundHandle *handle);
|
||||
|
||||
void sound_update_playing(struct bContext *C);
|
||||
|
||||
void sound_scrub(struct bContext *C);
|
||||
|
||||
#ifdef AUD_CAPI
|
||||
AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end);
|
||||
#endif
|
||||
|
||||
void sound_stop_all(struct bContext *C);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,13 +37,14 @@ extern "C" {
|
||||
/* generic blender movie support, could move to own module */
|
||||
|
||||
struct RenderData;
|
||||
void start_avi(struct RenderData *rd, int rectx, int recty);
|
||||
struct Scene;
|
||||
void start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
||||
void end_avi(void);
|
||||
void append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
||||
void makeavistring (struct RenderData *rd, char *string);
|
||||
|
||||
typedef struct bMovieHandle {
|
||||
void (*start_movie)(struct RenderData *rd, int rectx, int recty);
|
||||
void (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
||||
void (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
||||
void (*end_movie)(void);
|
||||
int (*get_next_frame)(struct RenderData *rd); /* optional */
|
||||
|
||||
@@ -57,8 +57,9 @@ extern "C" {
|
||||
|
||||
struct IDProperty;
|
||||
struct RenderData;
|
||||
struct Scene;
|
||||
|
||||
extern void start_ffmpeg(struct RenderData *rd, int rectx, int recty);
|
||||
extern void start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
||||
extern void end_ffmpeg(void);
|
||||
extern void append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
||||
|
||||
|
||||
@@ -33,8 +33,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct RenderData;
|
||||
struct Scene;
|
||||
|
||||
extern void start_frameserver(struct RenderData *rd, int rectx, int recty);
|
||||
extern void start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
||||
extern void end_frameserver(void);
|
||||
extern void append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
||||
extern int frameserver_loop(struct RenderData *rd);
|
||||
|
||||
@@ -34,6 +34,7 @@ SET(INC
|
||||
../../../extern/bullet2/src
|
||||
../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern
|
||||
../../../intern/bsp/extern
|
||||
../../../intern/audaspace
|
||||
${ZLIB_INC}
|
||||
)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ incs += ' #/extern/bullet2/src'
|
||||
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
|
||||
incs += ' ../gpu #/extern/glew/include'
|
||||
incs += ' #/intern/smoke/extern'
|
||||
incs += ' #/intern/audaspace'
|
||||
|
||||
incs += ' ' + env['BF_OPENGL_INC']
|
||||
incs += ' ' + env['BF_ZLIB_INC']
|
||||
|
||||
@@ -176,8 +176,6 @@ void pushpop_test()
|
||||
void free_blender(void)
|
||||
{
|
||||
/* samples are in a global list..., also sets G.main->sound->sample NULL */
|
||||
sound_free_all_samples();
|
||||
|
||||
free_main(G.main);
|
||||
G.main= NULL;
|
||||
|
||||
@@ -330,9 +328,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
|
||||
MEM_freeN(bfd->user);
|
||||
}
|
||||
|
||||
/* samples is a global list... */
|
||||
sound_free_all_samples();
|
||||
|
||||
/* case G_FILE_NO_UI or no screens in file */
|
||||
if(mode) {
|
||||
/* leave entire context further unaltered? */
|
||||
|
||||
@@ -567,7 +567,7 @@ void free_libblock(ListBase *lb, void *idv)
|
||||
//XXX free_script((Script *)id);
|
||||
break;
|
||||
case ID_SO:
|
||||
sound_free_sound((bSound *)id);
|
||||
sound_free((bSound*)id);
|
||||
break;
|
||||
case ID_GR:
|
||||
free_group((Group *)id);
|
||||
|
||||
@@ -123,7 +123,7 @@ int countPackedFiles(Main *bmain)
|
||||
{
|
||||
Image *ima;
|
||||
VFont *vf;
|
||||
bSample *sample;
|
||||
bSound *sound;
|
||||
int count = 0;
|
||||
|
||||
// let's check if there are packed files...
|
||||
@@ -135,10 +135,9 @@ int countPackedFiles(Main *bmain)
|
||||
if(vf->packedfile)
|
||||
count++;
|
||||
|
||||
if(samples)
|
||||
for(sample=samples->first; sample; sample=sample->id.next)
|
||||
if(sample->packedfile)
|
||||
count++;
|
||||
for(sound=bmain->sound.first; sound; sound=sound->id.next)
|
||||
if(sound->packedfile)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -208,8 +207,8 @@ void packAll(Main *bmain, ReportList *reports)
|
||||
{
|
||||
Image *ima;
|
||||
VFont *vf;
|
||||
bSample *sample;
|
||||
|
||||
bSound *sound;
|
||||
|
||||
for(ima=bmain->image.first; ima; ima=ima->id.next)
|
||||
if(ima->packedfile == NULL)
|
||||
ima->packedfile = newPackedFile(reports, ima->name);
|
||||
@@ -218,10 +217,9 @@ void packAll(Main *bmain, ReportList *reports)
|
||||
if(vf->packedfile == NULL)
|
||||
vf->packedfile = newPackedFile(reports, vf->name);
|
||||
|
||||
if(samples)
|
||||
for(sample=samples->first; sample; sample=sample->id.next)
|
||||
if(sample->packedfile == NULL)
|
||||
sound_set_packedfile(sample, newPackedFile(reports, sample->name));
|
||||
for(sound=bmain->sound.first; sound; sound=sound->id.next)
|
||||
if(sound->packedfile == NULL)
|
||||
sound->packedfile = newPackedFile(reports, sound->name);
|
||||
}
|
||||
|
||||
|
||||
@@ -456,28 +454,26 @@ int unpackVFont(ReportList *reports, VFont *vfont, int how)
|
||||
return (ret_value);
|
||||
}
|
||||
|
||||
int unpackSample(ReportList *reports, bSample *sample, int how)
|
||||
int unpackSound(ReportList *reports, bSound *sound, int how)
|
||||
{
|
||||
char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
|
||||
char *newname;
|
||||
int ret_value = RET_ERROR;
|
||||
PackedFile *pf;
|
||||
|
||||
if (sample != NULL) {
|
||||
strcpy(localname, sample->name);
|
||||
|
||||
if (sound != NULL) {
|
||||
strcpy(localname, sound->name);
|
||||
BLI_splitdirstring(localname, fi);
|
||||
sprintf(localname, "//samples/%s", fi);
|
||||
|
||||
newname = unpackFile(reports, sample->name, localname, sample->packedfile, how);
|
||||
sprintf(localname, "//sounds/%s", fi);
|
||||
|
||||
newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
|
||||
if (newname != NULL) {
|
||||
strcpy(sample->name, newname);
|
||||
strcpy(sound->name, newname);
|
||||
MEM_freeN(newname);
|
||||
|
||||
pf = sample->packedfile;
|
||||
// because samples and sounds can point to the
|
||||
// same packedfile we have to check them all
|
||||
sound_set_packedfile(sample, NULL);
|
||||
freePackedFile(pf);
|
||||
freePackedFile(sound->packedfile);
|
||||
sound->packedfile = 0;
|
||||
|
||||
sound_load(sound);
|
||||
|
||||
ret_value = RET_OK;
|
||||
}
|
||||
@@ -515,7 +511,7 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
|
||||
{
|
||||
Image *ima;
|
||||
VFont *vf;
|
||||
bSample *sample;
|
||||
bSound *sound;
|
||||
|
||||
for(ima=bmain->image.first; ima; ima=ima->id.next)
|
||||
if(ima->packedfile)
|
||||
@@ -525,9 +521,8 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
|
||||
if(vf->packedfile)
|
||||
unpackVFont(reports, vf, how);
|
||||
|
||||
if(samples)
|
||||
for(sample=samples->first; sample; sample=sample->id.next)
|
||||
if(sample->packedfile)
|
||||
unpackSample(reports, sample, how);
|
||||
for(sound=bmain->sound.first; sound; sound=sound->id.next)
|
||||
if(sound->packedfile)
|
||||
unpackSound(reports, sound, how);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_text_types.h"
|
||||
@@ -410,6 +412,7 @@ void init_actuator(bActuator *act)
|
||||
{
|
||||
/* also use when actuator changes type */
|
||||
bObjectActuator *oa;
|
||||
bSoundActuator *sa;
|
||||
|
||||
if(act->data) MEM_freeN(act->data);
|
||||
act->data= 0;
|
||||
@@ -422,7 +425,14 @@ void init_actuator(bActuator *act)
|
||||
break;
|
||||
#endif
|
||||
case ACT_SOUND:
|
||||
act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
|
||||
sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
|
||||
sa->volume = 1.0f;
|
||||
sa->sound3D.rolloff_factor = 1.0f;
|
||||
sa->sound3D.reference_distance = 1.0f;
|
||||
sa->sound3D.max_gain = 1.0f;
|
||||
sa->sound3D.cone_inner_angle = 360.0f;
|
||||
sa->sound3D.cone_outer_angle = 360.0f;
|
||||
sa->sound3D.max_distance = FLT_MAX;
|
||||
break;
|
||||
case ACT_CD:
|
||||
act->data= MEM_callocN(sizeof(bCDActuator), "cdact");
|
||||
|
||||
@@ -140,7 +140,7 @@ void free_scene(Scene *sce)
|
||||
/* do not free objects! */
|
||||
|
||||
BLI_freelistN(&sce->base);
|
||||
seq_free_editing(sce->ed);
|
||||
seq_free_editing(sce);
|
||||
|
||||
BKE_free_animdata((ID *)sce);
|
||||
BKE_keyingsets_free(&sce->keyingsets);
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
#include "BLI_threads.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_sound.h"
|
||||
#include "AUD_C-API.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
@@ -178,12 +182,16 @@ void seq_free_strip(Strip *strip)
|
||||
MEM_freeN(strip);
|
||||
}
|
||||
|
||||
void seq_free_sequence(Editing *ed, Sequence *seq)
|
||||
void seq_free_sequence(Scene *scene, Sequence *seq)
|
||||
{
|
||||
Editing *ed = scene->ed;
|
||||
|
||||
if(seq->strip) seq_free_strip(seq->strip);
|
||||
|
||||
if(seq->anim) IMB_free_anim(seq->anim);
|
||||
//XXX if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
|
||||
|
||||
if(seq->sound_handle)
|
||||
sound_delete_handle(scene, seq->sound_handle);
|
||||
|
||||
if (seq->type & SEQ_EFFECT) {
|
||||
struct SeqEffectHandle sh = get_sequence_effect(seq);
|
||||
@@ -208,8 +216,9 @@ Editing *seq_give_editing(Scene *scene, int alloc)
|
||||
return scene->ed;
|
||||
}
|
||||
|
||||
void seq_free_editing(Editing *ed)
|
||||
void seq_free_editing(Scene *scene)
|
||||
{
|
||||
Editing *ed = scene->ed;
|
||||
MetaStack *ms;
|
||||
Sequence *seq;
|
||||
|
||||
@@ -217,7 +226,7 @@ void seq_free_editing(Editing *ed)
|
||||
return;
|
||||
|
||||
SEQ_BEGIN(ed, seq) {
|
||||
seq_free_sequence(ed, seq);
|
||||
seq_free_sequence(scene, seq);
|
||||
}
|
||||
SEQ_END
|
||||
|
||||
@@ -444,6 +453,8 @@ void calc_sequence_disp(Sequence *seq)
|
||||
else if(seq->enddisp-seq->startdisp > 250) {
|
||||
seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
|
||||
}
|
||||
|
||||
seq_update_sound(seq);
|
||||
}
|
||||
|
||||
void calc_sequence(Sequence *seq)
|
||||
@@ -515,8 +526,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
|
||||
if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
|
||||
seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND ||
|
||||
seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
|
||||
seq->type == SEQ_SOUND ||
|
||||
seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -558,23 +569,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
|
||||
seq->len = 0;
|
||||
}
|
||||
seq->strip->len = seq->len;
|
||||
} else if (seq->type == SEQ_HD_SOUND) {
|
||||
// XXX if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
|
||||
// seq->hdaudio = sound_open_hdaudio(str);
|
||||
|
||||
if (!seq->hdaudio) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS) - seq->anim_startofs - seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
seq->len = 0;
|
||||
}
|
||||
seq->strip->len = seq->len;
|
||||
} else if (seq->type == SEQ_RAM_SOUND) {
|
||||
seq->len = (int) ( ((float)(seq->sound->streamlen-1)/
|
||||
((float)scene->audio.mixrate*4.0 ))
|
||||
* FPS);
|
||||
} else if (seq->type == SEQ_SOUND) {
|
||||
seq->len = AUD_getInfo(seq->sound->snd_sound).length * FPS;
|
||||
seq->len -= seq->anim_startofs;
|
||||
seq->len -= seq->anim_endofs;
|
||||
if (seq->len < 0) {
|
||||
@@ -693,8 +689,7 @@ char *give_seqname_by_type(int type)
|
||||
case SEQ_IMAGE: return "Image";
|
||||
case SEQ_SCENE: return "Scene";
|
||||
case SEQ_MOVIE: return "Movie";
|
||||
case SEQ_RAM_SOUND: return "Audio (RAM)";
|
||||
case SEQ_HD_SOUND: return "Audio (HD)";
|
||||
case SEQ_SOUND: return "Audio";
|
||||
case SEQ_CROSS: return "Cross";
|
||||
case SEQ_GAMCROSS: return "Gamma Cross";
|
||||
case SEQ_ADD: return "Add";
|
||||
@@ -1071,10 +1066,9 @@ int evaluate_seq_frame(Scene *scene, int cfra)
|
||||
|
||||
static int video_seq_is_rendered(Sequence * seq)
|
||||
{
|
||||
return (seq
|
||||
&& !(seq->flag & SEQ_MUTE)
|
||||
&& seq->type != SEQ_RAM_SOUND
|
||||
&& seq->type != SEQ_HD_SOUND);
|
||||
return (seq
|
||||
&& !(seq->flag & SEQ_MUTE)
|
||||
&& seq->type != SEQ_SOUND);
|
||||
}
|
||||
|
||||
static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
|
||||
@@ -3309,7 +3303,7 @@ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
|
||||
}
|
||||
|
||||
/* sounds cannot be extended past their endpoints */
|
||||
if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
|
||||
if (seq->type == SEQ_SOUND) {
|
||||
seq->startstill= 0;
|
||||
seq->endstill= 0;
|
||||
}
|
||||
@@ -3406,3 +3400,15 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void seq_update_sound(struct Sequence *seq)
|
||||
{
|
||||
if(seq->type == SEQ_SOUND)
|
||||
{
|
||||
seq->sound_handle->startframe = seq->startdisp;
|
||||
seq->sound_handle->endframe = seq->enddisp;
|
||||
seq->sound_handle->frameskip = seq->startofs + seq->anim_startofs;
|
||||
seq->sound_handle->mute = seq->flag & SEQ_MUTE ? 1 : 0;
|
||||
seq->sound_handle->changed = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* sound.c (mar-2001 nzc)
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
@@ -14,125 +14,468 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sound_types.h"
|
||||
#include "DNA_packedFile_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "AUD_C-API.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_packedFile.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
ListBase _samples = {0,0}, *samples = &_samples;
|
||||
|
||||
void sound_free_sound(bSound *sound)
|
||||
void sound_init()
|
||||
{
|
||||
/* when sounds have been loaded, but not played, the packedfile was not copied
|
||||
to sample block and not freed otherwise */
|
||||
if(sound->sample==NULL) {
|
||||
if (sound->newpackedfile) {
|
||||
freePackedFile(sound->newpackedfile);
|
||||
sound->newpackedfile = NULL;
|
||||
}
|
||||
}
|
||||
if (sound->stream) free(sound->stream);
|
||||
AUD_Specs specs;
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
specs.rate = AUD_RATE_44100;
|
||||
|
||||
if(!AUD_init(AUD_SDL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE))
|
||||
if(!AUD_init(AUD_OPENAL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE*4))
|
||||
AUD_init(AUD_NULL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void sound_free_sample(bSample *sample)
|
||||
void sound_reinit(struct bContext *C)
|
||||
{
|
||||
if (sample) {
|
||||
if (sample->data != &sample->fakedata[0] && sample->data != NULL) {
|
||||
MEM_freeN(sample->data);
|
||||
sample->data = &sample->fakedata[0];
|
||||
}
|
||||
|
||||
if (sample->packedfile) {
|
||||
freePackedFile(sample->packedfile); //FIXME: crashes sometimes
|
||||
sample->packedfile = NULL;
|
||||
}
|
||||
|
||||
if (sample->alindex != SAMPLE_INVALID) {
|
||||
// AUD_free_sample(sample->snd_sample);
|
||||
sample->alindex = SAMPLE_INVALID;
|
||||
}
|
||||
AUD_Specs specs;
|
||||
int device, buffersize;
|
||||
|
||||
sample->type = SAMPLE_INVALID;
|
||||
device = U.audiodevice;
|
||||
buffersize = U.mixbufsize;
|
||||
specs.channels = U.audiochannels;
|
||||
specs.format = U.audioformat;
|
||||
specs.rate = U.audiorate;
|
||||
|
||||
if(buffersize < 128)
|
||||
buffersize = AUD_DEFAULT_BUFFER_SIZE;
|
||||
|
||||
if(specs.rate < AUD_RATE_8000)
|
||||
specs.rate = AUD_RATE_44100;
|
||||
|
||||
if(specs.format <= AUD_FORMAT_INVALID)
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
|
||||
if(specs.channels <= AUD_CHANNELS_INVALID)
|
||||
specs.channels = AUD_CHANNELS_STEREO;
|
||||
|
||||
if(!AUD_init(device, specs, buffersize))
|
||||
AUD_init(AUD_NULL_DEVICE, specs, buffersize);
|
||||
}
|
||||
|
||||
void sound_exit()
|
||||
{
|
||||
AUD_exit();
|
||||
}
|
||||
|
||||
struct bSound* sound_new_file(struct Main *main, char* filename)
|
||||
{
|
||||
bSound* sound = NULL;
|
||||
|
||||
char str[FILE_MAX];
|
||||
int len;
|
||||
|
||||
strcpy(str, filename);
|
||||
BLI_convertstringcode(str, G.sce);
|
||||
|
||||
len = strlen(filename);
|
||||
while(len > 0 && filename[len-1] != '/' && filename[len-1] != '\\')
|
||||
len--;
|
||||
|
||||
sound = alloc_libblock(&main->sound, ID_SO, filename+len);
|
||||
strcpy(sound->name, filename);
|
||||
sound->type = SOUND_TYPE_FILE;
|
||||
|
||||
sound_load(sound);
|
||||
|
||||
if(!sound->snd_sound)
|
||||
{
|
||||
free_libblock(&main->sound, sound);
|
||||
sound = NULL;
|
||||
}
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
// XXX unused currently
|
||||
#if 0
|
||||
struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source)
|
||||
{
|
||||
bSound* sound = NULL;
|
||||
|
||||
char name[25];
|
||||
strcpy(name, "buf_");
|
||||
strcpy(name + 4, source->id.name);
|
||||
|
||||
sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
|
||||
|
||||
sound->child_sound = source;
|
||||
sound->type = SOUND_TYPE_BUFFER;
|
||||
|
||||
sound_load(sound);
|
||||
|
||||
if(!sound->snd_sound)
|
||||
{
|
||||
free_libblock(&CTX_data_main(C)->sound, sound);
|
||||
sound = NULL;
|
||||
}
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, float start, float end)
|
||||
{
|
||||
bSound* sound = NULL;
|
||||
|
||||
char name[25];
|
||||
strcpy(name, "lim_");
|
||||
strcpy(name + 4, source->id.name);
|
||||
|
||||
sound = alloc_libblock(&CTX_data_main(C)->sound, ID_SO, name);
|
||||
|
||||
sound->child_sound = source;
|
||||
sound->start = start;
|
||||
sound->end = end;
|
||||
sound->type = SOUND_TYPE_LIMITER;
|
||||
|
||||
sound_load(sound);
|
||||
|
||||
if(!sound->snd_sound)
|
||||
{
|
||||
free_libblock(&CTX_data_main(C)->sound, sound);
|
||||
sound = NULL;
|
||||
}
|
||||
|
||||
return sound;
|
||||
}
|
||||
#endif
|
||||
|
||||
void sound_delete(struct bContext *C, struct bSound* sound)
|
||||
{
|
||||
if(sound)
|
||||
{
|
||||
sound_free(sound);
|
||||
|
||||
sound_unlink(C, sound);
|
||||
|
||||
free_libblock(&CTX_data_main(C)->sound, sound);
|
||||
}
|
||||
}
|
||||
|
||||
/* this is called after file reading or undos */
|
||||
void sound_free_all_samples(void)
|
||||
void sound_cache(struct bSound* sound, int ignore)
|
||||
{
|
||||
bSample *sample;
|
||||
bSound *sound;
|
||||
|
||||
/* ensure no sample pointers exist, and check packedfile */
|
||||
for(sound= G.main->sound.first; sound; sound= sound->id.next) {
|
||||
if(sound->sample && sound->sample->packedfile==sound->newpackedfile)
|
||||
sound->newpackedfile= NULL;
|
||||
sound->sample= NULL;
|
||||
}
|
||||
|
||||
/* now free samples */
|
||||
for(sample= samples->first; sample; sample= sample->id.next)
|
||||
sound_free_sample(sample);
|
||||
BLI_freelistN(samples);
|
||||
|
||||
if(sound->cache && !ignore)
|
||||
AUD_unload(sound->cache);
|
||||
|
||||
sound->cache = AUD_bufferSound(sound->snd_sound);
|
||||
}
|
||||
|
||||
void sound_set_packedfile(bSample *sample, PackedFile *pf)
|
||||
void sound_load(struct bSound* sound)
|
||||
{
|
||||
bSound *sound;
|
||||
|
||||
if (sample) {
|
||||
sample->packedfile = pf;
|
||||
sound = G.main->sound.first;
|
||||
while (sound) {
|
||||
if (sound->sample == sample) {
|
||||
sound->newpackedfile = pf;
|
||||
if (pf == NULL) {
|
||||
strcpy(sound->name, sample->name);
|
||||
if(sound)
|
||||
{
|
||||
if(sound->snd_sound)
|
||||
{
|
||||
AUD_unload(sound->snd_sound);
|
||||
sound->snd_sound = NULL;
|
||||
}
|
||||
|
||||
switch(sound->type)
|
||||
{
|
||||
case SOUND_TYPE_FILE:
|
||||
{
|
||||
char fullpath[FILE_MAX];
|
||||
char *path;
|
||||
|
||||
/* load sound */
|
||||
PackedFile* pf = sound->packedfile;
|
||||
|
||||
/* dont modify soundact->sound->name, only change a copy */
|
||||
BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
|
||||
|
||||
if(sound->id.lib)
|
||||
path = sound->id.lib->filename;
|
||||
else
|
||||
path = G.sce;
|
||||
|
||||
BLI_convertstringcode(fullpath, path);
|
||||
|
||||
/* but we need a packed file then */
|
||||
if (pf)
|
||||
sound->snd_sound = AUD_loadBuffer((unsigned char*) pf->data, pf->size);
|
||||
/* or else load it from disk */
|
||||
else
|
||||
sound->snd_sound = AUD_load(fullpath);
|
||||
break;
|
||||
}
|
||||
case SOUND_TYPE_BUFFER:
|
||||
if(sound->child_sound && sound->child_sound->snd_sound)
|
||||
sound->snd_sound = AUD_bufferSound(sound->child_sound->snd_sound);
|
||||
break;
|
||||
case SOUND_TYPE_LIMITER:
|
||||
if(sound->child_sound && sound->child_sound->snd_sound)
|
||||
sound->snd_sound = AUD_limitSound(sound->child_sound, sound->start, sound->end);
|
||||
break;
|
||||
}
|
||||
|
||||
if(sound->cache)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sound_free(struct bSound* sound)
|
||||
{
|
||||
if (sound->packedfile)
|
||||
{
|
||||
freePackedFile(sound->packedfile);
|
||||
sound->packedfile = NULL;
|
||||
}
|
||||
|
||||
if(sound->snd_sound)
|
||||
{
|
||||
AUD_unload(sound->snd_sound);
|
||||
sound->snd_sound = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void sound_unlink(struct bContext *C, struct bSound* sound)
|
||||
{
|
||||
bSound *snd;
|
||||
Scene *scene;
|
||||
SoundHandle *handle;
|
||||
|
||||
for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next)
|
||||
{
|
||||
if(snd->child_sound == sound)
|
||||
{
|
||||
snd->child_sound = NULL;
|
||||
if(snd->snd_sound)
|
||||
{
|
||||
AUD_unload(sound->snd_sound);
|
||||
snd->snd_sound = NULL;
|
||||
}
|
||||
|
||||
sound_unlink(C, snd);
|
||||
}
|
||||
}
|
||||
|
||||
for(scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next)
|
||||
{
|
||||
for(handle = scene->sound_handles.first; handle; handle = handle->next)
|
||||
{
|
||||
if(handle->source == sound)
|
||||
{
|
||||
handle->source = NULL;
|
||||
if(handle->handle)
|
||||
AUD_stop(handle->handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SoundHandle* sound_new_handle(struct Scene *scene, struct bSound* sound, int startframe, int endframe, int frameskip)
|
||||
{
|
||||
ListBase* handles = &scene->sound_handles;
|
||||
|
||||
SoundHandle* handle = MEM_callocN(sizeof(SoundHandle), "sound_handle");
|
||||
handle->source = sound;
|
||||
handle->startframe = startframe;
|
||||
handle->endframe = endframe;
|
||||
handle->frameskip = frameskip;
|
||||
handle->state = AUD_STATUS_INVALID;
|
||||
handle->volume = 1.0f;
|
||||
|
||||
BLI_addtail(handles, handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void sound_delete_handle(struct Scene *scene, struct SoundHandle *handle)
|
||||
{
|
||||
if(handle == NULL)
|
||||
return;
|
||||
|
||||
if(handle->handle)
|
||||
AUD_stop(handle->handle);
|
||||
|
||||
BLI_freelinkN(&scene->sound_handles, handle);
|
||||
}
|
||||
|
||||
void sound_stop_all(struct bContext *C)
|
||||
{
|
||||
SoundHandle *handle;
|
||||
|
||||
for(handle = CTX_data_scene(C)->sound_handles.first; handle; handle = handle->next)
|
||||
{
|
||||
if(handle->state == AUD_STATUS_PLAYING)
|
||||
{
|
||||
AUD_pause(handle->handle);
|
||||
handle->state = AUD_STATUS_PAUSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SOUND_PLAYBACK_LAMBDA 1.0
|
||||
|
||||
void sound_update_playing(struct bContext *C)
|
||||
{
|
||||
SoundHandle *handle;
|
||||
Scene* scene = CTX_data_scene(C);
|
||||
int cfra = CFRA;
|
||||
float fps = FPS;
|
||||
int action;
|
||||
|
||||
AUD_lock();
|
||||
|
||||
for(handle = scene->sound_handles.first; handle; handle = handle->next)
|
||||
{
|
||||
if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute)
|
||||
{
|
||||
if(handle->state == AUD_STATUS_PLAYING)
|
||||
{
|
||||
AUD_pause(handle->handle);
|
||||
handle->state = AUD_STATUS_PAUSED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action = 0;
|
||||
|
||||
if(handle->changed != handle->source->changed)
|
||||
{
|
||||
handle->changed = handle->source->changed;
|
||||
action = 3;
|
||||
if(handle->state != AUD_STATUS_INVALID)
|
||||
{
|
||||
AUD_stop(handle->handle);
|
||||
handle->state = AUD_STATUS_INVALID;
|
||||
}
|
||||
}
|
||||
sound = sound->id.next;
|
||||
else
|
||||
{
|
||||
if(handle->state != AUD_STATUS_PLAYING)
|
||||
action = 3;
|
||||
else
|
||||
{
|
||||
handle->state = AUD_getStatus(handle->handle);
|
||||
if(handle->state != AUD_STATUS_PLAYING)
|
||||
action = 3;
|
||||
else
|
||||
{
|
||||
float diff = AUD_getPosition(handle->handle) - (cfra - handle->startframe) / fps;
|
||||
// AUD_XXX float diff = AUD_getPosition(handle->handle) * fps - cfra + handle->startframe
|
||||
if(diff < 0.0)
|
||||
diff = -diff;
|
||||
if(diff > SOUND_PLAYBACK_LAMBDA)
|
||||
// AUD_XXX if(diff > 5.0f)
|
||||
{
|
||||
action = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(action & 1)
|
||||
{
|
||||
if(handle->state == AUD_STATUS_INVALID)
|
||||
{
|
||||
if(handle->source && handle->source->snd_sound)
|
||||
{
|
||||
AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps);
|
||||
handle->handle = AUD_play(limiter, 1);
|
||||
AUD_unload(limiter);
|
||||
if(handle->handle)
|
||||
handle->state = AUD_STATUS_PLAYING;
|
||||
if(cfra == handle->startframe)
|
||||
action &= ~2;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(AUD_resume(handle->handle))
|
||||
handle->state = AUD_STATUS_PLAYING;
|
||||
else
|
||||
handle->state = AUD_STATUS_INVALID;
|
||||
}
|
||||
|
||||
if(action & 2)
|
||||
AUD_seek(handle->handle, (cfra - handle->startframe) / fps);
|
||||
}
|
||||
}
|
||||
|
||||
AUD_unlock();
|
||||
}
|
||||
|
||||
void sound_scrub(struct bContext *C)
|
||||
{
|
||||
SoundHandle *handle;
|
||||
Scene* scene = CTX_data_scene(C);
|
||||
int cfra = CFRA;
|
||||
float fps = FPS;
|
||||
|
||||
if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
|
||||
{
|
||||
AUD_lock();
|
||||
|
||||
for(handle = scene->sound_handles.first; handle; handle = handle->next)
|
||||
{
|
||||
if(cfra >= handle->startframe && cfra < handle->endframe && !handle->mute)
|
||||
{
|
||||
if(handle->source && handle->source->snd_sound)
|
||||
{
|
||||
int frameskip = handle->frameskip + cfra - handle->startframe;
|
||||
AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, frameskip / fps, (frameskip + 1)/fps);
|
||||
AUD_play(limiter, 0);
|
||||
AUD_unload(limiter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AUD_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
PackedFile* sound_find_packedfile(bSound *sound)
|
||||
AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end)
|
||||
{
|
||||
bSound *search;
|
||||
PackedFile *pf = NULL;
|
||||
char soundname[FILE_MAXDIR + FILE_MAXFILE], searchname[FILE_MAXDIR + FILE_MAXFILE];
|
||||
|
||||
// convert sound->name to abolute filename
|
||||
strcpy(soundname, sound->name);
|
||||
BLI_convertstringcode(soundname, G.sce);
|
||||
|
||||
search = G.main->sound.first;
|
||||
while (search) {
|
||||
if (search->sample && search->sample->packedfile) {
|
||||
strcpy(searchname, search->sample->name);
|
||||
BLI_convertstringcode(searchname, G.sce);
|
||||
|
||||
if (BLI_streq(searchname, soundname)) {
|
||||
pf = search->sample->packedfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (search->newpackedfile) {
|
||||
strcpy(searchname, search->name);
|
||||
BLI_convertstringcode(searchname, G.sce);
|
||||
if (BLI_streq(searchname, soundname)) {
|
||||
pf = search->newpackedfile;
|
||||
break;
|
||||
AUD_Device* mixdown = AUD_openReadDevice(specs);
|
||||
SoundHandle *handle;
|
||||
float fps = FPS;
|
||||
AUD_Sound *limiter, *delayer;
|
||||
int frameskip, s, e;
|
||||
|
||||
end++;
|
||||
|
||||
for(handle = scene->sound_handles.first; handle; handle = handle->next)
|
||||
{
|
||||
if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->snd_sound)
|
||||
{
|
||||
frameskip = handle->frameskip;
|
||||
s = handle->startframe - start;
|
||||
e = handle->frameskip + AUD_MIN(handle->endframe, end) - handle->startframe;
|
||||
|
||||
if(s < 0)
|
||||
{
|
||||
frameskip -= s;
|
||||
s = 0;
|
||||
}
|
||||
|
||||
limiter = AUD_limitSound(handle->source->snd_sound, frameskip / fps, e / fps);
|
||||
delayer = AUD_delaySound(limiter, s / fps);
|
||||
|
||||
AUD_playDevice(mixdown, delayer);
|
||||
|
||||
AUD_unload(delayer);
|
||||
AUD_unload(limiter);
|
||||
}
|
||||
search = search->id.next;
|
||||
}
|
||||
|
||||
return (pf);
|
||||
|
||||
return mixdown;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ void makeavistring (RenderData *rd, char *string)
|
||||
}
|
||||
}
|
||||
|
||||
void start_avi(RenderData *rd, int rectx, int recty)
|
||||
void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty)
|
||||
{
|
||||
int x, y;
|
||||
char name[256];
|
||||
|
||||
@@ -65,6 +65,10 @@
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "AUD_C-API.h"
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@@ -96,6 +100,8 @@ static int audio_input_frame_size = 0;
|
||||
static uint8_t* audio_output_buffer = 0;
|
||||
static int audio_outbuf_size = 0;
|
||||
|
||||
static AUD_Device* audio_mixdown_device = 0;
|
||||
|
||||
#define FFMPEG_AUTOSPLIT_SIZE 2000000000
|
||||
|
||||
/* Delete a picture buffer */
|
||||
@@ -127,9 +133,8 @@ static int write_audio_frame(void)
|
||||
|
||||
c = get_codec_from_stream(audio_stream);
|
||||
|
||||
//XXX audiostream_fill(audio_input_buffer,
|
||||
// audio_input_frame_size
|
||||
// * sizeof(short) * c->channels);
|
||||
if(audio_mixdown_device)
|
||||
AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_frame_size);
|
||||
|
||||
av_init_packet(&pkt);
|
||||
|
||||
@@ -827,11 +832,21 @@ static void makeffmpegstring(RenderData* rd, char* string) {
|
||||
}
|
||||
|
||||
|
||||
void start_ffmpeg(RenderData *rd, int rectx, int recty)
|
||||
void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty)
|
||||
{
|
||||
ffmpeg_autosplit_count = 0;
|
||||
|
||||
start_ffmpeg_impl(rd, rectx, recty);
|
||||
|
||||
if(ffmpeg_multiplex_audio && audio_stream)
|
||||
{
|
||||
AVCodecContext* c = get_codec_from_stream(audio_stream);
|
||||
AUD_Specs specs;
|
||||
specs.channels = c->channels;
|
||||
specs.format = AUD_FORMAT_S16;
|
||||
specs.rate = rd->audio.mixrate;
|
||||
audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra);
|
||||
}
|
||||
}
|
||||
|
||||
void end_ffmpeg(void);
|
||||
@@ -884,6 +899,12 @@ void end_ffmpeg(void)
|
||||
if (audio_stream && video_stream) {
|
||||
write_audio_frames();
|
||||
}
|
||||
|
||||
if(audio_mixdown_device)
|
||||
{
|
||||
AUD_closeReadDevice(audio_mixdown_device);
|
||||
audio_mixdown_device = 0;
|
||||
}
|
||||
|
||||
if (outfile) {
|
||||
av_write_trailer(outfile);
|
||||
|
||||
@@ -101,7 +101,7 @@ static int closesocket(int fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
void start_frameserver(RenderData *rd, int rectx, int recty)
|
||||
void start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int arg = 1;
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
/* for sequence */
|
||||
//XXX #include "BSE_sequence.h"
|
||||
//XXX define below from BSE_sequence.h - otherwise potentially odd behaviour
|
||||
#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE)
|
||||
#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_IMAGE)
|
||||
|
||||
/* path/file handeling stuff */
|
||||
#ifndef WIN32
|
||||
|
||||
@@ -149,6 +149,8 @@
|
||||
#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
#include "BKE_sound.h"
|
||||
|
||||
//XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
|
||||
//XXX #include "BIF_filelist.h" // badlevel too, where to move this? - elubie
|
||||
//XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
|
||||
@@ -4052,14 +4054,16 @@ static void lib_link_scene(FileData *fd, Main *main)
|
||||
if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
|
||||
if(seq->scene) seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
|
||||
if(seq->sound) {
|
||||
seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
|
||||
if(seq->type == SEQ_HD_SOUND)
|
||||
seq->type = SEQ_SOUND;
|
||||
else
|
||||
seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
|
||||
if (seq->sound) {
|
||||
seq->sound->id.us++;
|
||||
seq->sound->flags |= SOUND_FLAGS_SEQUENCE;
|
||||
seq->sound_handle= sound_new_handle(sce, seq->sound, seq->startdisp, seq->enddisp, seq->startofs);
|
||||
}
|
||||
}
|
||||
seq->anim= 0;
|
||||
seq->hdaudio = 0;
|
||||
}
|
||||
SEQ_END
|
||||
|
||||
@@ -4103,7 +4107,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
sce->theDag = NULL;
|
||||
sce->dagisvalid = 0;
|
||||
sce->obedit= NULL;
|
||||
|
||||
|
||||
memset(&sce->sound_handles, 0, sizeof(sce->sound_handles));
|
||||
|
||||
/* set users to one by default, not in lib-link, this will increase it for compo nodes */
|
||||
sce->id.us= 1;
|
||||
|
||||
@@ -5041,6 +5047,8 @@ static void lib_link_sound(FileData *fd, Main *main)
|
||||
sound->id.flag -= LIB_NEEDLINK;
|
||||
sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system
|
||||
sound->stream = 0;
|
||||
|
||||
sound_load(sound);
|
||||
}
|
||||
sound= sound->id.next;
|
||||
}
|
||||
@@ -9186,7 +9194,67 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
Object *ob;
|
||||
PTCacheID *pid;
|
||||
ListBase pidlist;
|
||||
|
||||
|
||||
bSound *sound;
|
||||
Sequence *seq;
|
||||
bActuator *act;
|
||||
|
||||
for(sound = main->sound.first; sound; sound = sound->id.next)
|
||||
{
|
||||
if(sound->newpackedfile)
|
||||
{
|
||||
sound->packedfile = sound->newpackedfile;
|
||||
sound->newpackedfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for(ob = main->object.first; ob; ob= ob->id.next) {
|
||||
for(act= ob->actuators.first; act; act= act->next) {
|
||||
if (act->type == ACT_SOUND) {
|
||||
bSoundActuator *sAct = (bSoundActuator*) act->data;
|
||||
if(sAct->sound)
|
||||
{
|
||||
sound = newlibadr(fd, lib, sAct->sound);
|
||||
sAct->flag = sound->flags | SOUND_FLAGS_3D ? ACT_SND_3D_SOUND : 0;
|
||||
sAct->pitch = sound->pitch;
|
||||
sAct->volume = sound->volume;
|
||||
sAct->sound3D.reference_distance = sound->distance;
|
||||
sAct->sound3D.max_gain = sound->max_gain;
|
||||
sAct->sound3D.min_gain = sound->min_gain;
|
||||
sAct->sound3D.rolloff_factor = sound->attenuation;
|
||||
}
|
||||
else
|
||||
{
|
||||
sAct->sound3D.reference_distance = 1.0f;
|
||||
sAct->volume = 1.0f;
|
||||
sAct->sound3D.max_gain = 1.0f;
|
||||
sAct->sound3D.rolloff_factor = 1.0f;
|
||||
}
|
||||
sAct->sound3D.cone_inner_angle = 360.0f;
|
||||
sAct->sound3D.cone_outer_angle = 360.0f;
|
||||
sAct->sound3D.max_distance = FLT_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(scene = main->scene.first; scene; scene = scene->id.next)
|
||||
{
|
||||
if(scene->ed && scene->ed->seqbasep)
|
||||
{
|
||||
for(seq = scene->ed->seqbasep->first; seq; seq = seq->next)
|
||||
{
|
||||
if(seq->type == SEQ_HD_SOUND)
|
||||
{
|
||||
char str[FILE_MAX];
|
||||
BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
|
||||
BLI_convertstringcode(str, G.sce);
|
||||
BLI_convertstringframe(str, scene->r.cfra);
|
||||
seq->sound = sound_new_file(main, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(screen= main->screen.first; screen; screen= screen->id.next) {
|
||||
do_versions_windowmanager_2_50(screen);
|
||||
do_versions_gpencil_2_50(main, screen);
|
||||
@@ -9504,7 +9572,17 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
||||
// XXX
|
||||
bfd->user->uifonts.first= bfd->user->uifonts.last= NULL;
|
||||
bfd->user->uistyles.first= bfd->user->uistyles.last= NULL;
|
||||
|
||||
|
||||
// AUD_XXX
|
||||
if(bfd->user->audiochannels == 0)
|
||||
bfd->user->audiochannels = 2;
|
||||
if(bfd->user->audiodevice == 0)
|
||||
bfd->user->audiodevice = 1;
|
||||
if(bfd->user->audioformat == 0)
|
||||
bfd->user->audioformat = 0x12;
|
||||
if(bfd->user->audiorate == 0)
|
||||
bfd->user->audiorate = 44100;
|
||||
|
||||
bhead = blo_nextbhead(fd, bhead);
|
||||
|
||||
/* read all attached data */
|
||||
|
||||
@@ -2137,45 +2137,21 @@ static void write_texts(WriteData *wd, ListBase *idbase)
|
||||
static void write_sounds(WriteData *wd, ListBase *idbase)
|
||||
{
|
||||
bSound *sound;
|
||||
bSample *sample;
|
||||
|
||||
PackedFile * pf;
|
||||
|
||||
// set all samples to unsaved status
|
||||
|
||||
sample = samples->first; // samples is a global defined in sound.c
|
||||
while (sample) {
|
||||
sample->flags |= SAMPLE_NEEDS_SAVE;
|
||||
sample = sample->id.next;
|
||||
}
|
||||
|
||||
sound= idbase->first;
|
||||
while(sound) {
|
||||
if(sound->id.us>0 || wd->current) {
|
||||
// do we need to save the packedfile as well ?
|
||||
sample = sound->sample;
|
||||
if (sample) {
|
||||
if (sample->flags & SAMPLE_NEEDS_SAVE) {
|
||||
sound->newpackedfile = sample->packedfile;
|
||||
sample->flags &= ~SAMPLE_NEEDS_SAVE;
|
||||
} else {
|
||||
sound->newpackedfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* write LibData */
|
||||
writestruct(wd, ID_SO, "bSound", 1, sound);
|
||||
if (sound->id.properties) IDP_WriteProperty(sound->id.properties, wd);
|
||||
|
||||
if (sound->newpackedfile) {
|
||||
pf = sound->newpackedfile;
|
||||
if (sound->packedfile) {
|
||||
pf = sound->packedfile;
|
||||
writestruct(wd, DATA, "PackedFile", 1, pf);
|
||||
writedata(wd, DATA, pf->size, pf->data);
|
||||
}
|
||||
|
||||
if (sample) {
|
||||
sound->newpackedfile = sample->packedfile;
|
||||
}
|
||||
}
|
||||
sound= sound->id.next;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ SET(INC ../windowmanager
|
||||
../../kernel/gen_system ../../../intern/SoundSystem ../readstreamglue
|
||||
../quicktime ../../../intern/elbeem/extern
|
||||
../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include ../../../intern/smoke/extern
|
||||
../../../intern/audaspace
|
||||
../nodes
|
||||
../gpu
|
||||
../blenfont
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#include "ED_markers.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "BKE_sound.h"
|
||||
|
||||
/* ********************** frame change operator ***************************/
|
||||
|
||||
/* Set any flags that are necessary to indicate modal time-changing operation */
|
||||
@@ -91,6 +93,8 @@ static void change_frame_apply(bContext *C, wmOperator *op)
|
||||
if (cfra < MINAFRAME) cfra= MINAFRAME;
|
||||
CFRA= cfra;
|
||||
|
||||
sound_scrub(C);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
|
||||
}
|
||||
|
||||
@@ -121,6 +125,7 @@ static int change_frame_exec(bContext *C, wmOperator *op)
|
||||
|
||||
change_frame_apply(C, op);
|
||||
change_frame_exit(C, op);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -2277,7 +2278,9 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
/* since we follow drawflags, we can't send notifier but tag regions ourselves */
|
||||
ED_update_for_newframe(C, 1);
|
||||
|
||||
|
||||
sound_update_playing(C);
|
||||
|
||||
for(sa= screen->areabase.first; sa; sa= sa->next) {
|
||||
ARegion *ar;
|
||||
for(ar= sa->regionbase.first; ar; ar= ar->next) {
|
||||
@@ -2322,6 +2325,7 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
if(screen->animtimer) {
|
||||
ED_screen_animation_timer(C, 0, 0);
|
||||
sound_stop_all(C);
|
||||
}
|
||||
else {
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
|
||||
@@ -228,7 +228,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update)
|
||||
rd.frs_sec_base= 1.0f;
|
||||
|
||||
if(BKE_imtype_is_movie(rd.imtype))
|
||||
mh->start_movie(&rd, sj->dumpsx, sj->dumpsy);
|
||||
mh->start_movie(sj->scene, &rd, sj->dumpsx, sj->dumpsy);
|
||||
else
|
||||
mh= NULL;
|
||||
|
||||
|
||||
@@ -840,7 +840,16 @@ void filelist_setfiletypes(struct FileList* filelist, short has_quicktime)
|
||||
|| BLI_testextensie(file->relname, ".mv")) {
|
||||
file->flags |= MOVIEFILE;
|
||||
}
|
||||
else if(BLI_testextensie(file->relname, ".wav")) {
|
||||
else if(BLI_testextensie(file->relname, ".wav")
|
||||
|| BLI_testextensie(file->relname, ".ogg")
|
||||
|| BLI_testextensie(file->relname, ".oga")
|
||||
|| BLI_testextensie(file->relname, ".mp3")
|
||||
|| BLI_testextensie(file->relname, ".mp2")
|
||||
|| BLI_testextensie(file->relname, ".ac3")
|
||||
|| BLI_testextensie(file->relname, ".aac")
|
||||
|| BLI_testextensie(file->relname, ".flac")
|
||||
|| BLI_testextensie(file->relname, ".wma")
|
||||
|| BLI_testextensie(file->relname, ".eac3")) {
|
||||
file->flags |= SOUNDFILE;
|
||||
}
|
||||
} else { // no quicktime
|
||||
@@ -875,7 +884,16 @@ void filelist_setfiletypes(struct FileList* filelist, short has_quicktime)
|
||||
|| BLI_testextensie(file->relname, ".mv")) {
|
||||
file->flags |= MOVIEFILE;
|
||||
}
|
||||
else if(BLI_testextensie(file->relname, ".wav")) {
|
||||
else if(BLI_testextensie(file->relname, ".wav")
|
||||
|| BLI_testextensie(file->relname, ".ogg")
|
||||
|| BLI_testextensie(file->relname, ".oga")
|
||||
|| BLI_testextensie(file->relname, ".mp3")
|
||||
|| BLI_testextensie(file->relname, ".mp2")
|
||||
|| BLI_testextensie(file->relname, ".ac3")
|
||||
|| BLI_testextensie(file->relname, ".aac")
|
||||
|| BLI_testextensie(file->relname, ".flac")
|
||||
|| BLI_testextensie(file->relname, ".wma")
|
||||
|| BLI_testextensie(file->relname, ".eac3")) {
|
||||
file->flags |= SOUNDFILE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1984,11 +1984,14 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
|
||||
}
|
||||
case ACT_SOUND:
|
||||
{
|
||||
ysize = 70;
|
||||
|
||||
sa = act->data;
|
||||
sa->sndnr = 0;
|
||||
|
||||
if(sa->flag & ACT_SND_3D_SOUND)
|
||||
ysize = 114;
|
||||
else
|
||||
ysize = 92;
|
||||
|
||||
wval = (width-20)/2;
|
||||
glRects(xco, yco-ysize, xco+width, yco);
|
||||
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
|
||||
@@ -2003,8 +2006,14 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
|
||||
char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4";
|
||||
uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,width-40,19, sa->sound->id.name+2, 0.0, 21.0, 0, 0, "");
|
||||
uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19, &sa->type, 0.0, 0.0, 0, 0, "");
|
||||
uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->sound->volume, 0.0, 1.0, 0, 0, "Sets the volume of this sound");
|
||||
uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->sound->pitch,-12.0, 12.0, 0, 0, "Sets the pitch of this sound");
|
||||
uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->volume, 0.0, 1.0, 0, 0, "Sets the volume of this sound");
|
||||
uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->pitch,-12.0, 12.0, 0, 0, "Sets the pitch of this sound");
|
||||
uiDefButS(block, TOG | BIT, 0, "3D Sound", xco+10, yco-88, width-20, 19, &sa->flag, 0.0, 1.0, 0.0, 0.0, "Plays the sound positioned in 3D space.");
|
||||
if(sa->flag & ACT_SND_3D_SOUND)
|
||||
{
|
||||
uiDefButF(block, NUM, 0, "Rolloff: ", xco+10, yco-110, wval, 19, &sa->sound3D.rolloff_factor, 0.0, 5.0, 0.0, 0.0, "The rolloff factor defines the influence factor on volume depending on distance.");
|
||||
uiDefButF(block, NUM, 0, "Reference distance: ", xco+wval+10, yco-110, wval, 19, &sa->sound3D.reference_distance, 0.0, 1000.0, 0.0, 0.0, "The reference distance is the distance where the sound has a gain of 1.0.");
|
||||
}
|
||||
}
|
||||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
@@ -4178,13 +4178,13 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
|
||||
case TSE_POSEGRP_BASE:
|
||||
UI_icon_draw(x, y, ICON_VERTEXSEL); break;
|
||||
case TSE_SEQUENCE:
|
||||
if((te->idcode==SEQ_MOVIE) || (te->idcode==SEQ_MOVIE_AND_HD_SOUND))
|
||||
if(te->idcode==SEQ_MOVIE)
|
||||
UI_icon_draw(x, y, ICON_SEQUENCE);
|
||||
else if(te->idcode==SEQ_META)
|
||||
UI_icon_draw(x, y, ICON_DOT);
|
||||
else if(te->idcode==SEQ_SCENE)
|
||||
UI_icon_draw(x, y, ICON_SCENE);
|
||||
else if((te->idcode==SEQ_RAM_SOUND) || (te->idcode==SEQ_HD_SOUND))
|
||||
else if(te->idcode==SEQ_SOUND)
|
||||
UI_icon_draw(x, y, ICON_SOUND);
|
||||
else if(te->idcode==SEQ_IMAGE)
|
||||
UI_icon_draw(x, y, ICON_IMAGE_COL);
|
||||
|
||||
@@ -6,5 +6,6 @@ sources = env.Glob('*.c')
|
||||
incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf'
|
||||
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
|
||||
incs += ' ../../makesrna'
|
||||
incs += ' #/intern/audaspace'
|
||||
|
||||
env.BlenderLib ( 'bf_editors_space_sequencer', sources, Split(incs), [], libtype=['core'], priority=[100] )
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "BKE_sound.h"
|
||||
#include "AUD_C-API.h"
|
||||
|
||||
/* own include */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
@@ -224,24 +227,80 @@ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
|
||||
RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME-2, "Scene Name", "Scene name to add as a strip");
|
||||
}
|
||||
|
||||
static Sequence* sequencer_add_sound_strip(bContext *C, wmOperator *op, int start_frame, int channel, char* filename)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= seq_give_editing(scene, TRUE);
|
||||
|
||||
bSound *sound;
|
||||
|
||||
Sequence *seq; /* generic strip vars */
|
||||
Strip *strip;
|
||||
StripElem *se;
|
||||
|
||||
AUD_SoundInfo info;
|
||||
|
||||
sound = sound_new_file(CTX_data_main(C), filename);
|
||||
|
||||
if (sound==NULL || sound->snd_sound == NULL) {
|
||||
if(op)
|
||||
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info = AUD_getInfo(sound->snd_sound);
|
||||
|
||||
if (info.specs.format == AUD_FORMAT_INVALID) {
|
||||
sound_delete(C, sound);
|
||||
if(op)
|
||||
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seq = alloc_sequence(ed->seqbasep, start_frame, channel);
|
||||
|
||||
seq->type= SEQ_SOUND;
|
||||
seq->sound= sound;
|
||||
|
||||
/* basic defaults */
|
||||
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
|
||||
strip->len = seq->len = (int) (info.length * FPS);
|
||||
strip->us= 1;
|
||||
|
||||
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
|
||||
|
||||
BLI_split_dirfile_basic(filename, strip->dir, se->name);
|
||||
|
||||
seq->sound_handle = sound_new_handle(scene, sound, start_frame, start_frame + strip->len, 0);
|
||||
|
||||
calc_sequence_disp(seq);
|
||||
sort_seq(scene);
|
||||
|
||||
/* last active name */
|
||||
strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR-1);
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
/* add movie operator */
|
||||
static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= seq_give_editing(scene, TRUE);
|
||||
|
||||
|
||||
struct anim *an;
|
||||
char filename[FILE_MAX];
|
||||
|
||||
Sequence *seq; /* generic strip vars */
|
||||
Sequence *seq, *soundseq; /* generic strip vars */
|
||||
Strip *strip;
|
||||
StripElem *se;
|
||||
|
||||
int start_frame, channel; /* operator props */
|
||||
|
||||
|
||||
int start_frame, channel, sound; /* operator props */
|
||||
|
||||
start_frame= RNA_int_get(op->ptr, "start_frame");
|
||||
channel= RNA_int_get(op->ptr, "channel");
|
||||
|
||||
sound = RNA_boolean_get(op->ptr, "sound");
|
||||
|
||||
RNA_string_get(op->ptr, "filename", filename);
|
||||
|
||||
an = openanim(filename, IB_rect);
|
||||
@@ -271,10 +330,19 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
|
||||
calc_sequence_disp(seq);
|
||||
sort_seq(scene);
|
||||
|
||||
if(sound)
|
||||
{
|
||||
soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, filename);
|
||||
if(soundseq != NULL)
|
||||
RNA_string_get(op->ptr, "name", soundseq->name);
|
||||
}
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "replace_sel")) {
|
||||
deselect_all_seq(scene);
|
||||
set_last_seq(scene, seq);
|
||||
seq->flag |= SELECT;
|
||||
if(soundseq)
|
||||
soundseq->flag |= SELECT;
|
||||
}
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
@@ -310,24 +378,15 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
|
||||
|
||||
WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE);
|
||||
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
|
||||
RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load hd sound with the movie"); // XXX need to impliment this
|
||||
RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie");
|
||||
}
|
||||
|
||||
|
||||
/* add sound operator */
|
||||
static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Editing *ed= seq_give_editing(scene, TRUE);
|
||||
|
||||
bSound *sound;
|
||||
|
||||
char filename[FILE_MAX];
|
||||
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Sequence *seq; /* generic strip vars */
|
||||
Strip *strip;
|
||||
StripElem *se;
|
||||
|
||||
int start_frame, channel; /* operator props */
|
||||
|
||||
start_frame= RNA_int_get(op->ptr, "start_frame");
|
||||
@@ -335,47 +394,16 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
|
||||
|
||||
RNA_string_get(op->ptr, "filename", filename);
|
||||
|
||||
/* XXX if(sfile->flag & FILE_STRINGCODE) {
|
||||
BLI_makestringcode(G.sce, str);
|
||||
}*/
|
||||
seq = sequencer_add_sound_strip(C, op, start_frame, channel, filename);
|
||||
|
||||
// XXX sound= sound_new_sound(filename);
|
||||
sound= NULL;
|
||||
|
||||
if (sound==NULL || sound->sample->type == SAMPLE_INVALID) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
|
||||
if(seq == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (sound==NULL || sound->sample->bits != 16) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Only 16 bit audio is supported");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
sound->flags |= SOUND_FLAGS_SEQUENCE;
|
||||
// XXX audio_makestream(sound);
|
||||
|
||||
seq = alloc_sequence(ed->seqbasep, start_frame, channel);
|
||||
|
||||
seq->type= SEQ_RAM_SOUND;
|
||||
seq->sound= sound;
|
||||
|
||||
/* basic defaults */
|
||||
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
|
||||
strip->len = seq->len = (int) ( ((float)(sound->streamlen-1) / ( (float)scene->r.audio.mixrate*4.0 ))* FPS);
|
||||
strip->us= 1;
|
||||
|
||||
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
|
||||
|
||||
BLI_split_dirfile_basic(filename, strip->dir, se->name);
|
||||
|
||||
RNA_string_get(op->ptr, "name", seq->name);
|
||||
|
||||
calc_sequence_disp(seq);
|
||||
sort_seq(scene);
|
||||
|
||||
/* last active name */
|
||||
strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR-1);
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "cache")) {
|
||||
sound_cache(seq->sound, 0);
|
||||
}
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "replace_sel")) {
|
||||
deselect_all_seq(scene);
|
||||
@@ -416,7 +444,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
|
||||
|
||||
WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE);
|
||||
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
|
||||
RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Load the sound as streaming audio"); // XXX need to impliment this
|
||||
RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
|
||||
}
|
||||
|
||||
/* add image operator */
|
||||
@@ -585,7 +613,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
|
||||
|
||||
if(seq->plugin==NULL) {
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
seq_free_sequence(ed, seq);
|
||||
seq_free_sequence(scene, seq);
|
||||
BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", filename);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -173,8 +173,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, char *col)
|
||||
case SEQ_PLUGIN:
|
||||
UI_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
|
||||
break;
|
||||
case SEQ_HD_SOUND:
|
||||
case SEQ_RAM_SOUND:
|
||||
case SEQ_SOUND:
|
||||
UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col);
|
||||
blendcol[0] = blendcol[1] = blendcol[2] = 128;
|
||||
if(seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
|
||||
@@ -546,11 +545,8 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
|
||||
else
|
||||
sprintf(str, "%d | %s", seq->len, give_seqname(seq));
|
||||
}
|
||||
else if (seq->type == SEQ_RAM_SOUND) {
|
||||
sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
|
||||
}
|
||||
else if (seq->type == SEQ_HD_SOUND) {
|
||||
sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
|
||||
else if (seq->type == SEQ_SOUND) {
|
||||
sprintf(str, "%d | %s", seq->len, seq->sound->name);
|
||||
}
|
||||
else if (seq->type == SEQ_MOVIE) {
|
||||
sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
|
||||
@@ -664,8 +660,9 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, SpaceSeq *sseq, Sequence *
|
||||
draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
|
||||
|
||||
/* draw additional info and controls */
|
||||
if (seq->type == SEQ_RAM_SOUND)
|
||||
drawseqwave(scene, v2d, seq, x1, y1, x2, y2, ar->winx);
|
||||
// XXX
|
||||
/* if (seq->type == SEQ_SOUND)
|
||||
drawseqwave(scene, v2d, seq, x1, y1, x2, y2, ar->winx);*/
|
||||
|
||||
if (!is_single_image)
|
||||
draw_seq_extensions(scene, sseq, seq);
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -166,7 +167,7 @@ Sequence *get_foreground_frame_seq(Scene *scene, int frame)
|
||||
if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame)
|
||||
continue;
|
||||
/* only use elements you can see - not */
|
||||
if (ELEM6(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_MOVIE_AND_HD_SOUND, SEQ_COLOR)) {
|
||||
if (ELEM5(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_COLOR)) {
|
||||
if (seq->machine > best_machine) {
|
||||
best_seq = seq;
|
||||
best_machine = seq->machine;
|
||||
@@ -563,7 +564,7 @@ static void reload_sound_strip(Scene *scene, char *name)
|
||||
calc_sequence(seqact);
|
||||
|
||||
seq->strip= 0;
|
||||
seq_free_sequence(ed, seq);
|
||||
seq_free_sequence(scene, seq);
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
|
||||
seq= ed->seqbasep->first;
|
||||
@@ -603,7 +604,7 @@ static void reload_image_strip(Scene *scene, char *name)
|
||||
calc_sequence(seqact);
|
||||
|
||||
seq->strip= 0;
|
||||
seq_free_sequence(ed, seq);
|
||||
seq_free_sequence(scene, seq);
|
||||
BLI_remlink(ed->seqbasep, seq);
|
||||
|
||||
update_changed_seq_and_deps(scene, seqact, 1, 1);
|
||||
@@ -722,7 +723,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
|
||||
|
||||
for(seq=ed->seqbasep->first; seq; seq=seq->next) {
|
||||
if(seq->flag & SELECT) {
|
||||
if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
|
||||
if (seq->type == SEQ_SOUND) {
|
||||
*error_str= "Can't apply effects to audio sequence strips";
|
||||
return 0;
|
||||
}
|
||||
@@ -849,7 +850,6 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
|
||||
|
||||
static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall)
|
||||
{
|
||||
Editing *ed= seq_give_editing(scene, FALSE);
|
||||
Sequence *seq, *seqn;
|
||||
Sequence *last_seq = get_last_seq(scene);
|
||||
|
||||
@@ -857,20 +857,20 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de
|
||||
while(seq) {
|
||||
seqn= seq->next;
|
||||
if((seq->flag & flag) || deleteall) {
|
||||
if(seq->type==SEQ_RAM_SOUND && seq->sound)
|
||||
if(seq->type==SEQ_SOUND && seq->sound)
|
||||
seq->sound->id.us--;
|
||||
|
||||
BLI_remlink(lb, seq);
|
||||
if(seq==last_seq) set_last_seq(scene, NULL);
|
||||
if(seq->type==SEQ_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1);
|
||||
if(seq->ipo) seq->ipo->id.us--;
|
||||
seq_free_sequence(ed, seq);
|
||||
seq_free_sequence(scene, seq);
|
||||
}
|
||||
seq= seqn;
|
||||
}
|
||||
}
|
||||
|
||||
static Sequence *dupli_seq(Sequence *seq)
|
||||
static Sequence *dupli_seq(struct Scene *scene, Sequence *seq)
|
||||
{
|
||||
Sequence *seqn = MEM_dupallocN(seq);
|
||||
// XXX animato: ID *id;
|
||||
@@ -936,14 +936,13 @@ static Sequence *dupli_seq(Sequence *seq)
|
||||
seqn->strip->stripdata =
|
||||
MEM_dupallocN(seq->strip->stripdata);
|
||||
seqn->anim= 0;
|
||||
} else if(seq->type == SEQ_RAM_SOUND) {
|
||||
seqn->strip->stripdata =
|
||||
} else if(seq->type == SEQ_SOUND) {
|
||||
seqn->strip->stripdata =
|
||||
MEM_dupallocN(seq->strip->stripdata);
|
||||
if(seq->sound_handle)
|
||||
seqn->sound_handle = sound_new_handle(scene, seqn->sound, seq->sound_handle->startframe, seq->sound_handle->endframe, seq->sound_handle->frameskip);
|
||||
|
||||
seqn->sound->id.us++;
|
||||
} else if(seq->type == SEQ_HD_SOUND) {
|
||||
seqn->strip->stripdata =
|
||||
MEM_dupallocN(seq->strip->stripdata);
|
||||
seqn->hdaudio = 0;
|
||||
} else if(seq->type == SEQ_IMAGE) {
|
||||
seqn->strip->stripdata =
|
||||
MEM_dupallocN(seq->strip->stripdata);
|
||||
@@ -970,13 +969,13 @@ static Sequence *dupli_seq(Sequence *seq)
|
||||
return seqn;
|
||||
}
|
||||
|
||||
static Sequence * deep_dupli_seq(Sequence * seq)
|
||||
static Sequence * deep_dupli_seq(struct Scene *scene, Sequence * seq)
|
||||
{
|
||||
Sequence * seqn = dupli_seq(seq);
|
||||
Sequence * seqn = dupli_seq(scene, seq);
|
||||
if (seq->type == SEQ_META) {
|
||||
Sequence * s;
|
||||
for(s= seq->seqbase.first; s; s = s->next) {
|
||||
Sequence * n = deep_dupli_seq(s);
|
||||
Sequence * n = deep_dupli_seq(scene, s);
|
||||
if (n) {
|
||||
BLI_addtail(&seqn->seqbase, n);
|
||||
}
|
||||
@@ -995,7 +994,7 @@ static void recurs_dupli_seq(Scene *scene, ListBase *old, ListBase *new)
|
||||
for(seq= old->first; seq; seq= seq->next) {
|
||||
seq->tmp= NULL;
|
||||
if(seq->flag & SELECT) {
|
||||
seqn = dupli_seq(seq);
|
||||
seqn = dupli_seq(scene, seq);
|
||||
if (seqn) { /*should never fail */
|
||||
seq->flag &= SEQ_DESEL;
|
||||
seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
|
||||
@@ -1061,10 +1060,10 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence * seq, int cutframe)
|
||||
|
||||
reload_sequence_new_file(scene, seq);
|
||||
calc_sequence(seq);
|
||||
|
||||
|
||||
if (!skip_dup) {
|
||||
/* Duplicate AFTER the first change */
|
||||
seqn = deep_dupli_seq(seq);
|
||||
seqn = deep_dupli_seq(scene, seq);
|
||||
}
|
||||
|
||||
if (seqn) {
|
||||
@@ -1150,10 +1149,10 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence * seq, int cutframe)
|
||||
}
|
||||
|
||||
calc_sequence(seq);
|
||||
|
||||
|
||||
if (!skip_dup) {
|
||||
/* Duplicate AFTER the first change */
|
||||
seqn = deep_dupli_seq(seq);
|
||||
seqn = deep_dupli_seq(scene, seq);
|
||||
}
|
||||
|
||||
if (seqn) {
|
||||
@@ -1493,11 +1492,13 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op)
|
||||
if(selected){ /* mute unselected */
|
||||
if (seq->flag & SELECT) {
|
||||
seq->flag |= SEQ_MUTE;
|
||||
seq_update_sound(seq);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((seq->flag & SELECT)==0) {
|
||||
seq->flag |= SEQ_MUTE;
|
||||
seq_update_sound(seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1544,11 +1545,13 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op)
|
||||
if(selected){ /* unmute unselected */
|
||||
if (seq->flag & SELECT) {
|
||||
seq->flag &= ~SEQ_MUTE;
|
||||
seq_update_sound(seq);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((seq->flag & SELECT)==0) {
|
||||
seq->flag &= ~SEQ_MUTE;
|
||||
seq_update_sound(seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2007,7 +2010,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
|
||||
start_ofs += step;
|
||||
}
|
||||
|
||||
seq_free_sequence(ed, seq);
|
||||
seq_free_sequence(scene, seq);
|
||||
seq = seq->next;
|
||||
} else {
|
||||
seq = seq->next;
|
||||
@@ -2130,7 +2133,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
|
||||
while(seq) {
|
||||
if(seq->flag & SELECT) {
|
||||
tot++;
|
||||
if (seq->type == SEQ_RAM_SOUND) {
|
||||
if (seq->type == SEQ_SOUND) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't make Meta Strip from audio");
|
||||
return OPERATOR_CANCELLED;;
|
||||
}
|
||||
@@ -2242,7 +2245,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *op)
|
||||
last_seq->seqbase.last= 0;
|
||||
|
||||
BLI_remlink(ed->seqbasep, last_seq);
|
||||
seq_free_sequence(ed, last_seq);
|
||||
seq_free_sequence(scene, last_seq);
|
||||
|
||||
/* emtpy meta strip, delete all effects depending on it */
|
||||
for(seq=ed->seqbasep->first; seq; seq=seq->next)
|
||||
|
||||
@@ -153,7 +153,7 @@ void select_single_seq(Scene *scene, Sequence *seq, int deselect_all) /* BRING B
|
||||
if(seq->strip)
|
||||
strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR-1);
|
||||
}
|
||||
else if((seq->type==SEQ_HD_SOUND) || (seq->type==SEQ_RAM_SOUND)) {
|
||||
else if(seq->type==SEQ_SOUND) {
|
||||
if(seq->strip)
|
||||
strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR-1);
|
||||
}
|
||||
@@ -336,7 +336,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR-1);
|
||||
}
|
||||
} else
|
||||
if (seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND) {
|
||||
if (seq->type == SEQ_SOUND) {
|
||||
if(seq->strip) {
|
||||
strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR-1);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ struct Scene;
|
||||
struct Group;
|
||||
struct Text;
|
||||
|
||||
// for Sound3D
|
||||
#include "DNA_sound_types.h"
|
||||
|
||||
/* ****************** ACTUATORS ********************* */
|
||||
|
||||
/* unused now, moved to editobjectactuator in 2.02. Still needed for dna */
|
||||
@@ -62,7 +65,9 @@ typedef struct bSoundActuator {
|
||||
short flag, sndnr;
|
||||
int sta, end;
|
||||
short pad1[2];
|
||||
float volume, pitch;
|
||||
struct bSound *sound;
|
||||
struct Sound3D sound3D;
|
||||
short type, makecopy;
|
||||
short copymade, pad2[1];
|
||||
} bSoundActuator;
|
||||
@@ -432,6 +437,9 @@ typedef struct FreeCamera {
|
||||
#define ACT_RANDOM_FLOAT_NORMAL 8
|
||||
#define ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL 9
|
||||
|
||||
/* SoundActuator->flag */
|
||||
#define ACT_SND_3D_SOUND 1
|
||||
|
||||
/* SoundActuator->type */
|
||||
#define ACT_SND_PLAY_STOP_SOUND 0
|
||||
#define ACT_SND_PLAY_END_SOUND 1
|
||||
|
||||
@@ -662,6 +662,7 @@ typedef struct Scene {
|
||||
ListBase markers;
|
||||
ListBase transform_spaces;
|
||||
|
||||
ListBase sound_handles;
|
||||
|
||||
/* none of the dependancy graph vars is mean to be saved */
|
||||
struct DagForest *theDag;
|
||||
|
||||
@@ -160,7 +160,7 @@ typedef struct Sequence {
|
||||
ListBase seqbase; /* list of strips for metastrips */
|
||||
|
||||
struct bSound *sound; /* the linked "bSound" object */
|
||||
struct hdaudio *hdaudio; /* external hdaudio object */
|
||||
struct SoundHandle *sound_handle;
|
||||
float level, pan; /* level in dB (0=full), pan -1..1 */
|
||||
int scenenr; /* for scene selection */
|
||||
float strobe;
|
||||
@@ -281,7 +281,7 @@ typedef struct SpeedControlVars {
|
||||
#define SEQ_MOVIE 3
|
||||
#define SEQ_RAM_SOUND 4
|
||||
#define SEQ_HD_SOUND 5
|
||||
#define SEQ_MOVIE_AND_HD_SOUND 6 /* helper for add_sequence */
|
||||
#define SEQ_SOUND 4
|
||||
|
||||
#define SEQ_EFFECT 8
|
||||
#define SEQ_CROSS 8
|
||||
|
||||
@@ -64,18 +64,43 @@ typedef struct bSample {
|
||||
short us;
|
||||
} bSample;
|
||||
|
||||
// runtime only - no saving
|
||||
typedef struct SoundHandle {
|
||||
struct SoundHandle *next, *prev;
|
||||
struct bSound *source;
|
||||
void *handle;
|
||||
int state;
|
||||
int startframe;
|
||||
int endframe;
|
||||
int frameskip;
|
||||
int mute;
|
||||
int changed;
|
||||
float volume;
|
||||
float pad;
|
||||
} SoundHandle;
|
||||
|
||||
typedef struct Sound3D
|
||||
{
|
||||
float min_gain;
|
||||
float max_gain;
|
||||
float reference_distance;
|
||||
float max_distance;
|
||||
float rolloff_factor;
|
||||
float cone_inner_angle;
|
||||
float cone_outer_angle;
|
||||
float cone_outer_gain;
|
||||
} Sound3D;
|
||||
|
||||
typedef struct bSound {
|
||||
ID id;
|
||||
char name[160];
|
||||
struct bSample *sample;
|
||||
void *stream;
|
||||
struct bSample *sample; // AUD_XXX deprecated
|
||||
void *stream; // AUD_XXX deprecated
|
||||
struct PackedFile *packedfile;
|
||||
struct PackedFile *newpackedfile;
|
||||
void *snd_sound;
|
||||
struct Ipo *ipo;
|
||||
float volume, panning;
|
||||
struct PackedFile *newpackedfile; // AUD_XXX deprecated
|
||||
void *snd_sound; // AUD_XXX used for AUD_Sound now
|
||||
struct Ipo *ipo; // AUD_XXX deprecated
|
||||
float volume, panning; // AUD_XXX deprecated
|
||||
/**
|
||||
* Sets the rollofffactor. The rollofffactor is a per-Source parameter
|
||||
* the application can use to increase or decrease the range of a source
|
||||
@@ -84,27 +109,43 @@ typedef struct bSound {
|
||||
* value of 0, which indicates that the application does not wish any
|
||||
* distance attenuation on the respective Source.
|
||||
*/
|
||||
float attenuation;
|
||||
float pitch;
|
||||
float attenuation; // AUD_XXX deprecated
|
||||
float pitch; // AUD_XXX deprecated
|
||||
/**
|
||||
* min_gain indicates the minimal gain which is always guaranteed for this sound
|
||||
*/
|
||||
float min_gain;
|
||||
float min_gain; // AUD_XXX deprecated
|
||||
/**
|
||||
* max_gain indicates the maximal gain which is always guaranteed for this sound
|
||||
*/
|
||||
float max_gain;
|
||||
float max_gain; // AUD_XXX deprecated
|
||||
/**
|
||||
* Sets the referencedistance at which the listener will experience gain.
|
||||
*/
|
||||
float distance;
|
||||
int flags;
|
||||
int streamlen;
|
||||
char channels;
|
||||
char highprio;
|
||||
char pad[10];
|
||||
float distance; // AUD_XXX deprecated
|
||||
int flags; // AUD_XXX deprecated
|
||||
int streamlen; // AUD_XXX deprecated
|
||||
char channels; // AUD_XXX deprecated
|
||||
char highprio; // AUD_XXX deprecated
|
||||
char pad[10]; // AUD_XXX deprecated
|
||||
|
||||
// AUD_XXX NEW
|
||||
int type;
|
||||
int changed;
|
||||
struct bSound *child_sound;
|
||||
void *cache;
|
||||
|
||||
// SOUND_TYPE_LIMITER
|
||||
float start, end;
|
||||
} bSound;
|
||||
|
||||
typedef enum eSound_Type {
|
||||
SOUND_TYPE_INVALID = -1,
|
||||
SOUND_TYPE_FILE = 0,
|
||||
SOUND_TYPE_BUFFER,
|
||||
SOUND_TYPE_LIMITER
|
||||
} eSound_Type;
|
||||
|
||||
typedef struct bSoundListener {
|
||||
ID id;
|
||||
/**
|
||||
|
||||
@@ -293,6 +293,11 @@ typedef struct UserDef {
|
||||
short userpref, viewzoom;
|
||||
|
||||
int mixbufsize;
|
||||
int audiodevice;
|
||||
int audiorate;
|
||||
int audioformat;
|
||||
int audiochannels;
|
||||
|
||||
int scrollback; /* console scrollback limit */
|
||||
int dpi; /* range 48-128? */
|
||||
short encoding;
|
||||
|
||||
@@ -192,10 +192,8 @@ static StructRNA* rna_Sequence_refine(struct PointerRNA *ptr)
|
||||
case SEQ_SCENE:
|
||||
return &RNA_SceneSequence;
|
||||
case SEQ_MOVIE:
|
||||
case SEQ_MOVIE_AND_HD_SOUND:
|
||||
return &RNA_MovieSequence;
|
||||
case SEQ_RAM_SOUND:
|
||||
case SEQ_HD_SOUND:
|
||||
case SEQ_SOUND:
|
||||
return &RNA_SoundSequence;
|
||||
case SEQ_CROSS:
|
||||
case SEQ_ADD:
|
||||
@@ -362,9 +360,7 @@ static void rna_def_sequence(BlenderRNA *brna)
|
||||
{SEQ_META, "META", 0, "Meta", ""},
|
||||
{SEQ_SCENE, "SCENE", 0, "Scene", ""},
|
||||
{SEQ_MOVIE, "MOVIE", 0, "Movie", ""},
|
||||
{SEQ_RAM_SOUND, "RAM_SOUND", 0, "Ram Sound", ""},
|
||||
{SEQ_HD_SOUND, "HD_SOUND", 0, "HD Sound", ""},
|
||||
{SEQ_MOVIE_AND_HD_SOUND, "MOVIE_AND_HD_SOUND", 0, "Movie and HD Sound", ""},
|
||||
{SEQ_SOUND, "_SOUND", 0, "Sound", ""},
|
||||
{SEQ_EFFECT, "REPLACE", 0, "Replace", ""},
|
||||
{SEQ_CROSS, "CROSS", 0, "Cross", ""},
|
||||
{SEQ_ADD, "ADD", 0, "Add", ""},
|
||||
@@ -616,21 +612,6 @@ static void rna_def_filter_video(StructRNA *srna)
|
||||
RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_filter_sound(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop= RNA_def_property(srna, "sound_gain", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "level");
|
||||
RNA_def_property_range(prop, -96.0f, 6.0f);
|
||||
RNA_def_property_ui_text(prop, "Sound Gain", "Sound level in dB (0 = full volume).");
|
||||
|
||||
prop= RNA_def_property(srna, "sound_pan", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "pan");
|
||||
RNA_def_property_range(prop, -1.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Sound Pan", "Stereo sound balance.");
|
||||
}
|
||||
|
||||
static void rna_def_proxy(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
@@ -772,7 +753,6 @@ static void rna_def_sound(BlenderRNA *brna)
|
||||
RNA_def_property_string_sdna(prop, NULL, "strip->dir");
|
||||
RNA_def_property_ui_text(prop, "Directory", "");
|
||||
|
||||
rna_def_filter_sound(srna);
|
||||
rna_def_input(srna);
|
||||
}
|
||||
|
||||
|
||||
@@ -149,71 +149,6 @@ static void rna_def_sound(BlenderRNA *brna)
|
||||
prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
|
||||
RNA_def_property_ui_text(prop, "Packed File", "");
|
||||
|
||||
/* game engine settings */
|
||||
prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "volume");
|
||||
RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 4);
|
||||
RNA_def_property_ui_text(prop, "Volume", "Game engine only: volume for this sound.");
|
||||
|
||||
prop= RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "pitch");
|
||||
RNA_def_property_ui_range(prop, -12.0, 12.0, 10, 4);
|
||||
RNA_def_property_ui_text(prop, "Pitch", "Game engine only: set the pitch of this sound.");
|
||||
|
||||
prop= RNA_def_property(srna, "loop", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_LOOP);
|
||||
RNA_def_property_ui_text(prop, "Sound Loop", "Game engine only: toggle between looping on/off.");
|
||||
|
||||
prop= RNA_def_property(srna, "ping_pong", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_BIDIRECTIONAL_LOOP);
|
||||
RNA_def_property_ui_text(prop, "Ping Pong", "Game engine only: Toggle between A->B and A->B->A looping.");
|
||||
|
||||
prop= RNA_def_property(srna, "sound_3d", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_3D);
|
||||
RNA_def_property_ui_text(prop, "3D Sound", "Game engine only: turns 3D sound on.");
|
||||
|
||||
prop= RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "attenuation");
|
||||
RNA_def_property_range(prop, 0.0, 5.0);
|
||||
RNA_def_property_ui_text(prop, "Attenuation", "Game engine only: sets the surround scaling factor for 3D sound.");
|
||||
|
||||
/* gain */
|
||||
prop= RNA_def_property(srna, "min_gain", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "min_gain");
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_ui_text(prop, "Min Gain", "Minimal gain which is always guaranteed for this sound.");
|
||||
|
||||
prop= RNA_def_property(srna, "max_gain", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "max_gain");
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_ui_text(prop, "Max Gain", "Maximal gain which is always guaranteed for this sound.");
|
||||
|
||||
prop= RNA_def_property(srna, "reference_distance", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "distance");
|
||||
RNA_def_property_ui_text(prop, "Reference Distance", "Reference distance at which the listener will experience gain.");
|
||||
RNA_def_property_ui_range(prop, 0.0, 1000.0, 10, 4); /* NOT used anywhere */
|
||||
|
||||
/* unused
|
||||
prop= RNA_def_property(srna, "panning", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "panning");
|
||||
RNA_def_property_ui_range(prop, -1.0, 1.0, 10, 4);
|
||||
RNA_def_property_ui_text(prop, "Panning", "Pan the sound from left to right"); */
|
||||
|
||||
/* unused
|
||||
prop= RNA_def_property(srna, "fixed_volume", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_FIXED_VOLUME);
|
||||
RNA_def_property_ui_text(prop, "Fixed Volume", "Constraint sound to fixed volume."); */
|
||||
|
||||
/* unused
|
||||
prop= RNA_def_property(srna, "fixed_panning", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_FIXED_PANNING);
|
||||
RNA_def_property_ui_text(prop, "Fixed Panning", "Constraint sound to fixed panning."); */
|
||||
|
||||
/* unused
|
||||
prop= RNA_def_property(srna, "priority", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", SOUND_FLAGS_PRIORITY);
|
||||
RNA_def_property_ui_text(prop, "Priority", "Make sound higher priority."); */
|
||||
}
|
||||
|
||||
void RNA_def_sound(BlenderRNA *brna)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
static void rna_userdef_lmb_select_set(struct PointerRNA *ptr,int value)
|
||||
@@ -116,6 +118,11 @@ static PointerRNA rna_UserDef_system_get(PointerRNA *ptr)
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesSystem, ptr->data);
|
||||
}
|
||||
|
||||
static void rna_UserDef_audio_update(bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
sound_reinit(C);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
|
||||
@@ -1977,6 +1984,46 @@ static void rna_def_userdef_system(BlenderRNA *brna)
|
||||
{512, "AUDIO_SAMPLES_512", 0, "512", "Set audio mixing buffer size to 512 samples"},
|
||||
{1024, "AUDIO_SAMPLES_1024", 0, "1024", "Set audio mixing buffer size to 1024 samples"},
|
||||
{2048, "AUDIO_SAMPLES_2048", 0, "2048", "Set audio mixing buffer size to 2048 samples"},
|
||||
{4096, "AUDIO_SAMPLES_4096", 0, "4096", "Set audio mixing buffer size to 4096 samples"},
|
||||
{8192, "AUDIO_SAMPLES_8192", 0, "8192", "Set audio mixing buffer size to 8192 samples"},
|
||||
{16384, "AUDIO_SAMPLES_16384", 0, "16384", "Set audio mixing buffer size to 16384 samples"},
|
||||
{32768, "AUDIO_SAMPLES_32768", 0, "32768", "Set audio mixing buffer size to 32768 samples"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem audio_device_items[] = {
|
||||
{0, "AUDIO_DEVICE_NULL", 0, "No Audio", "Null device - there will be no audio output."},
|
||||
{1, "AUDIO_DEVICE_SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage."},
|
||||
{2, "AUDIO_DEVICE_OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage."},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem audio_rate_items[] = {
|
||||
// {8000, "AUDIO_RATE_8000", 0, "8 kHz", "Set audio sampling rate to 8000 samples per second."},
|
||||
// {11025, "AUDIO_RATE_11025", 0, "11.025 kHz", "Set audio sampling rate to 11025 samples per second."},
|
||||
// {16000, "AUDIO_RATE_16000", 0, "16 kHz", "Set audio sampling rate to 16000 samples per second."},
|
||||
// {22050, "AUDIO_RATE_22050", 0, "22.05 kHz", "Set audio sampling rate to 22050 samples per second."},
|
||||
// {32000, "AUDIO_RATE_32000", 0, "32 kHz", "Set audio sampling rate to 32000 samples per second."},
|
||||
{44100, "AUDIO_RATE_44100", 0, "44.1 kHz", "Set audio sampling rate to 44100 samples per second."},
|
||||
{48000, "AUDIO_RATE_48000", 0, "48 kHz", "Set audio sampling rate to 48000 samples per second."},
|
||||
// {88200, "AUDIO_RATE_88200", 0, "88.2 kHz", "Set audio sampling rate to 88200 samples per second."},
|
||||
{96000, "AUDIO_RATE_96000", 0, "96 kHz", "Set audio sampling rate to 96000 samples per second."},
|
||||
{192000, "AUDIO_RATE_192000", 0, "192 kHz", "Set audio sampling rate to 192000 samples per second."},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem audio_format_items[] = {
|
||||
{0x01, "AUDIO_FORMAT_U8", 0, "8-bit Unsigned", "Set audio sample format to 8 bit unsigned integer."},
|
||||
{0x12, "AUDIO_FORMAT_S16", 0, "16-bit Signed", "Set audio sample format to 16 bit signed integer."},
|
||||
{0x13, "AUDIO_FORMAT_S24", 0, "24-bit Signed", "Set audio sample format to 24 bit signed integer."},
|
||||
{0x14, "AUDIO_FORMAT_S32", 0, "32-bit Signed", "Set audio sample format to 32 bit signed integer."},
|
||||
{0x24, "AUDIO_FORMAT_FLOAT", 0, "32-bit Float", "Set audio sample format to 32 bit float."},
|
||||
{0x28, "AUDIO_FORMAT_DOUBLE", 0, "64-bit Float", "Set audio sample format to 64 bit float."},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem audio_channel_items[] = {
|
||||
{1, "AUDIO_CHANNELS_MONO", 0, "Mono", "Set audio channels to mono."},
|
||||
{2, "AUDIO_CHANNELS_STEREO", 0, "Stereo", "Set audio channels to stereo."},
|
||||
{4, "AUDIO_CHANNELS_SURROUND4", 0, "4 Channels", "Set audio channels to 4 channels."},
|
||||
{6, "AUDIO_CHANNELS_SURROUND51", 0, "5.1 Surround", "Set audio channels to 5.1 surround sound."},
|
||||
{8, "AUDIO_CHANNELS_SURROUND71", 0, "7.1 Surround", "Set audio channels to 7.1 surround sound."},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem draw_method_items[] = {
|
||||
@@ -2078,6 +2125,31 @@ static void rna_def_userdef_system(BlenderRNA *brna)
|
||||
RNA_def_property_enum_sdna(prop, NULL, "mixbufsize");
|
||||
RNA_def_property_enum_items(prop, audio_mixing_samples_items);
|
||||
RNA_def_property_ui_text(prop, "Audio Mixing Buffer", "Sets the number of samples used by the audio mixing buffer.");
|
||||
RNA_def_property_update(prop, 0, "rna_UserDef_audio_update");
|
||||
|
||||
prop= RNA_def_property(srna, "audio_device", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "audiodevice");
|
||||
RNA_def_property_enum_items(prop, audio_device_items);
|
||||
RNA_def_property_ui_text(prop, "Audio Device", "Sets the audio output device.");
|
||||
RNA_def_property_update(prop, 0, "rna_UserDef_audio_update");
|
||||
|
||||
prop= RNA_def_property(srna, "audio_sample_rate", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "audiorate");
|
||||
RNA_def_property_enum_items(prop, audio_rate_items);
|
||||
RNA_def_property_ui_text(prop, "Audio Sample Rate", "Sets the audio sample rate.");
|
||||
RNA_def_property_update(prop, 0, "rna_UserDef_audio_update");
|
||||
|
||||
prop= RNA_def_property(srna, "audio_sample_format", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "audioformat");
|
||||
RNA_def_property_enum_items(prop, audio_format_items);
|
||||
RNA_def_property_ui_text(prop, "Audio Sample Format", "Sets the audio sample format.");
|
||||
RNA_def_property_update(prop, 0, "rna_UserDef_audio_update");
|
||||
|
||||
prop= RNA_def_property(srna, "audio_channels", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "audiochannels");
|
||||
RNA_def_property_enum_items(prop, audio_channel_items);
|
||||
RNA_def_property_ui_text(prop, "Audio Channels", "Sets the audio channel count.");
|
||||
RNA_def_property_update(prop, 0, "rna_UserDef_audio_update");
|
||||
|
||||
#if 0
|
||||
prop= RNA_def_property(srna, "verse_master", PROP_STRING, PROP_NONE);
|
||||
|
||||
@@ -2692,7 +2692,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
|
||||
re->result_ok= 0;
|
||||
|
||||
if(BKE_imtype_is_movie(scene->r.imtype))
|
||||
mh->start_movie(&re->r, re->rectx, re->recty);
|
||||
mh->start_movie(scene, &re->r, re->rectx, re->recty);
|
||||
|
||||
if (mh->get_next_frame) {
|
||||
while (!(G.afbreek == 1)) {
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_draw.h"
|
||||
|
||||
|
||||
#include "BKE_sound.h"
|
||||
|
||||
/* XXX */
|
||||
static void sound_init_listener(void)
|
||||
@@ -156,6 +156,8 @@ void WM_init(bContext *C)
|
||||
|
||||
read_Blog();
|
||||
BLI_strncpy(G.lib, G.sce, FILE_MAX);
|
||||
|
||||
sound_init();
|
||||
}
|
||||
|
||||
/* free strings of open recent files */
|
||||
@@ -184,7 +186,9 @@ extern void free_posebuf();
|
||||
void WM_exit(bContext *C)
|
||||
{
|
||||
wmWindow *win;
|
||||
|
||||
|
||||
sound_exit();
|
||||
|
||||
/* first wrap up running stuff, we assume only the active WM is running */
|
||||
/* modal handlers are on window level freed, others too? */
|
||||
/* note; same code copied in wm_files.c */
|
||||
|
||||
@@ -174,6 +174,7 @@ IF(WIN32)
|
||||
COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python26.dll\" \"${TARGETDIR}\\\"
|
||||
COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python26_d.dll\" \"${TARGETDIR}\\\"
|
||||
COMMAND copy /Y \"${WIN_LIBDIR}\\pthreads\\lib\\pthreadVC2.dll\" \"${TARGETDIR}\\\"
|
||||
COMMAND copy /Y \"${WIN_LIBDIR}\\samplerate\\lib\\libsamplerate-0.dll\" \"${TARGETDIR}\\\"
|
||||
)
|
||||
|
||||
IF(WITH_INTERNATIONAL)
|
||||
@@ -284,6 +285,7 @@ IF(UNIX)
|
||||
bf_dna
|
||||
bf_blenfont
|
||||
bf_soundsystem
|
||||
bf_audaspace
|
||||
)
|
||||
|
||||
FOREACH(SORTLIB ${BLENDER_SORTED_LIBS})
|
||||
|
||||
@@ -186,19 +186,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
|
||||
// create a networkdevice
|
||||
NG_NetworkDeviceInterface* networkdevice = new
|
||||
NG_LoopBackNetworkDeviceInterface();
|
||||
|
||||
|
||||
//
|
||||
SYS_SystemHandle hSystem = SYS_GetSystem();
|
||||
bool noaudio = SYS_GetCommandLineInt(hSystem,"noaudio",0);
|
||||
|
||||
if (noaudio)/*(noaudio) intrr: disable game engine audio (openal) */
|
||||
SND_DeviceManager::SetDeviceType(snd_e_dummydevice);
|
||||
|
||||
// get an audiodevice
|
||||
SND_DeviceManager::Subscribe();
|
||||
SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
|
||||
audiodevice->UseCD();
|
||||
|
||||
// create a ketsji/blendersystem (only needed for timing and stuff)
|
||||
KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
|
||||
|
||||
@@ -213,7 +202,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
|
||||
ketsjiengine->SetRenderTools(rendertools);
|
||||
ketsjiengine->SetRasterizer(rasterizer);
|
||||
ketsjiengine->SetNetworkDevice(networkdevice);
|
||||
ketsjiengine->SetAudioDevice(audiodevice);
|
||||
ketsjiengine->SetUseFixedTime(usefixed);
|
||||
ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
|
||||
|
||||
@@ -374,7 +362,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
|
||||
KX_Scene* startscene = new KX_Scene(keyboarddevice,
|
||||
mousedevice,
|
||||
networkdevice,
|
||||
audiodevice,
|
||||
startscenename,
|
||||
blscene);
|
||||
|
||||
@@ -519,8 +506,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw
|
||||
canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
|
||||
|
||||
// clean up some stuff
|
||||
audiodevice->StopCD();
|
||||
|
||||
if (ketsjiengine)
|
||||
{
|
||||
delete ketsjiengine;
|
||||
@@ -637,11 +622,6 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
|
||||
NG_NetworkDeviceInterface* networkdevice = new
|
||||
NG_LoopBackNetworkDeviceInterface();
|
||||
|
||||
// get an audiodevice
|
||||
SND_DeviceManager::Subscribe();
|
||||
SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
|
||||
audiodevice->UseCD();
|
||||
|
||||
// create a ketsji/blendersystem (only needed for timing and stuff)
|
||||
KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
|
||||
|
||||
@@ -692,7 +672,6 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
|
||||
KX_Scene* startscene = new KX_Scene(keyboarddevice,
|
||||
mousedevice,
|
||||
networkdevice,
|
||||
audiodevice,
|
||||
startscenename,
|
||||
blscene);
|
||||
|
||||
@@ -756,7 +735,6 @@ extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
|
||||
canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
|
||||
|
||||
// clean up some stuff
|
||||
audiodevice->StopCD();
|
||||
if (ketsjiengine)
|
||||
{
|
||||
delete ketsjiengine;
|
||||
|
||||
@@ -101,9 +101,6 @@
|
||||
#include "KX_KetsjiEngine.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
|
||||
#include"SND_Scene.h"
|
||||
#include "SND_SoundListener.h"
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
@@ -2616,23 +2613,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
}
|
||||
}
|
||||
|
||||
sumolist->Release();
|
||||
|
||||
// convert global sound stuff
|
||||
|
||||
/* XXX, glob is the very very wrong place for this
|
||||
* to be, re-enable once the listener has been moved into
|
||||
* the scene. */
|
||||
#if 1
|
||||
SND_Scene* soundscene = kxscene->GetSoundScene();
|
||||
SND_SoundListener* listener = soundscene->GetListener();
|
||||
if (listener && G.listener)
|
||||
{
|
||||
listener->SetDopplerFactor(G.listener->dopplerfactor);
|
||||
listener->SetDopplerVelocity(G.listener->dopplervelocity);
|
||||
listener->SetGain(G.listener->gain);
|
||||
}
|
||||
#endif
|
||||
sumolist->Release();
|
||||
|
||||
// convert world
|
||||
KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
|
||||
|
||||
@@ -32,6 +32,7 @@ SET(INC
|
||||
../../../intern/string
|
||||
../../../intern/guardedalloc
|
||||
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
|
||||
../../../intern/audaspace
|
||||
../../../intern/SoundSystem
|
||||
../../../intern/SoundSystem/include
|
||||
../../../intern/SoundSystem/openal
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
#include "KX_ConvertActuators.h"
|
||||
#include "SND_Scene.h"
|
||||
#include "AUD_C-API.h"
|
||||
// Actuators
|
||||
//SCA logiclibrary native logicbricks
|
||||
#include "SCA_PropertyActuator.h"
|
||||
@@ -347,8 +347,7 @@ void BL_ConvertActuators(char* maggiename,
|
||||
{
|
||||
bSoundActuator* soundact = (bSoundActuator*) bact->data;
|
||||
/* get type, and possibly a start and end frame */
|
||||
short startFrame = soundact->sta, stopFrame = soundact->end;
|
||||
KX_SoundActuator::KX_SOUNDACT_TYPE
|
||||
KX_SoundActuator::KX_SOUNDACT_TYPE
|
||||
soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
|
||||
|
||||
switch(soundact->type) {
|
||||
@@ -378,114 +377,38 @@ void BL_ConvertActuators(char* maggiename,
|
||||
|
||||
if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF)
|
||||
{
|
||||
SND_Scene* soundscene = scene->GetSoundScene();
|
||||
STR_String samplename = "";
|
||||
bool sampleisloaded = false;
|
||||
|
||||
if (soundact->sound) {
|
||||
/* Need to convert the samplename into absolute path
|
||||
* before checking if its loaded */
|
||||
char fullpath[FILE_MAX];
|
||||
|
||||
/* dont modify soundact->sound->name, only change a copy */
|
||||
BLI_strncpy(fullpath, soundact->sound->name, sizeof(fullpath));
|
||||
BLI_convertstringcode(fullpath, maggiename);
|
||||
samplename = fullpath;
|
||||
|
||||
/* let's see if the sample was already loaded */
|
||||
if (soundscene->IsSampleLoaded(samplename))
|
||||
{
|
||||
sampleisloaded = true;
|
||||
}
|
||||
else {
|
||||
/* if not, make it so */
|
||||
PackedFile* pf = soundact->sound->newpackedfile;
|
||||
|
||||
/* but we need a packed file then */
|
||||
if (pf)
|
||||
{
|
||||
if (soundscene->LoadSample(samplename, pf->data, pf->size) > -1)
|
||||
sampleisloaded = true;
|
||||
}
|
||||
/* or else load it from disk */
|
||||
else
|
||||
{
|
||||
if (soundscene->LoadSample(samplename, NULL, 0) > -1) {
|
||||
sampleisloaded = true;
|
||||
}
|
||||
else {
|
||||
std::cout << "WARNING: Sound actuator \"" << bact->name <<
|
||||
"\" from object \"" << blenderobject->id.name+2 <<
|
||||
"\" failed to load sample." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bSound* sound = soundact->sound;
|
||||
bool is3d = soundact->flag & ACT_SND_3D_SOUND ? true : false;
|
||||
AUD_Sound* snd_sound = NULL;
|
||||
KX_3DSoundSettings settings;
|
||||
settings.cone_inner_angle = soundact->sound3D.cone_inner_angle;
|
||||
settings.cone_outer_angle = soundact->sound3D.cone_outer_angle;
|
||||
settings.cone_outer_gain = soundact->sound3D.cone_outer_gain;
|
||||
settings.max_distance = soundact->sound3D.max_distance;
|
||||
settings.max_gain = soundact->sound3D.max_gain;
|
||||
settings.min_gain = soundact->sound3D.min_gain;
|
||||
settings.reference_distance = soundact->sound3D.reference_distance;
|
||||
settings.rolloff_factor = soundact->sound3D.rolloff_factor;
|
||||
|
||||
if(!sound)
|
||||
{
|
||||
std::cout << "WARNING: Sound actuator \"" << bact->name <<
|
||||
"\" from object \"" << blenderobject->id.name+2 <<
|
||||
"\" has no sound datablock." << std::endl;
|
||||
}
|
||||
|
||||
/* Note, allowing actuators for sounds that are not there was added since 2.47
|
||||
* This is because python may expect the actuator and raise an exception if it dosnt find it
|
||||
* better just to add a dummy sound actuator. */
|
||||
SND_SoundObject* sndobj = NULL;
|
||||
if (sampleisloaded)
|
||||
{
|
||||
/* setup the SND_SoundObject */
|
||||
sndobj = new SND_SoundObject();
|
||||
sndobj->SetSampleName(samplename.Ptr());
|
||||
sndobj->SetObjectName(bact->name);
|
||||
if (soundact->sound) {
|
||||
sndobj->SetRollOffFactor(soundact->sound->attenuation);
|
||||
sndobj->SetGain(soundact->sound->volume);
|
||||
sndobj->SetPitch(exp((soundact->sound->pitch / 12.0) * log(2.0)));
|
||||
// sndobj->SetLoopStart(soundact->sound->loopstart);
|
||||
// sndobj->SetLoopStart(soundact->sound->loopend);
|
||||
if (soundact->sound->flags & SOUND_FLAGS_LOOP)
|
||||
{
|
||||
if (soundact->sound->flags & SOUND_FLAGS_BIDIRECTIONAL_LOOP)
|
||||
sndobj->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
|
||||
else
|
||||
sndobj->SetLoopMode(SND_LOOP_NORMAL);
|
||||
}
|
||||
else {
|
||||
sndobj->SetLoopMode(SND_LOOP_OFF);
|
||||
}
|
||||
|
||||
if (soundact->sound->flags & SOUND_FLAGS_PRIORITY)
|
||||
sndobj->SetHighPriority(true);
|
||||
else
|
||||
sndobj->SetHighPriority(false);
|
||||
|
||||
if (soundact->sound->flags & SOUND_FLAGS_3D)
|
||||
sndobj->Set3D(true);
|
||||
else
|
||||
sndobj->Set3D(false);
|
||||
}
|
||||
else {
|
||||
/* dummy values for a NULL sound
|
||||
* see editsound.c - defaults are unlikely to change soon */
|
||||
sndobj->SetRollOffFactor(1.0);
|
||||
sndobj->SetGain(1.0);
|
||||
sndobj->SetPitch(1.0);
|
||||
sndobj->SetLoopMode(SND_LOOP_OFF);
|
||||
sndobj->SetHighPriority(false);
|
||||
sndobj->Set3D(false);
|
||||
}
|
||||
}
|
||||
KX_SoundActuator* tmpsoundact =
|
||||
new KX_SoundActuator(gameobj,
|
||||
sndobj,
|
||||
scene->GetSoundScene(), // needed for replication!
|
||||
soundActuatorType,
|
||||
startFrame,
|
||||
stopFrame);
|
||||
|
||||
else
|
||||
snd_sound = sound->cache ? sound->cache : sound->snd_sound;
|
||||
KX_SoundActuator* tmpsoundact =
|
||||
new KX_SoundActuator(gameobj,
|
||||
snd_sound,
|
||||
soundact->volume,
|
||||
exp((soundact->pitch / 12.0) * log(2.0)),
|
||||
is3d,
|
||||
settings,
|
||||
soundActuatorType);
|
||||
|
||||
tmpsoundact->SetName(bact->name);
|
||||
baseact = tmpsoundact;
|
||||
if (sndobj)
|
||||
soundscene->AddObject(sndobj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -525,27 +448,6 @@ void BL_ConvertActuators(char* maggiename,
|
||||
/* This is an error!!! */
|
||||
cdActuatorType = KX_CDActuator::KX_CDACT_NODEF;
|
||||
}
|
||||
|
||||
if (cdActuatorType != KX_CDActuator::KX_CDACT_NODEF)
|
||||
{
|
||||
SND_CDObject* pCD = SND_CDObject::Instance();
|
||||
|
||||
if (pCD)
|
||||
{
|
||||
pCD->SetGain(cdact->volume);
|
||||
|
||||
KX_CDActuator* tmpcdact =
|
||||
new KX_CDActuator(gameobj,
|
||||
scene->GetSoundScene(), // needed for replication!
|
||||
cdActuatorType,
|
||||
cdact->track,
|
||||
startFrame,
|
||||
stopFrame);
|
||||
|
||||
tmpcdact->SetName(bact->name);
|
||||
baseact = tmpcdact;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACT_PROPERTY:
|
||||
|
||||
@@ -6,6 +6,7 @@ defs = []
|
||||
|
||||
incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc'
|
||||
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
|
||||
incs += ' #intern/audaspace'
|
||||
incs += ' #intern/SoundSystem #intern/SoundSystem/include #intern/SoundSystem/openal'
|
||||
incs += ' #intern/SoundSystem/dummy #intern/SoundSystem/intern #source/gameengine/Converter'
|
||||
incs += ' #source/gameengine/BlenderRoutines #source/blender/imbuf'
|
||||
|
||||
@@ -55,6 +55,7 @@ SET(INC
|
||||
../../../source/gameengine/Physics/Sumo
|
||||
../../../source/gameengine/Physics/Sumo/Fuzzics/include
|
||||
../../../source/gameengine/Network/LoopBackNetwork
|
||||
../../../intern/audaspace
|
||||
../../../intern/SoundSystem
|
||||
../../../source/blender/misc
|
||||
../../../source/blender/blenloader
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "KX_CDActuator.h"
|
||||
#include "SND_CDObject.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "SND_Scene.h" // needed for replication
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@@ -44,21 +42,18 @@
|
||||
/* Native functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
KX_CDActuator::KX_CDActuator(SCA_IObject* gameobject,
|
||||
SND_Scene* soundscene,
|
||||
KX_CDACT_TYPE type,
|
||||
int track,
|
||||
short start,
|
||||
short end)
|
||||
: SCA_IActuator(gameobject)
|
||||
{
|
||||
m_soundscene = soundscene;
|
||||
m_type = type;
|
||||
m_track = track;
|
||||
m_lastEvent = true;
|
||||
m_isplaying = false;
|
||||
m_startFrame = start;
|
||||
m_endFrame = end;
|
||||
m_gain = SND_CDObject::Instance()->GetGain();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,60 +77,13 @@ bool KX_CDActuator::Update()
|
||||
{
|
||||
bool result = false;
|
||||
bool bNegativeEvent = IsNegativeEvent();
|
||||
|
||||
|
||||
RemoveAllEvents();
|
||||
|
||||
|
||||
if (!bNegativeEvent)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case KX_CDACT_PLAY_ALL:
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
|
||||
SND_CDObject::Instance()->SetTrack(1);
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
|
||||
//result = true;
|
||||
break;
|
||||
}
|
||||
case KX_CDACT_PLAY_TRACK:
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK);
|
||||
SND_CDObject::Instance()->SetTrack(m_track);
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
|
||||
//result = true;
|
||||
break;
|
||||
}
|
||||
case KX_CDACT_LOOP_TRACK:
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
|
||||
SND_CDObject::Instance()->SetTrack(m_track);
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
|
||||
//result = true;
|
||||
break;
|
||||
}
|
||||
case KX_CDACT_STOP:
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP);
|
||||
break;
|
||||
}
|
||||
case KX_CDACT_PAUSE:
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
|
||||
//result = true;
|
||||
break;
|
||||
}
|
||||
case KX_CDACT_RESUME:
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_RESUME);
|
||||
//result = true;
|
||||
break;
|
||||
}
|
||||
case KX_CDACT_VOLUME:
|
||||
{
|
||||
SND_CDObject::Instance()->SetGain(m_gain);
|
||||
//result = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// implement me !!
|
||||
break;
|
||||
@@ -196,7 +144,6 @@ PyMethodDef KX_CDActuator::Methods[] = {
|
||||
};
|
||||
|
||||
PyAttributeDef KX_CDActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_FLOAT_RW_CHECK("volume", 0.0, 1.0, KX_CDActuator, m_gain,pyattr_setGain),
|
||||
KX_PYATTRIBUTE_INT_RW("track", 1, 99, false, KX_CDActuator, m_track),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
@@ -204,7 +151,6 @@ PyAttributeDef KX_CDActuator::Attributes[] = {
|
||||
int KX_CDActuator::pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_CDActuator* act = static_cast<KX_CDActuator*>(self);
|
||||
SND_CDObject::Instance()->SetGain(act->m_gain);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -212,34 +158,30 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, startCD,
|
||||
"startCD()\n"
|
||||
"\tStarts the CD playing.\n")
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, pauseCD,
|
||||
"pauseCD()\n"
|
||||
"\tPauses the CD playing.\n")
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, resumeCD,
|
||||
"resumeCD()\n"
|
||||
"\tResumes the CD playing.\n")
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_RESUME);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, stopCD,
|
||||
"stopCD()\n"
|
||||
"\tStops the CD playing.\n")
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -250,9 +192,6 @@ KX_PYMETHODDEF_DOC_O(KX_CDActuator, playTrack,
|
||||
{
|
||||
if (PyLong_Check(value)) {
|
||||
int track = PyLong_AsSsize_t(value);
|
||||
SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK);
|
||||
SND_CDObject::Instance()->SetTrack(track);
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -263,11 +202,8 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, playAll,
|
||||
"playAll()\n"
|
||||
"\tPlays the CD from the beginning.\n")
|
||||
{
|
||||
SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL);
|
||||
SND_CDObject::Instance()->SetTrack(1);
|
||||
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated ----->
|
||||
PyObject* KX_CDActuator::PySetGain(PyObject* args)
|
||||
@@ -276,20 +212,18 @@ PyObject* KX_CDActuator::PySetGain(PyObject* args)
|
||||
ShowDeprecationWarning("setGain()", "the volume property");
|
||||
if (!PyArg_ParseTuple(args, "f:setGain", &gain))
|
||||
return NULL;
|
||||
|
||||
SND_CDObject::Instance()->SetGain(gain);
|
||||
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_CDActuator::PyGetGain(PyObject* args)
|
||||
{
|
||||
float gain = SND_CDObject::Instance()->GetGain();
|
||||
float gain = 1.0;
|
||||
ShowDeprecationWarning("getGain()", "the volume property");
|
||||
PyObject* result = PyFloat_FromDouble(gain);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
// <-----
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#define __KX_CDACTUATOR
|
||||
|
||||
#include "SCA_IActuator.h"
|
||||
#include "SND_CDObject.h"
|
||||
|
||||
class KX_CDActuator : public SCA_IActuator
|
||||
{
|
||||
@@ -41,9 +40,7 @@ class KX_CDActuator : public SCA_IActuator
|
||||
bool m_lastEvent;
|
||||
bool m_isplaying;
|
||||
/* just some handles to the audio-data... */
|
||||
class SND_Scene* m_soundscene;
|
||||
int m_track;
|
||||
float m_gain;
|
||||
short m_startFrame;
|
||||
short m_endFrame;
|
||||
|
||||
@@ -64,7 +61,6 @@ public:
|
||||
KX_CDACT_TYPE m_type;
|
||||
|
||||
KX_CDActuator(SCA_IObject* gameobject,
|
||||
SND_Scene* soundscene,
|
||||
KX_CDACT_TYPE type,
|
||||
int track,
|
||||
short start,
|
||||
|
||||
@@ -61,8 +61,7 @@
|
||||
#include "KX_PyConstraintBinding.h"
|
||||
#include "PHY_IPhysicsEnvironment.h"
|
||||
|
||||
#include "SND_Scene.h"
|
||||
#include "SND_IAudioDevice.h"
|
||||
#include "AUD_C-API.h"
|
||||
|
||||
#include "NG_NetworkScene.h"
|
||||
#include "NG_NetworkDeviceInterface.h"
|
||||
@@ -113,7 +112,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
|
||||
m_rendertools(NULL),
|
||||
m_sceneconverter(NULL),
|
||||
m_networkdevice(NULL),
|
||||
m_audiodevice(NULL),
|
||||
m_pythondictionary(NULL),
|
||||
m_keyboarddevice(NULL),
|
||||
m_mousedevice(NULL),
|
||||
@@ -211,15 +209,6 @@ void KX_KetsjiEngine::SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_KetsjiEngine::SetAudioDevice(SND_IAudioDevice* audiodevice)
|
||||
{
|
||||
MT_assert(audiodevice);
|
||||
m_audiodevice = audiodevice;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_KetsjiEngine::SetCanvas(RAS_ICanvas* canvas)
|
||||
{
|
||||
MT_assert(canvas);
|
||||
@@ -690,10 +679,7 @@ else
|
||||
|
||||
if (m_networkdevice)
|
||||
m_networkdevice->NextFrame();
|
||||
|
||||
if (m_audiodevice)
|
||||
m_audiodevice->NextFrame();
|
||||
|
||||
|
||||
// scene management
|
||||
ProcessScheduledScenes();
|
||||
|
||||
@@ -970,13 +956,40 @@ void KX_KetsjiEngine::DoSound(KX_Scene* scene)
|
||||
MT_Vector3 listenervelocity = cam->GetLinearVelocity();
|
||||
MT_Matrix3x3 listenerorientation = cam->NodeGetWorldOrientation();
|
||||
|
||||
SND_Scene* soundscene = scene->GetSoundScene();
|
||||
soundscene->SetListenerTransform(
|
||||
listenerposition,
|
||||
listenervelocity,
|
||||
listenerorientation);
|
||||
{
|
||||
AUD_3DData data;
|
||||
float f;
|
||||
|
||||
soundscene->Proceed();
|
||||
listenerorientation.getValue3x3(data.orientation);
|
||||
listenerposition.getValue(data.position);
|
||||
listenervelocity.getValue(data.velocity);
|
||||
|
||||
f = data.position[1];
|
||||
data.position[1] = data.position[2];
|
||||
data.position[2] = -f;
|
||||
|
||||
f = data.velocity[1];
|
||||
data.velocity[1] = data.velocity[2];
|
||||
data.velocity[2] = -f;
|
||||
|
||||
f = data.orientation[1];
|
||||
data.orientation[1] = data.orientation[2];
|
||||
data.orientation[2] = -f;
|
||||
|
||||
f = data.orientation[3];
|
||||
data.orientation[3] = -data.orientation[6];
|
||||
data.orientation[6] = f;
|
||||
|
||||
f = data.orientation[4];
|
||||
data.orientation[4] = -data.orientation[8];
|
||||
data.orientation[8] = -f;
|
||||
|
||||
f = data.orientation[5];
|
||||
data.orientation[5] = data.orientation[7];
|
||||
data.orientation[7] = f;
|
||||
|
||||
AUD_updateListener(&data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1595,7 +1608,6 @@ KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
|
||||
KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
|
||||
m_mousedevice,
|
||||
m_networkdevice,
|
||||
m_audiodevice,
|
||||
scenename,
|
||||
scene);
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ private:
|
||||
class RAS_IRenderTools* m_rendertools;
|
||||
class KX_ISceneConverter* m_sceneconverter;
|
||||
class NG_NetworkDeviceInterface* m_networkdevice;
|
||||
class SND_IAudioDevice* m_audiodevice;
|
||||
PyObject* m_pythondictionary;
|
||||
class SCA_IInputDevice* m_keyboarddevice;
|
||||
class SCA_IInputDevice* m_mousedevice;
|
||||
@@ -200,7 +199,6 @@ public:
|
||||
void SetKeyboardDevice(SCA_IInputDevice* keyboarddevice);
|
||||
void SetMouseDevice(SCA_IInputDevice* mousedevice);
|
||||
void SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice);
|
||||
void SetAudioDevice(SND_IAudioDevice* audiodevice);
|
||||
void SetCanvas(RAS_ICanvas* canvas);
|
||||
void SetRenderTools(RAS_IRenderTools* rendertools);
|
||||
void SetRasterizer(RAS_IRasterizer* rasterizer);
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#include "KX_Scene.h"
|
||||
#include "MT_assert.h"
|
||||
#include "SND_Scene.h"
|
||||
#include "KX_KetsjiEngine.h"
|
||||
#include "KX_BlenderMaterial.h"
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
@@ -135,7 +134,6 @@ extern bool gUseVisibilityTemp;
|
||||
KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
||||
class SCA_IInputDevice* mousedevice,
|
||||
class NG_NetworkDeviceInterface *ndi,
|
||||
class SND_IAudioDevice* adi,
|
||||
const STR_String& sceneName,
|
||||
Scene *scene):
|
||||
PyObjectPlus(),
|
||||
@@ -144,7 +142,6 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
||||
m_sceneConverter(NULL),
|
||||
m_physicsEnvironment(0),
|
||||
m_sceneName(sceneName),
|
||||
m_adi(adi),
|
||||
m_networkDeviceInterface(ndi),
|
||||
m_active_camera(NULL),
|
||||
m_ueberExecutionPriority(0),
|
||||
@@ -200,7 +197,6 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
||||
m_logicmgr->RegisterEventManager(joymgr);
|
||||
}
|
||||
|
||||
m_soundScene = new SND_Scene(adi);
|
||||
MT_assert (m_networkDeviceInterface != NULL);
|
||||
m_networkScene = new NG_NetworkScene(m_networkDeviceInterface);
|
||||
|
||||
@@ -250,9 +246,6 @@ KX_Scene::~KX_Scene()
|
||||
if (m_physicsEnvironment)
|
||||
delete m_physicsEnvironment;
|
||||
|
||||
if (m_soundScene)
|
||||
delete m_soundScene;
|
||||
|
||||
if (m_networkScene)
|
||||
delete m_networkScene;
|
||||
|
||||
@@ -364,12 +357,6 @@ class KX_WorldInfo* KX_Scene::GetWorldInfo()
|
||||
}
|
||||
|
||||
|
||||
|
||||
SND_Scene* KX_Scene::GetSoundScene()
|
||||
{
|
||||
return m_soundScene;
|
||||
}
|
||||
|
||||
const STR_String& KX_Scene::GetName()
|
||||
{
|
||||
return m_sceneName;
|
||||
|
||||
@@ -63,8 +63,6 @@ class SCA_TimeEventManager;
|
||||
class SCA_MouseManager;
|
||||
class SCA_ISystem;
|
||||
class SCA_IInputDevice;
|
||||
class SND_Scene;
|
||||
class SND_IAudioDevice;
|
||||
class NG_NetworkDeviceInterface;
|
||||
class NG_NetworkScene;
|
||||
class SG_IObject;
|
||||
@@ -160,14 +158,7 @@ protected:
|
||||
* @section Different scenes, linked to ketsji scene
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Sound scenes
|
||||
*/
|
||||
SND_Scene* m_soundScene;
|
||||
SND_IAudioDevice* m_adi;
|
||||
|
||||
/**
|
||||
* Network scene.
|
||||
*/
|
||||
NG_NetworkDeviceInterface* m_networkDeviceInterface;
|
||||
@@ -283,7 +274,6 @@ public:
|
||||
KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
||||
class SCA_IInputDevice* mousedevice,
|
||||
class NG_NetworkDeviceInterface* ndi,
|
||||
class SND_IAudioDevice* adi,
|
||||
const STR_String& scenename,
|
||||
struct Scene* scene);
|
||||
|
||||
@@ -480,7 +470,6 @@ public:
|
||||
void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam, int layer=0);
|
||||
void UpdateMeshTransformations();
|
||||
KX_Camera* GetpCamera();
|
||||
SND_Scene* GetSoundScene();
|
||||
NG_NetworkDeviceInterface* GetNetworkDeviceInterface();
|
||||
NG_NetworkScene* GetNetworkScene();
|
||||
|
||||
|
||||
@@ -46,37 +46,94 @@
|
||||
/* Native functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
|
||||
SND_SoundObject* sndobj,
|
||||
SND_Scene* sndscene,
|
||||
KX_SOUNDACT_TYPE type,
|
||||
short start,
|
||||
short end)
|
||||
AUD_Sound* sound,
|
||||
float volume,
|
||||
float pitch,
|
||||
bool is3d,
|
||||
KX_3DSoundSettings settings,
|
||||
KX_SOUNDACT_TYPE type)//,
|
||||
: SCA_IActuator(gameobj)
|
||||
{
|
||||
m_soundObject = sndobj;
|
||||
m_soundScene = sndscene;
|
||||
m_sound = sound;
|
||||
m_volume = volume;
|
||||
m_pitch = pitch;
|
||||
m_is3d = is3d;
|
||||
m_3d = settings;
|
||||
m_handle = NULL;
|
||||
m_type = type;
|
||||
m_lastEvent = true;
|
||||
m_isplaying = false;
|
||||
m_startFrame = start;
|
||||
m_endFrame = end;
|
||||
m_pino = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
KX_SoundActuator::~KX_SoundActuator()
|
||||
{
|
||||
if (m_soundObject)
|
||||
{
|
||||
m_soundScene->RemoveActiveObject(m_soundObject);
|
||||
m_soundScene->DeleteObject(m_soundObject);
|
||||
}
|
||||
if(m_handle)
|
||||
AUD_stop(m_handle);
|
||||
}
|
||||
|
||||
void KX_SoundActuator::play()
|
||||
{
|
||||
if(m_handle)
|
||||
AUD_stop(m_handle);
|
||||
|
||||
if(!m_sound)
|
||||
return;
|
||||
|
||||
// this is the sound that will be played and not deleted afterwards
|
||||
AUD_Sound* sound = m_sound;
|
||||
// this sounds are for temporary stacked sounds, will be deleted if not NULL
|
||||
AUD_Sound* sound2 = NULL;
|
||||
AUD_Sound* sound3 = NULL;
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case KX_SOUNDACT_LOOPBIDIRECTIONAL:
|
||||
case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
|
||||
// create a ping pong sound on sound2 stacked on the orignal sound
|
||||
sound2 = AUD_pingpongSound(sound);
|
||||
// create a loop sound on sound3 stacked on the pingpong sound and let that one play (save it to sound)
|
||||
sound = sound3 = AUD_loopSound(sound2);
|
||||
break;
|
||||
case KX_SOUNDACT_LOOPEND:
|
||||
case KX_SOUNDACT_LOOPSTOP:
|
||||
// create a loop sound on sound2 stacked on the pingpong sound and let that one play (save it to sound)
|
||||
sound = sound2 = AUD_loopSound(sound);
|
||||
break;
|
||||
case KX_SOUNDACT_PLAYSTOP:
|
||||
case KX_SOUNDACT_PLAYEND:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_is3d)
|
||||
{
|
||||
// sound shall be played 3D
|
||||
m_handle = AUD_play3D(sound, 0);
|
||||
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_MAX_GAIN, m_3d.max_gain);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_MIN_GAIN, m_3d.min_gain);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_REFERENCE_DISTANCE, m_3d.reference_distance);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_MAX_DISTANCE, m_3d.max_distance);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_ROLLOFF_FACTOR, m_3d.rolloff_factor);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_CONE_INNER_ANGLE, m_3d.cone_inner_angle);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_CONE_OUTER_ANGLE, m_3d.cone_outer_angle);
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_CONE_OUTER_GAIN, m_3d.cone_outer_gain);
|
||||
}
|
||||
else
|
||||
m_handle = AUD_play(sound, 0);
|
||||
|
||||
AUD_setSoundPitch(m_handle, m_pitch);
|
||||
AUD_setSoundVolume(m_handle, m_volume);
|
||||
m_isplaying = true;
|
||||
|
||||
// now we unload the pingpong and loop sounds, as we don't need them anymore
|
||||
// the started sound will continue playing like it was created, don't worry!
|
||||
if(sound3)
|
||||
AUD_unload(sound3);
|
||||
if(sound2)
|
||||
AUD_unload(sound2);
|
||||
}
|
||||
|
||||
CValue* KX_SoundActuator::GetReplica()
|
||||
{
|
||||
@@ -88,13 +145,8 @@ CValue* KX_SoundActuator::GetReplica()
|
||||
void KX_SoundActuator::ProcessReplica()
|
||||
{
|
||||
SCA_IActuator::ProcessReplica();
|
||||
if (m_soundObject)
|
||||
{
|
||||
SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
|
||||
setSoundObject(soundobj);
|
||||
m_soundScene->AddObject(soundobj);
|
||||
}
|
||||
}
|
||||
m_handle = 0;
|
||||
}
|
||||
|
||||
bool KX_SoundActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
@@ -108,22 +160,16 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
|
||||
|
||||
RemoveAllEvents();
|
||||
|
||||
if (!m_soundObject)
|
||||
if(!m_sound)
|
||||
return false;
|
||||
|
||||
// actual audio device playing state
|
||||
bool isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED && m_soundObject->GetPlaystate() != SND_INITIAL) ? true : false;
|
||||
|
||||
if (m_pino)
|
||||
{
|
||||
bNegativeEvent = true;
|
||||
m_pino = false;
|
||||
}
|
||||
bool isplaying = AUD_getStatus(m_handle) == AUD_STATUS_PLAYING;
|
||||
|
||||
if (bNegativeEvent)
|
||||
{
|
||||
{
|
||||
// here must be a check if it is still playing
|
||||
if (m_isplaying && isplaying)
|
||||
if (m_isplaying && isplaying)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
@@ -131,19 +177,20 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
|
||||
case KX_SOUNDACT_LOOPSTOP:
|
||||
case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
|
||||
{
|
||||
m_soundScene->RemoveActiveObject(m_soundObject);
|
||||
// stop immediately
|
||||
AUD_stop(m_handle);
|
||||
break;
|
||||
}
|
||||
case KX_SOUNDACT_PLAYEND:
|
||||
{
|
||||
m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
|
||||
// do nothing, sound will stop anyway when it's finished
|
||||
break;
|
||||
}
|
||||
case KX_SOUNDACT_LOOPEND:
|
||||
case KX_SOUNDACT_LOOPBIDIRECTIONAL:
|
||||
{
|
||||
m_soundObject->SetLoopMode(SND_LOOP_OFF);
|
||||
m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
|
||||
// stop the looping so that the sound stops when it finished
|
||||
AUD_stopLoop(m_handle);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -166,50 +213,49 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
|
||||
// the negative pulse is done continuesly
|
||||
#endif
|
||||
if (!m_isplaying)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case KX_SOUNDACT_LOOPBIDIRECTIONAL:
|
||||
case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
|
||||
{
|
||||
m_soundObject->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
|
||||
m_soundScene->AddActiveObject(m_soundObject, curtime);
|
||||
m_isplaying = true;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
case KX_SOUNDACT_LOOPEND:
|
||||
case KX_SOUNDACT_LOOPSTOP:
|
||||
{
|
||||
m_soundObject->SetLoopMode(SND_LOOP_NORMAL);
|
||||
m_soundScene->AddActiveObject(m_soundObject, curtime);
|
||||
m_isplaying = true;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
case KX_SOUNDACT_PLAYSTOP:
|
||||
case KX_SOUNDACT_PLAYEND:
|
||||
{
|
||||
m_soundObject->SetLoopMode(SND_LOOP_OFF);
|
||||
m_soundScene->AddActiveObject(m_soundObject, curtime);
|
||||
m_isplaying = true;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// implement me !!
|
||||
break;
|
||||
}
|
||||
}
|
||||
play();
|
||||
}
|
||||
// verify that the sound is still playing
|
||||
isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED && m_soundObject->GetPlaystate() != SND_INITIAL) ? true : false;
|
||||
isplaying = AUD_getStatus(m_handle) == AUD_STATUS_PLAYING ? true : false;
|
||||
|
||||
if (isplaying)
|
||||
{
|
||||
m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition());
|
||||
m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity());
|
||||
m_soundObject->SetOrientation(((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation());
|
||||
if(m_is3d)
|
||||
{
|
||||
AUD_3DData data;
|
||||
float f;
|
||||
((KX_GameObject*)this->GetParent())->NodeGetWorldPosition().getValue(data.position);
|
||||
((KX_GameObject*)this->GetParent())->GetLinearVelocity().getValue(data.velocity);
|
||||
((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation().getValue3x3(data.orientation);
|
||||
|
||||
/*
|
||||
* The 3D data from blender has to be transformed for OpenAL:
|
||||
* - In blender z is up and y is forwards
|
||||
* - In OpenAL y is up and z is backwards
|
||||
* We have to do that for all 5 vectors.
|
||||
*/
|
||||
f = data.position[1];
|
||||
data.position[1] = data.position[2];
|
||||
data.position[2] = -f;
|
||||
|
||||
f = data.velocity[1];
|
||||
data.velocity[1] = data.velocity[2];
|
||||
data.velocity[2] = -f;
|
||||
|
||||
f = data.orientation[1];
|
||||
data.orientation[1] = data.orientation[2];
|
||||
data.orientation[2] = -f;
|
||||
|
||||
f = data.orientation[4];
|
||||
data.orientation[4] = data.orientation[5];
|
||||
data.orientation[5] = -f;
|
||||
|
||||
f = data.orientation[7];
|
||||
data.orientation[7] = data.orientation[8];
|
||||
data.orientation[8] = -f;
|
||||
|
||||
AUD_update3DSource(m_handle, &data);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
@@ -217,23 +263,11 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
|
||||
m_isplaying = false;
|
||||
result = false;
|
||||
}
|
||||
/*
|
||||
if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP)))
|
||||
{
|
||||
m_pino = true;
|
||||
}
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject)
|
||||
{
|
||||
m_soundObject = soundobject;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python functions */
|
||||
@@ -272,19 +306,12 @@ PyTypeObject KX_SoundActuator::Type = {
|
||||
|
||||
PyMethodDef KX_SoundActuator::Methods[] = {
|
||||
// Deprecated ----->
|
||||
{"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL},
|
||||
{"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_NOARGS,NULL},
|
||||
{"setGain",(PyCFunction) KX_SoundActuator::sPySetGain,METH_VARARGS,NULL},
|
||||
{"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_NOARGS,NULL},
|
||||
{"setPitch",(PyCFunction) KX_SoundActuator::sPySetPitch,METH_VARARGS,NULL},
|
||||
{"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_NOARGS,NULL},
|
||||
{"setRollOffFactor",(PyCFunction) KX_SoundActuator::sPySetRollOffFactor,METH_VARARGS,NULL},
|
||||
{"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_NOARGS,NULL},
|
||||
{"setLooping",(PyCFunction) KX_SoundActuator::sPySetLooping,METH_VARARGS,NULL},
|
||||
{"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_NOARGS,NULL},
|
||||
{"setPosition",(PyCFunction) KX_SoundActuator::sPySetPosition,METH_VARARGS,NULL},
|
||||
{"setVelocity",(PyCFunction) KX_SoundActuator::sPySetVelocity,METH_VARARGS,NULL},
|
||||
{"setOrientation",(PyCFunction) KX_SoundActuator::sPySetOrientation,METH_VARARGS,NULL},
|
||||
{"setType",(PyCFunction) KX_SoundActuator::sPySetType,METH_VARARGS,NULL},
|
||||
{"getType",(PyCFunction) KX_SoundActuator::sPyGetType,METH_NOARGS,NULL},
|
||||
// <-----
|
||||
@@ -296,171 +323,91 @@ PyMethodDef KX_SoundActuator::Methods[] = {
|
||||
};
|
||||
|
||||
PyAttributeDef KX_SoundActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("fileName", KX_SoundActuator, pyattr_get_filename, pyattr_set_filename),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("volume", KX_SoundActuator, pyattr_get_gain, pyattr_set_gain),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("pitch", KX_SoundActuator, pyattr_get_pitch, pyattr_set_pitch),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("rollOffFactor", KX_SoundActuator, pyattr_get_rollOffFactor, pyattr_set_rollOffFactor),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("looping", KX_SoundActuator, pyattr_get_looping, pyattr_set_looping),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("position", KX_SoundActuator, pyattr_get_position, pyattr_set_position),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("velocity", KX_SoundActuator, pyattr_get_velocity, pyattr_set_velocity),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("orientation", KX_SoundActuator, pyattr_get_orientation, pyattr_set_orientation),
|
||||
KX_PYATTRIBUTE_ENUM_RW("mode",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
/* Methods ----------------------------------------------------------------- */
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, startSound,
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, startSound,
|
||||
"startSound()\n"
|
||||
"\tStarts the sound.\n")
|
||||
{
|
||||
if (m_soundObject)
|
||||
// This has no effect if the actuator is not active.
|
||||
// To start the sound you must activate the actuator.
|
||||
// This function is to restart the sound.
|
||||
m_soundObject->StartSound();
|
||||
switch(AUD_getStatus(m_handle))
|
||||
{
|
||||
case AUD_STATUS_PLAYING:
|
||||
break;
|
||||
case AUD_STATUS_PAUSED:
|
||||
AUD_resume(m_handle);
|
||||
break;
|
||||
default:
|
||||
play();
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, pauseSound,
|
||||
"pauseSound()\n"
|
||||
"\tPauses the sound.\n")
|
||||
{
|
||||
if (m_soundObject)
|
||||
// unfortunately, openal does not implement pause correctly, it is equivalent to a stop
|
||||
m_soundObject->PauseSound();
|
||||
AUD_pause(m_handle);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound,
|
||||
"stopSound()\n"
|
||||
"\tStops the sound.\n")
|
||||
{
|
||||
if (m_soundObject)
|
||||
m_soundObject->StopSound();
|
||||
AUD_stop(m_handle);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* Atribute setting and getting -------------------------------------------- */
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
if (!actuator->m_soundObject)
|
||||
{
|
||||
return PyUnicode_FromString("");
|
||||
}
|
||||
STR_String objectname = actuator->m_soundObject->GetObjectName();
|
||||
char* name = objectname.Ptr();
|
||||
|
||||
if (!name) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "value = actuator.fileName: KX_SoundActuator, unable to get sound fileName");
|
||||
return NULL;
|
||||
} else
|
||||
return PyUnicode_FromString(name);
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
float gain = (actuator->m_soundObject) ? actuator->m_soundObject->GetGain() : 1.0f;
|
||||
float gain = actuator->m_volume;
|
||||
|
||||
PyObject* result = PyFloat_FromDouble(gain);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
float pitch = (actuator->m_soundObject) ? actuator->m_soundObject->GetPitch() : 1.0;
|
||||
float pitch = actuator->m_pitch;
|
||||
|
||||
PyObject* result = PyFloat_FromDouble(pitch);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
float rollofffactor = (actuator->m_soundObject) ? actuator->m_soundObject->GetRollOffFactor() : 1.0;
|
||||
float rollofffactor = actuator->m_3d.rolloff_factor;
|
||||
PyObject* result = PyFloat_FromDouble(rollofffactor);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
int looping = (actuator->m_soundObject) ? actuator->m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
|
||||
PyObject* result = PyLong_FromSsize_t(looping);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_position(void * self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
MT_Vector3 pos(0.0, 0.0, 0.0);
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
pos = actuator->m_soundObject->GetPosition();
|
||||
|
||||
PyObject * result = PyObjectFrom(pos);
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
MT_Vector3 vel;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
vel = actuator->m_soundObject->GetVelocity();
|
||||
|
||||
PyObject * result = PyObjectFrom(vel);
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::pyattr_get_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
MT_Matrix3x3 ori;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
ori = actuator->m_soundObject->GetOrientation();
|
||||
|
||||
PyObject * result = PyObjectFrom(ori);
|
||||
return result;
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
char *soundName = NULL;
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator*> (self);
|
||||
// void *soundPointer = NULL; /*unused*/
|
||||
|
||||
if (!PyArg_Parse(value, "s", &soundName))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject) {
|
||||
actuator->m_soundObject->SetObjectName(soundName);
|
||||
}
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int KX_SoundActuator::pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
float gain = 1.0;
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
if (!PyArg_Parse(value, "f", &gain))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
actuator->m_soundObject->SetGain(gain);
|
||||
|
||||
|
||||
actuator->m_volume = gain;
|
||||
if(actuator->m_handle)
|
||||
AUD_setSoundVolume(actuator->m_handle, gain);
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
@@ -468,12 +415,13 @@ int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_D
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
if (!PyArg_Parse(value, "f", &pitch))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
actuator->m_soundObject->SetPitch(pitch);
|
||||
|
||||
|
||||
actuator->m_pitch = pitch;
|
||||
if(actuator->m_handle)
|
||||
AUD_setSoundPitch(actuator->m_handle, pitch);
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
@@ -481,104 +429,12 @@ int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATT
|
||||
float rollofffactor = 1.0;
|
||||
if (!PyArg_Parse(value, "f", &rollofffactor))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
actuator->m_soundObject->SetRollOffFactor(rollofffactor);
|
||||
|
||||
actuator->m_3d.rolloff_factor = rollofffactor;
|
||||
if(actuator->m_handle)
|
||||
AUD_set3DSourceSetting(actuator->m_handle, AUD_3DSS_ROLLOFF_FACTOR, rollofffactor);
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
int looping = 1;
|
||||
if (!PyArg_Parse(value, "i", &looping))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
actuator->m_soundObject->SetLoopMode(looping);
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
float pos[3];
|
||||
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
|
||||
if (!PyArg_ParseTuple(value, "fff", &pos[0], &pos[1], &pos[2]))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
actuator->m_soundObject->SetPosition(MT_Vector3(pos));
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
float vel[3];
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
|
||||
|
||||
if (!PyArg_ParseTuple(value, "fff", &vel[0], &vel[1], &vel[2]))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (actuator->m_soundObject)
|
||||
actuator->m_soundObject->SetVelocity(MT_Vector3(vel));
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
|
||||
MT_Matrix3x3 rot;
|
||||
KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
|
||||
|
||||
/* if value is not a sequence PyOrientationTo makes an error */
|
||||
if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator"))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
/* Since not having m_soundObject didn't do anything in the old version,
|
||||
* it probably should be kept that way */
|
||||
if (!actuator->m_soundObject)
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
|
||||
actuator->m_soundObject->SetOrientation(rot);
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
// Deprecated ----->
|
||||
PyObject* KX_SoundActuator::PySetFilename(PyObject* args)
|
||||
{
|
||||
char *soundName = NULL;
|
||||
ShowDeprecationWarning("setFilename()", "the fileName property");
|
||||
// void *soundPointer = NULL; /*unused*/
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &soundName))
|
||||
return NULL;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::PyGetFilename()
|
||||
{
|
||||
ShowDeprecationWarning("getFilename()", "the fileName property");
|
||||
if (!m_soundObject)
|
||||
{
|
||||
return PyUnicode_FromString("");
|
||||
}
|
||||
STR_String objectname = m_soundObject->GetObjectName();
|
||||
char* name = objectname.Ptr();
|
||||
|
||||
if (!name) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Unable to get sound fileName");
|
||||
return NULL;
|
||||
} else
|
||||
return PyUnicode_FromString(name);
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::PySetGain(PyObject* args)
|
||||
@@ -587,21 +443,22 @@ PyObject* KX_SoundActuator::PySetGain(PyObject* args)
|
||||
float gain = 1.0;
|
||||
if (!PyArg_ParseTuple(args, "f:setGain", &gain))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetGain(gain);
|
||||
|
||||
|
||||
m_volume = gain;
|
||||
if(m_handle)
|
||||
AUD_setSoundVolume(m_handle, gain);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PyGetGain()
|
||||
{
|
||||
ShowDeprecationWarning("getGain()", "the volume property");
|
||||
float gain = (m_soundObject) ? m_soundObject->GetGain() : 1.0f;
|
||||
float gain = m_volume;
|
||||
PyObject* result = PyFloat_FromDouble(gain);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -613,21 +470,22 @@ PyObject* KX_SoundActuator::PySetPitch(PyObject* args)
|
||||
float pitch = 1.0;
|
||||
if (!PyArg_ParseTuple(args, "f:setPitch", &pitch))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetPitch(pitch);
|
||||
|
||||
|
||||
m_pitch = pitch;
|
||||
if(m_handle)
|
||||
AUD_setSoundPitch(m_handle, pitch);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PyGetPitch()
|
||||
{
|
||||
ShowDeprecationWarning("getPitch()", "the pitch property");
|
||||
float pitch = (m_soundObject) ? m_soundObject->GetPitch() : 1.0;
|
||||
float pitch = m_pitch;
|
||||
PyObject* result = PyFloat_FromDouble(pitch);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -639,113 +497,27 @@ PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* args)
|
||||
float rollofffactor = 1.0;
|
||||
if (!PyArg_ParseTuple(args, "f:setRollOffFactor", &rollofffactor))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetRollOffFactor(rollofffactor);
|
||||
|
||||
m_3d.rolloff_factor = rollofffactor;
|
||||
if(m_handle)
|
||||
AUD_set3DSourceSetting(m_handle, AUD_3DSS_ROLLOFF_FACTOR, rollofffactor);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PyGetRollOffFactor()
|
||||
{
|
||||
ShowDeprecationWarning("getRollOffFactor()", "the rollOffFactor property");
|
||||
float rollofffactor = (m_soundObject) ? m_soundObject->GetRollOffFactor() : 1.0;
|
||||
float rollofffactor = m_3d.rolloff_factor;
|
||||
PyObject* result = PyFloat_FromDouble(rollofffactor);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PySetLooping(PyObject* args)
|
||||
{
|
||||
ShowDeprecationWarning("setLooping()", "the looping property");
|
||||
bool looping = 1;
|
||||
if (!PyArg_ParseTuple(args, "i:setLooping", &looping))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetLoopMode(looping);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PyGetLooping()
|
||||
{
|
||||
ShowDeprecationWarning("getLooping()", "the looping property");
|
||||
int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
|
||||
PyObject* result = PyLong_FromSsize_t(looping);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PySetPosition(PyObject* args)
|
||||
{
|
||||
MT_Point3 pos;
|
||||
ShowDeprecationWarning("setPosition()", "the position property");
|
||||
pos[0] = 0.0;
|
||||
pos[1] = 0.0;
|
||||
pos[2] = 0.0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "fff:setPosition", &pos[0], &pos[1], &pos[2]))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetPosition(pos);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PySetVelocity(PyObject* args)
|
||||
{
|
||||
MT_Vector3 vel;
|
||||
ShowDeprecationWarning("setVelocity()", "the velocity property");
|
||||
vel[0] = 0.0;
|
||||
vel[1] = 0.0;
|
||||
vel[2] = 0.0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "fff:setVelocity", &vel[0], &vel[1], &vel[2]))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetVelocity(vel);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_SoundActuator::PySetOrientation(PyObject* args)
|
||||
{
|
||||
MT_Matrix3x3 ori;
|
||||
ShowDeprecationWarning("setOrientation()", "the orientation property");
|
||||
ori[0][0] = 1.0;
|
||||
ori[0][1] = 0.0;
|
||||
ori[0][2] = 0.0;
|
||||
ori[1][0] = 0.0;
|
||||
ori[1][1] = 1.0;
|
||||
ori[1][2] = 0.0;
|
||||
ori[2][0] = 0.0;
|
||||
ori[2][1] = 0.0;
|
||||
ori[2][2] = 1.0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "fffffffff:setOrientation", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
|
||||
return NULL;
|
||||
|
||||
if (m_soundObject)
|
||||
m_soundObject->SetOrientation(ori);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* KX_SoundActuator::PySetType(PyObject* args)
|
||||
{
|
||||
int typeArg;
|
||||
|
||||
@@ -34,17 +34,41 @@
|
||||
|
||||
#include "SCA_IActuator.h"
|
||||
|
||||
#include "AUD_C-API.h"
|
||||
#include "BKE_sound.h"
|
||||
|
||||
typedef struct KX_3DSoundSettings
|
||||
{
|
||||
float min_gain;
|
||||
float max_gain;
|
||||
float reference_distance;
|
||||
float max_distance;
|
||||
float rolloff_factor;
|
||||
float cone_inner_angle;
|
||||
float cone_outer_angle;
|
||||
float cone_outer_gain;
|
||||
} KX_3DSoundSettings;
|
||||
|
||||
class KX_SoundActuator : public SCA_IActuator
|
||||
{
|
||||
Py_Header;
|
||||
bool m_lastEvent;
|
||||
// bool m_lastEvent;
|
||||
bool m_isplaying;
|
||||
/* just some handles to the audio-data... */
|
||||
class SND_SoundObject* m_soundObject;
|
||||
class SND_Scene* m_soundScene;
|
||||
short m_startFrame;
|
||||
short m_endFrame;
|
||||
bool m_pino;
|
||||
AUD_Sound* m_sound;
|
||||
float m_volume;
|
||||
float m_pitch;
|
||||
bool m_is3d;
|
||||
KX_3DSoundSettings m_3d;
|
||||
AUD_Handle* m_handle;
|
||||
// class SND_SoundObject* m_soundObject;
|
||||
// class SND_Scene* m_soundScene;
|
||||
// short m_startFrame;
|
||||
// short m_endFrame;
|
||||
// bool m_pino;
|
||||
|
||||
void play();
|
||||
|
||||
public:
|
||||
|
||||
enum KX_SOUNDACT_TYPE
|
||||
@@ -62,15 +86,15 @@ public:
|
||||
KX_SOUNDACT_TYPE m_type;
|
||||
|
||||
KX_SoundActuator(SCA_IObject* gameobj,
|
||||
class SND_SoundObject* sndobj,
|
||||
class SND_Scene* sndscene,
|
||||
KX_SOUNDACT_TYPE type,
|
||||
short start,
|
||||
short end);
|
||||
AUD_Sound* sound,
|
||||
float volume,
|
||||
float pitch,
|
||||
bool is3d,
|
||||
KX_3DSoundSettings settings,
|
||||
KX_SOUNDACT_TYPE type);
|
||||
|
||||
~KX_SoundActuator();
|
||||
|
||||
void setSoundObject(class SND_SoundObject* soundobject);
|
||||
virtual bool Update(double curtime, bool frame);
|
||||
|
||||
CValue* GetReplica();
|
||||
@@ -84,40 +108,23 @@ public:
|
||||
KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, pauseSound);
|
||||
KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, stopSound);
|
||||
|
||||
static int pyattr_set_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
static PyObject* pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
// Deprecated ----->
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetFilename);
|
||||
KX_PYMETHOD_NOARGS(KX_SoundActuator,GetFilename);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetGain);
|
||||
KX_PYMETHOD_NOARGS(KX_SoundActuator,GetGain);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetPitch);
|
||||
KX_PYMETHOD_NOARGS(KX_SoundActuator,GetPitch);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetRollOffFactor);
|
||||
KX_PYMETHOD_NOARGS(KX_SoundActuator,GetRollOffFactor);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetLooping);
|
||||
KX_PYMETHOD_NOARGS(KX_SoundActuator,GetLooping);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetPosition);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetVelocity);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetOrientation);
|
||||
KX_PYMETHOD_VARARGS(KX_SoundActuator,SetType);
|
||||
KX_PYMETHOD_NOARGS(KX_SoundActuator,GetType);
|
||||
// <-----
|
||||
|
||||
@@ -11,6 +11,7 @@ incs = '. #source/blender/python/generic' # Only for Mathutils! and bpy_internal
|
||||
incs += ' #source/kernel/gen_system #intern/string #intern/guardedalloc'
|
||||
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
|
||||
incs += ' #intern/SoundSystem #intern/SoundSystem/include #intern/SoundSystem/openal'
|
||||
incs += ' #intern/audaspace'
|
||||
incs += ' #intern/SoundSystem/dummy #intern/SoundSystem/intern #source/gameengine/Converter'
|
||||
incs += ' #source/gameengine/BlenderRoutines #source/blender/imbuf #intern/moto/include'
|
||||
incs += ' #source/gameengine/Ketsji #source/gameengine/Ketsji/KXNetwork #source/blender/blenlib'
|
||||
|
||||
@@ -90,6 +90,7 @@ ifndef CONFIG_GUESS
|
||||
export NAN_BSP ?= $(LCGDIR)/bsp
|
||||
export NAN_BOOLOP ?= $(LCGDIR)/boolop
|
||||
export NAN_SOUNDSYSTEM ?= $(LCGDIR)/SoundSystem
|
||||
export NAN_AUDASPACE ?= $(LCGDIR)/audaspace
|
||||
export NAN_STRING ?= $(LCGDIR)/string
|
||||
export NAN_MEMUTIL ?= $(LCGDIR)/memutil
|
||||
export NAN_CONTAINER ?= $(LCGDIR)/container
|
||||
|
||||
@@ -117,6 +117,7 @@ def setup_staticlibs(lenv):
|
||||
lenv['BF_JPEG_LIBPATH'],
|
||||
lenv['BF_PNG_LIBPATH'],
|
||||
lenv['BF_ZLIB_LIBPATH'],
|
||||
lenv['BF_LIBSAMPLERATE_LIBPATH'],
|
||||
lenv['BF_ICONV_LIBPATH']
|
||||
]
|
||||
|
||||
@@ -157,7 +158,8 @@ def setup_syslibs(lenv):
|
||||
|
||||
lenv['BF_JPEG_LIB'],
|
||||
lenv['BF_PNG_LIB'],
|
||||
lenv['BF_ZLIB_LIB']
|
||||
lenv['BF_ZLIB_LIB'],
|
||||
lenv['BF_LIBSAMPLERATE_LIB']
|
||||
]
|
||||
|
||||
syslibs += Split(lenv['BF_FREETYPE_LIB'])
|
||||
|
||||
@@ -30,6 +30,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC',
|
||||
'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
|
||||
'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
|
||||
'BF_LIBSAMPLERATE', 'BF_LIBSAMPLERATE_INC', 'BF_LIBSAMPLERATE_LIB', 'BF_LIBSAMPLERATE_LIBPATH',
|
||||
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
|
||||
'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
|
||||
'WITH_BF_DDS',
|
||||
@@ -173,6 +174,11 @@ def read_opts(cfg, args):
|
||||
('BF_SDL_LIB', 'SDL library', ''), #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
|
||||
('BF_SDL_LIBPATH', 'SDL library path', ''),
|
||||
|
||||
('BF_LIBSAMPLERATE', 'libsamplerate aka SRC base path', ''),
|
||||
('BF_LIBSAMPLERATE_INC', 'libsamplerate aka SRC include path', ''), #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
('BF_LIBSAMPLERATE_LIB', 'libsamplerate aka SRC library', ''), #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
|
||||
('BF_LIBSAMPLERATE_LIBPATH', 'libsamplerate aka SRC library path', ''),
|
||||
|
||||
('BF_PTHREADS', 'Pthreads base path', ''),
|
||||
('BF_PTHREADS_INC', 'Pthreads include path', ''),
|
||||
('BF_PTHREADS_LIB', 'Pthreads library', ''),
|
||||
|
||||
Reference in New Issue
Block a user