Add EA .WVE videos [Supercross 2000 (PS), Wing Commander 3/4 (PS)]

This commit is contained in:
bnnm 2018-03-29 15:39:33 +02:00
parent ae999b6769
commit c052848e26
13 changed files with 253 additions and 0 deletions

View File

@ -376,6 +376,7 @@ static const char* extension_list[] = {
"wsd",
"wsi",
"wv2", //txth/reserved [Slave Zero (PC)]
"wve",
"wvs",
"xa",
@ -592,6 +593,8 @@ static const layout_info layout_info_list[] = {
{layout_blocked_vgs, "blocked (VGS)"},
{layout_blocked_vawx, "blocked (VAWX)"},
{layout_blocked_xvag_subsong, "blocked (XVAG subsong)"},
{layout_blocked_ea_wve_au00, "blocked (EA WVE au00)"},
{layout_blocked_ea_wve_ad10, "blocked (EA WVE Ad10)"},
};
static const meta_info meta_info_list[] = {
@ -971,6 +974,8 @@ static const meta_info meta_info_list[] = {
{meta_WAVE_segmented, "EngineBlack .WAVE header (segmented)"},
{meta_SMV, "Cho Aniki Zero .SMV header"},
{meta_NXAP, "Nex NXAP header"},
{meta_EA_WVE_AU00, "Electronic Arts WVE (au00) header"},
{meta_EA_WVE_AD10, "Electronic Arts WVE (Ad10) header"},
#ifdef VGM_USE_MP4V2
{meta_MP4, "AAC header"},

View File

@ -167,6 +167,12 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
case layout_blocked_xvag_subsong:
block_update_xvag_subsong(vgmstream->next_block_offset,vgmstream);
break;
case layout_blocked_ea_wve_au00:
block_update_ea_wve_au00(vgmstream->next_block_offset,vgmstream);
break;
case layout_blocked_ea_wve_ad10:
block_update_ea_wve_ad10(vgmstream->next_block_offset,vgmstream);
break;
default:
break;
}

View File

@ -0,0 +1,42 @@
#include "layout.h"
#include "../coding/coding.h"
/* EA style blocks, one block per channel when stereo */
void block_update_ea_wve_ad10(off_t block_offset, VGMSTREAM * vgmstream) {
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
int i;
size_t block_size = 0;
size_t file_size = get_streamfile_size(streamFile);
while (block_offset < file_size) {
uint32_t block_id = read_32bitBE(block_offset+0x00, streamFile);
block_size = read_32bitBE(block_offset+0x04, streamFile);
if (block_id == 0x41643130 || block_id == 0x41643131) { /* "Ad10/Ad11" audio block/footer found */
break;
}
/* rest may be "MDEC" video blocks */
block_offset += block_size;
}
/* EOF reads (unsure if this helps) */
if (block_offset >= file_size) {
vgmstream->current_block_offset = block_offset;
vgmstream->next_block_offset = block_offset + 0x04;
vgmstream->current_block_size = 0;
return;
}
/* set offsets */
for (i = 0; i < vgmstream->channels; i++) {
vgmstream->ch[i].offset = block_offset + block_size*i + 0x08;
}
vgmstream->current_block_size = block_size - 0x08; /* one block per channel */
vgmstream->current_block_offset = block_offset;
vgmstream->next_block_offset = block_offset + block_size*vgmstream->channels;
}

View File

@ -0,0 +1,37 @@
#include "layout.h"
#include "../coding/coding.h"
/* EA style blocks */
void block_update_ea_wve_au00(off_t block_offset, VGMSTREAM * vgmstream) {
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
int i;
size_t block_size = 0, interleave;
size_t file_size = get_streamfile_size(streamFile);
while (block_offset < file_size) {
uint32_t block_id = read_32bitBE(block_offset+0x00, streamFile);
block_size = read_32bitBE(block_offset+0x04, streamFile);
if (block_id == 0x61753030 || block_id == 0x61753031) { /* "au00/au01" audio block/footer found */
break;
}
/* rest may be "MDEC" video blocks */
block_offset += block_size;
}
/* size adjusted to frame boundaries as blocks have padding */
interleave = ((block_size - 0x10) / vgmstream->interleave_block_size * vgmstream->interleave_block_size) / vgmstream->channels;
/* set offsets */
for (i = 0; i < vgmstream->channels; i++) {
vgmstream->ch[i].offset = (block_offset + 0x10) + interleave*i;
}
vgmstream->current_block_size = interleave;
vgmstream->current_block_offset = block_offset;
vgmstream->next_block_offset = block_offset + block_size;
}

View File

@ -61,6 +61,8 @@ void block_update_awc(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_vgs(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_vawx(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_xvag_subsong(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_ea_wve_au00(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_ea_wve_ad10(off_t block_offset, VGMSTREAM * vgmstream);
/* other layouts */
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);

View File

@ -387,6 +387,14 @@
<File
RelativePath=".\meta\ea_eaac.c"
>
</File>
<File
RelativePath=".\meta\ea_wve_au00.c"
>
</File>
<File
RelativePath=".\meta\ea_wve_ad10.c"
>
</File>
<File
RelativePath=".\meta\emff.c"
@ -1710,6 +1718,14 @@
RelativePath=".\layout\blocked_ea_1snh.c"
>
</File>
<File
RelativePath=".\layout\blocked_ea_wve_au00.c"
>
</File>
<File
RelativePath=".\layout\blocked_ea_wve_ad10.c"
>
</File>
<File
RelativePath=".\layout\blocked_vawx.c"
>

View File

@ -212,6 +212,8 @@
<ClCompile Include="meta\ea_schl_fixed.c" />
<ClCompile Include="meta\ea_1snh.c" />
<ClCompile Include="meta\ea_eaac.c" />
<ClCompile Include="meta\ea_wve_au00.c" />
<ClCompile Include="meta\ea_wve_ad10.c" />
<ClCompile Include="meta\emff.c" />
<ClCompile Include="meta\exakt_sc.c" />
<ClCompile Include="meta\ffw.c" />
@ -483,6 +485,8 @@
<ClCompile Include="layout\blocked_dec.c" />
<ClCompile Include="layout\blocked_ea_schl.c" />
<ClCompile Include="layout\blocked_ea_sns.c" />
<ClCompile Include="layout\blocked_ea_wve_au00.c" />
<ClCompile Include="layout\blocked_ea_wve_ad10.c" />
<ClCompile Include="layout\emff_blocked.c" />
<ClCompile Include="layout\filp_blocked.c" />
<ClCompile Include="layout\gsb_blocked.c" />

View File

@ -235,6 +235,12 @@
<ClCompile Include="meta\ea_eaac.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ea_wve_au00.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ea_wve_ad10.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\emff.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -1003,6 +1009,12 @@
<ClCompile Include="layout\blocked_ea_1snh.c">
<Filter>layout\Source Files</Filter>
</ClCompile>
<ClCompile Include="layout\blocked_ea_wve_au00.c">
<Filter>layout\Source Files</Filter>
</ClCompile>
<ClCompile Include="layout\blocked_ea_wve_ad10.c">
<Filter>layout\Source Files</Filter>
</ClCompile>
<ClCompile Include="layout\blocked_vgs.c">
<Filter>layout\Source Files</Filter>
</ClCompile>

56
src/meta/ea_wve_ad10.c Normal file
View File

@ -0,0 +1,56 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../layout/layout.h"
/* EA WVE (Ad10) - from Electronic Arts PS movies [Wing Commander 3/4 (PS)] */
VGMSTREAM * init_vgmstream_ea_wve_ad10(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag, channel_count;
/* checks */
if (!check_extensions(streamFile, "wve"))
goto fail;
start_offset = 0x00;
if (read_32bitBE(start_offset, streamFile) != 0x41643130 && /* "Ad10" */
read_32bitBE(start_offset, streamFile) != 0x41643131) /* "Ad11" (last block, but could be first) */
goto fail;
loop_flag = 0;
/* no header = no channels, but seems if the first PS-ADPCM header is 00 then it's mono, somehow
* (ex. Wing Commander 3 intro / Wing Commander 4 = stereo, rest of Wing Commander 3 = mono) */
channel_count = read_8bit(start_offset+0x08,streamFile) != 0 ? 2 : 1;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = 22050;
vgmstream->meta_type = meta_EA_WVE_AD10;
vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_blocked_ea_wve_ad10;
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
goto fail;
/* calc num_samples manually */
{
vgmstream->num_samples = 0;
block_update_ea_wve_ad10(start_offset,vgmstream);
do {
vgmstream->num_samples += ps_bytes_to_samples(vgmstream->current_block_size, 1);
block_update_ea_wve_ad10(vgmstream->next_block_offset,vgmstream);
}
while (vgmstream->next_block_offset < get_streamfile_size(streamFile));
}
block_update_ea_wve_ad10(start_offset, vgmstream);
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

61
src/meta/ea_wve_au00.c Normal file
View File

@ -0,0 +1,61 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../layout/layout.h"
/* EA WVE (VLC0/au00) - from Electronic Arts PS movies [Future Cop - L.A.P.D. (PS), Supercross 2000 (PS)] */
VGMSTREAM * init_vgmstream_ea_wve_au00(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag, channel_count;
/* checks */
if (!check_extensions(streamFile, "wve"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x564C4330) /* "VLC0" */
goto fail;
start_offset = read_32bitBE(0x04,streamFile);
if (read_32bitBE(start_offset, streamFile) != 0x61753030 && /* "au00" */
read_32bitBE(start_offset, streamFile) != 0x61753031) /* "au01" (last block, but could be first) */
goto fail;
loop_flag = 0;
channel_count = 2;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = 22050;
vgmstream->meta_type = meta_EA_WVE_AU00;
/* You'd think they'd use coding_EA_XA_int but instead it's PS-ADPCM without flags and 0x0f frame size
* (equivalent to configurable PS-ADPCM), surely to shoehorn EA-XA sizes into the PS1 hardware decoder */
vgmstream->coding_type = coding_PSX_cfg;
vgmstream->interleave_block_size = 0x0f;
vgmstream->layout_type = layout_blocked_ea_wve_au00;
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
goto fail;
/* calc num_samples manually */
{
vgmstream->num_samples = 0;
block_update_ea_wve_au00(start_offset,vgmstream);
do {
/* ps_cfg_bytes_to_samples */
vgmstream->num_samples += vgmstream->current_block_size / vgmstream->interleave_block_size*channel_count * 28 / channel_count;
block_update_ea_wve_au00(vgmstream->next_block_offset,vgmstream);
}
while (vgmstream->next_block_offset < get_streamfile_size(streamFile));
}
block_update_ea_wve_au00(start_offset, vgmstream);
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -717,4 +717,8 @@ VGMSTREAM * init_vgmstream_smv(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_nxap(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_wve_au00(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_wve_ad10(STREAMFILE * streamFile);
#endif /*_META_H*/

View File

@ -387,6 +387,8 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
init_vgmstream_rsd6wma,
init_vgmstream_smv,
init_vgmstream_nxap,
init_vgmstream_ea_wve_au00,
init_vgmstream_ea_wve_ad10,
init_vgmstream_txth, /* should go at the end (lower priority) */
#ifdef VGM_USE_FFMPEG
@ -926,6 +928,8 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
case layout_blocked_vgs:
case layout_blocked_vawx:
case layout_blocked_xvag_subsong:
case layout_blocked_ea_wve_au00:
case layout_blocked_ea_wve_ad10:
render_vgmstream_blocked(buffer,sample_count,vgmstream);
break;
case layout_aix:

View File

@ -249,6 +249,8 @@ typedef enum {
layout_blocked_vgs, /* Guitar Hero II (PS2) */
layout_blocked_vawx, /* No More Heroes 6ch (PS3) */
layout_blocked_xvag_subsong, /* XVAG subsongs [God of War III (PS4)] */
layout_blocked_ea_wve_au00, /* EA WVE au00 blocks */
layout_blocked_ea_wve_ad10, /* EA WVE Ad10 blocks */
/* otherwise odd */
layout_aix, /* CRI AIX's wheels within wheels */
@ -659,6 +661,8 @@ typedef enum {
meta_WAVE_segmented, /* EngineBlack games, segmented [Shantae and the Pirate's Curse (PC)] */
meta_SMV, /* Cho Aniki Zero (PSP) */
meta_NXAP, /* Nex Entertainment games [Time Crisis 4 (PS3), Time Crisis Razing Storm (PS3)] */
meta_EA_WVE_AU00, /* Electronic Arts PS movies [Future Cop - L.A.P.D. (PS), Supercross 2000 (PS)] */
meta_EA_WVE_AD10, /* Electronic Arts PS movies [Wing Commander 3/4 (PS)] */
#ifdef VGM_USE_MP4V2
meta_MP4, /* AAC (iOS) */