diff --git a/src/formats.c b/src/formats.c index 6a372cd4..9d589319 100644 --- a/src/formats.c +++ b/src/formats.c @@ -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"}, diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 55e96304..7f20fbc5 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -565,7 +565,6 @@ - @@ -585,6 +584,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 6c8724ec..6a03b7e6 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1516,9 +1516,6 @@ meta\Source Files - - meta\Source Files - meta\Source Files @@ -1576,6 +1573,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/bnk_sony.c b/src/meta/bnk_sony.c index 052a54f5..0d92f4f4 100644 --- a/src/meta/bnk_sony.c +++ b/src/meta/bnk_sony.c @@ -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? diff --git a/src/meta/meta.h b/src/meta/meta.h index d273c70b..788cddf5 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -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*/ diff --git a/src/meta/ps2_pnb.c b/src/meta/ps2_pnb.c deleted file mode 100644 index 5d9d4696..00000000 --- a/src/meta/ps2_pnb.c +++ /dev/null @@ -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;ich[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; -} diff --git a/src/meta/pwb.c b/src/meta/pwb.c new file mode 100644 index 00000000..408c7f77 --- /dev/null +++ b/src/meta/pwb.c @@ -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; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index 2b254355..64ca770b 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -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, diff --git a/src/vgmstream_types.h b/src/vgmstream_types.h index cbcdbe09..88f263ab 100644 --- a/src/vgmstream_types.h +++ b/src/vgmstream_types.h @@ -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) */