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_pos 16
#define ch_looping 20 #define ch_looping 20
#define ch_entnum 24 #define ch_entnum 24
#define ch_entchannel 28 #define ch_entchannel 28
#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

View file

@ -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;
@ -79,13 +79,15 @@ typedef struct
int leftvol; // 0-255 volume int leftvol; // 0-255 volume
int rightvol; // 0-255 volume int rightvol; // 0-255 volume
int end; // end time in global paintsamples 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 looping; // where to loop, -1 = no looping
int entnum; // to allow overriding a specific sound int entnum; // to allow overriding a specific sound
int entchannel; // int entchannel; //
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;

View file

@ -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,12 +220,11 @@ S_Init (void)
} }
snd_initialized = true; snd_initialized = true;
S_Startup (); S_Startup ();
if (sound_started == 0) // sound startup failed? Bail out. if (sound_started == 0) // sound startup failed? Bail out.
return; return;
SND_InitScaletable (); SND_InitScaletable ();
@ -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;

View file

@ -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;
} }