mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-12-11 13:11:47 +00:00
Fixed problems in the ADPCM decoder. Sound is working.
This commit is contained in:
parent
27b83db50d
commit
699e0e39f5
2 changed files with 65 additions and 52 deletions
|
@ -1008,7 +1008,7 @@ ALenum idSoundSample_OpenAL::GetOpenALBufferFormat() const
|
||||||
return alFormat;
|
return alFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 idSoundSample_OpenAL::MS_ADPCM_nibble( MS_ADPCM_decodeState_t* state, int8 nybble, int16* coeff )
|
int32 idSoundSample_OpenAL::MS_ADPCM_nibble( MS_ADPCM_decodeState_t* state, int8 nybble )
|
||||||
{
|
{
|
||||||
const int32 max_audioval = ( ( 1 << ( 16 - 1 ) ) - 1 );
|
const int32 max_audioval = ( ( 1 << ( 16 - 1 ) ) - 1 );
|
||||||
const int32 min_audioval = -( 1 << ( 16 - 1 ) );
|
const int32 min_audioval = -( 1 << ( 16 - 1 ) );
|
||||||
|
@ -1017,10 +1017,11 @@ int32 idSoundSample_OpenAL::MS_ADPCM_nibble( MS_ADPCM_decodeState_t* state, int8
|
||||||
230, 230, 230, 230, 307, 409, 512, 614,
|
230, 230, 230, 230, 307, 409, 512, 614,
|
||||||
768, 614, 512, 409, 307, 230, 230, 230
|
768, 614, 512, 409, 307, 230, 230, 230
|
||||||
};
|
};
|
||||||
|
|
||||||
int32 new_sample, delta;
|
int32 new_sample, delta;
|
||||||
|
|
||||||
new_sample = ( ( state->iSamp1 * coeff[0] ) +
|
new_sample = ( ( state->iSamp1 * state->coef1 ) +
|
||||||
( state->iSamp2 * coeff[1] ) ) / 256;
|
( state->iSamp2 * state->coef2 ) ) / 256;
|
||||||
|
|
||||||
if( nybble & 0x08 )
|
if( nybble & 0x08 )
|
||||||
{
|
{
|
||||||
|
@ -1055,12 +1056,13 @@ int32 idSoundSample_OpenAL::MS_ADPCM_nibble( MS_ADPCM_decodeState_t* state, int8
|
||||||
|
|
||||||
int idSoundSample_OpenAL::MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len )
|
int idSoundSample_OpenAL::MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len )
|
||||||
{
|
{
|
||||||
static MS_ADPCM_decodeState_t state[2];
|
static MS_ADPCM_decodeState_t states[2];
|
||||||
|
MS_ADPCM_decodeState_t* state[2];
|
||||||
|
|
||||||
uint8* freeable, *encoded, *decoded;
|
uint8* freeable, *encoded, *decoded;
|
||||||
int32 encoded_len, samplesleft;
|
int32 encoded_len, samplesleft;
|
||||||
int8 nybble;
|
int8 nybble;
|
||||||
bool stereo;
|
int8 stereo;
|
||||||
int16* coeff[2];
|
|
||||||
int32 new_sample;
|
int32 new_sample;
|
||||||
|
|
||||||
// Allocate the proper sized output buffer
|
// Allocate the proper sized output buffer
|
||||||
|
@ -1068,12 +1070,6 @@ int idSoundSample_OpenAL::MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len
|
||||||
encoded = *audio_buf;
|
encoded = *audio_buf;
|
||||||
freeable = *audio_buf;
|
freeable = *audio_buf;
|
||||||
|
|
||||||
/*
|
|
||||||
*audio_len = ( encoded_len / MS_ADPCM_state.wavefmt.blockalign ) *
|
|
||||||
MS_ADPCM_state.wSamplesPerBlock *
|
|
||||||
MS_ADPCM_state.wavefmt.channels * sizeof( int16 );
|
|
||||||
*/
|
|
||||||
|
|
||||||
*audio_len = ( encoded_len / format.basic.blockSize ) * format.extra.adpcm.samplesPerBlock * format.basic.numChannels * sizeof( int16 );
|
*audio_len = ( encoded_len / format.basic.blockSize ) * format.extra.adpcm.samplesPerBlock * format.basic.numChannels * sizeof( int16 );
|
||||||
|
|
||||||
*audio_buf = ( uint8* ) Mem_Alloc( *audio_len, TAG_AUDIO );
|
*audio_buf = ( uint8* ) Mem_Alloc( *audio_len, TAG_AUDIO );
|
||||||
|
@ -1084,65 +1080,79 @@ int idSoundSample_OpenAL::MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len
|
||||||
}
|
}
|
||||||
decoded = *audio_buf;
|
decoded = *audio_buf;
|
||||||
|
|
||||||
|
assert( format.basic.numChannels == 1 || format.basic.numChannels == 2 );
|
||||||
|
|
||||||
// Get ready... Go!
|
// Get ready... Go!
|
||||||
stereo = ( format.basic.numChannels == 2 );
|
stereo = ( format.basic.numChannels == 2 ) ? 1 : 0;
|
||||||
//state[0] = &MS_ADPCM_state.state[0];
|
state[0] = &states[0];
|
||||||
//state[1] = &MS_ADPCM_state.state[stereo];
|
state[1] = &states[stereo];
|
||||||
|
|
||||||
while( encoded_len >= format.basic.blockSize )
|
while( encoded_len >= format.basic.blockSize )
|
||||||
{
|
{
|
||||||
// Grab the initial information for this block
|
// Grab the initial information for this block
|
||||||
state[0].hPredictor = *encoded++;
|
state[0]->hPredictor = *encoded++;
|
||||||
|
|
||||||
|
assert( state[0]->hPredictor < format.extra.adpcm.numCoef );
|
||||||
|
state[0]->hPredictor = idMath::ClampInt( 0, 6, state[0]->hPredictor );
|
||||||
|
|
||||||
|
state[0]->coef1 = format.extra.adpcm.aCoef[state[0]->hPredictor].coef1;
|
||||||
|
state[0]->coef2 = format.extra.adpcm.aCoef[state[0]->hPredictor].coef2;
|
||||||
|
|
||||||
if( stereo )
|
if( stereo )
|
||||||
{
|
{
|
||||||
state[1].hPredictor = *encoded++;
|
state[1]->hPredictor = *encoded++;
|
||||||
|
|
||||||
|
assert( state[1]->hPredictor < format.extra.adpcm.numCoef );
|
||||||
|
state[1]->hPredictor = idMath::ClampInt( 0, 6, state[1]->hPredictor );
|
||||||
|
|
||||||
|
state[1]->coef1 = format.extra.adpcm.aCoef[state[1]->hPredictor].coef1;
|
||||||
|
state[1]->coef2 = format.extra.adpcm.aCoef[state[1]->hPredictor].coef2;
|
||||||
}
|
}
|
||||||
|
|
||||||
state[0].iDelta = ( ( encoded[1] << 8 ) | encoded[0] );
|
state[0]->iDelta = ( ( encoded[1] << 8 ) | encoded[0] );
|
||||||
encoded += sizeof( int16 );
|
encoded += sizeof( int16 );
|
||||||
if( stereo )
|
if( stereo )
|
||||||
{
|
{
|
||||||
state[1].iDelta = ( ( encoded[1] << 8 ) | encoded[0] );
|
state[1]->iDelta = ( ( encoded[1] << 8 ) | encoded[0] );
|
||||||
encoded += sizeof( int16 );
|
encoded += sizeof( int16 );
|
||||||
}
|
}
|
||||||
state[0].iSamp1 = ( ( encoded[1] << 8 ) | encoded[0] );
|
|
||||||
encoded += sizeof( int16 );
|
state[0]->iSamp1 = ( ( encoded[1] << 8 ) | encoded[0] );
|
||||||
if( stereo )
|
encoded += sizeof( int16 );
|
||||||
{
|
if( stereo )
|
||||||
state[1].iSamp1 = ( ( encoded[1] << 8 ) | encoded[0] );
|
{
|
||||||
encoded += sizeof( int16 );
|
state[1]->iSamp1 = ( ( encoded[1] << 8 ) | encoded[0] );
|
||||||
}
|
encoded += sizeof( int16 );
|
||||||
state[0].iSamp2 = ( ( encoded[1] << 8 ) | encoded[0] );
|
}
|
||||||
encoded += sizeof( int16 );
|
|
||||||
if( stereo )
|
state[0]->iSamp2 = ( ( encoded[1] << 8 ) | encoded[0] );
|
||||||
{
|
encoded += sizeof( int16 );
|
||||||
state[1].iSamp2 = ( ( encoded[1] << 8 ) | encoded[0] );
|
if( stereo )
|
||||||
|
{
|
||||||
|
state[1]->iSamp2 = ( ( encoded[1] << 8 ) | encoded[0] );
|
||||||
encoded += sizeof( int16 );
|
encoded += sizeof( int16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( state[0].hPredictor < format.extra.adpcm.numCoef );
|
|
||||||
assert( state[1].hPredictor < format.extra.adpcm.numCoef );
|
|
||||||
|
|
||||||
coeff[0] = &format.extra.adpcm.aCoef[state[0].hPredictor].coef1;
|
|
||||||
coeff[1] = &format.extra.adpcm.aCoef[state[1].hPredictor].coef2;
|
|
||||||
|
|
||||||
// Store the two initial samples we start with
|
// Store the two initial samples we start with
|
||||||
decoded[0] = state[0].iSamp2 & 0xFF;
|
decoded[0] = state[0]->iSamp2 & 0xFF;
|
||||||
decoded[1] = state[0].iSamp2 >> 8;
|
decoded[1] = ( state[0]->iSamp2 >> 8 ) & 0xFF;
|
||||||
decoded += 2;
|
decoded += 2;
|
||||||
if( stereo )
|
if( stereo )
|
||||||
{
|
{
|
||||||
decoded[0] = state[1].iSamp2 & 0xFF;
|
decoded[0] = state[1]->iSamp2 & 0xFF;
|
||||||
decoded[1] = state[1].iSamp2 >> 8;
|
decoded[1] = ( state[1]->iSamp2 >> 8 ) & 0xFF;
|
||||||
decoded += 2;
|
decoded += 2;
|
||||||
}
|
}
|
||||||
decoded[0] = state[0].iSamp1 & 0xFF;
|
|
||||||
decoded[1] = state[0].iSamp1 >> 8;
|
decoded[0] = state[0]->iSamp1 & 0xFF;
|
||||||
|
decoded[1] = ( state[0]->iSamp1 >> 8 ) & 0xFF;
|
||||||
decoded += 2;
|
decoded += 2;
|
||||||
if( stereo )
|
if( stereo )
|
||||||
{
|
{
|
||||||
decoded[0] = state[1].iSamp1 & 0xFF;
|
decoded[0] = state[1]->iSamp1 & 0xFF;
|
||||||
decoded[1] = state[1].iSamp1 >> 8;
|
decoded[1] = ( state[1]->iSamp1 >> 8 ) & 0xFF;
|
||||||
decoded += 2;
|
decoded += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,17 +1162,17 @@ int idSoundSample_OpenAL::MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len
|
||||||
while( samplesleft > 0 )
|
while( samplesleft > 0 )
|
||||||
{
|
{
|
||||||
nybble = ( *encoded ) >> 4;
|
nybble = ( *encoded ) >> 4;
|
||||||
new_sample = MS_ADPCM_nibble( &state[0], nybble, coeff[0] );
|
new_sample = MS_ADPCM_nibble( state[0], nybble );
|
||||||
|
|
||||||
decoded[0] = new_sample & 0xFF;
|
decoded[0] = new_sample & 0xFF;
|
||||||
new_sample >>= 8;
|
decoded[1] = ( new_sample >> 8 ) & 0xFF;
|
||||||
decoded[1] = new_sample & 0xFF;
|
|
||||||
decoded += 2;
|
decoded += 2;
|
||||||
|
|
||||||
nybble = ( *encoded ) & 0x0F;
|
nybble = ( *encoded ) & 0x0F;
|
||||||
new_sample = MS_ADPCM_nibble( &state[1], nybble, coeff[1] );
|
new_sample = MS_ADPCM_nibble( state[1], nybble );
|
||||||
|
|
||||||
decoded[0] = new_sample & 0xFF;
|
decoded[0] = new_sample & 0xFF;
|
||||||
new_sample >>= 8;
|
decoded[1] = ( new_sample >> 8 ) & 0xFF;
|
||||||
decoded[1] = new_sample & 0xFF;
|
|
||||||
decoded += 2;
|
decoded += 2;
|
||||||
|
|
||||||
++encoded;
|
++encoded;
|
||||||
|
|
|
@ -163,12 +163,15 @@ protected:
|
||||||
struct MS_ADPCM_decodeState_t
|
struct MS_ADPCM_decodeState_t
|
||||||
{
|
{
|
||||||
uint8 hPredictor;
|
uint8 hPredictor;
|
||||||
|
int16 coef1;
|
||||||
|
int16 coef2;
|
||||||
|
|
||||||
uint16 iDelta;
|
uint16 iDelta;
|
||||||
int16 iSamp1;
|
int16 iSamp1;
|
||||||
int16 iSamp2;
|
int16 iSamp2;
|
||||||
};
|
};
|
||||||
|
|
||||||
int32 MS_ADPCM_nibble( MS_ADPCM_decodeState_t* state, int8 nybble, int16* coeff );
|
int32 MS_ADPCM_nibble( MS_ADPCM_decodeState_t* state, int8 nybble );
|
||||||
int MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len );
|
int MS_ADPCM_decode( uint8** audio_buf, uint32* audio_len );
|
||||||
|
|
||||||
struct sampleBuffer_t
|
struct sampleBuffer_t
|
||||||
|
|
Loading…
Reference in a new issue