Fix some Ubi CKD [Rayman Origins (3DS/Vita)]

This commit is contained in:
bnnm 2021-12-31 16:20:52 +01:00
parent 0f5b806792
commit 382b0d2929
7 changed files with 110 additions and 12 deletions

View File

@ -194,6 +194,9 @@
<ClInclude Include="meta\ubi_lyn_streamfile.h">
<Filter>meta\Header Files</Filter>
</ClInclude>
<ClInclude Include="meta\ubi_ckd_cwav_streamfile.h">
<Filter>meta\Header Files</Filter>
</ClInclude>
<ClInclude Include="meta\meta.h">
<Filter>meta\Header Files</Filter>
</ClInclude>
@ -1150,6 +1153,9 @@
<ClCompile Include="meta\ubi_ckd.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ubi_ckd_cwav.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ubi_hx.c">
<Filter>meta\Source Files</Filter>
</ClCompile>

View File

@ -971,4 +971,6 @@ VGMSTREAM* init_vgmstream_lpcm_fb(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_wbk(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_ubi_ckd_cwav(STREAMFILE* sf);
#endif /*_META_H*/

View File

@ -355,13 +355,14 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
* .rws: Climax ATRAC3 [Silent Hill Origins (PSP), Oblivion (PSP)]
* .aud: EA Replay ATRAC3
* .at9: standard ATRAC9
* .ckd: renamed ATRAC9 [Rayman Origins (Vita)]
* .saf: Whacked! (Xbox)
* .mwv: Level-5 games [Dragon Quest VIII (PS2), Rogue Galaxy (PS2)]
* .ima: Baja: Edge of Control (PS3/X360)
* .nsa: Studio Ring games that uses NScripter [Hajimete no Otetsudai (PC)]
* .pcm: Silent Hill Arcade (PC)
*/
if ( check_extensions(sf, "wav,lwav,xwav,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,saf,ima,nsa,pcm") ) {
if ( check_extensions(sf, "wav,lwav,xwav,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm") ) {
;
}
else if ( check_extensions(sf, "mwv") ) {
@ -590,6 +591,11 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
JunkFound = 1;
break;
case 0x64737068: /* "dsph" */
case 0x63776176: /* "cwav" */
goto fail; /* parse elsewhere */
default:
/* ignorance is bliss */
break;
@ -625,6 +631,10 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
read_u32be(start_offset+0x3c, sf) == 0xFFFFFFFF)
goto fail;
///* MSADPCM .ckd are parsed elsewhere, though they are valid so no big deal if parsed here (just that loops should be ignored) */
if (!fmt.is_at9 && check_extensions(sf, "ckd"))
goto fail;
/* ignore Gitaroo Man Live! (PSP) multi-RIFF (to allow chunked TXTH) */
if (fmt.is_at3 && get_streamfile_size(sf) > 0x2800 && read_32bitBE(0x2800, sf) == 0x52494646) { /* "RIFF" */
goto fail;

View File

@ -1,5 +1,6 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../coding/coding.h"
typedef enum { MSADPCM, DSP, MP3, XMA2 } ckd_codec;
@ -9,31 +10,36 @@ VGMSTREAM* init_vgmstream_ubi_ckd(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
off_t start_offset, first_offset = 0x0c, chunk_offset;
size_t chunk_size, data_size;
int loop_flag, channel_count, interleave = 0, format;
int loop_flag, channels, interleave = 0, format;
ckd_codec codec;
int big_endian;
uint32_t (*read_u32)(off_t,STREAMFILE*);
uint16_t (*read_u16)(off_t,STREAMFILE*);
/* checks */
if (!is_id32be(0x00,sf, "RIFF"))
goto fail;
if (!is_id32be(0x08,sf, "WAVE"))
goto fail;
/* .wav.ckd: main (other files are called .xxx.ckd too) */
if (!check_extensions(sf,"ckd"))
goto fail;
/* another slighly funny RIFF */
if (read_u32be(0x00,sf) != 0x52494646) /* "RIFF" */
/* another slighly funny RIFF, mostly standard except machine endian and minor oddities */
if (!is_id32be(0x0c,sf, "fmt "))
goto fail;
if (read_u32be(0x08,sf) != 0x57415645) /* "WAVE" */
goto fail;
/* RIFF size is normal */
big_endian = guess_endianness32bit(0x04, sf);
read_u32 = big_endian ? read_u32be : read_u32le;
read_u16 = big_endian ? read_u16be : read_u16le;
if (read_u32(0x04, sf) + 0x04 + 0x04 != get_streamfile_size(sf))
goto fail;
loop_flag = 0;
format = read_u16(0x14,sf);
channel_count = read_u16(0x16,sf);
channels = read_u16(0x16,sf);
switch(format) {
case 0x0002:
@ -50,7 +56,7 @@ VGMSTREAM* init_vgmstream_ubi_ckd(STREAMFILE* sf) {
} else if (find_chunk_be(sf, 0x6461744C,first_offset,0, &chunk_offset,&chunk_size)) { /* "datL" */
/* mono "datL" or full interleave with a "datR" after the "datL" (no check, pretend it exists) */
start_offset = chunk_offset;
data_size = chunk_size * channel_count;
data_size = chunk_size * channels;
interleave = (0x4+0x4) + chunk_size; /* don't forget to skip the "datR"+size chunk */
} else {
goto fail;
@ -107,11 +113,11 @@ VGMSTREAM* init_vgmstream_ubi_ckd(STREAMFILE* sf) {
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
vgmstream = allocate_vgmstream(channels,loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_u32(0x18,sf);
vgmstream->num_samples = dsp_bytes_to_samples(data_size, channel_count);
vgmstream->num_samples = dsp_bytes_to_samples(data_size, channels);
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->meta_type = meta_UBI_CKD;
@ -170,4 +176,3 @@ fail:
close_vgmstream(vgmstream);
return NULL;
}

37
src/meta/ubi_ckd_cwav.c Normal file
View File

@ -0,0 +1,37 @@
#include "meta.h"
#include "../coding/coding.h"
#include "ubi_ckd_cwav_streamfile.h"
/* CKD RIFF - UbiArt Framework (v1) audio container [Rayman Origins (3DS)] */
VGMSTREAM* init_vgmstream_ubi_ckd_cwav(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
/* checks */
if (!is_id32be(0x00,sf, "RIFF"))
goto fail;
if (!is_id32be(0x08,sf, "WAVE"))
goto fail;
if (!(is_id32be(0x0c,sf, "dsph") || is_id32be(0x0c,sf, "cwav")))
goto fail;
/* .wav: main (unlike .wav.cdk of other versions) */
if (!check_extensions(sf,"wav,lwav"))
goto fail;
/* inside dsph (header+start, optional) and cwav (body, always) RIFF chunks is a full "CWAV",
* since dsph also contains some data just deblock */
temp_sf = setup_ubi_ckd_cwav_streamfile(sf);
if (!temp_sf) goto fail;
vgmstream = init_vgmstream_rwsd(temp_sf);
if (!vgmstream) goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -0,0 +1,37 @@
#ifndef _UBI_CKD_CWAV_STREAMFILE_H_
#define _UBI_CKD_CWAV_STREAMFILE_H_
#include "deblock_streamfile.h"
static void block_callback(STREAMFILE *sf, deblock_io_data *data) {
uint32_t chunk_type = read_u32be(data->physical_offset + 0x00, sf);
uint32_t chunk_size = read_u32le(data->physical_offset + 0x04, sf);
if (chunk_type == get_id32be("RIFF")) {
data->data_size = 0x0;
data->skip_size = 0x0;
data->block_size = 0x0c;
}
else {
data->data_size = chunk_size;
data->skip_size = 0x08;
data->block_size = data->data_size + data->skip_size;
}
}
/* Deblocks CWAV streams inside RIFF */
static STREAMFILE* setup_ubi_ckd_cwav_streamfile(STREAMFILE* sf) {
STREAMFILE *new_sf = NULL;
deblock_config_t cfg = {0};
cfg.stream_start = 0x00;
cfg.stream_size = get_streamfile_size(sf);
cfg.block_callback = block_callback;
/* setup sf */
new_sf = open_wrap_streamfile(sf);
new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
new_sf = open_fakename_streamfile_f(new_sf, NULL, "bcwav");
return new_sf;
}
#endif /* _UBI_CKD_CWAV_STREAMFILE_H_ */

View File

@ -518,6 +518,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
init_vgmstream_wbk,
init_vgmstream_wbk_nslb,
init_vgmstream_dsp_apex,
init_vgmstream_ubi_ckd_cwav,
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
init_vgmstream_agsc,