Added 'nosound' driver; misc sound_chooser fixes and warning removals
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@692 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -33,6 +33,20 @@
|
||||
|
||||
#define DEBUG
|
||||
|
||||
/* stanard SDL_audio driver */
|
||||
static const
|
||||
mixSDL_DriverInfo mixer_SDLdriver =
|
||||
{
|
||||
mixSDL_DriverGetName,
|
||||
mixSDL_DriverGetError,
|
||||
mixSDL_DriverOpenAudio,
|
||||
SDL_CloseAudio,
|
||||
SDL_PauseAudio
|
||||
};
|
||||
/* SDL_audio driver is the default */
|
||||
static mixSDL_Driver mixer_driver = &mixer_SDLdriver;
|
||||
static mixSDL_DriverFlags mixer_driverflags = 0;
|
||||
|
||||
static uint32 audio_opened = 0;
|
||||
static SDL_AudioSpec mixer_spec;
|
||||
static uint32 last_error = MIX_NO_ERROR;
|
||||
@@ -118,6 +132,25 @@ mixSDL_SetError (uint32 error)
|
||||
last_error = error;
|
||||
}
|
||||
|
||||
static const char*
|
||||
mixSDL_DriverGetName ()
|
||||
{
|
||||
return "SDL_audio";
|
||||
}
|
||||
|
||||
static const char*
|
||||
mixSDL_DriverGetError (void)
|
||||
{
|
||||
return SDL_GetError();
|
||||
}
|
||||
|
||||
static int
|
||||
mixSDL_DriverOpenAudio (void *desired, void *obtained)
|
||||
{
|
||||
return SDL_OpenAudio ((SDL_AudioSpec *) desired,
|
||||
(SDL_AudioSpec *) obtained);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* General interface
|
||||
*/
|
||||
@@ -130,9 +163,23 @@ mixSDL_GetError (void)
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
mixSDL_UseDriver (mixSDL_Driver driver, mixSDL_DriverFlags flags)
|
||||
{
|
||||
if (!driver)
|
||||
return;
|
||||
|
||||
if (driver == (mixSDL_Driver)~0)
|
||||
driver = &mixer_SDLdriver; /* default */
|
||||
|
||||
mixer_driver = driver;
|
||||
mixer_driverflags = flags;
|
||||
}
|
||||
|
||||
/* Open the mixer with a certain desired audio format */
|
||||
bool
|
||||
mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf)
|
||||
mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf,
|
||||
mixSDL_Quality quality)
|
||||
{
|
||||
SDL_AudioSpec desired;
|
||||
|
||||
@@ -158,14 +205,22 @@ mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf)
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf (stderr, "MixSDL using driver '%s'\n",
|
||||
mixer_driver->GetDriverName());
|
||||
|
||||
/* Set the desired format and frequency */
|
||||
desired.freq = frequency;
|
||||
desired.samples = samples_buf;
|
||||
desired.callback = mixSDL_mix_channels;
|
||||
if (mixer_driverflags & MIX_DRIVER_FAKE_PLAY)
|
||||
desired.callback = mixSDL_mix_fake;
|
||||
else if (quality == MIX_QUALITY_LOW)
|
||||
desired.callback = mixSDL_mix_lowq;
|
||||
else
|
||||
desired.callback = mixSDL_mix_channels;
|
||||
desired.userdata = NULL;
|
||||
|
||||
/* Accept nearly any audio format */
|
||||
if (SDL_OpenAudio (&desired, &mixer_spec) < 0)
|
||||
if (mixer_driver->OpenAudio (&desired, &mixer_spec) < 0)
|
||||
{
|
||||
mixSDL_SetError (MIX_SDL_FAILURE);
|
||||
return false;
|
||||
@@ -188,7 +243,7 @@ mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf)
|
||||
mixer_spec.channels < 1 || mixer_spec.channels > 2)
|
||||
{
|
||||
mixSDL_SetError (MIX_SDL_FAILURE);
|
||||
SDL_CloseAudio ();
|
||||
mixer_driver->CloseAudio ();
|
||||
fprintf (stderr, "mixSDL_OpenAudio: unable to aquire "
|
||||
"desired format\n");
|
||||
return false;
|
||||
@@ -208,7 +263,7 @@ mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf)
|
||||
mixSDL_InitMutex (act_mutex, "mixSDL_ActiveMutex");
|
||||
|
||||
audio_opened = 1;
|
||||
SDL_PauseAudio (0);
|
||||
mixer_driver->PauseAudio (0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1066,6 +1121,10 @@ mixSDL_SourceStop_internal (mixSDL_Source *src)
|
||||
static __inline__ bool
|
||||
mixSDL_SourceGetNextSample (mixSDL_Source *src, sint32* psamp)
|
||||
{
|
||||
/* fake the data if requested */
|
||||
if (mixer_driverflags & MIX_DRIVER_FAKE_DATA)
|
||||
return mixSDL_SourceGetFakeSample (src, psamp);
|
||||
|
||||
while (src->nextqueued)
|
||||
{
|
||||
mixSDL_Buffer *buf = src->nextqueued;
|
||||
@@ -1133,6 +1192,42 @@ mixSDL_SourceGetNextSample (mixSDL_Source *src, sint32* psamp)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* fake the next sample, but process buffers and states */
|
||||
static __inline__ bool
|
||||
mixSDL_SourceGetFakeSample (mixSDL_Source *src, sint32* psamp)
|
||||
{
|
||||
while (src->nextqueued)
|
||||
{
|
||||
mixSDL_Buffer *buf = src->nextqueued;
|
||||
|
||||
*psamp = 0;
|
||||
src->curbufofs += mixer_chansize;
|
||||
|
||||
if (src->curbufofs >= buf->size)
|
||||
{
|
||||
/* buffer exhausted, go next */
|
||||
buf->state = MIX_BUF_PROCESSED;
|
||||
src->curbufofs = 0;
|
||||
src->nextqueued = src->nextqueued->next;
|
||||
src->cprocessed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf->state = MIX_BUF_PLAYING;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* no more playable buffers */
|
||||
if (src->state >= MIX_PLAYING)
|
||||
mixSDL_SourceDeactivate (src);
|
||||
|
||||
src->state = MIX_STOPPED;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Buffers interface
|
||||
*/
|
||||
@@ -1406,45 +1501,49 @@ mixSDL_BufferData (mixSDL_Object bufobj, uint32 format, void* data,
|
||||
MIX_FORMAT_SAMPSIZE (mixer_format);
|
||||
|
||||
buf->size = dstsize;
|
||||
buf->data = HMalloc (dstsize);
|
||||
/* only copy/convert the data if not faking */
|
||||
if (! (mixer_driverflags & MIX_DRIVER_FAKE_DATA))
|
||||
{
|
||||
buf->data = HMalloc (dstsize);
|
||||
|
||||
if (format == mixer_format && freq == mixer_freq)
|
||||
{
|
||||
/* format identical to internal */
|
||||
buf->locked = true;
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
|
||||
memcpy (buf->data, data, size);
|
||||
if (MIX_FORMAT_SAMPSIZE (mixer_format) == 1)
|
||||
if (format == mixer_format && freq == mixer_freq)
|
||||
{
|
||||
/* convert buffer to S8 format internally */
|
||||
uint8* dst;
|
||||
for (dst = buf->data; dstsize; dstsize--, dst++)
|
||||
*dst ^= 0x80;
|
||||
/* format identical to internal */
|
||||
buf->locked = true;
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
|
||||
memcpy (buf->data, data, size);
|
||||
if (MIX_FORMAT_SAMPSIZE (mixer_format) == 1)
|
||||
{
|
||||
/* convert buffer to S8 format internally */
|
||||
uint8* dst;
|
||||
for (dst = buf->data; dstsize; dstsize--, dst++)
|
||||
*dst ^= 0x80;
|
||||
}
|
||||
|
||||
mixSDL_LockMutex (buf_mutex);
|
||||
buf->locked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* needs convertion */
|
||||
conv.srcfmt = format;
|
||||
conv.srcdata = data;
|
||||
conv.srcsize = size;
|
||||
conv.srcfreq = freq;
|
||||
conv.dstfmt = mixer_format;
|
||||
conv.dstdata = buf->data;
|
||||
conv.dstsize = dstsize;
|
||||
conv.dstfreq = mixer_freq;
|
||||
|
||||
mixSDL_LockMutex (buf_mutex);
|
||||
buf->locked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* needs convertion */
|
||||
conv.srcfmt = format;
|
||||
conv.srcdata = data;
|
||||
conv.srcsize = size;
|
||||
conv.srcfreq = freq;
|
||||
conv.dstfmt = mixer_format;
|
||||
conv.dstdata = buf->data;
|
||||
conv.dstsize = dstsize;
|
||||
conv.dstfreq = mixer_freq;
|
||||
buf->locked = true;
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
|
||||
buf->locked = true;
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
|
||||
mixSDL_ConvertBuffer_internal (&conv);
|
||||
|
||||
mixSDL_LockMutex (buf_mutex);
|
||||
buf->locked = false;
|
||||
mixSDL_ConvertBuffer_internal (&conv);
|
||||
|
||||
mixSDL_LockMutex (buf_mutex);
|
||||
buf->locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
buf->state = MIX_BUF_FILLED;
|
||||
@@ -1880,7 +1979,7 @@ mixSDL_mix_channels (void *userdata, uint8 *stream, sint32 len)
|
||||
fprintf (stderr, "mixSDL_mix_channels(): "
|
||||
"WARNING: work-buffer too small\n");
|
||||
#endif
|
||||
mixSDL_mix_lowq (stream, len);
|
||||
mixSDL_mix_lowq (userdata, stream, len);
|
||||
}
|
||||
|
||||
/* keep this order or die */
|
||||
@@ -1939,7 +2038,7 @@ mixSDL_mix_channels (void *userdata, uint8 *stream, sint32 len)
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
mixSDL_UnlockMutex (src_mutex);
|
||||
|
||||
(void)userdata; // satisfying compiler
|
||||
(void) userdata; // satisfying compiler - unused arg
|
||||
}
|
||||
|
||||
/* data unclipping - smooth out the areas that need to be clipped */
|
||||
@@ -2027,7 +2126,7 @@ mixSDL_UnclipWorkBuffer (sint32 *data, sint32 *end_data, uint32 step)
|
||||
|
||||
/* low quality faster version */
|
||||
static void
|
||||
mixSDL_mix_lowq (uint8 *stream, sint32 len)
|
||||
mixSDL_mix_lowq (void *userdata, uint8 *stream, sint32 len)
|
||||
{
|
||||
uint8 *end_stream = stream + len;
|
||||
|
||||
@@ -2088,4 +2187,44 @@ mixSDL_mix_lowq (uint8 *stream, sint32 len)
|
||||
mixSDL_UnlockMutex (act_mutex);
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
mixSDL_UnlockMutex (src_mutex);
|
||||
|
||||
(void) userdata; // satisfying compiler - unused arg
|
||||
}
|
||||
|
||||
/* fake mixer -- only process buffer and source states */
|
||||
static void
|
||||
mixSDL_mix_fake (void *userdata, uint8 *stream, sint32 len)
|
||||
{
|
||||
uint8 *end_stream = stream + len;
|
||||
|
||||
/* keep this order or die */
|
||||
mixSDL_LockMutex (src_mutex);
|
||||
mixSDL_LockMutex (buf_mutex);
|
||||
mixSDL_LockMutex (act_mutex);
|
||||
|
||||
for (; stream < end_stream; stream += mixer_chansize)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < MAX_SOURCES; i++)
|
||||
{
|
||||
mixSDL_Source *src;
|
||||
sint32 samp;
|
||||
|
||||
/* find next source */
|
||||
for (; i < MAX_SOURCES && (
|
||||
(src = active_sources[i]) == 0
|
||||
|| src->state != MIX_PLAYING
|
||||
|| !mixSDL_SourceGetFakeSample (src, &samp));
|
||||
i++)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* keep this order or die */
|
||||
mixSDL_UnlockMutex (act_mutex);
|
||||
mixSDL_UnlockMutex (buf_mutex);
|
||||
mixSDL_UnlockMutex (src_mutex);
|
||||
|
||||
(void) userdata; // satisfying compiler - unused arg
|
||||
}
|
||||
|
||||
@@ -134,6 +134,25 @@ typedef enum
|
||||
|
||||
} mixSDL_Format;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIX_QUALITY_LOW = 0,
|
||||
MIX_QUALITY_MEDIUM,
|
||||
MIX_QUALITY_HIGH,
|
||||
MIX_QUALITY_DEFAULT = MIX_QUALITY_MEDIUM,
|
||||
MIX_QUALITY_COUNT
|
||||
|
||||
} mixSDL_Quality;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIX_DRIVER_NOFLAGS = 0,
|
||||
MIX_DRIVER_FAKE_DATA = 1,
|
||||
MIX_DRIVER_FAKE_PLAY = 2,
|
||||
MIX_DRIVER_FAKE_ALL = MIX_DRIVER_FAKE_DATA | MIX_DRIVER_FAKE_PLAY
|
||||
|
||||
} mixSDL_DriverFlags;
|
||||
|
||||
/*************************************************
|
||||
* Interface Types
|
||||
*/
|
||||
@@ -179,12 +198,26 @@ typedef struct
|
||||
|
||||
#define mixSDL_srcMagic 0x5358494DU /* MIXS in LSB */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* (* GetDriverName) (void);
|
||||
const char* (* GetError) (void);
|
||||
/* see SDL for description of these functions */
|
||||
int (* OpenAudio) (void *desired, void *obtained);
|
||||
void (* CloseAudio) (void);
|
||||
void (* PauseAudio) (int pause_on);
|
||||
|
||||
} mixSDL_DriverInfo;
|
||||
typedef const mixSDL_DriverInfo *mixSDL_Driver;
|
||||
|
||||
/*************************************************
|
||||
* General interface
|
||||
*/
|
||||
uint32 mixSDL_GetError (void);
|
||||
void mixSDL_UseDriver (mixSDL_Driver driver, mixSDL_DriverFlags flags);
|
||||
|
||||
bool mixSDL_OpenAudio (uint32 freq, uint32 format, uint32 samples_buf);
|
||||
bool mixSDL_OpenAudio (uint32 freq, uint32 format, uint32 samples_buf,
|
||||
mixSDL_Quality quality);
|
||||
void mixSDL_CloseAudio (void);
|
||||
bool mixSDL_QuerySpec (uint32 *freq, uint32 *format, uint32 *channels);
|
||||
|
||||
|
||||
@@ -116,10 +116,18 @@ static void mixSDL_UnlockMutex (mixSDL_Mutex mtx);
|
||||
/* The Mixer */
|
||||
static void mixSDL_mix_channels (void *userdata, uint8 *stream,
|
||||
sint32 len);
|
||||
static void mixSDL_mix_lowq (void *userdata, uint8 *stream, sint32 len);
|
||||
static void mixSDL_mix_fake (void *userdata, uint8 *stream, sint32 len);
|
||||
static void mixSDL_UnclipWorkBuffer (sint32 *data, sint32 *end_data,
|
||||
uint32 step);
|
||||
static void mixSDL_mix_lowq (uint8 *stream, sint32 len);
|
||||
static __inline__ bool mixSDL_SourceGetNextSample (mixSDL_Source *src,
|
||||
sint32* samp);
|
||||
static __inline__ bool mixSDL_SourceGetFakeSample (mixSDL_Source *src,
|
||||
sint32* psamp);
|
||||
|
||||
/* SDL driver */
|
||||
static const char* mixSDL_DriverGetName (void);
|
||||
static const char* mixSDL_DriverGetError (void);
|
||||
static int mixSDL_DriverOpenAudio (void *desired, void *obtained);
|
||||
|
||||
#endif /* MIXERINT_H */
|
||||
|
||||
@@ -16,16 +16,56 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
//#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "SDL.h"
|
||||
#include "libs/sound/sound.h"
|
||||
#include "libs/tasklib.h"
|
||||
|
||||
static Task StreamDecoderTask;
|
||||
|
||||
/*******************************************************************
|
||||
* NoSound driver for MixSDL - declarations
|
||||
*/
|
||||
|
||||
static const char* NoSound_GetDriverName (void);
|
||||
static const char* NoSound_GetError (void);
|
||||
static int NoSound_OpenAudio (void *desired, void *obtained);
|
||||
static void NoSound_CloseAudio (void);
|
||||
static void NoSound_PauseAudio (int pause_on);
|
||||
|
||||
/* The nosound driver */
|
||||
static const
|
||||
mixSDL_DriverInfo NoSound_driver =
|
||||
{
|
||||
NoSound_GetDriverName,
|
||||
NoSound_GetError,
|
||||
NoSound_OpenAudio,
|
||||
NoSound_CloseAudio,
|
||||
NoSound_PauseAudio
|
||||
};
|
||||
static SDL_AudioSpec NoSound_spec;
|
||||
static Task NoSound_PlaybackTask;
|
||||
static bool NoSound_Paused = true;
|
||||
static const char* NoSound_ErrorStr = "";
|
||||
|
||||
/*******************************************************************
|
||||
* Other stuff
|
||||
*/
|
||||
static int current_driver = 0;
|
||||
|
||||
int TFB_NoSound_InitSound (int driver, int flags);
|
||||
|
||||
/*******************************************************************
|
||||
* Normal MixSDL sound
|
||||
*/
|
||||
|
||||
int
|
||||
TFB_mixSDL_InitSound (int driver, int flags)
|
||||
{
|
||||
int i;
|
||||
char SoundcardName[256];
|
||||
uint32 audio_rate, audio_channels, audio_bufsize, audio_format;
|
||||
mixSDL_Quality audio_quality;
|
||||
TFB_DecoderFormats formats =
|
||||
{
|
||||
MIX_IS_BIG_ENDIAN, MIX_WANT_BIG_ENDIAN,
|
||||
@@ -37,34 +77,39 @@ TFB_mixSDL_InitSound (int driver, int flags)
|
||||
if ((SDL_InitSubSystem(SDL_INIT_AUDIO)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Couldn't initialize audio subsystem: %s\n", SDL_GetError());
|
||||
exit(-1);
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "SDL audio subsystem initialized.\n");
|
||||
|
||||
if (flags & TFB_SOUNDFLAGS_HQAUDIO)
|
||||
{
|
||||
audio_quality = MIX_QUALITY_HIGH;
|
||||
audio_rate = 44100;
|
||||
audio_bufsize = 2048;
|
||||
}
|
||||
else if (flags & TFB_SOUNDFLAGS_LQAUDIO)
|
||||
{
|
||||
audio_quality = MIX_QUALITY_LOW;
|
||||
audio_rate = 22050;
|
||||
audio_bufsize = 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_quality = MIX_QUALITY_DEFAULT;
|
||||
audio_rate = 44100;
|
||||
audio_bufsize = 2048;
|
||||
}
|
||||
|
||||
fprintf (stderr, "Initializing internal Mixer for SDL_audio.\n");
|
||||
if (!mixSDL_OpenAudio(audio_rate, MIX_FORMAT_STEREO16, audio_bufsize))
|
||||
fprintf (stderr, "Initializing MixSDL mixer.\n");
|
||||
if (!mixSDL_OpenAudio(audio_rate, MIX_FORMAT_STEREO16,
|
||||
audio_bufsize, audio_quality))
|
||||
{
|
||||
fprintf (stderr, "Unable to open audio: %x, %s\n",
|
||||
mixSDL_GetError (), SDL_GetError ());
|
||||
exit (-1);
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "Mixer for SDL_audio initialized.\n");
|
||||
fprintf (stderr, "MixSDL Mixer initialized.\n");
|
||||
|
||||
atexit (TFB_UninitSound);
|
||||
|
||||
@@ -98,6 +143,8 @@ TFB_mixSDL_InitSound (int driver, int flags)
|
||||
StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024,
|
||||
"audio stream decoder");
|
||||
|
||||
current_driver = driver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -128,3 +175,170 @@ TFB_mixSDL_UninitSound (void)
|
||||
SoundDecoder_Uninit ();
|
||||
mixSDL_CloseAudio ();
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* NoSound driver for MixSDL
|
||||
*/
|
||||
|
||||
int
|
||||
TFB_NoSound_InitSound (int driver, int flags)
|
||||
{
|
||||
int i;
|
||||
uint32 audio_rate, audio_channels, audio_bufsize, audio_format;
|
||||
TFB_DecoderFormats formats =
|
||||
{
|
||||
0, 0, /* do not care about endianness */
|
||||
MIX_FORMAT_MONO8, MIX_FORMAT_STEREO8,
|
||||
MIX_FORMAT_MONO16, MIX_FORMAT_STEREO16
|
||||
};
|
||||
|
||||
if (flags & TFB_SOUNDFLAGS_HQAUDIO)
|
||||
{
|
||||
audio_rate = 44100;
|
||||
audio_bufsize = 2048;
|
||||
}
|
||||
else if (flags & TFB_SOUNDFLAGS_LQAUDIO)
|
||||
{
|
||||
audio_rate = 22050;
|
||||
audio_bufsize = 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_rate = 44100;
|
||||
audio_bufsize = 2048;
|
||||
}
|
||||
|
||||
fprintf (stderr, "Initializing MixSDL mixer.\n");
|
||||
mixSDL_UseDriver (&NoSound_driver, MIX_DRIVER_FAKE_ALL);
|
||||
if (!mixSDL_OpenAudio (audio_rate, MIX_FORMAT_STEREO16,
|
||||
audio_bufsize, MIX_QUALITY_DEFAULT))
|
||||
{
|
||||
fprintf (stderr, "Unable to open audio: %x, %s\n",
|
||||
mixSDL_GetError (), SDL_GetError ());
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, "MixSDL mixer initialized.\n");
|
||||
|
||||
atexit (TFB_UninitSound);
|
||||
|
||||
mixSDL_QuerySpec (&audio_rate, &audio_format, &audio_channels);
|
||||
fprintf (stderr, " opened 'fake' "
|
||||
"at %d Hz %d bit %s, %d samples audio buffer\n",
|
||||
audio_rate, audio_format & 0xFF,
|
||||
audio_channels > 1 ? "stereo" : "mono", audio_bufsize);
|
||||
|
||||
fprintf (stderr, "Initializing sound decoders.\n");
|
||||
SoundDecoder_Init (flags, &formats);
|
||||
fprintf (stderr, "Sound decoders initialized.\n");
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
mixSDL_GenSources (1, &soundSource[i].handle);
|
||||
|
||||
soundSource[i].sample = NULL;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
soundSource[i].stream_mutex = CreateMutex ();
|
||||
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);
|
||||
|
||||
StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024,
|
||||
"audio stream decoder");
|
||||
|
||||
current_driver = driver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_NoSound_UninitSound (void)
|
||||
{
|
||||
TFB_mixSDL_UninitSound ();
|
||||
}
|
||||
|
||||
int
|
||||
NoSound_PlaybackTaskFunc (void *data)
|
||||
{
|
||||
Task task = (Task)data;
|
||||
uint8 *stream;
|
||||
uint32 entryTime;
|
||||
sint32 period, delay;
|
||||
|
||||
stream = (uint8 *) HMalloc (NoSound_spec.size);
|
||||
period = 1000 * NoSound_spec.samples / NoSound_spec.freq;
|
||||
|
||||
while (!Task_ReadState (task, TASK_EXIT))
|
||||
{
|
||||
entryTime = SDL_GetTicks ();
|
||||
|
||||
if (!NoSound_Paused)
|
||||
{
|
||||
NoSound_spec.callback (NoSound_spec.userdata,
|
||||
stream, NoSound_spec.size);
|
||||
}
|
||||
|
||||
delay = period - (SDL_GetTicks () - entryTime);
|
||||
if (delay > 0)
|
||||
SDL_Delay (delay);
|
||||
}
|
||||
|
||||
FinishTask (task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
NoSound_GetDriverName ()
|
||||
{
|
||||
return "NoSound";
|
||||
}
|
||||
|
||||
static const char*
|
||||
NoSound_GetError ()
|
||||
{
|
||||
return NoSound_ErrorStr;
|
||||
}
|
||||
|
||||
static int
|
||||
NoSound_OpenAudio (void *desired, void *obtained)
|
||||
{
|
||||
/* we accept anything - copy the format verbatim */
|
||||
memcpy (&NoSound_spec, desired, sizeof (SDL_AudioSpec));
|
||||
/* calculate the requested PCM-buffer size and silence val */
|
||||
NoSound_spec.size = (NoSound_spec.format & 0x003f) / 8
|
||||
* NoSound_spec.channels * NoSound_spec.samples;
|
||||
NoSound_spec.silence = ((NoSound_spec.format >> 8) & 0x80) ^ 0x80;
|
||||
|
||||
memcpy (obtained, &NoSound_spec, sizeof (SDL_AudioSpec));
|
||||
|
||||
NoSound_PlaybackTask = AssignTask (NoSound_PlaybackTaskFunc, 1024,
|
||||
"nosound audio playback");
|
||||
if (!NoSound_PlaybackTask)
|
||||
{
|
||||
NoSound_ErrorStr = "Could not start Playback Task";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
NoSound_CloseAudio (void)
|
||||
{
|
||||
if (NoSound_PlaybackTask)
|
||||
{
|
||||
ConcludeTask (NoSound_PlaybackTask);
|
||||
NoSound_PlaybackTask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NoSound_PauseAudio (int pause_on)
|
||||
{
|
||||
NoSound_Paused = pause_on;
|
||||
}
|
||||
|
||||
@@ -38,8 +38,6 @@ TFB_alInitSound (int driver, int flags)
|
||||
};
|
||||
|
||||
fprintf (stderr, "Initializing OpenAL.\n");
|
||||
atexit (TFB_UninitSound);
|
||||
|
||||
#ifdef WIN32
|
||||
alcDevice = alcOpenDevice ((ALubyte*)"DirectSound3D");
|
||||
#else
|
||||
@@ -49,9 +47,11 @@ TFB_alInitSound (int driver, int flags)
|
||||
if (!alcDevice)
|
||||
{
|
||||
fprintf (stderr,"Couldn't initialize OpenAL: %d\n", alcGetError (NULL));
|
||||
exit (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
atexit (TFB_UninitSound);
|
||||
|
||||
alcContext = alcCreateContext (alcDevice, NULL);
|
||||
if (!alcContext)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Mixer abstraction layer for MixSDL
|
||||
/* Mixer abstraction layer
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OPENAL
|
||||
@@ -32,6 +32,13 @@ unsigned int TFBSOUND_FORMAT_STEREO16;
|
||||
unsigned int TFBSOUND_FORMAT_STEREO8;
|
||||
unsigned int TFBSOUND_FORMAT_MONO8;
|
||||
|
||||
int TFB_mixSDL_InitSound (int driver, int flags);
|
||||
int TFB_NoSound_InitSound (int driver, int flags);
|
||||
#ifdef HAVE_OPENAL
|
||||
int TFB_alInitSound (int driver, int flags);
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************
|
||||
* General interface
|
||||
*/
|
||||
@@ -241,9 +248,10 @@ TFBSound_ConvertBuffer (uint32 srcfmt, void* srcdata, uint32 srcsize,
|
||||
int
|
||||
TFB_choose_InitSound (int driver, int flags)
|
||||
{
|
||||
SoundDriver = driver;
|
||||
|
||||
if (driver == TFB_SOUNDDRIVER_OPENAL)
|
||||
{
|
||||
SoundDriver = driver;
|
||||
tfb_enum_lookup[TFBSOUND_GAIN] = AL_GAIN;
|
||||
tfb_enum_lookup[TFBSOUND_BUFFER] = AL_BUFFER;
|
||||
tfb_enum_lookup[TFBSOUND_SOURCE_STATE] = AL_SOURCE_STATE;
|
||||
@@ -262,7 +270,7 @@ TFB_choose_InitSound (int driver, int flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundDriver = driver;
|
||||
/* NoSound uses MixSDL, common values */
|
||||
tfb_enum_lookup[TFBSOUND_GAIN] = MIX_GAIN;
|
||||
tfb_enum_lookup[TFBSOUND_BUFFER] = MIX_BUFFER;
|
||||
tfb_enum_lookup[TFBSOUND_SOURCE_STATE] = MIX_SOURCE_STATE;
|
||||
@@ -277,7 +285,11 @@ TFB_choose_InitSound (int driver, int flags)
|
||||
TFBSOUND_FORMAT_STEREO16 = MIX_FORMAT_STEREO16;
|
||||
TFBSOUND_FORMAT_MONO8 = MIX_FORMAT_MONO8;
|
||||
TFBSOUND_FORMAT_STEREO8 = MIX_FORMAT_STEREO8;
|
||||
return (TFB_mixSDL_InitSound (driver, flags));
|
||||
|
||||
if (driver == TFB_SOUNDDRIVER_MIXSDL)
|
||||
return (TFB_mixSDL_InitSound (driver, flags));
|
||||
else
|
||||
return (TFB_NoSound_InitSound (driver, flags));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Simple mixer for use with SDL_audio
|
||||
/* Mixer abstraction layer
|
||||
*/
|
||||
|
||||
#ifndef SOUNDCHOOSER_H
|
||||
@@ -33,18 +33,6 @@
|
||||
#include "types.h"
|
||||
|
||||
|
||||
int TFB_mixSDL_InitSound (int driver, int flags);
|
||||
#ifdef HAVE_OPENAL
|
||||
int TFB_choose_InitSound (int driver, int flags);
|
||||
int TFB_alInitSound (int driver, int flags);
|
||||
#endif
|
||||
|
||||
void TFB_mixSDL_UninitSound (void);
|
||||
#ifdef HAVE_OPENAL
|
||||
void TFB_alUninitSound (void);
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Interface Types
|
||||
*/
|
||||
|
||||
@@ -32,6 +32,21 @@ static Task FadeTask;
|
||||
static SIZE TTotal;
|
||||
static SIZE volume_end;
|
||||
|
||||
|
||||
int TFB_mixSDL_InitSound (int driver, int flags);
|
||||
int TFB_NoSound_InitSound (int driver, int flags);
|
||||
#ifdef HAVE_OPENAL
|
||||
int TFB_choose_InitSound (int driver, int flags);
|
||||
int TFB_alInitSound (int driver, int flags);
|
||||
#endif
|
||||
|
||||
void TFB_mixSDL_UninitSound (void);
|
||||
void TFB_NoSound_UninitSound (void);
|
||||
#ifdef HAVE_OPENAL
|
||||
void TFB_alUninitSound (void);
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
fade_task (void *data)
|
||||
{
|
||||
@@ -93,28 +108,54 @@ FadeMusic (BYTE end_vol, SIZE TimeInterval)
|
||||
int
|
||||
TFB_InitSound (int driver, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_OPENAL
|
||||
return (TFB_choose_InitSound (driver, flags));
|
||||
ret = TFB_choose_InitSound (driver, flags);
|
||||
#else
|
||||
if (driver == TFB_SOUNDDRIVER_OPENAL)
|
||||
SoundDriver = driver;
|
||||
if (SoundDriver == TFB_SOUNDDRIVER_OPENAL)
|
||||
{
|
||||
fprintf (stderr, "OpenAL driver not compiled in, so using MixSDL\n");
|
||||
driver = TFB_SOUNDDRIVER_MIXSDL;
|
||||
SoundDriver = TFB_SOUNDDRIVER_MIXSDL;
|
||||
}
|
||||
return (TFB_mixSDL_InitSound (driver, flags));
|
||||
if (SoundDriver == TFB_SOUNDDRIVER_MIXSDL)
|
||||
ret = TFB_mixSDL_InitSound (SoundDriver, flags);
|
||||
else
|
||||
ret = TFB_NoSound_InitSound (SoundDriver, 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 (-1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_UninitSound (void)
|
||||
{
|
||||
#ifdef HAVE_OPENAL
|
||||
if (SoundDriver == TFB_SOUNDDRIVER_OPENAL)
|
||||
switch (SoundDriver)
|
||||
{
|
||||
case TFB_SOUNDDRIVER_OPENAL:
|
||||
#ifdef HAVE_OPENAL
|
||||
TFB_alUninitSound ();
|
||||
else
|
||||
TFB_mixSDL_UninitSound ();
|
||||
#else
|
||||
TFB_mixSDL_UninitSound ();
|
||||
fprintf (stderr, "TFB_UninitSound(): driver is set to OpenAL"
|
||||
"while OpenAL driver is not compiled in\n");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case TFB_SOUNDDRIVER_MIXSDL:
|
||||
TFB_mixSDL_UninitSound ();
|
||||
break;
|
||||
|
||||
case TFB_SOUNDDRIVER_NOSOUND:
|
||||
TFB_NoSound_UninitSound ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
enum
|
||||
{
|
||||
TFB_SOUNDDRIVER_MIXSDL,
|
||||
TFB_SOUNDDRIVER_NOSOUND,
|
||||
TFB_SOUNDDRIVER_OPENAL
|
||||
};
|
||||
extern int SoundDriver;
|
||||
|
||||
Reference in New Issue
Block a user