Use custom sound DMA instead of SDL for audio

This commit is contained in:
cypress 2023-09-11 11:19:31 -04:00
parent debcddf2cc
commit cfbf7f5098
10 changed files with 319 additions and 254 deletions

View file

@ -29,6 +29,7 @@ COMMON_OBJS = \
source/psp/input.o \ source/psp/input.o \
source/psp/main.o \ source/psp/main.o \
source/psp/math.o \ source/psp/math.o \
source/psp/sound.o \
source/psp/system.o \ source/psp/system.o \
source/psp/module.o \ source/psp/module.o \
source/psp/network.o \ source/psp/network.o \
@ -64,7 +65,6 @@ COMMON_OBJS = \
source/pr_cmds.o \ source/pr_cmds.o \
source/pr_edict.o \ source/pr_edict.o \
source/pr_exec.o \ source/pr_exec.o \
source/snd_sdl.o \
source/snd_dma.o \ source/snd_dma.o \
source/snd_mem.o \ source/snd_mem.o \
source/snd_mix.o \ source/snd_mix.o \
@ -108,14 +108,13 @@ HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO
OBJS = $(COMMON_OBJS) $(HARDWARE_VIDEO_ONLY_OBJS) OBJS = $(COMMON_OBJS) $(HARDWARE_VIDEO_ONLY_OBJS)
SDL_LIBS = -lSDL2 -lSDL2main -lGL
GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu -lpspvram GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu -lpspvram
AUDIO_LIBS = -lpspaudio -lpspmp3 source/psp/m33libs/libpspaudiocodec.a source/psp/m33libs/libpspkubridge.a AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspaudiocodec -lpspmp3 source/psp/m33libs/libpspkubridge.a
MISC_LIBS = -lpsppower -lpspmath -lpsphprm -ljpeg -lpng -lz MISC_LIBS = -lpsppower -lpspmath -lpsphprm -ljpeg -lpng -lz
NET_LIBS = -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl NET_LIBS = -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl
STD_LIBS = -lstdc++ -lm -lc STD_LIBS = -lstdc++ -lm -lc
LIBS = $(GPROF_LIBS) $(SDL_LIBS) $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) $(NET_LIBS) LIBS = $(GPROF_LIBS) $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) $(NET_LIBS)
CFLAGS = -ffast-math -O3 -Ofast -G0 -Wall $(GPROF_FLAGS) -Did386="0" -DPSP $(MODE) $(HARDWARE_VIDEO_ONLY_FLAGS) -DSWIZZLE32 -DPSP_MP3_HWDECODE -DFULLBRIGHT -DHL_RENDER -Wno-strict-aliasing -DPSP_VFPU CFLAGS = -ffast-math -O3 -Ofast -G0 -Wall $(GPROF_FLAGS) -Did386="0" -DPSP $(MODE) $(HARDWARE_VIDEO_ONLY_FLAGS) -DSWIZZLE32 -DPSP_MP3_HWDECODE -DFULLBRIGHT -DHL_RENDER -Wno-strict-aliasing -DPSP_VFPU
CXXFLAGS = -fno-rtti -Wcast-qual -Wno-write-strings -Wno-sign-compare -Wno-strict-aliasing CXXFLAGS = -fno-rtti -Wcast-qual -Wno-write-strings -Wno-sign-compare -Wno-strict-aliasing

View file

@ -29,6 +29,7 @@ COMMON_OBJS = \
source/psp/input.o \ source/psp/input.o \
source/psp/main.o \ source/psp/main.o \
source/psp/math.o \ source/psp/math.o \
source/psp/sound.o \
source/psp/system.o \ source/psp/system.o \
source/psp/module.o \ source/psp/module.o \
source/psp/network.o \ source/psp/network.o \
@ -64,7 +65,6 @@ COMMON_OBJS = \
source/pr_cmds.o \ source/pr_cmds.o \
source/pr_edict.o \ source/pr_edict.o \
source/pr_exec.o \ source/pr_exec.o \
source/snd_sdl.o \
source/snd_dma.o \ source/snd_dma.o \
source/snd_mem.o \ source/snd_mem.o \
source/snd_mix.o \ source/snd_mix.o \
@ -108,14 +108,13 @@ HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO
OBJS = $(COMMON_OBJS) $(HARDWARE_VIDEO_ONLY_OBJS) OBJS = $(COMMON_OBJS) $(HARDWARE_VIDEO_ONLY_OBJS)
SDL_LIBS = -lSDL2 -lSDL2main -lGL
GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu -lpspvram GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu -lpspvram
AUDIO_LIBS = -lpspaudio -lpspmp3 source/psp/m33libs/libpspaudiocodec.a source/psp/m33libs/libpspkubridge.a AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspaudiocodec -lpspmp3 source/psp/m33libs/libpspkubridge.a
MISC_LIBS = -lpsppower -lpspmath -lpsphprm -ljpeg -lpng -lz MISC_LIBS = -lpsppower -lpspmath -lpsphprm -ljpeg -lpng -lz
NET_LIBS = -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl NET_LIBS = -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl
STD_LIBS = -lstdc++ -lm -lc STD_LIBS = -lstdc++ -lm -lc
LIBS = $(GPROF_LIBS) $(SDL_LIBS) $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) $(NET_LIBS) LIBS = $(GPROF_LIBS) $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) $(NET_LIBS)
CFLAGS = -ffast-math -O3 -Ofast -G0 -Wall $(GPROF_FLAGS) -Did386="0" -DPSP $(MODE) $(HARDWARE_VIDEO_ONLY_FLAGS) -DSWIZZLE32 -DSLIM -DPSP_MP3_HWDECODE -DFULLBRIGHT -DHL_RENDER -Wno-strict-aliasing -DPSP_VFPU CFLAGS = -ffast-math -O3 -Ofast -G0 -Wall $(GPROF_FLAGS) -Did386="0" -DPSP $(MODE) $(HARDWARE_VIDEO_ONLY_FLAGS) -DSWIZZLE32 -DSLIM -DPSP_MP3_HWDECODE -DFULLBRIGHT -DHL_RENDER -Wno-strict-aliasing -DPSP_VFPU
CXXFLAGS = -fno-rtti -Wcast-qual -Wno-write-strings -Wno-sign-compare -Wno-strict-aliasing CXXFLAGS = -fno-rtti -Wcast-qual -Wno-write-strings -Wno-sign-compare -Wno-strict-aliasing

View file

@ -36,9 +36,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <pspge.h> #include <pspge.h>
#include <pspsysevent.h> #include <pspsysevent.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
extern "C" extern "C"
{ {
#include "../quakedef.h" #include "../quakedef.h"
@ -534,13 +531,6 @@ int user_main(SceSize argc, void* argp)
// Initialize the Common module. // Initialize the Common module.
InitExtModules (); InitExtModules ();
// Initialize SDL
if (SDL_Init(SDL_INIT_AUDIO) < 0)
{
Sys_Error("SDL2: Could not initialize!\n");
return 0;
}
ramClockSpeed = cpuClockSpeed = scePowerGetCpuClockFrequencyInt(); ramClockSpeed = cpuClockSpeed = scePowerGetCpuClockFrequencyInt();
busClockSpeed = scePowerGetBusClockFrequencyInt(); busClockSpeed = scePowerGetBusClockFrequencyInt();

View file

@ -23,4 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "module.h" #include "module.h"
// Set up the module info. // Set up the module info.
// Set up the module info.
PSP_MODULE_INFO("nzportable", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU);
PSP_HEAP_SIZE_KB(-1024); PSP_HEAP_SIZE_KB(-1024);

183
source/psp/sound.cpp Normal file
View file

@ -0,0 +1,183 @@
/*
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2007 Peter Mackay and Chris Swindle.
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.
*/
#include <pspaudiolib.h>
#include <pspdebug.h>
#include <pspkernel.h>
extern "C"
{
#include "../quakedef.h"
}
namespace quake
{
namespace sound
{
struct Sample
{
short left;
short right;
};
static const unsigned int channelCount = 2;
static const unsigned int inputBufferSize = 16384;
#if 1 //def NORMAL_MODE
static const unsigned int inputFrequency = 11025;
#else
static const unsigned int inputFrequency = 22050;
#endif
static const unsigned int outputFrequency = 44100;
static const unsigned int inputSamplesPerOutputSample = outputFrequency / inputFrequency;
static Sample inputBuffer[inputBufferSize];
static volatile unsigned int samplesRead;
static inline void copySamples(const Sample* first, const Sample* last, Sample* destination)
{
switch (inputSamplesPerOutputSample)
{
case 1:
memcpy(destination, first, (last - first) * sizeof(Sample));
break;
case 2:
for (const Sample* source = first; source != last; ++source)
{
const Sample sample = *source;
*destination++ = sample;
*destination++ = sample;
}
break;
case 4:
for (const Sample* source = first; source != last; ++source)
{
const Sample sample = *source;
*destination++ = sample;
*destination++ = sample;
*destination++ = sample;
*destination++ = sample;
}
break;
default:
break;
}
}
static void fillOutputBuffer(void* buffer, unsigned int samplesToWrite, void* userData)
{
// Where are we writing to?
Sample* const destination = static_cast<Sample*> (buffer);
// Where are we reading from?
const Sample* const firstSampleToRead = &inputBuffer[samplesRead];
// How many samples to read?
const unsigned int samplesToRead = samplesToWrite / inputSamplesPerOutputSample;
// Going to wrap past the end of the input buffer?
const unsigned int samplesBeforeEndOfInput = inputBufferSize - samplesRead;
if (samplesToRead > samplesBeforeEndOfInput)
{
// Yes, so write the first chunk from the end of the input buffer.
copySamples(
firstSampleToRead,
firstSampleToRead + samplesBeforeEndOfInput,
&destination[0]);
// Write the second chunk from the start of the input buffer.
const unsigned int samplesToReadFromBeginning = samplesToRead - samplesBeforeEndOfInput;
copySamples(
&inputBuffer[0],
&inputBuffer[samplesToReadFromBeginning],
&destination[samplesBeforeEndOfInput * inputSamplesPerOutputSample]);
}
else
{
// No wrapping, just copy.
copySamples(
firstSampleToRead,
firstSampleToRead + samplesToRead,
&destination[0]);
}
// Update the read offset.
samplesRead = (samplesRead + samplesToRead) % inputBufferSize;
}
}
}
using namespace quake;
using namespace quake::sound;
qboolean SNDDMA_Init(void)
{
// Set up Quake's audio.
shm = &sn;
shm->channels = channelCount;
shm->samplebits = 16;
shm->speed = inputFrequency;
shm->soundalive = qtrue;
shm->splitbuffer = qfalse;
shm->samples = inputBufferSize * channelCount;
shm->samplepos = 0;
shm->submission_chunk = 1;
shm->buffer = (unsigned char *) inputBuffer;
// Initialise the audio system. This initialises it for the CD audio module
// too.
pspAudioInit();
// Set the channel callback.
// Sound effects use channel 0, CD audio uses channel 1.
pspAudioSetChannelCallback(0, fillOutputBuffer, 0);
return qtrue;
}
void SNDDMA_Shutdown(void)
{
// Clear the mixing buffer so we don't get any noise during cleanup.
memset(inputBuffer, 0, sizeof(inputBuffer));
// Clear the channel callback.
pspAudioSetChannelCallback(0, 0, 0);
// Stop the audio system?
pspAudioEndPre();
// Insert a false delay so the thread can be cleaned up.
sceKernelDelayThread(50 * 1000);
// Shut down the audio system.
pspAudioEnd();
}
int SNDDMA_GetDMAPos(void)
{
return samplesRead * channelCount;
}
void SNDDMA_Submit(void)
{
}

View file

@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. See the GNU General Public License for more details.
@ -21,12 +21,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h" #include "quakedef.h"
void S_Play(void);
void S_PlayVol(void);
void S_SoundList(void); void S_Play_f(void);
void S_PlayVol_f(void);
void S_SoundList_f(void);
void S_Update_(); void S_Update_();
void S_StopAllSounds(qboolean clear); void S_StopAllSounds(qboolean clear);
void S_StopAllSoundsC(void); void S_StopAllSoundsC_f(void);
void S_VolumeDown_f (void); // Baker 3.60 - from JoeQuake 0.15
void S_VolumeUp_f (void); // Baker 3.60 - from JoeQuake 0.15
// ======================================================================= // =======================================================================
// Internal sound data & structures // Internal sound data & structures
@ -47,49 +51,43 @@ vec3_t listener_origin;
vec3_t listener_forward; vec3_t listener_forward;
vec3_t listener_right; vec3_t listener_right;
vec3_t listener_up; vec3_t listener_up;
vec_t sound_nominal_clip_dist=1000.0; vec_t sound_nominal_clip_dist=1500.0; // JPG - changed this from 1000 to 15000 (I'm 99% sure that's what it was in 1.06)
int soundtime; // sample PAIRS int soundtime; // sample PAIRS
int paintedtime; // sample PAIRS int paintedtime; // sample PAIRS
#define MAX_SFX 512
sfx_t *known_sfx; // hunk allocated [MAX_SFX] sfx_t *known_sfx; // hunk allocated [MAX_SFX]
int num_sfx; int num_sfx;
sfx_t *ambient_sfx[NUM_AMBIENTS]; sfx_t *ambient_sfx[NUM_AMBIENTS];
int desired_speed = 44100; //11025; int desired_speed = 11025;
int desired_bits = 16; int desired_bits = 16;
int sound_started=0; int sound_started=0;
cvar_t bgmvolume = {"bgmvolume", "1", true}; cvar_t bgmvolume = {"bgmvolume", "1", true};
cvar_t bgmtype = {"bgmtype", "cd", true}; // cd or none cvar_t bgmtype = {"bgmtype", "cd", true}; // cd or none
cvar_t volume = {"volume", "0.7", true}; cvar_t volume = {"volume", "0.7", true};
cvar_t nosound = {"nosound", "0"}; cvar_t nosound = {"nosound", "0"};
cvar_t precache = {"precache", "1"}; cvar_t precache = {"precache", "1"};
cvar_t loadas8bit = {"loadas8bit", "0"}; cvar_t loadas8bit = {"loadas8bit", "0"};
cvar_t bgmbuffer = {"bgmbuffer", "4096"}; cvar_t bgmbuffer = {"bgmbuffer", "4096"};
cvar_t ambient_level = {"ambient_level", "0.3"}; cvar_t ambient_level = {"ambient_level", "0.3", true}; // Baker 3.60 - Save to config
cvar_t ambient_fade = {"ambient_fade", "100"}; cvar_t ambient_fade = {"ambient_fade", "100"};
cvar_t snd_noextraupdate = {"snd_noextraupdate", "0"}; cvar_t snd_noextraupdate = {"snd_noextraupdate", "0"};
cvar_t snd_show = {"snd_show", "0"}; cvar_t snd_show = {"snd_show", "0"};
cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", true}; cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", true};
// ==================================================================== // ====================================================================
// User-setable variables // User-setable variables
// ==================================================================== // ====================================================================
//
// Fake dma is a synchronous faking of the DMA progress used for // Fake dma is a synchronous faking of the DMA progress used for
// isolating performance in the renderer. The fakedma_updates is // isolating performance in the renderer. The fakedma_updates is
// number of times S_Update() is called per second. // number of times S_Update() is called per second.
//
qboolean fakedma = false; qboolean fakedma = false;
int fakedma_updates = 15; int fakedma_updates = 15;
@ -114,7 +112,7 @@ void S_SoundInfo_f(void)
Con_Printf ("sound system not started\n"); Con_Printf ("sound system not started\n");
return; return;
} }
Con_Printf("%5d stereo\n", shm->channels - 1); Con_Printf("%5d stereo\n", shm->channels - 1);
Con_Printf("%5d samples\n", shm->samples); Con_Printf("%5d samples\n", shm->samples);
Con_Printf("%5d samplepos\n", shm->samplepos); Con_Printf("%5d samplepos\n", shm->samplepos);
@ -141,9 +139,7 @@ void S_Startup (void)
if (!fakedma) if (!fakedma)
{ {
rc = SNDDMA_Init(); if (!(rc = SNDDMA_Init()))
if (!rc)
{ {
Con_Printf("S_Startup: SNDDMA_Init failed.\n"); Con_Printf("S_Startup: SNDDMA_Init failed.\n");
sound_started = 0; sound_started = 0;
@ -160,22 +156,24 @@ void S_Startup (void)
S_Init S_Init
================ ================
*/ */
void CDAudioSetVolume (void);
void S_Init (void) void S_Init (void)
{ {
Con_Printf("\nSound Initialization\n");
if (COM_CheckParm("-nosound")) if (COM_CheckParm("-nosound"))
return; return;
Con_Printf("\nSound Initialization\n");
if (COM_CheckParm("-simsound")) if (COM_CheckParm("-simsound"))
fakedma = true; fakedma = true;
Cmd_AddCommand("play", S_Play); Cmd_AddCommand("play", S_Play_f);
Cmd_AddCommand("playvol", S_PlayVol); Cmd_AddCommand("playvol", S_PlayVol_f);
Cmd_AddCommand("stopsound", S_StopAllSoundsC); Cmd_AddCommand("stopsound", S_StopAllSoundsC_f);
Cmd_AddCommand("soundlist", S_SoundList); Cmd_AddCommand("soundlist", S_SoundList_f);
Cmd_AddCommand("soundinfo", S_SoundInfo_f); Cmd_AddCommand("soundinfo", S_SoundInfo_f);
Cmd_AddCommand ("volumedown", S_VolumeDown_f); // Baker 3.60 - from JoeQuake 0.15
Cmd_AddCommand ("volumeup", S_VolumeUp_f); // Baker 3.60 - from JoeQuake 0.15
Cvar_RegisterVariable(&nosound); Cvar_RegisterVariable(&nosound);
Cvar_RegisterVariable(&volume); Cvar_RegisterVariable(&volume);
@ -196,7 +194,6 @@ void S_Init (void)
} }
snd_initialized = true; snd_initialized = true;
S_Startup (); S_Startup ();
@ -223,9 +220,7 @@ void S_Init (void)
shm->buffer = Hunk_AllocName(1<<16, "shmbuf"); shm->buffer = Hunk_AllocName(1<<16, "shmbuf");
} }
if ( shm ) { Con_Printf ("Sound sampling rate: %i Hz\n", shm->speed);
Con_Printf ("Sound sampling rate: %i\n", shm->speed);
}
// provides a tick sound until washed clean // provides a tick sound until washed clean
@ -242,7 +237,6 @@ void S_Init (void)
void S_Shutdown(void) void S_Shutdown(void)
{ {
if (!sound_started) if (!sound_started)
return; return;
@ -253,9 +247,7 @@ void S_Shutdown(void)
sound_started = 0; sound_started = 0;
if (!fakedma) if (!fakedma)
{
SNDDMA_Shutdown(); SNDDMA_Shutdown();
}
} }
@ -277,24 +269,22 @@ sfx_t *S_FindName (char *name)
if (!name) if (!name)
Sys_Error ("S_FindName: NULL\n"); Sys_Error ("S_FindName: NULL\n");
if (Q_strlen(name) >= MAX_QPATH) if (strlen(name) >= MAX_QPATH)
Sys_Error ("Sound name too long: %s", name); Sys_Error ("Sound name too long: %s", name);
// see if already loaded // see if already loaded
for (i=0 ; i < num_sfx ; i++) for (i=0 ; i < num_sfx ; i++)
if (!strcmp(known_sfx[i].name, name)) if (!strcmp(known_sfx[i].name, name))
{
return &known_sfx[i]; return &known_sfx[i];
}
if (num_sfx == MAX_SFX) if (num_sfx == MAX_SFX)
Sys_Error ("S_FindName: out of sfx_t"); Sys_Error ("S_FindName: out of sfx_t");
sfx = &known_sfx[i]; sfx = &known_sfx[i];
strcpy (sfx->name, name); strcpy (sfx->name, name);
num_sfx++; num_sfx++;
return sfx; return sfx;
} }
@ -308,7 +298,7 @@ S_TouchSound
void S_TouchSound (char *name) void S_TouchSound (char *name)
{ {
sfx_t *sfx; sfx_t *sfx;
if (!sound_started) if (!sound_started)
return; return;
@ -330,11 +320,11 @@ sfx_t *S_PrecacheSound (char *name)
return NULL; return NULL;
sfx = S_FindName (name); sfx = S_FindName (name);
// cache it in // cache it in
if (precache.value) if (precache.value)
S_LoadSound (sfx); S_LoadSound (sfx);
return sfx; return sfx;
} }
@ -360,7 +350,7 @@ channel_t *SND_PickChannel(int entnum, int entchannel)
if (entchannel != 0 // channel 0 never overrides if (entchannel != 0 // channel 0 never overrides
&& channels[ch_idx].entnum == entnum && channels[ch_idx].entnum == entnum
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1) ) && (channels[ch_idx].entchannel == entchannel || entchannel == -1) )
{ // allways override sound from same entity { // always override sound from same entity
first_to_die = ch_idx; first_to_die = ch_idx;
break; break;
} }
@ -382,8 +372,8 @@ channel_t *SND_PickChannel(int entnum, int entchannel)
if (channels[first_to_die].sfx) if (channels[first_to_die].sfx)
channels[first_to_die].sfx = NULL; channels[first_to_die].sfx = NULL;
return &channels[first_to_die]; return &channels[first_to_die];
} }
/* /*
================= =================
@ -393,12 +383,12 @@ SND_Spatialize
void SND_Spatialize(channel_t *ch) void SND_Spatialize(channel_t *ch)
{ {
vec_t dot; vec_t dot;
vec_t ldist, rdist, dist; vec_t dist;
vec_t lscale, rscale, scale; vec_t lscale, rscale, scale;
vec3_t source_vec; vec3_t source_vec;
sfx_t *snd; sfx_t *snd;
// 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) if (ch->entnum == cl.viewentity)
{ {
ch->leftvol = ch->master_vol; ch->leftvol = ch->master_vol;
@ -410,9 +400,9 @@ void SND_Spatialize(channel_t *ch)
snd = ch->sfx; snd = ch->sfx;
VectorSubtract(ch->origin, listener_origin, source_vec); VectorSubtract(ch->origin, listener_origin, source_vec);
dist = VectorNormalize(source_vec) * ch->dist_mult; dist = VectorNormalize(source_vec) * ch->dist_mult;
dot = DotProduct(listener_right, source_vec); dot = DotProduct(listener_right, source_vec);
if (shm->channels == 1) if (shm->channels == 1)
@ -436,7 +426,7 @@ void SND_Spatialize(channel_t *ch)
ch->leftvol = (int) (ch->master_vol * scale); ch->leftvol = (int) (ch->master_vol * scale);
if (ch->leftvol < 0) if (ch->leftvol < 0)
ch->leftvol = 0; ch->leftvol = 0;
} }
// ======================================================================= // =======================================================================
@ -466,7 +456,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
target_chan = SND_PickChannel(entnum, entchannel); target_chan = SND_PickChannel(entnum, entchannel);
if (!target_chan) if (!target_chan)
return; return;
// spatialize // spatialize
memset (target_chan, 0, sizeof(*target_chan)); memset (target_chan, 0, sizeof(*target_chan));
VectorCopy(origin, target_chan->origin); VectorCopy(origin, target_chan->origin);
@ -480,8 +470,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
return; // not audible at all return; // not audible at all
// new channel // new channel
sc = S_LoadSound (sfx); if (!(sc = S_LoadSound (sfx)))
if (!sc)
{ {
target_chan->sfx = NULL; target_chan->sfx = NULL;
return; // couldn't load the sound's data return; // couldn't load the sound's data
@ -489,7 +478,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
target_chan->sfx = sfx; target_chan->sfx = sfx;
target_chan->pos = 0.0; target_chan->pos = 0.0;
target_chan->end = paintedtime + sc->length; target_chan->end = paintedtime + sc->length;
// if an identical sound has also been started this frame, offset the pos // if an identical sound has also been started this frame, offset the pos
// a bit to keep it from just making the first one louder // a bit to keep it from just making the first one louder
@ -507,7 +496,6 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
target_chan->end -= skip; target_chan->end -= skip;
break; break;
} }
} }
} }
@ -517,8 +505,7 @@ void S_StopSound(int entnum, int entchannel)
for (i=0 ; i<MAX_DYNAMIC_CHANNELS ; i++) for (i=0 ; i<MAX_DYNAMIC_CHANNELS ; i++)
{ {
if (channels[i].entnum == entnum if (channels[i].entnum == entnum && channels[i].entchannel == entchannel)
&& channels[i].entchannel == entchannel)
{ {
channels[i].end = 0; channels[i].end = 0;
channels[i].sfx = NULL; channels[i].sfx = NULL;
@ -540,13 +527,13 @@ void S_StopAllSounds(qboolean clear)
if (channels[i].sfx) if (channels[i].sfx)
channels[i].sfx = NULL; channels[i].sfx = NULL;
Q_memset(channels, 0, MAX_CHANNELS * sizeof(channel_t)); memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
if (clear) if (clear)
S_ClearBuffer (); S_ClearBuffer ();
} }
void S_StopAllSoundsC (void) void S_StopAllSoundsC_f (void)
{ {
S_StopAllSounds (true); S_StopAllSounds (true);
} }
@ -554,7 +541,7 @@ void S_StopAllSoundsC (void)
void S_ClearBuffer (void) void S_ClearBuffer (void)
{ {
int clear; int clear;
if (!sound_started || !shm || !shm->buffer) if (!sound_started || !shm || !shm->buffer)
return; return;
@ -563,7 +550,9 @@ void S_ClearBuffer (void)
else else
clear = 0; clear = 0;
Q_memset(shm->buffer, clear, shm->samples * shm->samplebits/8); {
memset(shm->buffer, clear, shm->samples * shm->samplebits/8);
}
} }
@ -589,8 +578,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss = &channels[total_channels]; ss = &channels[total_channels];
total_channels++; total_channels++;
sc = S_LoadSound (sfx); if (!(sc = S_LoadSound (sfx)))
if (!sc)
return; return;
if (sc->loopstart == -1) if (sc->loopstart == -1)
@ -598,13 +586,13 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
Con_Printf ("Sound %s not looped\n", sfx->name); Con_Printf ("Sound %s not looped\n", sfx->name);
return; return;
} }
ss->sfx = sfx; ss->sfx = sfx;
VectorCopy (origin, ss->origin); VectorCopy (origin, ss->origin);
ss->master_vol = vol; ss->master_vol = vol;
ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist;
ss->end = paintedtime + sc->length; ss->end = paintedtime + sc->length;
SND_Spatialize (ss); SND_Spatialize (ss);
} }
@ -640,9 +628,9 @@ void S_UpdateAmbientSounds (void)
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
{ {
chan = &channels[ambient_channel]; chan = &channels[ambient_channel];
chan->sfx = ambient_sfx[ambient_channel]; chan->sfx = ambient_sfx[ambient_channel];
vol = ambient_level.value * l->ambient_sound_level[ambient_channel]; vol = ambient_level.value * l->ambient_sound_level[ambient_channel];
if (vol < 8) if (vol < 8)
vol = 0; vol = 0;
@ -660,7 +648,7 @@ void S_UpdateAmbientSounds (void)
if (chan->master_vol < vol) if (chan->master_vol < vol)
chan->master_vol = vol; chan->master_vol = vol;
} }
chan->leftvol = chan->rightvol = chan->master_vol; chan->leftvol = chan->rightvol = chan->master_vol;
} }
} }
@ -687,13 +675,13 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
VectorCopy(forward, listener_forward); VectorCopy(forward, listener_forward);
VectorCopy(right, listener_right); VectorCopy(right, listener_right);
VectorCopy(up, listener_up); VectorCopy(up, listener_up);
// update general area ambient sound sources // update general area ambient sound sources
S_UpdateAmbientSounds (); S_UpdateAmbientSounds ();
combine = NULL; combine = NULL;
// update spatialization for static and dynamic sounds // update spatialization for static and dynamic sounds
ch = channels+NUM_AMBIENTS; ch = channels+NUM_AMBIENTS;
for (i=NUM_AMBIENTS ; i<total_channels; i++, ch++) for (i=NUM_AMBIENTS ; i<total_channels; i++, ch++)
{ {
@ -705,7 +693,7 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
// try to combine static sounds with a previous channel of the same // try to combine static sounds with a previous channel of the same
// sound effect so we don't mix five torches every frame // sound effect so we don't mix five torches every frame
if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS)
{ {
// see if it can just use the last one // see if it can just use the last one
@ -721,7 +709,7 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; j<i; j++, combine++) for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; j<i; j++, combine++)
if (combine->sfx == ch->sfx) if (combine->sfx == ch->sfx)
break; break;
if (j == total_channels) if (j == total_channels)
{ {
combine = NULL; combine = NULL;
@ -737,13 +725,9 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
continue; continue;
} }
} }
} }
//
// debugging output // debugging output
//
if (snd_show.value) if (snd_show.value)
{ {
total = 0; total = 0;
@ -754,7 +738,7 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
//Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name); //Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name);
total++; total++;
} }
Con_Printf ("----(%i)----\n", total); Con_Printf ("----(%i)----\n", total);
} }
@ -768,18 +752,18 @@ void GetSoundtime(void)
static int buffers; static int buffers;
static int oldsamplepos; static int oldsamplepos;
int fullsamples; int fullsamples;
fullsamples = shm->samples / shm->channels; fullsamples = shm->samples / shm->channels;
// it is possible to miscount buffers if it has wrapped twice between // it is possible to miscount buffers if it has wrapped twice between
// calls to S_Update. Oh well. // calls to S_Update. Oh well.
samplepos = SNDDMA_GetDMAPos(); samplepos = SNDDMA_GetDMAPos();
if (samplepos < oldsamplepos) if (samplepos < oldsamplepos)
{ {
buffers++; // buffer wrapped buffers++; // buffer wrapped
if (paintedtime > 0x40000000) if (paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits { // time to chop things off to avoid 32 bit limits
buffers = 0; buffers = 0;
@ -796,16 +780,15 @@ void S_ExtraUpdate (void)
{ {
if (snd_noextraupdate.value) if (snd_noextraupdate.value)
return; // don't pollute timings return; // don't pollute timings
S_Update_(); S_Update_();
} }
void S_Update_(void) void S_Update_(void)
{ {
/*#ifndef SDL
unsigned endtime; unsigned endtime;
int samps; int samps;
if (!sound_started || (snd_blocked > 0)) if (!sound_started || (snd_blocked > 0))
return; return;
@ -819,6 +802,8 @@ void S_Update_(void)
paintedtime = soundtime; paintedtime = soundtime;
} }
//OutputDebugString(va("paintedtime: %i, soundtime: %i\n", paintedtime, soundtime));
// mix ahead of current position // mix ahead of current position
endtime = soundtime + _snd_mixahead.value * shm->speed; endtime = soundtime + _snd_mixahead.value * shm->speed;
samps = shm->samples >> (shm->channels-1); samps = shm->samples >> (shm->channels-1);
@ -828,7 +813,6 @@ void S_Update_(void)
S_PaintChannels (endtime); S_PaintChannels (endtime);
SNDDMA_Submit (); SNDDMA_Submit ();
#endif*/
} }
/* /*
@ -839,55 +823,61 @@ console functions
=============================================================================== ===============================================================================
*/ */
void S_Play(void) void S_Play_f(void)
{ {
static int hash=345; static int hash=345;
int i; int i;
char name[256]; char name[256];
sfx_t *sfx; sfx_t *sfx;
i = 1; i = 1;
while (i<Cmd_Argc()) while (i<Cmd_Argc())
{ {
if (!Q_strrchr(Cmd_Argv(i), '.')) if (!strrchr(Cmd_Argv(i), '.'))
{ {
Q_strcpy(name, Cmd_Argv(i)); strcpy(name, Cmd_Argv(i));
Q_strcat(name, ".wav"); strlcat (name, ".wav", sizeof(name));
} }
else else
Q_strcpy(name, Cmd_Argv(i)); strcpy(name, Cmd_Argv(i));
sfx = S_PrecacheSound(name); sfx = S_PrecacheSound(name);
S_StartSound(hash++, 0, sfx, listener_origin, 1.0, 1.0); S_StartSound(hash++, 0, sfx, listener_origin, 1.0, 1.0);
i++; i++;
} }
} }
void S_PlayVol(void) void S_PlayVol_f(void)
{ {
static int hash=543; static int hash=543;
int i; int i;
float vol; float vol;
char name[256]; char name[256];
sfx_t *sfx; sfx_t *sfx;
if (Cmd_Argc() != 2)
{
Con_Printf ("Usage: playvol <filename>\n");
return;
}
i = 1; i = 1;
while (i<Cmd_Argc()) while (i<Cmd_Argc())
{ {
if (!Q_strrchr(Cmd_Argv(i), '.')) if (!strrchr(Cmd_Argv(i), '.'))
{ {
Q_strcpy(name, Cmd_Argv(i)); strcpy(name, Cmd_Argv(i));
Q_strcat(name, ".wav"); strlcat (name, ".wav", sizeof(name));
} }
else else
Q_strcpy(name, Cmd_Argv(i)); strcpy(name, Cmd_Argv(i));
sfx = S_PrecacheSound(name); sfx = S_PrecacheSound(name);
vol = Q_atof(Cmd_Argv(i+1)); vol = atof(Cmd_Argv(i+1));
S_StartSound(hash++, 0, sfx, listener_origin, vol, 1.0); S_StartSound(hash++, 0, sfx, listener_origin, vol, 1.0);
i+=2; i+=2;
} }
} }
void S_SoundList(void) void S_SoundList_f(void)
{ {
int i; int i;
sfx_t *sfx; sfx_t *sfx;
@ -897,8 +887,7 @@ void S_SoundList(void)
total = 0; total = 0;
for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++) for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
{ {
sc = Cache_Check (&sfx->cache); if (!(sc = Cache_Check (&sfx->cache)))
if (!sc)
continue; continue;
size = sc->length*sc->width*(sc->stereo+1); size = sc->length*sc->width*(sc->stereo+1);
total += size; total += size;
@ -911,6 +900,25 @@ void S_SoundList(void)
Con_Printf ("Total resident: %i\n", total); Con_Printf ("Total resident: %i\n", total);
} }
qboolean volume_changed;
void S_VolumeDown_f (void)
{
//S_LocalSound ("misc/menu3.wav");
volume.value -= 0.1;
volume.value = bound(0, volume.value, 1);
//Cvar_SetValueByRef (&volume, volume.value);
volume_changed = true;
}
void S_VolumeUp_f (void)
{
//S_LocalSound ("misc/menu3.wav");
volume.value += 0.1;
volume.value = bound(0, volume.value, 1);
//Cvar_SetValueByRef (&volume, volume.value);
volume_changed = true;
}
void S_LocalSound (char *sound) void S_LocalSound (char *sound)
{ {
@ -920,9 +928,8 @@ void S_LocalSound (char *sound)
return; return;
if (!sound_started) if (!sound_started)
return; return;
sfx = S_PrecacheSound (sound); if (!(sfx = S_PrecacheSound (sound)))
if (!sfx)
{ {
Con_Printf ("S_LocalSound: can't cache %s\n", sound); Con_Printf ("S_LocalSound: can't cache %s\n", sound);
return; return;
@ -943,4 +950,5 @@ void S_BeginPrecaching (void)
void S_EndPrecaching (void) void S_EndPrecaching (void)
{ {
} }

View file

@ -105,8 +105,7 @@ sfxcache_t *S_LoadSound (sfx_t *s)
byte stackbuf[1*1024]; // avoid dirtying the cache heap byte stackbuf[1*1024]; // avoid dirtying the cache heap
// see if still in memory // see if still in memory
sc = Cache_Check (&s->cache); if ((sc = Cache_Check (&s->cache)))
if (sc)
return sc; return sc;
//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); //Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
@ -116,9 +115,7 @@ sfxcache_t *S_LoadSound (sfx_t *s)
// Con_Printf ("loading %s\n",namebuffer); // Con_Printf ("loading %s\n",namebuffer);
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf)); if (!(data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf))))
if (!data)
{ {
Con_Printf ("Couldn't load %s\n", namebuffer); Con_Printf ("Couldn't load %s\n", namebuffer);
return NULL; return NULL;
@ -212,7 +209,7 @@ void FindNextChunk(char *name)
// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); // Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len);
data_p -= 8; data_p -= 8;
last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 ); last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
if (!Q_strncmp((char *)data_p, name, 4)) if (!strncmp((char*) data_p, name, 4))
return; return;
} }
} }
@ -262,7 +259,7 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
// find "RIFF" chunk // find "RIFF" chunk
FindChunk("RIFF"); FindChunk("RIFF");
if (!(data_p && !Q_strncmp((char *)data_p+8, "WAVE", 4))) if (!(data_p && !strncmp((char*) data_p+8, "WAVE", 4)))
{ {
Con_Printf("Missing RIFF/WAVE chunks\n"); Con_Printf("Missing RIFF/WAVE chunks\n");
return info; return info;
@ -303,7 +300,7 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
FindNextChunk ("LIST"); FindNextChunk ("LIST");
if (data_p) if (data_p)
{ {
if (!strncmp ((char *)data_p + 28, "mark", 4)) if (!strncmp ((char*) data_p + 28, "mark", 4))
{ // this is not a proper parse, but it works with cooledit... { // this is not a proper parse, but it works with cooledit...
data_p += 24; data_p += 24;
i = GetLittleLong (); // samples in loop i = GetLittleLong (); // samples in loop

View file

@ -34,8 +34,7 @@ void Snd_WriteLinearBlastStereo16 (void);
#if !id386 #if !id386
void Snd_WriteLinearBlastStereo16 (void) void Snd_WriteLinearBlastStereo16 (void)
{ {
int i; int i, val;
int val;
for (i=0 ; i<snd_linear_count ; i+=2) for (i=0 ; i<snd_linear_count ; i+=2)
{ {
@ -60,8 +59,7 @@ void Snd_WriteLinearBlastStereo16 (void)
void S_TransferStereo16 (int endtime) void S_TransferStereo16 (int endtime)
{ {
int lpos; int lpos, lpaintedtime;
int lpaintedtime;
DWORD *pbuf; DWORD *pbuf;
snd_vol = volume.value*256; snd_vol = volume.value*256;
@ -96,13 +94,7 @@ void S_TransferStereo16 (int endtime)
void S_TransferPaintBuffer(int endtime) void S_TransferPaintBuffer(int endtime)
{ {
int out_idx; int out_idx, count, out_mask, *p, step, val, snd_vol;
int count;
int out_mask;
int *p;
int step;
int val;
int snd_vol;
DWORD *pbuf; DWORD *pbuf;
if (shm->samplebits == 16 && shm->channels == 2) if (shm->samplebits == 16 && shm->channels == 2)
@ -153,6 +145,7 @@ void S_TransferPaintBuffer(int endtime)
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) & out_mask;
} }
} }
} }
@ -169,11 +162,9 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime);
void S_PaintChannels(int endtime) void S_PaintChannels(int endtime)
{ {
int i; int i, end, ltime, count;
int end;
channel_t *ch; channel_t *ch;
sfxcache_t *sc; sfxcache_t *sc;
int ltime, count;
while (paintedtime < endtime) while (paintedtime < endtime)
{ {
@ -183,7 +174,7 @@ void S_PaintChannels(int endtime)
end = paintedtime + PAINTBUFFER_SIZE; end = paintedtime + PAINTBUFFER_SIZE;
// clear the paint buffer // clear the paint buffer
Q_memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t)); memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
// paint in the channels. // paint in the channels.
ch = channels; ch = channels;
@ -193,8 +184,7 @@ void S_PaintChannels(int endtime)
continue; continue;
if (!ch->leftvol && !ch->rightvol) if (!ch->leftvol && !ch->rightvol)
continue; continue;
sc = S_LoadSound (ch->sfx); if (!(sc = S_LoadSound (ch->sfx)))
if (!sc)
continue; continue;
ltime = paintedtime; ltime = paintedtime;
@ -254,10 +244,8 @@ void SND_InitScaletable (void)
void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count) void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
{ {
int data; int i, data, *lscale, *rscale;
int *lscale, *rscale;
unsigned char *sfx; unsigned char *sfx;
int i;
if (ch->leftvol > 255) if (ch->leftvol > 255)
ch->leftvol = 255; ch->leftvol = 255;
@ -283,9 +271,7 @@ void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count) void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
{ {
int data; int data, left, right, leftvol, rightvol;
int left, right;
int leftvol, rightvol;
signed short *sfx; signed short *sfx;
int i; int i;

View file

@ -1,102 +0,0 @@
#include <stdio.h>
#include <SDL2/SDL_audio.h>
#include "quakedef.h"
static dma_t the_shm;
static int snd_inited;
extern int desired_speed;
extern int desired_bits;
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);
}
}
qboolean SNDDMA_Init(void)
{
SDL_AudioSpec desired, obtained;
snd_inited = 0;
/* Set up the desired format */
desired.freq = desired_speed;
switch (desired_bits) {
case 8:
desired.format = AUDIO_U8;
break;
case 16:
desired.format = AUDIO_S16LSB;
break;
default:
Con_Printf("Unknown number of audio bits: %d\n",
desired_bits);
return 0;
}
desired.channels = 2;
desired.samples = 48;
desired.callback = paint_audio;
/* Open the audio device */
if ( SDL_OpenAudio(&desired, &obtained) < 0 ) {
Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError());
return 0;
}
/* Make sure we can support the audio format */
switch (obtained.format) {
case AUDIO_U8:
/* Supported */
break;
case AUDIO_S16LSB:
case AUDIO_S16MSB:
/* 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;
}
SDL_PauseAudio(0);
/* Fill the audio DMA information block */
shm = &the_shm;
shm->splitbuffer = 0;
shm->samplebits = (obtained.format & 0xFF);
shm->speed = obtained.freq;
shm->channels = obtained.channels;
shm->samples = obtained.samples*shm->channels;
shm->samplepos = 0;
shm->submission_chunk = 1;
shm->buffer = NULL;
snd_inited = 1;
return 1;
}
int SNDDMA_GetDMAPos(void)
{
return shm->samplepos;
}
void SNDDMA_Shutdown(void)
{
if (snd_inited)
{
SDL_CloseAudio();
snd_inited = 0;
}
}

View file

@ -130,6 +130,8 @@ void SNDDMA_Shutdown(void);
#define MAX_CHANNELS 128 #define MAX_CHANNELS 128
#define MAX_DYNAMIC_CHANNELS 8 #define MAX_DYNAMIC_CHANNELS 8
#define MAX_SFX 512
extern channel_t channels[MAX_CHANNELS]; extern channel_t channels[MAX_CHANNELS];
// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds // 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds