mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-19 00:04:04 +01:00
Merge pull request #1385 from EdnessP/master
RWS 0x809: Better codec detection
This commit is contained in:
commit
b249869549
@ -1330,18 +1330,18 @@ different internally (encrypted, different versions, etc) and not always can be
|
||||
- Konami RWAX header [*RWAX*]
|
||||
- *rwax*: `.rwx`
|
||||
- Codecs: PCM16LE
|
||||
- **rws.c**
|
||||
- **rws_809.c**
|
||||
- RenderWare RWS header [*RWS*]
|
||||
- *rws*: `.rws`
|
||||
- *rws_809*: `.rws`
|
||||
- Codecs: PSX NGC_DSP PCM16BE PCM16LE
|
||||
- **rws_80d.c**
|
||||
- RenderWare RWS header [*RWS*]
|
||||
- *rws_80d*: `.rws`
|
||||
- Codecs: PCM16_int PCM16BE PCM16LE PSX NGC_DSP XBOX_IMA
|
||||
- **rwsd.c**
|
||||
- Nintendo RWSD header (single stream) [*RWSD*]
|
||||
- *rwsd*: `.brwsd .rwsd`
|
||||
- Codecs: PCM8 PCM16BE NGC_DSP
|
||||
- **rws_mono.c**
|
||||
- RenderWare RWS header [*RWS*]
|
||||
- *rws_mono*: `.rws`
|
||||
- Codecs: PSX PCM16BE PCM16LE
|
||||
- **rxws.c**
|
||||
- Sony RXWS header [*RXWS*]
|
||||
- *rxws*: `.xwb .xws + .xwh .xwb`
|
||||
|
@ -599,9 +599,9 @@
|
||||
<ClCompile Include="meta\rsd.c" />
|
||||
<ClCompile Include="meta\rstm_rockstar.c" />
|
||||
<ClCompile Include="meta\rwax.c" />
|
||||
<ClCompile Include="meta\rws.c" />
|
||||
<ClCompile Include="meta\rws_809.c" />
|
||||
<ClCompile Include="meta\rws_80d.c" />
|
||||
<ClCompile Include="meta\rwsd.c" />
|
||||
<ClCompile Include="meta\rws_mono.c" />
|
||||
<ClCompile Include="meta\rxws.c" />
|
||||
<ClCompile Include="meta\s3v.c" />
|
||||
<ClCompile Include="meta\sab.c" />
|
||||
|
@ -1618,15 +1618,15 @@
|
||||
<ClCompile Include="meta\rwax.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\rws.c">
|
||||
<ClCompile Include="meta\rws_809.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\rws_80d.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\rwsd.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\rws_mono.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\rxws.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -29,7 +29,7 @@ VGMSTREAM* init_vgmstream_awd(STREAMFILE* sf) {
|
||||
|
||||
data_offset = read_u32(0x08, sf);
|
||||
wavedict_offset = read_u32(0x0C, sf);
|
||||
//data_size = read_u32(0x14, sf);
|
||||
//data_size = read_u32(0x14, sf);
|
||||
/* Platform UUIDs in big endian
|
||||
* {FD9D32D3-E179-426A-8424-14720AC7F648}: GameCube
|
||||
* {ACC9EAAA-38FC-1749-AE81-64EADBC79353}: PlayStation 2
|
||||
@ -72,20 +72,20 @@ VGMSTREAM* init_vgmstream_awd(STREAMFILE* sf) {
|
||||
|
||||
/* is at the correct target song index */
|
||||
if (total_subsongs == target_subsong) {
|
||||
//entry_uuid_offset = read_u32(entry_info_offset + 0x00, sf); /* only used in Burnout games */
|
||||
//entry_uuid_offset = read_u32(entry_info_offset + 0x00, sf); /* only used in Burnout games */
|
||||
entry_name_offset = read_u32(entry_info_offset + 0x04, sf);
|
||||
|
||||
sample_rate = read_u32(entry_info_offset + 0x10, sf);
|
||||
stream_codec = read_u32(entry_info_offset + 0x14, sf);
|
||||
stream_size = read_u32(entry_info_offset + 0x18, sf);
|
||||
//bit_depth = read_u8(entry_info_offset + 0x1C, sf);
|
||||
//bit_depth = read_u8(entry_info_offset + 0x1C, sf);
|
||||
channels = read_u8(entry_info_offset + 0x1D, sf); /* always 1, don't think stereo entries exist */
|
||||
if (channels != 1)
|
||||
goto fail;
|
||||
|
||||
/* stores a "00: GCN ADPCM Header" chunk, otherwise empty */
|
||||
misc_data_offset = read_u32(entry_info_offset + 0x20, sf);
|
||||
//misc_data_size = read_u32(entry_info_offset + 0x24, sf);
|
||||
//misc_data_size = read_u32(entry_info_offset + 0x24, sf);
|
||||
|
||||
/* entry_info_offset + 0x2C to +0x44 has the target format information,
|
||||
* which in most cases would probably be identical to the input format
|
||||
|
@ -980,7 +980,7 @@ VGMSTREAM* init_vgmstream_ego_dic(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_awd(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_rws_mono(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_rws_809(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_pwb(STREAMFILE* sf);
|
||||
|
||||
|
@ -4,27 +4,27 @@
|
||||
|
||||
|
||||
/* RWS - RenderWare Stream (with the tag 0x809) */
|
||||
VGMSTREAM* init_vgmstream_rws_mono(STREAMFILE* sf) {
|
||||
VGMSTREAM* init_vgmstream_rws_809(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
bool big_endian;
|
||||
char header_name[STREAM_NAME_SIZE], stream_name[STREAM_NAME_SIZE];
|
||||
int bit_depth = 0, channels = 0, idx, interleave, loop_flag, sample_rate = 0, total_subsongs, target_subsong = sf->stream_index;
|
||||
int channels = 0, idx, interleave, loop_flag, sample_rate = 0, total_subsongs, target_subsong = sf->stream_index;
|
||||
read_u32_t read_u32;
|
||||
off_t chunk_offset, header_offset, stream_offset = 0;
|
||||
size_t chunk_size, header_size, stream_size = 0;
|
||||
off_t chunk_offset, header_offset, misc_data_offset = 0, stream_name_offset, stream_offset = 0;
|
||||
size_t chunk_size, header_size, misc_data_size, stream_size = 0;
|
||||
uint32_t codec_uuid = 0;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (read_u32le(0x00, sf) != 0x809) /* File ID */
|
||||
goto fail;
|
||||
|
||||
/* Burnout 2: Point of Impact (PS2, GCN, Xbox):
|
||||
* Predecessor to the common 0x80D-0x80F tag rws.c (which is also used in B2)
|
||||
* with some parts of it later reworked into awd.c seemingly */
|
||||
/* Burnout 2: Point of Impact (PS2, GCN, Xbox), Neighbours from Hell (GCN, Xbox):
|
||||
* Predecessor to the common 0x80D-0x80F tag RWS with some parts reworked into AWD? */
|
||||
if (!check_extensions(sf, "rws"))
|
||||
goto fail;
|
||||
|
||||
/* Uses various chunk IDs across the file:
|
||||
/* Uses the following chunk IDs across the file:
|
||||
* 0x00000809: File ID
|
||||
* 0x0000080A: File header ID
|
||||
* 0x0000080C: File data ID
|
||||
@ -63,19 +63,27 @@ VGMSTREAM* init_vgmstream_rws_mono(STREAMFILE* sf) {
|
||||
header_offset = chunk_offset + 0x0C;
|
||||
if (read_u32le(header_offset, sf) != 0x803) /* Stream header ID */
|
||||
goto fail;
|
||||
header_size = read_u32le(header_offset + 0x04, sf); /* usually 0xA0 */
|
||||
header_size = read_u32le(header_offset + 0x04, sf);
|
||||
|
||||
sample_rate = read_u32(header_offset + 0x10, sf);
|
||||
stream_size = read_u32(header_offset + 0x18, sf);
|
||||
bit_depth = read_u8(header_offset + 0x1C, sf);
|
||||
//bit_depth = read_u8(header_offset + 0x1C, sf);
|
||||
channels = read_u8(header_offset + 0x1D, sf); /* always 1? */
|
||||
if (channels != 1)
|
||||
goto fail;
|
||||
|
||||
/* Assumed misc data offs/size at header_offset + 0x20 to +0x24
|
||||
* which is always empty since GCN uses PCM S16BE encoding here */
|
||||
//misc_data_offset = read_u32(header_offset + 0x20, sf); /* assumed, but wrong? */
|
||||
misc_data_offset = header_offset + 0x3C;
|
||||
misc_data_size = read_u32(header_offset + 0x24, sf); /* 0x60 in GCN if DSP-ADPCM, otherwise 0 */
|
||||
|
||||
read_string(stream_name, STREAM_NAME_SIZE, header_offset + 0x7C, sf);
|
||||
codec_uuid = read_u32(header_offset + 0x2C, sf);
|
||||
|
||||
/* (header_offset + 0x3C + misc_data_size) + 0x00 to +0x18 has the target format
|
||||
* info which in most cases would probably be identical to the input format info */
|
||||
|
||||
/* (misc_data_size * 2) should be 0xC0 if it exists */
|
||||
stream_name_offset = header_offset + 0x7C + (misc_data_size * 2);
|
||||
read_string(stream_name, STREAM_NAME_SIZE, stream_name_offset, sf);
|
||||
|
||||
stream_offset = header_offset + header_size + 0x0C;
|
||||
if (read_u32le(stream_offset, sf) != 0x804) /* Stream data ID */
|
||||
@ -104,19 +112,27 @@ VGMSTREAM* init_vgmstream_rws_mono(STREAMFILE* sf) {
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
|
||||
/* Likely unreliable, but currently only can be tested with Burnout 2 */
|
||||
switch (bit_depth) {
|
||||
case 4: /* PS-ADPCM, normally DSP-ADPCM would be 4 too (as is in awd.c) but GCN uses PCM */
|
||||
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
break;
|
||||
|
||||
case 16: /* PCM Signed 16-bit */
|
||||
/* Seems to be the same as in rws_80d.c, maybe merge the two switches into one function? */
|
||||
switch (codec_uuid) {
|
||||
case 0xD01BD217: /* {D01BD217-3587-4EED-B9D9-B8E86EA9B995}: PCM Signed 16-bit */
|
||||
vgmstream->num_samples = pcm16_bytes_to_samples(stream_size, channels);
|
||||
vgmstream->coding_type = big_endian ? coding_PCM16BE : coding_PCM16LE;
|
||||
break;
|
||||
|
||||
case 0xD9EA9798: /* {D9EA9798-BBBC-447B-96B2-654759102E16}: PSX-ADPCM */
|
||||
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
break;
|
||||
|
||||
case 0xF86215B0: /* {F86215B0-31D5-4C29-BD37-CDBF9BD10C53}: DSP-ADPCM */
|
||||
vgmstream->num_samples = dsp_bytes_to_samples(stream_size, channels);
|
||||
dsp_read_coefs_be(vgmstream, sf, misc_data_offset + 0x1C, 0);
|
||||
dsp_read_hist_be(vgmstream, sf, misc_data_offset + 0x40, 0);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
break;
|
||||
|
||||
default:
|
||||
VGM_LOG("RWS: unknown codec 0x%08x\n", codec_uuid);
|
||||
goto fail;
|
||||
}
|
||||
|
@ -521,8 +521,8 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
||||
init_vgmstream_s_p_sth,
|
||||
init_vgmstream_utf_ahx,
|
||||
init_vgmstream_ego_dic,
|
||||
init_vgmstream_rws_mono,
|
||||
init_vgmstream_awd,
|
||||
init_vgmstream_rws_809,
|
||||
init_vgmstream_pwb,
|
||||
|
||||
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user