mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-17 23:36:41 +01:00
Fix REF-IMA ADPCM decoding/num_samples, as it's based on MS-IMA
This commit is contained in:
parent
5e00485948
commit
05916bdf26
@ -277,7 +277,7 @@ void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
|
||||
|
||||
/* IMA with variable-sized frames, header and custom nibble layout (outputs non-aligned number of samples).
|
||||
* Officially defined in "Microsoft Multimedia Standards Update" doc (RIFFNEW.pdf). */
|
||||
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
void decode_ms_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, samples_read = 0, samples_done = 0, max_samples;
|
||||
|
||||
int32_t hist1;// = stream->adpcm_history1_32;
|
||||
@ -331,6 +331,62 @@ void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * out
|
||||
//stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* Reflection's MS-IMA (some layout info from XA2WAV by Deniz Oezmen) */
|
||||
void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, samples_read = 0, samples_done = 0, max_samples;
|
||||
|
||||
int32_t hist1;// = stream->adpcm_history1_32;
|
||||
int step_index;// = stream->adpcm_step_index;
|
||||
|
||||
/* internal interleave (configurable size), mixed channels (4 byte per ch) */
|
||||
int block_channel_size = (vgmstream->interleave_block_size - 0x04*vgmstream->channels) / vgmstream->channels;
|
||||
int block_samples = ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
/* normal header (hist+step+reserved per channel) */
|
||||
{
|
||||
off_t header_offset = stream->offset + 0x04*channel;
|
||||
|
||||
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+0x02,stream->streamfile); /* 0x03: reserved */
|
||||
if (step_index < 0) step_index = 0;
|
||||
if (step_index > 88) step_index = 88;
|
||||
|
||||
/* write header sample */
|
||||
if (samples_read >= first_sample && samples_done < samples_to_do) {
|
||||
outbuf[samples_done * channelspacing] = (short)hist1;
|
||||
samples_done++;
|
||||
}
|
||||
samples_read++;
|
||||
}
|
||||
|
||||
max_samples = (block_samples - samples_read);
|
||||
if (max_samples > samples_to_do + first_sample - samples_done)
|
||||
max_samples = samples_to_do + first_sample - samples_done; /* for smaller last block */
|
||||
|
||||
/* decode nibbles (layout: all nibbles from one channel, then other channels) */
|
||||
for (i = 0; i < max_samples; i++) {
|
||||
off_t byte_offset = stream->offset + 0x04*vgmstream->channels + block_channel_size*channel + i/2;
|
||||
int nibble_shift = (i&1?4:0); /* low nibble first */
|
||||
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
|
||||
if (samples_read >= first_sample && samples_done < samples_to_do) {
|
||||
outbuf[samples_done * channelspacing] = (short)(hist1);
|
||||
samples_done++;
|
||||
}
|
||||
samples_read++;
|
||||
}
|
||||
|
||||
/* internal interleave: increment offset on complete frame */
|
||||
if (first_sample + samples_done == block_samples) {
|
||||
stream->offset += vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
//stream->adpcm_history1_32 = hist1;
|
||||
//stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* ************************************ */
|
||||
/* XBOX-IMA */
|
||||
/* ************************************ */
|
||||
@ -387,7 +443,7 @@ void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * o
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* mono XBOX ADPCM for interleave */
|
||||
/* mono XBOX-IMA ADPCM for interleave */
|
||||
void decode_xbox_ima_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, sample_count = 0, num_frame;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
@ -674,44 +730,6 @@ void decode_wwise_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample *
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
/* Reflection's MS-IMA (some layout info from XA2WAV) */
|
||||
void decode_ref_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
||||
int i, sample_count;
|
||||
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int step_index = stream->adpcm_step_index;
|
||||
|
||||
//internal interleave (configurable size), mixed channels (4 byte per ch)
|
||||
int block_channel_size = (vgmstream->interleave_block_size - 4*vgmstream->channels) / vgmstream->channels;
|
||||
int block_samples = (vgmstream->interleave_block_size - 4*vgmstream->channels) * 2 / vgmstream->channels;
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
//normal header (per channel)
|
||||
if (first_sample == 0) {
|
||||
off_t header_offset = stream->offset + 4*channel;
|
||||
|
||||
hist1 = read_16bitLE(header_offset,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+2,stream->streamfile);
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
}
|
||||
|
||||
//layout: all nibbles from one channel, then all nibbles from other
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
off_t byte_offset = stream->offset + 4*vgmstream->channels + block_channel_size*channel + i/2;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
//internal interleave: increment offset on complete frame
|
||||
if (i == block_samples) stream->offset += vgmstream->interleave_block_size;
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_step_index = step_index;
|
||||
}
|
||||
|
||||
void decode_awc_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
|
@ -1076,16 +1076,16 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
case coding_APPLE_IMA4:
|
||||
return 64;
|
||||
case coding_MS_IMA:
|
||||
return ((vgmstream->interleave_block_size-4*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
case coding_REF_IMA:
|
||||
return ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
case coding_RAD_IMA:
|
||||
case coding_WWISE_IMA:
|
||||
case coding_REF_IMA:
|
||||
return (vgmstream->interleave_block_size-4*vgmstream->channels)*2/vgmstream->channels;
|
||||
return (vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels;
|
||||
case coding_NDS_IMA:
|
||||
case coding_DAT4_IMA:
|
||||
return (vgmstream->interleave_block_size-4)*2;
|
||||
return (vgmstream->interleave_block_size - 0x04) * 2;
|
||||
case coding_AWC_IMA:
|
||||
return (0x800-4)*2;
|
||||
return (0x800 - 0x04) * 2;
|
||||
case coding_RAD_IMA_mono:
|
||||
return 32;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user