diff --git a/src/layout/thp_blocked.c b/src/layout/thp_blocked.c new file mode 100644 index 00000000..37afbcd8 --- /dev/null +++ b/src/layout/thp_blocked.c @@ -0,0 +1,32 @@ +#include "layout.h" +#include "../vgmstream.h" + +/* set up for the block at the given offset */ +void thp_block_update(off_t block_offset, VGMSTREAM * vgmstream) { + int i,j; + STREAMFILE *streamFile=vgmstream->ch[0].streamfile; + off_t start_offset; + off_t interleave_offset; + int32_t nextFrameSize; + + vgmstream->current_block_offset = block_offset; + nextFrameSize=read_32bitBE(vgmstream->current_block_offset,streamFile); + + vgmstream->next_block_offset = vgmstream->current_block_offset + + vgmstream->thpNextFrameSize; + vgmstream->thpNextFrameSize=nextFrameSize; + + start_offset=vgmstream->current_block_offset + + read_32bitBE(vgmstream->current_block_offset+0x08,streamFile)+0x10; + vgmstream->current_block_size=read_32bitBE(start_offset,streamFile); + start_offset+=8; + + for(i=0;ichannels;i++) { + for(j=0;j<16;j++) { + vgmstream->ch[i].adpcm_coef[j]=read_16bitBE(start_offset+(i*0x20)+(j*2),streamFile); + } + vgmstream->ch[i].adpcm_history1_16=read_16bitBE(start_offset + (0x20*vgmstream->channels) + (i*4),streamFile); + vgmstream->ch[i].adpcm_history2_16=read_16bitBE(start_offset + (0x20*vgmstream->channels) + (i*4) + 2,streamFile); + vgmstream->ch[i].offset = start_offset + (0x24*vgmstream->channels)+(i*vgmstream->current_block_size); + } +} diff --git a/src/meta/thp.c b/src/meta/thp.c new file mode 100644 index 00000000..49a561e2 --- /dev/null +++ b/src/meta/thp.c @@ -0,0 +1,91 @@ +#include "meta.h" +#include "../util.h" + +/* THP (Just play audio from .thp movie file) + by fastelbja */ + +VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile) { + + VGMSTREAM * vgmstream = NULL; + + char filename[260]; + off_t start_offset; + + uint32_t maxAudioSize=0; + + uint32_t numComponents; + off_t componentTypeOffset; + off_t componentDataOffset; + + 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); + + 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 + componentDataOffset+=0x0c; + } + + /* 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; +}