summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorZack Middleton <zturtleman@gmail.com>2013-12-15 00:18:29 -0600
committerTim Angus <tim@ngus.net>2014-06-17 17:43:37 +0100
commitd6e67ad9d11e3683094f5cca559b79744d3737ef (patch)
treec79d1c0fbbfe9ed45c99bc06adf0f917e33d4553 /src/client
parent1efa9bd0b4748ab2a8bc7b962fc7f0dce03daa8c (diff)
Fix playback of stereo sounds in Base sound system
Already works correctly in OpenAL.
Diffstat (limited to 'src/client')
-rw-r--r--src/client/snd_local.h1
-rw-r--r--src/client/snd_mem.c82
-rw-r--r--src/client/snd_mix.c68
3 files changed, 98 insertions, 53 deletions
diff --git a/src/client/snd_local.h b/src/client/snd_local.h
index 1f842d89..8f5be112 100644
--- a/src/client/snd_local.h
+++ b/src/client/snd_local.h
@@ -57,6 +57,7 @@ typedef struct sfx_s {
qboolean soundCompressed; // not in Memory
int soundCompressionMethod;
int soundLength;
+ int soundChannels;
char soundName[MAX_QPATH];
int lastTimeUsed;
int duration;
diff --git a/src/client/snd_mem.c b/src/client/snd_mem.c
index ecca5292..299d9d34 100644
--- a/src/client/snd_mem.c
+++ b/src/client/snd_mem.c
@@ -114,47 +114,51 @@ ResampleSfx
resample / decimate to the current source rate
================
*/
-static void ResampleSfx( sfx_t *sfx, int inrate, int inwidth, byte *data, qboolean compressed ) {
+static int ResampleSfx( sfx_t *sfx, int channels, int inrate, int inwidth, int samples, byte *data, qboolean compressed ) {
int outcount;
int srcsample;
float stepscale;
- int i;
+ int i, j;
int sample, samplefrac, fracstep;
int part;
sndBuffer *chunk;
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
- outcount = sfx->soundLength / stepscale;
- sfx->soundLength = outcount;
+ outcount = samples / stepscale;
samplefrac = 0;
- fracstep = stepscale * 256;
+ fracstep = stepscale * 256 * channels;
chunk = sfx->soundData;
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 8;
samplefrac += fracstep;
- if( inwidth == 2 ) {
- sample = ( ((short *)data)[srcsample] );
- } else {
- sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
- }
- part = (i&(SND_CHUNK_SIZE-1));
- if (part == 0) {
- sndBuffer *newchunk;
- newchunk = SND_malloc();
- if (chunk == NULL) {
- sfx->soundData = newchunk;
+ for (j=0 ; j<channels ; j++)
+ {
+ if( inwidth == 2 ) {
+ sample = ( ((short *)data)[srcsample+j] );
} else {
- chunk->next = newchunk;
+ sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
+ }
+ part = (i*channels+j)&(SND_CHUNK_SIZE-1);
+ if (part == 0) {
+ sndBuffer *newchunk;
+ newchunk = SND_malloc();
+ if (chunk == NULL) {
+ sfx->soundData = newchunk;
+ } else {
+ chunk->next = newchunk;
+ }
+ chunk = newchunk;
}
- chunk = newchunk;
- }
- chunk->sndChunk[part] = sample;
+ chunk->sndChunk[part] = sample;
+ }
}
+
+ return outcount;
}
/*
@@ -164,11 +168,11 @@ ResampleSfx
resample / decimate to the current source rate
================
*/
-static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byte *data ) {
+static int ResampleSfxRaw( short *sfx, int channels, int inrate, int inwidth, int samples, byte *data ) {
int outcount;
int srcsample;
float stepscale;
- int i;
+ int i, j;
int sample, samplefrac, fracstep;
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
@@ -176,18 +180,21 @@ static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byt
outcount = samples / stepscale;
samplefrac = 0;
- fracstep = stepscale * 256;
+ fracstep = stepscale * 256 * channels;
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;
+ for (j=0 ; j<channels ; j++)
+ {
+ if( inwidth == 2 ) {
+ sample = LittleShort ( ((short *)data)[srcsample+j] );
+ } else {
+ sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
+ }
+ sfx[i*channels+j] = sample;
}
- sfx[i] = sample;
}
return outcount;
}
@@ -226,7 +233,7 @@ qboolean S_LoadSound( sfx_t *sfx )
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName);
}
- samples = Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2);
+ samples = Hunk_AllocateTempMemory(info.channels * info.samples * sizeof(short) * 2);
sfx->lastTimeUsed = Com_Milliseconds()+1;
@@ -236,29 +243,30 @@ qboolean S_LoadSound( sfx_t *sfx )
// manager to do the right thing for us and page
// sound in as needed
- if( sfx->soundCompressed == qtrue) {
+ if( info.channels == 1 && sfx->soundCompressed == qtrue) {
sfx->soundCompressionMethod = 1;
sfx->soundData = NULL;
- sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, data + info.dataofs );
+ sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, data + info.dataofs );
S_AdpcmEncodeSound(sfx, samples);
#if 0
- } else if (info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
+ } else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
sfx->soundCompressionMethod = 3;
sfx->soundData = NULL;
- sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
+ sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
encodeMuLaw( sfx, samples);
- } else if (info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
+ } else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
sfx->soundCompressionMethod = 2;
sfx->soundData = NULL;
- sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
+ sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
encodeWavelet( sfx, samples);
#endif
} else {
sfx->soundCompressionMethod = 0;
- sfx->soundLength = info.samples;
sfx->soundData = NULL;
- ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse );
+ sfx->soundLength = ResampleSfx( sfx, info.channels, info.rate, info.width, info.samples, data + info.dataofs, qfalse );
}
+
+ sfx->soundChannels = info.channels;
Hunk_FreeTempMemory(samples);
Hunk_FreeTempMemory(data);
diff --git a/src/client/snd_mix.c b/src/client/snd_mix.c
index 80c892f5..3c2fd240 100644
--- a/src/client/snd_mix.c
+++ b/src/client/snd_mix.c
@@ -235,7 +235,7 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
- float ooff, fdata, fdiv, fleftvol, frightvol;
+ float ooff, fdata[2], fdiv, fleftvol, frightvol;
samp = &paintbuffer[ bufferOffset ];
@@ -243,6 +243,14 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
+ if ( sc->soundChannels == 2 ) {
+ sampleOffset *= sc->soundChannels;
+
+ if ( sampleOffset & 1 ) {
+ sampleOffset &= ~1;
+ }
+ }
+
chunk = sc->soundData;
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
@@ -275,6 +283,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
+
+ if ( sc->soundChannels == 2 ) {
+ data = samples[sampleOffset++];
+ }
samp[i].right += (data * rightvol)>>8;
if (sampleOffset == SND_CHUNK_SIZE) {
@@ -374,10 +386,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
- ooff = ooff + ch->dopplerScale;
+ ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
- fdata = 0;
- for (j=aoff; j<boff; j++) {
+ fdata[0] = fdata[1] = 0;
+ for (j=aoff; j<boff; j += sc->soundChannels) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if (!chunk) {
@@ -386,11 +398,17 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
- fdata += samples[j&(SND_CHUNK_SIZE-1)];
+ if ( sc->soundChannels == 2 ) {
+ fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
+ fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
+ } else {
+ fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
+ fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
+ }
}
- fdiv = 256 * (boff-aoff);
- samp[i].left += (fdata * fleftvol)/fdiv;
- samp[i].right += (fdata * frightvol)/fdiv;
+ fdiv = 256 * (boff-aoff) / sc->soundChannels;
+ samp[i].left += (fdata[0] * fleftvol)/fdiv;
+ samp[i].right += (fdata[1] * frightvol)/fdiv;
}
}
}
@@ -403,7 +421,7 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
- float ooff, fdata, fdiv, fleftvol, frightvol;
+ float ooff, fdata[2], fdiv, fleftvol, frightvol;
samp = &paintbuffer[ bufferOffset ];
@@ -411,6 +429,14 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
+ if ( sc->soundChannels == 2 ) {
+ sampleOffset *= sc->soundChannels;
+
+ if ( sampleOffset & 1 ) {
+ sampleOffset &= ~1;
+ }
+ }
+
chunk = sc->soundData;
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
@@ -427,6 +453,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
for ( i=0 ; i<count ; i++ ) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
+
+ if ( sc->soundChannels == 2 ) {
+ data = samples[sampleOffset++];
+ }
samp[i].right += (data * rightvol)>>8;
if (sampleOffset == SND_CHUNK_SIZE) {
@@ -448,10 +478,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
- ooff = ooff + ch->dopplerScale;
+ ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
- fdata = 0;
- for (j=aoff; j<boff; j++) {
+ fdata[0] = fdata[1] = 0;
+ for (j=aoff; j<boff; j += sc->soundChannels) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if (!chunk) {
@@ -460,11 +490,17 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
- fdata += samples[j&(SND_CHUNK_SIZE-1)];
+ if ( sc->soundChannels == 2 ) {
+ fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
+ fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
+ } else {
+ fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
+ fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
+ }
}
- fdiv = 256 * (boff-aoff);
- samp[i].left += (fdata * fleftvol)/fdiv;
- samp[i].right += (fdata * frightvol)/fdiv;
+ fdiv = 256 * (boff-aoff) / sc->soundChannels;
+ samp[i].left += (fdata[0] * fleftvol)/fdiv;
+ samp[i].right += (fdata[1] * frightvol)/fdiv;
}
}
}