mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-31 12:23:44 +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]
|
"ams", //txth/reserved [Super Dragon Ball Z (PS2) ELF names]
|
||||||
"amts", //fake extension/header id for .stm (renamed? to be removed?)
|
"amts", //fake extension/header id for .stm (renamed? to be removed?)
|
||||||
"ao",
|
"ao",
|
||||||
|
"ap",
|
||||||
"apc",
|
"apc",
|
||||||
"as4",
|
"as4",
|
||||||
"asd",
|
"asd",
|
||||||
@ -261,6 +262,7 @@ static const char* extension_list[] = {
|
|||||||
"lasf", //fake extension for .asf (various)
|
"lasf", //fake extension for .asf (various)
|
||||||
"lbin", //fake extension for .bin (various)
|
"lbin", //fake extension for .bin (various)
|
||||||
"leg",
|
"leg",
|
||||||
|
"lep",
|
||||||
"lflac", //fake extension for .flac, FFmpeg/not parsed
|
"lflac", //fake extension for .flac, FFmpeg/not parsed
|
||||||
"lin",
|
"lin",
|
||||||
"lm0",
|
"lm0",
|
||||||
@ -277,6 +279,7 @@ static const char* extension_list[] = {
|
|||||||
"lmpc", //fake extension for .mpc, FFmpeg/not parsed
|
"lmpc", //fake extension for .mpc, FFmpeg/not parsed
|
||||||
"logg", //fake extension for .ogg
|
"logg", //fake extension for .ogg
|
||||||
"lopus", //fake extension for .opus
|
"lopus", //fake extension for .opus
|
||||||
|
"lp",
|
||||||
"lpcm",
|
"lpcm",
|
||||||
"lpk",
|
"lpk",
|
||||||
"lps",
|
"lps",
|
||||||
|
@ -348,6 +348,10 @@
|
|||||||
RelativePath=".\meta\ppst_streamfile.h"
|
RelativePath=".\meta\ppst_streamfile.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\meta\ps2_enth_streamfile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\vsv_streamfile.h"
|
RelativePath=".\meta\vsv_streamfile.h"
|
||||||
>
|
>
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
<ClInclude Include="meta\kma9_streamfile.h" />
|
<ClInclude Include="meta\kma9_streamfile.h" />
|
||||||
<ClInclude Include="meta\lrmd_streamfile.h" />
|
<ClInclude Include="meta\lrmd_streamfile.h" />
|
||||||
<ClInclude Include="meta\ppst_streamfile.h" />
|
<ClInclude Include="meta\ppst_streamfile.h" />
|
||||||
|
<ClInclude Include="meta\ps2_enth_streamfile.h" />
|
||||||
<ClInclude Include="meta\vsv_streamfile.h" />
|
<ClInclude Include="meta\vsv_streamfile.h" />
|
||||||
<ClInclude Include="meta\xavs_streamfile.h" />
|
<ClInclude Include="meta\xavs_streamfile.h" />
|
||||||
<ClInclude Include="meta\xnb_streamfile.h" />
|
<ClInclude Include="meta\xnb_streamfile.h" />
|
||||||
|
@ -152,6 +152,9 @@
|
|||||||
<ClInclude Include="meta\ppst_streamfile.h">
|
<ClInclude Include="meta\ppst_streamfile.h">
|
||||||
<Filter>meta\Header Files</Filter>
|
<Filter>meta\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="meta\ps2_enth_streamfile.h">
|
||||||
|
<Filter>meta\Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="meta\vsv_streamfile.h">
|
<ClInclude Include="meta\vsv_streamfile.h">
|
||||||
<Filter>meta\Header Files</Filter>
|
<Filter>meta\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../coding/coding.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* init_vgmstream_ps2_enth(STREAMFILE* sf) {
|
||||||
VGMSTREAM* vgmstream = NULL;
|
VGMSTREAM* vgmstream = NULL;
|
||||||
|
STREAMFILE* temp_sf = NULL;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag, channels, sample_rate, interleave;
|
int loop_flag, channels, sample_rate, interleave;
|
||||||
int32_t data_size, loop_start;
|
int32_t data_size, loop_start;
|
||||||
@ -11,12 +13,13 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
|
|||||||
|
|
||||||
|
|
||||||
/* checks */
|
/* 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 */
|
* .enth: fake */
|
||||||
if (!check_extensions(sf, "bin,lbin,enth"))
|
if (!check_extensions(sf, "bin,lbin,lp,lep,ap,enth"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
id = read_32bitBE(0x00,sf);
|
id = read_u32be(0x00,sf);
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case 0x41502020: /* "AP " */
|
case 0x41502020: /* "AP " */
|
||||||
case 0x4C502020: /* "LP " */
|
case 0x4C502020: /* "LP " */
|
||||||
@ -24,7 +27,7 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
|
|||||||
interleave = read_u32le(0x0c,sf);
|
interleave = read_u32le(0x0c,sf);
|
||||||
loop_start = read_u32le(0x14,sf);
|
loop_start = read_u32le(0x14,sf);
|
||||||
data_size = read_u32le(0x18,sf);
|
data_size = read_u32le(0x18,sf);
|
||||||
start_offset = read_32bitLE(0x1C,sf);
|
start_offset = read_u32le(0x1C,sf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x4C455020: /* "LEP " */
|
case 0x4C455020: /* "LEP " */
|
||||||
@ -42,6 +45,7 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
|
|||||||
loop_flag = loop_start != 0;
|
loop_flag = loop_start != 0;
|
||||||
channels = 2;
|
channels = 2;
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
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->num_samples = pcm_bytes_to_samples(data_size, channels, 16);
|
||||||
vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start, channels, 16);
|
vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start, channels, 16);
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
/* PCM data look different or encrypted
|
|
||||||
* some PCM16 must be xored(?) with 0x8000, not sure when */
|
temp_sf = setup_lp_streamfile(sf, start_offset); /* encrypted/obfuscated PCM */
|
||||||
goto fail;
|
if (!temp_sf) goto fail;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x41502020: /* "AP " */
|
case 0x41502020: /* "AP " */
|
||||||
case 0x4C455020: /* "LEP " */
|
case 0x4C455020: /* "LEP " */
|
||||||
@ -77,10 +82,12 @@ VGMSTREAM* init_vgmstream_ps2_enth(STREAMFILE* sf) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
if (!vgmstream_open_stream(vgmstream, temp_sf ? temp_sf : sf, start_offset))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
close_streamfile(temp_sf);
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
fail:
|
fail:
|
||||||
|
close_streamfile(temp_sf);
|
||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
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