mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-26 22:11:18 +00:00
Fix playback of stereo sounds in Base sound system
Already works correctly in OpenAL.
This commit is contained in:
parent
623d107f42
commit
1a86229538
3 changed files with 98 additions and 53 deletions
|
@ -56,6 +56,7 @@ typedef struct sfx_s {
|
||||||
qboolean soundCompressed; // not in Memory
|
qboolean soundCompressed; // not in Memory
|
||||||
int soundCompressionMethod;
|
int soundCompressionMethod;
|
||||||
int soundLength;
|
int soundLength;
|
||||||
|
int soundChannels;
|
||||||
char soundName[MAX_QPATH];
|
char soundName[MAX_QPATH];
|
||||||
int lastTimeUsed;
|
int lastTimeUsed;
|
||||||
struct sfx_s *next;
|
struct sfx_s *next;
|
||||||
|
|
|
@ -113,47 +113,51 @@ ResampleSfx
|
||||||
resample / decimate to the current source rate
|
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 outcount;
|
||||||
int srcsample;
|
int srcsample;
|
||||||
float stepscale;
|
float stepscale;
|
||||||
int i;
|
int i, j;
|
||||||
int sample, samplefrac, fracstep;
|
int sample, samplefrac, fracstep;
|
||||||
int part;
|
int part;
|
||||||
sndBuffer *chunk;
|
sndBuffer *chunk;
|
||||||
|
|
||||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||||
|
|
||||||
outcount = sfx->soundLength / stepscale;
|
outcount = samples / stepscale;
|
||||||
sfx->soundLength = outcount;
|
|
||||||
|
|
||||||
samplefrac = 0;
|
samplefrac = 0;
|
||||||
fracstep = stepscale * 256;
|
fracstep = stepscale * 256 * channels;
|
||||||
chunk = sfx->soundData;
|
chunk = sfx->soundData;
|
||||||
|
|
||||||
for (i=0 ; i<outcount ; i++)
|
for (i=0 ; i<outcount ; i++)
|
||||||
{
|
{
|
||||||
srcsample = samplefrac >> 8;
|
srcsample = samplefrac >> 8;
|
||||||
samplefrac += fracstep;
|
samplefrac += fracstep;
|
||||||
if( inwidth == 2 ) {
|
for (j=0 ; j<channels ; j++)
|
||||||
sample = ( ((short *)data)[srcsample] );
|
{
|
||||||
} else {
|
if( inwidth == 2 ) {
|
||||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
sample = ( ((short *)data)[srcsample+j] );
|
||||||
}
|
|
||||||
part = (i&(SND_CHUNK_SIZE-1));
|
|
||||||
if (part == 0) {
|
|
||||||
sndBuffer *newchunk;
|
|
||||||
newchunk = SND_malloc();
|
|
||||||
if (chunk == NULL) {
|
|
||||||
sfx->soundData = newchunk;
|
|
||||||
} else {
|
} 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -163,11 +167,11 @@ ResampleSfx
|
||||||
resample / decimate to the current source rate
|
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 outcount;
|
||||||
int srcsample;
|
int srcsample;
|
||||||
float stepscale;
|
float stepscale;
|
||||||
int i;
|
int i, j;
|
||||||
int sample, samplefrac, fracstep;
|
int sample, samplefrac, fracstep;
|
||||||
|
|
||||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||||
|
@ -175,18 +179,21 @@ static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byt
|
||||||
outcount = samples / stepscale;
|
outcount = samples / stepscale;
|
||||||
|
|
||||||
samplefrac = 0;
|
samplefrac = 0;
|
||||||
fracstep = stepscale * 256;
|
fracstep = stepscale * 256 * channels;
|
||||||
|
|
||||||
for (i=0 ; i<outcount ; i++)
|
for (i=0 ; i<outcount ; i++)
|
||||||
{
|
{
|
||||||
srcsample = samplefrac >> 8;
|
srcsample = samplefrac >> 8;
|
||||||
samplefrac += fracstep;
|
samplefrac += fracstep;
|
||||||
if( inwidth == 2 ) {
|
for (j=0 ; j<channels ; j++)
|
||||||
sample = LittleShort ( ((short *)data)[srcsample] );
|
{
|
||||||
} else {
|
if( inwidth == 2 ) {
|
||||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
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;
|
return outcount;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +228,7 @@ qboolean S_LoadSound( sfx_t *sfx )
|
||||||
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName);
|
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;
|
sfx->lastTimeUsed = Com_Milliseconds()+1;
|
||||||
|
|
||||||
|
@ -231,29 +238,30 @@ qboolean S_LoadSound( sfx_t *sfx )
|
||||||
// manager to do the right thing for us and page
|
// manager to do the right thing for us and page
|
||||||
// sound in as needed
|
// sound in as needed
|
||||||
|
|
||||||
if( sfx->soundCompressed == qtrue) {
|
if( info.channels == 1 && sfx->soundCompressed == qtrue) {
|
||||||
sfx->soundCompressionMethod = 1;
|
sfx->soundCompressionMethod = 1;
|
||||||
sfx->soundData = NULL;
|
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);
|
S_AdpcmEncodeSound(sfx, samples);
|
||||||
#if 0
|
#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->soundCompressionMethod = 3;
|
||||||
sfx->soundData = NULL;
|
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);
|
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->soundCompressionMethod = 2;
|
||||||
sfx->soundData = NULL;
|
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);
|
encodeWavelet( sfx, samples);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
sfx->soundCompressionMethod = 0;
|
sfx->soundCompressionMethod = 0;
|
||||||
sfx->soundLength = info.samples;
|
|
||||||
sfx->soundData = NULL;
|
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(samples);
|
||||||
Hunk_FreeTempMemory(data);
|
Hunk_FreeTempMemory(data);
|
||||||
|
|
|
@ -234,7 +234,7 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
portable_samplepair_t *samp;
|
portable_samplepair_t *samp;
|
||||||
sndBuffer *chunk;
|
sndBuffer *chunk;
|
||||||
short *samples;
|
short *samples;
|
||||||
float ooff, fdata, fdiv, fleftvol, frightvol;
|
float ooff, fdata[2], fdiv, fleftvol, frightvol;
|
||||||
|
|
||||||
samp = &paintbuffer[ bufferOffset ];
|
samp = &paintbuffer[ bufferOffset ];
|
||||||
|
|
||||||
|
@ -242,6 +242,14 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
sampleOffset *= sc->soundChannels;
|
||||||
|
|
||||||
|
if ( sampleOffset & 1 ) {
|
||||||
|
sampleOffset &= ~1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chunk = sc->soundData;
|
chunk = sc->soundData;
|
||||||
while (sampleOffset>=SND_CHUNK_SIZE) {
|
while (sampleOffset>=SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
|
@ -274,6 +282,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))) {
|
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
|
||||||
data = samples[sampleOffset++];
|
data = samples[sampleOffset++];
|
||||||
samp[i].left += (data * leftvol)>>8;
|
samp[i].left += (data * leftvol)>>8;
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
data = samples[sampleOffset++];
|
||||||
|
}
|
||||||
samp[i].right += (data * rightvol)>>8;
|
samp[i].right += (data * rightvol)>>8;
|
||||||
|
|
||||||
if (sampleOffset == SND_CHUNK_SIZE) {
|
if (sampleOffset == SND_CHUNK_SIZE) {
|
||||||
|
@ -373,10 +385,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
for ( i=0 ; i<count ; i++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
|
|
||||||
aoff = ooff;
|
aoff = ooff;
|
||||||
ooff = ooff + ch->dopplerScale;
|
ooff = ooff + ch->dopplerScale * sc->soundChannels;
|
||||||
boff = ooff;
|
boff = ooff;
|
||||||
fdata = 0;
|
fdata[0] = fdata[1] = 0;
|
||||||
for (j=aoff; j<boff; j++) {
|
for (j=aoff; j<boff; j += sc->soundChannels) {
|
||||||
if (j == SND_CHUNK_SIZE) {
|
if (j == SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
|
@ -385,11 +397,17 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
samples = chunk->sndChunk;
|
samples = chunk->sndChunk;
|
||||||
ooff -= SND_CHUNK_SIZE;
|
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);
|
fdiv = 256 * (boff-aoff) / sc->soundChannels;
|
||||||
samp[i].left += (fdata * fleftvol)/fdiv;
|
samp[i].left += (fdata[0] * fleftvol)/fdiv;
|
||||||
samp[i].right += (fdata * frightvol)/fdiv;
|
samp[i].right += (fdata[1] * frightvol)/fdiv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +420,7 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
portable_samplepair_t *samp;
|
portable_samplepair_t *samp;
|
||||||
sndBuffer *chunk;
|
sndBuffer *chunk;
|
||||||
short *samples;
|
short *samples;
|
||||||
float ooff, fdata, fdiv, fleftvol, frightvol;
|
float ooff, fdata[2], fdiv, fleftvol, frightvol;
|
||||||
|
|
||||||
samp = &paintbuffer[ bufferOffset ];
|
samp = &paintbuffer[ bufferOffset ];
|
||||||
|
|
||||||
|
@ -410,6 +428,14 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
sampleOffset *= sc->soundChannels;
|
||||||
|
|
||||||
|
if ( sampleOffset & 1 ) {
|
||||||
|
sampleOffset &= ~1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chunk = sc->soundData;
|
chunk = sc->soundData;
|
||||||
while (sampleOffset>=SND_CHUNK_SIZE) {
|
while (sampleOffset>=SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
|
@ -426,6 +452,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
for ( i=0 ; i<count ; i++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
data = samples[sampleOffset++];
|
data = samples[sampleOffset++];
|
||||||
samp[i].left += (data * leftvol)>>8;
|
samp[i].left += (data * leftvol)>>8;
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
data = samples[sampleOffset++];
|
||||||
|
}
|
||||||
samp[i].right += (data * rightvol)>>8;
|
samp[i].right += (data * rightvol)>>8;
|
||||||
|
|
||||||
if (sampleOffset == SND_CHUNK_SIZE) {
|
if (sampleOffset == SND_CHUNK_SIZE) {
|
||||||
|
@ -447,10 +477,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
for ( i=0 ; i<count ; i++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
|
|
||||||
aoff = ooff;
|
aoff = ooff;
|
||||||
ooff = ooff + ch->dopplerScale;
|
ooff = ooff + ch->dopplerScale * sc->soundChannels;
|
||||||
boff = ooff;
|
boff = ooff;
|
||||||
fdata = 0;
|
fdata[0] = fdata[1] = 0;
|
||||||
for (j=aoff; j<boff; j++) {
|
for (j=aoff; j<boff; j += sc->soundChannels) {
|
||||||
if (j == SND_CHUNK_SIZE) {
|
if (j == SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
|
@ -459,11 +489,17 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
samples = chunk->sndChunk;
|
samples = chunk->sndChunk;
|
||||||
ooff -= SND_CHUNK_SIZE;
|
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);
|
fdiv = 256 * (boff-aoff) / sc->soundChannels;
|
||||||
samp[i].left += (fdata * fleftvol)/fdiv;
|
samp[i].left += (fdata[0] * fleftvol)/fdiv;
|
||||||
samp[i].right += (fdata * frightvol)/fdiv;
|
samp[i].right += (fdata[1] * frightvol)/fdiv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue