mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-09 01:01:07 +00:00
backports from uhexen2 source, preparing for streaming music support:
* snd_mix.c: Increased PAINTBUFFER_SIZE from 512 to 2048. * snd_mix.c: snd_vol is static now. it is calculated in S_PaintChannels and only used in SND_PaintChannelFrom16. all its other uses are removed from Snd_WriteLinearBlastStereo16, S_TransferStereo16, S_TransferPaintBuffer. The way it was, the sound volume was applied to the whole final contents of the paint buffer, but with this new quake2+ way we can add raw samples to the paint buffer with its own volume, such as bgmvolume. However, this makes the snd_scaletable to be recalculated everytime the sfxvolume is, changed, therefore it is adjusted that way to incorporate sfxvolume. * snd_mix.c: In S_PaintChannels, check against s_rawend and copy from the streaming sound source if necessary. * snd_dma.c: Added old_volume to detect sfxvolume changes. Made S_Update to compare it to sfxvolume.value and call SND_InitScaletable() if it changed. * snd_dma.c: Add new globals s_rawsamples and s_rawend. Reset s_rawend to 0 in S_ClearBuffer. Add new function S_RawSamples, adapted from quake2 with its 8 bit stereo playback fixed. * snd_dma.c (S_FileExtension): Add new function which returns the given sound file's extension including the dot, or NULL. * q_sound.h: Add new macro MAX_RAW_SAMPLES, defined as 8192. Add externs for new globals s_rawsamples and s_rawend. Add prototype for the new S_RawSamples and S_FileExtension functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@355 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
94767a4e6d
commit
bcef8e85f0
3 changed files with 188 additions and 14 deletions
|
@ -121,6 +121,12 @@ channel_t *SND_PickChannel(int entnum, int entchannel);
|
|||
// spatializes a channel
|
||||
void SND_Spatialize(channel_t *ch);
|
||||
|
||||
// music stream support
|
||||
void S_RawSamples(int samples, int rate, int width, int channels, byte * data, float volume);
|
||||
|
||||
// returns file's extension including the dot, or NULL
|
||||
const char *S_FileExtension (const char *name);
|
||||
|
||||
// initializes cycling through a DMA buffer and returns information on it
|
||||
qboolean SNDDMA_Init(void);
|
||||
|
||||
|
@ -166,6 +172,7 @@ extern int total_channels;
|
|||
extern qboolean fakedma;
|
||||
extern int fakedma_updates;
|
||||
extern int paintedtime;
|
||||
extern int s_rawend;
|
||||
extern vec3_t listener_origin;
|
||||
extern vec3_t listener_forward;
|
||||
extern vec3_t listener_right;
|
||||
|
@ -173,6 +180,9 @@ extern vec3_t listener_up;
|
|||
extern volatile dma_t *shm;
|
||||
extern volatile dma_t sn;
|
||||
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
|
||||
extern cvar_t loadas8bit;
|
||||
extern cvar_t bgmvolume;
|
||||
extern cvar_t sfxvolume;
|
||||
|
|
136
Quake/snd_dma.c
136
Quake/snd_dma.c
|
@ -53,6 +53,9 @@ vec3_t listener_up;
|
|||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
|
||||
int s_rawend;
|
||||
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
|
||||
|
||||
#define MAX_SFX 512
|
||||
sfx_t *known_sfx; // hunk allocated [MAX_SFX]
|
||||
|
@ -62,6 +65,8 @@ sfx_t *ambient_sfx[NUM_AMBIENTS];
|
|||
|
||||
qboolean sound_started = false;
|
||||
|
||||
static float oldvolume = -1.0;
|
||||
|
||||
cvar_t bgmvolume = {"bgmvolume", "1", true};
|
||||
cvar_t sfxvolume = {"volume", "0.7", true};
|
||||
|
||||
|
@ -251,6 +256,29 @@ sfx_t *S_FindName (const char *name)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FileExtension
|
||||
|
||||
return file's extension including the dot, or NULL
|
||||
=================
|
||||
*/
|
||||
const char *S_FileExtension (const char *name)
|
||||
{
|
||||
const char *ptr = name + strlen(name) - 1;
|
||||
|
||||
while (ptr > name &&
|
||||
(*ptr != '/' && *ptr != '\\'))
|
||||
{
|
||||
if (*ptr == '.')
|
||||
return ptr;
|
||||
ptr--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
S_TouchSound
|
||||
|
@ -511,6 +539,8 @@ void S_ClearBuffer (void)
|
|||
if (! shm->buffer)
|
||||
return;
|
||||
|
||||
s_rawend = 0;
|
||||
|
||||
if (shm->samplebits == 8)
|
||||
clear = 0x80;
|
||||
else
|
||||
|
@ -622,6 +652,106 @@ void S_UpdateAmbientSounds (void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
S_RawSamples (from QuakeII)
|
||||
|
||||
Streaming music support. Byte swapping
|
||||
of data must be handled by the codec.
|
||||
===================
|
||||
*/
|
||||
void S_RawSamples (int samples, int rate, int width, int channels, byte *data, float volume)
|
||||
{
|
||||
int i;
|
||||
int src, dst;
|
||||
float scale;
|
||||
int intVolume;
|
||||
|
||||
if (s_rawend < paintedtime)
|
||||
{
|
||||
s_rawend = paintedtime;
|
||||
}
|
||||
|
||||
scale = (float) rate / shm->speed;
|
||||
intVolume = (int) (256 * volume);
|
||||
|
||||
if (channels == 2 && 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 = ((short *) data)[src * 2] * intVolume;
|
||||
s_rawsamples [dst].right = ((short *) data)[src * 2 + 1] * intVolume;
|
||||
}
|
||||
}
|
||||
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 = ((short *) data)[src] * intVolume;
|
||||
s_rawsamples [dst].right = ((short *) data)[src] * intVolume;
|
||||
}
|
||||
}
|
||||
else if (channels == 2 && width == 1)
|
||||
{
|
||||
intVolume *= 256;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
src = i * scale;
|
||||
|
||||
if (src >= samples)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
// s_rawsamples [dst].left = ((char *) data)[src * 2] * intVolume;
|
||||
// s_rawsamples [dst].right = ((char *) data)[src * 2 + 1] * intVolume;
|
||||
/* the above doesn't work for me with U8, only the unsigned ones below do */
|
||||
s_rawsamples [dst].left = (((byte *) data)[src * 2] - 128) * intVolume;
|
||||
s_rawsamples [dst].right = (((byte *) data)[src * 2 + 1] - 128) * intVolume;
|
||||
}
|
||||
}
|
||||
else if (channels == 1 && width == 1)
|
||||
{
|
||||
intVolume *= 256;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
src = i * scale;
|
||||
|
||||
if (src >= samples)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
s_rawsamples [dst].left = (((byte *) data)[src] - 128) * intVolume;
|
||||
s_rawsamples [dst].right = (((byte *) data)[src] - 128) * intVolume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
S_Update
|
||||
|
@ -639,6 +769,12 @@ void S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
|
|||
if (!sound_started || (snd_blocked > 0))
|
||||
return;
|
||||
|
||||
if (sfxvolume.value != oldvolume)
|
||||
{
|
||||
oldvolume = sfxvolume.value;
|
||||
SND_InitScaletable ();
|
||||
}
|
||||
|
||||
VectorCopy(origin, listener_origin);
|
||||
VectorCopy(forward, listener_forward);
|
||||
VectorCopy(right, listener_right);
|
||||
|
|
|
@ -23,12 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
#define PAINTBUFFER_SIZE 512
|
||||
#define PAINTBUFFER_SIZE 2048
|
||||
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
|
||||
int snd_scaletable[32][256];
|
||||
int *snd_p, snd_linear_count, snd_vol;
|
||||
int *snd_p, snd_linear_count;
|
||||
short *snd_out;
|
||||
|
||||
static int snd_vol;
|
||||
|
||||
void Snd_WriteLinearBlastStereo16 (void);
|
||||
|
||||
void Snd_WriteLinearBlastStereo16 (void)
|
||||
|
@ -38,7 +40,7 @@ void Snd_WriteLinearBlastStereo16 (void)
|
|||
|
||||
for (i = 0; i < snd_linear_count; i += 2)
|
||||
{
|
||||
val = (snd_p[i]*snd_vol) >> 8;
|
||||
val = snd_p[i] >> 8;
|
||||
if (val > 0x7fff)
|
||||
snd_out[i] = 0x7fff;
|
||||
else if (val < (short)0x8000)
|
||||
|
@ -46,7 +48,7 @@ void Snd_WriteLinearBlastStereo16 (void)
|
|||
else
|
||||
snd_out[i] = val;
|
||||
|
||||
val = (snd_p[i+1]*snd_vol) >> 8;
|
||||
val = snd_p[i+1] >> 8;
|
||||
if (val > 0x7fff)
|
||||
snd_out[i+1] = 0x7fff;
|
||||
else if (val < (short)0x8000)
|
||||
|
@ -61,8 +63,6 @@ void S_TransferStereo16 (int endtime)
|
|||
int lpos;
|
||||
int lpaintedtime;
|
||||
|
||||
snd_vol = sfxvolume.value * 256;
|
||||
|
||||
snd_p = (int *) paintbuffer;
|
||||
lpaintedtime = paintedtime;
|
||||
|
||||
|
@ -104,14 +104,13 @@ void S_TransferPaintBuffer(int endtime)
|
|||
out_mask = shm->samples - 1;
|
||||
out_idx = paintedtime * shm->channels & out_mask;
|
||||
step = 3 - shm->channels;
|
||||
snd_vol = sfxvolume.value * 256;
|
||||
|
||||
if (shm->samplebits == 16)
|
||||
{
|
||||
short *out = (short *)shm->buffer;
|
||||
while (count--)
|
||||
{
|
||||
val = (*p * snd_vol) >> 8;
|
||||
val = *p >> 8;
|
||||
p+= step;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
|
@ -126,7 +125,7 @@ void S_TransferPaintBuffer(int endtime)
|
|||
unsigned char *out = shm->buffer;
|
||||
while (count--)
|
||||
{
|
||||
val = (*p * snd_vol) >> 8;
|
||||
val = *p >> 8;
|
||||
p+= step;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
|
@ -157,6 +156,8 @@ void S_PaintChannels (int endtime)
|
|||
channel_t *ch;
|
||||
sfxcache_t *sc;
|
||||
|
||||
snd_vol = sfxvolume.value * 256;
|
||||
|
||||
while (paintedtime < endtime)
|
||||
{
|
||||
// if paintbuffer is smaller than DMA buffer
|
||||
|
@ -165,7 +166,32 @@ void S_PaintChannels (int endtime)
|
|||
end = paintedtime + PAINTBUFFER_SIZE;
|
||||
|
||||
// clear the paint buffer
|
||||
memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
|
||||
if (s_rawend < paintedtime)
|
||||
{ // clear
|
||||
memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
|
||||
}
|
||||
else
|
||||
{ // copy from the streaming sound source
|
||||
int s;
|
||||
int stop;
|
||||
|
||||
stop = (end < s_rawend) ? end : s_rawend;
|
||||
|
||||
for (i = paintedtime; i < stop; i++)
|
||||
{
|
||||
s = i & (MAX_RAW_SAMPLES - 1);
|
||||
paintbuffer[i - paintedtime] = s_rawsamples[s];
|
||||
}
|
||||
// if (i != end)
|
||||
// Con_Printf ("partial stream\n");
|
||||
// else
|
||||
// Con_Printf ("full stream\n");
|
||||
for ( ; i < end; i++)
|
||||
{
|
||||
paintbuffer[i - paintedtime].left =
|
||||
paintbuffer[i - paintedtime].right = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// paint in the channels.
|
||||
ch = snd_channels;
|
||||
|
@ -224,9 +250,11 @@ void S_PaintChannels (int endtime)
|
|||
void SND_InitScaletable (void)
|
||||
{
|
||||
int i, j;
|
||||
int scale;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
scale = i * 8 * 256 * sfxvolume.value;
|
||||
for (j = 0; j < 256; j++)
|
||||
/* When compiling with gcc-4.1.0 at optimisations O1 and
|
||||
higher, the tricky signed char type conversion is not
|
||||
|
@ -234,8 +262,8 @@ void SND_InitScaletable (void)
|
|||
value from the index as required. From Kevin Shanahan.
|
||||
See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26719
|
||||
*/
|
||||
// snd_scaletable[i][j] = ((signed char)j) * i * 8;
|
||||
snd_scaletable[i][j] = ((j < 128) ? j : j - 0xff) * i * 8;
|
||||
// snd_scaletable[i][j] = ((signed char)j) * scale;
|
||||
snd_scaletable[i][j] = ((j < 128) ? j : j - 0xff) * scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,8 +302,8 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
signed short *sfx;
|
||||
int i;
|
||||
|
||||
leftvol = ch->leftvol;
|
||||
rightvol = ch->rightvol;
|
||||
leftvol = ch->leftvol * snd_vol;
|
||||
rightvol = ch->rightvol * snd_vol;
|
||||
sfx = (signed short *)sc->data + ch->pos;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
|
|
Loading…
Reference in a new issue