mirror of
https://git.code.sf.net/p/quake/newtree
synced 2025-05-10 14:20:38 +00:00
Merge phase separated mixing from nuq. Still has bugs, but defaults off.
This commit is contained in:
parent
36ddd0670e
commit
ea76f45bc6
4 changed files with 131 additions and 36 deletions
|
@ -93,7 +93,9 @@
|
||||||
#define ch_origin 32
|
#define ch_origin 32
|
||||||
#define ch_dist_mult 44
|
#define ch_dist_mult 44
|
||||||
#define ch_master_vol 48
|
#define ch_master_vol 48
|
||||||
#define ch_size 52
|
#define ch_phase 52
|
||||||
|
#define ch_oldphase 56
|
||||||
|
#define ch_size 60
|
||||||
|
|
||||||
// portable_samplepair_t structure
|
// portable_samplepair_t structure
|
||||||
// !!! if this is changed, it much be changed in sound.h too !!!
|
// !!! if this is changed, it much be changed in sound.h too !!!
|
||||||
|
@ -102,4 +104,3 @@
|
||||||
#define psp_size 8
|
#define psp_size 8
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "cvar.h"
|
#include "cvar.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
|
||||||
// !!! if this is changed, it much be changed in asm_i386.h too !!!
|
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int left;
|
int left;
|
||||||
|
@ -86,6 +86,8 @@ typedef struct
|
||||||
vec3_t origin; // origin of sound effect
|
vec3_t origin; // origin of sound effect
|
||||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||||
int master_vol; // 0-255 master volume
|
int master_vol; // 0-255 master volume
|
||||||
|
int phase; // phase shift between l-r in samples
|
||||||
|
int oldphase; // phase shift between l-r in samples
|
||||||
} channel_t;
|
} channel_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -137,7 +139,7 @@ void SNDDMA_Shutdown(void);
|
||||||
// User-setable variables
|
// User-setable variables
|
||||||
// ====================================================================
|
// ====================================================================
|
||||||
|
|
||||||
#define MAX_CHANNELS 128
|
#define MAX_CHANNELS 256
|
||||||
#define MAX_DYNAMIC_CHANNELS 8
|
#define MAX_DYNAMIC_CHANNELS 8
|
||||||
|
|
||||||
extern channel_t channels[MAX_CHANNELS];
|
extern channel_t channels[MAX_CHANNELS];
|
||||||
|
@ -170,6 +172,7 @@ extern cvar_t *bgmvolume;
|
||||||
extern cvar_t *volume;
|
extern cvar_t *volume;
|
||||||
|
|
||||||
extern cvar_t *snd_interp;
|
extern cvar_t *snd_interp;
|
||||||
|
extern cvar_t *snd_stereo_phase_separation;
|
||||||
|
|
||||||
extern qboolean snd_initialized;
|
extern qboolean snd_initialized;
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,13 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "host.h"
|
#include "client.h"
|
||||||
#include "sys.h"
|
|
||||||
#include "sound.h"
|
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "client.h"
|
#include "host.h"
|
||||||
#include "qargs.h"
|
#include "qargs.h"
|
||||||
|
#include "sys.h"
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
// fixme: Damn crappy complier doesn't allow me to UNDEF _win32 on command line!
|
// fixme: Damn crappy complier doesn't allow me to UNDEF _win32 on command line!
|
||||||
#ifdef WIN32SDL
|
#ifdef WIN32SDL
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
void S_Play (void);
|
void S_Play (void);
|
||||||
void S_PlayVol (void);
|
void S_PlayVol (void);
|
||||||
void S_SoundList (void);
|
void S_SoundList (void);
|
||||||
void S_Update_ ();
|
void S_Update_ (void);
|
||||||
void S_StopAllSounds (qboolean clear);
|
void S_StopAllSounds (qboolean clear);
|
||||||
void S_StopAllSoundsC (void);
|
void S_StopAllSoundsC (void);
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ cvar_t *ambient_fade;
|
||||||
cvar_t *snd_noextraupdate;
|
cvar_t *snd_noextraupdate;
|
||||||
cvar_t *snd_show;
|
cvar_t *snd_show;
|
||||||
cvar_t *snd_interp;
|
cvar_t *snd_interp;
|
||||||
|
cvar_t *snd_phasesep;
|
||||||
|
cvar_t *snd_volumesep;
|
||||||
cvar_t *_snd_mixahead;
|
cvar_t *_snd_mixahead;
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,7 +200,7 @@ void
|
||||||
S_Init (void)
|
S_Init (void)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Con_Printf("\nSound Initialization\n");
|
Con_Printf("\nSound Initialization\n");
|
||||||
|
|
||||||
Cmd_AddCommand ("play", S_Play);
|
Cmd_AddCommand ("play", S_Play);
|
||||||
Cmd_AddCommand ("playvol", S_PlayVol);
|
Cmd_AddCommand ("playvol", S_PlayVol);
|
||||||
|
@ -206,7 +208,6 @@ S_Init (void)
|
||||||
Cmd_AddCommand ("soundlist", S_SoundList);
|
Cmd_AddCommand ("soundlist", S_SoundList);
|
||||||
Cmd_AddCommand ("soundinfo", S_SoundInfo_f);
|
Cmd_AddCommand ("soundinfo", S_SoundInfo_f);
|
||||||
|
|
||||||
|
|
||||||
if (COM_CheckParm ("-nosound"))
|
if (COM_CheckParm ("-nosound"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -219,7 +220,6 @@ S_Init (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
snd_initialized = true;
|
snd_initialized = true;
|
||||||
|
|
||||||
S_Startup ();
|
S_Startup ();
|
||||||
|
@ -276,6 +276,8 @@ S_Init_Cvars (void)
|
||||||
snd_interp =
|
snd_interp =
|
||||||
Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE,
|
Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE,
|
||||||
"control sample interpolation");
|
"control sample interpolation");
|
||||||
|
snd_phasesep = Cvar_Get ("snd_phasesep", "0.0", CVAR_ARCHIVE, "max stereo phase separation in ms. 0.6 is for 20cm head");
|
||||||
|
snd_volumesep = Cvar_Get("snd_volumesep", "1.0", CVAR_ARCHIVE, "max stereo volume separation in ms. 1.0 is max");
|
||||||
_snd_mixahead = Cvar_Get ("_snd_mixahead", "0.1", CVAR_ARCHIVE, "None");
|
_snd_mixahead = Cvar_Get ("_snd_mixahead", "0.1", CVAR_ARCHIVE, "None");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,12 +408,8 @@ SND_PickChannel (int entnum, int entchannel)
|
||||||
ch_idx++) {
|
ch_idx++) {
|
||||||
if (entchannel != 0 // channel 0 never overrides
|
if (entchannel != 0 // channel 0 never overrides
|
||||||
&& channels[ch_idx].entnum == entnum
|
&& channels[ch_idx].entnum == entnum
|
||||||
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1)) { // allways
|
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1)) {
|
||||||
// override
|
// always override sound from same entity
|
||||||
// sound
|
|
||||||
// from
|
|
||||||
// same
|
|
||||||
// entity
|
|
||||||
first_to_die = ch_idx;
|
first_to_die = ch_idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -445,6 +443,7 @@ SND_Spatialize (channel_t *ch)
|
||||||
{
|
{
|
||||||
vec_t dot;
|
vec_t dot;
|
||||||
vec_t dist;
|
vec_t dist;
|
||||||
|
int phase; // in samples
|
||||||
vec_t lscale, rscale, scale;
|
vec_t lscale, rscale, scale;
|
||||||
vec3_t source_vec;
|
vec3_t source_vec;
|
||||||
sfx_t *snd;
|
sfx_t *snd;
|
||||||
|
@ -453,6 +452,7 @@ SND_Spatialize (channel_t *ch)
|
||||||
if (ch->entnum == cl.viewentity) {
|
if (ch->entnum == cl.viewentity) {
|
||||||
ch->leftvol = ch->master_vol;
|
ch->leftvol = ch->master_vol;
|
||||||
ch->rightvol = ch->master_vol;
|
ch->rightvol = ch->master_vol;
|
||||||
|
ch->phase = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// calculate stereo seperation and distance attenuation
|
// calculate stereo seperation and distance attenuation
|
||||||
|
@ -467,9 +467,11 @@ SND_Spatialize (channel_t *ch)
|
||||||
if (shm->channels == 1) {
|
if (shm->channels == 1) {
|
||||||
rscale = 1.0;
|
rscale = 1.0;
|
||||||
lscale = 1.0;
|
lscale = 1.0;
|
||||||
|
phase = 0;
|
||||||
} else {
|
} else {
|
||||||
rscale = 1.0 + dot;
|
rscale = 1.0 + dot * snd_volumesep->value;
|
||||||
lscale = 1.0 - dot;
|
lscale = 1.0 - dot * snd_volumesep->value;
|
||||||
|
phase = snd_phasesep->value * 0.001 * shm->speed * dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add in distance effect
|
// add in distance effect
|
||||||
|
@ -482,6 +484,8 @@ SND_Spatialize (channel_t *ch)
|
||||||
ch->leftvol = (int) (ch->master_vol * scale);
|
ch->leftvol = (int) (ch->master_vol * scale);
|
||||||
if (ch->leftvol < 0)
|
if (ch->leftvol < 0)
|
||||||
ch->leftvol = 0;
|
ch->leftvol = 0;
|
||||||
|
|
||||||
|
ch->phase = phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,6 +694,7 @@ S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
|
||||||
ss->end = paintedtime + sc->length;
|
ss->end = paintedtime + sc->length;
|
||||||
|
|
||||||
SND_Spatialize (ss);
|
SND_Spatialize (ss);
|
||||||
|
ss->oldphase = ss->phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -780,6 +785,7 @@ S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
|
||||||
for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) {
|
for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) {
|
||||||
if (!ch->sfx)
|
if (!ch->sfx)
|
||||||
continue;
|
continue;
|
||||||
|
ch->oldphase = ch->phase; // prepare to lerp from prev to next phase
|
||||||
SND_Spatialize (ch); // respatialize channel
|
SND_Spatialize (ch); // respatialize channel
|
||||||
if (!ch->leftvol && !ch->rightvol)
|
if (!ch->leftvol && !ch->rightvol)
|
||||||
continue;
|
continue;
|
||||||
|
|
105
source/snd_mix.c
105
source/snd_mix.c
|
@ -32,8 +32,9 @@
|
||||||
#ifdef HAVE_STRING_H
|
#ifdef HAVE_STRING_H
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
#include "sound.h"
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
// fixme: Damn crappy complier doesn't allow me to UNDEF _win32 on command line!
|
// fixme: Damn crappy complier doesn't allow me to UNDEF _win32 on command line!
|
||||||
#ifdef WIN32SDL
|
#ifdef WIN32SDL
|
||||||
|
@ -47,7 +48,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PAINTBUFFER_SIZE 512
|
#define PAINTBUFFER_SIZE 512
|
||||||
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
|
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2];
|
||||||
|
int max_overpaint; // number of extra samples painted due to phase shift
|
||||||
int snd_scaletable[32][256];
|
int snd_scaletable[32][256];
|
||||||
int *snd_p, snd_linear_count, snd_vol;
|
int *snd_p, snd_linear_count, snd_vol;
|
||||||
short *snd_out;
|
short *snd_out;
|
||||||
|
@ -289,9 +291,9 @@ S_PaintChannels (int endtime)
|
||||||
end = paintedtime + PAINTBUFFER_SIZE;
|
end = paintedtime + PAINTBUFFER_SIZE;
|
||||||
|
|
||||||
// clear the paint buffer
|
// clear the paint buffer
|
||||||
memset (paintbuffer, 0,
|
// memset (paintbuffer, 0,
|
||||||
|
// (end - paintedtime) * sizeof (portable_samplepair_t));
|
||||||
(end - paintedtime) * sizeof (portable_samplepair_t));
|
max_overpaint = 0;
|
||||||
|
|
||||||
// paint in the channels.
|
// paint in the channels.
|
||||||
ch = channels;
|
ch = channels;
|
||||||
|
@ -336,6 +338,12 @@ S_PaintChannels (int endtime)
|
||||||
|
|
||||||
// transfer out according to DMA format
|
// transfer out according to DMA format
|
||||||
S_TransferPaintBuffer (end);
|
S_TransferPaintBuffer (end);
|
||||||
|
|
||||||
|
memmove (paintbuffer, paintbuffer + end - paintedtime,
|
||||||
|
max_overpaint * sizeof (paintbuffer[0]));
|
||||||
|
memset (paintbuffer + max_overpaint, 0, sizeof (paintbuffer)
|
||||||
|
- max_overpaint * sizeof (paintbuffer[0]));
|
||||||
|
|
||||||
paintedtime = end;
|
paintedtime = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,19 +397,96 @@ SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
|
||||||
int left, right;
|
int left, right;
|
||||||
int leftvol, rightvol;
|
int leftvol, rightvol;
|
||||||
signed short *sfx;
|
signed short *sfx;
|
||||||
int i;
|
unsigned int i = 0;
|
||||||
|
unsigned int left_phase, right_phase; // Never allowed < 0 anyway
|
||||||
|
|
||||||
leftvol = ch->leftvol;
|
leftvol = ch->leftvol;
|
||||||
rightvol = ch->rightvol;
|
rightvol = ch->rightvol;
|
||||||
|
|
||||||
|
max_overpaint = max (abs (ch->phase),
|
||||||
|
max (abs (ch->oldphase), max_overpaint));
|
||||||
|
|
||||||
sfx = (signed short *) sc->data + ch->pos;
|
sfx = (signed short *) sc->data + ch->pos;
|
||||||
|
ch->pos += count;
|
||||||
|
|
||||||
|
if (ch->phase >= 0) {
|
||||||
|
left_phase = ch->phase;
|
||||||
|
right_phase = 0;
|
||||||
|
} else {
|
||||||
|
left_phase = 0;
|
||||||
|
right_phase = -ch->phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch->oldphase != ch->phase) {
|
||||||
|
unsigned int old_phase_left, old_phase_right;
|
||||||
|
unsigned int new_phase_left, new_phase_right;
|
||||||
|
unsigned int count_left, count_right, c;
|
||||||
|
|
||||||
|
if (ch->oldphase >= 0) {
|
||||||
|
old_phase_left = ch->oldphase;
|
||||||
|
old_phase_right = 0;
|
||||||
|
} else {
|
||||||
|
old_phase_left = 0;
|
||||||
|
old_phase_right = -ch->oldphase;
|
||||||
|
}
|
||||||
|
new_phase_left = left_phase;
|
||||||
|
new_phase_right = right_phase;
|
||||||
|
|
||||||
|
if (new_phase_left > old_phase_left)
|
||||||
|
count_left = 2 * (new_phase_left - old_phase_left);
|
||||||
|
else
|
||||||
|
count_left = old_phase_left - new_phase_left;
|
||||||
|
|
||||||
|
if (new_phase_right > old_phase_right)
|
||||||
|
count_right = 2 * (new_phase_right - old_phase_right);
|
||||||
|
else
|
||||||
|
count_right = old_phase_right - new_phase_right;
|
||||||
|
|
||||||
|
c = min (count, max (count_right, count_left));
|
||||||
|
count -= c;
|
||||||
|
while (c) {
|
||||||
|
int data = sfx[i];
|
||||||
|
int left = (data * leftvol) >> 8;
|
||||||
|
int right = (data * rightvol) >> 8;
|
||||||
|
|
||||||
|
if (new_phase_left < old_phase_left) {
|
||||||
|
if (!(count_left & 1)) {
|
||||||
|
paintbuffer[i + old_phase_left].left += left;
|
||||||
|
old_phase_left--;
|
||||||
|
}
|
||||||
|
count_left--;
|
||||||
|
} else if (new_phase_left > old_phase_left) {
|
||||||
|
paintbuffer[i + old_phase_left].left += left;
|
||||||
|
old_phase_left++;
|
||||||
|
paintbuffer[i + old_phase_left].left += left;
|
||||||
|
} else {
|
||||||
|
paintbuffer[i + old_phase_left].left += left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_phase_right < old_phase_right) {
|
||||||
|
if (!(count_right & 1)) {
|
||||||
|
paintbuffer[i + old_phase_right].right += right;
|
||||||
|
old_phase_right--;
|
||||||
|
}
|
||||||
|
count_right--;
|
||||||
|
} else if (new_phase_right > old_phase_right) {
|
||||||
|
paintbuffer[i + old_phase_right].right += right;
|
||||||
|
old_phase_right++;
|
||||||
|
paintbuffer[i + old_phase_right].right += right;
|
||||||
|
} else {
|
||||||
|
paintbuffer[i + old_phase_right].right += right;
|
||||||
|
}
|
||||||
|
|
||||||
|
c--;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
data = sfx[i];
|
data = sfx[i];
|
||||||
left = (data * leftvol) >> 8;
|
left = (data * leftvol) >> 8;
|
||||||
right = (data * rightvol) >> 8;
|
right = (data * rightvol) >> 8;
|
||||||
paintbuffer[i].left += left;
|
paintbuffer[i + left_phase].left += left;
|
||||||
paintbuffer[i].right += right;
|
paintbuffer[i + right_phase].right += right;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch->pos += count;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue