move dsp header reading into a function, so dsp stereo variants can use it

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@107 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2008-05-12 11:48:36 +00:00
parent 1054ca1596
commit 014d22b5eb

View File

@ -2,14 +2,79 @@
#include "../coding/coding.h"
#include "../util.h"
/* The standard .dsp */
/* If these variables are packed properly in the struct (one after another)
* then this is actually how they are laid out in the file, albeit big-endian */
struct dsp_header {
uint32_t sample_count;
uint32_t nibble_count;
uint32_t sample_rate;
uint16_t loop_flag;
uint16_t format;
uint32_t loop_start_offset;
uint32_t loop_end_offset;
uint32_t ca;
int16_t coef[16]; /* really 8x2 */
uint16_t gain;
uint16_t initial_ps;
int16_t initial_hist1;
int16_t initial_hist2;
uint16_t loop_ps;
int16_t loop_hist1;
int16_t loop_hist2;
};
/* nonzero on failure */
static int read_dsp_header(struct dsp_header *header, off_t offset, STREAMFILE *file) {
int i;
uint8_t buf[0x4a]; /* usually padded out to 0x60 */
if (read_streamfile(buf, offset, 0x4a, file) != 0x4a) return 1;
header->sample_count =
get_32bitBE(buf+0x00);
header->nibble_count =
get_32bitBE(buf+0x04);
header->sample_rate =
get_32bitBE(buf+0x08);
header->loop_flag =
get_16bitBE(buf+0x0c);
header->format =
get_16bitBE(buf+0x0e);
header->loop_start_offset =
get_32bitBE(buf+0x10);
header->loop_end_offset =
get_32bitBE(buf+0x14);
header->ca =
get_32bitBE(buf+0x18);
for (i=0; i < 16; i++)
header->coef[i] =
get_16bitBE(buf+0x1c+i*2);
header->gain =
get_16bitBE(buf+0x3c);
header->initial_ps =
get_16bitBE(buf+0x3e);
header->initial_hist1 =
get_16bitBE(buf+0x40);
header->initial_hist2 =
get_16bitBE(buf+0x42);
header->loop_ps =
get_16bitBE(buf+0x44);
header->loop_hist1 =
get_16bitBE(buf+0x46);
header->loop_hist2 =
get_16bitBE(buf+0x48);
return 0;
}
/* the standard .dsp, as generated by DSPADPCM.exe */
VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
int loop_flag;
off_t start_offset;
struct dsp_header header;
const off_t start_offset = 0x60;
int i;
/* check extension, case insensitive */
@ -19,22 +84,21 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
infile = open_streamfile(filename);
if (!infile) goto fail;
start_offset = 0x60;
if (read_dsp_header(&header, 0, infile)) goto fail;
/* check initial predictor/scale */
if (read_16bitBE(0x3e,infile) != (uint8_t)read_8bit(start_offset,infile))
if (header.initial_ps != (uint8_t)read_8bit(start_offset,infile))
goto fail;
/* check type==0 and gain==0 */
if (read_16bitBE(0x0e,infile) || read_16bitBE(0x3c,infile))
if (header.format || header.gain)
goto fail;
loop_flag = read_16bitBE(0xc,infile);
if (loop_flag) {
if (header.loop_flag) {
off_t loop_off;
/* check loop predictor/scale */
loop_off = read_32bitBE(0x10,infile)/16*8;
if (read_16bitBE(0x44,infile) != (uint8_t)read_8bit(start_offset+loop_off,infile))
loop_off = header.loop_start_offset/16*8;
if (header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,infile))
goto fail;
}
@ -47,47 +111,44 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(1,loop_flag);
vgmstream = allocate_vgmstream(1,header.loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(0,infile);
vgmstream->sample_rate = read_32bitBE(8,infile);
vgmstream->num_samples = header.sample_count;
vgmstream->sample_rate = header.sample_rate;
/*
vgmstream->loop_start_sample =
read_32bitBE(0x10,infile)/16*14;
vgmstream->loop_end_sample =
read_32bitBE(0x14,infile)/16*14;
*/
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
read_32bitBE(0x10,infile));
header.loop_start_offset);
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
read_32bitBE(0x14,infile))+1;
header.loop_end_offset)+1;
/* don't know why, but it does happen*/
if (vgmstream->loop_end_sample > vgmstream->num_samples)
vgmstream->loop_end_sample = vgmstream->num_samples;
start_offset = 0x60;
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_DSP_STD;
/* coeffs */
for (i=0;i<16;i++)
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x1c+i*2,infile);
vgmstream->ch[0].adpcm_coef[i] = header.coef[i];
/* initial history */
/* always 0 that I've ever seen, but for completeness... */
vgmstream->ch[0].adpcm_history1_16 = header.initial_hist1;
vgmstream->ch[0].adpcm_history2_16 = header.initial_hist2;
close_streamfile(infile); infile=NULL;
/* open the file for reading */
{
vgmstream->ch[0].streamfile = open_streamfile(filename);
vgmstream->ch[0].streamfile = open_streamfile(filename);
if (!vgmstream->ch[0].streamfile) goto fail;
if (!vgmstream->ch[0].streamfile) goto fail;
vgmstream->ch[0].channel_start_offset=
vgmstream->ch[0].offset=start_offset;
}
vgmstream->ch[0].channel_start_offset=
vgmstream->ch[0].offset=start_offset;
return vgmstream;