VGMStream: Updated libvgmstream code base
Updated VGMStream to r2023-35-ge417e033 Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
6d2b7c0ae6
commit
42977ce5bb
11 changed files with 100 additions and 105 deletions
|
@ -658,7 +658,6 @@
|
||||||
837CEAFC23487F2C00E62A4A /* raw_wavm.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE723487F2B00E62A4A /* raw_wavm.c */; };
|
837CEAFC23487F2C00E62A4A /* raw_wavm.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE723487F2B00E62A4A /* raw_wavm.c */; };
|
||||||
837CEAFD23487F2C00E62A4A /* psf.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE823487F2B00E62A4A /* psf.c */; };
|
837CEAFD23487F2C00E62A4A /* psf.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE823487F2B00E62A4A /* psf.c */; };
|
||||||
837CEAFE23487F2C00E62A4A /* jstm_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 837CEAE923487F2B00E62A4A /* jstm_streamfile.h */; };
|
837CEAFE23487F2C00E62A4A /* jstm_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 837CEAE923487F2B00E62A4A /* jstm_streamfile.h */; };
|
||||||
837CEAFF23487F2C00E62A4A /* raw_snds.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAEA23487F2B00E62A4A /* raw_snds.c */; };
|
|
||||||
837CEB0023487F2C00E62A4A /* smk.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAEB23487F2B00E62A4A /* smk.c */; };
|
837CEB0023487F2C00E62A4A /* smk.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAEB23487F2B00E62A4A /* smk.c */; };
|
||||||
837CEB0123487F2C00E62A4A /* xmu.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAEC23487F2C00E62A4A /* xmu.c */; };
|
837CEB0123487F2C00E62A4A /* xmu.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAEC23487F2C00E62A4A /* xmu.c */; };
|
||||||
837CEB0223487F2C00E62A4A /* raw_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAED23487F2C00E62A4A /* raw_int.c */; };
|
837CEB0223487F2C00E62A4A /* raw_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAED23487F2C00E62A4A /* raw_int.c */; };
|
||||||
|
@ -1618,7 +1617,6 @@
|
||||||
837CEAE723487F2B00E62A4A /* raw_wavm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_wavm.c; sourceTree = "<group>"; };
|
837CEAE723487F2B00E62A4A /* raw_wavm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_wavm.c; sourceTree = "<group>"; };
|
||||||
837CEAE823487F2B00E62A4A /* psf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = psf.c; sourceTree = "<group>"; };
|
837CEAE823487F2B00E62A4A /* psf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = psf.c; sourceTree = "<group>"; };
|
||||||
837CEAE923487F2B00E62A4A /* jstm_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jstm_streamfile.h; sourceTree = "<group>"; };
|
837CEAE923487F2B00E62A4A /* jstm_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jstm_streamfile.h; sourceTree = "<group>"; };
|
||||||
837CEAEA23487F2B00E62A4A /* raw_snds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_snds.c; sourceTree = "<group>"; };
|
|
||||||
837CEAEB23487F2B00E62A4A /* smk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smk.c; sourceTree = "<group>"; };
|
837CEAEB23487F2B00E62A4A /* smk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smk.c; sourceTree = "<group>"; };
|
||||||
837CEAEC23487F2C00E62A4A /* xmu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xmu.c; sourceTree = "<group>"; };
|
837CEAEC23487F2C00E62A4A /* xmu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xmu.c; sourceTree = "<group>"; };
|
||||||
837CEAED23487F2C00E62A4A /* raw_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_int.c; sourceTree = "<group>"; };
|
837CEAED23487F2C00E62A4A /* raw_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_int.c; sourceTree = "<group>"; };
|
||||||
|
@ -2617,7 +2615,6 @@
|
||||||
837CEADD23487F2A00E62A4A /* raw_pcm.c */,
|
837CEADD23487F2A00E62A4A /* raw_pcm.c */,
|
||||||
836F6EE718BDC2190095E648 /* raw_rsf.c */,
|
836F6EE718BDC2190095E648 /* raw_rsf.c */,
|
||||||
836F6EEA18BDC2190095E648 /* raw_s14_sss.c */,
|
836F6EEA18BDC2190095E648 /* raw_s14_sss.c */,
|
||||||
837CEAEA23487F2B00E62A4A /* raw_snds.c */,
|
|
||||||
837CEAE723487F2B00E62A4A /* raw_wavm.c */,
|
837CEAE723487F2B00E62A4A /* raw_wavm.c */,
|
||||||
836F6EE218BDC2190095E648 /* redspark.c */,
|
836F6EE218BDC2190095E648 /* redspark.c */,
|
||||||
834FE0D9215C79EA000A5D3D /* rfrm.c */,
|
834FE0D9215C79EA000A5D3D /* rfrm.c */,
|
||||||
|
@ -3609,7 +3606,6 @@
|
||||||
834F7E842C709F5B003AC386 /* apa3.c in Sources */,
|
834F7E842C709F5B003AC386 /* apa3.c in Sources */,
|
||||||
834FE106215C79ED000A5D3D /* utk.c in Sources */,
|
834FE106215C79ED000A5D3D /* utk.c in Sources */,
|
||||||
8373342B23F60CDC00DE14DC /* fwse.c in Sources */,
|
8373342B23F60CDC00DE14DC /* fwse.c in Sources */,
|
||||||
837CEAFF23487F2C00E62A4A /* raw_snds.c in Sources */,
|
|
||||||
83031EDC243C510500C3F3E0 /* vid1.c in Sources */,
|
83031EDC243C510500C3F3E0 /* vid1.c in Sources */,
|
||||||
834F7DD02C7093EA003AC386 /* icelib.c in Sources */,
|
834F7DD02C7093EA003AC386 /* icelib.c in Sources */,
|
||||||
83AA5D271F6E2F9C0020821C /* stma.c in Sources */,
|
83AA5D271F6E2F9C0020821C /* stma.c in Sources */,
|
||||||
|
|
|
@ -474,6 +474,7 @@ int decode_get_frame_size(VGMSTREAM* vgmstream) {
|
||||||
case coding_OKI16:
|
case coding_OKI16:
|
||||||
case coding_OKI4S:
|
case coding_OKI4S:
|
||||||
case coding_MTF_IMA:
|
case coding_MTF_IMA:
|
||||||
|
case coding_SNDS_IMA:
|
||||||
return 0x01;
|
return 0x01;
|
||||||
case coding_RAD_IMA:
|
case coding_RAD_IMA:
|
||||||
case coding_NDS_IMA:
|
case coding_NDS_IMA:
|
||||||
|
@ -487,7 +488,6 @@ int decode_get_frame_size(VGMSTREAM* vgmstream) {
|
||||||
return 0x800;
|
return 0x800;
|
||||||
case coding_RAD_IMA_mono:
|
case coding_RAD_IMA_mono:
|
||||||
return 0x14;
|
return 0x14;
|
||||||
case coding_SNDS_IMA:
|
|
||||||
case coding_QD_IMA:
|
case coding_QD_IMA:
|
||||||
return 0; //todo: 0x01?
|
return 0; //todo: 0x01?
|
||||||
case coding_UBI_IMA: /* variable (PCM then IMA) */
|
case coding_UBI_IMA: /* variable (PCM then IMA) */
|
||||||
|
|
|
@ -145,24 +145,27 @@ static void camelot_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offs
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The Incredibles PC, updates step_index before doing current sample */
|
/* The Incredibles PC, updates step_index before doing current sample, reverse engineered from the .exe
|
||||||
|
* (has no apparent name, files are raw data with .WAV extension but are inside a 'SNDS' folder).
|
||||||
|
* A few voices show slight drifting but tables and algo look fine, encoder issue? */
|
||||||
static void snds_ima_expand_nibble(VGMSTREAMCHANNEL* stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
static void snds_ima_expand_nibble(VGMSTREAMCHANNEL* stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||||
int sample_nibble, sample_decoded, step, delta;
|
int sample, step, delta;
|
||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
uint8_t code = (read_u8(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample = *hist1;
|
||||||
|
|
||||||
*step_index += ima_index_table[sample_nibble];
|
int code_pos = code & 7;
|
||||||
|
*step_index += ima_index_table[code_pos]; //OG table doesn't have negative indexes
|
||||||
if (*step_index < 0) *step_index = 0;
|
if (*step_index < 0) *step_index = 0;
|
||||||
if (*step_index > 88) *step_index = 88;
|
if (*step_index > 88) *step_index = 88;
|
||||||
|
|
||||||
step = ima_step_size_table[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = (sample_nibble & 7) * step / 4 + step / 8; /* standard IMA */
|
delta = (step >> 3) + ((step * code_pos) >> 2);
|
||||||
if (sample_nibble & 8) delta = -delta;
|
if (code & 8) delta = -delta;
|
||||||
sample_decoded += delta;
|
sample += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Omikron: The Nomad Soul, algorithm from the .exe */
|
/* Omikron: The Nomad Soul, algorithm from the .exe */
|
||||||
|
@ -440,20 +443,27 @@ void decode_camelot_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channe
|
||||||
}
|
}
|
||||||
|
|
||||||
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||||
int i, sample_count;
|
bool is_stereo = channelspacing > 1;
|
||||||
int32_t hist1 = stream->adpcm_history1_32;
|
|
||||||
int step_index = stream->adpcm_step_index;
|
int32_t hist1 = stream->adpcm_history1_32; // starts at 0
|
||||||
|
int step_index = stream->adpcm_step_index; // starts at 0
|
||||||
|
|
||||||
//external interleave
|
//external interleave
|
||||||
|
|
||||||
//no header
|
//no header
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
int sample_count = 0;
|
||||||
off_t byte_offset = stream->offset + i;//one nibble per channel
|
for (int i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||||
int nibble_shift = (channel==0?0:4); //high nibble first, based on channel
|
off_t byte_offset = is_stereo ?
|
||||||
|
stream->offset + i : // stereo: one nibble per channel
|
||||||
|
stream->offset + i/2; // mono: consecutive nibbles
|
||||||
|
int nibble_shift = is_stereo ?
|
||||||
|
((channel&1) ? 4:0) : //high nibble first
|
||||||
|
((i&1) ? 4:0);
|
||||||
|
|
||||||
snds_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
snds_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||||
outbuf[sample_count] = (short)(hist1);
|
outbuf[sample_count] = (short)(hist1);
|
||||||
|
sample_count += channelspacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->adpcm_history1_32 = hist1;
|
stream->adpcm_history1_32 = hist1;
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
|
|
||||||
/* Decodes Tantalus TADC ADPCM codec, used in Saturn games.
|
/* Decodes Tantalus TADC ADPCM codec, used in Saturn games.
|
||||||
* Guessed based on other XA-style codecs values. */
|
* Reverse engineered from the exe (@ 0x06086d2 w/ 0x06010000 base address) */
|
||||||
void decode_tantalus(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
void decode_tantalus(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||||
uint8_t frame[0x10] = {0};
|
uint8_t frame[0x10] = {0};
|
||||||
off_t frame_offset;
|
off_t frame_offset;
|
||||||
int i, frames_in, sample_count = 0;
|
int frames_in, sample_count = 0;
|
||||||
size_t bytes_per_frame, samples_per_frame;
|
size_t bytes_per_frame, samples_per_frame;
|
||||||
int shift, filter, coef1, coef2;
|
|
||||||
int32_t hist1 = stream->adpcm_history1_32;
|
int32_t hist1 = stream->adpcm_history1_32;
|
||||||
int32_t hist2 = stream->adpcm_history2_32;
|
int32_t hist2 = stream->adpcm_history2_32;
|
||||||
|
|
||||||
|
@ -22,39 +22,31 @@ void decode_tantalus(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspac
|
||||||
/* parse frame header */
|
/* parse frame header */
|
||||||
frame_offset = stream->offset + bytes_per_frame*frames_in;
|
frame_offset = stream->offset + bytes_per_frame*frames_in;
|
||||||
read_streamfile(frame, frame_offset, bytes_per_frame, stream->streamfile); /* ignore EOF errors */
|
read_streamfile(frame, frame_offset, bytes_per_frame, stream->streamfile); /* ignore EOF errors */
|
||||||
filter = (frame[0x00] >> 4) & 0xf; /* 0 in tested files */
|
|
||||||
shift = (frame[0x00] >> 0) & 0xf;
|
// there is no XA filter select code but upper 4 bits seem to be always 0
|
||||||
if (filter != 0) {
|
int shift = (frame[0x00] >> 0);
|
||||||
VGM_LOG_ONCE("TANTALUS: unknown filter\n");
|
|
||||||
coef1 = 64;
|
|
||||||
coef2 = 64; /* will sound horrid and hopefully reported */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
coef1 = 64;
|
|
||||||
coef2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* decode nibbles */
|
/* decode nibbles */
|
||||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
for (int i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||||
uint8_t nibbles = frame[0x01 + i/2];
|
uint8_t nibbles = frame[0x01 + i/2];
|
||||||
int32_t sample;
|
int32_t sample;
|
||||||
|
|
||||||
sample = i&1 ? /* low nibble first */
|
int8_t code = i&1 ? /* low nibble first */
|
||||||
get_high_nibble_signed(nibbles) :
|
get_high_nibble_signed(nibbles) :
|
||||||
get_low_nibble_signed(nibbles);
|
get_low_nibble_signed(nibbles);
|
||||||
sample = sample << (shift + 6);
|
|
||||||
sample = (sample + (hist1 * coef1) + (hist2 * coef2)) >> 6;
|
// calc is done via [code][shift] = delta LUT in OG code (perhaps because SH2 can only do 1/2/4 shifts)
|
||||||
|
// basically equivalent to an XA codec with coef1 = 1.0, coef2 = 0.0
|
||||||
|
sample = hist1 + (code << shift);
|
||||||
|
|
||||||
outbuf[sample_count] = clamp16(sample);
|
outbuf[sample_count] = clamp16(sample);
|
||||||
sample_count += channelspacing;
|
sample_count += channelspacing;
|
||||||
|
|
||||||
hist2 = hist1;
|
|
||||||
hist1 = sample;
|
hist1 = sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->adpcm_history1_32 = hist1;
|
stream->adpcm_history1_32 = hist1;
|
||||||
stream->adpcm_history2_32 = hist2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tantalus_bytes_to_samples(size_t bytes, int channels) {
|
int32_t tantalus_bytes_to_samples(size_t bytes, int channels) {
|
||||||
|
|
|
@ -543,7 +543,7 @@ static const char* extension_list[] = {
|
||||||
"sn0",
|
"sn0",
|
||||||
"snb",
|
"snb",
|
||||||
"snd",
|
"snd",
|
||||||
"snds",
|
"snds", //fake extension for .wav (renamed, to be removed)
|
||||||
"sng",
|
"sng",
|
||||||
"sngw",
|
"sngw",
|
||||||
"snr",
|
"snr",
|
||||||
|
|
|
@ -1566,6 +1566,12 @@ static const hcakey_info hcakey_list[] = {
|
||||||
// CHUNITHM Chinese Version (AC)
|
// CHUNITHM Chinese Version (AC)
|
||||||
{30194896045700459}, // 006B461914D5756B
|
{30194896045700459}, // 006B461914D5756B
|
||||||
|
|
||||||
|
// Raidou Remastered: The Mystery of the Soulless Army (PS4)
|
||||||
|
{954534454324}, // 000000DE3EAFE434
|
||||||
|
|
||||||
|
// Sand Land (multi)
|
||||||
|
{910990237314908160}, // 0CA47CCB51010000
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -482,8 +482,6 @@ VGMSTREAM * init_vgmstream_lsf_n1nj4n(STREAMFILE* streamFile);
|
||||||
VGMSTREAM * init_vgmstream_xwav_new(STREAMFILE* sf);
|
VGMSTREAM * init_vgmstream_xwav_new(STREAMFILE* sf);
|
||||||
VGMSTREAM * init_vgmstream_xwav_old(STREAMFILE* sf);
|
VGMSTREAM * init_vgmstream_xwav_old(STREAMFILE* sf);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_raw_snds(STREAMFILE* streamFile);
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_hyperscan_kvag(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_hyperscan_kvag(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM* init_vgmstream_psnd(STREAMFILE* sf);
|
VGMSTREAM* init_vgmstream_psnd(STREAMFILE* sf);
|
||||||
|
|
|
@ -10,19 +10,27 @@ VGMSTREAM* init_vgmstream_piff_tpcm(STREAMFILE* sf) {
|
||||||
|
|
||||||
|
|
||||||
/* checks */
|
/* checks */
|
||||||
|
if (!is_id32be(0x00,sf, "PIFF"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* .tad: from internal filenames */
|
/* .tad: from internal filenames */
|
||||||
if (!check_extensions(sf, "tad"))
|
if (!check_extensions(sf, "tad"))
|
||||||
goto fail;
|
return NULL;
|
||||||
/* Tantalus also has PIFF without this */
|
|
||||||
if (!is_id32be(0x00,sf, "PIFF") || !is_id32be(0x08,sf, "TPCM") || !is_id32be(0x0c,sf, "TADH"))
|
uint32_t piff_size = read_s32le(0x04,sf);
|
||||||
goto fail;
|
if (piff_size + 0x08 != get_streamfile_size(sf))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Tantalus also has PIFF without this
|
||||||
|
if (!is_id32be(0x08,sf, "TPCM") || !is_id32be(0x0c,sf, "TADH"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
header_offset = 0x14;
|
header_offset = 0x14;
|
||||||
/* 0x00: 1? */
|
// 0x00: 1?
|
||||||
/* 0x01: 1? */
|
// 0x01: 1?
|
||||||
channels = read_u16le(header_offset + 0x02,sf);
|
channels = read_u16le(header_offset + 0x02,sf);
|
||||||
sample_rate = read_s32le(header_offset + 0x04,sf);
|
sample_rate = read_s32le(header_offset + 0x04,sf);
|
||||||
/* 0x08+: ? (mostly fixed, maybe related to ADPCM?) */
|
// 0x08+: ? (mostly fixed, maybe related to ADPCM?)
|
||||||
loop_flag = 0;
|
loop_flag = 0;
|
||||||
|
|
||||||
if (!is_id32be(0x38,sf, "BODY"))
|
if (!is_id32be(0x38,sf, "BODY"))
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
#include "meta.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* .snds - from Heavy Iron's The Incredibles (PC) */
|
|
||||||
VGMSTREAM * init_vgmstream_raw_snds(STREAMFILE *streamFile) {
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
|
||||||
off_t start_offset;
|
|
||||||
int loop_flag, channel_count;
|
|
||||||
size_t file_size;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
|
|
||||||
/* checks */
|
|
||||||
if (!check_extensions(streamFile, "snds"))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
loop_flag = 0;
|
|
||||||
channel_count = 2;
|
|
||||||
start_offset = 0;
|
|
||||||
file_size = get_streamfile_size(streamFile);
|
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
|
||||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
|
||||||
if (!vgmstream) goto fail;
|
|
||||||
|
|
||||||
vgmstream->meta_type = meta_RAW_SNDS;
|
|
||||||
vgmstream->sample_rate = 48000;
|
|
||||||
|
|
||||||
/* file seems to be mistakenly 1/8 too long, check for 32 0 bytes where the padding should start */
|
|
||||||
vgmstream->num_samples = file_size*8/9;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (read_32bitBE(vgmstream->num_samples+i*4,streamFile) != 0) {
|
|
||||||
vgmstream->num_samples = file_size; /* no padding? just play the whole file */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_SNDS_IMA;
|
|
||||||
vgmstream->layout_type = layout_none;
|
|
||||||
|
|
||||||
|
|
||||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
|
||||||
goto fail;
|
|
||||||
return vgmstream;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ typedef enum {
|
||||||
ULAW,
|
ULAW,
|
||||||
ALAW,
|
ALAW,
|
||||||
DPCM_KCEJ,
|
DPCM_KCEJ,
|
||||||
|
IMA_SNDS,
|
||||||
|
|
||||||
UNKNOWN = 255,
|
UNKNOWN = 255,
|
||||||
} txth_codec_t;
|
} txth_codec_t;
|
||||||
|
@ -273,6 +274,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
||||||
case SDX2: coding = coding_SDX2; break;
|
case SDX2: coding = coding_SDX2; break;
|
||||||
case DVI_IMA: coding = coding_DVI_IMA; break;
|
case DVI_IMA: coding = coding_DVI_IMA; break;
|
||||||
case IMA_HV: coding = coding_HV_IMA; break;
|
case IMA_HV: coding = coding_HV_IMA; break;
|
||||||
|
case IMA_SNDS: coding = coding_SNDS_IMA; break;
|
||||||
#ifdef VGM_USE_MPEG
|
#ifdef VGM_USE_MPEG
|
||||||
case MPEG: coding = coding_MPEG_layer3; break; /* we later find out exactly which */
|
case MPEG: coding = coding_MPEG_layer3; break; /* we later find out exactly which */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1056,6 +1058,7 @@ static txth_codec_t parse_codec(txth_header* txth, const char* val) {
|
||||||
else if (is_string(val,"CP_YM")) return CP_YM;
|
else if (is_string(val,"CP_YM")) return CP_YM;
|
||||||
else if (is_string(val,"PCM_FLOAT_LE")) return PCM_FLOAT_LE;
|
else if (is_string(val,"PCM_FLOAT_LE")) return PCM_FLOAT_LE;
|
||||||
else if (is_string(val,"IMA_HV")) return IMA_HV;
|
else if (is_string(val,"IMA_HV")) return IMA_HV;
|
||||||
|
else if (is_string(val,"IMA_SNDS")) return IMA_SNDS;
|
||||||
else if (is_string(val,"HEVAG")) return HEVAG;
|
else if (is_string(val,"HEVAG")) return HEVAG;
|
||||||
else if (is_string(val,"ULAW")) return ULAW;
|
else if (is_string(val,"ULAW")) return ULAW;
|
||||||
else if (is_string(val,"ALAW")) return ALAW;
|
else if (is_string(val,"ALAW")) return ALAW;
|
||||||
|
@ -2268,6 +2271,7 @@ static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) {
|
||||||
case IMA:
|
case IMA:
|
||||||
case DVI_IMA:
|
case DVI_IMA:
|
||||||
case IMA_HV:
|
case IMA_HV:
|
||||||
|
case IMA_SNDS:
|
||||||
return ima_bytes_to_samples(bytes, txth->channels);
|
return ima_bytes_to_samples(bytes, txth->channels);
|
||||||
case AICA:
|
case AICA:
|
||||||
case YMZ:
|
case YMZ:
|
||||||
|
@ -2293,6 +2297,34 @@ static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO move
|
||||||
|
static uint32_t find_padding(STREAMFILE* sf, uint32_t start_offset, uint32_t data_size) {
|
||||||
|
uint8_t buf[0x2000];
|
||||||
|
uint32_t read_size = sizeof(buf);
|
||||||
|
|
||||||
|
int32_t offset = start_offset + data_size;
|
||||||
|
while (offset > start_offset) {
|
||||||
|
int32_t read_offset = offset - read_size;
|
||||||
|
if (read_offset < 0)
|
||||||
|
read_offset = 0;
|
||||||
|
|
||||||
|
int bytes = read_streamfile(buf, read_offset, read_size, sf);
|
||||||
|
while (bytes >= 0) {
|
||||||
|
bytes--;
|
||||||
|
|
||||||
|
if (buf[bytes] != 0) {
|
||||||
|
uint32_t last_offset = start_offset + data_size;
|
||||||
|
uint32_t curr_offset = read_offset + bytes + 1;
|
||||||
|
return last_offset - curr_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset -= read_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_padding_size(txth_header* txth, int discard_empty) {
|
static int get_padding_size(txth_header* txth, int discard_empty) {
|
||||||
if (txth->data_size == 0 || txth->channels == 0)
|
if (txth->data_size == 0 || txth->channels == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2300,6 +2332,11 @@ static int get_padding_size(txth_header* txth, int discard_empty) {
|
||||||
switch(txth->codec) {
|
switch(txth->codec) {
|
||||||
case PSX:
|
case PSX:
|
||||||
return ps_find_padding(txth->sf_body, txth->start_offset, txth->data_size, txth->channels, txth->interleave, discard_empty);
|
return ps_find_padding(txth->sf_body, txth->start_offset, txth->data_size, txth->channels, txth->interleave, discard_empty);
|
||||||
|
|
||||||
|
case IMA_SNDS: {
|
||||||
|
// several files seems to be 1/8 too long
|
||||||
|
return find_padding(txth->sf_body, txth->start_offset, txth->data_size);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,7 +554,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||||
init_vgmstream_raw_rsf, /* raw GC streamed files */
|
init_vgmstream_raw_rsf, /* raw GC streamed files */
|
||||||
init_vgmstream_raw_int, /* .int raw PCM */
|
init_vgmstream_raw_int, /* .int raw PCM */
|
||||||
init_vgmstream_ps_headerless, /* tries to detect a bunch of PS-ADPCM formats */
|
init_vgmstream_ps_headerless, /* tries to detect a bunch of PS-ADPCM formats */
|
||||||
init_vgmstream_raw_snds, /* .snds raw SNDS IMA */
|
|
||||||
init_vgmstream_raw_wavm, /* .wavm raw xbox */
|
init_vgmstream_raw_wavm, /* .wavm raw xbox */
|
||||||
init_vgmstream_raw_pcm, /* .raw raw PCM */
|
init_vgmstream_raw_pcm, /* .raw raw PCM */
|
||||||
init_vgmstream_raw_s14_sss, /* .s14/sss raw siren14 */
|
init_vgmstream_raw_s14_sss, /* .s14/sss raw siren14 */
|
||||||
|
|
Loading…
Reference in a new issue