An audio player for macOS 10.8 and newer. https://kode54.net/cog
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1865 lines
71KB

  1. #include "meta.h"
  2. #include "../layout/layout.h"
  3. #include "../coding/coding.h"
  4. #include "ea_schl_streamfile.h"
  5. /* header version */
  6. #define EA_VERSION_NONE -1
  7. #define EA_VERSION_V0 0x00 /* ~early PC (when codec1 was used) */
  8. #define EA_VERSION_V1 0x01 /* ~PC */
  9. #define EA_VERSION_V2 0x02 /* ~PS1 */
  10. #define EA_VERSION_V3 0x03 /* ~PS2 */
  11. /* platform constants (unassigned values seem internal only) */
  12. #define EA_PLATFORM_GENERIC -1 /* typically Wii/X360/PS3/videos */
  13. #define EA_PLATFORM_PC 0x00
  14. #define EA_PLATFORM_PSX 0x01
  15. #define EA_PLATFORM_N64 0x02
  16. #define EA_PLATFORM_MAC 0x03
  17. #define EA_PLATFORM_SAT 0x04
  18. #define EA_PLATFORM_PS2 0x05
  19. #define EA_PLATFORM_GC_WII 0x06
  20. #define EA_PLATFORM_XBOX 0x07
  21. #define EA_PLATFORM_X360 0x09
  22. #define EA_PLATFORM_PSP 0x0A
  23. #define EA_PLATFORM_PS3 0x0E /* very rare [Need for Speed: Carbon (PS3)] */
  24. #define EA_PLATFORM_3DS 0x14
  25. /* codec constants (undefined are probably reserved, ie.- sx.exe encodes PCM24/DVI but no platform decodes them) */
  26. /* CODEC1 values were used early, then they migrated to CODEC2 values */
  27. #define EA_CODEC1_NONE -1
  28. #define EA_CODEC1_PCM 0x00
  29. #define EA_CODEC1_VAG 0x01 // unsure
  30. #define EA_CODEC1_EAXA 0x07
  31. #define EA_CODEC1_MT10 0x09
  32. #define EA_CODEC1_N64 0x64 /* unknown but probably before MT10 */
  33. #define EA_CODEC2_NONE -1
  34. #define EA_CODEC2_MT10 0x04
  35. #define EA_CODEC2_VAG 0x05
  36. #define EA_CODEC2_S16BE 0x07
  37. #define EA_CODEC2_S16LE 0x08
  38. #define EA_CODEC2_S8 0x09
  39. #define EA_CODEC2_EAXA 0x0A
  40. #define EA_CODEC2_LAYER2 0x0F
  41. #define EA_CODEC2_LAYER3 0x10
  42. #define EA_CODEC2_GCADPCM 0x12
  43. #define EA_CODEC2_XBOXADPCM 0x14
  44. #define EA_CODEC2_MT5 0x16
  45. #define EA_CODEC2_EALAYER3 0x17
  46. #define EA_CODEC2_ATRAC3PLUS 0x1B
  47. #define EA_CODEC2_N64 0x64 /* unknown but probably before MT10 */
  48. /* Block headers, SCxy - where x is block ID and y is endianness flag (always 'l'?) */
  49. #define EA_BLOCKID_HEADER 0x5343486C /* "SCHl" */
  50. #define EA_BLOCKID_COUNT 0x5343436C /* "SCCl" */
  51. #define EA_BLOCKID_DATA 0x5343446C /* "SCDl" */
  52. #define EA_BLOCKID_LOOP 0x53434C6C /* "SCLl */
  53. #define EA_BLOCKID_END 0x5343456C /* "SCEl" */
  54. /* Localized block headers, Sxyy - where x is block ID and yy is lang code (e.g. "SHEN"), used in videos */
  55. #define EA_BLOCKID_LOC_HEADER 0x53480000 /* "SH" */
  56. #define EA_BLOCKID_LOC_COUNT 0x53430000 /* "SC" */
  57. #define EA_BLOCKID_LOC_DATA 0x53440000 /* "SD" */
  58. #define EA_BLOCKID_LOC_END 0x53450000 /* "SE" */
  59. #define EA_BLOCKID_LOC_EN 0x0000454E /* English */
  60. #define EA_BLOCKID_LOC_FR 0x00004652 /* French */
  61. #define EA_BLOCKID_LOC_GE 0x00004745 /* German, older */
  62. #define EA_BLOCKID_LOC_DE 0x00004445 /* German, newer */
  63. #define EA_BLOCKID_LOC_IT 0x00004954 /* Italian */
  64. #define EA_BLOCKID_LOC_SP 0x00005350 /* Castilian Spanish, older */
  65. #define EA_BLOCKID_LOC_ES 0x00004553 /* Castilian Spanish, newer */
  66. #define EA_BLOCKID_LOC_MX 0x00004D58 /* Mexican Spanish */
  67. #define EA_BLOCKID_LOC_RU 0x00005255 /* Russian */
  68. #define EA_BLOCKID_LOC_JA 0x00004A41 /* Japanese, older */
  69. #define EA_BLOCKID_LOC_JP 0x00004A50 /* Japanese, newer */
  70. #define EA_BLOCKID_LOC_PL 0x0000504C /* Polish */
  71. #define EA_BLOCKID_LOC_BR 0x00004252 /* Brazilian Portuguese */
  72. #define EA_BNK_HEADER_LE 0x424E4B6C /* "BNKl" */
  73. #define EA_BNK_HEADER_BE 0x424E4B62 /* "BNKb" */
  74. #define EA_MAX_CHANNELS 6
  75. typedef struct {
  76. int32_t num_samples;
  77. int32_t sample_rate;
  78. int32_t channels;
  79. int32_t platform;
  80. int32_t version;
  81. int32_t bps;
  82. int32_t codec1;
  83. int32_t codec2;
  84. int32_t loop_start;
  85. int32_t loop_end;
  86. uint32_t flag_value;
  87. off_t offsets[EA_MAX_CHANNELS];
  88. off_t coefs[EA_MAX_CHANNELS];
  89. off_t loops[EA_MAX_CHANNELS];
  90. int big_endian;
  91. int loop_flag;
  92. int codec_config;
  93. size_t stream_size;
  94. } ea_header;
  95. static VGMSTREAM * parse_schl_block(STREAMFILE* sf, off_t offset, int standalone);
  96. static VGMSTREAM * parse_bnk_header(STREAMFILE* sf, off_t offset, int target_stream, int is_embedded);
  97. static int parse_variable_header(STREAMFILE* sf, ea_header* ea, off_t begin_offset, int max_length, int bnk_version);
  98. static uint32_t read_patch(STREAMFILE* sf, off_t* offset);
  99. static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* sf, off_t start_offset, const ea_header* ea);
  100. static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int is_bnk, int standalone);
  101. static void update_ea_stream_size_and_samples(STREAMFILE* sf, off_t start_offset, VGMSTREAM* vgmstream, int standalone);
  102. /* EA SCHl with variable header - from EA games (roughly 1997~2010); generated by EA Canada's sx.exe/Sound eXchange */
  103. VGMSTREAM* init_vgmstream_ea_schl(STREAMFILE* sf) {
  104. /* check extension */
  105. /* they don't seem enforced by EA's tools but usually:
  106. * .asf: ~early (audio stream file?) [ex. Need for Speed II (PC)]
  107. * .lasf: fake for plugins
  108. * .str: ~early [ex. FIFA 98 (PS1), FIFA 2002 (PS1)]
  109. * .eam: ~mid?
  110. * .exa: ~mid [ex. 007 - From Russia with Love]
  111. * .sng: ~late (FIFA games)
  112. * .aud: ~late [ex. FIFA 14 (3DS)]
  113. * .strm: MySims Kingdom (Wii)
  114. * .stm: FIFA 12 (3DS)
  115. * .sx: FIFA 98 (SAT)
  116. * .xa: ?
  117. * .hab: GoldenEye - Rogue Agent (inside .big)
  118. * .xsf: 007 - Agent Under Fire (Xbox)
  119. * .gsf: 007 - Everything or Nothing (GC)
  120. * .mus: map/mpf+mus only?
  121. * (extensionless): SSX (PS2) (inside .big) */
  122. if (!check_extensions(sf,"asf,lasf,str,eam,exa,sng,aud,sx,xa,strm,stm,hab,xsf,gsf,mus,"))
  123. goto fail;
  124. /* check header */
  125. if (read_32bitBE(0x00,sf) != EA_BLOCKID_HEADER && /* "SCHl" */
  126. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_EN) && /* "SHEN" */
  127. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_FR) && /* "SHFR" */
  128. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_GE) && /* "SHGE" */
  129. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_DE) && /* "SHDE" */
  130. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_IT) && /* "SHIT" */
  131. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_SP) && /* "SHSP" */
  132. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_ES) && /* "SHES" */
  133. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_MX) && /* "SHMX" */
  134. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_RU) && /* "SHRU" */
  135. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_JA) && /* "SHJA" */
  136. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_JP) && /* "SHJP" */
  137. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_PL) && /* "SHPL" */
  138. read_32bitBE(0x00,sf) != (EA_BLOCKID_LOC_HEADER | EA_BLOCKID_LOC_BR)) /* "SHBR" */
  139. goto fail;
  140. /* Stream is divided into blocks/chunks: SCHl=audio header, SCCl=count of SCDl, SCDl=data xN, SCLl=loop end, SCEl=end.
  141. * Video uses picture blocks (MVhd/MV0K/etc) and sometimes multiaudio blocks (SHxx/SCxx/SDxx/SExx where xx=language).
  142. * The number/size is affected by: block rate setting, sample rate, channels, CPU location (SPU/main/DSP/others), etc */
  143. return parse_schl_block(sf, 0x00, 1);
  144. fail:
  145. return NULL;
  146. }
  147. /* EA SCHl inside non-demuxed videos, used in current gen games too */
  148. VGMSTREAM * init_vgmstream_ea_schl_video(STREAMFILE* sf) {
  149. VGMSTREAM* vgmstream = NULL;
  150. off_t offset = 0, start_offset = 0;
  151. int blocks_done = 0;
  152. int total_subsongs, target_subsong = sf->stream_index;
  153. int32_t(*read_32bit)(off_t, STREAMFILE*);
  154. /* check extension */
  155. /* .uv: early */
  156. /* .dct: early-mid [ex. Need for Speed II SE (PC), FIFA 98 (PC)] */
  157. /* .mad: mid */
  158. /* .vp6: late */
  159. if (check_extensions(sf, "uv,dct")) {
  160. /* starts with audio header block */
  161. if (read_32bitBE(0x00, sf) != EA_BLOCKID_HEADER) /* "SCHl" */
  162. goto fail;
  163. } else if (check_extensions(sf, "mad")) {
  164. /* check initial movie block id */
  165. if (read_32bitBE(0x00, sf) != 0x4D41446B) /* "MADk" */
  166. goto fail;
  167. } else if (check_extensions(sf, "vp6")) {
  168. /* check initial movie block id */
  169. if (read_32bitBE(0x00, sf) != 0x4D566864) /* "MVhd" */
  170. goto fail;
  171. } else {
  172. goto fail;
  173. }
  174. /* use block size to check endianness */
  175. if (guess_endianness32bit(0x04, sf)) {
  176. read_32bit = read_32bitBE;
  177. } else {
  178. read_32bit = read_32bitLE;
  179. }
  180. /* find starting valid header for the parser */
  181. while (offset < get_streamfile_size(sf)) {
  182. uint32_t block_id = read_32bitBE(offset+0x00,sf);
  183. uint32_t block_size = read_32bit (offset+0x04,sf);
  184. /* find "SCHl" or "SHxx" blocks */
  185. if ((block_id == EA_BLOCKID_HEADER) || ((block_id & 0xFFFF0000) == EA_BLOCKID_LOC_HEADER)) {
  186. start_offset = offset;
  187. break;
  188. }
  189. if (block_size == 0xFFFFFFFF)
  190. goto fail;
  191. if (blocks_done > 10)
  192. goto fail; /* unlikely to contain music */
  193. blocks_done++;
  194. offset += block_size;
  195. }
  196. if (offset >= get_streamfile_size(sf))
  197. goto fail;
  198. /* find target subsong (one per each SHxx multilang block) */
  199. total_subsongs = 1;
  200. if (target_subsong == 0) target_subsong = 1;
  201. offset = start_offset;
  202. while (offset < get_streamfile_size(sf)) {
  203. uint32_t block_id = read_32bitBE(offset+0x00,sf);
  204. uint32_t block_size = read_32bit (offset+0x04,sf);
  205. /* no more subsongs (assumes all SHxx headers go together) */
  206. if (((block_id & 0xFFFF0000) != EA_BLOCKID_LOC_HEADER)) {
  207. break;
  208. }
  209. if (target_subsong == total_subsongs) {
  210. start_offset = offset;
  211. /* keep counting subsongs */
  212. }
  213. total_subsongs++;
  214. offset += block_size;
  215. }
  216. if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
  217. vgmstream = parse_schl_block(sf, start_offset, 1);
  218. if (!vgmstream) goto fail;
  219. vgmstream->num_streams = total_subsongs;
  220. return vgmstream;
  221. fail:
  222. close_vgmstream(vgmstream);
  223. return NULL;
  224. }
  225. /* EA BNK with variable header - from EA games SFXs; also created by sx.exe */
  226. VGMSTREAM * init_vgmstream_ea_bnk(STREAMFILE* sf) {
  227. off_t offset;
  228. int target_stream = sf->stream_index;
  229. /* check extension */
  230. /* .bnk: common
  231. * .sdt: Harry Potter games
  232. * .mus: streams/jingles (rare)
  233. * .abk: GoldenEye - Rogue Agent
  234. * .ast: FIFA 2004 (inside .big) */
  235. if (!check_extensions(sf,"bnk,sdt,mus,abk,ast"))
  236. goto fail;
  237. /* check header (doesn't use EA blocks, otherwise very similar to SCHl) */
  238. if (read_32bitBE(0x100,sf) == EA_BNK_HEADER_LE)
  239. offset = 0x100; /* Harry Potter and the Goblet of Fire (PS2) .mus have weird extra 0x100 bytes */
  240. else
  241. offset = 0x00;
  242. if (target_stream == 0) target_stream = 1;
  243. return parse_bnk_header(sf, offset, target_stream - 1, 0);
  244. fail:
  245. return NULL;
  246. }
  247. /* EA ABK - common soundbank format in 6th-gen games, can reference RAM and streamed assets */
  248. /* RAM assets are stored in embedded BNK file */
  249. /* streamed assets are stored externally in AST file (mostly seen in earlier 6th-gen games) */
  250. VGMSTREAM * init_vgmstream_ea_abk(STREAMFILE* sf) {
  251. int bnk_target_stream, is_dupe, total_sounds = 0, target_stream = sf->stream_index;
  252. off_t bnk_offset, header_table_offset, base_offset, value_offset, table_offset, entry_offset, target_entry_offset, schl_offset, schl_loop_offset;
  253. uint32_t i, j, k, num_sounds, total_sound_tables;
  254. uint16_t num_tables;
  255. uint8_t sound_type, num_entries;
  256. off_t sound_table_offsets[0x2000];
  257. STREAMFILE * astData = NULL;
  258. VGMSTREAM * vgmstream = NULL;
  259. segmented_layout_data *data_s = NULL;
  260. int32_t(*read_32bit)(off_t, STREAMFILE*);
  261. int16_t(*read_16bit)(off_t, STREAMFILE*);
  262. /* check extension */
  263. if (!check_extensions(sf, "abk"))
  264. goto fail;
  265. if (read_32bitBE(0x00, sf) != 0x41424B43) /* "ABKC" */
  266. goto fail;
  267. /* use table offset to check endianness */
  268. if (guess_endianness32bit(0x1C, sf)) {
  269. read_32bit = read_32bitBE;
  270. read_16bit = read_16bitBE;
  271. } else {
  272. read_32bit = read_32bitLE;
  273. read_16bit = read_16bitLE;
  274. }
  275. if (target_stream == 0) target_stream = 1;
  276. if (target_stream < 0)
  277. goto fail;
  278. num_tables = read_16bit(0x0A, sf);
  279. header_table_offset = read_32bit(0x1C, sf);
  280. bnk_offset = read_32bit(0x20, sf);
  281. target_entry_offset = 0;
  282. total_sound_tables = 0;
  283. /* check to avoid clashing with the newer ABK format */
  284. if (bnk_offset &&
  285. read_32bitBE(bnk_offset, sf) != EA_BNK_HEADER_LE &&
  286. read_32bitBE(bnk_offset, sf) != EA_BNK_HEADER_BE)
  287. goto fail;
  288. for (i = 0; i < num_tables; i++) {
  289. num_entries = read_8bit(header_table_offset + 0x24, sf);
  290. base_offset = read_32bit(header_table_offset + 0x2C, sf);
  291. if (num_entries == 0xff) goto fail; /* EOF read */
  292. for (j = 0; j < num_entries; j++) {
  293. value_offset = read_32bit(header_table_offset + 0x3C + 0x04 * j, sf);
  294. table_offset = read_32bit(base_offset + value_offset + 0x04, sf);
  295. /* For some reason, there are duplicate entries pointing at the same sound tables */
  296. is_dupe = 0;
  297. for (k = 0; k < total_sound_tables; k++) {
  298. if (table_offset == sound_table_offsets[k]) {
  299. is_dupe = 1;
  300. break;
  301. }
  302. }
  303. if (is_dupe)
  304. continue;
  305. sound_table_offsets[total_sound_tables++] = table_offset;
  306. num_sounds = read_32bit(table_offset, sf);
  307. if (num_sounds == 0xffffffff) goto fail; /* EOF read */
  308. for (k = 0; k < num_sounds; k++) {
  309. entry_offset = table_offset + 0x04 + 0x0C * k;
  310. sound_type = read_8bit(entry_offset + 0x00, sf);
  311. /* some of these are dummies pointing at sound 0 in BNK */
  312. if (sound_type == 0x00 && read_32bit(entry_offset + 0x04, sf) == 0)
  313. continue;
  314. total_sounds++;
  315. if (target_stream == total_sounds)
  316. target_entry_offset = entry_offset;
  317. }
  318. }
  319. /* there can be another set of values, don't know what they mean */
  320. num_entries += read_8bit(header_table_offset + 0x27, sf);
  321. header_table_offset += 0x3C + num_entries * 0x04;
  322. }
  323. if (target_entry_offset == 0)
  324. goto fail;
  325. /* 0x00: type (0x00 - normal, 0x01 - streamed, 0x02 - streamed looped) */
  326. /* 0x01: ??? */
  327. /* 0x04: index for normal sounds, offset for streamed sounds */
  328. /* 0x08: loop offset for streamed sounds */
  329. sound_type = read_8bit(target_entry_offset + 0x00, sf);
  330. switch (sound_type) {
  331. case 0x00:
  332. if (!bnk_offset)
  333. goto fail;
  334. bnk_target_stream = read_32bit(target_entry_offset + 0x04, sf);
  335. vgmstream = parse_bnk_header(sf, bnk_offset, bnk_target_stream, 1);
  336. if (!vgmstream)
  337. goto fail;
  338. break;
  339. case 0x01:
  340. astData = open_streamfile_by_ext(sf, "ast");
  341. if (!astData)
  342. goto fail;
  343. schl_offset = read_32bit(target_entry_offset + 0x04, sf);
  344. if (read_32bitBE(schl_offset, astData) != EA_BLOCKID_HEADER)
  345. goto fail;
  346. vgmstream = parse_schl_block(astData, schl_offset, 0);
  347. if (!vgmstream)
  348. goto fail;
  349. break;
  350. case 0x02:
  351. astData = open_streamfile_by_ext(sf, "ast");
  352. if (!astData)
  353. goto fail;
  354. /* looped sounds basically consist of two independent segments
  355. * the first one is loop start, the second one is loop body */
  356. schl_offset = read_32bit(target_entry_offset + 0x04, sf);
  357. schl_loop_offset = read_32bit(target_entry_offset + 0x08, sf);
  358. if (read_32bitBE(schl_offset, astData) != EA_BLOCKID_HEADER ||
  359. read_32bitBE(schl_loop_offset, astData) != EA_BLOCKID_HEADER)
  360. goto fail;
  361. /* init layout */
  362. data_s = init_layout_segmented(2);
  363. if (!data_s) goto fail;
  364. /* load intro and loop segments */
  365. data_s->segments[0] = parse_schl_block(astData, schl_offset, 0);
  366. if (!data_s->segments[0]) goto fail;
  367. data_s->segments[1] = parse_schl_block(astData, schl_loop_offset, 0);
  368. if (!data_s->segments[1]) goto fail;
  369. /* setup segmented VGMSTREAMs */
  370. if (!setup_layout_segmented(data_s))
  371. goto fail;
  372. /* build the VGMSTREAM */
  373. vgmstream = allocate_vgmstream(data_s->segments[0]->channels, 1);
  374. if (!vgmstream) goto fail;
  375. vgmstream->sample_rate = data_s->segments[0]->sample_rate;
  376. vgmstream->num_samples = data_s->segments[0]->num_samples + data_s->segments[1]->num_samples;
  377. vgmstream->loop_start_sample = data_s->segments[0]->num_samples;
  378. vgmstream->loop_end_sample = vgmstream->num_samples;
  379. vgmstream->meta_type = meta_EA_SCHL;
  380. vgmstream->coding_type = data_s->segments[0]->coding_type;
  381. vgmstream->layout_type = layout_segmented;
  382. vgmstream->layout_data = data_s;
  383. break;
  384. default:
  385. goto fail;
  386. break;
  387. }
  388. vgmstream->num_streams = total_sounds;
  389. close_streamfile(astData);
  390. return vgmstream;
  391. fail:
  392. close_streamfile(astData);
  393. free_layout_segmented(data_s);
  394. return NULL;
  395. }
  396. /* EA HDR/DAT v1 (2004-2005) - used for storing speech and other streamed sounds (except for music) */
  397. VGMSTREAM * init_vgmstream_ea_hdr_dat(STREAMFILE* sf) {
  398. VGMSTREAM* vgmstream;
  399. STREAMFILE* sf_dat = NULL;
  400. int target_stream = sf->stream_index;
  401. uint32_t offset_mult;
  402. uint8_t userdata_size, total_sounds;
  403. size_t dat_size;
  404. off_t schl_offset;
  405. /* checks */
  406. if (!check_extensions(sf, "hdr"))
  407. goto fail;
  408. /* main header is machine endian but it's not important here */
  409. /* 0x00: ID */
  410. /* 0x02: sub-ID (used for different police voices in NFS games) */
  411. /* 0x04: parameters (userdata size, ...) */
  412. /* 0x05: number of files */
  413. /* 0x06: alt number of files? */
  414. /* 0x07: offset multiplier flag */
  415. /* 0x08: combined size of all sounds without padding divided by offset mult */
  416. /* 0x0a: zero */
  417. /* 0x0c: table start */
  418. /* no nice way to validate these so we do what we can */
  419. if (read_u16be(0x0a, sf) != 0)
  420. goto fail;
  421. /* first offset is always zero */
  422. if (read_u16be(0x0c, sf) != 0)
  423. goto fail;
  424. /* must be accompanied by DAT file with SCHl sounds */
  425. sf_dat = open_streamfile_by_ext(sf, "dat");
  426. if (!sf_dat)
  427. goto fail;
  428. if (read_u32be(0x00, sf_dat) != EA_BLOCKID_HEADER)
  429. goto fail;
  430. userdata_size = read_u8(0x04, sf) & 0x0F;
  431. total_sounds = read_u8(0x05, sf);
  432. offset_mult = read_u8(0x07, sf) * 0x0100 + 0x0100;
  433. if (read_u8(0x06, sf) > total_sounds)
  434. goto fail;
  435. dat_size = get_streamfile_size(sf_dat);
  436. if (read_u16le(0x08, sf) * offset_mult > dat_size &&
  437. read_u16be(0x08, sf) * offset_mult > dat_size)
  438. goto fail;
  439. if (target_stream == 0) target_stream = 1;
  440. if (target_stream < 0 || total_sounds == 0 || target_stream > total_sounds)
  441. goto fail;
  442. /* offsets are always big endian */
  443. schl_offset = read_u16be(0x0C + (0x02 + userdata_size) * (target_stream - 1), sf) * offset_mult;
  444. if (read_32bitBE(schl_offset, sf_dat) != EA_BLOCKID_HEADER)
  445. goto fail;
  446. vgmstream = parse_schl_block(sf_dat, schl_offset, 0);
  447. if (!vgmstream)
  448. goto fail;
  449. vgmstream->num_streams = total_sounds;
  450. close_streamfile(sf_dat);
  451. return vgmstream;
  452. fail:
  453. close_streamfile(sf_dat);
  454. return NULL;
  455. }
  456. /* EA HDR/DAT v2 (2006-2014) */
  457. VGMSTREAM * init_vgmstream_ea_hdr_dat_v2(STREAMFILE* sf) {
  458. VGMSTREAM *vgmstream;
  459. STREAMFILE *sf_dat = NULL;
  460. int target_stream = sf->stream_index;
  461. uint32_t offset_mult;
  462. uint8_t userdata_size, total_sounds;
  463. size_t dat_size;
  464. off_t schl_offset;
  465. /* checks */
  466. if (!check_extensions(sf, "hdr"))
  467. goto fail;
  468. /* main header is machine endian but it's not important here */
  469. /* 0x00: ID */
  470. /* 0x02: parameters (userdata size, ...) */
  471. /* 0x03: number of files */
  472. /* 0x04: sub-ID (used for different police voices in NFS games) */
  473. /* 0x08: alt number of files? */
  474. /* 0x09: offset mult */
  475. /* 0x0a: DAT size divided by offset mult */
  476. /* 0x0c: zero */
  477. /* 0x10: table start */
  478. /* no nice way to validate these so we do what we can */
  479. if (read_u32be(0x0c, sf) != 0)
  480. goto fail;
  481. /* first offset is always zero */
  482. if (read_u16be(0x10, sf) != 0)
  483. goto fail;
  484. /* must be accompanied by DAT file with SCHl sounds */
  485. sf_dat = open_streamfile_by_ext(sf, "dat");
  486. if (!sf_dat)
  487. goto fail;
  488. if (read_u32be(0x00, sf_dat) != EA_BLOCKID_HEADER)
  489. goto fail;
  490. userdata_size = read_u8(0x02, sf) & 0x0F;
  491. total_sounds = read_u8(0x03, sf);
  492. offset_mult = read_u8(0x09, sf) * 0x0100 + 0x0100;
  493. if (read_u8(0x08, sf) > total_sounds)
  494. goto fail;
  495. dat_size = get_streamfile_size(sf_dat);
  496. if (read_u16le(0x0a, sf) * offset_mult > dat_size &&
  497. read_u16be(0x0a, sf) * offset_mult > dat_size)
  498. goto fail;
  499. if (target_stream == 0) target_stream = 1;
  500. if (target_stream < 0 || total_sounds == 0 || target_stream > total_sounds)
  501. goto fail;
  502. /* offsets are always big endian */
  503. schl_offset = read_u16be(0x10 + (0x02 + userdata_size) * (target_stream - 1), sf) * offset_mult;
  504. if (read_32bitBE(schl_offset, sf_dat) != EA_BLOCKID_HEADER)
  505. goto fail;
  506. vgmstream = parse_schl_block(sf_dat, schl_offset, 0);
  507. if (!vgmstream)
  508. goto fail;
  509. vgmstream->num_streams = total_sounds;
  510. close_streamfile(sf_dat);
  511. return vgmstream;
  512. fail:
  513. close_streamfile(sf_dat);
  514. return NULL;
  515. }
  516. /* open map/mpf+mus pairs that aren't exact pairs, since EA's games can load any combo */
  517. static STREAMFILE* open_mapfile_pair(STREAMFILE* sf, int track, int num_tracks) {
  518. static const char *const mapfile_pairs[][2] = {
  519. /* standard cases, replace map part with mus part (from the end to preserve prefixes) */
  520. {"MUS_CTRL.MPF", "MUS_STR.MUS"}, /* GoldenEye - Rogue Agent (PS2) */
  521. {"mus_ctrl.mpf", "mus_str.mus"}, /* GoldenEye - Rogue Agent (others) */
  522. {"AKA_Mus.mpf", "Track.mus"}, /* Boogie */
  523. {"SSX4FE.mpf", "TrackFE.mus"}, /* SSX On Tour */
  524. {"SSX4Path.mpf", "Track.mus"}, /* SSX On Tour */
  525. {"SSX4.mpf", "moments0.mus,main.mus,load_loop0.mus"}, /* SSX Blur */
  526. {"willow.mpf", "willow.mus,willow_o.mus"}, /* Harry Potter and the Chamber of Secrets */
  527. {"exterior.mpf", "exterior.mus,ext_o.mus"}, /* Harry Potter and the Chamber of Secrets */
  528. {"Peak1Amb.mpf", "Peak1_Strm.mus,Peak1_Ovr0.mus"}, /* SSX 3 */
  529. {"Peak2Amb.mpf", "Peak2_Strm.mus,Peak2_Ovr0.mus"},
  530. {"Peak3Amb.mpf", "Peak3_Strm.mus,Peak3_Ovr0.mus"},
  531. {"*.mpf", "*_main.mus"}, /* 007 - Everything or Nothing */
  532. /* TODO: need better wildcard support
  533. * NSF2:
  534. * ZTRxxROK.MAP > ZTRxx.TRJ
  535. * ZTRxxTEC.MAP > ZTRxx.TRM
  536. * ZZSHOW.MAP and ZZSHOW2.MAP > ZZSHOW.MUS
  537. * NSF3:
  538. * ZTRxxROK.MAP > ZZZTRxxA.TRJ
  539. * ZTRxxTEC.MAP > ZZZTRxxB.TRM
  540. * ZTR00R0A.MAP and ZTR00R0B.MAP > ZZZTR00A.TRJ
  541. * other extra files that may need the hack below
  542. * SSX 3:
  543. * *.mpf > *.mus,xxloops0.mus
  544. * really need to think of something for this
  545. */
  546. };
  547. STREAMFILE* sf_mus = NULL;
  548. char file_name[PATH_LIMIT];
  549. int pair_count = (sizeof(mapfile_pairs)/sizeof(mapfile_pairs[0]));
  550. int i, j;
  551. size_t file_len, map_len;
  552. /* if loading the first track, try opening MUS with the same name first (most common scenario) */
  553. if (track == 0) {
  554. sf_mus = open_streamfile_by_ext(sf, "mus");
  555. if (sf_mus) return sf_mus;
  556. }
  557. get_streamfile_filename(sf, file_name, PATH_LIMIT);
  558. file_len = strlen(file_name);
  559. for (i = 0; i < pair_count; i++) {
  560. const char *map_name = mapfile_pairs[i][0];
  561. const char *mus_name = mapfile_pairs[i][1];
  562. char buf[PATH_LIMIT] = {0};
  563. char *pch;
  564. int use_mask = 0;
  565. map_len = strlen(map_name);
  566. /* replace map_name with expected mus_name */
  567. if (file_len < map_len)
  568. continue;
  569. if (map_name[0] == '*') {
  570. use_mask = 1;
  571. map_name++;
  572. map_len--;
  573. if (strcmp(file_name + (file_len - map_len), map_name) != 0)
  574. continue;
  575. } else {
  576. if (strcmp(file_name, map_name) != 0)
  577. continue;
  578. }
  579. strncpy(buf, mus_name, PATH_LIMIT - 1);
  580. pch = strtok(buf, ","); //TODO: not thread safe in std C
  581. for (j = 0; j < track && pch; j++) {
  582. pch = strtok(NULL, ",");
  583. }
  584. if (!pch) continue; /* invalid track */
  585. if (use_mask) {
  586. file_name[file_len - map_len] = '\0';
  587. strncat(file_name, pch + 1, PATH_LIMIT - 1);
  588. } else {
  589. strncpy(file_name, pch, PATH_LIMIT - 1);
  590. }
  591. sf_mus = open_streamfile_by_filename(sf, file_name);
  592. if (sf_mus) return sf_mus;
  593. get_streamfile_filename(sf, file_name, PATH_LIMIT); /* reset for next loop */
  594. }
  595. /* hack when when multiple maps point to the same mus, uses name before "+"
  596. * ex. ZZZTR00A.TRJ+ZTR00PGR.MAP or ZZZTR00A.TRJ+ZTR00R0A.MAP both point to ZZZTR00A.TRJ
  597. * [Need for Speed II (PS1), Need for Speed III (PS1)] */
  598. {
  599. char *mod_name = strchr(file_name, '+');
  600. if (mod_name)
  601. {
  602. mod_name[0] = '\0';
  603. sf_mus = open_streamfile_by_filename(sf, file_name);
  604. if (sf_mus) return sf_mus;
  605. }
  606. }
  607. VGM_LOG("No MPF/MUS pair specified for %s.\n", file_name);
  608. return NULL;
  609. }
  610. /* EA MAP/MUS combo - used in older games for interactive music (for EA's PathFinder tool) */
  611. VGMSTREAM * init_vgmstream_ea_map_mus(STREAMFILE* sf) {
  612. VGMSTREAM* vgmstream = NULL;
  613. STREAMFILE* sf_mus = NULL;
  614. uint8_t version, num_sounds, num_events, num_sections;
  615. off_t section_offset, schl_offset;
  616. int target_stream = sf->stream_index;
  617. /* check extension */
  618. if (!check_extensions(sf, "map,lin,mpf"))
  619. goto fail;
  620. /* always big endian */
  621. if (read_32bitBE(0x00, sf) != 0x50464478) /* "PFDx" */
  622. goto fail;
  623. version = read_8bit(0x04, sf);
  624. if (version > 1) goto fail;
  625. sf_mus = open_mapfile_pair(sf, 0, 1);
  626. if (!sf_mus) goto fail;
  627. /*
  628. * 0x04: version
  629. * 0x05: starting node
  630. * 0x06: number of nodes
  631. * 0x07: number of sections
  632. * 0x08: three zeroes
  633. * 0x0b: number of events
  634. * 0x0c: data start
  635. */
  636. num_sounds = read_8bit(0x06, sf);
  637. num_sections = read_8bit(0x07, sf);
  638. num_events = read_8bit(0x0b, sf);
  639. section_offset = 0x0c;
  640. /* section 1: nodes, contains information about segment playback order */
  641. section_offset += num_sounds * 0x1c;
  642. /* section 2: events, specific to game and track */
  643. section_offset += num_events * num_sections;
  644. if (target_stream == 0) target_stream = 1;
  645. if (target_stream < 0 || num_sounds == 0 || target_stream > num_sounds)
  646. goto fail;
  647. /* section 3: samples */
  648. schl_offset = read_32bitBE(section_offset + (target_stream - 1) * 0x04, sf);
  649. if (read_32bitBE(schl_offset, sf_mus) != EA_BLOCKID_HEADER)
  650. goto fail;
  651. vgmstream = parse_schl_block(sf_mus, schl_offset, 0);
  652. if (!vgmstream)
  653. goto fail;
  654. vgmstream->num_streams = num_sounds;
  655. close_streamfile(sf_mus);
  656. return vgmstream;
  657. fail:
  658. close_streamfile(sf_mus);
  659. return NULL;
  660. }
  661. /* EA MPF/MUS combo - used in 6th gen games for interactive music (for EA's PathFinder tool) */
  662. VGMSTREAM * init_vgmstream_ea_mpf_mus(STREAMFILE* sf) {
  663. VGMSTREAM* vgmstream = NULL;
  664. STREAMFILE* sf_mus = NULL;
  665. off_t tracks_table, samples_table, section_offset, entry_offset, eof_offset, off_mult, sound_offset;
  666. uint32_t track_start, track_hash = 0;
  667. uint16_t num_nodes;
  668. uint8_t version, sub_version, num_tracks, num_sections, num_events, num_routers, num_vars, subentry_num;
  669. int32_t(*read_32bit)(off_t, STREAMFILE*);
  670. int16_t(*read_16bit)(off_t, STREAMFILE*);
  671. int i;
  672. int target_stream = sf->stream_index, total_streams, big_endian, is_bnk = 0;
  673. /* check extension */
  674. if (!check_extensions(sf, "mpf"))
  675. goto fail;
  676. /* detect endianness */
  677. if (read_32bitBE(0x00, sf) == 0x50464478) { /* "PFDx" */
  678. read_32bit = read_32bitBE;
  679. read_16bit = read_16bitBE;
  680. big_endian = 1;
  681. } else if (read_32bitLE(0x00, sf) == 0x50464478) { /* "xDFP" */
  682. read_32bit = read_32bitLE;
  683. read_16bit = read_16bitLE;
  684. big_endian = 0;
  685. } else {
  686. goto fail;
  687. }
  688. version = read_8bit(0x04, sf);
  689. sub_version = read_8bit(0x05, sf);
  690. if (version < 3 || version > 5) goto fail;
  691. if (version == 5 && sub_version > 2) goto fail; /* newer version using SNR/SNS */
  692. num_tracks = read_8bit(0x0d, sf);
  693. num_sections = read_8bit(0x0e, sf);
  694. num_events = read_8bit(0x0f, sf);
  695. num_routers = read_8bit(0x10, sf);
  696. num_vars = read_8bit(0x11, sf);
  697. num_nodes = read_16bit(0x12, sf);
  698. /* HACK: number of sub-entries for nodes and events is stored in bitstreams that are different in LE and BE */
  699. /* I can't figure it out, so let's just use a workaround for now */
  700. if (target_stream == 0) target_stream = 1;
  701. if (version == 3)
  702. /* SSX Tricky (v3.1), Harry Potter and the Chamber of Secrets (v3.4) */ {
  703. /* we need to go through all the sections to get to the samples table */
  704. /* get the last entry offset */
  705. section_offset = 0x24;
  706. entry_offset = (uint16_t)read_16bit(section_offset + (num_nodes - 1) * 0x02, sf) * 0x04;
  707. if (sub_version == 1) {
  708. subentry_num = read_8bit(entry_offset + 0x0b, sf);
  709. } else if (sub_version == 4) {
  710. if (big_endian) {
  711. subentry_num = (read_32bitBE(entry_offset + 0x04, sf) >> 19) & 0xFF;
  712. } else {
  713. subentry_num = (read_32bitBE(entry_offset + 0x04, sf) >> 16) & 0xFF;
  714. }
  715. } else {
  716. goto fail;
  717. }
  718. section_offset = entry_offset + 0x0c + subentry_num * 0x04;
  719. section_offset += align_size_to_block(num_events * num_tracks * num_sections, 0x04);
  720. section_offset += num_routers * 0x04;
  721. section_offset += num_vars * 0x04;
  722. tracks_table = read_32bit(section_offset, sf) * 0x04;
  723. samples_table = tracks_table + (num_tracks + 1) * 0x04;
  724. for (i = num_tracks - 1; i >= 0; i--) {
  725. track_start = read_32bit(tracks_table + i * 0x04, sf) * 0x04;
  726. track_start = (track_start - samples_table) / 0x08;
  727. if (track_start <= target_stream - 1)
  728. break;
  729. }
  730. eof_offset = read_32bit(tracks_table + num_tracks * 0x04, sf) * 0x04;
  731. total_streams = (eof_offset - samples_table) / 0x08;
  732. off_mult = 0x04;
  733. } else if (version == 4) {
  734. /* Need for Speed: Underground 2, SSX 3, Harry Potter and the Prisoner of Azkaban */
  735. /* we need to go through all the sections to get to the samples table */
  736. /* get the last entry offset */
  737. section_offset = 0x20;
  738. entry_offset = (uint16_t)read_16bit(section_offset + (num_nodes - 1) * 0x02, sf) * 0x04;
  739. if (big_endian) {
  740. subentry_num = (read_32bitBE(entry_offset + 0x04, sf) >> 15) & 0xFF;
  741. } else {
  742. subentry_num = (read_32bitBE(entry_offset + 0x04, sf) >> 20) & 0xFF;
  743. }
  744. section_offset = entry_offset + 0x10 + subentry_num * 0x04;
  745. /* get the last entry offset */
  746. entry_offset = (uint16_t)read_16bit(section_offset + (num_events - 1) * 0x02, sf) * 0x04;
  747. if (big_endian) {
  748. subentry_num = (read_32bitBE(entry_offset + 0x0c, sf) >> 10) & 0xFF;
  749. } else {
  750. subentry_num = (read_32bitBE(entry_offset + 0x0c, sf) >> 8) & 0xFF;
  751. }
  752. section_offset = entry_offset + 0x10 + subentry_num * 0x10;
  753. /* TODO: verify this */
  754. section_offset = read_32bit(section_offset, sf) * 0x04;
  755. section_offset += num_routers * 0x04;
  756. section_offset += num_vars * 0x04;
  757. tracks_table = section_offset;
  758. samples_table = tracks_table + (num_tracks + 1) * 0x04;
  759. for (i = num_tracks - 1; i >= 0; i--) {
  760. track_start = read_32bit(tracks_table + i * 0x04, sf) * 0x04;
  761. track_start = (track_start - samples_table) / 0x08;
  762. if (track_start <= target_stream - 1)
  763. break;
  764. }
  765. eof_offset = read_32bit(tracks_table + num_tracks * 0x04, sf) * 0x04;
  766. total_streams = (eof_offset - samples_table) / 0x08;
  767. off_mult = 0x80;
  768. } else if (version == 5) {
  769. /* Need for Speed: Most Wanted, Need for Speed: Carbon */
  770. tracks_table = read_32bit(0x2c, sf);
  771. samples_table = read_32bit(0x34, sf);
  772. for (i = num_tracks - 1; i >= 0; i--) {
  773. entry_offset = read_32bit(tracks_table + i * 0x04, sf) * 0x04;
  774. track_start = read_32bit(entry_offset + 0x00, sf);
  775. if (track_start <= target_stream - 1) {
  776. track_hash = read_32bitBE(entry_offset + 0x08, sf);
  777. is_bnk = (track_hash == 0xF1F1F1F1);
  778. /* checks to distinguish it from SNR/SNS version */
  779. if (is_bnk) {
  780. if (read_32bitBE(entry_offset + 0x0c, sf) == 0x00)
  781. goto fail;
  782. track_hash = read_32bitBE(entry_offset + 0x14, sf);
  783. if (track_hash == 0xF1F1F1F1)
  784. continue; /* empty track */
  785. } else {
  786. if (read_32bitBE(entry_offset + 0x0c, sf) != 0x00)
  787. goto fail;
  788. }
  789. break;
  790. }
  791. }
  792. eof_offset = read_32bit(0x38, sf);
  793. total_streams = (eof_offset - samples_table) / 0x08;
  794. off_mult = 0x80;
  795. } else {
  796. goto fail;
  797. }
  798. if (target_stream < 0 || total_streams == 0 || target_stream > total_streams)
  799. goto fail;
  800. /* open MUS file that matches this track */
  801. sf_mus = open_mapfile_pair(sf, i, num_tracks);
  802. if (!sf_mus)
  803. goto fail;
  804. if (version == 5) {
  805. if (read_32bitBE(0x00, sf_mus) != track_hash)
  806. goto fail;
  807. } else {
  808. is_bnk = (read_32bitBE(0x00, sf_mus) == (big_endian ? EA_BNK_HEADER_BE : EA_BNK_HEADER_LE));
  809. }
  810. /* 0x00 - offset/BNK index, 0x04 - duration (in milliseconds) */
  811. if (is_bnk) {
  812. /* TODO: Harry Potter COS appears to reference only the first segments of multi-segment BNK sounds? */
  813. sound_offset = read_32bit(samples_table + (target_stream - 1) * 0x08 + 0x00, sf);
  814. vgmstream = parse_bnk_header(sf_mus, version < 5 ? 0x00 : 0x100, sound_offset, 1);
  815. if (!vgmstream)
  816. goto fail;
  817. } else {
  818. sound_offset = read_32bit(samples_table + (target_stream - 1) * 0x08 + 0x00, sf) * off_mult;
  819. if (read_32bitBE(sound_offset, sf_mus) != EA_BLOCKID_HEADER)
  820. goto fail;
  821. vgmstream = parse_schl_block(sf_mus, sound_offset, 0);
  822. if (!vgmstream)
  823. goto fail;
  824. }
  825. vgmstream->num_streams = total_streams;
  826. get_streamfile_filename(sf_mus, vgmstream->stream_name, STREAM_NAME_SIZE);
  827. close_streamfile(sf_mus);
  828. return vgmstream;
  829. fail:
  830. close_streamfile(sf_mus);
  831. return NULL;
  832. }
  833. /* EA SCHl with variable header - from EA games (roughly 1997~2010); generated by EA Canada's sx.exe/Sound eXchange */
  834. static VGMSTREAM * parse_schl_block(STREAMFILE* sf, off_t offset, int standalone) {
  835. off_t start_offset, header_offset;
  836. size_t header_size;
  837. uint32_t header_id;
  838. ea_header ea = { 0 };
  839. /* use higher bits to store target localized block in case of multilang video,
  840. * so only header sub-id will be read and other langs skipped */
  841. header_id = read_32bitBE(offset + 0x00, sf);
  842. if ((header_id & 0xFFFF0000) == EA_BLOCKID_LOC_HEADER) {
  843. ea.codec_config |= (header_id & 0xFFFF) << 16;
  844. }
  845. if (guess_endianness32bit(offset + 0x04, sf)) { /* size is always LE, except in early SS/MAC */
  846. header_size = read_32bitBE(offset + 0x04, sf);
  847. ea.codec_config |= 0x02;
  848. }
  849. else {
  850. header_size = read_32bitLE(offset + 0x04, sf);
  851. }
  852. header_offset = offset + 0x08;
  853. if (!parse_variable_header(sf, &ea, header_offset, header_size - 0x08, 0))
  854. goto fail;
  855. start_offset = offset + header_size; /* starts in "SCCl" (skipped in block layout) or very rarely "SCDl" and maybe movie blocks */
  856. /* rest is common */
  857. return init_vgmstream_ea_variable_header(sf, &ea, start_offset, 0, standalone);
  858. fail:
  859. return NULL;
  860. }
  861. /* EA BNK with variable header - from EA games SFXs; also created by sx.exe */
  862. static VGMSTREAM * parse_bnk_header(STREAMFILE* sf, off_t offset, int target_stream, int is_embedded) {
  863. uint32_t i;
  864. uint16_t num_sounds;
  865. off_t header_offset, start_offset, test_offset, table_offset, entry_offset;
  866. size_t header_size;
  867. ea_header ea = { 0 };
  868. int32_t(*read_32bit)(off_t, STREAMFILE*) = NULL;
  869. int16_t(*read_16bit)(off_t, STREAMFILE*) = NULL;
  870. VGMSTREAM *vgmstream = NULL;
  871. int bnk_version;
  872. int real_bnk_sounds = 0;
  873. /* check header */
  874. /* BNK header endianness is platform-native */
  875. if (read_32bitBE(offset + 0x00, sf) == EA_BNK_HEADER_BE) {
  876. read_32bit = read_32bitBE;
  877. read_16bit = read_16bitBE;
  878. } else if (read_32bitBE(offset + 0x00, sf) == EA_BNK_HEADER_LE) {
  879. read_32bit = read_32bitLE;
  880. read_16bit = read_16bitLE;
  881. } else {
  882. goto fail;
  883. }
  884. bnk_version = read_8bit(offset + 0x04, sf);
  885. num_sounds = read_16bit(offset + 0x06, sf);
  886. /* check multi-streams */
  887. switch (bnk_version) {
  888. case 0x02: /* early [Need For Speed II (PC/PS1), FIFA 98 (PC/PS1/SAT)] */
  889. table_offset = 0x0c;
  890. header_size = read_32bit(offset + 0x08, sf); /* full size */
  891. break;
  892. case 0x04: /* mid (last used in PSX banks) */
  893. case 0x05: /* late (generated by sx.exe ~v2+) */
  894. /* 0x08: header/file size, 0x0C: file size/null, 0x10: always null */
  895. table_offset = 0x14;
  896. header_size = get_streamfile_size(sf); /* unknown (header is variable and may have be garbage until data) */
  897. break;
  898. default:
  899. VGM_LOG("EA BNK: unknown version %x\n", bnk_version);
  900. goto fail;
  901. }
  902. header_offset = 0;
  903. if (is_embedded) {
  904. if (target_stream < 0 || target_stream >= num_sounds)
  905. goto fail;
  906. entry_offset = offset + table_offset + 0x04 * target_stream;
  907. header_offset = entry_offset + read_32bit(entry_offset, sf);
  908. } else {
  909. /* some of these are dummies with zero offset, skip them when opening standalone BNK */
  910. for (i = 0; i < num_sounds; i++) {
  911. entry_offset = offset + table_offset + 0x04 * i;
  912. test_offset = read_32bit(entry_offset, sf);
  913. if (test_offset != 0) {
  914. if (target_stream == real_bnk_sounds)
  915. header_offset = entry_offset + test_offset;
  916. real_bnk_sounds++;
  917. }
  918. }
  919. }
  920. if (header_offset == 0) goto fail;
  921. if (!parse_variable_header(sf, &ea, header_offset, header_size - header_offset, bnk_version))
  922. goto fail;
  923. /* fix absolute offsets so it works in next funcs */
  924. if (offset) {
  925. for (i = 0; i < ea.channels; i++) {
  926. ea.offsets[i] += offset;
  927. }
  928. }
  929. start_offset = ea.offsets[0]; /* first channel, presumably needed for MPEG */
  930. /* rest is common */
  931. vgmstream = init_vgmstream_ea_variable_header(sf, &ea, start_offset, bnk_version, 0);
  932. if (!vgmstream) goto fail;
  933. if (!is_embedded) {
  934. vgmstream->num_streams = real_bnk_sounds;
  935. }
  936. return vgmstream;
  937. fail:
  938. return NULL;
  939. }
  940. /* inits VGMSTREAM from a EA header */
  941. static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int bnk_version, int standalone) {
  942. VGMSTREAM * vgmstream = NULL;
  943. int i, ch;
  944. int is_bnk = bnk_version;
  945. /* build the VGMSTREAM */
  946. vgmstream = allocate_vgmstream(ea->channels, ea->loop_flag);
  947. if (!vgmstream) goto fail;
  948. vgmstream->sample_rate = ea->sample_rate;
  949. vgmstream->num_samples = ea->num_samples;
  950. vgmstream->loop_start_sample = ea->loop_start;
  951. vgmstream->loop_end_sample = ea->loop_end;
  952. vgmstream->codec_endian = ea->big_endian;
  953. vgmstream->codec_config = ea->codec_config;
  954. vgmstream->meta_type = is_bnk ? meta_EA_BNK : meta_EA_SCHL;
  955. if (is_bnk) {
  956. vgmstream->layout_type = layout_none;
  957. /* BNKs usually have absolute offsets for all channels ("full" interleave) except in some versions */
  958. if (ea->channels > 1 && ea->codec1 == EA_CODEC1_PCM) {
  959. int interleave = (ea->num_samples * (ea->bps == 8 ? 0x01 : 0x02)); /* full interleave */
  960. for (i = 0; i < ea->channels; i++) {
  961. ea->offsets[i] = ea->offsets[0] + interleave*i;
  962. }
  963. }
  964. else if (ea->channels > 1 && ea->codec1 == EA_CODEC1_VAG) {
  965. int interleave = (ea->num_samples / 28 * 16); /* full interleave */
  966. for (i = 0; i < ea->channels; i++) {
  967. ea->offsets[i] = ea->offsets[0] + interleave*i;
  968. }
  969. }
  970. else if (ea->channels > 1 && ea->codec2 == EA_CODEC2_GCADPCM && ea->offsets[0] == ea->offsets[1]) {
  971. /* pcstream+gcadpcm with sx.exe v2, not in flag_value, probably a bug (even with this parts of the wave are off) */
  972. int interleave = (ea->num_samples / 14 * 8); /* full interleave */
  973. for (i = 0; i < ea->channels; i++) {
  974. ea->offsets[i] = ea->offsets[0] + interleave*i;
  975. }
  976. }
  977. else if (ea->channels > 1 && ea->codec2 == EA_CODEC2_N64 && ea->offsets[1] == 0) {
  978. uint32_t interleave = ea->flag_value;
  979. for (i = 0; i < ea->channels; i++) {
  980. ea->offsets[i] = ea->offsets[0] + interleave * i;
  981. }
  982. }
  983. }
  984. else {
  985. vgmstream->layout_type = layout_blocked_ea_schl;
  986. }
  987. /* EA usually implements their codecs in all platforms (PS2/WII do EAXA/MT/EALAYER3) and
  988. * favors them over platform's natives (ex. EAXA vs VAG/DSP).
  989. * Unneeded codecs are removed over time (ex. LAYER3 when EALAYER3 was introduced). */
  990. switch (ea->codec2) {
  991. case EA_CODEC2_EAXA: /* EA-XA, CDXA ADPCM variant */
  992. if (ea->version == EA_VERSION_V0) {
  993. if (ea->platform != EA_PLATFORM_SAT && ea->channels > 1)
  994. vgmstream->coding_type = coding_EA_XA; /* original version, stereo stream */
  995. else
  996. vgmstream->coding_type = coding_EA_XA_int; /* interleaved mono streams */
  997. }
  998. else { /* later revision with PCM blocks and slighty modified decoding */
  999. vgmstream->coding_type = coding_EA_XA_V2;
  1000. }
  1001. break;
  1002. case EA_CODEC2_S8: /* PCM8 */
  1003. vgmstream->coding_type = coding_PCM8;
  1004. break;
  1005. case EA_CODEC2_S16BE: /* PCM16BE */
  1006. vgmstream->coding_type = coding_PCM16BE;
  1007. break;
  1008. case EA_CODEC2_S16LE: /* PCM16LE */
  1009. if (ea->version > EA_VERSION_V0) {
  1010. vgmstream->coding_type = coding_PCM16LE;
  1011. } else { /* Need for Speed III: Hot Pursuit (PC) */
  1012. vgmstream->coding_type = coding_PCM16_int;
  1013. }
  1014. break;
  1015. case EA_CODEC2_VAG: /* PS-ADPCM */
  1016. vgmstream->coding_type = coding_PSX;
  1017. break;
  1018. case EA_CODEC2_XBOXADPCM: /* XBOX IMA (interleaved mono) */
  1019. vgmstream->coding_type = coding_XBOX_IMA_int;
  1020. break;
  1021. case EA_CODEC2_GCADPCM: /* DSP */
  1022. vgmstream->coding_type = coding_NGC_DSP;
  1023. /* get them coefs (start offsets are not necessarily ordered) */
  1024. {
  1025. int16_t (*read_16bit)(off_t,STREAMFILE*) = ea->big_endian ? read_16bitBE : read_16bitLE;
  1026. for (ch=0; ch < ea->channels; ch++) {
  1027. for (i=0; i < 16; i++) { /* actual size 0x21, last byte unknown */
  1028. vgmstream->ch[ch].adpcm_coef[i] = read_16bit(ea->coefs[ch] + i*2, sf);
  1029. }
  1030. }
  1031. }
  1032. break;
  1033. case EA_CODEC2_N64: /* VADPCM */
  1034. vgmstream->coding_type = coding_VADPCM;
  1035. vgmstream->layout_type = layout_none;
  1036. for (ch = 0; ch < ea->channels; ch++) {
  1037. int order = read_u32be(ea->coefs[ch] + 0x00, sf);
  1038. int entries = read_u32be(ea->coefs[ch] + 0x04, sf);
  1039. vadpcm_read_coefs_be(vgmstream, sf, ea->coefs[ch] + 0x08, order, entries, ch);
  1040. }
  1041. break;
  1042. #ifdef VGM_USE_MPEG
  1043. case EA_CODEC2_LAYER2: /* MPEG Layer II, aka MP2 */
  1044. case EA_CODEC2_LAYER3: { /* MPEG Layer III, aka MP3 */
  1045. mpeg_custom_config cfg = {0};
  1046. off_t mpeg_start_offset = is_bnk ?
  1047. start_offset :
  1048. get_ea_stream_mpeg_start_offset(sf, start_offset, ea);
  1049. if (!mpeg_start_offset) goto fail;
  1050. /* layout is still blocks, but should work fine with the custom mpeg decoder */
  1051. vgmstream->codec_data = init_mpeg_custom(sf, mpeg_start_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_EA, &cfg);
  1052. if (!vgmstream->codec_data) goto fail;
  1053. break;
  1054. }
  1055. case EA_CODEC2_EALAYER3: { /* MP3 variant */
  1056. mpeg_custom_config cfg = {0};
  1057. off_t mpeg_start_offset = is_bnk ?
  1058. start_offset :
  1059. get_ea_stream_mpeg_start_offset(sf, start_offset, ea);
  1060. if (!mpeg_start_offset) goto fail;
  1061. /* layout is still blocks, but should work fine with the custom mpeg decoder */
  1062. vgmstream->codec_data = init_mpeg_custom(sf, mpeg_start_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_EAL31, &cfg);
  1063. if (!vgmstream->codec_data) goto fail;
  1064. break;
  1065. }
  1066. #endif
  1067. case EA_CODEC2_MT10: /* MicroTalk (10:1 compression) */
  1068. case EA_CODEC2_MT5: { /* MicroTalk (5:1 compression) */
  1069. int use_pcm_blocks = 0;
  1070. if (ea->version == EA_VERSION_V3 || (ea->version == EA_VERSION_V2 &&
  1071. (ea->platform == EA_PLATFORM_PC ||
  1072. ea->platform == EA_PLATFORM_MAC ||
  1073. ea->platform == EA_PLATFORM_GENERIC))) {
  1074. use_pcm_blocks = 1;
  1075. }
  1076. /* make relative loops absolute for the decoder */
  1077. if (ea->loop_flag) {
  1078. for (i = 0; i < ea->channels; i++) {
  1079. ea->loops[i] += ea->offsets[0];
  1080. }
  1081. }
  1082. vgmstream->coding_type = coding_EA_MT;
  1083. vgmstream->codec_data = init_ea_mt_loops(vgmstream->channels, use_pcm_blocks, ea->loop_start, ea->loops);
  1084. if (!vgmstream->codec_data) goto fail;
  1085. break;
  1086. }
  1087. #ifdef VGM_USE_FFMPEG
  1088. case EA_CODEC2_ATRAC3PLUS: {
  1089. /* regular ATRAC3plus chunked in SCxx blocks, including RIFF header [Medal of Honor Heroes 2 (PSP)] */
  1090. if (!is_bnk) {
  1091. STREAMFILE* temp_sf = NULL;
  1092. /* remove blocks on reads to feed FFmpeg a clean .at3 */
  1093. temp_sf = setup_schl_streamfile(sf, ea->codec2, ea->channels, start_offset, 0);
  1094. if (!temp_sf) goto fail;
  1095. start_offset = 0x00; /* must point to the custom streamfile's beginning */
  1096. ea->stream_size = get_streamfile_size(temp_sf);
  1097. vgmstream->codec_data = init_ffmpeg_atrac3_riff(temp_sf, start_offset, NULL);
  1098. close_streamfile(temp_sf);
  1099. }
  1100. else {
  1101. /* memory file without blocks */
  1102. vgmstream->codec_data = init_ffmpeg_atrac3_riff(sf, start_offset, NULL);
  1103. }
  1104. if (!vgmstream->codec_data) goto fail;
  1105. vgmstream->coding_type = coding_FFmpeg;
  1106. vgmstream->layout_type = layout_none;
  1107. break;
  1108. }
  1109. #endif
  1110. default:
  1111. VGM_LOG("EA SCHl: unknown codec2 0x%02x for platform 0x%02x\n", ea->codec2, ea->platform);
  1112. goto fail;
  1113. }
  1114. vgmstream->stream_size = ea->stream_size;
  1115. /* open files; channel offsets are updated below (force multibuffer for bnk) */
  1116. if (!vgmstream_open_stream_bf(vgmstream, sf, start_offset, 1))
  1117. goto fail;
  1118. if (is_bnk) {
  1119. /* setup channel offsets */
  1120. if (vgmstream->coding_type == coding_EA_XA) {
  1121. /* shared (stereo/mono codec) */
  1122. for (i = 0; i < vgmstream->channels; i++) {
  1123. vgmstream->ch[i].offset = ea->offsets[0];
  1124. }
  1125. }
  1126. //else if (vgmstream->layout_type == layout_interleave) { /* interleaved */
  1127. // for (i = 0; i < vgmstream->channels; i++) {
  1128. // vgmstream->ch[i].offset = ea->offsets[0] + vgmstream->interleave_block_size*i;
  1129. // }
  1130. //}
  1131. else if (vgmstream->coding_type == coding_PCM16_int && ea->version == EA_VERSION_V0) {
  1132. /* Need for Speed II (PC) bad offsets */
  1133. for (i = 0; i < vgmstream->channels; i++) {
  1134. vgmstream->ch[i].offset = ea->offsets[0] + 0x02*i;
  1135. }
  1136. }
  1137. else if (vgmstream->coding_type == coding_PCM8 && ea->platform == EA_PLATFORM_PS2 && ea->version == EA_VERSION_V3) {
  1138. /* SSX3 (PS2) weird 0x10 mini header (codec/loop start/loop end/samples) */
  1139. for (i = 0; i < vgmstream->channels; i++) {
  1140. vgmstream->ch[i].offset = ea->offsets[0] + 0x10;
  1141. }
  1142. }
  1143. else {
  1144. /* absolute */
  1145. for (i = 0; i < vgmstream->channels; i++) {
  1146. vgmstream->ch[i].offset = ea->offsets[i];
  1147. }
  1148. }
  1149. /* TODO: Figure out how to get stream size for BNK sounds */
  1150. }
  1151. else {
  1152. update_ea_stream_size_and_samples(sf, start_offset, vgmstream, standalone);
  1153. }
  1154. return vgmstream;
  1155. fail:
  1156. close_vgmstream(vgmstream);
  1157. return NULL;
  1158. }
  1159. static uint32_t read_patch(STREAMFILE* sf, off_t* offset) {
  1160. uint32_t result = 0;
  1161. uint8_t byte_count = read_8bit(*offset, sf);
  1162. (*offset)++;
  1163. if (byte_count == 0xFF) { /* signals 32b size (ex. custom user data) */
  1164. (*offset) += 4 + read_32bitBE(*offset, sf);
  1165. return 0;
  1166. }
  1167. if (byte_count > 4) { /* uncommon (ex. coef patches) */
  1168. (*offset) += byte_count;
  1169. return 0;
  1170. }
  1171. for ( ; byte_count > 0; byte_count--) { /* count of 0 is also possible, means value 0 */
  1172. result <<= 8;
  1173. result += (uint8_t)read_8bit(*offset, sf);
  1174. (*offset)++;
  1175. }
  1176. return result;
  1177. }
  1178. /* decodes EA's GSTR/PT header (mostly cross-referenced with sx.exe) */
  1179. static int parse_variable_header(STREAMFILE* sf, ea_header* ea, off_t begin_offset, int max_length, int bnk_version) {
  1180. off_t offset = begin_offset;
  1181. uint32_t platform_id;
  1182. int is_header_end = 0;
  1183. int is_bnk = bnk_version;
  1184. /* null defaults as 0 can be valid */
  1185. ea->version = EA_VERSION_NONE;
  1186. ea->codec1 = EA_CODEC1_NONE;
  1187. ea->codec2 = EA_CODEC2_NONE;
  1188. /* get platform info */
  1189. platform_id = read_32bitBE(offset, sf);
  1190. if (platform_id != 0x47535452 && (platform_id & 0xFFFF0000) != 0x50540000) {
  1191. offset += 4; /* skip unknown field (related to blocks/size?) in "nbapsstream" (NBA2000 PS, FIFA2001 PS) */
  1192. platform_id = read_32bitBE(offset, sf);
  1193. }
  1194. if (platform_id == 0x47535452) { /* "GSTR" = Generic STReam */
  1195. ea->platform = EA_PLATFORM_GENERIC;
  1196. offset += 4 + 4; /* GSTRs have an extra field (config?): ex. 0x01000000, 0x010000D8 BE */
  1197. }
  1198. else if ((platform_id & 0xFFFF0000) == 0x50540000) { /* "PT" = PlaTform */
  1199. ea->platform = (uint16_t)read_16bitLE(offset + 2,sf);
  1200. offset += 4;
  1201. }
  1202. else {
  1203. goto fail;
  1204. }
  1205. /* parse mini-chunks/tags (variable, ommited if default exists; some are removed in later versions of sx.exe) */
  1206. while (!is_header_end && offset - begin_offset < max_length) {
  1207. uint8_t patch_type = read_8bit(offset,sf);
  1208. offset++;
  1209. //;{ off_t test = offset; VGM_LOG("EA SCHl: patch=%02x at %lx, value=%x\n", patch_type, offset-1, read_patch(sf, &test)); }
  1210. switch(patch_type) {
  1211. case 0x00: /* signals non-default block rate and maybe other stuff; or padding after 0xFF */
  1212. if (!is_header_end)
  1213. read_patch(sf, &offset);
  1214. break;
  1215. case 0x05: /* unknown (usually 0x50 except Madden NFL 3DS: 0x3e800) */
  1216. case 0x06: /* priority (0..100, always 0x65 for streams, others for BNKs; rarely ommited) */
  1217. case 0x07: /* unknown (BNK only: 36|3A|40) */
  1218. case 0x08: /* release envelope (BNK only) */
  1219. case 0x09: /* related to playback envelope (BNK only) */
  1220. case 0x0A: /* bend range (BNK only) */
  1221. case 0x0B: /* bank channels (or, offsets[] size; defaults to 1 if not present, removed in sx.exe v3) */
  1222. case 0x0C: /* pan offset (BNK only) */
  1223. case 0x0D: /* random pan offset range (BNK only) */
  1224. case 0x0E: /* volume (BNK only) */
  1225. case 0x0F: /* random volume range (BNK only) */
  1226. case 0x10: /* detune (BNK only) */
  1227. case 0x11: /* random detune range (BNK only) */
  1228. case 0x12: /* unknown, rare (BNK only) [Need for Speed III: Hot Pursuit (PS1)] */
  1229. case 0x13: /* effect bus (0..127) */
  1230. case 0x14: /* emdedded user data (free size/value) */
  1231. case 0x15: /* unknown, rare (BNK only) [Need for Speed: High Stakes (PS1)] */
  1232. case 0x19: /* related to playback envelope (BNK only) */
  1233. case 0x1B: /* unknown (movie only?) */
  1234. case 0x1C: /* initial envelope volume (BNK only) */
  1235. case 0x1D: /* unknown, rare [NASCAR 06 (Xbox)] */
  1236. case 0x1E: /* related to ch1? (BNK only) */
  1237. case 0x1F:
  1238. case 0x20:
  1239. case 0x21: /* related to ch2? (BNK only) */
  1240. case 0x22:
  1241. case 0x23:
  1242. case 0x24: /* master random detune range (BNK only) */
  1243. case 0x25: /* unknown */
  1244. read_patch(sf, &offset);
  1245. break;
  1246. case 0xFC: /* padding for alignment between patches */
  1247. case 0xFD: /* info section start marker */
  1248. break;
  1249. case 0x83: /* codec1 defines, used early revisions */
  1250. ea->codec1 = read_patch(sf, &offset);
  1251. break;
  1252. case 0xA0: /* codec2 defines */
  1253. ea->codec2 = read_patch(sf, &offset);
  1254. break;
  1255. case 0x80: /* version, affecting some codecs */
  1256. ea->version = read_patch(sf, &offset);
  1257. break;
  1258. case 0x81: /* bits per sample for codec1 PCM */
  1259. ea->bps = read_patch(sf, &offset);
  1260. break;
  1261. case 0x82: /* channel count */
  1262. ea->channels = read_patch(sf, &offset);
  1263. break;
  1264. case 0x84: /* sample rate */
  1265. ea->sample_rate = read_patch(sf,&offset);
  1266. break;
  1267. case 0x85: /* sample count */
  1268. ea->num_samples = read_patch(sf, &offset);
  1269. break;
  1270. case 0x86: /* loop start sample */
  1271. ea->loop_start = read_patch(sf, &offset);
  1272. break;
  1273. case 0x87: /* loop end sample */
  1274. ea->loop_end = read_patch(sf, &offset) + 1; /* sx.exe does +1 */
  1275. break;
  1276. /* channel offsets (BNK only), can be the equal for all channels or interleaved; not necessarily contiguous */
  1277. case 0x88: /* absolute offset of ch1 (or ch1+ch2 for stereo EAXA) */
  1278. ea->offsets[0] = read_patch(sf, &offset);
  1279. break;
  1280. case 0x89: /* absolute offset of ch2 */
  1281. ea->offsets[1] = read_patch(sf, &offset);
  1282. break;
  1283. case 0x94: /* absolute offset of ch3 */
  1284. ea->offsets[2] = read_patch(sf, &offset);
  1285. break;
  1286. case 0x95: /* absolute offset of ch4 */
  1287. ea->offsets[3] = read_patch(sf, &offset);
  1288. break;
  1289. case 0xA2: /* absolute offset of ch5 */
  1290. ea->offsets[4] = read_patch(sf, &offset);
  1291. break;
  1292. case 0xA3: /* absolute offset of ch6 */
  1293. ea->offsets[5] = read_patch(sf, &offset);
  1294. break;
  1295. case 0x8F: /* DSP/N64BLK coefs ch1 */
  1296. ea->coefs[0] = offset+1;
  1297. read_patch(sf, &offset);
  1298. break;
  1299. case 0x90: /* DSP/N64BLK coefs ch2 */
  1300. ea->coefs[1] = offset+1;
  1301. read_patch(sf, &offset);
  1302. break;
  1303. case 0x91: /* DSP coefs ch3, and unknown in older versions */
  1304. ea->coefs[2] = offset+1;
  1305. read_patch(sf, &offset);
  1306. break;
  1307. case 0xAB: /* DSP coefs ch4 */
  1308. ea->coefs[3] = offset+1;
  1309. read_patch(sf, &offset);
  1310. break;
  1311. case 0xAC: /* DSP coefs ch5 */
  1312. ea->coefs[4] = offset+1;
  1313. read_patch(sf, &offset);
  1314. break;
  1315. case 0xAD: /* DSP coefs ch6 */
  1316. ea->coefs[5] = offset+1;
  1317. read_patch(sf, &offset);
  1318. break;
  1319. case 0x1A: /* EA-MT/EA-XA relative loop offset of ch1 */
  1320. ea->loops[0] = read_patch(sf, &offset);
  1321. break;
  1322. case 0x26: /* EA-MT/EA-XA relative loop offset of ch2 */
  1323. ea->loops[1] = read_patch(sf, &offset);
  1324. break;
  1325. case 0x27: /* EA-MT/EA-XA relative loop offset of ch3 */
  1326. ea->loops[2] = read_patch(sf, &offset);
  1327. break;
  1328. case 0x28: /* EA-MT/EA-XA relative loop offset of ch4 */
  1329. ea->loops[3] = read_patch(sf, &offset);
  1330. break;
  1331. case 0x29: /* EA-MT/EA-XA relative loop offset of ch5 */
  1332. ea->loops[4] = read_patch(sf, &offset);
  1333. break;
  1334. case 0x2a: /* EA-MT/EA-XA relative loop offset of ch6 */
  1335. ea->loops[5] = read_patch(sf, &offset);
  1336. break;
  1337. case 0x8C: /* flags (ex. play type = 01=static/02=dynamic | spatialize = 20=pan/etc) */
  1338. /* (ex. PS1 VAG=0, PS2 PCM/LAYER2=4, GC EAXA=4, 3DS DSP=512, Xbox EAXA=36, N64 BLK=05E800, N64 MT10=01588805E800) */
  1339. /* in rare cases value is the interleave, will be ignored if > 32b */
  1340. ea->flag_value = read_patch(sf, &offset);
  1341. break;
  1342. case 0x8A: /* long padding (always 0x00000000) */
  1343. case 0x8B: /* also padding? [Need for Speed: Hot Pursuit 2 (PC)] */
  1344. case 0x8D: /* unknown, rare [FIFA 07 (GC)] */
  1345. case 0x8E:
  1346. case 0x92: /* bytes per sample? */
  1347. case 0x93: /* unknown (BNK only) [Need for Speed III: Hot Pursuit (PC)] */
  1348. case 0x98: /* embedded time stretch 1 (long data for who-knows-what) */
  1349. case 0x99: /* embedded time stretch 2 */
  1350. case 0x9C: /* azimuth ch1 */
  1351. case 0x9D: /* azimuth ch2 */
  1352. case 0x9E: /* azimuth ch3 */
  1353. case 0x9F: /* azimuth ch4 */
  1354. case 0xA6: /* azimuth ch5 */
  1355. case 0xA7: /* azimuth ch6 */
  1356. case 0xA1: /* unknown and very rare, always 0x02 [FIFA 2001 (PS2)] */
  1357. read_patch(sf, &offset);
  1358. break;
  1359. case 0xFF: /* header end (then 0-padded so it's 32b aligned) */
  1360. is_header_end = 1;
  1361. break;
  1362. case 0xFE: /* info subsection start marker (rare [SSX3 (PS2)]) */
  1363. is_header_end = 1;
  1364. /* Signals that another info section starts, redefining codec/samples/offsets/etc
  1365. * (previous header values should be cleared first as not everything is overwritten).
  1366. * This subsection seems the same as a next or prev PT subsong, so it's ignored. */
  1367. break;
  1368. default:
  1369. VGM_LOG("EA SCHl: unknown patch 0x%02x\n", patch_type);
  1370. goto fail;
  1371. }
  1372. }
  1373. if (ea->channels > EA_MAX_CHANNELS)
  1374. goto fail;
  1375. /* Set defaults per platform, as the header ommits them when possible */
  1376. ea->loop_flag = (ea->loop_end);
  1377. /* affects blocks/codecs */
  1378. if (ea->platform == EA_PLATFORM_N64
  1379. || ea->platform == EA_PLATFORM_MAC
  1380. || ea->platform == EA_PLATFORM_SAT
  1381. || ea->platform == EA_PLATFORM_GC_WII
  1382. || ea->platform == EA_PLATFORM_X360
  1383. || ea->platform == EA_PLATFORM_PS3
  1384. || ea->platform == EA_PLATFORM_GENERIC) {
  1385. ea->big_endian = 1;
  1386. }
  1387. if (!ea->channels) {
  1388. ea->channels = 1;
  1389. }
  1390. /* version mainly affects defaults and minor stuff, can come with all codecs */
  1391. /* V0 is often just null but it's specified in some files (uncommon, with patch size 0x00) */
  1392. if (ea->version == EA_VERSION_NONE) {
  1393. switch(ea->platform) {
  1394. case EA_PLATFORM_PC: ea->version = EA_VERSION_V0; break;
  1395. case EA_PLATFORM_PSX: ea->version = EA_VERSION_V0; break; // assumed
  1396. case EA_PLATFORM_N64: ea->version = EA_VERSION_V0; break;
  1397. case EA_PLATFORM_MAC: ea->version = EA_VERSION_V0; break;
  1398. case EA_PLATFORM_SAT: ea->version = EA_VERSION_V0; break;
  1399. case EA_PLATFORM_PS2: ea->version = EA_VERSION_V1; break;
  1400. case EA_PLATFORM_GC_WII: ea->version = EA_VERSION_V2; break;
  1401. case EA_PLATFORM_XBOX: ea->version = EA_VERSION_V2; break;
  1402. case EA_PLATFORM_X360: ea->version = EA_VERSION_V3; break;
  1403. case EA_PLATFORM_PSP: ea->version = EA_VERSION_V3; break;
  1404. case EA_PLATFORM_PS3: ea->version = EA_VERSION_V3; break;
  1405. case EA_PLATFORM_3DS: ea->version = EA_VERSION_V3; break;
  1406. case EA_PLATFORM_GENERIC: ea->version = EA_VERSION_V2; break;
  1407. default:
  1408. VGM_LOG("EA SCHl: unknown default version for platform 0x%02x\n", ea->platform);
  1409. goto fail;
  1410. }
  1411. }
  1412. /* codec1 defaults */
  1413. if (ea->codec1 == EA_CODEC1_NONE && ea->version == EA_VERSION_V0) {
  1414. switch(ea->platform) {
  1415. case EA_PLATFORM_PC: ea->codec1 = EA_CODEC1_PCM; break;
  1416. case EA_PLATFORM_PSX: ea->codec1 = EA_CODEC1_VAG; break; // assumed
  1417. case EA_PLATFORM_N64: ea->codec1 = EA_CODEC1_N64; break;
  1418. case EA_PLATFORM_MAC: ea->codec1 = EA_CODEC1_PCM; break; // assumed
  1419. case EA_PLATFORM_SAT: ea->codec1 = EA_CODEC1_PCM; break;
  1420. default:
  1421. VGM_LOG("EA SCHl: unknown default codec1 for platform 0x%02x\n", ea->platform);
  1422. goto fail;
  1423. }
  1424. }
  1425. /* codec1 to codec2 to simplify later parsing */
  1426. if (ea->codec1 != EA_CODEC1_NONE && ea->codec2 == EA_CODEC2_NONE) {
  1427. switch (ea->codec1) {
  1428. case EA_CODEC1_PCM:
  1429. ea->codec2 = ea->bps==8 ? EA_CODEC2_S8 : (ea->big_endian ? EA_CODEC2_S16BE : EA_CODEC2_S16LE);
  1430. break;
  1431. case EA_CODEC1_VAG: ea->codec2 = EA_CODEC2_VAG; break;
  1432. case EA_CODEC1_EAXA: ea->codec2 = EA_CODEC2_EAXA; break;
  1433. case EA_CODEC1_MT10: ea->codec2 = EA_CODEC2_MT10; break;
  1434. case EA_CODEC1_N64: ea->codec2 = EA_CODEC2_N64; break;
  1435. default:
  1436. VGM_LOG("EA SCHl: unknown codec1 0x%02x\n", ea->codec1);
  1437. goto fail;
  1438. }
  1439. }
  1440. /* codec2 defaults */
  1441. if (ea->codec2 == EA_CODEC2_NONE) {
  1442. switch(ea->platform) {
  1443. case EA_PLATFORM_GENERIC: ea->codec2 = EA_CODEC2_EAXA; break;
  1444. case EA_PLATFORM_PC: ea->codec2 = EA_CODEC2_EAXA; break;
  1445. case EA_PLATFORM_PSX: ea->codec2 = EA_CODEC2_VAG; break;
  1446. case EA_PLATFORM_MAC: ea->codec2 = EA_CODEC2_EAXA; break;
  1447. case EA_PLATFORM_PS2: ea->codec2 = EA_CODEC2_VAG; break;
  1448. case EA_PLATFORM_GC_WII: ea->codec2 = EA_CODEC2_S16BE; break;
  1449. case EA_PLATFORM_XBOX: ea->codec2 = EA_CODEC2_S16LE; break;
  1450. case EA_PLATFORM_X360: ea->codec2 = EA_CODEC2_EAXA; break;
  1451. case EA_PLATFORM_PSP: ea->codec2 = EA_CODEC2_EAXA; break;
  1452. case EA_PLATFORM_PS3: ea->codec2 = EA_CODEC2_EAXA; break;
  1453. case EA_PLATFORM_3DS: ea->codec2 = EA_CODEC2_GCADPCM; break;
  1454. default:
  1455. VGM_LOG("EA SCHl: unknown default codec2 for platform 0x%02x\n", ea->platform);
  1456. goto fail;
  1457. }
  1458. }
  1459. /* somehow doesn't follow machine's sample rate or anything sensical */
  1460. if (!ea->sample_rate) {
  1461. switch(ea->platform) {
  1462. case EA_PLATFORM_GENERIC: ea->sample_rate = 48000; break;
  1463. case EA_PLATFORM_PC: ea->sample_rate = 22050; break;
  1464. case EA_PLATFORM_PSX: ea->sample_rate = 22050; break;
  1465. case EA_PLATFORM_N64: ea->sample_rate = 22050; break;
  1466. case EA_PLATFORM_MAC: ea->sample_rate = 22050; break;
  1467. case EA_PLATFORM_SAT: ea->sample_rate = 22050; break;
  1468. case EA_PLATFORM_PS2: ea->sample_rate = 22050; break;
  1469. case EA_PLATFORM_GC_WII: ea->sample_rate = 24000; break;
  1470. case EA_PLATFORM_XBOX: ea->sample_rate = 24000; break;
  1471. case EA_PLATFORM_X360: ea->sample_rate = 44100; break;
  1472. case EA_PLATFORM_PSP: ea->sample_rate = 22050; break;
  1473. case EA_PLATFORM_PS3: ea->sample_rate = 44100; break;
  1474. case EA_PLATFORM_3DS: ea->sample_rate = 32000; break;
  1475. default:
  1476. VGM_LOG("EA SCHl: unknown default sample rate for platform 0x%02x\n", ea->platform);
  1477. goto fail;
  1478. }
  1479. }
  1480. /* some codecs have ADPCM hist at the start of every block in streams (but not BNKs) */
  1481. if (!is_bnk) {
  1482. if (ea->codec2 == EA_CODEC2_GCADPCM) {
  1483. if (ea->platform == EA_PLATFORM_3DS)
  1484. ea->codec_config |= 0x01;
  1485. }
  1486. else if (ea->codec2 == EA_CODEC2_EAXA) {
  1487. /* EA-XA has ADPCM hist in earlier versions */
  1488. /* V0, V1: always */
  1489. /* V2: consoles only */
  1490. /* V3: never */
  1491. if (ea->version <= EA_VERSION_V1) {
  1492. ea->codec_config |= 0x01;
  1493. }
  1494. else if (ea->version == EA_VERSION_V2) {
  1495. if (ea->platform == EA_PLATFORM_PS2 || ea->platform == EA_PLATFORM_GC_WII || ea->platform == EA_PLATFORM_XBOX)
  1496. ea->codec_config |= 0x01;
  1497. }
  1498. }
  1499. }
  1500. return offset;
  1501. fail:
  1502. return 0;
  1503. }
  1504. static void update_ea_stream_size_and_samples(STREAMFILE* sf, off_t start_offset, VGMSTREAM *vgmstream, int standalone) {
  1505. uint32_t block_id;
  1506. int32_t num_samples = 0;
  1507. size_t stream_size = 0, file_size;
  1508. int multiple_schl = 0;
  1509. file_size = get_streamfile_size(sf);
  1510. /* formats with custom codecs */
  1511. if (vgmstream->layout_type != layout_blocked_ea_schl) {
  1512. return;
  1513. }
  1514. /* manually read totals */
  1515. vgmstream->next_block_offset = start_offset;
  1516. while (vgmstream->next_block_offset < file_size) {
  1517. block_update_ea_schl(vgmstream->next_block_offset, vgmstream);
  1518. if (vgmstream->current_block_samples < 0)
  1519. break;
  1520. block_id = read_32bitBE(vgmstream->current_block_offset + 0x00, sf);
  1521. if (block_id == EA_BLOCKID_END) { /* banks should never contain movie "SHxx" */
  1522. if (!standalone)
  1523. break;
  1524. }
  1525. else if (block_id == EA_BLOCKID_HEADER) { /* "SCHl" start block (movie "SHxx" shouldn't use multi files) */
  1526. multiple_schl = 1;
  1527. }
  1528. if (vgmstream->current_block_samples > 0) {
  1529. /* HACK: fix num_samples for streams with multiple SCHl. Need to eventually get rid of this.
  1530. * Get total samples by parsing block headers, needed when multiple files are stitched together.
  1531. * Some EA files (.mus/eam/sng/etc) concat many small subfiles, used for interactive/mapped
  1532. * music (.map/lin). Subfiles always share header, except num_samples. */
  1533. num_samples += vgmstream->current_block_samples;
  1534. /* stream size is almost never provided in bank files so we have to calc it manually */
  1535. stream_size += vgmstream->next_block_offset - vgmstream->ch[0].offset;
  1536. }
  1537. }
  1538. /* reset once we're done */
  1539. block_update_ea_schl(start_offset, vgmstream);
  1540. /* only use calculated samples with multiple subfiles (rarely header samples may be less due to padding) */
  1541. if (standalone && multiple_schl) {
  1542. VGM_LOG("EA SCHl: multiple SCHl found\n");
  1543. if (num_samples > vgmstream->num_samples) {
  1544. vgmstream->num_samples = num_samples;
  1545. }
  1546. }
  1547. if (vgmstream->stream_size == 0)
  1548. vgmstream->stream_size = stream_size;
  1549. }
  1550. /* find data start offset inside the first SCDl; not very elegant but oh well */
  1551. static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* sf, off_t start_offset, const ea_header* ea) {
  1552. size_t file_size = get_streamfile_size(sf);
  1553. off_t block_offset = start_offset;
  1554. int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
  1555. uint32_t header_lang = (ea->codec_config >> 16) & 0xFFFF;
  1556. while (block_offset < file_size) {
  1557. uint32_t block_id, block_size;
  1558. off_t offset;
  1559. block_id = read_32bitBE(block_offset+0x00,sf);
  1560. block_size = read_32bitLE(block_offset+0x04,sf);
  1561. if (block_size > 0x00F00000) /* size is always LE, except in early SAT/MAC */
  1562. block_size = read_32bitBE(block_offset+0x04,sf);
  1563. if (block_id == EA_BLOCKID_DATA || block_id == ((EA_BLOCKID_LOC_DATA | header_lang))) {
  1564. /* "SCDl" or target "SDxx" multilang blocks */
  1565. offset = read_32bit(block_offset+0x0c,sf); /* first value seems ok, second is something else in EALayer3 */
  1566. return block_offset + 0x0c + ea->channels*0x04 + offset;
  1567. }
  1568. else if (block_id == 0x00000000) {
  1569. goto fail; /* just in case */
  1570. }
  1571. else {
  1572. block_offset += block_size; /* size includes header */
  1573. }
  1574. }
  1575. fail:
  1576. return 0;
  1577. }