If you have an issue with any of our projects. feel free to register.

Commit bf95a58c authored by Christopher Snowhill's avatar Christopher Snowhill

Updated VGMStream to r1050-2930-g9a1b37d2

parent f5c7c4d4
......@@ -498,6 +498,7 @@
837CEB0423487F2C00E62A4A /* jstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAEF23487F2C00E62A4A /* jstm.c */; };
837CEB0523487F2C00E62A4A /* sqex_sead_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 837CEAF023487F2C00E62A4A /* sqex_sead_streamfile.h */; };
837CEB072348809400E62A4A /* seb.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEB062348809400E62A4A /* seb.c */; };
8385D4E6245174C700FF8E67 /* diva.c in Sources */ = {isa = PBXBuildFile; fileRef = 8385D4E2245174C600FF8E67 /* diva.c */; };
838BDB641D3AF08C0022CA6F /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB611D3AF08C0022CA6F /* libavcodec.a */; };
838BDB651D3AF08C0022CA6F /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB621D3AF08C0022CA6F /* libavformat.a */; };
838BDB661D3AF08C0022CA6F /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB631D3AF08C0022CA6F /* libavutil.a */; };
......@@ -1201,6 +1202,7 @@
837CEAEF23487F2C00E62A4A /* jstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jstm.c; sourceTree = "<group>"; };
837CEAF023487F2C00E62A4A /* sqex_sead_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqex_sead_streamfile.h; sourceTree = "<group>"; };
837CEB062348809400E62A4A /* seb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = seb.c; sourceTree = "<group>"; };
8385D4E2245174C600FF8E67 /* diva.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = diva.c; sourceTree = "<group>"; };
838BDB611D3AF08C0022CA6F /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = ../../ThirdParty/ffmpeg/lib/libavcodec.a; sourceTree = "<group>"; };
838BDB621D3AF08C0022CA6F /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavformat.a; path = ../../ThirdParty/ffmpeg/lib/libavformat.a; sourceTree = "<group>"; };
838BDB631D3AF08C0022CA6F /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = ../../ThirdParty/ffmpeg/lib/libavutil.a; sourceTree = "<group>"; };
......@@ -1664,6 +1666,7 @@
8373341E23F60CDB00DE14DC /* deblock_streamfile.h */,
8349A8EE1FE6257C00E26435 /* dec.c */,
834FE0CD215C79E8000A5D3D /* derf.c */,
8385D4E2245174C600FF8E67 /* diva.c */,
836F6E4318BDC2180095E648 /* dmsg_segh.c */,
8351F32C2212B57000A606E4 /* dsf.c */,
83299FCF1E7660C7003A3242 /* dsp_adx.c */,
......@@ -2663,6 +2666,7 @@
8306B0B220984552000302D4 /* blocked_mxch.c in Sources */,
837CEAFA23487F2C00E62A4A /* xa_04sw.c in Sources */,
836F6F8618BDC2190095E648 /* excitebots.c in Sources */,
8385D4E6245174C700FF8E67 /* diva.c in Sources */,
836F6FF418BDC2190095E648 /* rws.c in Sources */,
834FE100215C79ED000A5D3D /* svg.c in Sources */,
836F6F2518BDC2190095E648 /* g721_decoder.c in Sources */,
......
......@@ -19,7 +19,7 @@
* read num_bits (up to 25) from a bit offset.
* 25 since we read a 32 bit int, and need to adjust up to 7 bits from the byte-rounded fseek (32-7=25)
*/
static uint32_t read_bitsBE_b(off_t bit_offset, int num_bits, STREAMFILE *streamFile) {
static uint32_t read_bitsBE_b(int64_t bit_offset, int num_bits, STREAMFILE *streamFile) {
uint32_t num, mask;
if (num_bits > 25) return -1; //???
......@@ -400,7 +400,7 @@ fail:
/* XMA PARSING */
/* ******************************************** */
static void ms_audio_parse_header(STREAMFILE *streamFile, int xma_version, off_t offset_b, int bits_frame_size, size_t *first_frame_b, size_t *packet_skip_count, size_t *header_size_b) {
static void ms_audio_parse_header(STREAMFILE *streamFile, int xma_version, int64_t offset_b, int bits_frame_size, size_t *first_frame_b, size_t *packet_skip_count, size_t *header_size_b) {
if (xma_version == 1) { /* XMA1 */
//packet_sequence = read_bitsBE_b(offset_b+0, 4, streamFile); /* numbered from 0 to N */
//unknown = read_bitsBE_b(offset_b+4, 2, streamFile); /* packet_metadata? (always 2) */
......@@ -431,11 +431,11 @@ static void ms_audio_parse_header(STREAMFILE *streamFile, int xma_version, off_t
/* full packet skip, no new frames start in this packet (prev frames can end here)
* standardized to some value */
if (*packet_skip_count == 0x7FF) { /* XMA1, 11b */
VGM_LOG("MS_SAMPLES: XMA1 full packet_skip at 0x%x\n", (uint32_t)offset_b/8);
VGM_LOG("MS_SAMPLES: XMA1 full packet_skip\n");// at %"PRIx64"\n", offset_b/8);
*packet_skip_count = 0x800;
}
else if (*packet_skip_count == 0xFF) { /* XMA2, 8b*/
VGM_LOG("MS_SAMPLES: XMA2 full packet_skip at 0x%x\n", (uint32_t)offset_b/8);
VGM_LOG("MS_SAMPLES: XMA2 full packet_skip\n");// at %"PRIx64"\n", offset_b/8);
*packet_skip_count = 0x800;
}
......@@ -458,7 +458,7 @@ static void ms_audio_get_samples(ms_sample_data * msd, STREAMFILE *streamFile, i
int frames = 0, samples = 0, loop_start_frame = 0, loop_end_frame = 0;
size_t first_frame_b, packet_skip_count, header_size_b, frame_size_b;
off_t offset_b, packet_offset_b, frame_offset_b;
int64_t offset_b, packet_offset_b, frame_offset_b;
size_t packet_size = bytes_per_packet;
size_t packet_size_b = packet_size * 8;
......@@ -535,11 +535,11 @@ static void ms_audio_get_skips(STREAMFILE *streamFile, int xma_version, off_t da
int start_skip = 0, end_skip = 0;
size_t first_frame_b, packet_skip_count, header_size_b, frame_size_b;
off_t offset_b, packet_offset_b, frame_offset_b;
int64_t offset_b, packet_offset_b, frame_offset_b;
size_t packet_size = bytes_per_packet;
size_t packet_size_b = packet_size * 8;
off_t offset = data_offset;
int64_t offset = data_offset;
/* read packet */
{
......
#include <math.h>
#include "coding.h"
/* Relic Codec decoder, a fairly simple mono-interleave DCT-based codec.
......@@ -291,11 +292,16 @@ static uint32_t read_ubits(uint8_t bits, uint32_t offset, uint8_t *buf) {
}
static int read_sbits(uint8_t bits, uint32_t offset, uint8_t *buf) {
uint32_t val = read_ubits(bits, offset, buf);
int outval;
if (val >> (bits - 1) == 1) { /* upper bit = sign */
uint32_t mask = (1 << (bits - 1)) - 1;
return -(val & mask);
outval = (int)(val & mask);
outval = -outval;
}
return val;
else {
outval = (int)val;
}
return outval;
}
static void init_dequantization(float* scales) {
......@@ -338,7 +344,7 @@ static void unpack_frame(uint8_t *buf, int buf_size, float *freq1, float *freq2,
if (cb_bits > 0 && ev_bits > 0) {
pos = 0;
for (i = 0; i < RELIC_CRITICAL_BAND_COUNT - 1; i++) {
if (bit_offset >= 8*buf_size)
if (bit_offset >= 8u*buf_size)
break;
move = read_ubits(cb_bits, bit_offset, buf);
......@@ -360,7 +366,7 @@ static void unpack_frame(uint8_t *buf, int buf_size, float *freq1, float *freq2,
/* read first part */
pos = 0;
for (i = 0; i < RELIC_MAX_FREQ; i++) {
if (bit_offset >= 8*buf_size)
if (bit_offset >= 8u*buf_size)
break;
move = read_ubits(ei_bits, bit_offset, buf);
......@@ -384,7 +390,7 @@ static void unpack_frame(uint8_t *buf, int buf_size, float *freq1, float *freq2,
else {
pos = 0;
for (i = 0; i < RELIC_MAX_FREQ; i++) {
if (bit_offset >= 8*buf_size)
if (bit_offset >= 8u*buf_size)
break;
move = read_ubits(ei_bits, bit_offset, buf);
......@@ -436,7 +442,7 @@ static void copy_samples(relic_codec_data* data, sample_t* outbuf, int32_t sampl
for (ch = 0; ch < ichs; ch++) {
for (s = 0; s < samples; s++) {
double d64_sample = data->wave_cur[ch][skip + s];
int pcm_sample = clamp16(d64_sample);
int pcm_sample = clamp16((int32_t)d64_sample);
/* f32 in PCM 32767.0 .. -32768.0 format, original code
* does some custom double-to-int rint() though */
......@@ -453,12 +459,12 @@ static relic_codec_data* init_codec(int channels, int bitrate, int codec_rate) {
if (channels > RELIC_MAX_CHANNELS)
goto fail;
data = calloc(1, sizeof(relic_codec_data));
if (!data) goto fail;
data->channels = channels;
/* dequantized freq1+2 size (separate from DCT) */
if (codec_rate < 22050) /* probably 11025 only */
data->freq_size = RELIC_SIZE_LOW;
......@@ -471,7 +477,7 @@ static relic_codec_data* init_codec(int channels, int bitrate, int codec_rate) {
data->wave_size = RELIC_SIZE_HIGH;
data->dct_mode = RELIC_SIZE_HIGH;
data->samples_mode = RELIC_SIZE_HIGH;
init_dct(data->dct, RELIC_SIZE_HIGH);
init_window(data->window, RELIC_SIZE_HIGH);
init_dequantization(data->scales);
......
......@@ -145,6 +145,7 @@ static const char* extension_list[] = {
"ddsp",
"de2",
"dec",
"diva",
"dmsg",
"ds2", //txth/reserved [Star Wars Bounty Hunter (GC)]
"dsf",
......@@ -1285,6 +1286,7 @@ static const meta_info meta_info_list[] = {
{meta_KWB, "Koei Tecmo WaveBank header"},
{meta_LRMD, "Sony LRMD header"},
{meta_WWISE_FX, "Audiokinetic Wwise FX header"},
{meta_DIVA, "DIVA header"},
};
......
......@@ -261,11 +261,11 @@ static int find_adx_key(STREAMFILE *sf, uint8_t type, uint16_t *xor_start, uint1
/* try to find key in external file first */
{
uint8_t keybuf[0x20+1] = {0}; /* +1 extra null for keystrings */
uint8_t keybuf[0x40+1] = {0}; /* known max ~0x30, +1 extra null for keystrings */
size_t key_size;
/* handle type8 keystrings, key9 keycodes and derived keys too */
key_size = read_key_file(keybuf,0x20, sf);
key_size = read_key_file(keybuf, sizeof(keybuf), sf);
if (key_size > 0) {
int i, is_ascii = 0;
......
......@@ -193,6 +193,9 @@ static const adxkey_info adxkey8_list[] = {
/* Katekyoo Hitman Reborn! Let's Ansatsu! Nerawareta 10-daime! (PS2) */
{0x5381,0x52E5,0x53E9, "REBHITMAN",0},
/* 428: Fuusasareta Shibuya de (PS3) */
{0x52ff,0x649f,0x448f, "hj1kviaqqdzUacryoacwmscfvwtlfkVbbbqpqmzqnbile2euljywazejgyxxvqlf",0},
};
static const adxkey_info adxkey9_list[] = {
......@@ -234,8 +237,8 @@ static const adxkey_info adxkey9_list[] = {
/* Detective Conan Runner / Case Closed Runner (Android) */
{0x0613,0x0e3d,0x6dff, NULL,1175268187653273344}, // 104f643098e3f700
/* Persona 5 Royal (PS4)*/
{0x0000,0x1c85,0x1043, NULL,29902882}, // guessed with VGAudio
/* Persona 5 Royal (PS4) */
{0x0000,0x1c85,0x7043, NULL,29915170}, // 0000000001C87822
};
......
......@@ -6,10 +6,10 @@
VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
off_t subfile_offset, didx_offset, data_offset, offset;
size_t subfile_size, didx_size;
uint32_t subfile_id;
int big_endian;
off_t subfile_offset, base_offset = 0;
size_t subfile_size;
uint32_t subfile_id, header_id;
int big_endian, version, is_dummy = 0;
uint32_t (*read_u32)(off_t,STREAMFILE*);
int total_subsongs, target_subsong = sf->stream_index;
......@@ -17,47 +17,116 @@ VGMSTREAM* init_vgmstream_bkhd(STREAMFILE* sf) {
/* checks */
if (!check_extensions(sf,"bnk"))
goto fail;
if (read_u32be(0x00, sf) != 0x424B4844) /* "BKHD" */
if (read_u32be(0x00, sf) == 0x414B424B) /* "AKBK" [Shadowrun (X360)] */
base_offset = 0x0c;
if (read_u32be(base_offset + 0x00, sf) != 0x424B4844) /* "BKHD" */
goto fail;
big_endian = guess_endianness32bit(0x04, sf);
big_endian = guess_endianness32bit(base_offset + 0x04, sf);
read_u32 = big_endian ? read_u32be : read_u32le;
/* Wwise banks have event/track/sequence/etc info in the HIRC chunk, as well
* as other chunks, and may have a DIDX index to memory .wem in DATA.
* as other chunks, and may have a DATA/DIDX index to memory .wem in DATA.
* We support the internal .wem mainly for quick tests, as the HIRC is
* complex and better handled with TXTP (some info from Nicknine's script) */
/* unlike RIFF first chunk follows chunk rules */
if (!find_chunk(sf, 0x44494458, 0x00,0, &didx_offset, &didx_size, big_endian, 0)) /* "DIDX" */
goto fail;
if (!find_chunk(sf, 0x44415441, 0x00,0, &data_offset, NULL, big_endian, 0)) /* "DATA" */
goto fail;
* complex and better handled with TXTP (some info from Nicknine's script).
* unlike RIFF, first chunk follows chunk rules */
total_subsongs = didx_size / 0x0c;
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
version = read_u32(base_offset + 0x08, sf);
if (version == 0 || version == 1) { /* early games */
version = read_u32(base_offset + 0x10, sf);
}
offset = didx_offset + (target_subsong - 1) * 0x0c;
subfile_id = read_u32(offset + 0x00, sf);
subfile_offset = read_u32(offset + 0x04, sf) + data_offset;
subfile_size = read_u32(offset + 0x08, sf);
if (version <= 26) {
off_t data_offset, data_start, offset;
if (!find_chunk(sf, 0x44415441, base_offset, 0, &data_offset, NULL, big_endian, 0)) /* "DATA" */
goto fail;
/* index:
* 00: entries
* 04: null
* 08: entries size
* 0c: padding size after entries
* 10: data size
* 14: size?
* 18: data start
* 1c: data size
* per entry:
* 00: always -1
* 04: always 0
* 08: index number or -1
* 0c: 5 or -1?
* 0c: 5 or -1?
* 0c: 5 or -1?
* 10: stream offset (from data start) or -1 if none
* 14: stream size or 0 if none
*/
total_subsongs = read_u32(data_offset + 0x00, sf);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
data_start = read_u32(data_offset + 0x18, sf);
offset = data_offset + 0x20 + (target_subsong - 1) * 0x18;
subfile_id = read_u32(offset + 0x08, sf);
subfile_offset = read_u32(offset + 0x10, sf) + data_offset + 0x20 + data_start;
subfile_size = read_u32(offset + 0x14, sf);
}
else {
off_t didx_offset, data_offset, offset;
size_t didx_size;
if (!find_chunk(sf, 0x44494458, 0x00,0, &didx_offset, &didx_size, big_endian, 0)) /* "DIDX" */
goto fail;
if (!find_chunk(sf, 0x44415441, 0x00,0, &data_offset, NULL, big_endian, 0)) /* "DATA" */
goto fail;
total_subsongs = didx_size / 0x0c;
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
offset = didx_offset + (target_subsong - 1) * 0x0c;
subfile_id = read_u32(offset + 0x00, sf);
subfile_offset = read_u32(offset + 0x04, sf) + data_offset;
subfile_size = read_u32(offset + 0x08, sf);
}
//;VGM_LOG("BKHD: %lx, %x\n", subfile_offset, subfile_size);
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "wem");
if (!temp_sf) goto fail;
/* some indexes don't have that, but for now leave a dummy song for easier HIRC mapping */
if (subfile_offset <= 0 || subfile_size <= 0) {
//;VGM_LOG("BKHD: dummy entry");
temp_sf = setup_subfile_streamfile(sf, 0x00, 0x10, "raw");
if (!temp_sf) goto fail;
subfile_id = read_u32(0x00, temp_sf);
if (subfile_id == 0x52494646 || subfile_id == 0x52494658) { /* "RIFF" / "RIFX" */
vgmstream = init_vgmstream_wwise(temp_sf);
//todo make some better silent entry
vgmstream = init_vgmstream_raw_pcm(temp_sf);
if (!vgmstream) goto fail;
is_dummy = 1;
}
else {
vgmstream = init_vgmstream_bkhd_fx(temp_sf);
if (!vgmstream) goto fail;
//;VGM_LOG("BKHD: %lx, %x\n", subfile_offset, subfile_size);
/* could pass .wem but few files need memory .wem detection */
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, NULL);
if (!temp_sf) goto fail;
header_id = read_u32be(0x00, temp_sf);
if (header_id == 0x52494646 || header_id == 0x52494658) { /* "RIFF" / "RIFX" */
vgmstream = init_vgmstream_wwise(temp_sf);
if (!vgmstream) goto fail;
}
else {
vgmstream = init_vgmstream_bkhd_fx(temp_sf);
if (!vgmstream) goto fail;
}
}
vgmstream->num_streams = total_subsongs;
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%u", subfile_id);
if (is_dummy)
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%s", "dummy");
else if (subfile_id != 0xFFFFFFFF)
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%u", subfile_id);
close_streamfile(temp_sf);
return vgmstream;
......@@ -69,7 +138,7 @@ fail:
}
/* BKHD mini format, probably from a generator plugin [Borderlands 2 (X360)] */
/* BKHD mini format, probably from a FX generator plugin [Borderlands 2 (X360)] */
VGMSTREAM* init_vgmstream_bkhd_fx(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
off_t start_offset, data_size;
......@@ -93,8 +162,7 @@ VGMSTREAM* init_vgmstream_bkhd_fx(STREAMFILE* sf) {
/* 0x14/18: some float? */
entries = read_u32(0x1c, sf);
/* 0x20 data size / 0x10 */
if (read_u8(0x24, sf) != 4) /* bps */
goto fail;
/* 0x24 usually 4, sometimes higher values? */
/* 0x30: unknown table of 16b that goes up and down */
start_offset = 0x30 + align_size_to_block(entries * 0x02, 0x10);
......
#include "meta.h"
#include "../coding/coding.h"
/* DIVA - Hatsune Miku: Project DIVA Arcade */
VGMSTREAM * init_vgmstream_diva(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int channel_count;
int loop_end;
int loop_flag;
/* checks */
if (!check_extensions(streamFile, "diva"))
goto fail;
if (read_32bitBE(0x00, streamFile) != 0x44495641) /* "DIVA" */
goto fail;
start_offset = 0x40;
channel_count = read_8bit(0x1C, streamFile);
loop_end = read_32bitLE(0x18, streamFile);
loop_flag = (loop_end != 0);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(0x0C, streamFile);
vgmstream->num_samples = read_32bitLE(0x10, streamFile);
vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile);
vgmstream->loop_end_sample = loop_end;
vgmstream->meta_type = meta_DIVA;
vgmstream->layout_type = layout_none;
vgmstream->coding_type = coding_DVI_IMA;
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}
\ No newline at end of file
......@@ -454,6 +454,12 @@ static int parse_genh(STREAMFILE * streamFile, genh_header * genh) {
genh->num_samples = genh->num_samples > 0 ? genh->num_samples : genh->loop_end_sample;
genh->loop_flag = genh->loop_start_sample != -1;
/* fix for buggy GENHs that used to work before interleaved XBOX-IMA was added
* (could do check for other cases, but maybe it's better to give bad sound on nonsense values) */
if (genh->codec == XBOX && genh->interleave < 0x24) { /* found as 0x2 */
genh->interleave = 0;
}
return 1;
fail:
......
......@@ -6,7 +6,7 @@
#ifdef HCA_BRUTEFORCE
static void bruteforce_hca_key(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* out_keycode, uint16_t subkey);
#endif
static void find_hca_key(hca_codec_data * hca_data, unsigned long long * out_keycode, uint16_t subkey);
static void find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t subkey);
/* CRI HCA - streamed audio from CRI ADX2/Atom middleware */
......@@ -17,7 +17,6 @@ VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile) {
VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey) {
VGMSTREAM * vgmstream = NULL;
hca_codec_data * hca_data = NULL;
unsigned long long keycode = 0;
/* checks */
......@@ -32,6 +31,7 @@ VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey) {
/* find decryption key in external file or preloaded list */
if (hca_data->info.encryptionEnabled) {
uint64_t keycode = 0;
uint8_t keybuf[0x08+0x02];
size_t keysize;
......@@ -56,7 +56,7 @@ VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey) {
find_hca_key(hca_data, &keycode, subkey);
}
clHCA_SetKey(hca_data->handle, keycode); //maybe should be done through hca_decoder.c?
clHCA_SetKey(hca_data->handle, (unsigned long long)keycode); //maybe should be done through hca_decoder.c?
}
......@@ -139,25 +139,25 @@ static inline void test_key(hca_codec_data * hca_data, uint64_t key, uint16_t su
}
/* try to find the decryption key from a list. */
static void find_hca_key(hca_codec_data* hca_data, unsigned long long* out_keycode, uint16_t subkey) {
static void find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t subkey) {
const size_t keys_length = sizeof(hcakey_list) / sizeof(hcakey_info);
int best_score = -1;
int i,j;
*out_keycode = 0xCC55463930DBE1AB; /* defaults to PSO2 key, most common */
*p_keycode = 0xCC55463930DBE1AB; /* defaults to PSO2 key, most common */
for (i = 0; i < keys_length; i++) {
uint64_t key = hcakey_list[i].key;
size_t subkeys_size = hcakey_list[i].subkeys_size;
const uint16_t *subkeys = hcakey_list[i].subkeys;
test_key(hca_data, key, subkey, &best_score, out_keycode);
test_key(hca_data, key, subkey, &best_score, p_keycode);
if (best_score == 1)
goto done;
if (subkeys_size > 0 && subkey == 0) {
for (j = 0; j < subkeys_size; j++) {
test_key(hca_data, key, subkeys[j], &best_score, out_keycode);
test_key(hca_data, key, subkeys[j], &best_score, p_keycode);
if (best_score == 1)
goto done;
}
......@@ -166,7 +166,7 @@ static void find_hca_key(hca_codec_data* hca_data, unsigned long long* out_keyco
done:
VGM_ASSERT(best_score > 1, "HCA: best key=%08x%08x (score=%i)\n",
(uint32_t)((*out_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*out_keycode & 0xFFFFFFFF), best_score);
(uint32_t)((*p_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*p_keycode & 0xFFFFFFFF), best_score);
VGM_ASSERT(best_score < 0, "HCA: key not found\n");
}
......
......@@ -893,4 +893,6 @@ VGMSTREAM* init_vgmstream_bkhd_fx(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_encrypted(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_diva(STREAMFILE* sf);
#endif /*_META_H*/
#include "meta.h"
#include "../coding/coding.h"
typedef enum { IDSP, OPUS, } nus3audio_codec;
typedef enum { IDSP, OPUS, RIFF, } nus3audio_codec;
/* .nus3audio - Namco's newest newest audio container [Super Smash Bros. Ultimate (Switch)] */
VGMSTREAM * init_vgmstream_nus3audio(STREAMFILE *streamFile) {
VGMSTREAM *vgmstream = NULL;
STREAMFILE *temp_streamFile = NULL;
VGMSTREAM* init_vgmstream_nus3audio(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
off_t subfile_offset = 0, name_offset = 0;
size_t subfile_size = 0;
nus3audio_codec codec;
const char* fake_ext = NULL;
int total_subsongs, target_subsong = streamFile->stream_index;
int total_subsongs, target_subsong = sf->stream_index;
/* checks */
if (!check_extensions(streamFile, "nus3audio"))
if (!check_extensions(sf, "nus3audio"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x4E555333) /* "NUS3" */
if (read_u32be(0x00,sf) != 0x4E555333) /* "NUS3" */
goto fail;
if (read_32bitLE(0x04,streamFile) + 0x08 != get_streamfile_size(streamFile))
if (read_u32le(0x04,sf) + 0x08 != get_streamfile_size(sf))
goto fail;
if (read_32bitBE(0x08,streamFile) != 0x41554449) /* "AUDI" */
if (read_u32be(0x08,sf) != 0x41554449) /* "AUDI" */
goto fail;
/* parse existing chunks */
{
off_t offset = 0x0c;
size_t file_size = get_streamfile_size(streamFile);
size_t file_size = get_streamfile_size(sf);
uint32_t codec_id = 0;
total_subsongs = 0;
while (offset < file_size) {
uint32_t chunk_id = (uint32_t)read_32bitBE(offset+0x00, streamFile);
size_t chunk_size = (size_t)read_32bitLE(offset+0x04, streamFile);
uint32_t chunk_id = read_u32be(offset+0x00, sf);
size_t chunk_size = read_u32le(offset+0x04, sf);
switch(chunk_id) {
case 0x494E4458: /* "INDX": audio index */
total_subsongs = read_32bitLE(offset+0x08 + 0x00,streamFile);
total_subsongs = read_u32le(offset+0x08 + 0x00,sf);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
break;
case 0x4E4D4F46: /* "NMOF": name offsets (absolute, inside TNNM) */
name_offset = read_32bitLE(offset+0x08 + 0x04*(target_subsong-1),streamFile);
name_offset = read_u32le(offset+0x08 + 0x04*(target_subsong-1),sf);
break;
case 0x41444F46: /* "ADOF": audio offsets (absolute, inside PACK) */
subfile_offset = read_32bitLE(offset+0x08 + 0x08*(target_subsong-1) + 0x00,streamFile);
subfile_size = read_32bitLE(offset