Merge pull request #1139 from bnnm/log-kt

log kt
This commit is contained in:
bnnm 2022-05-13 21:55:23 +02:00 committed by GitHub
commit 968349fa1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 173 additions and 34 deletions

View File

@ -579,7 +579,7 @@ Console location and format depends on plugin:
- *Audacious*: start with `audacious -V` from terminal
- CLI utils: printed to stdout directly
Only a few errors are printed ATM but may be helpful for more common cases.
Only a few errors types are printed but may be helpful for more common cases.
## Tagging
Some of vgmstream's plugins support simple read-only tagging via external files.

View File

@ -119,7 +119,7 @@ static const char* extension_list[] = {
"brstm",
"brstmspm",
"brwav",
"brwsd",
"brwsd", //fake extension for RWSD (non-format)
"bsnd",
"btsnd",
"bvg",
@ -1225,7 +1225,8 @@ static const meta_info meta_info_list[] = {
{meta_HCA, "CRI HCA header"},
{meta_SVAG_SNK, "SNK SVAG header"},
{meta_PS2_VDS_VDM, "Procyon Studio VDS/VDM header"},
{meta_FFMPEG, "FFmpeg supported file format"},
{meta_FFMPEG, "FFmpeg supported format"},
{meta_FFMPEG_faulty, "FFmpeg supported format (check log)"},
{meta_X360_CXS, "tri-Crescendo CXS header"},
{meta_AKB, "Square-Enix AKB header"},
{meta_X360_PASX, "Premium Agency PASX header"},

View File

@ -203,6 +203,7 @@
<ClCompile Include="meta\bcstm.c" />
<ClCompile Include="meta\bfstm.c" />
<ClCompile Include="meta\bfwav.c" />
<ClCompile Include="meta\bw_mp3_riff.c" />
<ClCompile Include="meta\bwav.c" />
<ClCompile Include="meta\esf.c" />
<ClCompile Include="meta\excitebots.c" />

View File

@ -1948,6 +1948,9 @@
<ClCompile Include="meta\bwav.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\bw_mp3_riff.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\rad.c">
<Filter>meta\Source Files</Filter>
</ClCompile>

View File

@ -16,6 +16,7 @@ typedef struct {
int segment_count;
int layer_count;
int force_disable_loop;
} aix_header_t;
static VGMSTREAM* build_segmented_vgmstream(STREAMFILE* sf, aix_header_t* aix);
@ -74,13 +75,14 @@ VGMSTREAM* init_vgmstream_aix(STREAMFILE* sf) {
goto fail;
/* Metroid: Other M (Wii)'s bgm_m_stage_06_02 is truncated on disc, seemingly not an extraction error.
* Playing expected samples aligns to bgm_m_stage_06, so not sure how the game would actually play it,
* tweaking samples to max size sounds a bit abrupt. */
* Playing expected samples aligns to bgm_m_stage_06, but from tests seems the song stops once reaching
* the missing audio (doesn't loop). */
if (aix.segment_count == 3 && aix.segment_offsets[1] + aix.segment_sizes[1] > get_streamfile_size(sf)) {
aix.segment_count = 2;
aix.segment_sizes[1] = get_streamfile_size(sf) - aix.segment_offsets[1];
//aix.segment_samples[1] = 0;
aix.force_disable_loop = 1; /* force */
vgm_logi("AIX: missing data, parts will be silent\n");
}
}
@ -209,7 +211,7 @@ static VGMSTREAM* build_segmented_vgmstream(STREAMFILE* sf, aix_header_t* aix) {
if (!setup_layout_segmented(data))
goto fail;
/* known loop cases:
/* known loop cases (no info on header, controlled by game?):
* - 1 segment: main/no loop [Hatsune Miku: Project Diva (PSP)]
* - 2 segments: intro + loop [SoulCalibur IV (PS3)]
* - 3 segments: intro + loop + end [Dragon Ball Z: Burst Limit (PS3), Metroid: Other M (Wii)]
@ -218,6 +220,8 @@ static VGMSTREAM* build_segmented_vgmstream(STREAMFILE* sf, aix_header_t* aix) {
loop_flag = (aix->segment_count > 0 && aix->segment_count <= 5);
loop_start_segment = (aix->segment_count > 3) ? 2 : 1;
loop_end_segment = (aix->segment_count > 3) ? (aix->segment_count - 2) : 1;
if (aix->force_disable_loop)
loop_flag = 0;
/* build the segmented VGMSTREAM */
vgmstream = allocate_segmented_vgmstream(data, loop_flag, loop_start_segment, loop_end_segment);

View File

@ -7,7 +7,7 @@ VGMSTREAM* init_vgmstream_atsl(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
int total_subsongs, target_subsong = sf->stream_index;
int type, big_endian = 0, entries;
int type, version, big_endian = 0, entries;
uint32_t subfile_offset = 0, subfile_size = 0, header_size, entry_size;
init_vgmstream_t init_vgmstream = NULL;
@ -42,12 +42,14 @@ VGMSTREAM* init_vgmstream_atsl(STREAMFILE* sf) {
* - 01000000 01010501 .atsl from Nioh (PC)[KOVS] 2017-11
* - 01000000 00010501 .atsl from Nioh (PC)[KOVS] 2017-11
* - 000B0301 00080601 .atsl in G1l from Sengoku Musou Sanada Maru (Switch)[KTSS] 2017-09
* - 03070301 01060301 .atsl from Nioh (PS4)[ATRAC9]
* - 00090301 01060501 .atsl from Nioh (PS4)[ATRAC9]-bigger header
* - 010C0301 01060601 .atsl from Dynasty Warriors 9 (PS4)[KTAC]
* - 010D0301 01010601 .atsl from Dynasty Warriors 9 DLC (PC)[KOVS]
*/
type = read_u16le(0x0c, sf);
//version = read_u16le(0x0e, sf);
version = read_u16le(0x0e, sf);
switch(type) {
case 0x0100: /* KOVS */
init_vgmstream = init_vgmstream_ogg_vorbis;
@ -71,10 +73,17 @@ VGMSTREAM* init_vgmstream_atsl(STREAMFILE* sf) {
fake_ext = "at9";
entry_size = 0x28;
break;
case 0x0601: /* KTAC */
init_vgmstream = init_vgmstream_ktac;
fake_ext = "ktac";
entry_size = 0x3c;
case 0x0601: /* KTAC / ATRAC9 */
if (version == 0x0103 || version == 0x0105) {
init_vgmstream = init_vgmstream_riff;
fake_ext = "at9";
entry_size = 0x3c;
}
else {
init_vgmstream = init_vgmstream_ktac;
fake_ext = "ktac";
entry_size = 0x3c;
}
break;
case 0x0800: /* KTSS */
init_vgmstream = init_vgmstream_ktss;

75
src/meta/bw_mp3_riff.c Normal file
View File

@ -0,0 +1,75 @@
#include "meta.h"
#include "../coding/coding.h"
/* Bioware pseudo-format (for sfx) [Star Wars: Knights of the Old Republic 1/2 (PC/Switch/iOS)] */
VGMSTREAM* init_vgmstream_bw_mp3_riff(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
uint32_t subfile_offset = 0, subfile_size = 0;
/* checks */
if (read_u32be(0x00, sf) != 0xFFF360C4)
goto fail;
//if ((read_u32be(0x00, sf) & 0xFFF00000) != 0xFFF00000) /* no point to check other mp3s */
// goto fail;
if (!is_id32be(0x0d, sf, "LAME") && !is_id32be(0x1d6, sf, "RIFF"))
goto fail;
/* strange mix of micro empty MP3 (LAME3.93, common header) + standard RIFF */
subfile_offset = 0x1d6;
subfile_size = read_u32le(subfile_offset + 0x04, sf) + 0x08;
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "wav");
if (!temp_sf) goto fail;
/* init the VGMSTREAM */
vgmstream = init_vgmstream_riff(temp_sf);
if (!vgmstream) goto fail;
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}
/* Bioware pseudo-format (for music) [Star Wars: Knights of the Old Republic 1/2 (PC/Switch/iOS)] */
VGMSTREAM* init_vgmstream_bw_riff_mp3(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
uint32_t subfile_offset = 0, subfile_size = 0;
/* checks */
if (!is_id32be(0x00, sf, "RIFF"))
goto fail;
if (read_u32le(0x04, sf) != 0x32)
goto fail;
if (get_streamfile_size(sf) <= 0x32 + 0x08) /* ? */
goto fail;
/* strange mix of micro RIFF (with codec 0x01, "fact" and "data" size 0)) + standard MP3 (sometimes with ID3) */
subfile_offset = 0x3A;
subfile_size = get_streamfile_size(sf) - subfile_offset;
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "mp3");
if (!temp_sf) goto fail;
/* init the VGMSTREAM */
vgmstream = init_vgmstream_mpeg(temp_sf);
if (!vgmstream) goto fail;
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -7,7 +7,6 @@ static int read_pos_file(uint8_t* buf, size_t bufsize, STREAMFILE* sf);
static int find_meta_loops(ffmpeg_codec_data* data, int32_t* p_loop_start, int32_t* p_loop_end);
/* parses any format supported by FFmpeg and not handled elsewhere:
* - MP3 (.mp3, .mus): Marc Ecko's Getting Up (PC)
* - MPC (.mpc, mp+): Moonshine Runners (PC), Asphalt 7 (PC)
* - FLAC (.flac): Warcraft 3 Reforged (PC), Call of Duty: Ghosts (PC)
* - DUCK (.wav): Sonic Jam (SAT), Virtua Fighter 2 (SAT)
@ -26,6 +25,7 @@ VGMSTREAM* init_vgmstream_ffmpeg(STREAMFILE* sf) {
int loop_flag = 0, channels, sample_rate;
int32_t loop_start = 0, loop_end = 0, num_samples = 0, encoder_delay = 0;
int total_subsongs, target_subsong = sf->stream_index;
int faulty = 0; /* mark wonky rips in hopes people may fix them */
/* no checks */
//if (!check_extensions(sf, "..."))
@ -102,6 +102,21 @@ VGMSTREAM* init_vgmstream_ffmpeg(STREAMFILE* sf) {
ffmpeg_set_skip_samples(data, encoder_delay);
}
/* detect broken RIFFs */
if (is_id32be(0x00, sf, "RIFF")) {
uint32_t size = read_u32le(0x04, sf);
/* There is a log in RIFF too but to be extra sure and sometimes FFmpeg don't handle it (this is mainly for wrong AT3).
* Some proper RIFF can be parsed here too (like DUCK). */
if (size + 0x08 > get_streamfile_size(sf)) {
vgm_logi("RIFF/FFmpeg: incorrect size, file may have missing data\n");
faulty = 1;
}
else if (size + 0x08 < get_streamfile_size(sf)) {
vgm_logi("RIFF/FFmpeg: incorrect size, file may have padded data\n");
faulty = 1;
}
}
/* default but often inaccurate when calculated using bitrate (wrong for VBR) */
if (!num_samples) {
num_samples = ffmpeg_get_samples(data); /* may be 0 if FFmpeg can't precalculate it */
@ -115,7 +130,7 @@ VGMSTREAM* init_vgmstream_ffmpeg(STREAMFILE* sf) {
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_FFMPEG;
vgmstream->meta_type = faulty ? meta_FFMPEG_faulty : meta_FFMPEG;
vgmstream->sample_rate = sample_rate;
vgmstream->codec_data = data;

View File

@ -2,7 +2,7 @@
#include "../coding/coding.h"
#include "../layout/layout.h"
typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, KVS, /*KNS*/ } ktsr_codec;
typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, RIFF_ATRAC9, KOVS, /*KNS*/ } ktsr_codec;
#define MAX_CHANNELS 8
@ -126,8 +126,28 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) {
}
#endif
case RIFF_ATRAC9: {
VGMSTREAM* riff_vgmstream = NULL; //TODO: meh
STREAMFILE* temp_sf = setup_subfile_streamfile(sf_b, ktsr.stream_offsets[0], ktsr.stream_sizes[0], "at9");
if (!temp_sf) goto fail;
riff_vgmstream = init_vgmstream_riff(temp_sf);
close_streamfile(temp_sf);
if (!riff_vgmstream) goto fail;
riff_vgmstream->stream_size = vgmstream->stream_size;
riff_vgmstream->num_streams = vgmstream->num_streams;
riff_vgmstream->channel_layout = vgmstream->channel_layout;
strcpy(riff_vgmstream->stream_name, vgmstream->stream_name);
close_vgmstream(vgmstream);
if (sf_b != sf) close_streamfile(sf_b);
return riff_vgmstream;
}
#ifdef VGM_USE_VORBIS
case KVS: {
case KOVS: {
VGMSTREAM* ogg_vgmstream = NULL; //TODO: meh
STREAMFILE* temp_sf = setup_subfile_streamfile(sf_b, ktsr.stream_offsets[0], ktsr.stream_sizes[0], "kvs");
if (!temp_sf) goto fail;
@ -234,18 +254,28 @@ static int parse_codec(ktsr_header* ktsr) {
/* platform + format to codec, simplified until more codec combos are found */
switch(ktsr->platform) {
case 0x01: /* PC */
if (ktsr->is_external)
ktsr->codec = KVS;
else if (ktsr->format == 0x00)
if (ktsr->is_external) {
if (ktsr->format == 0x0005)
ktsr->codec = KOVS;
else
goto fail;
}
else if (ktsr->format == 0x0000) {
ktsr->codec = MSADPCM;
else
}
else {
goto fail;
}
break;
case 0x03: /* VITA */
if (ktsr->is_external)
goto fail;
else if (ktsr->format == 0x01)
case 0x03: /* PS4/VITA */
if (ktsr->is_external) {
if (ktsr->format == 0x1001)
ktsr->codec = RIFF_ATRAC9;
else
goto fail;
}
else if (ktsr->format == 0x0001)
ktsr->codec = ATRAC9;
else
goto fail;
@ -254,7 +284,7 @@ static int parse_codec(ktsr_header* ktsr) {
case 0x04: /* Switch */
if (ktsr->is_external)
goto fail; /* KTSS? */
else if (ktsr->format == 0x00)
else if (ktsr->format == 0x0000)
ktsr->codec = DSP;
else
goto fail;
@ -281,14 +311,14 @@ static int parse_ktsr_subfile(ktsr_header* ktsr, STREAMFILE* sf, uint32_t offset
/* probably could check the flag in sound header, but the format is kinda messy */
switch(type) {
case 0x38D0437D: /* external [Nioh (PC), Atelier Ryza (PC)] */
case 0x3DEA478D: /* external [Nioh (PC)] */
case 0x38D0437D: /* external [Nioh (PC/PS4), Atelier Ryza (PC)] */
case 0x3DEA478D: /* external [Nioh (PC)] (smaller) */
case 0xDF92529F: /* external [Atelier Ryza (PC)] */
case 0x6422007C: /* external [Atelier Ryza (PC)] */
/* 08 subtype? (ex. 0x522B86B9)
* 0c channels
* 10 ? (always 0x002706B8)
* 14 codec? (05=KVS)
* 14 external codec
* 18 sample rate
* 1c num samples
* 20 null?
@ -317,11 +347,6 @@ static int parse_ktsr_subfile(ktsr_header* ktsr, STREAMFILE* sf, uint32_t offset
}
ktsr->is_external = 1;
if (ktsr->format != 0x05) {
VGM_LOG("ktsr: unknown subcodec at %x\n", offset);
goto fail;
}
break;
case 0x41FDBD4E: /* internal [Attack on Titan: Wings of Freedom (Vita)] */

View File

@ -988,4 +988,7 @@ VGMSTREAM* init_vgmstream_adm3(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_tt_ad(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_bw_mp3_riff(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_bw_riff_mp3(STREAMFILE* sf);
#endif /*_META_H*/

View File

@ -524,6 +524,8 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
init_vgmstream_esf,
init_vgmstream_adm3,
init_vgmstream_tt_ad,
init_vgmstream_bw_mp3_riff,
init_vgmstream_bw_riff_mp3,
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
init_vgmstream_mpeg,

View File

@ -587,7 +587,8 @@ typedef enum {
meta_HCA, /* CRI HCA */
meta_SVAG_SNK,
meta_PS2_VDS_VDM, /* Graffiti Kingdom */
meta_FFMPEG, /* any file supported by FFmpeg */
meta_FFMPEG,
meta_FFMPEG_faulty,
meta_X360_CXS, /* Eternal Sonata (Xbox 360) */
meta_AKB, /* SQEX iOS */
meta_X360_PASX, /* Namco PASX (Soul Calibur II HD X360) */