Sound code refactoring: core api is now virtualized, MixSDL is divided to generic mixer and driver entities
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1310 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
Changes towards version 0.4:
|
||||
- Sound code refactoring: core api is now virtualized,
|
||||
MixSDL is divided to generic mixer and driver entities - Mika
|
||||
- Optimized MixSDL mixing and resampling routines
|
||||
(hopefully fixes bug #435) - Mika
|
||||
- MOD music should now play properly on big endian machines if using
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "SOUNDMODULE_SDL" /D "HAVE_ZIP" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "SOUNDMODULE_SDL" /D "HAVE_ZIP" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -460,11 +460,11 @@ SOURCE=..\sc2code\libs\resource\resintrn.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\openal\mixer.h
|
||||
SOURCE=..\sc2code\libs\sound\openal\audiodrv_openal.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\openal\sound_openal.c
|
||||
SOURCE=..\sc2code\libs\sound\openal\audiodrv_openal.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "decoders"
|
||||
@@ -603,44 +603,60 @@ SOURCE=..\sc2code\libs\sound\decoders\mikmod\virtch_common.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "mixer"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "mixsdl"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixsdl\mixer.c
|
||||
SOURCE=..\sc2code\libs\sound\mixer\sdl\audiodrv_sdl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixsdl\mixer.h
|
||||
SOURCE=..\sc2code\libs\sound\mixer\sdl\audiodrv_sdl.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "nosound"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixer\nosound\audiodrv_nosound.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixsdl\mixerint.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixsdl\sound_mixsdl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixsdl\sound_mixsdl.h
|
||||
SOURCE=..\sc2code\libs\sound\mixer\nosound\audiodrv_nosound.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixer\mixer.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixer\mixer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\mixer\mixerint.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\audiocore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\audiocore.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\fileinst.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\play.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\redbook.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\resinst.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -649,22 +665,6 @@ SOURCE=..\sc2code\libs\sound\sndintrn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sound_common.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sound_common.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sound_chooser.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sound_chooser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\trackplayer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "starcon.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/sound/sound_common.h"
|
||||
#include "libs/sound/sound.h"
|
||||
#include "oscill.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
if [ "$uqm_SOUNDMODULE" = openal ]; then
|
||||
uqm_SUBDIRS="openal mixsdl decoders"
|
||||
uqm_SUBDIRS="openal mixer decoders"
|
||||
uqm_CFLAGS="$uqm_CFLAGS -DHAVE_OPENAL"
|
||||
else # mixsdl
|
||||
uqm_SUBDIRS="mixsdl decoders"
|
||||
uqm_CFLAGS="$uqm_CFLAGS -DSOUNDMODULE_MIXSDL"
|
||||
else
|
||||
uqm_SUBDIRS="mixer decoders"
|
||||
fi
|
||||
|
||||
uqm_CFILES="fileinst.c resinst.c sound_common.c sound.c sfx.c music.c stream.c trackplayer.c sound_chooser.c"
|
||||
uqm_CFILES="audiocore.c fileinst.c resinst.c sound.c sfx.c music.c stream.c trackplayer.c"
|
||||
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Audio Core API (derived from OpenAL)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "audiocore.h"
|
||||
|
||||
static audio_Driver audiodrv;
|
||||
|
||||
/*
|
||||
* Declarations for driver init funcs
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OPENAL
|
||||
sint32 openAL_Init (audio_Driver *driver, sint32 flags);
|
||||
#endif
|
||||
sint32 mixSDL_Init (audio_Driver *driver, sint32 flags);
|
||||
sint32 noSound_Init (audio_Driver *driver, sint32 flags);
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
sint32
|
||||
initAudio (sint32 driver, sint32 flags)
|
||||
{
|
||||
sint32 ret;
|
||||
|
||||
#ifdef HAVE_OPENAL
|
||||
if (driver == audio_DRIVER_MIXSDL)
|
||||
ret = mixSDL_Init (&audiodrv, flags);
|
||||
else if (driver == audio_DRIVER_OPENAL)
|
||||
ret = openAL_Init (&audiodrv, flags);
|
||||
else
|
||||
ret = noSound_Init (&audiodrv, flags);
|
||||
#else
|
||||
if (driver == audio_DRIVER_OPENAL)
|
||||
{
|
||||
fprintf (stderr, "OpenAL driver not compiled in, so using MixSDL\n");
|
||||
driver = audio_DRIVER_MIXSDL;
|
||||
}
|
||||
if (driver == audio_DRIVER_MIXSDL)
|
||||
ret = mixSDL_Init (&audiodrv, flags);
|
||||
else
|
||||
ret = noSound_Init (&audiodrv, flags);
|
||||
#endif
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
fprintf (stderr, "Sound driver initialization failed.\n"
|
||||
"This may happen when a soundcard is "
|
||||
"not present or not available.\n"
|
||||
"NOTICE: Try running UQM with '--sound=none' option\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
unInitAudio (void)
|
||||
{
|
||||
audiodrv.Uninitialize ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* General
|
||||
*/
|
||||
|
||||
sint32
|
||||
audio_GetError (void)
|
||||
{
|
||||
return audiodrv.GetError ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sources
|
||||
*/
|
||||
|
||||
void
|
||||
audio_GenSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
audiodrv.GenSources (n, psrcobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_DeleteSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
audiodrv.DeleteSources (n, psrcobj);
|
||||
}
|
||||
|
||||
bool
|
||||
audio_IsSource (audio_Object srcobj)
|
||||
{
|
||||
return audiodrv.IsSource (srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value)
|
||||
|
||||
{
|
||||
audiodrv.Sourcei (srcobj, audiodrv.EnumLookup[pname], value);
|
||||
}
|
||||
|
||||
void
|
||||
audio_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value)
|
||||
{
|
||||
audiodrv.Sourcef (srcobj, audiodrv.EnumLookup[pname], value);
|
||||
}
|
||||
|
||||
void
|
||||
audio_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
audiodrv.Sourcefv (srcobj, audiodrv.EnumLookup[pname], value);
|
||||
}
|
||||
|
||||
void
|
||||
audio_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
audiodrv.GetSourcei (srcobj, audiodrv.EnumLookup[pname], value);
|
||||
}
|
||||
|
||||
void
|
||||
audio_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
audiodrv.GetSourcef (srcobj, audiodrv.EnumLookup[pname], value);
|
||||
}
|
||||
|
||||
void
|
||||
audio_SourceRewind (audio_Object srcobj)
|
||||
{
|
||||
audiodrv.SourceRewind (srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_SourcePlay (audio_Object srcobj)
|
||||
{
|
||||
audiodrv.SourcePlay (srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_SourcePause (audio_Object srcobj)
|
||||
{
|
||||
audiodrv.SourcePause (srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_SourceStop (audio_Object srcobj)
|
||||
{
|
||||
audiodrv.SourceStop (srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
audiodrv.SourceQueueBuffers (srcobj, n, pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
audiodrv.SourceUnqueueBuffers (srcobj, n, pbufobj);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Buffers
|
||||
*/
|
||||
|
||||
void
|
||||
audio_GenBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
audiodrv.GenBuffers (n, pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_DeleteBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
audiodrv.DeleteBuffers (n, pbufobj);
|
||||
}
|
||||
|
||||
bool
|
||||
audio_IsBuffer (audio_Object bufobj)
|
||||
{
|
||||
return audiodrv.IsBuffer (bufobj);
|
||||
}
|
||||
|
||||
void
|
||||
audio_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
audiodrv.GetBufferi (bufobj, audiodrv.EnumLookup[pname], value);
|
||||
}
|
||||
|
||||
void
|
||||
audio_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq)
|
||||
{
|
||||
audiodrv.BufferData (bufobj, audiodrv.EnumLookup[format], data, size,
|
||||
freq);
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Audio Core API (derived from OpenAL)
|
||||
*/
|
||||
|
||||
#ifndef _AUDIOCORE_H
|
||||
#define _AUDIOCORE_H
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
/* Available drivers */
|
||||
enum
|
||||
{
|
||||
audio_DRIVER_MIXSDL,
|
||||
audio_DRIVER_NOSOUND,
|
||||
audio_DRIVER_OPENAL
|
||||
};
|
||||
|
||||
/* Initialization flags */
|
||||
#define audio_QUALITY_HIGH (1 << 0)
|
||||
#define audio_QUALITY_MEDIUM (1 << 1)
|
||||
#define audio_QUALITY_LOW (1 << 2)
|
||||
|
||||
|
||||
/* Interface Types */
|
||||
typedef intptr_t audio_Object;
|
||||
typedef intptr_t audio_IntVal;
|
||||
typedef const sint32 audio_SourceProp;
|
||||
typedef const sint32 audio_BufferProp;
|
||||
|
||||
enum
|
||||
{
|
||||
/* Errors */
|
||||
audio_NO_ERROR = 0,
|
||||
audio_INVALID_NAME,
|
||||
audio_INVALID_ENUM,
|
||||
audio_INVALID_VALUE,
|
||||
audio_INVALID_OPERATION,
|
||||
audio_OUT_OF_MEMORY,
|
||||
audio_DRIVER_FAILURE,
|
||||
|
||||
/* Source properties */
|
||||
audio_POSITION,
|
||||
audio_LOOPING,
|
||||
audio_BUFFER,
|
||||
audio_GAIN,
|
||||
audio_SOURCE_STATE,
|
||||
audio_BUFFERS_QUEUED,
|
||||
audio_BUFFERS_PROCESSED,
|
||||
|
||||
/* Source state information */
|
||||
audio_INITIAL,
|
||||
audio_STOPPED,
|
||||
audio_PLAYING,
|
||||
audio_PAUSED,
|
||||
|
||||
/* Sound buffer properties */
|
||||
audio_FREQUENCY,
|
||||
audio_BITS,
|
||||
audio_CHANNELS,
|
||||
audio_SIZE,
|
||||
audio_DATA,
|
||||
audio_FORMAT_MONO16,
|
||||
audio_FORMAT_STEREO16,
|
||||
audio_FORMAT_MONO8,
|
||||
audio_FORMAT_STEREO8,
|
||||
audio_ENUM_SIZE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* General */
|
||||
void (* Uninitialize) (void);
|
||||
sint32 (* GetError) (void);
|
||||
sint32 driverID;
|
||||
sint32 EnumLookup[audio_ENUM_SIZE];
|
||||
|
||||
/* Sources */
|
||||
void (* GenSources) (uint32 n, audio_Object *psrcobj);
|
||||
void (* DeleteSources) (uint32 n, audio_Object *psrcobj);
|
||||
bool (* IsSource) (audio_Object srcobj);
|
||||
void (* Sourcei) (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value);
|
||||
void (* Sourcef) (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value);
|
||||
void (* Sourcefv) (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void (* GetSourcei) (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value);
|
||||
void (* GetSourcef) (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void (* SourceRewind) (audio_Object srcobj);
|
||||
void (* SourcePlay) (audio_Object srcobj);
|
||||
void (* SourcePause) (audio_Object srcobj);
|
||||
void (* SourceStop) (audio_Object srcobj);
|
||||
void (* SourceQueueBuffers) (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
void (* SourceUnqueueBuffers) (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
|
||||
/* Buffers */
|
||||
void (* GenBuffers) (uint32 n, audio_Object *pbufobj);
|
||||
void (* DeleteBuffers) (uint32 n, audio_Object *pbufobj);
|
||||
bool (* IsBuffer) (audio_Object bufobj);
|
||||
void (* GetBufferi) (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value);
|
||||
void (* BufferData) (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq);
|
||||
} audio_Driver;
|
||||
|
||||
|
||||
/* Initialization */
|
||||
sint32 initAudio (sint32 driver, sint32 flags);
|
||||
void unInitAudio (void);
|
||||
|
||||
/* General */
|
||||
sint32 audio_GetError (void);
|
||||
|
||||
/* Sources */
|
||||
void audio_GenSources (uint32 n, audio_Object *psrcobj);
|
||||
void audio_DeleteSources (uint32 n, audio_Object *psrcobj);
|
||||
bool audio_IsSource (audio_Object srcobj);
|
||||
void audio_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value);
|
||||
void audio_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value);
|
||||
void audio_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void audio_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value);
|
||||
void audio_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void audio_SourceRewind (audio_Object srcobj);
|
||||
void audio_SourcePlay (audio_Object srcobj);
|
||||
void audio_SourcePause (audio_Object srcobj);
|
||||
void audio_SourceStop (audio_Object srcobj);
|
||||
void audio_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
void audio_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
|
||||
/* Buffers */
|
||||
void audio_GenBuffers (uint32 n, audio_Object *pbufobj);
|
||||
void audio_DeleteBuffers (uint32 n, audio_Object *pbufobj);
|
||||
bool audio_IsBuffer (audio_Object bufobj);
|
||||
void audio_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value);
|
||||
void audio_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq);
|
||||
|
||||
#endif /* _AUDIOCORE_H */
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "uio.h"
|
||||
#include "decoder.h"
|
||||
#include "mikmod/mikmod.h"
|
||||
#include "libs/sound/sound_common.h"
|
||||
#include "libs/sound/audiocore.h"
|
||||
#include "modaud.h"
|
||||
|
||||
#define THIS_PTR TFB_SoundDecoder* This
|
||||
@@ -87,7 +87,7 @@ moda_InitModule (int flags, const TFB_DecoderFormats* fmts)
|
||||
MikMod_RegisterDriver (&drv_openal);
|
||||
MikMod_RegisterAllLoaders ();
|
||||
|
||||
if (flags & TFB_SOUNDFLAGS_HQAUDIO)
|
||||
if (flags & audio_QUALITY_HIGH)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
md_mode = DMODE_HQMIXER|DMODE_STEREO|DMODE_16BITS|DMODE_INTERP|DMODE_SURROUND;
|
||||
@@ -98,7 +98,7 @@ moda_InitModule (int flags, const TFB_DecoderFormats* fmts)
|
||||
md_mixfreq = 44100;
|
||||
md_reverb = 1;
|
||||
}
|
||||
else if (flags & TFB_SOUNDFLAGS_LQAUDIO)
|
||||
else if (flags & audio_QUALITY_LOW)
|
||||
{
|
||||
md_mode = DMODE_SOFT_MUSIC|DMODE_STEREO|DMODE_16BITS;
|
||||
md_mixfreq = 22050;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
uqm_SUBDIRS="sdl nosound"
|
||||
uqm_CFILES="mixer.c"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Mixer for low-level sound output drivers
|
||||
*/
|
||||
|
||||
#ifndef _MIXER_H
|
||||
#define _MIXER_H
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "endian_uqm.h"
|
||||
|
||||
/**
|
||||
* The interface heavily influenced by OpenAL
|
||||
* to the point where you should use OpenAL's
|
||||
* documentation when programming the mixer.
|
||||
* (some source properties are not supported)
|
||||
*
|
||||
* EXCEPTION: You may not queue the same buffer
|
||||
* on more than one source
|
||||
*/
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define MIX_IS_BIG_ENDIAN true
|
||||
# define MIX_WANT_BIG_ENDIAN true
|
||||
#else
|
||||
# define MIX_IS_BIG_ENDIAN false
|
||||
# define MIX_WANT_BIG_ENDIAN false
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mixer errors (see OpenAL errors)
|
||||
*/
|
||||
enum
|
||||
{
|
||||
MIX_NO_ERROR = 0,
|
||||
MIX_INVALID_NAME = 0xA001U,
|
||||
MIX_INVALID_ENUM = 0xA002U,
|
||||
MIX_INVALID_VALUE = 0xA003U,
|
||||
MIX_INVALID_OPERATION = 0xA004U,
|
||||
MIX_OUT_OF_MEMORY = 0xA005U,
|
||||
|
||||
MIX_DRIVER_FAILURE = 0xA101U
|
||||
};
|
||||
|
||||
/**
|
||||
* Source properties (see OpenAL)
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MIX_POSITION = 0x1004,
|
||||
MIX_LOOPING = 0x1007,
|
||||
MIX_BUFFER = 0x1009,
|
||||
MIX_GAIN = 0x100A,
|
||||
MIX_SOURCE_STATE = 0x1010,
|
||||
|
||||
MIX_BUFFERS_QUEUED = 0x1015,
|
||||
MIX_BUFFERS_PROCESSED = 0x1016
|
||||
|
||||
} mixer_SourceProp;
|
||||
|
||||
/**
|
||||
* Source state information
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MIX_INITIAL = 0,
|
||||
MIX_STOPPED,
|
||||
MIX_PLAYING,
|
||||
MIX_PAUSED,
|
||||
|
||||
} mixer_SourceState;
|
||||
|
||||
/**
|
||||
* Sound buffer properties
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MIX_FREQUENCY = 0x2001,
|
||||
MIX_BITS = 0x2002,
|
||||
MIX_CHANNELS = 0x2003,
|
||||
MIX_SIZE = 0x2004,
|
||||
MIX_DATA = 0x2005
|
||||
|
||||
} mixer_BufferProp;
|
||||
|
||||
/**
|
||||
* Buffer states: semi-private
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MIX_BUF_INITIAL = 0,
|
||||
MIX_BUF_FILLED,
|
||||
MIX_BUF_QUEUED,
|
||||
MIX_BUF_PLAYING,
|
||||
MIX_BUF_PROCESSED
|
||||
|
||||
} mixer_BufferState;
|
||||
|
||||
/** Sound buffers: format specifier.
|
||||
* bits 00..07: bytes per sample
|
||||
* bits 08..15: channels
|
||||
* bits 15..31: meaningless
|
||||
*/
|
||||
#define MIX_FORMAT_DUMMYID 0x00170000
|
||||
#define MIX_FORMAT_BPC(f) ((f) & 0xff)
|
||||
#define MIX_FORMAT_CHANS(f) (((f) >> 8) & 0xff)
|
||||
#define MIX_FORMAT_BPC_MAX 2
|
||||
#define MIX_FORMAT_CHANS_MAX 2
|
||||
#define MIX_FORMAT_MAKE(b, c) \
|
||||
( MIX_FORMAT_DUMMYID | ((b) & 0xff) | (((c) & 0xff) << 8) )
|
||||
|
||||
#define MIX_FORMAT_SAMPSIZE(f) \
|
||||
( MIX_FORMAT_BPC(f) * MIX_FORMAT_CHANS(f) )
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIX_FORMAT_MONO8 = MIX_FORMAT_MAKE (1, 1),
|
||||
MIX_FORMAT_STEREO8 = MIX_FORMAT_MAKE (1, 2),
|
||||
MIX_FORMAT_MONO16 = MIX_FORMAT_MAKE (2, 1),
|
||||
MIX_FORMAT_STEREO16 = MIX_FORMAT_MAKE (2, 2)
|
||||
|
||||
} mixer_Format;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIX_QUALITY_LOW = 0,
|
||||
MIX_QUALITY_MEDIUM,
|
||||
MIX_QUALITY_HIGH,
|
||||
MIX_QUALITY_DEFAULT = MIX_QUALITY_MEDIUM,
|
||||
MIX_QUALITY_COUNT
|
||||
|
||||
} mixer_Quality;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIX_NOFLAGS = 0,
|
||||
MIX_FAKE_DATA = 1
|
||||
} mixer_Flags;
|
||||
|
||||
/*************************************************
|
||||
* Interface Types
|
||||
*/
|
||||
|
||||
typedef intptr_t mixer_Object;
|
||||
typedef intptr_t mixer_IntVal;
|
||||
|
||||
typedef struct _mixer_Source mixer_Source;
|
||||
|
||||
typedef struct _mixer_Buffer
|
||||
{
|
||||
uint32 magic;
|
||||
bool locked;
|
||||
mixer_BufferState state;
|
||||
uint8 *data;
|
||||
uint32 size;
|
||||
uint32 sampsize;
|
||||
uint32 high;
|
||||
uint32 low;
|
||||
float (* Resample) (mixer_Source *src, bool left);
|
||||
/* original buffer values for OpenAL compat */
|
||||
void* orgdata;
|
||||
uint32 orgfreq;
|
||||
uint32 orgsize;
|
||||
uint32 orgchannels;
|
||||
uint32 orgchansize;
|
||||
/* next buffer in chain */
|
||||
struct _mixer_Buffer *next;
|
||||
|
||||
} mixer_Buffer;
|
||||
|
||||
#define mixer_bufMagic 0x4258494DU /* MIXB in LSB */
|
||||
|
||||
struct _mixer_Source
|
||||
{
|
||||
uint32 magic;
|
||||
bool locked;
|
||||
mixer_SourceState state;
|
||||
bool looping;
|
||||
float gain;
|
||||
uint32 cqueued;
|
||||
uint32 cprocessed;
|
||||
mixer_Buffer *firstqueued; /* first buf in the queue */
|
||||
mixer_Buffer *nextqueued; /* next to play, or 0 */
|
||||
mixer_Buffer *prevqueued; /* previously played */
|
||||
mixer_Buffer *lastqueued; /* last in queue */
|
||||
uint32 pos; /* position in current buffer */
|
||||
uint32 count; /* fractional part of pos */
|
||||
|
||||
float samplecache;
|
||||
|
||||
};
|
||||
|
||||
#define mixer_srcMagic 0x5358494DU /* MIXS in LSB */
|
||||
|
||||
/*************************************************
|
||||
* General interface
|
||||
*/
|
||||
uint32 mixer_GetError (void);
|
||||
|
||||
bool mixer_Init (uint32 frequency, uint32 format, mixer_Quality quality,
|
||||
mixer_Flags flags);
|
||||
void mixer_Uninit (void);
|
||||
void mixer_MixChannels (void *userdata, uint8 *stream, sint32 len);
|
||||
void mixer_MixFake (void *userdata, uint8 *stream, sint32 len);
|
||||
|
||||
/*************************************************
|
||||
* Sources
|
||||
*/
|
||||
void mixer_GenSources (uint32 n, mixer_Object *psrcobj);
|
||||
void mixer_DeleteSources (uint32 n, mixer_Object *psrcobj);
|
||||
bool mixer_IsSource (mixer_Object srcobj);
|
||||
void mixer_Sourcei (mixer_Object srcobj, mixer_SourceProp pname,
|
||||
mixer_IntVal value);
|
||||
void mixer_Sourcef (mixer_Object srcobj, mixer_SourceProp pname,
|
||||
float value);
|
||||
void mixer_Sourcefv (mixer_Object srcobj, mixer_SourceProp pname,
|
||||
float *value);
|
||||
void mixer_GetSourcei (mixer_Object srcobj, mixer_SourceProp pname,
|
||||
mixer_IntVal *value);
|
||||
void mixer_GetSourcef (mixer_Object srcobj, mixer_SourceProp pname,
|
||||
float *value);
|
||||
void mixer_SourceRewind (mixer_Object srcobj);
|
||||
void mixer_SourcePlay (mixer_Object srcobj);
|
||||
void mixer_SourcePause (mixer_Object srcobj);
|
||||
void mixer_SourceStop (mixer_Object srcobj);
|
||||
void mixer_SourceQueueBuffers (mixer_Object srcobj, uint32 n,
|
||||
mixer_Object* pbufobj);
|
||||
void mixer_SourceUnqueueBuffers (mixer_Object srcobj, uint32 n,
|
||||
mixer_Object* pbufobj);
|
||||
|
||||
/*************************************************
|
||||
* Buffers
|
||||
*/
|
||||
void mixer_GenBuffers (uint32 n, mixer_Object *pbufobj);
|
||||
void mixer_DeleteBuffers (uint32 n, mixer_Object *pbufobj);
|
||||
bool mixer_IsBuffer (mixer_Object bufobj);
|
||||
void mixer_GetBufferi (mixer_Object bufobj, mixer_BufferProp pname,
|
||||
mixer_IntVal *value);
|
||||
void mixer_BufferData (mixer_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq);
|
||||
|
||||
|
||||
/* Make sure the prop-value type is of suitable size
|
||||
* it must be able to store both int and void*
|
||||
* Adapted from SDL
|
||||
* This will generate "negative subscript or subscript is too large"
|
||||
* error during compile, if the actual size of a type is wrong
|
||||
*/
|
||||
#define MIX_COMPILE_TIME_ASSERT(name, x) \
|
||||
typedef int mixer_dummy_##name [(x) * 2 - 1]
|
||||
|
||||
MIX_COMPILE_TIME_ASSERT (mixer_Object,
|
||||
sizeof(mixer_Object) >= sizeof(void*));
|
||||
MIX_COMPILE_TIME_ASSERT (mixer_IntVal,
|
||||
sizeof(mixer_IntVal) >= sizeof(mixer_Object));
|
||||
|
||||
#undef MIX_COMPILE_TIME_ASSERT
|
||||
|
||||
#endif /* _MIXER_H */
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Mixer for low-level sound output drivers
|
||||
* Internals
|
||||
*/
|
||||
|
||||
#ifndef _MIXERINT_H
|
||||
#define _MIXERINT_H
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Internals
|
||||
*/
|
||||
|
||||
/* Conversion info types and funcs */
|
||||
typedef enum
|
||||
{
|
||||
mixConvNone = 0,
|
||||
mixConvStereoUp = 1,
|
||||
mixConvStereoDown = 2,
|
||||
mixConvSizeUp = 4,
|
||||
mixConvSizeDown = 8
|
||||
|
||||
} mixer_ConvFlags;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 srcfmt;
|
||||
void *srcdata;
|
||||
uint32 srcsize;
|
||||
uint32 srcbpc; /* bytes/sample for 1 chan */
|
||||
uint32 srcchans;
|
||||
uint32 srcsamples;
|
||||
|
||||
uint32 dstfmt;
|
||||
void *dstdata;
|
||||
uint32 dstsize;
|
||||
uint32 dstbpc; /* bytes/sample for 1 chan */
|
||||
uint32 dstchans;
|
||||
uint32 dstsamples;
|
||||
|
||||
mixer_ConvFlags flags;
|
||||
|
||||
} mixer_Convertion;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float (* Upsample) (mixer_Source *src, bool left);
|
||||
float (* Downsample) (mixer_Source *src, bool left);
|
||||
float (* None) (mixer_Source *src, bool left);
|
||||
} mixer_Resampling;
|
||||
|
||||
static void mixer_ConvertBuffer_internal (mixer_Convertion *conv);
|
||||
static void mixer_ResampleFlat (mixer_Convertion *conv);
|
||||
|
||||
static __inline__ sint32 mixer_GetSampleExt (void *src, uint32 bpc);
|
||||
static __inline__ sint32 mixer_GetSampleInt (void *src, uint32 bpc);
|
||||
static __inline__ void mixer_PutSampleInt (void *dst, uint32 bpc,
|
||||
sint32 samp);
|
||||
static __inline__ void mixer_PutSampleExt (void *dst, uint32 bpc,
|
||||
sint32 samp);
|
||||
|
||||
static float mixer_ResampleNone (mixer_Source *src, bool left);
|
||||
static float mixer_ResampleNearest (mixer_Source *src, bool left);
|
||||
static float mixer_UpsampleLinear (mixer_Source *src, bool left);
|
||||
static float mixer_UpsampleCubic (mixer_Source *src, bool left);
|
||||
|
||||
/* Source manipulation */
|
||||
static void mixer_SourceUnqueueAll (mixer_Source *src);
|
||||
static void mixer_SourceStop_internal (mixer_Source *src);
|
||||
static void mixer_SourceRewind_internal (mixer_Source *src);
|
||||
static void mixer_SourceActivate (mixer_Source* src);
|
||||
static void mixer_SourceDeactivate (mixer_Source* src);
|
||||
|
||||
static __inline__ bool mixer_CheckBufferState (mixer_Buffer *buf,
|
||||
const char* FuncName);
|
||||
|
||||
/* Clipping boundaries */
|
||||
#define MIX_S16_MAX ((float) SINT16_MAX)
|
||||
#define MIX_S16_MIN ((float) SINT16_MIN)
|
||||
#define MIX_S8_MAX ((float) SINT8_MAX)
|
||||
#define MIX_S8_MIN ((float) SINT8_MIN)
|
||||
|
||||
/* Channel gain adjustment for clipping reduction */
|
||||
#define MIX_GAIN_ADJ (0.75f)
|
||||
|
||||
/* The Mixer */
|
||||
static __inline__ bool mixer_SourceGetNextSample (mixer_Source *src,
|
||||
float *psamp, bool left);
|
||||
static __inline__ bool mixer_SourceGetFakeSample (mixer_Source *src,
|
||||
float *psamp, bool left);
|
||||
static __inline__ uint32 mixer_SourceAdvance (mixer_Source *src, bool left);
|
||||
|
||||
#endif /* _MIXERINT_H */
|
||||
@@ -0,0 +1 @@
|
||||
uqm_CFILES="audiodrv_nosound.c"
|
||||
@@ -0,0 +1,417 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Nosound audio driver
|
||||
*/
|
||||
|
||||
#include "audiodrv_nosound.h"
|
||||
|
||||
static Task StreamDecoderTask;
|
||||
static Task PlaybackTask;
|
||||
static uint32 nosound_freq = 22050;
|
||||
|
||||
static const audio_Driver noSound_Driver =
|
||||
{
|
||||
noSound_Uninit,
|
||||
noSound_GetError,
|
||||
audio_DRIVER_NOSOUND,
|
||||
{
|
||||
/* Errors */
|
||||
MIX_NO_ERROR,
|
||||
MIX_INVALID_NAME,
|
||||
MIX_INVALID_ENUM,
|
||||
MIX_INVALID_VALUE,
|
||||
MIX_INVALID_OPERATION,
|
||||
MIX_OUT_OF_MEMORY,
|
||||
MIX_DRIVER_FAILURE,
|
||||
|
||||
/* Source properties */
|
||||
MIX_POSITION,
|
||||
MIX_LOOPING,
|
||||
MIX_BUFFER,
|
||||
MIX_GAIN,
|
||||
MIX_SOURCE_STATE,
|
||||
MIX_BUFFERS_QUEUED,
|
||||
MIX_BUFFERS_PROCESSED,
|
||||
|
||||
/* Source state information */
|
||||
MIX_INITIAL,
|
||||
MIX_STOPPED,
|
||||
MIX_PLAYING,
|
||||
MIX_PAUSED,
|
||||
|
||||
/* Sound buffer properties */
|
||||
MIX_FREQUENCY,
|
||||
MIX_BITS,
|
||||
MIX_CHANNELS,
|
||||
MIX_SIZE,
|
||||
MIX_DATA,
|
||||
MIX_FORMAT_MONO16,
|
||||
MIX_FORMAT_STEREO16,
|
||||
MIX_FORMAT_MONO8,
|
||||
MIX_FORMAT_STEREO8
|
||||
},
|
||||
|
||||
/* Sources */
|
||||
noSound_GenSources,
|
||||
noSound_DeleteSources,
|
||||
noSound_IsSource,
|
||||
noSound_Sourcei,
|
||||
noSound_Sourcef,
|
||||
noSound_Sourcefv,
|
||||
noSound_GetSourcei,
|
||||
noSound_GetSourcef,
|
||||
noSound_SourceRewind,
|
||||
noSound_SourcePlay,
|
||||
noSound_SourcePause,
|
||||
noSound_SourceStop,
|
||||
noSound_SourceQueueBuffers,
|
||||
noSound_SourceUnqueueBuffers,
|
||||
|
||||
/* Buffers */
|
||||
noSound_GenBuffers,
|
||||
noSound_DeleteBuffers,
|
||||
noSound_IsBuffer,
|
||||
noSound_GetBufferi,
|
||||
noSound_BufferData
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
sint32
|
||||
noSound_Init (audio_Driver *driver, sint32 flags)
|
||||
{
|
||||
int i;
|
||||
TFB_DecoderFormats formats =
|
||||
{
|
||||
0, 0,
|
||||
audio_FORMAT_MONO8, audio_FORMAT_STEREO8,
|
||||
audio_FORMAT_MONO16, audio_FORMAT_STEREO16
|
||||
};
|
||||
|
||||
fprintf (stderr, "Using nosound audio driver.\n");
|
||||
fprintf (stderr, "Initializing mixer.\n");
|
||||
|
||||
if (!mixer_Init (nosound_freq, MIX_FORMAT_MAKE (1, 1),
|
||||
MIX_QUALITY_LOW, MIX_FAKE_DATA))
|
||||
{
|
||||
fprintf (stderr, "Mixer initialization failed: %x\n",
|
||||
mixer_GetError ());
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "Mixer initialized.\n");
|
||||
|
||||
fprintf (stderr, "Initializing sound decoders.\n");
|
||||
if (SoundDecoder_Init (flags, &formats))
|
||||
{
|
||||
fprintf (stderr, "Sound decoders initialization failed.\n");
|
||||
mixer_Uninit ();
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "Sound decoders initialized.\n");
|
||||
|
||||
*driver = noSound_Driver;
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
audio_GenSources (1, &soundSource[i].handle);
|
||||
soundSource[i].sample = NULL;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
soundSource[i].stream_mutex = CreateMutex ("Nosound stream mutex", SYNC_CLASS_AUDIO);
|
||||
soundSource[i].sbuffer = NULL;
|
||||
soundSource[i].sbuf_start = 0;
|
||||
soundSource[i].sbuf_size = 0;
|
||||
soundSource[i].sbuf_offset = 0;
|
||||
}
|
||||
|
||||
atexit (unInitAudio);
|
||||
|
||||
SetSFXVolume (sfxVolumeScale);
|
||||
SetSpeechVolume (speechVolumeScale);
|
||||
SetMusicVolume ((COUNT)musicVolume);
|
||||
|
||||
StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024,
|
||||
"audio stream decoder");
|
||||
PlaybackTask = AssignTask (PlaybackTaskFunc, 1024,
|
||||
"nosound audio playback");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
noSound_Uninit (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (StreamDecoderTask)
|
||||
{
|
||||
ConcludeTask (StreamDecoderTask);
|
||||
StreamDecoderTask = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
if (soundSource[i].sample && soundSource[i].sample->decoder)
|
||||
{
|
||||
StopStream (i);
|
||||
}
|
||||
if (soundSource[i].sbuffer)
|
||||
{
|
||||
void *sbuffer = soundSource[i].sbuffer;
|
||||
soundSource[i].sbuffer = NULL;
|
||||
HFree (sbuffer);
|
||||
}
|
||||
DestroyMutex (soundSource[i].stream_mutex);
|
||||
|
||||
noSound_DeleteSources (1, &soundSource[i].handle);
|
||||
}
|
||||
|
||||
if (PlaybackTask)
|
||||
{
|
||||
ConcludeTask (PlaybackTask);
|
||||
PlaybackTask = 0;
|
||||
}
|
||||
|
||||
mixer_Uninit ();
|
||||
SoundDecoder_Uninit ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Playback task
|
||||
*/
|
||||
|
||||
int
|
||||
PlaybackTaskFunc (void *data)
|
||||
{
|
||||
Task task = (Task)data;
|
||||
uint8 *stream;
|
||||
uint32 entryTime;
|
||||
sint32 period, delay;
|
||||
uint32 len = 2048;
|
||||
|
||||
stream = (uint8 *) HMalloc (len);
|
||||
period = (sint32)((len / (double)nosound_freq) * ONE_SECOND);
|
||||
|
||||
while (!Task_ReadState (task, TASK_EXIT))
|
||||
{
|
||||
entryTime = GetTimeCounter ();
|
||||
mixer_MixFake (NULL, stream, len);
|
||||
delay = period - (GetTimeCounter () - entryTime);
|
||||
if (delay > 0)
|
||||
SleepThread (delay);
|
||||
}
|
||||
|
||||
HFree (stream);
|
||||
FinishTask (task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* General
|
||||
*/
|
||||
|
||||
sint32
|
||||
noSound_GetError (void)
|
||||
{
|
||||
sint32 value = mixer_GetError ();
|
||||
switch (value)
|
||||
{
|
||||
case MIX_NO_ERROR:
|
||||
return audio_NO_ERROR;
|
||||
case MIX_INVALID_NAME:
|
||||
return audio_INVALID_NAME;
|
||||
case MIX_INVALID_ENUM:
|
||||
return audio_INVALID_ENUM;
|
||||
case MIX_INVALID_VALUE:
|
||||
return audio_INVALID_VALUE;
|
||||
case MIX_INVALID_OPERATION:
|
||||
return audio_INVALID_OPERATION;
|
||||
case MIX_OUT_OF_MEMORY:
|
||||
return audio_OUT_OF_MEMORY;
|
||||
default:
|
||||
fprintf (stderr, "noSound_GetError: unknown value %x\n",
|
||||
value);
|
||||
return audio_DRIVER_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sources
|
||||
*/
|
||||
|
||||
void
|
||||
noSound_GenSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
mixer_GenSources (n, (mixer_Object *) psrcobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_DeleteSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
mixer_DeleteSources (n, (mixer_Object *) psrcobj);
|
||||
}
|
||||
|
||||
bool
|
||||
noSound_IsSource (audio_Object srcobj)
|
||||
{
|
||||
return mixer_IsSource ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value)
|
||||
|
||||
{
|
||||
mixer_Sourcei ((mixer_Object) srcobj, (mixer_SourceProp) pname,
|
||||
(mixer_IntVal) value);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value)
|
||||
{
|
||||
mixer_Sourcef ((mixer_Object) srcobj, (mixer_SourceProp) pname, value);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
mixer_Sourcefv ((mixer_Object) srcobj, (mixer_SourceProp) pname, value);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
mixer_GetSourcei ((mixer_Object) srcobj, (mixer_SourceProp) pname,
|
||||
(mixer_IntVal *) value);
|
||||
if (pname == MIX_SOURCE_STATE)
|
||||
{
|
||||
switch (*value)
|
||||
{
|
||||
case MIX_INITIAL:
|
||||
*value = audio_INITIAL;
|
||||
break;
|
||||
case MIX_STOPPED:
|
||||
*value = audio_STOPPED;
|
||||
break;
|
||||
case MIX_PLAYING:
|
||||
*value = audio_PLAYING;
|
||||
break;
|
||||
case MIX_PAUSED:
|
||||
*value = audio_PAUSED;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "noSound_GetSourcei(): unknown value %x\n",
|
||||
*value);
|
||||
*value = audio_DRIVER_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
noSound_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
mixer_GetSourcef ((mixer_Object) srcobj, (mixer_SourceProp) pname, value);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_SourceRewind (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourceRewind ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_SourcePlay (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourcePlay ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_SourcePause (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourcePause ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_SourceStop (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourceStop ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
mixer_SourceQueueBuffers ((mixer_Object) srcobj, n,
|
||||
(mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
mixer_SourceUnqueueBuffers ((mixer_Object) srcobj, n,
|
||||
(mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Buffers
|
||||
*/
|
||||
|
||||
void
|
||||
noSound_GenBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
mixer_GenBuffers (n, (mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_DeleteBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
mixer_DeleteBuffers (n, (mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
bool
|
||||
noSound_IsBuffer (audio_Object bufobj)
|
||||
{
|
||||
return mixer_IsBuffer ((mixer_Object) bufobj);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
mixer_GetBufferi ((mixer_Object) bufobj, (mixer_BufferProp) pname,
|
||||
(mixer_IntVal *) value);
|
||||
}
|
||||
|
||||
void
|
||||
noSound_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq)
|
||||
{
|
||||
mixer_BufferData ((mixer_Object) bufobj, format, data, size, freq);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Nosound audio driver
|
||||
*/
|
||||
|
||||
#ifndef _AUDIODRV_NOSOUND_H
|
||||
#define _AUDIODRV_NOSOUND_H
|
||||
|
||||
#include "config.h"
|
||||
#include "libs/sound/sound.h"
|
||||
#include "libs/sound/mixer/mixer.h"
|
||||
|
||||
/* Playback task */
|
||||
int PlaybackTaskFunc (void *data);
|
||||
|
||||
/* General */
|
||||
sint32 noSound_Init (audio_Driver *driver, sint32 flags);
|
||||
void noSound_Uninit (void);
|
||||
sint32 noSound_GetError (void);
|
||||
|
||||
/* Sources */
|
||||
void noSound_GenSources (uint32 n, audio_Object *psrcobj);
|
||||
void noSound_DeleteSources (uint32 n, audio_Object *psrcobj);
|
||||
bool noSound_IsSource (audio_Object srcobj);
|
||||
void noSound_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value);
|
||||
void noSound_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value);
|
||||
void noSound_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void noSound_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value);
|
||||
void noSound_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void noSound_SourceRewind (audio_Object srcobj);
|
||||
void noSound_SourcePlay (audio_Object srcobj);
|
||||
void noSound_SourcePause (audio_Object srcobj);
|
||||
void noSound_SourceStop (audio_Object srcobj);
|
||||
void noSound_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
void noSound_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
|
||||
/* Buffers */
|
||||
void noSound_GenBuffers (uint32 n, audio_Object *pbufobj);
|
||||
void noSound_DeleteBuffers (uint32 n, audio_Object *pbufobj);
|
||||
bool noSound_IsBuffer (audio_Object bufobj);
|
||||
void noSound_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value);
|
||||
void noSound_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq);
|
||||
|
||||
|
||||
#endif /* _AUDIODRV_NOSOUND_H */
|
||||
@@ -0,0 +1 @@
|
||||
uqm_CFILES="audiodrv_sdl.c"
|
||||
@@ -0,0 +1,434 @@
|
||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* SDL audio driver
|
||||
*/
|
||||
|
||||
#include "audiodrv_sdl.h"
|
||||
|
||||
static Task StreamDecoderTask;
|
||||
|
||||
static const audio_Driver mixSDL_Driver =
|
||||
{
|
||||
mixSDL_Uninit,
|
||||
mixSDL_GetError,
|
||||
audio_DRIVER_MIXSDL,
|
||||
{
|
||||
/* Errors */
|
||||
MIX_NO_ERROR,
|
||||
MIX_INVALID_NAME,
|
||||
MIX_INVALID_ENUM,
|
||||
MIX_INVALID_VALUE,
|
||||
MIX_INVALID_OPERATION,
|
||||
MIX_OUT_OF_MEMORY,
|
||||
MIX_DRIVER_FAILURE,
|
||||
|
||||
/* Source properties */
|
||||
MIX_POSITION,
|
||||
MIX_LOOPING,
|
||||
MIX_BUFFER,
|
||||
MIX_GAIN,
|
||||
MIX_SOURCE_STATE,
|
||||
MIX_BUFFERS_QUEUED,
|
||||
MIX_BUFFERS_PROCESSED,
|
||||
|
||||
/* Source state information */
|
||||
MIX_INITIAL,
|
||||
MIX_STOPPED,
|
||||
MIX_PLAYING,
|
||||
MIX_PAUSED,
|
||||
|
||||
/* Sound buffer properties */
|
||||
MIX_FREQUENCY,
|
||||
MIX_BITS,
|
||||
MIX_CHANNELS,
|
||||
MIX_SIZE,
|
||||
MIX_DATA,
|
||||
MIX_FORMAT_MONO16,
|
||||
MIX_FORMAT_STEREO16,
|
||||
MIX_FORMAT_MONO8,
|
||||
MIX_FORMAT_STEREO8
|
||||
},
|
||||
|
||||
/* Sources */
|
||||
mixSDL_GenSources,
|
||||
mixSDL_DeleteSources,
|
||||
mixSDL_IsSource,
|
||||
mixSDL_Sourcei,
|
||||
mixSDL_Sourcef,
|
||||
mixSDL_Sourcefv,
|
||||
mixSDL_GetSourcei,
|
||||
mixSDL_GetSourcef,
|
||||
mixSDL_SourceRewind,
|
||||
mixSDL_SourcePlay,
|
||||
mixSDL_SourcePause,
|
||||
mixSDL_SourceStop,
|
||||
mixSDL_SourceQueueBuffers,
|
||||
mixSDL_SourceUnqueueBuffers,
|
||||
|
||||
/* Buffers */
|
||||
mixSDL_GenBuffers,
|
||||
mixSDL_DeleteBuffers,
|
||||
mixSDL_IsBuffer,
|
||||
mixSDL_GetBufferi,
|
||||
mixSDL_BufferData
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
sint32
|
||||
mixSDL_Init (audio_Driver *driver, sint32 flags)
|
||||
{
|
||||
int i;
|
||||
char devicename[256];
|
||||
SDL_AudioSpec desired, obtained;
|
||||
mixer_Quality quality;
|
||||
TFB_DecoderFormats formats =
|
||||
{
|
||||
MIX_IS_BIG_ENDIAN, MIX_WANT_BIG_ENDIAN,
|
||||
audio_FORMAT_MONO8, audio_FORMAT_STEREO8,
|
||||
audio_FORMAT_MONO16, audio_FORMAT_STEREO16
|
||||
};
|
||||
|
||||
fprintf (stderr, "Initializing SDL audio subsystem.\n");
|
||||
if ((SDL_InitSubSystem(SDL_INIT_AUDIO)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Couldn't initialize audio subsystem: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "SDL audio subsystem initialized.\n");
|
||||
|
||||
if (flags & audio_QUALITY_HIGH)
|
||||
{
|
||||
quality = MIX_QUALITY_HIGH;
|
||||
desired.freq = 44100;
|
||||
desired.samples = 4096;
|
||||
}
|
||||
else if (flags & audio_QUALITY_LOW)
|
||||
{
|
||||
quality = MIX_QUALITY_LOW;
|
||||
desired.freq = 22050;
|
||||
desired.samples = 2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
quality = MIX_QUALITY_DEFAULT;
|
||||
desired.freq = 44100;
|
||||
desired.samples = 4096;
|
||||
}
|
||||
|
||||
desired.format = AUDIO_S16SYS;
|
||||
desired.channels = 2;
|
||||
desired.callback = mixer_MixChannels;
|
||||
|
||||
fprintf (stderr, "Opening SDL audio device.\n");
|
||||
if (SDL_OpenAudio (&desired, &obtained) < 0)
|
||||
{
|
||||
fprintf (stderr, "Unable to open audio device: %s\n", SDL_GetError ());
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
return -1;
|
||||
}
|
||||
if (obtained.format != desired.format ||
|
||||
(obtained.channels != 1 && obtained.channels != 2))
|
||||
{
|
||||
fprintf (stderr, "Unable to obtain desired audio format.\n");
|
||||
SDL_CloseAudio ();
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_AudioDriverName (devicename, sizeof (devicename));
|
||||
fprintf (stderr, " using %s at %d Hz 16 bit %s, %d samples audio buffer\n",
|
||||
devicename, obtained.freq, obtained.channels > 1 ? "stereo" : "mono",
|
||||
obtained.samples);
|
||||
|
||||
fprintf (stderr, "Initializing mixer.\n");
|
||||
if (!mixer_Init (obtained.freq, MIX_FORMAT_MAKE (2, obtained.channels),
|
||||
quality, 0))
|
||||
{
|
||||
fprintf (stderr, "Mixer initialization failed: %x\n",
|
||||
mixer_GetError ());
|
||||
SDL_CloseAudio ();
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "Mixer initialized.\n");
|
||||
|
||||
fprintf (stderr, "Initializing sound decoders.\n");
|
||||
if (SoundDecoder_Init (flags, &formats))
|
||||
{
|
||||
fprintf (stderr, "Sound decoders initialization failed.\n");
|
||||
SDL_CloseAudio ();
|
||||
mixer_Uninit ();
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "Sound decoders initialized.\n");
|
||||
|
||||
*driver = mixSDL_Driver;
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
audio_GenSources (1, &soundSource[i].handle);
|
||||
soundSource[i].sample = NULL;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
soundSource[i].stream_mutex = CreateMutex ("MixSDL stream mutex", SYNC_CLASS_AUDIO);
|
||||
soundSource[i].sbuffer = NULL;
|
||||
soundSource[i].sbuf_start = 0;
|
||||
soundSource[i].sbuf_size = 0;
|
||||
soundSource[i].sbuf_offset = 0;
|
||||
}
|
||||
|
||||
atexit (unInitAudio);
|
||||
|
||||
SetSFXVolume (sfxVolumeScale);
|
||||
SetSpeechVolume (speechVolumeScale);
|
||||
SetMusicVolume ((COUNT)musicVolume);
|
||||
|
||||
StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024,
|
||||
"audio stream decoder");
|
||||
|
||||
SDL_PauseAudio (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_Uninit (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (StreamDecoderTask)
|
||||
{
|
||||
ConcludeTask (StreamDecoderTask);
|
||||
StreamDecoderTask = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
if (soundSource[i].sample && soundSource[i].sample->decoder)
|
||||
{
|
||||
StopStream (i);
|
||||
}
|
||||
if (soundSource[i].sbuffer)
|
||||
{
|
||||
void *sbuffer = soundSource[i].sbuffer;
|
||||
soundSource[i].sbuffer = NULL;
|
||||
HFree (sbuffer);
|
||||
}
|
||||
DestroyMutex (soundSource[i].stream_mutex);
|
||||
|
||||
mixSDL_DeleteSources (1, &soundSource[i].handle);
|
||||
}
|
||||
|
||||
SDL_CloseAudio ();
|
||||
mixer_Uninit ();
|
||||
SoundDecoder_Uninit ();
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* General
|
||||
*/
|
||||
|
||||
sint32
|
||||
mixSDL_GetError (void)
|
||||
{
|
||||
sint32 value = mixer_GetError ();
|
||||
switch (value)
|
||||
{
|
||||
case MIX_NO_ERROR:
|
||||
return audio_NO_ERROR;
|
||||
case MIX_INVALID_NAME:
|
||||
return audio_INVALID_NAME;
|
||||
case MIX_INVALID_ENUM:
|
||||
return audio_INVALID_ENUM;
|
||||
case MIX_INVALID_VALUE:
|
||||
return audio_INVALID_VALUE;
|
||||
case MIX_INVALID_OPERATION:
|
||||
return audio_INVALID_OPERATION;
|
||||
case MIX_OUT_OF_MEMORY:
|
||||
return audio_OUT_OF_MEMORY;
|
||||
default:
|
||||
fprintf (stderr, "mixSDL_GetError: unknown value %x\n", value);
|
||||
return audio_DRIVER_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sources
|
||||
*/
|
||||
|
||||
void
|
||||
mixSDL_GenSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
mixer_GenSources (n, (mixer_Object *) psrcobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_DeleteSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
mixer_DeleteSources (n, (mixer_Object *) psrcobj);
|
||||
}
|
||||
|
||||
bool
|
||||
mixSDL_IsSource (audio_Object srcobj)
|
||||
{
|
||||
return mixer_IsSource ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value)
|
||||
|
||||
{
|
||||
mixer_Sourcei ((mixer_Object) srcobj, (mixer_SourceProp) pname,
|
||||
(mixer_IntVal) value);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value)
|
||||
{
|
||||
mixer_Sourcef ((mixer_Object) srcobj, (mixer_SourceProp) pname, value);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
mixer_Sourcefv ((mixer_Object) srcobj, (mixer_SourceProp) pname, value);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
mixer_GetSourcei ((mixer_Object) srcobj, (mixer_SourceProp) pname,
|
||||
(mixer_IntVal *) value);
|
||||
if (pname == MIX_SOURCE_STATE)
|
||||
{
|
||||
switch (*value)
|
||||
{
|
||||
case MIX_INITIAL:
|
||||
*value = audio_INITIAL;
|
||||
break;
|
||||
case MIX_STOPPED:
|
||||
*value = audio_STOPPED;
|
||||
break;
|
||||
case MIX_PLAYING:
|
||||
*value = audio_PLAYING;
|
||||
break;
|
||||
case MIX_PAUSED:
|
||||
*value = audio_PAUSED;
|
||||
break;
|
||||
default:
|
||||
*value = audio_DRIVER_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
mixer_GetSourcef ((mixer_Object) srcobj, (mixer_SourceProp) pname, value);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_SourceRewind (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourceRewind ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_SourcePlay (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourcePlay ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_SourcePause (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourcePause ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_SourceStop (audio_Object srcobj)
|
||||
{
|
||||
mixer_SourceStop ((mixer_Object) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
mixer_SourceQueueBuffers ((mixer_Object) srcobj, n,
|
||||
(mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
mixer_SourceUnqueueBuffers ((mixer_Object) srcobj, n,
|
||||
(mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Buffers
|
||||
*/
|
||||
|
||||
void
|
||||
mixSDL_GenBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
mixer_GenBuffers (n, (mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_DeleteBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
mixer_DeleteBuffers (n, (mixer_Object *) pbufobj);
|
||||
}
|
||||
|
||||
bool
|
||||
mixSDL_IsBuffer (audio_Object bufobj)
|
||||
{
|
||||
return mixer_IsBuffer ((mixer_Object) bufobj);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
mixer_GetBufferi ((mixer_Object) bufobj, (mixer_BufferProp) pname,
|
||||
(mixer_IntVal *) value);
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq)
|
||||
{
|
||||
mixer_BufferData ((mixer_Object) bufobj, format, data, size, freq);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* SDL audio driver
|
||||
*/
|
||||
|
||||
#ifndef _AUDIODRV_SDL_H
|
||||
#define _AUDIODRV_SDL_H
|
||||
|
||||
#include "config.h"
|
||||
#include "libs/sound/sound.h"
|
||||
#include "libs/sound/mixer/mixer.h"
|
||||
#include <SDL.h>
|
||||
|
||||
/* General */
|
||||
sint32 mixSDL_Init (audio_Driver *driver, sint32 flags);
|
||||
void mixSDL_Uninit (void);
|
||||
sint32 mixSDL_GetError (void);
|
||||
|
||||
/* Sources */
|
||||
void mixSDL_GenSources (uint32 n, audio_Object *psrcobj);
|
||||
void mixSDL_DeleteSources (uint32 n, audio_Object *psrcobj);
|
||||
bool mixSDL_IsSource (audio_Object srcobj);
|
||||
void mixSDL_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value);
|
||||
void mixSDL_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value);
|
||||
void mixSDL_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void mixSDL_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value);
|
||||
void mixSDL_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void mixSDL_SourceRewind (audio_Object srcobj);
|
||||
void mixSDL_SourcePlay (audio_Object srcobj);
|
||||
void mixSDL_SourcePause (audio_Object srcobj);
|
||||
void mixSDL_SourceStop (audio_Object srcobj);
|
||||
void mixSDL_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
void mixSDL_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
|
||||
/* Buffers */
|
||||
void mixSDL_GenBuffers (uint32 n, audio_Object *pbufobj);
|
||||
void mixSDL_DeleteBuffers (uint32 n, audio_Object *pbufobj);
|
||||
bool mixSDL_IsBuffer (audio_Object bufobj);
|
||||
void mixSDL_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value);
|
||||
void mixSDL_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq);
|
||||
|
||||
|
||||
#endif /* _AUDIODRV_SDL_H */
|
||||
@@ -103,7 +103,7 @@ SetMusicVolume (COUNT Volume)
|
||||
{
|
||||
float f = (Volume / (float)MAX_VOLUME) * musicVolumeScale;
|
||||
musicVolume = Volume;
|
||||
TFBSound_Sourcef (soundSource[MUSIC_SOURCE].handle, TFBSOUND_GAIN, f);
|
||||
audio_Sourcef (soundSource[MUSIC_SOURCE].handle, audio_GAIN, f);
|
||||
}
|
||||
|
||||
MEM_HANDLE
|
||||
@@ -169,8 +169,8 @@ _GetMusicData (uio_Stream *fp, DWORD length)
|
||||
(*pmus)->decoder->frequency, (*pmus)->decoder->format);
|
||||
|
||||
(*pmus)->num_buffers = 64;
|
||||
(*pmus)->buffer = (TFBSound_Object *) HMalloc (sizeof (TFBSound_Object) * (*pmus)->num_buffers);
|
||||
TFBSound_GenBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
|
||||
(*pmus)->buffer = (audio_Object *) HMalloc (sizeof (audio_Object) * (*pmus)->num_buffers);
|
||||
audio_GenBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ _ReleaseMusicData (MEM_HANDLE handle)
|
||||
|
||||
(*pmus)->decoder = NULL;
|
||||
SoundDecoder_Free (decoder);
|
||||
TFBSound_DeleteBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
|
||||
audio_DeleteBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
|
||||
HFree ((*pmus)->buffer);
|
||||
if ((*pmus)->buffer_tag)
|
||||
HFree ((*pmus)->buffer_tag);
|
||||
|
||||
@@ -1 +1 @@
|
||||
uqm_CFILES="sound_openal.c"
|
||||
uqm_CFILES="audiodrv_openal.c"
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* OpenAL audio driver
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OPENAL
|
||||
|
||||
#include "audiodrv_openal.h"
|
||||
|
||||
ALCcontext *alcContext = NULL;
|
||||
ALCdevice *alcDevice = NULL;
|
||||
ALfloat listenerPos[] = {0.0f, 0.0f, 0.0f};
|
||||
ALfloat listenerVel[] = {0.0f, 0.0f, 0.0f};
|
||||
ALfloat listenerOri[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f};
|
||||
static Task StreamDecoderTask;
|
||||
|
||||
static const audio_Driver openAL_Driver =
|
||||
{
|
||||
openAL_Uninit,
|
||||
openAL_GetError,
|
||||
audio_DRIVER_OPENAL,
|
||||
{
|
||||
/* Errors */
|
||||
AL_FALSE,
|
||||
AL_INVALID_NAME,
|
||||
AL_INVALID_ENUM,
|
||||
AL_INVALID_VALUE,
|
||||
AL_INVALID_OPERATION,
|
||||
AL_OUT_OF_MEMORY,
|
||||
audio_DRIVER_FAILURE,
|
||||
|
||||
/* Source properties */
|
||||
AL_POSITION,
|
||||
AL_LOOPING,
|
||||
AL_BUFFER,
|
||||
AL_GAIN,
|
||||
AL_SOURCE_STATE,
|
||||
AL_BUFFERS_QUEUED,
|
||||
AL_BUFFERS_PROCESSED,
|
||||
|
||||
/* Source state information */
|
||||
AL_INITIAL,
|
||||
AL_STOPPED,
|
||||
AL_PLAYING,
|
||||
AL_PAUSED,
|
||||
|
||||
/* Sound buffer properties */
|
||||
AL_FREQUENCY,
|
||||
AL_BITS,
|
||||
AL_CHANNELS,
|
||||
AL_SIZE,
|
||||
AL_DATA,
|
||||
AL_FORMAT_MONO16,
|
||||
AL_FORMAT_STEREO16,
|
||||
AL_FORMAT_MONO8,
|
||||
AL_FORMAT_STEREO8
|
||||
},
|
||||
|
||||
/* Sources */
|
||||
openAL_GenSources,
|
||||
openAL_DeleteSources,
|
||||
openAL_IsSource,
|
||||
openAL_Sourcei,
|
||||
openAL_Sourcef,
|
||||
openAL_Sourcefv,
|
||||
openAL_GetSourcei,
|
||||
openAL_GetSourcef,
|
||||
openAL_SourceRewind,
|
||||
openAL_SourcePlay,
|
||||
openAL_SourcePause,
|
||||
openAL_SourceStop,
|
||||
openAL_SourceQueueBuffers,
|
||||
openAL_SourceUnqueueBuffers,
|
||||
|
||||
/* Buffers */
|
||||
openAL_GenBuffers,
|
||||
openAL_DeleteBuffers,
|
||||
openAL_IsBuffer,
|
||||
openAL_GetBufferi,
|
||||
openAL_BufferData
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
sint32
|
||||
openAL_Init (audio_Driver *driver, sint32 flags)
|
||||
{
|
||||
int i;
|
||||
TFB_DecoderFormats formats =
|
||||
{
|
||||
MIX_IS_BIG_ENDIAN, MIX_WANT_BIG_ENDIAN,
|
||||
audio_FORMAT_MONO8, audio_FORMAT_STEREO8,
|
||||
audio_FORMAT_MONO16, audio_FORMAT_STEREO16
|
||||
};
|
||||
|
||||
fprintf (stderr, "Initializing OpenAL.\n");
|
||||
#ifdef WIN32
|
||||
alcDevice = alcOpenDevice ((ALubyte*)"DirectSound3D");
|
||||
#else
|
||||
alcDevice = alcOpenDevice (NULL);
|
||||
#endif
|
||||
|
||||
if (!alcDevice)
|
||||
{
|
||||
fprintf (stderr,"Couldn't initialize OpenAL: %d\n", alcGetError (NULL));
|
||||
return -1;
|
||||
}
|
||||
|
||||
*driver = openAL_Driver;
|
||||
atexit (unInitAudio);
|
||||
|
||||
alcContext = alcCreateContext (alcDevice, NULL);
|
||||
if (!alcContext)
|
||||
{
|
||||
fprintf (stderr, "Couldn't create OpenAL context: %d\n", alcGetError (alcDevice));
|
||||
}
|
||||
|
||||
alcMakeContextCurrent (alcContext);
|
||||
|
||||
fprintf (stderr, "OpenAL initialized.\n");
|
||||
fprintf (stderr, " version: %s\n", alGetString (AL_VERSION));
|
||||
fprintf (stderr, " vendor: %s\n", alGetString (AL_VENDOR));
|
||||
fprintf (stderr, " renderer: %s\n", alGetString (AL_RENDERER));
|
||||
fprintf (stderr, " device: %s\n",
|
||||
alcGetString (alcDevice, ALC_DEFAULT_DEVICE_SPECIFIER));
|
||||
//fprintf (stderr, " extensions: %s\n", alGetString (AL_EXTENSIONS));
|
||||
|
||||
fprintf (stderr, "Initializing sound decoders.\n");
|
||||
SoundDecoder_Init (flags, &formats);
|
||||
fprintf (stderr, "Sound decoders initialized.\n");
|
||||
|
||||
alListenerfv (AL_POSITION, listenerPos);
|
||||
alListenerfv (AL_VELOCITY, listenerVel);
|
||||
alListenerfv (AL_ORIENTATION, listenerOri);
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
float zero[3] = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
alGenSources (1, &soundSource[i].handle);
|
||||
alSourcei (soundSource[i].handle, AL_LOOPING, AL_FALSE);
|
||||
alSourcefv (soundSource[i].handle, AL_POSITION, zero);
|
||||
alSourcefv (soundSource[i].handle, AL_VELOCITY, zero);
|
||||
alSourcefv (soundSource[i].handle, AL_DIRECTION, zero);
|
||||
|
||||
soundSource[i].sample = NULL;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
soundSource[i].stream_mutex = CreateMutex ("OpenAL stream mutex", SYNC_CLASS_AUDIO);
|
||||
soundSource[i].sbuffer = NULL;
|
||||
soundSource[i].sbuf_start = 0;
|
||||
soundSource[i].sbuf_size = 0;
|
||||
soundSource[i].sbuf_offset = 0;
|
||||
}
|
||||
|
||||
SetSFXVolume (sfxVolumeScale);
|
||||
SetSpeechVolume (speechVolumeScale);
|
||||
SetMusicVolume ((COUNT) musicVolume);
|
||||
|
||||
if (optStereoSFX)
|
||||
alDistanceModel (AL_INVERSE_DISTANCE);
|
||||
else
|
||||
alDistanceModel (AL_NONE);
|
||||
|
||||
StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024,
|
||||
"audio stream decoder");
|
||||
|
||||
(void) driver; // eat compiler warning
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
openAL_Uninit (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (StreamDecoderTask)
|
||||
{
|
||||
ConcludeTask (StreamDecoderTask);
|
||||
StreamDecoderTask = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
if (soundSource[i].sample && soundSource[i].sample->decoder)
|
||||
{
|
||||
StopStream (i);
|
||||
}
|
||||
if (soundSource[i].sbuffer)
|
||||
{
|
||||
void *sbuffer = soundSource[i].sbuffer;
|
||||
soundSource[i].sbuffer = NULL;
|
||||
HFree (sbuffer);
|
||||
}
|
||||
DestroyMutex (soundSource[i].stream_mutex);
|
||||
}
|
||||
|
||||
alcMakeContextCurrent (NULL);
|
||||
alcDestroyContext (alcContext);
|
||||
alcContext = NULL;
|
||||
alcCloseDevice (alcDevice);
|
||||
alcDevice = NULL;
|
||||
|
||||
SoundDecoder_Uninit ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* General
|
||||
*/
|
||||
|
||||
sint32
|
||||
openAL_GetError (void)
|
||||
{
|
||||
ALint value = alGetError ();
|
||||
switch (value)
|
||||
{
|
||||
case AL_FALSE:
|
||||
return audio_NO_ERROR;
|
||||
case AL_INVALID_NAME:
|
||||
return audio_INVALID_NAME;
|
||||
case AL_INVALID_ENUM:
|
||||
return audio_INVALID_ENUM;
|
||||
case AL_INVALID_VALUE:
|
||||
return audio_INVALID_VALUE;
|
||||
case AL_INVALID_OPERATION:
|
||||
return audio_INVALID_OPERATION;
|
||||
case AL_OUT_OF_MEMORY:
|
||||
return audio_OUT_OF_MEMORY;
|
||||
default:
|
||||
fprintf (stderr, "openAL_GetError: unknown value %x\n", value);
|
||||
return audio_DRIVER_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sources
|
||||
*/
|
||||
|
||||
void
|
||||
openAL_GenSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
alGenSources ((ALsizei) n, (ALuint *) psrcobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_DeleteSources (uint32 n, audio_Object *psrcobj)
|
||||
{
|
||||
alDeleteSources ((ALsizei) n, (ALuint *) psrcobj);
|
||||
}
|
||||
|
||||
bool
|
||||
openAL_IsSource (audio_Object srcobj)
|
||||
{
|
||||
return alIsSource ((ALuint) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value)
|
||||
|
||||
{
|
||||
alSourcei ((ALuint) srcobj, (ALenum) pname, (ALint) value);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value)
|
||||
{
|
||||
alSourcef ((ALuint) srcobj, (ALenum) pname, (ALfloat) value);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
alSourcefv ((ALuint) srcobj, (ALenum) pname, (ALfloat *) value);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
alGetSourcei ((ALuint) srcobj, (ALenum) pname, (ALint *) value);
|
||||
if (pname == AL_SOURCE_STATE)
|
||||
{
|
||||
switch (*value)
|
||||
{
|
||||
case AL_INITIAL:
|
||||
*value = audio_INITIAL;
|
||||
break;
|
||||
case AL_STOPPED:
|
||||
*value = audio_STOPPED;
|
||||
break;
|
||||
case AL_PLAYING:
|
||||
*value = audio_PLAYING;
|
||||
break;
|
||||
case AL_PAUSED:
|
||||
*value = audio_PAUSED;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "openAL_GetSourcei(): unknown value %x\n",
|
||||
*value);
|
||||
*value = audio_DRIVER_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
openAL_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value)
|
||||
{
|
||||
alGetSourcef ((ALuint) srcobj, (ALenum) pname, (ALfloat *) value);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_SourceRewind (audio_Object srcobj)
|
||||
{
|
||||
alSourceRewind ((ALuint) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_SourcePlay (audio_Object srcobj)
|
||||
{
|
||||
alSourcePlay ((ALuint) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_SourcePause (audio_Object srcobj)
|
||||
{
|
||||
alSourcePause ((ALuint) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_SourceStop (audio_Object srcobj)
|
||||
{
|
||||
alSourceStop ((ALuint) srcobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
alSourceQueueBuffers ((ALuint) srcobj, (ALsizei) n, (ALuint *) pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj)
|
||||
{
|
||||
alSourceUnqueueBuffers ((ALuint) srcobj, (ALsizei) n, (ALuint *) pbufobj);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Buffers
|
||||
*/
|
||||
|
||||
void
|
||||
openAL_GenBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
alGenBuffers ((ALsizei) n, (ALuint *) pbufobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_DeleteBuffers (uint32 n, audio_Object *pbufobj)
|
||||
{
|
||||
alDeleteBuffers ((ALsizei) n, (ALuint *) pbufobj);
|
||||
}
|
||||
|
||||
bool
|
||||
openAL_IsBuffer (audio_Object bufobj)
|
||||
{
|
||||
return alIsBuffer ((ALuint) bufobj);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value)
|
||||
{
|
||||
alGetBufferi ((ALuint) bufobj, (ALenum) pname, (ALint *) value);
|
||||
}
|
||||
|
||||
void
|
||||
openAL_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq)
|
||||
{
|
||||
alBufferData ((ALuint) bufobj, (ALenum) format, (ALvoid *) data,
|
||||
(ALsizei) size, (ALsizei) freq);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* OpenAL audio driver
|
||||
*/
|
||||
|
||||
#ifndef _AUDIODRV_OPENAL_H
|
||||
#define _AUDIODRV_OPENAL_H
|
||||
|
||||
#include "config.h"
|
||||
#include "libs/sound/sound.h"
|
||||
#include "options.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# include <al.h>
|
||||
# include <alc.h>
|
||||
# ifdef _MSC_VER
|
||||
# pragma comment (lib, "OpenAL32.lib")
|
||||
# endif
|
||||
#else
|
||||
# include <AL/al.h>
|
||||
# include <AL/alc.h>
|
||||
# define AL_INVALID_ENUM AL_ILLEGAL_ENUM
|
||||
# define AL_INVALID_OPERATION AL_ILLEGAL_COMMAND
|
||||
# define AL_DATA 0x2005
|
||||
#endif
|
||||
|
||||
/* This is just a simple endianness setup for decoders */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define MIX_IS_BIG_ENDIAN true
|
||||
# define MIX_WANT_BIG_ENDIAN false
|
||||
#else
|
||||
# define MIX_IS_BIG_ENDIAN false
|
||||
# define MIX_WANT_BIG_ENDIAN false
|
||||
#endif
|
||||
|
||||
|
||||
/* General */
|
||||
sint32 openAL_Init (audio_Driver *driver, sint32 flags);
|
||||
void openAL_Uninit (void);
|
||||
sint32 openAL_GetError (void);
|
||||
|
||||
/* Sources */
|
||||
void openAL_GenSources (uint32 n, audio_Object *psrcobj);
|
||||
void openAL_DeleteSources (uint32 n, audio_Object *psrcobj);
|
||||
bool openAL_IsSource (audio_Object srcobj);
|
||||
void openAL_Sourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal value);
|
||||
void openAL_Sourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float value);
|
||||
void openAL_Sourcefv (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void openAL_GetSourcei (audio_Object srcobj, audio_SourceProp pname,
|
||||
audio_IntVal *value);
|
||||
void openAL_GetSourcef (audio_Object srcobj, audio_SourceProp pname,
|
||||
float *value);
|
||||
void openAL_SourceRewind (audio_Object srcobj);
|
||||
void openAL_SourcePlay (audio_Object srcobj);
|
||||
void openAL_SourcePause (audio_Object srcobj);
|
||||
void openAL_SourceStop (audio_Object srcobj);
|
||||
void openAL_SourceQueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
void openAL_SourceUnqueueBuffers (audio_Object srcobj, uint32 n,
|
||||
audio_Object* pbufobj);
|
||||
|
||||
/* Buffers */
|
||||
void openAL_GenBuffers (uint32 n, audio_Object *pbufobj);
|
||||
void openAL_DeleteBuffers (uint32 n, audio_Object *pbufobj);
|
||||
bool openAL_IsBuffer (audio_Object bufobj);
|
||||
void openAL_GetBufferi (audio_Object bufobj, audio_BufferProp pname,
|
||||
audio_IntVal *value);
|
||||
void openAL_BufferData (audio_Object bufobj, uint32 format, void* data,
|
||||
uint32 size, uint32 freq);
|
||||
|
||||
|
||||
#endif /* _AUDIODRV_OPENAL_H */
|
||||
@@ -42,9 +42,9 @@ PlayChannel (COUNT channel, PVOID sample, SoundPosition pos,
|
||||
if (optStereoSFX)
|
||||
UpdateSoundPosition (channel, pos);
|
||||
|
||||
TFBSound_Sourcei (soundSource[channel].handle, TFBSOUND_BUFFER,
|
||||
audio_Sourcei (soundSource[channel].handle, audio_BUFFER,
|
||||
tfb_sample->buffer[0]);
|
||||
TFBSound_SourcePlay (soundSource[channel].handle);
|
||||
audio_SourcePlay (soundSource[channel].handle);
|
||||
(void) priority;
|
||||
}
|
||||
|
||||
@@ -62,15 +62,15 @@ CheckFinishedChannels (void)
|
||||
|
||||
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
|
||||
{
|
||||
TFBSound_IntVal state;
|
||||
audio_IntVal state;
|
||||
|
||||
TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_SOURCE_STATE,
|
||||
audio_GetSourcei (soundSource[i].handle, audio_SOURCE_STATE,
|
||||
&state);
|
||||
if (state == TFBSOUND_STOPPED)
|
||||
if (state == audio_STOPPED)
|
||||
{
|
||||
CleanSource (i);
|
||||
// and if it failed... we still dont care
|
||||
TFBSound_GetError();
|
||||
audio_GetError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,11 +78,11 @@ CheckFinishedChannels (void)
|
||||
BOOLEAN
|
||||
ChannelPlaying (COUNT WhichChannel)
|
||||
{
|
||||
TFBSound_IntVal state;
|
||||
audio_IntVal state;
|
||||
|
||||
TFBSound_GetSourcei (soundSource[WhichChannel].handle,
|
||||
TFBSOUND_SOURCE_STATE, &state);
|
||||
if (state == TFBSOUND_PLAYING)
|
||||
audio_GetSourcei (soundSource[WhichChannel].handle,
|
||||
audio_SOURCE_STATE, &state);
|
||||
if (state == audio_PLAYING)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -110,14 +110,14 @@ UpdateSoundPosition (COUNT channel, SoundPosition pos)
|
||||
fpos[0] = pos.x / ATTENUATION;
|
||||
fpos[1] = 0.0f;
|
||||
fpos[2] = pos.y / ATTENUATION;
|
||||
TFBSound_Sourcefv (soundSource[channel].handle, TFBSOUND_POSITION, fpos);
|
||||
audio_Sourcefv (soundSource[channel].handle, audio_POSITION, fpos);
|
||||
//fprintf (stderr, "UpdateSoundPosition(): channel %d, pos %d %d, posobj %x\n",
|
||||
// channel, pos.x, pos.y, (unsigned int)soundSource[channel].positional_object);
|
||||
}
|
||||
else
|
||||
{
|
||||
fpos[0] = fpos[1] = fpos[2] = 0.0f;
|
||||
TFBSound_Sourcefv (soundSource[channel].handle, TFBSOUND_POSITION, fpos);
|
||||
audio_Sourcefv (soundSource[channel].handle, audio_POSITION, fpos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ SetChannelVolume (COUNT channel, COUNT volume, BYTE priority)
|
||||
// I wonder what this whole priority business is...
|
||||
// I can probably ignore it.
|
||||
{
|
||||
TFBSound_Sourcef (soundSource[channel].handle, TFBSOUND_GAIN,
|
||||
audio_Sourcef (soundSource[channel].handle, audio_GAIN,
|
||||
(volume / (float)MAX_VOLUME) * sfxVolumeScale);
|
||||
(void)priority; // ignored
|
||||
}
|
||||
@@ -219,10 +219,10 @@ _GetSoundBankData (uio_Stream *fp, DWORD length)
|
||||
//fprintf (stderr, "_GetSoundBankData(): decoded_bytes %d\n", decoded_bytes);
|
||||
|
||||
sndfx[snd_ct]->num_buffers = 1;
|
||||
sndfx[snd_ct]->buffer = (TFBSound_Object *) HMalloc (
|
||||
sizeof (TFBSound_Object) * sndfx[snd_ct]->num_buffers);
|
||||
TFBSound_GenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer);
|
||||
TFBSound_BufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format,
|
||||
sndfx[snd_ct]->buffer = (audio_Object *) HMalloc (
|
||||
sizeof (audio_Object) * sndfx[snd_ct]->num_buffers);
|
||||
audio_GenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer);
|
||||
audio_BufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format,
|
||||
sndfx[snd_ct]->decoder->buffer, decoded_bytes,
|
||||
sndfx[snd_ct]->decoder->frequency);
|
||||
|
||||
@@ -313,7 +313,7 @@ _ReleaseSoundBankData (MEM_HANDLE Snd)
|
||||
|
||||
if ((*sptr)->decoder)
|
||||
SoundDecoder_Free ((*sptr)->decoder);
|
||||
TFBSound_DeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer);
|
||||
audio_DeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer);
|
||||
HFree ((*sptr)->buffer);
|
||||
if ((*sptr)->buffer_tag)
|
||||
HFree ((*sptr)->buffer_tag);
|
||||
|
||||
@@ -16,9 +16,16 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/sound/sound_common.h"
|
||||
#include "sound.h"
|
||||
|
||||
static Task FadeTask;
|
||||
static SIZE TTotal;
|
||||
static SIZE volume_end;
|
||||
|
||||
int musicVolume = (MAX_VOLUME >> 1);
|
||||
float musicVolumeScale = 1.0f;
|
||||
float sfxVolumeScale = 1.0f;
|
||||
float speechVolumeScale = 1.0f;
|
||||
TFB_SoundSource soundSource[NUM_SOUNDSOURCES];
|
||||
|
||||
|
||||
@@ -37,36 +44,36 @@ void
|
||||
CleanSource (int iSource)
|
||||
{
|
||||
#define MAX_STACK_BUFFERS 64
|
||||
TFBSound_IntVal processed;
|
||||
audio_IntVal processed;
|
||||
|
||||
soundSource[iSource].positional_object = NULL;
|
||||
TFBSound_GetSourcei (soundSource[iSource].handle,
|
||||
TFBSOUND_BUFFERS_PROCESSED, &processed);
|
||||
audio_GetSourcei (soundSource[iSource].handle,
|
||||
audio_BUFFERS_PROCESSED, &processed);
|
||||
if (processed != 0)
|
||||
{
|
||||
TFBSound_Object stack_bufs[MAX_STACK_BUFFERS];
|
||||
TFBSound_Object *bufs;
|
||||
audio_Object stack_bufs[MAX_STACK_BUFFERS];
|
||||
audio_Object *bufs;
|
||||
|
||||
if (processed > MAX_STACK_BUFFERS)
|
||||
bufs = (TFBSound_Object *) HMalloc (
|
||||
sizeof (TFBSound_Object) * processed);
|
||||
bufs = (audio_Object *) HMalloc (
|
||||
sizeof (audio_Object) * processed);
|
||||
else
|
||||
bufs = stack_bufs;
|
||||
|
||||
TFBSound_SourceUnqueueBuffers (soundSource[iSource].handle,
|
||||
audio_SourceUnqueueBuffers (soundSource[iSource].handle,
|
||||
processed, bufs);
|
||||
|
||||
if (processed > MAX_STACK_BUFFERS)
|
||||
HFree (bufs);
|
||||
}
|
||||
// set the source state to 'initial'
|
||||
TFBSound_SourceRewind (soundSource[iSource].handle);
|
||||
audio_SourceRewind (soundSource[iSource].handle);
|
||||
}
|
||||
|
||||
void
|
||||
StopSource (int iSource)
|
||||
{
|
||||
TFBSound_SourceStop (soundSource[iSource].handle);
|
||||
audio_SourceStop (soundSource[iSource].handle);
|
||||
CleanSource (iSource);
|
||||
}
|
||||
|
||||
@@ -90,9 +97,9 @@ SoundPlaying (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
TFBSound_IntVal state;
|
||||
TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_SOURCE_STATE, &state);
|
||||
if (state == TFBSOUND_PLAYING)
|
||||
audio_IntVal state;
|
||||
audio_GetSourcei (soundSource[i].handle, audio_SOURCE_STATE, &state);
|
||||
if (state == audio_PLAYING)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -134,12 +141,69 @@ void SetSFXVolume (float volume)
|
||||
int i;
|
||||
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
|
||||
{
|
||||
TFBSound_Sourcef (soundSource[i].handle, TFBSOUND_GAIN, volume);
|
||||
audio_Sourcef (soundSource[i].handle, audio_GAIN, volume);
|
||||
}
|
||||
}
|
||||
|
||||
void SetSpeechVolume (float volume)
|
||||
{
|
||||
TFBSound_Sourcef (soundSource[SPEECH_SOURCE].handle, TFBSOUND_GAIN, volume);
|
||||
audio_Sourcef (soundSource[SPEECH_SOURCE].handle, audio_GAIN, volume);
|
||||
}
|
||||
|
||||
static int
|
||||
fade_task (void *data)
|
||||
{
|
||||
SIZE TDelta, volume_beg;
|
||||
DWORD StartTime, CurTime;
|
||||
Task task = (Task) data;
|
||||
|
||||
volume_beg = musicVolume;
|
||||
StartTime = CurTime = GetTimeCounter ();
|
||||
do
|
||||
{
|
||||
SleepThreadUntil (CurTime + ONE_SECOND / 120);
|
||||
CurTime = GetTimeCounter ();
|
||||
if ((TDelta = (SIZE) (CurTime - StartTime)) > TTotal)
|
||||
TDelta = TTotal;
|
||||
|
||||
SetMusicVolume ((COUNT) (volume_beg + (SIZE)
|
||||
((long) (volume_end - volume_beg) * TDelta / TTotal)));
|
||||
} while (TDelta < TTotal);
|
||||
|
||||
FadeTask = 0;
|
||||
FinishTask (task);
|
||||
return (1);
|
||||
}
|
||||
|
||||
DWORD
|
||||
FadeMusic (BYTE end_vol, SIZE TimeInterval)
|
||||
{
|
||||
DWORD TimeOut;
|
||||
|
||||
if (FadeTask)
|
||||
{
|
||||
volume_end = musicVolume;
|
||||
TTotal = 1;
|
||||
do
|
||||
TaskSwitch ();
|
||||
while (FadeTask);
|
||||
TaskSwitch ();
|
||||
}
|
||||
|
||||
if ((TTotal = TimeInterval) <= 0)
|
||||
TTotal = 1; /* prevent divide by zero and negative fade */
|
||||
volume_end = end_vol;
|
||||
|
||||
if (TTotal > 1 && (FadeTask = AssignTask (fade_task, 0,
|
||||
"fade music")))
|
||||
{
|
||||
TimeOut = GetTimeCounter () + TTotal + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMusicVolume (end_vol);
|
||||
TimeOut = GetTimeCounter ();
|
||||
}
|
||||
|
||||
return (TimeOut);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,8 @@
|
||||
#include "starcon.h"
|
||||
#include "misc.h"
|
||||
#include "libs/strings/strintrn.h"
|
||||
#include "libs/sound/sndintrn.h"
|
||||
#include "libs/sound/sound_common.h"
|
||||
#ifdef HAVE_OPENAL
|
||||
#include "libs/sound/sound_chooser.h"
|
||||
#else
|
||||
#include "mixsdl/sound_mixsdl.h"
|
||||
#endif
|
||||
#include "sndintrn.h"
|
||||
#include "audiocore.h"
|
||||
#include "decoders/decoder.h"
|
||||
|
||||
#define FIRST_SFX_SOURCE 0
|
||||
@@ -39,7 +34,7 @@
|
||||
typedef struct
|
||||
{
|
||||
int in_use;
|
||||
TFBSound_Object buf_name;
|
||||
audio_Object buf_name;
|
||||
void *data; // user-defined data
|
||||
} TFB_SoundTag;
|
||||
|
||||
@@ -51,13 +46,13 @@ typedef struct tfb_soundcallbacks
|
||||
// return TRUE to continue, FALSE to abort
|
||||
bool (* OnStartStream) (TFB_SoundSample*);
|
||||
// return TRUE to continue, FALSE to abort
|
||||
bool (* OnEndChunk) (TFB_SoundSample*, TFBSound_Object);
|
||||
bool (* OnEndChunk) (TFB_SoundSample*, audio_Object);
|
||||
// return TRUE to continue, FALSE to abort
|
||||
void (* OnEndStream) (TFB_SoundSample*);
|
||||
// tagged buffer callback
|
||||
void (* OnTaggedBuffer) (TFB_SoundSample*, TFB_SoundTag*);
|
||||
// buffer just queued
|
||||
void (* OnQueueBuffer) (TFB_SoundSample*, TFBSound_Object);
|
||||
void (* OnQueueBuffer) (TFB_SoundSample*, audio_Object);
|
||||
} TFB_SoundCallbacks;
|
||||
|
||||
// audio data
|
||||
@@ -65,7 +60,7 @@ struct tfb_soundsample
|
||||
{
|
||||
TFB_SoundDecoder *decoder; // decoder to read from
|
||||
float length; // total length of decoder chain in seconds
|
||||
TFBSound_Object *buffer;
|
||||
audio_Object *buffer;
|
||||
uint32 num_buffers;
|
||||
TFB_SoundTag *buffer_tag;
|
||||
sint32 offset; // initial offset
|
||||
@@ -77,7 +72,7 @@ struct tfb_soundsample
|
||||
typedef struct tfb_soundsource
|
||||
{
|
||||
TFB_SoundSample *sample;
|
||||
TFBSound_Object handle;
|
||||
audio_Object handle;
|
||||
bool stream_should_be_playing;
|
||||
Mutex stream_mutex;
|
||||
sint32 start_time;
|
||||
@@ -96,6 +91,11 @@ typedef struct tfb_soundsource
|
||||
|
||||
extern TFB_SoundSource soundSource[];
|
||||
|
||||
extern int musicVolume;
|
||||
extern float musicVolumeScale;
|
||||
extern float sfxVolumeScale;
|
||||
extern float speechVolumeScale;
|
||||
|
||||
void StopSource (int iSource);
|
||||
void CleanSource (int iSource);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo
|
||||
offset += (sint32)(SoundDecoder_GetTime (sample->decoder) * (float)ONE_SECOND);
|
||||
soundSource[source].sample = sample;
|
||||
soundSource[source].sample->decoder->looping = looping;
|
||||
TFBSound_Sourcei (soundSource[source].handle, TFBSOUND_LOOPING, false);
|
||||
audio_Sourcei (soundSource[source].handle, audio_LOOPING, false);
|
||||
|
||||
if (scope)
|
||||
{
|
||||
@@ -60,9 +60,9 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo
|
||||
if (decoded_bytes == 0)
|
||||
break;
|
||||
|
||||
TFBSound_BufferData (sample->buffer[i], sample->decoder->format, sample->decoder->buffer,
|
||||
audio_BufferData (sample->buffer[i], sample->decoder->format, sample->decoder->buffer,
|
||||
decoded_bytes, sample->decoder->frequency);
|
||||
TFBSound_SourceQueueBuffers (soundSource[source].handle, 1, &sample->buffer[i]);
|
||||
audio_SourceQueueBuffers (soundSource[source].handle, 1, &sample->buffer[i]);
|
||||
if (sample->callbacks.OnQueueBuffer)
|
||||
sample->callbacks.OnQueueBuffer (sample, sample->buffer[i]);
|
||||
|
||||
@@ -90,7 +90,7 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo
|
||||
soundSource[source].sbuf_lasttime = GetTimeCounter ();
|
||||
soundSource[source].start_time = (sint32)GetTimeCounter () - offset;
|
||||
soundSource[source].stream_should_be_playing = TRUE;
|
||||
TFBSound_SourcePlay (soundSource[source].handle);
|
||||
audio_SourcePlay (soundSource[source].handle);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -116,14 +116,14 @@ void
|
||||
PauseStream (uint32 source)
|
||||
{
|
||||
soundSource[source].stream_should_be_playing = FALSE;
|
||||
TFBSound_SourcePause (soundSource[source].handle);
|
||||
audio_SourcePause (soundSource[source].handle);
|
||||
}
|
||||
|
||||
void
|
||||
ResumeStream (uint32 source)
|
||||
{
|
||||
soundSource[source].stream_should_be_playing = TRUE;
|
||||
TFBSound_SourcePlay (soundSource[source].handle);
|
||||
audio_SourcePlay (soundSource[source].handle);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -150,7 +150,7 @@ PlayingStream (uint32 source)
|
||||
}
|
||||
|
||||
TFB_SoundTag*
|
||||
TFB_FindTaggedBuffer (TFB_SoundSample* sample, TFBSound_Object buffer)
|
||||
TFB_FindTaggedBuffer (TFB_SoundSample* sample, audio_Object buffer)
|
||||
{
|
||||
uint32 buf_num;
|
||||
|
||||
@@ -167,7 +167,7 @@ TFB_FindTaggedBuffer (TFB_SoundSample* sample, TFBSound_Object buffer)
|
||||
}
|
||||
|
||||
void
|
||||
TFB_TagBuffer (TFB_SoundSample* sample, TFBSound_Object buffer, void* data)
|
||||
TFB_TagBuffer (TFB_SoundSample* sample, audio_Object buffer, void* data)
|
||||
{
|
||||
uint32 buf_num;
|
||||
|
||||
@@ -198,7 +198,7 @@ StreamDecoderTaskFunc (void *data)
|
||||
{
|
||||
Task task = (Task)data;
|
||||
int i;
|
||||
TFBSound_Object last_buffer[NUM_SOUNDSOURCES];
|
||||
audio_Object last_buffer[NUM_SOUNDSOURCES];
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; i++)
|
||||
last_buffer[i] = 0;
|
||||
@@ -210,8 +210,8 @@ StreamDecoderTaskFunc (void *data)
|
||||
|
||||
for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
TFBSound_IntVal processed, queued;
|
||||
TFBSound_IntVal state;
|
||||
audio_IntVal processed, queued;
|
||||
audio_IntVal state;
|
||||
|
||||
LockMutex (soundSource[i].stream_mutex);
|
||||
|
||||
@@ -224,13 +224,13 @@ StreamDecoderTaskFunc (void *data)
|
||||
continue;
|
||||
}
|
||||
|
||||
TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_BUFFERS_PROCESSED, &processed);
|
||||
TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_BUFFERS_QUEUED, &queued);
|
||||
audio_GetSourcei (soundSource[i].handle, audio_BUFFERS_PROCESSED, &processed);
|
||||
audio_GetSourcei (soundSource[i].handle, audio_BUFFERS_QUEUED, &queued);
|
||||
|
||||
if (processed == 0)
|
||||
{
|
||||
TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_SOURCE_STATE, &state);
|
||||
if (state != TFBSOUND_PLAYING)
|
||||
audio_GetSourcei (soundSource[i].handle, audio_SOURCE_STATE, &state);
|
||||
if (state != audio_PLAYING)
|
||||
{
|
||||
if (queued == 0 && soundSource[i].sample->decoder->error == SOUNDDECODER_EOF)
|
||||
{
|
||||
@@ -243,7 +243,7 @@ StreamDecoderTaskFunc (void *data)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): buffer underrun when playing %s, source %d\n",
|
||||
soundSource[i].sample->decoder->filename, i);
|
||||
TFBSound_SourcePlay (soundSource[i].handle);
|
||||
audio_SourcePlay (soundSource[i].handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,14 +253,14 @@ StreamDecoderTaskFunc (void *data)
|
||||
while (processed)
|
||||
{
|
||||
uint32 error;
|
||||
TFBSound_Object buffer;
|
||||
audio_Object buffer;
|
||||
uint32 decoded_bytes;
|
||||
|
||||
TFBSound_GetError (); // clear error state
|
||||
audio_GetError (); // clear error state
|
||||
|
||||
TFBSound_SourceUnqueueBuffers (soundSource[i].handle, 1, &buffer);
|
||||
audio_SourceUnqueueBuffers (soundSource[i].handle, 1, &buffer);
|
||||
|
||||
if ((error = TFBSound_GetError()) != TFBSOUND_NO_ERROR)
|
||||
if ((error = audio_GetError()) != audio_NO_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceUnqueueBuffers: %x, file %s, source %d\n", error, soundSource[i].sample->decoder->filename, i);
|
||||
break;
|
||||
@@ -276,9 +276,9 @@ StreamDecoderTaskFunc (void *data)
|
||||
}
|
||||
}
|
||||
{
|
||||
TFBSound_IntVal buf_size;
|
||||
audio_IntVal buf_size;
|
||||
soundSource[i].sbuf_lasttime = GetTimeCounter ();
|
||||
TFBSound_GetBufferi(buffer, TFBSOUND_SIZE, &buf_size);
|
||||
audio_GetBufferi(buffer, audio_SIZE, &buf_size);
|
||||
soundSource[i].sbuf_offset += buf_size;
|
||||
if (soundSource[i].sbuf_offset > soundSource[i].sbuf_size)
|
||||
soundSource[i].sbuf_offset -= soundSource[i].sbuf_size;
|
||||
@@ -317,38 +317,19 @@ StreamDecoderTaskFunc (void *data)
|
||||
|
||||
if (decoded_bytes > 0)
|
||||
{
|
||||
#if defined HAVE_OPENAL && !defined (WIN32) // && !defined (MacOS and BeOS too)
|
||||
// *nix OpenAL implementation has to handle stereo data differently to avoid mixing it to mono
|
||||
if (SoundDriver == TFB_SOUNDDRIVER_OPENAL &&
|
||||
(soundSource[i].sample->decoder->format == TFBSOUND_FORMAT_STEREO8 ||
|
||||
soundSource[i].sample->decoder->format == TFBSOUND_FORMAT_STEREO16))
|
||||
{
|
||||
TFBSound_BufferData_Linux (buffer, soundSource[i].sample->decoder->format,
|
||||
soundSource[i].sample->decoder->buffer, decoded_bytes,
|
||||
soundSource[i].sample->decoder->frequency,
|
||||
soundSource[i].sample->decoder->format);
|
||||
}
|
||||
else
|
||||
{
|
||||
TFBSound_BufferData (buffer, soundSource[i].sample->decoder->format,
|
||||
soundSource[i].sample->decoder->buffer, decoded_bytes,
|
||||
soundSource[i].sample->decoder->frequency);
|
||||
}
|
||||
#else
|
||||
TFBSound_BufferData (buffer, soundSource[i].sample->decoder->format,
|
||||
audio_BufferData (buffer, soundSource[i].sample->decoder->format,
|
||||
soundSource[i].sample->decoder->buffer, decoded_bytes,
|
||||
soundSource[i].sample->decoder->frequency);
|
||||
#endif
|
||||
|
||||
if ((error = TFBSound_GetError()) != TFBSOUND_NO_ERROR)
|
||||
if ((error = audio_GetError()) != audio_NO_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): TFBSound error after TFBSound_BufferData: %x, file %s, source %d, decoded_bytes %d\n",
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): TFBSound error after audio_BufferData: %x, file %s, source %d, decoded_bytes %d\n",
|
||||
error, soundSource[i].sample->decoder->filename, i, decoded_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
last_buffer[i] = buffer;
|
||||
TFBSound_SourceQueueBuffers (soundSource[i].handle, 1, &buffer);
|
||||
audio_SourceQueueBuffers (soundSource[i].handle, 1, &buffer);
|
||||
// do OnQueue callback
|
||||
if (soundSource[i].sample->callbacks.OnQueueBuffer)
|
||||
soundSource[i].sample->callbacks.OnQueueBuffer (
|
||||
@@ -390,9 +371,9 @@ StreamDecoderTaskFunc (void *data)
|
||||
}
|
||||
}
|
||||
|
||||
if ((error = TFBSound_GetError()) != TFBSOUND_NO_ERROR)
|
||||
if ((error = audio_GetError()) != audio_NO_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): TFBSound error after TFBSound_SourceQueueBuffers: %x, file %s, source %d, decoded_bytes %d\n",
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): TFBSound error after audio_SourceQueueBuffers: %x, file %s, source %d, decoded_bytes %d\n",
|
||||
error, soundSource[i].sample->decoder->filename, i, decoded_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,14 +25,9 @@ void ResumeStream (uint32 source);
|
||||
void SeekStream (uint32 source, uint32 pos);
|
||||
BOOLEAN PlayingStream (uint32 source);
|
||||
int StreamDecoderTaskFunc (void *data);
|
||||
int PreDecodeClips (TFB_SoundSample *sample, TFB_SoundDecoder *decoders[], bool autofree);
|
||||
void PlayDecodedClip (TFB_SoundSample *sample, uint32 source, bool scope);
|
||||
|
||||
TFB_SoundTag* FindTaggedBuffer (TFB_SoundSample* sample, TFBSound_Object buffer);
|
||||
TFB_SoundTag* FindTaggedBuffer (TFB_SoundSample* sample, audio_Object buffer);
|
||||
void TFB_ClearBufferTag (TFB_SoundTag* ptag);
|
||||
void TFB_TagBuffer (TFB_SoundSample* sample, TFBSound_Object buffer, void* data);
|
||||
|
||||
extern bool speech_advancetrack;
|
||||
void advance_track (int channel_finished);
|
||||
void TFB_TagBuffer (TFB_SoundSample* sample, audio_Object buffer, void* data);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,7 @@ bool is_sample_playing(TFB_SoundSample* samp);
|
||||
|
||||
// stream callbacks
|
||||
static bool OnTrackStart (TFB_SoundSample* sample);
|
||||
static bool OnChunkEnd (TFB_SoundSample* sample, TFBSound_Object buffer);
|
||||
static bool OnChunkEnd (TFB_SoundSample* sample, audio_Object buffer);
|
||||
static void OnTrackEnd (TFB_SoundSample* sample);
|
||||
static void OnTrackTag (TFB_SoundSample* sample, TFB_SoundTag* tag);
|
||||
|
||||
@@ -123,13 +123,13 @@ ResumeTrack ()
|
||||
if (scd->read_chain_ptr || sound_sample->decoder)
|
||||
{
|
||||
// Only try to start the track if there is something to play
|
||||
TFBSound_IntVal state;
|
||||
audio_IntVal state;
|
||||
BOOLEAN playing;
|
||||
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
TFBSound_GetSourcei (soundSource[SPEECH_SOURCE].handle, TFBSOUND_SOURCE_STATE, &state);
|
||||
audio_GetSourcei (soundSource[SPEECH_SOURCE].handle, audio_SOURCE_STATE, &state);
|
||||
playing = PlayingStream (SPEECH_SOURCE);
|
||||
if (!track_pos_changed && !playing && state == TFBSOUND_PAUSED)
|
||||
if (!track_pos_changed && !playing && state == audio_PAUSED)
|
||||
{
|
||||
/*adjust start time so the slider doesn't go crazy*/
|
||||
soundSource[SPEECH_SOURCE].start_time += GetTimeCounter () - soundSource[SPEECH_SOURCE].pause_time;
|
||||
@@ -198,7 +198,7 @@ StopTrack ()
|
||||
if (sound_sample)
|
||||
{
|
||||
DestroyMutex (track_mutex);
|
||||
TFBSound_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
|
||||
audio_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
|
||||
HFree (sound_sample->buffer);
|
||||
HFree (sound_sample->buffer_tag);
|
||||
HFree (sound_sample->data);
|
||||
@@ -254,7 +254,7 @@ OnTrackStart (TFB_SoundSample* sample)
|
||||
}
|
||||
|
||||
static bool
|
||||
OnChunkEnd (TFB_SoundSample* sample, TFBSound_Object buffer)
|
||||
OnChunkEnd (TFB_SoundSample* sample, audio_Object buffer)
|
||||
{
|
||||
TFB_SoundChainData* scd = (TFB_SoundChainData*) sample->data;
|
||||
|
||||
@@ -591,7 +591,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp, TFB_Tra
|
||||
sound_sample->num_buffers = 8;
|
||||
sound_sample->buffer_tag = HCalloc (sizeof (TFB_SoundTag) * sound_sample->num_buffers);
|
||||
sound_sample->buffer = HMalloc (sizeof (uint32) * sound_sample->num_buffers);
|
||||
TFBSound_GenBuffers (sound_sample->num_buffers, sound_sample->buffer);
|
||||
audio_GenBuffers (sound_sample->num_buffers, sound_sample->buffer);
|
||||
decoder = SoundDecoder_Load (contentDir, TrackName, 4096,
|
||||
startTime, time_stamps[page_counter]);
|
||||
scd->read_chain_ptr = create_soundchain (decoder, 0.0);
|
||||
@@ -652,7 +652,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp, TFB_Tra
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "SpliceTrack(): couldn't load %s\n", TrackName);
|
||||
TFBSound_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
|
||||
audio_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
|
||||
destroy_soundchain (first_chain);
|
||||
first_chain = NULL;
|
||||
HFree (sound_sample->buffer);
|
||||
@@ -839,7 +839,7 @@ GetSoundData (void *data)
|
||||
UBYTE *sbuffer = soundSource[SPEECH_SOURCE].sbuffer;
|
||||
|
||||
assert (soundSource[SPEECH_SOURCE].sample->decoder->frequency == 11025);
|
||||
assert (soundSource[SPEECH_SOURCE].sample->decoder->format == TFBSOUND_FORMAT_MONO16);
|
||||
assert (soundSource[SPEECH_SOURCE].sample->decoder->format == audio_FORMAT_MONO16);
|
||||
|
||||
if (delta < 0)
|
||||
{
|
||||
@@ -908,7 +908,7 @@ GetSoundData (void *data)
|
||||
UBYTE *sbuffer = soundSource[MUSIC_SOURCE].sbuffer;
|
||||
|
||||
assert (soundSource[MUSIC_SOURCE].sample->decoder->frequency >= 11025);
|
||||
assert (soundSource[MUSIC_SOURCE].sample->decoder->format == TFBSOUND_FORMAT_STEREO16);
|
||||
assert (soundSource[MUSIC_SOURCE].sample->decoder->format == audio_FORMAT_STEREO16);
|
||||
|
||||
step = soundSource[MUSIC_SOURCE].sample->decoder->frequency / 11025 * 16;
|
||||
if (step % 2 == 1)
|
||||
|
||||
@@ -34,7 +34,7 @@ TFB_VideoCallbacks vp_DecoderCBs =
|
||||
static bool vp_AudioStart (TFB_SoundSample* sample);
|
||||
static void vp_AudioEnd (TFB_SoundSample* sample);
|
||||
static void vp_BufferTag (TFB_SoundSample* sample, TFB_SoundTag* tag);
|
||||
static void vp_QueueBuffer (TFB_SoundSample* sample, TFBSound_Object buffer);
|
||||
static void vp_QueueBuffer (TFB_SoundSample* sample, audio_Object buffer);
|
||||
|
||||
static TFB_SoundCallbacks vp_AudioCBs =
|
||||
{
|
||||
@@ -515,7 +515,7 @@ vp_BufferTag (TFB_SoundSample* sample, TFB_SoundTag* tag)
|
||||
}
|
||||
|
||||
static void
|
||||
vp_QueueBuffer (TFB_SoundSample* sample, TFBSound_Object buffer)
|
||||
vp_QueueBuffer (TFB_SoundSample* sample, audio_Object buffer)
|
||||
{
|
||||
//TFB_VideoClip* vid = sample->data;
|
||||
|
||||
|
||||
+14
-14
@@ -30,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/sound/sound_common.h"
|
||||
#include "libs/sound/sound.h"
|
||||
#include "libs/input/input_common.h"
|
||||
#include "libs/tasklib.h"
|
||||
#include "file.h"
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "uqmversion.h"
|
||||
#include "comm.h"
|
||||
|
||||
#if defined(GFXMODULE_SDL) || defined(SOUNDMODULE_SDL)
|
||||
#if defined(GFXMODULE_SDL)
|
||||
# include <SDL.h>
|
||||
// Including this is actually necessary on OSX.
|
||||
#endif
|
||||
@@ -66,9 +66,9 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int gfxdriver = TFB_GFXDRIVER_SDL_PURE;
|
||||
int snddriver = TFB_SOUNDDRIVER_MIXSDL;
|
||||
int snddriver = audio_DRIVER_MIXSDL;
|
||||
int gfxflags = 0;
|
||||
int soundflags = TFB_SOUNDFLAGS_MQAUDIO;
|
||||
int soundflags = audio_QUALITY_MEDIUM;
|
||||
int width = 640, height = 480, bpp = 16;
|
||||
int vol;
|
||||
int val;
|
||||
@@ -218,18 +218,18 @@ main (int argc, char *argv[])
|
||||
case 'q':
|
||||
if (!strcmp (optarg, "high"))
|
||||
{
|
||||
soundflags &= ~(TFB_SOUNDFLAGS_MQAUDIO|TFB_SOUNDFLAGS_LQAUDIO);
|
||||
soundflags |= TFB_SOUNDFLAGS_HQAUDIO;
|
||||
soundflags &= ~(audio_QUALITY_MEDIUM|audio_QUALITY_LOW);
|
||||
soundflags |= audio_QUALITY_HIGH;
|
||||
}
|
||||
else if (!strcmp (optarg, "medium"))
|
||||
{
|
||||
soundflags &= ~(TFB_SOUNDFLAGS_HQAUDIO|TFB_SOUNDFLAGS_LQAUDIO);
|
||||
soundflags |= TFB_SOUNDFLAGS_MQAUDIO;
|
||||
soundflags &= ~(audio_QUALITY_HIGH|audio_QUALITY_LOW);
|
||||
soundflags |= audio_QUALITY_MEDIUM;
|
||||
}
|
||||
else if (!strcmp (optarg, "low"))
|
||||
{
|
||||
soundflags &= ~(TFB_SOUNDFLAGS_HQAUDIO|TFB_SOUNDFLAGS_MQAUDIO);
|
||||
soundflags |= TFB_SOUNDFLAGS_LQAUDIO;
|
||||
soundflags &= ~(audio_QUALITY_HIGH|audio_QUALITY_MEDIUM);
|
||||
soundflags |= audio_QUALITY_LOW;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
@@ -272,15 +272,15 @@ main (int argc, char *argv[])
|
||||
case SOUND_OPT:
|
||||
if (!strcmp (optarg, "openal"))
|
||||
{
|
||||
snddriver = TFB_SOUNDDRIVER_OPENAL;
|
||||
snddriver = audio_DRIVER_OPENAL;
|
||||
}
|
||||
else if (!strcmp (optarg, "none"))
|
||||
{
|
||||
snddriver = TFB_SOUNDDRIVER_NOSOUND;
|
||||
snddriver = audio_DRIVER_NOSOUND;
|
||||
}
|
||||
else if (!strcmp (optarg, "mixsdl"))
|
||||
{
|
||||
snddriver = TFB_SOUNDDRIVER_MIXSDL;
|
||||
snddriver = audio_DRIVER_MIXSDL;
|
||||
}
|
||||
break;
|
||||
case STEREOSFX_OPT:
|
||||
@@ -357,7 +357,7 @@ main (int argc, char *argv[])
|
||||
init_communication ();
|
||||
if (gammaset)
|
||||
TFB_SetGamma (gamma);
|
||||
TFB_InitSound (snddriver, soundflags);
|
||||
initAudio (snddriver, soundflags);
|
||||
TFB_InitInput (TFB_INPUTDRIVER_SDL, 0);
|
||||
|
||||
AssignTask (Starcon2Main, 1024, "Starcon2Main");
|
||||
|
||||
Reference in New Issue
Block a user