Add .pwb [Psychonauts (PS2)]

Also remove .pnb
This commit is contained in:
bnnm 2023-06-25 16:07:16 +02:00
parent 97bf6bf5fe
commit 803db193b7
9 changed files with 115 additions and 93 deletions

View File

@ -416,7 +416,6 @@ static const char* extension_list[] = {
"pcm",
"pdt",
"pk",
"pnb",
"pona",
"pos",
"ps3",
@ -424,6 +423,7 @@ static const char* extension_list[] = {
"psf",
"psh", //fake extension for .vsv (to be removed)
"psnd",
"pwb",
"r",
"rac", //txth/reserved [Manhunt (Xbox)]
@ -976,9 +976,9 @@ static const meta_info meta_info_list[] = {
{meta_CSMP, "Retro Studios CSMP header"},
{meta_RFRM, "Retro Studios RFRM header"},
{meta_DTK, "Nintendo DTK raw header"},
{meta_RSF, "Retro Studios RSF raw header"},
{meta_RSF, "Retro Studios .RSF raw header"},
{meta_AFC, "Nintendo .AFC header"},
{meta_AST, "Nintendo AST header"},
{meta_AST, "Nintendo .AST header"},
{meta_HALPST, "HAL Laboratory HALPST header"},
{meta_DSP_RS03, "Retro Studios RS03 header"},
{meta_DSP_STD, "Nintendo DSP header"},
@ -987,7 +987,7 @@ static const meta_info meta_info_list[] = {
{meta_ADS, "Sony ADS header"},
{meta_NPS, "Namco NPSF header"},
{meta_RWSD, "Nintendo RWSD header (single stream)"},
{meta_RWAR, "Nintendo RWAR header (single RWAV stream)"},
{meta_RWAR, "Nintendo RWAR header (single stream)"},
{meta_RWAV, "Nintendo RWAV header"},
{meta_CWAV, "Nintendo CWAV header"},
{meta_FWAV, "Nintendo FWAV header"},
@ -1013,9 +1013,9 @@ static const meta_info meta_info_list[] = {
{meta_SEB, "Game Arts .SEB header"},
{meta_STR_WAV, "Blitz Games .STR+WAV header"},
{meta_ILD, "Tose ILD header"},
{meta_PS2_PNB, "assumed PNB (PsychoNauts Bgm File) by .pnb extension"},
{meta_PWB, "Double Fine WB header"},
{meta_RAW_WAVM, "Xbox .wavm raw header"},
{meta_DSP_STR, "assumed Conan Gamecube STR File by .str extension"},
{meta_DSP_STR, "Cauldron .STR header"},
{meta_EA_SCHL, "Electronic Arts SCHl header (variable)"},
{meta_EA_SCHL_fixed, "Electronic Arts SCHl header (fixed)"},
{meta_CAF, "tri-Crescendo CAF Header"},

View File

@ -565,7 +565,6 @@
<ClCompile Include="meta\ps2_msa.c" />
<ClCompile Include="meta\ps2_p2bt.c" />
<ClCompile Include="meta\ps2_pcm.c" />
<ClCompile Include="meta\ps2_pnb.c" />
<ClCompile Include="meta\ps2_rnd.c" />
<ClCompile Include="meta\ps2_rstm.c" />
<ClCompile Include="meta\ps2_sl3.c" />
@ -585,6 +584,7 @@
<ClCompile Include="meta\psb.c" />
<ClCompile Include="meta\psf.c" />
<ClCompile Include="meta\ps_headerless.c" />
<ClCompile Include="meta\pwb.c" />
<ClCompile Include="meta\rad.c" />
<ClCompile Include="meta\raw_int.c" />
<ClCompile Include="meta\raw_pcm.c" />

View File

@ -1516,9 +1516,6 @@
<ClCompile Include="meta\ps2_pcm.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ps2_pnb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ps2_rnd.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -1576,6 +1573,9 @@
<ClCompile Include="meta\ps_headerless.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\pwb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\rad.c">
<Filter>meta\Source Files</Filter>
</ClCompile>

View File

@ -9,9 +9,8 @@ typedef enum { PSX, PCM16, ATRAC9, HEVAG } bnk_codec;
VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
uint32_t start_offset, stream_offset, name_offset = 0;
uint32_t sblk_offset, data_offset;
uint32_t stream_size, data_size, interleave = 0;
int channels = 0, loop_flag, sample_rate, parts, sblk_version, big_endian;
uint32_t stream_size, interleave = 0;
int channels = 0, loop_flag, sample_rate, big_endian;
int loop_start = 0, loop_end = 0;
uint32_t center_note, center_fine, flags;
uint32_t atrac9_info = 0;
@ -37,25 +36,33 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
big_endian = 0;
}
else {
goto fail;
return NULL;
}
/* checks */
if (!check_extensions(sf, "bnk"))
goto fail;
return NULL;
uint32_t sblk_offset, sblk_size, data_offset, data_size, zlsd_size = 0;
int parts, sblk_version;
parts = read_u32(0x04,sf);
if (parts < 2 || parts > 3) goto fail;
if (parts < 2 || parts > 3)
return NULL;
/* in theory a bank can contain multiple blocks */
sblk_offset = read_u32(0x08,sf);
/* 0x0c: sblk size */
sblk_size = read_u32(0x0c,sf);
data_offset = read_u32(0x10,sf);
data_size = read_u32(0x14,sf);
/* when sblk_offset >= 0x20: */
/* 0x18: ZLSD small footer, rare in earlier versions [Yakuza 6's Puyo Puyo (PS4)] */
/* 0x1c: ZLSD size */
data_size = read_u32(0x14,sf);
if (sblk_offset >= 0x20) {
/* ZLSD small footer, rare in earlier versions and more common later [Yakuza 6's Puyo Puyo (PS4)] */
//zlsd_offset = read_u32(0x18,sf);
zlsd_size = read_u32(0x1c,sf);
}
if (sblk_offset + sblk_size + data_size + zlsd_size != get_streamfile_size(sf))
return NULL;
/* SE banks, also used for music. Most table fields seems reserved/defaults and
* don't change much between subsongs or files, so they aren't described in detail.
@ -64,7 +71,7 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
/* SBlk part: parse header */
if (read_u32(sblk_offset+0x00,sf) != get_id32be("klBS")) /* SBlk = SFX block */
goto fail;
return NULL;
sblk_version = read_u32(sblk_offset+0x04,sf);
/* 0x08: flags? (sblk_version>=0x0d?, 0x03=Vita, 0x06=PS4, 0x05=PS5)
* - 04: non-fixed bank?

View File

@ -111,8 +111,6 @@ VGMSTREAM * init_vgmstream_seb(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ild(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_pnb(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_raw_wavm(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ngc_str(STREAMFILE *streamFile);
@ -983,4 +981,6 @@ VGMSTREAM* init_vgmstream_sscf_encrypted(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_ego_dic(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_pwb(STREAMFILE* sf);
#endif /*_META_H*/

View File

@ -1,66 +0,0 @@
#include "meta.h"
#include "../util.h"
/* PNB : PsychoNauts Bgm File */
VGMSTREAM * init_vgmstream_ps2_pnb(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT];
int loop_flag=0;
int channel_count;
off_t start_offset;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("pnb",filename_extension(filename))) goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x0C,streamFile)!=0xFFFFFFFF);
channel_count=1;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = 1;
vgmstream->sample_rate = 44100;
/* Check for Compression Scheme */
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitBE(0x08,streamFile)/16*28;
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitBE(0x0C,streamFile)/16*28;
vgmstream->loop_end_sample = vgmstream->num_samples;
}
vgmstream->interleave_block_size = 0x10;
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_PNB;
start_offset = (off_t)read_32bitBE(0x00,streamFile);
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[i].streamfile) goto fail;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=
(off_t)(start_offset+vgmstream->interleave_block_size*i);
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

82
src/meta/pwb.c Normal file
View File

@ -0,0 +1,82 @@
#include "meta.h"
#include "../coding/coding.h"
/* WB - from Psychonauts (PS2) */
VGMSTREAM* init_vgmstream_pwb(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
int channels, loop_flag;
uint32_t stream_offset, stream_size, loop_start, loop_end;
/* checks */
if (!is_id32be(0x00, sf, "WB\2\0"))
return NULL;
/* .pwb: actual extension (bigfile has only hashes but there are names in internal files)
* (some .pwb have a companion .psb, seems cue-related) */
if (!check_extensions(sf, "pwb"))
return NULL;
/* 00: ID
* 04: null
* 08: header offset? (0x20)
* 0c: header size? (0x20)
* 10: entries offset
* 14: entries size
* 18: data offset
* 1c: data size
* 20: always 1 (channels? codec?)
* 24: entries count
* 28: entry size
* 2c: data offset
*/
stream_offset = read_u32le(0x18, sf);
int total_subsongs = read_s32le(0x24, sf);
int target_subsong = sf->stream_index;
if (target_subsong == 0) target_subsong = 1;
if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail;
{
uint32_t offset = read_u32le(0x10, sf) + (target_subsong - 1) * read_u32le(0x28, sf);
/* 0x00: flags? */
/* 0x04: always 000AC449 */
stream_offset = read_u32le(offset + 0x08, sf) + stream_offset;
stream_size = read_u32le(offset + 0x0c, sf);
loop_start = read_u32le(offset + 0x10, sf);
loop_end = read_u32le(offset + 0x14, sf) + loop_start;
loop_flag = loop_end; /* both 0 if no loop */
channels = 1;
}
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_PWB;
vgmstream->sample_rate = 24000;
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels);
vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start, channels);
vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, channels);
vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_none;
vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
if (!vgmstream_open_stream(vgmstream, sf, stream_offset))
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
close_streamfile(sf);
return NULL;
}

View File

@ -525,6 +525,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_utf_ahx,
init_vgmstream_ego_dic,
init_vgmstream_awd,
init_vgmstream_pwb,
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
init_vgmstream_scd_pcm,
@ -534,7 +535,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_mjb_mjh,
init_vgmstream_mic_koei,
init_vgmstream_seb,
init_vgmstream_ps2_pnb,
init_vgmstream_sli_loops,
init_vgmstream_tgc,

View File

@ -310,7 +310,7 @@ typedef enum {
meta_SEB,
meta_STR_WAV, /* Blitz Games STR+WAV files */
meta_ILD,
meta_PS2_PNB, /* PsychoNauts Bgm File */
meta_PWB,
meta_VPK, /* VPK Audio File */
meta_PS2_BMDX, /* Beatmania thing */
meta_PS2_IVB, /* Langrisser 3 IVB */
@ -506,7 +506,6 @@ typedef enum {
meta_EB_SFX, /* Excitebots .sfx */
meta_EB_SF0, /* Excitebots .sf0 */
meta_MTAF,
meta_VAG_custom,
meta_ALP,
meta_WPD, /* Shuffle! (PC) */
meta_MN_STR, /* Mini Ninjas (PC/PS3/WII) */