adding xbox decoder + WAVM support

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@194 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
fastelbja 2008-05-23 22:52:02 +00:00
parent eac7190023
commit f7de62c8c9
11 changed files with 180 additions and 4 deletions

View File

@ -9,6 +9,7 @@ void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
void g72x_init_state(struct g72x_state *state_ptr); void g72x_init_state(struct g72x_state *state_ptr);
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_xbox_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_ngc_afc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_ngc_afc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);

View File

@ -63,3 +63,54 @@ void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
stream->adpcm_history1_16 = hist1; stream->adpcm_history1_16 = hist1;
stream->adpcm_step_index = step_index; stream->adpcm_step_index = step_index;
} }
void decode_xbox_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
int i=first_sample;
int sample_nibble;
int sample_decoded;
int delta;
int32_t sample_count=0;
int32_t hist1=stream->adpcm_history1_32;
int step_index = stream->adpcm_step_index;
off_t offset=stream->offset;
first_sample = first_sample % 64;
hist1 = read_16bitLE(offset,stream->streamfile);
step_index = read_16bitLE(offset+2,stream->streamfile);
/* Skip sample predictors */
offset+=(4*channelspacing)-5;
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
int step = ADPCMTable[step_index];
offset += (i%2?0:1);
if(!(i%8) && channelspacing>1) offset+=4;
sample_nibble = (read_8bit(offset,stream->streamfile) >> (i&1?4:0))&0xf;
sample_decoded=hist1;
delta = step >> 3;
if (sample_nibble & 1) delta += step >> 2;
if (sample_nibble & 2) delta += step >> 1;
if (sample_nibble & 4) delta += step;
if (sample_nibble & 8)
sample_decoded -= delta;
else
sample_decoded += delta;
hist1=clamp16(sample_decoded);
step_index += IMA_IndexTable[sample_nibble];
if (step_index < 0) step_index=0;
if (step_index > 88) step_index=88;
outbuf[sample_count]=(short)(hist1);
}
stream->adpcm_history1_32=hist1;
stream->adpcm_step_index=step_index;
}

View File

@ -51,6 +51,9 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
case layout_xa_blocked: case layout_xa_blocked:
xa_block_update(vgmstream->next_block_offset,vgmstream); xa_block_update(vgmstream->next_block_offset,vgmstream);
break; break;
case layout_xbox_blocked:
xbox_block_update(vgmstream->next_block_offset,vgmstream);
break;
default: default:
break; break;
} }

View File

@ -12,6 +12,8 @@ void halpst_block_update(off_t block_ofset, VGMSTREAM * vgmstream);
void xa_block_update(off_t block_offset, VGMSTREAM * vgmstream); void xa_block_update(off_t block_offset, VGMSTREAM * vgmstream);
void xbox_block_update(off_t block_offset, VGMSTREAM * vgmstream);
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream); void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
void render_vgmstream_nolayout(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream); void render_vgmstream_nolayout(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);

15
src/layout/xbox_blocked.c Normal file
View File

@ -0,0 +1,15 @@
#include "layout.h"
#include "../vgmstream.h"
/* set up for the block at the given offset */
void xbox_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
int i;
vgmstream->current_block_offset = block_offset;
vgmstream->current_block_size = 36*vgmstream->channels;
vgmstream->next_block_offset = vgmstream->current_block_offset+vgmstream->current_block_size;
for (i=0;i<vgmstream->channels;i++) {
vgmstream->ch[i].offset = vgmstream->current_block_offset +
4*i;
}
}

View File

@ -314,6 +314,10 @@
RelativePath=".\meta\rwsd.c" RelativePath=".\meta\rwsd.c"
> >
</File> </File>
<File
RelativePath=".\meta\xbox_wavm.c"
>
</File>
</Filter> </Filter>
</Filter> </Filter>
<Filter <Filter
@ -410,6 +414,10 @@
RelativePath=".\layout\xa_blocked.c" RelativePath=".\layout\xa_blocked.c"
> >
</File> </File>
<File
RelativePath=".\layout\xbox_blocked.c"
>
</File>
</Filter> </Filter>
</Filter> </Filter>
</Files> </Files>

View File

@ -67,4 +67,6 @@ VGMSTREAM * init_vgmstream_ps2_ild(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_pnb(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_ps2_pnb(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_xbox_wavm(STREAMFILE *streamFile);
#endif #endif

67
src/meta/xbox_wavm.c Normal file
View File

@ -0,0 +1,67 @@
#include "meta.h"
#include "../util.h"
/* WAVM
WAVM is an headerless format which can be found on XBOX
known extensions : WAVM
2008-05-23 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_xbox_wavm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
off_t start_offset;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("wavm",filename_extension(filename))) goto fail;
/* No loop on wavm */
loop_flag = 0;
/* Always stereo files */
channel_count=2;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
/* allways 2 channels @ 44100 Hz */
vgmstream->channels = 2;
vgmstream->sample_rate = 44100;
vgmstream->coding_type = coding_XBOX;
vgmstream->num_samples = get_streamfile_size(streamFile) / 36 * 64 / vgmstream->channels;
vgmstream->layout_type = layout_xbox_blocked;
vgmstream->current_block_size=36*vgmstream->channels;
vgmstream->current_block_offset=0;
xbox_block_update(0,vgmstream);
vgmstream->meta_type = meta_XBOX_WAVM;
start_offset = 0;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
if (!vgmstream->ch[i].streamfile) goto fail;
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -15,7 +15,7 @@
* List of functions that will recognize files. These should correspond pretty * List of functions that will recognize files. These should correspond pretty
* directly to the metadata types * directly to the metadata types
*/ */
#define INIT_VGMSTREAM_FCNS 32 #define INIT_VGMSTREAM_FCNS 33
VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(STREAMFILE *streamFile) = { VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(STREAMFILE *streamFile) = {
init_vgmstream_adx, /* 0 */ init_vgmstream_adx, /* 0 */
init_vgmstream_brstm, /* 1 */ init_vgmstream_brstm, /* 1 */
@ -48,7 +48,8 @@ VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(STREAMFILE *streamFile)
init_vgmstream_psx_gms, /* 28 */ init_vgmstream_psx_gms, /* 28 */
init_vgmstream_ps2_str, /* 29 */ init_vgmstream_ps2_str, /* 29 */
init_vgmstream_ps2_ild, /* 30 */ init_vgmstream_ps2_ild, /* 30 */
init_vgmstream_ps2_pnb /* 31 */ init_vgmstream_ps2_pnb, /* 31 */
init_vgmstream_xbox_wavm /* 32 */
}; };
/* internal version with all parameters */ /* internal version with all parameters */
@ -223,6 +224,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
case layout_ast_blocked: case layout_ast_blocked:
case layout_halpst_blocked: case layout_halpst_blocked:
case layout_xa_blocked: case layout_xa_blocked:
case layout_xbox_blocked:
render_vgmstream_blocked(buffer,sample_count,vgmstream); render_vgmstream_blocked(buffer,sample_count,vgmstream);
break; break;
} }
@ -249,6 +251,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
case coding_PSX: case coding_PSX:
case coding_XA: case coding_XA:
return 28; return 28;
case coding_XBOX:
return 64;
default: default:
return 0; return 0;
} }
@ -286,6 +290,8 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
return 16; return 16;
case coding_XA: case coding_XA:
return 14*vgmstream->channels; return 14*vgmstream->channels;
case coding_XBOX:
return 64+(4*vgmstream->channels);
default: default:
return 0; return 0;
} }
@ -346,6 +352,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
vgmstream->channels,vgmstream->samples_into_block, vgmstream->channels,vgmstream->samples_into_block,
samples_to_do); samples_to_do);
} }
break;
case coding_XBOX:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_xbox_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do,chan);
}
break; break;
case coding_NGC_DTK: case coding_NGC_DTK:
for (chan=0;chan<vgmstream->channels;chan++) { for (chan=0;chan<vgmstream->channels;chan++) {
@ -542,6 +555,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
break; break;
case coding_XA: case coding_XA:
snprintf(temp,TEMPSIZE,"CD-ROM XA 4-bit ADPCM"); snprintf(temp,TEMPSIZE,"CD-ROM XA 4-bit ADPCM");
break;
case coding_XBOX:
snprintf(temp,TEMPSIZE,"XBOX 4-bit IMA ADPCM");
break; break;
default: default:
snprintf(temp,TEMPSIZE,"CANNOT DECODE"); snprintf(temp,TEMPSIZE,"CANNOT DECODE");
@ -572,6 +588,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
break; break;
case layout_xa_blocked: case layout_xa_blocked:
snprintf(temp,TEMPSIZE,"CD-ROM XA"); snprintf(temp,TEMPSIZE,"CD-ROM XA");
break;
case layout_xbox_blocked:
snprintf(temp,TEMPSIZE,"XBOX blocked");
break; break;
default: default:
snprintf(temp,TEMPSIZE,"INCONCEIVABLE"); snprintf(temp,TEMPSIZE,"INCONCEIVABLE");
@ -718,7 +737,10 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
snprintf(temp,TEMPSIZE,"ILD header"); snprintf(temp,TEMPSIZE,"ILD header");
break; break;
case meta_PS2_PNB: case meta_PS2_PNB:
snprintf(temp,TEMPSIZE,"assumed PNB (PsychoNauts Bgm File) by .pnb header"); snprintf(temp,TEMPSIZE,"assumed PNB (PsychoNauts Bgm File) by .pnb extension");
break;
case meta_XBOX_WAVM:
snprintf(temp,TEMPSIZE,"assumed Xbox WAVM file by .wavm extension");
break; break;
default: default:
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");

View File

@ -24,6 +24,7 @@ typedef enum {
coding_NGC_AFC, /* NGC ADPCM, called AFC */ coding_NGC_AFC, /* NGC ADPCM, called AFC */
coding_PSX, /* PSX & PS2 ADPCM */ coding_PSX, /* PSX & PS2 ADPCM */
coding_XA, /* PSX CD-XA */ coding_XA, /* PSX CD-XA */
coding_XBOX, /* XBOX IMA */
} coding_t; } coding_t;
/* The layout type specifies how the sound data is laid out in the file */ /* The layout type specifies how the sound data is laid out in the file */
@ -40,6 +41,7 @@ typedef enum {
layout_ast_blocked, /* .ast STRM with BLCK blocks*/ layout_ast_blocked, /* .ast STRM with BLCK blocks*/
layout_halpst_blocked, /* blocks with HALPST-format header */ layout_halpst_blocked, /* blocks with HALPST-format header */
layout_xa_blocked, layout_xa_blocked,
layout_xbox_blocked,
#if 0 #if 0
layout_strm_blocked, /* */ layout_strm_blocked, /* */
#endif #endif
@ -98,6 +100,8 @@ typedef enum {
meta_PS2_PNB, /* PsychoNauts Bgm File */ meta_PS2_PNB, /* PsychoNauts Bgm File */
meta_PSX_XA, /* CD-XA with RIFF header */ meta_PSX_XA, /* CD-XA with RIFF header */
meta_XBOX_WAVM, /* XBOX WAVM File */
meta_RAW, /* RAW PCM file */ meta_RAW, /* RAW PCM file */
} meta_t; } meta_t;

View File

@ -105,7 +105,8 @@ char * extension_list[] = {
"gms\0GMS Audio File (*.GMS)\0", "gms\0GMS Audio File (*.GMS)\0",
"str\0STR Audio File (*.STR)\0", "str\0STR Audio File (*.STR)\0",
"ild\0ILD Audio File (*.ILD)\0", "ild\0ILD Audio File (*.ILD)\0",
"pnb\0PNB Audio File (*.PNB)\0" "pnb\0PNB Audio File (*.PNB)\0",
"wavm\0WAVM Audio File (*.WAVM)\0"
}; };
void about(HWND hwndParent) { void about(HWND hwndParent) {