diff options
Diffstat (limited to 'lib/vgmstream/src/meta/ngc_caf.c')
-rw-r--r-- | lib/vgmstream/src/meta/ngc_caf.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/vgmstream/src/meta/ngc_caf.c b/lib/vgmstream/src/meta/ngc_caf.c new file mode 100644 index 0000000000..f56b6db56b --- /dev/null +++ b/lib/vgmstream/src/meta/ngc_caf.c @@ -0,0 +1,75 @@ +#include "meta.h" +#include "../layout/layout.h" +#include "../util.h" + +VGMSTREAM * init_vgmstream_caf(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + + // Calculate sample length ... + int32_t num_of_samples=0; + int32_t block_count=0; + + uint32_t loop_start=-1; + + off_t offset=0; + off_t next_block; + off_t file_length; + int i; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("cfn",filename_extension(filename))) goto fail; + + /* Check "CAF " ID */ + if (read_32bitBE(0,streamFile)!=0x43414620) goto fail; + + // Calculate sample length ... + file_length=(off_t)get_streamfile_size(streamFile); + + do { + next_block=read_32bitBE(offset+0x04,streamFile); + num_of_samples+=read_32bitBE(offset+0x14,streamFile)/8*14; + + if(read_32bitBE(offset+0x20,streamFile)==read_32bitBE(offset+0x08,streamFile)) { + loop_start=num_of_samples-read_32bitBE(offset+0x14,streamFile)/8*14; + } + offset+=next_block; + block_count++; + } while(offset<file_length); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(2,(loop_start!=-1)); /* always stereo */ + if (!vgmstream) goto fail; + + vgmstream->channels=2; + vgmstream->sample_rate=32000; + vgmstream->num_samples=num_of_samples; + + if(loop_start!=-1) { + vgmstream->loop_start_sample=loop_start; + vgmstream->loop_end_sample=num_of_samples; + } + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_caf_blocked; + vgmstream->meta_type = meta_CFN; + + /* open the file for reading by each channel */ + { + for (i=0;i<2;i++) { + vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000); + + if (!vgmstream->ch[i].streamfile) goto fail; + } + } + + caf_block_update(0,vgmstream); + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} |