mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 07:44:43 +01:00
Add ADPCM .xpcm [Eternal Fantasy (PC)]
This commit is contained in:
parent
9b7161a207
commit
ab90e08484
29
src/coding/circus_decoder.c
Normal file
29
src/coding/circus_decoder.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "coding.h"
|
||||
|
||||
|
||||
/* Circus XPCM mode 2 decoding, verified vs EF.exe (info from foo_adpcm/libpcm and https://github.com/lioncash/ExtractData) */
|
||||
void decode_circus_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_pos = 0;
|
||||
int32_t hist = stream->adpcm_history1_32;
|
||||
int scale = stream->adpcm_scale;
|
||||
off_t frame_offset = stream->offset; /* frame size is 1 */
|
||||
|
||||
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int8_t code = read_8bit(frame_offset+i,stream->streamfile);
|
||||
|
||||
hist += code << scale;
|
||||
if (code == 0) {
|
||||
if (scale > 0)
|
||||
scale--;
|
||||
}
|
||||
else if (code == 127 || code == -128) {
|
||||
if (scale < 8)
|
||||
scale++;
|
||||
}
|
||||
outbuf[sample_pos] = hist;
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist;
|
||||
stream->adpcm_scale = scale;
|
||||
}
|
@ -165,6 +165,8 @@ void decode_xmd(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
/* derf_decoder */
|
||||
void decode_derf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
/* circus_decoder */
|
||||
void decode_circus_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
/* ea_mt_decoder*/
|
||||
ea_mt_codec_data *init_ea_mt(int channels, int type);
|
||||
|
@ -605,6 +605,7 @@ static const coding_info coding_info_list[] = {
|
||||
{coding_DERF, "Xilam DERF 8-bit DPCM"},
|
||||
{coding_ACM, "InterPlay ACM"},
|
||||
{coding_NWA, "VisualArt's NWA DPCM"},
|
||||
{coding_CIRCUS_ADPCM, "Circus 8-bit ADPCM"},
|
||||
|
||||
{coding_EA_MT, "Electronic Arts MicroTalk"},
|
||||
|
||||
|
@ -1726,6 +1726,14 @@
|
||||
RelativePath=".\coding\yamaha_decoder.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\coding\celt_fsb_decoder.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\coding\circus_decoder.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\coding\coding_utils.c"
|
||||
>
|
||||
|
@ -126,6 +126,7 @@
|
||||
<ClCompile Include="coding\at3plus_decoder.c" />
|
||||
<ClCompile Include="coding\atrac9_decoder.c" />
|
||||
<ClCompile Include="coding\celt_fsb_decoder.c" />
|
||||
<ClCompile Include="coding\circus_decoder.c" />
|
||||
<ClCompile Include="coding\coding_utils.c" />
|
||||
<ClCompile Include="coding\ffmpeg_decoder.c" />
|
||||
<ClCompile Include="coding\ffmpeg_decoder_custom_opus.c" />
|
||||
|
@ -1417,6 +1417,9 @@
|
||||
<ClCompile Include="coding\celt_fsb_decoder.c">
|
||||
<Filter>coding\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="coding\circus_decoder.c">
|
||||
<Filter>coding\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\bcstm.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -9,7 +9,6 @@ VGMSTREAM * init_vgmstream_xpcm(STREAMFILE *streamFile) {
|
||||
int loop_flag, channel_count, codec, subcodec, sample_rate;
|
||||
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "pcm"))
|
||||
goto fail;
|
||||
@ -27,7 +26,7 @@ VGMSTREAM * init_vgmstream_xpcm(STREAMFILE *streamFile) {
|
||||
/* 0x14: average bitrate */
|
||||
/* 0x18: block size */
|
||||
/* 0x1a: output bits (16) */
|
||||
start_offset = 0x1c;
|
||||
start_offset = 0x1c; /* compressed size in codec 0x01/03 */
|
||||
|
||||
loop_flag = 0;
|
||||
|
||||
@ -47,11 +46,16 @@ VGMSTREAM * init_vgmstream_xpcm(STREAMFILE *streamFile) {
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
break;
|
||||
case 0x02:
|
||||
if (subcodec != 0) goto fail;
|
||||
vgmstream->coding_type = coding_CIRCUS_ADPCM;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x01;
|
||||
break;
|
||||
|
||||
case 0x01: /* LZSS + VQ */
|
||||
case 0x02: /* ADPCM */
|
||||
case 0x03: /* unknown */
|
||||
default:
|
||||
/* 0x1c contains compressed size for those */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -1124,6 +1124,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
case coding_DERF:
|
||||
case coding_NWA:
|
||||
case coding_SASSC:
|
||||
case coding_CIRCUS_ADPCM:
|
||||
return 1;
|
||||
|
||||
case coding_IMA:
|
||||
@ -1299,6 +1300,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
case coding_DERF:
|
||||
case coding_NWA:
|
||||
case coding_SASSC:
|
||||
case coding_CIRCUS_ADPCM:
|
||||
return 0x01;
|
||||
|
||||
case coding_IMA:
|
||||
@ -1743,6 +1745,12 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||
vgmstream->channels,vgmstream->samples_into_block,samples_to_do);
|
||||
}
|
||||
break;
|
||||
case coding_CIRCUS_ADPCM:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_circus_adpcm(&vgmstream->ch[ch],buffer+samples_written*vgmstream->channels+ch,
|
||||
vgmstream->channels,vgmstream->samples_into_block,samples_to_do);
|
||||
}
|
||||
break;
|
||||
|
||||
case coding_IMA:
|
||||
case coding_IMA_int:
|
||||
|
@ -159,6 +159,7 @@ typedef enum {
|
||||
coding_DERF, /* DERF 8-bit DPCM */
|
||||
coding_ACM, /* InterPlay ACM */
|
||||
coding_NWA, /* VisualArt's NWA */
|
||||
coding_CIRCUS_ADPCM, /* Circus 8-bit ADPCM */
|
||||
|
||||
coding_EA_MT, /* Electronic Arts MicroTalk (linear-predictive speech codec) */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user