summaryrefslogtreecommitdiff
path: root/src/i_sdlsound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i_sdlsound.c')
-rw-r--r--src/i_sdlsound.c126
1 files changed, 79 insertions, 47 deletions
diff --git a/src/i_sdlsound.c b/src/i_sdlsound.c
index 2b30d2b6..2c574222 100644
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
//
// Copyright(C) 1993-1996 Id Software, Inc.
-// Copyright(C) 2005 Simon Howard
+// Copyright(C) 2005-8 Simon Howard
// Copyright(C) 2008 David Flater
//
// This program is free software; you can redistribute it and/or
@@ -42,7 +42,6 @@
#include "i_sound.h"
#include "i_system.h"
#include "m_argv.h"
-#include "sounds.h"
#include "w_wad.h"
#include "z_zone.h"
@@ -53,7 +52,6 @@
static boolean sound_initialised = false;
-static Mix_Chunk sound_chunks[NUMSFX];
static sfxinfo_t *channels_playing[NUM_CHANNELS];
static int mixer_freq;
@@ -64,6 +62,27 @@ static uint32_t (*ExpandSoundData)(byte *data, int samplerate, int length,
int use_libsamplerate = 0;
+// The driver_data field is used to point to a Mix_Chunk structure that
+// has data about the expanded version of the sound effect. These are
+// allocated on demand.
+
+static Mix_Chunk *GetSoundChunk(sfxinfo_t *sfxinfo)
+{
+ Mix_Chunk *chunk;
+
+ // No chunk for this structure yet? Allocate it.
+
+ if (sfxinfo->driver_data == NULL)
+ {
+ chunk = Z_Malloc(sizeof(Mix_Chunk), PU_STATIC, NULL);
+ chunk->abuf = NULL;
+ chunk->allocated = 0;
+ sfxinfo->driver_data = chunk;
+ }
+
+ return sfxinfo->driver_data;
+}
+
// When a sound stops, check if it is still playing. If it is not,
// we can mark the sound data as CACHE to be freed back for other
// means.
@@ -72,7 +91,7 @@ static void ReleaseSoundOnChannel(int channel)
{
int i;
sfxinfo_t *sfxinfo = channels_playing[channel];
- int id;
+ Mix_Chunk *chunk;
if (sfxinfo == NULL)
{
@@ -90,9 +109,9 @@ static void ReleaseSoundOnChannel(int channel)
}
// Not used on any channel, and can be safely released
- // TODO
- id = sfxinfo - S_sfx;
- Z_ChangeTag(sound_chunks[id].abuf, PU_CACHE);
+
+ chunk = GetSoundChunk(sfxinfo);
+ Z_ChangeTag(chunk->abuf, PU_CACHE);
}
#ifdef HAVE_LIBSAMPLERATE
@@ -356,12 +375,12 @@ static uint32_t ExpandSoundData_SDL(byte *data,
static boolean CacheSFX(sfxinfo_t *sfxinfo)
{
+ Mix_Chunk *chunk;
int lumpnum;
unsigned int lumplen;
int samplerate;
int clipped;
unsigned int length;
- int sound_id;
byte *data;
// need to load the sound
@@ -394,23 +413,20 @@ static boolean CacheSFX(sfxinfo_t *sfxinfo)
}
// Sample rate conversion
- // DWF 2008-02-10: sound_chunks[sound].alen and abuf are determined
+ // DWF 2008-02-10: chunk->alen and abuf are determined
// by ExpandSoundData.
- sound_id = sfxinfo - S_sfx;
- sound_chunks[sound_id].allocated = 1;
- sound_chunks[sound_id].volume = MIX_MAX_VOLUME;
+ chunk = GetSoundChunk(sfxinfo);
+ chunk->allocated = 1;
+ chunk->volume = MIX_MAX_VOLUME;
- clipped = ExpandSoundData(data + 8,
- samplerate,
- length,
- &sound_chunks[sound_id]);
+ clipped = ExpandSoundData(data + 8, samplerate, length, chunk);
if (clipped)
{
- fprintf(stderr, "Sound %d: clipped %u samples (%0.2f %%)\n",
- sound_id, clipped,
- 400.0 * clipped / sound_chunks[sound_id].alen);
+ fprintf(stderr, "Sound '%s': clipped %u samples (%0.2f %%)\n",
+ sfxinfo->name, clipped,
+ 400.0 * clipped / chunk->alen);
}
// don't need the original lump any more
@@ -424,14 +440,22 @@ static boolean CacheSFX(sfxinfo_t *sfxinfo)
// Preload all the sound effects - stops nasty ingame freezes
-static void I_PrecacheSounds(void)
+static void I_SDL_PrecacheSounds(sfxinfo_t *sounds, int num_sounds)
{
+ Mix_Chunk *chunk;
char namebuf[9];
int i;
- printf("I_PrecacheSounds: Precaching all sound effects..");
+ // Don't need to precache the sounds unless we are using libsamplerate.
+
+ if (use_libsamplerate == 0)
+ {
+ return;
+ }
+
+ printf("I_SDL_PrecacheSounds: Precaching all sound effects..");
- for (i=sfx_pistol; i<NUMSFX; ++i)
+ for (i=0; i<num_sounds; ++i)
{
if ((i % 6) == 0)
{
@@ -439,17 +463,18 @@ static void I_PrecacheSounds(void)
fflush(stdout);
}
- sprintf(namebuf, "ds%s", DEH_String(S_sfx[i].name));
+ sprintf(namebuf, "ds%s", DEH_String(sounds[i].name));
- S_sfx[i].lumpnum = W_CheckNumForName(namebuf);
+ sounds[i].lumpnum = W_CheckNumForName(namebuf);
- if (S_sfx[i].lumpnum != -1)
+ if (sounds[i].lumpnum != -1)
{
- CacheSFX(&S_sfx[i]);
+ CacheSFX(&sounds[i]);
+ chunk = GetSoundChunk(&sounds[i]);
- if (sound_chunks[i].abuf != NULL)
+ if (chunk->abuf != NULL)
{
- Z_ChangeTag(sound_chunks[i].abuf, PU_CACHE);
+ Z_ChangeTag(chunk->abuf, PU_CACHE);
}
}
}
@@ -457,27 +482,40 @@ static void I_PrecacheSounds(void)
printf("\n");
}
+#else
+
+static void I_SDL_PrecacheSounds(sfxinfo_t *sounds, int num_sounds)
+{
+ // no-op
+}
+
#endif
-static Mix_Chunk *GetSFXChunk(sfxinfo_t *sfxinfo)
+// Load a SFX chunk into memory and ensure that it is locked.
+
+static boolean LockSound(sfxinfo_t *sfxinfo)
{
- int sound_id;
+ Mix_Chunk *chunk;
- sound_id = sfxinfo - S_sfx;
+ chunk = GetSoundChunk(sfxinfo);
- if (sound_chunks[sound_id].abuf == NULL)
+ if (chunk->abuf == NULL)
{
+ // Not yet loaded, or has been freed. Load the sound data.
+
if (!CacheSFX(sfxinfo))
- return NULL;
+ {
+ return false;
+ }
}
else
{
// don't free the sound while it is playing!
- Z_ChangeTag(sound_chunks[sound_id].abuf, PU_STATIC);
+ Z_ChangeTag(chunk->abuf, PU_STATIC);
}
- return &sound_chunks[sound_id];
+ return true;
}
@@ -540,13 +578,13 @@ static int I_SDL_StartSound(sfxinfo_t *sfxinfo, int channel, int vol, int sep)
// Get the sound data
- chunk = GetSFXChunk(sfxinfo);
-
- if (chunk == NULL)
+ if (!LockSound(sfxinfo))
{
- return -1;
+ return -1;
}
+ chunk = GetSoundChunk(sfxinfo);
+
// play sound
Mix_PlayChannelTimed(channel, chunk, 0, -1);
@@ -628,14 +666,9 @@ static boolean I_SDL_InitSound(void)
// No sounds yet
- for (i=0; i<NUMSFX; ++i)
- {
- sound_chunks[i].abuf = NULL;
- }
-
for (i=0; i<NUM_CHANNELS; ++i)
{
- channels_playing[i] = sfx_None;
+ channels_playing[i] = NULL;
}
if (SDL_Init(SDL_INIT_AUDIO) < 0)
@@ -664,8 +697,6 @@ static boolean I_SDL_InitSound(void)
}
ExpandSoundData = ExpandSoundData_SRC;
-
- I_PrecacheSounds();
}
#else
if (use_libsamplerate != 0)
@@ -707,5 +738,6 @@ sound_module_t sound_sdl_module =
I_SDL_StartSound,
I_SDL_StopSound,
I_SDL_SoundIsPlaying,
+ I_SDL_PrecacheSounds,
};