Fix Enthusia PCM files and add .lp/ap/lep

This commit is contained in:
bnnm 2020-10-17 19:00:02 +02:00
parent 70d2092434
commit 6fc5e604e7
6 changed files with 66 additions and 9 deletions

View File

@ -67,6 +67,7 @@ static const char* extension_list[] = {
"ams", //txth/reserved [Super Dragon Ball Z (PS2) ELF names]
"amts", //fake extension/header id for .stm (renamed? to be removed?)
"ao",
"ap",
"apc",
"as4",
"asd",
@ -261,6 +262,7 @@ static const char* extension_list[] = {
"lasf", //fake extension for .asf (various)
"lbin", //fake extension for .bin (various)
"leg",
"lep",
"lflac", //fake extension for .flac, FFmpeg/not parsed
"lin",
"lm0",
@ -277,6 +279,7 @@ static const char* extension_list[] = {
"lmpc", //fake extension for .mpc, FFmpeg/not parsed
"logg", //fake extension for .ogg
"lopus", //fake extension for .opus
"lp",
"lpcm",
"lpk",
"lps",

View File

@ -348,6 +348,10 @@
RelativePath=".\meta\ppst_streamfile.h"
>
</File>
<File
RelativePath=".\meta\ps2_enth_streamfile.h"
>
</File>
<File
RelativePath=".\meta\vsv_streamfile.h"
>

View File

@ -122,6 +122,7 @@
<ClInclude Include="meta\kma9_streamfile.h" />
<ClInclude Include="meta\lrmd_streamfile.h" />
<ClInclude Include="meta\ppst_streamfile.h" />
<ClInclude Include="meta\ps2_enth_streamfile.h" />
<ClInclude Include="meta\vsv_streamfile.h" />
<ClInclude Include="meta\xavs_streamfile.h" />
<ClInclude Include="meta\xnb_streamfile.h" />

View File

@ -152,6 +152,9 @@
<ClInclude Include="meta\ppst_streamfile.h">
<Filter>meta\Header Files</Filter>
</ClInclude>
<ClInclude Include="meta\ps2_enth_streamfile.h">
<Filter>meta\Header Files</Filter>
</ClInclude>
<ClInclude Include="meta\vsv_streamfile.h">
<Filter>meta\Header Files</Filter>
</ClInclude>

View File

@ -1,9 +1,11 @@
#include "meta.h"
#include "../coding/coding.h"
#include "ps2_enth_streamfile.h"
/* LP/AP/LEP - from Enthusia: Professional Racing */
/* LP/AP/LEP - from Konami (KCES)'s Enthusia: Professional Racing (PS2) */
VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
off_t start_offset;
int loop_flag, channels, sample_rate, interleave;
int32_t data_size, loop_start;
@ -11,12 +13,13 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
/* checks */
/* .bin/lbin: assumed (no actual extensino in bigfiles)
/* .bin/lbin: internal (no names in bigfiles but exes mention "bgm%05d.bin" and "LEP data")
* .lp/lep/ap: header ID
* .enth: fake */
if (!check_extensions(sf, "bin,lbin,enth"))
if (!check_extensions(sf, "bin,lbin,lp,lep,ap,enth"))
goto fail;
id = read_32bitBE(0x00,sf);
id = read_u32be(0x00,sf);
switch (id) {
case 0x41502020: /* "AP " */
case 0x4C502020: /* "LP " */
@ -24,7 +27,7 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
interleave = read_u32le(0x0c,sf);
loop_start = read_u32le(0x14,sf);
data_size = read_u32le(0x18,sf);
start_offset = read_32bitLE(0x1C,sf);
start_offset = read_u32le(0x1C,sf);
break;
case 0x4C455020: /* "LEP " */
@ -42,6 +45,7 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
loop_flag = loop_start != 0;
channels = 2;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
@ -58,9 +62,10 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
vgmstream->num_samples = pcm_bytes_to_samples(data_size, channels, 16);
vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start, channels, 16);
vgmstream->loop_end_sample = vgmstream->num_samples;
/* PCM data look different or encrypted
* some PCM16 must be xored(?) with 0x8000, not sure when */
goto fail;
temp_sf = setup_lp_streamfile(sf, start_offset); /* encrypted/obfuscated PCM */
if (!temp_sf) goto fail;
break;
case 0x41502020: /* "AP " */
case 0x4C455020: /* "LEP " */
@ -77,10 +82,12 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
goto fail;
}
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
if (!vgmstream_open_stream(vgmstream, temp_sf ? temp_sf : sf, start_offset))
goto fail;
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -0,0 +1,39 @@
#ifndef _LP_STREAMFILE_H_
#define _LP_STREAMFILE_H_
#include "../streamfile.h"
typedef struct {
off_t start;
} lp_io_data;
static size_t lp_io_read(STREAMFILE *sf, uint8_t *dest, off_t offset, size_t length, lp_io_data* data) {
int i;
size_t bytes = read_streamfile(dest, offset, length, sf);
/* PCM16LE frames are ROL'ed (or lower bit is ignored?) so this only works if reads are aligned
* to sizeof(uint16_t); maybe could be a new decoder but seems like a waste */
for (i = 0; i < bytes / 2 * 2; i += 2) {
if (offset + i >= data->start) {
uint16_t v = get_u16le(dest + i);
v = (v << 1) | ((v >> 15) & 0x0001);
put_u16le(dest + i, v);
}
}
return bytes;
}
/* decrypts Enthusia "LP" PCM streams */
static STREAMFILE* setup_lp_streamfile(STREAMFILE* sf, off_t start) {
STREAMFILE* new_sf = NULL;
lp_io_data io_data = {0};
io_data.start = start;
new_sf = open_wrap_streamfile(sf);
new_sf = open_io_streamfile_f(new_sf, &io_data, sizeof(lp_io_data), lp_io_read, NULL);
return new_sf;
}
#endif /* _LP_STREAMFILE_H_ */