From d5720e39446fc88005ce885dc05c2164f2464db0 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sat, 4 Feb 2023 23:45:54 -0800 Subject: [PATCH] Updated VGMStream to r1810-97-g408cada5 Signed-off-by: Christopher Snowhill --- .../libcelt_0061.xcodeproj/project.pbxproj | 156 ++--- .../libcelt_0110.xcodeproj/project.pbxproj | 156 ++--- .../libvgmstream.xcodeproj/project.pbxproj | 116 ++-- .../vgmstream/src/coding/at3plus_decoder.c | 82 --- .../vgmstream/src/coding/at3plus_decoder.h | 11 - .../vgmstream/src/coding/celt_fsb_decoder.c | 38 +- .../vgmstream/vgmstream/src/coding/coding.h | 45 +- .../vgmstream/src/coding/coding_utils.c | 398 +------------ .../vgmstream/src/coding/ffmpeg_decoder.c | 6 +- .../src/coding/ffmpeg_decoder_custom_opus.c | 26 +- .../src/coding/ffmpeg_decoder_utils.c | 550 +++++++++++++++--- .../vgmstream/src/coding/ice_decoder_icelib.h | 4 +- .../src/coding/mpeg_custom_utils_ahx.c | 260 ++++++--- .../src/coding/mpeg_custom_utils_ealayer3.c | 155 +++-- .../vgmstream/src/coding/mpeg_decoder.c | 3 + .../vgmstream/src/coding/ogg_vorbis_decoder.c | 3 + .../vgmstream/src/coding/pcm_decoder.c | 15 + .../vgmstream/src/coding/sdx2_decoder.c | 62 +- Frameworks/vgmstream/vgmstream/src/decode.c | 44 +- Frameworks/vgmstream/vgmstream/src/formats.c | 31 +- .../vgmstream/vgmstream/src/layout/blocked.c | 3 - .../vgmstream/src/layout/blocked_tra.c | 17 - .../vgmstream/vgmstream/src/layout/layout.h | 1 - .../src/meta/{ta_aac.c => aac_triace.c} | 24 +- Frameworks/vgmstream/vgmstream/src/meta/adx.c | 32 +- .../vgmstream/vgmstream/src/meta/adx_keys.h | 146 +---- Frameworks/vgmstream/vgmstream/src/meta/ahx.c | 123 ++-- .../vgmstream/vgmstream/src/meta/ahx_keys.h | 52 ++ Frameworks/vgmstream/vgmstream/src/meta/akb.c | 32 - .../vgmstream/vgmstream/src/meta/astb.c | 83 +++ Frameworks/vgmstream/vgmstream/src/meta/aus.c | 85 +-- Frameworks/vgmstream/vgmstream/src/meta/awc.c | 24 +- Frameworks/vgmstream/vgmstream/src/meta/baf.c | 61 +- .../vgmstream/vgmstream/src/meta/bfstm.c | 4 +- .../vgmstream/vgmstream/src/meta/bnk_sony.c | 19 +- .../vgmstream/vgmstream/src/meta/brstm.c | 203 +++---- Frameworks/vgmstream/vgmstream/src/meta/cps.c | 50 ++ Frameworks/vgmstream/vgmstream/src/meta/cxs.c | 56 ++ .../vgmstream/vgmstream/src/meta/ea_eaac.c | 17 +- .../vgmstream/vgmstream/src/meta/ea_swvr.c | 81 +-- .../src/meta/encrypted_mc161_streamfile.h | 4 +- Frameworks/vgmstream/vgmstream/src/meta/fsb.c | 16 +- .../vgmstream/vgmstream/src/meta/fsb5.c | 9 +- .../vgmstream/src/meta/fsb_encrypted.c | 83 +-- .../vgmstream/vgmstream/src/meta/fsb_keys.h | 207 ++----- Frameworks/vgmstream/vgmstream/src/meta/gca.c | 32 +- .../vgmstream/vgmstream/src/meta/genh.c | 98 ++-- Frameworks/vgmstream/vgmstream/src/meta/ghs.c | 163 ++++++ .../vgmstream/vgmstream/src/meta/gsp_gsb.c | 66 +-- Frameworks/vgmstream/vgmstream/src/meta/gtd.c | 136 ----- .../vgmstream/vgmstream/src/meta/hca_keys.h | 14 +- Frameworks/vgmstream/vgmstream/src/meta/his.c | 88 ++- .../vgmstream/vgmstream/src/meta/idtech.c | 36 +- Frameworks/vgmstream/vgmstream/src/meta/isb.c | 5 +- .../vgmstream/vgmstream/src/meta/ivaud.c | 6 +- .../vgmstream/vgmstream/src/meta/ktsr.c | 109 ++-- Frameworks/vgmstream/vgmstream/src/meta/kwb.c | 9 +- .../vgmstream/vgmstream/src/meta/meta.h | 29 +- Frameworks/vgmstream/vgmstream/src/meta/mul.c | 7 +- .../vgmstream/src/meta/ngc_dsp_std.c | 38 +- Frameworks/vgmstream/vgmstream/src/meta/nub.c | 10 +- .../vgmstream/vgmstream/src/meta/opus.c | 17 +- Frameworks/vgmstream/vgmstream/src/meta/p3d.c | 6 +- .../vgmstream/vgmstream/src/meta/pasx.c | 66 +++ .../vgmstream/vgmstream/src/meta/ps2_ccc.c | 68 --- .../vgmstream/vgmstream/src/meta/ps3_cps.c | 74 --- Frameworks/vgmstream/vgmstream/src/meta/psb.c | 8 +- .../vgmstream/vgmstream/src/meta/riff.c | 71 +-- Frameworks/vgmstream/vgmstream/src/meta/rsd.c | 45 +- .../vgmstream/vgmstream/src/meta/rwsd.c | 6 + .../vgmstream/vgmstream/src/meta/rxws.c | 49 -- Frameworks/vgmstream/vgmstream/src/meta/s3v.c | 4 +- .../vgmstream/vgmstream/src/meta/sdrh.c | 359 ++++++++++++ Frameworks/vgmstream/vgmstream/src/meta/seg.c | 42 +- Frameworks/vgmstream/vgmstream/src/meta/smk.c | 3 + Frameworks/vgmstream/vgmstream/src/meta/smp.c | 27 +- .../src/meta/{naomi_spsd.c => spsd.c} | 56 +- .../vgmstream/vgmstream/src/meta/sqex_scd.c | 6 +- .../vgmstream/vgmstream/src/meta/ster.c | 7 +- .../vgmstream/vgmstream/src/meta/str_wav.c | 12 +- .../vgmstream/vgmstream/src/meta/txth.c | 84 +-- .../vgmstream/vgmstream/src/meta/ubi_bao.c | 22 +- .../vgmstream/vgmstream/src/meta/ubi_ckd.c | 6 +- .../vgmstream/vgmstream/src/meta/ubi_hx.c | 9 +- .../vgmstream/vgmstream/src/meta/ubi_lyn.c | 7 +- .../vgmstream/vgmstream/src/meta/ubi_raki.c | 32 +- .../vgmstream/vgmstream/src/meta/ubi_sb.c | 14 +- Frameworks/vgmstream/vgmstream/src/meta/vag.c | 13 +- Frameworks/vgmstream/vgmstream/src/meta/vgs.c | 31 +- Frameworks/vgmstream/vgmstream/src/meta/wbk.c | 6 +- .../vgmstream/vgmstream/src/meta/wwise.c | 12 +- .../vgmstream/vgmstream/src/meta/x360_ast.c | 89 --- .../vgmstream/vgmstream/src/meta/x360_cxs.c | 63 -- .../vgmstream/vgmstream/src/meta/x360_pasx.c | 71 --- .../vgmstream/vgmstream/src/meta/x360_tra.c | 61 -- Frameworks/vgmstream/vgmstream/src/meta/xma.c | 14 +- .../vgmstream/vgmstream/src/meta/xma_ue3.c | 41 +- Frameworks/vgmstream/vgmstream/src/meta/xnb.c | 9 +- Frameworks/vgmstream/vgmstream/src/meta/xse.c | 301 ---------- .../vgmstream/vgmstream/src/meta/xwav.c | 33 +- Frameworks/vgmstream/vgmstream/src/meta/xwb.c | 21 +- Frameworks/vgmstream/vgmstream/src/meta/xwc.c | 86 +-- .../vgmstream/src/meta/xwma_konami.c | 43 +- .../src/meta/{xmv_valve.c => xwv_valve.c} | 39 +- Frameworks/vgmstream/vgmstream/src/render.c | 1 - .../vgmstream/vgmstream/src/stack_alloc.h | 112 ---- .../mpeg_bitreader.h => util/bitstream_msb.h} | 79 ++- .../vgmstream/vgmstream/src/util/cri_keys.c | 139 +++++ .../vgmstream/vgmstream/src/util/cri_keys.h | 13 + .../vgmstream/vgmstream/src/util/m2_psb.c | 2 +- .../vgmstream/vgmstream/src/vgmstream.c | 31 +- .../vgmstream/vgmstream/src/vgmstream.h | 35 +- 112 files changed, 3219 insertions(+), 3665 deletions(-) delete mode 100644 Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.h delete mode 100644 Frameworks/vgmstream/vgmstream/src/layout/blocked_tra.c rename Frameworks/vgmstream/vgmstream/src/meta/{ta_aac.c => aac_triace.c} (97%) create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/ahx_keys.h create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/astb.c create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/cps.c create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/cxs.c create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/ghs.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/gtd.c create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/pasx.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/ps2_ccc.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/ps3_cps.c create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/sdrh.c rename Frameworks/vgmstream/vgmstream/src/meta/{naomi_spsd.c => spsd.c} (62%) delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/x360_ast.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/x360_cxs.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/x360_pasx.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/x360_tra.c delete mode 100644 Frameworks/vgmstream/vgmstream/src/meta/xse.c rename Frameworks/vgmstream/vgmstream/src/meta/{xmv_valve.c => xwv_valve.c} (85%) delete mode 100644 Frameworks/vgmstream/vgmstream/src/stack_alloc.h rename Frameworks/vgmstream/vgmstream/src/{coding/mpeg_bitreader.h => util/bitstream_msb.h} (57%) create mode 100644 Frameworks/vgmstream/vgmstream/src/util/cri_keys.c create mode 100644 Frameworks/vgmstream/vgmstream/src/util/cri_keys.h diff --git a/Frameworks/libcelt_0061/libcelt_0061/libcelt_0061.xcodeproj/project.pbxproj b/Frameworks/libcelt_0061/libcelt_0061/libcelt_0061.xcodeproj/project.pbxproj index 27fc51142..112f8aad9 100644 --- a/Frameworks/libcelt_0061/libcelt_0061/libcelt_0061.xcodeproj/project.pbxproj +++ b/Frameworks/libcelt_0061/libcelt_0061/libcelt_0061.xcodeproj/project.pbxproj @@ -386,45 +386,45 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "HAVE_CONFIG_H=1", - "alg_quant=alg_quant", - "alg_unquant=alg_unquant", - "celt_decode=celt_0061_decode", - "celt_decoder_create=celt_0061_decoder_create", - "celt_decoder_create_custom=celt_0061_decoder_create_custom", - "celt_decoder_destroy=celt_0061_decoder_destroy", - "celt_mode_create=celt_0061_mode_create", - "celt_mode_destroy=celt_0061_mode_destroy", - "celt_mode_info=celt_0061_mode_info", - "celt_encoder_destroy=celt_0061_encoder_destroy", - "celt_encoder_create=celt_0061_encoder_create", - "celt_encode=celt_0061_encode", - "celt_encode_float=celt_0061_encode_float", - "celt_encoder_ctl=celt_0061_encoder_ctl", - "celt_decode_float=celt_0061_decode_float", - "celt_decoder_ctl=celt_0061_decoder_ctl", - "compute_allocation=compute_0061_allocation", - "compute_band_energies=compute_0061_band_energies", - "denormalise_bands=denormalise_0061_bands", - "ec_dec_init=ec_0061_dec_init", - "ec_decode=ec_0061_decode", - "ec_decode_bin=ec_0061_decode_bin", - "ec_dec_update=ec_0061_dec_update", - "ec_dec_uint=ec_0061_dec_uint", - "ec_dec_bits=ec_0061_dec_bits", - "ec_enc_init=ec_0061_enc_init", - "ec_encode=ec_0061_encode", - "ec_encode_bin=ec_0061_encode_bin", - "ec_enc_uint=ec_0061_enc_uint", - "ec_enc_bits=ec_0061_enc_bits", - "ec_enc_done=ec_0061_enc_done", - "normalise_bands=normalise_0061_bands", - "renormalise_vector=renormalise_0061_vector", - "quant_coarse_energy=quant_0061_coarse_energy", - "quant_fine_energy=quant_0061_fine_energy", - "quant_energy_finalise=quant_0061_energy_finalise", - "unquant_coarse_energy=unquant_0061_coarse_energy", - "unquant_energy_finalise=unquant_0061_energy_finalise", - "unquant_fine_energy=unquant_0061_fine_energy", + "alg_quant=alg_quant_0061", + "alg_unquant=alg_unquant_0061", + "celt_decode=celt_decode_0061", + "celt_decoder_create=celt_decoder_create_0061", + "celt_decoder_create_custom=celt_decoder_create_custom_0061", + "celt_decoder_destroy=celt_decoder_destroy_0061", + "celt_mode_create=celt_mode_create_0061", + "celt_mode_destroy=celt_mode_destroy_0061", + "celt_mode_info=celt_mode_info_0061", + "celt_encoder_destroy=celt_encoder_destroy_0061", + "celt_encoder_create=celt_encoder_create_0061", + "celt_encode=celt_encode_0061", + "celt_encode_float=celt_encode_float_0061", + "celt_encoder_ctl=celt_encoder_ctl_0061", + "celt_decode_float=celt_decode_float_0061", + "celt_decoder_ctl=celt_decoder_ctl_0061", + "compute_allocation=compute_allocation_0061", + "compute_band_energies=compute_band_energies_0061", + "denormalise_bands=denormalise_bands_0061", + "ec_dec_init=ec_dec_init_0061", + "ec_decode=ec_decode_0061", + "ec_decode_bin=ec_decode_bin_0061", + "ec_dec_update=ec_dec_update_0061", + "ec_dec_uint=ec_dec_uint_0061", + "ec_dec_bits=ec_dec_bits_0061", + "ec_enc_init=ec_enc_init_0061", + "ec_encode=ec_encode_0061", + "ec_encode_bin=ec_encode_bin_0061", + "ec_enc_uint=ec_enc_uint_0061", + "ec_enc_bits=ec_enc_bits_0061", + "ec_enc_done=ec_enc_done_0061", + "normalise_bands=normalise_bands_0061", + "renormalise_vector=renormalise_vector_0061", + "quant_coarse_energy=quant_coarse_energy_0061", + "quant_fine_energy=quant_fine_energy_0061", + "quant_energy_finalise=quant_energy_finalise_0061", + "unquant_coarse_energy=unquant_coarse_energy_0061", + "unquant_energy_finalise=unquant_energy_finalise_0061", + "unquant_fine_energy=unquant_fine_energy_0061", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -487,45 +487,45 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1", - "alg_quant=alg_quant", - "alg_unquant=alg_unquant", - "celt_decode=celt_0061_decode", - "celt_decoder_create=celt_0061_decoder_create", - "celt_decoder_create_custom=celt_0061_decoder_create_custom", - "celt_decoder_destroy=celt_0061_decoder_destroy", - "celt_mode_create=celt_0061_mode_create", - "celt_mode_destroy=celt_0061_mode_destroy", - "celt_mode_info=celt_0061_mode_info", - "celt_encoder_destroy=celt_0061_encoder_destroy", - "celt_encoder_create=celt_0061_encoder_create", - "celt_encode=celt_0061_encode", - "celt_encode_float=celt_0061_encode_float", - "celt_encoder_ctl=celt_0061_encoder_ctl", - "celt_decode_float=celt_0061_decode_float", - "celt_decoder_ctl=celt_0061_decoder_ctl", - "compute_allocation=compute_0061_allocation", - "compute_band_energies=compute_0061_band_energies", - "denormalise_bands=denormalise_0061_bands", - "ec_dec_init=ec_0061_dec_init", - "ec_decode=ec_0061_decode", - "ec_decode_bin=ec_0061_decode_bin", - "ec_dec_update=ec_0061_dec_update", - "ec_dec_uint=ec_0061_dec_uint", - "ec_dec_bits=ec_0061_dec_bits", - "ec_enc_init=ec_0061_enc_init", - "ec_encode=ec_0061_encode", - "ec_encode_bin=ec_0061_encode_bin", - "ec_enc_uint=ec_0061_enc_uint", - "ec_enc_bits=ec_0061_enc_bits", - "ec_enc_done=ec_0061_enc_done", - "normalise_bands=normalise_0061_bands", - "renormalise_vector=renormalise_0061_vector", - "quant_coarse_energy=quant_0061_coarse_energy", - "quant_fine_energy=quant_0061_fine_energy", - "quant_energy_finalise=quant_0061_energy_finalise", - "unquant_coarse_energy=unquant_0061_coarse_energy", - "unquant_energy_finalise=unquant_0061_energy_finalise", - "unquant_fine_energy=unquant_0061_fine_energy", + "alg_quant=alg_quant_0061", + "alg_unquant=alg_unquant_0061", + "celt_decode=celt_decode_0061", + "celt_decoder_create=celt_decoder_create_0061", + "celt_decoder_create_custom=celt_decoder_create_custom_0061", + "celt_decoder_destroy=celt_decoder_destroy_0061", + "celt_mode_create=celt_mode_create_0061", + "celt_mode_destroy=celt_mode_destroy_0061", + "celt_mode_info=celt_mode_info_0061", + "celt_encoder_destroy=celt_encoder_destroy_0061", + "celt_encoder_create=celt_encoder_create_0061", + "celt_encode=celt_encode_0061", + "celt_encode_float=celt_encode_float_0061", + "celt_encoder_ctl=celt_encoder_ctl_0061", + "celt_decode_float=celt_decode_float_0061", + "celt_decoder_ctl=celt_decoder_ctl_0061", + "compute_allocation=compute_allocation_0061", + "compute_band_energies=compute_band_energies_0061", + "denormalise_bands=denormalise_bands_0061", + "ec_dec_init=ec_dec_init_0061", + "ec_decode=ec_decode_0061", + "ec_decode_bin=ec_decode_bin_0061", + "ec_dec_update=ec_dec_update_0061", + "ec_dec_uint=ec_dec_uint_0061", + "ec_dec_bits=ec_dec_bits_0061", + "ec_enc_init=ec_enc_init_0061", + "ec_encode=ec_encode_0061", + "ec_encode_bin=ec_encode_bin_0061", + "ec_enc_uint=ec_enc_uint_0061", + "ec_enc_bits=ec_enc_bits_0061", + "ec_enc_done=ec_enc_done_0061", + "normalise_bands=normalise_bands_0061", + "renormalise_vector=renormalise_vector_0061", + "quant_coarse_energy=quant_coarse_energy_0061", + "quant_fine_energy=quant_fine_energy_0061", + "quant_energy_finalise=quant_energy_finalise_0061", + "unquant_coarse_energy=unquant_coarse_energy_0061", + "unquant_energy_finalise=unquant_energy_finalise_0061", + "unquant_fine_energy=unquant_fine_energy_0061", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; diff --git a/Frameworks/libcelt_0110/libcelt_0110/libcelt_0110.xcodeproj/project.pbxproj b/Frameworks/libcelt_0110/libcelt_0110/libcelt_0110.xcodeproj/project.pbxproj index b6f11bbec..36e69ccb9 100644 --- a/Frameworks/libcelt_0110/libcelt_0110/libcelt_0110.xcodeproj/project.pbxproj +++ b/Frameworks/libcelt_0110/libcelt_0110/libcelt_0110.xcodeproj/project.pbxproj @@ -374,45 +374,45 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "HAVE_CONFIG_H=1", - "alg_quant=alg_quant", - "alg_unquant=alg_unquant", - "celt_decode=celt_0110_decode", - "celt_decoder_create=celt_0110_decoder_create", - "celt_decoder_create_custom=celt_0110_decoder_create_custom", - "celt_decoder_destroy=celt_0110_decoder_destroy", - "celt_mode_create=celt_0110_mode_create", - "celt_mode_destroy=celt_0110_mode_destroy", - "celt_mode_info=celt_0110_mode_info", - "celt_encoder_destroy=celt_0110_encoder_destroy", - "celt_encoder_create=celt_0110_encoder_create", - "celt_encode=celt_0110_encode", - "celt_encode_float=celt_0110_encode_float", - "celt_encoder_ctl=celt_0110_encoder_ctl", - "celt_decode_float=celt_0110_decode_float", - "celt_decoder_ctl=celt_0110_decoder_ctl", - "compute_allocation=compute_0110_allocation", - "compute_band_energies=compute_0110_band_energies", - "denormalise_bands=denormalise_0110_bands", - "ec_dec_init=ec_0110_dec_init", - "ec_decode=ec_0110_decode", - "ec_decode_bin=ec_0110_decode_bin", - "ec_dec_update=ec_0110_dec_update", - "ec_dec_uint=ec_0110_dec_uint", - "ec_dec_bits=ec_0110_dec_bits", - "ec_enc_init=ec_0110_enc_init", - "ec_encode=ec_0110_encode", - "ec_encode_bin=ec_0110_encode_bin", - "ec_enc_uint=ec_0110_enc_uint", - "ec_enc_bits=ec_0110_enc_bits", - "ec_enc_done=ec_0110_enc_done", - "normalise_bands=normalise_0110_bands", - "renormalise_vector=renormalise_0110_vector", - "quant_coarse_energy=quant_0110_coarse_energy", - "quant_fine_energy=quant_0110_fine_energy", - "quant_energy_finalise=quant_0110_energy_finalise", - "unquant_coarse_energy=unquant_0110_coarse_energy", - "unquant_energy_finalise=unquant_0110_energy_finalise", - "unquant_fine_energy=unquant_0110_fine_energy", + "alg_quant=alg_quant_0110", + "alg_unquant=alg_unquant_0110", + "celt_decode=celt_decode_0110", + "celt_decoder_create=celt_decoder_create_0110", + "celt_decoder_create_custom=celt_decoder_create_custom_0110", + "celt_decoder_destroy=celt_decoder_destroy_0110", + "celt_mode_create=celt_mode_create_0110", + "celt_mode_destroy=celt_mode_destroy_0110", + "celt_mode_info=celt_mode_info_0110", + "celt_encoder_destroy=celt_encoder_destroy_0110", + "celt_encoder_create=celt_encoder_create_0110", + "celt_encode=celt_encode_0110", + "celt_encode_float=celt_encode_float_0110", + "celt_encoder_ctl=celt_encoder_ctl_0110", + "celt_decode_float=celt_decode_float_0110", + "celt_decoder_ctl=celt_decoder_ctl_0110", + "compute_allocation=compute_allocation_0110", + "compute_band_energies=compute_band_energies_0110", + "denormalise_bands=denormalise_bands_0110", + "ec_dec_init=ec_dec_init_0110", + "ec_decode=ec_decode_0110", + "ec_decode_bin=ec_decode_bin_0110", + "ec_dec_update=ec_dec_update_0110", + "ec_dec_uint=ec_dec_uint_0110", + "ec_dec_bits=ec_dec_bits_0110", + "ec_enc_init=ec_enc_init_0110", + "ec_encode=ec_encode_0110", + "ec_encode_bin=ec_encode_bin_0110", + "ec_enc_uint=ec_enc_uint_0110", + "ec_enc_bits=ec_enc_bits_0110", + "ec_enc_done=ec_enc_done_0110", + "normalise_bands=normalise_bands_0110", + "renormalise_vector=renormalise_vector_0110", + "quant_coarse_energy=quant_coarse_energy_0110", + "quant_fine_energy=quant_fine_energy_0110", + "quant_energy_finalise=quant_energy_finalise_0110", + "unquant_coarse_energy=unquant_coarse_energy_0110", + "unquant_energy_finalise=unquant_energy_finalise_0110", + "unquant_fine_energy=unquant_fine_energy_0110", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -475,45 +475,45 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "HAVE_CONFIG_H=1", - "alg_quant=alg_quant", - "alg_unquant=alg_unquant", - "celt_decode=celt_0110_decode", - "celt_decoder_create=celt_0110_decoder_create", - "celt_decoder_create_custom=celt_0110_decoder_create_custom", - "celt_decoder_destroy=celt_0110_decoder_destroy", - "celt_mode_create=celt_0110_mode_create", - "celt_mode_destroy=celt_0110_mode_destroy", - "celt_mode_info=celt_0110_mode_info", - "celt_encoder_destroy=celt_0110_encoder_destroy", - "celt_encoder_create=celt_0110_encoder_create", - "celt_encode=celt_0110_encode", - "celt_encode_float=celt_0110_encode_float", - "celt_encoder_ctl=celt_0110_encoder_ctl", - "celt_decode_float=celt_0110_decode_float", - "celt_decoder_ctl=celt_0110_decoder_ctl", - "compute_allocation=compute_0110_allocation", - "compute_band_energies=compute_0110_band_energies", - "denormalise_bands=denormalise_0110_bands", - "ec_dec_init=ec_0110_dec_init", - "ec_decode=ec_0110_decode", - "ec_decode_bin=ec_0110_decode_bin", - "ec_dec_update=ec_0110_dec_update", - "ec_dec_uint=ec_0110_dec_uint", - "ec_dec_bits=ec_0110_dec_bits", - "ec_enc_init=ec_0110_enc_init", - "ec_encode=ec_0110_encode", - "ec_encode_bin=ec_0110_encode_bin", - "ec_enc_uint=ec_0110_enc_uint", - "ec_enc_bits=ec_0110_enc_bits", - "ec_enc_done=ec_0110_enc_done", - "normalise_bands=normalise_0110_bands", - "renormalise_vector=renormalise_0110_vector", - "quant_coarse_energy=quant_0110_coarse_energy", - "quant_fine_energy=quant_0110_fine_energy", - "quant_energy_finalise=quant_0110_energy_finalise", - "unquant_coarse_energy=unquant_0110_coarse_energy", - "unquant_energy_finalise=unquant_0110_energy_finalise", - "unquant_fine_energy=unquant_0110_fine_energy", + "alg_quant=alg_quant_0110", + "alg_unquant=alg_unquant_0110", + "celt_decode=celt_decode_0110", + "celt_decoder_create=celt_decoder_create_0110", + "celt_decoder_create_custom=celt_decoder_create_custom_0110", + "celt_decoder_destroy=celt_decoder_destroy_0110", + "celt_mode_create=celt_mode_create_0110", + "celt_mode_destroy=celt_mode_destroy_0110", + "celt_mode_info=celt_mode_info_0110", + "celt_encoder_destroy=celt_encoder_destroy_0110", + "celt_encoder_create=celt_encoder_create_0110", + "celt_encode=celt_encode_0110", + "celt_encode_float=celt_encode_float_0110", + "celt_encoder_ctl=celt_encoder_ctl_0110", + "celt_decode_float=celt_decode_float_0110", + "celt_decoder_ctl=celt_decoder_ctl_0110", + "compute_allocation=compute_allocation_0110", + "compute_band_energies=compute_band_energies_0110", + "denormalise_bands=denormalise_bands_0110", + "ec_dec_init=ec_dec_init_0110", + "ec_decode=ec_decode_0110", + "ec_decode_bin=ec_decode_bin_0110", + "ec_dec_update=ec_dec_update_0110", + "ec_dec_uint=ec_dec_uint_0110", + "ec_dec_bits=ec_dec_bits_0110", + "ec_enc_init=ec_enc_init_0110", + "ec_encode=ec_encode_0110", + "ec_encode_bin=ec_encode_bin_0110", + "ec_enc_uint=ec_enc_uint_0110", + "ec_enc_bits=ec_enc_bits_0110", + "ec_enc_done=ec_enc_done_0110", + "normalise_bands=normalise_bands_0110", + "renormalise_vector=renormalise_vector_0110", + "quant_coarse_energy=quant_coarse_energy_0110", + "quant_fine_energy=quant_fine_energy_0110", + "quant_energy_finalise=quant_energy_finalise_0110", + "unquant_coarse_energy=unquant_coarse_energy_0110", + "unquant_energy_finalise=unquant_energy_finalise_0110", + "unquant_fine_energy=unquant_fine_energy_0110", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; diff --git a/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj b/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj index 7a08dd76d..3c73610d1 100644 --- a/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj +++ b/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj @@ -25,7 +25,6 @@ 83031EDC243C510500C3F3E0 /* vid1.c in Sources */ = {isa = PBXBuildFile; fileRef = 83031ED7243C510400C3F3E0 /* vid1.c */; }; 83031EDD243C510500C3F3E0 /* xnb_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83031ED8243C510500C3F3E0 /* xnb_streamfile.h */; }; 830595D8277EEAA500EBFAAE /* ffmpeg_decoder_custom_mp4.c in Sources */ = {isa = PBXBuildFile; fileRef = 830595D7277EEAA500EBFAAE /* ffmpeg_decoder_custom_mp4.c */; }; - 8306B08420984518000302D4 /* at3plus_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08120984517000302D4 /* at3plus_decoder.c */; }; 8306B08520984518000302D4 /* yamaha_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08220984517000302D4 /* yamaha_decoder.c */; }; 8306B08620984518000302D4 /* fadpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08320984517000302D4 /* fadpcm_decoder.c */; }; 8306B0A220984552000302D4 /* blocked_bdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0872098454C000302D4 /* blocked_bdsp.c */; }; @@ -45,7 +44,6 @@ 8306B0B120984552000302D4 /* blocked_halpst.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0962098454F000302D4 /* blocked_halpst.c */; }; 8306B0B220984552000302D4 /* blocked_mxch.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0972098454F000302D4 /* blocked_mxch.c */; }; 8306B0B320984552000302D4 /* blocked_thp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09820984550000302D4 /* blocked_thp.c */; }; - 8306B0B420984552000302D4 /* blocked_tra.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09920984550000302D4 /* blocked_tra.c */; }; 8306B0B620984552000302D4 /* blocked_hwas.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09B20984550000302D4 /* blocked_hwas.c */; }; 8306B0B720984552000302D4 /* blocked_str_snds.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09C20984550000302D4 /* blocked_str_snds.c */; }; 8306B0B820984552000302D4 /* blocked_ws_aud.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09D20984551000302D4 /* blocked_ws_aud.c */; }; @@ -99,8 +97,8 @@ 831BA61B1EAC61A500CF89B0 /* sgxd.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6111EAC61A500CF89B0 /* sgxd.c */; }; 831BA61C1EAC61A500CF89B0 /* sxd.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6121EAC61A500CF89B0 /* sxd.c */; }; 831BA61D1EAC61A500CF89B0 /* ubi_raki.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6131EAC61A500CF89B0 /* ubi_raki.c */; }; - 831BA61F1EAC61A500CF89B0 /* x360_cxs.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6151EAC61A500CF89B0 /* x360_cxs.c */; }; - 831BA6211EAC61A500CF89B0 /* x360_pasx.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6171EAC61A500CF89B0 /* x360_pasx.c */; }; + 831BA61F1EAC61A500CF89B0 /* cxs.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6151EAC61A500CF89B0 /* cxs.c */; }; + 831BA6211EAC61A500CF89B0 /* pasx.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6171EAC61A500CF89B0 /* pasx.c */; }; 831BA6281EAC61CB00CF89B0 /* coding_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6221EAC61CB00CF89B0 /* coding_utils.c */; }; 8322ECE7240268BB009E9429 /* raw_al.c in Sources */ = {isa = PBXBuildFile; fileRef = 8322ECE6240268BA009E9429 /* raw_al.c */; }; 832389501D2246C300482226 /* hca.c in Sources */ = {isa = PBXBuildFile; fileRef = 8323894F1D2246C300482226 /* hca.c */; }; @@ -293,6 +291,11 @@ 835C883722CC17BE001B4B3F /* ogg_vorbis_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 835C883522CC17BE001B4B3F /* ogg_vorbis_streamfile.h */; }; 836C052B23F62F1A00FA07C7 /* libatrac9.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 835FC6C623F62AEF006960FA /* libatrac9.framework */; }; 836C052C23F62F3100FA07C7 /* libatrac9.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 835FC6C623F62AEF006960FA /* libatrac9.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 836DF622298F83F400CD0580 /* cri_keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 836DF61F298F83F400CD0580 /* cri_keys.h */; }; + 836DF623298F83F400CD0580 /* bitstream_msb.h in Headers */ = {isa = PBXBuildFile; fileRef = 836DF620298F83F400CD0580 /* bitstream_msb.h */; }; + 836DF624298F83F400CD0580 /* cri_keys.c in Sources */ = {isa = PBXBuildFile; fileRef = 836DF621298F83F400CD0580 /* cri_keys.c */; }; + 836DF627298F864100CD0580 /* cps.c in Sources */ = {isa = PBXBuildFile; fileRef = 836DF625298F864100CD0580 /* cps.c */; }; + 836DF628298F864100CD0580 /* ahx_keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 836DF626298F864100CD0580 /* ahx_keys.h */; }; 836EF0DB27BB975900BF35B2 /* libvorbis.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 836EF0D027BB960A00BF35B2 /* libvorbis.0.dylib */; }; 836EF0DD27BB97C500BF35B2 /* libvorbisfile.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 836EF0DC27BB97BA00BF35B2 /* libvorbisfile.3.dylib */; }; 836F46AE28208735005B9B87 /* blocked_tt_ad.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F46AD28208735005B9B87 /* blocked_tt_ad.c */; }; @@ -380,7 +383,7 @@ 836F6FA018BDC2190095E648 /* musx.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6418BDC2180095E648 /* musx.c */; }; 836F6FA118BDC2190095E648 /* myspd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6518BDC2180095E648 /* myspd.c */; }; 836F6FA218BDC2190095E648 /* naomi_adpcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6618BDC2180095E648 /* naomi_adpcm.c */; }; - 836F6FA318BDC2190095E648 /* naomi_spsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6718BDC2180095E648 /* naomi_spsd.c */; }; + 836F6FA318BDC2190095E648 /* spsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6718BDC2180095E648 /* spsd.c */; }; 836F6FA418BDC2190095E648 /* nds_hwas.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6818BDC2180095E648 /* nds_hwas.c */; }; 836F6FA518BDC2190095E648 /* nds_rrds.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6918BDC2180095E648 /* nds_rrds.c */; }; 836F6FA718BDC2190095E648 /* nds_strm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6B18BDC2180095E648 /* nds_strm.c */; }; @@ -411,7 +414,6 @@ 836F6FD018BDC2190095E648 /* ps2_b1s.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9418BDC2180095E648 /* ps2_b1s.c */; }; 836F6FD118BDC2190095E648 /* ps2_bg00.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9518BDC2180095E648 /* ps2_bg00.c */; }; 836F6FD218BDC2190095E648 /* ps2_bmdx.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9618BDC2180095E648 /* ps2_bmdx.c */; }; - 836F6FD318BDC2190095E648 /* ps2_ccc.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9718BDC2180095E648 /* ps2_ccc.c */; }; 836F6FD418BDC2190095E648 /* hxd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9818BDC2180095E648 /* hxd.c */; }; 836F6FD518BDC2190095E648 /* ps2_enth.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9918BDC2180095E648 /* ps2_enth.c */; }; 836F6FD718BDC2190095E648 /* ps2_filp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9B18BDC2180095E648 /* ps2_filp.c */; }; @@ -452,7 +454,6 @@ 836F700D18BDC2190095E648 /* ps2_wmus.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED118BDC2190095E648 /* ps2_wmus.c */; }; 836F700E18BDC2190095E648 /* ps2_xa2.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED218BDC2190095E648 /* ps2_xa2.c */; }; 836F700F18BDC2190095E648 /* ps2_xa30.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED318BDC2190095E648 /* ps2_xa30.c */; }; - 836F701118BDC2190095E648 /* ps3_cps.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED518BDC2190095E648 /* ps3_cps.c */; }; 836F701518BDC2190095E648 /* ps3_past.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED918BDC2190095E648 /* ps3_past.c */; }; 836F701E18BDC2190095E648 /* redspark.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EE218BDC2190095E648 /* redspark.c */; }; 836F701F18BDC2190095E648 /* riff.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EE318BDC2190095E648 /* riff.c */; }; @@ -490,7 +491,6 @@ 836F704318BDC2190095E648 /* wpd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0718BDC2190095E648 /* wpd.c */; }; 836F704418BDC2190095E648 /* ws_aud.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0818BDC2190095E648 /* ws_aud.c */; }; 836F704518BDC2190095E648 /* wvs.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0918BDC2190095E648 /* wvs.c */; }; - 836F704618BDC2190095E648 /* x360_tra.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0A18BDC2190095E648 /* x360_tra.c */; }; 836F704818BDC2190095E648 /* xbox_ims.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0C18BDC2190095E648 /* xbox_ims.c */; }; 836F704E18BDC2190095E648 /* xss.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1218BDC2190095E648 /* xss.c */; }; 836F704F18BDC2190095E648 /* xwb.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1318BDC2190095E648 /* xwb.c */; }; @@ -504,10 +504,10 @@ 836F705718BDC2190095E648 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1B18BDC2190095E648 /* util.h */; settings = {ATTRIBUTES = (Public, ); }; }; 836F705818BDC2190095E648 /* vgmstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1C18BDC2190095E648 /* vgmstream.c */; }; 836F705918BDC2190095E648 /* vgmstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1D18BDC2190095E648 /* vgmstream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 83709E051ECBC1A4005C03D3 /* gtd.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709DFF1ECBC1A4005C03D3 /* gtd.c */; }; + 83709E051ECBC1A4005C03D3 /* ghs.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709DFF1ECBC1A4005C03D3 /* ghs.c */; }; 83709E061ECBC1A4005C03D3 /* mc3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E001ECBC1A4005C03D3 /* mc3.c */; }; 83709E071ECBC1A4005C03D3 /* mss.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E011ECBC1A4005C03D3 /* mss.c */; }; - 83709E091ECBC1A4005C03D3 /* ta_aac.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E031ECBC1A4005C03D3 /* ta_aac.c */; }; + 83709E091ECBC1A4005C03D3 /* aac_triace.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E031ECBC1A4005C03D3 /* aac_triace.c */; }; 83709E0D1ECBC1C3005C03D3 /* mc3_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E0B1ECBC1C3005C03D3 /* mc3_decoder.c */; }; 83709E0E1ECBC1C3005C03D3 /* psv_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E0C1ECBC1C3005C03D3 /* psv_decoder.c */; }; 8373341623F60C7B00DE14DC /* g7221_decoder_aes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373340E23F60C7A00DE14DC /* g7221_decoder_aes.h */; }; @@ -541,7 +541,7 @@ 837CEAF423487F2C00E62A4A /* xa_xa30.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEADF23487F2A00E62A4A /* xa_xa30.c */; }; 837CEAF523487F2C00E62A4A /* ubi_hx.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE023487F2A00E62A4A /* ubi_hx.c */; }; 837CEAF723487F2C00E62A4A /* nub.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE223487F2A00E62A4A /* nub.c */; }; - 837CEAF823487F2C00E62A4A /* xmv_valve.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE323487F2A00E62A4A /* xmv_valve.c */; }; + 837CEAF823487F2C00E62A4A /* xwv_valve.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE323487F2A00E62A4A /* xwv_valve.c */; }; 837CEAF923487F2C00E62A4A /* xavs.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE423487F2A00E62A4A /* xavs.c */; }; 837CEAFA23487F2C00E62A4A /* xa_04sw.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE523487F2B00E62A4A /* xa_04sw.c */; }; 837CEAFB23487F2C00E62A4A /* ima.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAE623487F2B00E62A4A /* ima.c */; }; @@ -608,13 +608,12 @@ 83A21F8C201D8982000F04B9 /* kma9.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A21F83201D8981000F04B9 /* kma9.c */; }; 83A21F8D201D8982000F04B9 /* sqex_sead.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A21F84201D8981000F04B9 /* sqex_sead.c */; }; 83A3F0741E3AD8B900D6A794 /* formats.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A3F0711E3AD8B900D6A794 /* formats.c */; }; - 83A3F0761E3AD8B900D6A794 /* stack_alloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A3F0731E3AD8B900D6A794 /* stack_alloc.h */; }; 83A5F75F198DF021009AF94C /* bfwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A5F75E198DF021009AF94C /* bfwav.c */; }; 83A8BADD256679C5000F5F3F /* wady_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BADC256679C5000F5F3F /* wady_decoder.c */; }; 83A8BADF256679E3000F5F3F /* blocked_xwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BADE256679E3000F5F3F /* blocked_xwav.c */; }; 83A8BAE525667AA8000F5F3F /* wady.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BAE025667AA7000F5F3F /* wady.c */; }; 83A8BAE625667AA8000F5F3F /* ps2_enth_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A8BAE125667AA7000F5F3F /* ps2_enth_streamfile.h */; }; - 83A8BAE725667AA8000F5F3F /* xse.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BAE225667AA7000F5F3F /* xse.c */; }; + 83A8BAE725667AA8000F5F3F /* sdrh.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BAE225667AA7000F5F3F /* sdrh.c */; }; 83A8BAE825667AA8000F5F3F /* xwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BAE325667AA7000F5F3F /* xwav.c */; }; 83A8BAE925667AA8000F5F3F /* cpk.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A8BAE425667AA7000F5F3F /* cpk.c */; }; 83AA5D161F6E2F600020821C /* ea_xa_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA5D0E1F6E2F5F0020821C /* ea_xa_decoder.c */; }; @@ -631,7 +630,6 @@ 83AA7D19279EBD0B00087AA4 /* libavutil.57.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83AA7D16279EBCF900087AA4 /* libavutil.57.dylib */; }; 83AA7D1A279EBD0D00087AA4 /* libswresample.4.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83AA7D15279EBCF900087AA4 /* libswresample.4.dylib */; }; 83AA7F722519BFEA004C5298 /* vorbis_bitreader.h in Headers */ = {isa = PBXBuildFile; fileRef = 83AA7F6D2519BFEA004C5298 /* vorbis_bitreader.h */; }; - 83AA7F732519BFEA004C5298 /* mpeg_bitreader.h in Headers */ = {isa = PBXBuildFile; fileRef = 83AA7F712519BFEA004C5298 /* mpeg_bitreader.h */; }; 83AA7F7D2519C042004C5298 /* dsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA7F742519C041004C5298 /* dsb.c */; }; 83AA7F7E2519C042004C5298 /* svag_kcet.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA7F752519C041004C5298 /* svag_kcet.c */; }; 83AA7F7F2519C042004C5298 /* bsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA7F762519C042004C5298 /* bsf.c */; }; @@ -645,7 +643,7 @@ 83AA7F8B2519C076004C5298 /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = 83AA7F872519C076004C5298 /* render.h */; }; 83AA7F8C2519C076004C5298 /* render.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA7F882519C076004C5298 /* render.c */; }; 83AA7F8D2519C076004C5298 /* decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AA7F892519C076004C5298 /* decode.c */; }; - 83AB8C761E8072A100086084 /* x360_ast.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AB8C741E8072A100086084 /* x360_ast.c */; }; + 83AB8C761E8072A100086084 /* astb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AB8C741E8072A100086084 /* astb.c */; }; 83AF2CC926226BA500538240 /* gcub.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AF2CC526226BA400538240 /* gcub.c */; }; 83AF2CCA26226BA500538240 /* exst.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AF2CC626226BA400538240 /* exst.c */; }; 83AF2CCB26226BA500538240 /* ogv_3rdeye.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AF2CC726226BA400538240 /* ogv_3rdeye.c */; }; @@ -653,7 +651,6 @@ 83AFABBC23795202002F3947 /* xssb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AFABB923795201002F3947 /* xssb.c */; }; 83AFABBD23795202002F3947 /* ea_eaac_opus_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83AFABBA23795202002F3947 /* ea_eaac_opus_streamfile.h */; }; 83AFABBE23795202002F3947 /* isb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83AFABBB23795202002F3947 /* isb.c */; }; - 83B46FD12707FB2100847FC9 /* at3plus_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B46FCD2707FB2100847FC9 /* at3plus_decoder.h */; }; 83B46FD52707FB9A00847FC9 /* endianness.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B46FD42707FB9A00847FC9 /* endianness.h */; }; 83B69B222845A26600D2435A /* bw_mp3_riff.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B69B212845A26600D2435A /* bw_mp3_riff.c */; }; 83B72E3A27904589006007A3 /* libfdk-aac.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83B72E342790452C006007A3 /* libfdk-aac.2.dylib */; }; @@ -853,7 +850,6 @@ 83031ED7243C510400C3F3E0 /* vid1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vid1.c; sourceTree = ""; }; 83031ED8243C510500C3F3E0 /* xnb_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xnb_streamfile.h; sourceTree = ""; }; 830595D7277EEAA500EBFAAE /* ffmpeg_decoder_custom_mp4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffmpeg_decoder_custom_mp4.c; sourceTree = ""; }; - 8306B08120984517000302D4 /* at3plus_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = at3plus_decoder.c; sourceTree = ""; }; 8306B08220984517000302D4 /* yamaha_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yamaha_decoder.c; sourceTree = ""; }; 8306B08320984517000302D4 /* fadpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fadpcm_decoder.c; sourceTree = ""; }; 8306B0872098454C000302D4 /* blocked_bdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_bdsp.c; sourceTree = ""; }; @@ -873,7 +869,6 @@ 8306B0962098454F000302D4 /* blocked_halpst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_halpst.c; sourceTree = ""; }; 8306B0972098454F000302D4 /* blocked_mxch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_mxch.c; sourceTree = ""; }; 8306B09820984550000302D4 /* blocked_thp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_thp.c; sourceTree = ""; }; - 8306B09920984550000302D4 /* blocked_tra.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_tra.c; sourceTree = ""; }; 8306B09B20984550000302D4 /* blocked_hwas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_hwas.c; sourceTree = ""; }; 8306B09C20984550000302D4 /* blocked_str_snds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_str_snds.c; sourceTree = ""; }; 8306B09D20984551000302D4 /* blocked_ws_aud.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ws_aud.c; sourceTree = ""; }; @@ -927,8 +922,8 @@ 831BA6111EAC61A500CF89B0 /* sgxd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sgxd.c; sourceTree = ""; }; 831BA6121EAC61A500CF89B0 /* sxd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sxd.c; sourceTree = ""; }; 831BA6131EAC61A500CF89B0 /* ubi_raki.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_raki.c; sourceTree = ""; }; - 831BA6151EAC61A500CF89B0 /* x360_cxs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x360_cxs.c; sourceTree = ""; }; - 831BA6171EAC61A500CF89B0 /* x360_pasx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x360_pasx.c; sourceTree = ""; }; + 831BA6151EAC61A500CF89B0 /* cxs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cxs.c; sourceTree = ""; }; + 831BA6171EAC61A500CF89B0 /* pasx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pasx.c; sourceTree = ""; }; 831BA6221EAC61CB00CF89B0 /* coding_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = coding_utils.c; sourceTree = ""; }; 831BD11F1EEE1CF200198540 /* ngc_ulw.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ngc_ulw.c; sourceTree = ""; }; 8322ECE6240268BA009E9429 /* raw_al.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_al.c; sourceTree = ""; }; @@ -1121,6 +1116,11 @@ 835C883122CC17BD001B4B3F /* bwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bwav.c; sourceTree = ""; }; 835C883522CC17BE001B4B3F /* ogg_vorbis_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ogg_vorbis_streamfile.h; sourceTree = ""; }; 835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libatrac9.xcodeproj; path = ../libatrac9/libatrac9.xcodeproj; sourceTree = ""; }; + 836DF61F298F83F400CD0580 /* cri_keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cri_keys.h; sourceTree = ""; }; + 836DF620298F83F400CD0580 /* bitstream_msb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitstream_msb.h; sourceTree = ""; }; + 836DF621298F83F400CD0580 /* cri_keys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cri_keys.c; sourceTree = ""; }; + 836DF625298F864100CD0580 /* cps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cps.c; sourceTree = ""; }; + 836DF626298F864100CD0580 /* ahx_keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ahx_keys.h; sourceTree = ""; }; 836EF0D027BB960A00BF35B2 /* libvorbis.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbis.0.dylib; path = ../../ThirdParty/vorbis/lib/libvorbis.0.dylib; sourceTree = ""; }; 836EF0DC27BB97BA00BF35B2 /* libvorbisfile.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbisfile.3.dylib; path = ../../ThirdParty/vorbis/lib/libvorbisfile.3.dylib; sourceTree = ""; }; 836F46AD28208735005B9B87 /* blocked_tt_ad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_tt_ad.c; sourceTree = ""; }; @@ -1210,7 +1210,7 @@ 836F6E6418BDC2180095E648 /* musx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = musx.c; sourceTree = ""; }; 836F6E6518BDC2180095E648 /* myspd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = myspd.c; sourceTree = ""; }; 836F6E6618BDC2180095E648 /* naomi_adpcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = naomi_adpcm.c; sourceTree = ""; }; - 836F6E6718BDC2180095E648 /* naomi_spsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = naomi_spsd.c; sourceTree = ""; }; + 836F6E6718BDC2180095E648 /* spsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spsd.c; sourceTree = ""; }; 836F6E6818BDC2180095E648 /* nds_hwas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_hwas.c; sourceTree = ""; }; 836F6E6918BDC2180095E648 /* nds_rrds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_rrds.c; sourceTree = ""; }; 836F6E6B18BDC2180095E648 /* nds_strm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_strm.c; sourceTree = ""; }; @@ -1241,7 +1241,6 @@ 836F6E9418BDC2180095E648 /* ps2_b1s.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_b1s.c; sourceTree = ""; }; 836F6E9518BDC2180095E648 /* ps2_bg00.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_bg00.c; sourceTree = ""; }; 836F6E9618BDC2180095E648 /* ps2_bmdx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_bmdx.c; sourceTree = ""; }; - 836F6E9718BDC2180095E648 /* ps2_ccc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_ccc.c; sourceTree = ""; }; 836F6E9818BDC2180095E648 /* hxd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hxd.c; sourceTree = ""; }; 836F6E9918BDC2180095E648 /* ps2_enth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_enth.c; sourceTree = ""; }; 836F6E9B18BDC2180095E648 /* ps2_filp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_filp.c; sourceTree = ""; }; @@ -1282,7 +1281,6 @@ 836F6ED118BDC2190095E648 /* ps2_wmus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_wmus.c; sourceTree = ""; }; 836F6ED218BDC2190095E648 /* ps2_xa2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_xa2.c; sourceTree = ""; }; 836F6ED318BDC2190095E648 /* ps2_xa30.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_xa30.c; sourceTree = ""; }; - 836F6ED518BDC2190095E648 /* ps3_cps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps3_cps.c; sourceTree = ""; }; 836F6ED918BDC2190095E648 /* ps3_past.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps3_past.c; sourceTree = ""; }; 836F6EE218BDC2190095E648 /* redspark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = redspark.c; sourceTree = ""; }; 836F6EE318BDC2190095E648 /* riff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = riff.c; sourceTree = ""; }; @@ -1320,7 +1318,6 @@ 836F6F0718BDC2190095E648 /* wpd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wpd.c; sourceTree = ""; }; 836F6F0818BDC2190095E648 /* ws_aud.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ws_aud.c; sourceTree = ""; }; 836F6F0918BDC2190095E648 /* wvs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wvs.c; sourceTree = ""; }; - 836F6F0A18BDC2190095E648 /* x360_tra.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x360_tra.c; sourceTree = ""; }; 836F6F0C18BDC2190095E648 /* xbox_ims.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xbox_ims.c; sourceTree = ""; }; 836F6F1218BDC2190095E648 /* xss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xss.c; sourceTree = ""; }; 836F6F1318BDC2190095E648 /* xwb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwb.c; sourceTree = ""; }; @@ -1334,10 +1331,10 @@ 836F6F1B18BDC2190095E648 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; 836F6F1C18BDC2190095E648 /* vgmstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgmstream.c; sourceTree = ""; }; 836F6F1D18BDC2190095E648 /* vgmstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vgmstream.h; sourceTree = ""; }; - 83709DFF1ECBC1A4005C03D3 /* gtd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gtd.c; sourceTree = ""; }; + 83709DFF1ECBC1A4005C03D3 /* ghs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ghs.c; sourceTree = ""; }; 83709E001ECBC1A4005C03D3 /* mc3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3.c; sourceTree = ""; }; 83709E011ECBC1A4005C03D3 /* mss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mss.c; sourceTree = ""; }; - 83709E031ECBC1A4005C03D3 /* ta_aac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ta_aac.c; sourceTree = ""; }; + 83709E031ECBC1A4005C03D3 /* aac_triace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_triace.c; sourceTree = ""; }; 83709E0B1ECBC1C3005C03D3 /* mc3_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3_decoder.c; sourceTree = ""; }; 83709E0C1ECBC1C3005C03D3 /* psv_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = psv_decoder.c; sourceTree = ""; }; 8373340E23F60C7A00DE14DC /* g7221_decoder_aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g7221_decoder_aes.h; sourceTree = ""; }; @@ -1372,7 +1369,7 @@ 837CEADF23487F2A00E62A4A /* xa_xa30.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xa_xa30.c; sourceTree = ""; }; 837CEAE023487F2A00E62A4A /* ubi_hx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_hx.c; sourceTree = ""; }; 837CEAE223487F2A00E62A4A /* nub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nub.c; sourceTree = ""; }; - 837CEAE323487F2A00E62A4A /* xmv_valve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xmv_valve.c; sourceTree = ""; }; + 837CEAE323487F2A00E62A4A /* xwv_valve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwv_valve.c; sourceTree = ""; }; 837CEAE423487F2A00E62A4A /* xavs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xavs.c; sourceTree = ""; }; 837CEAE523487F2B00E62A4A /* xa_04sw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xa_04sw.c; sourceTree = ""; }; 837CEAE623487F2B00E62A4A /* ima.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ima.c; sourceTree = ""; }; @@ -1438,13 +1435,12 @@ 83A21F83201D8981000F04B9 /* kma9.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kma9.c; sourceTree = ""; }; 83A21F84201D8981000F04B9 /* sqex_sead.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sqex_sead.c; sourceTree = ""; }; 83A3F0711E3AD8B900D6A794 /* formats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = formats.c; sourceTree = ""; }; - 83A3F0731E3AD8B900D6A794 /* stack_alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_alloc.h; sourceTree = ""; }; 83A5F75E198DF021009AF94C /* bfwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfwav.c; sourceTree = ""; }; 83A8BADC256679C5000F5F3F /* wady_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wady_decoder.c; sourceTree = ""; }; 83A8BADE256679E3000F5F3F /* blocked_xwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_xwav.c; sourceTree = ""; }; 83A8BAE025667AA7000F5F3F /* wady.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wady.c; sourceTree = ""; }; 83A8BAE125667AA7000F5F3F /* ps2_enth_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ps2_enth_streamfile.h; sourceTree = ""; }; - 83A8BAE225667AA7000F5F3F /* xse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xse.c; sourceTree = ""; }; + 83A8BAE225667AA7000F5F3F /* sdrh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sdrh.c; sourceTree = ""; }; 83A8BAE325667AA7000F5F3F /* xwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwav.c; sourceTree = ""; }; 83A8BAE425667AA7000F5F3F /* cpk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cpk.c; sourceTree = ""; }; 83AA5D0E1F6E2F5F0020821C /* ea_xa_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_xa_decoder.c; sourceTree = ""; }; @@ -1461,7 +1457,6 @@ 83AA7D15279EBCF900087AA4 /* libswresample.4.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libswresample.4.dylib; path = ../../ThirdParty/ffmpeg/lib/libswresample.4.dylib; sourceTree = ""; }; 83AA7D16279EBCF900087AA4 /* libavutil.57.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavutil.57.dylib; path = ../../ThirdParty/ffmpeg/lib/libavutil.57.dylib; sourceTree = ""; }; 83AA7F6D2519BFEA004C5298 /* vorbis_bitreader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbis_bitreader.h; sourceTree = ""; }; - 83AA7F712519BFEA004C5298 /* mpeg_bitreader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpeg_bitreader.h; sourceTree = ""; }; 83AA7F742519C041004C5298 /* dsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsb.c; sourceTree = ""; }; 83AA7F752519C041004C5298 /* svag_kcet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svag_kcet.c; sourceTree = ""; }; 83AA7F762519C042004C5298 /* bsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bsf.c; sourceTree = ""; }; @@ -1475,7 +1470,7 @@ 83AA7F872519C076004C5298 /* render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = render.h; sourceTree = ""; }; 83AA7F882519C076004C5298 /* render.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = render.c; sourceTree = ""; }; 83AA7F892519C076004C5298 /* decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decode.c; sourceTree = ""; }; - 83AB8C741E8072A100086084 /* x360_ast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x360_ast.c; sourceTree = ""; }; + 83AB8C741E8072A100086084 /* astb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = astb.c; sourceTree = ""; }; 83AF2CC526226BA400538240 /* gcub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gcub.c; sourceTree = ""; }; 83AF2CC626226BA400538240 /* exst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = exst.c; sourceTree = ""; }; 83AF2CC726226BA400538240 /* ogv_3rdeye.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ogv_3rdeye.c; sourceTree = ""; }; @@ -1483,7 +1478,6 @@ 83AFABB923795201002F3947 /* xssb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xssb.c; sourceTree = ""; }; 83AFABBA23795202002F3947 /* ea_eaac_opus_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ea_eaac_opus_streamfile.h; sourceTree = ""; }; 83AFABBB23795202002F3947 /* isb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = isb.c; sourceTree = ""; }; - 83B46FCD2707FB2100847FC9 /* at3plus_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = at3plus_decoder.h; sourceTree = ""; }; 83B46FD42707FB9A00847FC9 /* endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endianness.h; sourceTree = ""; }; 83B69B212845A26600D2435A /* bw_mp3_riff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bw_mp3_riff.c; sourceTree = ""; }; 83B72E342790452C006007A3 /* libfdk-aac.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libfdk-aac.2.dylib"; path = "../../ThirdParty/fdk-aac/lib/libfdk-aac.2.dylib"; sourceTree = ""; }; @@ -1775,7 +1769,6 @@ 83AA7F882519C076004C5298 /* render.c */, 83AA7F872519C076004C5298 /* render.h */, 8347C7472796D76700FA8A7D /* seek.c */, - 83A3F0731E3AD8B900D6A794 /* stack_alloc.h */, 836F6F1718BDC2190095E648 /* streamfile.c */, 836F6F1818BDC2190095E648 /* streamfile.h */, 836F6F1918BDC2190095E648 /* streamtypes.h */, @@ -1796,8 +1789,6 @@ 836F6DE018BDC2180095E648 /* acm_decoder.c */, 836F6DE218BDC2180095E648 /* adx_decoder.c */, 8315958320FEC831007002F0 /* asf_decoder.c */, - 8306B08120984517000302D4 /* at3plus_decoder.c */, - 83B46FCD2707FB2100847FC9 /* at3plus_decoder.h */, 830EBE0F2004655D0023AA10 /* atrac9_decoder.c */, 834FE0B2215C798C000A5D3D /* celt_fsb_decoder.c */, 83031EBF243C50A800C3F3E0 /* circus_decoder_lib_data.h */, @@ -1843,7 +1834,6 @@ 836F6DEC18BDC2180095E648 /* lsf_decoder.c */, 83709E0B1ECBC1C3005C03D3 /* mc3_decoder.c */, 836F6DEE18BDC2180095E648 /* mp4_aac_decoder.c */, - 83AA7F712519BFEA004C5298 /* mpeg_bitreader.h */, 839E21D91F2EDAF000EE54D7 /* mpeg_custom_utils_ahx.c */, 83AA5D141F6E2F600020821C /* mpeg_custom_utils_awc.c */, 83AA5D131F6E2F5F0020821C /* mpeg_custom_utils_ealayer3.c */, @@ -1931,7 +1921,6 @@ 8306B08F2098454E000302D4 /* blocked_sthd.c */, 8306B09C20984550000302D4 /* blocked_str_snds.c */, 8306B09820984550000302D4 /* blocked_thp.c */, - 8306B09920984550000302D4 /* blocked_tra.c */, 836F46AD28208735005B9B87 /* blocked_tt_ad.c */, 83031ECA243C50CB00C3F3E0 /* blocked_ubi_sce.c */, 83AA5D1A1F6E2F7F0020821C /* blocked_vgs.c */, @@ -1964,6 +1953,7 @@ 83C727FE22BC893900678B4A /* 9tav.c */, 8351F32A2212B57000A606E4 /* 208.c */, 834FE0C8215C79E7000A5D3D /* a2m.c */, + 83709E031ECBC1A4005C03D3 /* aac_triace.c */, 836F6E2A18BDC2180095E648 /* aax.c */, 837CEAD623487E8300E62A4A /* acb.c */, 836F6E2B18BDC2180095E648 /* acm.c */, @@ -1979,6 +1969,7 @@ 8349A9001FE6258000E26435 /* afc.c */, 836F6E2F18BDC2180095E648 /* agsc.c */, 834FE0E5215C79EC000A5D3D /* ahv.c */, + 836DF626298F864100CD0580 /* ahx_keys.h */, 836F6E3018BDC2180095E648 /* ahx.c */, 834FE0C1215C79E5000A5D3D /* aif_asobo.c */, 836F6E3118BDC2180095E648 /* aifc.c */, @@ -1993,6 +1984,7 @@ 835B9B8B2730BF2C00F87EE3 /* ast_mmv.c */, 835B9B8A2730BF2C00F87EE3 /* ast_mv.c */, 836F6E3518BDC2180095E648 /* ast.c */, + 83AB8C741E8072A100086084 /* astb.c */, 8306B0D520984590000302D4 /* atsl.c */, 83A21F7C201D897F000F04B9 /* atx.c */, 83EED5D2203A8BC7008BEB45 /* aus.c */, @@ -2024,9 +2016,11 @@ 834FE0E8215C79EC000A5D3D /* ck.c */, 8346D97825BF838C00D1A8B0 /* compresswave.c */, 83A8BAE425667AA7000F5F3F /* cpk.c */, + 836DF625298F864100CD0580 /* cps.c */, 83FC176B23AC58D100E1025F /* csb.c */, 834FE0D8215C79EA000A5D3D /* csmp.c */, 836F6E3C18BDC2180095E648 /* cstr.c */, + 831BA6151EAC61A500CF89B0 /* cxs.c */, 836F6E3D18BDC2180095E648 /* dc_asd.c */, 836F6E3F18BDC2180095E648 /* dc_idvi.c */, 836F6E4018BDC2180095E648 /* dc_kcey.c */, @@ -2080,9 +2074,9 @@ 836F6E4E18BDC2180095E648 /* gcsw.c */, 83AF2CC526226BA400538240 /* gcub.c */, 836F6E4F18BDC2180095E648 /* genh.c */, + 83709DFF1ECBC1A4005C03D3 /* ghs.c */, 8375737421F950EC00F01AF5 /* gin.c */, 836F6E5118BDC2180095E648 /* gsp_gsb.c */, - 83709DFF1ECBC1A4005C03D3 /* gtd.c */, 8342469020C4D22F00926E48 /* h4m.c */, 836F6E5218BDC2180095E648 /* halpst.c */, 835B9B8D2730BF2D00F87EE3 /* hca_bf.h */, @@ -2157,7 +2151,6 @@ 836F6E6518BDC2180095E648 /* myspd.c */, 8349A9061FE6258100E26435 /* naac.c */, 836F6E6618BDC2180095E648 /* naomi_adpcm.c */, - 836F6E6718BDC2180095E648 /* naomi_spsd.c */, 836F6E6818BDC2180095E648 /* nds_hwas.c */, 836F6E6918BDC2180095E648 /* nds_rrds.c */, 830165991F256BD000CA0941 /* nds_strm_ffta2.c */, @@ -2197,6 +2190,7 @@ 8306B0CE2098458E000302D4 /* opus.c */, 836F6E8318BDC2180095E648 /* otm.c */, 836F6E8418BDC2180095E648 /* p3d.c */, + 831BA6171EAC61A500CF89B0 /* pasx.c */, 8349A8FE1FE6257F00E26435 /* pc_adp_otns.c */, 8349A8F01FE6257C00E26435 /* pc_ast.c */, 836F6E8618BDC2180095E648 /* pc_mxst.c */, @@ -2214,7 +2208,6 @@ 836F6E9418BDC2180095E648 /* ps2_b1s.c */, 836F6E9518BDC2180095E648 /* ps2_bg00.c */, 836F6E9618BDC2180095E648 /* ps2_bmdx.c */, - 836F6E9718BDC2180095E648 /* ps2_ccc.c */, 83A8BAE125667AA7000F5F3F /* ps2_enth_streamfile.h */, 836F6E9918BDC2180095E648 /* ps2_enth.c */, 836F6E9B18BDC2180095E648 /* ps2_filp.c */, @@ -2255,7 +2248,6 @@ 8349A8FC1FE6257F00E26435 /* ps2_xa2_rrp.c */, 836F6ED218BDC2190095E648 /* ps2_xa2.c */, 836F6ED318BDC2190095E648 /* ps2_xa30.c */, - 836F6ED518BDC2190095E648 /* ps3_cps.c */, 836F6ED918BDC2190095E648 /* ps3_past.c */, 8315868326F586E200803A3A /* psb.c */, 837CEAE823487F2B00E62A4A /* psf.c */, @@ -2290,6 +2282,7 @@ 8349A8F51FE6257D00E26435 /* scd_pcm.c */, 836F6EEE18BDC2190095E648 /* sd9.c */, 834FE0E6215C79EC000A5D3D /* sdf.c */, + 83A8BAE225667AA7000F5F3F /* sdrh.c */, 836F6EEF18BDC2190095E648 /* sdt.c */, 837CEB062348809400E62A4A /* seb.c */, 836F6EF018BDC2190095E648 /* seg.c */, @@ -2307,6 +2300,7 @@ 835559FB2869102B005FE93A /* sndz.c */, 836F6EBE18BDC2190095E648 /* spm.c */, 83A21F82201D8981000F04B9 /* sps_n1.c */, + 836F6E6718BDC2180095E648 /* spsd.c */, 836F6EF318BDC2190095E648 /* spt_spd.c */, 836F6EF418BDC2190095E648 /* sqex_scd.c */, 83A21F84201D8981000F04B9 /* sqex_sead.c */, @@ -2328,7 +2322,6 @@ 836F6EF918BDC2190095E648 /* svs.c */, 83D0381724A4129A004CF90F /* swav.c */, 831BA6121EAC61A500CF89B0 /* sxd.c */, - 83709E031ECBC1A4005C03D3 /* ta_aac.c */, 83E7FD6425EF2B2400683FD2 /* tac.c */, 8373342E23F60D4100DE14DC /* tgc.c */, 836F6EFA18BDC2190095E648 /* thp.c */, @@ -2386,10 +2379,6 @@ 836F6F0918BDC2190095E648 /* wvs.c */, 83FF0EBB1E93282100C58054 /* wwise.c */, 839FBFF826C354E60016A78A /* wxd_wxh.c */, - 83AB8C741E8072A100086084 /* x360_ast.c */, - 831BA6151EAC61A500CF89B0 /* x360_cxs.c */, - 831BA6171EAC61A500CF89B0 /* x360_pasx.c */, - 836F6F0A18BDC2190095E648 /* x360_tra.c */, 837CEAE523487F2B00E62A4A /* xa_04sw.c */, 837CEADF23487F2A00E62A4A /* xa_xa30.c */, 832BF81521E0514A006F50F1 /* xa.c */, @@ -2402,14 +2391,12 @@ 8350C0541E071881009E0A93 /* xma.c */, 834FE0DC215C79EA000A5D3D /* xmd.c */, 837CEAEC23487F2C00E62A4A /* xmu.c */, - 837CEAE323487F2A00E62A4A /* xmv_valve.c */, 83031ED6243C510400C3F3E0 /* xnb_lz4mg.h */, 83031ED8243C510500C3F3E0 /* xnb_streamfile.h */, 830EBE112004656E0023AA10 /* xnb.c */, 832BF81921E0514A006F50F1 /* xopus.c */, 832BF80A21E05148006F50F1 /* xpcm.c */, 832BF80C21E05148006F50F1 /* xps.c */, - 83A8BAE225667AA7000F5F3F /* xse.c */, 83FC417226D3304D009A2022 /* xsh_xsd_xss.c */, 836F6F1218BDC2190095E648 /* xss.c */, 83AFABB923795201002F3947 /* xssb.c */, @@ -2423,6 +2410,7 @@ 83C7280222BC893A00678B4A /* xwma_konami_streamfile.h */, 83C7280B22BC893C00678B4A /* xwma_konami.c */, 832BF81621E0514A006F50F1 /* xwma.c */, + 837CEAE323487F2A00E62A4A /* xwv_valve.c */, 836F6F1418BDC2190095E648 /* ydsp.c */, 836F6F1518BDC2190095E648 /* zsd.c */, 832BF80E21E05149006F50F1 /* zsnd_streamfile.h */, @@ -2445,8 +2433,11 @@ 83D26A7C26E66DC2001A9475 /* util */ = { isa = PBXGroup; children = ( + 836DF620298F83F400CD0580 /* bitstream_msb.h */, 83D26A8026E66DC2001A9475 /* chunks.c */, 83D26A7E26E66DC2001A9475 /* chunks.h */, + 836DF621298F83F400CD0580 /* cri_keys.c */, + 836DF61F298F83F400CD0580 /* cri_keys.h */, 836F46B5282087A6005B9B87 /* cri_utf.c */, 836F46B6282087A6005B9B87 /* cri_utf.h */, 83B46FD42707FB9A00847FC9 /* endianness.h */, @@ -2524,6 +2515,7 @@ 83C7282722BC8C1500678B4A /* plugins.h in Headers */, 83256CC128666C620036D9C0 /* index.h in Headers */, 834FE0ED215C79ED000A5D3D /* fsb_interleave_streamfile.h in Headers */, + 836DF622298F83F400CD0580 /* cri_keys.h in Headers */, 8351F32E2212B57000A606E4 /* ubi_bao_streamfile.h in Headers */, 8349A9111FE6258200E26435 /* bar_streamfile.h in Headers */, 83256CE128666C620036D9C0 /* sample.h in Headers */, @@ -2540,7 +2532,6 @@ 83AA7F722519BFEA004C5298 /* vorbis_bitreader.h in Headers */, 83256CD628666C620036D9C0 /* newhuffman.h in Headers */, 834FE0BA215C798C000A5D3D /* ea_mt_decoder_utk.h in Headers */, - 83B46FD12707FB2100847FC9 /* at3plus_decoder.h in Headers */, 835C883722CC17BE001B4B3F /* ogg_vorbis_streamfile.h in Headers */, 837CEAFE23487F2C00E62A4A /* jstm_streamfile.h in Headers */, 832BF82021E0514B006F50F1 /* zsnd_streamfile.h in Headers */, @@ -2549,14 +2540,13 @@ 83031EDB243C510500C3F3E0 /* xnb_lz4mg.h in Headers */, 836F705418BDC2190095E648 /* streamfile.h in Headers */, 835B9B922730BF2D00F87EE3 /* hca_bf.h in Headers */, + 836DF623298F83F400CD0580 /* bitstream_msb.h in Headers */, 83256CDD28666C620036D9C0 /* l3tabs.h in Headers */, - 83A3F0761E3AD8B900D6A794 /* stack_alloc.h in Headers */, 8373342723F60CDC00DE14DC /* lrmd_streamfile.h in Headers */, 83C7281122BC893D00678B4A /* 9tav_streamfile.h in Headers */, 83256CD928666C620036D9C0 /* costabs.h in Headers */, 83C7280F22BC893D00678B4A /* xwb_xsb.h in Headers */, 8315868B26F586F900803A3A /* m2_psb.h in Headers */, - 83AA7F732519BFEA004C5298 /* mpeg_bitreader.h in Headers */, 83256CD428666C620036D9C0 /* icy.h in Headers */, 83256CDC28666C620036D9C0 /* icy2utf8.h in Headers */, 832FC36F278FAE3E0056A860 /* encrypted_mc161_streamfile.h in Headers */, @@ -2604,6 +2594,7 @@ 8373341923F60C7B00DE14DC /* g7221_decoder_lib_data.h in Headers */, 83256CCC28666C620036D9C0 /* init_layer12.h in Headers */, 83AFABBD23795202002F3947 /* ea_eaac_opus_streamfile.h in Headers */, + 836DF628298F864100CD0580 /* ahx_keys.h in Headers */, 83256CBF28666C620036D9C0 /* l12tabs.h in Headers */, 83256CCF28666C620036D9C0 /* synth_sse3d.h in Headers */, 83256CD528666C620036D9C0 /* fmt123.h in Headers */, @@ -2878,10 +2869,11 @@ 8349A90A1FE6258200E26435 /* sab.c in Sources */, 83AF2CC926226BA500538240 /* gcub.c in Sources */, 8306B08620984518000302D4 /* fadpcm_decoder.c in Sources */, - 83AB8C761E8072A100086084 /* x360_ast.c in Sources */, + 83AB8C761E8072A100086084 /* astb.c in Sources */, 834FE105215C79ED000A5D3D /* xmd.c in Sources */, 837CEADA23487E8300E62A4A /* acb.c in Sources */, 834FE0F6215C79ED000A5D3D /* derf.c in Sources */, + 836DF624298F83F400CD0580 /* cri_keys.c in Sources */, 83D20081248DDB770048BD24 /* sadl.c in Sources */, 836F6F8B18BDC2190095E648 /* genh.c in Sources */, 83C7281922BC893D00678B4A /* fsb5_fev.c in Sources */, @@ -2893,7 +2885,7 @@ 836F703C18BDC2190095E648 /* wii_bns.c in Sources */, 830EBE132004656E0023AA10 /* xnb.c in Sources */, 835027131ED119E000C25929 /* mta2_decoder.c in Sources */, - 83A8BAE725667AA8000F5F3F /* xse.c in Sources */, + 83A8BAE725667AA8000F5F3F /* sdrh.c in Sources */, 8306B0DB20984590000302D4 /* nxap.c in Sources */, 836F6FA718BDC2190095E648 /* nds_strm.c in Sources */, 8349A91A1FE6258200E26435 /* vxn.c in Sources */, @@ -2936,7 +2928,6 @@ 837CEAFB23487F2C00E62A4A /* ima.c in Sources */, 836F702D18BDC2190095E648 /* sfl.c in Sources */, 83D7318C1A749EEE00CA1366 /* g719_decoder.c in Sources */, - 836F701118BDC2190095E648 /* ps3_cps.c in Sources */, 8306B0DA20984590000302D4 /* ea_wve_au00.c in Sources */, 83A21F85201D8981000F04B9 /* atx.c in Sources */, 83A8BADF256679E3000F5F3F /* blocked_xwav.c in Sources */, @@ -2951,7 +2942,7 @@ 83AA7F812519C042004C5298 /* silence.c in Sources */, 834FE0B3215C798C000A5D3D /* acm_decoder_util.c in Sources */, 837CEA7A23487E2500E62A4A /* ffmpeg_decoder_utils.c in Sources */, - 837CEAF823487F2C00E62A4A /* xmv_valve.c in Sources */, + 837CEAF823487F2C00E62A4A /* xwv_valve.c in Sources */, 836F6F6718BDC2190095E648 /* acm.c in Sources */, 834FE0FD215C79ED000A5D3D /* vpk.c in Sources */, 8306B0DF20984590000302D4 /* ea_wve_ad10.c in Sources */, @@ -2986,7 +2977,6 @@ 836F6FEF18BDC2190095E648 /* ps2_pnb.c in Sources */, 836F6FCB18BDC2190095E648 /* ads.c in Sources */, 834FE108215C79ED000A5D3D /* hd3_bd3.c in Sources */, - 836F6FD318BDC2190095E648 /* ps2_ccc.c in Sources */, 83C7281C22BC893D00678B4A /* sfh.c in Sources */, 834FE0FC215C79ED000A5D3D /* vai.c in Sources */, 83D2007F248DDB770048BD24 /* mups.c in Sources */, @@ -3119,7 +3109,7 @@ 83A16D2B22D2ADE800B90C4C /* awb.c in Sources */, 831BA6191EAC61A500CF89B0 /* ogl.c in Sources */, 83709E061ECBC1A4005C03D3 /* mc3.c in Sources */, - 831BA61F1EAC61A500CF89B0 /* x360_cxs.c in Sources */, + 831BA61F1EAC61A500CF89B0 /* cxs.c in Sources */, 836F6FCD18BDC2190095E648 /* ps2_ass.c in Sources */, 8349A90B1FE6258200E26435 /* ps2_pcm.c in Sources */, 836F6F4A18BDC2190095E648 /* interleave.c in Sources */, @@ -3133,7 +3123,6 @@ 837CEAF223487F2C00E62A4A /* raw_pcm.c in Sources */, 836F6FA518BDC2190095E648 /* nds_rrds.c in Sources */, 836F702F18BDC2190095E648 /* spt_spd.c in Sources */, - 836F704618BDC2190095E648 /* x360_tra.c in Sources */, 834FE0F0215C79ED000A5D3D /* apc.c in Sources */, 836F6FFA18BDC2190095E648 /* spm.c in Sources */, 83C7281B22BC893D00678B4A /* strm_abylight.c in Sources */, @@ -3182,14 +3171,13 @@ 836F6FDB18BDC2190095E648 /* ps2_hsf.c in Sources */, 836F6FF618BDC2190095E648 /* ster.c in Sources */, 834FE10E215C79ED000A5D3D /* ahv.c in Sources */, - 8306B08420984518000302D4 /* at3plus_decoder.c in Sources */, 8349A90E1FE6258200E26435 /* scd_pcm.c in Sources */, 834FE0F9215C79ED000A5D3D /* wavebatch.c in Sources */, 836F6F9518BDC2190095E648 /* kraw.c in Sources */, 836F6FB718BDC2190095E648 /* ngc_ssm.c in Sources */, 8306B0E920984590000302D4 /* opus.c in Sources */, 832BF80021E050B7006F50F1 /* mpeg_custom_utils_eamp3.c in Sources */, - 83709E051ECBC1A4005C03D3 /* gtd.c in Sources */, + 83709E051ECBC1A4005C03D3 /* ghs.c in Sources */, 8306B0A420984552000302D4 /* segmented.c in Sources */, 83A21F86201D8981000F04B9 /* xwc.c in Sources */, 8306B0A620984552000302D4 /* blocked_ea_wve_ad10.c in Sources */, @@ -3208,14 +3196,14 @@ 836F6F3C18BDC2190095E648 /* xa_decoder.c in Sources */, 8317C24C26982CC1007DD0B8 /* sspr.c in Sources */, 832BF82521E0514B006F50F1 /* ogg_opus.c in Sources */, - 83709E091ECBC1A4005C03D3 /* ta_aac.c in Sources */, + 83709E091ECBC1A4005C03D3 /* aac_triace.c in Sources */, 836F6F9118BDC2190095E648 /* ios_psnd.c in Sources */, 836F700618BDC2190095E648 /* vgs_ps.c in Sources */, 834FE10F215C79ED000A5D3D /* sdf.c in Sources */, 834FE0FF215C79ED000A5D3D /* sscf.c in Sources */, 8373341A23F60C7B00DE14DC /* relic_decoder_mixfft.c in Sources */, 836F6FAA18BDC2190095E648 /* ngc_bh2pcm.c in Sources */, - 831BA6211EAC61A500CF89B0 /* x360_pasx.c in Sources */, + 831BA6211EAC61A500CF89B0 /* pasx.c in Sources */, 832BF82621E0514B006F50F1 /* nwav.c in Sources */, 836F6F3018BDC2190095E648 /* nds_procyon_decoder.c in Sources */, 8349A8E81FE6253900E26435 /* blocked_dec.c in Sources */, @@ -3238,6 +3226,7 @@ 83A21F88201D8981000F04B9 /* ogg_vorbis.c in Sources */, 837CEAF923487F2C00E62A4A /* xavs.c in Sources */, 836F6F8E18BDC2190095E648 /* halpst.c in Sources */, + 836DF627298F864100CD0580 /* cps.c in Sources */, 8319018128F67F1500B70711 /* ice_decoder_icelib.c in Sources */, 836F6FEE18BDC2190095E648 /* ps2_p2bt.c in Sources */, 836F702618BDC2190095E648 /* s14_sss.c in Sources */, @@ -3277,7 +3266,6 @@ 836F6FA218BDC2190095E648 /* naomi_adpcm.c in Sources */, 837CEAF123487F2C00E62A4A /* xvas.c in Sources */, 836F6FBF18BDC2190095E648 /* otm.c in Sources */, - 8306B0B420984552000302D4 /* blocked_tra.c in Sources */, 834FE0B8215C798C000A5D3D /* acm_decoder_decode.c in Sources */, 8399335F2591E8C1001855AF /* ifs.c in Sources */, 8373342A23F60CDC00DE14DC /* lrmd.c in Sources */, @@ -3305,7 +3293,7 @@ 8349A9151FE6258200E26435 /* ps2_xa2_rrp.c in Sources */, 836F703518BDC2190095E648 /* svs.c in Sources */, 8347C7492796D76700FA8A7D /* seek.c in Sources */, - 836F6FA318BDC2190095E648 /* naomi_spsd.c in Sources */, + 836F6FA318BDC2190095E648 /* spsd.c in Sources */, 8306B0B920984552000302D4 /* blocked_matx.c in Sources */, 83A21F7B201D895B000F04B9 /* blocked_xvag.c in Sources */, 836F6FBA18BDC2190095E648 /* ngc_ymf.c in Sources */, diff --git a/Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.c deleted file mode 100644 index 13a99ee0e..000000000 --- a/Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "coding.h" -#include "../util.h" - -#ifdef VGM_USE_MAIATRAC3PLUS -#include "maiatrac3plus.h" -#include "at3plus_decoder.h" - -maiatrac3plus_codec_data *init_at3plus() { - - maiatrac3plus_codec_data *data = malloc(sizeof(maiatrac3plus_codec_data)); - data->buffer = 0; - data->samples_discard = 0; - data->handle = Atrac3plusDecoder_openContext(); - if (!data->handle) goto fail; - - return data; - -fail: - return NULL; -} - -void decode_at3plus(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel) { - VGMSTREAMCHANNEL *ch = &vgmstream->ch[0]; - maiatrac3plus_codec_data *data = vgmstream->codec_data; - int i; - - int first_sample = vgmstream->samples_into_block % 2048; - - if (0 == channel && (0 == first_sample || data->samples_discard == first_sample)) - { - uint8_t code_buffer[0x8000]; - int blocks_to_decode = 1; - int max_blocks_to_decode = (ch->offset - ch->channel_start_offset) / vgmstream->interleave_block_size + 1; - if (data->samples_discard) blocks_to_decode = 8; - if (blocks_to_decode > max_blocks_to_decode) blocks_to_decode = max_blocks_to_decode; - while (blocks_to_decode--) { - ch->streamfile->read(ch->streamfile, code_buffer, ch->offset - blocks_to_decode * vgmstream->interleave_block_size, vgmstream->interleave_block_size); - Atrac3plusDecoder_decodeFrame(data->handle, code_buffer, vgmstream->interleave_block_size, &data->channels, (void**)&data->buffer); - } - data->samples_discard = 0; - } - - for (i = 0; i < samples_to_do; i++) { - outbuf[i*channelspacing] = data->buffer[(first_sample+i)*data->channels+channel]; - } - - if (0 == channel && 2048 == first_sample + samples_to_do) { - ch->offset += vgmstream->interleave_block_size; - } -} - - -void reset_at3plus(VGMSTREAM *vgmstream) { - maiatrac3plus_codec_data *data = vgmstream->codec_data; - if (!data) return; - - if (data->handle) - Atrac3plusDecoder_closeContext(data->handle); - data->handle = Atrac3plusDecoder_openContext(); - data->samples_discard = 0; -} - -void seek_at3plus(VGMSTREAM *vgmstream, int32_t num_sample) { - int blocks_to_skip = num_sample / 2048; - int samples_to_discard = num_sample % 2048; - maiatrac3plus_codec_data *data = (maiatrac3plus_codec_data *)(vgmstream->codec_data); - if (!data) return; - - vgmstream->loop_ch[0].offset = - vgmstream->loop_ch[0].channel_start_offset + - vgmstream->interleave_block_size * blocks_to_skip; - data->samples_discard = samples_to_discard; -} - -void free_at3plus(maiatrac3plus_codec_data *data) { - if (data) { - if (data->handle) Atrac3plusDecoder_closeContext(data->handle); - free(data); - } -} - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.h b/Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.h deleted file mode 100644 index 08093eff1..000000000 --- a/Frameworks/vgmstream/vgmstream/src/coding/at3plus_decoder.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _AT3PLUS_DECODER_H -#define _AT3PLUS_DECODER_H - -struct maiatrac3plus_codec_data { - sample_t* buffer; - int channels; - int samples_discard; - void* handle; -}; - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/coding/celt_fsb_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/celt_fsb_decoder.c index 402c9b1d6..09e548ee1 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/celt_fsb_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/celt_fsb_decoder.c @@ -21,15 +21,15 @@ struct celt_codec_data { int channel_mode; celt_lib_t version; - void *mode_handle; - void *decoder_handle; + void* mode_handle; + void* decoder_handle; }; /* FSB CELT, frames with custom header and standard data (API info from FMOD DLLs). * FMOD used various libcelt versions, thus some tweaks are needed for them to coexist. */ -celt_codec_data *init_celt_fsb(int channels, celt_lib_t version) { +celt_codec_data* init_celt_fsb(int channels, celt_lib_t version) { int error = 0, lib_version = 0; celt_codec_data* data = NULL; @@ -42,24 +42,24 @@ celt_codec_data *init_celt_fsb(int channels, celt_lib_t version) { switch(data->version) { case CELT_0_06_1: /* older FSB4 (FMOD ~4.33) */ - data->mode_handle = celt_0061_mode_create(FSB_CELT_INTERNAL_SAMPLE_RATE, data->channel_mode, FSB_CELT_SAMPLES_PER_FRAME, &error); + data->mode_handle = celt_mode_create_0061(FSB_CELT_INTERNAL_SAMPLE_RATE, data->channel_mode, FSB_CELT_SAMPLES_PER_FRAME, &error); if (!data->mode_handle || error != CELT_OK) goto fail; - error = celt_0061_mode_info(data->mode_handle, CELT_GET_BITSTREAM_VERSION, &lib_version); + error = celt_mode_info_0061(data->mode_handle, CELT_GET_BITSTREAM_VERSION, &lib_version); if (error != CELT_OK || lib_version != FSB_CELT_0_06_1_VERSION) goto fail; - data->decoder_handle = celt_0061_decoder_create(data->mode_handle); + data->decoder_handle = celt_decoder_create_0061(data->mode_handle); if (!data->decoder_handle) goto fail; break; case CELT_0_11_0: /* newer FSB4 (FMOD ~4.34), FSB5 */ - data->mode_handle = celt_0110_mode_create(FSB_CELT_INTERNAL_SAMPLE_RATE, FSB_CELT_SAMPLES_PER_FRAME, &error); /* "custom" and not ok? */ + data->mode_handle = celt_mode_create_0110(FSB_CELT_INTERNAL_SAMPLE_RATE, FSB_CELT_SAMPLES_PER_FRAME, &error); /* "custom" and not ok? */ if (!data->mode_handle || error != CELT_OK) goto fail; - error = celt_0110_mode_info(data->mode_handle, CELT_GET_BITSTREAM_VERSION, &lib_version); + error = celt_mode_info_0110(data->mode_handle, CELT_GET_BITSTREAM_VERSION, &lib_version); if (error != CELT_OK || lib_version != FSB_CELT_0_11_0_VERSION) goto fail; - data->decoder_handle = celt_0110_decoder_create_custom(data->mode_handle, data->channel_mode, &error); + data->decoder_handle = celt_decoder_create_custom_0110(data->mode_handle, data->channel_mode, &error); if (!data->decoder_handle || error != CELT_OK) goto fail; break; @@ -136,11 +136,11 @@ void decode_celt_fsb(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_ switch(data->version) { case CELT_0_06_1: - status = celt_0061_decode(data->decoder_handle, data_buffer,bytes, data->sample_buffer); + status = celt_decode_0061(data->decoder_handle, data_buffer,bytes, data->sample_buffer); break; case CELT_0_11_0: - status = celt_0110_decode(data->decoder_handle, data_buffer,bytes, data->sample_buffer, FSB_CELT_SAMPLES_PER_FRAME); + status = celt_decode_0110(data->decoder_handle, data_buffer,bytes, data->sample_buffer, FSB_CELT_SAMPLES_PER_FRAME); break; default: @@ -167,16 +167,16 @@ void reset_celt_fsb(celt_codec_data* data) { /* recreate decoder (mode should not change) */ switch(data->version) { case CELT_0_06_1: - if (data->decoder_handle) celt_0061_decoder_destroy(data->decoder_handle); + if (data->decoder_handle) celt_decoder_destroy_0061(data->decoder_handle); - data->decoder_handle = celt_0061_decoder_create(data->mode_handle); + data->decoder_handle = celt_decoder_create_0061(data->mode_handle); if (!data->decoder_handle) goto fail; break; case CELT_0_11_0: - if (data->decoder_handle) celt_0110_decoder_destroy(data->decoder_handle); + if (data->decoder_handle) celt_decoder_destroy_0110(data->decoder_handle); - data->decoder_handle = celt_0110_decoder_create_custom(data->mode_handle, data->channel_mode, NULL); + data->decoder_handle = celt_decoder_create_custom_0110(data->mode_handle, data->channel_mode, NULL); if (!data->decoder_handle) goto fail; break; @@ -211,13 +211,13 @@ void free_celt_fsb(celt_codec_data* data) { switch(data->version) { case CELT_0_06_1: - if (data->decoder_handle) celt_0061_decoder_destroy(data->decoder_handle); - if (data->mode_handle) celt_0061_mode_destroy(data->mode_handle); + if (data->decoder_handle) celt_decoder_destroy_0061(data->decoder_handle); + if (data->mode_handle) celt_mode_destroy_0061(data->mode_handle); break; case CELT_0_11_0: - if (data->decoder_handle) celt_0110_decoder_destroy(data->decoder_handle); - if (data->mode_handle) celt_0110_mode_destroy(data->mode_handle); + if (data->decoder_handle) celt_decoder_destroy_0110(data->decoder_handle); + if (data->mode_handle) celt_mode_destroy_0110(data->mode_handle); break; default: diff --git a/Frameworks/vgmstream/vgmstream/src/coding/coding.h b/Frameworks/vgmstream/vgmstream/src/coding/coding.h index 013a8adeb..430b0b57e 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/coding.h +++ b/Frameworks/vgmstream/vgmstream/src/coding/coding.h @@ -93,7 +93,9 @@ void decode_ulaw_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspac void decode_alaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_pcmfloat(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian); void decode_pcm24le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_pcm24be(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); int32_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample); +int32_t pcm24_bytes_to_samples(size_t bytes, int channels); int32_t pcm16_bytes_to_samples(size_t bytes, int channels); int32_t pcm8_bytes_to_samples(size_t bytes, int channels); @@ -473,6 +475,13 @@ typedef enum { MPEG_EAMP3 /* custom frame header + MPEG frame + PCM blocks */ } mpeg_custom_t; +typedef struct { + int type; + uint16_t key1; + uint16_t key2; + uint16_t key3; +} crikey_t; + /* config for the above modes */ typedef struct { int channels; /* max channels */ @@ -485,11 +494,7 @@ typedef struct { int encryption; /* encryption mode */ int big_endian; int skip_samples; - /* for AHX */ - int cri_type; - uint16_t cri_key1; - uint16_t cri_key2; - uint16_t cri_key3; + crikey_t crikey; /* for AHX */ } mpeg_custom_config; mpeg_codec_data* init_mpeg(STREAMFILE* sf, off_t start_offset, coding_t *coding_type, int channels); @@ -504,6 +509,7 @@ long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data* data); uint32_t mpeg_get_tag_size(STREAMFILE* sf, uint32_t offset, uint32_t header); int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info); +int test_ahx_key(STREAMFILE* sf, off_t offset, crikey_t* crikey); #endif @@ -540,18 +546,6 @@ void free_mp4_aac(mp4_aac_codec_data* data); #endif -#ifdef VGM_USE_MAIATRAC3PLUS -/* at3plus_decoder */ -typedef struct maiatrac3plus_codec_data maiatrac3plus_codec_data; - -maiatrac3plus_codec_data* init_at3plus(); -void decode_at3plus(VGMSTREAM* vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel); -void reset_at3plus(VGMSTREAM* vgmstream); -void seek_at3plus(VGMSTREAM* vgmstream, int32_t num_sample); -void free_at3plus(maiatrac3plus_codec_data* data); -#endif - - #ifdef VGM_USE_ATRAC9 /* atrac9_decoder */ typedef struct { @@ -627,8 +621,16 @@ STREAMFILE* ffmpeg_get_streamfile(ffmpeg_codec_data* data); /* ffmpeg_decoder_utils.c (helper-things) */ ffmpeg_codec_data* init_ffmpeg_atrac3_raw(STREAMFILE* sf, off_t offset, size_t data_size, int sample_count, int channels, int sample_rate, int block_align, int encoder_delay); ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* out_samples); +ffmpeg_codec_data* init_ffmpeg_atrac3plus_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_align, int encoder_delay); + ffmpeg_codec_data* init_ffmpeg_aac(STREAMFILE* sf, off_t offset, size_t size, int skip_samples); + ffmpeg_codec_data* init_ffmpeg_xwma(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int format, int channels, int sample_rate, int avg_bitrate, int block_size); +//TODO: make init_ffmpeg_xwma_fmt(be) too to pass fmt chunk? +ffmpeg_codec_data* init_ffmpeg_xma1_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int channels, int sample_rate, int stream_mode); +ffmpeg_codec_data* init_ffmpeg_xma2_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_size, int block_count); +ffmpeg_codec_data* init_ffmpeg_xma_chunk(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size); +ffmpeg_codec_data* init_ffmpeg_xma_chunk_split(STREAMFILE* sf_head, STREAMFILE* sf_data, uint32_t data_offset, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size); /* ffmpeg_decoder_custom_opus.c (helper-things) */ typedef struct { @@ -685,15 +687,6 @@ ffmpeg_codec_data* init_ffmpeg_mp4_custom_lyn(STREAMFILE* sf, mp4_custom_t* mp4) #endif -/* coding_utils */ -int ffmpeg_fmt_chunk_swap_endian(uint8_t* chunk, size_t chunk_size, uint16_t codec); -int ffmpeg_make_riff_atrac3plus(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay); -int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode); -int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size); -int ffmpeg_make_riff_xma_from_fmt_chunk(uint8_t* buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE* sf, int big_endian); -int ffmpeg_make_riff_xma2_from_xma2_chunk(uint8_t* buf, size_t buf_size, off_t xma2_offset, size_t xma2_size, size_t data_size, STREAMFILE* sf); -int ffmpeg_make_riff_xwma(uint8_t* buf, size_t buf_size, int codec, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align); - /* MS audio format's sample info (struct to avoid passing so much stuff, separate for reusing) */ typedef struct { /* input */ diff --git a/Frameworks/vgmstream/vgmstream/src/coding/coding_utils.c b/Frameworks/vgmstream/vgmstream/src/coding/coding_utils.c index 3cecf8762..f60f006f3 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/coding_utils.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/coding_utils.c @@ -5,20 +5,14 @@ /** * Various utils for formats that aren't handled their own decoder or meta - * - * ffmpeg_make_riff_* utils don't depend on FFmpeg, but rather, they make headers that FFmpeg - * can use (it doesn't understand all valid RIFF headers, nor the utils make 100% correct headers). */ - /* ******************************************** */ -/* INTERNAL UTILS */ +/* XMA PARSING */ /* ******************************************** */ -/** - * 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) - */ +/* 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(int64_t bit_offset, int num_bits, STREAMFILE* sf) { uint32_t num, mask; if (num_bits > 25) return -1; //??? @@ -32,377 +26,6 @@ static uint32_t read_bitsBE_b(int64_t bit_offset, int num_bits, STREAMFILE* sf) } -/* ******************************************** */ -/* FAKE RIFF HELPERS */ -/* ******************************************** */ -/* All helpers copy a RIFF header to buf and returns the number of bytes in buf or -1 when buf is not big enough */ - -int ffmpeg_make_riff_atrac3plus(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay) { - uint16_t codec_ATRAC3plus = 0xfffe; /* wave format extensible */ - size_t riff_size = 4+4+ 4 + 0x3c + 0x14 + 4+4; - - if (buf_size < riff_size) - return -1; - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); - - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, 0x34);/*fmt size*/ - put_16bitLE(buf+0x14, codec_ATRAC3plus); - put_16bitLE(buf+0x16, channels); - put_32bitLE(buf+0x18, sample_rate); - put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong) */ - put_32bitLE(buf+0x20, (int16_t)(block_align)); /* block align */ - - put_16bitLE(buf+0x24, 0x22); /* extra data size */ - put_16bitLE(buf+0x26, 0x0800); /* samples per block */ - put_32bitLE(buf+0x28, 0x0000003); /* unknown */ - put_32bitBE(buf+0x2c, 0xBFAA23E9); /* GUID1 */ - put_32bitBE(buf+0x30, 0x58CB7144); /* GUID2 */ - put_32bitBE(buf+0x34, 0xA119FFFA); /* GUID3 */ - put_32bitBE(buf+0x38, 0x01E4CE62); /* GUID4 */ - put_16bitBE(buf+0x3c, 0x0010); /* unknown */ - put_16bitBE(buf+0x3e, 0x0000); /* config */ //todo this varies with block size, but FFmpeg doesn't use it - put_32bitBE(buf+0x40, 0x00000000); /* empty */ - put_32bitBE(buf+0x44, 0x00000000); /* empty */ - - memcpy(buf+0x48, "fact", 4); - put_32bitLE(buf+0x4c, 0x0c); /* fact size */ - put_32bitLE(buf+0x50, sample_count); - put_32bitLE(buf+0x54, 0); /* unknown */ - put_32bitLE(buf+0x58, encoder_delay); - - memcpy(buf+0x5c, "data", 4); - put_32bitLE(buf+0x60, data_size); /* data size */ - - return riff_size; -} - -int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode) { - uint16_t codec_XMA1 = 0x0165; - size_t riff_size; - int streams, i; - - /* stream disposition: - * 0: default (ex. 5ch = 2ch + 2ch + 1ch = 3 streams) - * 1: lineal (ex. 5ch = 1ch + 1ch + 1ch + 1ch + 1ch = 5 streams), unusual but exists - * others: not seen (ex. maybe 5ch = 2ch + 1ch + 1ch + 1ch = 4 streams) */ - switch(stream_mode) { - case 0 : streams = (channels + 1) / 2; break; - case 1 : streams = channels; break; - default: return 0; - } - - riff_size = 4+4+ 4 + 0x14 + 0x14*streams + 4+4; - - if (buf_size < riff_size) - return -1; - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); - - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, 0xc + 0x14*streams);/*fmt size*/ - put_16bitLE(buf+0x14, codec_XMA1); - put_16bitLE(buf+0x16, 16); /* bits per sample */ - put_16bitLE(buf+0x18, 0x10D6); /* encoder options */ - put_16bitLE(buf+0x1a, 0); /* largest stream skip (wrong, unneeded) */ - put_16bitLE(buf+0x1c, streams); /* number of streams */ - put_8bit (buf+0x1e, 0); /* loop count */ - put_8bit (buf+0x1f, 2); /* version */ - - for (i = 0; i < streams; i++) { - int stream_channels; - uint32_t speakers; - off_t off = 0x20 + 0x14*i;/* stream riff offset */ - - if (stream_mode == 1) { - /* lineal */ - stream_channels = 1; - switch(i) { /* per stream, values observed */ - case 0: speakers = 0x0001; break;/* L */ - case 1: speakers = 0x0002; break;/* R */ - case 2: speakers = 0x0004; break;/* C */ - case 3: speakers = 0x0008; break;/* LFE */ - case 4: speakers = 0x0040; break;/* LB */ - case 5: speakers = 0x0080; break;/* RB */ - case 6: speakers = 0x0000; break;/* ? */ - case 7: speakers = 0x0000; break;/* ? */ - default: speakers = 0; - } - } - else { - /* with odd channels the last stream is mono */ - stream_channels = channels / streams + (channels%2 != 0 && i+1 != streams ? 1 : 0); - switch(i) { /* per stream, values from xmaencode */ - case 0: speakers = stream_channels == 1 ? 0x0001 : 0x0201; break;/* L R */ - case 1: speakers = stream_channels == 1 ? 0x0004 : 0x0804; break;/* C LFE */ - case 2: speakers = stream_channels == 1 ? 0x0040 : 0x8040; break;/* LB RB */ - case 3: speakers = stream_channels == 1 ? 0x0000 : 0x0000; break;/* somehow empty (maybe should use 0x2010 LS RS) */ - default: speakers = 0; - } - } - - put_32bitLE(buf+off+0x00, sample_rate*stream_channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ - put_32bitLE(buf+off+0x04, sample_rate); - put_32bitLE(buf+off+0x08, 0); /* loop start */ - put_32bitLE(buf+off+0x0c, 0); /* loop end */ - put_8bit (buf+off+0x10, 0); /* loop subframe */ - put_8bit (buf+off+0x11, stream_channels); - put_16bitLE(buf+off+0x12, speakers); - } - - /* xmaencode decoding rejects XMA1 without "seek" chunk, though it doesn't seem to use it - * (needs to be have entries but can be bogus, also generates seek for even small sounds) */ - - memcpy(buf+riff_size-4-4, "data", 4); - put_32bitLE(buf+riff_size-4, data_size); /* data size */ - - return riff_size; -} - -int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size) { - uint16_t codec_XMA2 = 0x0166; - size_t riff_size = 4+4+ 4 + 0x3c + 4+4; - size_t bytecount; - int streams; - uint32_t speakers; - - /* info from xma2defs.h, xact3wb.h and audiodefs.h */ - streams = (channels + 1) / 2; - switch (channels) { - case 1: speakers = 0x04; break; /* 1.0: FC */ - case 2: speakers = 0x01 | 0x02; break; /* 2.0: FL FR */ - case 3: speakers = 0x01 | 0x02 | 0x08; break; /* 2.1: FL FR LF */ - case 4: speakers = 0x01 | 0x02 | 0x10 | 0x20; break; /* 4.0: FL FR BL BR */ - case 5: speakers = 0x01 | 0x02 | 0x08 | 0x10 | 0x20; break; /* 4.1: FL FR LF BL BR */ - case 6: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20; break; /* 5.1: FL FR FC LF BL BR */ - case 7: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x0100; break; /* 6.1: FL FR FC LF BL BR BC */ - case 8: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80; break; /* 7.1: FL FR FC LF BL BR FLC FRC */ - default: speakers = 0; break; - } - - if (buf_size < riff_size) - return -1; - - bytecount = sample_count * channels * sizeof(sample); - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); - - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, 0x34);/*fmt size*/ - put_16bitLE(buf+0x14, codec_XMA2); - put_16bitLE(buf+0x16, channels); - put_32bitLE(buf+0x18, sample_rate); - put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ - put_16bitLE(buf+0x20, (int16_t)(channels*sizeof(sample))); /* block align */ - put_16bitLE(buf+0x22, 16); /* bits per sample */ - - put_16bitLE(buf+0x24, 0x22); /* extra data size */ - put_16bitLE(buf+0x26, streams); /* number of streams */ - put_32bitLE(buf+0x28, speakers); /* speaker position */ - put_32bitLE(buf+0x2c, bytecount); /* PCM samples */ - put_32bitLE(buf+0x30, block_size); /* XMA block size (can be zero, it's for seeking only) */ - /* (looping values not set, expected to be handled externally) */ - put_32bitLE(buf+0x34, 0); /* play begin */ - put_32bitLE(buf+0x38, 0); /* play length */ - put_32bitLE(buf+0x3c, 0); /* loop begin */ - put_32bitLE(buf+0x40, 0); /* loop length */ - put_8bit(buf+0x44, 0); /* loop count */ - put_8bit(buf+0x45, 4); /* encoder version */ - put_16bitLE(buf+0x46, block_count); /* blocks count (entries in seek table, can be zero) */ - - memcpy(buf+0x48, "data", 4); - put_32bitLE(buf+0x4c, data_size); /* data size */ - - return riff_size; -} - -/* Makes a XMA1/2 RIFF header for FFmpeg using a "fmt " chunk (XMAWAVEFORMAT or XMA2WAVEFORMATEX) as a base: - * Useful to preserve the stream layout */ -int ffmpeg_make_riff_xma_from_fmt_chunk(uint8_t* buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE* sf, int big_endian) { - size_t riff_size = 4+4+ 4 + 4+4+fmt_size + 4+4; - uint8_t chunk[0x100]; - - if (buf_size < riff_size || fmt_size > 0x100) - goto fail; - if (read_streamfile(chunk,fmt_offset,fmt_size, sf) != fmt_size) - goto fail; - - if (big_endian) { - int codec = read_16bitBE(fmt_offset,sf); - ffmpeg_fmt_chunk_swap_endian(chunk, fmt_size, codec); - } - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); - - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, fmt_size);/*fmt size*/ - memcpy(buf+0x14, chunk, fmt_size); - - memcpy(buf+0x14+fmt_size, "data", 4); - put_32bitLE(buf+0x14+fmt_size+4, data_size); /* data size */ - - return riff_size; - -fail: - return -1; -} - -/* Makes a XMA2 RIFF header for FFmpeg using a "XMA2" chunk (XMA2WAVEFORMAT) as a base. - * Useful to preserve the stream layout */ -int ffmpeg_make_riff_xma2_from_xma2_chunk(uint8_t* buf, size_t buf_size, off_t xma2_offset, size_t xma2_size, size_t data_size, STREAMFILE* sf) { - uint8_t chunk[0x100]; - size_t riff_size; - - riff_size = 4+4+ 4 + 4+4+xma2_size + 4+4; - if (buf_size < riff_size || xma2_size > 0x100) - goto fail; - if (read_streamfile(chunk,xma2_offset,xma2_size, sf) != xma2_size) - goto fail; - - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); - - memcpy(buf+0x0c, "XMA2", 4); - put_32bitLE(buf+0x10, xma2_size); - memcpy(buf+0x14, chunk, xma2_size); - - memcpy(buf+0x14+xma2_size, "data", 4); - put_32bitLE(buf+0x14+xma2_size+4, data_size); /* data size */ - - return riff_size; - -fail: - return -1; -} - -int ffmpeg_make_riff_xwma(uint8_t* buf, size_t buf_size, int codec, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align) { - size_t riff_size = 4+4+ 4 + 0x1a + 4+4; - - if (buf_size < riff_size) - return -1; - - /* XWMA encoder only allows a few channel/sample rate/bitrate combinations, - * but some create identical files with fake bitrate (1ch 22050hz at - * 20/48/192kbps are all 20kbps, with the exact same codec data). - * Decoder needs correct bitrate to work, so it's normalized here. */ - /* (may be removed once FFmpeg fixes this) */ - if (codec == 0x161) { /* WMAv2 only */ - int ch = channels; - int sr = sample_rate; - int br = avg_bps * 8; - - /* Must be a bug in MS's encoder, as later versions of xWMAEncode remove these bitrates */ - if (ch == 1) { - if (sr == 22050 && (br==48000 || br==192000)) - br = 20000; - else if (sr == 32000 && (br==48000 || br==192000)) - br = 20000; - else if (sr == 44100 && (br==96000 || br==192000)) - br = 48000; - } - else if (ch == 2) { - if (sr == 22050 && (br==48000 || br==192000)) - br = 32000; - else if (sr == 32000 && (br==192000)) - br = 48000; - } - - avg_bps = br / 8; - } - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "XWMA", 4); - - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, 0x12);/*fmt size*/ - put_16bitLE(buf+0x14, codec); - put_16bitLE(buf+0x16, channels); - put_32bitLE(buf+0x18, sample_rate); - put_32bitLE(buf+0x1c, avg_bps); /* average bytes per second, somehow vital for XWMA */ - put_16bitLE(buf+0x20, block_align); /* block align */ - put_16bitLE(buf+0x22, 16); /* bits per sample */ - put_16bitLE(buf+0x24, 0); /* extra size */ - /* here goes the "dpds" seek table, but it's optional and not needed by FFmpeg (and also buggy) */ - - memcpy(buf+0x26, "data", 4); - put_32bitLE(buf+0x2a, data_size); /* data size */ - - return riff_size; -} - - -int ffmpeg_fmt_chunk_swap_endian(uint8_t* chunk, size_t chunk_size, uint16_t codec) { - int i; - /* swap from LE to BE or the other way around, doesn't matter */ - switch(codec) { - case 0x165: { /* XMA1 */ - put_16bitLE(chunk + 0x00, get_16bitBE(chunk + 0x00));/*FormatTag*/ - put_16bitLE(chunk + 0x02, get_16bitBE(chunk + 0x02));/*BitsPerSample*/ - put_16bitLE(chunk + 0x04, get_16bitBE(chunk + 0x04));/*EncodeOptions*/ - put_16bitLE(chunk + 0x06, get_16bitBE(chunk + 0x06));/*LargestSkip*/ - put_16bitLE(chunk + 0x08, get_16bitBE(chunk + 0x08));/*NumStreams*/ - // put_8bit(chunk + 0x0a, get_8bit(chunk + 0x0a));/*LoopCount*/ - // put_8bit(chunk + 0x0b, get_8bit(chunk + 0x0b));/*Version*/ - for (i = 0xc; i < chunk_size; i += 0x14) { /* reverse endianness for each stream */ - put_32bitLE(chunk + i + 0x00, get_32bitBE(chunk + i + 0x00));/*PsuedoBytesPerSec*/ - put_32bitLE(chunk + i + 0x04, get_32bitBE(chunk + i + 0x04));/*SampleRate*/ - put_32bitLE(chunk + i + 0x08, get_32bitBE(chunk + i + 0x08));/*LoopStart*/ - put_32bitLE(chunk + i + 0x0c, get_32bitBE(chunk + i + 0x0c));/*LoopEnd*/ - // put_8bit(chunk + i + 0x10, get_8bit(chunk + i + 0x10));/*SubframeData*/ - // put_8bit(chunk + i + 0x11, get_8bit(chunk + i + 0x11));/*Channels*/ - put_16bitLE(chunk + i + 0x12, get_16bitBE(chunk + i + 0x12));/*ChannelMask*/ - } - break; - } - - case 0x166: { /* XMA2 */ - put_16bitLE(chunk + 0x00, get_16bitBE(chunk + 0x00));/*wFormatTag*/ - put_16bitLE(chunk + 0x02, get_16bitBE(chunk + 0x02));/*nChannels*/ - put_32bitLE(chunk + 0x04, get_32bitBE(chunk + 0x04));/*nSamplesPerSec*/ - put_32bitLE(chunk + 0x08, get_32bitBE(chunk + 0x08));/*nAvgBytesPerSec*/ - put_16bitLE(chunk + 0x0c, get_16bitBE(chunk + 0x0c));/*nBlockAlign*/ - put_16bitLE(chunk + 0x0e, get_16bitBE(chunk + 0x0e));/*wBitsPerSample*/ - put_16bitLE(chunk + 0x10, get_16bitBE(chunk + 0x10));/*cbSize*/ - put_16bitLE(chunk + 0x12, get_16bitBE(chunk + 0x12));/*NumStreams*/ - put_32bitLE(chunk + 0x14, get_32bitBE(chunk + 0x14));/*ChannelMask*/ - put_32bitLE(chunk + 0x18, get_32bitBE(chunk + 0x18));/*SamplesEncoded*/ - put_32bitLE(chunk + 0x1c, get_32bitBE(chunk + 0x1c));/*BytesPerBlock*/ - put_32bitLE(chunk + 0x20, get_32bitBE(chunk + 0x20));/*PlayBegin*/ - put_32bitLE(chunk + 0x24, get_32bitBE(chunk + 0x24));/*PlayLength*/ - put_32bitLE(chunk + 0x28, get_32bitBE(chunk + 0x28));/*LoopBegin*/ - put_32bitLE(chunk + 0x2c, get_32bitBE(chunk + 0x2c));/*LoopLength*/ - /* put_8bit(chunk + 0x30, get_8bit(chunk + 0x30));*//*LoopCount*/ - /* put_8bit(chunk + 0x31, get_8bit(chunk + 0x31));*//*EncoderVersion*/ - put_16bitLE(chunk + 0x32, get_16bitBE(chunk + 0x32));/*BlockCount*/ - break; - } - default: - goto fail; - } - - return 1; - -fail: - return 0; -} - - -/* ******************************************** */ -/* XMA PARSING */ -/* ******************************************** */ - static void ms_audio_parse_header(STREAMFILE* sf, 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 */ @@ -845,7 +468,11 @@ void xma_fix_raw_samples_ch(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t stream_o } } -#ifdef VGM_USE_FFMPEG + +#if 0 + //TODO: ffmpeg now handles internal frame encoder delay, but not correctly in all cases + // without this in most cases should be equivalent as before +//#ifdef VGM_USE_FFMPEG /* also fix FFmpeg, since we now know exact skips */ { ffmpeg_codec_data* data = vgmstream->codec_data; @@ -951,18 +578,17 @@ void xma2_parse_xma2_chunk(STREAMFILE* sf, off_t chunk_offset, int* out_channels int channels, sample_rate, loop_flag, num_samples, loop_start_sample, loop_end_sample; off_t offset; - xma2_chunk_version = read_8bit(chunk_offset+0x00,sf); - num_streams = read_8bit(chunk_offset+0x01,sf); + xma2_chunk_version = read_u8(chunk_offset+0x00,sf); + num_streams = read_u8(chunk_offset+0x01,sf); loop_start_sample = read_32bit(chunk_offset+0x04,sf); loop_end_sample = read_32bit(chunk_offset+0x08,sf); - loop_flag = (uint8_t)read_8bit(chunk_offset+0x03,sf) > 0 || loop_end_sample; /* rarely not set, encoder default */ + loop_flag = read_u8(chunk_offset+0x03,sf) > 0 || loop_end_sample; /* rarely not set, encoder default */ sample_rate = read_32bit(chunk_offset+0x0c,sf); /* may need loop end +1 */ offset = xma2_chunk_version == 3 ? 0x14 : 0x1C; num_samples = read_32bit(chunk_offset+offset+0x00,sf); - /* pcm_samples in original sample rate (not usable as file may be resampled) */ - /* pcm_samples = read_32bitBE(chunk_offset+offset+0x04,sf)*/ + //pcm_samples = read_32bitBE(chunk_offset+offset+0x04,sf) /* in original sample rate (not usable as file may be resampled) */ offset = xma2_chunk_version == 3 ? 0x20 : 0x28; channels = 0; /* channels is the sum of all streams */ diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c index 9b0e50c6a..35d013ded 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c @@ -389,7 +389,8 @@ ffmpeg_codec_data* init_ffmpeg_header_offset_subsong(STREAMFILE* sf, uint8_t* he if (data->skip_samples < 0) data->skip_samples = 0; -#if 0 //LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 64, 100) +#if 0 + //LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 64, 100) /* exposed before but not too reliable either */ else if (stream->start_skip_samples) /* samples to skip in the first packet */ data->skip_samples = stream->start_skip_samples; @@ -404,7 +405,8 @@ ffmpeg_codec_data* init_ffmpeg_header_offset_subsong(STREAMFILE* sf, uint8_t* he VGM_ASSERT(stream->codecpar->trailing_padding > 0, "FFMPEG: trailing_padding %i\n", (int)stream->codecpar->trailing_padding); VGM_ASSERT(stream->codecpar->seek_preroll > 0, "FFMPEG: seek_preroll %i\n", (int)stream->codecpar->seek_preroll);//seek delay: OPUS VGM_ASSERT(stream->start_time > 0, "FFMPEG: start_time %i\n", (int)stream->start_time); //delay -#if 0 //LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 64, 100) +#if 0 + //LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 64, 100) VGM_ASSERT(stream->first_discard_sample > 0, "FFMPEG: first_discard_sample %i\n", (int)stream->first_discard_sample); //padding: MP3 VGM_ASSERT(stream->last_discard_sample > 0, "FFMPEG: last_discard_sample %i\n", (int)stream->last_discard_sample); //padding: MP3 VGM_ASSERT(stream->skip_samples > 0, "FFMPEG: skip_samples %i\n", (int)stream->skip_samples); //delay: MP4 diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_custom_opus.c b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_custom_opus.c index d6b19169b..bdb4ca2b7 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_custom_opus.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_custom_opus.c @@ -500,11 +500,22 @@ static size_t make_opus_header(uint8_t* buf, int buf_size, opus_config *cfg) { size_t header_size = 0x13; int mapping_family = 0; - /* special multichannel config */ + /* Opus can't play a Nch file unless the channel mapping is properly configured (not implicit). + * A 8ch file may be 2ch+2ch+1ch+1ch+2ch; this is defined with a "channel mapping": + * - mapping family: + * 0 = standard (single stream mono/stereo, >2ch = error, and table MUST be ommited) + * 1 = standard multichannel (1..8ch), using Vorbis channel layout (needs table) + * 255 = undefined (1..255ch) application defined (needs table) + * - mapping table: + * - stream count: internal opus streams (>= 1), of 1/2ch + * - coupled count: internal stereo streams (<= streams) + * - mappings: one byte per channel with the channel position (0..Nch), or 255 (silence) + */ + + /* set mapping family */ if (cfg->channels > 2 || cfg->stream_count > 1) { - /* channel config: 0=standard (single stream mono/stereo), 1=vorbis, 255: not defined */ - mapping_family = 1; - header_size += 0x01+0x01+cfg->channels; + mapping_family = 1; //todo test 255 + header_size += 0x01 + 0x01 + cfg->channels; /* table size */ } if (cfg->skip < 0) { @@ -526,14 +537,15 @@ static size_t make_opus_header(uint8_t* buf, int buf_size, opus_config *cfg) { put_u16le(buf+0x10, 0); /* output gain */ put_u8 (buf+0x12, mapping_family); + /* set mapping table */ if (mapping_family > 0) { int i; - /* internal mono/stereo streams (N mono/stereo streams that make M channels) */ + /* total streams (mono/stereo) */ put_u8(buf+0x13, cfg->stream_count); - /* joint stereo streams (rest would be mono, so 6ch can be 2ch+2ch+1ch+1ch = 2 coupled in 4 streams */ + /* stereo streams (6ch can be 2ch+2ch+1ch+1ch = 2 coupled in 4 streams) */ put_u8(buf+0x14, cfg->coupled_count); - /* mapping per channel (order of channels, ex: 0x000104050203) */ + /* mapping per channel (order of channels, ex: 00 01 04 05 02 03) */ for (i = 0; i < cfg->channels; i++) { put_u8(buf+0x15+i, cfg->channel_mapping[i]); } diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c index 38fc0d38b..3765c6e75 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c @@ -2,47 +2,49 @@ #ifdef VGM_USE_FFMPEG +/* Helper inits for FFmpeg's codecs. RIFF utils make headers for FFmpeg (it doesn't understand all valid RIFF headers, + * nor the utils make 100% correct headers). */ + static int ffmpeg_make_riff_atrac3(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int joint_stereo, int encoder_delay) { - uint16_t codec_ATRAC3 = 0x0270; - size_t riff_size = 4+4+ 4 + 0x28 + 0x10 + 4+4; - if (buf_size < riff_size) - return -1; + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + 0x20) + (0x04 * 2 + 0x08) + (0x04 * 2); + if (buf_max > buf_size) + return 0; - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ + memcpy (buf+0x08, "WAVE", 0x04); - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, 0x20);/*fmt size*/ - put_16bitLE(buf+0x14, codec_ATRAC3); - put_16bitLE(buf+0x16, channels); - put_32bitLE(buf+0x18, sample_rate); - put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong) */ - put_32bitLE(buf+0x20, (int16_t)(block_align)); /* block align */ + memcpy (buf+0x0c, "fmt ", 0x04); + put_u32le(buf+0x10, 0x20); /* fmt size */ + put_u16le(buf+0x14, 0x0270); /* ATRAC3 codec */ + put_u16le(buf+0x16, channels); + put_u32le(buf+0x18, sample_rate); + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong) */ + put_u16le(buf+0x20, block_align); /* block align */ - put_16bitLE(buf+0x24, 0x0e); /* extra data size */ - put_16bitLE(buf+0x26, 1); /* unknown, always 1 */ - put_16bitLE(buf+0x28, 0x0800 * channels); /* unknown (some size? 0x1000=2ch, 0x0800=1ch) */ - put_16bitLE(buf+0x2a, 0); /* unknown, always 0 */ - put_16bitLE(buf+0x2c, joint_stereo ? 0x0001 : 0x0000); - put_16bitLE(buf+0x2e, joint_stereo ? 0x0001 : 0x0000); /* repeated? */ - put_16bitLE(buf+0x30, 1); /* unknown, always 1 (frame_factor?) */ - put_16bitLE(buf+0x32, 0); /* unknown, always 0 */ + put_u16le(buf+0x24, 0x0e); /* extra data size */ + put_u16le(buf+0x26, 1); /* unknown, always 1 */ + put_u16le(buf+0x28, 0x0800 * channels); /* unknown (some size? 0x1000=2ch, 0x0800=1ch) */ + put_u16le(buf+0x2a, 0); /* unknown, always 0 */ + put_u16le(buf+0x2c, joint_stereo ? 0x0001 : 0x0000); + put_u16le(buf+0x2e, joint_stereo ? 0x0001 : 0x0000); /* repeated? */ + put_u16le(buf+0x30, 1); /* unknown, always 1 (frame_factor?) */ + put_u16le(buf+0x32, 0); /* unknown, always 0 */ - memcpy(buf+0x34, "fact", 4); - put_32bitLE(buf+0x38, 0x8); /* fact size */ - put_32bitLE(buf+0x3c, sample_count); - put_32bitLE(buf+0x40, encoder_delay); + memcpy (buf+0x34, "fact", 0x04); + put_u32le(buf+0x38, 0x08); /* fact size */ + put_u32le(buf+0x3c, sample_count); + put_u32le(buf+0x40, encoder_delay); - memcpy(buf+0x44, "data", 4); - put_32bitLE(buf+0x48, data_size); /* data size */ + memcpy (buf+0x44, "data", 0x04); + put_u32le(buf+0x48, data_size); /* data size */ - return riff_size; + return buf_max; } ffmpeg_codec_data* init_ffmpeg_atrac3_raw(STREAMFILE* sf, off_t offset, size_t data_size, int sample_count, int channels, int sample_rate, int block_align, int encoder_delay) { - ffmpeg_codec_data *ffmpeg_data = NULL; + ffmpeg_codec_data* data = NULL; uint8_t buf[0x100]; int bytes; int joint_stereo = (block_align == 0x60*channels) && channels > 1; /* only lowest block size does joint stereo */ @@ -50,8 +52,8 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_raw(STREAMFILE* sf, off_t offset, size_t d /* create fake header + init ffmpeg + apply fixes to FFmpeg decoding */ bytes = ffmpeg_make_riff_atrac3(buf,sizeof(buf), sample_count, data_size, channels, sample_rate, block_align, joint_stereo, encoder_delay); - ffmpeg_data = init_ffmpeg_header_offset(sf, buf,bytes, offset,data_size); - if (!ffmpeg_data) goto fail; + data = init_ffmpeg_header_offset(sf, buf,bytes, offset,data_size); + if (!data) goto fail; /* unlike with RIFF ATRAC3 we don't set implicit delay, as raw ATRAC3 headers often give loop/samples * in offsets, so calcs are expected to be handled externally (presumably the game would call raw decoding API @@ -59,23 +61,23 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_raw(STREAMFILE* sf, off_t offset, size_t d /* encoder delay: encoder introduces some garbage (not always silent) samples to skip at the beginning (at least 1 frame) * FFmpeg doesn't set this, and even if it ever does it's probably better to force it for the implicit skip. */ - ffmpeg_set_skip_samples(ffmpeg_data, encoder_delay); + ffmpeg_set_skip_samples(data, encoder_delay); //ffmpeg_set_samples(sample_count); /* useful? */ /* invert ATRAC3: waveform is inverted vs official tools (not noticeable but for accuracy) */ if (is_at3) { - ffmpeg_set_invert_floats(ffmpeg_data); + ffmpeg_set_invert_floats(data); } - return ffmpeg_data; + return data; fail: - free_ffmpeg(ffmpeg_data); + free_ffmpeg(data); return NULL; } /* init ATRAC3/plus while adding some fixes */ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_samples) { - ffmpeg_codec_data *ffmpeg_data = NULL; + ffmpeg_codec_data* data = NULL; int is_at3 = 0, is_at3p = 0, codec; size_t riff_size; int fact_samples, skip_samples, implicit_skip; @@ -84,11 +86,11 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ /* some simplified checks just in case */ - if (read_32bitBE(offset + 0x00,sf) != 0x52494646) /* "RIFF" */ + if (!is_id32be(offset + 0x00,sf, "RIFF")) goto fail; - riff_size = read_32bitLE(offset + 0x04,sf) + 0x08; - codec = (uint16_t)read_16bitLE(offset + 0x14, sf); + riff_size = read_u32le(offset + 0x04,sf) + 0x08; + codec = read_u16le(offset + 0x14, sf); switch(codec) { case 0x0270: is_at3 = 1; break; case 0xFFFE: is_at3p = 1; break; @@ -98,20 +100,20 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ /* init ffmpeg + apply fixes to FFmpeg decoding (with these fixes should be * sample-accurate vs official tools, except usual +-1 float-to-pcm conversion) */ - ffmpeg_data = init_ffmpeg_offset(sf, offset, riff_size); - if (!ffmpeg_data) goto fail; + data = init_ffmpeg_offset(sf, offset, riff_size); + if (!data) goto fail; /* well behaved .at3 define "fact" but official tools accept files without it */ - if (find_chunk_le(sf,0x66616374,offset + 0x0c,0, &fact_offset, &fact_size)) { /* "fact" */ + if (find_chunk_le(sf, get_id32be("fact"), offset + 0x0c,0, &fact_offset, &fact_size)) { if (fact_size == 0x08) { /* early AT3 (mainly PSP games) */ - fact_samples = read_32bitLE(fact_offset + 0x00, sf); - skip_samples = read_32bitLE(fact_offset + 0x04, sf); /* base skip samples */ + fact_samples = read_s32le(fact_offset + 0x00, sf); + skip_samples = read_s32le(fact_offset + 0x04, sf); /* base skip samples */ } else if (fact_size == 0x0c) { /* late AT3 (mainly PS3 games and few PSP games) */ - fact_samples = read_32bitLE(fact_offset + 0x00, sf); + fact_samples = read_s32le(fact_offset + 0x00, sf); /* 0x04: base skip samples, ignored by decoder */ - skip_samples = read_32bitLE(fact_offset + 0x08, sf); /* skip samples with implicit skip of 184 added */ + skip_samples = read_s32le(fact_offset + 0x08, sf); /* skip samples with implicit skip of 184 added */ } else { VGM_LOG("ATRAC3: unknown fact size\n"); @@ -137,7 +139,7 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ implicit_skip = 69; } else if (is_at3p && fact_size == 0x08) { - implicit_skip = 184*2; + implicit_skip = 184 * 2; } else if (is_at3p && fact_size == 0x0c) { implicit_skip = 184; /* first 184 is already added to delay vs field at 0x08 */ @@ -151,38 +153,112 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ /* encoder delay: encoder introduces some garbage (not always silent) samples to skip at the beginning (at least 1 frame) * FFmpeg doesn't set this, and even if it ever does it's probably better to force it for the implicit skip. */ - ffmpeg_set_skip_samples(ffmpeg_data, skip_samples + implicit_skip); + ffmpeg_set_skip_samples(data, skip_samples + implicit_skip); //ffmpeg_set_samples(sample_count); /* useful? */ /* invert ATRAC3: waveform is inverted vs official tools (not noticeable but for accuracy) */ if (is_at3) { - ffmpeg_set_invert_floats(ffmpeg_data); + ffmpeg_set_invert_floats(data); } /* multichannel fix: LFE channel should be reordered on decode (ATRAC3Plus only, only 1/2/6/8ch exist): * - 6ch: FL FR FC BL BR LFE > FL FR FC LFE BL BR * - 8ch: FL FR FC BL BR SL SR LFE > FL FR FC LFE BL BR SL SR */ - if (is_at3p && ffmpeg_get_channels(ffmpeg_data) == 6) { + if (is_at3p && ffmpeg_get_channels(data) == 6) { /* LFE BR BL > LFE BL BR > same */ int channel_remap[] = { 0, 1, 2, 5, 5, 5, }; - ffmpeg_set_channel_remapping(ffmpeg_data, channel_remap); + ffmpeg_set_channel_remapping(data, channel_remap); } - else if (is_at3p && ffmpeg_get_channels(ffmpeg_data) == 8) { + else if (is_at3p && ffmpeg_get_channels(data) == 8) { /* LFE BR SL SR BL > LFE BL SL SR BR > LFE BL BR SR SL > LFE BL BR SL SR > same */ int channel_remap[] = { 0, 1, 2, 7, 7, 7, 7, 7}; - ffmpeg_set_channel_remapping(ffmpeg_data, channel_remap); + ffmpeg_set_channel_remapping(data, channel_remap); } if (p_samples) *p_samples = fact_samples; - return ffmpeg_data; + return data; fail: - free_ffmpeg(ffmpeg_data); + free_ffmpeg(data); return NULL; } + +static int ffmpeg_make_riff_atrac3plus(uint8_t* buf, int buf_size, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_align, int encoder_delay) { + + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + 0x34) + (0x04 * 2 + 0x0c) + (0x04 * 2); + if (buf_max > buf_size) + return 0; + + /* standard */ + int channel_layout = 0; + switch(channels) { + case 1: channel_layout = mapping_MONO; break; + case 2: channel_layout = mapping_STEREO; break; + case 3: channel_layout = mapping_2POINT1; break; + case 4: channel_layout = mapping_QUAD; break; + case 5: channel_layout = mapping_5POINT0; break; + case 6: channel_layout = mapping_5POINT1; break; + default: break; + } + + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); + memcpy (buf+0x08, "WAVE", 0x04); + + memcpy (buf+0x0c, "fmt ", 0x04); + put_u32le(buf+0x10, 0x34); + put_u16le(buf+0x14, 0xfffe); /* WAVEFORMATEXTENSIBLE */ + put_u16le(buf+0x16, channels); + put_u32le(buf+0x18, sample_rate); + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong) */ + put_u32le(buf+0x20, block_align); /* block align */ + + put_u16le(buf+0x24, 0x22); /* extra data size */ + put_u16le(buf+0x26, 0x0800); /* samples per block */ + put_u32le(buf+0x28, channel_layout); + + put_u32be(buf+0x2c, 0xBFAA23E9); /* GUID1 */ + put_u32be(buf+0x30, 0x58CB7144); /* GUID2 */ + put_u32be(buf+0x34, 0xA119FFFA); /* GUID3 */ + put_u32be(buf+0x38, 0x01E4CE62); /* GUID4 */ + put_u16be(buf+0x3c, 0x0010); /* unknown */ + put_u16be(buf+0x3e, 0x0000); /* unknown, atrac3plus config (varies with block size, FFmpeg doesn't use it) */ + put_u32be(buf+0x40, 0x00000000); /* reserved? */ + put_u32be(buf+0x44, 0x00000000); /* reserved? */ + + memcpy (buf+0x48, "fact", 0x04); + put_u32le(buf+0x4c, 0x0c); /* fact size */ + put_u32le(buf+0x50, sample_count); + put_u32le(buf+0x54, 0); /* unknown */ + put_u32le(buf+0x58, encoder_delay); + + memcpy (buf+0x5c, "data", 0x04); + put_u32le(buf+0x60, data_size); /* data size */ + + return buf_max; +} + +ffmpeg_codec_data* init_ffmpeg_atrac3plus_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_align, int encoder_delay) { + ffmpeg_codec_data* data = NULL; + uint8_t buf[0x100]; + int bytes; + + bytes = ffmpeg_make_riff_atrac3plus(buf,sizeof(buf), data_size, sample_count, channels, sample_rate, block_align, encoder_delay); + data = init_ffmpeg_header_offset(sf, buf, bytes, data_offset, data_size); + if (!data) goto fail; + + ffmpeg_set_skip_samples(data, encoder_delay); + + return data; +fail: + free_ffmpeg(data); + return NULL; +} + + ffmpeg_codec_data* init_ffmpeg_aac(STREAMFILE* sf, off_t offset, size_t size, int skip_samples) { ffmpeg_codec_data* data = NULL; @@ -203,34 +279,366 @@ fail: return NULL; } -//TODO: make init_ffmpeg_xwma_fmt(be) too to pass fmt chunk + +static int ffmpeg_make_riff_xwma(uint8_t* buf, size_t buf_size, uint32_t data_size, int format, int channels, int sample_rate, int avg_bps, int block_align) { + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + 0x12) + (0x04 * 2); + if (buf_max > buf_size) + return 0; + + /* XWMA encoder only allows a few channel/sample rate/bitrate combinations, + * but some create identical files with fake bitrate (1ch 22050hz at + * 20/48/192kbps are all 20kbps, with the exact same codec data). + * Decoder needs correct bitrate to work, so it's normalized here. */ + /* (may be removed once FFmpeg fixes this) */ + if (format == 0x161) { /* WMAv2 only */ + int ch = channels; + int sr = sample_rate; + int br = avg_bps * 8; + + /* Must be a bug in MS's encoder, as later versions of xWMAEncode remove these bitrates */ + if (ch == 1) { + if (sr == 22050 && (br==48000 || br==192000)) { + br = 20000; + } + else if (sr == 32000 && (br==48000 || br==192000)) + br = 20000; + else if (sr == 44100 && (br==96000 || br==192000)) + br = 48000; + } + else if (ch == 2) { + if (sr == 22050 && (br==48000 || br==192000)) + br = 32000; + else if (sr == 32000 && (br==192000)) + br = 48000; + } + + avg_bps = br / 8; + } + + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ + memcpy (buf+0x08, "XWMA", 0x04); + + memcpy (buf+0x0c, "fmt ", 0x04); + put_u32le(buf+0x10, 0x12); /* fmt size */ + put_u16le(buf+0x14, format); + put_u16le(buf+0x16, channels); + put_u32le(buf+0x18, sample_rate); + put_u32le(buf+0x1c, avg_bps); /* average bytes per second, somehow vital for XWMA */ + put_u16le(buf+0x20, block_align); /* block align */ + put_u16le(buf+0x22, 16); /* bits per sample */ + put_u16le(buf+0x24, 0); /* extra size */ + /* here goes the "dpds" seek table, but it's optional and not needed by FFmpeg (and also buggy) */ + + memcpy (buf+0x26, "data", 4); + put_u32le(buf+0x2a, data_size); + + return buf_max; +} ffmpeg_codec_data* init_ffmpeg_xwma(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int format, int channels, int sample_rate, int avg_bitrate, int block_size) { ffmpeg_codec_data* data = NULL; uint8_t buf[0x100]; int bytes; - bytes = ffmpeg_make_riff_xwma(buf, sizeof(buf), format, data_size, channels, sample_rate, avg_bitrate, block_size); + bytes = ffmpeg_make_riff_xwma(buf, sizeof(buf), data_size, format, channels, sample_rate, avg_bitrate, block_size); data = init_ffmpeg_header_offset(sf, buf,bytes, data_offset, data_size); if (!data) goto fail; - if (format == 0x161) { - int skip_samples = 0; + return data; +fail: + free_ffmpeg(data); + return NULL; +} - /* Skip WMA encoder delay, not specified in the flags or containers (ASF/XWMA), - * but verified compared to Microsoft's output. Seems to match frame_samples * 2 */ - if (sample_rate >= 32000) - skip_samples = 4096; - else if (sample_rate >= 22050) - skip_samples = 2048; - else if (sample_rate >= 8000) - skip_samples = 1024; - ffmpeg_set_skip_samples(data, skip_samples); +static int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t data_size, int channels, int sample_rate, int stream_mode) { + + /* stream disposition: + * 0: default (ex. 5ch = 2ch + 2ch + 1ch = 3 streams) + * 1: lineal (ex. 5ch = 1ch + 1ch + 1ch + 1ch + 1ch = 5 streams), unusual but exists + * others: not seen (ex. maybe 5ch = 2ch + 1ch + 1ch + 1ch = 4 streams) */ + int streams; + switch(stream_mode) { + case 0 : streams = (channels + 1) / 2; break; + case 1 : streams = channels; break; + default: return 0; } - //TODO WMAPro uses variable skips and is more complex - //TODO ffmpeg's WMA doesn't properly output trailing samples (ignored patch...) + int buf_max = (0x04 * 2 + 0x4) + (0x04 * 2 + 0x0c + 0x14 * streams) + (0x04 * 2); + if (buf_max > buf_size) + return 0; + + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ + memcpy (buf+0x08, "WAVE", 0x04); + + memcpy (buf+0x0c, "fmt ", 0x04); + put_u32le(buf+0x10, 0x0c + 0x14 * streams); /* fmt size */ + put_u16le(buf+0x14, 0x0165); /* XMA1 */ + put_u16le(buf+0x16, 16); /* bits per sample */ + put_u16le(buf+0x18, 0x10D6); /* encoder options */ + put_u16le(buf+0x1a, 0); /* largest stream skip (wrong, unneeded) */ + put_u16le(buf+0x1c, streams); /* number of streams */ + put_u8 (buf+0x1e, 0); /* loop count */ + put_u8 (buf+0x1f, 2); /* version */ + + for (int i = 0; i < streams; i++) { + int stream_channels; + uint32_t speakers; + off_t off = 0x20 + 0x14 * i; /* stream riff offset */ + + if (stream_mode == 1) { + /* lineal */ + stream_channels = 1; + switch(i) { /* per stream, values observed */ + case 0: speakers = 0x0001; break;/* L */ + case 1: speakers = 0x0002; break;/* R */ + case 2: speakers = 0x0004; break;/* C */ + case 3: speakers = 0x0008; break;/* LFE */ + case 4: speakers = 0x0040; break;/* LB */ + case 5: speakers = 0x0080; break;/* RB */ + case 6: speakers = 0x0000; break;/* ? */ + case 7: speakers = 0x0000; break;/* ? */ + default: speakers = 0; + } + } + else { + /* with odd channels the last stream is mono */ + stream_channels = channels / streams + (channels%2 != 0 && i+1 != streams ? 1 : 0); + switch(i) { /* per stream, values from xmaencode */ + case 0: speakers = stream_channels == 1 ? 0x0001 : 0x0201; break;/* L R */ + case 1: speakers = stream_channels == 1 ? 0x0004 : 0x0804; break;/* C LFE */ + case 2: speakers = stream_channels == 1 ? 0x0040 : 0x8040; break;/* LB RB */ + case 3: speakers = stream_channels == 1 ? 0x0000 : 0x0000; break;/* somehow empty (maybe should use 0x2010 LS RS) */ + default: speakers = 0; + } + } + + put_u32le(buf+off+0x00, sample_rate*stream_channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ + put_u32le(buf+off+0x04, sample_rate); + put_u32le(buf+off+0x08, 0); /* loop start */ + put_u32le(buf+off+0x0c, 0); /* loop end */ + put_u8 (buf+off+0x10, 0); /* loop subframe */ + put_u8 (buf+off+0x11, stream_channels); + put_u16le(buf+off+0x12, speakers); + } + + /* xmaencode decoding rejects XMA1 without "seek" chunk, though it doesn't seem to use it + * (needs to be have entries but can be bogus, also generates seek for even small sounds) */ + + memcpy (buf + buf_max - (0x04 * 2), "data", 0x04); + put_u32le(buf + buf_max - (0x04 * 1), data_size); + + return buf_max; +} + +ffmpeg_codec_data* init_ffmpeg_xma1_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int channels, int sample_rate, int stream_mode) { + ffmpeg_codec_data* data = NULL; + uint8_t buf[0x100]; + int bytes; + + bytes = ffmpeg_make_riff_xma1(buf, sizeof(buf), data_size, channels, sample_rate, stream_mode); + data = init_ffmpeg_header_offset(sf, buf, bytes, data_offset, data_size); + if (!data) goto fail; + + /* n5.1.2 XMA1 hangs on seeks near end (infinite loop), presumably due to missing flush in wmapro.c's ff_xma1_decoder + frame skip samples */ + ffmpeg_set_force_seek(data); + + return data; +fail: + free_ffmpeg(data); + return NULL; +} + + +static int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t data_size, int32_t sample_count, int channels, int sample_rate, int block_size, int block_count) { + size_t bytecount; + int streams; + uint32_t speakers; + + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + 0x34) + (0x04 * 2); + if (buf_max > buf_size) + return 0; + + /* info from xma2defs.h, xact3wb.h and audiodefs.h */ + streams = (channels + 1) / 2; + switch (channels) { + case 1: speakers = 0x04; break; /* 1.0: FC */ + case 2: speakers = 0x01 | 0x02; break; /* 2.0: FL FR */ + case 3: speakers = 0x01 | 0x02 | 0x08; break; /* 2.1: FL FR LF */ + case 4: speakers = 0x01 | 0x02 | 0x10 | 0x20; break; /* 4.0: FL FR BL BR */ + case 5: speakers = 0x01 | 0x02 | 0x08 | 0x10 | 0x20; break; /* 4.1: FL FR LF BL BR */ + case 6: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20; break; /* 5.1: FL FR FC LF BL BR */ + case 7: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x100; break; /* 6.1: FL FR FC LF BL BR BC */ + case 8: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80; break; /* 7.1: FL FR FC LF BL BR FLC FRC */ + default: speakers = 0; break; + } + + bytecount = sample_count * channels * sizeof(sample); + + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ + memcpy (buf+0x08, "WAVE", 0x04); + + memcpy (buf+0x0c, "fmt ", 0x04); + put_u32le(buf+0x10, 0x34); /* fmt size */ + put_u16le(buf+0x14, 0x0166); /* XMA2 */ + put_u16le(buf+0x16, channels); + put_u32le(buf+0x18, sample_rate); + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ + put_u16le(buf+0x20, (uint16_t)(channels * sizeof(sample))); /* block align */ + put_u16le(buf+0x22, 16); /* bits per sample */ + + put_u16le(buf+0x24, 0x22); /* extra data size */ + put_u16le(buf+0x26, streams); /* number of streams */ + put_u32le(buf+0x28, speakers); /* speaker position */ + put_u32le(buf+0x2c, bytecount); /* PCM samples */ + put_u32le(buf+0x30, block_size); /* XMA block size (can be zero, for seeking only) */ + /* (looping values not set, expected to be handled externally) */ + put_u32le(buf+0x34, 0); /* play begin */ + put_u32le(buf+0x38, 0); /* play length */ + put_u32le(buf+0x3c, 0); /* loop begin */ + put_u32le(buf+0x40, 0); /* loop length */ + put_u8 (buf+0x44, 0); /* loop count */ + put_u8 (buf+0x45, 4); /* encoder version */ + put_u16le(buf+0x46, block_count); /* blocks count (entries in seek table, can be zero) */ + + memcpy (buf+0x48, "data", 0x04); + put_u32le(buf+0x4c, data_size); /* data size */ + + return buf_max; +} + +ffmpeg_codec_data* init_ffmpeg_xma2_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_size, int block_count) { + ffmpeg_codec_data* data = NULL; + uint8_t buf[0x100]; + int bytes; + + /* seemingly not needed but just in case */ + if (block_size <= 0) + block_size = 0x8000; /* default */ + if (block_count <= 0) + block_count = (data_size / block_size) + (data_size % block_size != 0 ? 1 : 0); /* approx */ + + bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), data_size, sample_count, channels, sample_rate, block_size, block_count); + data = init_ffmpeg_header_offset(sf, buf, bytes, data_offset, data_size); + if (!data) goto fail; + + return data; +fail: + free_ffmpeg(data); + return NULL; +} + + +/* swap from LE to BE or the other way around */ +static int ffmpeg_fmt_chunk_swap_endian(uint8_t* chunk, uint32_t chunk_size, uint16_t codec) { + int i; + + switch(codec) { + case 0x6501: + case 0x0165: /* XMA1 */ + put_u16le(chunk + 0x00, get_u16be(chunk + 0x00)); /*FormatTag*/ + put_u16le(chunk + 0x02, get_u16be(chunk + 0x02)); /*BitsPerSample*/ + put_u16le(chunk + 0x04, get_u16be(chunk + 0x04)); /*EncodeOptions*/ + put_u16le(chunk + 0x06, get_u16be(chunk + 0x06)); /*LargestSkip*/ + put_u16le(chunk + 0x08, get_u16be(chunk + 0x08)); /*NumStreams*/ + // put_u8(chunk + 0x0a, get_u8(chunk + 0x0a)); /*LoopCount*/ + // put_u8(chunk + 0x0b, get_u8(chunk + 0x0b)); /*Version*/ + for (i = 0xc; i < chunk_size; i += 0x14) { /* reverse endianness for each stream */ + put_u32le(chunk + i + 0x00, get_u32be(chunk + i + 0x00)); /*PsuedoBytesPerSec*/ + put_u32le(chunk + i + 0x04, get_u32be(chunk + i + 0x04)); /*SampleRate*/ + put_u32le(chunk + i + 0x08, get_u32be(chunk + i + 0x08)); /*LoopStart*/ + put_u32le(chunk + i + 0x0c, get_u32be(chunk + i + 0x0c)); /*LoopEnd*/ + // put_u8(chunk + i + 0x10, get_u8(chunk + i + 0x10)); /*SubframeData*/ + // put_u8(chunk + i + 0x11, get_u8(chunk + i + 0x11)); /*Channels*/ + put_u16le(chunk + i + 0x12, get_u16be(chunk + i + 0x12)); /*ChannelMask*/ + } + break; + + case 0x6601: + case 0x0166: /* XMA2 */ + put_u16le(chunk + 0x00, get_u16be(chunk + 0x00)); /*wFormatTag*/ + put_u16le(chunk + 0x02, get_u16be(chunk + 0x02)); /*nChannels*/ + put_u32le(chunk + 0x04, get_u32be(chunk + 0x04)); /*nSamplesPerSec*/ + put_u32le(chunk + 0x08, get_u32be(chunk + 0x08)); /*nAvgBytesPerSec*/ + put_u16le(chunk + 0x0c, get_u16be(chunk + 0x0c)); /*nBlockAlign*/ + put_u16le(chunk + 0x0e, get_u16be(chunk + 0x0e)); /*wBitsPerSample*/ + put_u16le(chunk + 0x10, get_u16be(chunk + 0x10)); /*cbSize*/ + put_u16le(chunk + 0x12, get_u16be(chunk + 0x12)); /*NumStreams*/ + put_u32le(chunk + 0x14, get_u32be(chunk + 0x14)); /*ChannelMask*/ + put_u32le(chunk + 0x18, get_u32be(chunk + 0x18)); /*SamplesEncoded*/ + put_u32le(chunk + 0x1c, get_u32be(chunk + 0x1c)); /*BytesPerBlock*/ + put_u32le(chunk + 0x20, get_u32be(chunk + 0x20)); /*PlayBegin*/ + put_u32le(chunk + 0x24, get_u32be(chunk + 0x24)); /*PlayLength*/ + put_u32le(chunk + 0x28, get_u32be(chunk + 0x28)); /*LoopBegin*/ + put_u32le(chunk + 0x2c, get_u32be(chunk + 0x2c)); /*LoopLength*/ + // put_u8(chunk + 0x30, get_u8(chunk + 0x30)); /*LoopCount*/ + // put_u8(chunk + 0x31, get_u8(chunk + 0x31)); /*EncoderVersion*/ + put_u16le(chunk + 0x32, get_u16be(chunk + 0x32)); /*BlockCount*/ + break; + + default: + goto fail; + } + + return 1; +fail: + return 0; +} + + +/* Makes a XMA1/2 RIFF header using a "fmt " chunk (XMAWAVEFORMAT/XMA2WAVEFORMATEX) or "XMA2" chunk (XMA2WAVEFORMAT), as a base: + * Useful to preserve the stream layout */ +static int ffmpeg_make_riff_xma_chunk(STREAMFILE* sf, uint8_t* buf, int buf_size, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size, int* p_is_xma1) { + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + chunk_size) + (0x04 * 2); + if (buf_max > buf_size) + return 0; + + if (read_streamfile(buf+0x14, chunk_offset, chunk_size, sf) != chunk_size) + return 0; + + /* checks info from the chunk itself */ + int is_xma1 = 0; + int is_xma2_old = buf[0x14] == 0x03 || buf[0x14] == 0x04; + if (!is_xma2_old) { + uint16_t codec = get_u16le(buf+0x14); + int is_be = (codec > 0x1000); + if (is_be) + ffmpeg_fmt_chunk_swap_endian(buf+0x14, chunk_size, codec); + is_xma1 = codec == 0x0165 || codec == 0x6501; + } + + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2)+ data_size); /* riff size */ + memcpy (buf+0x08, "WAVE", 0x04); + memcpy (buf+0x0c, is_xma2_old ? "XMA2" : "fmt ", 0x04); + put_u32le(buf+0x10, chunk_size); + /* copied chunk in between */ + memcpy (buf+0x14 + chunk_size + 0x00, "data", 0x04); + put_u32le(buf+0x14 + chunk_size + 0x04, data_size); + + *p_is_xma1 = is_xma1; + return buf_max; +} + +ffmpeg_codec_data* init_ffmpeg_xma_chunk(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size) { + return init_ffmpeg_xma_chunk_split(sf, sf, data_offset, data_size, chunk_offset, chunk_size); +} + +ffmpeg_codec_data* init_ffmpeg_xma_chunk_split(STREAMFILE* sf_head, STREAMFILE* sf_data, uint32_t data_offset, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size) { + ffmpeg_codec_data* data = NULL; + uint8_t buf[0x100]; + int is_xma1 = 0; + + int bytes = ffmpeg_make_riff_xma_chunk(sf_head, buf, sizeof(buf), data_size, chunk_offset, chunk_size, &is_xma1); + data = init_ffmpeg_header_offset(sf_data, buf, bytes, data_offset, data_size); + if (!data) goto fail; + + /* n5.1.2 XMA1 hangs on seeks near end (infinite loop), presumably due to missing flush in wmapro.c's ff_xma1_decoder + frame skip samples */ + if (is_xma1) + ffmpeg_set_force_seek(data); return data; fail: diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ice_decoder_icelib.h b/Frameworks/vgmstream/vgmstream/src/coding/ice_decoder_icelib.h index bcfb40cdb..f7255f916 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ice_decoder_icelib.h +++ b/Frameworks/vgmstream/vgmstream/src/coding/ice_decoder_icelib.h @@ -26,9 +26,9 @@ typedef struct { int filebuf_size; /* custom IO */ - void* arg; + void* arg; int (*read)(void* dst, int size, int n, void* arg); - int (*seek)(void* arg, int offset, int whence); + int (*seek)(void* arg, int offset, int whence); } icesnd_callback_t; diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ahx.c b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ahx.c index 1398707dd..03da22858 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ahx.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ahx.c @@ -1,111 +1,223 @@ -#include "mpeg_decoder.h" - #ifdef VGM_USE_MPEG +#include "mpeg_decoder.h" +#include "../util/bitstream_msb.h" +#include "coding.h" + #define MPEG_AHX_EXPECTED_FRAME_SIZE 0x414 -static int ahx_decrypt_type08(uint8_t * buffer, mpeg_custom_config *config); +/* AHX is more or less VBR MP2 using a fixed header (0xFFF5E0C0) that sets frame size 0x414 (1ch, 160kbps, 22050Hz) + * but are typically much shorter (ignores padding), output sample rate is also ignored. + * + * MPEG1 Layer II (MP2) bitstream format for reference: + * - MPEG header, 32b + * - 'bit allocation' indexes (MP2's config determines bands and table with bit size per band, in AHX's case 30 bands and total 107 bits) + * - 16-bit CRC if set in header (never in AHX) + * - scale factor selection info (SCFSI), 2b per band/channel (if band has bit alloc set) + * - scale factors, bits depending on selection info (if band has bit alloc set) + * - quantized samples, bits depending on bit alloc info + * - padding (removed in AHX) + */ -/* writes data to the buffer and moves offsets, transforming AHX frames as needed */ -int mpeg_custom_parse_frame_ahx(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream) { - mpeg_custom_stream *ms = data->streams[num_stream]; - size_t current_data_size = 0; - size_t file_size = get_streamfile_size(stream->streamfile); - /* AHX has a 0xFFF5E0C0 header with frame size 0x414 (160kbps, 22050Hz) but they actually are much shorter */ +#define AHX_BANDS 30 +#define AHX_GRANULES 12 +static const uint8_t AHX_BITALLOC_TABLE[32] = { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; +static const uint8_t AHX_OFFSET_TABLE[5][16] = { + { 0 }, + { 0 }, + { 0, 1, 3, 4, }, + { 0, 1, 3, 4, 5, 6, 7, 8, }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } +}; +static const int8_t AHX_QBITS_TABLE[17] = { -5, -7, 3, -10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; - /* read supposed frame size first (to minimize reads) */ - ms->bytes_in_buffer = read_streamfile(ms->buffer, stream->offset, MPEG_AHX_EXPECTED_FRAME_SIZE, stream->streamfile); +/* Decrypts and tests a AHX frame with current by reading all bits, as wrong keys should go over size. Reverse engineered + * from CRI libs. (MPEG1 Layer II code abridged for AHX, which is always mono and has fixed bands/tables, some info from ahx2wav.c) */ +static int ahx_decrypt(uint8_t* buf, int curr_size, crikey_t* crikey) { + uint32_t bit_alloc[AHX_BANDS] = {0}; + uint32_t scfsi[AHX_BANDS] = {0}; + bitstream_t ib = {0}; + bitstream_t ob = {0}; - /* find actual frame size by looking for the next frame header */ - { - uint32_t current_header = get_u32be(ms->buffer); - int next_pos = 0x04; + bm_setup(&ib, buf, curr_size); /* frame */ + bm_setup(&ob, buf, curr_size); /* decrypted frame */ - while (next_pos <= MPEG_AHX_EXPECTED_FRAME_SIZE) { - uint32_t next_header = get_u32be(ms->buffer + next_pos); + /* MPEG header (fixed in AHX, otherwise layer/bitrate/channels sets bands+tables) */ + bm_skip(&ib, 32); + bm_skip(&ob, 32); - if (current_header == next_header) { - current_data_size = next_pos; - break; - } + /* read bit allocs for later */ + for (int i = 0; i < AHX_BANDS; i++) { + int ba_bits = AHX_BITALLOC_TABLE[i]; - /* AHXs end in a 0x0c footer (0x41485845 28632943 52490000 / "AHXE(c)CRI\0\0") */ - if (stream->offset + next_pos + 0x0c >= file_size) { - current_data_size = next_pos; - break; - } + bm_get (&ib, ba_bits, &bit_alloc[i]); + bm_skip(&ob, ba_bits); + } - next_pos++; + /* get first scalefactor info to decide key */ + if (bit_alloc[0]) { + bm_get (&ib, 2, &scfsi[0]); + bm_skip(&ob, 2); + } + + uint16_t key; + switch(scfsi[0]) { + case 1: key = crikey->key1; break; + case 2: key = crikey->key2; break; + case 3: key = crikey->key3; break; + default: key = 0; /* 0: no key (common in null frames) */ + } + + /* decrypt rest of scalefactors (only first ones are encrypted though) */ + for (int i = 1; i < AHX_BANDS; i++) { + if (bit_alloc[i]) { + bm_get (&ib, 2, &scfsi[i]); + scfsi[i] ^= (key & 3); + bm_put(&ob, 2, scfsi[i]); + } + key >>= 2; + } + + /* read scalefactors (past this point no need to decrypt/write frame) */ + for (int i = 0; i < AHX_BANDS; i++) { + if (bit_alloc[i] == 0) + continue; + + switch(scfsi[i]) { + case 0: bm_skip(&ib, 6 * 3); break; + case 1: + case 3: bm_skip(&ib, 6 * 2); break; + case 2: bm_skip(&ib, 6 * 1); break; + default: break; } } - if (current_data_size == 0 || current_data_size > ms->buffer_size || current_data_size > MPEG_AHX_EXPECTED_FRAME_SIZE) { - VGM_LOG("MPEG AHX: incorrect data_size 0x%x\n", current_data_size); + /* read quants */ + for (int gr = 0; gr < AHX_GRANULES; gr++) { + for (int i = 0; i < AHX_BANDS; i++) { + int ba_value = bit_alloc[i]; + if (ba_value == 0) + continue; + + int ba_bits = AHX_BITALLOC_TABLE[i]; + int qb_index = AHX_OFFSET_TABLE[ba_bits][ba_value - 1]; + int qbits = AHX_QBITS_TABLE[qb_index]; + + if (qbits < 0) + qbits = -qbits; + else + qbits = qbits * 3; /* 3 qs */ + + int ok = bm_skip(&ib, qbits); + if (!ok) goto fail; + } + } + + /* read padding */ + { + int bpos = bm_pos(&ib); + if (bpos % 8) { + bm_skip(&ib, 8 - (bpos % 8)); + } + } + + /* if file was properly read/decrypted this size should land in next frame header or near EOF */ + return bm_pos(&ib) / 8; +fail: + return 0; +} + + +/* writes data to the buffer and moves offsets, transforming AHX frames as needed */ +int mpeg_custom_parse_frame_ahx(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) { + mpeg_custom_stream *ms = data->streams[num_stream]; + size_t curr_size = 0; + size_t file_size = get_streamfile_size(stream->streamfile); + + + /* Find actual frame size by looking for the next frame header. Not very elegant but simpler, works with encrypted AHX, + * and possibly faster than reading frame size's bits with ahx_decrypt */ + { + ms->bytes_in_buffer = read_streamfile(ms->buffer, stream->offset, MPEG_AHX_EXPECTED_FRAME_SIZE + 0x04, stream->streamfile); + + uint32_t curr_header = get_u32be(ms->buffer); + int pos = 0x04; + while (pos <= MPEG_AHX_EXPECTED_FRAME_SIZE) { + + /* next sync test */ + if (ms->buffer[pos] == 0xFF) { + uint32_t next_header = get_u32be(ms->buffer + pos); + if (curr_header == next_header) { + curr_size = pos; + break; + } + } + + /* AHX footer (0x8001000C 41485845 28632943 52490000 = 0x8001 tag + size + "AHXE(c)CRI\0\0") */ + if (stream->offset + pos + 0x10 >= file_size) { + curr_size = pos; + break; + } + + pos++; + } + } + + if (curr_size == 0 || curr_size > ms->buffer_size || curr_size > MPEG_AHX_EXPECTED_FRAME_SIZE) { + VGM_LOG("MPEG AHX: incorrect data_size 0x%x\n", curr_size); goto fail; } /* 0-fill up to expected size to keep mpg123 happy */ - memset(ms->buffer + current_data_size, 0, MPEG_AHX_EXPECTED_FRAME_SIZE - current_data_size); + memset(ms->buffer + curr_size, 0, MPEG_AHX_EXPECTED_FRAME_SIZE - curr_size); ms->bytes_in_buffer = MPEG_AHX_EXPECTED_FRAME_SIZE; - - /* decrypt if needed */ - switch(data->config.encryption) { - case 0x00: break; - case 0x08: ahx_decrypt_type08(ms->buffer, &data->config); break; - default: - VGM_LOG("MPEG AHX: unknown encryption 0x%x\n", data->config.encryption); - break; /* garbled frame */ + /* decrypt if needed (only 0x08 is known but 0x09 is probably the same) */ + if (data->config.encryption == 0x08) { + ahx_decrypt(ms->buffer, curr_size, &data->config.crikey); } /* update offsets */ - stream->offset += current_data_size; - if (stream->offset + 0x0c >= file_size) - stream->offset = file_size; /* skip 0x0c footer to reach EOF (shouldn't happen normally) */ + stream->offset += curr_size; + if (stream->offset + 0x10 >= file_size) + stream->offset = file_size; /* skip footer to reach EOF (shouldn't happen normally) */ return 1; fail: return 0; } -/* Decrypts an AHX type 0x08 (keystring) encrypted frame. Algorithm by Thealexbarney */ -static int ahx_decrypt_type08(uint8_t * buffer, mpeg_custom_config *config) { - int i, index, encrypted_bits; - uint32_t value; - uint16_t current_key; - /* encryption 0x08 modifies a few bits every frame, here we decrypt and write to data buffer */ +#define AHX_KEY_BUFFER 0x2000 +#define AHX_KEY_TEST_FRAMES 15 /* wrong keys may work ok in some frames */ - /* derive keystring to 3 primes, using the type 0x08 method, and assign each an index of 1/2/3 (0=no key) */ - /* (externally done for now, see: https://github.com/Thealexbarney/VGAudio/blob/2.0/src/VGAudio/Codecs/CriAdx/CriAdxKey.cs) */ +/* check if current key ends properly in frame syncs */ +int test_ahx_key(STREAMFILE* sf, off_t offset, crikey_t* crikey) { + int bytes; + uint8_t buf[AHX_KEY_BUFFER]; + const int buf_size = sizeof(buf); + int pos = 0; + uint32_t base_sync, curr_sync; - /* read 2b from a bitstream offset to decrypt, and use it as an index to get the key. - * AHX encrypted bitstream starts at 107b (0x0d*8+3), every frame, and seem to always use index 2 */ - value = get_u32be(buffer + 0x0d); - index = (value >> (32-3-2)) & 0x03; - switch(index) { - case 0: current_key = 0; break; - case 1: current_key = config->cri_key1; break; - case 2: current_key = config->cri_key2; break; - case 3: current_key = config->cri_key3; break; - default: goto fail; + bytes = read_streamfile(buf, offset, buf_size, sf); + //if (bytes != buf_size) goto fail; /* possible in small AHX */ + + base_sync = get_u32be(buf + 0x00); + for (int i = 0; i < AHX_KEY_TEST_FRAMES; i++) { + + int size = ahx_decrypt(buf + pos, bytes, crikey); + if (size <= 0 || size >= bytes - 0x04) goto fail; + + bytes -= size; + pos += size; + + curr_sync = get_u32be(buf + pos); + if (curr_sync == 0x00800100) /* EOF tag */ + break; + if (base_sync != curr_sync) + goto fail; } - /* AHX for DC: 16b, normal: 6b (no idea, probably some Layer II field) */ - encrypted_bits = config->cri_type == 0x10 ? 16 : 6; - - /* decrypt next bitstream 2b pairs, up to 16b (max key size): - * - read 2b from bitstream (from higher to lower) - * - read 2b from key (from lower to higher) - * - XOR them to decrypt */ - for (i = 0; i < encrypted_bits; i+=2) { - uint32_t xor_2b = (current_key >> i) & 0x03; - value ^= ((xor_2b << (32-3-2-2)) >> i); - } - - /* write output */ - put_32bitBE(buffer + 0x0d, value); - return 1; fail: return 0; diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ealayer3.c b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ealayer3.c index 21f22e726..63c2abe6c 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ealayer3.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils_ealayer3.c @@ -1,5 +1,5 @@ #include "mpeg_decoder.h" -#include "mpeg_bitreader.h" +#include "../util/bitstream_msb.h" #ifdef VGM_USE_MPEG @@ -108,7 +108,7 @@ int mpeg_custom_setup_init_ealayer3(STREAMFILE* sf, off_t start_offset, mpeg_cod { ib.sf = sf; ib.offset = start_offset; - ib.is.buf = ib.buf; + bm_setup(&ib.is, ib.buf, 0); // filled later ok = ealayer3_parse_frame(data, -1, &ib, &eaf); if (!ok) goto fail; @@ -156,7 +156,7 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data* ib_0.sf = stream->streamfile; ib_0.offset = stream->offset; - ib_0.is.buf = ib_0.buf; + bm_setup(&ib_0.is, ib_0.buf, 0); // filled later ok = ealayer3_parse_frame(data, num_stream, &ib_0, &eaf_0); if (!ok) goto fail; @@ -199,7 +199,7 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data* ib_1.sf = stream->streamfile; ib_1.offset = stream->offset; - ib_1.is.buf = ib_1.buf; + bm_setup(&ib_1.is, ib_1.buf, 0); // filled later ok = ealayer3_parse_frame(data, num_stream, &ib_1, &eaf_1); if (!ok) goto fail; @@ -222,12 +222,12 @@ int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data* { bitstream_t os = {0}; - init_bitstream(&os, ms->buffer, ms->buffer_size); + bm_setup(&os, ms->buffer, ms->buffer_size); ok = ealayer3_rebuild_mpeg_frame(&ib_0.is, &eaf_0, &ib_1.is, &eaf_1, &os); if (!ok) goto fail; - ms->bytes_in_buffer = os.b_off / 8; /* wrote full MPEG frame, hopefully */ + ms->bytes_in_buffer = bm_pos(&os) / 8; /* wrote full MPEG frame, hopefully */ } return 1; @@ -267,8 +267,8 @@ static void fill_buf(ealayer3_buffer_t* ib, int bits) { //;VGM_LOG("filled: %lx + %x (b=%i, m=%i)\n", ib->offset, bytes_size, bits, (mod > 0 ? 8 - mod : 0)); - read_size = read_streamfile(ib->buf + ib->is.bufsize, ib->offset, bytes_size, ib->sf); - ib->is.bufsize += read_size; + read_size = read_streamfile(ib->buf + ib->is.bufsize, ib->offset, bytes_size, ib->sf); //TODO don't access internals + bm_fill(&ib->is, read_size); ib->offset += read_size; ib->leftover_bits = (mod > 0 ? 8 - mod : 0); } @@ -309,7 +309,7 @@ static int ealayer3_parse_frame_v1(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf, /* read EA-frame V1 header */ fill_buf(ib, 8); - rb_bits(is, 8,&eaf->v1_pcm_flag); + bm_get(is, 8,&eaf->v1_pcm_flag); eaf->pre_size = 1; /* 8b */ @@ -331,15 +331,15 @@ static int ealayer3_parse_frame_v1(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf, /* check PCM block */ if (eaf->v1_pcm_flag == 0xEE) { fill_buf(ib, 32); - rb_bits(is, 16,&eaf->v1_offset_samples); /* PCM block offset in the buffer */ - rb_bits(is, 16,&eaf->v1_pcm_samples); /* number of PCM samples, can be 0 */ + bm_get(is, 16,&eaf->v1_offset_samples); /* PCM block offset in the buffer */ + bm_get(is, 16,&eaf->v1_pcm_samples); /* number of PCM samples, can be 0 */ eaf->pre_size += 2+2; /* 16b+16b */ eaf->pcm_size = (2*eaf->v1_pcm_samples * channels_per_frame); if (is_v1b) { /* extra 32b in v1b */ fill_buf(ib, 32); - rb_bits(is, 32,&eaf->v1_pcm_unknown); + bm_get(is, 32,&eaf->v1_pcm_unknown); eaf->pre_size += 4; /* 32b */ @@ -363,19 +363,19 @@ static int ealayer3_parse_frame_v2(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf) /* read EA-frame V2 header */ fill_buf(ib, 16); - rb_bits(is, 1,&eaf->v2_extended_flag); - rb_bits(is, 1,&eaf->v2_stereo_flag); - rb_bits(is, 2,&eaf->v2_reserved); - rb_bits(is, 12,&eaf->v2_frame_size); + bm_get(is, 1,&eaf->v2_extended_flag); + bm_get(is, 1,&eaf->v2_stereo_flag); + bm_get(is, 2,&eaf->v2_reserved); + bm_get(is, 12,&eaf->v2_frame_size); eaf->pre_size = 2; /* 16b */ if (eaf->v2_extended_flag) { fill_buf(ib, 32); - rb_bits(is, 2,&eaf->v2_offset_mode); - rb_bits(is, 10,&eaf->v2_offset_samples); - rb_bits(is, 10,&eaf->v2_pcm_samples); - rb_bits(is, 10,&eaf->v2_common_size); + bm_get(is, 2,&eaf->v2_offset_mode); + bm_get(is, 10,&eaf->v2_offset_samples); + bm_get(is, 10,&eaf->v2_pcm_samples); + bm_get(is, 10,&eaf->v2_common_size); eaf->pre_size += 4; /* 32b */ } @@ -423,16 +423,16 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t* static const int channel_table[4] = { 2,2,2, 1 }; /* [channel_mode] */ bitstream_t* is = &ib->is; - off_t start_b_off = is->b_off; + off_t start_b_off = bm_pos(is); int i, fill_bits, others_2_bits; /* read main header */ fill_buf(ib, 8); - rb_bits(is, 2,&eaf->version_index); - rb_bits(is, 2,&eaf->sample_rate_index); - rb_bits(is, 2,&eaf->channel_mode); - rb_bits(is, 2,&eaf->mode_extension); + bm_get(is, 2,&eaf->version_index); + bm_get(is, 2,&eaf->sample_rate_index); + bm_get(is, 2,&eaf->channel_mode); + bm_get(is, 2,&eaf->mode_extension); /* check empty frame */ @@ -460,7 +460,7 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t* /* read side info */ fill_buf(ib, 1); - rb_bits(is, 1,&eaf->granule_index); + bm_get(is, 1,&eaf->granule_index); fill_bits = (eaf->mpeg1 && eaf->granule_index == 1) ? 4 * eaf->channels : 0; fill_bits = fill_bits + (12 + 32 + others_2_bits) * eaf->channels; @@ -468,21 +468,21 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t* if (eaf->mpeg1 && eaf->granule_index == 1) { for (i = 0; i < eaf->channels; i++) { - rb_bits(is, 4,&eaf->scfsi[i]); + bm_get(is, 4,&eaf->scfsi[i]); } } for (i = 0; i < eaf->channels; i++) { - rb_bits(is, 12,&eaf->main_data_size[i]); + bm_get(is, 12,&eaf->main_data_size[i]); /* divided in 47b=32+15 (MPEG1) or 51b=32+19 (MPEG2), arbitrarily */ - rb_bits(is, 32,&eaf->others_1[i]); - rb_bits(is, others_2_bits,&eaf->others_2[i]); + bm_get(is, 32,&eaf->others_1[i]); + bm_get(is, others_2_bits,&eaf->others_2[i]); } /* derived */ - eaf->data_offset_b = is->b_off; /* header size + above size */ - eaf->base_size_b = (is->b_off - start_b_off); /* above size without header */ + eaf->data_offset_b = bm_pos(is); /* header size + above size */ + eaf->base_size_b = (bm_pos(is) - start_b_off); /* above size without header */ for (i = 0; i < eaf->channels; i++) { eaf->data_size_b += eaf->main_data_size[i]; /* can be 0, meaning a micro EA-frame */ } @@ -490,7 +490,7 @@ static int ealayer3_parse_frame_common(ealayer3_buffer_t* ib, ealayer3_frame_t* eaf->padding_size_b = 8 - ((eaf->base_size_b+eaf->data_size_b) % 8); fill_buf(ib, eaf->data_size_b + eaf->padding_size_b); /* read MPEG data (not PCM block) */ - is->b_off += eaf->data_size_b + eaf->padding_size_b; + bm_skip(is, eaf->data_size_b + eaf->padding_size_b); eaf->common_size = (eaf->base_size_b + eaf->data_size_b + eaf->padding_size_b)/8; @@ -542,55 +542,55 @@ static int ealayer3_rebuild_mpeg_frame(bitstream_t* is_0, ealayer3_frame_t* eaf_ #endif /* write MPEG1/2 frame header */ - wb_bits(os, 11, 0x7FF); /* sync */ - wb_bits(os, 2, eaf_0->version_index); - wb_bits(os, 2, 0x01); /* layer III index */ - wb_bits(os, 1, 1); /* "no CRC" flag */ - wb_bits(os, 4, expected_bitrate_index); - wb_bits(os, 2, eaf_0->sample_rate_index); - wb_bits(os, 1, 0); /* padding */ - wb_bits(os, 1, 0); /* private */ - wb_bits(os, 2, eaf_0->channel_mode); - wb_bits(os, 2, eaf_0->mode_extension); - wb_bits(os, 1, 1); /* copyrighted */ - wb_bits(os, 1, 1); /* original */ - wb_bits(os, 2, 0); /* emphasis */ + bm_put(os, 11, 0x7FF); /* sync */ + bm_put(os, 2, eaf_0->version_index); + bm_put(os, 2, 0x01); /* layer III index */ + bm_put(os, 1, 1); /* "no CRC" flag */ + bm_put(os, 4, expected_bitrate_index); + bm_put(os, 2, eaf_0->sample_rate_index); + bm_put(os, 1, 0); /* padding */ + bm_put(os, 1, 0); /* private */ + bm_put(os, 2, eaf_0->channel_mode); + bm_put(os, 2, eaf_0->mode_extension); + bm_put(os, 1, 1); /* copyrighted */ + bm_put(os, 1, 1); /* original */ + bm_put(os, 2, 0); /* emphasis */ if (eaf_0->mpeg1) { int private_bits = (eaf_0->channels==1 ? 5 : 3); /* write MPEG1 side info */ - wb_bits(os, 9, 0); /* main data start (no bit reservoir) */ - wb_bits(os, private_bits, 0); + bm_put(os, 9, 0); /* main data start (no bit reservoir) */ + bm_put(os, private_bits, 0); for (i = 0; i < eaf_1->channels; i++) { - wb_bits(os, 4, eaf_1->scfsi[i]); /* saved in granule1 only */ + bm_put(os, 4, eaf_1->scfsi[i]); /* saved in granule1 only */ } for (i = 0; i < eaf_0->channels; i++) { /* granule0 */ - wb_bits(os, 12, eaf_0->main_data_size[i]); - wb_bits(os, 32, eaf_0->others_1[i]); - wb_bits(os, 47-32, eaf_0->others_2[i]); + bm_put(os, 12, eaf_0->main_data_size[i]); + bm_put(os, 32, eaf_0->others_1[i]); + bm_put(os, 47-32, eaf_0->others_2[i]); } for (i = 0; i < eaf_1->channels; i++) { /* granule1 */ - wb_bits(os, 12, eaf_1->main_data_size[i]); - wb_bits(os, 32, eaf_1->others_1[i]); - wb_bits(os, 47-32, eaf_1->others_2[i]); + bm_put(os, 12, eaf_1->main_data_size[i]); + bm_put(os, 32, eaf_1->others_1[i]); + bm_put(os, 47-32, eaf_1->others_2[i]); } /* write MPEG1 main data */ - is_0->b_off = eaf_0->data_offset_b; + bm_set(is_0, eaf_0->data_offset_b); for (i = 0; i < eaf_0->channels; i++) { /* granule0 */ for (j = 0; j < eaf_0->main_data_size[i]; j++) { - rb_bits(is_0, 1, &c); - wb_bits(os, 1, c); + bm_get(is_0, 1, &c); + bm_put(os, 1, c); } } - is_1->b_off = eaf_1->data_offset_b; + bm_set(is_1, eaf_1->data_offset_b); for (i = 0; i < eaf_1->channels; i++) { /* granule1 */ for (j = 0; j < eaf_1->main_data_size[i]; j++) { - rb_bits(is_1, 1, &c); - wb_bits(os, 1, c); + bm_get(is_1, 1, &c); + bm_put(os, 1, c); } } } @@ -598,43 +598,42 @@ static int ealayer3_rebuild_mpeg_frame(bitstream_t* is_0, ealayer3_frame_t* eaf_ int private_bits = (eaf_0->channels==1 ? 1 : 2); /* write MPEG2 side info */ - wb_bits(os, 8, 0); /* main data start (no bit reservoir) */ - wb_bits(os, private_bits, 0); + bm_put(os, 8, 0); /* main data start (no bit reservoir) */ + bm_put(os, private_bits, 0); for (i = 0; i < eaf_0->channels; i++) { - wb_bits(os, 12, eaf_0->main_data_size[i]); - wb_bits(os, 32, eaf_0->others_1[i]); - wb_bits(os, 51-32, eaf_0->others_2[i]); + bm_put(os, 12, eaf_0->main_data_size[i]); + bm_put(os, 32, eaf_0->others_1[i]); + bm_put(os, 51-32, eaf_0->others_2[i]); } /* write MPEG2 main data */ - is_0->b_off = eaf_0->data_offset_b; + bm_set(is_0, eaf_0->data_offset_b); for (i = 0; i < eaf_0->channels; i++) { for (j = 0; j < eaf_0->main_data_size[i]; j++) { - rb_bits(is_0, 1, &c); - wb_bits(os, 1, c); + bm_get(is_0, 1, &c); + bm_put(os, 1, c); } } } /* align to closest 8b */ - if (os->b_off % 8) { - int align_bits = 8 - (os->b_off % 8); - wb_bits(os, align_bits, 0); + if (bm_pos(os) % 8) { + int align_bits = 8 - (bm_pos(os) % 8); + bm_put(os, align_bits, 0); } - if (os->b_off/8 > expected_frame_size) { + if (bm_pos(os) / 8 > expected_frame_size) { /* bit reservoir! shouldn't happen with free bitrate, otherwise it's hard to fix as needs complex buffering/calcs */ - VGM_LOG("EAL3: written 0x%x but expected less than 0x%x\n", (uint32_t)(os->b_off/8), expected_frame_size); + VGM_LOG("EAL3: written 0x%x but expected less than 0x%x\n", (uint32_t)(bm_pos(os) / 8), expected_frame_size); } else { /* fill ancillary data (should be ignored, but 0x00 seems to improve mpg123's free bitrate detection) */ - memset(os->buf + os->b_off/8, 0x00, expected_frame_size - os->b_off/8); + memset(os->buf + bm_pos(os) / 8, 0x00, expected_frame_size - bm_pos(os) / 8); } - os->b_off = expected_frame_size*8; - + bm_set(os, expected_frame_size * 8); return 1; fail: @@ -835,7 +834,7 @@ static int ealayer3_skip_data(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, i for (i = 0; i < skips; i++) { ib.sf = stream->streamfile; ib.offset = stream->offset; - ib.is.buf = ib.buf; + bm_setup(&ib.is, ib.buf, 0); // filled later ok = ealayer3_parse_frame(data, num_stream, &ib, &eaf); if (!ok) goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c index 06b5c3a6f..c3de6cca6 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c @@ -207,6 +207,9 @@ static mpg123_handle* init_mpg123_handle(void) { mpg123_param(m,MPG123_REMOVE_FLAGS,MPG123_GAPLESS,0.0); /* wonky support */ mpg123_param(m,MPG123_RESYNC_LIMIT, -1, 0x2000); /* just in case, games shouldn't ever need this */ +#ifndef VGM_DEBUG_OUTPUT + mpg123_param(m, MPG123_ADD_FLAGS, MPG123_QUIET, 1); +#endif if (mpg123_open_feed(m) != MPG123_OK) { goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ogg_vorbis_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/ogg_vorbis_decoder.c index 5f8a43d63..21a202585 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ogg_vorbis_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ogg_vorbis_decoder.c @@ -43,6 +43,9 @@ ogg_vorbis_codec_data* init_ogg_vorbis(STREAMFILE* sf, off_t start, off_t size, callbacks.close_func = ov_close_func; callbacks.tell_func = ov_tell_func; + if (!size) + size = get_streamfile_size(sf) - start; + /* test if this is a proper Ogg Vorbis file, with the current (from init_x) STREAMFILE * (quick test without having to malloc first, though if one invoked this it'll probably success) */ { diff --git a/Frameworks/vgmstream/vgmstream/src/coding/pcm_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/pcm_decoder.c index 472c8b727..7a1e61e08 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/pcm_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/pcm_decoder.c @@ -216,6 +216,17 @@ void decode_pcmfloat(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspac } } +void decode_pcm24be(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { + int i; + int32_t sample_count; + + for (i=first_sample,sample_count=0; ioffset + i * 0x03; + int v = read_u8(offset+0x02, stream->streamfile) | (read_s16be(offset + 0x00, stream->streamfile) << 8); + outbuf[sample_count] = (v >> 8); + } +} + void decode_pcm24le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { int i; int32_t sample_count; @@ -232,6 +243,10 @@ int32_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample) { return ((int64_t)bytes * 8) / channels / bits_per_sample; } +int32_t pcm24_bytes_to_samples(size_t bytes, int channels) { + return pcm_bytes_to_samples(bytes, channels, 24); +} + int32_t pcm16_bytes_to_samples(size_t bytes, int channels) { return pcm_bytes_to_samples(bytes, channels, 16); } diff --git a/Frameworks/vgmstream/vgmstream/src/coding/sdx2_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/sdx2_decoder.c index ff6022c38..ff662cdc0 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/sdx2_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/sdx2_decoder.c @@ -33,32 +33,44 @@ static int16_t squares[256] = { 31250, 31752, 32258 }; -/* for (i=-128;i<128;i++) { double j = (i/2)/2.0; cubes[i+128] = floor(j*j*j); } */ +/* +for (uint16_t i = 0; i < 0x100; i += 1) { + int16_t v = i; + v -= 0x80; + v *= 0x100; + int32_t a = v; + a *= a; + a >>= 15; + a *= v; + a >>= 15; + cubes[i] = a; +} +*/ static int16_t cubes[256] = { - -32768,-31256,-31256,-29791,-29791,-28373,-28373,-27000,-27000,-25672,-25672, - -24389,-24389,-23149,-23149,-21952,-21952,-20797,-20797,-19683,-19683,-18610, - -18610,-17576,-17576,-16581,-16581,-15625,-15625,-14706,-14706,-13824,-13824, - -12978,-12978,-12167,-12167,-11391,-11391,-10648,-10648, -9938, -9938, -9261, - -9261, -8615, -8615, -8000, -8000, -7415, -7415, -6859, -6859, -6332, -6332, - -5832, -5832, -5359, -5359, -4913, -4913, -4492, -4492, -4096, -4096, -3724, - -3724, -3375, -3375, -3049, -3049, -2744, -2744, -2460, -2460, -2197, -2197, - -1953, -1953, -1728, -1728, -1521, -1521, -1331, -1331, -1158, -1158, -1000, - -1000, -857, -857, -729, -729, -614, -614, -512, -512, -422, -422, - -343, -343, -275, -275, -216, -216, -166, -166, -125, -125, -91, - -91, -64, -64, -43, -43, -27, -27, -16, -16, -8, -8, - -3, -3, -1, -1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 3, 3, 8, 8, 16, 16, 27, 27, 43, - 43, 64, 64, 91, 91, 125, 125, 166, 166, 216, 216, - 275, 275, 343, 343, 422, 422, 512, 512, 614, 614, 729, - 729, 857, 857, 1000, 1000, 1158, 1158, 1331, 1331, 1521, 1521, - 1728, 1728, 1953, 1953, 2197, 2197, 2460, 2460, 2744, 2744, 3049, - 3049, 3375, 3375, 3724, 3724, 4096, 4096, 4492, 4492, 4913, 4913, - 5359, 5359, 5832, 5832, 6332, 6332, 6859, 6859, 7415, 7415, 8000, - 8000, 8615, 8615, 9261, 9261, 9938, 9938, 10648, 10648, 11391, 11391, - 12167, 12167, 12978, 12978, 13824, 13824, 14706, 14706, 15625, 15625, 16581, - 16581, 17576, 17576, 18610, 18610, 19683, 19683, 20797, 20797, 21952, 21952, - 23149, 23149, 24389, 24389, 25672, 25672, 27000, 27000, 28373, 28373, 29791, - 29791, 31256, 31256 + -32768,-32006,-31256,-30518,-29791,-29077,-28373,-27681,-27000,-26331,-25673, + -25026,-24389,-23764,-23150,-22546,-21952,-21370,-20797,-20235,-19683,-19142, + -18610,-18088,-17576,-17074,-16582,-16099,-15625,-15161,-14707,-14261,-13824, + -13397,-12978,-12569,-12167,-11775,-11391,-11016,-10648,-10290, -9939, -9596, + -9261, -8935, -8616, -8304, -8000, -7704, -7415, -7134, -6859, -6592, -6332, + -6079, -5832, -5593, -5360, -5133, -4913, -4700, -4493, -4292, -4096, -3907, + -3724, -3547, -3375, -3210, -3049, -2894, -2744, -2600, -2461, -2327, -2197, + -2073, -1954, -1839, -1728, -1623, -1521, -1424, -1331, -1243, -1158, -1077, + -1000, -927, -858, -792, -729, -670, -615, -562, -512, -466, -422, + -382, -343, -308, -275, -245, -216, -191, -167, -145, -125, -108, + -92, -77, -64, -53, -43, -35, -27, -21, -16, -12, -8, + -6, -4, -2, -1, -1, -1, -1, 0, 0, 0, 0, + 1, 1, 3, 5, 8, 11, 15, 20, 27, 34, 42, + 52, 64, 76, 91, 107, 125, 144, 166, 190, 216, 244, + 274, 307, 343, 381, 421, 465, 512, 561, 614, 669, 729, + 791, 857, 926, 1000, 1076, 1157, 1242, 1331, 1423, 1520, 1622, + 1728, 1838, 1953, 2072, 2197, 2326, 2460, 2599, 2744, 2893, 3048, + 3209, 3375, 3546, 3723, 3906, 4096, 4291, 4492, 4699, 4913, 5132, + 5359, 5592, 5832, 6078, 6331, 6591, 6859, 7133, 7414, 7703, 8000, + 8303, 8615, 8934, 9261, 9595, 9938, 10289, 10648, 11015, 11390, 11774, + 12167, 12568, 12977, 13396, 13824, 14260, 14706, 15160, 15625, 16098, 16581, + 17073, 17576, 18087, 18609, 19141, 19683, 20234, 20796, 21369, 21952, 22545, + 23149, 23763, 24389, 25025, 25672, 26330, 27000, 27680, 28372, 29076, 29791, + 30517, 31255, 32005 }; static void decode_delta_exact(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int16_t * table) { diff --git a/Frameworks/vgmstream/vgmstream/src/decode.c b/Frameworks/vgmstream/vgmstream/src/decode.c index ad7e20467..0aefcf9b0 100644 --- a/Frameworks/vgmstream/vgmstream/src/decode.c +++ b/Frameworks/vgmstream/vgmstream/src/decode.c @@ -4,9 +4,6 @@ #include "coding/coding.h" #include "mixing.h" #include "plugins.h" -#ifdef VGM_USE_MAIATRAC3PLUS -#include "at3plus_decoder.h" -#endif /* custom codec handling, not exactly "decode" stuff but here to simplify adding new codecs */ @@ -94,12 +91,6 @@ void free_codec(VGMSTREAM* vgmstream) { } #endif -#ifdef VGM_USE_MAIATRAC3PLUS - if (vgmstream->coding_type == coding_AT3plus) { - free_at3plus(vgmstream->codec_data); - } -#endif - #ifdef VGM_USE_ATRAC9 if (vgmstream->coding_type == coding_ATRAC9) { free_atrac9(vgmstream->codec_data); @@ -188,12 +179,6 @@ void seek_codec(VGMSTREAM* vgmstream) { } #endif -#ifdef VGM_USE_MAIATRAC3PLUS - if (vgmstream->coding_type == coding_AT3plus) { - seek_at3plus(vgmstream, vgmstream->loop_current_sample); - } -#endif - #ifdef VGM_USE_ATRAC9 if (vgmstream->coding_type == coding_ATRAC9) { seek_atrac9(vgmstream, vgmstream->loop_current_sample); @@ -305,12 +290,6 @@ void reset_codec(VGMSTREAM* vgmstream) { } #endif -#ifdef VGM_USE_MAIATRAC3PLUS - if (vgmstream->coding_type == coding_AT3plus) { - reset_at3plus(vgmstream); - } -#endif - #ifdef VGM_USE_ATRAC9 if (vgmstream->coding_type == coding_ATRAC9) { reset_atrac9(vgmstream->codec_data); @@ -387,6 +366,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM* vgmstream) { case coding_ALAW: case coding_PCMFLOAT: case coding_PCM24LE: + case coding_PCM24BE: return 1; #ifdef VGM_USE_VORBIS case coding_OGG_VORBIS: @@ -557,10 +537,6 @@ int get_vgmstream_samples_per_frame(VGMSTREAM* vgmstream) { case coding_MP4_AAC: return ((mp4_aac_codec_data*)vgmstream->codec_data)->samples_per_frame; #endif -#ifdef VGM_USE_MAIATRAC3PLUS - case coding_AT3plus: - return 2048 - ((maiatrac3plus_codec_data*)vgmstream->codec_data)->samples_discard; -#endif #ifdef VGM_USE_ATRAC9 case coding_ATRAC9: return 0; /* varies with config data, usually 256 or 1024 */ @@ -619,6 +595,7 @@ int get_vgmstream_frame_size(VGMSTREAM* vgmstream) { case coding_PCMFLOAT: return 0x04; case coding_PCM24LE: + case coding_PCM24BE: return 0x03; case coding_SDX2: @@ -734,9 +711,6 @@ int get_vgmstream_frame_size(VGMSTREAM* vgmstream) { #ifdef VGM_USE_G719 case coding_G719: #endif -#ifdef VGM_USE_MAIATRAC3PLUS - case coding_AT3plus: -#endif #ifdef VGM_USE_FFMPEG case coding_FFmpeg: #endif @@ -925,6 +899,13 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_ } break; + case coding_PCM24BE: + for (ch = 0; ch < vgmstream->channels; ch++) { + decode_pcm24be(&vgmstream->ch[ch], buffer + ch, + vgmstream->channels, vgmstream->samples_into_block, samples_to_do); + } + break; + case coding_NDS_IMA: for (ch = 0; ch < vgmstream->channels; ch++) { decode_nds_ima(&vgmstream->ch[ch], buffer+ch, @@ -1304,13 +1285,6 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_ } break; #endif -#ifdef VGM_USE_MAIATRAC3PLUS - case coding_AT3plus: - for (ch = 0; ch < vgmstream->channels; ch++) { - decode_at3plus(vgmstream, buffer+ch, vgmstream->channels, samples_to_do, ch); - } - break; -#endif #ifdef VGM_USE_ATRAC9 case coding_ATRAC9: decode_atrac9(vgmstream, buffer, samples_to_do, vgmstream->channels); diff --git a/Frameworks/vgmstream/vgmstream/src/formats.c b/Frameworks/vgmstream/vgmstream/src/formats.c index 8a6836aa7..307030edd 100644 --- a/Frameworks/vgmstream/vgmstream/src/formats.c +++ b/Frameworks/vgmstream/vgmstream/src/formats.c @@ -97,6 +97,7 @@ static const char* extension_list[] = { "bar", "bcstm", "bcwav", + "bcv", //txth/reserved [The Bigs (PSP)] "bd3", "bdsp", "bfstm", @@ -109,6 +110,7 @@ static const char* extension_list[] = { "bik", "bika", //fake extension for .bik (to be removed) "bik2", + "binka", //FFmpeg/not parsed (BINK AUDIO) //"bin", //common "bk2", "bkr", //txth/reserved [P.N.03 (GC), Viewtiful Joe (GC)] @@ -132,7 +134,6 @@ static const char* extension_list[] = { "cads", "caf", "cbd2", - "ccc", //fake extension (to be removed) "cd", "cfn", //fake extension for CAF (renamed, to be removed?) "chd", //txth/reserved [Donkey Konga (GC), Star Fox Assault (GC)] @@ -184,6 +185,7 @@ static const char* extension_list[] = { "ezw", "fag", + "fcb", //FFmpeg/not parsed (BINK AUDIO) "fda", "ffw", "filp", @@ -438,7 +440,6 @@ static const char* extension_list[] = { "rws", "rwsd", "rwx", - "rxw", "rxx", //txth/reserved [Full Auto (X360)] "s14", @@ -498,6 +499,7 @@ static const char* extension_list[] = { "smp", "smpl", //fake extension/header id for .v0/v1 (renamed, to be removed) "smv", + "snb", "snd", "snds", "sng", @@ -756,6 +758,7 @@ static const coding_info coding_info_list[] = { {coding_ALAW, "8-bit a-Law"}, {coding_PCMFLOAT, "32-bit float PCM"}, {coding_PCM24LE, "24-bit Little Endian PCM"}, + {coding_PCM24BE, "24-bit Big Endian PCM"}, {coding_CRI_ADX, "CRI ADX 4-bit ADPCM"}, {coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM (fixed coefficients)"}, @@ -884,9 +887,6 @@ static const coding_info coding_info_list[] = { #ifdef VGM_USE_G719 {coding_G719, "ITU G.719 annex B (Polycom Siren 22)"}, #endif -#ifdef VGM_USE_MAIATRAC3PLUS - {coding_AT3plus, "ATRAC3plus"}, -#endif #ifdef VGM_USE_ATRAC9 {coding_ATRAC9, "ATRAC9"}, #endif @@ -937,7 +937,6 @@ static const layout_info layout_info_list[] = { {layout_blocked_vs_str, "blocked (STR VS)"}, {layout_blocked_rws, "blocked (RWS)"}, {layout_blocked_hwas, "blocked (HWAS)"}, - {layout_blocked_tra, "blocked (TRA)"}, {layout_blocked_ea_sns, "blocked (EA SNS)"}, {layout_blocked_awc, "blocked (AWC)"}, {layout_blocked_vgs, "blocked (VGS)"}, @@ -998,7 +997,6 @@ static const meta_info meta_info_list[] = { {meta_DSP_MSS, "Double DSP header stereo by .mss extension"}, {meta_DSP_GCM, "Double DSP header stereo by .gcm extension"}, {meta_IDSP_TT, "Traveller's Tales IDSP header"}, - {meta_RSTM_SPM, "Nintendo RSTM header (brstmspm)"}, {meta_RAW_PCM, "PC .raw raw header"}, {meta_PS2_VAGi, "Sony VAGi header"}, {meta_PS2_VAGp, "Sony VAGp header"}, @@ -1087,14 +1085,13 @@ static const meta_info meta_info_list[] = { {meta_DC_IDVI, "Capcom IDVI header"}, {meta_KRAW, "Geometry Wars: Galaxies KRAW header"}, {meta_NGC_YMF, "YMF DSP Header"}, - {meta_PS2_CCC, "CCC Header"}, {meta_FAG, "Radical .FAG Header"}, {meta_PS2_MIHB, "Sony MultiStream MIC header"}, {meta_DSP_WII_MUS, "mus header"}, {meta_WII_SNG, "SNG DSP Header"}, {meta_RSD, "Radical RSD header"}, {meta_DC_ASD, "ASD Header"}, - {meta_NAOMI_SPSD, "Naomi SPSD header"}, + {meta_SPSD, "Sega Naomi SPSD header"}, {meta_FFXI_BGW, "Square Enix .BGW header"}, {meta_FFXI_SPW, "Square Enix .SPW header"}, {meta_PS2_ASS, "SystemSoft .ASS header"}, @@ -1122,7 +1119,6 @@ static const meta_info meta_info_list[] = { {meta_PS2_P2BT, "Pop'n'Music 7 Header"}, {meta_PS2_GBTS, "Pop'n'Music 9 Header"}, {meta_NGC_DSP_IADP, "IADP Header"}, - {meta_RSTM_shrunken, "Nintendo RSTM header, corrupted by Atlus"}, {meta_RIFF_WAVE_MWV, "RIFF WAVE header with .mwv flavoring"}, {meta_FFCC_STR, "Final Fantasy: Crystal Chronicles STR header"}, {meta_SAT_BAKA, "Konami BAKA header"}, @@ -1195,7 +1191,7 @@ static const meta_info meta_info_list[] = { {meta_DSP_DSPW, "Capcom DSPW header"}, {meta_PS2_JSTM, "JSTM Header"}, {meta_XVAG, "Sony XVAG header"}, - {meta_PS3_CPS, "tri-Crescendo CPS Header"}, + {meta_CPS, "tri-Crescendo CPS Header"}, {meta_SQEX_SCD, "Square-Enix SCD header"}, {meta_NGC_NST_DSP, "Animaniacs NST header"}, {meta_BAF, "Bizarre Creations .baf header"}, @@ -1204,7 +1200,6 @@ static const meta_info meta_info_list[] = { {meta_SGXD, "Sony SGXD header"}, {meta_WII_RAS, "RAS header"}, {meta_SPM, "Square SPM header"}, - {meta_X360_TRA, "Terminal Reality .TRA raw header"}, {meta_VGS_PS, "Princess Soft VGS header"}, {meta_PS2_IAB, "Runtime .IAB header"}, {meta_VS_STR, "Square .VS STR* header"}, @@ -1244,18 +1239,18 @@ static const meta_info meta_info_list[] = { {meta_PS2_VDS_VDM, "Procyon Studio VDS/VDM header"}, {meta_FFMPEG, "FFmpeg supported format"}, {meta_FFMPEG_faulty, "FFmpeg supported format (check log)"}, - {meta_X360_CXS, "tri-Crescendo CXS header"}, + {meta_CXS, "tri-Crescendo CXS header"}, {meta_AKB, "Square-Enix AKB header"}, - {meta_X360_PASX, "Premium Agency PASX header"}, + {meta_PASX, "Premium Agency PASX header"}, {meta_XMA_RIFF, "Microsoft XMA RIFF header"}, - {meta_X360_AST, "Capcom AST (X360) header"}, + {meta_ASTB, "Capcom ASTB header"}, {meta_WWISE_RIFF, "Audiokinetic Wwise RIFF header"}, {meta_UBI_RAKI, "Ubisoft RAKI header"}, {meta_SXD, "Sony SXD header"}, {meta_OGL, "Shin'en OGL header"}, {meta_MC3, "Paradigm MC3 header"}, - {meta_GTD, "GTD/GHS header"}, - {meta_TA_AAC, "tri-Ace AAC header"}, + {meta_GHS, "Hexadrive GHS/S_P_STH header"}, + {meta_AAC_TRIACE, "tri-Ace AAC header"}, {meta_MTA2, "Konami MTA2 header"}, {meta_NGC_ULW, "Criterion ULW raw header"}, {meta_XA_XA30, "Reflections XA30 header"}, @@ -1369,7 +1364,7 @@ static const meta_info meta_info_list[] = { {meta_PSF, "Pivotal PSF header"}, {meta_DSP_ITL_i, "Infernal .ITL DSP header"}, {meta_IMA, "Blitz Games .IMA header"}, - {meta_XMV_VALVE, "Valve XMV header"}, + {meta_XWV_VALVE, "Valve XWV header"}, {meta_UBI_HX, "Ubisoft HXx header"}, {meta_BMP_KONAMI, "Konami BMP header"}, {meta_ISB, "Creative ISACT header"}, diff --git a/Frameworks/vgmstream/vgmstream/src/layout/blocked.c b/Frameworks/vgmstream/vgmstream/src/layout/blocked.c index dff0e4967..395af40ea 100644 --- a/Frameworks/vgmstream/vgmstream/src/layout/blocked.c +++ b/Frameworks/vgmstream/vgmstream/src/layout/blocked.c @@ -159,9 +159,6 @@ void block_update(off_t block_offset, VGMSTREAM* vgmstream) { case layout_blocked_bdsp: block_update_bdsp(block_offset,vgmstream); break; - case layout_blocked_tra: - block_update_tra(block_offset,vgmstream); - break; case layout_blocked_ps2_iab: block_update_ps2_iab(block_offset,vgmstream); break; diff --git a/Frameworks/vgmstream/vgmstream/src/layout/blocked_tra.c b/Frameworks/vgmstream/vgmstream/src/layout/blocked_tra.c deleted file mode 100644 index db29fe8ed..000000000 --- a/Frameworks/vgmstream/vgmstream/src/layout/blocked_tra.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "layout.h" -#include "../vgmstream.h" - -/* set up for the block at the given offset (first 32bytes is useless for decoding) */ -void block_update_tra(off_t block_offset, VGMSTREAM * vgmstream) { - int i; - - vgmstream->current_block_offset = block_offset; - vgmstream->current_block_size = 0x400; - vgmstream->next_block_offset = vgmstream->current_block_offset+vgmstream->current_block_size+8; - vgmstream->current_block_size/=vgmstream->channels; - - for (i=0;ichannels;i++) { - vgmstream->ch[i].offset = vgmstream->current_block_offset+(vgmstream->current_block_size*i)+0x4*(i+1); - - } -} diff --git a/Frameworks/vgmstream/vgmstream/src/layout/layout.h b/Frameworks/vgmstream/vgmstream/src/layout/layout.h index 7accda7e4..971143eb5 100644 --- a/Frameworks/vgmstream/vgmstream/src/layout/layout.h +++ b/Frameworks/vgmstream/vgmstream/src/layout/layout.h @@ -31,7 +31,6 @@ void block_update_ivaud(off_t block_offset, VGMSTREAM* vgmstream); void block_update_ea_swvr(off_t block_offset, VGMSTREAM* vgmstream); void block_update_adm(off_t block_offset, VGMSTREAM* vgmstream); void block_update_bdsp(off_t block_offset, VGMSTREAM* vgmstream); -void block_update_tra(off_t block_offset, VGMSTREAM* vgmstream); void block_update_ps2_iab(off_t block_offset, VGMSTREAM* vgmstream); void block_update_vs_str(off_t block_offset, VGMSTREAM* vgmstream); void block_update_rws(off_t block_offset, VGMSTREAM* vgmstream); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ta_aac.c b/Frameworks/vgmstream/vgmstream/src/meta/aac_triace.c similarity index 97% rename from Frameworks/vgmstream/vgmstream/src/meta/ta_aac.c rename to Frameworks/vgmstream/vgmstream/src/meta/aac_triace.c index c8eab4119..95986a44d 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ta_aac.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/aac_triace.c @@ -15,28 +15,28 @@ typedef struct { int32_t loop_end; int loop_flag; - off_t stream_offset; - off_t stream_size; - off_t extra_offset; + uint32_t stream_offset; + uint32_t stream_size; + uint32_t extra_offset; - off_t name_offset; + uint32_t name_offset; } aac_header; static int parse_aac(STREAMFILE* sf, aac_header* aac); /* AAC - tri-Ace (ASKA engine) Audio Container */ -VGMSTREAM* init_vgmstream_ta_aac(STREAMFILE* sf) { +VGMSTREAM* init_vgmstream_aac_triace(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; aac_header aac = {0}; /* checks */ + if (!is_id32be(0x00, sf, "AAC ") && !is_id32le(0x00, sf, "AAC ")) + goto fail; /* .aac: actual extension, .laac: for players to avoid hijacking MP4/AAC */ if (!check_extensions(sf, "aac,laac")) goto fail; - if (!is_id32be(0x00, sf, "AAC ") && !is_id32le(0x00, sf, "AAC ")) - goto fail; if (!parse_aac(sf, &aac)) goto fail; @@ -46,7 +46,7 @@ VGMSTREAM* init_vgmstream_ta_aac(STREAMFILE* sf) { vgmstream = allocate_vgmstream(aac.channels, aac.loop_flag); if (!vgmstream) goto fail; - vgmstream->meta_type = meta_TA_AAC; + vgmstream->meta_type = meta_AAC_TRIACE; vgmstream->sample_rate = aac.sample_rate; vgmstream->num_streams = aac.total_subsongs; vgmstream->stream_size = aac.stream_size; @@ -55,11 +55,7 @@ VGMSTREAM* init_vgmstream_ta_aac(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0165: { /* Infinite Undiscovery (X360), Star Ocean 4 (X360), Resonance of Fate (X360) */ - uint8_t buf[0x100]; - size_t bytes; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), aac.num_samples, aac.stream_size, aac.channels, aac.sample_rate, aac.block_count, aac.block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, aac.stream_offset, aac.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, aac.stream_offset, aac.stream_size, aac.num_samples, aac.channels, aac.sample_rate, aac.block_size, aac.block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -261,7 +257,7 @@ static int parse_aac_v1(STREAMFILE* sf, aac_header* aac) { aac->block_count = read_u32be(offset + 0x2c, sf); /* one UI file has a smaller header, early version? */ - if (read_u32be(offset + 0x30, sf) == 0x7374726D) { + if (is_id32be(offset + 0x30, sf, "strm")) { aac->loop_flag = 0; /* ? */ strm_offset = 0x30; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/adx.c b/Frameworks/vgmstream/vgmstream/src/meta/adx.c index e4bdcd766..51fe4c146 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/adx.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/adx.c @@ -6,6 +6,7 @@ #include "meta.h" #include "adx_keys.h" #include "../coding/coding.h" +#include "../util/cri_keys.h" #ifdef VGM_DEBUG_OUTPUT @@ -280,39 +281,32 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1 key_size = read_key_file(keybuf, sizeof(keybuf), sf); if (key_size > 0) { - int is_ascii = 0; + int is_keystring = 0; - /* keystrings should be ASCII, also needed to tell apart 0x06 strings from derived keys */ if (type == 8) { - is_ascii = 1; - for (i = 0; i < key_size; i++) { - if (keybuf[i] < 0x20 || keybuf[i] > 0x7f) { - is_ascii = 0; - break; - } - } + is_keystring = cri_key8_valid_keystring(keybuf, key_size); } - if (key_size == 0x06 && !is_ascii) { + if (key_size == 0x06 && !is_keystring) { *xor_start = get_u16be(keybuf + 0x00); *xor_mult = get_u16be(keybuf + 0x02); *xor_add = get_u16be(keybuf + 0x04); return 1; } - else if (type == 8 && is_ascii) { + else if (type == 8 && is_keystring) { const char* keystring = (const char*)keybuf; - derive_adx_key8(keystring, xor_start, xor_mult, xor_add); + cri_key8_derive(keystring, xor_start, xor_mult, xor_add); return 1; } else if (type == 9 && key_size == 0x08) { uint64_t keycode = get_u64be(keybuf); - derive_adx_key9(keycode, subkey, xor_start, xor_mult, xor_add); + cri_key9_derive(keycode, subkey, xor_start, xor_mult, xor_add); return 1; } else if (type == 9 && key_size == 0x08+0x02) { uint64_t file_keycode = get_u64be(keybuf+0x00); uint16_t file_subkey = get_u16be(keybuf+0x08); - derive_adx_key9(file_keycode, file_subkey, xor_start, xor_mult, xor_add); + cri_key9_derive(file_keycode, file_subkey, xor_start, xor_mult, xor_add); return 1; } } @@ -438,7 +432,7 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1 #ifdef ADX_BRUTEFORCE if (buf) { keycode = get_u64be(buf + key_id); - derive_adx_key9(keycode, subkey, &key_xor, &key_mul, &key_add); + cri_key9_derive(keycode, subkey, &key_xor, &key_mul, &key_add); } else #endif @@ -450,11 +444,11 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1 key_add = keys[key_id].add; } else if (type == 8 && keys[key_id].key8) { - derive_adx_key8(keys[key_id].key8, &key_xor, &key_mul, &key_add); + cri_key8_derive(keys[key_id].key8, &key_xor, &key_mul, &key_add); } else if (type == 9 && keys[key_id].key9) { uint64_t keycode = keys[key_id].key9; - derive_adx_key9(keycode, subkey, &key_xor, &key_mul, &key_add); + cri_key9_derive(keycode, subkey, &key_xor, &key_mul, &key_add); } else { VGM_LOG("ADX: incorrectly defined key id=%i\n", key_id); @@ -474,13 +468,13 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1 mul = keys[key_id].mult; add = keys[key_id].add; if (type == 8 && keys[key_id].key8) { - derive_adx_key8(keys[key_id].key8, &test_xor, &test_mul, &test_add); + cri_key8_derive(keys[key_id].key8, &test_xor, &test_mul, &test_add); VGM_LOG("key8: pre=%04x %04x %04x vs calc=%04x %04x %04x = %s (\"%s\")\n", xor,mul,add, test_xor,test_mul,test_add, xor==test_xor && mul==test_mul && add==test_add ? "ok" : "ko", keys[key_id].key8); } else if (type == 9 && keys[key_id].key9) { - derive_adx_key9(keys[key_id].key9, subkey, &test_xor, &test_mul, &test_add); + cri_key9_derive(keys[key_id].key9, subkey, &test_xor, &test_mul, &test_add); VGM_LOG("key9: pre=%04x %04x %04x vs calc=%04x %04x %04x = %s (%"PRIu64")\n", xor,mul,add, test_xor,test_mul,test_add, xor==test_xor && mul==test_mul && add==test_add ? "ok" : "ko", keys[key_id].key9); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/adx_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/adx_keys.h index 14d2fb0da..7ddb2d438 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/adx_keys.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/adx_keys.h @@ -1,6 +1,8 @@ #ifndef _ADX_KEYS_H_ #define _ADX_KEYS_H_ +#include +#include typedef struct { uint16_t start, mult, add; /* XOR values derived from the actual key */ @@ -53,7 +55,7 @@ static const adxkey_info adxkey8_list[] = { {0x55b7,0x6191,0x5a77, "morio",0}, /* Amagami (PS2) [Enterbrain] */ - {0x5a17,0x509f,0x5bfd, "mituba",0}, /* also AHX key */ + {0x5a17,0x509f,0x5bfd, "mituba",0}, /* Yamasa Digi Portable: Matsuri no Tatsujin (PSP) [Yamasa] */ {0x4c01,0x549d,0x676f, "7fa0xB9tw3",0}, @@ -122,7 +124,7 @@ static const adxkey_info adxkey8_list[] = { {0x4c73,0x4d8d,0x5827, "URABOKU-penguin",0}, /* StormLover!! (PSP), StormLover Kai!! (PSP) [Vridge] */ - {0x5a11,0x67e5,0x6751, "HEXDPFMDKPQW",0}, /* unknown AHX key */ + {0x5a11,0x67e5,0x6751, "HEXDPFMDKPQW",0}, /* Sora no Otoshimono: DokiDoki Summer Vacation (PSP) [Kadokawa Shoten] */ {0x5e75,0x4a89,0x4c61, "funen-gomi",0}, @@ -131,25 +133,26 @@ static const adxkey_info adxkey8_list[] = { {0x64ab,0x5297,0x632f, "sonic",0}, /* Lucky Star: Net Idol Meister (PSP) [Vridge, Kadokawa Shoten] */ - {0x4d81,0x5243,0x58c7, "JJOLIFJLE",0}, /* unknown AHX key */ + /* Baka to Test to Shoukanjuu Portable (PSP) */ + {0x4d81,0x5243,0x58c7, "JJOLIFJLE",0}, /* Ishin Renka: Ryouma Gaiden (PSP) [Vridge] */ - {0x54d1,0x526d,0x5e8b, "LQAFJOIEJ",0}, /* unknown AHX key */ + {0x54d1,0x526d,0x5e8b, "LQAFJOIEJ",0}, /* Lucky Star: Ryouou Gakuen Outousai Portable (PSP) [Vridge] */ - {0x4d05,0x663b,0x6343, "IUNOIRU",0}, /* unknown AHX key */ + {0x4d05,0x663b,0x6343, "IUNOIRU",0}, /* Marriage Royale: Prism Story (PSP) [Vridge] */ - {0x40a9,0x46b1,0x62ad, "ROYMAR",0}, /* unknown AHX key */ + {0x40a9,0x46b1,0x62ad, "ROYMAR",0}, /* Nogizaka Haruka no Himitsu: Doujinshi Hajimemashita (PSP) [Vridge] */ - {0x4609,0x671f,0x4b65, "CLKMEOUHFLIE",0}, /* unknown AHX key */ + {0x4609,0x671f,0x4b65, "CLKMEOUHFLIE",0}, /* Slotter Mania P: Mach Go Go Go III (PSP) [Dorart] */ {0x41ef,0x463d,0x5507, "SGGK",0}, /* Nichijou: Uchuujin (PSP) [Vridge] */ - {0x4369,0x486d,0x5461, "LJLOUHIU787",0}, /* unknown AHX key */ + {0x4369,0x486d,0x5461, "LJLOUHIU787",0}, /* R-15 Portable (PSP) [Kadokawa Shoten] */ {0x6809,0x5fd5,0x5bb1, "R-15(Heart)Love",0}, @@ -158,7 +161,7 @@ static const adxkey_info adxkey8_list[] = { {0x5c33,0x4133,0x4ce7, "bi88a#fas",0}, /* StormLover Natsu Koi!! (PSP) [Vridge] */ - {0x4133,0x5a01,0x5723, "LIKDFJUIDJOQ",0}, /* unknown AHX key */ + {0x4133,0x5a01,0x5723, "LIKDFJUIDJOQ",0}, /* Shounen Onmyouji: Tsubasa yo Ima, Sora e Kaere (PS2) [Kadokawa Shoten] */ {0x55d9,0x46d3,0x5b01, "SONMYOJI",0}, @@ -272,129 +275,4 @@ static const adxkey_info adxkey9_list[] = { static const int adxkey8_list_count = sizeof(adxkey8_list) / sizeof(adxkey8_list[0]); static const int adxkey9_list_count = sizeof(adxkey9_list) / sizeof(adxkey9_list[0]); - -/* preloaded list used to derive keystrings from ADX_Decoder, found in executables (see VGAudio for how to calculate) */ -static const uint16_t key8_primes[0x400] = { - 0x401B,0x4021,0x4025,0x402B,0x4031,0x403F,0x4043,0x4045,0x405D,0x4061,0x4067,0x406D,0x4087,0x4091,0x40A3,0x40A9, - 0x40B1,0x40B7,0x40BD,0x40DB,0x40DF,0x40EB,0x40F7,0x40F9,0x4109,0x410B,0x4111,0x4115,0x4121,0x4133,0x4135,0x413B, - 0x413F,0x4159,0x4165,0x416B,0x4177,0x417B,0x4193,0x41AB,0x41B7,0x41BD,0x41BF,0x41CB,0x41E7,0x41EF,0x41F3,0x41F9, - 0x4205,0x4207,0x4219,0x421F,0x4223,0x4229,0x422F,0x4243,0x4253,0x4255,0x425B,0x4261,0x4273,0x427D,0x4283,0x4285, - 0x4289,0x4291,0x4297,0x429D,0x42B5,0x42C5,0x42CB,0x42D3,0x42DD,0x42E3,0x42F1,0x4307,0x430F,0x431F,0x4325,0x4327, - 0x4333,0x4337,0x4339,0x434F,0x4357,0x4369,0x438B,0x438D,0x4393,0x43A5,0x43A9,0x43AF,0x43B5,0x43BD,0x43C7,0x43CF, - 0x43E1,0x43E7,0x43EB,0x43ED,0x43F1,0x43F9,0x4409,0x440B,0x4417,0x4423,0x4429,0x443B,0x443F,0x4445,0x444B,0x4451, - 0x4453,0x4459,0x4465,0x446F,0x4483,0x448F,0x44A1,0x44A5,0x44AB,0x44AD,0x44BD,0x44BF,0x44C9,0x44D7,0x44DB,0x44F9, - 0x44FB,0x4505,0x4511,0x4513,0x452B,0x4531,0x4541,0x4549,0x4553,0x4555,0x4561,0x4577,0x457D,0x457F,0x458F,0x45A3, - 0x45AD,0x45AF,0x45BB,0x45C7,0x45D9,0x45E3,0x45EF,0x45F5,0x45F7,0x4601,0x4603,0x4609,0x4613,0x4625,0x4627,0x4633, - 0x4639,0x463D,0x4643,0x4645,0x465D,0x4679,0x467B,0x467F,0x4681,0x468B,0x468D,0x469D,0x46A9,0x46B1,0x46C7,0x46C9, - 0x46CF,0x46D3,0x46D5,0x46DF,0x46E5,0x46F9,0x4705,0x470F,0x4717,0x4723,0x4729,0x472F,0x4735,0x4739,0x474B,0x474D, - 0x4751,0x475D,0x476F,0x4771,0x477D,0x4783,0x4787,0x4789,0x4799,0x47A5,0x47B1,0x47BF,0x47C3,0x47CB,0x47DD,0x47E1, - 0x47ED,0x47FB,0x4801,0x4807,0x480B,0x4813,0x4819,0x481D,0x4831,0x483D,0x4847,0x4855,0x4859,0x485B,0x486B,0x486D, - 0x4879,0x4897,0x489B,0x48A1,0x48B9,0x48CD,0x48E5,0x48EF,0x48F7,0x4903,0x490D,0x4919,0x491F,0x492B,0x4937,0x493D, - 0x4945,0x4955,0x4963,0x4969,0x496D,0x4973,0x4997,0x49AB,0x49B5,0x49D3,0x49DF,0x49E1,0x49E5,0x49E7,0x4A03,0x4A0F, - 0x4A1D,0x4A23,0x4A39,0x4A41,0x4A45,0x4A57,0x4A5D,0x4A6B,0x4A7D,0x4A81,0x4A87,0x4A89,0x4A8F,0x4AB1,0x4AC3,0x4AC5, - 0x4AD5,0x4ADB,0x4AED,0x4AEF,0x4B07,0x4B0B,0x4B0D,0x4B13,0x4B1F,0x4B25,0x4B31,0x4B3B,0x4B43,0x4B49,0x4B59,0x4B65, - 0x4B6D,0x4B77,0x4B85,0x4BAD,0x4BB3,0x4BB5,0x4BBB,0x4BBF,0x4BCB,0x4BD9,0x4BDD,0x4BDF,0x4BE3,0x4BE5,0x4BE9,0x4BF1, - 0x4BF7,0x4C01,0x4C07,0x4C0D,0x4C0F,0x4C15,0x4C1B,0x4C21,0x4C2D,0x4C33,0x4C4B,0x4C55,0x4C57,0x4C61,0x4C67,0x4C73, - 0x4C79,0x4C7F,0x4C8D,0x4C93,0x4C99,0x4CCD,0x4CE1,0x4CE7,0x4CF1,0x4CF3,0x4CFD,0x4D05,0x4D0F,0x4D1B,0x4D27,0x4D29, - 0x4D2F,0x4D33,0x4D41,0x4D51,0x4D59,0x4D65,0x4D6B,0x4D81,0x4D83,0x4D8D,0x4D95,0x4D9B,0x4DB1,0x4DB3,0x4DC9,0x4DCF, - 0x4DD7,0x4DE1,0x4DED,0x4DF9,0x4DFB,0x4E05,0x4E0B,0x4E17,0x4E19,0x4E1D,0x4E2B,0x4E35,0x4E37,0x4E3D,0x4E4F,0x4E53, - 0x4E5F,0x4E67,0x4E79,0x4E85,0x4E8B,0x4E91,0x4E95,0x4E9B,0x4EA1,0x4EAF,0x4EB3,0x4EB5,0x4EC1,0x4ECD,0x4ED1,0x4ED7, - 0x4EE9,0x4EFB,0x4F07,0x4F09,0x4F19,0x4F25,0x4F2D,0x4F3F,0x4F49,0x4F63,0x4F67,0x4F6D,0x4F75,0x4F7B,0x4F81,0x4F85, - 0x4F87,0x4F91,0x4FA5,0x4FA9,0x4FAF,0x4FB7,0x4FBB,0x4FCF,0x4FD9,0x4FDB,0x4FFD,0x4FFF,0x5003,0x501B,0x501D,0x5029, - 0x5035,0x503F,0x5045,0x5047,0x5053,0x5071,0x5077,0x5083,0x5093,0x509F,0x50A1,0x50B7,0x50C9,0x50D5,0x50E3,0x50ED, - 0x50EF,0x50FB,0x5107,0x510B,0x510D,0x5111,0x5117,0x5123,0x5125,0x5135,0x5147,0x5149,0x5171,0x5179,0x5189,0x518F, - 0x5197,0x51A1,0x51A3,0x51A7,0x51B9,0x51C1,0x51CB,0x51D3,0x51DF,0x51E3,0x51F5,0x51F7,0x5209,0x5213,0x5215,0x5219, - 0x521B,0x521F,0x5227,0x5243,0x5245,0x524B,0x5261,0x526D,0x5273,0x5281,0x5293,0x5297,0x529D,0x52A5,0x52AB,0x52B1, - 0x52BB,0x52C3,0x52C7,0x52C9,0x52DB,0x52E5,0x52EB,0x52FF,0x5315,0x531D,0x5323,0x5341,0x5345,0x5347,0x534B,0x535D, - 0x5363,0x5381,0x5383,0x5387,0x538F,0x5395,0x5399,0x539F,0x53AB,0x53B9,0x53DB,0x53E9,0x53EF,0x53F3,0x53F5,0x53FB, - 0x53FF,0x540D,0x5411,0x5413,0x5419,0x5435,0x5437,0x543B,0x5441,0x5449,0x5453,0x5455,0x545F,0x5461,0x546B,0x546D, - 0x5471,0x548F,0x5491,0x549D,0x54A9,0x54B3,0x54C5,0x54D1,0x54DF,0x54E9,0x54EB,0x54F7,0x54FD,0x5507,0x550D,0x551B, - 0x5527,0x552B,0x5539,0x553D,0x554F,0x5551,0x555B,0x5563,0x5567,0x556F,0x5579,0x5585,0x5597,0x55A9,0x55B1,0x55B7, - 0x55C9,0x55D9,0x55E7,0x55ED,0x55F3,0x55FD,0x560B,0x560F,0x5615,0x5617,0x5623,0x562F,0x5633,0x5639,0x563F,0x564B, - 0x564D,0x565D,0x565F,0x566B,0x5671,0x5675,0x5683,0x5689,0x568D,0x568F,0x569B,0x56AD,0x56B1,0x56D5,0x56E7,0x56F3, - 0x56FF,0x5701,0x5705,0x5707,0x570B,0x5713,0x571F,0x5723,0x5747,0x574D,0x575F,0x5761,0x576D,0x5777,0x577D,0x5789, - 0x57A1,0x57A9,0x57AF,0x57B5,0x57C5,0x57D1,0x57D3,0x57E5,0x57EF,0x5803,0x580D,0x580F,0x5815,0x5827,0x582B,0x582D, - 0x5855,0x585B,0x585D,0x586D,0x586F,0x5873,0x587B,0x588D,0x5897,0x58A3,0x58A9,0x58AB,0x58B5,0x58BD,0x58C1,0x58C7, - 0x58D3,0x58D5,0x58DF,0x58F1,0x58F9,0x58FF,0x5903,0x5917,0x591B,0x5921,0x5945,0x594B,0x594D,0x5957,0x595D,0x5975, - 0x597B,0x5989,0x5999,0x599F,0x59B1,0x59B3,0x59BD,0x59D1,0x59DB,0x59E3,0x59E9,0x59ED,0x59F3,0x59F5,0x59FF,0x5A01, - 0x5A0D,0x5A11,0x5A13,0x5A17,0x5A1F,0x5A29,0x5A2F,0x5A3B,0x5A4D,0x5A5B,0x5A67,0x5A77,0x5A7F,0x5A85,0x5A95,0x5A9D, - 0x5AA1,0x5AA3,0x5AA9,0x5ABB,0x5AD3,0x5AE5,0x5AEF,0x5AFB,0x5AFD,0x5B01,0x5B0F,0x5B19,0x5B1F,0x5B25,0x5B2B,0x5B3D, - 0x5B49,0x5B4B,0x5B67,0x5B79,0x5B87,0x5B97,0x5BA3,0x5BB1,0x5BC9,0x5BD5,0x5BEB,0x5BF1,0x5BF3,0x5BFD,0x5C05,0x5C09, - 0x5C0B,0x5C0F,0x5C1D,0x5C29,0x5C2F,0x5C33,0x5C39,0x5C47,0x5C4B,0x5C4D,0x5C51,0x5C6F,0x5C75,0x5C77,0x5C7D,0x5C87, - 0x5C89,0x5CA7,0x5CBD,0x5CBF,0x5CC3,0x5CC9,0x5CD1,0x5CD7,0x5CDD,0x5CED,0x5CF9,0x5D05,0x5D0B,0x5D13,0x5D17,0x5D19, - 0x5D31,0x5D3D,0x5D41,0x5D47,0x5D4F,0x5D55,0x5D5B,0x5D65,0x5D67,0x5D6D,0x5D79,0x5D95,0x5DA3,0x5DA9,0x5DAD,0x5DB9, - 0x5DC1,0x5DC7,0x5DD3,0x5DD7,0x5DDD,0x5DEB,0x5DF1,0x5DFD,0x5E07,0x5E0D,0x5E13,0x5E1B,0x5E21,0x5E27,0x5E2B,0x5E2D, - 0x5E31,0x5E39,0x5E45,0x5E49,0x5E57,0x5E69,0x5E73,0x5E75,0x5E85,0x5E8B,0x5E9F,0x5EA5,0x5EAF,0x5EB7,0x5EBB,0x5ED9, - 0x5EFD,0x5F09,0x5F11,0x5F27,0x5F33,0x5F35,0x5F3B,0x5F47,0x5F57,0x5F5D,0x5F63,0x5F65,0x5F77,0x5F7B,0x5F95,0x5F99, - 0x5FA1,0x5FB3,0x5FBD,0x5FC5,0x5FCF,0x5FD5,0x5FE3,0x5FE7,0x5FFB,0x6011,0x6023,0x602F,0x6037,0x6053,0x605F,0x6065, - 0x606B,0x6073,0x6079,0x6085,0x609D,0x60AD,0x60BB,0x60BF,0x60CD,0x60D9,0x60DF,0x60E9,0x60F5,0x6109,0x610F,0x6113, - 0x611B,0x612D,0x6139,0x614B,0x6155,0x6157,0x615B,0x616F,0x6179,0x6187,0x618B,0x6191,0x6193,0x619D,0x61B5,0x61C7, - 0x61C9,0x61CD,0x61E1,0x61F1,0x61FF,0x6209,0x6217,0x621D,0x6221,0x6227,0x623B,0x6241,0x624B,0x6251,0x6253,0x625F, - 0x6265,0x6283,0x628D,0x6295,0x629B,0x629F,0x62A5,0x62AD,0x62D5,0x62D7,0x62DB,0x62DD,0x62E9,0x62FB,0x62FF,0x6305, - 0x630D,0x6317,0x631D,0x632F,0x6341,0x6343,0x634F,0x635F,0x6367,0x636D,0x6371,0x6377,0x637D,0x637F,0x63B3,0x63C1, - 0x63C5,0x63D9,0x63E9,0x63EB,0x63EF,0x63F5,0x6401,0x6403,0x6409,0x6415,0x6421,0x6427,0x642B,0x6439,0x6443,0x6449, - 0x644F,0x645D,0x6467,0x6475,0x6485,0x648D,0x6493,0x649F,0x64A3,0x64AB,0x64C1,0x64C7,0x64C9,0x64DB,0x64F1,0x64F7, - 0x64F9,0x650B,0x6511,0x6521,0x652F,0x6539,0x653F,0x654B,0x654D,0x6553,0x6557,0x655F,0x6571,0x657D,0x658D,0x658F, - 0x6593,0x65A1,0x65A5,0x65AD,0x65B9,0x65C5,0x65E3,0x65F3,0x65FB,0x65FF,0x6601,0x6607,0x661D,0x6629,0x6631,0x663B, - 0x6641,0x6647,0x664D,0x665B,0x6661,0x6673,0x667D,0x6689,0x668B,0x6695,0x6697,0x669B,0x66B5,0x66B9,0x66C5,0x66CD, - 0x66D1,0x66E3,0x66EB,0x66F5,0x6703,0x6713,0x6719,0x671F,0x6727,0x6731,0x6737,0x673F,0x6745,0x6751,0x675B,0x676F, - 0x6779,0x6781,0x6785,0x6791,0x67AB,0x67BD,0x67C1,0x67CD,0x67DF,0x67E5,0x6803,0x6809,0x6811,0x6817,0x682D,0x6839, -}; - -static void derive_adx_key8(const char* key8, uint16_t* p_start, uint16_t* p_mult, uint16_t* p_add) { - size_t key_size; - uint16_t start = 0, mult = 0, add = 0; - int i; - - if (key8 == NULL || key8[0] == '\0') /* strlen >= 1 */ - goto end; - - /* calcs as found in exes, though there is some unrolling in the original code */ - key_size = strlen(key8); - start = key8_primes[0x100]; - mult = key8_primes[0x200]; - add = key8_primes[0x300]; - - for (i = 0; i < key_size; i++) { - char c = key8[i]; - start = key8_primes[start * key8_primes[c + 0x80] % 0x400]; - mult = key8_primes[mult * key8_primes[c + 0x80] % 0x400]; - add = key8_primes[add * key8_primes[c + 0x80] % 0x400]; - } - -end: - *p_start = start; - *p_mult = mult; - *p_add = add; -} - - -static void derive_adx_key9(uint64_t key9, uint16_t subkey, uint16_t* p_start, uint16_t* p_mult, uint16_t* p_add) { - uint16_t start = 0, mult = 0, add = 0; - - /* 0 is ignored by CRI's encoder, only from 1..18446744073709551615 */ - if (key9 == 0) - goto end; - - if (subkey) { - key9 = key9 * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) ); - } - - key9--; - start = (int)(((key9 >> 27) & 0x7fff)); - mult = (int)(((key9 >> 12) & 0x7ffc) | 1); - add = (int)(((key9 << 1 ) & 0x7fff) | 1); - - /* alt from ADX_Decoder, probably the same */ - //start = ((key9 >> 27) & 0x7FFF); - //mult = ((key9 >> 12) & 0x7FFC) | 1; - //add = ((key9 << 1 ) & 0x7FFE) | 1; - //mult |= add << 16; - -end: - *p_start = start; - *p_mult = mult; - *p_add = add; -} - #endif/*_ADX_KEYS_H_*/ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ahx.c b/Frameworks/vgmstream/vgmstream/src/meta/ahx.c index 6ea24780c..e5c98fe78 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ahx.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ahx.c @@ -1,10 +1,13 @@ #include "meta.h" #include "../coding/coding.h" -#include "../util.h" -#if 0 -#include "adx_keys.h" +#include "ahx_keys.h" +#include "../util/cri_keys.h" + +#ifdef VGM_USE_MPEG +static int find_ahx_key(STREAMFILE* sf, off_t offset, crikey_t* crikey); #endif + /* AHX - CRI voice format */ VGMSTREAM* init_vgmstream_ahx(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; @@ -23,7 +26,7 @@ VGMSTREAM* init_vgmstream_ahx(STREAMFILE* sf) { read_u32be(start_offset - 0x04,sf) != 0x29435249) /* ")CRI" */ goto fail; - /* types: 0x10 = AHX for DC with bigger frames, 0x11 = AHX, 0x0N = ADX */ + /* types: 0x10 = AHX for DC with fixed MPEG frame bits (bigger frames), 0x11 = standard AHX, 0x0N = ADX */ type = read_u8(0x04,sf); if (type != 0x10 && type != 0x11) goto fail; @@ -52,40 +55,13 @@ VGMSTREAM* init_vgmstream_ahx(STREAMFILE* sf) { { #ifdef VGM_USE_MPEG mpeg_custom_config cfg = {0}; + crikey_t* crikey = &cfg.crikey; - cfg.encryption = read_u8(0x13,sf); /* 0x08 = keyword encryption */ - cfg.cri_type = type; + cfg.encryption = read_u8(0x13,sf); /* only type 0x08 is known */ + crikey->type = cfg.encryption; if (cfg.encryption) { - uint8_t keybuf[0x10+1] = {0}; /* approximate max for keystrings, +1 extra null for keystrings */ - size_t key_size; - - key_size = read_key_file(keybuf, sizeof(keybuf), sf); - if (key_size > 0) { -#if 0 - int i, is_ascii; - is_ascii = 1; - for (i = 0; i < key_size; i++) { - if (keybuf[i] < 0x20 || keybuf[i] > 0x7f) { - is_ascii = 0; - break; - } - } -#endif - if (key_size == 0x06 /*&& !is_ascii*/) { - cfg.cri_key1 = get_u16be(keybuf + 0x00); - cfg.cri_key2 = get_u16be(keybuf + 0x02); - cfg.cri_key3 = get_u16be(keybuf + 0x04); - } -#if 0 - else if (is_ascii) { - const char* keystring = (const char*)keybuf; - - derive_adx_key8(keystring, &cfg.cri_key1, &cfg.cri_key2, &cfg.cri_key3); - VGM_LOG("ok: %x, %x, %x\n", cfg.cri_key1, cfg.cri_key2, cfg.cri_key3 ); - } -#endif - } + find_ahx_key(sf, start_offset, crikey); } vgmstream->layout_type = layout_none; @@ -104,3 +80,80 @@ fail: close_vgmstream(vgmstream); return NULL; } + +#ifdef VGM_USE_MPEG +static int find_ahx_keyfile(STREAMFILE* sf, crikey_t* crikey) { + uint8_t keybuf[0x10+1] = {0}; /* approximate max for keystrings, +1 extra null for keystrings */ + size_t key_size; + int is_keystring = 0; + + key_size = read_key_file(keybuf, sizeof(keybuf) - 1, sf); + if (key_size <= 0) + goto fail; + + + if (crikey->type == 8) { + is_keystring = cri_key8_valid_keystring(keybuf, key_size); + } + + if (key_size == 0x06 && !is_keystring) { + crikey->key1 = get_u16be(keybuf + 0x00); + crikey->key2 = get_u16be(keybuf + 0x02); + crikey->key3 = get_u16be(keybuf + 0x04); + } + else if (crikey->type == 8 && is_keystring) { + const char* keystring = (const char*)keybuf; + cri_key8_derive(keystring, &crikey->key1, &crikey->key2, &crikey->key3); + } + else { + goto fail; + } + + return 1; +fail: + return 0; +} + +static int find_ahx_keylist(STREAMFILE* sf, off_t offset, crikey_t* crikey) { + int i; + int keycount = ahxkey8_list_count; + const ahxkey_info* keys = ahxkey8_list; + + + for (i = 0; i < keycount; i++) { + if (crikey->type == 0x08) { + cri_key8_derive(keys[i].key8, &crikey->key1, &crikey->key2, &crikey->key3); + //;VGM_LOG("AHX: testing %s [%04x %04x %04x]\n", keys[i].key8, crikey->key1, crikey->key2, crikey->key3); + } + else { + continue; + } + + if (test_ahx_key(sf, offset, crikey)) { + //;VGM_LOG("AHX key found\n"); + return 1; + } + } + + return 0; +} + +static int find_ahx_key(STREAMFILE* sf, off_t offset, crikey_t* crikey) { + int ok; + + ok = find_ahx_keyfile(sf, crikey); + if (ok) + return 1; + + ok = find_ahx_keylist(sf, offset, crikey); + if (ok) + return 1; + + + crikey->key1 = 0; + crikey->key2 = 0; + crikey->key3 = 0; + vgm_logi("AHX: decryption key not found\n"); + return 0; +} +#endif diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ahx_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/ahx_keys.h new file mode 100644 index 000000000..aa2316fe6 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/ahx_keys.h @@ -0,0 +1,52 @@ +#ifndef _AHX_KEYS_H_ +#define _AHX_KEYS_H_ + +#include +#include + +typedef struct { + const char* key8; /* keystring used by type 8 encryption */ + uint64_t key9; /* reserved (not seen) */ +} ahxkey_info; + +/** + * List of known keys, from exes. Generally same as ADX keys as CRI's key init seems shared. + */ +static const ahxkey_info ahxkey8_list[] = { + + /* Amagami (PS2) [Enterbrain] */ + {"mituba",0}, + + /* StormLover!! (PSP), StormLover Kai!! (PSP) [Vridge] */ + {"HEXDPFMDKPQW",0}, + + /* Lucky Star: Net Idol Meister (PSP) [Vridge, Kadokawa Shoten] */ + /* Baka to Test to Shoukanjuu Portable (PSP) */ + {"JJOLIFJLE",0}, + + /* Ishin Renka: Ryouma Gaiden (PSP) [Vridge] */ + {"LQAFJOIEJ",0}, + + /* Lucky Star: Ryouou Gakuen Outousai Portable (PSP) [Vridge] */ + {"IUNOIRU",0}, + + /* Marriage Royale: Prism Story (PSP) [Vridge] */ + {"ROYMAR",0}, + + /* Nogizaka Haruka no Himitsu: Doujinshi Hajimemashita (PSP) [Vridge] */ + {"CLKMEOUHFLIE",0}, + + /* Nichijou: Uchuujin (PSP) [Vridge] */ + {"LJLOUHIU787",0}, + + /* StormLover Natsu Koi!! (PSP) [Vridge] */ + {"LIKDFJUIDJOQ",0}, + + /* Corpse Party: Book of Shadows (PSP) */ + {"\x83\x76\x83\x89\x83\x60\x83\x69Lovers_Day",0}, // "プラチナLovers_Day" in SHIFT-JIS + +}; + +static const int ahxkey8_list_count = sizeof(ahxkey8_list) / sizeof(ahxkey8_list[0]); + +#endif /* _AHX_KEYS_H_ */ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/akb.c b/Frameworks/vgmstream/vgmstream/src/meta/akb.c index 327f1ec46..df763f078 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/akb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/akb.c @@ -3,38 +3,6 @@ #include "sqex_streamfile.h" -#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC) -/* AKB (AAC only) - found in SQEX iOS games */ -VGMSTREAM * init_vgmstream_akb_mp4(STREAMFILE *sf) { - VGMSTREAM * vgmstream = NULL; - - size_t filesize; - uint32_t loop_start, loop_end; - - if ((uint32_t)read_32bitBE(0, sf) != 0x414b4220) goto fail; - - loop_start = read_s32le(0x14, sf); - loop_end = read_s32le(0x18, sf); - - filesize = get_streamfile_size( sf ); - - vgmstream = init_vgmstream_mp4_aac_offset( sf, 0x20, filesize - 0x20 ); - if ( !vgmstream ) goto fail; - - if ( loop_start || loop_end ) { - vgmstream->loop_flag = 1; - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - } - - return vgmstream; - -fail: - return NULL; -} -#endif - - /* AKB - found in SQEX 'sdlib' iOS/Android games */ VGMSTREAM* init_vgmstream_akb(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/astb.c b/Frameworks/vgmstream/vgmstream/src/meta/astb.c new file mode 100644 index 000000000..e987e1c47 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/astb.c @@ -0,0 +1,83 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* ASTB - found in Dead Rising (X360) */ +VGMSTREAM* init_vgmstream_astb(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset, data_size; + int loop_flag, channels; + int i, xma_streams; + + /* check */ + if (!is_id32be(0x00,sf, "ASTB")) + goto fail; + if (!check_extensions(sf,"ast")) + goto fail; + + if (read_u32be(0x04,sf) != get_streamfile_size(sf)) + goto fail; + if (read_u16be(0x30,sf) != 0x165) /* only seen XMA1 */ + goto fail; + + start_offset = read_u32be(0x10,sf); + data_size = read_u32be(0x20,sf); + xma_streams = read_u16be(0x38,sf); + + loop_flag = read_u8(0x3a,sf); + channels = 0; /* sum of all stream channels (though only 1/2ch ever seen) */ + for (i = 0; i < xma_streams; i++) { + channels += read_u8(0x3c + 0x14 * i + 0x11,sf); + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_s32be(0x40,sf); + vgmstream->meta_type = meta_ASTB; + + { + /* manually find sample offsets (XMA1 nonsense again) */ + ms_sample_data msd = {0}; + + msd.xma_version = 1; + msd.channels = channels; + msd.data_offset = start_offset; + msd.data_size = data_size; + msd.loop_flag = loop_flag; + msd.loop_start_b = read_u32be(0x44,sf); + msd.loop_end_b = read_u32be(0x48,sf); + msd.loop_start_subframe = read_u8(0x4c,sf) & 0xF; /* lower 4b: subframe where the loop starts, 0..4 */ + msd.loop_end_subframe = read_u8(0x4c,sf) >> 4; /* upper 4b: subframe where the loop ends, 0..3 */ + + xma_get_samples(&msd, sf); + vgmstream->num_samples = msd.num_samples; + vgmstream->loop_start_sample = msd.loop_start_sample; + vgmstream->loop_end_sample = msd.loop_end_sample; + } + +#ifdef VGM_USE_FFMPEG + { + off_t fmt_offset = 0x30; + size_t fmt_size = 0x0c + xma_streams * 0x14; + + /* XMA1 "fmt" chunk @ 0x20 (BE, unlike the usual LE) */ + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, fmt_offset, fmt_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, fmt_offset, 1,1); + } +#else + goto fail; +#endif + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/aus.c b/Frameworks/vgmstream/vgmstream/src/meta/aus.c index 26a571634..374d0d162 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/aus.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/aus.c @@ -1,71 +1,48 @@ #include "meta.h" #include "../util.h" -/* AUS (found in various Capcom games) */ -VGMSTREAM * init_vgmstream_aus(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; +/* AUS - Atomic Planet games [Jackie Chan Adventures (PS2), Mega Man Anniversary Collection (PS2/Xbox)] */ +VGMSTREAM* init_vgmstream_aus(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; - int loop_flag = 0; - int channel_count; + int loop_flag, channels, codec; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("aus",filename_extension(filename))) goto fail; - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x41555320) /* "AUS " */ + /* checks */ + if (!is_id32be(0x00, sf, "AUS ")) + goto fail; + if (!check_extensions(sf, "aus")) goto fail; - loop_flag = (read_32bitLE(0x0c,streamFile)!=0); - channel_count = read_32bitLE(0xC,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + channels = read_u32le(0x0c,sf); + start_offset = 0x800; + codec = read_u16le(0x06,sf); + loop_flag = (read_u32le(0x1c,sf) == 1); /* games seem to just do full loops, even when makes no sense (jingles/megaman stages) */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x800; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - vgmstream->num_samples = read_32bitLE(0x08,streamFile); + vgmstream->meta_type = meta_AUS; + vgmstream->sample_rate = read_s32le(0x10,sf); /* uses pretty odd values */ + vgmstream->num_samples = read_s32le(0x08,sf); + vgmstream->loop_start_sample = read_s32le(0x14,sf); /* always 0? */ + vgmstream->loop_end_sample = read_s32le(0x18,sf); /* always samples? */ - if(read_16bitLE(0x06,streamFile)==0x02) { - vgmstream->coding_type = coding_XBOX_IMA; - vgmstream->layout_type=layout_none; - } else { - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x800; - } - - if (loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x08,streamFile); - } - - vgmstream->meta_type = meta_AUS; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } + if (codec == 0x02) { + vgmstream->coding_type = coding_XBOX_IMA; + vgmstream->layout_type = layout_none; + } + else { + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x800; } + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; return vgmstream; - - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/awc.c b/Frameworks/vgmstream/vgmstream/src/meta/awc.c index b3dad4f03..be6ebf8f9 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/awc.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/awc.c @@ -70,9 +70,7 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x05: { /* XMA2 (X360) */ - uint8_t buf[0x100]; - size_t bytes, block_size, block_count, substream_size; - off_t substream_offset; + uint32_t substream_size, substream_offset; if (awc.is_music) { /* 1ch XMAs in blocks, we'll use layered layout + custom IO to get multi-FFmpegs working */ @@ -95,26 +93,22 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { data->layers[i] = allocate_vgmstream(layer_channels, 0); if (!data->layers[i]) goto fail; - data->layers[i]->sample_rate = awc.sample_rate; data->layers[i]->meta_type = meta_AWC; data->layers[i]->coding_type = coding_FFmpeg; data->layers[i]->layout_type = layout_none; + data->layers[i]->sample_rate = awc.sample_rate; data->layers[i]->num_samples = awc.num_samples; /* setup custom IO streamfile, pass to FFmpeg and hope it's fooled */ temp_sf = setup_awc_xma_streamfile(sf, awc.stream_offset, awc.stream_size, awc.block_chunk, awc.channels, i); if (!temp_sf) goto fail; - substream_offset = 0; /* where FFmpeg thinks data starts, which our custom sf will clamp */ + substream_offset = 0x00; /* where FFmpeg thinks data starts, which our custom sf will clamp */ substream_size = get_streamfile_size(temp_sf); /* data of one XMA substream without blocks */ - block_size = 0x8000; /* no idea */ - block_count = substream_size / block_size; /* not accurate but not needed */ - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, awc.num_samples, substream_size, layer_channels, awc.sample_rate, block_count, block_size); - data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, substream_offset,substream_size); - - xma_fix_raw_samples(data->layers[i], temp_sf, substream_offset,substream_size, 0, 0,0); /* samples are ok? */ + data->layers[i]->codec_data = init_ffmpeg_xma2_raw(temp_sf, substream_offset, substream_size, awc.num_samples, layer_channels, awc.sample_rate, 0, 0); + if (data->layers[i]) + xma_fix_raw_samples(data->layers[i], temp_sf, substream_offset, substream_size, 0, 0,0); /* samples are ok? */ close_streamfile(temp_sf); if (!data->layers[i]->codec_data) goto fail; } @@ -125,11 +119,7 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { } else { /* regular XMA for sfx */ - block_size = 0x8000; /* no idea */ - block_count = awc.stream_size / block_size; /* not accurate but not needed */ - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, awc.num_samples, awc.stream_size, awc.channels, awc.sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, awc.stream_offset,awc.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, awc.stream_offset, awc.stream_size, awc.num_samples, awc.channels, awc.sample_rate, 0, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/baf.c b/Frameworks/vgmstream/vgmstream/src/meta/baf.c index a6409fac8..303db7e3e 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/baf.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/baf.c @@ -179,11 +179,7 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) { #ifdef VGM_USE_FFMPEG case 0x08: { - uint8_t buf[0x100]; - int bytes; - - bytes = ffmpeg_make_riff_xma1(buf,0x100, 0, stream_size, vgmstream->channels, vgmstream->sample_rate, 0); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,stream_size); + vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, start_offset, stream_size, vgmstream->channels, vgmstream->sample_rate, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -229,58 +225,3 @@ fail: close_vgmstream(vgmstream); return NULL; } - -/* awful PS3 splits of the above with bad offsets and all */ -VGMSTREAM * init_vgmstream_baf_badrip(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t WAVE_size, stream_size; - off_t start_offset; - long sample_count; - int sample_rate; - - const int frame_size = 33; - const int frame_samples = (frame_size-1) * 2; - int channels; - int loop_flag = 0; - - /* checks */ - if ( !check_extensions(streamFile, "baf") ) - goto fail; - if (read_32bitBE(0,streamFile) != 0x57415645) /* "WAVE" */ - goto fail; - WAVE_size = read_32bitBE(4,streamFile); - if (WAVE_size != 0x4c) /* && WAVE_size != 0x50*/ - goto fail; - if (read_32bitBE(WAVE_size,streamFile) != 0x44415441) /* "DATA"*/ - goto fail; - /* check that WAVE size is data size */ - stream_size = read_32bitBE(0x30,streamFile); - if (read_32bitBE(WAVE_size+4,streamFile)-8 != stream_size) goto fail; - - sample_count = read_32bitBE(0x44,streamFile); - sample_rate = read_32bitBE(0x40,streamFile); - /* unsure how to detect channel count, so use a hack */ - channels = (long long)stream_size / frame_size * frame_samples / sample_count; - start_offset = WAVE_size + 8; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channels,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = sample_count; - - vgmstream->coding_type = coding_PSX_cfg; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = frame_size; - vgmstream->meta_type = meta_BAF; - - if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/bfstm.c b/Frameworks/vgmstream/vgmstream/src/meta/bfstm.c index 229cb2e8a..86e8dd1c1 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/bfstm.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/bfstm.c @@ -28,10 +28,10 @@ VGMSTREAM* init_vgmstream_bfstm(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf,"bfstm")) - goto fail; if (!is_id32be(0x00,sf, "FSTM")) goto fail; + if (!check_extensions(sf,"bfstm")) + goto fail; /* 0x06(2): header size (0x40) * 0x08: version (0x00000400) * 0x0c: file size */ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c b/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c index 896ce0f60..13476ba70 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c @@ -54,7 +54,7 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { data_offset = read_u32(0x10,sf); data_size = read_u32(0x14,sf); /* when sblk_offset >= 0x20: */ - /* 0x18: ZLSD small footer, rare [Yakuza 6's Puyo Puyo (PS4)] */ + /* 0x18: ZLSD small footer, rare in earlier versions [Yakuza 6's Puyo Puyo (PS4)] */ /* 0x1c: ZLSD size */ /* SE banks, also used for music. Most table fields seems reserved/defaults and @@ -66,14 +66,17 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { if (read_u32(sblk_offset+0x00,sf) != get_id32be("klBS")) /* SBlk = SFX block */ goto fail; sblk_version = read_u32(sblk_offset+0x04,sf); - /* 0x08: flags? (sblk_version>=0x0d?, 0x03=Vita, 0x06=PS4) + /* 0x08: flags? (sblk_version>=0x0d?, 0x03=Vita, 0x06=PS4, 0x05=PS5) * - 04: non-fixed bank? * - 100: has names - * - 200: has user data - */ - /* 0x0c: block id */ - /* 0x10: block number */ - /* 0x11: padding */ + * - 200: has user data */ + /* version < v0x1a: + * - 0x0c: block id + * - 0x10: block number + * - 0x11: padding + * version >= v0x1a: + * - 0x0c: hash (0x10) + * - 0x1c: filename (0x100?) */ //;VGM_LOG("BNK: sblk_offset=%lx, data_offset=%lx, sblk_version %x\n", sblk_offset, data_offset, sblk_version); { @@ -141,6 +144,8 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { table2_suboffset = 0x00; break; + case 0x1a: /* Demon's Souls (PS5) */ + default: vgm_logi("BNK: unknown version %x (report)\n", sblk_version); goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/brstm.c b/Frameworks/vgmstream/vgmstream/src/meta/brstm.c index 80f811957..98d3c8954 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/brstm.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/brstm.c @@ -1,168 +1,123 @@ #include "meta.h" -#include "../util.h" +#include "../coding/coding.h" -VGMSTREAM * init_vgmstream_brstm(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; +VGMSTREAM* init_vgmstream_brstm(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + uint32_t start_offset, head_size, head_offset, info_offset; + int channels, loop_flag, codec, version; - coding_t coding_type; - - off_t head_offset; - int codec_number; - int channel_count; - int loop_flag; - /* Certain Super Paper Mario tracks have a 44.1KHz sample rate in the - * header, but they should be played at 22.05KHz. We will make this - * correction if we see a file with a .brstmspm extension. */ - int spm_flag = 0; - /* Trauma Center Second Opinion has an odd, semi-corrupt header */ - int atlus_shrunken_head = 0; - - off_t start_offset; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("brstm",filename_extension(filename))) { - if (strcasecmp("brstmspm",filename_extension(filename))) goto fail; - else spm_flag = 1; - } - - /* check header */ - if ((uint32_t)read_32bitBE(0,streamFile)!=0x5253544D) /* "RSTM" */ + /* checks */ + if (!is_id32be(0x00,sf, "RSTM")) goto fail; - if ((uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0100) - { - if ((uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0001) - goto fail; - else - atlus_shrunken_head = 1; + + /* .brstm: standard + * .brstmspm: fake hack */ + if (!check_extensions(sf,"brstm,brstmspm")) + goto fail; + + if (read_u16be(0x04, sf) != 0xFEFF) /* BE BOM for all Wii games */ + goto fail; + + version = read_u16be(0x06, sf); /* 0.1 (Trauma Center), 1.0 (all others) */ + if (read_u32be(0x08, sf) != get_streamfile_size(sf)) + goto fail; + + head_size = read_u16be(0x0c, sf); + /* 0x0e: chunk count */ + + if (version == 0x0001) { + /* smaller simpler header found in some (beta?) files */ + head_offset = head_size; + info_offset = head_offset + 0x08; + } + else { + /* chunk table: offset + sixe x N chunks */ + head_offset = read_u32be(0x10,sf); /* in practice same as head_size */ + info_offset = head_offset + 0x20; + /* HEAD starts with a sub-chunk table (info, )*/ } - /* get head offset, check */ - head_offset = read_32bitBE(0x10,streamFile); - if (atlus_shrunken_head) - { - /* the HEAD chunk is where we would expect to find the offset of that - * chunk... */ + if (!is_id32be(head_offset,sf, "HEAD")) + goto fail; + /* 0x04: chunk size (set to 0x8 in v0.1) */ - if ((uint32_t)head_offset!=0x48454144 || read_32bitBE(0x14,streamFile) != 8) - goto fail; + codec = read_u8(info_offset+0x00,sf); + loop_flag = read_u8(info_offset+0x01,sf); + channels = read_u8(info_offset+0x02,sf); - head_offset = -8; /* most of the normal Nintendo RSTM offsets work - with this assumption */ - } - else - { - if ((uint32_t)read_32bitBE(head_offset,streamFile)!=0x48454144) /* "HEAD" */ - goto fail; - } + start_offset = read_u32be(info_offset+0x10,sf); /* inside DATA chunk */ - /* check type details */ - codec_number = read_8bit(head_offset+0x20,streamFile); - loop_flag = read_8bit(head_offset+0x21,streamFile); - channel_count = read_8bit(head_offset+0x22,streamFile); + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; - switch (codec_number) { + vgmstream->meta_type = meta_RSTM; + + vgmstream->sample_rate = read_u16be(info_offset+0x04,sf); + vgmstream->loop_start_sample = read_s32be(info_offset+0x08,sf); + vgmstream->num_samples = read_s32be(info_offset+0x0c,sf); + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->interleave_block_size = read_u32be(info_offset+0x18,sf); + vgmstream->interleave_last_block_size = read_u32be(info_offset+0x28,sf); + + /* many Super Paper Mario tracks have a 44.1KHz sample rate in the header, + * but they should be played at 22.05KHz; detect with fake extension */ + if (vgmstream->sample_rate == 44100 && check_extensions(sf, "brstmspm")) //TODO remove + vgmstream->sample_rate = 22050; + + vgmstream->layout_type = (channels == 1) ? layout_none : layout_interleave; + switch(codec) { case 0: - coding_type = coding_PCM8; + vgmstream->coding_type = coding_PCM8; break; case 1: - coding_type = coding_PCM16BE; + vgmstream->coding_type = coding_PCM16BE; break; case 2: - coding_type = coding_NGC_DSP; + vgmstream->coding_type = coding_NGC_DSP; break; default: goto fail; } - if (channel_count < 1) goto fail; - - /* build the VGMSTREAM */ - - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - vgmstream->num_samples = read_32bitBE(head_offset+0x2c,streamFile); - vgmstream->sample_rate = (uint16_t)read_16bitBE(head_offset+0x24,streamFile); - /* channels and loop flag are set by allocate_vgmstream */ - vgmstream->loop_start_sample = read_32bitBE(head_offset+0x28,streamFile); - vgmstream->loop_end_sample = vgmstream->num_samples; - - vgmstream->coding_type = coding_type; - vgmstream->layout_type = (channel_count == 1) ? layout_none : layout_interleave; - vgmstream->meta_type = meta_RSTM; - if (atlus_shrunken_head) - vgmstream->meta_type = meta_RSTM_shrunken; - - if (spm_flag&& vgmstream->sample_rate == 44100) { - vgmstream->meta_type = meta_RSTM_SPM; - vgmstream->sample_rate = 22050; - } - - vgmstream->interleave_block_size = read_32bitBE(head_offset+0x38,streamFile); - vgmstream->interleave_last_block_size = read_32bitBE(head_offset+0x48,streamFile); - + // TODO read hist if (vgmstream->coding_type == coding_NGC_DSP) { off_t coef_offset; - off_t head_part3_offset; off_t adpcm_header_offset; - int i,j; - int coef_spacing; + int i, ch; - if (atlus_shrunken_head) - { - coef_offset = 0x50; - coef_spacing = 0x30; - - for (j = 0; j < vgmstream->channels; j++) { - for (i = 0; i < 16; i++) { - vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(head_offset + coef_offset + j * coef_spacing + i * 2,streamFile); - } - } + if (version == 0x0001) { + /* standard */ + VGM_LOG("ss=%x\n", head_offset + 0x38); + dsp_read_coefs_be(vgmstream, sf, head_offset + 0x38, 0x30); } - else - { - head_part3_offset = read_32bitBE(head_offset + 0x1c, streamFile); + else { + uint32_t head_part3_offset = read_32bitBE(head_offset + 0x1c, sf); - for (j = 0; j < vgmstream->channels; j++) { + /* read from offset table */ + for (ch = 0; ch < vgmstream->channels; ch++) { adpcm_header_offset = head_offset + 0x08 + head_part3_offset + 0x04 /* skip over HEAD part 3 */ - + j * 0x08 /* skip to channel's ADPCM offset table */ + + ch * 0x08 /* skip to channel's ADPCM offset table */ + 0x04; /* ADPCM header offset field */ coef_offset = head_offset + 0x08 - + read_32bitBE(adpcm_header_offset, streamFile) + + read_u32be(adpcm_header_offset, sf) + 0x08; /* coeffs field */ for (i = 0; i < 16; i++) { - vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_offset + i * 2, streamFile); + vgmstream->ch[ch].adpcm_coef[i] = read_s16be(coef_offset + i * 2, sf); } } } } - start_offset = read_32bitBE(head_offset+0x30,streamFile); - - /* open the file for reading by each channel */ - { - int i; - for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - - if (!vgmstream->ch[i].streamfile) goto fail; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset= - start_offset + i*vgmstream->interleave_block_size; - } - } - + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; return vgmstream; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/cps.c b/Frameworks/vgmstream/vgmstream/src/meta/cps.c new file mode 100644 index 000000000..071c5be0e --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/cps.c @@ -0,0 +1,50 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* CPS - tri-Crescendo games [Eternal Sonata (PS3)] */ +VGMSTREAM* init_vgmstream_cps(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + + /* checks */ + if (!is_id32be(0x00,sf, "CPS ")) + goto fail; + if (!check_extensions(sf,"cps")) + goto fail; + + start_offset = read_32bitBE(0x04,sf); + channels = read_32bitBE(0x08,sf); + loop_flag = read_32bitBE(0x18,sf); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_CPS; + vgmstream->channels = channels; + vgmstream->sample_rate = read_32bitBE(0x10,sf); + if (read_32bitBE(0x20,sf) == 0) { + vgmstream->coding_type = coding_PCM16BE; + vgmstream->layout_type = layout_interleave; + vgmstream->num_samples = pcm16_bytes_to_samples(read_32bitBE(0x0c,sf), channels); + vgmstream->interleave_block_size = 2; + } + else { + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->num_samples = ps_bytes_to_samples(read_32bitBE(0x0c,sf), channels); + vgmstream->interleave_block_size = 0x10; + vgmstream->loop_start_sample = ps_bytes_to_samples(read_32bitBE(0x14,sf), channels); + vgmstream->loop_end_sample = ps_bytes_to_samples(read_32bitBE(0x18,sf), channels); + } + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/cxs.c b/Frameworks/vgmstream/vgmstream/src/meta/cxs.c new file mode 100644 index 000000000..3cf02d589 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/cxs.c @@ -0,0 +1,56 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* CXS - tri-Crescendo games [Eternal Sonata (X360)] */ +VGMSTREAM* init_vgmstream_cxs(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + /* checks */ + if (!is_id32be(0x00,sf, "CXS ")) + goto fail; + if (!check_extensions(sf,"cxs")) + goto fail; + + loop_flag = read_32bitBE(0x18,sf) > 0; + channels = read_32bitBE(0x0c,sf); + start_offset = read_32bitBE(0x04,sf) + read_32bitBE(0x28,sf); /* assumed, seek table always at 0x800 */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + /* 0x04: data start? */ + vgmstream->sample_rate = read_32bitBE(0x08,sf); + vgmstream->num_samples = read_32bitBE(0x10,sf); + vgmstream->loop_start_sample = read_32bitBE(0x14,sf); + vgmstream->loop_end_sample = read_32bitBE(0x18,sf); + /* 0x1c: below */ + + vgmstream->meta_type = meta_CXS; + +#ifdef VGM_USE_FFMPEG + { + uint32_t block_count = read_32bitBE(0x1c,sf); + uint32_t block_size = read_32bitBE(0x20,sf); + uint32_t data_size = read_32bitBE(0x24,sf); + + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, 0, 0,1); /* num samples are ok */ + } +#else + goto fail; +#endif + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c b/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c index d9fbe03ec..ce8e7dd50 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c @@ -1847,8 +1847,7 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_ /* EA-XMA uses completely separate 1/2ch streams, unlike standard XMA that interleaves 1/2ch * streams with a skip counter to reinterleave (so EA-XMA streams don't have skips set) */ case EAAC_CODEC_EAXMA: { - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size; size_t stream_size; int is_xma1; @@ -1856,18 +1855,18 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_ if (!temp_sf) goto fail; stream_size = get_streamfile_size(temp_sf); - block_size = 0x10000; /* unused */ - block_count = stream_size / block_size + ((stream_size % block_size) ? 1 : 0); + block_size = 0x10000; /* EA adopted XMA2 when it appeared around 2006, but detection isn't so easy * (SNS with XMA2 do exist). Decoder should work when playing XMA1 as XMA2, but * the other way around can cause issues, so it's safer to just use XMA2. */ is_xma1 = 0; //eaac->version == EAAC_VERSION_V0; /* approximate */ - if (is_xma1) - bytes = ffmpeg_make_riff_xma1(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, 0); - else - bytes = ffmpeg_make_riff_xma2(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, block_count, block_size); - data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, 0x00, stream_size); + if (is_xma1) { + data->layers[i]->codec_data = init_ffmpeg_xma1_raw(temp_sf, 0x00, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, 0); + } + else { + data->layers[i]->codec_data = init_ffmpeg_xma2_raw(temp_sf, 0x00, stream_size, data->layers[i]->num_samples, data->layers[i]->channels, data->layers[i]->sample_rate, block_size, 0); + } if (!data->layers[i]->codec_data) goto fail; data->layers[i]->coding_type = coding_FFmpeg; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ea_swvr.c b/Frameworks/vgmstream/vgmstream/src/meta/ea_swvr.c index 53b53a52e..6f1ff03a2 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ea_swvr.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ea_swvr.c @@ -1,25 +1,22 @@ #include "meta.h" #include "../layout/layout.h" #include "../coding/coding.h" +#include "../util/endianness.h" /* SWVR - from EA games, demuxed from .av/trk/mis/etc [Future Cop L.A.P.D. (PS/PC), Freekstyle (PS2/GC), EA Sports Supercross (PS)] */ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { - VGMSTREAM * vgmstream = NULL; + VGMSTREAM* vgmstream = NULL; off_t start_offset; - int loop_flag = 0, channels, sample_rate, big_endian; + int loop_flag = 0, channels, sample_rate, big_endian, loop_block = 0; coding_t coding; uint32_t block_id; - int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; - int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL; + read_u32_t read_u32 = NULL; + read_u16_t read_u16 = NULL; int total_subsongs, target_subsong = sf->stream_index; /* checks */ - /* .stream: common (found inside files) - * .str: shortened, probably unnecessary */ - if (!check_extensions(sf,"stream,str")) - goto fail; /* Files have no actual audio headers, so we inspect the first block for known values. * Freekstyle uses multiblocks/subsongs (though some subsongs may be clones?) */ @@ -27,40 +24,48 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { /* blocks ids are in machine endianness */ if (read_u32be(0x00,sf) == get_id32be("RVWS")) { /* PS1/PS2/PC */ big_endian = 0; - read_32bit = read_32bitLE; - read_16bit = read_16bitLE; - start_offset = read_32bit(0x04, sf); + read_u32 = read_u32le; + read_u16 = read_u16le; + start_offset = read_u32(0x04, sf); + /* 0x08: null */ + loop_block = read_u32(0x0c, sf); /* uncommon [NASCAR Racing (PS1), Rumble Racing (PS2)] */ } else if (read_u32be(0x00,sf) == get_id32be("SWVR")) { /* GC */ big_endian = 1; - read_32bit = read_32bitBE; - read_16bit = read_16bitBE; - start_offset = read_32bit(0x04, sf); + read_u32 = read_u32be; + read_u16 = read_u16be; + start_offset = read_u32(0x04, sf); } else if (read_u32be(0x00,sf) == get_id32be("MGAV")) { /* Freekstyle (PS2) raw movies */ big_endian = 0; - read_32bit = read_32bitLE; - read_16bit = read_16bitLE; + read_u32 = read_u32le; + read_u16 = read_u16le; start_offset = 0x00; } else if (read_u32be(0x00,sf) == get_id32be("DSPM")) { /* Freekstyle (GC) raw movies */ big_endian = 1; - read_32bit = read_32bitBE; - read_16bit = read_16bitBE; + read_u32 = read_u32be; + read_u16 = read_u16be; start_offset = 0x00; } else { goto fail; } - if (read_32bit(start_offset+0x00, sf) == get_id32be("PADD")) /* Freekstyle */ - start_offset += read_32bit(start_offset+0x04, sf); + /* .stream: common (found inside files) + * .str: shortened, probably unnecessary */ + if (!check_extensions(sf,"stream,str")) + goto fail; - if (read_32bit(start_offset+0x00, sf) == get_id32be("FILL")) /* Freekstyle */ - start_offset += read_32bit(start_offset+0x04, sf); + + if (read_u32(start_offset+0x00, sf) == get_id32be("PADD")) /* Freekstyle */ + start_offset += read_u32(start_offset+0x04, sf); + + if (read_u32(start_offset+0x00, sf) == get_id32be("FILL")) /* Freekstyle */ + start_offset += read_u32(start_offset+0x04, sf); total_subsongs = 1; - block_id = read_32bit(start_offset, sf); + block_id = read_u32(start_offset, sf); /* value after block id (usually at 0x38) is number of blocks of 0x6000 (results in file size, including FILLs) */ /* intended sample rate for PSX music (verified in emus) should be 14260, but is found in ELF as pitch value @@ -69,8 +74,8 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { switch(block_id) { case 0x5641474D: /* "VAGM" (stereo music) */ coding = coding_PSX; - if (read_16bit(start_offset+0x1a, sf) == 0x0024) { - total_subsongs = read_32bit(start_offset+0x0c, sf)+1; + if (read_u16(start_offset+0x1a, sf) == 0x0024) { + total_subsongs = read_u32(start_offset+0x0c, sf)+1; sample_rate = 22050; /* Freekstyle (PS2) */ } else { @@ -80,7 +85,7 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { break; case 0x56414742: /* "VAGB" (mono sfx/voices)*/ coding = coding_PSX; - if (read_16bit(start_offset+0x1a, sf) == 0x6400) { + if (read_u16(start_offset+0x1a, sf) == 0x6400) { sample_rate = 22050; /* Freekstyle (PS2) */ } else { @@ -91,7 +96,7 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { break; case 0x4453504D: /* "DSPM" (stereo music) */ coding = coding_NGC_DSP; - total_subsongs = read_32bit(start_offset+0x0c, sf)+1; + total_subsongs = read_u32(start_offset+0x0c, sf)+1; sample_rate = 22050; /* Freekstyle (GC) */ channels = 2; break; @@ -106,7 +111,7 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { sample_rate = 14291; /* assumed, by comparing vs PSX output [Future Cop (PC)] */ break; case 0x53484F43: /* "SHOC" (a generic block but hopefully has PC sounds) */ - if (read_32bit(start_offset+0x10, sf) == get_id32be("SHDR")) { /* Future Cop (PC) */ + if (read_u32(start_offset+0x10, sf) == get_id32be("SHDR")) { /* Future Cop (PC) */ /* there is a mini header? after SHDR * 0x00: 5 * 0x04: "snds" @@ -118,7 +123,7 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { * 0x1c: 1 * 0x20: 1 * 0x24: 0x4F430000 */ - if (read_32bit(start_offset+0x18, sf) != get_id32be("snds")) + if (read_u32(start_offset+0x18, sf) != get_id32be("snds")) goto fail; coding = coding_PCM8_U_int; channels = 1; @@ -139,7 +144,7 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { if (target_subsong == 0) target_subsong = 1; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; - loop_flag = 0;//(channels > 1); /* some Future Cop LAPD tracks repeat but other games have fadeouts */ + loop_flag = (loop_block > 0);//(channels > 1); /* some Future Cop LAPD tracks repeat but other games have fadeouts */ /* build the VGMSTREAM */ @@ -162,9 +167,11 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { /* calc num_samples manually */ { - int num_samples; + int block, num_samples; + vgmstream->stream_index = target_subsong; /* needed to skip other subsong-blocks */ vgmstream->next_block_offset = start_offset; + block = 0; do { block_update(vgmstream->next_block_offset,vgmstream); switch(vgmstream->coding_type) { @@ -174,15 +181,19 @@ VGMSTREAM* init_vgmstream_ea_swvr(STREAMFILE* sf) { default: num_samples = 0; break; } vgmstream->num_samples += num_samples; + + /* check loop on data blocks */ + if (num_samples) { + block++; + if (loop_block == block) /* 1=first */ + vgmstream->loop_start_sample = vgmstream->num_samples; + } } while (vgmstream->next_block_offset < get_streamfile_size(sf)); block_update(start_offset, vgmstream); } - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = vgmstream->num_samples; - } + vgmstream->loop_end_sample = vgmstream->num_samples; return vgmstream; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/encrypted_mc161_streamfile.h b/Frameworks/vgmstream/vgmstream/src/meta/encrypted_mc161_streamfile.h index e8a1fde6a..8eeb08d03 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/encrypted_mc161_streamfile.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/encrypted_mc161_streamfile.h @@ -16,8 +16,8 @@ static void decrypt_chunk(uint8_t* buf, int buf_size, mc161_io_data* data) { for (i = 0; i < buf_size; i++) { - buf[i] = (uint8_t)(buf[i] ^ ((hash >> 8) & 0xFF)); - hash = (int32_t)(hash * 498729871) + (85731 * (int8_t)buf[i]); /* signed */ + buf[i] = (uint8_t)(buf[i] ^ ((hash >> 8) & 0xFF)); + hash = (int32_t)(hash * 498729871) + (85731 * (int8_t)buf[i]); /* signed */ } data->curr_key = hash; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb.c b/Frameworks/vgmstream/vgmstream/src/meta/fsb.c index 1407627f8..ab9961591 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb.c @@ -118,7 +118,7 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { /* .fsb: standard * .bnk: Hard Corps Uprising (PS3) - * .sfx: Geon Cube (Wii) + * .sfx: Geon Cube (Wii) * .xen: Guitar Hero: World Tour (PC) */ if ( !check_extensions(sf, "fsb,bnk,sfx,xen") ) goto fail; @@ -388,19 +388,15 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case XMA: { /* FSB3: The Bourne Conspiracy 2008 (X360), FSB4: Armored Core V (X360), Hard Corps (X360) */ - uint8_t buf[0x100]; - size_t bytes, block_size, block_count; + int block_size = 0x8000; /* FSB default */ - if (fsb.version != FMOD_FSB_VERSION_4_0) { /* 3.x, though no actual output changes [ex. Guitar Hero III (X360)] */ - bytes = ffmpeg_make_riff_xma1(buf, sizeof(buf), fsb.num_samples, fsb.stream_size, fsb.channels, fsb.sample_rate, 0); + if (fsb.version != FMOD_FSB_VERSION_4_0) { + /* 3.x, though no actual output changes [ex. Guitar Hero III (X360), The Bourne Conspiracy (X360)] */ + vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, fsb.stream_offset, fsb.stream_size, fsb.channels, fsb.sample_rate, 0); } else { - block_size = 0x8000; /* FSB default */ - block_count = fsb.stream_size / block_size; /* not accurate but not needed (custom_data_offset+0x14 -1?) */ - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), fsb.num_samples, fsb.stream_size, fsb.channels, fsb.sample_rate, block_count, block_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, fsb.stream_offset, fsb.stream_size, fsb.num_samples, fsb.channels, fsb.sample_rate, block_size, 0); } - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, fsb.stream_offset,fsb.stream_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c b/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c index 11478bf4b..1b893772e 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c @@ -367,14 +367,9 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0A: {/* FMOD_SOUND_FORMAT_XMA [Minecraft Story Mode (X360)] */ - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size = 0x8000; /* FSB default */ - block_size = 0x8000; /* FSB default */ - block_count = fsb5.stream_size / block_size + (fsb5.stream_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, fsb5.stream_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sb, buf,bytes, fsb5.stream_offset, fsb5.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, fsb5.stream_offset, fsb5.stream_size, fsb5.num_samples, fsb5.channels, fsb5.sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb_encrypted.c b/Frameworks/vgmstream/vgmstream/src/meta/fsb_encrypted.c index 23b4e8071..de7c773f8 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb_encrypted.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb_encrypted.c @@ -3,6 +3,8 @@ #include "fsb_encrypted_streamfile.h" +static VGMSTREAM* test_fsbkey(STREAMFILE* sf, const uint8_t* key, size_t key_size, uint8_t flags); + /* fully encrypted FSBs */ VGMSTREAM* init_vgmstream_fsb_encrypted(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; @@ -18,58 +20,21 @@ VGMSTREAM* init_vgmstream_fsb_encrypted(STREAMFILE* sf) { if (!check_extensions(sf, "fsb,ps3,xen")) goto fail; - /* try fsbkey + all combinations of FSB4/5 and decryption algorithms */ { - STREAMFILE* temp_sf = NULL; uint8_t key[FSB_KEY_MAX]; size_t key_size = read_key_file(key, FSB_KEY_MAX, sf); - if (key_size) { - { - temp_sf = setup_fsb_streamfile(sf, key,key_size, 0); - if (!temp_sf) goto fail; - - if (!vgmstream) vgmstream = init_vgmstream_fsb(temp_sf); - if (!vgmstream) vgmstream = init_vgmstream_fsb5(temp_sf); - - close_streamfile(temp_sf); - } - - if (!vgmstream) { - temp_sf = setup_fsb_streamfile(sf, key,key_size, 1); - if (!temp_sf) goto fail; - - if (!vgmstream) vgmstream = init_vgmstream_fsb(temp_sf); - if (!vgmstream) vgmstream = init_vgmstream_fsb5(temp_sf); - - close_streamfile(temp_sf); - } - } + test_fsbkey(sf, key, key_size, MODE_FSBS_ALL); } /* try all keys until one works */ if (!vgmstream) { - int i; - STREAMFILE* temp_sf = NULL; - - for (i = 0; i < fsbkey_list_count; i++) { + for (int i = 0; i < fsbkey_list_count; i++) { fsbkey_info entry = fsbkey_list[i]; - //;VGM_LOG("fsbkey: size=%i, is_fsb5=%i, is_alt=%i\n", entry.fsbkey_size,entry.is_fsb5, entry.is_alt); - temp_sf = setup_fsb_streamfile(sf, entry.fsbkey, entry.fsbkey_size, entry.is_alt); - if (!temp_sf) goto fail; - - if (fsbkey_list[i].is_fsb5) { - vgmstream = init_vgmstream_fsb5(temp_sf); - } else { - vgmstream = init_vgmstream_fsb(temp_sf); - } - - //;if (vgmstream) dump_streamfile(temp_sf, 0); - - close_streamfile(temp_sf); + vgmstream = test_fsbkey(sf, (const uint8_t*)entry.key, entry.key_size, entry.flags); if (vgmstream) break; } } @@ -83,3 +48,41 @@ fail: close_vgmstream(vgmstream); return NULL; } + +static VGMSTREAM* test_fsbkey(STREAMFILE* sf, const uint8_t* key, size_t key_size, uint8_t flags) { + STREAMFILE* temp_sf = NULL; + VGMSTREAM* vc = NULL; + + if (!key_size) + return NULL; + + int test_fsb4 = flags & FLAG_FSB4; + int test_fsb5 = flags & FLAG_FSB5; + int test_std = flags & FLAG_STD; + int test_alt = flags & FLAG_ALT; + + + if (!vc && test_std) { + temp_sf = setup_fsb_streamfile(sf, key, key_size, 0); + if (!temp_sf) return NULL; + + if (!vc && test_fsb4) vc = init_vgmstream_fsb(temp_sf); + if (!vc && test_fsb5) vc = init_vgmstream_fsb5(temp_sf); + + //;if (vgmstream) dump_streamfile(temp_sf, 0); + close_streamfile(temp_sf); + } + + if (!vc && test_alt) { + temp_sf = setup_fsb_streamfile(sf, key, key_size, 1); + if (!temp_sf) return NULL; + + if (!vc && test_fsb4) vc = init_vgmstream_fsb(temp_sf); + if (!vc && test_fsb5) vc = init_vgmstream_fsb5(temp_sf); + + //;if (vgmstream) dump_streamfile(temp_sf, 0); + close_streamfile(temp_sf); + } + + return vc; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/fsb_keys.h index 4a623d718..66e891ec9 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb_keys.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb_keys.h @@ -1,100 +1,11 @@ #ifndef _FSB_KEYS_H_ #define _FSB_KEYS_H_ +#include -/** +/* * List of known keys, found in aluigi's site (http://aluigi.altervista.org), forums, guessfsb.exe or manually. */ -/* DJ Hero 2 (X360) */ //"nos71RiT" -static const uint8_t key_dj2[] = { 0x6E,0x6F,0x73,0x37,0x31,0x52,0x69,0x54 }; - -/* Double Fine Productions: Brutal Legend, Massive Chalice, etc (multi) */ //"DFm3t4lFTW" -static const uint8_t key_dfp[] = { 0x44,0x46,0x6D,0x33,0x74,0x34,0x6C,0x46,0x54,0x57 }; - -/* N++ (PC?) */ //"H$#FJa%7gRZZOlxLiN50&g5Q" -static const uint8_t key_npp[] = { 0x48,0x24,0x23,0x46,0x4A,0x61,0x25,0x37,0x67,0x52,0x5A,0x5A,0x4F,0x6C,0x78,0x4C,0x69,0x4E,0x35,0x30,0x26,0x67,0x35,0x51 }; - -/* Slightly Mad Studios: Project CARS (PC?), World of Speed (PC) */ //"sTOoeJXI2LjK8jBMOk8h5IDRNZl3jq3I" -static const uint8_t key_sms[] = { 0x73,0x54,0x4F,0x6F,0x65,0x4A,0x58,0x49,0x32,0x4C,0x6A,0x4B,0x38,0x6A,0x42,0x4D,0x4F,0x6B,0x38,0x68,0x35,0x49,0x44,0x52,0x4E,0x5A,0x6C,0x33,0x6A,0x71,0x33,0x49 }; - -/* Ghost in the Shell: First Assault (PC) */ //"%lAn2{Pi*Lhw3T}@7*!kV=?qS$@iNlJ" -static const uint8_t key_gfs[] = { 0x25,0x6C,0x41,0x6E,0x32,0x7B,0x50,0x69,0x2A,0x4C,0x68,0x77,0x33,0x54,0x7D,0x40,0x37,0x2A,0x21,0x6B,0x56,0x3D,0x3F,0x71,0x53,0x24,0x40,0x69,0x4E,0x6C,0x4A }; - -/* RevHeadz Engine Sounds (Mobile) */ //"1^7%82#&5$~/8sz" -static const uint8_t key_rev[] = { 0x31,0x5E,0x37,0x25,0x38,0x32,0x23,0x26,0x35,0x24,0x7E,0x2F,0x38,0x73,0x7A }; - -/* Dark Souls 3 (PC) */ //"FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg" -static const uint8_t key_ds3[] = { 0x46,0x44,0x50,0x72,0x56,0x75,0x54,0x34,0x66,0x41,0x46,0x76,0x64,0x48,0x4A,0x59,0x41,0x67,0x79,0x4D,0x7A,0x52,0x46,0x34,0x45,0x63,0x42,0x41,0x6E,0x4B,0x67 }; - -/* Mortal Kombat X/XL (PC) */ //"996164B5FC0F402983F61F220BB51DC6" -static const uint8_t key_mkx[] = { 0x39,0x39,0x36,0x31,0x36,0x34,0x42,0x35,0x46,0x43,0x30,0x46,0x34,0x30,0x32,0x39,0x38,0x33,0x46,0x36,0x31,0x46,0x32,0x32,0x30,0x42,0x42,0x35,0x31,0x44,0x43,0x36 }; - -/* Xian Xia Chuan (PC) */ //"gat@tcqs2010" -static const uint8_t key_xxc[] = { 0x67,0x61,0x74,0x40,0x74,0x63,0x71,0x73,0x32,0x30,0x31,0x30 }; - -/* Mirror War: Reincarnation of Holiness (PC) */ //"logicsounddesignmwsdev" -static const uint8_t key_mwr[] = { 0x6C,0x6F,0x67,0x69,0x63,0x73,0x6F,0x75,0x6E,0x64,0x64,0x65,0x73,0x69,0x67,0x6E,0x6D,0x77,0x73,0x64,0x65,0x76 }; - -/* Need for Speed Shift 2 Unleashed (PC demo?) */ //"p&oACY^c4LK5C2v^x5nIO6kg5vNH$tlj" -static const uint8_t key_n2u[] = { 0x70,0x26,0x6F,0x41,0x43,0x59,0x5E,0x63,0x34,0x4C,0x4B,0x35,0x43,0x32,0x76,0x5E,0x78,0x35,0x6E,0x49,0x4F,0x36,0x6B,0x67,0x35,0x76,0x4E,0x48,0x24,0x74,0x6C,0x6A }; - -/* Critter Crunch (PC), Superbrothers: Sword & Sworcery (PC) */ //"j1$Mk0Libg3#apEr42mo" -static const uint8_t key_ccr[] = { 0x6A,0x31,0x24,0x4D,0x6B,0x30,0x4C,0x69,0x62,0x67,0x33,0x23,0x61,0x70,0x45,0x72,0x34,0x32,0x6D,0x6F }; - -/* Cyphers */ //"@kdj43nKDN^k*kj3ndf02hd95nsl(NJG" -static const uint8_t key_cyp[] = { 0x40,0x6B,0x64,0x6A,0x34,0x33,0x6E,0x4B,0x44,0x4E,0x5E,0x6B,0x2A,0x6B,0x6A,0x33,0x6E,0x64,0x66,0x30,0x32,0x68,0x64,0x39,0x35,0x6E,0x73,0x6C,0x28,0x4E,0x4A,0x47 }; - -/* Xuan Dou Zhi Wang / King of Combat */ //"Xiayuwu69252.Sonicli81223#$*@*0" -static const uint8_t key_xdz[] = { 0x58,0x69,0x61,0x79,0x75,0x77,0x75,0x36,0x39,0x32,0x35,0x32,0x2E,0x53,0x6F,0x6E,0x69,0x63,0x6C,0x69,0x38,0x31,0x32,0x32,0x33,0x23,0x24,0x2A,0x40,0x2A,0x30 }; - -/* Ji Feng Zhi Ren / Kritika Online */ //"kri_tika_5050_" -static const uint8_t key_jzz[] = { 0x6B,0x72,0x69,0x5F,0x74,0x69,0x6B,0x61,0x5F,0x35,0x30,0x35,0x30,0x5F }; - -/* Invisible Inc. (PC?) */ //"mint78run52" -static const uint8_t key_inv[] = { 0x6D,0x69,0x6E,0x74,0x37,0x38,0x72,0x75,0x6E,0x35,0x32 }; - -/* Guitar Hero 3 */ //"5atu6w4zaw" -static const uint8_t key_gh3[] = { 0x35,0x61,0x74,0x75,0x36,0x77,0x34,0x7A,0x61,0x77 }; - -/* Supreme Commander 2 */ //"B2A7BB00" -static const uint8_t key_sc2[] = { 0x42,0x32,0x41,0x37,0x42,0x42,0x30,0x30 }; - -/* Cookie Run: Ovenbreak */ //"ghfxhslrghfxhslr" -static const uint8_t key_cro[] = { 0x67,0x68,0x66,0x78,0x68,0x73,0x6C,0x72,0x67,0x68,0x66,0x78,0x68,0x73,0x6C,0x72 }; - -/* Monster Jam (PS2) */ //"truck/impact/carbody" -static const uint8_t key_mtj[] = { 0x74,0x72,0x75,0x63,0x6B,0x2F,0x69,0x6D,0x70,0x61,0x63,0x74,0x2F,0x63,0x61,0x72,0x62,0x6F,0x64,0x79 }; - -/* Guitar Hero 5 (X360) */ -static const uint8_t key_gh5[] = { 0xFC,0xF9,0xE4,0xB3,0xF5,0x57,0x5C,0xA5,0xAC,0x13,0xEC,0x4A,0x43,0x19,0x58,0xEB,0x4E,0xF3,0x84,0x0B,0x8B,0x78,0xFA,0xFD,0xBB,0x18,0x46,0x7E,0x31,0xFB,0xD0 }; - -/* Sekiro: Shadows Die Twice (PC) */ //"G0KTrWjS9syqF7vVD6RaVXlFD91gMgkC" -static const uint8_t key_sek[] = { 0x47,0x30,0x4B,0x54,0x72,0x57,0x6A,0x53,0x39,0x73,0x79,0x71,0x46,0x37,0x76,0x56,0x44,0x36,0x52,0x61,0x56,0x58,0x6C,0x46,0x44,0x39,0x31,0x67,0x4D,0x67,0x6B,0x43 }; - -/* SCP: Unity (PC) */ //"BasicEncryptionKey" -static const uint8_t key_scp[] = { 0x42,0x61,0x73,0x69,0x63,0x45,0x6E,0x63,0x72,0x79,0x70,0x74,0x69,0x6F,0x6E,0x4B,0x65,0x79 }; - -/* Guitar Hero: Metallica (X360) */ -static const uint8_t key_ghm[] = { 0x8C,0xFA,0xF3,0x14,0xB1,0x53,0xDA,0xAB,0x2B,0x82,0x6B,0xD5,0x55,0x16,0xCF,0x01,0x90,0x20,0x28,0x14,0xB1,0x53,0xD8 }; - -/* Worms Rumble Beta (PC) */ //"FXnTffGJ9LS855Gc" -static const uint8_t key_wrb[] = { 0x46,0x58,0x6E,0x54,0x66,0x66,0x47,0x4A,0x39,0x4C,0x53,0x38,0x35,0x35,0x47,0x63 }; - -/* Bubble Fighter (PC) */ //"qjvkeoqkrdhkdckd" -static const uint8_t key_bbf[] = { 0x71,0x6A,0x76,0x6B,0x65,0x6F,0x71,0x6B,0x72,0x64,0x68,0x6B,0x64,0x63,0x6B,0x64 }; - -/* Fall Guys (PC) update ~2021-11 */ //"p@4_ih*srN:UJk&8" -static const uint8_t key_fg1[] = { 0x70,0x40,0x34,0x5F,0x69,0x68,0x2A,0x73,0x72,0x4E,0x3A,0x55,0x4A,0x6B,0x26,0x38 }; - -/* Fall Guys (PC) update ~2022-07 */ //",&.XZ8]fLu%caPF+" -static const uint8_t key_fg2[] = { 0x2c,0x26,0x2e,0x58,0x5a,0x38,0x5d,0x66,0x4c,0x75,0x25,0x63,0x61,0x50,0x46,0x2b }; - -/* Achilles: Legends Untold (PC) */ //"Achilles_0_15_DpG" -static const uint8_t key_alu[] = { 0x41,0x63,0x68,0x69,0x6C,0x6C,0x65,0x73,0x5F,0x30,0x5F,0x31,0x35,0x5F,0x44,0x70,0x47 }; - -/* Cult of the Lamb Demo (PC) */ //"4FB8CC894515617939F4E1B7D50972D27213B8E6" -static const uint8_t key_col[] = { 0x34,0x46,0x42,0x38,0x43,0x43,0x38,0x39,0x34,0x35,0x31,0x35,0x36,0x31,0x37,0x39,0x33,0x39,0x46,0x34,0x45,0x31,0x42,0x37,0x44,0x35,0x30,0x39,0x37,0x32,0x44,0x32,0x37,0x32,0x31,0x33,0x42,0x38,0x45,0x36 }; - // Unknown: // - Battle: Los Angeles // - Guitar Hero: Warriors of Rock, DJ hero FSB @@ -102,70 +13,62 @@ static const uint8_t key_col[] = { 0x34,0x46,0x42,0x38,0x43,0x43,0x38,0x39,0x34, // - Gas Guzzlers: Combat Carnage (PC?) "C5FA83EA64B34EC2BFE" hex or text? [FSB5] typedef struct { - int is_fsb5; /* FSB5 or FSB4/3*/ - int is_alt; /* alt XOR mode (seemingly not tied to FSB version or anything) */ - size_t fsbkey_size; - const uint8_t* fsbkey; + uint8_t flags; + const char* key; + size_t key_size; /* precalc'd for speed */ } fsbkey_info; +#define FLAG_FSB4 (1 << 0) /* key is valid for FSB4/3 */ +#define FLAG_FSB5 (1 << 1) /* key is valid for FSB5 */ +#define FLAG_STD (1 << 2) /* regular XOR mode */ +#define FLAG_ALT (1 << 3) /* alt XOR mode (seemingly not tied to FSB version or anything, maybe wrong key) */ + +#define MODE_FSB4_STD (FLAG_FSB4 | FLAG_STD) +#define MODE_FSB4_ALT (FLAG_FSB4 | FLAG_ALT) +#define MODE_FSB4_ALL (FLAG_FSB4 | FLAG_ALT) +#define MODE_FSB5_STD (FLAG_FSB5 | FLAG_STD) +#define MODE_FSB5_ALT (FLAG_FSB5 | FLAG_STD) +#define MODE_FSB5_ALL (FLAG_FSB5 | FLAG_STD | FLAG_ALT) +#define MODE_FSBS_STD (FLAG_FSB4 | FLAG_FSB5 | FLAG_STD) +#define MODE_FSBS_ALL (FLAG_FSB4 | FLAG_FSB5 | FLAG_STD | FLAG_ALT) + +/* ugly macro for string + precomputed len (removing string's extra NULL)*/ +#define FSBKEY_ADD(key) key, sizeof(key) - 1 + static const fsbkey_info fsbkey_list[] = { - { 0,0, sizeof(key_dj2),key_dj2 }, - { 0,0, sizeof(key_dfp),key_dfp },//FSB4 - { 1,0, sizeof(key_dfp),key_dfp },//FSB5 - { 1,0, sizeof(key_npp),key_npp },//FSB5 - { 1,0, sizeof(key_sms),key_sms },//FSB5 - { 1,0, sizeof(key_gfs),key_gfs },//FSB5 - { 1,0, sizeof(key_rev),key_rev },//FSB5 - { 1,0, sizeof(key_ds3),key_ds3 },//untested - { 1,1, sizeof(key_ds3),key_ds3 }, - { 1,0, sizeof(key_mkx),key_mkx },//FSB5 - { 0,0, sizeof(key_xxc),key_xxc },//untested - { 0,1, sizeof(key_xxc),key_xxc },//untested - { 1,0, sizeof(key_xxc),key_xxc },//untested - { 1,1, sizeof(key_xxc),key_xxc },//untested - { 1,0, sizeof(key_mwr),key_mwr },//FSB5 - { 0,0, sizeof(key_n2u),key_n2u },//untested - { 0,1, sizeof(key_n2u),key_n2u },//untested - { 0,0, sizeof(key_ccr),key_ccr },//untested - { 0,1, sizeof(key_ccr),key_ccr },//untested - { 1,0, sizeof(key_ccr),key_ccr },//untested - { 1,1, sizeof(key_ccr),key_ccr },//untested - { 0,0, sizeof(key_cyp),key_cyp },//untested - { 0,1, sizeof(key_cyp),key_cyp },//untested - { 1,0, sizeof(key_cyp),key_cyp },//untested - { 1,1, sizeof(key_cyp),key_cyp },//untested - { 0,0, sizeof(key_xdz),key_xdz },//untested - { 0,1, sizeof(key_xdz),key_xdz },//untested - { 1,0, sizeof(key_xdz),key_xdz },//untested - { 1,1, sizeof(key_xdz),key_xdz },//untested - { 0,0, sizeof(key_jzz),key_jzz },//untested - { 0,1, sizeof(key_jzz),key_jzz },//untested - { 1,0, sizeof(key_jzz),key_jzz },//untested - { 1,1, sizeof(key_jzz),key_jzz },//untested - { 0,0, sizeof(key_inv),key_inv },//untested - { 0,1, sizeof(key_inv),key_inv },//untested - { 1,0, sizeof(key_inv),key_inv },//untested - { 1,1, sizeof(key_inv),key_inv },//untested - { 0,0, sizeof(key_gh3),key_gh3 },//untested - { 0,1, sizeof(key_gh3),key_gh3 },//untested - { 1,0, sizeof(key_gh3),key_gh3 },//untested - { 1,1, sizeof(key_gh3),key_gh3 },//untested - { 0,0, sizeof(key_sc2),key_sc2 },//untested - { 0,1, sizeof(key_sc2),key_sc2 },//untested - { 1,0, sizeof(key_sc2),key_sc2 },//untested - { 1,1, sizeof(key_sc2),key_sc2 },//untested - { 1,0, sizeof(key_cro),key_cro }, - { 0,1, sizeof(key_mtj),key_mtj },// FSB3 - { 0,1, sizeof(key_gh5),key_gh5 },// FSB4 - { 1,0, sizeof(key_sek),key_sek },// FSB5 - { 1,0, sizeof(key_scp),key_scp },// FSB5 - { 0,1, sizeof(key_ghm),key_ghm },// FSB4 - { 1,0, sizeof(key_wrb),key_wrb },// FSB5 - { 0,0, sizeof(key_bbf),key_bbf },// FSB4 - { 1,0, sizeof(key_fg1),key_fg1 },// FSB5 - { 1,0, sizeof(key_fg2),key_fg2 },// FSB5 - { 1,0, sizeof(key_alu),key_alu },// FSB5 - { 1,0, sizeof(key_col),key_col },// FSB5 + { MODE_FSBS_STD, FSBKEY_ADD("DFm3t4lFTW") }, // Double Fine Productions: Brutal Legend, Massive Chalice, etc (multi) + { MODE_FSB4_STD, FSBKEY_ADD("nos71RiT") }, // DJ Hero 2 (X360) + { MODE_FSB5_STD, FSBKEY_ADD("H$#FJa%7gRZZOlxLiN50&g5Q") }, // N++ (PC?) + { MODE_FSB5_STD, FSBKEY_ADD("sTOoeJXI2LjK8jBMOk8h5IDRNZl3jq3I") }, // Slightly Mad Studios: Project CARS (PC?), World of Speed (PC) + { MODE_FSB5_STD, FSBKEY_ADD("%lAn2{Pi*Lhw3T}@7*!kV=?qS$@iNlJ") }, // Ghost in the Shell: First Assault (PC) + { MODE_FSB5_STD, FSBKEY_ADD("1^7%82#&5$~/8sz") }, // RevHeadz Engine Sounds (Mobile) + { MODE_FSB5_ALL, FSBKEY_ADD("FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg") }, // Dark Souls 3 (PC) [untested] + { MODE_FSB4_ALL, FSBKEY_ADD("p&oACY^c4LK5C2v^x5nIO6kg5vNH$tlj") }, // Need for Speed Shift 2 Unleashed (PC demo?)[untested] + { MODE_FSB5_STD, FSBKEY_ADD("996164B5FC0F402983F61F220BB51DC6") }, // Mortal Kombat X/XL (PC) + { MODE_FSB5_STD, FSBKEY_ADD("logicsounddesignmwsdev") }, // Mirror War: Reincarnation of Holiness (PC) + { MODE_FSBS_ALL, FSBKEY_ADD("gat@tcqs2010") }, // Xian Xia Chuan (PC) [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("j1$Mk0Libg3#apEr42mo") }, // Critter Crunch (PC), Superbrothers: Sword & Sworcery (PC) [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("@kdj43nKDN^k*kj3ndf02hd95nsl(NJG") }, // Cyphers [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("Xiayuwu69252.Sonicli81223#$*@*0") }, // Xuan Dou Zhi Wang / King of Combat [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("kri_tika_5050_") }, // Ji Feng Zhi Ren / Kritika Online [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("mint78run52") }, // Invisible Inc. (PC?) [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("5atu6w4zaw") }, // Guitar Hero 3 [untested] + { MODE_FSBS_ALL, FSBKEY_ADD("B2A7BB00") }, // Supreme Commander 2 [untested] + { MODE_FSB4_STD, FSBKEY_ADD("ghfxhslrghfxhslr") }, // Cookie Run: Ovenbreak + { MODE_FSB4_ALT, FSBKEY_ADD("truck/impact/carbody") },// Monster Jam (PS2) [FSB3] + { MODE_FSB4_ALT, FSBKEY_ADD("\xFC\xF9\xE4\xB3\xF5\x57\x5C\xA5\xAC\x13\xEC\x4A\x43\x19\x58\xEB\x4E\xF3\x84\x0B\x8B\x78\xFA\xFD\xBB\x18\x46\x7E\x31\xFB\xD0") }, + { MODE_FSB4_ALT, FSBKEY_ADD("\x8C\xFA\xF3\x14\xB1\x53\xDA\xAB\x2B\x82\x6B\xD5\x55\x16\xCF\x01\x90\x20\x28\x14\xB1\x53\xD8") }, + { MODE_FSB5_STD, FSBKEY_ADD("G0KTrWjS9syqF7vVD6RaVXlFD91gMgkC") }, // Sekiro: Shadows Die Twice (PC) + { MODE_FSB5_STD, FSBKEY_ADD("BasicEncryptionKey") }, // SCP: Unity (PC) + { MODE_FSB5_STD, FSBKEY_ADD("FXnTffGJ9LS855Gc") }, // Worms Rumble Beta (PC) + { MODE_FSB4_STD, FSBKEY_ADD("qjvkeoqkrdhkdckd") }, // Bubble Fighter (PC) + { MODE_FSB5_STD, FSBKEY_ADD("p@4_ih*srN:UJk&8") }, // Fall Guys (PC) update ~2021-11 + { MODE_FSB5_STD, FSBKEY_ADD(",&.XZ8]fLu%caPF+") }, // Fall Guys (PC) update ~2022-07 + { MODE_FSB5_STD, FSBKEY_ADD("Achilles_0_15_DpG") }, // Achilles: Legends Untold (PC) + { MODE_FSB5_STD, FSBKEY_ADD("4FB8CC894515617939F4E1B7D50972D27213B8E6") }, // Cult of the Lamb Demo (PC) + { MODE_FSB5_STD, FSBKEY_ADD("X3EK%Bbga-%Y9HZZ%gkc*C512*$$DhRxWTGgjUG@=rUD") }, // Signalis (PC) + { MODE_FSB5_STD, FSBKEY_ADD("281ad163160cfc16f9a22c6755a64fad") }, // Ash Echoes beta (Android) + }; static const int fsbkey_list_count = sizeof(fsbkey_list) / sizeof(fsbkey_list[0]); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/gca.c b/Frameworks/vgmstream/vgmstream/src/meta/gca.c index 246068773..bd00b9482 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/gca.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/gca.c @@ -3,39 +3,37 @@ #include "../util.h" /* GCA - Terminal Reality games [Metal Slug Anthology (Wii), BlowOut (GC)] */ -VGMSTREAM * init_vgmstream_gca(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_gca(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; - int loop_flag, channel_count; + int loop_flag, channels; /* checks */ - if (!check_extensions(streamFile, "gca")) + if (!is_id32be(0x00,sf, "GCA1")) goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x47434131) /* "GCA1" */ + if (!check_extensions(sf, "gca")) goto fail; start_offset = 0x40; loop_flag = 0; - channel_count = 1; + channels = 1; - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); if (!vgmstream) goto fail; - vgmstream->sample_rate = read_32bitBE(0x2A,streamFile); - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = dsp_nibbles_to_samples(read_32bitBE(0x26,streamFile));//read_32bitBE(0x26,streamFile)*7/8; - - vgmstream->layout_type = layout_none; /* we have no interleave, so we have no layout */ vgmstream->meta_type = meta_GCA; + vgmstream->sample_rate = read_32bitBE(0x2A,sf); + vgmstream->num_samples = dsp_nibbles_to_samples(read_32bitBE(0x26,sf));//read_32bitBE(0x26,streamFile)*7/8; - dsp_read_coefs_be(vgmstream,streamFile,0x04,0x00); + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_none; - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + dsp_read_coefs_be(vgmstream, sf, 0x04, 0x00); + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/genh.c b/Frameworks/vgmstream/vgmstream/src/meta/genh.c index b7d1b82fd..aff7810e7 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/genh.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/genh.c @@ -70,21 +70,21 @@ typedef struct { static int parse_genh(STREAMFILE * streamFile, genh_header * genh); /* GENH is an artificial "generic" header for headerless streams */ -VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_genh(STREAMFILE *sf) { + VGMSTREAM* vgmstream = NULL; genh_header genh = {0}; coding_t coding; int i, j; - /* check extension, case insensitive */ - if (!check_extensions(streamFile,"genh")) goto fail; - - /* check header magic */ - if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail; + /* checks */ + if (!is_id32be(0x0,sf, "GENH")) + goto fail; + if (!check_extensions(sf,"genh")) + goto fail; /* process the header */ - if (!parse_genh(streamFile, &genh)) + if (!parse_genh(sf, &genh)) goto fail; @@ -277,13 +277,13 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { /* normal/split coefs */ if ((genh.coef_type & 1) == 0) { /* normal mode */ for (j = 0; j < 16; j++) { - vgmstream->ch[i].adpcm_coef[j] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, streamFile); + vgmstream->ch[i].adpcm_coef[j] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, sf); } } else { /* split coefs, 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right */ for (j = 0; j < 8; j++) { - vgmstream->ch[i].adpcm_coef[j*2] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, streamFile); - vgmstream->ch[i].adpcm_coef[j*2+1] = read_16bit(genh.coef_split_offset + i*genh.coef_split_spacing + j*2, streamFile); + vgmstream->ch[i].adpcm_coef[j*2] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, sf); + vgmstream->ch[i].adpcm_coef[j*2+1] = read_16bit(genh.coef_split_offset + i*genh.coef_split_spacing + j*2, sf); } } } @@ -292,7 +292,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { #ifdef VGM_USE_MPEG case coding_MPEG_layer3: vgmstream->layout_type = layout_none; - vgmstream->codec_data = init_mpeg(streamFile, genh.start_offset, &coding, vgmstream->channels); + vgmstream->codec_data = init_mpeg(sf, genh.start_offset, &coding, vgmstream->channels); if (!vgmstream->codec_data) goto fail; break; @@ -303,60 +303,48 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { if (genh.codec == FFMPEG || genh.codec == AC3 || genh.codec == AAC) { /* default FFmpeg */ - ffmpeg_data = init_ffmpeg_offset(streamFile, genh.start_offset,genh.data_size); + ffmpeg_data = init_ffmpeg_offset(sf, genh.start_offset,genh.data_size); if ( !ffmpeg_data ) goto fail; //if (vgmstream->num_samples == 0) // vgmstream->num_samples = ffmpeg_get_samples(ffmpeg_data); /* sometimes works */ } + else if (genh.codec == ATRAC3) { + int block_align, encoder_delay; + + block_align = genh.interleave; + encoder_delay = genh.skip_samples; + + ffmpeg_data = init_ffmpeg_atrac3_raw(sf, genh.start_offset,genh.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + if (!ffmpeg_data) goto fail; + } + else if (genh.codec == ATRAC3PLUS) { + int block_size = genh.interleave; + + ffmpeg_data = init_ffmpeg_atrac3plus_raw(sf, genh.start_offset, genh.data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, genh.skip_samples); + if (!ffmpeg_data) goto fail; + } + else if (genh.codec == XMA1) { + int xma_stream_mode = genh.codec_mode == 1 ? 1 : 0; + + ffmpeg_data = init_ffmpeg_xma1_raw(sf, genh.start_offset, genh.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); + if (!ffmpeg_data) goto fail; + } + else if (genh.codec == XMA2) { + int block_size = genh.interleave; + + ffmpeg_data = init_ffmpeg_xma2_raw(sf, genh.start_offset, genh.data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); + if (!ffmpeg_data) goto fail; + } else { - /* fake header FFmpeg */ - uint8_t buf[200]; - int32_t bytes; - - if (genh.codec == ATRAC3) { - int block_align, encoder_delay; - - block_align = genh.interleave; - encoder_delay = genh.skip_samples; - - ffmpeg_data = init_ffmpeg_atrac3_raw(streamFile, genh.start_offset,genh.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); - if (!ffmpeg_data) goto fail; - } - else if (genh.codec == ATRAC3PLUS) { - int block_size = genh.interleave; - - bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, genh.skip_samples); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size); - if ( !ffmpeg_data ) goto fail; - } - else if (genh.codec == XMA1) { - int xma_stream_mode = genh.codec_mode == 1 ? 1 : 0; - - bytes = ffmpeg_make_riff_xma1(buf, 100, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size); - if ( !ffmpeg_data ) goto fail; - } - else if (genh.codec == XMA2) { - int block_count, block_size; - - block_size = genh.interleave ? genh.interleave : 2048; - block_count = genh.data_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size); - if ( !ffmpeg_data ) goto fail; - } - else { - goto fail; - } + goto fail; } vgmstream->codec_data = ffmpeg_data; vgmstream->layout_type = layout_none; if (genh.codec == XMA1 || genh.codec == XMA2) { - xma_fix_raw_samples(vgmstream, streamFile, genh.start_offset,genh.data_size, 0, 0,0); + xma_fix_raw_samples(vgmstream, sf, genh.start_offset,genh.data_size, 0, 0,0); } else if (genh.skip_samples_mode && genh.skip_samples >= 0 && genh.codec != ATRAC3) { /* force encoder delay */ ffmpeg_set_skip_samples(ffmpeg_data, genh.skip_samples); } @@ -373,7 +361,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { vgmstream->allow_dual_stereo = 1; - if ( !vgmstream_open_stream(vgmstream,streamFile,genh.start_offset) ) + if ( !vgmstream_open_stream(vgmstream,sf,genh.start_offset) ) goto fail; return vgmstream; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ghs.c b/Frameworks/vgmstream/vgmstream/src/meta/ghs.c new file mode 100644 index 000000000..254ac5ef1 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/ghs.c @@ -0,0 +1,163 @@ +#include "meta.h" +#include "../coding/coding.h" + +typedef enum { XMA2, ATRAC9 } gtd_codec; +//TODO rename gtd to ghs +/* GHS - Hexadrive's HexaEngine games [Knights Contract (X360), Valhalla Knights 3 (Vita)] */ +VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset, chunk_offset, stpr_offset, name_offset = 0, loop_start_offset, loop_end_offset; + size_t data_size, chunk_size; + int loop_flag, channels, sample_rate; + int num_samples, loop_start_sample, loop_end_sample; + uint32_t at9_config_data; + gtd_codec codec; + + + /* checks */ + if (!is_id32be(0x00,sf, "GHS ")) + goto fail; + if ( !check_extensions(sf,"gtd")) + goto fail; + + + /* header type, not formally specified */ + if (read_32bitBE(0x04,sf) == 1 && read_16bitBE(0x0C,sf) == 0x0166) { /* XMA2 */ + /* 0x08(4): seek table size */ + chunk_offset = 0x0c; /* custom header with a "fmt " data chunk inside */ + chunk_size = 0x34; + + channels = read_16bitBE(chunk_offset+0x02,sf); + sample_rate = read_32bitBE(chunk_offset+0x04,sf); + xma2_parse_fmt_chunk_extra(sf, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); + + start_offset = read_32bitBE(0x58,sf); /* always 0x800 */ + data_size = read_32bitBE(0x5c,sf); + /* 0x34(18): null, 0x54(4): seek table offset, 0x58(4): seek table size, 0x5c(8): null, 0x64: seek table */ + + stpr_offset = read_32bitBE(chunk_offset+0x54,sf) + read_32bitBE(chunk_offset+0x58,sf); + if (is_id32be(stpr_offset,sf, "STPR")) { + /* SRPR encases the original "S_P_STH" header (no data) */ + name_offset = stpr_offset + 0xB8; /* there are offsets fields but seems to work */ + } + + codec = XMA2; + } + else if (0x34 + read_32bitLE(0x30,sf) + read_32bitLE(0x0c,sf) == get_streamfile_size(sf)) { /* ATRAC9 */ + + data_size = read_32bitLE(0x0c,sf); + start_offset = 0x34 + read_32bitLE(0x30,sf); + channels = read_32bitLE(0x10,sf); + sample_rate = read_32bitLE(0x14,sf); + loop_start_offset = read_32bitLE(0x1c, sf); + loop_end_offset = read_32bitLE(0x20, sf); + loop_flag = loop_end_offset > loop_start_offset; + at9_config_data = read_32bitBE(0x28,sf); + /* 0x18-0x28: fixed/unknown values */ + + stpr_offset = 0x2c; + if (is_id32be(stpr_offset,sf, "STPR")) { + /* STPR encases the original "S_P_STH" header (no data) */ + name_offset = stpr_offset + 0xE8; /* there are offsets fields but seems to work */ + } + + codec = ATRAC9; + } + else { + goto fail; + } + + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + vgmstream->meta_type = meta_GHS; + if (name_offset) //encoding is Shift-Jis in some PSV files + read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,sf); + + switch(codec) { +#ifdef VGM_USE_FFMPEG + case XMA2: + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, chunk_offset, chunk_size); + if ( !vgmstream->codec_data ) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + vgmstream->num_samples = num_samples; + + xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, chunk_offset, 1,1); + break; +#endif +#ifdef VGM_USE_ATRAC9 + case ATRAC9: { + atrac9_config cfg = {0}; + + cfg.channels = vgmstream->channels; + cfg.config_data = at9_config_data; + + vgmstream->codec_data = init_atrac9(&cfg); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_ATRAC9; + vgmstream->layout_type = layout_none; + if (loop_flag) { + vgmstream->loop_start_sample = atrac9_bytes_to_samples(loop_start_offset - start_offset, vgmstream->codec_data); + vgmstream->loop_end_sample = atrac9_bytes_to_samples(loop_end_offset - start_offset, vgmstream->codec_data); + } + vgmstream->num_samples = atrac9_bytes_to_samples(data_size, vgmstream->codec_data); + break; + } + +#endif + + default: + goto fail; + } + + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} + +/* S_P_STH - Hexadrive's HexaEngine games [Knights Contract (PS3)] */ +VGMSTREAM* init_vgmstream_s_p_sth(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; + uint32_t subfile_offset, subfile_size, name_offset; + + + /* checks */ + if (!is_id64be(0x00,sf,"S_P_STH\x01")) + goto fail; + if (!check_extensions(sf,"gtd")) + goto fail; + + subfile_offset = read_u32be(0x08, sf); + subfile_size = get_streamfile_size(sf) - subfile_offset; + + temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "msf"); + if (!temp_sf) goto fail; + + vgmstream = init_vgmstream_msf(temp_sf); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_GHS; + name_offset = 0xB0; /* there are offsets fields but seems to work */ + read_string(vgmstream->stream_name, STREAM_NAME_SIZE, name_offset, sf); + + close_streamfile(temp_sf); + return vgmstream; + +fail: + close_streamfile(temp_sf); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/gsp_gsb.c b/Frameworks/vgmstream/vgmstream/src/meta/gsp_gsb.c index b04fdf0a6..d0d2174e3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/gsp_gsb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/gsp_gsb.c @@ -3,53 +3,53 @@ #include "../coding/coding.h" /* GSP+GSB - from Tecmo's Super Swing Golf 1 & 2 (Wii), Quantum Theory (PS3/X360) */ -VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - STREAMFILE * streamHeader = NULL; +VGMSTREAM* init_vgmstream_gsp_gsb(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* sf_head = NULL; int loop_flag, channel_count, sample_rate, num_samples, loop_start, loop_end; off_t start_offset, chunk_offset, first_offset; size_t data_size; int codec; - + /* checks */ - if (!check_extensions(streamFile,"gsb")) + if (!check_extensions(sf,"gsb")) goto fail; - streamHeader = open_streamfile_by_ext(streamFile, "gsp"); - if (!streamHeader) goto fail; + sf_head = open_streamfile_by_ext(sf, "gsp"); + if (!sf_head) goto fail; - if (read_32bitBE(0x00,streamHeader) != 0x47534E44) /* "GSND" */ + if (!is_id32be(0x00,sf_head, "GSND")) goto fail; /* 0x04: version? */ /* 0x08: 1? */ /* 0x0c: 0? */ - first_offset = read_32bitBE(0x10,streamHeader); /* usually 0x14 */ + first_offset = read_32bitBE(0x10,sf_head); /* usually 0x14 */ - if (!find_chunk_be(streamHeader, 0x48454144,first_offset,1, &chunk_offset,NULL)) /* "HEAD" */ + if (!find_chunk_be(sf_head, 0x48454144,first_offset,1, &chunk_offset,NULL)) /* "HEAD" */ goto fail; /* 0x00: header size */ /* 0x04: num_chunks */ - if (!find_chunk_be(streamHeader, 0x44415441,first_offset,1, &chunk_offset,NULL)) /* "DATA" */ + if (!find_chunk_be(sf_head, 0x44415441,first_offset,1, &chunk_offset,NULL)) /* "DATA" */ goto fail; - data_size = read_32bitBE(chunk_offset + 0x00,streamHeader); - codec = read_32bitBE(chunk_offset + 0x04,streamHeader); - sample_rate = read_32bitBE(chunk_offset + 0x08,streamHeader); + data_size = read_32bitBE(chunk_offset + 0x00,sf_head); + codec = read_32bitBE(chunk_offset + 0x04,sf_head); + sample_rate = read_32bitBE(chunk_offset + 0x08,sf_head); /* 0x0c: always 16? */ - channel_count = read_16bitBE(chunk_offset + 0x0e,streamHeader); + channel_count = read_16bitBE(chunk_offset + 0x0e,sf_head); /* 0x10: always 0? */ - num_samples = read_32bitBE(chunk_offset + 0x14,streamHeader); + num_samples = read_32bitBE(chunk_offset + 0x14,sf_head); /* 0x18: always 0? */ /* 0x1c: unk (varies with codec_id) */ - if (!find_chunk_be(streamHeader, 0x42534943,first_offset,1, &chunk_offset,NULL)) /* "BSIC" */ + if (!find_chunk_be(sf_head, 0x42534943,first_offset,1, &chunk_offset,NULL)) /* "BSIC" */ goto fail; /* 0x00/0x04: probably volume/pan/etc floats (1.0) */ /* 0x08: null? */ - loop_flag = read_8bit(chunk_offset+0x0c,streamHeader); - loop_start = read_32bitBE(chunk_offset+0x10,streamHeader); - loop_end = read_32bitBE(chunk_offset+0x14,streamHeader); + loop_flag = read_8bit(chunk_offset+0x0c,sf_head); + loop_start = read_32bitBE(chunk_offset+0x10,sf_head); + loop_end = read_32bitBE(chunk_offset+0x14,sf_head); //if (!find_chunk_be(streamHeader, 0x4E414D45,first_offset,1, &chunk_offset,NULL)) /* "NAME" */ // goto fail; @@ -79,16 +79,16 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { vgmstream->coding_type = coding_NGC_DSP; vgmstream->layout_type = layout_blocked_gsb; - if (!find_chunk_be(streamHeader, 0x47434558,first_offset,1, &chunk_offset,NULL)) /* "GCEX" */ + if (!find_chunk_be(sf_head, 0x47434558,first_offset,1, &chunk_offset,NULL)) /* "GCEX" */ goto fail; //vgmstream->current_block_size = read_32bitBE(chunk_offset+0x00,streamHeader); - block_header_size = read_32bitBE(chunk_offset+0x04,streamHeader); - num_blocks = read_32bitBE(chunk_offset+0x08,streamHeader); + block_header_size = read_32bitBE(chunk_offset+0x04,sf_head); + num_blocks = read_32bitBE(chunk_offset+0x08,sf_head); vgmstream->num_samples = (data_size - block_header_size * num_blocks) / 8 / vgmstream->channels * 14; /* 0x0c+: unk */ - dsp_read_coefs_be(vgmstream, streamHeader, chunk_offset+0x18, 0x30); + dsp_read_coefs_be(vgmstream, sf_head, chunk_offset+0x18, 0x30); break; } #ifdef VGM_USE_FFMPEG @@ -100,7 +100,7 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { vgmstream->num_samples = atrac3_bytes_to_samples(data_size, block_align) - encoder_delay; /* fix num_samples as header samples seem to be modified to match altered (49999/48001) sample rates somehow */ - vgmstream->codec_data = init_ffmpeg_atrac3_raw(streamFile, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + vgmstream->codec_data = init_ffmpeg_atrac3_raw(sf, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -112,21 +112,17 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { } case 0x09: { /* XMA2 [Quantum Theory (PS3)] */ - uint8_t buf[0x100]; - int32_t bytes; - - if (!find_chunk_be(streamHeader, 0x584D4558,first_offset,1, &chunk_offset,NULL)) /* "XMEX" */ + if (!find_chunk_be(sf_head, 0x584D4558,first_offset,1, &chunk_offset,NULL)) /* "XMEX" */ goto fail; /* 0x00: fmt0x166 header (BE) */ /* 0x34: seek table */ - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,200, chunk_offset,0x34, data_size, streamHeader, 1); - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk_split(sf_head, sf, start_offset, data_size, chunk_offset, 0x34); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok */ + xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* samples are ok */ break; } #endif @@ -135,13 +131,13 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { } - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; - close_streamfile(streamHeader); + close_streamfile(sf_head); return vgmstream; fail: - close_streamfile(streamHeader); + close_streamfile(sf_head); close_vgmstream(vgmstream); return NULL; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/gtd.c b/Frameworks/vgmstream/vgmstream/src/meta/gtd.c deleted file mode 100644 index 8d77ca5e0..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/gtd.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -typedef enum { XMA2, ATRAC9 } gtd_codec; - -/* GTD - found in Knights Contract (X360, PS3), Valhalla Knights 3 (PSV) */ -VGMSTREAM * init_vgmstream_gtd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, chunk_offset, stpr_offset, name_offset = 0, loop_start_offset, loop_end_offset; - size_t data_size, chunk_size; - int loop_flag, channel_count, sample_rate; - int num_samples, loop_start_sample, loop_end_sample; - uint32_t at9_config_data; - gtd_codec codec; - - - /* check extension, case insensitive */ - if ( !check_extensions(streamFile,"gtd")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x47485320) /* "GHS " */ - goto fail; - - /* header type, not formally specified */ - if (read_32bitBE(0x04,streamFile) == 1 && read_16bitBE(0x0C,streamFile) == 0x0166) { /* XMA2 */ - /* 0x08(4): seek table size */ - chunk_offset = 0x0c; /* custom header with a "fmt " data chunk inside */ - chunk_size = 0x34; - - channel_count = read_16bitBE(chunk_offset+0x02,streamFile); - sample_rate = read_32bitBE(chunk_offset+0x04,streamFile); - xma2_parse_fmt_chunk_extra(streamFile, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); - - start_offset = read_32bitBE(0x58,streamFile); /* always 0x800 */ - data_size = read_32bitBE(0x5c,streamFile); - /* 0x34(18): null, 0x54(4): seek table offset, 0x58(4): seek table size, 0x5c(8): null, 0x64: seek table */ - - stpr_offset = read_32bitBE(chunk_offset+0x54,streamFile) + read_32bitBE(chunk_offset+0x58,streamFile); - if (read_32bitBE(stpr_offset,streamFile) == 0x53545052) { /* "STPR" */ - name_offset = stpr_offset + 0xB8; /* there are offsets fields but seems to work */ - } - - codec = XMA2; - } - else if (0x34 + read_32bitLE(0x30,streamFile) + read_32bitLE(0x0c,streamFile) == get_streamfile_size(streamFile)) { /* ATRAC9 */ - - data_size = read_32bitLE(0x0c,streamFile); - start_offset = 0x34 + read_32bitLE(0x30,streamFile); - channel_count = read_32bitLE(0x10,streamFile); - sample_rate = read_32bitLE(0x14,streamFile); - loop_start_offset = read_32bitLE(0x1c, streamFile); - loop_end_offset = read_32bitLE(0x20, streamFile); - loop_flag = loop_end_offset > loop_start_offset; - at9_config_data = read_32bitBE(0x28,streamFile); - /* 0x18-0x28: fixed/unknown values */ - - stpr_offset = 0x2c; - if (read_32bitBE(stpr_offset,streamFile) == 0x53545052) { /* "STPR" */ - name_offset = stpr_offset + 0xE8; /* there are offsets fields but seems to work */ - } - - codec = ATRAC9; - } - else { - /* apparently there is a PS3 variation (MSF inside?) */ - goto fail; - } - - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->loop_start_sample = loop_start_sample; - vgmstream->loop_end_sample = loop_end_sample; - vgmstream->meta_type = meta_GTD; - if (name_offset) //encoding is Shift-Jis in some PSV files - read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamFile); - - switch(codec) { -#ifdef VGM_USE_FFMPEG - case XMA2: { - uint8_t buf[0x100]; - size_t bytes; - - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, streamFile, 1); - if (bytes <= 0) goto fail; - - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); - if ( !vgmstream->codec_data ) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - vgmstream->num_samples = num_samples; - - xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, chunk_offset, 1,1); - break; - } -#endif -#ifdef VGM_USE_ATRAC9 - case ATRAC9: { - atrac9_config cfg = {0}; - - cfg.channels = vgmstream->channels; - cfg.config_data = at9_config_data; - - vgmstream->codec_data = init_atrac9(&cfg); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_ATRAC9; - vgmstream->layout_type = layout_none; - if (loop_flag) { - vgmstream->loop_start_sample = atrac9_bytes_to_samples(loop_start_offset - start_offset, vgmstream->codec_data); - vgmstream->loop_end_sample = atrac9_bytes_to_samples(loop_end_offset - start_offset, vgmstream->codec_data); - } - vgmstream->num_samples = atrac9_bytes_to_samples(data_size, vgmstream->codec_data); - break; - } - -#endif - - default: - goto fail; - } - - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h index 55bc11e3c..cc305f733 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h @@ -1,7 +1,7 @@ #ifndef _HCA_KEYS_H_ #define _HCA_KEYS_H_ - -#include "hca_keys_awb.h" +#include +//#include "hca_keys_awb.h" typedef struct { uint64_t key; /* hca key or seed ('user') key */ @@ -1091,12 +1091,18 @@ static const hcakey_info hcakey_list[] = { // P Sengoku Otome 6 ~Akatsuki no Sekigahara~ (Android) {97648135}, // 0000000005d1fe07 - + // CHUNITHM International Version (AC) {33426922444908636}, // 0076C19BDE43685C - + // Star Ocean: The Divine Force (PC) {68308868861462528}, // 00f2ae8de77f0800 + + // Sin Chronicle (Android) + {4385672148314579020}, // 3CDD0995259D604C + + // The Eminence in Shadow: Master of Garden (Android) + {8115775984160473168}, // 70A1074224880050 }; #endif/*_HCA_KEYS_H_*/ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/his.c b/Frameworks/vgmstream/vgmstream/src/meta/his.c index 3034db0e1..7fc4861d9 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/his.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/his.c @@ -3,10 +3,10 @@ /* HIS - Her Interactive games [Nancy Drew series (PC)] */ -VGMSTREAM * init_vgmstream_his(STREAMFILE *sf) { - VGMSTREAM * vgmstream = NULL; - int channels, loop_flag = 0, bps, sample_rate, num_samples, version; - off_t start_offset; +VGMSTREAM* init_vgmstream_his(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + int channels, loop_flag = 0, bps, sample_rate, num_samples, version, codec; + uint32_t start_offset; /* checks */ @@ -17,8 +17,10 @@ VGMSTREAM * init_vgmstream_his(STREAMFILE *sf) { goto fail; if (is_id32be(0x00,sf, "Her ")) { /* "Her Interactive Sound\x1a" */ - /* Nancy Drew: Secrets Can Kill (PC) */ version = 0; + codec = 1; + + /* Nancy Drew: Secrets Can Kill (PC) */ channels = read_u16le(0x16,sf); sample_rate = read_u32le(0x18,sf); /* 0x1c: bitrate */ @@ -34,7 +36,7 @@ VGMSTREAM * init_vgmstream_his(STREAMFILE *sf) { else if (is_id32be(0x00,sf, "HIS\0")) { /* most(?) others */ version = read_u32le(0x04,sf); - /* 0x08: codec */ + /* 0x08: format? (always 1) */ channels = read_u16le(0x0a,sf); sample_rate = read_u32le(0x0c,sf); /* 0x10: bitrate */ @@ -42,28 +44,51 @@ VGMSTREAM * init_vgmstream_his(STREAMFILE *sf) { bps = read_u16le(0x16,sf); num_samples = pcm_bytes_to_samples(read_u32le(0x18,sf), channels, bps); /* true even for Ogg */ + if (version >= 2) { + codec = read_u16le(0x1c,sf); /* 1:pcm, 2:ogg */ + /* 0x1e: data or null in later(?) games */ + } + else { + codec = 1; + } - /* later games use "OggS" */ - if (version == 1) + if (version == 1) { start_offset = 0x1c; /* Nancy Drew: The Final Scene (PC) */ - else if (version == 2 && is_id32be(0x1e,sf, "OggS")) - start_offset = 0x1e; /* Nancy Drew: The Haunted Carousel (PC) */ - else if (version == 2 && is_id32be(0x20,sf, "OggS")) - start_offset = 0x20; /* Nancy Drew: The Silent Spy (PC) */ - else + } + else if (version == 2) { + if (codec == 1) { + uint32_t left_size = get_streamfile_size(sf) - 0x1e; + if (num_samples == pcm_bytes_to_samples(left_size, channels, bps)) + start_offset = 0x1e; /* Nancy Drew: Ghost Dogs of Moon Lake (PC) */ + else + start_offset = 0x20; /* assumed */ + } + else if (codec == 2) { + if (read_u16le(0x1e, sf) != 0) + start_offset = 0x1e; /* Nancy Drew: The Haunted Carousel (PC) */ + else + start_offset = 0x20; /* Nancy Drew: The Silent Spy (PC) */ + } + else { + goto fail; + } + } + else { goto fail; + } } else { goto fail; } - - if (version == 2) { +/* + if (codec == 2) { ogg_vorbis_meta_info_t ovmi = {0}; ovmi.meta_type = meta_HIS; return init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi); } +*/ /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channels, loop_flag); @@ -73,17 +98,32 @@ VGMSTREAM * init_vgmstream_his(STREAMFILE *sf) { vgmstream->sample_rate = sample_rate; vgmstream->num_samples = num_samples; - switch (bps) { - case 8: - vgmstream->coding_type = coding_PCM8_U; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x01; + switch (codec) { + case 1: + switch (bps) { + case 8: + vgmstream->coding_type = coding_PCM8_U; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x01; + break; + case 16: + vgmstream->coding_type = coding_PCM16LE; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x02; + break; + default: + goto fail; + } break; - case 16: - vgmstream->coding_type = coding_PCM16LE; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x02; + + case 2: +#ifdef VGM_USE_VORBIS + vgmstream->codec_data = init_ogg_vorbis(sf, start_offset, 0, NULL); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_OGG_VORBIS; + vgmstream->layout_type = layout_none; break; +#endif default: goto fail; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/idtech.c b/Frameworks/vgmstream/vgmstream/src/meta/idtech.c index 915c24bb8..bae933ff0 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/idtech.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/idtech.c @@ -13,14 +13,14 @@ VGMSTREAM* init_vgmstream_mzrt_v0(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00,sf, "mzrt")) + goto fail; + if (read_u32be(0x04, sf) != 0) /* version */ + goto fail; + if (!check_extensions(sf, "idwav,idmsf,idxma")) goto fail; - if (!is_id32be(0x00,sf, "mzrt")) - goto fail; - - if (read_u32be(0x04, sf) != 0) /* version */ - goto fail; /* this format is bizarrely mis-aligned (and mis-designed too) */ @@ -111,12 +111,9 @@ VGMSTREAM* init_vgmstream_mzrt_v0(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0166: { - uint8_t buf[0x100]; - int bytes; size_t stream_size = get_streamfile_size(temp_sf); - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,sizeof(buf), 0x15,0x34, stream_size, sf, 0); - vgmstream->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, 0x00,stream_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk_split(sf, temp_sf, 0x00, stream_size, 0x15, 0x34); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -167,14 +164,14 @@ VGMSTREAM* init_vgmstream_mzrt_v1(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "idmsf")) //idmsa: untested - goto fail; - if (!is_id32be(0x00,sf, "mzrt")) goto fail; if (read_u32be(0x04, sf) != 1) /* version */ goto fail; + if (!check_extensions(sf, "idmsf")) //idmsa: untested + goto fail; + type = read_s32be(0x09,sf); if (type == 0) { /* Rage */ /* 0x0d: null */ @@ -314,14 +311,14 @@ VGMSTREAM* init_vgmstream_bsnf(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "bsnd")) - goto fail; - if (!is_id32be(0x00,sf, "bsnf")) /* null-terminated string */ goto fail; if (read_u32be(0x05, sf) != 0x00000100) /* version */ goto fail; + if (!check_extensions(sf, "bsnd")) + goto fail; + offset = 0x18; stream_size = read_u32be(offset + 0x00,sf); @@ -430,14 +427,9 @@ VGMSTREAM* init_vgmstream_bsnf(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0166: { - uint8_t buf[0x100]; - size_t bytes, block_size, block_count; + int block_size = 0x800; - block_size = 0x800; - block_count = stream_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), num_samples, stream_size, channels, sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sb, buf, bytes, start_offset, stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, stream_size, num_samples, channels, sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/isb.c b/Frameworks/vgmstream/vgmstream/src/meta/isb.c index ed489dcdc..b2a9bd361 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/isb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/isb.c @@ -238,8 +238,6 @@ VGMSTREAM* init_vgmstream_isb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x04: { - uint8_t buf[0x100]; - size_t bytes; off_t fmt_offset = start_offset; size_t fmt_size = 0x20; @@ -247,8 +245,7 @@ VGMSTREAM* init_vgmstream_isb(STREAMFILE* sf) { stream_size -= fmt_size; /* XMA1 "fmt" chunk (BE, unlike the usual LE) */ - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,sizeof(buf), fmt_offset,fmt_size, stream_size, sf, 1); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset, stream_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, stream_size, fmt_offset, fmt_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ivaud.c b/Frameworks/vgmstream/vgmstream/src/meta/ivaud.c index 0fd4a368c..43113eac3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ivaud.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ivaud.c @@ -62,16 +62,12 @@ VGMSTREAM* init_vgmstream_ivaud(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0000: { /* XMA2 (X360) */ - uint8_t buf[0x100]; - size_t bytes; - if (ivaud.is_music) { goto fail; } else { /* regular XMA for sfx */ - bytes = ffmpeg_make_riff_xma1(buf, 0x100, ivaud.num_samples, ivaud.stream_size, ivaud.channel_count, ivaud.sample_rate, 0); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, ivaud.stream_offset, ivaud.stream_size); + vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, ivaud.stream_offset, ivaud.stream_size, ivaud.channel_count, ivaud.sample_rate, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ktsr.c b/Frameworks/vgmstream/vgmstream/src/meta/ktsr.c index 11312d905..125ce2d70 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ktsr.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ktsr.c @@ -2,7 +2,7 @@ #include "../coding/coding.h" #include "../layout/layout.h" -typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, RIFF_ATRAC9, KOVS, /*KNS*/ } ktsr_codec; +typedef enum { NONE, MSADPCM, DSP, GCADPCM, ATRAC9, RIFF_ATRAC9, KOVS, KTSS, } ktsr_codec; #define MAX_CHANNELS 8 @@ -33,9 +33,9 @@ typedef struct { static int parse_ktsr(ktsr_header* ktsr, STREAMFILE* sf); static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE *sf, uint32_t config_data); +static VGMSTREAM* init_vgmstream_ktsr_sub(STREAMFILE* sf_b, ktsr_header* ktsr, VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf), const char* ext); - -/* KTSR - Koei Tecmo sound resource countainer */ +/* KTSR - Koei Tecmo sound resource container */ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; STREAMFILE* sf_b = NULL; @@ -76,6 +76,26 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) { } + /* subfiles */ + { + VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf) = NULL; + const char* ext; + switch(ktsr.codec) { + case RIFF_ATRAC9: init_vgmstream = init_vgmstream_riff; ext = "at9"; break; + case KOVS: init_vgmstream = init_vgmstream_ogg_vorbis; ext = "kvs"; break; + case KTSS: init_vgmstream = init_vgmstream_ktss; ext = "ktss"; break; + default: break; + } + + if (init_vgmstream) { + vgmstream = init_vgmstream_ktsr_sub(sf_b, &ktsr, init_vgmstream, ext); + if (!vgmstream) goto fail; + + if (sf_b != sf) close_streamfile(sf_b); + return vgmstream; + } + } + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(ktsr.channels, ktsr.loop_flag); if (!vgmstream) goto fail; @@ -125,49 +145,6 @@ VGMSTREAM* init_vgmstream_ktsr(STREAMFILE* sf) { break; } #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 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; - - ogg_vgmstream = init_vgmstream_ogg_vorbis(temp_sf); - close_streamfile(temp_sf); - if (!ogg_vgmstream) goto fail; - - ogg_vgmstream->stream_size = vgmstream->stream_size; - ogg_vgmstream->num_streams = vgmstream->num_streams; - ogg_vgmstream->channel_layout = vgmstream->channel_layout; - /* loops look shared */ - strcpy(ogg_vgmstream->stream_name, vgmstream->stream_name); - - close_vgmstream(vgmstream); - if (sf_b != sf) close_streamfile(sf_b); - return ogg_vgmstream; - } -#endif - default: goto fail; } @@ -193,6 +170,26 @@ fail: return NULL; } +// TODO improve, unity with other metas that do similar stuff +static VGMSTREAM* init_vgmstream_ktsr_sub(STREAMFILE* sf_b, ktsr_header* ktsr, VGMSTREAM* (*init_vgmstream)(STREAMFILE* sf), const char* ext) { + VGMSTREAM* sub_vgmstream = NULL; + STREAMFILE* temp_sf = setup_subfile_streamfile(sf_b, ktsr->stream_offsets[0], ktsr->stream_sizes[0], ext); + if (!temp_sf) return NULL; + + sub_vgmstream = init_vgmstream(temp_sf); + close_streamfile(temp_sf); + if (!sub_vgmstream) return NULL; + + sub_vgmstream->stream_size = ktsr->stream_sizes[0]; + sub_vgmstream->num_streams = ktsr->total_subsongs; + sub_vgmstream->channel_layout = ktsr->channel_layout; + + strcpy(sub_vgmstream->stream_name, ktsr->name); + + return sub_vgmstream; +} + + static layered_layout_data* build_layered_atrac9(ktsr_header* ktsr, STREAMFILE* sf, uint32_t config_data) { STREAMFILE* temp_sf = NULL; layered_layout_data* data = NULL; @@ -256,12 +253,12 @@ static int parse_codec(ktsr_header* ktsr) { case 0x01: /* PC */ if (ktsr->is_external) { if (ktsr->format == 0x0005) - ktsr->codec = KOVS; + ktsr->codec = KOVS; // Atelier Ryza (PC) else goto fail; } else if (ktsr->format == 0x0000) { - ktsr->codec = MSADPCM; + ktsr->codec = MSADPCM; // Warrior Orochi 4 (PC) } else { goto fail; @@ -271,21 +268,25 @@ static int parse_codec(ktsr_header* ktsr) { case 0x03: /* PS4/VITA */ if (ktsr->is_external) { if (ktsr->format == 0x1001) - ktsr->codec = RIFF_ATRAC9; + ktsr->codec = RIFF_ATRAC9; // Nioh (PS4) else goto fail; } else if (ktsr->format == 0x0001) - ktsr->codec = ATRAC9; + ktsr->codec = ATRAC9; // Attack on Titan: Wings of Freedom (Vita) else goto fail; break; case 0x04: /* Switch */ - if (ktsr->is_external) - goto fail; /* KTSS? */ + if (ktsr->is_external) { + if (ktsr->format == 0x0005) + ktsr->codec = KTSS; // [Ultra Kaiju Monster Rancher (Switch)] + else + goto fail; + } else if (ktsr->format == 0x0000) - ktsr->codec = DSP; + ktsr->codec = DSP; // Fire Emblem: Three Houses (Switch) else goto fail; break; @@ -296,7 +297,7 @@ static int parse_codec(ktsr_header* ktsr) { return 1; fail: - VGM_LOG("ktsr: unknown codec combo: ext=%x, fmt=%x, ptf=%x\n", ktsr->is_external, ktsr->format, ktsr->platform); + VGM_LOG("ktsr: unknown codec combo: external=%x, format=%x, platform=%x\n", ktsr->is_external, ktsr->format, ktsr->platform); return 0; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/kwb.c b/Frameworks/vgmstream/vgmstream/src/meta/kwb.c index 04025e2a3..3317938f4 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/kwb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/kwb.c @@ -215,16 +215,11 @@ static VGMSTREAM* init_vgmstream_koei_wavebank(kwb_header* kwb, STREAMFILE* sf_h #ifdef VGM_USE_FFMPEG case XMA2: { - uint8_t buf[0x100]; - size_t bytes, block_size, block_count; + int block_size = 0x800; /* ? */ if (kwb->channels > 1) goto fail; - block_size = 0x800; /* ? */ - block_count = kwb->stream_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, kwb->stream_size, kwb->channels, kwb->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf_b, buf,bytes, kwb->stream_offset, kwb->stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf_b, kwb->stream_offset, kwb->stream_size, vgmstream->num_samples, kwb->channels, kwb->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/meta.h b/Frameworks/vgmstream/vgmstream/src/meta/meta.h index 8f2c27065..fe608631f 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/meta.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/meta.h @@ -85,7 +85,6 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_xa(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_rxws(STREAMFILE* sf); -VGMSTREAM * init_vgmstream_rxws_badrip(STREAMFILE* sf); VGMSTREAM * init_vgmstream_raw_int(STREAMFILE *streamFile); @@ -159,8 +158,6 @@ VGMSTREAM* init_vgmstream_mp4_aac_ffmpeg(STREAMFILE* sf); #if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC) VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size); - -VGMSTREAM * init_vgmstream_akb_mp4(STREAMFILE *streamFile); #endif VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile); @@ -299,8 +296,6 @@ VGMSTREAM * init_vgmstream_ngc_ymf(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_sadl(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_ps2_ccc(STREAMFILE * streamFile); - VGMSTREAM * init_vgmstream_fag(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ps2_mihb(STREAMFILE * streamFile); @@ -314,7 +309,7 @@ VGMSTREAM * init_vgmstream_rsd(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_dc_asd(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_naomi_spsd(STREAMFILE * streamFile); +VGMSTREAM* init_vgmstream_spsd(STREAMFILE* sf); VGMSTREAM * init_vgmstream_bgw(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_spw(STREAMFILE * streamFile); @@ -490,14 +485,13 @@ VGMSTREAM * init_vgmstream_jstm(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_xvag(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_ps3_cps(STREAMFILE* streamFile); +VGMSTREAM* init_vgmstream_cps(STREAMFILE* sf); VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ngc_nst_dsp(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_baf(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_baf_badrip(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_msf(STREAMFILE* streamFile); @@ -509,8 +503,6 @@ VGMSTREAM * init_vgmstream_wii_ras(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_spm(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_x360_tra(STREAMFILE* streamFile); - VGMSTREAM * init_vgmstream_ps2_iab(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_vs_str(STREAMFILE* streamFile); @@ -582,21 +574,21 @@ VGMSTREAM * init_vgmstream_bik(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_cxs(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_dsp_adx(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_x360_ast(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_astb(STREAMFILE* sf); VGMSTREAM* init_vgmstream_wwise(STREAMFILE* sf); VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch); VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_pasx(STREAMFILE* sf); VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile); @@ -604,9 +596,10 @@ VGMSTREAM * init_vgmstream_ogl(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_mc3(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_gtd(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_s_p_sth(STREAMFILE* sf); -VGMSTREAM* init_vgmstream_ta_aac(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_aac_triace(STREAMFILE* sf); VGMSTREAM * init_vgmstream_va3(STREAMFILE *streamFile); @@ -875,7 +868,7 @@ VGMSTREAM * init_vgmstream_nub_dsp(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_nub_idsp(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_nub_is14(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_xmv_valve(STREAMFILE * streamFile); +VGMSTREAM* init_vgmstream_xwv_valve(STREAMFILE* sf); VGMSTREAM * init_vgmstream_ubi_hx(STREAMFILE * streamFile); @@ -927,8 +920,8 @@ VGMSTREAM* init_vgmstream_dsb(STREAMFILE* sf); VGMSTREAM* init_vgmstream_bsf(STREAMFILE* sf); -VGMSTREAM* init_vgmstream_xse_new(STREAMFILE* sf); -VGMSTREAM* init_vgmstream_xse_old(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_sdrh_new(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_sdrh_old(STREAMFILE* sf); VGMSTREAM* init_vgmstream_wady(STREAMFILE* sf); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/mul.c b/Frameworks/vgmstream/vgmstream/src/meta/mul.c index 15186bdf2..4eb042a18 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/mul.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/mul.c @@ -252,8 +252,6 @@ static layered_layout_data* build_layered_mul(STREAMFILE* sf, off_t offset, int switch(codec) { #ifdef VGM_USE_FFMPEG case XMA1: { - uint8_t buf[0x100]; - int bytes; size_t stream_size; int layer_channels = 1; @@ -269,12 +267,11 @@ static layered_layout_data* build_layered_mul(STREAMFILE* sf, off_t offset, int data->layers[i]->sample_rate = vgmstream->sample_rate; data->layers[i]->num_samples = vgmstream->num_samples; - bytes = ffmpeg_make_riff_xma1(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, 0); - data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, 0x00, stream_size); + data->layers[i]->codec_data = init_ffmpeg_xma1_raw(temp_sf, 0x00, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, 0); if (!data->layers[i]->codec_data) goto fail; - data->layers[i]->coding_type = coding_FFmpeg; data->layers[i]->layout_type = layout_none; + data->layers[i]->stream_size = stream_size; xma_fix_raw_samples(data->layers[i], temp_sf, 0x00,stream_size, 0, 0,0); /* ? */ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_std.c b/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_std.c index 9347f0fc9..a15a4b1e3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_std.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_std.c @@ -11,8 +11,8 @@ struct dsp_header { uint32_t sample_rate; /* 0x08 (generally 22/32/44/48kz but games like Wario World set 32028hz to adjust for GC's rate) */ uint16_t loop_flag; /* 0x0c */ uint16_t format; /* 0x0e (always 0 for ADPCM) */ - uint32_t loop_start_offset; /* 0x10 */ - uint32_t loop_end_offset; /* 0x14 */ + uint32_t loop_start_offset; /* 0x10 (in nibbles, should be 2 if 0/not set) */ + uint32_t loop_end_offset; /* 0x14 (in nibbles) */ uint32_t initial_offset; /* 0x18 ("ca", in nibbles, should be 2) */ int16_t coef[16]; /* 0x1c (eight pairs) */ uint16_t gain; /* 0x3c (always 0 for ADPCM) */ @@ -23,7 +23,7 @@ struct dsp_header { int16_t loop_hist1; /* 0x46 */ int16_t loop_hist2; /* 0x48 */ int16_t channels; /* 0x4a (DSPADPCM.exe ~v2.7 extension) */ - int16_t block_size; /* 0x4c */ + uint16_t block_size; /* 0x4c */ /* padding/reserved up to 0x60, DSPADPCM.exe from GC adds garbage here (uninitialized MSVC memory?) * [ex. Batallion Wars (GC), Timesplitters 2 (GC)], 0xcccc...cccc with DSPADPCMD */ }; @@ -291,7 +291,7 @@ fail: /* ********************************* */ -/* .dsp - standard dsp as generated by DSPADPCM.exe */ +/* .dsp - standard mono dsp as generated by DSPADPCM.exe */ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; struct dsp_header header; @@ -304,7 +304,7 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { goto fail; /* .dsp: standard - * .adp: Dr. Muto/Battalion Wars (GC) mono files + * .adp: Dr. Muto/Battalion Wars (GC), Tale of Despereaux (Wii) * (extensionless): Tony Hawk's Downhill Jam (Wii) */ if (!check_extensions(sf, "dsp,adp,")) goto fail; @@ -319,7 +319,8 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { * out thoroughly, we're probably not dealing with a genuine mono DSP. * In many cases these will pass all the other checks, including the * predictor/scale check if the first byte is 0 */ - //todo maybe this meta should be after others, so they have a chance to detect >1ch .dsp + //TODO: maybe this meta should be after others, so they have a better chance to detect >1ch .dsp + // (but .dsp is the common case, so it'd be slower) { int ko; struct dsp_header header2; @@ -344,6 +345,21 @@ VGMSTREAM* init_vgmstream_ngc_dsp_std(STREAMFILE* sf) { header.loop_flag == header2.loop_flag) { goto fail; } + + /* ignore ddsp, that set samples/nibbles counting both channels so can't be detected + * (could check for .dsp but most files don't need this) */ + if (check_extensions(sf, "adp")) { + uint32_t interleave = (get_streamfile_size(sf) / 2); + + ko = !read_dsp_header_be(&header2, interleave, sf); + if (!ko && + header.sample_count == header2.sample_count && + header.nibble_count == header2.nibble_count && + header.sample_rate == header2.sample_rate && + header.loop_flag == header2.loop_flag) { + goto fail; + } + } } if (header.loop_flag) { @@ -822,14 +838,15 @@ fail: return NULL; } -/* .ddsp - full interleaved dsp [Shark Tale, (GC), The Sims 2: Pets (Wii), Wacky Races: Crash & Dash (Wii)] */ +/* .ddsp - full interleaved dsp [Shark Tale (GC), The Sims 2: Pets (Wii), Wacky Races: Crash & Dash (Wii)] */ VGMSTREAM* init_vgmstream_dsp_ddsp(STREAMFILE* sf) { dsp_meta dspm = {0}; /* checks */ - /* .ddsp: assumed? + /* .adp: Tale of Despereaux (Wii) */ + /* .ddsp: fake extension (games have bigfiles without names, but has references to .wav) * .wav: Wacky Races: Crash & Dash (Wii) */ - if (!check_extensions(sf, "ddsp,wav,lwav")) + if (!check_extensions(sf, "adp,ddsp,wav,lwav")) goto fail; dspm.channels = 2; @@ -840,6 +857,9 @@ VGMSTREAM* init_vgmstream_dsp_ddsp(STREAMFILE* sf) { dspm.start_offset = 0x60; dspm.interleave = dspm.header_spacing; + /* this format has nibbles in both headers matching all data (not just for that channel), + * and interleave is exact half even for files that aren't aligned to 0x10 */ + dspm.meta_type = meta_DSP_DDSP; return init_vgmstream_dsp_common(sf, &dspm); fail: diff --git a/Frameworks/vgmstream/vgmstream/src/meta/nub.c b/Frameworks/vgmstream/vgmstream/src/meta/nub.c index 4794edfd5..5e69a6584 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/nub.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/nub.c @@ -489,15 +489,7 @@ VGMSTREAM* init_vgmstream_nub_xma(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG { - uint8_t buf[0x100]; - size_t bytes; - - if (nus_codec == 0x04) { - bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf,0x100, chunk_offset,chunk_size, data_size, sf); - } else { - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, sf, 1); - } - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, chunk_offset, chunk_size); if ( !vgmstream->codec_data ) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/opus.c b/Frameworks/vgmstream/vgmstream/src/meta/opus.c index 218e260b6..f8e1832e4 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/opus.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/opus.c @@ -103,8 +103,10 @@ static VGMSTREAM* init_vgmstream_opus(STREAMFILE* sf, meta_t meta_type, off_t of vgmstream->layout_type = layout_none; vgmstream->channel_layout = ffmpeg_get_channel_layout(vgmstream->codec_data); - if (vgmstream->num_samples == 0) { + if (vgmstream->num_samples <= 0) { vgmstream->num_samples = switch_opus_get_samples(start_offset, data_size, sf) - skip; + if (num_samples < 0 && vgmstream->loop_end_sample > vgmstream->num_samples) /* special flag for weird cases */ + vgmstream->loop_end_sample = vgmstream->num_samples; } } #else @@ -293,18 +295,21 @@ VGMSTREAM* init_vgmstream_opus_shinen(STREAMFILE* sf) { /* checks */ if (read_u32be(0x08,sf) != 0x01000080) goto fail; - if ( !check_extensions(sf,"opus,lopus")) + if (!check_extensions(sf,"opus,lopus")) goto fail; offset = 0x08; - num_samples = 0; - loop_start = read_32bitLE(0x00,sf); - loop_end = read_32bitLE(0x04,sf); /* 0 if no loop */ + loop_start = read_s32le(0x00,sf); + loop_end = read_s32le(0x04,sf); /* 0 if no loop */ + + /* tepaneca.opus has loop_end slightly bigger than samples, but doesn't seem an encoder delay thing since + * several tracks do full loops to 0 and sound ok. Mark with a special flag to allow this case. */ + num_samples = -1; if (loop_start > loop_end) goto fail; /* just in case */ - return init_vgmstream_opus(sf, meta_OPUS, offset, num_samples,loop_start,loop_end); + return init_vgmstream_opus(sf, meta_OPUS, offset, num_samples, loop_start, loop_end); fail: return NULL; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/p3d.c b/Frameworks/vgmstream/vgmstream/src/meta/p3d.c index 0a7bb263d..fd4c9e3c8 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/p3d.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/p3d.c @@ -180,12 +180,8 @@ VGMSTREAM* init_vgmstream_p3d(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x786D6100: { /* "xma\0" (X360) */ - uint8_t buf[0x100]; - size_t bytes; - //TODO: some in Spider-Man 4 beta use 18ch but ffmpeg supports max 16ch XMA2 - bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf, sizeof(buf), xma2_offset, xma2_size, data_size, sf); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, xma2_offset, xma2_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/pasx.c b/Frameworks/vgmstream/vgmstream/src/meta/pasx.c new file mode 100644 index 000000000..ffea2c929 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/pasx.c @@ -0,0 +1,66 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* PASX - from Premium Agency games [SoulCalibur II HD (X360), Death By Cube (X360)] */ +VGMSTREAM* init_vgmstream_pasx(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset, chunk_offset; + size_t data_size, chunk_size; + int loop_flag, channels, sample_rate; + int num_samples, loop_start_sample, loop_end_sample; + + + /* checks */ + if (!is_id32be(0x00,sf, "PASX")) + goto fail; + + /* .past: Soul Calibur II HD + * .sgb: Death By Cube */ + if (!check_extensions(sf,"past,sgb")) + goto fail; + + + /* custom header with a "fmt " data chunk inside */ + chunk_size = read_32bitBE(0x08,sf); + data_size = read_32bitBE(0x0c,sf); + chunk_offset = read_32bitBE(0x10,sf); /* 0x14: fmt offset end */ + start_offset = read_32bitBE(0x18,sf); + + channels = read_16bitBE(chunk_offset+0x02,sf); + sample_rate = read_32bitBE(chunk_offset+0x04,sf); + xma2_parse_fmt_chunk_extra(sf, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + vgmstream->meta_type = meta_PASX; + +#ifdef VGM_USE_FFMPEG + { + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, chunk_offset, chunk_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, chunk_offset, 1,1); + } +#else + goto fail; +#endif + + + /* open the file for reading */ + if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ps2_ccc.c b/Frameworks/vgmstream/vgmstream/src/meta/ps2_ccc.c deleted file mode 100644 index d0745a662..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/ps2_ccc.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "meta.h" -#include "../util.h" - -/* CCC */ -VGMSTREAM * init_vgmstream_ps2_ccc(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; - int loop_flag = 0; - int channel_count; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("ccc",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x01000000) - goto fail; - - /* check file size */ - if (read_32bitLE(0x0C,streamFile)+0x50 != get_streamfile_size(streamFile)) - goto fail; - - loop_flag = 0; - channel_count = 2; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0x50; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x04,streamFile); - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = (read_32bitLE(0x08,streamFile))/channel_count/0x10*28; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x08,streamFile))/channel_count/0x10*28; - } - - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x2000; - vgmstream->meta_type = meta_PS2_CCC; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ps3_cps.c b/Frameworks/vgmstream/vgmstream/src/meta/ps3_cps.c deleted file mode 100644 index 78e2a8037..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/ps3_cps.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "meta.h" -#include "../util.h" - -/* CPS (from Eternal Sonata) */ -VGMSTREAM * init_vgmstream_ps3_cps(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; - - int loop_flag; - int channel_count; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("cps",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x43505320) /* "CPS" */ - goto fail; - - loop_flag = read_32bitBE(0x18,streamFile); - - channel_count = read_32bitBE(0x8,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = read_32bitBE(0x4,streamFile); - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x10,streamFile); - if (read_32bitBE(0x20,streamFile)==0x00000000){ - vgmstream->coding_type = coding_PCM16BE; - vgmstream->num_samples = read_32bitBE(0xc,streamFile)/4; - vgmstream->interleave_block_size = 2; - } - else { - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = read_32bitBE(0xc,streamFile)*28/32; - vgmstream->interleave_block_size = 0x10; - } - - if (loop_flag) { - vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile)*28/32; - vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile)*28/32; - } - - vgmstream->layout_type = layout_interleave; - vgmstream->meta_type = meta_PS3_CPS; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/psb.c b/Frameworks/vgmstream/vgmstream/src/meta/psb.c index 72eaa476a..f674627f8 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/psb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/psb.c @@ -168,7 +168,7 @@ VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf) { break; #ifdef VGM_USE_FFMPEG - case XWMA: { /* [Senxin Aleste (AC)] */ + case XWMA: { /* Senxin Aleste (AC) */ vgmstream->codec_data = init_ffmpeg_xwma(sf, psb.stream_offset[0], psb.stream_size[0], psb.format, psb.channels, psb.sample_rate, psb.avg_bitrate, psb.block_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; @@ -182,11 +182,7 @@ VGMSTREAM* init_vgmstream_psb(STREAMFILE* sf) { } case XMA2: { /* Sega Vintage Collection (X360) */ - uint8_t buf[0x100]; - size_t bytes; - - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, sizeof(buf), psb.fmt_offset, psb.fmt_size, psb.stream_size[0], sf, 1); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, psb.stream_offset[0], psb.stream_size[0]); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, psb.stream_offset[0], psb.stream_size[0], psb.fmt_offset, psb.fmt_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/riff.c b/Frameworks/vgmstream/vgmstream/src/meta/riff.c index 213d19ff6..b58d8bb1c 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/riff.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/riff.c @@ -95,7 +95,7 @@ typedef struct { int is_at9; } riff_fmt_chunk; -static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk* fmt, int mwv) { +static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk* fmt) { uint32_t (*read_u32)(off_t,STREAMFILE*) = big_endian ? read_u32be : read_u32le; uint16_t (*read_u16)(off_t,STREAMFILE*) = big_endian ? read_u16be : read_u16le; @@ -227,7 +227,6 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk break; case 0x0555: /* Level-5 0x555 ADPCM (unofficial) */ - if (!mwv) goto fail; fmt->coding_type = coding_L5_555; fmt->interleave = 0x12; break; @@ -278,13 +277,6 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk fmt->coding_type = coding_FFmpeg; fmt->is_at3p = 1; break; -#elif defined(VGM_USE_MAIATRAC3PLUS) - uint16_t bztmp = read_u16(offset+0x32,sf); - bztmp = (bztmp >> 8) | (bztmp << 8); - fmt->coding_type = coding_AT3plus; - fmt->block_size = (bztmp & 0x3FF) * 8 + 8; /* should match fmt->block_size */ - fmt->is_at3p = 1; - break; #else goto fail; #endif @@ -337,9 +329,8 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { int FormatChunkFound = 0, DataChunkFound = 0, JunkFound = 0; - int mwv = 0; - off_t mwv_pflt_offset = -1; - off_t mwv_ctrl_offset = -1; + off_t mwv_pflt_offset = 0; + off_t mwv_ctrl_offset = 0; int ignore_riff_size = 0; @@ -347,6 +338,13 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { if (!is_id32be(0x00,sf,"RIFF")) goto fail; + riff_size = read_u32le(0x04,sf); + + if (!is_id32be(0x08,sf, "WAVE")) + goto fail; + + file_size = get_streamfile_size(sf); + /* .lwav: to avoid hijacking .wav * .xwav: fake for Xbox games (not needed anymore) * .da: The Great Battle VI (PS1) @@ -379,24 +377,12 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { * .ogg/logg: Luftrausers (Vita)[ATRAC9] * .p1d: Farming Simulator 15 (Vita)[ATRAC9] * .xms: Ty the Tasmanian Tiger (Xbox) + * .mus: Burnout Legends/Dominator (PSP) */ - 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,xvag,ogg,logg,p1d,xms") ) { - ; - } - else if ( check_extensions(sf, "mwv") ) { - mwv = 1; - } - else { + if (!check_extensions(sf, "wav,lwav,xwav,mwv,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm,xvag,ogg,logg,p1d,xms,mus")) { goto fail; } - riff_size = read_u32le(0x04,sf); - - if (!is_id32be(0x08,sf, "WAVE")) - goto fail; - - file_size = get_streamfile_size(sf); - /* some games have wonky sizes, selectively fix to catch bad rips and new mutations */ if (file_size != riff_size + 0x08) { uint16_t codec = read_u16le(0x14,sf); @@ -425,7 +411,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { else if (codec == 0xFFFE && riff_size + 0x08 + 0x18 == file_size) riff_size += 0x18; /* [F1 2011 (Vita)] (adds a "pada" chunk but RIFF size wasn't updated) */ - else if (mwv) { + else if (codec == 0x0555) { int channels = read_u16le(0x16, sf); /* [Dragon Quest VIII (PS2), Rogue Galaxy (PS2)] */ size_t file_size_fixed = riff_size + 0x08 + 0x04 * (channels - 1); @@ -486,7 +472,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { if (FormatChunkFound) goto fail; /* only one per file */ FormatChunkFound = 1; - if (!read_fmt(0, sf, current_chunk, &fmt, mwv)) + if (!read_fmt(0, sf, current_chunk, &fmt)) goto fail; /* some Dreamcast/Naomi games again [Headhunter (DC), Bomber hehhe (DC), Rayman 2 (DC)] */ @@ -574,12 +560,10 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { goto fail; /* parsed elsewhere */ case 0x70666c74: /* "pflt" (.mwv extension) */ - if (!mwv) break; /* ignore if not in an mwv */ mwv_pflt_offset = current_chunk; /* predictor filters */ break; case 0x6374726c: /* "ctrl" (.mwv extension) */ - if (!mwv) break; loop_flag = read_32bitLE(current_chunk+0x08, sf); mwv_ctrl_offset = current_chunk; break; @@ -688,9 +672,6 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case coding_FFmpeg: #endif -#ifdef VGM_USE_MAIATRAC3PLUS - case coding_AT3plus: -#endif #ifdef VGM_USE_ATRAC9 case coding_ATRAC9: #endif @@ -725,7 +706,6 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { break; case coding_L5_555: - if (!mwv) goto fail; vgmstream->num_samples = data_size / 0x12 / fmt.channels * 32; /* coefs */ @@ -735,7 +715,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { int filter_count = read_32bitLE(mwv_pflt_offset+0x0c, sf); if (filter_count > 0x20) goto fail; - if (mwv_pflt_offset == -1 || + if (!mwv_pflt_offset || read_32bitLE(mwv_pflt_offset+0x08, sf) != filter_order || read_32bitLE(mwv_pflt_offset+0x04, sf) < 8 + filter_count * 4 * filter_order) goto fail; @@ -799,17 +779,6 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { break; } #endif -#ifdef VGM_USE_MAIATRAC3PLUS - case coding_AT3plus: { - vgmstream->codec_data = init_at3plus(); - - /* get rough total samples but favor fact_samples if available (skip isn't correctly handled for now) */ - vgmstream->num_samples = atrac3plus_bytes_to_samples(data_size, fmt.block_size); - if (fact_sample_count > 0 && fact_sample_count + fact_sample_skip < vgmstream->num_samples) - vgmstream->num_samples = fact_sample_count + fact_sample_skip; - break; - } -#endif #ifdef VGM_USE_ATRAC9 case coding_ATRAC9: { atrac9_config cfg = {0}; @@ -908,9 +877,10 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { vgmstream->loop_end_sample = loop_end_wsmp; vgmstream->meta_type = meta_RIFF_WAVE_wsmp; } - else if (mwv && mwv_ctrl_offset != -1) { - vgmstream->loop_start_sample = read_32bitLE(mwv_ctrl_offset+12, sf); + else if (fmt.coding_type == coding_L5_555 && mwv_ctrl_offset) { + vgmstream->loop_start_sample = read_s32le(mwv_ctrl_offset + 0x0c, sf); vgmstream->loop_end_sample = vgmstream->num_samples; + vgmstream->meta_type = meta_RIFF_WAVE_MWV; } else if (loop_start_cue != -1) { vgmstream->loop_start_sample = loop_start_cue; @@ -927,9 +897,6 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { } } } - if (mwv) { - vgmstream->meta_type = meta_RIFF_WAVE_MWV; - } if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; @@ -1105,7 +1072,7 @@ VGMSTREAM* init_vgmstream_rifx(STREAMFILE* sf) { if (FormatChunkFound) goto fail; FormatChunkFound = 1; - if (!read_fmt(1, sf, current_chunk, &fmt, 0)) + if (!read_fmt(1, sf, current_chunk, &fmt)) goto fail; break; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/rsd.c b/Frameworks/vgmstream/vgmstream/src/meta/rsd.c index cb47075f8..84651d88c 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/rsd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/rsd.c @@ -13,9 +13,9 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf,"rsd,rsp")) + if ((read_u32be(0x00,sf) & 0xFFFFFF00) != get_id32be("RSD\00")) goto fail; - if ((read_u32be(0x00,sf) & 0xFFFFFF00) != 0x52534400) /* "RSD\00" */ + if (!check_extensions(sf,"rsd,rsp")) goto fail; loop_flag = 0; @@ -168,40 +168,34 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { } case 0x584D4120: { /* "XMA " [Crash of the Titans (X360)-v1, Crash: Mind over Mutant (X360)-v2] */ - uint8_t buf[0x100]; - size_t bytes, xma_size, block_size, block_count; - int xma_version; + uint32_t chunk_size = read_32bitBE(0x800, sf); + uint32_t seek_size = read_32bitBE(0x804, sf); + uint32_t stream_size = read_32bitBE(0x808, sf); + uint32_t chunk_offset = 0x80c; + int old_xma2_version = read_u8(chunk_offset + 0x00, sf); + start_offset = chunk_offset + chunk_size + seek_size; - /* skip mini header */ - start_offset = 0x800 + read_32bitBE(0x800, sf) + read_32bitBE(0x804, sf) + 0xc; /* assumed, seek table always at 0x800 */ - xma_size = read_32bitBE(0x808, sf); - xma_version = read_u8(0x80C, sf); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, stream_size, chunk_offset, chunk_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; - switch (xma_version) { + /* read PCM samples rather than full samples (dev trickery?) */ + switch (old_xma2_version) { case 0x03: - vgmstream->sample_rate = read_32bitBE(0x818, sf); - vgmstream->num_samples = read_32bitBE(0x824, sf); - block_count = read_32bitBE(0x828, sf); - block_size = 0x10000; + vgmstream->sample_rate = read_32bitBE(chunk_offset + 0x0c, sf); + vgmstream->num_samples = read_32bitBE(chunk_offset + 0x18, sf); break; case 0x04: - vgmstream->num_samples = read_32bitBE(0x814, sf); - vgmstream->sample_rate = read_32bitBE(0x818, sf); - block_count = read_32bitBE(0x830, sf); - block_size = 0x10000; + vgmstream->num_samples = read_32bitBE(chunk_offset + 0x08, sf); + vgmstream->sample_rate = read_32bitBE(chunk_offset + 0x0c, sf); break; default: goto fail; } - bytes = ffmpeg_make_riff_xma2(buf,sizeof(buf), vgmstream->num_samples, xma_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, start_offset, xma_size); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - /* for some reason (dev trickery?) .rsd don't set skip in the bitstream, though they should */ + /* for some reason (dev trickery?) .rsd don't set skips in the bitstream, though they should */ //xma_fix_raw_samples(vgmstream, sf, start_offset,xma_size, 0, 0,0); ffmpeg_set_skip_samples(vgmstream->codec_data, 512+64); break; @@ -218,7 +212,6 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/rwsd.c b/Frameworks/vgmstream/vgmstream/src/meta/rwsd.c index f4a0a248d..a8078261a 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/rwsd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/rwsd.c @@ -106,6 +106,12 @@ VGMSTREAM* init_vgmstream_rwsd(STREAMFILE* sf) { stream_size = read_32bitBE(wave_offset + 0x50,sf); + /* this meta is a hack as WSD is just note info, and data offsets are elsewhere in the brsar, + * while this assumes whatever data follows RWSD must belong to it (common but fails in Wii Sports), + * detect data excess and reject (probably should use brawlbox's info offsets) */ + if (stream_size * channels + 0x10000 < get_streamfile_size(sf) - start_offset) + goto fail; + /* open the file for reading by each channel */ { int i; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/rxws.c b/Frameworks/vgmstream/vgmstream/src/meta/rxws.c index 6294b5086..0b3bb774d 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/rxws.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/rxws.c @@ -191,52 +191,3 @@ fail: close_vgmstream(vgmstream); return NULL; } - - -/* .RXW - legacy fake ext/header for poorly split XWH+XWB files generated by old tools (incorrect header/chunk sizes) */ -VGMSTREAM* init_vgmstream_rxws_badrip(STREAMFILE* sf) { - VGMSTREAM* vgmstream = NULL; - int loop_flag=0, channels; - off_t start_offset; - - /* check extension, case insensitive */ - if (!check_extensions(sf,"rxw")) - goto fail; - - /* check RXWS/FORM Header */ - if (!((read_32bitBE(0x00,sf) == 0x52585753) && - (read_32bitBE(0x10,sf) == 0x464F524D))) - goto fail; - - loop_flag = (read_u32le(0x3C,sf)!=0xFFFFFFFF); - channels=2; /* Always stereo files */ - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channels,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = read_32bitLE(0x2E,sf); - vgmstream->num_samples = (read_32bitLE(0x38,sf)*28/16)/2; - - /* Get loop point values */ - if(vgmstream->loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x3C,sf)/16*14; - vgmstream->loop_end_sample = read_32bitLE(0x38,sf)/16*14; - } - - vgmstream->interleave_block_size = read_32bitLE(0x1c,sf)+0x10; - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->meta_type = meta_RXWS; - start_offset = 0x40; - - /* open the file for reading */ - if (!vgmstream_open_stream(vgmstream, sf, start_offset)) - goto fail; - - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/s3v.c b/Frameworks/vgmstream/vgmstream/src/meta/s3v.c index bc7b95537..fe00307ca 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/s3v.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/s3v.c @@ -5,7 +5,7 @@ VGMSTREAM * init_vgmstream_s3v(STREAMFILE *sf) { VGMSTREAM * vgmstream = NULL; off_t start_offset; - int32_t channel_count, loop_flag; + int32_t channel_count, loop_flag; size_t data_size; /* checks */ @@ -18,7 +18,7 @@ VGMSTREAM * init_vgmstream_s3v(STREAMFILE *sf) { /* No discernible loop_flag so we'll just use signatures. Might have to update on a per game basis. */ - switch (read_32bitBE(0x14, sf)) { + switch (read_32bitBE(0x14, sf)) { case 0x82FA0000: // SOUND VOLTEX EXCEED GEAR ver5 Theme BGM case 0x1BFD0000: // SOUND VOLTEX EXCEED GEAR ver6 Theme BGM case 0x9AFD0000: // SOUND VOLTEX Custom song selection BGM TypeA diff --git a/Frameworks/vgmstream/vgmstream/src/meta/sdrh.c b/Frameworks/vgmstream/vgmstream/src/meta/sdrh.c new file mode 100644 index 000000000..e5aaa54c9 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/sdrh.c @@ -0,0 +1,359 @@ +#include "meta.h" +#include "../layout/layout.h" +#include "../coding/coding.h" + + +/* SDRH - banks for newer feelplus-related ("FeelEngine") games [Mindjack (PS3/X360), Moon Diver (PS3/X360)] */ +VGMSTREAM* init_vgmstream_sdrh_new(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + uint32_t start_offset, stream_size; + int loop_flag = 0, channels, codec, sample_rate, seek_count; + int32_t num_samples, loop_start, loop_end; + int total_subsongs, target_subsong = sf->stream_index; + + + /* checks */ + if (!is_id32le(0x00,sf, "SDRH")) /* LE */ + goto fail; + if (!check_extensions(sf, "xse")) + goto fail; + + /* similar to older version but BE and a bit less complex */ + /* 0x04: version/config? + * 0x08: data size + * 0x30: file name in a custom 40-char (RADIX style) encoding + * others: ? + */ + + /* parse section */ + { + uint32_t offset, base_size, stream_offset, data_size = 0, entry_size = 0; + int i; + int tables = read_u16be(0x1C,sf); + int entries; + + offset = 0; + /* read sections: FE=cues? (same in platforms), WV=header position + sample rate?, FT=? (same in platforms), XW=waves */ + for (i = 0; i < tables; i++) { + uint16_t id = read_u16be(0x40 + 0x10 * i + 0x00,sf); + /* 0x02: offset in 0x40s */ + /* 0x04: section size */ + /* 0x08: always 1 */ + /* 0x0c: null */ + if (id == 0x5857) { /* "XW" */ + offset += read_u16be(0x40 + 0x10 * i + 0x02,sf) * 0x40; + break; + } + } + + /* section header (other sections have a similar header) */ + /* 0x00: section size (including data) */ + base_size = read_u16be(offset + 0x04,sf); + entries = read_u16be(offset + 0x06,sf); + /* 0x08: null */ + start_offset = read_u32be(offset + 0x0c,sf) + offset; /* size including padding up to start */ + + offset += base_size; + + total_subsongs = entries; + if (target_subsong == 0) target_subsong = 1; + if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; + + /* find stream header (entries can be variable-sized) */ + for (i = 0; i < entries; i++) { + entry_size = read_u16be(offset + 0x04,sf) * 0x10; + + if (i + 1 == target_subsong) + break; + offset += entry_size; + } + + /* parse target header (similar to xwav) */ + data_size = read_u32be(offset + 0x00,sf) - entry_size; + /* 0x00: data/entry size */ + /* 0x04: entry size */ + codec = read_u8(offset + 0x06,sf); /* assumed */ + loop_flag = read_u8(offset + 0x07,sf); /* assumed */ + /* 0x08: bps? flags? */ + channels = read_u8(offset + 0x09,sf); + seek_count = read_u16be(offset + 0x0a,sf); + num_samples = read_u32be(offset + 0x0c,sf); + + sample_rate = read_u32be(offset + 0x10,sf); + loop_start = read_u32be(offset + 0x14,sf); + loop_end = read_u32be(offset + 0x18,sf); + /* 0x1c: flags? */ + + stream_offset = read_u32be(offset + 0x20,sf); + + /* Mindjack uses full offsets here (aligned to 0x800), while Moon Diver points to a sub-offset + * (offsets also aren't ordered) */ + if ((stream_offset & 0x000007FF) != 0) { + stream_offset = read_u16be(offset + stream_offset, sf) * 0x800; + //TODO some files that loop have wrong size/num_samples? (ex.MJ system.xse #23 #138) + } + + /* other values change per game (seek table, etc) */ + + start_offset += stream_offset; + stream_size = data_size; + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_SDRH; + vgmstream->num_samples = num_samples; + vgmstream->sample_rate = sample_rate; + + vgmstream->stream_size = stream_size; + vgmstream->num_streams = total_subsongs; + + switch(codec) { + case 2: /* Mindjack (PS3), Moon Diver (PS3) */ + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x10; + + /* seen in a few Mindjack files */ + if (loop_end > num_samples && loop_end - 8 <= num_samples) + loop_end = num_samples; + + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + break; + +#ifdef VGM_USE_FFMPEG + case 1: { /* Mindjack (X360), Moon Diver (X360) */ + int block_size = 0x10000; /* XWAV new default */ + int block_count = seek_count; + + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, stream_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + //TODO fix loops/samples vs ATRAC3 + /* may be only applying end_skip to num_samples? */ + xma_fix_raw_samples(vgmstream, sf, start_offset, stream_size, 0, 0,0); + break; + } + + case 7: { /* Mindjack (PS3) */ + int block_align, encoder_delay; + + block_align = 0x98 * vgmstream->channels; + encoder_delay = 1024 + 69*2; /* observed default, but seems files run out of space */ + + vgmstream->codec_data = init_ffmpeg_atrac3_raw(sf, start_offset, stream_size, vgmstream->num_samples, vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + /* set offset samples (offset 0 jumps to sample 0 > pre-applied delay, and offset end loops after sample end > adjusted delay) */ + vgmstream->loop_start_sample = atrac3_bytes_to_samples(loop_start, block_align); //- encoder_delay + vgmstream->loop_end_sample = atrac3_bytes_to_samples(loop_end, block_align) - encoder_delay; + break; + } +#endif + + default: + goto fail; + } + + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} + + +/* SDRH - banks for older feelplus-related games [Lost Odyssey (X360), Lost Odyssey Demo (X360)] */ +VGMSTREAM* init_vgmstream_sdrh_old(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + uint32_t start_offset, stream_size; + int loop_flag = 0, channels = 0, codec, sample_rate, seek_count; + int32_t num_samples, loop_start, loop_end; + int total_subsongs, target_subsong = sf->stream_index; + + + /* checks */ + if (!is_id32be(0x00,sf, "SDRH")) + goto fail; + + /* .xse: actual extension (LO demo) */ + if (!check_extensions(sf, "xse")) + goto fail; + + /* similar to older version but LE and a bit more complex */ + /* 0x04: version/config? + * 0x08: data size + * 0x30: file name in a custom 40-char (RADIX style) encoding + * others: ? (change in old/new) + */ + + /* parse section */ + { + uint32_t offset, base_size, stream_offset, data_size = 0, entry_size = 0; + int i; + int tables = read_u8(0x15,sf); + int entries; + + offset = 0x40; + /* read sections (FE=cues?, WV=mini-headers + XW offset, FT=?, FQ=?, XW=waves) */ + for (i = 0; i < tables; i++) { + uint16_t id = read_u16be(0x40 + 0x08 * i + 0x00,sf); + /* 0x02: null? */ + /* 0x04: offset from table start */ + if (id == 0x5857) { /* "XW" */ + offset += read_u32le(0x40 + 0x08 * i + 0x04,sf); + break; + } + } + + /* section header (other sections have a similar header) */ + /* 0x00: section size (including data) */ + base_size = read_u16le(offset + 0x04,sf); + /* 0x06: ? */ + entries = read_u16le(offset + 0x08,sf); + start_offset = read_u32le(offset + 0x0c,sf) + offset; /* size including padding up to start */ + + offset += base_size; + + total_subsongs = entries; + if (target_subsong == 0) target_subsong = 1; + if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; + + /* find stream header */ + stream_offset = 0; + for (i = 0; i < entries; i++) { + data_size = read_u32le(offset + 0x00,sf); + entry_size = read_u16le(offset + 0x04,sf) * 0x10; + data_size -= entry_size; + + if (i + 1 == target_subsong) + break; + offset += entry_size; + stream_offset += data_size; /* no offset */ + } + + /* parse target header (similar to xwav) */ + /* 0x00: data size + entry size */ + /* 0x04: entry size */ + codec = read_u8(offset + 0x06,sf); /* assumed */ + /* 0x07: flag? */ + /* 0x08: bps? */ + /* 0x09: codec? */ + /* 0x0a: null (seek size?) */ + num_samples = read_u32le(offset + 0x0c,sf); /* XMA1: loop start/end info */ + + seek_count = read_u16le(offset + 0x10,sf); /* XMA1: loop start/end bytes? */ + sample_rate = read_u16le(offset + 0x14,sf); + if (entry_size == 0x20) { + channels = read_u8(offset + 0x17,sf); + } + loop_start = 0; //read_u32le(offset + 0x18,sf); /* ? */ + loop_end = 0; //read_u32le(offset + 0x1c,sf); /* ? */ + + if (entry_size >= 0x30) { + /* 0x20: null */ + /* 0x24: ? */ + /* 0x26: channel layout */ + channels = read_u8(offset + 0x27,sf); + /* 0x28: ? */ + /* 0x2c: null? */ + } + + loop_flag = loop_end > 0; + + start_offset += stream_offset; + stream_size = data_size; + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_SDRH; + vgmstream->num_samples = num_samples; + vgmstream->sample_rate = sample_rate; + + vgmstream->stream_size = stream_size; + vgmstream->num_streams = total_subsongs; + + switch(codec) { + +#ifdef VGM_USE_FFMPEG + case 1: { /* Lost Odyssey Demo (X360) */ + vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, start_offset, stream_size, vgmstream->channels, vgmstream->sample_rate, 0); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + { + ms_sample_data msd = {0}; + + msd.xma_version = 1; + msd.channels = channels; + msd.data_offset = start_offset; + msd.data_size = stream_size; + msd.loop_flag = loop_flag; + msd.loop_start_b= 0; //loop_start_b; + msd.loop_end_b = 0; //loop_end_b; + msd.loop_start_subframe = 0; //loop_subframe & 0xF; /* lower 4b: subframe where the loop starts, 0..4 */ + msd.loop_end_subframe = 0; //loop_subframe >> 4; /* upper 4b: subframe where the loop ends, 0..3 */ + msd.chunk_offset = 0; + + xma_get_samples(&msd, sf); + + vgmstream->num_samples = msd.num_samples; + //loop_start_sample = msd.loop_start_sample; + //loop_end_sample = msd.loop_end_sample; + } + + + xma_fix_raw_samples(vgmstream, sf, start_offset, stream_size, 0, 0, 1); + break; + } + case 4: { /* Lost Odyssey (X360) */ + int block_size = 0x8000; /* XWAV old default */ + int block_count = seek_count; + + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, stream_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + xma_fix_raw_samples(vgmstream, sf, start_offset, stream_size, 0, 0, 1); + break; + } +#endif + + default: + goto fail; + } + + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/seg.c b/Frameworks/vgmstream/vgmstream/src/meta/seg.c index 87e6f85b2..27bed92ff 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/seg.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/seg.c @@ -2,8 +2,8 @@ #include "../coding/coding.h" /* SEG - from Stormfront games [Eragon (multi), Forgotten Realms: Demon Stone (multi) */ -VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_seg(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; int loop_flag, channel_count; size_t data_size; @@ -12,24 +12,24 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { /* checks */ - if (!check_extensions(streamFile, "seg")) + if (!is_id32be(0x00,sf, "seg\0")) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x73656700) /* "seg\0" */ + if (!check_extensions(sf, "seg")) goto fail; - codec = read_32bitBE(0x04,streamFile); + codec = read_32bitBE(0x04,sf); /* 0x08: version? (2: Eragon, Spiderwick Chronicles Wii / 3: Spiderwick Chronicles X360 / 4: Spiderwick Chronicles PC) */ - if (guess_endianness32bit(0x08,streamFile)) { + if (guess_endianness32bit(0x08,sf)) { read_32bit = read_32bitBE; } else { read_32bit = read_32bitLE; } /* 0x0c: file size */ - data_size = read_32bit(0x10, streamFile); /* including interleave padding */ + data_size = read_32bit(0x10, sf); /* including interleave padding */ /* 0x14: null */ - loop_flag = read_32bit(0x20,streamFile); /* rare */ - channel_count = read_32bit(0x24,streamFile); + loop_flag = read_32bit(0x20,sf); /* rare */ + channel_count = read_32bit(0x24,sf); /* 0x28: extradata 1 entries (0x08 per entry, unknown) */ /* 0x2c: extradata 1 offset */ /* 0x30: extradata 2 entries (0x10 or 0x14 per entry, seek/hist table?) */ @@ -43,13 +43,13 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { if (!vgmstream) goto fail; vgmstream->meta_type = meta_SEG; - vgmstream->sample_rate = read_32bit(0x18,streamFile); - vgmstream->num_samples = read_32bit(0x1c,streamFile); + vgmstream->sample_rate = read_32bit(0x18,sf); + vgmstream->num_samples = read_32bit(0x1c,sf); if (loop_flag) { vgmstream->loop_start_sample = 0; vgmstream->loop_end_sample = vgmstream->num_samples; } - read_string(vgmstream->stream_name,0x20+1, 0x38,streamFile); + read_string(vgmstream->stream_name,0x20+1, 0x38,sf); switch(codec) { case 0x70733200: /* "ps2\0" */ @@ -71,8 +71,8 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { vgmstream->interleave_first_block_size = vgmstream->interleave_block_size - vgmstream->interleave_first_skip; /* standard dsp header at start_offset */ - dsp_read_coefs_be(vgmstream, streamFile, start_offset+0x1c, vgmstream->interleave_block_size); - dsp_read_hist_be(vgmstream, streamFile, start_offset+0x40, vgmstream->interleave_block_size); + dsp_read_coefs_be(vgmstream, sf, start_offset+0x1c, vgmstream->interleave_block_size); + dsp_read_hist_be(vgmstream, sf, start_offset+0x40, vgmstream->interleave_block_size); start_offset += vgmstream->interleave_first_skip; break; @@ -84,19 +84,14 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 0x78623300: { /* "xb3\0" */ - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size = 0x4000; - block_size = 0x4000; - block_count = data_size / block_size + (data_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok */ + xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* samples are ok */ break; } #endif @@ -105,10 +100,9 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { goto fail; } - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/smk.c b/Frameworks/vgmstream/vgmstream/src/meta/smk.c index e5b91735a..1a2a8b73a 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/smk.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/smk.c @@ -43,6 +43,9 @@ VGMSTREAM* init_vgmstream_smk(STREAMFILE *sf) { if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; + + // wrong decoding otherwise + ffmpeg_set_force_seek(vgmstream->codec_data); #else goto fail; #endif diff --git a/Frameworks/vgmstream/vgmstream/src/meta/smp.c b/Frameworks/vgmstream/vgmstream/src/meta/smp.c index 6dbf31c1f..bde31878d 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/smp.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/smp.c @@ -11,14 +11,16 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "smp")) - goto fail; - version = read_u32le(0x00,sf); if (version != 0x05 && /* Ghostbusters (PS2), Mushroom Men (Wii) */ version != 0x06 && /* Ghostbusters (PS3/X360/PC) */ version != 0x07 && /* Ghostbusters (PSP) */ - version != 0x08) /* Chandragupta (PS2/PSP), Street Cricket Champions 1/2 (PSP), Guilty Party (Wii) */ + version != 0x08) /* Def Jam Rapstar (X360), Chandragupta (PS2/PSP), Street Cricket Champions 1/2 (PSP), Guilty Party (Wii) */ + goto fail; + + /* .smp: common + * .snb: Def Jam Rapstar (X360)-few files */ + if (!check_extensions(sf, "smp,snb")) goto fail; /* 0x04~14: guid? */ @@ -28,6 +30,9 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { start_offset = read_u32le(0x1c,sf); data_size = read_u32le(0x20,sf); codec = read_u32le(0x24,sf); + if (start_offset + data_size != get_streamfile_size(sf)) + goto fail; + /* smaller header found in Guilty Party (Wii) */ if (version == 0x08 && start_offset == 0x80) { channels = read_u8(0x28,sf); @@ -102,17 +107,14 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x07: { - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size, block_count; if (bps != 16) goto fail; - /* 0x34(0x28): XMA config/table? */ + /* 0x34(0x28): XMA config/table? (unknown format) */ + block_size = read_u16le(0x3e,sf); + block_count = read_u16le(0x54,sf); - block_size = 0x8000; /* assumed, @0x3e(2)? */ - block_count = data_size / block_size + (data_size % block_size ? 1 : 0); /* @0x54(2)? */ - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -130,7 +132,6 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/naomi_spsd.c b/Frameworks/vgmstream/vgmstream/src/meta/spsd.c similarity index 62% rename from Frameworks/vgmstream/vgmstream/src/meta/naomi_spsd.c rename to Frameworks/vgmstream/vgmstream/src/meta/spsd.c index 76b1c4ed5..955d83530 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/naomi_spsd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/spsd.c @@ -2,66 +2,66 @@ #include "../coding/coding.h" /* SPSD - Naomi (arcade) and early Dreamcast streams [Guilty Gear X (Naomi), Crazy Taxi (Naomi), Virtua Tennis 2 (Naomi)] */ -VGMSTREAM * init_vgmstream_naomi_spsd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_spsd(STREAMFILE *sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; size_t data_size; - int loop_flag, channel_count, codec, flags, index; + int loop_flag, channels, codec, flags, index; /* checks */ + if (!is_id32be(0x00,sf, "SPSD")) + goto fail; /* .str: actual extension, rare [Shenmue (DC)] - * .spsd: header id */ - if (!check_extensions(streamFile, "str,spsd")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x53505344) /* "SPSD" */ + * .spsd: header id (maybe real ext is .PSD, similar to "SMLT" > .MLT) */ + if (!check_extensions(sf, "str,spsd")) goto fail; - if (read_32bitBE(0x04,streamFile) != 0x01010004 && /* standard version */ - read_32bitBE(0x04,streamFile) != 0x00010004) /* uncommon version [Crazy Taxi (Naomi)] */ + if (read_32bitBE(0x04,sf) != 0x01010004 && /* standard version */ + read_32bitBE(0x04,sf) != 0x00010004) /* uncommon version [Crazy Taxi (Naomi)] */ goto fail; - codec = read_8bit(0x08,streamFile); - flags = read_8bit(0x09,streamFile); - index = read_16bitLE(0x0a,streamFile); - data_size = read_32bitLE(0x0c,streamFile); + codec = read_8bit(0x08,sf); + flags = read_8bit(0x09,sf); + index = read_16bitLE(0x0a,sf); + data_size = read_32bitLE(0x0c,sf); //if (data_size + start_offset != get_streamfile_size(streamFile)) // goto fail; /* some rips out there have incorrect padding */ //todo with 0x80 seems 0x2c is a loop_start_sample but must be adjusted to +1 block? (uncommon flag though) loop_flag = (flags & 0x80); - channel_count = ((flags & 0x01) || (flags & 0x02)) ? 2 : 1; /* 0x02 is rare but looks normal (Virtua Tennis 2) */ + channels = ((flags & 0x01) || (flags & 0x02)) ? 2 : 1; /* 0x02 is rare but looks normal (Virtua Tennis 2) */ start_offset = 0x40; /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channels,loop_flag); if (!vgmstream) goto fail; - vgmstream->sample_rate = (uint16_t)read_16bitLE(0x2A,streamFile); + vgmstream->sample_rate = (uint16_t)read_16bitLE(0x2A,sf); - vgmstream->meta_type = meta_NAOMI_SPSD; + vgmstream->meta_type = meta_SPSD; switch (codec) { - case 0x00: /* [Virtua Tennis 2 (Naomi), Club Kart - European Session (Naomi)] */ + case 0x00: /* [Virtua Tennis 2 (Naomi), Club Kart: European Session (Naomi)] */ vgmstream->coding_type = coding_PCM16LE; - vgmstream->num_samples = pcm_bytes_to_samples(data_size,channel_count,16); - vgmstream->loop_start_sample = read_32bitLE(0x2c,streamFile) + pcm_bytes_to_samples(0x2000*channel_count,channel_count,16); + vgmstream->num_samples = pcm_bytes_to_samples(data_size,channels,16); + vgmstream->loop_start_sample = read_32bitLE(0x2c,sf) + pcm_bytes_to_samples(0x2000*channels,channels,16); vgmstream->loop_end_sample = vgmstream->num_samples; break; case 0x01: /* [Virtua Tennis 2 (Naomi)] */ vgmstream->coding_type = coding_PCM8; - vgmstream->num_samples = pcm_bytes_to_samples(data_size,channel_count,8); - vgmstream->loop_start_sample = read_32bitLE(0x2c,streamFile) + pcm_bytes_to_samples(0x2000*channel_count,channel_count,8); + vgmstream->num_samples = pcm_bytes_to_samples(data_size,channels,8); + vgmstream->loop_start_sample = read_32bitLE(0x2c,sf) + pcm_bytes_to_samples(0x2000*channels,channels,8); vgmstream->loop_end_sample = vgmstream->num_samples; break; case 0x03: /* standard */ vgmstream->coding_type = coding_AICA_int; - vgmstream->num_samples = yamaha_bytes_to_samples(data_size,channel_count); - vgmstream->loop_start_sample = /*read_32bitLE(0x2c,streamFile) +*/ yamaha_bytes_to_samples(0x2000*channel_count,channel_count); + vgmstream->num_samples = yamaha_bytes_to_samples(data_size,channels); + vgmstream->loop_start_sample = /*read_32bitLE(0x2c,streamFile) +*/ yamaha_bytes_to_samples(0x2000*channels,channels); vgmstream->loop_end_sample = vgmstream->num_samples; break; @@ -72,7 +72,7 @@ VGMSTREAM * init_vgmstream_naomi_spsd(STREAMFILE *streamFile) { /* interleave index, maybe */ switch(index) { case 0x0000: - if (channel_count != 1) goto fail; + if (channels != 1) goto fail; vgmstream->layout_type = layout_none; break; @@ -85,7 +85,7 @@ VGMSTREAM * init_vgmstream_naomi_spsd(STREAMFILE *streamFile) { case 0x00ff: vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = data_size / channel_count; + vgmstream->interleave_block_size = data_size / channels; break; default: @@ -97,13 +97,13 @@ VGMSTREAM * init_vgmstream_naomi_spsd(STREAMFILE *streamFile) { * at 0x30(4*ch) is some config per channel but doesn't seem to affect ADPCM (found with PCM too) */ { int i; - for (i = 0; i < channel_count; i++) { + for (i = 0; i < channels; i++) { vgmstream->ch[i].adpcm_step_index = 0x7f; } } - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/sqex_scd.c b/Frameworks/vgmstream/vgmstream/src/meta/sqex_scd.c index 272f109eb..f8e00fbf8 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/sqex_scd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/sqex_scd.c @@ -310,14 +310,10 @@ VGMSTREAM* init_vgmstream_sqex_scd(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0B: { /* XMA2 [Final Fantasy (X360), Lightning Returns (X360) sfx, Kingdom Hearts 2.8 (X1)] */ - uint8_t buf[0x100]; - int32_t bytes; - /* extradata: * 0x00: fmt0x166 header (BE X360, LE XBone) * 0x34: seek table */ - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, extradata_offset,0x34, stream_size, sf, big_endian); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, start_offset, stream_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, stream_size, extradata_offset, 0x34); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ster.c b/Frameworks/vgmstream/vgmstream/src/meta/ster.c index 293ea80e4..0ca2d0ff5 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ster.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ster.c @@ -10,13 +10,14 @@ VGMSTREAM* init_vgmstream_ster(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00,sf, "STER")) + goto fail; + /* .ster: header id (no apparent names/extensions) * .sfs: generic bigfile extension (to be removed?)*/ if (!check_extensions(sf, "ster,sfs")) goto fail; - if (!is_id32be(0x00,sf, "STER")) - goto fail; channel_size = read_u32le(0x04, sf); loop_start = read_u32le(0x08, sf); /* absolute (ex. offset 0x50 for full loops) */ /* 0x0c: data size BE */ @@ -28,7 +29,7 @@ VGMSTREAM* init_vgmstream_ster(STREAMFILE* sf) { start_offset = 0x30; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/str_wav.c b/Frameworks/vgmstream/vgmstream/src/meta/str_wav.c index 331918bca..84e9117ca 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/str_wav.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/str_wav.c @@ -160,16 +160,10 @@ VGMSTREAM* init_vgmstream_str_wav(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case XMA2: { - uint8_t buf[0x100]; - size_t stream_size; - size_t bytes, block_size, block_count; + uint32_t stream_size = get_streamfile_size(sf); + int block_size = 0x10000; - stream_size = get_streamfile_size(sf); - block_size = 0x10000; - block_count = stream_size / block_size; /* not accurate? */ - - bytes = ffmpeg_make_riff_xma2(buf,0x100, strwav.num_samples, stream_size, strwav.channels, strwav.sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, 0x00,stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, 0x00, stream_size, strwav.num_samples, strwav.channels, strwav.sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/txth.c b/Frameworks/vgmstream/vgmstream/src/meta/txth.c index ca0f2a9ea..e261a3f9a 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/txth.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/txth.c @@ -44,6 +44,8 @@ typedef enum { ASF = 30, /* Argonaut ASF 4-bit ADPCM */ EAXA = 31, /* Electronic Arts EA-XA 4-bit ADPCM v1 */ OKI4S = 32, /* OKI ADPCM with 16-bit output (unlike OKI/VOX/Dialogic ADPCM's 12-bit) */ + PCM24LE = 33, /* 24-bit Little Endian PCM */ + PCM24BE = 34, /* 24-bit Big Endian PCM */ XA, XA_EA, CP_YM, @@ -226,6 +228,8 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case PSX_bf: case HEVAG: interleave = 0x10; break; case NGC_DSP: interleave = 0x08; break; + case PCM24LE: interleave = 0x03; break; + case PCM24BE: interleave = 0x03; break; case PCM16LE: case PCM16BE: interleave = 0x02; break; case PCM8: @@ -246,6 +250,8 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case HEVAG: coding = coding_HEVAG; break; case XBOX: coding = coding_XBOX_IMA; break; case NGC_DTK: coding = coding_NGC_DTK; break; + case PCM24LE: coding = coding_PCM24LE; break; + case PCM24BE: coding = coding_PCM24BE; break; case PCM16LE: coding = coding_PCM16LE; break; case PCM16BE: coding = coding_PCM16BE; break; case PCM8: coding = coding_PCM8; break; @@ -318,6 +324,8 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case coding_PCM8_U_int: vgmstream->layout_type = layout_none; break; + case coding_PCM24LE: + case coding_PCM24BE: case coding_PCM16LE: case coding_PCM16BE: case coding_PCM8: @@ -550,47 +558,35 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { ffmpeg_data = init_ffmpeg_aac(txth.sf_body, txth.start_offset, txth.data_size, 0); if (!ffmpeg_data) goto fail; } + else if (txth.codec == ATRAC3) { + int block_align, encoder_delay; + + block_align = txth.interleave; + encoder_delay = txth.skip_samples; + + ffmpeg_data = init_ffmpeg_atrac3_raw(txth.sf_body, txth.start_offset,txth.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + if (!ffmpeg_data) goto fail; + } + else if (txth.codec == ATRAC3PLUS) { + int block_size = txth.interleave; + + ffmpeg_data = init_ffmpeg_atrac3plus_raw(txth.sf_body, txth.start_offset, txth.data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, txth.skip_samples); + if (!ffmpeg_data) goto fail; + } + else if (txth.codec == XMA1) { + int xma_stream_mode = txth.codec_mode == 1 ? 1 : 0; + + ffmpeg_data = init_ffmpeg_xma1_raw(txth.sf_body, txth.start_offset, txth.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); + if (!ffmpeg_data) goto fail; + } + else if (txth.codec == XMA2) { + int block_size = txth.interleave; + + ffmpeg_data = init_ffmpeg_xma2_raw(sf, txth.start_offset, txth.data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); + if (!ffmpeg_data) goto fail; + } else { - /* fake header FFmpeg */ - uint8_t buf[0x100]; - int32_t bytes; - - if (txth.codec == ATRAC3) { - int block_align, encoder_delay; - - block_align = txth.interleave; - encoder_delay = txth.skip_samples; - - ffmpeg_data = init_ffmpeg_atrac3_raw(txth.sf_body, txth.start_offset,txth.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); - if (!ffmpeg_data) goto fail; - } - else if (txth.codec == ATRAC3PLUS) { - int block_size = txth.interleave; - - bytes = ffmpeg_make_riff_atrac3plus(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, txth.skip_samples); - ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); - if ( !ffmpeg_data ) goto fail; - } - else if (txth.codec == XMA1) { - int xma_stream_mode = txth.codec_mode == 1 ? 1 : 0; - - bytes = ffmpeg_make_riff_xma1(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); - ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); - if ( !ffmpeg_data ) goto fail; - } - else if (txth.codec == XMA2) { - int block_count, block_size; - - block_size = txth.interleave ? txth.interleave : 2048; - block_count = txth.data_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); - if ( !ffmpeg_data ) goto fail; - } - else { - goto fail; - } + goto fail; } vgmstream->codec_data = ffmpeg_data; @@ -598,7 +594,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { if (txth.codec == XMA1 || txth.codec == XMA2) { xma_fix_raw_samples(vgmstream, txth.sf_body, txth.start_offset,txth.data_size, 0, 0,0); - } else if (txth.skip_samples_set && txth.codec != ATRAC3) { /* force encoder delay */ + } else if (txth.skip_samples_set && txth.codec != ATRAC3 && txth.codec != ATRAC3PLUS) { /* force encoder delay */ ffmpeg_set_skip_samples(ffmpeg_data, txth.skip_samples); } @@ -953,6 +949,8 @@ static txth_codec_t parse_codec(txth_header* txth, const char* val) { else if (is_string(val,"XBOX")) return XBOX; else if (is_string(val,"NGC_DTK")) return NGC_DTK; else if (is_string(val,"DTK")) return NGC_DTK; + else if (is_string(val,"PCM24BE")) return PCM24BE; + else if (is_string(val,"PCM24LE")) return PCM24LE; else if (is_string(val,"PCM16BE")) return PCM16BE; else if (is_string(val,"PCM16LE")) return PCM16LE; else if (is_string(val,"PCM8")) return PCM8; @@ -2103,6 +2101,10 @@ static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) { case PSX_bf: case HEVAG: return ps_bytes_to_samples(bytes, txth->channels); + case PCM24BE: + return pcm24_bytes_to_samples(bytes, txth->channels); + case PCM24LE: + return pcm24_bytes_to_samples(bytes, txth->channels); case PCM16BE: case PCM16LE: return pcm16_bytes_to_samples(bytes, txth->channels); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_bao.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_bao.c index 04afbe876..9093e4422 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_bao.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_bao.c @@ -275,7 +275,7 @@ static VGMSTREAM* init_vgmstream_ubi_bao_base(ubi_bao_header* bao, STREAMFILE* s vgmstream->coding_type = coding_NGC_DSP; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = bao->stream_size / bao->channels; -VGM_LOG("dsp=%x, %x, %x\n", bao->header_offset, bao->header_size, bao->extra_size); + /* mini DSP header (first 0x10 seem to contain DSP header fields like nibbles and format) */ dsp_read_coefs_be(vgmstream, streamHead, bao->header_offset + bao->header_size + bao->extra_size + 0x10, 0x40); dsp_read_hist_be (vgmstream, streamHead, bao->header_offset + bao->header_size + bao->extra_size + 0x34, 0x40); /* after gain/initial ps */ @@ -286,10 +286,9 @@ VGM_LOG("dsp=%x, %x, %x\n", bao->header_offset, bao->header_size, bao->extra_siz case RAW_XMA1: case RAW_XMA2_OLD: case RAW_XMA2_NEW: { - uint8_t buf[0x100]; - size_t bytes, chunk_size, data_size; + size_t chunk_size, data_size; off_t chunk_offset; - STREAMFILE* streamXMA; + STREAMFILE* sf_xma; switch(bao->codec) { case RAW_XMA1: chunk_size = 0x20; break; @@ -339,26 +338,19 @@ VGM_LOG("dsp=%x, %x, %x\n", bao->header_offset, bao->header_size, bao->extra_siz header_size += align_size_to_block(sec2_num * bits_per_frame, 32) / 8; /* bitstream seek table? */ header_size += sec3_num * 0x08; - streamXMA = streamData; + sf_xma = streamData; chunk_offset = 0x00; start_offset += header_size; data_size = sec2_num * frame_size; } else { - streamXMA = streamHead; + sf_xma = streamHead; chunk_offset = bao->header_offset + bao->header_size; start_offset = 0x00; data_size = bao->stream_size; } - if (bao->codec == RAW_XMA2_OLD) { - bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf,0x100, chunk_offset, chunk_size, data_size, streamXMA); - } - else { - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset, chunk_size, data_size, streamXMA, 1); - } - - vgmstream->codec_data = init_ffmpeg_header_offset(streamData, buf, bytes, start_offset, data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf_xma, start_offset, data_size, chunk_offset, chunk_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -1368,7 +1360,7 @@ static STREAMFILE* open_atomic_bao(ubi_bao_file file_type, uint32_t file_id, int snprintf(buf,buf_size, "%08x.bao", file_id); sf_bao = open_streamfile_by_filename(sf, buf); if (sf_bao) return sf_bao; - } + } else { /* %08x.sbao nomenclature (in addition to %08x.bao) present in Shaun White Snowboarding (Windows Vista) exe. */ snprintf(buf,buf_size, "%08x.sbao", file_id); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_ckd.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_ckd.c index baac19f1d..6f76a4d16 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_ckd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_ckd.c @@ -148,11 +148,7 @@ VGMSTREAM* init_vgmstream_ubi_ckd(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case XMA2: { - uint8_t buf[0x100]; - int bytes; - - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, sizeof(buf), 0x14, 0x34, data_size, sf, 1); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, 0x14, 0x34); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_hx.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_hx.c index 6dc4c5a14..2a830ab07 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_hx.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_hx.c @@ -745,14 +745,9 @@ static VGMSTREAM* init_vgmstream_ubi_hx_header(ubi_hx_header* hx, STREAMFILE* sf #ifdef VGM_USE_FFMPEG case XMA2: { - int bytes, block_count, block_size; - uint8_t buf[0x200]; + int block_size = 0x800; - block_size = 0x800; - block_count = hx->stream_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf,0x200, hx->num_samples, hx->stream_size, hx->channels, hx->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sb, buf,bytes, hx->stream_offset,hx->stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sb, hx->stream_offset, hx->stream_size, hx->num_samples, hx->channels, hx->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_lyn.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_lyn.c index a57574dc7..36daec2b6 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_lyn.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_lyn.c @@ -273,8 +273,6 @@ VGMSTREAM* init_vgmstream_ubi_lyn(STREAMFILE* sf) { } case 0x0166: { /* XMA (X360), standard */ - uint8_t buf[0x100]; - int bytes; off_t chunk_offset; size_t chunk_size, seek_size; @@ -286,9 +284,8 @@ VGMSTREAM* init_vgmstream_ubi_lyn(STREAMFILE* sf) { start_offset += (0x04 + 0x04 + chunk_size + 0x04 + seek_size); data_size -= (0x04 + 0x04 + chunk_size + 0x04 + seek_size); - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, sf, 1); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); - if ( !vgmstream->codec_data ) goto fail; + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, chunk_offset, chunk_size); + if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_raki.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_raki.c index 790a0497d..82626b29e 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_raki.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_raki.c @@ -3,8 +3,8 @@ /* RAKI - Ubisoft audio format [Rayman Legends, Just Dance 2017 (multi)] */ -VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *sf) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_ubi_raki(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset, offset, fmt_offset; size_t header_size, data_size; int big_endian; @@ -16,19 +16,22 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *sf) { /* checks */ + + /* some games (ex. Rayman Legends PS3) have a 32b file type before the RAKI data. However offsets are + * absolute and expect the type exists, so it's part of the file and not an extraction defect. + * Type varies between platforms (0x09, 0x0b, etc). */ + if ((is_id32be(0x00,sf, "RAKI"))) + offset = 0x00; + else if (is_id32be(0x04,sf, "RAKI")) + offset = 0x04; + else + goto fail; + /* .rak: Just Dance 2017 * .ckd: Rayman Legends (technically .wav.ckd/rak) */ if (!check_extensions(sf,"rak,ckd")) goto fail; - /* some games (ex. Rayman Legends PS3) have a 32b file type before the RAKI data. However - * offsets are absolute and expect the type exists, so it's part of the file and not an extraction defect. */ - if ((read_32bitBE(0x00,sf) == 0x52414B49)) /* "RAKI" */ - offset = 0x00; - else if ((read_32bitBE(0x04,sf) == 0x52414B49)) /* type varies between platforms (0x09, 0x0b) so ignore */ - offset = 0x04; - else - goto fail; /* 0x04: version? (0x00, 0x07, 0x0a, etc); */ platform = read_32bitBE(offset+0x08,sf); /* string */ @@ -182,20 +185,15 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *sf) { #ifdef VGM_USE_FFMPEG case 0x58333630786D6132: { /* "X360xma2" */ /* chunks: "seek" (XMA2 seek table), "data" */ - uint8_t buf[100]; - int bytes, block_count; if (!block_align) goto fail; - block_count = data_size / block_align + (data_size % block_align ? 1 : 0); + vgmstream->num_samples = read_32bit(fmt_offset+0x18,sf); - bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_align); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_align, 0); if ( !vgmstream->codec_data ) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - vgmstream->num_samples = read_32bit(fmt_offset+0x18,sf); - xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* should apply to num_samples? */ break; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c index 2e6d7f8fb..58e0de211 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c @@ -1118,10 +1118,9 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h // Probably a beta/custom encoder that creates some buggy frames, that a real X360 handles ok, but trips FFmpeg // xmaencode decodes correctly if counters are fixed (otherwise has clicks on every frame). case FMT_XMA1: { - uint8_t buf[0x100]; uint32_t sec1_num, sec2_num, sec3_num, bits_per_frame; uint8_t flag; - size_t bytes, chunk_size, header_size, data_size; + size_t chunk_size, header_size, data_size; off_t header_offset; chunk_size = 0x20; @@ -1146,9 +1145,7 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h start_offset += header_size; data_size = sec2_num * 0x800; - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, header_offset, chunk_size, data_size, sf_data, 1); - - vgmstream->codec_data = init_ffmpeg_header_offset(sf_data, buf, bytes, start_offset, data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf_data, start_offset, data_size, header_offset, chunk_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -1158,8 +1155,7 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h } case RAW_XMA1: { - uint8_t buf[0x100]; - size_t bytes, chunk_size; + size_t chunk_size; off_t header_offset; VGM_ASSERT(sb->is_streamed, "UBI SB: Raw XMA used for streamed sound\n"); @@ -1170,9 +1166,7 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h if (header_offset == 0) header_offset = sb->extra_offset; - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, header_offset, chunk_size, sb->stream_size, sf_head, 1); - - vgmstream->codec_data = init_ffmpeg_header_offset(sf_data, buf, bytes, start_offset, sb->stream_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk_split(sf_head, sf_data, start_offset, sb->stream_size, header_offset, chunk_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/vag.c b/Frameworks/vgmstream/vgmstream/src/meta/vag.c index 764427ac3..aed923c02 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/vag.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/vag.c @@ -246,12 +246,19 @@ VGMSTREAM* init_vgmstream_vag(STREAMFILE* sf) { channel_size = channel_size / channels; } else if (version == 0x00000020 && reserved == 0x01010101) { - /* Gift (PS2) */ + /* Eko Software */ start_offset = 0x800; channels = 2; /* mono VAGs in this game are standard, without reserved value */ - interleave = 0x2000; - if (read_u32be(0x4800,sf) == 0x00000000) /* one file has bigger interleave, detectable with ch2's null frame */ + + /* detect interleave with ch2's null frame */ + if (read_u32be(0x800 + 0x400,sf) == 0x00000000) /* Woody Woodpecker: Escape from Buzz Buzzard Park (PS2) */ + interleave = 0x400; + else if (read_u32be(0x800 + 0x4000,sf) == 0x00000000) /* Gift (PS2), one file */ interleave = 0x4000; + else if (read_u32be(0x800 + 0x2000,sf) == 0x00000000) /* Gift (PS2) */ + interleave = 0x2000; + else + goto fail; channel_size = channel_size / channels; has_interleave_last = 1; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/vgs.c b/Frameworks/vgmstream/vgmstream/src/meta/vgs.c index db55f8fb0..c4f9940a5 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/vgs.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/vgs.c @@ -4,27 +4,26 @@ #include "../layout/layout.h" /* VGS - from Guitar Hero Encore - Rocks the 80s, Guitar Hero II PS2 */ -VGMSTREAM * init_vgmstream_vgs(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_vgs(STREAMFILE *sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; size_t channel_size = 0, stream_data_size, stream_frame_count; - int channel_count = 0, loop_flag = 0, sample_rate = 0, stream_sample_rate; + int channels = 0, loop_flag = 0, sample_rate = 0, stream_sample_rate; int i; - /* check extension, case insensitive */ - if (!check_extensions(streamFile,"vgs")) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x56675321) /* "VgS!" */ + /* checks */ + if (!is_id32be(0x00,sf, "VgS!")) goto fail; /* 0x04: version? */ + if (!check_extensions(sf,"vgs")) + goto fail; + /* contains N streams, which can have one less frame, or half frame and sample rate */ for (i = 0; i < 8; i++) { - stream_sample_rate = read_32bitLE(0x08 + 0x08*i + 0x00,streamFile); - stream_frame_count = read_32bitLE(0x08 + 0x08*i + 0x04,streamFile); + stream_sample_rate = read_32bitLE(0x08 + 0x08*i + 0x00,sf); + stream_frame_count = read_32bitLE(0x08 + 0x08*i + 0x04,sf); stream_data_size = stream_frame_count*0x10; if (stream_sample_rate == 0) @@ -47,24 +46,24 @@ VGMSTREAM * init_vgmstream_vgs(STREAMFILE *streamFile) { break; } - channel_count++; + channels++; } start_offset = 0x80; - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; vgmstream->meta_type = meta_VGS; vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = ps_bytes_to_samples(channel_size*channel_count, channel_count); + vgmstream->num_samples = ps_bytes_to_samples(channel_size * channels, channels); vgmstream->coding_type = coding_PSX_badflags; /* flag = stream/channel number */ vgmstream->layout_type = layout_blocked_vgs; - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; fail: diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wbk.c b/Frameworks/vgmstream/vgmstream/src/meta/wbk.c index 1abef6d21..884c2925b 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/wbk.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/wbk.c @@ -301,9 +301,8 @@ VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x30: { /* RIFF XMA */ - uint8_t buf[0x100]; off_t riff_fmt_offset, riff_data_offset; - size_t bytes, riff_fmt_size, riff_data_size; + size_t riff_fmt_size, riff_data_size; sound_offset += 0x0c; sound_size -= 0x0c; @@ -317,9 +316,8 @@ VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf) { goto fail; sound_offset = riff_data_offset; - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, riff_fmt_offset, riff_fmt_size, riff_data_size, sf, 0); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, riff_data_offset, riff_data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, riff_data_offset, riff_data_size, riff_fmt_offset, riff_fmt_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wwise.c b/Frameworks/vgmstream/vgmstream/src/meta/wwise.c index 09f44d6e0..852fcc0a2 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/wwise.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/wwise.c @@ -365,9 +365,6 @@ VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch) { #ifdef VGM_USE_FFMPEG case XMA2: { /* X360/XBone */ - uint8_t buf[0x100]; - int bytes; - /* endian check should be enough */ //if (ww.fmt_size != ...) goto fail; /* XMA1 0x20, XMA2old: 0x34, XMA2new: 0x40, XMA2 Guitar Hero Live/padded: 0x64, etc */ @@ -375,14 +372,7 @@ VGMSTREAM* init_vgmstream_wwise_bnk(STREAMFILE* sf, int* p_prefetch) { if (!(ww.big_endian || (!ww.big_endian && check_extensions(sf,"wem,bnk")))) goto fail; - if (ww.xma2_offset) { /* older */ - bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf, sizeof(buf), ww.xma2_offset, ww.xma2_size, ww.data_size, sf); - } - else { /* newer */ - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, sizeof(buf), ww.fmt_offset, ww.fmt_size, ww.data_size, sf, ww.big_endian); - } - - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, ww.data_offset,ww.data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, ww.data_offset, ww.data_size, ww.xma2_offset ? ww.xma2_offset : ww.fmt_offset, ww.xma2_size ? ww.xma2_size : ww.fmt_size); if ( !vgmstream->codec_data ) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/x360_ast.c b/Frameworks/vgmstream/vgmstream/src/meta/x360_ast.c deleted file mode 100644 index 68a331f83..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/x360_ast.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* ASTB - found in Dead Rising (X360) */ -VGMSTREAM * init_vgmstream_x360_ast(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, data_size; - int loop_flag, channel_count; - int i, xma_streams; - - /* check extension, case insensitive */ - if ( !check_extensions(streamFile,"ast")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x41535442) /* "ASTB" */ - goto fail; - - if (read_32bitBE(0x04,streamFile) != get_streamfile_size(streamFile)) goto fail; - if (read_16bitBE(0x30,streamFile) != 0x165) goto fail; /* only seen XMA1 */ - - xma_streams = read_16bitBE(0x38,streamFile); - - loop_flag = read_8bit(0x3a,streamFile); - channel_count = 0; /* sum of all stream channels (though only 1/2ch ever seen) */ - for (i = 0; i < xma_streams; i++) { - channel_count += read_8bit(0x3c + 0x14*i + 0x11,streamFile); - } - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - start_offset = read_32bitBE(0x10,streamFile); - data_size = read_32bitBE(0x20,streamFile); - - vgmstream->sample_rate = read_32bitBE(0x40,streamFile); - vgmstream->meta_type = meta_X360_AST; - - { - /* manually find sample offsets (XMA1 nonsense again) */ - ms_sample_data msd = {0}; - - msd.xma_version = 1; - msd.channels = channel_count; - msd.data_offset = start_offset; - msd.data_size = data_size; - msd.loop_flag = loop_flag; - msd.loop_start_b = read_32bitBE(0x44,streamFile); - msd.loop_end_b = read_32bitBE(0x48,streamFile); - msd.loop_start_subframe = read_8bit(0x4c,streamFile) & 0xF; /* lower 4b: subframe where the loop starts, 0..4 */ - msd.loop_end_subframe = read_8bit(0x4c,streamFile) >> 4; /* upper 4b: subframe where the loop ends, 0..3 */ - - xma_get_samples(&msd, streamFile); - vgmstream->num_samples = msd.num_samples; - vgmstream->loop_start_sample = msd.loop_start_sample; - vgmstream->loop_end_sample = msd.loop_end_sample; - } - -#ifdef VGM_USE_FFMPEG - { - uint8_t buf[100]; - size_t bytes; - - off_t fmt_offset = 0x30; - size_t fmt_size = 0x0c + xma_streams * 0x14; - - /* XMA1 "fmt" chunk @ 0x20 (BE, unlike the usual LE) */ - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,100, fmt_offset,fmt_size, data_size, streamFile, 1); - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); - if ( !vgmstream->codec_data ) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, fmt_offset, 1,1); - } -#else - goto fail; -#endif - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/x360_cxs.c b/Frameworks/vgmstream/vgmstream/src/meta/x360_cxs.c deleted file mode 100644 index eb080a4a3..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/x360_cxs.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* CXS - found in Eternal Sonata (X360) */ -VGMSTREAM* init_vgmstream_x360_cxs(STREAMFILE* sf) { - VGMSTREAM* vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - /* checks */ - if ( !check_extensions(sf,"cxs")) - goto fail; - if (read_32bitBE(0x00,sf) != 0x43585320) /* "CXS " */ - goto fail; - - loop_flag = read_32bitBE(0x18,sf) > 0; - channel_count = read_32bitBE(0x0c,sf); - start_offset = read_32bitBE(0x04,sf) + read_32bitBE(0x28,sf); /* assumed, seek table always at 0x800 */ - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* 0x04: data start? */ - vgmstream->sample_rate = read_32bitBE(0x08,sf); - vgmstream->num_samples = read_32bitBE(0x10,sf); - vgmstream->loop_start_sample = read_32bitBE(0x14,sf); - vgmstream->loop_end_sample = read_32bitBE(0x18,sf); - /* 0x1c: below */ - - vgmstream->meta_type = meta_X360_CXS; - -#ifdef VGM_USE_FFMPEG - { - uint8_t buf[0x100]; - size_t bytes, datasize, block_size, block_count; - - block_count = read_32bitBE(0x1c,sf); - block_size = read_32bitBE(0x20,sf); - datasize = read_32bitBE(0x24,sf); - - bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - if (bytes <= 0) goto fail; - - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,datasize); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - xma_fix_raw_samples(vgmstream, sf, start_offset,datasize, 0, 0,1); /* num samples are ok */ - } -#else - goto fail; -#endif - - if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/x360_pasx.c b/Frameworks/vgmstream/vgmstream/src/meta/x360_pasx.c deleted file mode 100644 index 45b60c5d2..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/x360_pasx.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* PASX - from Premium Agency games [SoulCalibur II HD (X360), Death By Cube (X360)] */ -VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, chunk_offset; - size_t data_size, chunk_size; - int loop_flag, channel_count, sample_rate; - int num_samples, loop_start_sample, loop_end_sample; - - - /* checks */ - /* .past: Soul Calibur II HD - * .sgb: Death By Cube */ - if ( !check_extensions(streamFile,"past,sgb")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x50415358) /* "PASX" */ - goto fail; - - - /* custom header with a "fmt " data chunk inside */ - chunk_size = read_32bitBE(0x08,streamFile); - data_size = read_32bitBE(0x0c,streamFile); - chunk_offset = read_32bitBE(0x10,streamFile); /* 0x14: fmt offset end */ - start_offset = read_32bitBE(0x18,streamFile); - - channel_count = read_16bitBE(chunk_offset+0x02,streamFile); - sample_rate = read_32bitBE(chunk_offset+0x04,streamFile); - xma2_parse_fmt_chunk_extra(streamFile, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start_sample; - vgmstream->loop_end_sample = loop_end_sample; - vgmstream->meta_type = meta_X360_PASX; - -#ifdef VGM_USE_FFMPEG - { - uint8_t buf[0x100]; - size_t bytes; - - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, streamFile, 1); - if (bytes <= 0) goto fail; - - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); - if ( !vgmstream->codec_data ) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, chunk_offset, 1,1); - } -#else - goto fail; -#endif - - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/x360_tra.c b/Frameworks/vgmstream/vgmstream/src/meta/x360_tra.c deleted file mode 100644 index d1227a688..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/x360_tra.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "meta.h" -#include "../layout/layout.h" -#include "../util.h" - -/* TRA - - TRA is an headerless format which can be found on DefJam Rapstar (X360) - known extensions : WAVM - - 2010-12-03 - Fastelbja : First version ... -*/ -VGMSTREAM * init_vgmstream_x360_tra(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - - int loop_flag=0; - int channel_count; - int i; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("tra",filename_extension(filename))) goto fail; - - /* No loop on wavm */ - loop_flag = 0; - - /* Always stereo files */ - channel_count=2; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - /* allways 2 channels @ 44100 Hz */ - vgmstream->channels = 2; - vgmstream->sample_rate = 24000; - - vgmstream->coding_type = coding_DVI_IMA_int; - vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile) - ((get_streamfile_size(streamFile)/0x204)*4)); - vgmstream->layout_type = layout_blocked_tra; - - vgmstream->meta_type = meta_X360_TRA; - - /* open the file for reading by each channel */ - { - for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - - if (!vgmstream->ch[i].streamfile) goto fail; - } - } - - block_update_tra(0,vgmstream); - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xma.c b/Frameworks/vgmstream/vgmstream/src/meta/xma.c index 338c44123..a7eadf1f3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xma.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xma.c @@ -141,17 +141,7 @@ VGMSTREAM* init_vgmstream_xma(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG { - uint8_t buf[0x100]; - int bytes; - - if (is_xma2_old) { - bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf, sizeof(buf), chunk_offset,chunk_size, data_size, sf); - } - else { - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, sizeof(buf), chunk_offset,chunk_size, data_size, sf, fmt_be); - } - - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, start_offset, data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, chunk_offset, chunk_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -162,11 +152,9 @@ VGMSTREAM* init_vgmstream_xma(STREAMFILE* sf) { goto fail; #endif - if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xma_ue3.c b/Frameworks/vgmstream/vgmstream/src/meta/xma_ue3.c index 324457cd6..1bf31e4fd 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xma_ue3.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xma_ue3.c @@ -2,36 +2,36 @@ #include "../coding/coding.h" /* XMA from Unreal Engine games */ -VGMSTREAM* init_vgmstream_xma_ue3(STREAMFILE *sf) { +VGMSTREAM* init_vgmstream_xma_ue3(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; - off_t start_offset, chunk_offset; - int loop_flag, channel_count, sample_rate, is_xma2_old = 0; + uint32_t start_offset, chunk_offset; + int loop_flag, channel_count, sample_rate; int num_samples, loop_start_sample, loop_end_sample; - size_t file_size, fmt_size, seek_size, data_size; + uint32_t file_size, chunk_size, seek_size, data_size; - /* checks */ - /* .xma: assumed */ - /* .x360audio: fake produced by UE Viewer */ - if (!check_extensions(sf, "xma,x360audio,")) - goto fail; - /* UE3 uses class-like chunks called "SoundNodeWave" to store info and (rarely multi) raw audio data. Other * platforms use standard formats (PC=Ogg, PS3=MSF), while X360 has mutant XMA. Extractors transmogrify * UE3 XMA into RIFF XMA (discarding seek table and changing endianness) but we'll support actual raw * data for completeness. UE4 has .uexp which are very similar so XBone may use the same XMA. */ + /* checks */ file_size = get_streamfile_size(sf); - fmt_size = read_u32be(0x00, sf); + chunk_size = read_u32be(0x00, sf); seek_size = read_u32be(0x04, sf); data_size = read_u32be(0x08, sf); - if (0x0c + fmt_size + seek_size + data_size != file_size) + if (0x0c + chunk_size + seek_size + data_size != file_size) goto fail; + + /* .xma: assumed */ + /* .x360audio: fake produced by UE Viewer */ + if (!check_extensions(sf, "xma,x360audio,")) + goto fail; + chunk_offset = 0x0c; /* parse sample data (always BE unlike real XMA) */ - if (fmt_size != 0x34) { /* old XMA2 [The Last Remnant (X360)] */ - is_xma2_old = 1; + if (chunk_size != 0x34) { /* old XMA2 [The Last Remnant (X360)] */ xma2_parse_xma2_chunk(sf, chunk_offset, &channel_count,&sample_rate, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample); } else { /* new XMA2 [Shadows of the Damned (X360)] */ @@ -40,7 +40,7 @@ VGMSTREAM* init_vgmstream_xma_ue3(STREAMFILE *sf) { xma2_parse_fmt_chunk_extra(sf, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); } - start_offset = 0x0c + fmt_size + seek_size; + start_offset = 0x0c + chunk_size + seek_size; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); @@ -54,15 +54,7 @@ VGMSTREAM* init_vgmstream_xma_ue3(STREAMFILE *sf) { #ifdef VGM_USE_FFMPEG { - uint8_t buf[0x100]; - size_t bytes; - - if (is_xma2_old) { - bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf,0x100, chunk_offset,fmt_size, data_size, sf); - } else { - bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,fmt_size, data_size, sf, 1); - } - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, data_size, chunk_offset, chunk_size); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -91,7 +83,6 @@ VGMSTREAM* init_vgmstream_xma_ue3(STREAMFILE *sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xnb.c b/Frameworks/vgmstream/vgmstream/src/meta/xnb.c index 0b8152e1d..df03784e1 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xnb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xnb.c @@ -259,14 +259,9 @@ VGMSTREAM* init_vgmstream_xnb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x166: { /* Terraria (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x10000; /* guessed */ - block_size = 0x10000; /* guessed */ - block_count = data_size / block_size + (data_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf,0x100, num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf_h, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf_h, start_offset, data_size, num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xse.c b/Frameworks/vgmstream/vgmstream/src/meta/xse.c deleted file mode 100644 index 1b5a46968..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/xse.c +++ /dev/null @@ -1,301 +0,0 @@ -#include "meta.h" -#include "../layout/layout.h" -#include "../coding/coding.h" - - -/* SDRH - banks for newer feelplus-related games [Mindjack (PS3/X360)] */ -VGMSTREAM* init_vgmstream_xse_new(STREAMFILE* sf) { - VGMSTREAM* vgmstream = NULL; - off_t start_offset, data_size, stream_size; - int loop_flag = 0, channels, codec, sample_rate, seek_count; - int32_t num_samples, loop_start, loop_end; - off_t offset; - int total_subsongs, target_subsong = sf->stream_index; - - - /* checks */ - if (!check_extensions(sf, "xse")) - goto fail; - if (read_u32be(0x00,sf) != 0x48524453) /* "HRDS" */ - goto fail; - - /* similar to older version but BE and a bit less complex */ - /* 0x04: version/config? - * 0x08: data size - * 0x30: file name in some strange encoding/compression? - * others: ? (change in old/new) - */ - - /* parse section */ - { - int i; - int tables = read_u16be(0x1C,sf); - off_t base_size, stream_offset; - int entries; - - offset = 0; - /* read sections (FE=cues?, WV=mini-headers?, XW=waves) */ - for (i = 0; i < tables; i++) { - uint16_t id = read_u16be(0x40 + 0x10 * i + 0x00,sf); - /* 0x02: offset in 0x40s */ - /* 0x04: section size */ - /* 0x08: always 1 */ - /* 0x0c: null */ - if (id == 0x5857) { /* "XW" */ - offset += read_u16be(0x40 + 0x10 * i + 0x02,sf) * 0x40; - break; - } - } - - /* section header (other sections have a similar header) */ - /* 0x00: section size */ - base_size = read_u16be(offset + 0x04,sf); - entries = read_u16be(offset + 0x06,sf); - /* 0x08: null */ - start_offset = read_u32be(offset + 0x0c,sf) + offset; /* size including padding up to start */ - - offset += base_size; - - total_subsongs = entries; - if (target_subsong == 0) target_subsong = 1; - if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; - - /* find stream header (entries can be variable-sized) */ - for (i = 0; i < entries; i++) { - size_t seek_size = read_u16be(offset + 0x0a,sf) * 0x04; - size_t entry_size = align_size_to_block(0x30 + seek_size, 0x10); - - if (i + 1 == target_subsong) - break; - offset += entry_size; - } - - /* parse target header (similar to xwav) */ - stream_size = read_u32be(offset + 0x00,sf); - /* 0x04: codec? (16=PS3, 03=X360) */ - codec = read_u8(offset + 0x06,sf); /* assumed */ - loop_flag = read_u8(offset + 0x07,sf); /* assumed */ - /* 0x08: bps? */ - channels = read_u8(offset + 0x09,sf); - seek_count = read_u16be(offset + 0x0a,sf); - num_samples = read_u32be(offset + 0x0c,sf); - sample_rate = read_u32be(offset + 0x10,sf); - loop_start = read_u32be(offset + 0x14,sf); - loop_end = read_u32be(offset + 0x18,sf); - /* 0x1c: ? */ - stream_offset = read_u32be(offset + 0x20,sf); /* within data */ - /* 0x24: ? */ - /* 0x26 seek entries */ - /* 0x28: ? */ - /* 0x2c: null? */ - - start_offset += stream_offset; - } - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channels, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_SDRH; - vgmstream->num_samples = num_samples; - vgmstream->sample_rate = sample_rate; - - vgmstream->stream_size = stream_size; - vgmstream->num_streams = total_subsongs; - - switch(codec) { - case 2: /* Mindjack (PS3) */ - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x10; - - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - - break; - -#ifdef VGM_USE_FFMPEG - case 1: { /* Mindjack (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; - - data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x10000; /* XWAV new default */ - block_count = seek_count; - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - - //todo fix loops/samples vs ATRAC3 - /* may be only applying end_skip to num_samples? */ - xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); - break; - } -#endif - - default: - goto fail; - } - - - if (!vgmstream_open_stream(vgmstream, sf, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} - - -/* SDRH - banks for older feelplus-related games [Lost Odyssey (X360)] */ -VGMSTREAM* init_vgmstream_xse_old(STREAMFILE* sf) { - VGMSTREAM* vgmstream = NULL; - off_t start_offset, data_size, stream_size; - int loop_flag = 0, channels, codec, sample_rate, seek_count; - int32_t num_samples, loop_start, loop_end; - off_t offset; - int total_subsongs, target_subsong = sf->stream_index; - - - /* checks */ - /* .xse: assumed */ - if (!check_extensions(sf, "xse")) - goto fail; - if (read_u32be(0x00,sf) != 0x53445248) /* "SDRH" */ - goto fail; - - /* similar to older version but LE and a bit more complex */ - /* 0x04: version/config? - * 0x08: data size - * 0x30: file name in some strange encoding/compression? - * others: ? (change in old/new) - */ - - /* parse section */ - { - int i; - int tables = read_u8(0x15,sf); - off_t base_size, stream_offset; - int entries; - - offset = 0x40; - /* read sections (FE=cues?, WV=mini-headers?, FT=?, FQ=?, XW=waves) */ - for (i = 0; i < tables; i++) { - uint16_t id = read_u16be(0x40 + 0x08 * i + 0x00,sf); - /* 0x02: null? */ - /* 0x04: offset from table start */ - if (id == 0x5857) { /* "XW" */ - offset += read_u32le(0x40 + 0x08 * i + 0x04,sf); - break; - } - } - - /* section header (other sections have a similar header) */ - /* 0x00: section size */ - base_size = read_u16le(offset + 0x04,sf); - /* 0x06: ? */ - entries = read_u16le(offset + 0x08,sf); - start_offset = read_u32le(offset + 0x0c,sf) + offset; /* size including padding up to start */ - - offset += base_size; - - total_subsongs = entries; - if (target_subsong == 0) target_subsong = 1; - if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; - - /* find stream header */ - stream_offset = 0; - for (i = 0; i < entries; i++) { - size_t data_size = read_u32le(offset + 0x00,sf) - 0x30; - size_t seek_size = 0; //read_u16be(offset + 0x0a,sf) * 0x04; /* not seen */ - size_t entry_size = align_size_to_block(0x30 + seek_size, 0x10); - - if (i + 1 == target_subsong) - break; - offset += entry_size; - stream_offset += data_size; /* no offset? */ - } - - /* parse target header (similar to xwav) */ - stream_size = read_u32le(offset + 0x00,sf) - 0x30; /* adds entry size */ - /* 0x04: codec? (16=PS3, 03=X360) */ - codec = read_u8(offset + 0x06,sf); /* assumed */ - /* 0x07: flag? */ - /* 0x08: bps? */ - /* 0x09: codec? */ - /* 0x0a: null */ - num_samples = read_u32le(offset + 0x0c,sf); - seek_count = read_u16le(offset + 0x10,sf); - sample_rate = read_u32le(offset + 0x14,sf); - loop_start = 0; //read_u32le(offset + 0x18,sf); /* ? */ - loop_end = 0; //read_u32le(offset + 0x1c,sf); /* ? */ - /* 0x20: null */ - /* 0x24: ? */ - /* 0x26: channel layout */ - channels = read_u8(offset + 0x27,sf); - /* 0x28: ? */ - /* 0x2c: null? */ - - loop_flag = loop_end > 0; - - start_offset += stream_offset; - } - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channels, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_SDRH; - vgmstream->num_samples = num_samples; - vgmstream->sample_rate = sample_rate; - - vgmstream->stream_size = stream_size; - vgmstream->num_streams = total_subsongs; - - switch(codec) { - -#ifdef VGM_USE_FFMPEG - case 4: { /* Lost Odyssey (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; - - data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x8000; /* XWAV old default */ - block_count = seek_count; - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - - xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, 0, 0, 1); - break; - } -#endif - - default: - goto fail; - } - - - if (!vgmstream_open_stream(vgmstream, sf, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xwav.c b/Frameworks/vgmstream/vgmstream/src/meta/xwav.c index d3a0c8e4f..1c54d5df6 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xwav.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xwav.c @@ -12,12 +12,13 @@ VGMSTREAM* init_vgmstream_xwav_new(STREAMFILE* sf) { /* checks */ + if (!is_id32le(0x00,sf, "XWAV")) + goto fail; + /* .xwv: actual extension [Moon Diver (PS3/X360)] * .vawx: header id */ if (!check_extensions(sf, "xwv,vawx")) goto fail; - if (read_u32be(0x00,sf) != 0x56415758) /* "VAWX" */ - goto fail; /* similar to older version but BE and a bit less complex */ /* 0x04: data size @@ -29,7 +30,7 @@ VGMSTREAM* init_vgmstream_xwav_new(STREAMFILE* sf) { * 0x16: file number * 0x18: null * 0x1c: null - * 0x20: file name in some strange encoding/compression? + * 0x20: file name in a custom 40-char (RADIX style) encoding */ start_offset = 0x800; @@ -71,15 +72,12 @@ VGMSTREAM* init_vgmstream_xwav_new(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 1: { /* No Nore Heroes (X360), Moon Diver (X360), Ninety-Nine Nights 2 (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x10000; /* XWAV new default */ + int block_count = read_u16be(0x30 + 0x0A, sf); /* also at 0x56 */ data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x10000; /* XWAV new default */ - block_count = read_u16be(0x30 + 0x0A, sf); /* also at 0x56 */ - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -136,10 +134,11 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) { /* checks */ - /* .xwv: actual extension [Bullet Witch (X360)] */ - if (!check_extensions(sf, "xwv")) + if (!is_id32be(0x00,sf, "XWAV")) goto fail; - if (read_u32be(0x00,sf) != 0x58574156) /* "XWAV" */ + + /* .xwv: actual extension [Bullet Witch (X360), Lost Odyssey Demo (X360)] */ + if (!check_extensions(sf, "xwv")) goto fail; /* similar to newer version but LE and a bit more complex */ @@ -224,15 +223,12 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 4: { /* Lost Odyssey (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x8000; /* XWAV old default */ + int block_count = read_u16be(0x30, sf); data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x8000; /* XWAV old default */ - block_count = read_u16be(0x30, sf); - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -253,7 +249,6 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xwb.c b/Frameworks/vgmstream/vgmstream/src/meta/xwb.c index 233694d94..fe841e25f 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xwb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xwb.c @@ -484,11 +484,7 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case XMA1: { /* Kameo (X360), Table Tennis (X360) */ - uint8_t buf[0x100]; - int bytes; - - bytes = ffmpeg_make_riff_xma1(buf, sizeof(buf), vgmstream->num_samples, xwb.stream_size, vgmstream->channels, vgmstream->sample_rate, 0); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, xwb.stream_offset,xwb.stream_size); + vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, xwb.stream_offset, xwb.stream_size, vgmstream->channels, vgmstream->sample_rate, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -505,14 +501,9 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) { } case XMA2: { /* Blue Dragon (X360) */ - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size = 0x10000; /* XACT default */ - block_size = 0x10000; /* XACT default */ - block_count = xwb.stream_size / block_size + (xwb.stream_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, xwb.stream_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, xwb.stream_offset,xwb.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, xwb.stream_offset, xwb.stream_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -537,8 +528,7 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) { } case XWMA: { /* WMAudio2 (WMA v2): BlazBlue (X360), WMAudio3 (WMA Pro): Bullet Witch (PC) voices */ - uint8_t buf[0x100]; - int bytes, bps_index, block_align, block_index, avg_bps, wma_codec; + int bps_index, block_align, block_index, avg_bps, wma_codec; bps_index = (xwb.block_align >> 5); /* upper 3b bytes-per-second index (docs say 2b+6b but are wrong) */ block_index = (xwb.block_align) & 0x1F; /*lower 5b block alignment index */ @@ -549,8 +539,7 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) { block_align = wma_block_align_index[block_index]; wma_codec = xwb.bits_per_sample ? 0x162 : 0x161; /* 0=WMAudio2, 1=WMAudio3 */ - bytes = ffmpeg_make_riff_xwma(buf, sizeof(buf), wma_codec, xwb.stream_size, vgmstream->channels, vgmstream->sample_rate, avg_bps, block_align); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, xwb.stream_offset,xwb.stream_size); + vgmstream->codec_data = init_ffmpeg_xwma(sf, xwb.stream_offset, xwb.stream_size, wma_codec, vgmstream->channels, vgmstream->sample_rate, avg_bps, block_align); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xwc.c b/Frameworks/vgmstream/vgmstream/src/meta/xwc.c index 659cf4ee5..e3edffac2 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xwc.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xwc.c @@ -2,40 +2,40 @@ #include "../coding/coding.h" /* .XWC - Starbreeze games [Chronicles of Riddick: Assault on Dark Athena, Syndicate] */ -VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, extra_offset; - size_t data_size; - int loop_flag, channel_count, codec, num_samples; +VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset, extra_offset; + size_t data_size; + int loop_flag, channels, codec, num_samples; /* checks */ /* .xwc: extension of the bigfile, individual files don't have one */ - if ( !check_extensions(streamFile,"xwc")) + if (!check_extensions(sf,"xwc")) goto fail; /* version */ - if (read_32bitBE(0x00,streamFile) == 0x00030000 && - read_32bitBE(0x04,streamFile) == 0x00900000) { /* The Darkness */ - data_size = read_32bitLE(0x08, streamFile) + 0x1c; /* not including subheader */ - channel_count = read_32bitLE(0x0c, streamFile); + if (read_32bitBE(0x00,sf) == 0x00030000 && + read_32bitBE(0x04,sf) == 0x00900000) { /* The Darkness */ + data_size = read_32bitLE(0x08, sf) + 0x1c; /* not including subheader */ + channels = read_32bitLE(0x0c, sf); /* 0x10: num_samples */ /* 0x14: 0x8000? */ /* 0x18: null */ - codec = read_32bitBE(0x1c, streamFile); - num_samples = read_32bitLE(0x20, streamFile); + codec = read_32bitBE(0x1c, sf); + num_samples = read_32bitLE(0x20, sf); /* 0x24: config data >> 2? (0x00(1): channels; 0x01(2): ?, 0x03(2): sample_rate) */ extra_offset = 0x28; } - else if (read_32bitBE(0x00,streamFile) == 0x00040000 && - read_32bitBE(0x04,streamFile) == 0x00900000) { /* Riddick, Syndicate */ - data_size = read_32bitLE(0x08, streamFile) + 0x24; /* not including subheader */ - channel_count = read_32bitLE(0x0c, streamFile); + else if (read_32bitBE(0x00,sf) == 0x00040000 && + read_32bitBE(0x04,sf) == 0x00900000) { /* Riddick, Syndicate */ + data_size = read_32bitLE(0x08, sf) + 0x24; /* not including subheader */ + channels = read_32bitLE(0x0c, sf); /* 0x10: num_samples */ /* 0x14: 0x8000? */ - codec = read_32bitBE(0x24, streamFile); - num_samples = read_32bitLE(0x28, streamFile); + codec = read_32bitBE(0x24, sf); + num_samples = read_32bitLE(0x28, sf); /* 0x2c: config data >> 2? (0x00(1): channels; 0x01(2): ?, 0x03(2): sample_rate) */ /* 0x30+: codec dependant */ extra_offset = 0x30; @@ -48,7 +48,7 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) { /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channels,loop_flag); if (!vgmstream) goto fail; vgmstream->meta_type = meta_XWC; @@ -60,10 +60,10 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) { mpeg_custom_config cfg = {0}; start_offset = 0x800; - vgmstream->num_samples = read_32bitLE(extra_offset+0x00, streamFile); /* with encoder delay */ //todo improve - cfg.data_size = read_32bitLE(extra_offset+0x04, streamFile); /* without padding */ + vgmstream->num_samples = read_32bitLE(extra_offset+0x00, sf); /* with encoder delay */ //todo improve + cfg.data_size = read_32bitLE(extra_offset+0x04, sf); /* without padding */ - vgmstream->codec_data = init_mpeg_custom(streamFile, start_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, &cfg); + vgmstream->codec_data = init_mpeg_custom(sf, start_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, &cfg); if (!vgmstream->codec_data) goto fail; vgmstream->layout_type = layout_none; @@ -73,41 +73,41 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) { #endif #ifdef VGM_USE_FFMPEG case 0x584D4100: { /* "XMA\0" (X360) */ - uint8_t buf[0x100]; - int32_t bytes, seek_size, block_size, block_count, sample_rate, chunk_size; + uint32_t seek_size, chunk_size, chunk_offset; + int block_size, block_count, sample_rate; - seek_size = read_32bitLE(extra_offset + 0x00, streamFile); - chunk_size = read_32bitLE(extra_offset + 0x04 + seek_size, streamFile); + seek_size = read_32bitLE(extra_offset + 0x00, sf); + chunk_size = read_32bitLE(extra_offset + 0x04 + seek_size, sf); + chunk_offset = extra_offset + 0x04 + seek_size + 0x04; - start_offset = extra_offset+ 0x04 + seek_size + chunk_size + 0x08; + data_size = read_32bitLE(chunk_offset + chunk_size + 0x00, sf); + start_offset = chunk_offset + chunk_size + 0x04; start_offset += (start_offset % 0x800) ? 0x800 - (start_offset % 0x800) : 0; /* padded */ - data_size = data_size - start_offset; if (chunk_size == 0x34) { /* new XMA2 */ - sample_rate = read_32bitLE(extra_offset+0x04+seek_size+0x08, streamFile); - block_size = read_32bitLE(extra_offset+0x04+seek_size+0x20, streamFile); + sample_rate = read_32bitLE(extra_offset+0x04+seek_size+0x08, sf); + block_size = read_32bitLE(extra_offset+0x04+seek_size+0x20, sf); block_count = data_size / block_size; /* others: standard RIFF XMA2 fmt? */ } - else if (chunk_size == 0x2c) { /* old XMA2 */ - sample_rate = read_32bitBE(extra_offset+0x04+seek_size+0x10, streamFile); - block_size = read_32bitBE(extra_offset+0x04+seek_size+0x1c, streamFile); - block_count = read_32bitBE(extra_offset+0x04+seek_size+0x28, streamFile); + else if (chunk_size == 0x2c) { /* old XMA2 (not fully valid?) */ + sample_rate = read_32bitBE(extra_offset+0x04+seek_size+0x10, sf); + block_size = read_32bitBE(extra_offset+0x04+seek_size+0x1c, sf); + block_count = read_32bitBE(extra_offset+0x04+seek_size+0x28, sf); /* others: scrambled RIFF fmt BE values */ } else { goto fail; } - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + vgmstream->sample_rate = sample_rate; + + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - vgmstream->sample_rate = sample_rate; - - xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok, fix delay */ + xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* samples are ok, fix delay */ break; } #endif @@ -116,12 +116,13 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) { start_offset = 0x30; data_size = data_size - start_offset; - vgmstream->codec_data = init_ogg_vorbis(streamFile, start_offset, data_size, NULL); + vgmstream->sample_rate = read_32bitLE(start_offset + 0x28, sf); + + vgmstream->codec_data = init_ogg_vorbis(sf, start_offset, data_size, NULL); if ( !vgmstream->codec_data ) goto fail; vgmstream->coding_type = coding_OGG_VORBIS; vgmstream->layout_type = layout_none; - vgmstream->sample_rate = read_32bitLE(start_offset + 0x28, streamFile); break; } #endif @@ -130,10 +131,9 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) { } - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xwma_konami.c b/Frameworks/vgmstream/vgmstream/src/meta/xwma_konami.c index 3ed2ca6ba..f4b07103f 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xwma_konami.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xwma_konami.c @@ -4,30 +4,30 @@ /* MSFC - Konami (Armature?) variation [Metal Gear Solid 2 HD (X360), Metal Gear Solid 3 HD (X360)] */ -VGMSTREAM * init_vgmstream_xwma_konami(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_xwma_konami(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; - int loop_flag, channel_count, codec, sample_rate; + int loop_flag, channels, codec, sample_rate; size_t data_size; - STREAMFILE *temp_streamFile = NULL; + STREAMFILE *temp_sf = NULL; /* checks */ - if (!check_extensions(streamFile,"xwma")) + if (!is_id32be(0x00,sf, "XWMA")) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x58574D41) /* "XWMA" */ + if (!check_extensions(sf,"xwma")) goto fail; - codec = read_32bitBE(0x04,streamFile); - channel_count = read_32bitBE(0x08,streamFile); - sample_rate = read_32bitBE(0x0c,streamFile); - data_size = read_32bitBE(0x10,streamFile); /* data size without padding */ + codec = read_32bitBE(0x04,sf); + channels = read_32bitBE(0x08,sf); + sample_rate = read_32bitBE(0x0c,sf); + data_size = read_32bitBE(0x10,sf); /* data size without padding */ loop_flag = 0; start_offset = 0x20; /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); + vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; vgmstream->sample_rate = sample_rate; @@ -35,19 +35,15 @@ VGMSTREAM * init_vgmstream_xwma_konami(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG { - uint8_t buf[0x100]; - int bytes, avg_bps, block_align; - /* 0x10: related to size? */ - avg_bps = read_32bitBE(0x14, streamFile); - block_align = read_32bitBE(0x18, streamFile); + int avg_bps = read_32bitBE(0x14, sf); + int block_align = read_32bitBE(0x18, sf); /* data has padding (unrelated to KCEJ blocks) */ - temp_streamFile = setup_xwma_konami_streamfile(streamFile, start_offset, block_align); - if (!temp_streamFile) goto fail; + temp_sf = setup_xwma_konami_streamfile(sf, start_offset, block_align); + if (!temp_sf) goto fail; - bytes = ffmpeg_make_riff_xwma(buf,0x100, codec, data_size, channel_count, sample_rate, avg_bps, block_align); - vgmstream->codec_data = init_ffmpeg_header_offset(temp_streamFile, buf,bytes, 0x00,data_size); + vgmstream->codec_data = init_ffmpeg_xwma(temp_sf, 0x00, data_size, codec, channels, sample_rate, avg_bps, block_align); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -62,7 +58,7 @@ VGMSTREAM * init_vgmstream_xwma_konami(STREAMFILE *streamFile) { if (codec == 0x0161) - wma_get_samples(&msd, temp_streamFile, block_align, vgmstream->sample_rate,0x001F); + wma_get_samples(&msd, temp_sf, block_align, vgmstream->sample_rate,0x001F); //else //todo not correct // wmapro_get_samples(&msd, temp_streamFile, block_align, vgmstream->sample_rate,0x00E0); @@ -76,11 +72,10 @@ VGMSTREAM * init_vgmstream_xwma_konami(STREAMFILE *streamFile) { goto fail; #endif - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); return vgmstream; - fail: - close_streamfile(temp_streamFile); + close_streamfile(temp_sf); close_vgmstream(vgmstream); return NULL; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xmv_valve.c b/Frameworks/vgmstream/vgmstream/src/meta/xwv_valve.c similarity index 85% rename from Frameworks/vgmstream/vgmstream/src/meta/xmv_valve.c rename to Frameworks/vgmstream/vgmstream/src/meta/xwv_valve.c index f8fbdf205..eca6dc23a 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xmv_valve.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xwv_valve.c @@ -10,17 +10,16 @@ VGMSTREAM* init_vgmstream_xbox_hlwav(STREAMFILE* sf) { int loop_flag; /* checks */ - if (!check_extensions(sf, "wav,lwav")) - goto fail; - - /* check header and size */ header_size = read_u32le(0x00, sf); if (header_size != 0x14) goto fail; data_size = read_u32le(0x04, sf); start_offset = read_u32le(0x08, sf); - if (data_size != get_streamfile_size(sf) - start_offset) + if (start_offset + data_size != get_streamfile_size(sf)) + goto fail; + + if (!check_extensions(sf, "wav,lwav")) goto fail; loop_start = read_s32le(0x0c, sf); @@ -76,9 +75,9 @@ fail: return NULL; } -/* .360.WAV, .PS3.WAV - from Valve games running on Source Engine, evolution of Xbox .WAV format seen above */ -/* [The Orange Box (X360), Portal 2 (PS3/X360), Counter-Strike: Global Offensive (PS3/X360)] */ -VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { +/* XWV - from Valve games running on Source Engine, evolution of Xbox .WAV format seen above + * [The Orange Box (X360), Portal 2 (PS3/X360), Counter-Strike: Global Offensive (PS3/X360)] */ +VGMSTREAM* init_vgmstream_xwv_valve(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; int32_t loop_start; uint32_t start_offset, data_size, sample_rate, num_samples; @@ -87,15 +86,15 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { int loop_flag; /* checks */ - if (!is_id32be(0x00, sf, "XMV ")) + if (!is_id32be(0x00, sf, "XWV ")) + goto fail; + if (read_u32be(0x04, sf) != 0x04) /* only version 4 is known */ goto fail; + /* technically .360.wav, .ps3.wav */ if (!check_extensions(sf, "wav,lwav")) goto fail; - /* only version 4 is known */ - if (read_u32be(0x04, sf) != 0x04) - goto fail; start_offset = read_u32be(0x10, sf); data_size = read_u32be(0x14, sf); @@ -127,7 +126,7 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; - vgmstream->meta_type = meta_XMV_VALVE; + vgmstream->meta_type = meta_XWV_VALVE; vgmstream->sample_rate = sample_rate; vgmstream->num_samples = num_samples; vgmstream->loop_start_sample = loop_start; @@ -139,27 +138,23 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x02; break; + #ifdef VGM_USE_FFMPEG case 0x01: { /* XMA */ - uint8_t buf[0x100]; - int block_count, block_size; - size_t bytes; + int block_size = 0x800; - block_size = 0x800; - block_count = data_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, num_samples, data_size, channels, sample_rate, block_count, block_size); - - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, start_offset, data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, num_samples, channels, sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; + vgmstream->loop_end_sample -= loop_end_skip; xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, 0, 1, 1); break; } #endif + #ifdef VGM_USE_MPEG case 0x03: { /* MP3 */ coding_t mpeg_coding; diff --git a/Frameworks/vgmstream/vgmstream/src/render.c b/Frameworks/vgmstream/vgmstream/src/render.c index 6233ec844..06e9af443 100644 --- a/Frameworks/vgmstream/vgmstream/src/render.c +++ b/Frameworks/vgmstream/vgmstream/src/render.c @@ -286,7 +286,6 @@ int render_layout(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) { case layout_blocked_ea_swvr: case layout_blocked_adm: case layout_blocked_bdsp: - case layout_blocked_tra: case layout_blocked_ps2_iab: case layout_blocked_vs_str: case layout_blocked_rws: diff --git a/Frameworks/vgmstream/vgmstream/src/stack_alloc.h b/Frameworks/vgmstream/vgmstream/src/stack_alloc.h deleted file mode 100644 index 17c85383c..000000000 --- a/Frameworks/vgmstream/vgmstream/src/stack_alloc.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 2002-2003 Jean-Marc Valin - Copyright (C) 2007-2009 Xiph.Org Foundation */ -/** - @file stack_alloc.h - @brief Temporary memory allocation on stack - */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef STACK_ALLOC_H -#define STACK_ALLOC_H - -#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA)) -#error "Vgmstream requires one of VAR_ARRAYS or USE_ALLOCA be defined to select the temporary allocation mode." -#endif - -#ifdef USE_ALLOCA -# ifdef WIN32 -# include -# else -# ifdef HAVE_ALLOCA_H -# include -# else -# include -# endif -# endif -#endif - -/** - * @def ALIGN(stack, size) - * - * Aligns the stack to a 'size' boundary - * - * @param stack Stack - * @param size New size boundary - */ - -/** - * @def PUSH(stack, size, type) - * - * Allocates 'size' elements of type 'type' on the stack - * - * @param stack Stack - * @param size Number of elements - * @param type Type of element - */ - -/** - * @def VARDECL(var) - * - * Declare variable on stack - * - * @param var Variable to declare - */ - -/** - * @def ALLOC(var, size, type) - * - * Allocate 'size' elements of 'type' on stack - * - * @param var Name of variable to allocate - * @param size Number of elements - * @param type Type of element - */ - -#if defined(VAR_ARRAYS) - -#define VARDECL(type, var) -#define ALLOC(var, size, type) type var[size] -#define SAVE_STACK -#define RESTORE_STACK -#define ALLOC_STACK - -#elif defined(USE_ALLOCA) - -#define VARDECL(type, var) type *var - -# ifdef WIN32 -# define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) -# else -# define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) -# endif - -#define SAVE_STACK -#define RESTORE_STACK -#define ALLOC_STACK - -#endif /* VAR_ARRAYS */ - -#endif /* STACK_ALLOC_H */ diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_bitreader.h b/Frameworks/vgmstream/vgmstream/src/util/bitstream_msb.h similarity index 57% rename from Frameworks/vgmstream/vgmstream/src/coding/mpeg_bitreader.h rename to Frameworks/vgmstream/vgmstream/src/util/bitstream_msb.h index 345f8aba4..77fd0f078 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_bitreader.h +++ b/Frameworks/vgmstream/vgmstream/src/util/bitstream_msb.h @@ -1,29 +1,70 @@ -#ifndef _MPEG_BITREADER_H -#define _MPEG_BITREADER_H +#ifndef _BITSTREAM_MSB_H +#define _BITSTREAM_MSB_H + +#include /* Simple bitreader for MPEG/standard bit format. - * Kept in .h since it's slightly faster (compiler can optimize statics better) */ - + * Kept in .h since it's slightly faster (compiler can optimize better) */ typedef struct { uint8_t* buf; /* buffer to read/write */ - size_t bufsize; /* max size of the buffer */ - uint32_t b_off; /* current offset in bits inside the buffer */ + size_t bufsize; /* max size */ + size_t b_max; /* max size in bits */ + uint32_t b_off; /* current offset in bits inside buffer */ } bitstream_t; -/* convenience util */ -static void init_bitstream(bitstream_t* b, uint8_t* buf, size_t bufsize) { - b->buf = buf; - b->bufsize = bufsize; - b->b_off = 0; + +static inline void bm_setup(bitstream_t* bs, uint8_t* buf, size_t bufsize) { + bs->buf = buf; + bs->bufsize = bufsize; + bs->b_max = bufsize * 8; + bs->b_off = 0; } -/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSF). */ -static int rb_bits(bitstream_t* ib, uint32_t bits, uint32_t* value) { +static inline int bm_set(bitstream_t* bs, uint32_t b_off) { + if (bs->b_off > bs->b_max) + goto fail; + + bs->b_off = b_off; + + return 1; +fail: + return 0; +} + +static inline int bm_fill(bitstream_t* bs, uint32_t bytes) { + if (bs->b_off > bs->b_max) + goto fail; + + bs->bufsize += bytes; + bs->b_max += bytes * 8; + + return 1; +fail: + return 0; +} + +static inline int bm_skip(bitstream_t* bs, uint32_t bits) { + if (bs->b_off + bits > bs->b_max) + goto fail; + + bs->b_off += bits; + + return 1; +fail: + return 0; +} + +static inline int bm_pos(bitstream_t* bs) { + return bs->b_off; +} + +/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSB). */ +static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) { uint32_t shift, pos, val; int i, bit_buf, bit_val; - if (bits > 32 || ib->b_off + bits > ib->bufsize * 8) + if (bits > 32 || ib->b_off + bits > ib->b_max) goto fail; pos = ib->b_off / 8; /* byte offset */ @@ -48,18 +89,17 @@ static int rb_bits(bitstream_t* ib, uint32_t bits, uint32_t* value) { ib->b_off += bits; return 1; fail: - VGM_LOG("BITREADER: read fail\n"); + //VGM_LOG("BITREADER: read fail\n"); *value = 0; return 0; } -#ifndef BITSTREAM_READ_ONLY -/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSF). */ -static int wb_bits(bitstream_t* ob, uint32_t bits, uint32_t value) { +/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSB). */ +static inline int bm_put(bitstream_t* ob, uint32_t bits, uint32_t value) { uint32_t shift, pos; int i, bit_val, bit_buf; - if (bits > 32 || ob->b_off + bits > ob->bufsize * 8) + if (bits > 32 || ob->b_off + bits > ob->b_max) goto fail; pos = ob->b_off / 8; /* byte offset */ @@ -86,6 +126,5 @@ static int wb_bits(bitstream_t* ob, uint32_t bits, uint32_t value) { fail: return 0; } -#endif #endif diff --git a/Frameworks/vgmstream/vgmstream/src/util/cri_keys.c b/Frameworks/vgmstream/vgmstream/src/util/cri_keys.c new file mode 100644 index 000000000..dbce900f2 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/util/cri_keys.c @@ -0,0 +1,139 @@ +#include "cri_keys.h" +#include + + +/* preloaded list used to derive keystrings from ADX_Decoder, found in executables (see VGAudio for how to calculate) */ +static const uint16_t key8_primes[0x400] = { + 0x401B,0x4021,0x4025,0x402B,0x4031,0x403F,0x4043,0x4045,0x405D,0x4061,0x4067,0x406D,0x4087,0x4091,0x40A3,0x40A9, + 0x40B1,0x40B7,0x40BD,0x40DB,0x40DF,0x40EB,0x40F7,0x40F9,0x4109,0x410B,0x4111,0x4115,0x4121,0x4133,0x4135,0x413B, + 0x413F,0x4159,0x4165,0x416B,0x4177,0x417B,0x4193,0x41AB,0x41B7,0x41BD,0x41BF,0x41CB,0x41E7,0x41EF,0x41F3,0x41F9, + 0x4205,0x4207,0x4219,0x421F,0x4223,0x4229,0x422F,0x4243,0x4253,0x4255,0x425B,0x4261,0x4273,0x427D,0x4283,0x4285, + 0x4289,0x4291,0x4297,0x429D,0x42B5,0x42C5,0x42CB,0x42D3,0x42DD,0x42E3,0x42F1,0x4307,0x430F,0x431F,0x4325,0x4327, + 0x4333,0x4337,0x4339,0x434F,0x4357,0x4369,0x438B,0x438D,0x4393,0x43A5,0x43A9,0x43AF,0x43B5,0x43BD,0x43C7,0x43CF, + 0x43E1,0x43E7,0x43EB,0x43ED,0x43F1,0x43F9,0x4409,0x440B,0x4417,0x4423,0x4429,0x443B,0x443F,0x4445,0x444B,0x4451, + 0x4453,0x4459,0x4465,0x446F,0x4483,0x448F,0x44A1,0x44A5,0x44AB,0x44AD,0x44BD,0x44BF,0x44C9,0x44D7,0x44DB,0x44F9, + 0x44FB,0x4505,0x4511,0x4513,0x452B,0x4531,0x4541,0x4549,0x4553,0x4555,0x4561,0x4577,0x457D,0x457F,0x458F,0x45A3, + 0x45AD,0x45AF,0x45BB,0x45C7,0x45D9,0x45E3,0x45EF,0x45F5,0x45F7,0x4601,0x4603,0x4609,0x4613,0x4625,0x4627,0x4633, + 0x4639,0x463D,0x4643,0x4645,0x465D,0x4679,0x467B,0x467F,0x4681,0x468B,0x468D,0x469D,0x46A9,0x46B1,0x46C7,0x46C9, + 0x46CF,0x46D3,0x46D5,0x46DF,0x46E5,0x46F9,0x4705,0x470F,0x4717,0x4723,0x4729,0x472F,0x4735,0x4739,0x474B,0x474D, + 0x4751,0x475D,0x476F,0x4771,0x477D,0x4783,0x4787,0x4789,0x4799,0x47A5,0x47B1,0x47BF,0x47C3,0x47CB,0x47DD,0x47E1, + 0x47ED,0x47FB,0x4801,0x4807,0x480B,0x4813,0x4819,0x481D,0x4831,0x483D,0x4847,0x4855,0x4859,0x485B,0x486B,0x486D, + 0x4879,0x4897,0x489B,0x48A1,0x48B9,0x48CD,0x48E5,0x48EF,0x48F7,0x4903,0x490D,0x4919,0x491F,0x492B,0x4937,0x493D, + 0x4945,0x4955,0x4963,0x4969,0x496D,0x4973,0x4997,0x49AB,0x49B5,0x49D3,0x49DF,0x49E1,0x49E5,0x49E7,0x4A03,0x4A0F, + 0x4A1D,0x4A23,0x4A39,0x4A41,0x4A45,0x4A57,0x4A5D,0x4A6B,0x4A7D,0x4A81,0x4A87,0x4A89,0x4A8F,0x4AB1,0x4AC3,0x4AC5, + 0x4AD5,0x4ADB,0x4AED,0x4AEF,0x4B07,0x4B0B,0x4B0D,0x4B13,0x4B1F,0x4B25,0x4B31,0x4B3B,0x4B43,0x4B49,0x4B59,0x4B65, + 0x4B6D,0x4B77,0x4B85,0x4BAD,0x4BB3,0x4BB5,0x4BBB,0x4BBF,0x4BCB,0x4BD9,0x4BDD,0x4BDF,0x4BE3,0x4BE5,0x4BE9,0x4BF1, + 0x4BF7,0x4C01,0x4C07,0x4C0D,0x4C0F,0x4C15,0x4C1B,0x4C21,0x4C2D,0x4C33,0x4C4B,0x4C55,0x4C57,0x4C61,0x4C67,0x4C73, + 0x4C79,0x4C7F,0x4C8D,0x4C93,0x4C99,0x4CCD,0x4CE1,0x4CE7,0x4CF1,0x4CF3,0x4CFD,0x4D05,0x4D0F,0x4D1B,0x4D27,0x4D29, + 0x4D2F,0x4D33,0x4D41,0x4D51,0x4D59,0x4D65,0x4D6B,0x4D81,0x4D83,0x4D8D,0x4D95,0x4D9B,0x4DB1,0x4DB3,0x4DC9,0x4DCF, + 0x4DD7,0x4DE1,0x4DED,0x4DF9,0x4DFB,0x4E05,0x4E0B,0x4E17,0x4E19,0x4E1D,0x4E2B,0x4E35,0x4E37,0x4E3D,0x4E4F,0x4E53, + 0x4E5F,0x4E67,0x4E79,0x4E85,0x4E8B,0x4E91,0x4E95,0x4E9B,0x4EA1,0x4EAF,0x4EB3,0x4EB5,0x4EC1,0x4ECD,0x4ED1,0x4ED7, + 0x4EE9,0x4EFB,0x4F07,0x4F09,0x4F19,0x4F25,0x4F2D,0x4F3F,0x4F49,0x4F63,0x4F67,0x4F6D,0x4F75,0x4F7B,0x4F81,0x4F85, + 0x4F87,0x4F91,0x4FA5,0x4FA9,0x4FAF,0x4FB7,0x4FBB,0x4FCF,0x4FD9,0x4FDB,0x4FFD,0x4FFF,0x5003,0x501B,0x501D,0x5029, + 0x5035,0x503F,0x5045,0x5047,0x5053,0x5071,0x5077,0x5083,0x5093,0x509F,0x50A1,0x50B7,0x50C9,0x50D5,0x50E3,0x50ED, + 0x50EF,0x50FB,0x5107,0x510B,0x510D,0x5111,0x5117,0x5123,0x5125,0x5135,0x5147,0x5149,0x5171,0x5179,0x5189,0x518F, + 0x5197,0x51A1,0x51A3,0x51A7,0x51B9,0x51C1,0x51CB,0x51D3,0x51DF,0x51E3,0x51F5,0x51F7,0x5209,0x5213,0x5215,0x5219, + 0x521B,0x521F,0x5227,0x5243,0x5245,0x524B,0x5261,0x526D,0x5273,0x5281,0x5293,0x5297,0x529D,0x52A5,0x52AB,0x52B1, + 0x52BB,0x52C3,0x52C7,0x52C9,0x52DB,0x52E5,0x52EB,0x52FF,0x5315,0x531D,0x5323,0x5341,0x5345,0x5347,0x534B,0x535D, + 0x5363,0x5381,0x5383,0x5387,0x538F,0x5395,0x5399,0x539F,0x53AB,0x53B9,0x53DB,0x53E9,0x53EF,0x53F3,0x53F5,0x53FB, + 0x53FF,0x540D,0x5411,0x5413,0x5419,0x5435,0x5437,0x543B,0x5441,0x5449,0x5453,0x5455,0x545F,0x5461,0x546B,0x546D, + 0x5471,0x548F,0x5491,0x549D,0x54A9,0x54B3,0x54C5,0x54D1,0x54DF,0x54E9,0x54EB,0x54F7,0x54FD,0x5507,0x550D,0x551B, + 0x5527,0x552B,0x5539,0x553D,0x554F,0x5551,0x555B,0x5563,0x5567,0x556F,0x5579,0x5585,0x5597,0x55A9,0x55B1,0x55B7, + 0x55C9,0x55D9,0x55E7,0x55ED,0x55F3,0x55FD,0x560B,0x560F,0x5615,0x5617,0x5623,0x562F,0x5633,0x5639,0x563F,0x564B, + 0x564D,0x565D,0x565F,0x566B,0x5671,0x5675,0x5683,0x5689,0x568D,0x568F,0x569B,0x56AD,0x56B1,0x56D5,0x56E7,0x56F3, + 0x56FF,0x5701,0x5705,0x5707,0x570B,0x5713,0x571F,0x5723,0x5747,0x574D,0x575F,0x5761,0x576D,0x5777,0x577D,0x5789, + 0x57A1,0x57A9,0x57AF,0x57B5,0x57C5,0x57D1,0x57D3,0x57E5,0x57EF,0x5803,0x580D,0x580F,0x5815,0x5827,0x582B,0x582D, + 0x5855,0x585B,0x585D,0x586D,0x586F,0x5873,0x587B,0x588D,0x5897,0x58A3,0x58A9,0x58AB,0x58B5,0x58BD,0x58C1,0x58C7, + 0x58D3,0x58D5,0x58DF,0x58F1,0x58F9,0x58FF,0x5903,0x5917,0x591B,0x5921,0x5945,0x594B,0x594D,0x5957,0x595D,0x5975, + 0x597B,0x5989,0x5999,0x599F,0x59B1,0x59B3,0x59BD,0x59D1,0x59DB,0x59E3,0x59E9,0x59ED,0x59F3,0x59F5,0x59FF,0x5A01, + 0x5A0D,0x5A11,0x5A13,0x5A17,0x5A1F,0x5A29,0x5A2F,0x5A3B,0x5A4D,0x5A5B,0x5A67,0x5A77,0x5A7F,0x5A85,0x5A95,0x5A9D, + 0x5AA1,0x5AA3,0x5AA9,0x5ABB,0x5AD3,0x5AE5,0x5AEF,0x5AFB,0x5AFD,0x5B01,0x5B0F,0x5B19,0x5B1F,0x5B25,0x5B2B,0x5B3D, + 0x5B49,0x5B4B,0x5B67,0x5B79,0x5B87,0x5B97,0x5BA3,0x5BB1,0x5BC9,0x5BD5,0x5BEB,0x5BF1,0x5BF3,0x5BFD,0x5C05,0x5C09, + 0x5C0B,0x5C0F,0x5C1D,0x5C29,0x5C2F,0x5C33,0x5C39,0x5C47,0x5C4B,0x5C4D,0x5C51,0x5C6F,0x5C75,0x5C77,0x5C7D,0x5C87, + 0x5C89,0x5CA7,0x5CBD,0x5CBF,0x5CC3,0x5CC9,0x5CD1,0x5CD7,0x5CDD,0x5CED,0x5CF9,0x5D05,0x5D0B,0x5D13,0x5D17,0x5D19, + 0x5D31,0x5D3D,0x5D41,0x5D47,0x5D4F,0x5D55,0x5D5B,0x5D65,0x5D67,0x5D6D,0x5D79,0x5D95,0x5DA3,0x5DA9,0x5DAD,0x5DB9, + 0x5DC1,0x5DC7,0x5DD3,0x5DD7,0x5DDD,0x5DEB,0x5DF1,0x5DFD,0x5E07,0x5E0D,0x5E13,0x5E1B,0x5E21,0x5E27,0x5E2B,0x5E2D, + 0x5E31,0x5E39,0x5E45,0x5E49,0x5E57,0x5E69,0x5E73,0x5E75,0x5E85,0x5E8B,0x5E9F,0x5EA5,0x5EAF,0x5EB7,0x5EBB,0x5ED9, + 0x5EFD,0x5F09,0x5F11,0x5F27,0x5F33,0x5F35,0x5F3B,0x5F47,0x5F57,0x5F5D,0x5F63,0x5F65,0x5F77,0x5F7B,0x5F95,0x5F99, + 0x5FA1,0x5FB3,0x5FBD,0x5FC5,0x5FCF,0x5FD5,0x5FE3,0x5FE7,0x5FFB,0x6011,0x6023,0x602F,0x6037,0x6053,0x605F,0x6065, + 0x606B,0x6073,0x6079,0x6085,0x609D,0x60AD,0x60BB,0x60BF,0x60CD,0x60D9,0x60DF,0x60E9,0x60F5,0x6109,0x610F,0x6113, + 0x611B,0x612D,0x6139,0x614B,0x6155,0x6157,0x615B,0x616F,0x6179,0x6187,0x618B,0x6191,0x6193,0x619D,0x61B5,0x61C7, + 0x61C9,0x61CD,0x61E1,0x61F1,0x61FF,0x6209,0x6217,0x621D,0x6221,0x6227,0x623B,0x6241,0x624B,0x6251,0x6253,0x625F, + 0x6265,0x6283,0x628D,0x6295,0x629B,0x629F,0x62A5,0x62AD,0x62D5,0x62D7,0x62DB,0x62DD,0x62E9,0x62FB,0x62FF,0x6305, + 0x630D,0x6317,0x631D,0x632F,0x6341,0x6343,0x634F,0x635F,0x6367,0x636D,0x6371,0x6377,0x637D,0x637F,0x63B3,0x63C1, + 0x63C5,0x63D9,0x63E9,0x63EB,0x63EF,0x63F5,0x6401,0x6403,0x6409,0x6415,0x6421,0x6427,0x642B,0x6439,0x6443,0x6449, + 0x644F,0x645D,0x6467,0x6475,0x6485,0x648D,0x6493,0x649F,0x64A3,0x64AB,0x64C1,0x64C7,0x64C9,0x64DB,0x64F1,0x64F7, + 0x64F9,0x650B,0x6511,0x6521,0x652F,0x6539,0x653F,0x654B,0x654D,0x6553,0x6557,0x655F,0x6571,0x657D,0x658D,0x658F, + 0x6593,0x65A1,0x65A5,0x65AD,0x65B9,0x65C5,0x65E3,0x65F3,0x65FB,0x65FF,0x6601,0x6607,0x661D,0x6629,0x6631,0x663B, + 0x6641,0x6647,0x664D,0x665B,0x6661,0x6673,0x667D,0x6689,0x668B,0x6695,0x6697,0x669B,0x66B5,0x66B9,0x66C5,0x66CD, + 0x66D1,0x66E3,0x66EB,0x66F5,0x6703,0x6713,0x6719,0x671F,0x6727,0x6731,0x6737,0x673F,0x6745,0x6751,0x675B,0x676F, + 0x6779,0x6781,0x6785,0x6791,0x67AB,0x67BD,0x67C1,0x67CD,0x67DF,0x67E5,0x6803,0x6809,0x6811,0x6817,0x682D,0x6839, +}; + +void cri_key8_derive(const char* key8, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3) { + size_t key_size; + uint16_t key1 = 0, key2 = 0, key3 = 0; + int i; + + if (key8 == NULL || key8[0] == '\0') /* strlen >= 1 */ + goto end; + + /* calcs as found in exes, though there is some unrolling in the original code */ + key_size = strlen(key8); + key1 = key8_primes[0x100]; + key2 = key8_primes[0x200]; + key3 = key8_primes[0x300]; + + for (i = 0; i < key_size; i++) { + char c = key8[i]; + key1 = key8_primes[key1 * key8_primes[c + 0x80] % 0x400]; + key2 = key8_primes[key2 * key8_primes[c + 0x80] % 0x400]; + key3 = key8_primes[key3 * key8_primes[c + 0x80] % 0x400]; + } + +end: + *p_key1 = key1; + *p_key2 = key2; + *p_key3 = key3; +} + + +void cri_key9_derive(uint64_t key9, uint16_t subkey, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3) { + uint16_t key1 = 0, key2 = 0, key3 = 0; + + /* 0 is ignored by CRI's encoder, only from 1..18446744073709551615 */ + if (key9 == 0) + goto end; + + if (subkey) { + key9 = key9 * ( ((uint64_t)subkey << 16u) | ((uint16_t)~subkey + 2u) ); + } + + key9--; + key1 = (int)(((key9 >> 27) & 0x7fff)); + key2 = (int)(((key9 >> 12) & 0x7ffc) | 1); + key3 = (int)(((key9 << 1 ) & 0x7fff) | 1); + + /* alt from ADX_Decoder, probably the same */ + //key1 = ((key9 >> 27) & 0x7FFF); + //key2 = ((key9 >> 12) & 0x7FFC) | 1; + //key3 = ((key9 << 1 ) & 0x7FFE) | 1; + //key2 |= key3 << 16; + +end: + *p_key1 = key1; + *p_key2 = key2; + *p_key3 = key3; +} + +int cri_key8_valid_keystring(uint8_t* buf, int buf_size) { + int i; + + for (i = 0; i < buf_size; i++) { + if (buf[i] < 0x20 || buf[i] > 0x8f) { /* allow 0x8x for (uncommon) cases of SHIFT-JIS */ + return 0; + } + } + + return 1; +} diff --git a/Frameworks/vgmstream/vgmstream/src/util/cri_keys.h b/Frameworks/vgmstream/vgmstream/src/util/cri_keys.h new file mode 100644 index 000000000..7748b9d16 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/util/cri_keys.h @@ -0,0 +1,13 @@ +#ifndef _CRI_KEYS_H_ +#define _CRI_KEYS_H_ + +#include + +/* common CRI key helpers */ + +void cri_key8_derive(const char* key8, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3); +void cri_key9_derive(uint64_t key9, uint16_t subkey, uint16_t* p_key1, uint16_t* p_key2, uint16_t* p_key3); + +int cri_key8_valid_keystring(uint8_t* buf, int buf_size); + +#endif /* _CRI_KEYS_H_ */ diff --git a/Frameworks/vgmstream/vgmstream/src/util/m2_psb.c b/Frameworks/vgmstream/vgmstream/src/util/m2_psb.c index 26ca69607..d38dcd774 100644 --- a/Frameworks/vgmstream/vgmstream/src/util/m2_psb.c +++ b/Frameworks/vgmstream/vgmstream/src/util/m2_psb.c @@ -15,7 +15,7 @@ * 21 // object: root (x2 listN + other data) * 0D 04 0D 06,0B,0D,0E // list8[4]: key indexes (#0 "id", #1 "spec", #2 "version", #3 "voice"; found in a separate "key names" table) * 0D 04 0D 00,02,04,09 // list8[4]: byte offsets of next 4 items - * 15 02 // #0 string8: string key #2 ("pc") + * 15 02 // #0 string8: string key #2 ("pc") * 1E 5C8F823F // #1 float32: 1.02 * 05 02 // #2 int8: 2 * 21 // #3 object diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream.c b/Frameworks/vgmstream/vgmstream/src/vgmstream.c index 3121e0a41..c4478df0b 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream.c +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream.c @@ -38,7 +38,6 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_gcsw, init_vgmstream_ads, init_vgmstream_nps, - init_vgmstream_rwsd, init_vgmstream_xa, init_vgmstream_rxws, init_vgmstream_ngc_dsp_stm, @@ -134,7 +133,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_ngc_pdt, init_vgmstream_wii_mus, init_vgmstream_dc_asd, - init_vgmstream_naomi_spsd, + init_vgmstream_spsd, init_vgmstream_rsd, init_vgmstream_bgw, init_vgmstream_spw, @@ -231,7 +230,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_dsp_dspw, init_vgmstream_jstm, init_vgmstream_xvag, - init_vgmstream_ps3_cps, + init_vgmstream_cps, init_vgmstream_sqex_scd, init_vgmstream_ngc_nst_dsp, init_vgmstream_baf, @@ -240,7 +239,6 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_sgxd, init_vgmstream_wii_ras, init_vgmstream_spm, - init_vgmstream_x360_tra, init_vgmstream_ps2_iab, init_vgmstream_vs_str, init_vgmstream_lsf_n1nj4n, @@ -280,7 +278,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_hca, init_vgmstream_svag_snk, init_vgmstream_ps2_vds_vdm, - init_vgmstream_x360_cxs, + init_vgmstream_cxs, init_vgmstream_dsp_adx, init_vgmstream_akb, init_vgmstream_akb2, @@ -288,16 +286,16 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_mp4_aac_ffmpeg, #endif init_vgmstream_bik, - init_vgmstream_x360_ast, + init_vgmstream_astb, init_vgmstream_wwise, init_vgmstream_ubi_raki, - init_vgmstream_x360_pasx, + init_vgmstream_pasx, init_vgmstream_xma, init_vgmstream_sxd, init_vgmstream_ogl, init_vgmstream_mc3, - init_vgmstream_gtd, - init_vgmstream_ta_aac, + init_vgmstream_ghs, + init_vgmstream_aac_triace, init_vgmstream_va3, init_vgmstream_mta2, init_vgmstream_mta2_container, @@ -455,7 +453,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_nub_xma, init_vgmstream_nub_idsp, init_vgmstream_nub_is14, - init_vgmstream_xmv_valve, + init_vgmstream_xwv_valve, init_vgmstream_ubi_hx, init_vgmstream_bmp_konami, init_vgmstream_opus_opusnx, @@ -481,8 +479,8 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_zwv, init_vgmstream_dsb, init_vgmstream_bsf, - init_vgmstream_xse_new, - init_vgmstream_xse_old, + init_vgmstream_sdrh_new, + init_vgmstream_sdrh_old, init_vgmstream_wady, init_vgmstream_dsp_sqex, init_vgmstream_dsp_wiivoice, @@ -526,6 +524,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_vab, init_vgmstream_bigrp, init_vgmstream_sscf_encrypted, + init_vgmstream_s_p_sth, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_scd_pcm, @@ -542,10 +541,10 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ - init_vgmstream_dtk, + init_vgmstream_dtk, /* semi-raw GC streamed files */ init_vgmstream_mpeg, /* semi-raw MP3 */ - init_vgmstream_encrypted, /* encrypted stuff */ init_vgmstream_btsnd, /* semi-headerless */ + init_vgmstream_encrypted, /* encrypted stuff */ init_vgmstream_raw_int, /* .int raw PCM */ init_vgmstream_ps_headerless, /* tries to detect a bunch of PS-ADPCM formats */ init_vgmstream_raw_snds, /* .snds raw SNDS IMA */ @@ -556,10 +555,8 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_ngc_ulw, /* .ulw raw u-Law */ init_vgmstream_exakt_sc, /* .sc raw PCM */ init_vgmstream_zwdsp, /* fake format */ - init_vgmstream_ps2_ccc, /* fake format, to be removed */ init_vgmstream_ps2_adm, /* weird non-constant PSX blocks */ - init_vgmstream_baf_badrip, /* crap, to be removed */ - init_vgmstream_rxws_badrip, /* crap, to be removed */ + init_vgmstream_rwsd, /* crap, to be removed */ #ifdef VGM_USE_FFMPEG init_vgmstream_ffmpeg, /* may play anything incorrectly, since FFmpeg doesn't check extensions */ #endif diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream.h b/Frameworks/vgmstream/vgmstream/src/vgmstream.h index 3d155e154..8261504a6 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream.h +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream.h @@ -35,7 +35,6 @@ enum { //#define VGM_USE_G719 //#define VGM_USE_MP4V2 //#define VGM_USE_FDKAAC -//#define VGM_USE_MAIATRAC3PLUS //#define VGM_USE_FFMPEG //#define VGM_USE_ATRAC9 //#define VGM_USE_CELT @@ -80,7 +79,8 @@ typedef enum { coding_ALAW, /* 8-bit a-Law (non-linear PCM) */ coding_PCMFLOAT, /* 32-bit float PCM */ - coding_PCM24LE, /* 24-bit PCM */ + coding_PCM24LE, /* little endian 24-bit PCM */ + coding_PCM24BE, /* big endian 24-bit PCM */ /* ADPCM */ coding_CRI_ADX, /* CRI ADX */ @@ -222,10 +222,6 @@ typedef enum { coding_MP4_AAC, /* AAC (MDCT-based) */ #endif -#ifdef VGM_USE_MAIATRAC3PLUS - coding_AT3plus, /* Sony ATRAC3plus (MDCT-based) */ -#endif - #ifdef VGM_USE_ATRAC9 coding_ATRAC9, /* Sony ATRAC9 (MDCT-based) */ #endif @@ -274,7 +270,6 @@ typedef enum { layout_blocked_bdsp, layout_blocked_mxch, layout_blocked_ivaud, /* GTA IV .ivaud blocks */ - layout_blocked_tra, /* DefJam Rapstar .tra blocks */ layout_blocked_ps2_iab, layout_blocked_vs_str, layout_blocked_rws, @@ -334,9 +329,7 @@ typedef enum { meta_RWAV, /* contents of RWAR */ meta_CWAV, /* contents of CWAR */ meta_FWAV, /* contents of FWAR */ - meta_RSTM_SPM, /* RSTM with 44->22khz hack */ meta_THP, /* THP movie files */ - meta_RSTM_shrunken, /* Atlus' mutant shortened RSTM */ meta_SWAV, meta_NDS_RRDS, /* Ridge Racer DS */ meta_WII_BNS, /* Wii BNS Banner Sound (similar to RSTM) */ @@ -434,12 +427,11 @@ typedef enum { meta_PS2_JOE, /* Wall-E / Pixar games */ meta_NGC_YMF, /* WWE WrestleMania X8 */ meta_SADL, - meta_PS2_CCC, /* Tokyo Xtreme Racer DRIFT 2 */ meta_FAG, /* Jackie Chan - Stuntmaster */ meta_PS2_MIHB, /* Merged MIH+MIB */ meta_NGC_PDT, /* Mario Party 6 */ meta_DC_ASD, /* Miss Moonligh */ - meta_NAOMI_SPSD, /* Guilty Gear X */ + meta_SPSD, meta_RSD, meta_PS2_ASS, /* ASS */ meta_SEG, /* Eragon */ @@ -557,13 +549,12 @@ typedef enum { meta_NGC_NST_DSP, /* Animaniacs [NGC] */ meta_BAF, /* Bizarre Creations (Blur, James Bond) */ meta_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */ - meta_PS3_CPS, /* Eternal Sonata (PS3) */ + meta_CPS, meta_MSF, meta_PS3_PAST, /* Bakugan Battle Brawlers (PS3) */ meta_SGXD, /* Sony: Folklore, Genji, Tokyo Jungle (PS3), Brave Story, Kurohyo (PSP) */ meta_WII_RAS, /* Donkey Kong Country Returns (Wii) */ meta_SPM, - meta_X360_TRA, /* Def Jam Rapstar */ meta_VGS_PS, meta_PS2_IAB, /* Ueki no Housoku - Taosu ze Robert Juudan!! (PS2) */ meta_VS_STR, /* The Bouncer */ @@ -601,25 +592,25 @@ typedef enum { meta_PS2_VDS_VDM, /* Graffiti Kingdom */ 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) */ - meta_XMA_RIFF, /* Microsoft RIFF XMA */ - meta_X360_AST, /* Dead Rising (X360) */ + meta_CXS, + meta_AKB, + meta_PASX, + meta_XMA_RIFF, + meta_ASTB, meta_WWISE_RIFF, /* Audiokinetic Wwise RIFF/RIFX */ meta_UBI_RAKI, /* Ubisoft RAKI header (Rayman Legends, Just Dance 2017) */ meta_SXD, /* Sony SXD (Gravity Rush, Freedom Wars PSV) */ meta_OGL, /* Shin'en Wii/WiiU (Jett Rocket (Wii), FAST Racing NEO (WiiU)) */ meta_MC3, /* Paradigm games (T3 PS2, MX Rider PS2, MI: Operation Surma PS2) */ - meta_GTD, /* Knights Contract (X360/PS3), Valhalla Knights 3 (PSV) */ - meta_TA_AAC, + meta_GHS, + meta_AAC_TRIACE, meta_MTA2, meta_NGC_ULW, /* Burnout 1 (GC only) */ meta_XA_XA30, meta_XA_04SW, meta_TXTH, /* generic text header */ meta_SK_AUD, /* Silicon Knights .AUD (Eternal Darkness GC) */ - meta_AHX, /* CRI AHX header */ + meta_AHX, meta_STM, /* Angel Studios/Rockstar San Diego Games */ meta_BINK, /* RAD Game Tools BINK audio/video */ meta_EA_SNU, /* Electronic Arts SNU (Dead Space) */ @@ -725,7 +716,7 @@ typedef enum { meta_PSF, meta_DSP_ITL_i, meta_IMA, - meta_XMV_VALVE, + meta_XWV_VALVE, meta_UBI_HX, meta_BMP_KONAMI, meta_ISB,