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:
gewlitys
2004-01-04 03:38:04 +00:00
parent b729f3f1bc
commit 248e1e4d6b
29 changed files with 4331 additions and 179 deletions
+2
View File
@@ -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
+39 -39
View File
@@ -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
+1 -1
View 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"
+4 -5
View File
@@ -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"
+226
View File
@@ -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);
}
+166
View File
@@ -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 */
+3 -3
View File
@@ -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
+274
View File
@@ -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 */
+108
View File
@@ -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 */
+4 -4
View File
@@ -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
View File
@@ -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 */
+18 -18
View File
@@ -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);
+80 -16
View File
@@ -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);
}
+12 -12
View File
@@ -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);
+28 -47
View File
@@ -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);
}
}
+2 -7
View File
@@ -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
+10 -10
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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");