diff --git a/src/layout/blocked.c b/src/layout/blocked.c index d44a104a..bc876b39 100644 --- a/src/layout/blocked.c +++ b/src/layout/blocked.c @@ -85,8 +85,11 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM * case layout_de2_blocked: de2_block_update(vgmstream->next_block_offset,vgmstream); break; - case layout_emff_blocked: - emff_block_update(vgmstream->next_block_offset,vgmstream); + case layout_emff_ps2_blocked: + emff_ps2_block_update(vgmstream->next_block_offset,vgmstream); + break; + case layout_emff_ngc_blocked: + emff_ngc_block_update(vgmstream->next_block_offset,vgmstream); break; case layout_vs_blocked: vs_block_update(vgmstream->next_block_offset,vgmstream); diff --git a/src/layout/emff_blocked.c b/src/layout/emff_blocked.c index eb39b4e6..b3ed7f5f 100644 --- a/src/layout/emff_blocked.c +++ b/src/layout/emff_blocked.c @@ -2,7 +2,7 @@ #include "../vgmstream.h" /* set up for the block at the given offset */ -void emff_block_update(off_t block_offset, VGMSTREAM * vgmstream) { +void emff_ps2_block_update(off_t block_offset, VGMSTREAM * vgmstream) { int i; vgmstream->current_block_offset = block_offset; @@ -16,3 +16,19 @@ void emff_block_update(off_t block_offset, VGMSTREAM * vgmstream) { vgmstream->ch[i].offset = vgmstream->current_block_offset+0x20+(vgmstream->current_block_size*i); } } + +void emff_ngc_block_update(off_t block_offset, VGMSTREAM * vgmstream) { + int i; + + vgmstream->current_block_offset = block_offset; + vgmstream->current_block_size = read_32bitBE( + vgmstream->current_block_offset+0x20, + vgmstream->ch[0].streamfile); + vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size+0x40; + vgmstream->current_block_size/=vgmstream->channels; + + for (i=0;ichannels;i++) { + vgmstream->ch[i].offset = vgmstream->current_block_offset+0x40+(vgmstream->current_block_size*i); + } +} + diff --git a/src/layout/layout.h b/src/layout/layout.h index 1598b833..1a98ca25 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -30,7 +30,9 @@ void de2_block_update(off_t block_offset, VGMSTREAM * vgmstream); void vs_block_update(off_t block_offset, VGMSTREAM * vgmstream); -void emff_block_update(off_t block_offset, VGMSTREAM * vgmstream); +void emff_ps2_block_update(off_t block_offset, VGMSTREAM * vgmstream); + +void emff_ngc_block_update(off_t block_offset, VGMSTREAM * vgmstream); void xvas_block_update(off_t block_offset, VGMSTREAM * vgmstream); diff --git a/src/layout/test_blocked.c b/src/layout/test_blocked.c deleted file mode 100644 index c22d216f..00000000 --- a/src/layout/test_blocked.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "layout.h" -#include "../vgmstream.h" - -/* set up for the block at the given offset */ -void test_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+0x10, - vgmstream->ch[0].streamfile); - vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size+0x20; - vgmstream->current_block_size/=vgmstream->channels; - - for (i=0;ichannels;i++) { - vgmstream->ch[i].offset = vgmstream->current_block_offset+0x20+(vgmstream->current_block_size*i); - } -} diff --git a/src/meta/_test.c b/src/meta/_test.c deleted file mode 100644 index c7dcbf49..00000000 --- a/src/meta/_test.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "meta.h" -#include "../util.h" - -VGMSTREAM * init_vgmstream_test(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[260]; - off_t start_offset; - int loop_flag = 0; - int channel_count; - int i; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("test",filename_extension(filename))) goto fail; - - /* check header */ -#if 0 - if (read_32bitBE(0x00,streamFile) != 0x53565300) /* "SVS\0" */ - goto fail; -#endif - - loop_flag = 0; - channel_count = read_32bitLE(0x0c,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_32bitLE(0x00,streamFile); - vgmstream->coding_type = coding_PSX; - /* vgmstream->num_samples = read_32bitLE(0x08,streamFile); */ - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = read_32bitLE(0x08,streamFile); - } - - vgmstream->layout_type = layout_test_blocked; - vgmstream->interleave_block_size = 0x10; - vgmstream->meta_type = meta_TEST; - - /* open the file for reading */ - { - for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,0x2000); - if (!vgmstream->ch[i].streamfile) goto fail; - } - } - - - /* Calc num_samples */ - test_block_update(start_offset,vgmstream); - vgmstream->num_samples=0; - - do { - vgmstream->num_samples += vgmstream->current_block_size*28/16; - test_block_update(vgmstream->next_block_offset,vgmstream); - } while (vgmstream->next_block_offsetget_name(streamFile,filename,sizeof(filename)); if (strcasecmp("emff",filename_extension(filename))) goto fail; - /* check header */ -#if 0 - if (read_32bitBE(0x00,streamFile) != 0x53565300) /* "SVS\0" */ - goto fail; -#endif + /* do some checks on the file, cause we have no magic words to check the header... + it seems if 0x800 and 0x804 = 0 then the file has only audio, if 0x800 = 1 + it has a text section, if both are 1 it's video with a text section included... */ - loop_flag = (read_32bitLE(0x04,streamFile) != 0xFFFFFFFF); - channel_count = read_32bitLE(0x0C,streamFile); - + if (read_32bitBE(0x800,streamFile) == 0x01000000 || /* "0x01000000" */ + read_32bitBE(0x804,streamFile) == 0x01000000) /* "0x01000000" */ + goto fail; + + + frequency = read_32bitLE(0x0,streamFile); + channel_count = read_32bitLE(0xC,streamFile); + + + if (frequency > 48000 || + channel_count > 8) { + goto fail; + } + + loop_flag = (read_32bitLE(0x4,streamFile) != 0xFFFFFFFF); + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; /* fill in the vital statistics */ - start_offset = 0x800; + + start_offset = 0x800; + vgmstream->sample_rate = frequency; vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x00,streamFile); - vgmstream->coding_type = coding_PSX; - /* vgmstream->num_samples = read_32bitLE(0x08,streamFile); */ - if (loop_flag) { - vgmstream->loop_start_sample = loop_flag; - vgmstream->loop_end_sample = read_32bitLE(0x08,streamFile); + vgmstream->coding_type = coding_PSX; + + + 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); } - vgmstream->layout_type = layout_emff_blocked; - vgmstream->interleave_block_size = 0x10; - vgmstream->meta_type = meta_EMFF; + vgmstream->layout_type = layout_emff_ps2_blocked; + vgmstream->interleave_block_size = 0x10; + vgmstream->meta_type = meta_EMFF_PS2; - /* open the file for reading */ - { + /* 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 = streamFile->open(streamFile,filename,0x2000); - if (!vgmstream->ch[i].streamfile) goto fail; - } - } - - + vgmstream->ch[i].streamfile = file; + } + } + /* Calc num_samples */ - emff_block_update(start_offset,vgmstream); + emff_ps2_block_update(start_offset,vgmstream); vgmstream->num_samples=0; do { - vgmstream->num_samples += vgmstream->current_block_size*28/16/channel_count; - emff_block_update(vgmstream->next_block_offset,vgmstream); + + vgmstream->num_samples += vgmstream->current_block_size*28/16; + emff_ps2_block_update(vgmstream->next_block_offset,vgmstream); } while (vgmstream->next_block_offsetget_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("emff",filename_extension(filename))) goto fail; + + /* do some checks on the file, cause we have no magic words to check the header... + it seems if 0x800 and 0x804 = 0 then the file has only audio, if 0x800 = 1 + it has a text section, if both are 1 it's video with a text section included... */ + + if (read_32bitBE(0x800,streamFile) == 0x00000001 || /* "0x00000001" */ + read_32bitBE(0x804,streamFile) == 0x00000001) /* "0x00000001" */ + goto fail; + + + frequency = read_32bitBE(0x0,streamFile); + channel_count = read_32bitBE(0xC,streamFile); + + + if (frequency > 48000 || + channel_count > 8) { + goto fail; + } + + loop_flag = (read_32bitBE(0x4,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->sample_rate = frequency; + vgmstream->channels = channel_count; + vgmstream->coding_type = coding_NGC_DSP; + + + if (loop_flag) { + vgmstream->loop_start_sample = (read_32bitBE(0x28,streamFile)-start_offset)*14/8/channel_count; + vgmstream->loop_end_sample = read_32bitBE(0x8,streamFile); + } + + vgmstream->layout_type = layout_emff_ngc_blocked; + vgmstream->interleave_block_size = 0x10; + vgmstream->meta_type = meta_EMFF_NGC; + + /* 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; + } + } + + + if (vgmstream->coding_type == coding_NGC_DSP) { + 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); + } + } + } + + /* Calc num_samples */ + emff_ngc_block_update(start_offset,vgmstream); + vgmstream->num_samples=0; + + do { + + vgmstream->num_samples += vgmstream->current_block_size*14/8; + emff_ngc_block_update(vgmstream->next_block_offset,vgmstream); + } while (vgmstream->next_block_offsetget_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("thp",filename_extension(filename)) && - strcasecmp("dsp",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x54485000) - goto fail; - + char componentTypes[16]; + + int loop_flag; + int channel_count; + int i; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("thp",filename_extension(filename)) && + strcasecmp("dsp",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x54485000) + goto fail; + maxAudioSize = read_32bitBE(0x0C,streamFile); - thpVersion = read_8bit(0x06,streamFile); - + thpVersion = read_8bit(0x06,streamFile); + if(maxAudioSize==0) // no sound goto fail; - - loop_flag = 0; // allways unloop - - /* fill in the vital statistics */ - start_offset = read_32bitBE(0x28,streamFile); - - // Get info from the first block - componentTypeOffset = read_32bitBE(0x20,streamFile); - numComponents = read_32bitBE(componentTypeOffset ,streamFile); - componentDataOffset=componentTypeOffset+0x14; - componentTypeOffset+=4; - - for(i=0;ichannels=channel_count; - vgmstream->sample_rate=read_32bitBE(componentDataOffset+4,streamFile); - vgmstream->num_samples=read_32bitBE(componentDataOffset+8,streamFile); - break; - } else { - if(thpVersion==0x10) - componentDataOffset+=0x0c; - else - componentDataOffset+=0x08; - } - } - - /* 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->thpNextFrameSize=read_32bitBE(0x18,streamFile); + + loop_flag = 0; // allways unloop + + /* fill in the vital statistics */ + start_offset = read_32bitBE(0x28,streamFile); + + // Get info from the first block + componentTypeOffset = read_32bitBE(0x20,streamFile); + numComponents = read_32bitBE(componentTypeOffset ,streamFile); + componentDataOffset=componentTypeOffset+0x14; + componentTypeOffset+=4; + + for(i=0;ichannels=channel_count; + vgmstream->sample_rate=read_32bitBE(componentDataOffset+4,streamFile); + vgmstream->num_samples=read_32bitBE(componentDataOffset+8,streamFile); + break; + } else { + if(thpVersion==0x10) + componentDataOffset+=0x0c; + else + componentDataOffset+=0x08; + } + } + + /* 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->thpNextFrameSize=read_32bitBE(0x18,streamFile); thp_block_update(start_offset,vgmstream); - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->layout_type = layout_thp_blocked; - vgmstream->meta_type = meta_THP; - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_thp_blocked; + vgmstream->meta_type = meta_THP; + + 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 8203ca95..f614355e 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -173,7 +173,8 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_vgs, init_vgmstream_dc_wav_dcs, init_vgmstream_wii_smp, - init_vgmstream_emff, + init_vgmstream_emff_ps2, + init_vgmstream_emff_ngc, init_vgmstream_ss_stream, init_vgmstream_thp, init_vgmstream_wii_sts, @@ -532,7 +533,8 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre case layout_matx_blocked: case layout_de2_blocked: case layout_vs_blocked: - case layout_emff_blocked: + case layout_emff_ps2_blocked: + case layout_emff_ngc_blocked: case layout_xvas_blocked: case layout_thp_blocked: render_vgmstream_blocked(buffer,sample_count,vgmstream); @@ -1359,8 +1361,11 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case layout_vs_blocked: snprintf(temp,TEMPSIZE,"vs blocked"); break; - case layout_emff_blocked: - snprintf(temp,TEMPSIZE,"EMFF blocked"); + case layout_emff_ps2_blocked: + snprintf(temp,TEMPSIZE,"EMFF (PS2) blocked"); + break; + case layout_emff_ngc_blocked: + snprintf(temp,TEMPSIZE,"EMFF (NGC/WII) blocked"); break; case layout_thp_blocked: snprintf(temp,TEMPSIZE,"THP Movie Audio blocked"); @@ -1905,7 +1910,8 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_WII_SMP: snprintf(temp,TEMPSIZE,"SMP DSP Header"); break; - case meta_EMFF: + case meta_EMFF_PS2: + case meta_EMFF_NGC: snprintf(temp,TEMPSIZE,"Eidos Music File Format Header"); break; case meta_THP: diff --git a/src/vgmstream.h b/src/vgmstream.h index cc8d5da9..7c3a2cfb 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -120,7 +120,8 @@ typedef enum { layout_de2_blocked, layout_xvas_blocked, layout_vs_blocked, - layout_emff_blocked, + layout_emff_ps2_blocked, + layout_emff_ngc_blocked, layout_thp_blocked, #if 0 @@ -289,7 +290,8 @@ typedef enum { meta_VGS, /* Guitar Hero Encore - Rocks the 80s */ meta_DC_WAV_DCS, /* Evil Twin - Cypriens Chronicles (DC) */ meta_WII_SMP, /* Mushroom Men - The Spore Wars */ - meta_EMFF, /* Eidos Music File Format */ + meta_EMFF_PS2, /* Eidos Music File Format for PS2*/ + meta_EMFF_NGC, /* Eidos Music File Format for NGC/WII */ meta_XBOX_WAVM, /* XBOX WAVM File */ meta_XBOX_RIFF, /* XBOX RIFF/WAVE File */