mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 15:54:05 +01:00
Fix Enthusia PCM files and add .lp/ap/lep
This commit is contained in:
parent
70d2092434
commit
6fc5e604e7
@ -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",
|
||||
|
@ -348,6 +348,10 @@
|
||||
RelativePath=".\meta\ppst_streamfile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_enth_streamfile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\vsv_streamfile.h"
|
||||
>
|
||||
|
@ -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" />
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
39
src/meta/ps2_enth_streamfile.h
Normal file
39
src/meta/ps2_enth_streamfile.h
Normal 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_ */
|
Loading…
x
Reference in New Issue
Block a user