Merge phase separated mixing from nuq. Still has bugs, but defaults off.

This commit is contained in:
Ragnvald Maartmann-Moe IV 2000-12-19 19:02:37 +00:00
parent 36ddd0670e
commit ea76f45bc6
4 changed files with 131 additions and 36 deletions

View file

@ -89,11 +89,13 @@
#define ch_pos 16
#define ch_looping 20
#define ch_entnum 24
#define ch_entchannel 28
#define ch_entchannel 28
#define ch_origin 32
#define ch_dist_mult 44
#define ch_master_vol 48
#define ch_size 52
#define ch_dist_mult 44
#define ch_master_vol 48
#define ch_phase 52
#define ch_oldphase 56
#define ch_size 60
// portable_samplepair_t structure
// !!! if this is changed, it much be changed in sound.h too !!!
@ -102,4 +104,3 @@
#define psp_size 8
#endif

View file

@ -34,7 +34,7 @@
#include "cvar.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
{
int left;
@ -79,13 +79,15 @@ typedef struct
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
int end; // end time in global paintsamples
int pos; // sample position in sfx
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; // origin of sound effect
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;
typedef struct
@ -137,7 +139,7 @@ void SNDDMA_Shutdown(void);
// User-setable variables
// ====================================================================
#define MAX_CHANNELS 128
#define MAX_CHANNELS 256
#define MAX_DYNAMIC_CHANNELS 8
extern channel_t channels[MAX_CHANNELS];
@ -170,6 +172,7 @@ extern cvar_t *bgmvolume;
extern cvar_t *volume;
extern cvar_t *snd_interp;
extern cvar_t *snd_stereo_phase_separation;
extern qboolean snd_initialized;

View file

@ -30,13 +30,13 @@
# include "config.h"
#endif
#include "host.h"
#include "sys.h"
#include "sound.h"
#include "client.h"
#include "cmd.h"
#include "console.h"
#include "client.h"
#include "host.h"
#include "qargs.h"
#include "sys.h"
#include "sound.h"
// fixme: Damn crappy complier doesn't allow me to UNDEF _win32 on command line!
#ifdef WIN32SDL
@ -54,7 +54,7 @@
void S_Play (void);
void S_PlayVol (void);
void S_SoundList (void);
void S_Update_ ();
void S_Update_ (void);
void S_StopAllSounds (qboolean clear);
void S_StopAllSoundsC (void);
@ -108,6 +108,8 @@ cvar_t *ambient_fade;
cvar_t *snd_noextraupdate;
cvar_t *snd_show;
cvar_t *snd_interp;
cvar_t *snd_phasesep;
cvar_t *snd_volumesep;
cvar_t *_snd_mixahead;
@ -198,7 +200,7 @@ void
S_Init (void)
{
// Con_Printf("\nSound Initialization\n");
Con_Printf("\nSound Initialization\n");
Cmd_AddCommand ("play", S_Play);
Cmd_AddCommand ("playvol", S_PlayVol);
@ -206,7 +208,6 @@ S_Init (void)
Cmd_AddCommand ("soundlist", S_SoundList);
Cmd_AddCommand ("soundinfo", S_SoundInfo_f);
if (COM_CheckParm ("-nosound"))
return;
@ -219,12 +220,11 @@ S_Init (void)
}
snd_initialized = true;
S_Startup ();
if (sound_started == 0) // sound startup failed? Bail out.
if (sound_started == 0) // sound startup failed? Bail out.
return;
SND_InitScaletable ();
@ -276,6 +276,8 @@ S_Init_Cvars (void)
snd_interp =
Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE,
"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");
}
@ -406,12 +408,8 @@ SND_PickChannel (int entnum, int entchannel)
ch_idx++) {
if (entchannel != 0 // channel 0 never overrides
&& channels[ch_idx].entnum == entnum
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1)) { // allways
// override
// sound
// from
// same
// entity
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1)) {
// always override sound from same entity
first_to_die = ch_idx;
break;
}
@ -445,6 +443,7 @@ SND_Spatialize (channel_t *ch)
{
vec_t dot;
vec_t dist;
int phase; // in samples
vec_t lscale, rscale, scale;
vec3_t source_vec;
sfx_t *snd;
@ -453,6 +452,7 @@ SND_Spatialize (channel_t *ch)
if (ch->entnum == cl.viewentity) {
ch->leftvol = ch->master_vol;
ch->rightvol = ch->master_vol;
ch->phase = 0;
return;
}
// calculate stereo seperation and distance attenuation
@ -467,9 +467,11 @@ SND_Spatialize (channel_t *ch)
if (shm->channels == 1) {
rscale = 1.0;
lscale = 1.0;
phase = 0;
} else {
rscale = 1.0 + dot;
lscale = 1.0 - dot;
rscale = 1.0 + dot * snd_volumesep->value;
lscale = 1.0 - dot * snd_volumesep->value;
phase = snd_phasesep->value * 0.001 * shm->speed * dot;
}
// add in distance effect
@ -482,6 +484,8 @@ SND_Spatialize (channel_t *ch)
ch->leftvol = (int) (ch->master_vol * scale);
if (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;
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++) {
if (!ch->sfx)
continue;
ch->oldphase = ch->phase; // prepare to lerp from prev to next phase
SND_Spatialize (ch); // respatialize channel
if (!ch->leftvol && !ch->rightvol)
continue;

View file

@ -32,8 +32,9 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "sound.h"
#include "console.h"
#include "sound.h"
// fixme: Damn crappy complier doesn't allow me to UNDEF _win32 on command line!
#ifdef WIN32SDL
@ -47,7 +48,8 @@
#endif
#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_p, snd_linear_count, snd_vol;
short *snd_out;
@ -289,9 +291,9 @@ S_PaintChannels (int endtime)
end = paintedtime + PAINTBUFFER_SIZE;
// clear the paint buffer
memset (paintbuffer, 0,
(end - paintedtime) * sizeof (portable_samplepair_t));
// memset (paintbuffer, 0,
// (end - paintedtime) * sizeof (portable_samplepair_t));
max_overpaint = 0;
// paint in the channels.
ch = channels;
@ -336,6 +338,12 @@ S_PaintChannels (int endtime)
// transfer out according to DMA format
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;
}
}
@ -389,19 +397,96 @@ SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
int left, right;
int leftvol, rightvol;
signed short *sfx;
int i;
unsigned int i = 0;
unsigned int left_phase, right_phase; // Never allowed < 0 anyway
leftvol = ch->leftvol;
rightvol = ch->rightvol;
max_overpaint = max (abs (ch->phase),
max (abs (ch->oldphase), max_overpaint));
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++) {
data = sfx[i];
left = (data * leftvol) >> 8;
right = (data * rightvol) >> 8;
paintbuffer[i].left += left;
paintbuffer[i].right += right;
paintbuffer[i + left_phase].left += left;
paintbuffer[i + right_phase].right += right;
}
ch->pos += count;
}