2008-04-03 15:40:36 +02:00
|
|
|
#ifdef _MSC_VER
|
2008-04-03 15:56:50 +02:00
|
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
2008-04-03 15:40:36 +02:00
|
|
|
#endif
|
|
|
|
|
2008-03-11 02:27:59 +01:00
|
|
|
#include <stdio.h>
|
2008-03-25 08:30:04 +01:00
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
2008-01-31 07:04:26 +01:00
|
|
|
#include "vgmstream.h"
|
2008-05-06 05:35:37 +02:00
|
|
|
#include "meta/meta.h"
|
|
|
|
#include "layout/layout.h"
|
|
|
|
#include "coding/coding.h"
|
2008-05-04 22:36:40 +02:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
static void try_dual_file_stereo(VGMSTREAM * opened_vgmstream, STREAMFILE *streamFile, VGMSTREAM* (*init_vgmstream_function)(STREAMFILE*));
|
2017-04-22 13:31:12 +02:00
|
|
|
|
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* List of functions that will recognize files */
|
|
|
|
VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
|
2008-06-09 02:20:08 +02:00
|
|
|
init_vgmstream_adx,
|
|
|
|
init_vgmstream_brstm,
|
2014-08-03 01:10:45 +02:00
|
|
|
init_vgmstream_bfwav,
|
2014-10-18 23:54:31 +02:00
|
|
|
init_vgmstream_bfstm,
|
2015-01-22 01:28:43 +01:00
|
|
|
init_vgmstream_mca,
|
|
|
|
init_vgmstream_btsnd,
|
2008-06-09 02:20:08 +02:00
|
|
|
init_vgmstream_nds_strm,
|
|
|
|
init_vgmstream_agsc,
|
|
|
|
init_vgmstream_ngc_adpdtk,
|
|
|
|
init_vgmstream_rsf,
|
|
|
|
init_vgmstream_afc,
|
|
|
|
init_vgmstream_ast,
|
|
|
|
init_vgmstream_halpst,
|
|
|
|
init_vgmstream_rs03,
|
|
|
|
init_vgmstream_ngc_dsp_std,
|
2017-05-14 02:35:20 +02:00
|
|
|
init_vgmstream_ngc_mdsp_std,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ngc_dsp_csmp,
|
2017-11-25 00:43:18 +01:00
|
|
|
init_vgmstream_cstr,
|
2008-06-09 02:20:08 +02:00
|
|
|
init_vgmstream_gcsw,
|
|
|
|
init_vgmstream_ps2_ads,
|
|
|
|
init_vgmstream_ps2_npsf,
|
|
|
|
init_vgmstream_rwsd,
|
|
|
|
init_vgmstream_cdxa,
|
2017-05-13 23:54:09 +02:00
|
|
|
init_vgmstream_ps2_rxws,
|
2008-06-09 02:20:08 +02:00
|
|
|
init_vgmstream_ps2_rxw,
|
|
|
|
init_vgmstream_ps2_int,
|
2017-08-28 17:47:19 +02:00
|
|
|
init_vgmstream_ngc_dsp_stm,
|
2008-06-09 02:20:08 +02:00
|
|
|
init_vgmstream_ps2_exst,
|
|
|
|
init_vgmstream_ps2_svag,
|
|
|
|
init_vgmstream_ps2_mib,
|
|
|
|
init_vgmstream_ngc_mpdsp,
|
|
|
|
init_vgmstream_ps2_mic,
|
|
|
|
init_vgmstream_ngc_dsp_std_int,
|
|
|
|
init_vgmstream_raw,
|
|
|
|
init_vgmstream_ps2_vag,
|
|
|
|
init_vgmstream_psx_gms,
|
|
|
|
init_vgmstream_ps2_str,
|
|
|
|
init_vgmstream_ps2_ild,
|
|
|
|
init_vgmstream_ps2_pnb,
|
|
|
|
init_vgmstream_xbox_wavm,
|
|
|
|
init_vgmstream_xbox_xwav,
|
|
|
|
init_vgmstream_ngc_str,
|
2017-07-01 23:02:24 +02:00
|
|
|
init_vgmstream_ea_schl,
|
2008-06-09 02:20:08 +02:00
|
|
|
init_vgmstream_caf,
|
|
|
|
init_vgmstream_ps2_vpk,
|
2008-06-10 03:20:54 +02:00
|
|
|
init_vgmstream_genh,
|
2008-06-15 09:59:43 +02:00
|
|
|
#ifdef VGM_USE_VORBIS
|
2008-06-15 06:01:03 +02:00
|
|
|
init_vgmstream_ogg_vorbis,
|
2008-07-21 07:50:28 +02:00
|
|
|
init_vgmstream_sli_ogg,
|
2008-07-22 04:18:32 +02:00
|
|
|
init_vgmstream_sfl,
|
2008-06-15 09:59:43 +02:00
|
|
|
#endif
|
2012-08-30 14:35:12 +02:00
|
|
|
#if 0
|
|
|
|
init_vgmstream_mp4_aac,
|
|
|
|
#endif
|
2013-06-14 02:42:24 +02:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
2012-08-30 14:35:12 +02:00
|
|
|
init_vgmstream_akb,
|
2013-06-14 02:42:24 +02:00
|
|
|
#endif
|
2008-06-15 11:23:34 +02:00
|
|
|
init_vgmstream_sadb,
|
2008-06-25 20:04:39 +02:00
|
|
|
init_vgmstream_ps2_bmdx,
|
2008-06-29 03:30:13 +02:00
|
|
|
init_vgmstream_wsi,
|
2008-07-01 05:23:44 +02:00
|
|
|
init_vgmstream_aifc,
|
2008-07-02 15:39:51 +02:00
|
|
|
init_vgmstream_str_snds,
|
2008-07-03 04:20:52 +02:00
|
|
|
init_vgmstream_ws_aud,
|
2008-07-05 13:49:29 +02:00
|
|
|
init_vgmstream_ahx,
|
2008-07-06 10:59:14 +02:00
|
|
|
init_vgmstream_ivb,
|
2008-07-06 14:23:37 +02:00
|
|
|
init_vgmstream_svs,
|
2008-07-06 20:05:04 +02:00
|
|
|
init_vgmstream_riff,
|
2009-05-25 22:59:50 +02:00
|
|
|
init_vgmstream_rifx,
|
2008-07-06 20:05:04 +02:00
|
|
|
init_vgmstream_pos,
|
2008-07-11 02:41:21 +02:00
|
|
|
init_vgmstream_nwa,
|
2017-11-18 02:20:52 +01:00
|
|
|
init_vgmstream_ea_1snh,
|
2008-07-12 17:20:39 +02:00
|
|
|
init_vgmstream_xss,
|
|
|
|
init_vgmstream_sl3,
|
|
|
|
init_vgmstream_hgc1,
|
|
|
|
init_vgmstream_aus,
|
|
|
|
init_vgmstream_rws,
|
2016-12-29 14:06:57 +01:00
|
|
|
init_vgmstream_fsb,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_fsb4_wav,
|
2014-04-24 06:31:04 +02:00
|
|
|
init_vgmstream_fsb5,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_rwx,
|
|
|
|
init_vgmstream_xwb,
|
2017-06-24 23:33:49 +02:00
|
|
|
init_vgmstream_ps2_xa30,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_musc,
|
2008-11-09 12:37:21 +01:00
|
|
|
init_vgmstream_musx_v004,
|
2010-05-02 21:16:35 +02:00
|
|
|
init_vgmstream_musx_v005,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_musx_v006,
|
|
|
|
init_vgmstream_musx_v010,
|
|
|
|
init_vgmstream_musx_v201,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_leg,
|
|
|
|
init_vgmstream_filp,
|
|
|
|
init_vgmstream_ikm,
|
|
|
|
init_vgmstream_sfs,
|
|
|
|
init_vgmstream_bg00,
|
2017-11-15 23:26:38 +01:00
|
|
|
init_vgmstream_sat_dvi,
|
|
|
|
init_vgmstream_dc_kcey,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_ps2_rstm,
|
2008-07-20 07:41:41 +02:00
|
|
|
init_vgmstream_acm,
|
2008-07-21 01:28:16 +02:00
|
|
|
init_vgmstream_mus_acm,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_ps2_kces,
|
|
|
|
init_vgmstream_ps2_dxh,
|
|
|
|
init_vgmstream_ps2_psh,
|
2017-11-16 00:41:06 +01:00
|
|
|
init_vgmstream_scd_pcm,
|
|
|
|
init_vgmstream_ps2_pcm,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_ps2_rkv,
|
|
|
|
init_vgmstream_ps2_psw,
|
|
|
|
init_vgmstream_ps2_vas,
|
|
|
|
init_vgmstream_ps2_tec,
|
|
|
|
init_vgmstream_ps2_enth,
|
|
|
|
init_vgmstream_sdt,
|
2008-08-02 12:24:28 +02:00
|
|
|
init_vgmstream_aix,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_ngc_tydsp,
|
|
|
|
init_vgmstream_ngc_swd,
|
2008-12-20 22:26:01 +01:00
|
|
|
init_vgmstream_capdsp,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_xbox_wvs,
|
2009-08-25 05:21:28 +02:00
|
|
|
init_vgmstream_ngc_wvs,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_dc_str,
|
2009-01-23 15:06:14 +01:00
|
|
|
init_vgmstream_dc_str_v2,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_xbox_matx,
|
2017-11-23 22:48:11 +01:00
|
|
|
init_vgmstream_dec,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_vs,
|
2008-08-13 08:11:05 +02:00
|
|
|
init_vgmstream_dc_str,
|
2009-01-23 15:06:14 +01:00
|
|
|
init_vgmstream_dc_str_v2,
|
2008-08-22 02:24:15 +02:00
|
|
|
init_vgmstream_xbox_xmu,
|
|
|
|
init_vgmstream_xbox_xvas,
|
|
|
|
init_vgmstream_ngc_bh2pcm,
|
|
|
|
init_vgmstream_sat_sap,
|
|
|
|
init_vgmstream_dc_idvi,
|
|
|
|
init_vgmstream_ps2_rnd,
|
|
|
|
init_vgmstream_wii_idsp,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_kraw,
|
|
|
|
init_vgmstream_ps2_omu,
|
|
|
|
init_vgmstream_ps2_xa2,
|
2010-05-02 21:16:35 +02:00
|
|
|
//init_vgmstream_idsp,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_idsp2,
|
|
|
|
init_vgmstream_idsp3,
|
2010-04-20 22:26:10 +02:00
|
|
|
init_vgmstream_idsp4,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_ngc_ymf,
|
2008-09-23 13:07:41 +02:00
|
|
|
init_vgmstream_sadl,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_ps2_ccc,
|
|
|
|
init_vgmstream_psx_fag,
|
|
|
|
init_vgmstream_ps2_mihb,
|
|
|
|
init_vgmstream_ngc_pdt,
|
2008-10-11 06:00:57 +02:00
|
|
|
init_vgmstream_wii_mus,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_dc_asd,
|
|
|
|
init_vgmstream_naomi_spsd,
|
|
|
|
init_vgmstream_rsd2vag,
|
|
|
|
init_vgmstream_rsd2pcmb,
|
|
|
|
init_vgmstream_rsd2xadp,
|
2009-04-25 18:45:22 +02:00
|
|
|
init_vgmstream_rsd3vag,
|
2009-05-20 04:48:13 +02:00
|
|
|
init_vgmstream_rsd3gadp,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_rsd3pcm,
|
2009-05-20 04:48:13 +02:00
|
|
|
init_vgmstream_rsd3pcmb,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_rsd4pcmb,
|
|
|
|
init_vgmstream_rsd4pcm,
|
2009-10-17 21:17:42 +02:00
|
|
|
init_vgmstream_rsd4radp,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_rsd4vag,
|
|
|
|
init_vgmstream_rsd6vag,
|
|
|
|
init_vgmstream_rsd6wadp,
|
|
|
|
init_vgmstream_rsd6xadp,
|
2009-09-12 06:51:39 +02:00
|
|
|
init_vgmstream_rsd6radp,
|
2008-11-07 00:30:33 +01:00
|
|
|
init_vgmstream_bgw,
|
2008-11-07 02:47:39 +01:00
|
|
|
init_vgmstream_spw,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_ps2_ass,
|
|
|
|
init_vgmstream_waa_wac_wad_wam,
|
2011-01-22 03:31:52 +01:00
|
|
|
init_vgmstream_seg,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_nds_strm_ffta2,
|
|
|
|
init_vgmstream_str_asr,
|
|
|
|
init_vgmstream_zwdsp,
|
|
|
|
init_vgmstream_gca,
|
|
|
|
init_vgmstream_spt_spd,
|
|
|
|
init_vgmstream_ish_isd,
|
|
|
|
init_vgmstream_gsp_gsb,
|
|
|
|
init_vgmstream_ydsp,
|
|
|
|
init_vgmstream_msvp,
|
|
|
|
init_vgmstream_ngc_ssm,
|
|
|
|
init_vgmstream_ps2_joe,
|
|
|
|
init_vgmstream_vgs,
|
2010-02-15 10:02:31 +01:00
|
|
|
init_vgmstream_dc_dcsw_dcs,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_wii_smp,
|
|
|
|
init_vgmstream_emff_ps2,
|
|
|
|
init_vgmstream_emff_ngc,
|
|
|
|
init_vgmstream_thp,
|
|
|
|
init_vgmstream_wii_sts,
|
|
|
|
init_vgmstream_ps2_p2bt,
|
|
|
|
init_vgmstream_ps2_gbts,
|
2008-12-24 01:00:10 +01:00
|
|
|
init_vgmstream_wii_sng,
|
2010-09-16 13:53:36 +02:00
|
|
|
init_vgmstream_ngc_dsp_iadp,
|
2009-01-03 12:08:44 +01:00
|
|
|
init_vgmstream_aax,
|
2011-01-04 15:20:49 +01:00
|
|
|
init_vgmstream_utf_dsp,
|
2009-01-08 15:29:40 +01:00
|
|
|
init_vgmstream_ngc_ffcc_str,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_sat_baka,
|
|
|
|
init_vgmstream_nds_swav,
|
2009-02-08 09:36:33 +01:00
|
|
|
init_vgmstream_ps2_vsf,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_nds_rrds,
|
|
|
|
init_vgmstream_ps2_tk5,
|
|
|
|
init_vgmstream_ps2_vsf_tta,
|
|
|
|
init_vgmstream_ads,
|
|
|
|
init_vgmstream_wii_str,
|
|
|
|
init_vgmstream_ps2_mcg,
|
2009-03-13 00:42:56 +01:00
|
|
|
init_vgmstream_zsd,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_ps2_vgs,
|
2009-03-16 16:45:02 +01:00
|
|
|
init_vgmstream_RedSpark,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_ivaud,
|
2009-03-26 00:25:30 +01:00
|
|
|
init_vgmstream_wii_wsd,
|
2009-04-19 11:49:08 +02:00
|
|
|
init_vgmstream_wii_ndp,
|
|
|
|
init_vgmstream_ps2_sps,
|
|
|
|
init_vgmstream_ps2_xa2_rrp,
|
|
|
|
init_vgmstream_nds_hwas,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ngc_lps,
|
2009-05-01 17:03:51 +02:00
|
|
|
init_vgmstream_ps2_snd,
|
2009-05-10 09:14:29 +02:00
|
|
|
init_vgmstream_naomi_adpcm,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_sd9,
|
|
|
|
init_vgmstream_2dx9,
|
|
|
|
init_vgmstream_dsp_ygo,
|
2009-07-11 13:28:36 +02:00
|
|
|
init_vgmstream_ps2_vgv,
|
2009-08-23 10:42:14 +02:00
|
|
|
init_vgmstream_ngc_gcub,
|
2009-08-25 19:50:43 +02:00
|
|
|
init_vgmstream_maxis_xa,
|
|
|
|
init_vgmstream_ngc_sck_dsp,
|
2009-08-30 04:16:54 +02:00
|
|
|
init_vgmstream_apple_caff,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_pc_mxst,
|
|
|
|
init_vgmstream_sab,
|
2009-09-04 06:19:39 +02:00
|
|
|
init_vgmstream_exakt_sc,
|
2009-09-05 14:18:34 +02:00
|
|
|
init_vgmstream_wii_bns,
|
2009-09-11 20:40:26 +02:00
|
|
|
init_vgmstream_wii_was,
|
2010-02-19 12:28:29 +01:00
|
|
|
init_vgmstream_pona_3do,
|
|
|
|
init_vgmstream_pona_psx,
|
2009-10-15 11:24:04 +02:00
|
|
|
init_vgmstream_xbox_hlwav,
|
2009-11-18 01:46:36 +01:00
|
|
|
init_vgmstream_stx,
|
2010-01-10 22:22:20 +01:00
|
|
|
init_vgmstream_myspd,
|
2010-01-19 20:40:41 +01:00
|
|
|
init_vgmstream_his,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ps2_ast,
|
|
|
|
init_vgmstream_dmsg,
|
2010-05-02 21:16:35 +02:00
|
|
|
init_vgmstream_ngc_dsp_aaap,
|
|
|
|
init_vgmstream_ngc_dsp_konami,
|
2010-04-20 22:26:10 +02:00
|
|
|
init_vgmstream_ps2_ster,
|
|
|
|
init_vgmstream_ps2_wb,
|
2010-03-23 21:57:12 +01:00
|
|
|
init_vgmstream_bnsf,
|
|
|
|
init_vgmstream_s14_sss,
|
2010-03-29 22:06:08 +02:00
|
|
|
init_vgmstream_ps2_gcm,
|
2010-04-20 22:26:10 +02:00
|
|
|
init_vgmstream_ps2_smpl,
|
|
|
|
init_vgmstream_ps2_msa,
|
|
|
|
init_vgmstream_ps2_voi,
|
|
|
|
init_vgmstream_ps2_khv,
|
2010-04-10 12:55:14 +02:00
|
|
|
init_vgmstream_pc_smp,
|
2010-04-20 22:26:10 +02:00
|
|
|
init_vgmstream_ngc_bo2,
|
|
|
|
init_vgmstream_dsp_ddsp,
|
2010-04-10 14:06:25 +02:00
|
|
|
init_vgmstream_p3d,
|
2010-05-31 01:56:35 +02:00
|
|
|
init_vgmstream_ps2_tk1,
|
|
|
|
init_vgmstream_ps2_adsc,
|
2010-04-20 22:26:10 +02:00
|
|
|
init_vgmstream_ngc_dsp_mpds,
|
|
|
|
init_vgmstream_dsp_str_ig,
|
|
|
|
init_vgmstream_psx_mgav,
|
2010-05-02 21:16:35 +02:00
|
|
|
init_vgmstream_ngc_dsp_sth_str1,
|
|
|
|
init_vgmstream_ngc_dsp_sth_str2,
|
|
|
|
init_vgmstream_ngc_dsp_sth_str3,
|
|
|
|
init_vgmstream_ps2_b1s,
|
|
|
|
init_vgmstream_ps2_wad,
|
|
|
|
init_vgmstream_dsp_xiii,
|
|
|
|
init_vgmstream_dsp_cabelas,
|
|
|
|
init_vgmstream_ps2_adm,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ps2_lpcm,
|
2010-05-10 10:02:22 +02:00
|
|
|
init_vgmstream_dsp_bdsp,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ps2_vms,
|
2017-05-18 21:00:42 +02:00
|
|
|
init_vgmstream_xau,
|
2010-06-13 06:41:26 +02:00
|
|
|
init_vgmstream_gh3_bar,
|
2010-07-27 21:45:59 +02:00
|
|
|
init_vgmstream_ffw,
|
2010-08-04 11:12:08 +02:00
|
|
|
init_vgmstream_dsp_dspw,
|
2010-08-28 03:43:40 +02:00
|
|
|
init_vgmstream_ps2_jstm,
|
2017-09-29 23:37:20 +02:00
|
|
|
init_vgmstream_xvag,
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ps3_cps,
|
2011-02-08 13:56:16 +01:00
|
|
|
init_vgmstream_sqex_scd,
|
2010-09-11 19:53:33 +02:00
|
|
|
init_vgmstream_ngc_nst_dsp,
|
2010-09-11 22:57:39 +02:00
|
|
|
init_vgmstream_baf,
|
2010-09-14 20:22:49 +02:00
|
|
|
init_vgmstream_ps3_msf,
|
2010-09-30 02:04:17 +02:00
|
|
|
init_vgmstream_nub_vag,
|
2010-10-12 02:16:49 +02:00
|
|
|
init_vgmstream_ps3_past,
|
2017-03-18 15:07:58 +01:00
|
|
|
init_vgmstream_sgxd,
|
2010-11-22 02:45:39 +01:00
|
|
|
init_vgmstream_ngca,
|
|
|
|
init_vgmstream_wii_ras,
|
2010-11-29 03:02:27 +01:00
|
|
|
init_vgmstream_ps2_spm,
|
2010-12-04 00:21:36 +01:00
|
|
|
init_vgmstream_x360_tra,
|
2010-12-06 23:22:06 +01:00
|
|
|
init_vgmstream_ps2_iab,
|
2010-12-29 13:33:33 +01:00
|
|
|
init_vgmstream_ps2_strlr,
|
2011-01-13 09:11:58 +01:00
|
|
|
init_vgmstream_lsf_n1nj4n,
|
2017-01-07 17:04:21 +01:00
|
|
|
init_vgmstream_vawx,
|
2011-02-06 10:49:57 +01:00
|
|
|
init_vgmstream_pc_snds,
|
2011-02-13 03:23:53 +01:00
|
|
|
init_vgmstream_ps2_wmus,
|
2011-02-15 19:24:50 +01:00
|
|
|
init_vgmstream_hyperscan_kvag,
|
2011-02-19 03:59:42 +01:00
|
|
|
init_vgmstream_ios_psnd,
|
2017-01-25 20:25:39 +01:00
|
|
|
init_vgmstream_pc_adp_bos,
|
|
|
|
init_vgmstream_pc_adp_otns,
|
2011-03-03 10:03:18 +01:00
|
|
|
init_vgmstream_eb_sfx,
|
|
|
|
init_vgmstream_eb_sf0,
|
2011-03-23 04:17:53 +01:00
|
|
|
init_vgmstream_ps3_klbs,
|
2011-05-07 13:05:05 +02:00
|
|
|
init_vgmstream_ps2_mtaf,
|
2011-05-18 22:33:00 +02:00
|
|
|
init_vgmstream_tun,
|
|
|
|
init_vgmstream_wpd,
|
2011-07-22 07:32:10 +02:00
|
|
|
init_vgmstream_mn_str,
|
2017-05-12 19:15:18 +02:00
|
|
|
init_vgmstream_mss,
|
2012-03-21 04:30:36 +01:00
|
|
|
init_vgmstream_ps2_hsf,
|
2012-04-14 18:07:21 +02:00
|
|
|
init_vgmstream_ps3_ivag,
|
2012-08-15 05:41:24 +02:00
|
|
|
init_vgmstream_ps2_2pfs,
|
2012-08-20 07:17:52 +02:00
|
|
|
init_vgmstream_xnbm,
|
2012-08-31 07:12:04 +02:00
|
|
|
init_vgmstream_rsd6oogv,
|
2013-09-03 20:14:14 +02:00
|
|
|
init_vgmstream_ubi_ckd,
|
2013-09-03 20:27:36 +02:00
|
|
|
init_vgmstream_ps2_vbk,
|
2014-02-26 07:25:02 +01:00
|
|
|
init_vgmstream_otm,
|
2014-02-26 07:31:28 +01:00
|
|
|
init_vgmstream_bcstm,
|
2014-10-19 23:10:31 +02:00
|
|
|
init_vgmstream_3ds_idsp,
|
2017-01-18 21:28:14 +01:00
|
|
|
init_vgmstream_kt_g1l,
|
|
|
|
init_vgmstream_kt_wiibgm,
|
2016-06-28 09:20:37 +02:00
|
|
|
init_vgmstream_hca,
|
2016-10-27 23:21:12 +02:00
|
|
|
init_vgmstream_ps2_svag_snk,
|
2017-01-08 12:59:04 +01:00
|
|
|
init_vgmstream_ps2_vds_vdm,
|
2017-01-08 14:19:32 +01:00
|
|
|
init_vgmstream_x360_cxs,
|
2017-01-25 22:23:45 +01:00
|
|
|
init_vgmstream_dsp_adx,
|
2017-02-12 14:42:02 +01:00
|
|
|
init_vgmstream_akb_multi,
|
|
|
|
init_vgmstream_akb2_multi,
|
2017-07-15 11:49:28 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
init_vgmstream_mp4_aac_ffmpeg,
|
|
|
|
#endif
|
2017-08-18 19:24:19 +02:00
|
|
|
init_vgmstream_bik,
|
2017-03-19 00:44:58 +01:00
|
|
|
init_vgmstream_x360_ast,
|
2017-04-02 12:27:21 +02:00
|
|
|
init_vgmstream_wwise,
|
2017-04-07 18:01:04 +02:00
|
|
|
init_vgmstream_ubi_raki,
|
2017-04-22 12:09:43 +02:00
|
|
|
init_vgmstream_x360_pasx,
|
2017-09-29 23:37:20 +02:00
|
|
|
init_vgmstream_nub_xma,
|
2017-04-22 13:12:01 +02:00
|
|
|
init_vgmstream_xma,
|
2017-04-22 15:00:22 +02:00
|
|
|
init_vgmstream_sxd,
|
2017-04-22 19:25:54 +02:00
|
|
|
init_vgmstream_ogl,
|
2017-04-28 17:26:25 +02:00
|
|
|
init_vgmstream_mc3,
|
2017-05-13 01:55:31 +02:00
|
|
|
init_vgmstream_gtd,
|
2017-05-13 02:22:15 +02:00
|
|
|
init_vgmstream_rsd6xma,
|
|
|
|
init_vgmstream_ta_aac_x360,
|
|
|
|
init_vgmstream_ta_aac_ps3,
|
2017-05-18 19:16:44 +02:00
|
|
|
init_vgmstream_ps3_mta2,
|
2017-06-09 22:26:09 +02:00
|
|
|
init_vgmstream_ngc_ulw,
|
2017-06-24 23:30:10 +02:00
|
|
|
init_vgmstream_pc_xa30,
|
2017-06-25 00:27:58 +02:00
|
|
|
init_vgmstream_wii_04sw,
|
2017-07-23 03:46:55 +02:00
|
|
|
init_vgmstream_ea_bnk,
|
2017-07-23 17:09:55 +02:00
|
|
|
init_vgmstream_ea_schl_fixed,
|
2017-07-29 11:46:53 +02:00
|
|
|
init_vgmstream_sk_aud,
|
2017-08-12 18:42:38 +02:00
|
|
|
init_vgmstream_stm,
|
2017-08-20 02:18:48 +02:00
|
|
|
init_vgmstream_ea_snu,
|
2017-08-28 15:14:24 +02:00
|
|
|
init_vgmstream_awc,
|
2017-09-30 01:27:47 +02:00
|
|
|
init_vgmstream_nsw_opus,
|
2017-10-08 17:51:54 +02:00
|
|
|
init_vgmstream_pc_al2,
|
2017-11-05 17:06:40 +01:00
|
|
|
init_vgmstream_pc_ast,
|
2017-11-23 22:32:31 +01:00
|
|
|
init_vgmstream_naac,
|
2017-11-05 17:06:40 +01:00
|
|
|
init_vgmstream_ubi_sb,
|
2017-02-12 14:42:02 +01:00
|
|
|
|
2017-07-15 11:49:28 +02:00
|
|
|
init_vgmstream_txth, /* should go at the end (lower priority) */
|
2016-07-17 08:02:27 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
2017-01-08 01:09:20 +01:00
|
|
|
init_vgmstream_ffmpeg, /* should go at the end */
|
2016-07-17 08:02:27 +02:00
|
|
|
#endif
|
2008-01-31 07:04:26 +01:00
|
|
|
};
|
|
|
|
|
2008-06-09 02:20:08 +02:00
|
|
|
|
2008-03-25 08:30:04 +01:00
|
|
|
/* internal version with all parameters */
|
2017-11-24 20:15:23 +01:00
|
|
|
static VGMSTREAM * init_vgmstream_internal(STREAMFILE *streamFile) {
|
2017-01-08 01:09:20 +01:00
|
|
|
int i, fcns_size;
|
2008-05-20 17:18:38 +02:00
|
|
|
|
|
|
|
if (!streamFile)
|
|
|
|
return NULL;
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
fcns_size = (sizeof(init_vgmstream_functions)/sizeof(init_vgmstream_functions[0]));
|
2008-01-31 07:04:26 +01:00
|
|
|
/* try a series of formats, see which works */
|
2017-04-29 22:37:15 +02:00
|
|
|
for (i=0; i < fcns_size; i++) {
|
2017-01-08 01:09:20 +01:00
|
|
|
/* call init function and see if valid VGMSTREAM was returned */
|
2017-11-24 20:15:23 +01:00
|
|
|
VGMSTREAM * vgmstream = (init_vgmstream_functions[i])(streamFile);
|
|
|
|
if (!vgmstream)
|
|
|
|
continue;
|
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* fail if there is nothing to play (without this check vgmstream can generate empty files) */
|
|
|
|
if (vgmstream->num_samples <= 0) {
|
|
|
|
VGM_LOG("VGMSTREAM: wrong num_samples (ns=%i / 0x%08x)\n", vgmstream->num_samples, vgmstream->num_samples);
|
|
|
|
close_vgmstream(vgmstream);
|
|
|
|
continue;
|
|
|
|
}
|
2016-11-11 23:36:12 +01:00
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* everything should have a reasonable sample rate (300 is Wwise min) */
|
|
|
|
if (vgmstream->sample_rate < 300 || vgmstream->sample_rate > 96000) {
|
|
|
|
VGM_LOG("VGMSTREAM: wrong sample rate (sr=%i)\n", vgmstream->sample_rate);
|
|
|
|
close_vgmstream(vgmstream);
|
|
|
|
continue;
|
|
|
|
}
|
2016-07-17 08:02:27 +02:00
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* Sanify loops! */
|
|
|
|
if (vgmstream->loop_flag) {
|
|
|
|
if ((vgmstream->loop_end_sample <= vgmstream->loop_start_sample)
|
|
|
|
|| (vgmstream->loop_end_sample > vgmstream->num_samples)
|
|
|
|
|| (vgmstream->loop_start_sample < 0) ) {
|
|
|
|
vgmstream->loop_flag = 0;
|
|
|
|
VGM_LOG("VGMSTREAM: wrong loops ignored (lss=%i, lse=%i, ns=%i)\n", vgmstream->loop_start_sample, vgmstream->loop_end_sample, vgmstream->num_samples);
|
2016-07-17 08:02:27 +02:00
|
|
|
}
|
2017-11-25 00:43:18 +01:00
|
|
|
}
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* test if candidate for dual stereo */
|
|
|
|
if (vgmstream->channels == 1 && (
|
|
|
|
(vgmstream->meta_type == meta_DSP_STD) ||
|
|
|
|
(vgmstream->meta_type == meta_PS2_VAGp) ||
|
|
|
|
(vgmstream->meta_type == meta_GENH) ||
|
|
|
|
(vgmstream->meta_type == meta_TXTH) ||
|
|
|
|
(vgmstream->meta_type == meta_KRAW) ||
|
|
|
|
(vgmstream->meta_type == meta_PS2_MIB) ||
|
|
|
|
(vgmstream->meta_type == meta_NGC_LPS) ||
|
|
|
|
(vgmstream->meta_type == meta_DSP_YGO) ||
|
|
|
|
(vgmstream->meta_type == meta_DSP_AGSC) ||
|
|
|
|
(vgmstream->meta_type == meta_PS2_SMPL) ||
|
|
|
|
(vgmstream->meta_type == meta_NGCA) ||
|
|
|
|
(vgmstream->meta_type == meta_NUB_VAG) ||
|
|
|
|
(vgmstream->meta_type == meta_SPT_SPD) ||
|
|
|
|
(vgmstream->meta_type == meta_EB_SFX) ||
|
|
|
|
(vgmstream->meta_type == meta_CWAV)
|
|
|
|
)) {
|
|
|
|
try_dual_file_stereo(vgmstream, streamFile, init_vgmstream_functions[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef VGM_DEBUG_OUTPUT
|
|
|
|
/* debug fun */
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
/* probable segfault but some layouts/codecs could ignore these */
|
|
|
|
for (i = 0; i < vgmstream->channels; i++) {
|
|
|
|
VGM_ASSERT(vgmstream->ch[i].streamfile == NULL, "VGMSTREAM: null streamfile in ch%i\n",i);
|
2008-03-25 08:30:04 +01:00
|
|
|
}
|
2017-11-25 00:43:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif/*VGM_DEBUG_OUTPUT*/
|
|
|
|
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-03-04 02:05:07 +01:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
2017-11-25 00:43:18 +01:00
|
|
|
/* check FFmpeg streams here, for lack of a better place */
|
|
|
|
if (vgmstream->coding_type == coding_FFmpeg) {
|
|
|
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
|
|
|
if (data->streamCount && !vgmstream->num_streams) {
|
|
|
|
vgmstream->num_streams = data->streamCount;
|
2017-03-04 02:05:07 +01:00
|
|
|
}
|
2017-11-25 00:43:18 +01:00
|
|
|
}
|
2017-03-04 02:05:07 +01:00
|
|
|
#endif
|
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* save info */
|
|
|
|
vgmstream->stream_index = streamFile->stream_index;
|
2017-08-12 11:27:10 +02:00
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* save start things so we can restart for seeking */
|
|
|
|
memcpy(vgmstream->start_ch,vgmstream->ch,sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
|
|
|
|
memcpy(vgmstream->start_vgmstream,vgmstream,sizeof(VGMSTREAM));
|
2008-05-19 05:58:15 +02:00
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
return vgmstream;
|
2008-01-31 07:04:26 +01:00
|
|
|
}
|
|
|
|
|
2017-11-25 00:43:18 +01:00
|
|
|
/* not supported */
|
2008-01-31 07:04:26 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-05-20 17:18:38 +02:00
|
|
|
/* format detection and VGMSTREAM setup, uses default parameters */
|
|
|
|
VGMSTREAM * init_vgmstream(const char * const filename) {
|
|
|
|
VGMSTREAM *vgmstream = NULL;
|
|
|
|
STREAMFILE *streamFile = open_stdio_streamfile(filename);
|
|
|
|
if (streamFile) {
|
|
|
|
vgmstream = init_vgmstream_from_STREAMFILE(streamFile);
|
|
|
|
close_streamfile(streamFile);
|
|
|
|
}
|
|
|
|
return vgmstream;
|
|
|
|
}
|
|
|
|
|
|
|
|
VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile) {
|
2017-11-24 20:15:23 +01:00
|
|
|
return init_vgmstream_internal(streamFile);
|
2008-05-20 17:18:38 +02:00
|
|
|
}
|
|
|
|
|
2008-05-19 05:58:15 +02:00
|
|
|
/* Reset a VGMSTREAM to its state at the start of playback.
|
|
|
|
* Note that this does not reset the constituent STREAMFILES. */
|
|
|
|
void reset_vgmstream(VGMSTREAM * vgmstream) {
|
|
|
|
/* copy the vgmstream back into itself */
|
|
|
|
memcpy(vgmstream,vgmstream->start_vgmstream,sizeof(VGMSTREAM));
|
|
|
|
|
|
|
|
/* copy the initial channels */
|
|
|
|
memcpy(vgmstream->ch,vgmstream->start_ch,sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
|
|
|
|
|
|
|
|
/* loop_ch is not zeroed here because there is a possibility of the
|
|
|
|
* init_vgmstream_* function doing something tricky and precomputing it.
|
|
|
|
* Otherwise hit_loop will be 0 and it will be copied over anyway when we
|
|
|
|
* really hit the loop start. */
|
2008-06-15 06:01:03 +02:00
|
|
|
|
|
|
|
#ifdef VGM_USE_VORBIS
|
2008-07-21 07:50:28 +02:00
|
|
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
2017-04-29 22:37:15 +02:00
|
|
|
reset_ogg_vorbis(vgmstream);
|
2008-06-15 06:01:03 +02:00
|
|
|
}
|
2017-03-25 14:57:44 +01:00
|
|
|
|
2017-07-28 23:26:58 +02:00
|
|
|
if (vgmstream->coding_type==coding_VORBIS_custom) {
|
|
|
|
reset_vorbis_custom(vgmstream);
|
2017-04-22 19:25:54 +02:00
|
|
|
}
|
2008-06-15 06:01:03 +02:00
|
|
|
#endif
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2016-06-28 09:20:37 +02:00
|
|
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
2017-04-29 22:37:15 +02:00
|
|
|
reset_hca(vgmstream);
|
2016-06-28 09:20:37 +02:00
|
|
|
}
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2013-06-14 02:42:24 +02:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
2012-08-30 14:35:12 +02:00
|
|
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
2017-04-29 22:37:15 +02:00
|
|
|
reset_mp4_aac(vgmstream);
|
2012-08-30 14:35:12 +02:00
|
|
|
}
|
2013-06-14 02:42:24 +02:00
|
|
|
#endif
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2008-07-05 13:49:29 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
2017-07-29 13:05:23 +02:00
|
|
|
if (vgmstream->coding_type==coding_MPEG_custom ||
|
2017-08-05 17:54:50 +02:00
|
|
|
vgmstream->coding_type==coding_MPEG_ealayer3 ||
|
2017-07-29 13:05:23 +02:00
|
|
|
vgmstream->coding_type==coding_MPEG_layer1 ||
|
|
|
|
vgmstream->coding_type==coding_MPEG_layer2 ||
|
|
|
|
vgmstream->coding_type==coding_MPEG_layer3) {
|
2017-02-17 17:20:40 +01:00
|
|
|
reset_mpeg(vgmstream);
|
2008-07-05 13:49:29 +02:00
|
|
|
}
|
|
|
|
#endif
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2010-03-23 21:57:12 +01:00
|
|
|
#ifdef VGM_USE_G7221
|
|
|
|
if (vgmstream->coding_type==coding_G7221 ||
|
|
|
|
vgmstream->coding_type==coding_G7221C) {
|
2017-04-29 22:37:15 +02:00
|
|
|
reset_g7221(vgmstream);
|
2010-03-23 21:57:12 +01:00
|
|
|
}
|
|
|
|
#endif
|
2008-07-20 07:41:41 +02:00
|
|
|
|
2015-01-25 06:08:25 +01:00
|
|
|
#ifdef VGM_USE_G719
|
|
|
|
if (vgmstream->coding_type==coding_G719) {
|
2017-04-29 22:37:15 +02:00
|
|
|
reset_g719(vgmstream);
|
2015-01-25 06:08:25 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-06-26 11:54:15 +02:00
|
|
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
2013-06-26 13:36:57 +02:00
|
|
|
if (vgmstream->coding_type==coding_AT3plus) {
|
2017-04-29 22:37:15 +02:00
|
|
|
reset_at3plus(vgmstream);
|
2013-06-26 11:54:15 +02:00
|
|
|
}
|
|
|
|
#endif
|
2016-07-17 08:02:27 +02:00
|
|
|
|
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
2016-12-01 19:58:51 +01:00
|
|
|
reset_ffmpeg(vgmstream);
|
2016-07-17 08:02:27 +02:00
|
|
|
}
|
|
|
|
#endif
|
2013-06-26 11:54:15 +02:00
|
|
|
|
2008-07-20 09:28:17 +02:00
|
|
|
if (vgmstream->coding_type==coding_ACM) {
|
|
|
|
mus_acm_codec_data *data = vgmstream->codec_data;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
data->current_file = 0;
|
|
|
|
for (i=0;i<data->file_count;i++) {
|
|
|
|
acm_reset(data->files[i]);
|
|
|
|
}
|
|
|
|
}
|
2008-08-02 12:24:28 +02:00
|
|
|
|
|
|
|
if (vgmstream->layout_type==layout_aix) {
|
|
|
|
aix_codec_data *data = vgmstream->codec_data;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
data->current_segment = 0;
|
|
|
|
for (i=0;i<data->segment_count*data->stream_count;i++)
|
|
|
|
{
|
|
|
|
reset_vgmstream(data->adxs[i]);
|
|
|
|
}
|
|
|
|
}
|
2008-08-03 16:58:03 +02:00
|
|
|
|
2009-01-03 12:08:44 +01:00
|
|
|
if (vgmstream->layout_type==layout_aax) {
|
|
|
|
aax_codec_data *data = vgmstream->codec_data;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
data->current_segment = 0;
|
|
|
|
for (i=0;i<data->segment_count;i++)
|
|
|
|
{
|
|
|
|
reset_vgmstream(data->adxs[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-03 16:58:03 +02:00
|
|
|
if (
|
|
|
|
vgmstream->coding_type == coding_NWA0 ||
|
|
|
|
vgmstream->coding_type == coding_NWA1 ||
|
|
|
|
vgmstream->coding_type == coding_NWA2 ||
|
|
|
|
vgmstream->coding_type == coding_NWA3 ||
|
|
|
|
vgmstream->coding_type == coding_NWA4 ||
|
|
|
|
vgmstream->coding_type == coding_NWA5
|
|
|
|
) {
|
|
|
|
nwa_codec_data *data = vgmstream->codec_data;
|
|
|
|
reset_nwa(data->nwa);
|
|
|
|
}
|
2012-08-24 19:36:40 +02:00
|
|
|
|
|
|
|
if (vgmstream->layout_type==layout_scd_int) {
|
|
|
|
scd_int_codec_data *data = vgmstream->codec_data;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0;i<data->substream_count;i++)
|
|
|
|
{
|
|
|
|
reset_vgmstream(data->substreams[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-19 05:58:15 +02:00
|
|
|
}
|
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
/* simply allocate memory for the VGMSTREAM and its channels */
|
|
|
|
VGMSTREAM * allocate_vgmstream(int channel_count, int looped) {
|
|
|
|
VGMSTREAM * vgmstream;
|
2008-05-19 05:58:15 +02:00
|
|
|
VGMSTREAM * start_vgmstream;
|
2008-01-31 07:04:26 +01:00
|
|
|
VGMSTREAMCHANNEL * channels;
|
|
|
|
VGMSTREAMCHANNEL * start_channels;
|
|
|
|
VGMSTREAMCHANNEL * loop_channels;
|
|
|
|
|
2008-04-02 19:50:50 +02:00
|
|
|
if (channel_count <= 0) return NULL;
|
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
vgmstream = calloc(1,sizeof(VGMSTREAM));
|
|
|
|
if (!vgmstream) return NULL;
|
2008-08-03 16:58:03 +02:00
|
|
|
|
|
|
|
vgmstream->ch = NULL;
|
|
|
|
vgmstream->start_ch = NULL;
|
|
|
|
vgmstream->loop_ch = NULL;
|
|
|
|
vgmstream->start_vgmstream = NULL;
|
|
|
|
vgmstream->codec_data = NULL;
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2008-05-19 05:58:15 +02:00
|
|
|
start_vgmstream = calloc(1,sizeof(VGMSTREAM));
|
|
|
|
if (!start_vgmstream) {
|
|
|
|
free(vgmstream);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
vgmstream->start_vgmstream = start_vgmstream;
|
|
|
|
start_vgmstream->start_vgmstream = start_vgmstream;
|
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
channels = calloc(channel_count,sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!channels) {
|
|
|
|
free(vgmstream);
|
2008-05-19 05:58:15 +02:00
|
|
|
free(start_vgmstream);
|
2008-01-31 07:04:26 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
vgmstream->ch = channels;
|
|
|
|
vgmstream->channels = channel_count;
|
|
|
|
|
|
|
|
start_channels = calloc(channel_count,sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!start_channels) {
|
|
|
|
free(vgmstream);
|
2008-05-19 05:58:15 +02:00
|
|
|
free(start_vgmstream);
|
2008-01-31 07:04:26 +01:00
|
|
|
free(channels);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
vgmstream->start_ch = start_channels;
|
|
|
|
|
|
|
|
if (looped) {
|
|
|
|
loop_channels = calloc(channel_count,sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!loop_channels) {
|
|
|
|
free(vgmstream);
|
2008-05-19 05:58:15 +02:00
|
|
|
free(start_vgmstream);
|
2008-01-31 07:04:26 +01:00
|
|
|
free(channels);
|
|
|
|
free(start_channels);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
vgmstream->loop_ch = loop_channels;
|
|
|
|
}
|
|
|
|
|
|
|
|
vgmstream->loop_flag = looped;
|
|
|
|
|
|
|
|
return vgmstream;
|
|
|
|
}
|
|
|
|
|
|
|
|
void close_vgmstream(VGMSTREAM * vgmstream) {
|
2017-04-29 22:37:15 +02:00
|
|
|
if (!vgmstream)
|
|
|
|
return;
|
2008-01-31 07:04:26 +01:00
|
|
|
|
2008-06-15 06:01:03 +02:00
|
|
|
#ifdef VGM_USE_VORBIS
|
2008-07-21 07:50:28 +02:00
|
|
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_ogg_vorbis(vgmstream->codec_data);
|
|
|
|
vgmstream->codec_data = NULL;
|
2008-06-15 06:01:03 +02:00
|
|
|
}
|
2017-03-25 14:57:44 +01:00
|
|
|
|
2017-07-28 23:26:58 +02:00
|
|
|
if (vgmstream->coding_type==coding_VORBIS_custom) {
|
|
|
|
free_vorbis_custom(vgmstream->codec_data);
|
2017-04-22 19:25:54 +02:00
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
2008-06-15 06:01:03 +02:00
|
|
|
#endif
|
2016-06-29 04:27:30 +02:00
|
|
|
|
2016-06-28 09:20:37 +02:00
|
|
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_hca(vgmstream->codec_data);
|
|
|
|
vgmstream->codec_data = NULL;
|
2016-06-28 09:20:37 +02:00
|
|
|
}
|
2016-07-17 08:02:27 +02:00
|
|
|
|
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_ffmpeg(vgmstream->codec_data);
|
|
|
|
vgmstream->codec_data = NULL;
|
2016-07-17 08:02:27 +02:00
|
|
|
}
|
|
|
|
#endif
|
2008-06-15 06:01:03 +02:00
|
|
|
|
2013-06-14 02:42:24 +02:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
2012-08-30 14:35:12 +02:00
|
|
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_mp4_aac(vgmstream->codec_data);
|
|
|
|
vgmstream->codec_data = NULL;
|
2012-08-30 14:35:12 +02:00
|
|
|
}
|
2013-06-14 02:42:24 +02:00
|
|
|
#endif
|
2012-08-30 14:35:12 +02:00
|
|
|
|
2008-07-05 13:49:29 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
2017-07-29 13:05:23 +02:00
|
|
|
if (vgmstream->coding_type==coding_MPEG_custom ||
|
2017-08-05 17:54:50 +02:00
|
|
|
vgmstream->coding_type==coding_MPEG_ealayer3 ||
|
2017-07-29 13:05:23 +02:00
|
|
|
vgmstream->coding_type==coding_MPEG_layer1 ||
|
|
|
|
vgmstream->coding_type==coding_MPEG_layer2 ||
|
|
|
|
vgmstream->coding_type==coding_MPEG_layer3) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_mpeg(vgmstream->codec_data);
|
2017-02-17 17:20:40 +01:00
|
|
|
vgmstream->codec_data = NULL;
|
2008-07-05 13:49:29 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-03-23 21:57:12 +01:00
|
|
|
#ifdef VGM_USE_G7221
|
|
|
|
if (vgmstream->coding_type == coding_G7221 ||
|
|
|
|
vgmstream->coding_type == coding_G7221C) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_g7221(vgmstream);
|
2010-03-23 21:57:12 +01:00
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-01-25 06:08:25 +01:00
|
|
|
#ifdef VGM_USE_G719
|
|
|
|
if (vgmstream->coding_type == coding_G719) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_g719(vgmstream);
|
2015-01-25 06:08:25 +01:00
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-06-26 11:54:15 +02:00
|
|
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
2013-06-26 13:36:57 +02:00
|
|
|
if (vgmstream->coding_type == coding_AT3plus) {
|
2017-04-29 22:37:15 +02:00
|
|
|
free_at3plus(vgmstream->codec_data);
|
|
|
|
vgmstream->codec_data = NULL;
|
2013-06-26 11:54:15 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-07-20 07:41:41 +02:00
|
|
|
if (vgmstream->coding_type==coding_ACM) {
|
2016-06-29 04:27:30 +02:00
|
|
|
mus_acm_codec_data *data = (mus_acm_codec_data *) vgmstream->codec_data;
|
2008-07-20 07:41:41 +02:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (data->files) {
|
|
|
|
int i;
|
|
|
|
for (i=0; i<data->file_count; i++) {
|
|
|
|
/* shouldn't be duplicates */
|
|
|
|
if (data->files[i]) {
|
|
|
|
acm_close(data->files[i]);
|
|
|
|
data->files[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(data->files);
|
|
|
|
data->files = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(vgmstream->codec_data);
|
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-02 12:24:28 +02:00
|
|
|
if (vgmstream->layout_type==layout_aix) {
|
2016-06-29 04:27:30 +02:00
|
|
|
aix_codec_data *data = (aix_codec_data *) vgmstream->codec_data;
|
2008-08-02 12:24:28 +02:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (data->adxs) {
|
|
|
|
int i;
|
|
|
|
for (i=0;i<data->segment_count*data->stream_count;i++) {
|
|
|
|
|
|
|
|
/* note that the AIX close_streamfile won't do anything but
|
|
|
|
* deallocate itself, there is only one open file and that
|
|
|
|
* is in vgmstream->ch[0].streamfile */
|
|
|
|
close_vgmstream(data->adxs[i]);
|
|
|
|
}
|
|
|
|
free(data->adxs);
|
|
|
|
}
|
|
|
|
if (data->sample_counts) {
|
|
|
|
free(data->sample_counts);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
2008-08-03 16:58:03 +02:00
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
2009-01-03 12:08:44 +01:00
|
|
|
if (vgmstream->layout_type==layout_aax) {
|
2016-06-29 04:27:30 +02:00
|
|
|
aax_codec_data *data = (aax_codec_data *) vgmstream->codec_data;
|
2009-01-03 12:08:44 +01:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (data->adxs) {
|
|
|
|
int i;
|
|
|
|
for (i=0;i<data->segment_count;i++) {
|
|
|
|
|
|
|
|
/* note that the AAX close_streamfile won't do anything but
|
|
|
|
* deallocate itself, there is only one open file and that
|
|
|
|
* is in vgmstream->ch[0].streamfile */
|
|
|
|
close_vgmstream(data->adxs[i]);
|
|
|
|
}
|
|
|
|
free(data->adxs);
|
|
|
|
}
|
|
|
|
if (data->sample_counts) {
|
|
|
|
free(data->sample_counts);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
2008-08-03 16:58:03 +02:00
|
|
|
|
|
|
|
if (
|
|
|
|
vgmstream->coding_type == coding_NWA0 ||
|
|
|
|
vgmstream->coding_type == coding_NWA1 ||
|
|
|
|
vgmstream->coding_type == coding_NWA2 ||
|
|
|
|
vgmstream->coding_type == coding_NWA3 ||
|
|
|
|
vgmstream->coding_type == coding_NWA4 ||
|
|
|
|
vgmstream->coding_type == coding_NWA5
|
|
|
|
) {
|
2016-06-29 04:27:30 +02:00
|
|
|
nwa_codec_data *data = (nwa_codec_data *) vgmstream->codec_data;
|
2008-08-03 16:58:03 +02:00
|
|
|
close_nwa(data->nwa);
|
|
|
|
free(data);
|
|
|
|
|
|
|
|
vgmstream->codec_data = NULL;
|
2008-08-02 12:24:28 +02:00
|
|
|
}
|
|
|
|
|
2012-08-24 19:36:40 +02:00
|
|
|
if (vgmstream->layout_type==layout_scd_int) {
|
2016-06-29 04:27:30 +02:00
|
|
|
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
|
2012-08-24 19:36:40 +02:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (data->substreams) {
|
|
|
|
int i;
|
|
|
|
for (i=0;i<data->substream_count;i++) {
|
|
|
|
|
|
|
|
/* note that the scd_int close_streamfile won't do anything
|
|
|
|
* but deallocate itself, there is only one open file and
|
|
|
|
* that is in vgmstream->ch[0].streamfile */
|
|
|
|
close_vgmstream(data->substreams[i]);
|
2017-01-18 21:19:43 +01:00
|
|
|
if(data->intfiles[i]) close_streamfile(data->intfiles[i]);
|
2012-08-24 19:36:40 +02:00
|
|
|
}
|
|
|
|
free(data->substreams);
|
|
|
|
free(data->intfiles);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
vgmstream->codec_data = NULL;
|
|
|
|
}
|
|
|
|
|
2008-08-02 12:24:28 +02:00
|
|
|
/* now that the special cases have had their chance, clean up the standard items */
|
2017-10-28 01:34:32 +02:00
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
|
|
|
|
for (i=0;i<vgmstream->channels;i++) {
|
|
|
|
if (vgmstream->ch[i].streamfile) {
|
|
|
|
close_streamfile(vgmstream->ch[i].streamfile);
|
|
|
|
/* Multiple channels might have the same streamfile. Find the others
|
|
|
|
* that are the same as this and clear them so they won't be closed
|
|
|
|
* again. */
|
|
|
|
for (j=0;j<vgmstream->channels;j++) {
|
|
|
|
if (i!=j && vgmstream->ch[j].streamfile ==
|
|
|
|
vgmstream->ch[i].streamfile) {
|
|
|
|
vgmstream->ch[j].streamfile = NULL;
|
|
|
|
}
|
2008-08-02 12:24:28 +02:00
|
|
|
}
|
2017-10-28 01:34:32 +02:00
|
|
|
vgmstream->ch[i].streamfile = NULL;
|
2008-08-02 12:24:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vgmstream->loop_ch) free(vgmstream->loop_ch);
|
|
|
|
if (vgmstream->start_ch) free(vgmstream->start_ch);
|
|
|
|
if (vgmstream->ch) free(vgmstream->ch);
|
|
|
|
/* the start_vgmstream is considered just data */
|
|
|
|
if (vgmstream->start_vgmstream) free(vgmstream->start_vgmstream);
|
|
|
|
|
2008-01-31 07:04:26 +01:00
|
|
|
free(vgmstream);
|
|
|
|
}
|
|
|
|
|
2017-05-18 19:55:00 +02:00
|
|
|
/* calculate samples based on player's config */
|
2008-05-16 22:28:36 +02:00
|
|
|
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM * vgmstream) {
|
2008-01-31 07:04:26 +01:00
|
|
|
if (vgmstream->loop_flag) {
|
2017-05-18 19:55:00 +02:00
|
|
|
if (fadeseconds < 0) { /* a bit hack-y to avoid signature change */
|
|
|
|
/* Continue playing the file normally after looping, instead of fading.
|
|
|
|
* Most files cut abruply after the loop, but some do have proper endings.
|
|
|
|
* With looptimes = 1 this option should give the same output vs loop disabled */
|
|
|
|
int loop_count = (int)looptimes; /* no half loops allowed */
|
2017-08-18 19:32:51 +02:00
|
|
|
//vgmstream->loop_target = loop_count; /* handled externally, as this is into-only */
|
2017-05-18 19:55:00 +02:00
|
|
|
return vgmstream->loop_start_sample
|
|
|
|
+ (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * loop_count
|
|
|
|
+ (vgmstream->num_samples - vgmstream->loop_end_sample);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return vgmstream->loop_start_sample
|
|
|
|
+ (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * looptimes
|
|
|
|
+ (fadedelayseconds + fadeseconds) * vgmstream->sample_rate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return vgmstream->num_samples;
|
|
|
|
}
|
2008-01-31 07:04:26 +01:00
|
|
|
}
|
|
|
|
|
2017-05-18 19:55:00 +02:00
|
|
|
/* decode data into sample buffer */
|
2008-01-31 07:04:26 +01:00
|
|
|
void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) {
|
|
|
|
switch (vgmstream->layout_type) {
|
|
|
|
case layout_interleave:
|
2008-02-04 16:20:20 +01:00
|
|
|
case layout_interleave_shortblock:
|
2008-01-31 07:04:26 +01:00
|
|
|
render_vgmstream_interleave(buffer,sample_count,vgmstream);
|
|
|
|
break;
|
2008-06-15 09:59:43 +02:00
|
|
|
#ifdef VGM_USE_VORBIS
|
2008-06-15 06:01:03 +02:00
|
|
|
case layout_ogg_vorbis:
|
2008-07-05 13:49:29 +02:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_MPEG
|
2017-07-29 13:05:23 +02:00
|
|
|
case layout_mpeg_custom:
|
2008-06-15 09:59:43 +02:00
|
|
|
#endif
|
2008-02-05 01:03:39 +01:00
|
|
|
case layout_none:
|
|
|
|
render_vgmstream_nolayout(buffer,sample_count,vgmstream);
|
|
|
|
break;
|
2009-09-02 14:18:23 +02:00
|
|
|
case layout_mxch_blocked:
|
2008-03-04 01:46:55 +01:00
|
|
|
case layout_ast_blocked:
|
2008-03-04 08:15:25 +01:00
|
|
|
case layout_halpst_blocked:
|
2009-04-19 11:49:08 +02:00
|
|
|
case layout_xa_blocked:
|
|
|
|
case layout_ea_blocked:
|
2017-11-18 02:20:52 +01:00
|
|
|
case layout_blocked_ea_1snh:
|
2009-04-19 11:49:08 +02:00
|
|
|
case layout_caf_blocked:
|
2008-06-29 03:30:13 +02:00
|
|
|
case layout_wsi_blocked:
|
2008-07-02 15:39:51 +02:00
|
|
|
case layout_str_snds_blocked:
|
2008-07-03 04:20:52 +02:00
|
|
|
case layout_ws_aud_blocked:
|
2009-04-19 11:49:08 +02:00
|
|
|
case layout_matx_blocked:
|
2017-11-23 22:48:11 +01:00
|
|
|
case layout_blocked_dec:
|
2009-04-19 11:49:08 +02:00
|
|
|
case layout_vs_blocked:
|
|
|
|
case layout_emff_ps2_blocked:
|
|
|
|
case layout_emff_ngc_blocked:
|
|
|
|
case layout_gsb_blocked:
|
|
|
|
case layout_xvas_blocked:
|
|
|
|
case layout_thp_blocked:
|
|
|
|
case layout_filp_blocked:
|
|
|
|
case layout_ivaud_blocked:
|
2010-04-20 22:26:10 +02:00
|
|
|
case layout_psx_mgav_blocked:
|
2010-05-02 21:16:35 +02:00
|
|
|
case layout_ps2_adm_blocked:
|
2010-05-10 10:02:22 +02:00
|
|
|
case layout_dsp_bdsp_blocked:
|
2010-12-03 23:48:51 +01:00
|
|
|
case layout_tra_blocked:
|
2010-12-06 23:22:06 +01:00
|
|
|
case layout_ps2_iab_blocked:
|
2017-06-10 02:25:49 +02:00
|
|
|
case layout_ps2_strlr_blocked:
|
|
|
|
case layout_rws_blocked:
|
2017-07-23 13:16:59 +02:00
|
|
|
case layout_hwas_blocked:
|
2017-08-20 02:18:48 +02:00
|
|
|
case layout_ea_sns_blocked:
|
2017-08-28 16:07:09 +02:00
|
|
|
case layout_blocked_awc:
|
2017-08-28 20:05:03 +02:00
|
|
|
case layout_blocked_vgs:
|
2008-03-04 08:15:25 +01:00
|
|
|
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
2010-11-24 05:27:59 +01:00
|
|
|
break;
|
2008-07-14 15:30:26 +02:00
|
|
|
case layout_interleave_byte:
|
|
|
|
render_vgmstream_interleave_byte(buffer,sample_count,vgmstream);
|
|
|
|
break;
|
2008-07-20 09:28:17 +02:00
|
|
|
case layout_acm:
|
2008-07-21 01:28:16 +02:00
|
|
|
case layout_mus_acm:
|
2008-07-20 09:28:17 +02:00
|
|
|
render_vgmstream_mus_acm(buffer,sample_count,vgmstream);
|
|
|
|
break;
|
2008-08-02 12:24:28 +02:00
|
|
|
case layout_aix:
|
|
|
|
render_vgmstream_aix(buffer,sample_count,vgmstream);
|
2009-01-17 07:35:39 +01:00
|
|
|
break;
|
2009-01-03 12:08:44 +01:00
|
|
|
case layout_aax:
|
|
|
|
render_vgmstream_aax(buffer,sample_count,vgmstream);
|
2008-08-02 12:24:28 +02:00
|
|
|
break;
|
2012-08-24 19:36:40 +02:00
|
|
|
case layout_scd_int:
|
|
|
|
render_vgmstream_scd_int(buffer,sample_count,vgmstream);
|
|
|
|
break;
|
2017-10-28 01:34:32 +02:00
|
|
|
default:
|
|
|
|
break;
|
2008-01-31 07:04:26 +01:00
|
|
|
}
|
|
|
|
}
|
2008-02-05 03:17:35 +01:00
|
|
|
|
2017-05-13 01:55:31 +02:00
|
|
|
/* get the size in samples of a single frame (1 or N channels), for interleaved/blocked layouts */
|
2008-02-05 03:17:35 +01:00
|
|
|
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_CRI_ADX:
|
2017-05-13 23:04:30 +02:00
|
|
|
case coding_CRI_ADX_fixed:
|
2017-05-14 00:37:24 +02:00
|
|
|
case coding_CRI_ADX_exp:
|
2011-08-20 14:00:01 +02:00
|
|
|
case coding_CRI_ADX_enc_8:
|
|
|
|
case coding_CRI_ADX_enc_9:
|
2017-05-13 22:17:27 +02:00
|
|
|
return (vgmstream->interleave_block_size - 2) * 2;
|
2009-01-04 16:36:06 +01:00
|
|
|
case coding_L5_555:
|
2008-02-05 03:17:35 +01:00
|
|
|
return 32;
|
|
|
|
case coding_NGC_DSP:
|
|
|
|
return 14;
|
|
|
|
case coding_PCM16LE:
|
2010-08-28 03:43:40 +02:00
|
|
|
case coding_PCM16LE_XOR_int:
|
2008-02-05 03:17:35 +01:00
|
|
|
case coding_PCM16BE:
|
2017-08-27 22:17:13 +02:00
|
|
|
case coding_PCM16_int:
|
2008-02-05 03:17:35 +01:00
|
|
|
case coding_PCM8:
|
2009-04-28 18:52:49 +02:00
|
|
|
case coding_PCM8_U:
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_PCM8_int:
|
2008-07-30 22:58:50 +02:00
|
|
|
case coding_PCM8_SB_int:
|
2008-11-23 13:21:36 +01:00
|
|
|
case coding_PCM8_U_int:
|
2017-06-09 22:26:09 +02:00
|
|
|
case coding_ULAW:
|
2017-10-08 17:51:54 +02:00
|
|
|
case coding_ALAW:
|
2017-08-18 18:54:21 +02:00
|
|
|
case coding_PCMFLOAT:
|
|
|
|
return 1;
|
2008-06-15 09:59:43 +02:00
|
|
|
#ifdef VGM_USE_VORBIS
|
2008-06-15 06:01:03 +02:00
|
|
|
case coding_ogg_vorbis:
|
2017-07-28 23:26:58 +02:00
|
|
|
case coding_VORBIS_custom:
|
2008-07-05 13:49:29 +02:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_MPEG
|
2017-07-29 13:05:23 +02:00
|
|
|
case coding_MPEG_custom:
|
2017-08-05 17:54:50 +02:00
|
|
|
case coding_MPEG_ealayer3:
|
2017-07-29 13:05:23 +02:00
|
|
|
case coding_MPEG_layer1:
|
|
|
|
case coding_MPEG_layer2:
|
|
|
|
case coding_MPEG_layer3:
|
2008-06-15 09:59:43 +02:00
|
|
|
#endif
|
2008-07-01 05:23:44 +02:00
|
|
|
case coding_SDX2:
|
2008-07-14 22:42:49 +02:00
|
|
|
case coding_SDX2_int:
|
2010-07-27 14:24:03 +02:00
|
|
|
case coding_CBD2:
|
2008-07-20 07:41:41 +02:00
|
|
|
case coding_ACM:
|
2008-08-03 16:58:03 +02:00
|
|
|
case coding_NWA0:
|
|
|
|
case coding_NWA1:
|
|
|
|
case coding_NWA2:
|
|
|
|
case coding_NWA3:
|
|
|
|
case coding_NWA4:
|
|
|
|
case coding_NWA5:
|
2009-09-04 06:19:39 +02:00
|
|
|
case coding_SASSC:
|
2008-02-05 03:17:35 +01:00
|
|
|
return 1;
|
2008-02-05 10:21:20 +01:00
|
|
|
case coding_NDS_IMA:
|
2009-12-16 07:12:53 +01:00
|
|
|
case coding_DAT4_IMA:
|
2009-04-19 11:49:08 +02:00
|
|
|
return (vgmstream->interleave_block_size-4)*2;
|
2008-02-13 15:31:21 +01:00
|
|
|
case coding_NGC_DTK:
|
|
|
|
return 28;
|
2008-02-14 23:10:08 +01:00
|
|
|
case coding_G721:
|
2017-11-19 03:32:21 +01:00
|
|
|
case coding_IMA:
|
2008-07-02 03:41:20 +02:00
|
|
|
case coding_DVI_IMA:
|
2011-02-06 10:49:57 +01:00
|
|
|
case coding_SNDS_IMA:
|
2017-01-25 20:25:39 +01:00
|
|
|
case coding_OTNS_IMA:
|
2017-11-05 17:06:40 +01:00
|
|
|
case coding_UBI_IMA:
|
2008-02-14 23:10:08 +01:00
|
|
|
return 1;
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_IMA_int:
|
|
|
|
case coding_DVI_IMA_int:
|
2017-11-18 22:25:44 +01:00
|
|
|
case coding_3DS_IMA:
|
2008-08-13 08:11:05 +02:00
|
|
|
case coding_AICA:
|
2009-04-19 11:49:08 +02:00
|
|
|
return 2;
|
2008-03-03 22:38:11 +01:00
|
|
|
case coding_NGC_AFC:
|
2017-01-17 19:37:47 +01:00
|
|
|
return 16;
|
2008-05-05 00:10:30 +02:00
|
|
|
case coding_PSX:
|
2008-07-25 21:02:29 +02:00
|
|
|
case coding_PSX_badflags:
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_PSX_bmdx:
|
|
|
|
case coding_HEVAG:
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_XA:
|
|
|
|
return 28;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_PSX_cfg:
|
2016-12-29 23:34:21 +01:00
|
|
|
return (vgmstream->interleave_block_size - 1) * 2; /* decodes 1 byte into 2 bytes */
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_XBOX:
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_XBOX_int:
|
2017-02-04 19:19:51 +01:00
|
|
|
case coding_FSB_IMA:
|
2017-01-15 20:44:52 +01:00
|
|
|
return 64;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_EA_XA:
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_EA_XA_int:
|
|
|
|
case coding_EA_XA_V2:
|
2008-05-05 00:10:30 +02:00
|
|
|
return 28;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_MAXIS_XA:
|
2009-09-01 23:28:55 +02:00
|
|
|
return 14*vgmstream->channels;
|
2017-08-20 02:18:48 +02:00
|
|
|
case coding_EA_XAS:
|
|
|
|
return 128;
|
2008-07-03 23:21:01 +02:00
|
|
|
case coding_WS:
|
2017-04-29 22:37:15 +02:00
|
|
|
/* only works if output sample size is 8 bit, which always is for WS ADPCM */
|
2008-07-04 02:06:51 +02:00
|
|
|
return vgmstream->ws_output_size;
|
2008-08-11 09:19:44 +02:00
|
|
|
case coding_MSADPCM:
|
2008-08-11 10:10:59 +02:00
|
|
|
return (vgmstream->interleave_block_size-(7-1)*vgmstream->channels)*2/vgmstream->channels;
|
2009-08-30 04:16:54 +02:00
|
|
|
case coding_APPLE_IMA4:
|
|
|
|
return 64;
|
2009-03-09 13:48:53 +01:00
|
|
|
case coding_MS_IMA:
|
2009-09-12 06:51:39 +02:00
|
|
|
case coding_RAD_IMA:
|
2017-04-11 19:59:29 +02:00
|
|
|
case coding_WWISE_IMA:
|
2017-06-24 23:30:10 +02:00
|
|
|
case coding_REF_IMA:
|
2009-03-09 13:48:53 +01:00
|
|
|
return (vgmstream->interleave_block_size-4*vgmstream->channels)*2/vgmstream->channels;
|
2017-08-28 16:07:09 +02:00
|
|
|
case coding_AWC_IMA:
|
|
|
|
return (0x800-4)*2;
|
2010-04-10 14:06:25 +02:00
|
|
|
case coding_RAD_IMA_mono:
|
|
|
|
return 32;
|
2008-12-28 07:29:43 +01:00
|
|
|
case coding_NDS_PROCYON:
|
|
|
|
return 30;
|
2010-03-21 05:23:18 +01:00
|
|
|
#ifdef VGM_USE_G7221
|
|
|
|
case coding_G7221C:
|
|
|
|
return 32000/50;
|
|
|
|
case coding_G7221:
|
|
|
|
return 16000/50;
|
2015-01-25 06:08:25 +01:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_G719
|
|
|
|
case coding_G719:
|
|
|
|
return 48000/50;
|
2016-07-17 08:02:27 +02:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
case coding_FFmpeg:
|
|
|
|
{
|
|
|
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
2016-11-29 20:22:20 +01:00
|
|
|
if (data) {
|
|
|
|
/* must know the full block size for edge loops */
|
2016-12-10 15:53:29 +01:00
|
|
|
return data->sampleBufferBlock;
|
2016-07-17 08:02:27 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
2010-03-21 05:23:18 +01:00
|
|
|
#endif
|
2011-01-13 09:11:58 +01:00
|
|
|
case coding_LSF:
|
|
|
|
return 54;
|
2011-05-07 13:05:05 +02:00
|
|
|
case coding_MTAF:
|
|
|
|
return 0x80*2;
|
2017-05-18 19:16:44 +02:00
|
|
|
case coding_MTA2:
|
|
|
|
return 0x80*2;
|
2017-04-28 17:26:25 +02:00
|
|
|
case coding_MC3:
|
|
|
|
return 10;
|
2016-06-28 09:20:37 +02:00
|
|
|
case coding_CRI_HCA:
|
|
|
|
return clHCA_samplesPerBlock;
|
2013-06-14 02:42:24 +02:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
2012-08-30 14:35:12 +02:00
|
|
|
case coding_MP4_AAC:
|
|
|
|
return ((mp4_aac_codec_data*)vgmstream->codec_data)->samples_per_frame;
|
2013-06-26 11:54:15 +02:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
2013-06-26 13:36:57 +02:00
|
|
|
case coding_AT3plus:
|
2013-06-26 11:54:15 +02:00
|
|
|
return 2048 - ((maiatrac3plus_codec_data*)vgmstream->codec_data)->samples_discard;
|
2013-06-14 02:42:24 +02:00
|
|
|
#endif
|
2008-02-05 03:17:35 +01:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-05 10:21:20 +01:00
|
|
|
int get_vgmstream_samples_per_shortframe(VGMSTREAM * vgmstream) {
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_NDS_IMA:
|
|
|
|
return (vgmstream->interleave_smallblock_size-4)*2;
|
|
|
|
default:
|
|
|
|
return get_vgmstream_samples_per_frame(vgmstream);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-13 01:55:31 +02:00
|
|
|
/* get the data size of a single frame (1 or N channels), for interleaved/blocked layouts */
|
2008-02-05 03:17:35 +01:00
|
|
|
int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_CRI_ADX:
|
2017-05-13 23:04:30 +02:00
|
|
|
case coding_CRI_ADX_fixed:
|
2017-05-14 00:37:24 +02:00
|
|
|
case coding_CRI_ADX_exp:
|
2011-08-20 14:00:01 +02:00
|
|
|
case coding_CRI_ADX_enc_8:
|
|
|
|
case coding_CRI_ADX_enc_9:
|
2017-05-13 23:04:30 +02:00
|
|
|
return vgmstream->interleave_block_size;
|
2009-01-04 16:36:06 +01:00
|
|
|
case coding_L5_555:
|
2008-02-05 03:17:35 +01:00
|
|
|
return 18;
|
|
|
|
case coding_NGC_DSP:
|
|
|
|
return 8;
|
|
|
|
case coding_PCM16LE:
|
2010-08-28 03:43:40 +02:00
|
|
|
case coding_PCM16LE_XOR_int:
|
2008-02-05 03:17:35 +01:00
|
|
|
case coding_PCM16BE:
|
2017-08-27 22:17:13 +02:00
|
|
|
case coding_PCM16_int:
|
2008-02-05 03:17:35 +01:00
|
|
|
return 2;
|
|
|
|
case coding_PCM8:
|
2009-04-28 18:52:49 +02:00
|
|
|
case coding_PCM8_U:
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_PCM8_int:
|
2008-07-30 22:58:50 +02:00
|
|
|
case coding_PCM8_SB_int:
|
2008-11-23 13:21:36 +01:00
|
|
|
case coding_PCM8_U_int:
|
2017-06-09 22:26:09 +02:00
|
|
|
case coding_ULAW:
|
2017-10-08 17:51:54 +02:00
|
|
|
case coding_ALAW:
|
2017-08-18 18:54:21 +02:00
|
|
|
return 1;
|
|
|
|
case coding_PCMFLOAT:
|
|
|
|
return 4;
|
2008-07-01 05:23:44 +02:00
|
|
|
case coding_SDX2:
|
2008-07-14 22:42:49 +02:00
|
|
|
case coding_SDX2_int:
|
2010-07-27 14:24:03 +02:00
|
|
|
case coding_CBD2:
|
2008-08-03 16:58:03 +02:00
|
|
|
case coding_NWA0:
|
|
|
|
case coding_NWA1:
|
|
|
|
case coding_NWA2:
|
|
|
|
case coding_NWA3:
|
|
|
|
case coding_NWA4:
|
|
|
|
case coding_NWA5:
|
2009-09-04 06:19:39 +02:00
|
|
|
case coding_SASSC:
|
2008-02-05 03:17:35 +01:00
|
|
|
return 1;
|
2009-03-09 13:48:53 +01:00
|
|
|
case coding_MS_IMA:
|
2009-09-12 06:51:39 +02:00
|
|
|
case coding_RAD_IMA:
|
2008-02-05 10:21:20 +01:00
|
|
|
case coding_NDS_IMA:
|
2009-12-16 07:12:53 +01:00
|
|
|
case coding_DAT4_IMA:
|
2017-04-11 19:59:29 +02:00
|
|
|
case coding_WWISE_IMA:
|
2017-06-24 23:30:10 +02:00
|
|
|
case coding_REF_IMA:
|
2008-02-05 10:21:20 +01:00
|
|
|
return vgmstream->interleave_block_size;
|
2017-08-28 16:07:09 +02:00
|
|
|
case coding_AWC_IMA:
|
|
|
|
return 0x800;
|
2010-04-10 14:06:25 +02:00
|
|
|
case coding_RAD_IMA_mono:
|
|
|
|
return 0x14;
|
2008-02-13 15:31:21 +01:00
|
|
|
case coding_NGC_DTK:
|
|
|
|
return 32;
|
2008-02-14 23:10:08 +01:00
|
|
|
case coding_G721:
|
2011-02-06 10:49:57 +01:00
|
|
|
case coding_SNDS_IMA:
|
2017-01-25 20:25:39 +01:00
|
|
|
case coding_OTNS_IMA:
|
2017-11-05 17:06:40 +01:00
|
|
|
case coding_UBI_IMA: /* variable (PCM then IMA) */
|
2008-02-14 23:10:08 +01:00
|
|
|
return 0;
|
2008-03-03 22:38:11 +01:00
|
|
|
case coding_NGC_AFC:
|
2017-01-17 19:37:47 +01:00
|
|
|
return 9;
|
2008-05-05 00:10:30 +02:00
|
|
|
case coding_PSX:
|
2008-07-25 21:02:29 +02:00
|
|
|
case coding_PSX_badflags:
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_PSX_bmdx:
|
|
|
|
case coding_HEVAG:
|
2008-12-28 07:29:43 +01:00
|
|
|
case coding_NDS_PROCYON:
|
2008-05-05 00:10:30 +02:00
|
|
|
return 16;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_PSX_cfg:
|
2016-12-29 23:34:21 +01:00
|
|
|
return vgmstream->interleave_block_size;
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_XA:
|
|
|
|
return 14*vgmstream->channels;
|
|
|
|
case coding_XBOX:
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_XBOX_int:
|
2017-02-04 19:19:51 +01:00
|
|
|
case coding_FSB_IMA:
|
2009-04-19 11:49:08 +02:00
|
|
|
return 36;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_EA_XA:
|
2017-07-08 00:27:36 +02:00
|
|
|
return 0x1E;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_EA_XA_int:
|
2017-07-08 00:27:36 +02:00
|
|
|
return 0x0F;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_MAXIS_XA:
|
2017-07-08 00:27:36 +02:00
|
|
|
return 0x0F*vgmstream->channels;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_EA_XA_V2:
|
|
|
|
return 1; /* the frame is variant in size (ADPCM frames of 0x0F or PCM frames) */
|
2017-08-20 02:18:48 +02:00
|
|
|
case coding_EA_XAS:
|
|
|
|
return 0x4c*vgmstream->channels;
|
2008-07-03 23:21:01 +02:00
|
|
|
case coding_WS:
|
|
|
|
return vgmstream->current_block_size;
|
2017-11-19 03:32:21 +01:00
|
|
|
case coding_IMA:
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_IMA_int:
|
2017-11-17 17:18:17 +01:00
|
|
|
case coding_DVI_IMA:
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_DVI_IMA_int:
|
2017-11-18 22:25:44 +01:00
|
|
|
case coding_3DS_IMA:
|
2017-11-19 03:32:21 +01:00
|
|
|
return 0x01;
|
2008-08-13 08:11:05 +02:00
|
|
|
case coding_AICA:
|
2017-11-19 03:32:21 +01:00
|
|
|
return 1;
|
2009-08-30 04:16:54 +02:00
|
|
|
case coding_APPLE_IMA4:
|
|
|
|
return 34;
|
2011-01-13 09:11:58 +01:00
|
|
|
case coding_LSF:
|
|
|
|
return 28;
|
2010-03-21 05:23:18 +01:00
|
|
|
#ifdef VGM_USE_G7221
|
|
|
|
case coding_G7221C:
|
|
|
|
case coding_G7221:
|
2013-06-26 11:54:15 +02:00
|
|
|
#endif
|
2015-08-13 01:09:10 +02:00
|
|
|
#ifdef VGM_USE_G719
|
2015-01-25 06:08:25 +01:00
|
|
|
case coding_G719:
|
|
|
|
#endif
|
2013-06-26 11:54:15 +02:00
|
|
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
2013-06-26 13:36:57 +02:00
|
|
|
case coding_AT3plus:
|
2016-07-17 08:02:27 +02:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
case coding_FFmpeg:
|
2010-03-21 05:23:18 +01:00
|
|
|
#endif
|
2008-08-11 09:19:44 +02:00
|
|
|
case coding_MSADPCM:
|
2011-05-07 13:05:05 +02:00
|
|
|
case coding_MTAF:
|
2008-08-11 09:19:44 +02:00
|
|
|
return vgmstream->interleave_block_size;
|
2017-05-18 19:16:44 +02:00
|
|
|
case coding_MTA2:
|
|
|
|
return 0x90;
|
2017-04-28 17:26:25 +02:00
|
|
|
case coding_MC3:
|
|
|
|
return 4;
|
2008-02-05 03:17:35 +01:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-05 10:21:20 +01:00
|
|
|
int get_vgmstream_shortframe_size(VGMSTREAM * vgmstream) {
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_NDS_IMA:
|
|
|
|
return vgmstream->interleave_smallblock_size;
|
|
|
|
default:
|
|
|
|
return get_vgmstream_frame_size(vgmstream);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-14 15:30:26 +02:00
|
|
|
void decode_vgmstream_mem(VGMSTREAM * vgmstream, int samples_written, int samples_to_do, sample * buffer, uint8_t * data, int channel) {
|
|
|
|
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_NGC_DSP:
|
|
|
|
decode_ngc_dsp_mem(&vgmstream->ch[channel],
|
|
|
|
buffer+samples_written*vgmstream->channels+channel,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do, data);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-05 03:17:35 +01:00
|
|
|
void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to_do, sample * buffer) {
|
|
|
|
int chan;
|
|
|
|
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_CRI_ADX:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_adx(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2017-05-13 22:17:27 +02:00
|
|
|
samples_to_do,
|
|
|
|
vgmstream->interleave_block_size);
|
2008-02-05 03:17:35 +01:00
|
|
|
}
|
|
|
|
|
2017-05-14 00:37:24 +02:00
|
|
|
break;
|
|
|
|
case coding_CRI_ADX_exp:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_adx_exp(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,
|
|
|
|
vgmstream->interleave_block_size);
|
|
|
|
}
|
|
|
|
|
2017-05-13 23:04:30 +02:00
|
|
|
break;
|
|
|
|
case coding_CRI_ADX_fixed:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_adx_fixed(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,
|
|
|
|
vgmstream->interleave_block_size);
|
2008-02-05 03:17:35 +01:00
|
|
|
}
|
|
|
|
|
2008-12-24 08:19:15 +01:00
|
|
|
break;
|
2011-08-20 14:00:01 +02:00
|
|
|
case coding_CRI_ADX_enc_8:
|
|
|
|
case coding_CRI_ADX_enc_9:
|
2008-12-24 08:19:15 +01:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_adx_enc(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2017-05-13 22:17:27 +02:00
|
|
|
samples_to_do,
|
|
|
|
vgmstream->interleave_block_size);
|
2008-12-24 08:19:15 +01:00
|
|
|
}
|
|
|
|
|
2008-02-05 03:17:35 +01:00
|
|
|
break;
|
|
|
|
case coding_NGC_DSP:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2008-03-03 22:38:11 +01:00
|
|
|
decode_ngc_dsp(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-02-05 03:17:35 +01:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case coding_PCM16LE:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm16LE(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2010-08-28 03:43:40 +02:00
|
|
|
case coding_PCM16LE_XOR_int:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm16LE_XOR_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-02-05 03:17:35 +01:00
|
|
|
case coding_PCM16BE:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm16BE(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-08-27 22:17:13 +02:00
|
|
|
case coding_PCM16_int:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm16_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,
|
|
|
|
vgmstream->codec_endian);
|
|
|
|
}
|
|
|
|
break;
|
2008-02-05 03:17:35 +01:00
|
|
|
case coding_PCM8:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm8(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2009-04-28 18:52:49 +02:00
|
|
|
case coding_PCM8_U:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm8_unsigned(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-07-14 22:42:49 +02:00
|
|
|
case coding_PCM8_int:
|
2008-07-14 21:21:45 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2008-07-14 22:42:49 +02:00
|
|
|
decode_pcm8_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-07-14 21:21:45 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-07-30 22:58:50 +02:00
|
|
|
case coding_PCM8_SB_int:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm8_sb_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-11-23 13:21:36 +01:00
|
|
|
case coding_PCM8_U_int:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_pcm8_unsigned_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-06-09 22:26:09 +02:00
|
|
|
case coding_ULAW:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ulaw(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-10-08 17:51:54 +02:00
|
|
|
case coding_ALAW:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_alaw(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-08-18 18:54:21 +02:00
|
|
|
case coding_PCMFLOAT:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-08-27 22:17:13 +02:00
|
|
|
decode_pcmfloat(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2017-08-18 18:54:21 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2017-08-27 22:17:13 +02:00
|
|
|
samples_to_do,
|
|
|
|
vgmstream->codec_endian);
|
2017-08-18 18:54:21 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2008-02-05 10:21:20 +01:00
|
|
|
case coding_NDS_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_nds_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-05-24 00:52:02 +02:00
|
|
|
break;
|
2009-12-16 07:12:53 +01:00
|
|
|
case coding_DAT4_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_dat4_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_XBOX:
|
2008-05-24 00:52:02 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2008-09-21 16:58:50 +02:00
|
|
|
decode_xbox_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-05-24 00:52:02 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
2009-03-09 13:48:53 +01:00
|
|
|
break;
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_XBOX_int:
|
2009-06-29 23:58:40 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-10-27 18:56:34 +02:00
|
|
|
decode_xbox_ima_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2009-06-29 23:58:40 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_MS_IMA:
|
2009-03-09 13:48:53 +01:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ms_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
2008-02-05 10:21:20 +01:00
|
|
|
break;
|
2009-09-12 06:51:39 +02:00
|
|
|
case coding_RAD_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_rad_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2010-04-10 14:06:25 +02:00
|
|
|
case coding_RAD_IMA_mono:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_rad_ima_mono(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-02-13 15:31:21 +01:00
|
|
|
case coding_NGC_DTK:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ngc_dtk(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2008-02-14 23:10:08 +01:00
|
|
|
case coding_G721:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_g721(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-03-03 22:38:11 +01:00
|
|
|
case coding_NGC_AFC:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ngc_afc(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-05-04 22:36:40 +02:00
|
|
|
case coding_PSX:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-01-08 01:09:20 +01:00
|
|
|
decode_psx(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-05-04 22:36:40 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-06-25 22:39:15 +02:00
|
|
|
break;
|
2008-07-25 21:02:29 +02:00
|
|
|
case coding_PSX_badflags:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_psx_badflags(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_PSX_bmdx:
|
2008-06-25 22:39:15 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-01-08 01:09:20 +01:00
|
|
|
decode_psx_bmdx(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-06-25 22:39:15 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-11-07 00:30:33 +01:00
|
|
|
break;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_HEVAG:
|
2016-12-21 20:44:16 +01:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-01-08 01:09:20 +01:00
|
|
|
decode_hevag(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2016-12-21 20:44:16 +01:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_PSX_cfg:
|
2016-12-21 23:00:34 +01:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-01-08 01:09:20 +01:00
|
|
|
decode_psx_configurable(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2016-12-21 23:00:34 +01:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2016-12-29 23:34:21 +01:00
|
|
|
samples_to_do, vgmstream->interleave_block_size);
|
2016-12-21 23:00:34 +01:00
|
|
|
}
|
|
|
|
break;
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_XA:
|
2008-05-10 21:59:29 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2008-07-14 22:42:49 +02:00
|
|
|
decode_xa(vgmstream,buffer+samples_written*vgmstream->channels+chan,
|
2008-05-10 21:59:29 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2008-07-14 22:42:49 +02:00
|
|
|
samples_to_do,chan);
|
2008-05-10 21:59:29 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-01-08 01:09:20 +01:00
|
|
|
case coding_EA_XA:
|
2008-06-02 19:58:08 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-01-08 01:09:20 +01:00
|
|
|
decode_ea_xa(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-06-02 19:58:08 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_EA_XA_int:
|
2008-07-14 21:21:45 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-07-21 19:19:58 +02:00
|
|
|
decode_ea_xa_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2017-07-08 00:27:36 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_EA_XA_V2:
|
2017-07-08 00:27:36 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-07-21 19:19:58 +02:00
|
|
|
decode_ea_xa_v2(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-07-14 21:21:45 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-07-21 19:19:58 +02:00
|
|
|
case coding_MAXIS_XA:
|
2009-09-01 23:28:55 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-07-21 19:19:58 +02:00
|
|
|
decode_maxis_xa(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2009-09-01 23:28:55 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2017-08-20 02:18:48 +02:00
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case coding_EA_XAS:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ea_xas(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2009-09-01 23:28:55 +02:00
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2008-06-15 06:01:03 +02:00
|
|
|
#ifdef VGM_USE_VORBIS
|
|
|
|
case coding_ogg_vorbis:
|
|
|
|
decode_ogg_vorbis(vgmstream->codec_data,
|
|
|
|
buffer+samples_written*vgmstream->channels,samples_to_do,
|
|
|
|
vgmstream->channels);
|
|
|
|
break;
|
2017-03-25 14:57:44 +01:00
|
|
|
|
2017-07-28 23:26:58 +02:00
|
|
|
case coding_VORBIS_custom:
|
|
|
|
decode_vorbis_custom(vgmstream,
|
2017-04-22 19:25:54 +02:00
|
|
|
buffer+samples_written*vgmstream->channels,samples_to_do,
|
|
|
|
vgmstream->channels);
|
|
|
|
break;
|
2008-06-15 06:01:03 +02:00
|
|
|
#endif
|
2016-06-28 09:20:37 +02:00
|
|
|
case coding_CRI_HCA:
|
|
|
|
decode_hca(vgmstream->codec_data,
|
|
|
|
buffer+samples_written*vgmstream->channels,samples_to_do,
|
|
|
|
vgmstream->channels);
|
|
|
|
break;
|
2016-07-17 08:02:27 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
case coding_FFmpeg:
|
|
|
|
decode_ffmpeg(vgmstream,
|
|
|
|
buffer+samples_written*vgmstream->channels,
|
|
|
|
samples_to_do,
|
|
|
|
vgmstream->channels);
|
|
|
|
break;
|
|
|
|
#endif
|
2013-06-14 02:42:24 +02:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
2012-08-30 14:35:12 +02:00
|
|
|
case coding_MP4_AAC:
|
|
|
|
decode_mp4_aac(vgmstream->codec_data,
|
|
|
|
buffer+samples_written*vgmstream->channels,samples_to_do,
|
|
|
|
vgmstream->channels);
|
|
|
|
break;
|
2013-06-14 02:42:24 +02:00
|
|
|
#endif
|
2008-07-01 05:23:44 +02:00
|
|
|
case coding_SDX2:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_sdx2(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-07-14 22:42:49 +02:00
|
|
|
break;
|
|
|
|
case coding_SDX2_int:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_sdx2_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-07-01 05:23:44 +02:00
|
|
|
break;
|
2010-07-27 14:24:03 +02:00
|
|
|
case coding_CBD2:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_cbd2(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case coding_CBD2_int:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_cbd2_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-11-19 03:32:21 +01:00
|
|
|
case coding_IMA:
|
|
|
|
case coding_IMA_int:
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_DVI_IMA:
|
2017-04-29 02:53:36 +02:00
|
|
|
case coding_DVI_IMA_int:
|
2008-07-02 03:41:20 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2017-11-19 03:32:21 +01:00
|
|
|
int is_stereo = (vgmstream->channels > 1 && vgmstream->coding_type == coding_IMA)
|
|
|
|
|| (vgmstream->channels > 1 && vgmstream->coding_type == coding_DVI_IMA);
|
2017-11-17 17:18:17 +01:00
|
|
|
int is_high_first = vgmstream->coding_type == coding_DVI_IMA || vgmstream->coding_type == coding_DVI_IMA_int;
|
|
|
|
|
|
|
|
decode_standard_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2008-07-14 21:21:45 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
2017-11-17 17:18:17 +01:00
|
|
|
samples_to_do, chan, is_stereo, is_high_first);
|
2008-07-14 21:21:45 +02:00
|
|
|
}
|
2008-07-02 03:41:20 +02:00
|
|
|
break;
|
2017-11-18 22:25:44 +01:00
|
|
|
case coding_3DS_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_3ds_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2009-08-30 04:16:54 +02:00
|
|
|
case coding_APPLE_IMA4:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_apple_ima4(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2011-02-06 10:49:57 +01:00
|
|
|
case coding_SNDS_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_snds_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-01-25 20:25:39 +01:00
|
|
|
case coding_OTNS_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_otns_ima(vgmstream, &vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2017-02-04 19:19:51 +01:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case coding_FSB_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_fsb_ima(vgmstream, &vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
2017-01-25 20:25:39 +01:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-04-11 19:59:29 +02:00
|
|
|
case coding_WWISE_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_wwise_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-06-24 23:30:10 +02:00
|
|
|
case coding_REF_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ref_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-08-28 16:07:09 +02:00
|
|
|
case coding_AWC_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_awc_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-11-05 17:06:40 +01:00
|
|
|
case coding_UBI_IMA:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_ubi_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do,chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-01-25 20:25:39 +01:00
|
|
|
|
2008-07-03 23:21:01 +02:00
|
|
|
case coding_WS:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2008-07-04 02:06:51 +02:00
|
|
|
decode_ws(vgmstream,chan,buffer+samples_written*vgmstream->channels+chan,
|
2008-07-03 23:21:01 +02:00
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2008-07-05 13:49:29 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
2017-07-29 13:05:23 +02:00
|
|
|
case coding_MPEG_custom:
|
2017-08-05 17:54:50 +02:00
|
|
|
case coding_MPEG_ealayer3:
|
2017-07-29 13:05:23 +02:00
|
|
|
case coding_MPEG_layer1:
|
|
|
|
case coding_MPEG_layer2:
|
|
|
|
case coding_MPEG_layer3:
|
2008-07-06 17:33:38 +02:00
|
|
|
decode_mpeg(
|
2017-02-18 18:27:21 +01:00
|
|
|
vgmstream,
|
|
|
|
buffer+samples_written*vgmstream->channels,
|
|
|
|
samples_to_do,
|
2008-07-06 17:33:38 +02:00
|
|
|
vgmstream->channels);
|
2008-07-05 13:49:29 +02:00
|
|
|
break;
|
2010-03-21 05:23:18 +01:00
|
|
|
#endif
|
|
|
|
#ifdef VGM_USE_G7221
|
|
|
|
case coding_G7221:
|
|
|
|
case coding_G7221C:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_g7221(vgmstream,
|
2010-03-23 21:57:12 +01:00
|
|
|
buffer+samples_written*vgmstream->channels+chan,
|
2010-03-21 05:23:18 +01:00
|
|
|
vgmstream->channels,
|
|
|
|
samples_to_do,
|
|
|
|
chan);
|
|
|
|
}
|
|
|
|
break;
|
2013-06-26 11:54:15 +02:00
|
|
|
#endif
|
2015-01-25 06:08:25 +01:00
|
|
|
#ifdef VGM_USE_G719
|
|
|
|
case coding_G719:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_g719(vgmstream,
|
|
|
|
buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,
|
|
|
|
samples_to_do,
|
|
|
|
chan);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
2013-06-26 11:54:15 +02:00
|
|
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
2013-06-26 13:36:57 +02:00
|
|
|
case coding_AT3plus:
|
2013-06-26 11:54:15 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
2013-06-26 13:36:57 +02:00
|
|
|
decode_at3plus(vgmstream,
|
2013-06-26 11:54:15 +02:00
|
|
|
buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,
|
|
|
|
samples_to_do,
|
|
|
|
chan);
|
|
|
|
}
|
|
|
|
break;
|
2008-08-02 12:24:28 +02:00
|
|
|
#endif
|
2008-07-20 07:41:41 +02:00
|
|
|
case coding_ACM:
|
2008-07-20 09:28:17 +02:00
|
|
|
/* handled in its own layout, here to quiet compiler */
|
2008-07-20 07:41:41 +02:00
|
|
|
break;
|
2008-08-03 16:58:03 +02:00
|
|
|
case coding_NWA0:
|
|
|
|
case coding_NWA1:
|
|
|
|
case coding_NWA2:
|
|
|
|
case coding_NWA3:
|
|
|
|
case coding_NWA4:
|
|
|
|
case coding_NWA5:
|
|
|
|
decode_nwa(((nwa_codec_data*)vgmstream->codec_data)->nwa,
|
|
|
|
buffer+samples_written*vgmstream->channels,
|
|
|
|
samples_to_do
|
|
|
|
);
|
|
|
|
break;
|
2008-08-11 09:19:44 +02:00
|
|
|
case coding_MSADPCM:
|
|
|
|
if (vgmstream->channels == 2) {
|
|
|
|
decode_msadpcm_stereo(vgmstream,
|
|
|
|
buffer+samples_written*vgmstream->channels,
|
|
|
|
vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2010-04-12 05:35:58 +02:00
|
|
|
else if (vgmstream->channels == 1)
|
|
|
|
{
|
|
|
|
decode_msadpcm_mono(vgmstream,
|
|
|
|
buffer+samples_written*vgmstream->channels,
|
|
|
|
vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-08-11 10:10:59 +02:00
|
|
|
break;
|
2009-04-19 11:49:08 +02:00
|
|
|
case coding_AICA:
|
2008-08-13 08:11:05 +02:00
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_aica(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
break;
|
2008-12-28 07:29:43 +01:00
|
|
|
case coding_NDS_PROCYON:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_nds_procyon(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2009-01-04 16:36:06 +01:00
|
|
|
break;
|
|
|
|
case coding_L5_555:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_l5_555(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
|
2009-09-04 06:19:39 +02:00
|
|
|
break;
|
|
|
|
case coding_SASSC:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_SASSC(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
|
|
|
|
2011-01-13 09:11:58 +01:00
|
|
|
break;
|
|
|
|
case coding_LSF:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_lsf(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels,vgmstream->samples_into_block,
|
|
|
|
samples_to_do);
|
|
|
|
}
|
2008-12-28 07:29:43 +01:00
|
|
|
break;
|
2011-05-07 13:05:05 +02:00
|
|
|
case coding_MTAF:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_mtaf(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels, vgmstream->samples_into_block, samples_to_do,
|
|
|
|
chan, vgmstream->channels);
|
|
|
|
}
|
|
|
|
break;
|
2017-05-18 19:16:44 +02:00
|
|
|
case coding_MTA2:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_mta2(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels, vgmstream->samples_into_block, samples_to_do,
|
|
|
|
chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-04-28 17:26:25 +02:00
|
|
|
case coding_MC3:
|
|
|
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
|
|
|
decode_mc3(vgmstream, &vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
|
|
|
vgmstream->channels, vgmstream->samples_into_block, samples_to_do,
|
|
|
|
chan);
|
|
|
|
}
|
|
|
|
break;
|
2017-10-28 01:34:32 +02:00
|
|
|
default:
|
|
|
|
break;
|
2008-02-05 03:17:35 +01:00
|
|
|
}
|
|
|
|
}
|
2008-02-05 07:21:57 +01:00
|
|
|
|
|
|
|
int vgmstream_samples_to_do(int samples_this_block, int samples_per_frame, VGMSTREAM * vgmstream) {
|
|
|
|
int samples_to_do;
|
|
|
|
int samples_left_this_block;
|
|
|
|
|
|
|
|
samples_left_this_block = samples_this_block - vgmstream->samples_into_block;
|
|
|
|
samples_to_do = samples_left_this_block;
|
|
|
|
|
|
|
|
/* fun loopy crap */
|
|
|
|
/* Why did I think this would be any simpler? */
|
|
|
|
if (vgmstream->loop_flag) {
|
|
|
|
/* are we going to hit the loop end during this block? */
|
|
|
|
if (vgmstream->current_sample+samples_left_this_block > vgmstream->loop_end_sample) {
|
|
|
|
/* only do to just before it */
|
|
|
|
samples_to_do = vgmstream->loop_end_sample-vgmstream->current_sample;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* are we going to hit the loop start during this block? */
|
|
|
|
if (!vgmstream->hit_loop && vgmstream->current_sample+samples_left_this_block > vgmstream->loop_start_sample) {
|
|
|
|
/* only do to just before it */
|
|
|
|
samples_to_do = vgmstream->loop_start_sample-vgmstream->current_sample;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if it's a framed encoding don't do more than one frame */
|
2017-04-29 22:37:15 +02:00
|
|
|
if (samples_per_frame>1 && (vgmstream->samples_into_block%samples_per_frame)+samples_to_do>samples_per_frame)
|
|
|
|
samples_to_do = samples_per_frame - (vgmstream->samples_into_block%samples_per_frame);
|
2008-02-05 07:21:57 +01:00
|
|
|
|
|
|
|
return samples_to_do;
|
|
|
|
}
|
|
|
|
|
2017-05-18 19:55:00 +02:00
|
|
|
/* loop if end sample is reached, and return 1 if we did loop */
|
2008-02-05 07:21:57 +01:00
|
|
|
int vgmstream_do_loop(VGMSTREAM * vgmstream) {
|
2017-05-18 19:55:00 +02:00
|
|
|
/*if (!vgmstream->loop_flag) return 0;*/
|
2017-04-29 22:37:15 +02:00
|
|
|
|
2017-05-18 19:55:00 +02:00
|
|
|
/* is this the loop end? = new loop, continue from loop_start_sample */
|
2017-04-29 22:37:15 +02:00
|
|
|
if (vgmstream->current_sample==vgmstream->loop_end_sample) {
|
|
|
|
|
2017-05-18 19:55:00 +02:00
|
|
|
/* disable looping if target count reached and continue normally
|
|
|
|
* (only needed with the "play stream end after looping N times" option enabled) */
|
|
|
|
vgmstream->loop_count++;
|
|
|
|
if (vgmstream->loop_target && vgmstream->loop_target == vgmstream->loop_count) {
|
|
|
|
vgmstream->loop_flag = 0; /* could be improved but works ok */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
/* against everything I hold sacred, preserve adpcm
|
|
|
|
* history through loop for certain types */
|
|
|
|
if (vgmstream->meta_type == meta_DSP_STD ||
|
|
|
|
vgmstream->meta_type == meta_DSP_RS03 ||
|
|
|
|
vgmstream->meta_type == meta_DSP_CSTR ||
|
|
|
|
vgmstream->coding_type == coding_PSX ||
|
|
|
|
vgmstream->coding_type == coding_PSX_bmdx ||
|
|
|
|
vgmstream->coding_type == coding_PSX_badflags) {
|
|
|
|
int i;
|
|
|
|
for (i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->loop_ch[i].adpcm_history1_16 = vgmstream->ch[i].adpcm_history1_16;
|
|
|
|
vgmstream->loop_ch[i].adpcm_history2_16 = vgmstream->ch[i].adpcm_history2_16;
|
|
|
|
vgmstream->loop_ch[i].adpcm_history1_32 = vgmstream->ch[i].adpcm_history1_32;
|
|
|
|
vgmstream->loop_ch[i].adpcm_history2_32 = vgmstream->ch[i].adpcm_history2_32;
|
2008-03-25 08:30:04 +01:00
|
|
|
}
|
2017-04-29 22:37:15 +02:00
|
|
|
}
|
2016-12-21 20:44:16 +01:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
|
|
|
|
/* prepare certain codecs' internal state for looping */
|
|
|
|
|
|
|
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
|
|
|
loop_hca(vgmstream);
|
|
|
|
}
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2008-06-15 06:01:03 +02:00
|
|
|
#ifdef VGM_USE_VORBIS
|
2017-04-29 22:37:15 +02:00
|
|
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
|
|
|
seek_ogg_vorbis(vgmstream, vgmstream->loop_sample);
|
|
|
|
}
|
2017-03-25 14:57:44 +01:00
|
|
|
|
2017-07-28 23:26:58 +02:00
|
|
|
if (vgmstream->coding_type==coding_VORBIS_custom) {
|
|
|
|
seek_vorbis_custom(vgmstream, vgmstream->loop_start_sample);
|
2017-04-29 22:37:15 +02:00
|
|
|
}
|
2008-07-06 17:33:38 +02:00
|
|
|
#endif
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2016-07-17 08:02:27 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
2017-04-29 22:37:15 +02:00
|
|
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
|
|
|
seek_ffmpeg(vgmstream, vgmstream->loop_start_sample);
|
|
|
|
}
|
2017-01-08 01:09:20 +01:00
|
|
|
#endif
|
|
|
|
|
2013-06-14 02:42:24 +02:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
2017-04-29 22:37:15 +02:00
|
|
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
|
|
|
seek_mp4_aac(vgmstream, vgmstream->loop_sample);
|
|
|
|
}
|
2013-06-14 02:42:24 +02:00
|
|
|
#endif
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2013-06-26 11:54:15 +02:00
|
|
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
2017-04-29 22:37:15 +02:00
|
|
|
if (vgmstream->coding_type==coding_AT3plus) {
|
|
|
|
seek_at3plus(vgmstream, vgmstream->loop_sample);
|
|
|
|
}
|
2013-06-26 11:54:15 +02:00
|
|
|
#endif
|
2017-01-08 01:09:20 +01:00
|
|
|
|
2008-07-06 17:33:38 +02:00
|
|
|
#ifdef VGM_USE_MPEG
|
2017-07-29 13:05:23 +02:00
|
|
|
if (vgmstream->coding_type==coding_MPEG_custom ||
|
2017-08-05 17:54:50 +02:00
|
|
|
vgmstream->coding_type==coding_MPEG_ealayer3 ||
|
2017-07-29 13:05:23 +02:00
|
|
|
vgmstream->coding_type==coding_MPEG_layer1 ||
|
|
|
|
vgmstream->coding_type==coding_MPEG_layer2 ||
|
|
|
|
vgmstream->coding_type==coding_MPEG_layer3) {
|
|
|
|
seek_mpeg(vgmstream, vgmstream->loop_sample);
|
2017-04-29 22:37:15 +02:00
|
|
|
}
|
2008-06-15 06:01:03 +02:00
|
|
|
#endif
|
2008-08-03 17:21:05 +02:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
if (vgmstream->coding_type == coding_NWA0 ||
|
|
|
|
vgmstream->coding_type == coding_NWA1 ||
|
|
|
|
vgmstream->coding_type == coding_NWA2 ||
|
|
|
|
vgmstream->coding_type == coding_NWA3 ||
|
|
|
|
vgmstream->coding_type == coding_NWA4 ||
|
|
|
|
vgmstream->coding_type == coding_NWA5)
|
|
|
|
{
|
|
|
|
nwa_codec_data *data = vgmstream->codec_data;
|
|
|
|
seek_nwa(data->nwa, vgmstream->loop_sample);
|
|
|
|
}
|
2008-08-03 17:21:05 +02:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
/* restore! */
|
|
|
|
memcpy(vgmstream->ch,vgmstream->loop_ch,sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
|
|
|
|
vgmstream->current_sample = vgmstream->loop_sample;
|
|
|
|
vgmstream->samples_into_block = vgmstream->loop_samples_into_block;
|
|
|
|
vgmstream->current_block_size = vgmstream->loop_block_size;
|
|
|
|
vgmstream->current_block_offset = vgmstream->loop_block_offset;
|
|
|
|
vgmstream->next_block_offset = vgmstream->loop_next_block_offset;
|
2008-08-03 17:21:05 +02:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
return 1; /* looped */
|
|
|
|
}
|
2008-02-05 07:21:57 +01:00
|
|
|
|
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
/* is this the loop start? */
|
|
|
|
if (!vgmstream->hit_loop && vgmstream->current_sample==vgmstream->loop_start_sample) {
|
|
|
|
/* save! */
|
|
|
|
memcpy(vgmstream->loop_ch,vgmstream->ch,sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
|
2008-02-05 07:21:57 +01:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
vgmstream->loop_sample = vgmstream->current_sample;
|
|
|
|
vgmstream->loop_samples_into_block = vgmstream->samples_into_block;
|
|
|
|
vgmstream->loop_block_size = vgmstream->current_block_size;
|
|
|
|
vgmstream->loop_block_offset = vgmstream->current_block_offset;
|
|
|
|
vgmstream->loop_next_block_offset = vgmstream->next_block_offset;
|
|
|
|
vgmstream->hit_loop = 1;
|
|
|
|
}
|
2008-02-05 07:21:57 +01:00
|
|
|
|
2017-04-29 22:37:15 +02:00
|
|
|
return 0; /* not looped */
|
2008-02-05 07:21:57 +01:00
|
|
|
}
|
2008-02-05 07:44:44 +01:00
|
|
|
|
2008-03-11 02:27:59 +01:00
|
|
|
/* build a descriptive string */
|
|
|
|
void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
|
|
|
#define TEMPSIZE 256
|
|
|
|
char temp[TEMPSIZE];
|
2017-01-08 02:27:35 +01:00
|
|
|
const char* description;
|
2008-03-11 02:27:59 +01:00
|
|
|
|
2008-02-05 07:44:44 +01:00
|
|
|
if (!vgmstream) {
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"NULL VGMSTREAM");
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
2008-02-05 07:44:44 +01:00
|
|
|
return;
|
|
|
|
}
|
2008-03-11 02:27:59 +01:00
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"sample rate: %d Hz\n"
|
2008-03-11 02:27:59 +01:00
|
|
|
"channels: %d\n",
|
2017-04-29 02:19:27 +02:00
|
|
|
vgmstream->sample_rate,
|
|
|
|
vgmstream->channels);
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
|
|
|
|
2008-02-05 07:44:44 +01:00
|
|
|
if (vgmstream->loop_flag) {
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"loop start: %d samples (%.4f seconds)\n"
|
2011-07-07 17:25:38 +02:00
|
|
|
"loop end: %d samples (%.4f seconds)\n",
|
2008-03-11 02:27:59 +01:00
|
|
|
vgmstream->loop_start_sample,
|
|
|
|
(double)vgmstream->loop_start_sample/vgmstream->sample_rate,
|
|
|
|
vgmstream->loop_end_sample,
|
|
|
|
(double)vgmstream->loop_end_sample/vgmstream->sample_rate);
|
|
|
|
concatn(length,desc,temp);
|
2008-02-05 07:44:44 +01:00
|
|
|
}
|
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"stream total samples: %d (%.4f seconds)\n",
|
2008-03-11 02:27:59 +01:00
|
|
|
vgmstream->num_samples,
|
|
|
|
(double)vgmstream->num_samples/vgmstream->sample_rate);
|
|
|
|
concatn(length,desc,temp);
|
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"encoding: ");
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
2008-02-05 07:44:44 +01:00
|
|
|
switch (vgmstream->coding_type) {
|
2016-07-17 08:02:27 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
2017-01-08 02:27:35 +01:00
|
|
|
case coding_FFmpeg: {
|
|
|
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
|
|
|
if (vgmstream->codec_data) {
|
|
|
|
if (data->codec && data->codec->long_name) {
|
2017-04-29 16:23:50 +02:00
|
|
|
snprintf(temp,TEMPSIZE,"%s",data->codec->long_name);
|
2017-01-08 02:27:35 +01:00
|
|
|
} else if (data->codec && data->codec->name) {
|
2017-04-29 16:23:50 +02:00
|
|
|
snprintf(temp,TEMPSIZE,"%s",data->codec->name);
|
2017-01-08 02:27:35 +01:00
|
|
|
} else {
|
|
|
|
snprintf(temp,TEMPSIZE,"FFmpeg (unknown codec)");
|
2016-07-17 08:02:27 +02:00
|
|
|
}
|
2017-01-08 02:27:35 +01:00
|
|
|
} else {
|
|
|
|
snprintf(temp,TEMPSIZE,"FFmpeg");
|
2016-07-17 08:02:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-01-08 02:27:35 +01:00
|
|
|
}
|
2016-07-17 08:02:27 +02:00
|
|
|
#endif
|
2008-02-05 07:44:44 +01:00
|
|
|
default:
|
2017-01-08 02:27:35 +01:00
|
|
|
description = get_vgmstream_coding_description(vgmstream->coding_type);
|
|
|
|
if (!description)
|
|
|
|
description = "CANNOT DECODE";
|
2017-04-29 16:23:50 +02:00
|
|
|
snprintf(temp,TEMPSIZE,"%s",description);
|
2017-01-08 02:27:35 +01:00
|
|
|
break;
|
2008-02-05 07:44:44 +01:00
|
|
|
}
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"\nlayout: ");
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
2008-02-05 07:44:44 +01:00
|
|
|
switch (vgmstream->layout_type) {
|
|
|
|
default:
|
2017-01-08 02:27:35 +01:00
|
|
|
description = get_vgmstream_layout_description(vgmstream->layout_type);
|
|
|
|
if (!description)
|
|
|
|
description = "INCONCEIVABLE";
|
2017-04-29 16:23:50 +02:00
|
|
|
snprintf(temp,TEMPSIZE,"%s",description);
|
2017-01-08 02:27:35 +01:00
|
|
|
break;
|
2008-02-05 07:44:44 +01:00
|
|
|
}
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"\n");
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
2008-02-05 07:44:44 +01:00
|
|
|
|
2017-01-08 02:27:35 +01:00
|
|
|
if (vgmstream->layout_type == layout_interleave
|
|
|
|
|| vgmstream->layout_type == layout_interleave_shortblock
|
|
|
|
|| vgmstream->layout_type == layout_interleave_byte) {
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"interleave: %#x bytes\n",
|
2008-05-18 19:17:49 +02:00
|
|
|
(int32_t)vgmstream->interleave_block_size);
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
|
|
|
|
2008-02-05 07:44:44 +01:00
|
|
|
if (vgmstream->layout_type == layout_interleave_shortblock) {
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"last block interleave: %#x bytes\n",
|
2008-05-18 19:17:49 +02:00
|
|
|
(int32_t)vgmstream->interleave_smallblock_size);
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
2008-02-05 07:44:44 +01:00
|
|
|
}
|
|
|
|
}
|
2008-03-03 22:38:11 +01:00
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
/* codecs with blocks + headers (there are more, this is a start) */
|
|
|
|
if (vgmstream->layout_type == layout_none && vgmstream->interleave_block_size > 0) {
|
|
|
|
switch (vgmstream->coding_type) {
|
|
|
|
case coding_MSADPCM:
|
|
|
|
case coding_MS_IMA:
|
|
|
|
case coding_MC3:
|
|
|
|
case coding_WWISE_IMA:
|
2017-06-24 23:30:10 +02:00
|
|
|
case coding_REF_IMA:
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"block size: %#x bytes\n",
|
|
|
|
(int32_t)vgmstream->interleave_block_size);
|
|
|
|
concatn(length,desc,temp);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-03-11 02:27:59 +01:00
|
|
|
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"metadata from: ");
|
|
|
|
concatn(length,desc,temp);
|
2008-03-03 22:38:11 +01:00
|
|
|
switch (vgmstream->meta_type) {
|
2017-01-08 02:27:35 +01:00
|
|
|
default:
|
|
|
|
description = get_vgmstream_meta_description(vgmstream->meta_type);
|
|
|
|
if (!description)
|
|
|
|
description = "THEY SHOULD HAVE SENT A POET";
|
2017-04-29 16:23:50 +02:00
|
|
|
snprintf(temp,TEMPSIZE,"%s",description);
|
2008-03-03 22:38:11 +01:00
|
|
|
break;
|
|
|
|
}
|
2008-03-11 02:27:59 +01:00
|
|
|
concatn(length,desc,temp);
|
2017-03-04 02:05:07 +01:00
|
|
|
|
|
|
|
/* only interesting if more than one */
|
|
|
|
if (vgmstream->num_streams > 1) {
|
2017-04-29 02:19:27 +02:00
|
|
|
snprintf(temp,TEMPSIZE,
|
2017-08-19 15:59:29 +02:00
|
|
|
"\nstream count: %d",
|
2017-04-29 02:19:27 +02:00
|
|
|
vgmstream->num_streams);
|
2017-03-04 02:05:07 +01:00
|
|
|
concatn(length,desc,temp);
|
|
|
|
}
|
2017-08-12 11:27:10 +02:00
|
|
|
|
|
|
|
if (vgmstream->num_streams > 1 && vgmstream->stream_index > 0) {
|
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"\nstream index: %d",
|
|
|
|
vgmstream->stream_index);
|
|
|
|
concatn(length,desc,temp);
|
|
|
|
}
|
|
|
|
if (vgmstream->stream_name[0] != '\0') {
|
|
|
|
snprintf(temp,TEMPSIZE,
|
|
|
|
"\nstream name: %s",
|
|
|
|
vgmstream->stream_name);
|
|
|
|
concatn(length,desc,temp);
|
|
|
|
}
|
2008-02-05 07:44:44 +01:00
|
|
|
}
|
2008-03-25 08:30:04 +01:00
|
|
|
|
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* See if there is a second file which may be the second channel, given an already opened mono vgmstream.
|
|
|
|
* If a suitable file is found, open it and change opened_vgmstream to a stereo vgmstream. */
|
|
|
|
static void try_dual_file_stereo(VGMSTREAM * opened_vgmstream, STREAMFILE *streamFile, VGMSTREAM*(*init_vgmstream_function)(STREAMFILE *)) {
|
|
|
|
/* filename search pairs for dual file stereo */
|
|
|
|
static const char * const dfs_pairs[][2] = {
|
|
|
|
{"L","R"},
|
|
|
|
{"l","r"},
|
|
|
|
{"_0","_1"},
|
|
|
|
{"left","right"},
|
|
|
|
{"Left","Right"},
|
|
|
|
};
|
|
|
|
char new_filename[PATH_LIMIT];
|
2008-03-25 08:30:04 +01:00
|
|
|
char * ext;
|
2017-11-24 20:15:23 +01:00
|
|
|
int dfs_pair = -1; /* -1=no stereo, 0=opened_vgmstream is left, 1=opened_vgmstream is right */
|
|
|
|
VGMSTREAM *new_vgmstream = NULL;
|
|
|
|
STREAMFILE *dual_streamFile = NULL;
|
|
|
|
int i,j, dfs_pair_count;
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
if (opened_vgmstream->channels != 1)
|
|
|
|
return;
|
2008-05-20 17:18:38 +02:00
|
|
|
|
2009-04-19 11:49:08 +02:00
|
|
|
/* vgmstream's layout stuff currently assumes a single file */
|
|
|
|
// fastelbja : no need ... this one works ok with dual file
|
2017-11-24 20:15:23 +01:00
|
|
|
//if (opened_vgmstream->layout != layout_none) return;
|
|
|
|
//todo force layout_none if layout_interleave?
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
streamFile->get_name(streamFile,new_filename,sizeof(new_filename));
|
|
|
|
if (strlen(new_filename)<2) return; /* we need at least a base and a name ending to replace */
|
|
|
|
|
|
|
|
ext = (char *)filename_extension(new_filename);
|
|
|
|
if (ext-new_filename >= 1 && ext[-1]=='.') ext--; /* excluding "." */
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* find pair from base name and modify new_filename with the opposite */
|
|
|
|
dfs_pair_count = (sizeof(dfs_pairs)/sizeof(dfs_pairs[0]));
|
|
|
|
for (i = 0; dfs_pair == -1 && i< dfs_pair_count; i++) {
|
|
|
|
for (j=0; dfs_pair==-1 && j<2; j++) {
|
|
|
|
const char * this_suffix = dfs_pairs[i][j];
|
|
|
|
size_t this_suffix_len = strlen(dfs_pairs[i][j]);
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* if suffix matches copy opposite to ext pointer (thus to new_filename) */
|
|
|
|
if ( !memcmp(ext - this_suffix_len,this_suffix,this_suffix_len) ) {
|
|
|
|
const char * other_suffix = dfs_pairs[i][j^1];
|
|
|
|
size_t other_suffix_len = strlen(dfs_pairs[i][j^1]);
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
dfs_pair = j;
|
|
|
|
memmove(ext + other_suffix_len - this_suffix_len, ext,strlen(ext)+1); /* move the extension and terminator, too */
|
|
|
|
memcpy (ext - this_suffix_len, other_suffix,other_suffix_len); /* make the new name */
|
2008-03-25 08:30:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* see if the filename had a suitable L/R-pair name */
|
|
|
|
if (dfs_pair == -1)
|
|
|
|
goto fail;
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* try to init other channel (new_filename now has the opposite name) */
|
|
|
|
dual_streamFile = streamFile->open(streamFile,new_filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
if (!dual_streamFile) goto fail;
|
2008-06-26 04:08:26 +02:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
new_vgmstream = init_vgmstream_function(dual_streamFile); /* use the init that just worked, no other should work */
|
|
|
|
close_streamfile(dual_streamFile);
|
2008-03-25 08:30:04 +01:00
|
|
|
|
|
|
|
/* see if we were able to open the file, and if everything matched nicely */
|
2017-11-24 20:15:23 +01:00
|
|
|
if (new_vgmstream &&
|
|
|
|
new_vgmstream->channels == 1 &&
|
|
|
|
/* we have seen legitimate pairs where these are off by one...
|
|
|
|
* but leaving it commented out until I can find those and recheck */
|
|
|
|
/* abs(new_vgmstream->num_samples-opened_vgmstream->num_samples <= 1) && */
|
|
|
|
new_vgmstream->num_samples == opened_vgmstream->num_samples &&
|
|
|
|
new_vgmstream->sample_rate == opened_vgmstream->sample_rate &&
|
|
|
|
new_vgmstream->meta_type == opened_vgmstream->meta_type &&
|
|
|
|
new_vgmstream->coding_type == opened_vgmstream->coding_type &&
|
|
|
|
new_vgmstream->layout_type == opened_vgmstream->layout_type &&
|
|
|
|
new_vgmstream->loop_flag == opened_vgmstream->loop_flag &&
|
|
|
|
/* check these even if there is no loop, because they should then be zero in both */
|
|
|
|
new_vgmstream->loop_start_sample == opened_vgmstream->loop_start_sample &&
|
|
|
|
new_vgmstream->loop_end_sample == opened_vgmstream->loop_end_sample &&
|
2008-03-25 08:30:04 +01:00
|
|
|
/* check even if the layout doesn't use them, because it is
|
2017-11-24 20:15:23 +01:00
|
|
|
* difficult to determine when it does, and they should be zero otherwise, anyway */
|
|
|
|
new_vgmstream->interleave_block_size == opened_vgmstream->interleave_block_size &&
|
|
|
|
new_vgmstream->interleave_smallblock_size == opened_vgmstream->interleave_smallblock_size) {
|
2008-03-25 08:30:04 +01:00
|
|
|
/* We seem to have a usable, matching file. Merge in the second channel. */
|
|
|
|
VGMSTREAMCHANNEL * new_chans;
|
|
|
|
VGMSTREAMCHANNEL * new_loop_chans = NULL;
|
|
|
|
VGMSTREAMCHANNEL * new_start_chans = NULL;
|
|
|
|
|
|
|
|
/* build the channels */
|
|
|
|
new_chans = calloc(2,sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!new_chans) goto fail;
|
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
memcpy(&new_chans[dfs_pair],&opened_vgmstream->ch[0],sizeof(VGMSTREAMCHANNEL));
|
|
|
|
memcpy(&new_chans[dfs_pair^1],&new_vgmstream->ch[0],sizeof(VGMSTREAMCHANNEL));
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
/* loop and start will be initialized later, we just need to allocate them here */
|
2008-03-25 08:30:04 +01:00
|
|
|
new_start_chans = calloc(2,sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!new_start_chans) {
|
|
|
|
free(new_chans);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
if (opened_vgmstream->loop_ch) {
|
2008-03-25 08:30:04 +01:00
|
|
|
new_loop_chans = calloc(2,sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!new_loop_chans) {
|
|
|
|
free(new_chans);
|
|
|
|
free(new_start_chans);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove the existing structures */
|
|
|
|
/* not using close_vgmstream as that would close the file */
|
2017-11-24 20:15:23 +01:00
|
|
|
free(opened_vgmstream->ch);
|
|
|
|
free(new_vgmstream->ch);
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
free(opened_vgmstream->start_ch);
|
|
|
|
free(new_vgmstream->start_ch);
|
2008-03-25 08:30:04 +01:00
|
|
|
|
2017-11-24 20:15:23 +01:00
|
|
|
if (opened_vgmstream->loop_ch) {
|
|
|
|
free(opened_vgmstream->loop_ch);
|
|
|
|
free(new_vgmstream->loop_ch);
|
2008-03-25 08:30:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* fill in the new structures */
|
2017-11-24 20:15:23 +01:00
|
|
|
opened_vgmstream->ch = new_chans;
|
|
|
|
opened_vgmstream->start_ch = new_start_chans;
|
|
|
|
opened_vgmstream->loop_ch = new_loop_chans;
|
2008-03-25 08:30:04 +01:00
|
|
|
|
|
|
|
/* stereo! */
|
2017-11-24 20:15:23 +01:00
|
|
|
opened_vgmstream->channels = 2;
|
2008-03-25 08:30:04 +01:00
|
|
|
|
|
|
|
/* discard the second VGMSTREAM */
|
2017-11-24 20:15:23 +01:00
|
|
|
free(new_vgmstream);
|
2008-03-25 08:30:04 +01:00
|
|
|
}
|
|
|
|
fail:
|
2008-05-20 17:18:38 +02:00
|
|
|
return;
|
2009-07-30 06:10:16 +02:00
|
|
|
}
|
2015-02-09 04:01:26 +01:00
|
|
|
|
2015-02-14 01:47:59 +01:00
|
|
|
static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
2015-02-09 04:01:26 +01:00
|
|
|
{
|
2015-02-14 01:47:59 +01:00
|
|
|
if (vgmstream->layout_type==layout_scd_int) {
|
2016-06-28 09:20:37 +02:00
|
|
|
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
|
2015-02-14 01:47:59 +01:00
|
|
|
if (data) {
|
|
|
|
return data->substream_count;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef VGM_USE_VORBIS
|
|
|
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
2016-06-28 09:20:37 +02:00
|
|
|
ogg_vorbis_codec_data *data = (ogg_vorbis_codec_data *) vgmstream->codec_data;
|
2015-02-14 01:47:59 +01:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2016-06-28 09:20:37 +02:00
|
|
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
|
|
|
hca_codec_data *data = (hca_codec_data *) vgmstream->codec_data;
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2016-07-17 08:02:27 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
|
|
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2015-02-14 01:47:59 +01:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
|
|
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
2016-06-28 09:20:37 +02:00
|
|
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
2015-02-14 01:47:59 +01:00
|
|
|
if (data) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return vgmstream->channels;
|
|
|
|
}
|
|
|
|
|
|
|
|
static STREAMFILE * get_vgmstream_streamfile(VGMSTREAM * vgmstream, int channel)
|
|
|
|
{
|
|
|
|
if (vgmstream->layout_type==layout_scd_int) {
|
2016-06-28 09:20:37 +02:00
|
|
|
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
|
2015-02-14 01:47:59 +01:00
|
|
|
return data->intfiles[channel];
|
|
|
|
}
|
|
|
|
#ifdef VGM_USE_VORBIS
|
|
|
|
if (vgmstream->coding_type==coding_ogg_vorbis) {
|
2016-06-28 09:20:37 +02:00
|
|
|
ogg_vorbis_codec_data *data = (ogg_vorbis_codec_data *) vgmstream->codec_data;
|
2015-02-14 01:47:59 +01:00
|
|
|
|
|
|
|
return data->ov_streamfile.streamfile;
|
|
|
|
}
|
|
|
|
#endif
|
2016-06-28 09:20:37 +02:00
|
|
|
if (vgmstream->coding_type==coding_CRI_HCA) {
|
|
|
|
hca_codec_data *data = (hca_codec_data *) vgmstream->codec_data;
|
|
|
|
|
|
|
|
return data->streamfile;
|
|
|
|
}
|
2016-07-17 08:02:27 +02:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
|
|
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
|
|
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
|
|
|
|
|
|
|
return data->streamfile;
|
|
|
|
}
|
|
|
|
#endif
|
2015-02-14 01:47:59 +01:00
|
|
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
|
|
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
2016-06-28 09:20:37 +02:00
|
|
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
2015-02-14 01:47:59 +01:00
|
|
|
return data->if_file.streamfile;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return vgmstream->ch[channel].streamfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int get_vgmstream_channel_average_bitrate(STREAMFILE * streamfile, int sample_rate, int length_samples)
|
|
|
|
{
|
|
|
|
return (int)((int64_t)get_streamfile_size(streamfile) * 8 * sample_rate / length_samples);
|
2015-02-09 04:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream)
|
|
|
|
{
|
|
|
|
char path_current[PATH_LIMIT];
|
|
|
|
char path_compare[PATH_LIMIT];
|
|
|
|
|
|
|
|
unsigned int i, j;
|
|
|
|
int bitrate = 0;
|
|
|
|
int sample_rate = vgmstream->sample_rate;
|
|
|
|
int length_samples = vgmstream->num_samples;
|
2015-02-14 01:47:59 +01:00
|
|
|
int channels = get_vgmstream_channel_count(vgmstream);
|
|
|
|
STREAMFILE * streamFile;
|
2015-08-24 01:44:23 +02:00
|
|
|
|
2016-08-11 03:34:13 +02:00
|
|
|
if (!sample_rate || !channels || !length_samples)
|
|
|
|
return 0;
|
2015-02-09 04:01:26 +01:00
|
|
|
|
2015-02-14 01:47:59 +01:00
|
|
|
if (channels >= 1) {
|
|
|
|
streamFile = get_vgmstream_streamfile(vgmstream, 0);
|
|
|
|
if (streamFile) {
|
|
|
|
bitrate += get_vgmstream_channel_average_bitrate(streamFile, sample_rate, length_samples);
|
|
|
|
}
|
|
|
|
}
|
2015-02-09 04:01:26 +01:00
|
|
|
|
2015-02-14 01:47:59 +01:00
|
|
|
for (i = 1; i < channels; ++i)
|
2015-02-09 04:01:26 +01:00
|
|
|
{
|
2015-02-14 01:47:59 +01:00
|
|
|
streamFile = get_vgmstream_streamfile(vgmstream, i);
|
|
|
|
if (!streamFile)
|
2015-02-12 23:22:51 +01:00
|
|
|
continue;
|
2015-02-14 01:49:29 +01:00
|
|
|
streamFile->get_name(streamFile, path_current, sizeof(path_current));
|
2015-02-09 04:01:26 +01:00
|
|
|
for (j = 0; j < i; ++j)
|
|
|
|
{
|
2015-02-14 01:47:59 +01:00
|
|
|
STREAMFILE * compareFile = get_vgmstream_streamfile(vgmstream, j);
|
|
|
|
if (!compareFile)
|
2015-02-12 23:22:51 +01:00
|
|
|
continue;
|
2015-02-14 01:49:29 +01:00
|
|
|
streamFile->get_name(compareFile, path_compare, sizeof(path_compare));
|
2015-02-09 04:01:26 +01:00
|
|
|
if (!strcmp(path_current, path_compare))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (j == i)
|
2015-02-14 01:47:59 +01:00
|
|
|
bitrate += get_vgmstream_channel_average_bitrate(streamFile, sample_rate, length_samples);
|
2015-02-09 04:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return bitrate;
|
|
|
|
}
|
2017-01-14 00:59:54 +01:00
|
|
|
|
|
|
|
|
2017-03-09 20:38:52 +01:00
|
|
|
/**
|
|
|
|
* Inits vgmstreams' channels doing two things:
|
|
|
|
* - sets the starting offset per channel (depending on the layout)
|
|
|
|
* - opens its own streamfile from on a base one. One streamfile per channel may be open (to improve read/seeks).
|
|
|
|
* Should be called in metas before returning the VGMSTREAM..
|
|
|
|
*/
|
2017-01-14 00:59:54 +01:00
|
|
|
int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset) {
|
|
|
|
STREAMFILE * file;
|
|
|
|
char filename[PATH_LIMIT];
|
|
|
|
int ch;
|
2017-01-15 21:02:01 +01:00
|
|
|
int use_streamfile_per_channel = 0;
|
|
|
|
int use_same_offset_per_channel = 0;
|
2017-01-14 00:59:54 +01:00
|
|
|
|
2017-03-09 20:38:52 +01:00
|
|
|
|
|
|
|
/* stream/offsets not needed, scd manages itself */
|
|
|
|
if (vgmstream->layout_type == layout_scd_int)
|
|
|
|
return 1;
|
|
|
|
|
2017-01-14 00:59:54 +01:00
|
|
|
#ifdef VGM_USE_FFMPEG
|
2017-03-09 20:38:52 +01:00
|
|
|
/* stream/offsets not needed, FFmpeg manages itself */
|
|
|
|
if (vgmstream->coding_type == coding_FFmpeg)
|
2017-01-14 00:59:54 +01:00
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
|
2017-01-15 21:02:01 +01:00
|
|
|
/* if interleave is big enough keep a buffer per channel */
|
2017-06-24 22:53:17 +02:00
|
|
|
if (vgmstream->interleave_block_size * vgmstream->channels >= STREAMFILE_DEFAULT_BUFFER_SIZE) {
|
2017-01-15 21:02:01 +01:00
|
|
|
use_streamfile_per_channel = 1;
|
2017-01-14 00:59:54 +01:00
|
|
|
}
|
|
|
|
|
2017-03-09 20:38:52 +01:00
|
|
|
/* for mono or codecs like IMA (XBOX, MS IMA, MS ADPCM) where channels work with the same bytes */
|
2017-02-18 18:27:21 +01:00
|
|
|
if (vgmstream->layout_type == layout_none) {
|
2017-01-15 21:02:01 +01:00
|
|
|
use_same_offset_per_channel = 1;
|
2017-01-14 00:59:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
|
|
/* open the file for reading by each channel */
|
|
|
|
{
|
2017-01-15 21:02:01 +01:00
|
|
|
if (!use_streamfile_per_channel) {
|
|
|
|
file = streamFile->open(streamFile,filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
if (!file) goto fail;
|
|
|
|
}
|
2017-01-14 00:59:54 +01:00
|
|
|
|
|
|
|
for (ch=0; ch < vgmstream->channels; ch++) {
|
2017-01-15 21:02:01 +01:00
|
|
|
off_t offset;
|
|
|
|
if (use_same_offset_per_channel) {
|
|
|
|
offset = start_offset;
|
|
|
|
} else {
|
|
|
|
offset = start_offset + vgmstream->interleave_block_size*ch;
|
2017-01-14 00:59:54 +01:00
|
|
|
}
|
2017-01-15 21:02:01 +01:00
|
|
|
|
|
|
|
/* open new one if needed */
|
|
|
|
if (use_streamfile_per_channel) {
|
|
|
|
file = streamFile->open(streamFile,filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
if (!file) goto fail;
|
2017-01-14 00:59:54 +01:00
|
|
|
}
|
2017-01-15 21:02:01 +01:00
|
|
|
|
|
|
|
vgmstream->ch[ch].streamfile = file;
|
|
|
|
vgmstream->ch[ch].channel_start_offset =
|
|
|
|
vgmstream->ch[ch].offset = offset;
|
2017-01-14 00:59:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2017-01-15 21:02:01 +01:00
|
|
|
|
|
|
|
fail:
|
2017-01-25 22:31:28 +01:00
|
|
|
/* open streams will be closed in close_vgmstream(), hopefully called by the meta */
|
2017-01-15 21:02:01 +01:00
|
|
|
return 0;
|
2017-01-14 00:59:54 +01:00
|
|
|
}
|