mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-03-26 12:52:00 +00:00
Reformat the sound system code
caedes and some other people will probably kill me for this, but I'm the idiot who has to maintain the code. And that's much easier if it's in a readable und writeable state.
This commit is contained in:
parent
51cc3369b1
commit
d8e35b82c7
8 changed files with 1374 additions and 1143 deletions
|
@ -27,89 +27,97 @@
|
|||
#ifndef CL_SOUND_LOCAL_H
|
||||
#define CL_SOUND_LOCAL_H
|
||||
|
||||
typedef struct {
|
||||
int left;
|
||||
int right;
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct {
|
||||
int length;
|
||||
int loopstart;
|
||||
int speed; /* not needed, because converted on load? */
|
||||
int width;
|
||||
typedef struct
|
||||
{
|
||||
int length;
|
||||
int loopstart;
|
||||
int speed; /* not needed, because converted on load? */
|
||||
int width;
|
||||
#if USE_OPENAL
|
||||
int size;
|
||||
int bufnum;
|
||||
int size;
|
||||
int bufnum;
|
||||
#endif
|
||||
int stereo;
|
||||
byte data[1]; /* variable sized */
|
||||
int stereo;
|
||||
byte data[1]; /* variable sized */
|
||||
} sfxcache_t;
|
||||
|
||||
typedef struct sfx_s {
|
||||
char name[MAX_QPATH];
|
||||
int registration_sequence;
|
||||
sfxcache_t *cache;
|
||||
char *truename;
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
int registration_sequence;
|
||||
sfxcache_t *cache;
|
||||
char *truename;
|
||||
} sfx_t;
|
||||
|
||||
/* a playsound_t will be generated by each call to S_StartSound,
|
||||
when the mixer reaches playsound->begin, the playsound will
|
||||
be assigned to a channel */
|
||||
typedef struct playsound_s {
|
||||
struct playsound_s *prev, *next;
|
||||
sfx_t *sfx;
|
||||
float volume;
|
||||
float attenuation;
|
||||
int entnum;
|
||||
int entchannel;
|
||||
qboolean fixed_origin; /* use origin field instead of entnum's origin */
|
||||
vec3_t origin;
|
||||
unsigned begin; /* begin on this sample */
|
||||
* when the mixer reaches playsound->begin, the playsound will
|
||||
* be assigned to a channel */
|
||||
typedef struct playsound_s
|
||||
{
|
||||
struct playsound_s *prev, *next;
|
||||
sfx_t *sfx;
|
||||
float volume;
|
||||
float attenuation;
|
||||
int entnum;
|
||||
int entchannel;
|
||||
qboolean fixed_origin; /* use origin field instead of entnum's origin */
|
||||
vec3_t origin;
|
||||
unsigned begin; /* begin on this sample */
|
||||
} playsound_t;
|
||||
|
||||
typedef struct {
|
||||
int channels;
|
||||
int samples; /* mono samples in buffer */
|
||||
int submission_chunk; /* don't mix less than this */
|
||||
int samplepos; /* in mono samples */
|
||||
int samplebits;
|
||||
int speed;
|
||||
byte *buffer;
|
||||
typedef struct
|
||||
{
|
||||
int channels;
|
||||
int samples; /* mono samples in buffer */
|
||||
int submission_chunk; /* don't mix less than this */
|
||||
int samplepos; /* in mono samples */
|
||||
int samplebits;
|
||||
int speed;
|
||||
byte *buffer;
|
||||
} dma_t;
|
||||
|
||||
typedef struct {
|
||||
sfx_t *sfx; /* sfx number */
|
||||
int leftvol; /* 0-255 volume */
|
||||
int rightvol; /* 0-255 volume */
|
||||
int end; /* end time in global paintsamples */
|
||||
int pos; /* sample position in sfx */
|
||||
int looping; /* where to loop, -1 = no looping */
|
||||
int entnum; /* to allow overriding a specific sound */
|
||||
int entchannel;
|
||||
vec3_t origin; /* only use if fixed_origin is set */
|
||||
vec_t dist_mult; /* distance multiplier (attenuation/clipK) */
|
||||
int master_vol; /* 0-255 master volume */
|
||||
qboolean fixed_origin; /* use origin instead of fetching entnum's origin */
|
||||
qboolean autosound; /* from an entity->sound, cleared each frame */
|
||||
typedef struct
|
||||
{
|
||||
sfx_t *sfx; /* sfx number */
|
||||
int leftvol; /* 0-255 volume */
|
||||
int rightvol; /* 0-255 volume */
|
||||
int end; /* end time in global paintsamples */
|
||||
int pos; /* sample position in sfx */
|
||||
int looping; /* where to loop, -1 = no looping */
|
||||
int entnum; /* to allow overriding a specific sound */
|
||||
int entchannel;
|
||||
vec3_t origin; /* only use if fixed_origin is set */
|
||||
vec_t dist_mult; /* distance multiplier (attenuation/clipK) */
|
||||
int master_vol; /* 0-255 master volume */
|
||||
qboolean fixed_origin; /* use origin instead of fetching entnum's origin */
|
||||
qboolean autosound; /* from an entity->sound, cleared each frame */
|
||||
#if USE_OPENAL
|
||||
int autoframe;
|
||||
int srcnum;
|
||||
int autoframe;
|
||||
int srcnum;
|
||||
#endif
|
||||
} channel_t;
|
||||
|
||||
typedef struct {
|
||||
int rate;
|
||||
int width;
|
||||
int channels;
|
||||
int loopstart;
|
||||
int samples;
|
||||
int dataofs; /* chunk starts this many bytes from file start */
|
||||
typedef struct
|
||||
{
|
||||
int rate;
|
||||
int width;
|
||||
int channels;
|
||||
int loopstart;
|
||||
int samples;
|
||||
int dataofs; /* chunk starts this many bytes from file start */
|
||||
} wavinfo_t;
|
||||
|
||||
typedef enum {
|
||||
SS_NOT = 0, // soundsystem not started
|
||||
SS_DMA, // soundsystem started, using DMA/SDL
|
||||
SS_OAL // soundsystem started, using OpenAL
|
||||
typedef enum
|
||||
{
|
||||
SS_NOT = 0, /* soundsystem not started */
|
||||
SS_DMA, /* soundsystem started, using DMA/SDL */
|
||||
SS_OAL /* soundsystem started, using OpenAL */
|
||||
} sndstarted_t;
|
||||
|
||||
extern sndstarted_t sound_started;
|
||||
|
@ -119,42 +127,42 @@ extern sndstarted_t sound_started;
|
|||
qboolean SNDDMA_Init(void);
|
||||
|
||||
/* gets the current DMA position */
|
||||
int SNDDMA_GetDMAPos(void);
|
||||
int SNDDMA_GetDMAPos(void);
|
||||
|
||||
/* shutdown the DMA xfer. */
|
||||
void SNDDMA_Shutdown(void);
|
||||
void SNDDMA_BeginPainting (void);
|
||||
void SNDDMA_Submit(void);
|
||||
void SNDDMA_Shutdown(void);
|
||||
void SNDDMA_BeginPainting(void);
|
||||
void SNDDMA_Submit(void);
|
||||
|
||||
#define MAX_CHANNELS 32
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern int s_numchannels;
|
||||
#define MAX_CHANNELS 32
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern int s_numchannels;
|
||||
|
||||
extern int paintedtime;
|
||||
extern int s_rawend;
|
||||
extern vec3_t listener_origin;
|
||||
extern vec3_t listener_forward;
|
||||
extern vec3_t listener_right;
|
||||
extern vec3_t listener_up;
|
||||
extern dma_t dma;
|
||||
extern playsound_t s_pendingplays;
|
||||
extern int paintedtime;
|
||||
extern int s_rawend;
|
||||
extern vec3_t listener_origin;
|
||||
extern vec3_t listener_forward;
|
||||
extern vec3_t listener_right;
|
||||
extern vec3_t listener_up;
|
||||
extern dma_t dma;
|
||||
extern playsound_t s_pendingplays;
|
||||
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
|
||||
extern cvar_t *s_volume;
|
||||
extern cvar_t *s_nosound;
|
||||
extern cvar_t *s_loadas8bit;
|
||||
extern cvar_t *s_khz;
|
||||
extern cvar_t *s_show;
|
||||
extern cvar_t *s_mixahead;
|
||||
extern cvar_t *s_testsound;
|
||||
extern cvar_t *s_ambient;
|
||||
extern cvar_t *s_volume;
|
||||
extern cvar_t *s_nosound;
|
||||
extern cvar_t *s_loadas8bit;
|
||||
extern cvar_t *s_khz;
|
||||
extern cvar_t *s_show;
|
||||
extern cvar_t *s_mixahead;
|
||||
extern cvar_t *s_testsound;
|
||||
extern cvar_t *s_ambient;
|
||||
|
||||
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
|
||||
void S_InitScaletable (void);
|
||||
sfxcache_t *S_LoadSound (sfx_t *s);
|
||||
void S_IssuePlaysound (playsound_t *ps);
|
||||
wavinfo_t GetWavinfo(char *name, byte *wav, int wavlength);
|
||||
void S_InitScaletable(void);
|
||||
sfxcache_t *S_LoadSound(sfx_t *s);
|
||||
void S_IssuePlaysound(playsound_t *ps);
|
||||
void S_PaintChannels(int endtime);
|
||||
|
||||
/* picks a channel based on priorities, empty slots, number of channels */
|
||||
|
@ -163,28 +171,30 @@ channel_t *S_PickChannel(int entnum, int entchannel);
|
|||
/* spatializes a channel */
|
||||
void S_Spatialize(channel_t *ch);
|
||||
|
||||
void S_BuildSoundList( int *sounds );
|
||||
void S_BuildSoundList(int *sounds);
|
||||
|
||||
#if USE_OPENAL
|
||||
// this stuff was taken from Q2Pro
|
||||
// only begin attenuating sound volumes when outside the FULLVOLUME range
|
||||
#define SOUND_FULLVOLUME 80
|
||||
#define SOUND_LOOPATTENUATE 0.003
|
||||
/* Only begin attenuating sound volumes
|
||||
when outside the FULLVOLUME range */
|
||||
#define SOUND_FULLVOLUME 80
|
||||
#define SOUND_LOOPATTENUATE 0.003
|
||||
|
||||
// number of buffers in flight (needed for ogg)
|
||||
/* number of buffers in flight (needed for ogg) */
|
||||
extern int active_buffers;
|
||||
|
||||
// for snd_al.c - copied from Q2Pro and adapted
|
||||
void AL_SoundInfo( void );
|
||||
qboolean AL_Init( void );
|
||||
void AL_Shutdown( void );
|
||||
sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data );
|
||||
void AL_DeleteSfx( sfx_t *s );
|
||||
void AL_StopChannel( channel_t *ch );
|
||||
void AL_PlayChannel( channel_t *ch );
|
||||
void AL_StopAllChannels( void );
|
||||
void AL_Update( void );
|
||||
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume );
|
||||
#endif
|
||||
/* for snd_al.c - copied from Q2Pro and adapted */
|
||||
void AL_SoundInfo(void);
|
||||
qboolean AL_Init(void);
|
||||
void AL_Shutdown(void);
|
||||
sfxcache_t *AL_UploadSfx(sfx_t *s, wavinfo_t *s_info, byte *data);
|
||||
void AL_DeleteSfx(sfx_t *s);
|
||||
void AL_StopChannel(channel_t *ch);
|
||||
void AL_PlayChannel(channel_t *ch);
|
||||
void AL_StopAllChannels(void);
|
||||
void AL_Update(void);
|
||||
void AL_RawSamples(int samples, int rate, int width,
|
||||
int channels, byte *data, float volume);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,24 +30,29 @@
|
|||
|
||||
struct sfx_s;
|
||||
|
||||
void S_Init (void);
|
||||
void S_Shutdown (void);
|
||||
void S_Init(void);
|
||||
void S_Shutdown(void);
|
||||
|
||||
/* if origin is NULL, the sound will be dynamically sourced from the entity */
|
||||
void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs);
|
||||
/* if origin is NULL, the sound will be
|
||||
dynamically sourced from the entity */
|
||||
void S_StartSound(vec3_t origin, int entnum, int entchannel,
|
||||
struct sfx_s *sfx, float fvol, float attenuation,
|
||||
float timeofs);
|
||||
|
||||
void S_StartLocalSound (char *s);
|
||||
void S_RawSamples (int samples, int rate, int width, int channels, byte *data, float volume);
|
||||
void S_StartLocalSound(char *s);
|
||||
void S_RawSamples(int samples, int rate, int width, int channels,
|
||||
byte *data, float volume);
|
||||
void S_StopAllSounds(void);
|
||||
void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
|
||||
void S_Activate (qboolean active);
|
||||
void S_BeginRegistration (void);
|
||||
struct sfx_s *S_RegisterSound (char *sample);
|
||||
void S_EndRegistration (void);
|
||||
struct sfx_s *S_FindName (char *name, qboolean create);
|
||||
void S_Update(vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
|
||||
void S_Activate(qboolean active);
|
||||
void S_BeginRegistration(void);
|
||||
struct sfx_s *S_RegisterSound(char *sample);
|
||||
void S_EndRegistration(void);
|
||||
struct sfx_s *S_FindName(char *name, qboolean create);
|
||||
|
||||
/* the sound code makes callbacks to the client for entitiy position
|
||||
information, so entities can be dynamically re-spatialized */
|
||||
void CL_GetEntitySoundOrigin (int ent, vec3_t org);
|
||||
/* the sound code makes callbacks to the client for
|
||||
entitiy position information, so entities can be
|
||||
dynamically re-spatialized */
|
||||
void CL_GetEntitySoundOrigin(int ent, vec3_t org);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,49 +25,51 @@
|
|||
#ifdef OGG
|
||||
|
||||
#ifndef CL_SOUND_VORBIS_H
|
||||
#define CL_SOUND_VORBIS_H
|
||||
#define CL_SOUND_VORBIS_H
|
||||
|
||||
/* The OGG codec can return the samples in a number
|
||||
of different formats, we use the standard signed
|
||||
short format. */
|
||||
#define OGG_SAMPLEWIDTH 2
|
||||
* of different formats, we use the standard signed
|
||||
* short format. */
|
||||
#define OGG_SAMPLEWIDTH 2
|
||||
#define OGG_DIR "music"
|
||||
|
||||
#define OGG_DIR "music"
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
PLAY,
|
||||
PAUSE,
|
||||
STOP
|
||||
} ogg_status_t;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
ABS,
|
||||
REL
|
||||
} ogg_seek_t;
|
||||
|
||||
void OGG_Init (void);
|
||||
void OGG_Shutdown(void);
|
||||
void OGG_Reinit(void);
|
||||
qboolean OGG_Check(char *name);
|
||||
void OGG_Seek (ogg_seek_t type, double offset);
|
||||
void OGG_LoadFileList(void);
|
||||
void OGG_LoadPlaylist(char *name);
|
||||
qboolean OGG_Open(ogg_seek_t type, int offset);
|
||||
qboolean OGG_OpenName(char *filename);
|
||||
int OGG_Read (void);
|
||||
void OGG_Sequence(void);
|
||||
void OGG_Stop (void);
|
||||
void OGG_Stream(void);
|
||||
void S_RawSamplesVol(int samples, int rate, int width, int channels, byte * data, float volume);
|
||||
void OGG_Init(void);
|
||||
void OGG_Shutdown(void);
|
||||
void OGG_Reinit(void);
|
||||
qboolean OGG_Check(char *name);
|
||||
void OGG_Seek(ogg_seek_t type, double offset);
|
||||
void OGG_LoadFileList(void);
|
||||
void OGG_LoadPlaylist(char *name);
|
||||
qboolean OGG_Open(ogg_seek_t type, int offset);
|
||||
qboolean OGG_OpenName(char *filename);
|
||||
int OGG_Read(void);
|
||||
void OGG_Sequence(void);
|
||||
void OGG_Stop(void);
|
||||
void OGG_Stream(void);
|
||||
void S_RawSamplesVol(int samples, int rate, int width,
|
||||
int channels, byte *data, float volume);
|
||||
|
||||
/* Console commands. */
|
||||
void OGG_ListCmd(void);
|
||||
void OGG_ParseCmd(char *arg);
|
||||
void OGG_PauseCmd(void);
|
||||
void OGG_PlayCmd(void);
|
||||
void OGG_ResumeCmd(void);
|
||||
void OGG_SeekCmd(void);
|
||||
void OGG_StatusCmd(void);
|
||||
void OGG_ListCmd(void);
|
||||
void OGG_ParseCmd(char *arg);
|
||||
void OGG_PauseCmd(void);
|
||||
void OGG_PlayCmd(void);
|
||||
void OGG_ResumeCmd(void);
|
||||
void OGG_SeekCmd(void);
|
||||
void OGG_StatusCmd(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -21,10 +21,9 @@
|
|||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Most of these functions are from the Q2Pro project, and some are from
|
||||
* zeq2. We adapted them to work with Yamagi Quake II
|
||||
*
|
||||
* This is an OpenAL backend for the Quake II Soundsystem.
|
||||
* This is an OpenAL backend for the Quake II Soundsystem. Most of these
|
||||
* functions are from the Q2Pro project, and some are from zeq2. We
|
||||
* adapted them to work with Yamagi Quake II.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
@ -36,11 +35,12 @@
|
|||
#include "header/local.h"
|
||||
#include "header/vorbis.h"
|
||||
|
||||
// translates from AL coordinate system to quake
|
||||
#define AL_UnpackVector(v) -v[1],v[2],-v[0]
|
||||
#define AL_CopyVector(a,b) ((b)[0]=-(a)[1],(b)[1]=(a)[2],(b)[2]=-(a)[0])
|
||||
/* translates from AL coordinate system to quake */
|
||||
#define AL_UnpackVector(v) - v[1], v[2], -v[0]
|
||||
#define AL_CopyVector(a, b) ((b)[0] = -(a)[1], (b)[1] = (a)[2], (b)[2] = \
|
||||
-(a)[0])
|
||||
|
||||
// OpenAL implementation should support at least this number of sources
|
||||
/* OpenAL implementation should support at least this number of sources */
|
||||
#define MIN_CHANNELS 16
|
||||
|
||||
qboolean streamPlaying;
|
||||
|
@ -49,27 +49,31 @@ int active_buffers;
|
|||
static ALuint streamSource;
|
||||
static ALuint underwaterFilter;
|
||||
|
||||
static ALuint s_srcnums[MAX_CHANNELS-1];
|
||||
static ALuint s_srcnums[MAX_CHANNELS - 1];
|
||||
static int s_framecount;
|
||||
|
||||
// Forward Declarations
|
||||
static void S_AL_StreamUpdate( void );
|
||||
static void S_AL_StreamDie( void );
|
||||
// /Forward Declarations
|
||||
/* Forward Declarations */
|
||||
static void S_AL_StreamUpdate(void);
|
||||
static void S_AL_StreamDie(void);
|
||||
|
||||
static void AL_InitStreamSource() {
|
||||
qalSourcei (streamSource, AL_BUFFER, 0 );
|
||||
qalSourcei (streamSource, AL_LOOPING, AL_FALSE );
|
||||
qalSource3f(streamSource, AL_POSITION, 0.0, 0.0, 0.0);
|
||||
qalSource3f(streamSource, AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
qalSource3f(streamSource, AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
qalSourcef (streamSource, AL_ROLLOFF_FACTOR, 0.0 );
|
||||
qalSourcei (streamSource, AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
/* /Forward Declarations */
|
||||
|
||||
static void
|
||||
AL_InitStreamSource()
|
||||
{
|
||||
qalSourcei(streamSource, AL_BUFFER, 0);
|
||||
qalSourcei(streamSource, AL_LOOPING, AL_FALSE);
|
||||
qalSource3f(streamSource, AL_POSITION, 0.0, 0.0, 0.0);
|
||||
qalSource3f(streamSource, AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
qalSource3f(streamSource, AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
qalSourcef(streamSource, AL_ROLLOFF_FACTOR, 0.0);
|
||||
qalSourcei(streamSource, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
}
|
||||
|
||||
static void AL_InitUnderwaterFilter()
|
||||
static void
|
||||
AL_InitUnderwaterFilter()
|
||||
{
|
||||
// Generate a filter
|
||||
/* Generate a filter */
|
||||
qalGenFilters(1, &underwaterFilter);
|
||||
|
||||
if (qalGetError() != AL_NO_ERROR)
|
||||
|
@ -78,7 +82,7 @@ static void AL_InitUnderwaterFilter()
|
|||
return;
|
||||
}
|
||||
|
||||
// Low pass filter for underwater effect
|
||||
/* Low pass filter for underwater effect */
|
||||
qalFilteri(underwaterFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
|
||||
|
||||
if (qalGetError() != AL_NO_ERROR)
|
||||
|
@ -87,44 +91,55 @@ static void AL_InitUnderwaterFilter()
|
|||
return;
|
||||
}
|
||||
|
||||
// The effect
|
||||
/* The effect */
|
||||
qalFilterf(underwaterFilter, AL_LOWPASS_GAIN, 1.5);
|
||||
qalFilterf(underwaterFilter, AL_LOWPASS_GAINHF, 0.25);
|
||||
}
|
||||
|
||||
qboolean AL_Init( void ) {
|
||||
qboolean
|
||||
AL_Init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !QAL_Init() ) {
|
||||
Com_Printf( "ERROR: OpenAL failed to initialize.\n" );
|
||||
if (!QAL_Init())
|
||||
{
|
||||
Com_Printf("ERROR: OpenAL failed to initialize.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for linear distance extension
|
||||
if( !qalIsExtensionPresent( "AL_EXT_LINEAR_DISTANCE" ) ) {
|
||||
Com_Printf( "ERROR: Required AL_EXT_LINEAR_DISTANCE extension is missing.\n" );
|
||||
/* check for linear distance extension */
|
||||
if (!qalIsExtensionPresent("AL_EXT_LINEAR_DISTANCE"))
|
||||
{
|
||||
Com_Printf("ERROR: Required AL_EXT_LINEAR_DISTANCE extension is missing.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// generate source names
|
||||
/* generate source names */
|
||||
qalGetError();
|
||||
qalGenSources( 1, &streamSource );
|
||||
if( qalGetError() != AL_NO_ERROR )
|
||||
{
|
||||
Com_Printf( "ERROR: Couldn't get a single Source.\n" );
|
||||
goto fail;
|
||||
qalGenSources(1, &streamSource);
|
||||
|
||||
} else {
|
||||
// -1 because we already got one channel for streaming
|
||||
for( i = 0; i < MAX_CHANNELS - 1; i++ ) {
|
||||
qalGenSources( 1, &s_srcnums[i] );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
if (qalGetError() != AL_NO_ERROR)
|
||||
{
|
||||
Com_Printf("ERROR: Couldn't get a single Source.\n");
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* -1 because we already got one channel for streaming */
|
||||
for (i = 0; i < MAX_CHANNELS - 1; i++)
|
||||
{
|
||||
qalGenSources(1, &s_srcnums[i]);
|
||||
|
||||
if (qalGetError() != AL_NO_ERROR)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i < MIN_CHANNELS - 1 ) {
|
||||
Com_Printf( "ERROR: Required at least %d sources, but got %d.\n", MIN_CHANNELS, i+1 );
|
||||
if (i < MIN_CHANNELS - 1)
|
||||
{
|
||||
Com_Printf("ERROR: Required at least %d sources, but got %d.\n",
|
||||
MIN_CHANNELS, i + 1);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -142,44 +157,53 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
void AL_Shutdown( void ) {
|
||||
Com_Printf( "Shutting down OpenAL.\n" );
|
||||
void
|
||||
AL_Shutdown(void)
|
||||
{
|
||||
Com_Printf("Shutting down OpenAL.\n");
|
||||
|
||||
S_AL_StreamDie();
|
||||
|
||||
qalDeleteSources(1, &streamSource);
|
||||
qalDeleteFilters(1, &underwaterFilter);
|
||||
|
||||
if( s_numchannels ) {
|
||||
// delete source names
|
||||
qalDeleteSources( s_numchannels, s_srcnums );
|
||||
memset( s_srcnums, 0, sizeof( s_srcnums ) );
|
||||
if (s_numchannels)
|
||||
{
|
||||
/* delete source names */
|
||||
qalDeleteSources(s_numchannels, s_srcnums);
|
||||
memset(s_srcnums, 0, sizeof(s_srcnums));
|
||||
s_numchannels = 0;
|
||||
}
|
||||
|
||||
QAL_Shutdown();
|
||||
}
|
||||
|
||||
sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data ) {
|
||||
sfxcache_t *
|
||||
AL_UploadSfx(sfx_t *s, wavinfo_t *s_info, byte *data)
|
||||
{
|
||||
sfxcache_t *sc;
|
||||
ALsizei size = s_info->samples * s_info->width;
|
||||
ALenum format = s_info->width == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
|
||||
ALuint name;
|
||||
|
||||
if( !size ) {
|
||||
if (!size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qalGetError();
|
||||
qalGenBuffers( 1, &name );
|
||||
qalBufferData( name, format, data, size, s_info->rate );
|
||||
qalGenBuffers(1, &name);
|
||||
qalBufferData(name, format, data, size, s_info->rate);
|
||||
active_buffers++;
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
|
||||
if (qalGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// allocate placeholder sfxcache
|
||||
/* allocate placeholder sfxcache */
|
||||
sc = s->cache = Z_TagMalloc(sizeof(*sc), 0);
|
||||
sc->length = s_info->samples * 1000 / s_info->rate; // in msec
|
||||
sc->length = s_info->samples * 1000 / s_info->rate; /* in msec */
|
||||
sc->loopstart = s_info->loopstart;
|
||||
sc->width = s_info->width;
|
||||
sc->size = size;
|
||||
|
@ -188,147 +212,212 @@ sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data ) {
|
|||
return sc;
|
||||
}
|
||||
|
||||
void AL_DeleteSfx( sfx_t *s ) {
|
||||
void
|
||||
AL_DeleteSfx(sfx_t *s)
|
||||
{
|
||||
sfxcache_t *sc;
|
||||
ALuint name;
|
||||
|
||||
sc = s->cache;
|
||||
if( !sc ) {
|
||||
|
||||
if (!sc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
name = sc->bufnum;
|
||||
qalDeleteBuffers( 1, &name );
|
||||
qalDeleteBuffers(1, &name);
|
||||
active_buffers--;
|
||||
}
|
||||
|
||||
void AL_StopChannel( channel_t *ch ) {
|
||||
|
||||
void
|
||||
AL_StopChannel(channel_t *ch)
|
||||
{
|
||||
if (s_show->value > 1)
|
||||
Com_Printf("%s: %s\n", __func__, ch->sfx->name );
|
||||
|
||||
// stop it
|
||||
qalSourceStop( ch->srcnum );
|
||||
qalSourcei( ch->srcnum, AL_BUFFER, AL_NONE );
|
||||
memset (ch, 0, sizeof(*ch));
|
||||
}
|
||||
|
||||
static void AL_Spatialize( channel_t *ch ) {
|
||||
vec3_t origin;
|
||||
|
||||
// anything coming from the view entity will always be full volume
|
||||
// no attenuation = no spatialization
|
||||
if( ch->entnum == -1 || ch->entnum == cl.playernum + 1 || !ch->dist_mult ) {
|
||||
VectorCopy( listener_origin, origin );
|
||||
} else if( ch->fixed_origin ) {
|
||||
VectorCopy( ch->origin, origin );
|
||||
} else {
|
||||
CL_GetEntitySoundOrigin( ch->entnum, origin );
|
||||
{
|
||||
Com_Printf("%s: %s\n", __func__, ch->sfx->name);
|
||||
}
|
||||
|
||||
qalSource3f( ch->srcnum, AL_POSITION, AL_UnpackVector( origin ) );
|
||||
/* stop it */
|
||||
qalSourceStop(ch->srcnum);
|
||||
qalSourcei(ch->srcnum, AL_BUFFER, AL_NONE);
|
||||
memset(ch, 0, sizeof(*ch));
|
||||
}
|
||||
|
||||
void AL_PlayChannel( channel_t *ch ) {
|
||||
static void
|
||||
AL_Spatialize(channel_t *ch)
|
||||
{
|
||||
vec3_t origin;
|
||||
|
||||
/* anything coming from the view entity
|
||||
will always be full volume. no
|
||||
attenuation = no spatialization */
|
||||
if ((ch->entnum == -1) || (ch->entnum == cl.playernum + 1) ||
|
||||
!ch->dist_mult)
|
||||
{
|
||||
VectorCopy(listener_origin, origin);
|
||||
}
|
||||
else if (ch->fixed_origin)
|
||||
{
|
||||
VectorCopy(ch->origin, origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_GetEntitySoundOrigin(ch->entnum, origin);
|
||||
}
|
||||
|
||||
qalSource3f(ch->srcnum, AL_POSITION, AL_UnpackVector(origin));
|
||||
}
|
||||
|
||||
void
|
||||
AL_PlayChannel(channel_t *ch)
|
||||
{
|
||||
sfxcache_t *sc = ch->sfx->cache;
|
||||
|
||||
if (s_show->value > 1)
|
||||
Com_Printf("%s: %s\n", __func__, ch->sfx->name );
|
||||
{
|
||||
Com_Printf("%s: %s\n", __func__, ch->sfx->name);
|
||||
}
|
||||
|
||||
ch->srcnum = s_srcnums[ch - channels];
|
||||
qalGetError();
|
||||
qalSourcei( ch->srcnum, AL_BUFFER, sc->bufnum );
|
||||
qalSourcei( ch->srcnum, AL_LOOPING, ch->autosound ? AL_TRUE : AL_FALSE );
|
||||
qalSourcef( ch->srcnum, AL_GAIN, ch->master_vol );
|
||||
qalSourcef( ch->srcnum, AL_REFERENCE_DISTANCE, SOUND_FULLVOLUME );
|
||||
qalSourcef( ch->srcnum, AL_MAX_DISTANCE, 8192 );
|
||||
qalSourcef( ch->srcnum, AL_ROLLOFF_FACTOR, ch->dist_mult * ( 8192 - SOUND_FULLVOLUME ) );
|
||||
qalSourcei(ch->srcnum, AL_BUFFER, sc->bufnum);
|
||||
qalSourcei(ch->srcnum, AL_LOOPING, ch->autosound ? AL_TRUE : AL_FALSE);
|
||||
qalSourcef(ch->srcnum, AL_GAIN, ch->master_vol);
|
||||
qalSourcef(ch->srcnum, AL_REFERENCE_DISTANCE, SOUND_FULLVOLUME);
|
||||
qalSourcef(ch->srcnum, AL_MAX_DISTANCE, 8192);
|
||||
qalSourcef(ch->srcnum, AL_ROLLOFF_FACTOR, ch->dist_mult *
|
||||
(8192 - SOUND_FULLVOLUME));
|
||||
|
||||
AL_Spatialize( ch );
|
||||
AL_Spatialize(ch);
|
||||
|
||||
// play it
|
||||
qalSourcePlay( ch->srcnum );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
AL_StopChannel( ch );
|
||||
/* play it */
|
||||
qalSourcePlay(ch->srcnum);
|
||||
|
||||
if (qalGetError() != AL_NO_ERROR)
|
||||
{
|
||||
AL_StopChannel(ch);
|
||||
}
|
||||
}
|
||||
|
||||
void AL_StopAllChannels( void ) {
|
||||
int i;
|
||||
channel_t *ch;
|
||||
void
|
||||
AL_StopAllChannels(void)
|
||||
{
|
||||
int i;
|
||||
channel_t *ch;
|
||||
|
||||
ch = channels;
|
||||
for( i = 0; i < s_numchannels; i++, ch++ ) {
|
||||
|
||||
for (i = 0; i < s_numchannels; i++, ch++)
|
||||
{
|
||||
if (!ch->sfx)
|
||||
{
|
||||
continue;
|
||||
AL_StopChannel( ch );
|
||||
}
|
||||
|
||||
AL_StopChannel(ch);
|
||||
}
|
||||
|
||||
s_rawend = 0;
|
||||
S_AL_StreamDie();
|
||||
}
|
||||
|
||||
static channel_t *AL_FindLoopingSound( int entnum, sfx_t *sfx ) {
|
||||
int i;
|
||||
channel_t *ch;
|
||||
static channel_t *
|
||||
AL_FindLoopingSound(int entnum, sfx_t *sfx)
|
||||
{
|
||||
int i;
|
||||
channel_t *ch;
|
||||
|
||||
ch = channels;
|
||||
for( i = 0; i < s_numchannels; i++, ch++ ) {
|
||||
if( !ch->sfx )
|
||||
|
||||
for (i = 0; i < s_numchannels; i++, ch++)
|
||||
{
|
||||
if (!ch->sfx)
|
||||
{
|
||||
continue;
|
||||
if( !ch->autosound )
|
||||
}
|
||||
|
||||
if (!ch->autosound)
|
||||
{
|
||||
continue;
|
||||
if( ch->entnum != entnum )
|
||||
}
|
||||
|
||||
if (ch->entnum != entnum)
|
||||
{
|
||||
continue;
|
||||
if( ch->sfx != sfx )
|
||||
}
|
||||
|
||||
if (ch->sfx != sfx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void AL_AddLoopSounds( void ) {
|
||||
int i;
|
||||
int sounds[MAX_EDICTS];
|
||||
channel_t *ch;
|
||||
sfx_t *sfx;
|
||||
sfxcache_t *sc;
|
||||
int num;
|
||||
entity_state_t *ent;
|
||||
static void
|
||||
AL_AddLoopSounds(void)
|
||||
{
|
||||
int i;
|
||||
int sounds[MAX_EDICTS];
|
||||
channel_t *ch;
|
||||
sfx_t *sfx;
|
||||
sfxcache_t *sc;
|
||||
int num;
|
||||
entity_state_t *ent;
|
||||
|
||||
if( cls.state != ca_active || cl_paused->value || !s_ambient->value ) {
|
||||
if ((cls.state != ca_active) || cl_paused->value || !s_ambient->value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
S_BuildSoundList( sounds );
|
||||
S_BuildSoundList(sounds);
|
||||
|
||||
for( i = 0; i < cl.frame.num_entities; i++ ) {
|
||||
for (i = 0; i < cl.frame.num_entities; i++)
|
||||
{
|
||||
if (!sounds[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sfx = cl.sound_precache[sounds[i]];
|
||||
|
||||
if (!sfx)
|
||||
continue; // bad sound effect
|
||||
{
|
||||
continue; /* bad sound effect */
|
||||
}
|
||||
|
||||
sc = sfx->cache;
|
||||
|
||||
if (!sc)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
num = ( cl.frame.parse_entities + i ) & ( MAX_PARSE_ENTITIES - 1 );
|
||||
ent = &cl_parse_entities [ num ];
|
||||
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
|
||||
ent = &cl_parse_entities[num];
|
||||
|
||||
ch = AL_FindLoopingSound( ent->number, sfx );
|
||||
if( ch ) {
|
||||
ch = AL_FindLoopingSound(ent->number, sfx);
|
||||
|
||||
if (ch)
|
||||
{
|
||||
ch->autoframe = s_framecount;
|
||||
ch->end = paintedtime + sc->length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate a channel
|
||||
/* allocate a channel */
|
||||
ch = S_PickChannel(0, 0);
|
||||
if (!ch)
|
||||
continue;
|
||||
|
||||
ch->autosound = true; // remove next frame
|
||||
if (!ch)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ch->autosound = true; /* remove next frame */
|
||||
ch->autoframe = s_framecount;
|
||||
ch->sfx = sfx;
|
||||
ch->entnum = ent->number;
|
||||
|
@ -336,116 +425,145 @@ static void AL_AddLoopSounds( void ) {
|
|||
ch->dist_mult = SOUND_LOOPATTENUATE;
|
||||
ch->end = paintedtime + sc->length;
|
||||
|
||||
AL_PlayChannel( ch );
|
||||
AL_PlayChannel(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static void AL_IssuePlaysounds( void ) {
|
||||
static void
|
||||
AL_IssuePlaysounds(void)
|
||||
{
|
||||
playsound_t *ps;
|
||||
|
||||
// start any playsounds
|
||||
while (1) {
|
||||
/* start any playsounds */
|
||||
while (1)
|
||||
{
|
||||
ps = s_pendingplays.next;
|
||||
|
||||
if (ps == &s_pendingplays)
|
||||
break; // no more pending sounds
|
||||
{
|
||||
break; /* no more pending sounds */
|
||||
}
|
||||
|
||||
if (ps->begin > paintedtime)
|
||||
{
|
||||
break;
|
||||
S_IssuePlaysound (ps);
|
||||
}
|
||||
|
||||
S_IssuePlaysound(ps);
|
||||
}
|
||||
}
|
||||
|
||||
void AL_Update( void ) {
|
||||
int i;
|
||||
channel_t *ch;
|
||||
vec_t orientation[6];
|
||||
void
|
||||
AL_Update(void)
|
||||
{
|
||||
int i;
|
||||
channel_t *ch;
|
||||
vec_t orientation[6];
|
||||
|
||||
paintedtime = cl.time;
|
||||
|
||||
// set listener parameters
|
||||
qalListener3f( AL_POSITION, AL_UnpackVector( listener_origin ) );
|
||||
AL_CopyVector( listener_forward, orientation );
|
||||
AL_CopyVector( listener_up, orientation + 3 );
|
||||
qalListenerfv( AL_ORIENTATION, orientation );
|
||||
qalListenerf( AL_GAIN, s_volume->value );
|
||||
qalDistanceModel( AL_LINEAR_DISTANCE_CLAMPED );
|
||||
/* set listener parameters */
|
||||
qalListener3f(AL_POSITION, AL_UnpackVector(listener_origin));
|
||||
AL_CopyVector(listener_forward, orientation);
|
||||
AL_CopyVector(listener_up, orientation + 3);
|
||||
qalListenerfv(AL_ORIENTATION, orientation);
|
||||
qalListenerf(AL_GAIN, s_volume->value);
|
||||
qalDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
||||
|
||||
// update spatialization for dynamic sounds
|
||||
/* update spatialization for dynamic sounds */
|
||||
ch = channels;
|
||||
for( i = 0; i < s_numchannels; i++, ch++ ) {
|
||||
if( !ch->sfx )
|
||||
continue;
|
||||
|
||||
if( ch->autosound ) {
|
||||
// autosounds are regenerated fresh each frame
|
||||
if( ch->autoframe != s_framecount ) {
|
||||
AL_StopChannel( ch );
|
||||
for (i = 0; i < s_numchannels; i++, ch++)
|
||||
{
|
||||
if (!ch->sfx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch->autosound)
|
||||
{
|
||||
/* autosounds are regenerated fresh each frame */
|
||||
if (ch->autoframe != s_framecount)
|
||||
{
|
||||
AL_StopChannel(ch);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ALenum state;
|
||||
|
||||
qalGetError();
|
||||
qalGetSourcei( ch->srcnum, AL_SOURCE_STATE, &state );
|
||||
if( qalGetError() != AL_NO_ERROR || state == AL_STOPPED ) {
|
||||
AL_StopChannel( ch );
|
||||
qalGetSourcei(ch->srcnum, AL_SOURCE_STATE, &state);
|
||||
|
||||
if ((qalGetError() != AL_NO_ERROR) || (state == AL_STOPPED))
|
||||
{
|
||||
AL_StopChannel(ch);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_show->value) {
|
||||
Com_Printf ("%3i %s\n", ch->master_vol, ch->sfx->name);
|
||||
if (s_show->value)
|
||||
{
|
||||
Com_Printf("%3i %s\n", ch->master_vol, ch->sfx->name);
|
||||
}
|
||||
|
||||
AL_Spatialize(ch); // respatialize channel
|
||||
AL_Spatialize(ch); /* respatialize channel */
|
||||
}
|
||||
|
||||
s_framecount++;
|
||||
|
||||
// add loopsounds
|
||||
AL_AddLoopSounds ();
|
||||
/* add loopsounds */
|
||||
AL_AddLoopSounds();
|
||||
|
||||
// add music
|
||||
/* add music */
|
||||
OGG_Stream();
|
||||
S_AL_StreamUpdate();
|
||||
|
||||
AL_IssuePlaysounds();
|
||||
}
|
||||
|
||||
void AL_Underwater()
|
||||
void
|
||||
AL_Underwater()
|
||||
{
|
||||
int i;
|
||||
if(sound_started != SS_OAL) {
|
||||
|
||||
if (sound_started != SS_OAL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply to all sources
|
||||
/* Apply to all sources */
|
||||
for (i = 0; i < s_numchannels; i++)
|
||||
{
|
||||
qalSourcei(s_srcnums[i], AL_DIRECT_FILTER, underwaterFilter);
|
||||
}
|
||||
}
|
||||
|
||||
void AL_Overwater()
|
||||
void
|
||||
AL_Overwater()
|
||||
{
|
||||
int i;
|
||||
|
||||
// Apply to all sources
|
||||
/* Apply to all sources */
|
||||
for (i = 0; i < s_numchannels; i++)
|
||||
{
|
||||
qalSourcei(s_srcnums[i], AL_DIRECT_FILTER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void S_AL_StreamDie( void )
|
||||
static void
|
||||
S_AL_StreamDie(void)
|
||||
{
|
||||
int numBuffers;
|
||||
int numBuffers;
|
||||
|
||||
streamPlaying = false;
|
||||
qalSourceStop(streamSource);
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
qalGetSourcei( streamSource, AL_BUFFERS_QUEUED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
/* Un-queue any buffers, and delete them */
|
||||
qalGetSourcei(streamSource, AL_BUFFERS_QUEUED, &numBuffers);
|
||||
|
||||
while (numBuffers--)
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
|
||||
|
@ -454,14 +572,16 @@ static void S_AL_StreamDie( void )
|
|||
}
|
||||
}
|
||||
|
||||
static void S_AL_StreamUpdate( void )
|
||||
static void
|
||||
S_AL_StreamUpdate(void)
|
||||
{
|
||||
int numBuffers;
|
||||
ALint state;
|
||||
int numBuffers;
|
||||
ALint state;
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
qalGetSourcei( streamSource, AL_BUFFERS_PROCESSED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
/* Un-queue any buffers, and delete them */
|
||||
qalGetSourcei(streamSource, AL_BUFFERS_PROCESSED, &numBuffers);
|
||||
|
||||
while (numBuffers--)
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
|
||||
|
@ -469,70 +589,84 @@ static void S_AL_StreamUpdate( void )
|
|||
active_buffers--;
|
||||
}
|
||||
|
||||
// Start the streamSource playing if necessary
|
||||
qalGetSourcei( streamSource, AL_BUFFERS_QUEUED, &numBuffers );
|
||||
/* Start the streamSource playing if necessary */
|
||||
qalGetSourcei(streamSource, AL_BUFFERS_QUEUED, &numBuffers);
|
||||
|
||||
qalGetSourcei(streamSource, AL_SOURCE_STATE, &state);
|
||||
if(state == AL_STOPPED)
|
||||
|
||||
if (state == AL_STOPPED)
|
||||
{
|
||||
streamPlaying = false;
|
||||
}
|
||||
|
||||
if( !streamPlaying && numBuffers )
|
||||
if (!streamPlaying && numBuffers)
|
||||
{
|
||||
qalSourcePlay( streamSource );
|
||||
qalSourcePlay(streamSource);
|
||||
streamPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
static ALuint S_AL_Format(int width, int channels)
|
||||
static ALuint
|
||||
S_AL_Format(int width, int channels)
|
||||
{
|
||||
ALuint format = AL_FORMAT_MONO16;
|
||||
|
||||
// Work out format
|
||||
if(width == 1)
|
||||
/* Work out format */
|
||||
if (width == 1)
|
||||
{
|
||||
if(channels == 1)
|
||||
if (channels == 1)
|
||||
{
|
||||
format = AL_FORMAT_MONO8;
|
||||
else if(channels == 2)
|
||||
}
|
||||
else if (channels == 2)
|
||||
{
|
||||
format = AL_FORMAT_STEREO8;
|
||||
}
|
||||
}
|
||||
else if(width == 2)
|
||||
else if (width == 2)
|
||||
{
|
||||
if(channels == 1)
|
||||
if (channels == 1)
|
||||
{
|
||||
format = AL_FORMAT_MONO16;
|
||||
else if(channels == 2)
|
||||
}
|
||||
else if (channels == 2)
|
||||
{
|
||||
format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume )
|
||||
void
|
||||
AL_RawSamples(int samples, int rate, int width, int channels,
|
||||
byte *data, float volume)
|
||||
{
|
||||
ALuint buffer;
|
||||
ALuint format;
|
||||
|
||||
format = S_AL_Format( width, channels );
|
||||
format = S_AL_Format(width, channels);
|
||||
|
||||
// Create a buffer, and stuff the data into it
|
||||
/* Create a buffer, and stuff the data into it */
|
||||
qalGenBuffers(1, &buffer);
|
||||
qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);
|
||||
qalBufferData(buffer, format, (ALvoid *)data,
|
||||
(samples * width * channels), rate);
|
||||
active_buffers++;
|
||||
|
||||
// set volume
|
||||
qalSourcef( streamSource, AL_GAIN, volume );
|
||||
/* set volume */
|
||||
qalSourcef(streamSource, AL_GAIN, volume);
|
||||
|
||||
// Shove the data onto the streamSource
|
||||
/* Shove the data onto the streamSource */
|
||||
qalSourceQueueBuffers(streamSource, 1, &buffer);
|
||||
|
||||
// emulate behavior of S_RawSamples for s_rawend
|
||||
/* emulate behavior of S_RawSamples for s_rawend */
|
||||
s_rawend += samples;
|
||||
}
|
||||
|
||||
void AL_UnqueueRawSamples()
|
||||
void
|
||||
AL_UnqueueRawSamples()
|
||||
{
|
||||
S_AL_StreamDie();
|
||||
}
|
||||
|
||||
#endif // USE_OPENAL
|
||||
#endif /* USE_OPENAL */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,8 +19,9 @@
|
|||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* The sound caching. This file contains support functions for loading
|
||||
* the sound samples into the memory.
|
||||
* The sound caching. This file contains support functions for
|
||||
* processing the soundsamples, load them into the memory and
|
||||
* provide them to the SDL or OpenAL sound backend.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
@ -29,7 +30,7 @@
|
|||
#include "header/local.h"
|
||||
|
||||
void
|
||||
ResampleSfx ( sfx_t *sfx, int inrate, int inwidth, byte *data )
|
||||
ResampleSfx(sfx_t *sfx, int inrate, int inwidth, byte *data)
|
||||
{
|
||||
int outcount;
|
||||
int srcsample;
|
||||
|
@ -37,37 +38,38 @@ ResampleSfx ( sfx_t *sfx, int inrate, int inwidth, byte *data )
|
|||
int i;
|
||||
int sample;
|
||||
unsigned int samplefrac, fracstep;
|
||||
sfxcache_t *sc;
|
||||
sfxcache_t *sc;
|
||||
|
||||
sc = sfx->cache;
|
||||
|
||||
if ( !sc )
|
||||
if (!sc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
stepscale = (float) inrate / dma.speed; /* this is usually 0.5, 1, or 2 */
|
||||
stepscale = (float)inrate / dma.speed; /* this is usually 0.5, 1, or 2 */
|
||||
|
||||
outcount = (int) ( sc->length / stepscale );
|
||||
outcount = (int)(sc->length / stepscale);
|
||||
|
||||
if ( outcount == 0 )
|
||||
if (outcount == 0)
|
||||
{
|
||||
Com_Printf( "ResampleSfx: Invalid sound file '%s' (zero length)\n", sfx->name );
|
||||
Z_Free( sfx->cache );
|
||||
Com_Printf("ResampleSfx: Invalid sound file '%s' (zero length)\n",
|
||||
sfx->name);
|
||||
Z_Free(sfx->cache);
|
||||
sfx->cache = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
sc->length = outcount;
|
||||
|
||||
if ( sc->loopstart != -1 )
|
||||
if (sc->loopstart != -1)
|
||||
{
|
||||
sc->loopstart = (int) ( sc->loopstart / stepscale );
|
||||
sc->loopstart = (int)(sc->loopstart / stepscale);
|
||||
}
|
||||
|
||||
sc->speed = dma.speed;
|
||||
|
||||
if ( s_loadas8bit->value )
|
||||
if (s_loadas8bit->value)
|
||||
{
|
||||
sc->width = 1;
|
||||
}
|
||||
|
@ -81,62 +83,62 @@ ResampleSfx ( sfx_t *sfx, int inrate, int inwidth, byte *data )
|
|||
|
||||
/* resample / decimate to the current source rate */
|
||||
samplefrac = 0;
|
||||
fracstep = (int) ( stepscale * 256 );
|
||||
fracstep = (int)(stepscale * 256);
|
||||
|
||||
for ( i = 0; i < outcount; i++ )
|
||||
for (i = 0; i < outcount; i++)
|
||||
{
|
||||
srcsample = samplefrac >> 8;
|
||||
samplefrac += fracstep;
|
||||
|
||||
if ( inwidth == 2 )
|
||||
if (inwidth == 2)
|
||||
{
|
||||
sample = LittleShort( ( (short *) data ) [ srcsample ] );
|
||||
sample = LittleShort(((short *)data)[srcsample]);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sample = (int) ( (unsigned char) ( data [ srcsample ] ) - 128 ) << 8;
|
||||
sample = (int)((unsigned char)(data[srcsample]) - 128) << 8;
|
||||
}
|
||||
|
||||
if ( sc->width == 2 )
|
||||
if (sc->width == 2)
|
||||
{
|
||||
( (short *) sc->data ) [ i ] = sample;
|
||||
((short *)sc->data)[i] = sample;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
( (signed char *) sc->data ) [ i ] = sample >> 8;
|
||||
((signed char *)sc->data)[i] = sample >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sfxcache_t *
|
||||
S_LoadSound ( sfx_t *s )
|
||||
S_LoadSound(sfx_t *s)
|
||||
{
|
||||
char namebuffer [ MAX_QPATH ];
|
||||
byte *data;
|
||||
char namebuffer[MAX_QPATH];
|
||||
byte *data;
|
||||
wavinfo_t info;
|
||||
int len;
|
||||
float stepscale;
|
||||
sfxcache_t *sc;
|
||||
sfxcache_t *sc;
|
||||
int size;
|
||||
char *name;
|
||||
char *name;
|
||||
|
||||
if ( s->name [ 0 ] == '*' )
|
||||
if (s->name[0] == '*')
|
||||
{
|
||||
return ( NULL );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* see if still in memory */
|
||||
sc = s->cache;
|
||||
|
||||
if ( sc )
|
||||
if (sc)
|
||||
{
|
||||
return ( sc );
|
||||
return sc;
|
||||
}
|
||||
|
||||
/* load it in */
|
||||
if ( s->truename )
|
||||
if (s->truename)
|
||||
{
|
||||
name = s->truename;
|
||||
}
|
||||
|
@ -146,48 +148,52 @@ S_LoadSound ( sfx_t *s )
|
|||
name = s->name;
|
||||
}
|
||||
|
||||
if ( name [ 0 ] == '#' )
|
||||
if (name[0] == '#')
|
||||
{
|
||||
strcpy( namebuffer, &name [ 1 ] );
|
||||
} else {
|
||||
Com_sprintf( namebuffer, sizeof ( namebuffer ), "sound/%s", name );
|
||||
strcpy(namebuffer, &name[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_sprintf(namebuffer, sizeof(namebuffer), "sound/%s", name);
|
||||
}
|
||||
|
||||
size = FS_LoadFile( namebuffer, (void **) &data );
|
||||
size = FS_LoadFile(namebuffer, (void **)&data);
|
||||
|
||||
if ( !data )
|
||||
if (!data)
|
||||
{
|
||||
s->cache = NULL;
|
||||
Com_DPrintf( "Couldn't load %s\n", namebuffer );
|
||||
return ( NULL );
|
||||
Com_DPrintf("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info = GetWavinfo( s->name, data, size );
|
||||
info = GetWavinfo(s->name, data, size);
|
||||
|
||||
if ( info.channels != 1 )
|
||||
if (info.channels != 1)
|
||||
{
|
||||
Com_Printf( "%s is a stereo sample\n", s->name );
|
||||
FS_FreeFile( data );
|
||||
return ( NULL );
|
||||
Com_Printf("%s is a stereo sample\n", s->name);
|
||||
FS_FreeFile(data);
|
||||
return NULL;
|
||||
}
|
||||
if (sound_started != SS_OAL) {
|
||||
stepscale = (float) info.rate / dma.speed;
|
||||
len = (int) ( info.samples / stepscale );
|
||||
|
||||
if ( ( info.samples == 0 ) || ( len == 0 ) )
|
||||
if (sound_started != SS_OAL)
|
||||
{
|
||||
stepscale = (float)info.rate / dma.speed;
|
||||
len = (int)(info.samples / stepscale);
|
||||
|
||||
if ((info.samples == 0) || (len == 0))
|
||||
{
|
||||
Com_Printf( "WARNING: Zero length sound encountered: %s\n", s->name );
|
||||
FS_FreeFile( data );
|
||||
return ( NULL );
|
||||
Com_Printf("WARNING: Zero length sound encountered: %s\n", s->name);
|
||||
FS_FreeFile(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = len * info.width * info.channels;
|
||||
sc = s->cache = Z_Malloc( len + sizeof ( sfxcache_t ) );
|
||||
sc = s->cache = Z_Malloc(len + sizeof(sfxcache_t));
|
||||
|
||||
if ( !sc )
|
||||
if (!sc)
|
||||
{
|
||||
FS_FreeFile( data );
|
||||
return ( NULL );
|
||||
FS_FreeFile(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sc->length = info.samples;
|
||||
|
@ -199,12 +205,17 @@ S_LoadSound ( sfx_t *s )
|
|||
|
||||
#if USE_OPENAL
|
||||
if (sound_started == SS_OAL)
|
||||
{
|
||||
sc = AL_UploadSfx(s, &info, data + info.dataofs);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
ResampleSfx( s, sc->speed, sc->width, data + info.dataofs );
|
||||
{
|
||||
ResampleSfx(s, sc->speed, sc->width, data + info.dataofs);
|
||||
}
|
||||
|
||||
FS_FreeFile( data );
|
||||
FS_FreeFile(data);
|
||||
|
||||
return ( sc );
|
||||
return sc;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* This file implements a subset of the WAVE audio file format
|
||||
* This file implements a subset of the WAVE audio file format.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
@ -27,48 +27,45 @@
|
|||
#include "../header/client.h"
|
||||
#include "header/local.h"
|
||||
|
||||
// FIXME: this code is really fucked up, those global variables make me sick.
|
||||
// someone should clean this up one day..
|
||||
|
||||
byte *data_p;
|
||||
byte *iff_end;
|
||||
byte *last_chunk;
|
||||
byte *iff_data;
|
||||
int iff_chunk_len;
|
||||
byte *data_p;
|
||||
byte *iff_end;
|
||||
byte *last_chunk;
|
||||
byte *iff_data;
|
||||
int iff_chunk_len;
|
||||
|
||||
short
|
||||
GetLittleShort ( void )
|
||||
GetLittleShort(void)
|
||||
{
|
||||
short val = 0;
|
||||
|
||||
val = *data_p;
|
||||
val = val + ( *( data_p + 1 ) << 8 );
|
||||
val = val + (*(data_p + 1) << 8);
|
||||
data_p += 2;
|
||||
return ( val );
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
GetLittleLong ( void )
|
||||
GetLittleLong(void)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
val = *data_p;
|
||||
val = val + ( *( data_p + 1 ) << 8 );
|
||||
val = val + ( *( data_p + 2 ) << 16 );
|
||||
val = val + ( *( data_p + 3 ) << 24 );
|
||||
val = val + (*(data_p + 1) << 8);
|
||||
val = val + (*(data_p + 2) << 16);
|
||||
val = val + (*(data_p + 3) << 24);
|
||||
data_p += 4;
|
||||
return ( val );
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
FindNextChunk ( char *name )
|
||||
FindNextChunk(char *name)
|
||||
{
|
||||
while ( 1 )
|
||||
while (1)
|
||||
{
|
||||
data_p = last_chunk;
|
||||
data_p += 4;
|
||||
|
||||
if ( data_p >= iff_end )
|
||||
if (data_p >= iff_end)
|
||||
{
|
||||
data_p = NULL;
|
||||
return;
|
||||
|
@ -76,16 +73,16 @@ FindNextChunk ( char *name )
|
|||
|
||||
iff_chunk_len = GetLittleLong();
|
||||
|
||||
if ( iff_chunk_len < 0 )
|
||||
if (iff_chunk_len < 0)
|
||||
{
|
||||
data_p = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
data_p -= 8;
|
||||
last_chunk = data_p + 8 + ( ( iff_chunk_len + 1 ) & ~1 );
|
||||
last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1);
|
||||
|
||||
if ( !strncmp( (const char *) data_p, name, 4 ) )
|
||||
if (!strncmp((const char *)data_p, name, 4))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -93,57 +90,57 @@ FindNextChunk ( char *name )
|
|||
}
|
||||
|
||||
void
|
||||
FindChunk ( char *name )
|
||||
FindChunk(char *name)
|
||||
{
|
||||
last_chunk = iff_data;
|
||||
FindNextChunk( name );
|
||||
FindNextChunk(name);
|
||||
}
|
||||
|
||||
wavinfo_t
|
||||
GetWavinfo ( char *name, byte *wav, int wavlength )
|
||||
GetWavinfo(char *name, byte *wav, int wavlength)
|
||||
{
|
||||
wavinfo_t info;
|
||||
int i;
|
||||
int format;
|
||||
int samples;
|
||||
|
||||
memset( &info, 0, sizeof ( info ) );
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if ( !wav )
|
||||
if (!wav)
|
||||
{
|
||||
return ( info );
|
||||
return info;
|
||||
}
|
||||
|
||||
iff_data = wav;
|
||||
iff_end = wav + wavlength;
|
||||
|
||||
/* find "RIFF" chunk */
|
||||
FindChunk( "RIFF" );
|
||||
FindChunk("RIFF");
|
||||
|
||||
if ( !( data_p && !strncmp( (const char *) data_p + 8, "WAVE", 4 ) ) )
|
||||
if (!(data_p && !strncmp((const char *)data_p + 8, "WAVE", 4)))
|
||||
{
|
||||
Com_Printf( "Missing RIFF/WAVE chunks\n" );
|
||||
return ( info );
|
||||
Com_Printf("Missing RIFF/WAVE chunks\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
/* get "fmt " chunk */
|
||||
iff_data = data_p + 12;
|
||||
|
||||
FindChunk( "fmt " );
|
||||
FindChunk("fmt ");
|
||||
|
||||
if ( !data_p )
|
||||
if (!data_p)
|
||||
{
|
||||
Com_Printf( "Missing fmt chunk\n" );
|
||||
return ( info );
|
||||
Com_Printf("Missing fmt chunk\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
data_p += 8;
|
||||
format = GetLittleShort();
|
||||
|
||||
if ( format != 1 )
|
||||
if (format != 1)
|
||||
{
|
||||
Com_Printf( "Microsoft PCM format only\n" );
|
||||
return ( info );
|
||||
Com_Printf("Microsoft PCM format only\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
info.channels = GetLittleShort();
|
||||
|
@ -152,21 +149,24 @@ GetWavinfo ( char *name, byte *wav, int wavlength )
|
|||
info.width = GetLittleShort() / 8;
|
||||
|
||||
/* get cue chunk */
|
||||
FindChunk( "cue " );
|
||||
FindChunk("cue ");
|
||||
|
||||
if ( data_p )
|
||||
if (data_p)
|
||||
{
|
||||
data_p += 32;
|
||||
info.loopstart = GetLittleLong();
|
||||
|
||||
/* if the next chunk is a LIST chunk, look for a cue length marker */
|
||||
FindNextChunk( "LIST" );
|
||||
/* if the next chunk is a LIST chunk,
|
||||
look for a cue length marker */
|
||||
FindNextChunk("LIST");
|
||||
|
||||
if ( data_p )
|
||||
if (data_p)
|
||||
{
|
||||
if ( ( ( data_p - wav ) + 32 <= wavlength ) && !strncmp( (const char *) data_p + 28, "mark", 4 ) )
|
||||
if (((data_p - wav) + 32 <= wavlength) &&
|
||||
!strncmp((const 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;
|
||||
i = GetLittleLong(); /* samples in loop */
|
||||
info.samples = info.loopstart + i;
|
||||
|
@ -179,22 +179,22 @@ GetWavinfo ( char *name, byte *wav, int wavlength )
|
|||
}
|
||||
|
||||
/* find data chunk */
|
||||
FindChunk( "data" );
|
||||
FindChunk("data");
|
||||
|
||||
if ( !data_p )
|
||||
if (!data_p)
|
||||
{
|
||||
Com_Printf( "Missing data chunk\n" );
|
||||
return ( info );
|
||||
Com_Printf("Missing data chunk\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
data_p += 4;
|
||||
samples = GetLittleLong() / info.width;
|
||||
|
||||
if ( info.samples )
|
||||
if (info.samples)
|
||||
{
|
||||
if ( samples < info.samples )
|
||||
if (samples < info.samples)
|
||||
{
|
||||
Com_Error( ERR_DROP, "Sound %s has a bad loop length", name );
|
||||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -202,7 +202,8 @@ GetWavinfo ( char *name, byte *wav, int wavlength )
|
|||
info.samples = samples;
|
||||
}
|
||||
|
||||
info.dataofs = (int) ( data_p - wav );
|
||||
info.dataofs = (int)(data_p - wav);
|
||||
|
||||
return ( info );
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue