mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 09:40:51 +01:00
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:
parent
1054ca1596
commit
014d22b5eb
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user