mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2024-11-10 07:21:58 +00:00
snd_dma.c: added SNDDMA_LockBuffer() as a new API, needed for, well, proper buffer
locking. removed simsound. removed unused S_AmbientOff() and S_AmbientOn(). other multiple cleanups and fixes. snd_sdl.c: replaced the old broken implementation which used to cause LRU failures with the one adapted from the uhexen2 project. sound.h: added missing prototypes, including the new SNDDMA_LockBuffer(). git-svn-id: http://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@6 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
e40351322e
commit
4ca694aad1
3 changed files with 281 additions and 215 deletions
240
Quake/snd_dma.c
240
Quake/snd_dma.c
|
@ -35,15 +35,13 @@ void S_StopAllSoundsC(void);
|
|||
// =======================================================================
|
||||
|
||||
channel_t channels[MAX_CHANNELS];
|
||||
int total_channels;
|
||||
int total_channels;
|
||||
|
||||
int snd_blocked = 0;
|
||||
static qboolean snd_ambient = 1;
|
||||
qboolean snd_initialized = false;
|
||||
int snd_blocked = 0;
|
||||
qboolean snd_initialized = false;
|
||||
|
||||
// pointer should go away
|
||||
volatile dma_t *shm = 0;
|
||||
volatile dma_t sn;
|
||||
volatile dma_t *shm = NULL;
|
||||
volatile dma_t sn;
|
||||
|
||||
vec3_t listener_origin;
|
||||
vec3_t listener_forward;
|
||||
|
@ -51,17 +49,17 @@ vec3_t listener_right;
|
|||
vec3_t listener_up;
|
||||
vec_t sound_nominal_clip_dist=1000.0;
|
||||
|
||||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
|
||||
|
||||
#define MAX_SFX 512
|
||||
sfx_t *known_sfx; // hunk allocated [MAX_SFX]
|
||||
int num_sfx;
|
||||
int num_sfx;
|
||||
|
||||
sfx_t *ambient_sfx[NUM_AMBIENTS];
|
||||
|
||||
int sound_started=0;
|
||||
qboolean sound_started = false;
|
||||
|
||||
cvar_t bgmvolume = {"bgmvolume", "1", true};
|
||||
cvar_t volume = {"volume", "0.7", true};
|
||||
|
@ -78,33 +76,6 @@ cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", true};
|
|||
cvar_t sndspeed = {"sndspeed", "11025"};
|
||||
|
||||
|
||||
// ====================================================================
|
||||
// User-setable variables
|
||||
// ====================================================================
|
||||
|
||||
|
||||
//
|
||||
// Fake dma is a synchronous faking of the DMA progress used for
|
||||
// isolating performance in the renderer. The fakedma_updates is
|
||||
// number of times S_Update() is called per second.
|
||||
//
|
||||
|
||||
qboolean fakedma = false;
|
||||
int fakedma_updates = 15;
|
||||
|
||||
|
||||
void S_AmbientOff (void)
|
||||
{
|
||||
snd_ambient = false;
|
||||
}
|
||||
|
||||
|
||||
void S_AmbientOn (void)
|
||||
{
|
||||
snd_ambient = true;
|
||||
}
|
||||
|
||||
|
||||
void S_SoundInfo_f(void)
|
||||
{
|
||||
if (!sound_started || !shm)
|
||||
|
@ -113,14 +84,13 @@ void S_SoundInfo_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
Con_Printf("%5d stereo\n", shm->channels - 1);
|
||||
Con_Printf("%5d samples\n", shm->samples);
|
||||
Con_Printf("%5d samplepos\n", shm->samplepos);
|
||||
Con_Printf("%5d samplebits\n", shm->samplebits);
|
||||
Con_Printf("%5d submission_chunk\n", shm->submission_chunk);
|
||||
Con_Printf("%5d speed\n", shm->speed);
|
||||
Con_Printf("0x%x dma buffer\n", shm->buffer);
|
||||
Con_Printf("%d bit, %s, %d Hz\n", shm->samplebits,
|
||||
(shm->channels == 2) ? "stereo" : "mono", shm->speed);
|
||||
Con_Printf("%5d samples\n", shm->samples);
|
||||
Con_Printf("%5d samplepos\n", shm->samplepos);
|
||||
Con_Printf("%5d submission_chunk\n", shm->submission_chunk);
|
||||
Con_Printf("%5d total_channels\n", total_channels);
|
||||
Con_Printf("%p dma buffer\n", shm->buffer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,21 +107,19 @@ void S_Startup (void)
|
|||
if (!snd_initialized)
|
||||
return;
|
||||
|
||||
if (!fakedma)
|
||||
sound_started = SNDDMA_Init();
|
||||
|
||||
if (!sound_started)
|
||||
{
|
||||
rc = SNDDMA_Init();
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
Con_Printf("S_Startup: SNDDMA_Init failed.\n");
|
||||
#endif
|
||||
sound_started = 0;
|
||||
return;
|
||||
}
|
||||
Con_Printf("Failed initializing sound\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("Audio: %d bit, %s, %d Hz\n",
|
||||
shm->samplebits,
|
||||
(shm->channels == 2) ? "stereo" : "mono",
|
||||
shm->speed);
|
||||
}
|
||||
|
||||
sound_started = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,23 +130,11 @@ S_Init
|
|||
*/
|
||||
void S_Init (void)
|
||||
{
|
||||
if (COM_CheckParm("-nosound"))
|
||||
if (snd_initialized)
|
||||
{
|
||||
Con_Printf("Sound is already initialized\n");
|
||||
return;
|
||||
|
||||
//johnfitz -- clean up init readouts
|
||||
Con_Printf("Sound Initialization\n");
|
||||
//Con_Printf("------------- Init Sound -------------\n");
|
||||
//Con_Printf("%cSound Init\n", 2);
|
||||
//johnfitz
|
||||
|
||||
if (COM_CheckParm("-simsound"))
|
||||
fakedma = true;
|
||||
|
||||
Cmd_AddCommand("play", S_Play);
|
||||
Cmd_AddCommand("playvol", S_PlayVol);
|
||||
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
|
||||
Cmd_AddCommand("soundlist", S_SoundList);
|
||||
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
||||
}
|
||||
|
||||
Cvar_RegisterVariable(&nosound, NULL);
|
||||
Cvar_RegisterVariable(&volume, NULL);
|
||||
|
@ -191,7 +147,18 @@ void S_Init (void)
|
|||
Cvar_RegisterVariable(&snd_noextraupdate, NULL);
|
||||
Cvar_RegisterVariable(&snd_show, NULL);
|
||||
Cvar_RegisterVariable(&_snd_mixahead, NULL);
|
||||
Cvar_RegisterVariable(&sndspeed, NULL);
|
||||
Cvar_RegisterVariable(&sndspeed, NULL);
|
||||
|
||||
if (COM_CheckParm("-nosound"))
|
||||
return;
|
||||
|
||||
Con_Printf("Sound Initialization\n");
|
||||
|
||||
Cmd_AddCommand("play", S_Play);
|
||||
Cmd_AddCommand("playvol", S_PlayVol);
|
||||
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
|
||||
Cmd_AddCommand("soundlist", S_SoundList);
|
||||
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
||||
|
||||
if (COM_CheckParm("-sndspeed"))
|
||||
{
|
||||
|
@ -204,38 +171,18 @@ void S_Init (void)
|
|||
Con_Printf ("loading all sounds as 8bit\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
snd_initialized = true;
|
||||
|
||||
S_Startup ();
|
||||
|
||||
SND_InitScaletable ();
|
||||
|
||||
known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t");
|
||||
num_sfx = 0;
|
||||
|
||||
// create a piece of DMA memory
|
||||
snd_initialized = true;
|
||||
|
||||
if (fakedma)
|
||||
{
|
||||
shm = (void *) Hunk_AllocName(sizeof(*shm), "shm");
|
||||
shm->splitbuffer = 0;
|
||||
shm->samplebits = 16;
|
||||
shm->speed = 22050;
|
||||
shm->channels = 2;
|
||||
shm->samples = 32768;
|
||||
shm->samplepos = 0;
|
||||
shm->soundalive = true;
|
||||
shm->gamealive = true;
|
||||
shm->submission_chunk = 1;
|
||||
shm->buffer = Hunk_AllocName(1<<16, "shmbuf");
|
||||
}
|
||||
|
||||
Con_Printf ("Sound sampling rate: %i\n", shm->speed);
|
||||
S_Startup ();
|
||||
if (sound_started == 0)
|
||||
return;
|
||||
|
||||
// provides a tick sound until washed clean
|
||||
|
||||
// if (shm->buffer)
|
||||
// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging
|
||||
|
||||
|
@ -252,20 +199,16 @@ void S_Init (void)
|
|||
|
||||
void S_Shutdown(void)
|
||||
{
|
||||
|
||||
if (!sound_started)
|
||||
return;
|
||||
|
||||
if (shm)
|
||||
shm->gamealive = 0;
|
||||
|
||||
shm = 0;
|
||||
sound_started = 0;
|
||||
snd_blocked = 0;
|
||||
|
||||
if (!fakedma)
|
||||
{
|
||||
SNDDMA_Shutdown();
|
||||
}
|
||||
SNDDMA_Shutdown();
|
||||
shm = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -285,17 +228,19 @@ sfx_t *S_FindName (char *name)
|
|||
sfx_t *sfx;
|
||||
|
||||
if (!name)
|
||||
Sys_Error ("S_FindName: NULL\n");
|
||||
Sys_Error ("S_FindName: NULL");
|
||||
|
||||
if (Q_strlen(name) >= MAX_QPATH)
|
||||
Sys_Error ("Sound name too long: %s", name);
|
||||
|
||||
// see if already loaded
|
||||
for (i=0 ; i < num_sfx ; i++)
|
||||
{
|
||||
if (!Q_strcmp(known_sfx[i].name, name))
|
||||
{
|
||||
return &known_sfx[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (num_sfx == MAX_SFX)
|
||||
Sys_Error ("S_FindName: out of sfx_t");
|
||||
|
@ -406,12 +351,8 @@ void SND_Spatialize(channel_t *ch)
|
|||
vec_t dist;
|
||||
vec_t lscale, rscale, scale;
|
||||
vec3_t source_vec;
|
||||
sfx_t *snd;
|
||||
/* unused -- kristian
|
||||
vec_t ldist, rdist;
|
||||
*/
|
||||
|
||||
// anything coming from the view entity will allways be full volume
|
||||
// anything coming from the view entity will always be full volume
|
||||
if (ch->entnum == cl.viewentity)
|
||||
{
|
||||
ch->leftvol = ch->master_vol;
|
||||
|
@ -420,12 +361,8 @@ void SND_Spatialize(channel_t *ch)
|
|||
}
|
||||
|
||||
// calculate stereo seperation and distance attenuation
|
||||
|
||||
snd = ch->sfx;
|
||||
VectorSubtract(ch->origin, listener_origin, source_vec);
|
||||
|
||||
dist = VectorNormalize(source_vec) * ch->dist_mult;
|
||||
|
||||
dot = DotProduct(listener_right, source_vec);
|
||||
|
||||
if (shm->channels == 1)
|
||||
|
@ -460,7 +397,6 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
|
|||
{
|
||||
channel_t *target_chan, *check;
|
||||
sfxcache_t *sc;
|
||||
int vol;
|
||||
int ch_idx;
|
||||
int skip;
|
||||
|
||||
|
@ -473,8 +409,6 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
|
|||
if (nosound.value)
|
||||
return;
|
||||
|
||||
vol = fvol*255;
|
||||
|
||||
// pick a channel to play on
|
||||
target_chan = SND_PickChannel(entnum, entchannel);
|
||||
if (!target_chan)
|
||||
|
@ -484,7 +418,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
|
|||
memset (target_chan, 0, sizeof(*target_chan));
|
||||
VectorCopy(origin, target_chan->origin);
|
||||
target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
|
||||
target_chan->master_vol = vol;
|
||||
target_chan->master_vol = (int) (fvol * 255);
|
||||
target_chan->entnum = entnum;
|
||||
target_chan->entchannel = entchannel;
|
||||
SND_Spatialize(target_chan);
|
||||
|
@ -520,7 +454,6 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
|
|||
target_chan->end -= skip;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,10 +483,12 @@ void S_StopAllSounds(qboolean clear)
|
|||
total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
|
||||
|
||||
for (i=0 ; i<MAX_CHANNELS ; i++)
|
||||
{
|
||||
if (channels[i].sfx)
|
||||
channels[i].sfx = NULL;
|
||||
}
|
||||
|
||||
Q_memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
|
||||
memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
|
||||
|
||||
if (clear)
|
||||
S_ClearBuffer ();
|
||||
|
@ -568,7 +503,11 @@ void S_ClearBuffer (void)
|
|||
{
|
||||
int clear;
|
||||
|
||||
if (!sound_started || !shm || !shm->buffer)
|
||||
if (!sound_started || !shm)
|
||||
return;
|
||||
|
||||
SNDDMA_LockBuffer ();
|
||||
if (! shm->buffer)
|
||||
return;
|
||||
|
||||
if (shm->samplebits == 8)
|
||||
|
@ -576,7 +515,9 @@ void S_ClearBuffer (void)
|
|||
else
|
||||
clear = 0;
|
||||
|
||||
Q_memset(shm->buffer, clear, shm->samples * shm->samplebits/8);
|
||||
memset(shm->buffer, clear, shm->samples * shm->samplebits / 8);
|
||||
|
||||
SNDDMA_Submit ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -636,9 +577,6 @@ void S_UpdateAmbientSounds (void)
|
|||
int ambient_channel;
|
||||
channel_t *chan;
|
||||
|
||||
if (!snd_ambient)
|
||||
return;
|
||||
|
||||
//johnfitz -- no ambients when disconnected
|
||||
if (cls.state != ca_connected)
|
||||
return;
|
||||
|
@ -737,8 +675,10 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
|
|||
// search for one
|
||||
combine = channels+MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;
|
||||
for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; j<i; j++, combine++)
|
||||
{
|
||||
if (combine->sfx == ch->sfx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == total_channels)
|
||||
{
|
||||
|
@ -755,8 +695,6 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -767,11 +705,13 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
|
|||
total = 0;
|
||||
ch = channels;
|
||||
for (i=0 ; i<total_channels; i++, ch++)
|
||||
{
|
||||
if (ch->sfx && (ch->leftvol || ch->rightvol) )
|
||||
{
|
||||
//Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
Con_Printf ("----(%i)----\n", total);
|
||||
}
|
||||
|
@ -824,12 +764,17 @@ void S_ExtraUpdate (void)
|
|||
|
||||
void S_Update_(void)
|
||||
{
|
||||
unsigned endtime;
|
||||
int samps;
|
||||
#if 1
|
||||
unsigned int endtime;
|
||||
int samps;
|
||||
|
||||
if (!sound_started || (snd_blocked > 0))
|
||||
return;
|
||||
|
||||
SNDDMA_LockBuffer ();
|
||||
if (! shm->buffer)
|
||||
return;
|
||||
|
||||
// Updates DMA time
|
||||
GetSoundtime();
|
||||
|
||||
|
@ -848,7 +793,32 @@ void S_Update_(void)
|
|||
|
||||
S_PaintChannels (endtime);
|
||||
|
||||
// SNDDMA_Submit ();
|
||||
SNDDMA_Submit ();
|
||||
#endif
|
||||
}
|
||||
|
||||
void S_BlockSound (void)
|
||||
{
|
||||
/* FIXME: do we really need the blocking at the
|
||||
* driver level?
|
||||
*/
|
||||
if (sound_started && ++snd_blocked == 1)
|
||||
{
|
||||
S_ClearBuffer ();
|
||||
if (shm)
|
||||
SNDDMA_BlockSound();
|
||||
}
|
||||
}
|
||||
|
||||
void S_UnblockSound (void)
|
||||
{
|
||||
if (!sound_started || !snd_blocked)
|
||||
return;
|
||||
if (--snd_blocked == 0)
|
||||
{
|
||||
SNDDMA_UnblockSound();
|
||||
S_ClearBuffer ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -932,7 +902,7 @@ void S_SoundList(void)
|
|||
}
|
||||
|
||||
|
||||
void S_LocalSound (char *sound)
|
||||
void S_LocalSound (char *name)
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
|
@ -941,10 +911,10 @@ void S_LocalSound (char *sound)
|
|||
if (!sound_started)
|
||||
return;
|
||||
|
||||
sfx = S_PrecacheSound (sound);
|
||||
sfx = S_PrecacheSound (name);
|
||||
if (!sfx)
|
||||
{
|
||||
Con_Printf ("S_LocalSound: can't cache %s\n", sound);
|
||||
Con_Printf ("S_LocalSound: can't cache %s\n", name);
|
||||
return;
|
||||
}
|
||||
S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1);
|
||||
|
|
240
Quake/snd_sdl.c
240
Quake/snd_sdl.c
|
@ -1,125 +1,207 @@
|
|||
/*
|
||||
Copyright (C) 1996-2001 Id Software, Inc.
|
||||
Copyright (C) 2002-2005 John Fitzgibbons and others
|
||||
Copyright (C) 2007-2008 Kristian Duske
|
||||
snd_sdl2.c
|
||||
SDL audio driver for Hexen II: Hammer of Thyrion, based on the
|
||||
implementations found in the quakeforge and quake3-icculus.org
|
||||
projects.
|
||||
|
||||
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.
|
||||
$Id: snd_sdl2.c,v 1.8 2010/01/23 12:01:23 sezero Exp $
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
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.
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor,
|
||||
Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// stolen from http://www.libsdl.org/projects/quake/ -- apologies, I don't know the author's name
|
||||
|
||||
#include <stdio.h>
|
||||
#include "quakedef.h"
|
||||
#include "SDL.h"
|
||||
|
||||
static dma_t the_shm;
|
||||
static int snd_inited;
|
||||
static int buffersize;
|
||||
|
||||
#define BUF_SIZE 512
|
||||
|
||||
static void paint_audio(void *unused, Uint8 *stream, int len)
|
||||
static void paint_audio (void *unused, Uint8 *stream, int len)
|
||||
{
|
||||
if ( shm ) {
|
||||
shm->buffer = stream;
|
||||
shm->samplepos += len/(shm->samplebits/8)/2;
|
||||
// Check for samplepos overflow?
|
||||
S_PaintChannels (shm->samplepos);
|
||||
int pos, tobufend;
|
||||
int len1, len2;
|
||||
|
||||
if (!shm)
|
||||
{ /* shouldn't happen, but just in case */
|
||||
memset(stream, 0, len);
|
||||
return;
|
||||
}
|
||||
|
||||
pos = (shm->samplepos * (shm->samplebits / 8));
|
||||
if (pos >= buffersize)
|
||||
shm->samplepos = pos = 0;
|
||||
|
||||
tobufend = buffersize - pos; /* bytes to buffer's end. */
|
||||
len1 = len;
|
||||
len2 = 0;
|
||||
|
||||
if (len1 > tobufend)
|
||||
{
|
||||
len1 = tobufend;
|
||||
len2 = len - len1;
|
||||
}
|
||||
|
||||
memcpy(stream, shm->buffer + pos, len1);
|
||||
|
||||
if (len2 <= 0)
|
||||
{
|
||||
shm->samplepos += (len1 / (shm->samplebits / 8));
|
||||
}
|
||||
else
|
||||
{ /* wraparound? */
|
||||
memcpy(stream + len1, shm->buffer, len2);
|
||||
shm->samplepos = (len2 / (shm->samplebits / 8));
|
||||
}
|
||||
|
||||
if (shm->samplepos >= buffersize)
|
||||
shm->samplepos = 0;
|
||||
}
|
||||
|
||||
qboolean SNDDMA_Init(void)
|
||||
qboolean SNDDMA_Init (void)
|
||||
{
|
||||
SDL_AudioSpec desired, obtained;
|
||||
int tmp, val;
|
||||
char drivername[128];
|
||||
|
||||
snd_inited = 0;
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1)
|
||||
{
|
||||
Con_Printf("Couldn't init SDL audio: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set up the desired format */
|
||||
desired.freq = sndspeed.value;
|
||||
if (loadas8bit.value) {
|
||||
desired.format = AUDIO_U8;
|
||||
} else {
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
desired.format = AUDIO_S16MSB;
|
||||
else
|
||||
desired.format = AUDIO_S16LSB;
|
||||
}
|
||||
desired.channels = 2;
|
||||
desired.samples = BUF_SIZE;
|
||||
desired.freq = tmp = sndspeed.value;
|
||||
desired.format = (loadas8bit.value) ? AUDIO_U8 : AUDIO_S16SYS;
|
||||
desired.channels = 2; /* = desired_channels; */
|
||||
if (desired.freq <= 11025)
|
||||
desired.samples = 256;
|
||||
else if (desired.freq <= 22050)
|
||||
desired.samples = 512;
|
||||
else if (desired.freq <= 44100)
|
||||
desired.samples = 1024;
|
||||
else
|
||||
desired.samples = 2048; /* shrug */
|
||||
desired.callback = paint_audio;
|
||||
desired.userdata = NULL;
|
||||
|
||||
/* Open the audio device */
|
||||
if ( SDL_OpenAudio(&desired, &obtained) < 0 ) {
|
||||
Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError());
|
||||
return 0;
|
||||
if (SDL_OpenAudio(&desired, &obtained) == -1)
|
||||
{
|
||||
Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError());
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make sure we can support the audio format */
|
||||
switch (obtained.format) {
|
||||
case AUDIO_U8:
|
||||
/* Supported */
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
case AUDIO_S16MSB:
|
||||
if ( ((obtained.format == AUDIO_S16LSB) &&
|
||||
(SDL_BYTEORDER == SDL_LIL_ENDIAN)) ||
|
||||
((obtained.format == AUDIO_S16MSB) &&
|
||||
(SDL_BYTEORDER == SDL_BIG_ENDIAN)) ) {
|
||||
/* Supported */
|
||||
break;
|
||||
}
|
||||
/* Unsupported, fall through */;
|
||||
default:
|
||||
/* Not supported -- force SDL to do our bidding */
|
||||
SDL_CloseAudio();
|
||||
if ( SDL_OpenAudio(&desired, NULL) < 0 ) {
|
||||
Con_Printf("Couldn't open SDL audio: %s\n",
|
||||
SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
memcpy(&obtained, &desired, sizeof(desired));
|
||||
break;
|
||||
switch (obtained.format)
|
||||
{
|
||||
case AUDIO_U8:
|
||||
case AUDIO_S16SYS:
|
||||
/* Supported */
|
||||
break;
|
||||
default:
|
||||
Con_Printf ("Unsupported audio format received (%u)\n", obtained.format);
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
return false;
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
memset ((void *) &sn, 0, sizeof(dma_t));
|
||||
shm = &sn;
|
||||
|
||||
/* Fill the audio DMA information block */
|
||||
shm = &the_shm;
|
||||
shm->splitbuffer = 0;
|
||||
shm->samplebits = (obtained.format & 0xFF);
|
||||
shm->samplebits = (obtained.format & 0xFF); /* first byte of format is bits */
|
||||
if (obtained.freq != tmp)
|
||||
Con_Printf ("Warning: Rate set (%d) didn't match requested rate (%d)!\n", obtained.freq, tmp);
|
||||
shm->speed = obtained.freq;
|
||||
shm->channels = obtained.channels;
|
||||
shm->samples = obtained.samples*shm->channels;
|
||||
tmp = (obtained.samples * obtained.channels) * 10;
|
||||
if (tmp & (tmp - 1))
|
||||
{ /* make it a power of two */
|
||||
val = 1;
|
||||
while (val < tmp)
|
||||
val <<= 1;
|
||||
|
||||
tmp = val;
|
||||
}
|
||||
shm->samples = tmp;
|
||||
shm->samplepos = 0;
|
||||
shm->submission_chunk = 1;
|
||||
shm->buffer = NULL;
|
||||
|
||||
snd_inited = 1;
|
||||
return 1;
|
||||
Con_Printf ("SDL audio spec : %d Hz, %d samples, %d channels\n",
|
||||
obtained.freq, obtained.samples, obtained.channels);
|
||||
if (SDL_AudioDriverName(drivername, sizeof(drivername)) == NULL)
|
||||
strcpy(drivername, "(UNKNOWN)");
|
||||
buffersize = shm->samples * (shm->samplebits / 8);
|
||||
Con_Printf ("SDL audio driver: %s, %d bytes buffer\n", drivername, buffersize);
|
||||
|
||||
shm->buffer = (unsigned char *) calloc (1, buffersize);
|
||||
if (!shm->buffer)
|
||||
{
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
shm = NULL;
|
||||
Con_Printf ("Failed allocating memory for SDL audio\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int SNDDMA_GetDMAPos(void)
|
||||
int SNDDMA_GetDMAPos (void)
|
||||
{
|
||||
return shm->samplepos;
|
||||
}
|
||||
|
||||
void SNDDMA_Shutdown(void)
|
||||
void SNDDMA_Shutdown (void)
|
||||
{
|
||||
if (snd_inited)
|
||||
if (shm)
|
||||
{
|
||||
Con_Printf ("Shutting down SDL sound\n");
|
||||
SDL_PauseAudio(1);
|
||||
SDL_LockAudio ();
|
||||
SDL_CloseAudio();
|
||||
snd_inited = 0;
|
||||
if (shm->buffer)
|
||||
free (shm->buffer);
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
shm->buffer = NULL;
|
||||
shm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SNDDMA_LockBuffer (void)
|
||||
{
|
||||
SDL_LockAudio ();
|
||||
}
|
||||
|
||||
void SNDDMA_Submit (void)
|
||||
{
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
|
||||
void SNDDMA_BlockSound (void)
|
||||
{
|
||||
SDL_PauseAudio(1);
|
||||
}
|
||||
|
||||
void SNDDMA_UnblockSound (void)
|
||||
{
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,9 @@ void S_ClearBuffer (void);
|
|||
void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
|
||||
void S_ExtraUpdate (void);
|
||||
|
||||
void S_BlockSound (void);
|
||||
void S_UnblockSound (void);
|
||||
|
||||
sfx_t *S_PrecacheSound (char *sample);
|
||||
void S_TouchSound (char *sample);
|
||||
void S_ClearPrecache (void);
|
||||
|
@ -125,6 +128,18 @@ int SNDDMA_GetDMAPos(void);
|
|||
// shutdown the DMA xfer.
|
||||
void SNDDMA_Shutdown(void);
|
||||
|
||||
/* validates & locks the dma buffer */
|
||||
void SNDDMA_LockBuffer(void);
|
||||
|
||||
/* unlocks the dma buffer / sends sound to the device */
|
||||
void SNDDMA_Submit(void);
|
||||
|
||||
/* blocks sound output upon window focus loss */
|
||||
void SNDDMA_BlockSound(void);
|
||||
|
||||
/* unblocks the output upon window focus gain */
|
||||
void SNDDMA_UnblockSound(void);
|
||||
|
||||
// ====================================================================
|
||||
// User-setable variables
|
||||
// ====================================================================
|
||||
|
@ -172,7 +187,6 @@ sfxcache_t *S_LoadSound (sfx_t *s);
|
|||
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
|
||||
|
||||
void SND_InitScaletable (void);
|
||||
void SNDDMA_Submit(void);
|
||||
|
||||
void S_AmbientOff (void);
|
||||
void S_AmbientOn (void);
|
||||
|
|
Loading…
Reference in a new issue