mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-04-11 20:51:37 +00:00
weitere Dateien des Soundsystems neu formatiert und kommentiert
This commit is contained in:
parent
0c4a7d291f
commit
fe587b7148
6 changed files with 604 additions and 721 deletions
|
@ -190,7 +190,7 @@ void S_Shutdown(void) {
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns the name of sound
|
||||
* Returns the name of a sound
|
||||
*/
|
||||
sfx_t *S_FindName (char *name, qboolean create) {
|
||||
int i;
|
||||
|
@ -296,7 +296,7 @@ void S_EndRegistration (void) {
|
|||
if (sfx->registration_sequence != s_registration_sequence) {
|
||||
/* don't need this sound */
|
||||
if (sfx->cache) /* it is possible to have a leftover */
|
||||
Z_Free (sfx->cache); /* from a server that didn't finish loading */
|
||||
Z_Free (sfx->cache); /* from a server that didn't finish loading */
|
||||
|
||||
memset (sfx, 0, sizeof(*sfx));
|
||||
|
||||
|
@ -383,9 +383,9 @@ void S_SpatializeOrigin (vec3_t origin, float master_vol, float dist_mult, int *
|
|||
dist -= SOUND_FULLVOLUME;
|
||||
|
||||
if (dist < 0)
|
||||
dist = 0; /* close enough to be at full volume */
|
||||
dist = 0; /* close enough to be at full volume */
|
||||
|
||||
dist *= dist_mult; /* different attenuation levels */
|
||||
dist *= dist_mult; /* different attenuation levels */
|
||||
|
||||
dot = DotProduct(listener_right, source_vec);
|
||||
|
||||
|
@ -796,7 +796,7 @@ void S_AddLoopSounds (void) {
|
|||
|
||||
ch->leftvol = left_total;
|
||||
ch->rightvol = right_total;
|
||||
ch->autosound = true; /* remove next frame */
|
||||
ch->autosound = true; /* remove next frame */
|
||||
ch->sfx = sfx;
|
||||
|
||||
/* Sometimes, the sc->length argument can become 0,
|
||||
|
@ -952,7 +952,7 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) {
|
|||
continue;
|
||||
}
|
||||
|
||||
S_Spatialize(ch); /* respatialize channel */
|
||||
S_Spatialize(ch); /* respatialize channel */
|
||||
|
||||
if (!ch->leftvol && !ch->rightvol) {
|
||||
memset (ch, 0, sizeof(*ch));
|
||||
|
@ -1107,3 +1107,4 @@ void S_SoundList(void) {
|
|||
|
||||
Com_Printf ("Total resident: %i\n", total);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,128 +1,113 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Local defines of the sound system
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
// snd_loc.h -- private sound functions
|
||||
|
||||
// !!! if this is changed, the asm code must change !!!
|
||||
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;
|
||||
int stereo;
|
||||
byte data[1]; // variable sized
|
||||
typedef struct {
|
||||
int length;
|
||||
int loopstart;
|
||||
int speed; /* not needed, because converted on load? */
|
||||
int width;
|
||||
int stereo;
|
||||
byte data[1]; /* variable sized */
|
||||
} sfxcache_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
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
|
||||
{
|
||||
/* 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
|
||||
qboolean fixed_origin; /* use origin field instead of entnum's origin */
|
||||
vec3_t origin;
|
||||
unsigned begin; // begin on this sample
|
||||
unsigned begin; /* begin on this sample */
|
||||
} playsound_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
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 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;
|
||||
|
||||
// !!! if this is changed, the asm code must change !!!
|
||||
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 OBSOLETE?
|
||||
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 */
|
||||
} channel_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int rate;
|
||||
int width;
|
||||
int channels;
|
||||
int loopstart;
|
||||
int samples;
|
||||
int dataofs; // chunk starts this many bytes from file start
|
||||
int dataofs; /* chunk starts this many bytes from file start */
|
||||
} wavinfo_t;
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
SYSTEM SPECIFIC FUNCTIONS
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
// initializes cycling through a DMA buffer and returns information on it
|
||||
/* initializes cycling through a DMA
|
||||
buffer and returns information on it */
|
||||
qboolean SNDDMA_Init(void);
|
||||
|
||||
// gets the current DMA position
|
||||
/* gets the current DMA position */
|
||||
int SNDDMA_GetDMAPos(void);
|
||||
|
||||
// shutdown the DMA xfer.
|
||||
/* shutdown the DMA xfer. */
|
||||
void SNDDMA_Shutdown(void);
|
||||
|
||||
void SNDDMA_BeginPainting (void);
|
||||
|
||||
void SNDDMA_Submit(void);
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_CHANNELS 32
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
|
||||
|
@ -148,17 +133,13 @@ extern cvar_t *s_testsound;
|
|||
extern cvar_t *s_primary;
|
||||
|
||||
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
|
||||
/* picks a channel based on priorities, empty slots, number of channels */
|
||||
channel_t *S_PickChannel(int entnum, int entchannel);
|
||||
|
||||
// spatializes a channel
|
||||
/* spatializes a channel */
|
||||
void S_Spatialize(channel_t *ch);
|
||||
|
|
|
@ -1,38 +1,39 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
// snd_mem.c: sound caching
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* The sound caching. This files manages a double linked list (a circle
|
||||
* buffer) which caches the sound samples and provides their memory
|
||||
* adresses to the low level sound backend. It also implements the WAV
|
||||
* fileformat and functions for loading the samples into the list.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "../header/client.h"
|
||||
#include "snd_loc.h"
|
||||
|
||||
int cache_full_cycle;
|
||||
|
||||
int cache_full_cycle;
|
||||
byte *S_Alloc (int size);
|
||||
|
||||
/*
|
||||
================
|
||||
ResampleSfx
|
||||
================
|
||||
*/
|
||||
void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data)
|
||||
{
|
||||
void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) {
|
||||
int outcount;
|
||||
int srcsample;
|
||||
float stepscale;
|
||||
|
@ -40,65 +41,63 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data)
|
|||
int sample;
|
||||
unsigned int samplefrac, fracstep;
|
||||
sfxcache_t *sc;
|
||||
|
||||
|
||||
sc = sfx->cache;
|
||||
|
||||
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);
|
||||
sc->length = outcount;
|
||||
|
||||
if (sc->loopstart != -1)
|
||||
sc->loopstart = (int)(sc->loopstart / stepscale);
|
||||
|
||||
sc->speed = dma.speed;
|
||||
|
||||
if (s_loadas8bit->value)
|
||||
sc->width = 1;
|
||||
|
||||
else
|
||||
sc->width = inwidth;
|
||||
|
||||
sc->stereo = 0;
|
||||
|
||||
// resample / decimate to the current source rate
|
||||
|
||||
if (stepscale == 1 && inwidth == 1 && sc->width == 1)
|
||||
{
|
||||
// fast special case
|
||||
/* resample / decimate to the current source rate */
|
||||
if (stepscale == 1 && inwidth == 1 && sc->width == 1) {
|
||||
/* fast special case */
|
||||
for (i=0 ; i<outcount ; i++)
|
||||
((signed char *)sc->data)[i]
|
||||
= (int)( (unsigned char)(data[i]) - 128);
|
||||
}
|
||||
else
|
||||
{
|
||||
// general case
|
||||
|
||||
} else {
|
||||
/* general case */
|
||||
samplefrac = 0;
|
||||
fracstep = (int)(stepscale*256);
|
||||
for (i=0 ; i<outcount ; i++)
|
||||
{
|
||||
|
||||
for (i=0 ; i<outcount ; i++) {
|
||||
srcsample = samplefrac >> 8;
|
||||
samplefrac += fracstep;
|
||||
|
||||
if (inwidth == 2)
|
||||
sample = LittleShort ( ((short *)data)[srcsample] );
|
||||
|
||||
else
|
||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
||||
|
||||
if (sc->width == 2)
|
||||
((short *)sc->data)[i] = sample;
|
||||
|
||||
else
|
||||
((signed char *)sc->data)[i] = sample >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
==============
|
||||
S_LoadSound
|
||||
==============
|
||||
*/
|
||||
sfxcache_t *S_LoadSound (sfx_t *s)
|
||||
{
|
||||
char namebuffer[MAX_QPATH];
|
||||
sfxcache_t *S_LoadSound (sfx_t *s) {
|
||||
char namebuffer[MAX_QPATH];
|
||||
byte *data;
|
||||
wavinfo_t info;
|
||||
int len;
|
||||
|
@ -110,58 +109,59 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
if (s->name[0] == '*')
|
||||
return NULL;
|
||||
|
||||
// see if still in memory
|
||||
/* see if still in memory */
|
||||
sc = s->cache;
|
||||
|
||||
if (sc)
|
||||
return sc;
|
||||
|
||||
// load it in
|
||||
/* load it in */
|
||||
if (s->truename)
|
||||
name = s->truename;
|
||||
|
||||
else
|
||||
name = s->name;
|
||||
|
||||
if (name[0] == '#')
|
||||
strcpy(namebuffer, &name[1]);
|
||||
|
||||
else
|
||||
Com_sprintf (namebuffer, sizeof(namebuffer), "sound/%s", name);
|
||||
|
||||
size = FS_LoadFile (namebuffer, (void **)&data);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
if (!data) {
|
||||
s->cache = NULL;
|
||||
Com_DPrintf ("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
stepscale = (float)info.rate / dma.speed;
|
||||
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;
|
||||
}
|
||||
if (info.samples == 0 || len == 0) {
|
||||
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));
|
||||
if (!sc)
|
||||
{
|
||||
|
||||
if (!sc) {
|
||||
FS_FreeFile (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
sc->length = info.samples;
|
||||
sc->loopstart = info.loopstart;
|
||||
sc->speed = info.rate;
|
||||
|
@ -175,23 +175,13 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
return sc;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
WAV loading
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
byte *data_p;
|
||||
byte *iff_end;
|
||||
byte *last_chunk;
|
||||
byte *iff_data;
|
||||
int iff_chunk_len;
|
||||
|
||||
|
||||
short GetLittleShort(void)
|
||||
{
|
||||
short GetLittleShort(void) {
|
||||
short val = 0;
|
||||
val = *data_p;
|
||||
val = val + (*(data_p+1)<<8);
|
||||
|
@ -199,8 +189,7 @@ short GetLittleShort(void)
|
|||
return val;
|
||||
}
|
||||
|
||||
int GetLittleLong(void)
|
||||
{
|
||||
int GetLittleLong(void) {
|
||||
int val = 0;
|
||||
val = *data_p;
|
||||
val = val + (*(data_p+1)<<8);
|
||||
|
@ -210,46 +199,44 @@ int GetLittleLong(void)
|
|||
return val;
|
||||
}
|
||||
|
||||
void FindNextChunk(char *name)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
void FindNextChunk(char *name) {
|
||||
while (1) {
|
||||
data_p=last_chunk;
|
||||
|
||||
if (data_p >= iff_end)
|
||||
{ // didn't find the chunk
|
||||
if (data_p >= iff_end) {
|
||||
/* didn't find the chunk */
|
||||
data_p = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
data_p += 4;
|
||||
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 );
|
||||
|
||||
if (!strncmp((const char *)data_p, name, 4))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void FindChunk(char *name)
|
||||
{
|
||||
void FindChunk(char *name) {
|
||||
last_chunk = iff_data;
|
||||
FindNextChunk (name);
|
||||
}
|
||||
|
||||
void DumpChunks(void)
|
||||
{
|
||||
void DumpChunks(void) {
|
||||
char str[5];
|
||||
|
||||
|
||||
str[4] = 0;
|
||||
data_p=iff_data;
|
||||
do
|
||||
{
|
||||
|
||||
do {
|
||||
memcpy (str, data_p, 4);
|
||||
data_p += 4;
|
||||
iff_chunk_len = GetLittleLong();
|
||||
|
@ -258,13 +245,7 @@ void DumpChunks(void)
|
|||
} while (data_p < iff_end);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
GetWavinfo
|
||||
============
|
||||
*/
|
||||
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
|
||||
{
|
||||
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) {
|
||||
wavinfo_t info;
|
||||
int i;
|
||||
int format;
|
||||
|
@ -274,31 +255,32 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
|
|||
|
||||
if (!wav)
|
||||
return info;
|
||||
|
||||
|
||||
iff_data = wav;
|
||||
iff_end = wav + wavlength;
|
||||
|
||||
// find "RIFF" chunk
|
||||
/* find "RIFF" chunk */
|
||||
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;
|
||||
}
|
||||
|
||||
// get "fmt " chunk
|
||||
/* get "fmt " chunk */
|
||||
iff_data = data_p + 12;
|
||||
|
||||
FindChunk("fmt ");
|
||||
if (!data_p)
|
||||
{
|
||||
|
||||
if (!data_p) {
|
||||
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;
|
||||
}
|
||||
|
@ -308,32 +290,32 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
|
|||
data_p += 4+2;
|
||||
info.width = GetLittleShort() / 8;
|
||||
|
||||
// get cue chunk
|
||||
/* get cue chunk */
|
||||
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
|
||||
/* if the next chunk is a LIST chunk, look for a cue length marker */
|
||||
FindNextChunk ("LIST");
|
||||
if (data_p)
|
||||
{
|
||||
if (!strncmp ((const char *)data_p + 28, "mark", 4))
|
||||
{ // this is not a proper parse, but it works with cooledit...
|
||||
|
||||
if (data_p) {
|
||||
if (!strncmp ((const char *)data_p + 28, "mark", 4)) {
|
||||
/* this is not a proper parse, but it works with cooledit... */
|
||||
data_p += 24;
|
||||
i = GetLittleLong (); // samples in loop
|
||||
i = GetLittleLong (); /* samples in loop */
|
||||
info.samples = info.loopstart + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
} else
|
||||
info.loopstart = -1;
|
||||
|
||||
// find data chunk
|
||||
/* find data chunk */
|
||||
FindChunk("data");
|
||||
if (!data_p)
|
||||
{
|
||||
|
||||
if (!data_p) {
|
||||
Com_Printf("Missing data chunk\n");
|
||||
return info;
|
||||
}
|
||||
|
@ -341,16 +323,14 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
|
|||
data_p += 4;
|
||||
samples = GetLittleLong () / info.width;
|
||||
|
||||
if (info.samples)
|
||||
{
|
||||
if (info.samples) {
|
||||
if (samples < info.samples)
|
||||
Com_Error (ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
else
|
||||
|
||||
} else
|
||||
info.samples = samples;
|
||||
|
||||
info.dataofs = data_p - wav;
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,80 +1,91 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
// snd_mix.c -- portable code to mix sounds for snd_dma.c
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* This code mixes two or more sound samples into one. It also
|
||||
* implements sample rate changing and per channel extraction.
|
||||
* It's called by the upper level sound framework, snd_dma.c
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "../header/client.h"
|
||||
#include "snd_loc.h"
|
||||
|
||||
#define PAINTBUFFER_SIZE 8192
|
||||
#define PAINTBUFFER_SIZE 8192
|
||||
|
||||
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
|
||||
int snd_scaletable[32][256];
|
||||
int *snd_p, snd_linear_count, snd_vol;
|
||||
short *snd_out;
|
||||
|
||||
void S_WriteLinearBlastStereo16 (void)
|
||||
{
|
||||
void S_WriteLinearBlastStereo16 (void) {
|
||||
int i;
|
||||
int val;
|
||||
|
||||
for (i=0 ; i<snd_linear_count ; i+=2)
|
||||
{
|
||||
for (i=0 ; i<snd_linear_count ; i+=2) {
|
||||
val = snd_p[i]>>8;
|
||||
|
||||
if (val > 0x7fff)
|
||||
snd_out[i] = 0x7fff;
|
||||
|
||||
else if (val < (short)0x8000)
|
||||
snd_out[i] = (short)0x8000;
|
||||
|
||||
else
|
||||
snd_out[i] = val;
|
||||
|
||||
val = snd_p[i+1]>>8;
|
||||
|
||||
if (val > 0x7fff)
|
||||
snd_out[i+1] = 0x7fff;
|
||||
|
||||
else if (val < (short)0x8000)
|
||||
snd_out[i+1] = (short)0x8000;
|
||||
|
||||
else
|
||||
snd_out[i+1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void S_TransferStereo16 (unsigned long *pbuf, int endtime)
|
||||
{
|
||||
void S_TransferStereo16 (unsigned long *pbuf, int endtime) {
|
||||
int lpos;
|
||||
int lpaintedtime;
|
||||
|
||||
|
||||
snd_p = (int *) paintbuffer;
|
||||
lpaintedtime = paintedtime;
|
||||
|
||||
while (lpaintedtime < endtime)
|
||||
{
|
||||
// handle recirculating buffer issues
|
||||
while (lpaintedtime < endtime) {
|
||||
/* handle recirculating buffer issues */
|
||||
lpos = lpaintedtime & ((dma.samples>>1)-1);
|
||||
|
||||
snd_out = (short *) pbuf + (lpos<<1);
|
||||
|
||||
snd_linear_count = (dma.samples>>1) - lpos;
|
||||
|
||||
if (lpaintedtime + snd_linear_count > endtime)
|
||||
snd_linear_count = endtime - lpaintedtime;
|
||||
|
||||
snd_linear_count <<= 1;
|
||||
|
||||
// write a linear blast of samples
|
||||
/* write a linear blast of samples */
|
||||
S_WriteLinearBlastStereo16 ();
|
||||
|
||||
snd_p += snd_linear_count;
|
||||
|
@ -82,14 +93,7 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_TransferPaintBuffer
|
||||
|
||||
===================
|
||||
*/
|
||||
void S_TransferPaintBuffer(int endtime)
|
||||
{
|
||||
void S_TransferPaintBuffer(int endtime) {
|
||||
int out_idx;
|
||||
int count;
|
||||
int out_mask;
|
||||
|
@ -100,64 +104,69 @@ void S_TransferPaintBuffer(int endtime)
|
|||
|
||||
pbuf = (unsigned long *)dma.buffer;
|
||||
|
||||
if (s_testsound->value)
|
||||
{
|
||||
if (s_testsound->value) {
|
||||
static float x = 0.05;
|
||||
static float y = 0.0001;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
x += y;
|
||||
|
||||
if (x > 0.15)
|
||||
y = -0.0001;
|
||||
|
||||
else if (x < 0.0005)
|
||||
y = 0.0001;
|
||||
|
||||
// write a fixed sine wave
|
||||
/* write a fixed sine wave */
|
||||
count = (endtime - paintedtime);
|
||||
|
||||
for (i=0 ; i<count ; i++)
|
||||
paintbuffer[i].left = paintbuffer[i].right = (int)((float)sin((paintedtime+i)*0.1f)*20000*256);
|
||||
}
|
||||
|
||||
|
||||
if (dma.samplebits == 16 && dma.channels == 2)
|
||||
{ // optimized case
|
||||
if (dma.samplebits == 16 && dma.channels == 2) {
|
||||
/* optimized case */
|
||||
S_TransferStereo16 (pbuf, endtime);
|
||||
}
|
||||
else
|
||||
{ // general case
|
||||
|
||||
} else {
|
||||
/* general case */
|
||||
p = (int *) paintbuffer;
|
||||
count = (endtime - paintedtime) * dma.channels;
|
||||
out_mask = dma.samples - 1;
|
||||
out_mask = dma.samples - 1;
|
||||
out_idx = paintedtime * dma.channels & out_mask;
|
||||
step = 3 - dma.channels;
|
||||
|
||||
if (dma.samplebits == 16)
|
||||
{
|
||||
if (dma.samplebits == 16) {
|
||||
short *out = (short *) pbuf;
|
||||
while (count--)
|
||||
{
|
||||
|
||||
while (count--) {
|
||||
val = *p >> 8;
|
||||
p+= step;
|
||||
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
|
||||
else if (val < (short)0x8000)
|
||||
val = (short)0x8000;
|
||||
|
||||
out[out_idx] = val;
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
}
|
||||
else if (dma.samplebits == 8)
|
||||
{
|
||||
|
||||
} else if (dma.samplebits == 8) {
|
||||
unsigned char *out = (unsigned char *) pbuf;
|
||||
while (count--)
|
||||
{
|
||||
|
||||
while (count--) {
|
||||
val = *p >> 8;
|
||||
p+= step;
|
||||
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
|
||||
else if (val < (short)0x8000)
|
||||
val = (short)0x8000;
|
||||
|
||||
out[out_idx] = (val>>8) + 128;
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
|
@ -165,20 +174,10 @@ void S_TransferPaintBuffer(int endtime)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
CHANNEL MIXING
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
|
||||
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
|
||||
|
||||
void S_PaintChannels(int endtime)
|
||||
{
|
||||
void S_PaintChannels(int endtime) {
|
||||
int i;
|
||||
int end;
|
||||
channel_t *ch;
|
||||
|
@ -188,135 +187,129 @@ void S_PaintChannels(int endtime)
|
|||
|
||||
snd_vol = s_volume->value*256;
|
||||
|
||||
while (paintedtime < endtime)
|
||||
{
|
||||
// if paintbuffer is smaller than DMA buffer
|
||||
while (paintedtime < endtime) {
|
||||
/* if paintbuffer is smaller than DMA buffer */
|
||||
end = endtime;
|
||||
|
||||
if (endtime - paintedtime > PAINTBUFFER_SIZE)
|
||||
end = paintedtime + PAINTBUFFER_SIZE;
|
||||
|
||||
// start any playsounds
|
||||
while (1)
|
||||
{
|
||||
/* start any playsounds */
|
||||
while (1) {
|
||||
ps = s_pendingplays.next;
|
||||
|
||||
|
||||
if (ps == NULL)
|
||||
break;
|
||||
|
||||
if (ps == &s_pendingplays)
|
||||
break; // no more pending sounds
|
||||
if (ps->begin <= paintedtime)
|
||||
{
|
||||
break; /* no more pending sounds */
|
||||
|
||||
if (ps->begin <= paintedtime) {
|
||||
S_IssuePlaysound (ps);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ps->begin < end)
|
||||
end = ps->begin; // stop here
|
||||
end = ps->begin; /* stop here */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// clear the paint buffer
|
||||
if (s_rawend < paintedtime)
|
||||
{
|
||||
/* clear the paint buffer */
|
||||
if (s_rawend < paintedtime) {
|
||||
memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
|
||||
}
|
||||
else
|
||||
{ // copy from the streaming sound source
|
||||
|
||||
} else {
|
||||
/* copy from the streaming sound source */
|
||||
int s;
|
||||
int stop;
|
||||
|
||||
stop = (end < s_rawend) ? end : s_rawend;
|
||||
|
||||
for (i=paintedtime ; i<stop ; i++)
|
||||
{
|
||||
for (i=paintedtime ; i<stop ; i++) {
|
||||
s = i&(MAX_RAW_SAMPLES-1);
|
||||
paintbuffer[i-paintedtime] = s_rawsamples[s];
|
||||
}
|
||||
for ( ; i<end ; i++)
|
||||
{
|
||||
|
||||
for ( ; i<end ; i++) {
|
||||
paintbuffer[i-paintedtime].left =
|
||||
paintbuffer[i-paintedtime].right = 0;
|
||||
paintbuffer[i-paintedtime].right = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// paint in the channels.
|
||||
/* paint in the channels. */
|
||||
ch = channels;
|
||||
for (i=0; i<MAX_CHANNELS ; i++, ch++)
|
||||
{
|
||||
|
||||
for (i=0; i<MAX_CHANNELS ; i++, ch++) {
|
||||
ltime = paintedtime;
|
||||
|
||||
while (ltime < end)
|
||||
{
|
||||
|
||||
while (ltime < end) {
|
||||
if (!ch->sfx || (!ch->leftvol && !ch->rightvol) )
|
||||
break;
|
||||
|
||||
// max painting is to the end of the buffer
|
||||
/* max painting is to the end of the buffer */
|
||||
count = end - ltime;
|
||||
|
||||
// might be stopped by running out of data
|
||||
/* might be stopped by running out of data */
|
||||
if (ch->end - ltime < count)
|
||||
count = ch->end - ltime;
|
||||
|
||||
|
||||
sc = S_LoadSound (ch->sfx);
|
||||
|
||||
if (!sc)
|
||||
break;
|
||||
|
||||
if (count > 0 && ch->sfx)
|
||||
{
|
||||
if (sc->width == 1)// FIXME; 8 bit asm is wrong now
|
||||
if (count > 0 && ch->sfx) {
|
||||
if (sc->width == 1)
|
||||
S_PaintChannelFrom8(ch, sc, count, ltime - paintedtime);
|
||||
|
||||
else
|
||||
S_PaintChannelFrom16(ch, sc, count, ltime - paintedtime);
|
||||
|
||||
|
||||
ltime += count;
|
||||
}
|
||||
|
||||
// if at end of loop, restart
|
||||
if (ltime >= ch->end)
|
||||
{
|
||||
if (ch->autosound)
|
||||
{ // autolooping sounds always go back to start
|
||||
/* if at end of loop, restart */
|
||||
if (ltime >= ch->end) {
|
||||
if (ch->autosound) {
|
||||
/* autolooping sounds always go back to start */
|
||||
ch->pos = 0;
|
||||
ch->end = ltime + sc->length;
|
||||
}
|
||||
else if (sc->loopstart >= 0)
|
||||
{
|
||||
|
||||
} else if (sc->loopstart >= 0) {
|
||||
ch->pos = sc->loopstart;
|
||||
ch->end = ltime + sc->length - ch->pos;
|
||||
}
|
||||
else
|
||||
{ // channel just stopped
|
||||
|
||||
} else {
|
||||
/* channel just stopped */
|
||||
ch->sfx = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// transfer out according to DMA format
|
||||
/* transfer out according to DMA format */
|
||||
S_TransferPaintBuffer(end);
|
||||
paintedtime = end;
|
||||
}
|
||||
}
|
||||
|
||||
void S_InitScaletable (void)
|
||||
{
|
||||
void S_InitScaletable (void) {
|
||||
int i, j;
|
||||
int scale;
|
||||
|
||||
s_volume->modified = false;
|
||||
for (i=0 ; i<32 ; i++)
|
||||
{
|
||||
|
||||
for (i=0 ; i<32 ; i++) {
|
||||
scale = (int)(i * 8 * 256 * s_volume->value);
|
||||
|
||||
for (j=0 ; j<256 ; j++)
|
||||
snd_scaletable[i][j] = ((signed char)j) * scale;
|
||||
}
|
||||
}
|
||||
|
||||
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int offset)
|
||||
{
|
||||
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int offset) {
|
||||
int data;
|
||||
int *lscale, *rscale;
|
||||
unsigned char *sfx;
|
||||
|
@ -325,29 +318,26 @@ void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int offset)
|
|||
|
||||
if (ch->leftvol > 255)
|
||||
ch->leftvol = 255;
|
||||
|
||||
if (ch->rightvol > 255)
|
||||
ch->rightvol = 255;
|
||||
|
||||
//ZOID-- >>11 has been changed to >>3, >>11 didn't make much sense
|
||||
//as it would always be zero.
|
||||
|
||||
lscale = snd_scaletable[ ch->leftvol >> 3];
|
||||
rscale = snd_scaletable[ ch->rightvol >> 3];
|
||||
sfx = sc->data + ch->pos;
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
|
||||
for (i=0 ; i<count ; i++, samp++)
|
||||
{
|
||||
for (i=0 ; i<count ; i++, samp++) {
|
||||
data = sfx[i];
|
||||
samp->left += lscale[data];
|
||||
samp->right += rscale[data];
|
||||
}
|
||||
|
||||
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset)
|
||||
{
|
||||
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset) {
|
||||
int data;
|
||||
int left, right;
|
||||
int leftvol, rightvol;
|
||||
|
@ -360,8 +350,8 @@ void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset)
|
|||
sfx = (signed short *)sc->data + ch->pos;
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
for (i=0 ; i<count ; i++, samp++)
|
||||
{
|
||||
|
||||
for (i=0 ; i<count ; i++, samp++) {
|
||||
data = sfx[i];
|
||||
left = (data * leftvol)>>8;
|
||||
right = (data * rightvol)>>8;
|
||||
|
@ -371,4 +361,3 @@ void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset)
|
|||
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,32 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
|
||||
OGG Vorbis decoding
|
||||
|
||||
==========================================================
|
||||
*/
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* This file implements an interface to libvorbis for decoding
|
||||
* OGG/Vorbis files. Strongly spoken this file isn't part of the
|
||||
* sound system but part of the main client. It justs converts
|
||||
* Vorbis streams into normal, raw Wave stream which are injected
|
||||
* into snd_mem.c as if they were normal wave files. At this moment
|
||||
* only background music playback and in theory .cin movie file
|
||||
* playback is supported.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
@ -31,35 +36,30 @@
|
|||
#include "snd_loc.h"
|
||||
#include "snd_ogg.h"
|
||||
|
||||
extern int sound_started; /* Sound initialization flag. */
|
||||
extern cvar_t *fs_basedir; /* Path to "music". */
|
||||
extern int sound_started; /* Sound initialization flag. */
|
||||
extern cvar_t *fs_basedir; /* Path to "music". */
|
||||
|
||||
qboolean ogg_first_init = true; /* First initialization flag. */
|
||||
qboolean ogg_started = false; /* Initialization flag. */
|
||||
byte *ogg_buffer; /* File buffer. */
|
||||
char **ogg_filelist; /* List of Ogg Vorbis files. */
|
||||
char ovBuf[4096]; /* Buffer for sound. */
|
||||
int ogg_curfile; /* Index of currently played file. */
|
||||
int ogg_numfiles; /* Number of Ogg Vorbis files. */
|
||||
int ovSection; /* Position in Ogg Vorbis file. */
|
||||
ogg_status_t ogg_status; /* Status indicator. */
|
||||
cvar_t *ogg_autoplay; /* Play this song when started. */
|
||||
cvar_t *ogg_check; /* Check Ogg files or not. */
|
||||
cvar_t *ogg_playlist; /* Playlist. */
|
||||
cvar_t *ogg_sequence; /* Sequence play indicator. */
|
||||
cvar_t *ogg_volume; /* Music volume. */
|
||||
OggVorbis_File ovFile; /* Ogg Vorbis file. */
|
||||
qboolean ogg_first_init = true; /* First initialization flag. */
|
||||
qboolean ogg_started = false; /* Initialization flag. */
|
||||
byte *ogg_buffer; /* File buffer. */
|
||||
char **ogg_filelist; /* List of Ogg Vorbis files. */
|
||||
char ovBuf[4096]; /* Buffer for sound. */
|
||||
int ogg_curfile; /* Index of currently played file. */
|
||||
int ogg_numfiles; /* Number of Ogg Vorbis files. */
|
||||
int ovSection; /* Position in Ogg Vorbis file. */
|
||||
ogg_status_t ogg_status; /* Status indicator. */
|
||||
cvar_t *ogg_autoplay; /* Play this song when started. */
|
||||
cvar_t *ogg_check; /* Check Ogg files or not. */
|
||||
cvar_t *ogg_playlist; /* Playlist. */
|
||||
cvar_t *ogg_sequence; /* Sequence play indicator. */
|
||||
cvar_t *ogg_volume; /* Music volume. */
|
||||
OggVorbis_File ovFile; /* Ogg Vorbis file. */
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Init
|
||||
|
||||
Initialize the Ogg Vorbis subsystem.
|
||||
==========
|
||||
*/
|
||||
void OGG_Init(void)
|
||||
{
|
||||
cvar_t *cv; /* Cvar pointer. */
|
||||
* Initialize the Ogg Vorbis subsystem.
|
||||
*/
|
||||
void OGG_Init(void) {
|
||||
cvar_t *cv; /* Cvar pointer. */
|
||||
|
||||
if (ogg_started)
|
||||
return;
|
||||
|
@ -68,6 +68,7 @@ void OGG_Init(void)
|
|||
|
||||
/* Skip initialization if disabled. */
|
||||
cv = Cvar_Get ("ogg_enable", "0", CVAR_ARCHIVE);
|
||||
|
||||
if (cv->value != 1) {
|
||||
Com_Printf ("Ogg Vorbis not initializing.\n");
|
||||
return;
|
||||
|
@ -92,8 +93,10 @@ void OGG_Init(void)
|
|||
|
||||
/* Build list of files. */
|
||||
ogg_numfiles = 0;
|
||||
|
||||
if (ogg_playlist->string[0] != '\0')
|
||||
OGG_LoadPlaylist(ogg_playlist->string);
|
||||
|
||||
if (ogg_numfiles == 0)
|
||||
OGG_LoadFileList();
|
||||
|
||||
|
@ -124,14 +127,9 @@ void OGG_Init(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Shutdown
|
||||
|
||||
Shutdown the Ogg Vorbis subsystem.
|
||||
==========
|
||||
*/
|
||||
void OGG_Shutdown(void)
|
||||
{
|
||||
* Shutdown the Ogg Vorbis subsystem.
|
||||
*/
|
||||
void OGG_Shutdown(void) {
|
||||
|
||||
if (!ogg_started)
|
||||
return;
|
||||
|
@ -157,42 +155,34 @@ void OGG_Shutdown(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Reinit
|
||||
|
||||
Reinitialize the Ogg Vorbis subsystem.
|
||||
==========
|
||||
*/
|
||||
void OGG_Reinit(void)
|
||||
{
|
||||
* Reinitialize the Ogg Vorbis subsystem.
|
||||
*/
|
||||
void OGG_Reinit(void) {
|
||||
|
||||
OGG_Shutdown();
|
||||
OGG_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Check
|
||||
|
||||
Check if the file is a valid Ogg Vorbis file.
|
||||
==========
|
||||
*/
|
||||
qboolean OGG_Check(char *name)
|
||||
{
|
||||
qboolean res; /* Return value. */
|
||||
byte *buffer; /* File buffer. */
|
||||
int size; /* File size. */
|
||||
OggVorbis_File ovf; /* Ogg Vorbis file. */
|
||||
* Check if the file is a valid Ogg Vorbis file.
|
||||
*/
|
||||
qboolean OGG_Check(char *name) {
|
||||
qboolean res; /* Return value. */
|
||||
byte *buffer; /* File buffer. */
|
||||
int size; /* File size. */
|
||||
OggVorbis_File ovf; /* Ogg Vorbis file. */
|
||||
|
||||
if (ogg_check->value == 0)
|
||||
return (true);
|
||||
|
||||
res = false;
|
||||
|
||||
if ((size = FS_LoadFile(name, (void**)&buffer)) > 0) {
|
||||
if (ov_test(NULL, &ovf, (char *)buffer, size) == 0) {
|
||||
res = true;
|
||||
ov_clear(&ovf);
|
||||
}
|
||||
|
||||
FS_FreeFile(buffer);
|
||||
}
|
||||
|
||||
|
@ -200,16 +190,11 @@ qboolean OGG_Check(char *name)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Seek
|
||||
|
||||
Change position in the file.
|
||||
==========
|
||||
*/
|
||||
void OGG_Seek(ogg_seek_t type, double offset)
|
||||
{
|
||||
double pos; /* Position in file (in seconds). */
|
||||
double total; /* Length of file (in seconds). */
|
||||
* Change position in the file.
|
||||
*/
|
||||
void OGG_Seek(ogg_seek_t type, double offset) {
|
||||
double pos; /* Position in file (in seconds). */
|
||||
double total; /* Length of file (in seconds). */
|
||||
|
||||
/* Check if the file is seekable. */
|
||||
if (ov_seekable(&ovFile) == 0) {
|
||||
|
@ -222,43 +207,46 @@ void OGG_Seek(ogg_seek_t type, double offset)
|
|||
total = ov_time_total(&ovFile, -1);
|
||||
|
||||
switch (type) {
|
||||
case ABS:
|
||||
if (offset >= 0 && offset <= total) {
|
||||
if (ov_time_seek(&ovFile, offset) != 0)
|
||||
Com_Printf("OGG_Seek: could not seek.\n");
|
||||
else
|
||||
Com_Printf("%0.2f -> %0.2f of %0.2f.\n", pos, offset, total);
|
||||
} else
|
||||
Com_Printf("OGG_Seek: invalid offset.\n");
|
||||
break;
|
||||
case REL:
|
||||
if (pos + offset >= 0 && pos + offset <= total) {
|
||||
if (ov_time_seek(&ovFile, pos + offset) != 0)
|
||||
Com_Printf("OGG_Seek: could not seek.\n");
|
||||
else
|
||||
Com_Printf("%0.2f -> %0.2f of %0.2f.\n", pos, pos + offset, total);
|
||||
} else
|
||||
Com_Printf("OGG_Seek: invalid offset.\n");
|
||||
break;
|
||||
case ABS:
|
||||
|
||||
if (offset >= 0 && offset <= total) {
|
||||
if (ov_time_seek(&ovFile, offset) != 0)
|
||||
Com_Printf("OGG_Seek: could not seek.\n");
|
||||
|
||||
else
|
||||
Com_Printf("%0.2f -> %0.2f of %0.2f.\n", pos, offset, total);
|
||||
|
||||
} else
|
||||
Com_Printf("OGG_Seek: invalid offset.\n");
|
||||
|
||||
break;
|
||||
case REL:
|
||||
|
||||
if (pos + offset >= 0 && pos + offset <= total) {
|
||||
if (ov_time_seek(&ovFile, pos + offset) != 0)
|
||||
Com_Printf("OGG_Seek: could not seek.\n");
|
||||
|
||||
else
|
||||
Com_Printf("%0.2f -> %0.2f of %0.2f.\n", pos, pos + offset, total);
|
||||
|
||||
} else
|
||||
Com_Printf("OGG_Seek: invalid offset.\n");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_LoadFileList
|
||||
|
||||
Load list of Ogg Vorbis files in "music".
|
||||
==========
|
||||
*/
|
||||
void OGG_LoadFileList(void)
|
||||
{
|
||||
char **list; /* List of .ogg files. */
|
||||
int i; /* Loop counter. */
|
||||
int j; /* Real position in list. */
|
||||
* Load list of Ogg Vorbis files in "music".
|
||||
*/
|
||||
void OGG_LoadFileList(void) {
|
||||
char **list; /* List of .ogg files. */
|
||||
int i; /* Loop counter. */
|
||||
int j; /* Real position in list. */
|
||||
|
||||
/* Get file list. */
|
||||
list = FS_ListFiles2(va("%s/*.ogg", OGG_DIR), &ogg_numfiles, 0,
|
||||
SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
|
||||
SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
|
||||
ogg_numfiles--;
|
||||
|
||||
/* Check if there are posible Ogg files. */
|
||||
|
@ -274,6 +262,7 @@ void OGG_LoadFileList(void)
|
|||
free(list[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
ogg_filelist[j++] = list[i];
|
||||
}
|
||||
|
||||
|
@ -286,32 +275,28 @@ void OGG_LoadFileList(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_LoadPlaylist
|
||||
|
||||
Load playlist.
|
||||
==========
|
||||
*/
|
||||
void OGG_LoadPlaylist(char *playlist)
|
||||
{
|
||||
byte *buffer; /* Buffer to read the file. */
|
||||
char *ptr; /* Pointer for parsing the file. */
|
||||
int i; /* Loop counter. */
|
||||
int size; /* Length of buffer and strings. */
|
||||
* Load playlist.
|
||||
*/
|
||||
void OGG_LoadPlaylist(char *playlist) {
|
||||
byte *buffer; /* Buffer to read the file. */
|
||||
char *ptr; /* Pointer for parsing the file. */
|
||||
int i; /* Loop counter. */
|
||||
int size; /* Length of buffer and strings. */
|
||||
|
||||
/* Open playlist. */
|
||||
if ((size = FS_LoadFile(va("%s/%s.lst", OGG_DIR, ogg_playlist->string),
|
||||
(void **)&buffer)) < 0) {
|
||||
(void **)&buffer)) < 0) {
|
||||
Com_Printf("OGG_LoadPlaylist: could not open playlist: %s.\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Count the files in playlist. */
|
||||
for (ptr = strsep((char **) &buffer, "\n");
|
||||
ptr != NULL;
|
||||
ptr = strsep(NULL, "\n")) {
|
||||
ptr != NULL;
|
||||
ptr = strsep(NULL, "\n")) {
|
||||
if ((byte *)ptr != buffer)
|
||||
ptr[-1] = '\n';
|
||||
|
||||
if (OGG_Check(va("%s/%s", OGG_DIR, ptr)))
|
||||
ogg_numfiles++;
|
||||
}
|
||||
|
@ -320,9 +305,10 @@ void OGG_LoadPlaylist(char *playlist)
|
|||
ogg_filelist = malloc(sizeof(char *) * ogg_numfiles);
|
||||
|
||||
i = 0;
|
||||
|
||||
for (ptr = strsep((char **) &buffer, "\n");
|
||||
ptr != NULL;
|
||||
ptr = strsep(NULL, "\n"))
|
||||
ptr != NULL;
|
||||
ptr = strsep(NULL, "\n"))
|
||||
if (OGG_Check(va("%s/%s", OGG_DIR, ptr)))
|
||||
ogg_filelist[i++] = strdup(va("%s/%s", OGG_DIR, ptr));
|
||||
|
||||
|
@ -331,45 +317,48 @@ void OGG_LoadPlaylist(char *playlist)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Open
|
||||
|
||||
Play Ogg Vorbis file (with absolute or relative index).
|
||||
==========
|
||||
*/
|
||||
qboolean OGG_Open(ogg_seek_t type, int offset)
|
||||
{
|
||||
int size; /* File size. */
|
||||
int pos; /* Absolute position. */
|
||||
int res; /* Error indicator. */
|
||||
* Play Ogg Vorbis file (with absolute or relative index).
|
||||
*/
|
||||
qboolean OGG_Open(ogg_seek_t type, int offset) {
|
||||
int size; /* File size. */
|
||||
int pos; /* Absolute position. */
|
||||
int res; /* Error indicator. */
|
||||
|
||||
pos = -1;
|
||||
|
||||
switch (type) {
|
||||
case ABS:
|
||||
/* Absolute index. */
|
||||
if (offset < 0 || offset >= ogg_numfiles) {
|
||||
Com_Printf("OGG_Open: %d out of range.\n", offset+1);
|
||||
return (false);
|
||||
} else
|
||||
pos = offset;
|
||||
break;
|
||||
case REL:
|
||||
/* Simulate a loopback. */
|
||||
if (ogg_curfile == -1 && offset < 0)
|
||||
offset++;
|
||||
while (ogg_curfile + offset < 0)
|
||||
offset += ogg_numfiles;
|
||||
while (ogg_curfile + offset >= ogg_numfiles)
|
||||
offset -= ogg_numfiles;
|
||||
pos = ogg_curfile + offset;
|
||||
break;
|
||||
case ABS:
|
||||
|
||||
/* Absolute index. */
|
||||
if (offset < 0 || offset >= ogg_numfiles) {
|
||||
Com_Printf("OGG_Open: %d out of range.\n", offset+1);
|
||||
return (false);
|
||||
|
||||
} else
|
||||
pos = offset;
|
||||
|
||||
break;
|
||||
case REL:
|
||||
|
||||
/* Simulate a loopback. */
|
||||
if (ogg_curfile == -1 && offset < 0)
|
||||
offset++;
|
||||
|
||||
while (ogg_curfile + offset < 0)
|
||||
offset += ogg_numfiles;
|
||||
|
||||
while (ogg_curfile + offset >= ogg_numfiles)
|
||||
offset -= ogg_numfiles;
|
||||
|
||||
pos = ogg_curfile + offset;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check running music. */
|
||||
if (ogg_status == PLAY) {
|
||||
if (ogg_curfile == pos)
|
||||
return (true);
|
||||
|
||||
else
|
||||
OGG_Stop();
|
||||
}
|
||||
|
@ -396,14 +385,9 @@ qboolean OGG_Open(ogg_seek_t type, int offset)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_OpenName
|
||||
|
||||
Play Ogg Vorbis file (with name only).
|
||||
==========
|
||||
*/
|
||||
qboolean OGG_OpenName(char *filename)
|
||||
{
|
||||
* Play Ogg Vorbis file (with name only).
|
||||
*/
|
||||
qboolean OGG_OpenName(char *filename) {
|
||||
char *name; /* File name. */
|
||||
int i; /* Loop counter. */
|
||||
|
||||
|
@ -415,6 +399,7 @@ qboolean OGG_OpenName(char *filename)
|
|||
|
||||
if (i < ogg_numfiles)
|
||||
return (OGG_Open(ABS, i));
|
||||
|
||||
else {
|
||||
Com_Printf("OGG_OpenName: '%s' not in the list.\n", filename);
|
||||
return (false);
|
||||
|
@ -422,14 +407,9 @@ qboolean OGG_OpenName(char *filename)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Read
|
||||
|
||||
Play a portion of the currently opened file.
|
||||
==========
|
||||
*/
|
||||
int OGG_Read(void)
|
||||
{
|
||||
* Play a portion of the currently opened file.
|
||||
*/
|
||||
int OGG_Read(void) {
|
||||
int res; /* Number of bytes read. */
|
||||
|
||||
/* Read and resample. */
|
||||
|
@ -446,23 +426,22 @@ int OGG_Read(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Sequence
|
||||
|
||||
Play files in sequence.
|
||||
==========
|
||||
*/
|
||||
void OGG_Sequence(void)
|
||||
{
|
||||
* Play files in sequence.
|
||||
*/
|
||||
void OGG_Sequence(void) {
|
||||
|
||||
if (strcmp(ogg_sequence->string, "next") == 0)
|
||||
OGG_Open(REL, 1);
|
||||
|
||||
else if (strcmp(ogg_sequence->string, "prev") == 0)
|
||||
OGG_Open(REL, -1);
|
||||
|
||||
else if (strcmp(ogg_sequence->string, "random") == 0)
|
||||
OGG_Open(ABS, rand() % ogg_numfiles);
|
||||
|
||||
else if (strcmp(ogg_sequence->string, "loop") == 0)
|
||||
OGG_Open(REL, 0);
|
||||
|
||||
else if (strcmp(ogg_sequence->string, "none") != 0) {
|
||||
Com_Printf("Invalid value of ogg_sequence: %s\n", ogg_sequence->string);
|
||||
Cvar_Set("ogg_sequence", "none");
|
||||
|
@ -470,14 +449,9 @@ void OGG_Sequence(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Stop
|
||||
|
||||
Stop playing the current file.
|
||||
==========
|
||||
*/
|
||||
void OGG_Stop(void)
|
||||
{
|
||||
* Stop playing the current file.
|
||||
*/
|
||||
void OGG_Stop(void) {
|
||||
|
||||
if (ogg_status == STOP)
|
||||
return;
|
||||
|
@ -492,15 +466,9 @@ void OGG_Stop(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_Stream
|
||||
|
||||
Stream music.
|
||||
==========
|
||||
*/
|
||||
void OGG_Stream(void)
|
||||
{
|
||||
|
||||
* Stream music.
|
||||
*/
|
||||
void OGG_Stream(void) {
|
||||
if (!ogg_started)
|
||||
return;
|
||||
|
||||
|
@ -509,14 +477,9 @@ void OGG_Stream(void)
|
|||
}
|
||||
|
||||
/*
|
||||
============
|
||||
S_RawSamplesVol
|
||||
|
||||
Cinematic streaming and voice over network (with volume)
|
||||
============
|
||||
*/
|
||||
void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data, float volume)
|
||||
{
|
||||
* Cinematic streaming
|
||||
*/
|
||||
void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data, float volume) {
|
||||
int i;
|
||||
int src, dst;
|
||||
float scale;
|
||||
|
@ -529,13 +492,10 @@ void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data
|
|||
|
||||
scale = (float)rate / dma.speed;
|
||||
|
||||
//Com_Printf ("%i < %i < %i\n", soundtime, paintedtime, s_rawend);
|
||||
if (channels == 2 && width == 2)
|
||||
{
|
||||
if (scale == 1.0)
|
||||
{ // optimized case
|
||||
for (i=0 ; i<samples ; i++)
|
||||
{
|
||||
if (channels == 2 && width == 2) {
|
||||
if (scale == 1.0) {
|
||||
/* optimized case */
|
||||
for (i=0 ; i<samples ; i++) {
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
|
@ -543,14 +503,14 @@ void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data
|
|||
s_rawsamples[dst].right =
|
||||
(int)(volume * LittleShort(((short *)data)[i*2+1])) << 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
|
||||
} else {
|
||||
for (i=0 ; ; i++) {
|
||||
src = i*scale;
|
||||
|
||||
if (src >= samples)
|
||||
break;
|
||||
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
|
@ -559,14 +519,14 @@ void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data
|
|||
(int)(volume * LittleShort(((short *)data)[src*2+1])) << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (channels == 1 && width == 2)
|
||||
{
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
|
||||
} else if (channels == 1 && width == 2) {
|
||||
for (i=0 ; ; i++) {
|
||||
src = i*scale;
|
||||
|
||||
if (src >= samples)
|
||||
break;
|
||||
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
|
@ -574,14 +534,14 @@ void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data
|
|||
s_rawsamples[dst].right =
|
||||
(int)(volume * LittleShort(((short *)data)[src])) << 8;
|
||||
}
|
||||
}
|
||||
else if (channels == 2 && width == 1)
|
||||
{
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
|
||||
} else if (channels == 2 && width == 1) {
|
||||
for (i=0 ; ; i++) {
|
||||
src = i*scale;
|
||||
|
||||
if (src >= samples)
|
||||
break;
|
||||
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
|
@ -589,35 +549,28 @@ void S_RawSamplesVol (int samples, int rate, int width, int channels, byte *data
|
|||
s_rawsamples[dst].right =
|
||||
(int)(volume * ((char *)data)[src*2+1]) << 16;
|
||||
}
|
||||
}
|
||||
else if (channels == 1 && width == 1)
|
||||
{
|
||||
for (i=0 ; ; i++)
|
||||
{
|
||||
|
||||
} else if (channels == 1 && width == 1) {
|
||||
for (i=0 ; ; i++) {
|
||||
src = i*scale;
|
||||
|
||||
if (src >= samples)
|
||||
break;
|
||||
|
||||
dst = s_rawend&(MAX_RAW_SAMPLES-1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left =
|
||||
(int)(volume * (((byte *)data)[src]-128)) << 16;
|
||||
s_rawsamples[dst].right =
|
||||
(int)(volume * (((byte *)data)[src]-128)) << 16;
|
||||
s_rawsamples[dst].right =
|
||||
(int)(volume * (((byte *)data)[src]-128)) << 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Console commands. */
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_ListCmd
|
||||
|
||||
List Ogg Vorbis files.
|
||||
==========
|
||||
*/
|
||||
void OGG_ListCmd(void)
|
||||
{
|
||||
* List Ogg Vorbis files.
|
||||
*/
|
||||
void OGG_ListCmd(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ogg_numfiles; i++)
|
||||
|
@ -627,68 +580,61 @@ void OGG_ListCmd(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_ParseCmd
|
||||
|
||||
Parse play controls.
|
||||
==========
|
||||
*/
|
||||
void OGG_ParseCmd(char *arg)
|
||||
{
|
||||
int n;
|
||||
* Parse play controls.
|
||||
*/
|
||||
void OGG_ParseCmd(char *arg) {
|
||||
int n;
|
||||
cvar_t *ogg_enable;
|
||||
ogg_enable = Cvar_Get ("ogg_enable", "0", CVAR_ARCHIVE);
|
||||
ogg_enable = Cvar_Get ("ogg_enable", "0", CVAR_ARCHIVE);
|
||||
|
||||
switch (arg[0]) {
|
||||
case '#':
|
||||
n = atoi(arg+1) - 1;
|
||||
OGG_Open(ABS, n);
|
||||
break;
|
||||
case '?':
|
||||
OGG_Open(ABS, rand() % ogg_numfiles);
|
||||
break;
|
||||
case '>':
|
||||
if (strlen(arg) > 1)
|
||||
OGG_Open(REL, atoi(arg+1));
|
||||
else
|
||||
OGG_Open(REL, 1);
|
||||
break;
|
||||
case '<':
|
||||
if (strlen(arg) > 1)
|
||||
OGG_Open(REL, -atoi(arg+1));
|
||||
else
|
||||
OGG_Open(REL, -1);
|
||||
break;
|
||||
default:
|
||||
if (ogg_enable->value != 0)
|
||||
OGG_OpenName(arg);
|
||||
break;
|
||||
case '#':
|
||||
n = atoi(arg+1) - 1;
|
||||
OGG_Open(ABS, n);
|
||||
break;
|
||||
case '?':
|
||||
OGG_Open(ABS, rand() % ogg_numfiles);
|
||||
break;
|
||||
case '>':
|
||||
|
||||
if (strlen(arg) > 1)
|
||||
OGG_Open(REL, atoi(arg+1));
|
||||
|
||||
else
|
||||
OGG_Open(REL, 1);
|
||||
|
||||
break;
|
||||
case '<':
|
||||
|
||||
if (strlen(arg) > 1)
|
||||
OGG_Open(REL, -atoi(arg+1));
|
||||
|
||||
else
|
||||
OGG_Open(REL, -1);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
if (ogg_enable->value != 0)
|
||||
OGG_OpenName(arg);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_PauseCmd
|
||||
|
||||
Pause current song.
|
||||
==========
|
||||
*/
|
||||
void OGG_PauseCmd(void)
|
||||
{
|
||||
* Pause current song.
|
||||
*/
|
||||
void OGG_PauseCmd(void) {
|
||||
|
||||
if (ogg_status == PLAY)
|
||||
ogg_status = PAUSE;
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_PlayCmd
|
||||
|
||||
Play control.
|
||||
==========
|
||||
*/
|
||||
void OGG_PlayCmd( void )
|
||||
{
|
||||
* Play control.
|
||||
*/
|
||||
void OGG_PlayCmd( void ) {
|
||||
|
||||
if (Cmd_Argc() < 2) {
|
||||
Com_Printf("Usage: ogg_play {filename | #n | ? | >n | <n}\n");
|
||||
|
@ -699,28 +645,18 @@ void OGG_PlayCmd( void )
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_ResumeCmd
|
||||
|
||||
Resume current song.
|
||||
==========
|
||||
*/
|
||||
void OGG_ResumeCmd(void)
|
||||
{
|
||||
* Resume current song.
|
||||
*/
|
||||
void OGG_ResumeCmd(void) {
|
||||
|
||||
if (ogg_status == PAUSE)
|
||||
ogg_status = PLAY;
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_SeekCmd
|
||||
|
||||
Change position in the file being played.
|
||||
==========
|
||||
*/
|
||||
void OGG_SeekCmd(void)
|
||||
{
|
||||
* Change position in the file being played.
|
||||
*/
|
||||
void OGG_SeekCmd(void) {
|
||||
|
||||
if (ogg_status != STOP)
|
||||
return;
|
||||
|
@ -744,30 +680,28 @@ void OGG_SeekCmd(void)
|
|||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
OGG_StatusCmd
|
||||
|
||||
Display status.
|
||||
==========
|
||||
*/
|
||||
void OGG_StatusCmd(void)
|
||||
{
|
||||
* Display status.
|
||||
*/
|
||||
void OGG_StatusCmd(void) {
|
||||
|
||||
switch (ogg_status) {
|
||||
case PLAY:
|
||||
Com_Printf("Playing file %d (%s) at %0.2f seconds.\n",
|
||||
ogg_curfile+1, ogg_filelist[ogg_curfile], ov_time_tell(&ovFile));
|
||||
break;
|
||||
case PAUSE:
|
||||
Com_Printf("Paused file %d (%s) at %0.2f seconds.\n",
|
||||
ogg_curfile+1, ogg_filelist[ogg_curfile], ov_time_tell(&ovFile));
|
||||
break;
|
||||
case STOP:
|
||||
if (ogg_curfile == -1)
|
||||
Com_Printf("Stopped.\n");
|
||||
else
|
||||
Com_Printf("Stopped file %d (%s).\n",
|
||||
ogg_curfile+1, ogg_filelist[ogg_curfile]);
|
||||
break;
|
||||
case PLAY:
|
||||
Com_Printf("Playing file %d (%s) at %0.2f seconds.\n",
|
||||
ogg_curfile+1, ogg_filelist[ogg_curfile], ov_time_tell(&ovFile));
|
||||
break;
|
||||
case PAUSE:
|
||||
Com_Printf("Paused file %d (%s) at %0.2f seconds.\n",
|
||||
ogg_curfile+1, ogg_filelist[ogg_curfile], ov_time_tell(&ovFile));
|
||||
break;
|
||||
case STOP:
|
||||
|
||||
if (ogg_curfile == -1)
|
||||
Com_Printf("Stopped.\n");
|
||||
|
||||
else
|
||||
Com_Printf("Stopped file %d (%s).\n",
|
||||
ogg_curfile+1, ogg_filelist[ogg_curfile]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ==========================================================
|
||||
* 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.
|
||||
*
|
||||
* OGG Vorbis decoding
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* The header file for the OGG/Vorbis playback
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#ifndef _SND_OGG_H_
|
||||
#define _SND_OGG_H_
|
||||
|
||||
#define OGG_DIR "music"
|
||||
#define OGG_DIR "music"
|
||||
|
||||
typedef enum {
|
||||
PLAY,
|
||||
|
@ -48,14 +47,13 @@ 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);
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue