diff --git a/src/Makefile b/src/Makefile index 599d7dce..841aa85e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -45,7 +45,8 @@ LAYOUT_OBJS=layout/ast_blocked.o \ layout/filp_blocked.o \ layout/aax_layout.o \ layout/ivaud_layout.o \ - layout/mxch_blocked.o + layout/mxch_blocked.o \ + layout/mgav_blocked.o META_OBJS=meta/adx_header.o \ meta/afc_header.o \ @@ -212,7 +213,6 @@ META_OBJS=meta/adx_header.o \ meta/pc_sob.o \ meta/exakt_sc.o \ meta/wii_bns.o \ - meta/wii_was.o \ meta/pona.o \ meta/fsb_test.o \ meta/xbox_hlwav.o \ @@ -233,7 +233,12 @@ META_OBJS=meta/adx_header.o \ meta/ps2_msa.o \ meta/pc_smp.o \ meta/p3d.o \ - meta/ps2_adsc.o + meta/ps2_adsc.o \ + meta/psx_str_mgav.o \ + meta/ngc_bo2.o \ + meta/ngc_dsp_mpds.o \ + meta/ps2_khv.o \ + meta/ps2_voi.o OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) diff --git a/src/layout/Makefile.unix.am b/src/layout/Makefile.unix.am index e285faff..a738753a 100644 --- a/src/layout/Makefile.unix.am +++ b/src/layout/Makefile.unix.am @@ -30,5 +30,6 @@ liblayout_la_SOURCES += filp_blocked.c liblayout_la_SOURCES += aax_layout.c liblayout_la_SOURCES += ivaud_layout.c liblayout_la_SOURCES += mxch_blocked.c +liblayout_la_SOURCES += psx_mgav_blocked.c EXTRA_DIST = layout.h diff --git a/src/layout/blocked.c b/src/layout/blocked.c index 719d83e2..d72f27d5 100644 --- a/src/layout/blocked.c +++ b/src/layout/blocked.c @@ -112,6 +112,9 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM * case layout_ivaud_blocked: ivaud_block_update(vgmstream->next_block_offset,vgmstream); break; + case layout_psx_mgav_blocked: + psx_mgav_block_update(vgmstream->next_block_offset,vgmstream); + break; default: break; } diff --git a/src/layout/layout.h b/src/layout/layout.h index a62b9dee..dead4b7e 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -58,4 +58,6 @@ void render_vgmstream_aix(sample * buffer, int32_t sample_count, VGMSTREAM * vgm void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream); +void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream); + #endif diff --git a/src/layout/psx_mgav_blocked.c b/src/layout/psx_mgav_blocked.c new file mode 100644 index 00000000..e2a3d21a --- /dev/null +++ b/src/layout/psx_mgav_blocked.c @@ -0,0 +1,17 @@ +#include "layout.h" +#include "../vgmstream.h" + +/* set up for the block at the given offset */ +void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream) { + int i; + + vgmstream->current_block_offset = block_offset; + vgmstream->current_block_size = read_32bitLE(vgmstream->current_block_offset+0x04,vgmstream->ch[0].streamfile)-0x1C; + vgmstream->next_block_offset = vgmstream->current_block_offset+vgmstream->current_block_size+0x1C; + vgmstream->current_block_size/=vgmstream->channels; + + for (i=0;ichannels;i++) { + vgmstream->ch[i].offset = vgmstream->current_block_offset+0x1C+(vgmstream->current_block_size*i); + + } +} diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 93d5b062..8185e777 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -1,7 +1,7 @@  + + @@ -442,10 +446,18 @@ RelativePath=".\meta\ngc_bh2pcm.c" > + + + + @@ -610,6 +622,10 @@ RelativePath=".\meta\ps2_kces.c" > + + @@ -734,6 +750,10 @@ RelativePath=".\meta\ps2_vgv.c" > + + @@ -762,6 +782,10 @@ RelativePath=".\meta\psx_gms.c" > + + @@ -898,10 +922,6 @@ RelativePath=".\meta\wii_sts.c" > - - @@ -1162,6 +1182,10 @@ RelativePath=".\layout\nolayout.c" > + + diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index 5d3eb7a3..7d744bd0 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -168,7 +168,6 @@ libmeta_la_SOURCES += pc_mxst.c libmeta_la_SOURCES += pc_sob.c libmeta_la_SOURCES += exakt_sc.c libmeta_la_SOURCES += wii_bns.c -libmeta_la_SOURCES += wii_was.c libmeta_la_SOURCES += pona.c libmeta_la_SOURCES += fsb_test.c libmeta_la_SOURCES += xbox_hlwav.c @@ -190,5 +189,10 @@ libmeta_la_SOURCES += ps2_msa.c libmeta_la_SOURCES += pc_smp.c libmeta_la_SOURCES += p3d.c libmeta_la_SOURCES += ps2_adsc.c +libmeta_la_SOURCES += psx_str_mgav.c +libmeta_la_SOURCES += ngc_bo2.c +libmeta_la_SOURCES += ngc_dsp_mpds.c +libmeta_la_SOURCES += ps2_khv.c +libmeta_la_SOURCES += ps2_voi.c EXTRA_DIST = meta.h diff --git a/src/meta/emff.c b/src/meta/emff.c index f0546249..579c72cf 100644 --- a/src/meta/emff.c +++ b/src/meta/emff.c @@ -60,7 +60,7 @@ VGMSTREAM * init_vgmstream_emff_ps2(STREAMFILE *streamFile) { /* Calc num_samples */ emff_ps2_block_update(start_offset,vgmstream); - vgmstream->num_samples = read_32bitLE(0x8,streamFile);; + vgmstream->num_samples = read_32bitLE(0x8,streamFile); if (loop_flag) { vgmstream->loop_start_sample = (read_32bitLE(0x28,streamFile)-start_offset)*28/16/channel_count; vgmstream->loop_end_sample = read_32bitLE(0x8,streamFile); diff --git a/src/meta/fsb_test.c b/src/meta/fsb_test.c index 2417e201..26c2f2b7 100644 --- a/src/meta/fsb_test.c +++ b/src/meta/fsb_test.c @@ -1,120 +1,96 @@ #include "meta.h" #include "../util.h" -/* FSB3.0 & FSB3.1*/ +/* FSB3.0 */ VGMSTREAM * init_vgmstream_fsb3(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; int fsb_headerlen; - int loop_flag; - int channel_count; + int channel_count; + int loop_flag = 0; + int FSBFlag = 0; + int i, c; off_t start_offset; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("fsb",filename_extension(filename)) && - strcasecmp("lfsb",filename_extension(filename))) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x46534233) goto fail; /* "FSB3" */ - - /* "Check if the FSB is used as conatiner or as single file" */ - if (read_32bitLE(0x04,streamFile) != 0x1) goto fail; - /* Check if we're dealing with a FSB3.0 or FSB3.1 file */ - if ((read_32bitBE(0x10,streamFile) != 0x00000300) && - (read_32bitBE(0x10,streamFile) != 0x01000300)) + if (strcasecmp("fsb",filename_extension(filename))) + goto fail; + + /* check header for "FSB3" string */ + if (read_32bitBE(0x00,streamFile) != 0x46534233) + goto fail; + + /* "Check if the FSB is used as conatiner or as single file" */ + if (read_32bitLE(0x04,streamFile) != 0x1) + goto fail; + + /* Check if we're dealing with a FSB3.0 file */ + if ((read_32bitBE(0x10,streamFile) != 0x00000300) && + ((read_32bitBE(0x10,streamFile) != 0x01000300))) goto fail; - if (read_32bitBE(0x48,streamFile) == 0x02000806) { // Metroid Prime 3 - loop_flag = 1; - } else { - loop_flag = 0; - } + channel_count = read_16bitLE(0x56,streamFile); + fsb_headerlen = read_32bitLE(0x08,streamFile); - channel_count = read_16bitLE(0x56,streamFile); - fsb_headerlen = read_32bitLE(0x08,streamFile); + FSBFlag = read_32bitLE(0x48,streamFile); + if (FSBFlag&0x2 || FSBFlag&0x4 || FSBFlag&0x6) + loop_flag = 1; + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - // fsb_format = ; - switch (((uint8_t)read_8bit(0x4A, streamFile)) >> 4) { - case 0x0: // Nintendo DSP - // Hack to support an illegal coding flag - if (read_32bitBE(0x48,streamFile) == 0x50010000) { // Fantastic 4: Rise of the Silver Surfer - vgmstream->coding_type = coding_PCM16LE; - vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))/2/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x0C,streamFile))/2/channel_count; - } - if (channel_count == 1) { - vgmstream->layout_type = layout_none; - } else if (channel_count > 1) { - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 2; - } - } else { - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))*14/8/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x0C,streamFile))*14/8/channel_count; - } - if (channel_count == 1) { - vgmstream->layout_type = layout_none; - } else if (channel_count > 1) { - vgmstream->layout_type = layout_interleave_byte; - vgmstream->interleave_block_size = 2; - } - } - break; - case 0x4: // XBOX IMA ADPCM - vgmstream->coding_type = coding_XBOX; - vgmstream->layout_type = layout_none; - vgmstream->num_samples = read_32bitLE(0x0C,streamFile)*64/36/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile)*64/36/channel_count; - } - break; - case 0x8: // PS2 APDCM - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x10; - vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))*28/16/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x0C,streamFile))*28/16/channel_count; - } - break; - default: - goto fail; - } - - /* fill in the vital statistics */ start_offset = fsb_headerlen+0x18; vgmstream->sample_rate = (read_32bitLE(0x4C, streamFile)); - if (read_32bitBE(0x10,streamFile) == 0x00000300) { - vgmstream->meta_type = meta_FSB3_0; - } else if (read_32bitBE(0x10,streamFile) == 0x01000300) { - vgmstream->meta_type = meta_FSB3_1; + // XBOX IMA + if (FSBFlag&0x00400000) { + vgmstream->coding_type = coding_XBOX; + vgmstream->layout_type = layout_none; } - if (vgmstream->coding_type == coding_NGC_DSP) { - int i,c; + // PS2 ADPCM + else if (FSBFlag&0x00800000) { + vgmstream->coding_type = coding_PSX; + if (channel_count == 1) { + vgmstream->layout_type = layout_none; + } else if (channel_count > 1) { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x10; + } + } + + // Nintendo DSP + else if (FSBFlag&0x02000000) { + vgmstream->coding_type = coding_NGC_DSP; + + if (channel_count == 1) { + vgmstream->layout_type = layout_none; + } else if (channel_count > 1) { + vgmstream->layout_type = layout_interleave_byte; + vgmstream->interleave_block_size = 2; + } + for (c=0;cch[c].adpcm_coef[i] = read_16bitBE(0x68+c*0x2e +i*2,streamFile); } } + } + + vgmstream->num_samples = read_32bitLE(0x38,streamFile); + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitLE(0x40,streamFile); + vgmstream->loop_end_sample = read_32bitLE(0x44,streamFile); + } + vgmstream->meta_type = meta_FSB3_0; + /* open the file for reading */ { int i; diff --git a/src/meta/idsp.c b/src/meta/idsp.c index 2b4495be..2f8289c4 100644 --- a/src/meta/idsp.c +++ b/src/meta/idsp.c @@ -5,11 +5,10 @@ VGMSTREAM * init_vgmstream_idsp(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; + int loop_flag = 0; + int channel_count; off_t start_offset; - int loop_flag; - int channel_count; - /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("idsp",filename_extension(filename))) goto fail; @@ -18,17 +17,20 @@ VGMSTREAM * init_vgmstream_idsp(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x49445350) /* "IDSP" */ goto fail; - - loop_flag = 0; channel_count = read_32bitBE(0x04,streamFile); - /* build the VGMSTREAM */ + if (channel_count > 8) + { + goto fail; + } + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0xD0; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0x28,streamFile); vgmstream->coding_type = coding_NGC_DSP; vgmstream->num_samples = read_32bitBE(0x20,streamFile); @@ -41,7 +43,6 @@ VGMSTREAM * init_vgmstream_idsp(STREAMFILE *streamFile) { vgmstream->interleave_block_size = read_32bitBE(0x0C,streamFile); vgmstream->meta_type = meta_IDSP; - if (vgmstream->coding_type == coding_NGC_DSP) { int i; for (i=0;i<16;i++) { @@ -78,8 +79,6 @@ fail: return NULL; } - - /* "idsp/IDSP" Soul Calibur Legends (Wii) Sky Crawlers: Innocent Aces (Wii) @@ -87,10 +86,10 @@ fail: VGMSTREAM * init_vgmstream_idsp2(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; - off_t start_offset; int loop_flag; - int channel_count; - int i, j; + int channel_count; + int i, j; + off_t start_offset; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -104,11 +103,16 @@ VGMSTREAM * init_vgmstream_idsp2(STREAMFILE *streamFile) { loop_flag = read_32bitBE(0x20,streamFile); channel_count = read_32bitBE(0xC4,streamFile); - /* build the VGMSTREAM */ + if (channel_count > 8) + { + goto fail; + } + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = (channel_count * 0x60) + 0x100; vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0xC8,streamFile); @@ -119,30 +123,36 @@ VGMSTREAM * init_vgmstream_idsp2(STREAMFILE *streamFile) { vgmstream->loop_end_sample = (read_32bitBE(0xD4,streamFile)); } - if (channel_count == 1) { + if (channel_count == 1) + { vgmstream->layout_type = layout_none; - } else if (channel_count > 1) { - if (read_32bitBE(0xD8,streamFile) == 0) { - vgmstream->layout_type = layout_none; - vgmstream->interleave_block_size = (get_streamfile_size(streamFile)-start_offset)/2; - } else if (read_32bitBE(0xD8,streamFile) > 0) { - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = read_32bitBE(0xD8,streamFile); - } - } + } + else if (channel_count > 1) + { + if (read_32bitBE(0xD8,streamFile) == 0) + { + vgmstream->layout_type = layout_none; + vgmstream->interleave_block_size = (get_streamfile_size(streamFile)-start_offset)/2; + } + else if (read_32bitBE(0xD8,streamFile) > 0) + { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = read_32bitBE(0xD8,streamFile); + } + } - vgmstream->meta_type = meta_IDSP2; + vgmstream->meta_type = meta_IDSP; - { - if (vgmstream->coding_type == coding_NGC_DSP) { - off_t coef_table[8] = {0x118,0x178,0x1D8,0x238,0x298,0x2F8,0x358,0x3B8}; - for (j=0;jchannels;j++) { - for (i=0;i<16;i++) { - vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile); - } - } - } - } + { + if (vgmstream->coding_type == coding_NGC_DSP) { + off_t coef_table[8] = {0x118,0x178,0x1D8,0x238,0x298,0x2F8,0x358,0x3B8}; + for (j=0;jchannels;j++) { + for (i=0;i<16;i++) { + vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile); + } + } + } + } /* open the file for reading */ { @@ -175,10 +185,9 @@ fail: VGMSTREAM * init_vgmstream_idsp3(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; - off_t start_offset; - int loop_flag = 1; - int channel_count; + int channel_count; + off_t start_offset; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -188,17 +197,20 @@ VGMSTREAM * init_vgmstream_idsp3(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x49445350) /* IDSP */ goto fail; - - // loop_flag = read_32bitBE(0x08,streamFile); channel_count = read_32bitBE(0x24,streamFile); - - /* build the VGMSTREAM */ + + if (channel_count > 8) + { + goto fail; + } + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0xD4; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0x14,streamFile); vgmstream->coding_type = coding_NGC_DSP; vgmstream->num_samples = read_32bitBE(0x0C,streamFile); @@ -207,10 +219,9 @@ VGMSTREAM * init_vgmstream_idsp3(STREAMFILE *streamFile) { vgmstream->loop_end_sample = (read_32bitBE(0x0C,streamFile)); } - vgmstream->layout_type = layout_interleave; + vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile); - vgmstream->meta_type = meta_IDSP3; - + vgmstream->meta_type = meta_IDSP; if (vgmstream->coding_type == coding_NGC_DSP) { int i; @@ -249,4 +260,86 @@ fail: } +/* IDSP (Defender NGC) */ +VGMSTREAM * init_vgmstream_idsp4(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int loop_flag = 0; + int channel_count; + off_t start_offset; + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("idsp",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x49445350) /* "IDSP" */ + goto fail; + + channel_count = read_32bitBE(0x0C,streamFile); + + if (channel_count > 2) // Refuse everything else for now + { + goto fail; + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x70; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x08,streamFile); + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = read_32bitBE(0x04,streamFile)/channel_count/8*14; + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = read_32bitBE(0x04,streamFile)/channel_count/8*14; + } + + if (channel_count == 1) + { + vgmstream->layout_type = layout_none; + } + else + { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = read_32bitBE(0x10,streamFile); + } + + vgmstream->meta_type = meta_IDSP; + + { + int i; + for (i=0;i<16;i++) + vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x14+i*2,streamFile); + if (channel_count == 2) { + for (i=0;i<16;i++) + vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x42+i*2,streamFile); + } + } + + /* open the file for reading */ + { + int i; + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset=start_offset+ + vgmstream->interleave_block_size*i; + + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} \ No newline at end of file diff --git a/src/meta/meta.h b/src/meta/meta.h index 74bb7c2a..9f54c2fe 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -251,6 +251,8 @@ VGMSTREAM * init_vgmstream_idsp2(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_idsp3(STREAMFILE * streamFile); +VGMSTREAM * init_vgmstream_idsp4(STREAMFILE * streamFile); + VGMSTREAM * init_vgmstream_ngc_ymf(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_sadl(STREAMFILE * streamFile); @@ -459,12 +461,26 @@ VGMSTREAM * init_vgmstream_ps2_smpl(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ps2_msa(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_ps2_voi(STREAMFILE* streamFile); + +VGMSTREAM * init_vgmstream_ps2_khv(STREAMFILE* streamFile); + VGMSTREAM * init_vgmstream_pc_smp(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_ngc_bo2(STREAMFILE* streamFile); + +VGMSTREAM * init_vgmstream_dsp_ddsp(STREAMFILE* streamFile); + VGMSTREAM * init_vgmstream_p3d(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ps2_tk1(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ps2_adsc(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE* streamFile); + +VGMSTREAM * init_vgmstream_dsp_str_ig(STREAMFILE* streamFile); + +VGMSTREAM * init_vgmstream_psx_mgav(STREAMFILE* streamFile); + #endif diff --git a/src/meta/musx.c b/src/meta/musx.c index 5f1a4140..552abb0b 100644 --- a/src/meta/musx.c +++ b/src/meta/musx.c @@ -6,11 +6,9 @@ VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; + int loop_flag = 0; + int channel_count; off_t start_offset; - int musx_type; /* determining the decoder by strings like "PS2_", "GC__" and so on */ - //int musx_version; /* 0x08 provides a "version" byte */ - int loop_flag = 0; - int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -18,57 +16,68 @@ VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) { /* check header */ if (read_32bitBE(0x00,streamFile) != 0x4D555358) /* "MUSX" */ - goto fail; - if (read_32bitBE(0x08,streamFile) != 0x04000000) /* "0x04000000" */ - goto fail; - - /* This is tricky, the header changes it's layout if the file is unlooped */ + goto fail; + if (read_32bitBE(0x08,streamFile) != 0x04000000) /* "0x04000000" */ + goto fail; + + /* This is tricky, the header changes it's layout if the file is unlooped */ loop_flag = (read_32bitLE(0x840,streamFile)!=0xFFFFFFFF); channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - musx_type=(read_32bitBE(0x10,streamFile)); - - switch (musx_type) { - case 0x5053325F: /* PS2_ */ + switch (read_32bitBE(0x10,streamFile)) + { + case 0x5053325F: /* PS2_ */ start_offset = read_32bitLE(0x28,streamFile); vgmstream->channels = channel_count; vgmstream->sample_rate = 32000; - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))*28/16/channel_count; + vgmstream->coding_type = coding_PSX; // PS2 ADPCM + vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))/16/channel_count*28; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x80; - vgmstream->meta_type = meta_MUSX_V004; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))*28/16/channel_count; - vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))*28/16/channel_count; - } - break; - /* seems to not work for Spyro, maybe i find other games for testing - case 0x58425F5F: XB__ - start_offset = read_32bitLE(0x28,streamFile); + if (loop_flag) + { + vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))/16/channel_count*28; + vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))/16/channel_count*28; + } + break; + case 0x47435F5F: /* GC__ */ + start_offset = read_32bitBE(0x28,streamFile); vgmstream->channels = channel_count; vgmstream->sample_rate = 32000; - vgmstream->coding_type = coding_XBOX; - vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))*64/36/channel_count; - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_MUSX_V004; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))*64/36/channel_count; - vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))*64/36/channel_count; - } - break; - */ - default: - goto fail; - - } + vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM + vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))/16/channel_count*28; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x20; + if (loop_flag) + { + vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))/16/channel_count*28; + vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))/16/channel_count*28; + } + break; + case 0x58425F5F: /* XB__ */ + start_offset = read_32bitLE(0x28,streamFile); + vgmstream->channels = channel_count; + vgmstream->sample_rate = 44100; + vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM + vgmstream->num_samples = (read_32bitLE(0x2C,streamFile))/16/channel_count*28; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x20; + if (loop_flag) + { + vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))/16/channel_count*28; + vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))/16/channel_count*28; + } + break; + default: + goto fail; + } + vgmstream->meta_type = meta_MUSX_V004; + /* open the file for reading */ { int i; @@ -78,15 +87,9 @@ VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) { for (i=0;ich[i].streamfile = file; - - if (vgmstream->coding_type == coding_XBOX) { - /* xbox interleaving is a little odd */ - vgmstream->ch[i].channel_start_offset=start_offset; - } else { - vgmstream->ch[i].channel_start_offset= - start_offset+vgmstream->interleave_block_size*i; - } - vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset; + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset=start_offset+ + vgmstream->interleave_block_size*i; } } @@ -146,6 +149,20 @@ VGMSTREAM * init_vgmstream_musx_v006(STREAMFILE *streamFile) { vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))*28/16/channel_count; vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))*28/16/channel_count; } + break; + case 0x47435F5F: /* GC__ */ + start_offset = read_32bitBE(0x28,streamFile); + vgmstream->channels = channel_count; + vgmstream->sample_rate = 32000; + vgmstream->coding_type = coding_DAT4_IMA; + vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))*28/16/channel_count; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x20; + vgmstream->meta_type = meta_MUSX_V006; + if (loop_flag) { + vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))*28/16/channel_count; + vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))*28/16/channel_count; + } break; default: goto fail; @@ -302,7 +319,8 @@ VGMSTREAM * init_vgmstream_musx_v201(STREAMFILE *streamFile) { /* check header */ if (read_32bitBE(0x00,streamFile) != 0x4D555358) /* "MUSX" */ goto fail; - if (read_32bitBE(0x08,streamFile) != 0xC9000000) /* "0xC9000000" */ + if ((read_32bitBE(0x08,streamFile) != 0xC9000000) && + (read_32bitLE(0x08,streamFile) != 0xC9000000)) /* "0xC9000000" */ goto fail; channel_count = 2; diff --git a/src/meta/ngc_bo2.c b/src/meta/ngc_bo2.c new file mode 100644 index 00000000..5c17b0ef --- /dev/null +++ b/src/meta/ngc_bo2.c @@ -0,0 +1,100 @@ +#include "meta.h" +#include "../util.h" + +/* BO2 (Blood Omen 2 NGC) */ +VGMSTREAM * init_vgmstream_ngc_bo2(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int loop_flag; + int channels; + int channel_count; + off_t start_offset; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("bo2",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x0) /* "IDSP" */ + goto fail; + + switch (read_32bitBE(0x10,streamFile)) + { + case 0x0: + channels = 1; + break; + case 0x1: + channels = 2; + break; + default: + goto fail; + } + + if ((get_streamfile_size(streamFile)) < ((read_32bitBE(0x0C,streamFile)/14*8*channels)+0x800)) + { + goto fail; + } + + channel_count = channels; + loop_flag = (read_32bitBE(0x08,streamFile) != 0xFFFFFFFF); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x800; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x04,streamFile); + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = read_32bitBE(0x0C,streamFile); + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x08,streamFile); + vgmstream->loop_end_sample = read_32bitBE(0x0C,streamFile); + } + + if (channel_count == 1) + { + vgmstream->layout_type = layout_none; + } + else + { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x400; + } + + vgmstream->meta_type = meta_NGC_BO2; + + { + int i; + for (i=0;i<16;i++) + vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x24+i*2,streamFile); + if (channel_count == 2) { + for (i=0;i<16;i++) + vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x52+i*2,streamFile); + } + } + + /* open the file for reading */ + { + int i; + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset=start_offset+ + vgmstream->interleave_block_size*i; + + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} \ No newline at end of file diff --git a/src/meta/ngc_dsp_mpds.c b/src/meta/ngc_dsp_mpds.c new file mode 100644 index 00000000..67295cb8 --- /dev/null +++ b/src/meta/ngc_dsp_mpds.c @@ -0,0 +1,100 @@ +#include "meta.h" +#include "../util.h" + +/* MPDS - found in Big Air Freestyle, Terminator 3 (no coeffs), etc */ +VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int loop_flag = 0; + int channel_count; + off_t start_offset; + int ch1_header_start, ch2_header_start, ch1_start, ch2_start; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("dsp",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x4D504453) /* "MPDS" */ + goto fail; + /* Version byte ??? */ + if (read_32bitBE(0x04,streamFile) != 0x00010000) /* "0x10000" */ + goto fail; + /* compare sample count with body size */ + if (((read_32bitBE(0x08,streamFile)/7*8)) != (read_32bitBE(0x0C,streamFile))) + goto fail; + + channel_count = read_32bitBE(0x14,streamFile); + + if (channel_count > 2) + { + goto fail; + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->channels = channel_count; + + if (channel_count == 1) + { + vgmstream->layout_type = layout_none; + ch1_start = 0x80; + } + else if (channel_count == 2) + { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = read_32bitBE(0x18,streamFile); + ch1_start = 0x80; + ch2_start = 0x80 + vgmstream->interleave_block_size; + } + else + { + goto fail; + } + + vgmstream->sample_rate = read_32bitBE(0x10,streamFile); + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = read_32bitBE(0x08,streamFile); + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = read_32bitBE(0x08,streamFile); + } + + vgmstream->meta_type = meta_NGC_DSP_MPDS; + + { + int i; + for (i=0;i<16;i++) + vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x24+i*2,streamFile); + + if (channel_count == 2) + { + for (i=0;i<16;i++) + vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x4C+i*2,streamFile); + } + } + + /* open the file for reading */ + vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[0].streamfile) goto fail; + vgmstream->ch[0].channel_start_offset = + vgmstream->ch[0].offset=ch1_start; + + if (channel_count == 2) + { + vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[1].streamfile) goto fail; + vgmstream->ch[1].channel_start_offset = + vgmstream->ch[1].offset=ch2_start; + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} \ No newline at end of file diff --git a/src/meta/ngc_dsp_std.c b/src/meta/ngc_dsp_std.c index 6e0c4f98..413aed87 100644 --- a/src/meta/ngc_dsp_std.c +++ b/src/meta/ngc_dsp_std.c @@ -1365,3 +1365,423 @@ fail: if (vgmstream) close_vgmstream(vgmstream); return NULL; } + + +/* .ddsp files, two DSP files stuck together, without additional header */ +VGMSTREAM * init_vgmstream_dsp_ddsp(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + + off_t channel_1_start, channel_2_start, channel_1_size, channel_2_size; + + struct dsp_header ch0_header,ch1_header; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("ddsp",filename_extension(filename))) goto fail; + + /* read .wsd header */ + channel_1_start = 0; + channel_2_start = (get_streamfile_size(streamFile)/2); + channel_1_size = (get_streamfile_size(streamFile)/2)-0x60; + channel_2_size = (get_streamfile_size(streamFile)/2)-0x60; + + /* check header */ + if (channel_1_size != channel_2_size) goto fail; + if (channel_1_start != 0x0) goto fail; + if (channel_1_size < 0x20 || channel_2_size < 0x20) goto fail; + if (channel_1_start + channel_1_size > channel_2_start) goto fail; + if (channel_2_start + channel_2_size > get_streamfile_size(streamFile)) + goto fail; + + /* get DSP headers */ + if (read_dsp_header(&ch0_header, channel_1_start, streamFile)) goto fail; + if (read_dsp_header(&ch1_header, channel_2_start, streamFile)) goto fail; + + /* check initial predictor/scale */ + if (ch0_header.initial_ps != + (uint8_t)read_8bit(channel_1_start + 0x60, streamFile)) + goto fail; + + if (ch1_header.initial_ps != + (uint8_t)read_8bit(channel_2_start + 0x60, streamFile)) + goto fail; + + /* check type==0 and gain==0 */ + if (ch0_header.format || ch0_header.gain || + ch1_header.format || ch1_header.gain) + goto fail; + + /* check for agreement */ + if ( + ch0_header.sample_count != ch1_header.sample_count || + ch0_header.nibble_count != ch1_header.nibble_count || + ch0_header.sample_rate != ch1_header.sample_rate || + ch0_header.loop_flag != ch1_header.loop_flag || + ch0_header.loop_start_offset != ch1_header.loop_start_offset || + ch0_header.loop_end_offset != ch1_header.loop_end_offset + ) goto fail; + + if (ch0_header.loop_flag) { + off_t loop_off; + /* check loop predictor/scale */ + loop_off = ch0_header.loop_start_offset/16*8; + if (ch0_header.loop_ps != + (uint8_t)read_8bit(channel_1_start+0x60+loop_off,streamFile)) + goto fail; + if (ch1_header.loop_ps != + (uint8_t)read_8bit(channel_2_start+0x60+loop_off,streamFile)) + goto fail; + } + + /* build the VGMSTREAM */ + + vgmstream = allocate_vgmstream(2,ch0_header.loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->num_samples = ch0_header.sample_count; + vgmstream->sample_rate = ch0_header.sample_rate; + + vgmstream->loop_start_sample = dsp_nibbles_to_samples( + ch0_header.loop_start_offset); + vgmstream->loop_end_sample = dsp_nibbles_to_samples( + ch0_header.loop_end_offset)+1; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_DSP_DDSP; + + /* coeffs */ + { + int i; + for (i=0;i<16;i++) { + vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i]; + vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i]; + } + } + + /* initial history */ + /* always 0 that I've ever seen, but for completeness... */ + vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1; + vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2; + vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1; + vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2; + + /* open the file for reading */ + vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[0].streamfile) goto fail; + + vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[1].streamfile) goto fail; + + vgmstream->ch[0].channel_start_offset = + vgmstream->ch[0].offset=channel_1_start+0x60; + vgmstream->ch[1].channel_start_offset = + vgmstream->ch[1].offset=channel_2_start+0x60; + + return vgmstream; + +fail: + /* clean up anything we may have opened */ + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} + + +/* .was files, DSP file(s), with additional iSWS header */ +VGMSTREAM * init_vgmstream_wii_was(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + struct dsp_header ch0_header,ch1_header; + off_t ch1_header_start, ch2_header_start, ch1_start, ch2_start; + int channel_count; + int i; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if ((strcasecmp("dsp",filename_extension(filename))) && + (strcasecmp("isws",filename_extension(filename))) && + (strcasecmp("was",filename_extension(filename)))) + goto fail; + + /* read iSWS header */ + if (read_32bitBE(0x0,streamFile) != 0x69535753) + goto fail; + + channel_count = read_32bitBE(0x08,streamFile); + + if (channel_count == 1) + { + + ch1_header_start = 0x20; + ch1_start = 0x80; + + /* get DSP headers */ + if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail; + + /* check initial predictor/scale */ + if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile)) + goto fail; + + /* check type==0 and gain==0 */ + if (ch0_header.format || ch0_header.gain) + goto fail; + + if (ch0_header.loop_flag) + { + off_t loop_off; + /* check loop predictor/scale */ + loop_off = ch0_header.loop_start_offset/16*8; + if (ch0_header.loop_ps != (uint8_t)read_8bit(ch1_start+loop_off,streamFile)) + goto fail; + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(1,ch0_header.loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->num_samples = ch0_header.sample_count; + vgmstream->sample_rate = ch0_header.sample_rate; + + vgmstream->loop_start_sample = dsp_nibbles_to_samples( + ch0_header.loop_start_offset); + vgmstream->loop_end_sample = dsp_nibbles_to_samples( + ch0_header.loop_end_offset)+1; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_WII_WAS; + + /* coeffs */ + for (i=0;i<16;i++) { + vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i]; + } + + /* initial history */ + /* always 0 that I've ever seen, but for completeness... */ + vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1; + vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2; + + /* open the file for reading */ + vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[0].streamfile) + goto fail; + vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start; + + } + else if (channel_count == 2) + { + + + ch1_header_start = 0x20; + ch2_header_start = 0x80; + ch1_start = 0xE0; + ch2_start = 0xE0 + (read_32bitBE(0x10,streamFile)); + + /* get DSP headers */ + if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail; + if (read_dsp_header(&ch1_header, ch2_header_start, streamFile)) goto fail; + + /* check initial predictor/scale */ + if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile)) + goto fail; + if (ch1_header.initial_ps != (uint8_t)read_8bit(ch2_start, streamFile)) + goto fail; + + /* check type==0 and gain==0 */ + if (ch0_header.format || ch0_header.gain) + goto fail; + if (ch1_header.format || ch1_header.gain) + goto fail; + + /* check for agreement */ + if ( + ch0_header.sample_count != ch1_header.sample_count || + ch0_header.nibble_count != ch1_header.nibble_count || + ch0_header.sample_rate != ch1_header.sample_rate || + ch0_header.loop_flag != ch1_header.loop_flag || + ch0_header.loop_start_offset != ch1_header.loop_start_offset || + ch0_header.loop_end_offset != ch1_header.loop_end_offset + ) goto fail; + + if (ch0_header.loop_flag) + { + off_t loop_off; + /* check loop predictor/scale */ + loop_off = ch0_header.loop_start_offset/16*8; + + if (ch0_header.loop_ps != (uint8_t)read_8bit(ch1_start+loop_off,streamFile)) + goto fail; + if (ch1_header.loop_ps != (uint8_t)read_8bit(ch2_start+loop_off,streamFile)) + goto fail; + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(2,ch0_header.loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->num_samples = ch0_header.sample_count; + vgmstream->sample_rate = ch0_header.sample_rate; + + vgmstream->loop_start_sample = dsp_nibbles_to_samples( + ch0_header.loop_start_offset); + vgmstream->loop_end_sample = dsp_nibbles_to_samples( + ch0_header.loop_end_offset)+1; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = read_32bitBE(0x10,streamFile); + vgmstream->meta_type = meta_WII_WAS; + + /* coeffs */ + for (i=0;i<16;i++) { + vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i]; + vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i]; + } + + /* initial history */ + /* always 0 that I've ever seen, but for completeness... */ + vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1; + vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2; + vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1; + vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2; + + /* open the file for reading */ + vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[0].streamfile) + goto fail; + vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start; + + vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[1].streamfile) + goto fail; + vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start; + + } + else + { + goto fail; + } + + return vgmstream; + + +fail: + /* clean up anything we may have opened */ + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} + + +/* .str found in Micro Machines, Superman: Shadow of Apokolips */ +VGMSTREAM * init_vgmstream_dsp_str_ig(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + struct dsp_header ch0_header,ch1_header; + off_t ch1_header_start, ch2_header_start, ch1_start, ch2_start; + int channel_count; + int i; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("str",filename_extension(filename))) + goto fail; + + channel_count = 2; + + ch1_header_start = 0x00; + ch2_header_start = 0x80; + ch1_start = 0x800; + ch2_start = 0x4800; + + /* get DSP headers */ + if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail; + if (read_dsp_header(&ch1_header, ch2_header_start, streamFile)) goto fail; + + /* check initial predictor/scale */ + if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile)) + goto fail; + if (ch1_header.initial_ps != (uint8_t)read_8bit(ch2_start, streamFile)) + goto fail; + + /* check type==0 and gain==0 */ + if (ch0_header.format || ch0_header.gain) + goto fail; + if (ch1_header.format || ch1_header.gain) + goto fail; + + /* check for agreement */ + if ( + ch0_header.sample_count != ch1_header.sample_count || + ch0_header.nibble_count != ch1_header.nibble_count || + ch0_header.sample_rate != ch1_header.sample_rate || + ch0_header.loop_flag != ch1_header.loop_flag || + ch0_header.loop_start_offset != ch1_header.loop_start_offset || + ch0_header.loop_end_offset != ch1_header.loop_end_offset + ) goto fail; + + if (ch0_header.loop_flag) + { + off_t loop_off; + /* check loop predictor/scale */ + loop_off = ch0_header.loop_start_offset/16*8; + + if (ch0_header.loop_ps != (uint8_t)read_8bit(ch1_start+loop_off,streamFile)) + goto fail; + if (ch1_header.loop_ps != (uint8_t)read_8bit(ch2_start+loop_off,streamFile)) + goto fail; + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(2,ch0_header.loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->num_samples = ch0_header.sample_count; + vgmstream->sample_rate = ch0_header.sample_rate; + + vgmstream->loop_start_sample = dsp_nibbles_to_samples( + ch0_header.loop_start_offset); + vgmstream->loop_end_sample = dsp_nibbles_to_samples( + ch0_header.loop_end_offset)+1; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x4000; + vgmstream->meta_type = meta_DSP_STR_IG; + + /* coeffs */ + for (i=0;i<16;i++) { + vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i]; + vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i]; + } + + /* initial history */ + /* always 0 that I've ever seen, but for completeness... */ + vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1; + vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2; + vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1; + vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2; + + /* open the file for reading */ + vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[0].streamfile) + goto fail; + vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start; + + vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!vgmstream->ch[1].streamfile) + goto fail; + vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start; + + return vgmstream; + + +fail: + /* clean up anything we may have opened */ + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ngc_pdt.c b/src/meta/ngc_pdt.c index 56e70292..b0d8402d 100644 --- a/src/meta/ngc_pdt.c +++ b/src/meta/ngc_pdt.c @@ -1,79 +1,101 @@ -#include "meta.h" -#include "../util.h" - -/* PDT - Custom Generated File (Mario Party) */ -VGMSTREAM * init_vgmstream_ngc_pdt(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[260]; - off_t start_offset; - int loop_flag; - int channel_count; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("pdt",filename_extension(filename))) goto fail; - -#if 0 - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x00000000) /* 0x0 */ - goto fail; -#endif - - loop_flag = (read_32bitBE(0x0C,streamFile)!=2); /* not sure, but it seems unlooped = 2 */ - channel_count = 2; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0x60; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x04,streamFile); - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = read_32bitBE(0x08,streamFile)*14/8/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = read_32bitBE(0x0C,streamFile)*14/8/channel_count; - vgmstream->loop_end_sample = read_32bitBE(0x08,streamFile)*14/8/channel_count; - } - - /* dealing with no interleave, 'cause the interleave - for 2 channels is larger than the sample count/2 */ - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_NGC_PDT; - - - if (vgmstream->coding_type == coding_NGC_DSP) { - int i; - for (i=0;i<16;i++) { - vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile); - } - if (vgmstream->channels == 2) { - for (i=0;i<16;i++) { - vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x40+i*2,streamFile); - } - } - } - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=(get_streamfile_size(streamFile)+start_offset)/2*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../util.h" + +/* PDT - Custom Generated File (Mario Party) */ +VGMSTREAM * init_vgmstream_ngc_pdt(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int loop_flag; + int channel_count; + off_t start_offset; + int second_channel_start; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("pdt",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x50445420) /* "PDT " */ + goto fail; + if (read_32bitBE(0x04,streamFile) != 0x44535020) /* "DSP " */ + goto fail; + if (read_32bitBE(0x08,streamFile) != 0x48454144) /* "HEAD " */ + goto fail; + if (read_16bitBE(0x0C,streamFile) != 0x4552) /* "ER " */ + goto fail; + + loop_flag = (read_32bitBE(0x1C,streamFile)!=2); + channel_count = (uint16_t)(read_16bitLE(0x0E,streamFile)); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x800; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x14,streamFile); + vgmstream->coding_type = coding_NGC_DSP; + + if (channel_count == 1) + { + vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count/2; + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x1C,streamFile)*14/8/channel_count/2; + vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile)*14/8/channel_count/2; + } + } + else if (channel_count == 2) + { + vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count; + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x1C,streamFile)*14/8/channel_count; + vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile)*14/8/channel_count; + } + second_channel_start = (get_streamfile_size(streamFile)+start_offset)/2; + } + else + { + goto fail; + } + + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_NGC_PDT; + + if (vgmstream->coding_type == coding_NGC_DSP) { + int i; + for (i=0;i<16;i++) { + vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x50+i*2,streamFile); + } + if (vgmstream->channels == 2) { + for (i=0;i<16;i++) { + vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x70+i*2,streamFile); + } + } + } + + /* open the file for reading */ + { + int i; + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + + vgmstream->ch[0].channel_start_offset=start_offset; + if (channel_count == 2) { + if (second_channel_start == -1) goto fail; + vgmstream->ch[1].channel_start_offset=second_channel_start; + } + vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset; + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ngc_ssm.c b/src/meta/ngc_ssm.c index 7ea40369..e6253e6a 100644 --- a/src/meta/ngc_ssm.c +++ b/src/meta/ngc_ssm.c @@ -82,7 +82,7 @@ VGMSTREAM * init_vgmstream_ngc_ssm(STREAMFILE *streamFile) { } } -} + } return vgmstream; diff --git a/src/meta/ps2_khv.c b/src/meta/ps2_khv.c new file mode 100644 index 00000000..43831155 --- /dev/null +++ b/src/meta/ps2_khv.c @@ -0,0 +1,65 @@ +#include "meta.h" +#include "../util.h" + +/* KHV (from Kingdom Hearts 2) */ +/* VAG files with custom headers */ +VGMSTREAM * init_vgmstream_ps2_khv(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int loop_flag = 0; + int channel_count; + off_t start_offset; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("khv",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x56414770) /* "VAGp" */ + goto fail; + + loop_flag = (read_32bitBE(0x14,streamFile)!=0); + channel_count = 2; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x60; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x10,streamFile); + vgmstream->coding_type = coding_PSX; + vgmstream->num_samples = read_32bitBE(0x0C,streamFile); + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile); + vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile); + } + + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x10; + vgmstream->meta_type = meta_PS2_KHV; + + /* open the file for reading */ + { + int i; + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset=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/ps2_voi.c b/src/meta/ps2_voi.c new file mode 100644 index 00000000..9352be0f --- /dev/null +++ b/src/meta/ps2_voi.c @@ -0,0 +1,81 @@ +#include "meta.h" +#include "../util.h" + +/* VOI - found in "RAW Danger" (PS2) */ +VGMSTREAM * init_vgmstream_ps2_voi(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int loop_flag = 0; + int channel_count; + off_t start_offset; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("voi",filename_extension(filename))) goto fail; + + /* check header */ + if (((read_32bitLE(0x04,streamFile)*2)+0x800) != (get_streamfile_size(streamFile))) + { + goto fail; + } + + loop_flag = 0; + channel_count = read_32bitLE(0x00,streamFile); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x800; + vgmstream->channels = channel_count; + vgmstream->coding_type = coding_PCM16LE; + vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)/channel_count/2; + + if (loop_flag) + { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = (read_32bitLE(0x04,streamFile)/2); + } + + if (read_32bitLE(0x08,streamFile) == 0) + { + vgmstream->sample_rate = 48000; + vgmstream->interleave_block_size = 0x200; + } + else if (read_32bitLE(0x08,streamFile) == 1) + { + vgmstream->sample_rate = 24000; + vgmstream->interleave_block_size = 0x100; + } + else + { + goto fail; + } + + vgmstream->layout_type = layout_interleave; + vgmstream->meta_type = meta_PS2_VOI; + + /* open the file for reading */ + { + int i; + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset=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/psx_str_mgav.c b/src/meta/psx_str_mgav.c new file mode 100644 index 00000000..a3307a8e --- /dev/null +++ b/src/meta/psx_str_mgav.c @@ -0,0 +1,77 @@ +#include "meta.h" +#include "../layout/layout.h" +#include "../util.h" + +/* STR (Future Cop L.A.P.D.) */ +VGMSTREAM * init_vgmstream_psx_mgav(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + off_t current_chunk; + char filename[260]; + int loop_flag = 0; + int channel_count; + int dataBuffer = 0; + int i; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("str",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x52565753) /* "RVWS" */ + goto fail; + + loop_flag = 1; + channel_count = 2; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = read_32bitLE(0x4,streamFile); + vgmstream->channels = channel_count; + vgmstream->sample_rate = 16000; + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_psx_mgav_blocked; + vgmstream->meta_type = meta_PSX_MGAV; + + /* open the file for reading */ + { + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + } + } + + // calculate samples + current_chunk = start_offset; + vgmstream->num_samples = 0; + while ((current_chunk + start_offset) < (get_streamfile_size(streamFile))) + { + dataBuffer = (read_32bitBE(current_chunk,streamFile)); + if (dataBuffer == 0x4D474156) /* "MGAV" */ + { + psx_mgav_block_update(start_offset,vgmstream); + vgmstream->num_samples += vgmstream->current_block_size/16*28; + current_chunk += vgmstream->current_block_size + 0x1C; + } + current_chunk += 0x10; + } + + + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; + } + + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/spt_spd.c b/src/meta/spt_spd.c index 0d769589..da1eb316 100644 --- a/src/meta/spt_spd.c +++ b/src/meta/spt_spd.c @@ -7,64 +7,68 @@ */ VGMSTREAM * init_vgmstream_spt_spd(STREAMFILE *streamFile) { - - VGMSTREAM * vgmstream = NULL; - STREAMFILE * streamFileSPT = NULL; - char filename[260]; + + VGMSTREAM * vgmstream = NULL; + STREAMFILE * streamFileSPT = NULL; + char filename[260]; char filenameSPT[260]; - int i; int channel_count; int loop_flag; + int i; - /* check extension, case insensitive */ + /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("spd",filename_extension(filename))) goto fail; + strcpy(filenameSPT,filename); + strcpy(filenameSPT+strlen(filenameSPT)-3,"spt"); - strcpy(filenameSPT,filename); - strcpy(filenameSPT+strlen(filenameSPT)-3,"spt"); + streamFileSPT = streamFile->open(streamFile,filenameSPT,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!streamFileSPT) + goto fail; + + if (read_32bitBE(0x0,streamFileSPT) != 0x1) // make sure that it's not a container + goto fail; - streamFileSPT = streamFile->open(streamFile,filenameSPT,STREAMFILE_DEFAULT_BUFFER_SIZE); - - - if (!streamFileSPT) goto fail; - - channel_count = read_32bitBE(0x00,streamFileSPT); - loop_flag = read_32bitBE(0x04,streamFileSPT); + channel_count = 1; + loop_flag = (read_32bitBE(0x0C,streamFileSPT) == 0x2); /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; /* fill in the vital statistics */ - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x08,streamFileSPT); - vgmstream->num_samples=read_32bitBE(0x14,streamFileSPT)*14/16/channel_count; - - switch ((read_32bitBE(0x0,streamFileSPT))) { - case 1: - vgmstream->coding_type = coding_NGC_DSP; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x08,streamFileSPT); + + switch ((read_32bitBE(0x4,streamFileSPT))) { + case 0: + case 1: + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples=read_32bitBE(0x14,streamFileSPT)*14/16/channel_count; + if(loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = read_32bitBE(0x14,streamFileSPT)*14/16/channel_count; + } + break; + case 2: + vgmstream->coding_type = coding_PCM16BE; + vgmstream->num_samples=read_32bitBE(0x14,streamFileSPT)/channel_count; + if(loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = read_32bitBE(0x14,streamFileSPT)/channel_count; + } break; - case 2: - vgmstream->coding_type = coding_PCM16BE; - break; - default: - goto fail; - } - - if(loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = read_32bitBE(0x14,streamFileSPT)*14/16/channel_count; - } - - if (channel_count == 1) { - vgmstream->layout_type = layout_none; - } else if (channel_count == 2) { - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size=(read_32bitBE(0x34,streamFileSPT)*channel_count)/2; - } - + default: + goto fail; + } + if (channel_count == 1) { + vgmstream->layout_type = layout_none; + } else if (channel_count == 2) { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size=(read_32bitBE(0x34,streamFileSPT)*channel_count)/2; + } vgmstream->meta_type = meta_SPT_SPD; @@ -74,7 +78,6 @@ VGMSTREAM * init_vgmstream_spt_spd(STREAMFILE *streamFile) { /* Not sure, i'll put a fake value here for now */ vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000); vgmstream->ch[i].offset = 0; - if (!vgmstream->ch[i].streamfile) goto fail; } } diff --git a/src/meta/ss_stream.c b/src/meta/ss_stream.c index a2e3f610..0631fe00 100644 --- a/src/meta/ss_stream.c +++ b/src/meta/ss_stream.c @@ -117,8 +117,9 @@ VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; int loop_flag=0; - int channels; + int channels; int channel_count; + int freq_flag; off_t start_offset; int i; @@ -128,6 +129,7 @@ VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE *streamFile) { strcasecmp("ss7",filename_extension(filename))) goto fail; loop_flag = 0; + freq_flag = read_8bit(0x08,streamFile); if (read_8bit(0x0C,streamFile) == 0) { channels = 1; @@ -143,17 +145,19 @@ VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE *streamFile) { if (!vgmstream) goto fail; /* fill in the vital statistics */ - vgmstream->channels = channel_count; - - + vgmstream->channels = channel_count; + vgmstream->sample_rate = 48000; +#if 0 if (!strcasecmp("ss3",filename_extension(filename))) { vgmstream->sample_rate = 32000; } else if (!strcasecmp("ss7",filename_extension(filename))) { vgmstream->sample_rate = 48000; } +#endif + start_offset = (read_8bit(0x07,streamFile)+5); if (channel_count == 1){ start_offset = 0x3C; diff --git a/src/meta/wii_was.c b/src/meta/wii_was.c deleted file mode 100644 index 8c492218..00000000 --- a/src/meta/wii_was.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "meta.h" -#include "../util.h" - -/* WAS / ISWS - -found in: DiRT 2 (Wii) - Formula 1 2009 (Wii) - Sega Superstars Tennis (Wii) -*/ - -VGMSTREAM * init_vgmstream_wii_was(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[260]; - off_t start_offset; - int loop_flag; - int channel_count; - int i, j; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("was",filename_extension(filename)) && - (strcasecmp("isws",filename_extension(filename)))) goto fail; - - /* check header */ - if (read_32bitBE(0x0,streamFile) != 0x69535753) /* iSWS */ - goto fail; - - loop_flag = 0; - channel_count = read_32bitBE(0x8,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = (channel_count * 0x60) + 0x20; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x28,streamFile); - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = read_32bitBE(0x20,streamFile); - vgmstream->layout_type = layout_interleave; - - if (channel_count == 1) { - vgmstream->layout_type = layout_none; - } else if (channel_count > 1) { - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = read_32bitBE(0x10,streamFile); - } - - vgmstream->meta_type = meta_WII_WAS; - - { - off_t coef_table[8] = {0x3C,0x9C,0xFC,0x15C,0x1BC,0x21C,0x27C,0x2DC}; - for (j=0;jchannels;j++) { - for (i=0;i<16;i++) { - vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile); - } - } - } - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - - - - return vgmstream; - -fail: - /* clean up anything we may have opened */ - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/src/meta/zwdsp.c b/src/meta/zwdsp.c index 4e9d53df..a26b71b9 100644 --- a/src/meta/zwdsp.c +++ b/src/meta/zwdsp.c @@ -1,86 +1,88 @@ -#include "meta.h" -#include "../util.h" - -/* ZWDSP (hcs' custom DSP files from Zack & Wiki) */ -VGMSTREAM * init_vgmstream_zwdsp(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[260]; - off_t start_offset; - - int loop_flag; - int channel_count = 2; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("zwdsp",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x00000000) /* 0x0 */ - goto fail; - - /* Retrieve the loop flag, some files have 0x0 and some 0x02 as "no loop" */ - - switch (read_32bitBE(0x10, streamFile)) { - case 0: - case 2: - loop_flag = 0; - break; - default: - loop_flag = 1; - } - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0x90; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x08,streamFile); - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = read_32bitBE(0x10,streamFile)*14/8/channel_count; - vgmstream->loop_end_sample = read_32bitBE(0x14,streamFile)*14/8/channel_count; - } - - - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_ZWDSP; - - - if (vgmstream->coding_type == coding_NGC_DSP) { - int i; - for (i=0;i<16;i++) { - vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile); - } - if (vgmstream->channels == 2) { - for (i=0;i<16;i++) { - vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x60+i*2,streamFile); - } - } - } - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - ((get_streamfile_size(streamFile)-start_offset)/2)*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../util.h" + +/* ZWDSP (hcs' custom DSP files from Zack & Wiki) */ +VGMSTREAM * init_vgmstream_zwdsp(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + int second_channel_start; + int loop_flag; + int channel_count = 2; + off_t start_offset; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("zwdsp",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x00000000) /* 0x0 */ + goto fail; + + /* Retrieve the loop flag, some files have 0x0 and some 0x02 as "no loop" */ + + switch (read_32bitBE(0x10, streamFile)) { + case 0: + case 2: + loop_flag = 0; + break; + default: + loop_flag = 1; + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x90; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x08,streamFile); + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count; + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x10,streamFile)*14/8/channel_count; + vgmstream->loop_end_sample = read_32bitBE(0x14,streamFile)*14/8/channel_count; + } + + + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_ZWDSP; + + + if (vgmstream->coding_type == coding_NGC_DSP) { + int i; + for (i=0;i<16;i++) { + vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile); + } + if (vgmstream->channels == 2) { + for (i=0;i<16;i++) { + vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x60+i*2,streamFile); + } + } + } + + second_channel_start = (get_streamfile_size(streamFile)+start_offset)/2; + { + int i; + STREAMFILE * file; + file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (!file) goto fail; + for (i=0;ich[i].streamfile = file; + + vgmstream->ch[0].channel_start_offset=start_offset; + if (channel_count == 2) { + if (second_channel_start == -1) goto fail; + vgmstream->ch[1].channel_start_offset=second_channel_start; + } + vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset; + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index d1a5b659..64437b6d 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -143,6 +143,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_idsp, init_vgmstream_idsp2, init_vgmstream_idsp3, + init_vgmstream_idsp4, init_vgmstream_ngc_ymf, init_vgmstream_sadl, init_vgmstream_ps2_ccc, @@ -243,19 +244,26 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_dmsg, init_vgmstream_ngc_aaap, init_vgmstream_ngc_dsp_tmnt2, - init_vgmstream_ps2_ster, - init_vgmstream_ps2_wb, + init_vgmstream_ps2_ster, + init_vgmstream_ps2_wb, init_vgmstream_bnsf, #ifdef VGM_USE_G7221 init_vgmstream_s14_sss, #endif init_vgmstream_ps2_gcm, - init_vgmstream_ps2_smpl, - init_vgmstream_ps2_msa, + init_vgmstream_ps2_smpl, + init_vgmstream_ps2_msa, + init_vgmstream_ps2_voi, + init_vgmstream_ps2_khv, init_vgmstream_pc_smp, + init_vgmstream_ngc_bo2, + init_vgmstream_dsp_ddsp, init_vgmstream_p3d, - init_vgmstream_ps2_tk1, - init_vgmstream_ps2_adsc, + init_vgmstream_ps2_tk1, + init_vgmstream_ps2_adsc, + init_vgmstream_ngc_dsp_mpds, + init_vgmstream_dsp_str_ig, + init_vgmstream_psx_mgav, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) @@ -288,9 +296,10 @@ VGMSTREAM * init_vgmstream_internal(STREAMFILE *streamFile, int do_dfs) { (vgmstream->meta_type == meta_KRAW) || (vgmstream->meta_type == meta_PS2_MIB) || (vgmstream->meta_type == meta_NGC_LPS) || - (vgmstream->meta_type == meta_DSP_YGO) || + (vgmstream->meta_type == meta_DSP_YGO) || (vgmstream->meta_type == meta_DSP_AGSC) || - (vgmstream->meta_type == meta_PS2_SMPL) + (vgmstream->meta_type == meta_PS2_SMPL) || + (vgmstream->meta_type == meta_SPT_SPD) ) && vgmstream->channels == 1) { try_dual_file_stereo(vgmstream, streamFile); } @@ -691,6 +700,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre case layout_thp_blocked: case layout_filp_blocked: case layout_ivaud_blocked: + case layout_psx_mgav_blocked: render_vgmstream_blocked(buffer,sample_count,vgmstream); break; case layout_interleave_byte: @@ -1737,6 +1747,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case layout_filp_blocked: snprintf(temp,TEMPSIZE,"FILp blocked"); break; + case layout_psx_mgav_blocked: + snprintf(temp,TEMPSIZE,"MGAV blocked"); + break; #ifdef VGM_USE_MPEG case layout_fake_mpeg: snprintf(temp,TEMPSIZE,"MPEG Audio stream with incorrect frame headers"); @@ -2283,12 +2296,6 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_IDSP: snprintf(temp,TEMPSIZE,"IDSP Header"); break; - case meta_IDSP2: - snprintf(temp,TEMPSIZE,"IDSP Header"); - break; - case meta_IDSP3: - snprintf(temp,TEMPSIZE,"IDSP Header"); - break; case meta_WAA_WAC_WAD_WAM: snprintf(temp,TEMPSIZE,"WAA/WAC/WAD/WAM RIFF Header"); break; @@ -2528,14 +2535,29 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_PC_SMP: snprintf(temp,TEMPSIZE,"Ghostbusters .smp Header"); break; + case meta_NGC_PDT: + snprintf(temp,TEMPSIZE,"PDT DSP header"); + break; + case meta_NGC_BO2: + snprintf(temp,TEMPSIZE,"Blood Omen 2 DSP header"); + break; case meta_P3D: snprintf(temp,TEMPSIZE,"Prototype P3D Header"); break; - case meta_PS2_TK1: + case meta_PS2_TK1: snprintf(temp,TEMPSIZE,"Tekken TK5STRM1 Header"); break; - case meta_PS2_ADSC: + case meta_PS2_ADSC: snprintf(temp,TEMPSIZE,"ADSC Header"); + break; + case meta_NGC_DSP_MPDS: + snprintf(temp,TEMPSIZE,"MPDS DSP header"); + break; + case meta_DSP_STR_IG: + snprintf(temp,TEMPSIZE,"Infogrames dual dsp header"); + break; + case meta_PSX_MGAV: + snprintf(temp,TEMPSIZE,"Electronic Arts RVWS header"); break; default: snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); diff --git a/src/vgmstream.h b/src/vgmstream.h index 3734e8a4..07c96549 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -147,8 +147,8 @@ typedef enum { layout_gsb_blocked, layout_thp_blocked, layout_filp_blocked, - layout_mxch_blocked, - + layout_mxch_blocked, + layout_psx_mgav_blocked, #if 0 layout_strm_blocked, /* */ #endif @@ -295,9 +295,7 @@ typedef enum { meta_KRAW, /* Geometry Wars - Galaxies */ meta_PS2_OMU, /* PS2 Int file with Header */ meta_PS2_XA2, /* XG3 Extreme-G Racing */ - meta_IDSP, /* Chronicles of Narnia */ - meta_IDSP2, /* Soul Calibur */ - meta_IDSP3, /* Mario Strikers Charged */ + meta_IDSP, /* Chronicles of Narnia, Soul Calibur Legends, Mario Strikers Charged */ meta_SPT_SPD, /* Variouis */ meta_ISH_ISD, /* Various */ meta_GSP_GSB, /* Various */ @@ -444,17 +442,24 @@ typedef enum { meta_PS2_AST, /* Some KOEI game (PS2) */ meta_DMSG, /* Nightcaster II - Equinox (XBOX) */ meta_NGC_AAAP, /* Turok: Evolution (NGC) */ - meta_PS2_STER, /* Juuni Kokuki: Kakukaku Taru Ou Michi Beni Midori no Uka */ - meta_PS2_WB, /* Shooting Love. ~TRIZEAL~ */ + meta_PS2_STER, /* Juuni Kokuki: Kakukaku Taru Ou Michi Beni Midori no Uka */ + meta_PS2_WB, /* Shooting Love. ~TRIZEAL~ */ meta_S14, /* raw Siren 14, 24kbit mono */ meta_SSS, /* raw Siren 14, 48kbit stereo */ - meta_PS2_GCM, /* NamCollection */ - meta_PS2_SMPL, /* Homura */ - meta_PS2_MSA, /* Psyvariar -Complete Edition- */ + meta_PS2_GCM, /* NamCollection */ + meta_PS2_SMPL, /* Homura */ + meta_PS2_MSA, /* Psyvariar -Complete Edition- */ + meta_PS2_VOI, /* RAW Danger (Zettaizetsumei Toshi 2 - Itetsuita Kiokutachi) [PS2] */ + meta_PS2_KHV, /* Kingdom Hearts 2 VAG streams */ meta_PC_SMP, /* Ghostbusters PC .smp */ meta_P3D, /* Prototype P3D */ - meta_PS2_TK1, /* Tekken (NamCollection) */ + meta_PS2_TK1, /* Tekken (NamCollection) */ meta_PS2_ADSC, /* Kenka Bancho 2: Full Throttle */ + meta_NGC_BO2, /* Blood Omen 2 (NGC) */ + meta_DSP_DDSP, /* Various (2 dsp files stuck together */ + meta_NGC_DSP_MPDS, /* Big Air Freestyle, Terminator 3 */ + meta_DSP_STR_IG, /* Micro Machines, Superman Superman: Shadow of Apokolis */ + meta_PSX_MGAV, /* Future Cop L.A.P.D. */ } meta_t; typedef struct { diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c index 739903d7..a5fa42b0 100644 --- a/winamp/in_vgmstream.c +++ b/winamp/in_vgmstream.c @@ -111,6 +111,7 @@ char * extension_list[] = { "bmdx\0BMDX Audio File (*.BMDX)\0", "bns\0BNS Audio File (*.BNS)\0", "bnsf\0BNSF Audio File (*.BNSF)\0", + "bo2\0BO2 Audio File (*.BO2)\0", "brstm;brstmspm\0BRSTM Audio File (*.BRSTM)\0", "caf\0CAF Audio File (*.CAF)\0", @@ -121,6 +122,7 @@ char * extension_list[] = { "dcs\0DCS Audio File (*.DCS)\0", "de2\0DE2 Audio File (*.DE2)\0", + "ddsp\0DDSP Audio File (*.DDSP)\0", "dmsg\0DMSG Audio File (*.DMSG)\0", "dsp\0DSP Audio File (*.DSP)\0", "dtk\0DTK Audio File (*.DTK)\0", @@ -164,6 +166,7 @@ char * extension_list[] = { "kces\0KCES Audio File (*.KCES)\0", "kcey\0KCEY Audio File (*.KCEY)\0", + "khv\0KHV Audio File (*.KHV)\0", "kraw\0KRAW Audio File (*.KRAW)\0", "leg\0LEG Audio File (*.LEG)\0", @@ -178,6 +181,7 @@ char * extension_list[] = { "mic\0PS2 MIC Audio File (*.MIC)\0", "mihb\0MIHB Audio File (*.MIHB)\0", "mpdsp\0MPDSP Audio File (*.MPDSP)\0", + "mpds\0MPDS Audio File (*.MPDS)\0", "msa\0MSA Audio File (*.MSA)\0", "mss\0MSS Audio File (*.MSS)\0", "msvp\0MSVP Audio File (*.MSVP)\0", @@ -212,6 +216,7 @@ char * extension_list[] = { "rsd\0RSD Audio File (*.RSD)\0", "rsf\0RSF Audio File (*.RSF)\0", "rstm\0RSTM Audio File (*.RSTM)\0", + "rvws\0RVWS Audio File (*.RVWS)\0", "rwar\0RWAR Audio File (*.RWSD)\0", "rwav\0RWAV Audio File (*.RWAV)\0", "rws\0RWS Audio File (*.RWS)\0", @@ -233,7 +238,7 @@ char * extension_list[] = { "sl3\0SL3 Audio File (*.SL3)\0", "sli\0SLI Audio File (*.SLI)\0", "smp\0SMP Audio File (*.SMP)\0", - "smpl\0SMPL Audio File (*.SMPL)\0", + "smpl\0SMPL Audio File (*.SMPL)\0", "snd\0SND Audio File (*.SND)\0", "sng\0SNG Audio File (*.SNG)\0", "sns\0SNS Audio File (*.SNS)\0", @@ -274,6 +279,7 @@ char * extension_list[] = { "vs\0VS Audio File (*.VS)\0", "vsf\0VSF Audio File (*.VSF)\0", "vgv\0VGV Audio File (*.VGV)\0", + "voi\0VOI Audio File (*.VOI)\0", "waa\0WAA Audio File (*.WAA)\0", "wac\0WAC Audio File (*.WAC)\0", @@ -281,7 +287,7 @@ char * extension_list[] = { "wam\0WAM Audio File (*.WAM)\0", "wavm\0WAVM Audio File (*.WAVM)\0", "was\0WAS Audio File (*.WAS)\0", - "wb\0WB Audio File (*.WB)\0", + "wb\0WB Audio File (*.WB)\0", "wii\0WII Audio File (*.WII)\0", "wp2\0WP2 Audio File (*.WP2)\0", "wsd\0WSD Audio File (*.WSD)\0",