diff --git a/src/Makefile b/src/Makefile index 6a9db907..f9517368 100644 --- a/src/Makefile +++ b/src/Makefile @@ -134,7 +134,8 @@ META_OBJS=meta/adx_header.o \ meta/kraw.o \ meta/ps2_xa2.o \ meta/idsp.o \ - meta/ngc_ymf.o + meta/ngc_ymf.o \ + meta/nds_sad.o OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index d87c42b3..725a040b 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -317,6 +317,10 @@ RelativePath=".\meta\musx.c" > + + diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index b76aab1e..3ed5345f 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -103,4 +103,5 @@ libmeta_la_SOURCES += kraw.c libmeta_la_SOURCES += ps2_xa2.c libmeta_la_SOURCES += idsp.c libmeta_la_SOURCES += ngc_ymf.c +libmeta_la_SOURCES += nds_sad.c EXTRA_DIST = meta.h diff --git a/src/meta/meta.h b/src/meta/meta.h index cf39ffe6..9da9611a 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -227,4 +227,6 @@ VGMSTREAM * init_vgmstream_idsp(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ngc_ymf(STREAMFILE * streamFile); +VGMSTREAM * init_vgmstream_sadl(STREAMFILE * streamFile); + #endif diff --git a/src/meta/nds_sad.c b/src/meta/nds_sad.c new file mode 100644 index 00000000..4d160f52 --- /dev/null +++ b/src/meta/nds_sad.c @@ -0,0 +1,69 @@ +#include "meta.h" +#include "../util.h" + +/* sadl (only the Professor Layton interleaved IMA version) */ +VGMSTREAM * init_vgmstream_sadl(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("sad",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x7361646c) /* "sadl" */ + goto fail; + + /* check file size */ + if (read_32bitLE(0x40,streamFile) != get_streamfile_size(streamFile) ) + goto fail; + + /* check for the simple IMA type that we can handle */ + if (read_8bit(0xc,streamFile) != 0x11) + goto fail; + + loop_flag = 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 = 0x100; + vgmstream->channels = channel_count; + vgmstream->sample_rate = 16000; + vgmstream->coding_type = coding_INT_IMA; + vgmstream->num_samples = read_32bitLE(0x50,streamFile);; + vgmstream->interleave_block_size=0x10; + + vgmstream->layout_type = layout_interleave; + vgmstream->meta_type = meta_SADL; + + /* 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/vgmstream.c b/src/vgmstream.c index 86499066..963fbb5d 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -129,6 +129,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_ps2_xa2, init_vgmstream_idsp, init_vgmstream_ngc_ymf, + init_vgmstream_sadl, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) @@ -545,6 +546,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) { case coding_EACS_IMA: case coding_IMA: return 1; + case coding_INT_IMA: case coding_INT_DVI_IMA: case coding_AICA: return 2; @@ -629,6 +631,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) { return 1; // the frame is variant in size case coding_WS: return vgmstream->current_block_size; + case coding_INT_IMA: case coding_INT_DVI_IMA: case coding_AICA: return 1; @@ -837,6 +840,7 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to } break; case coding_IMA: + case coding_INT_IMA: for (chan=0;chanchannels;chan++) { decode_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, vgmstream->channels,vgmstream->samples_into_block, @@ -1145,6 +1149,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case coding_EACS_IMA: snprintf(temp,TEMPSIZE,"EACS 4-bit IMA ADPCM"); break; + case coding_INT_IMA: + snprintf(temp,TEMPSIZE,"Interleaved 4-bit IMA ADPCM"); + break; case coding_IMA: snprintf(temp,TEMPSIZE,"4-bit IMA ADPCM"); break; @@ -1507,6 +1514,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_DSP_SADB: snprintf(temp,TEMPSIZE,"sadb header"); break; + case meta_SADL: + snprintf(temp,TEMPSIZE,"sadl header"); + break; case meta_PS2_BMDX: snprintf(temp,TEMPSIZE,"Beatmania .bmdx header"); break; diff --git a/src/vgmstream.h b/src/vgmstream.h index 70e1b5ec..96c1e640 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -64,6 +64,7 @@ typedef enum { coding_INT_DVI_IMA, /* Interleaved DVI */ coding_EACS_IMA, coding_IMA, /* bare IMA, low nibble first */ + coding_INT_IMA, /* */ coding_WS, /* Westwood Studios' custom VBR ADPCM */ #ifdef VGM_USE_MPEG coding_fake_MPEG2_L2, /* MPEG-2 Layer 2 (AHX), with lying headers */ @@ -235,6 +236,7 @@ typedef enum { meta_PS2_XA2, /* XA2 XG3 file */ meta_IDSP, /* Chronicles of Narnia */ meta_NGC_YMF, /* WWE WrestleMania X8 */ + meta_SADL, /* .sad */ meta_XBOX_WAVM, /* XBOX WAVM File */ meta_XBOX_RIFF, /* XBOX RIFF/WAVE File */