main.cc 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. #include <cstdlib>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <iomanip>
  7. #include <sstream>
  8. #include <algorithm>
  9. #include <string>
  10. #include <list>
  11. #include <vector>
  12. // TODO: This tool needs the "libupse" fixing so it can build properly
  13. #include <zlib.h>
  14. extern "C"
  15. {
  16. //#include <upse.h>
  17. }
  18. #include <tinyxml/tinyxml.h>
  19. #ifdef QGears_SOUND
  20. #include <vorbis/codec.h>
  21. #include <vorbis/vorbisenc.h>
  22. #endif
  23. #include <boost/filesystem/path.hpp>
  24. #include <boost/filesystem/operations.hpp>
  25. #include "typedefs.h"
  26. #include "walkthrough.hh"
  27. using namespace std;
  28. using namespace boost::filesystem;
  29. #define SIZEOF(arg__) (sizeof(arg__) / sizeof(arg__[0]))
  30. #define MATH_ROUNDUP(x, base) (((x) + ((base)-1)) & ~((base)-1))
  31. #ifdef linux
  32. #define ESC_RED "\33[31m"
  33. #define ESC_GREEN "\33[32m"
  34. #define ESC_ORANGE "\33[33m"
  35. #define ESC_BLUE "\33[34m"
  36. #define ESC_MAGENTA "\33[35m"
  37. #define ESC_CYAN "\33[36m"
  38. #define ESC_GREY "\33[37m"
  39. #define ESC_RESET "\33[0m"
  40. #else
  41. #define ESC_RED ""
  42. #define ESC_GREEN ""
  43. #define ESC_ORANGE ""
  44. #define ESC_BLUE ""
  45. #define ESC_MAGENTA ""
  46. #define ESC_CYAN ""
  47. #define ESC_GREY ""
  48. #define ESC_RESET ""
  49. #endif
  50. static const u32 g_PSF_FREQUENCY = 44100;
  51. static const u32 g_PSF_CHANNELS_COUNT = 2;
  52. static const u32 g_TIME_DELTA = g_PSF_FREQUENCY * 5 / 100; // 0.05 seconds
  53. static const char *g_MAGIC = "AKAO";
  54. static const string g_AKAO_EXT("akao");
  55. static const string g_PSF_EXT("psf");
  56. static const string g_PCM_EXT("pcm");
  57. static const string g_OGG_EXT("ogg");
  58. static const string g_PSF_DRV_FN("ff7_scus94163_psf_v10.bin");
  59. static const u32 g_PSF_DRV_OFFSET = 0x1a8800;
  60. static const u32 g_PSF_SEQ_OFFSET = 0x1c0800;
  61. static const u32 g_PSX_TEXT_START = 0x800;
  62. static const u32 g_PSX_TEXT_SIZE = 0x1e0000;
  63. static const u32 g_PSX_PSF_JUMP_OFFSET = 0x1960;
  64. static const u32 g_PSX_PSF_JUMP_DATA = 0x0806e00f;
  65. static const u32 g_AKAO_OPCODE_TABLE_OFFSET = 0x3a028;
  66. static const string g_CONFIG_FN("config.xml");
  67. static const struct
  68. {
  69. u8 id;
  70. u8 count;
  71. } g_OP_PARAMS[] =
  72. {
  73. {0xa0, 0}, {0xa6, 0}, {0xa7, 0}, {0xb3, 0}, {0xb6, 0}, {0xba, 0}, {0xbe, 0}, {0xc2, 0},
  74. {0xc3, 0}, {0xc4, 0}, {0xc5, 0}, {0xc6, 0}, {0xc7, 0}, {0xc8, 0}, {0xca, 0}, {0xcb, 0},
  75. {0xcc, 0}, {0xcd, 0}, {0xd0, 0}, {0xd1, 0}, {0xd4, 0}, {0xd5, 0}, {0xd6, 0}, {0xd7, 0},
  76. {0xdb, 0}, {0xe0, 0}, {0xe1, 0}, {0xe2, 0}, {0xe3, 0}, {0xe4, 0}, {0xe5, 0}, {0xe6, 0},
  77. {0xe7, 0}, {0xed, 0}, {0xf3, 0}, {0xf5, 0}, {0xf9, 0}, {0xfa, 0}, {0xfb, 0}, {0xfc, 0},
  78. {0xff, 0}, {0xa1, 1}, {0xa2, 1}, {0xa3, 1}, {0xa5, 1}, {0xa8, 1}, {0xaa, 1}, {0xac, 1},
  79. {0xad, 1}, {0xae, 1}, {0xaf, 1}, {0xb1, 1}, {0xb2, 1}, {0xb5, 1}, {0xb7, 1}, {0xb9, 1},
  80. {0xbb, 1}, {0xbd, 1}, {0xbf, 1}, {0xc0, 1}, {0xc1, 1}, {0xc9, 1}, {0xce, 1}, {0xcf, 1},
  81. {0xd2, 1}, {0xd3, 1}, {0xd8, 1}, {0xd9, 1}, {0xda, 1}, {0xdc, 1}, {0xf2, 1}, {0xf6, 1},
  82. {0xf8, 1}, {0xa4, 2}, {0xa9, 2}, {0xab, 2}, {0xb0, 2}, {0xbc, 2}, {0xdd, 2}, {0xde, 2},
  83. {0xdf, 2}, {0xe8, 2}, {0xea, 2}, {0xec, 2}, {0xee, 2}, {0xf4, 2}, {0xf7, 2}, {0xfd, 2},
  84. {0xfe, 2}, {0xb4, 3}, {0xb8, 3}, {0xe9, 3}, {0xeb, 3}, {0xef, 3}, {0xf0, 3}, {0xf1, 3}
  85. };
  86. static const struct OpcodeTable
  87. {
  88. u8 data[0x100];
  89. OpcodeTable()
  90. {
  91. memset((char *)data, 0x00, sizeof(data));
  92. for(u32 i = 0; i < SIZEOF(g_OP_PARAMS); ++i)
  93. data[g_OP_PARAMS[i].id] = g_OP_PARAMS[i].count;
  94. }
  95. } g_OPCODE_TABLE;
  96. static const struct PatchEntry
  97. {
  98. string filename;
  99. u32 offset;
  100. }g_PSX_PSF_PATCHES[4] =
  101. {
  102. {"SOUND/INSTR.ALL" , 0x000e0800},
  103. {"SOUND/INSTR.DAT" , 0x00156800},
  104. {"SOUND/INSTR2.ALL", 0x00158800},
  105. {"SOUND/INSTR2.DAT", 0x00196800}
  106. };
  107. enum ReaderState
  108. {
  109. RS_MAGIC,
  110. RS_FOUND,
  111. RS_COUNT
  112. };
  113. struct PsxExeHeader
  114. {
  115. char magic[8];
  116. u32 text;
  117. u32 data;
  118. u32 pc0;
  119. u32 gp0;
  120. u32 t_addr;
  121. u32 t_size;
  122. u32 d_addr;
  123. u32 d_size;
  124. u32 b_addr;
  125. u32 b_size;
  126. u32 s_addr;
  127. u32 s_size;
  128. u32 saved_sp;
  129. u32 saved_fp;
  130. u32 saved_gp;
  131. u32 saved_ra;
  132. u32 saved_s0;
  133. };
  134. struct PsfHeader
  135. {
  136. char magic[3];
  137. u8 version;
  138. u32 reserved_size;
  139. u32 program_size;
  140. u32 program_crc;
  141. };
  142. struct AkaoHeader
  143. {
  144. u8 magic[4];
  145. u16 id;
  146. u16 length;
  147. u16 reverb_mode;
  148. struct TimeStamp
  149. {
  150. u8 year;
  151. u8 month;
  152. u8 day;
  153. u8 hour;
  154. u8 minute;
  155. u8 second;
  156. //} __attribute__((packed)) timestamp;
  157. //} __attribute__((packed));
  158. };
  159. };
  160. struct Channel
  161. {
  162. u32 index;
  163. u8 *stream;
  164. u32 length;
  165. u32 length_file;
  166. u32 loop_start;
  167. u32 loop_end;
  168. bool control_only;
  169. };
  170. struct ChannelParam
  171. {
  172. u32 attack_size;
  173. u32 loop_size;
  174. };
  175. struct VorbisEncoderContext
  176. {
  177. #ifdef QGears_SOUND
  178. vorbis_info vi;
  179. vorbis_dsp_state vds;
  180. vorbis_comment vc;
  181. vorbis_block vb;
  182. ogg_stream_state os;
  183. ogg_page og;
  184. ogg_packet op;
  185. #endif
  186. ofstream ofs_file;
  187. };
  188. struct PsfContext
  189. {
  190. u32 samples_decoded;
  191. u32 samples_total;
  192. ofstream of_pcm;
  193. VorbisEncoderContext venc_ctx;
  194. };
  195. template <typename T>
  196. string to_string(T arg)
  197. {
  198. string result;
  199. stringstream sS;
  200. sS << arg;
  201. sS >> result;
  202. return result;
  203. }
  204. vector<Channel> akao_frame_parse(u8 *, u32);
  205. void akao_frame_print(const vector<Channel> &, u8 *, u32);
  206. bool akao_timestamp_valid(const AkaoHeader::TimeStamp &);
  207. bool operator<(const Channel &, const Channel &);
  208. void akao_extract_cb(void *, path);
  209. void file_list_cb(void *, path);
  210. void files_delete_duplicates(list<path> &);
  211. void audio_tracks_create(path, list<path> &, path, path, path, const char *, float, bool, bool);
  212. bool lzs_detect(const u8 *, u32);
  213. u8 *lzs_extract(u32 &, const u8 *, u32);
  214. void psf_decode(path, path, bool, char *, u32, u32, u32, float);
  215. u32 psf_decode_time(char *, u32);
  216. void psf_write(string, const u8 *, u32);
  217. char *psf_alloc(u32 &, const u8 *, u32);
  218. void psf_free(char *);
  219. void upse_write_audio_cb(unsigned char *, long, void *);
  220. void upse_breakpoint_cb(u32, void *);
  221. static void *upse_open_cb(char *, char *);
  222. static size_t upse_read_cb(void *, size_t, size_t, void *);
  223. static int upse_seek_cb(void *, long, int);
  224. static int upse_close_cb(void *);
  225. int vorbis_encoder_init(VorbisEncoderContext &, path, u32, float);
  226. void vorbis_encoder_free(VorbisEncoderContext &);
  227. int vorbis_encoder_update(VorbisEncoderContext &, s16 *, u32, u32, bool);
  228. string str_lowercase(string);
  229. streampos file_get_size(ifstream &);
  230. void file_read(u8 *r_data, string a_path);
  231. void print_channel_stat(ChannelParam);
  232. string samples_to_time(u32);
  233. /*
  234. static upse_iofuncs_t upse_iofuncs =
  235. {
  236. upse_open_cb,
  237. upse_read_cb,
  238. upse_seek_cb,
  239. upse_close_cb
  240. };
  241. */
  242. // this is needed as workaround for dumb libupse io callbacks
  243. u32 g_psf_data_size;
  244. u32 g_psf_data_offset;
  245. int main(int argc, char *argv[])
  246. {
  247. bool print_usage = true;
  248. bool mode_print_frame = false;
  249. if(argc == 2)
  250. {
  251. path argument(argv[1]);
  252. // passed akao frame
  253. string extension(argument.extension().string());
  254. if(extension.size() && string(extension, 1, argument.extension().string().size() - 1) == g_AKAO_EXT)
  255. {
  256. mode_print_frame = true;
  257. print_usage = false;
  258. }
  259. // passed game directory
  260. else if(is_directory(argument) && exists(argument))
  261. {
  262. print_usage = false;
  263. }
  264. }
  265. if(print_usage)
  266. {
  267. cout << "usage: " << argv[0] << " <game_directory | akao_frame_file>" << endl;
  268. return 1;
  269. }
  270. string argument(argv[1]);
  271. if(mode_print_frame)
  272. {
  273. ifstream iF(argument.c_str(), ios::binary);
  274. if(iF.is_open())
  275. {
  276. u32 frame_size = static_cast<u32>(file_get_size(iF));
  277. u8 *frame = new u8[frame_size];
  278. iF.read((char *)frame, frame_size);
  279. iF.close();
  280. vector<Channel> channels = akao_frame_parse(frame, frame_size);
  281. akao_frame_print(channels, frame, frame_size);
  282. delete [] frame;
  283. }
  284. else
  285. {
  286. cout << "error: unable to open file " << argument << endl;
  287. }
  288. }
  289. else
  290. {
  291. TiXmlDocument config_xml(g_CONFIG_FN.c_str());
  292. if(config_xml.LoadFile())
  293. {
  294. TiXmlElement *config_node = config_xml.RootElement();
  295. // dump akao frames to directory
  296. cout << "searching data files for akao frames:" << endl;
  297. create_directory(g_AKAO_EXT);
  298. walkthrough(argument, akao_extract_cb, NULL);
  299. cout << endl;
  300. // remove duplicates
  301. cout << "removing duplicates:" << endl;
  302. list<path> akao_file_list;
  303. walkthrough(g_AKAO_EXT, file_list_cb, &akao_file_list);
  304. akao_file_list.sort();
  305. files_delete_duplicates(akao_file_list);
  306. cout << endl;
  307. // create audio tracks
  308. int dump_psf = 0;
  309. int dump_pcm = 0;
  310. float ogg_quality = 0.4f;
  311. if(config_node->QueryIntAttribute("dump_psf", &dump_psf) != TIXML_SUCCESS)
  312. cout << "error: dump_psf isn't integer" << endl;
  313. if(config_node->QueryIntAttribute("dump_pcm", &dump_pcm) != TIXML_SUCCESS)
  314. cout << "error: dump_pcm isn't integer" << endl;
  315. if(config_node->QueryFloatAttribute("ogg_quality", &ogg_quality) != TIXML_SUCCESS)
  316. cout << "error: ogg_quality isn't float" << endl;
  317. cout << "creating audio tracks:" << endl;
  318. audio_tracks_create(argument, akao_file_list,
  319. config_node->Attribute("output_directory"),
  320. config_node->Attribute("music_xml"),
  321. config_node->Attribute("music_directory"),
  322. config_node->Attribute("custom_bios"),
  323. ogg_quality, dump_psf > 0, dump_pcm > 0);
  324. cout << endl;
  325. }
  326. else
  327. {
  328. cout << "error: unable to load configuration file" << endl;
  329. return 1;
  330. }
  331. }
  332. return 0;
  333. }
  334. vector<Channel> akao_frame_parse(u8 *a_frame, u32 a_frame_size)
  335. {
  336. vector<Channel> channels;
  337. AkaoHeader &header = *((AkaoHeader *)a_frame);
  338. u32 file_index = sizeof(header);
  339. u32 channels_mask = *(u32 *)&a_frame[file_index];
  340. file_index += sizeof(u32);
  341. Channel ch;
  342. for(u32 i = 0; i < sizeof(u32) * 8; ++i)
  343. if(channels_mask & (1 << i))
  344. {
  345. ch.index = i;
  346. ch.stream = &a_frame[file_index + sizeof(u16) + *(u16 *)&a_frame[file_index]];
  347. file_index += sizeof(u16);
  348. ch.control_only = true;
  349. channels.push_back(ch);
  350. }
  351. sort(channels.begin(), channels.end());
  352. // loop start and end detection
  353. for(u32 i = 0; i < channels.size(); ++i)
  354. {
  355. u32 state = 0;
  356. u32 c8_start = channels[i].loop_start = channels[i].length = channels[i].length_file =
  357. (i < channels.size() - 1 ? channels[i + 1].stream
  358. : &a_frame[min((u32)(sizeof(header) + header.length), (u32)a_frame_size)]) - channels[i].stream;
  359. for(u32 j = 0; j < channels[i].length; ++j)
  360. {
  361. if(state)
  362. {
  363. --state;
  364. }
  365. else
  366. {
  367. if(channels[i].stream[j] < 0xa0)
  368. channels[i].control_only = false;
  369. state = g_OPCODE_TABLE.data[channels[i].stream[j]];
  370. channels[i].loop_end = j;
  371. switch(channels[i].stream[j])
  372. {
  373. case 0xc8:
  374. if(c8_start == channels[i].length)
  375. c8_start = j;
  376. break;
  377. case 0xee:
  378. channels[i].loop_start = j + 3 + *(s16 *)&channels[i].stream[j + 1];
  379. channels[i].length = j + 1 + state;
  380. break;
  381. case 0xa0:
  382. channels[i].length = j + 1 + state;
  383. break;
  384. case 0xca:
  385. channels[i].loop_start = c8_start;
  386. channels[i].length = j + 1 + state;
  387. }
  388. }
  389. }
  390. }
  391. return channels;
  392. }
  393. void akao_frame_print(const vector<Channel> &a_channels, u8 *a_frame, u32 a_frame_size)
  394. {
  395. AkaoHeader &header = *((AkaoHeader *)a_frame);
  396. cout << setfill('0');
  397. cout << dec;
  398. cout << "id: " << ESC_GREEN << header.id << ESC_RESET << endl;
  399. cout << "size: " << ESC_GREEN << header.length << ESC_RESET << endl;
  400. cout << "reverb mode: " << ESC_GREEN << header.reverb_mode << ESC_RESET << endl;
  401. cout << hex;
  402. #ifdef QGears_SOUND
  403. cout << "date: " << ESC_GREEN
  404. << setw(2) << (int)header.timestamp.year << '/'
  405. << setw(2) << (int)header.timestamp.month << '/'
  406. << setw(2) << (int)header.timestamp.day << ' '
  407. << setw(2) << (int)header.timestamp.hour << ':'
  408. << setw(2) << (int)header.timestamp.minute << ':'
  409. << setw(2) << (int)header.timestamp.second
  410. << ESC_RESET << endl;
  411. #endif
  412. cout << "channels count: " << dec << ESC_GREEN << a_channels.size() << ESC_RESET << hex << endl;
  413. for(u32 i = 0; i < a_channels.size(); ++i)
  414. {
  415. u32 state = 0;
  416. const char *color = ESC_RED;
  417. cout << "channel " << dec << (a_channels[i].index + 1) << hex << " [size: "
  418. << dec << a_channels[i].length << hex << "]: " << endl;
  419. for(u32 j = 0; j < a_channels[i].length; ++j)
  420. {
  421. if(state)
  422. {
  423. color = ESC_ORANGE;
  424. --state;
  425. }
  426. else
  427. {
  428. color = a_channels[i].stream[j] < 0xa0 ? ESC_MAGENTA : ESC_RED;
  429. if(j == a_channels[i].loop_start || j == a_channels[i].loop_end)
  430. color = ESC_CYAN;
  431. state = g_OPCODE_TABLE.data[a_channels[i].stream[j]];
  432. }
  433. cout << color << setw(2) << (int)a_channels[i].stream[j] << ' ';
  434. }
  435. cout << ESC_RESET << endl;
  436. }
  437. }
  438. bool akao_timestamp_valid(const AkaoHeader::TimeStamp &a_timestamp)
  439. {
  440. static const u8 LIMIT_YEAR = 0x99;
  441. static const u8 LIMIT_MONTH = 0x12;
  442. static const u8 LIMIT_DAY = 0x31;
  443. static const u8 LIMIT_HOUR = 0x23;
  444. static const u8 LIMIT_MINUTE = 0x59;
  445. static const u8 LIMIT_SECOND = 0x59;
  446. return a_timestamp.year <= LIMIT_YEAR &&
  447. a_timestamp.month <= LIMIT_MONTH &&
  448. a_timestamp.day <= LIMIT_DAY &&
  449. a_timestamp.hour <= LIMIT_HOUR &&
  450. a_timestamp.minute <= LIMIT_MINUTE &&
  451. a_timestamp.second <= LIMIT_SECOND;
  452. }
  453. bool operator<(const Channel &a_ch1, const Channel &a_ch2)
  454. {
  455. return a_ch1.stream < a_ch2.stream;
  456. }
  457. void akao_extract_cb(void *a_data, path a_file)
  458. {
  459. ifstream iF(a_file.string().c_str(), ios::binary);
  460. if(!iF.is_open())
  461. {
  462. cout << "error: unable to open " << a_file << endl;
  463. return;
  464. }
  465. // read full file to memory
  466. u32 buffer_size = static_cast<u32>(file_get_size(iF));
  467. u8 *buffer = new u8[buffer_size];
  468. iF.read((char *)buffer, buffer_size);
  469. iF.close();
  470. cout << "searching in " << a_file << "... " << endl;
  471. // detect and extract if compressed
  472. if(lzs_detect(buffer, buffer_size))
  473. {
  474. u8 *buffer_old = buffer;
  475. buffer = lzs_extract(buffer_size, buffer_old, buffer_size);
  476. delete [] buffer_old;
  477. }
  478. cout << setfill('0');
  479. ReaderState state = RS_MAGIC;
  480. u32 magic_pos = 0;
  481. u32 input_offset = 0;
  482. int akao_counter = 0;
  483. while(input_offset < buffer_size)
  484. {
  485. switch(state)
  486. {
  487. case RS_MAGIC:
  488. magic_pos = buffer[input_offset++] == g_MAGIC[magic_pos] ? magic_pos + 1 : 0;
  489. if(magic_pos >= strlen(g_MAGIC))
  490. state = RS_FOUND;
  491. break;
  492. case RS_FOUND:
  493. {
  494. // fill akao header
  495. AkaoHeader header;
  496. memcpy(header.magic, g_MAGIC, strlen(g_MAGIC));
  497. memcpy(&header.id, &buffer[input_offset], sizeof(header) - sizeof(header.magic));
  498. #ifdef QGears_SOUND
  499. if(akao_timestamp_valid(header.timestamp))
  500. {
  501. input_offset += sizeof(header) - sizeof(header.magic);
  502. ++akao_counter;
  503. // construct save path
  504. string output_fn(a_file.filename().string());
  505. size_t dot_pos;
  506. while((dot_pos = output_fn.find_last_of(".")) != string::npos)
  507. output_fn.replace(dot_pos, 1, "_");
  508. output_fn += "_" + to_string(akao_counter);
  509. output_fn = str_lowercase(output_fn);
  510. path output_path(g_AKAO_EXT / path(output_fn));
  511. output_path.replace_extension(g_AKAO_EXT);
  512. ofstream oF;
  513. oF.open(output_path.string().c_str(), ios::binary);
  514. if(oF.is_open())
  515. {
  516. cout << "\tfound id 0x" << hex << setw(2) << header.id << dec << ", dumping to " << output_path << "... ";
  517. oF.write((char *)&header, sizeof(header));
  518. oF.write((char *)&buffer[input_offset], header.length);
  519. input_offset += header.length;
  520. oF.close();
  521. cout << "done" << endl;
  522. }
  523. else
  524. {
  525. cout << "error: unable to open " << output_path << endl;
  526. return;
  527. }
  528. }
  529. #endif
  530. magic_pos = 0;
  531. state = RS_MAGIC;
  532. }
  533. break;
  534. default:
  535. ;
  536. }
  537. }
  538. delete [] buffer;
  539. }
  540. void file_list_cb(void *a_data, path a_file)
  541. {
  542. list<path> &file_list = *(list<path> *)a_data;
  543. file_list.push_back(a_file);
  544. }
  545. void files_delete_duplicates(list<path> &r_file_list)
  546. {
  547. for(list<path>::iterator it = r_file_list.begin(); it != r_file_list.end(); ++it)
  548. {
  549. ifstream iF1(it->string().c_str(), ios::binary);
  550. if(!iF1.is_open())
  551. {
  552. cout << "error: unable to open " << *it << endl;
  553. continue;
  554. }
  555. u32 buffer1_size = static_cast<u32>(file_get_size(iF1));
  556. u8 *buffer1 = new u8[buffer1_size];
  557. iF1.read((char *)buffer1, buffer1_size);
  558. iF1.close();
  559. list<path>::iterator jt = it;
  560. ++jt;
  561. while(jt != r_file_list.end())
  562. {
  563. bool erased = false;
  564. ifstream iF2(jt->string().c_str(), ios::binary);
  565. if(iF2.is_open())
  566. {
  567. u32 buffer2_size = static_cast<u32>(file_get_size(iF2));
  568. if(buffer1_size == buffer2_size)
  569. {
  570. u8 *buffer2 = new u8[buffer2_size];
  571. iF2.read((char *)buffer2, buffer2_size);
  572. if(!memcmp(buffer1, buffer2, buffer1_size))
  573. {
  574. cout << "\t file " << *it << " equal to " << *jt << ", removing the latter" << endl;
  575. remove(path(*jt));
  576. jt = r_file_list.erase(jt);
  577. erased = true;
  578. }
  579. delete [] buffer2;
  580. }
  581. }
  582. else
  583. {
  584. cout << "error: unable to open " << *jt << endl;
  585. }
  586. if(!erased)
  587. ++jt;
  588. }
  589. delete [] buffer1;
  590. }
  591. }
  592. void audio_tracks_create(path a_game_path, list<path> &a_file_list, path a_output_path, path a_music_xml_fn,
  593. path a_music_path, const char *a_bios_fn, float a_ogg_quality, bool a_dump_psf, bool a_dump_pcm)
  594. {
  595. /*
  596. cout << "creating psf driver template... ";
  597. // read full file to memory
  598. u32 psf_driver_size = g_PSX_TEXT_START + g_PSX_TEXT_SIZE;
  599. u8 *psf_driver = new u8[psf_driver_size];
  600. memset(psf_driver, 0, psf_driver_size);
  601. file_read(psf_driver, (a_game_path / "SCUS_941.63").string());
  602. // convert psx executable to psf driver
  603. PsxExeHeader &header = *(PsxExeHeader *)psf_driver;
  604. // set maximal possible size to executable
  605. header.t_size = g_PSX_TEXT_SIZE;
  606. // set jump offset to psf driver
  607. *(u32 *)&psf_driver[g_PSX_PSF_JUMP_OFFSET] = g_PSX_PSF_JUMP_DATA;
  608. // inject sound data to executable
  609. for(u32 i = 0; i < SIZEOF(g_PSX_PSF_PATCHES); ++i)
  610. file_read(&psf_driver[g_PSX_PSF_PATCHES[i].offset], (a_game_path / g_PSX_PSF_PATCHES[i].filename).string());
  611. // inject psf driver payload
  612. file_read(&psf_driver[g_PSF_DRV_OFFSET], g_PSF_DRV_FN);
  613. cout << "done" << endl;
  614. if(a_bios_fn != NULL && strlen(a_bios_fn))
  615. {
  616. cout << "setting custom bios " << a_bios_fn << "... ";
  617. upse_set_custom_bios(a_bios_fn);
  618. cout << "done" << endl;
  619. }
  620. create_directory(a_output_path);
  621. create_directory(a_output_path / a_music_path);
  622. // create xml structure
  623. TiXmlDocument music_xml;
  624. music_xml.LinkEndChild(new TiXmlDeclaration("1.0", "utf-8", ""));
  625. TiXmlElement *music_xml_root = new TiXmlElement("musics");
  626. music_xml.LinkEndChild(music_xml_root);
  627. for(list<path>::iterator it = a_file_list.begin(); it != a_file_list.end(); ++it)
  628. {
  629. // read file
  630. ifstream iF(it->string().c_str(), ios::binary);
  631. if(!iF.is_open())
  632. {
  633. cout << "error: unable to open file " << *it << endl;
  634. continue;
  635. }
  636. cout << "processing " << *it << "... " << endl;
  637. u32 file_size = file_get_size(iF);
  638. u8 *file_data = new u8[file_size];
  639. iF.read((char *)file_data, file_size);
  640. iF.close();
  641. // analyze channels and get loop and total channel times
  642. vector<Channel> channels = akao_frame_parse(file_data, file_size);
  643. vector<ChannelParam> channel_params;
  644. for(u32 i = 0; i < channels.size(); ++i)
  645. {
  646. cout << "\tchannel " << setw(2) << channels[i].index + 1;
  647. if(channels[i].control_only)
  648. {
  649. cout << " contains only control opcodes, skipping" << endl;
  650. continue;
  651. }
  652. cout << " detecting properties... ";
  653. u32 time_loop = 0;
  654. u8 opcode_backup;
  655. bool loop_enabled = channels[i].loop_start != channels[i].length_file;
  656. // if track is looped, calculate channel loop start time
  657. if(loop_enabled)
  658. {
  659. // place a0 opcode to loop start, place breakpoint at a0 and get time
  660. u8 &loop_start = channels[i].stream[channels[i].loop_start];
  661. opcode_backup = loop_start;
  662. // patch opcode, write psf and get time
  663. loop_start = 0xa0;
  664. memcpy(&psf_driver[g_PSF_SEQ_OFFSET], file_data, file_size);
  665. u32 psf_data_size;
  666. char *psf_data = psf_alloc(psf_data_size, psf_driver, psf_driver_size);
  667. memset(&psf_driver[g_PSF_SEQ_OFFSET], 0, file_size);
  668. time_loop = psf_decode_time(psf_data, psf_data_size);
  669. psf_free(psf_data);
  670. // restore previous opcode
  671. loop_start = opcode_backup;
  672. }
  673. // calculate channel end time
  674. u8 &loop_end = channels[i].stream[channels[i].loop_end];
  675. opcode_backup = loop_end;
  676. // patch opcode, write psf and get time
  677. loop_end = 0xa0;
  678. memcpy(&psf_driver[g_PSF_SEQ_OFFSET], file_data, file_size);
  679. u32 psf_data_size;
  680. char *psf_data = psf_alloc(psf_data_size, psf_driver, psf_driver_size);
  681. memset(&psf_driver[g_PSF_SEQ_OFFSET], 0, file_size);
  682. u32 time_end = psf_decode_time(psf_data, psf_data_size);
  683. psf_free(psf_data);
  684. // restore previous opcode
  685. loop_end = opcode_backup;
  686. ChannelParam ch_param;
  687. if(loop_enabled)
  688. {
  689. ch_param.attack_size = time_loop;
  690. ch_param.loop_size = time_end - time_loop;
  691. }
  692. else
  693. {
  694. ch_param.attack_size = time_end;
  695. ch_param.loop_size = 0;
  696. }
  697. channel_params.push_back(ch_param);
  698. cout << "attack/loop/total: ";
  699. print_channel_stat(ch_param);
  700. cout << endl;
  701. }
  702. // if full track isn't empty
  703. if(channel_params.size())
  704. {
  705. // find maximal attack and loop sizes
  706. u32 attack_max_index = 0;
  707. u32 loop_max_index = 0;
  708. for(u32 i = 0; i < channel_params.size(); ++i)
  709. {
  710. if(channel_params[i].attack_size > channel_params[attack_max_index].attack_size)
  711. attack_max_index = i;
  712. if(channel_params[i].loop_size > channel_params[loop_max_index].loop_size)
  713. loop_max_index = i;
  714. }
  715. // take average loop size
  716. u32 loop_sum = 0;
  717. u32 loop_count = 0;
  718. for(u32 i = 0; i < channel_params.size(); ++i)
  719. {
  720. if(abs((s64)channel_params[i].loop_size -
  721. (s64)channel_params[loop_max_index].loop_size) <= g_TIME_DELTA)
  722. {
  723. loop_sum += channel_params[i].loop_size;
  724. ++loop_count;
  725. }
  726. }
  727. ChannelParam ch_final;
  728. ch_final.attack_size = channel_params[attack_max_index].attack_size;
  729. ch_final.loop_size = loop_sum / loop_count;
  730. cout << "final attack/loop/total: ";
  731. print_channel_stat(ch_final);
  732. cout << endl;
  733. // decode psf to wav
  734. memcpy(&psf_driver[g_PSF_SEQ_OFFSET], file_data, file_size);
  735. u32 psf_data_size;
  736. char *psf_data = psf_alloc(psf_data_size, psf_driver, psf_driver_size);
  737. if(a_dump_psf)
  738. {
  739. path psf_fn(a_output_path / a_music_path / it->filename());
  740. psf_fn.replace_extension(g_PSF_EXT);
  741. cout << psf_fn << endl;
  742. ofstream oF(psf_fn.string().c_str(), ios::binary);
  743. if(oF.is_open())
  744. {
  745. cout << "\twriting file " << psf_fn << "... ";
  746. oF.write(psf_data, psf_data_size);
  747. cout << "done" << endl;
  748. }
  749. else
  750. {
  751. cout << "error: unable to open " << psf_fn << endl;
  752. }
  753. }
  754. memset(&psf_driver[g_PSF_SEQ_OFFSET], 0, file_size);
  755. path ogg_fn(a_music_path / it->filename());
  756. ogg_fn.replace_extension(g_OGG_EXT);
  757. path raw_fn(a_music_path / it->filename());
  758. raw_fn.replace_extension(g_PCM_EXT);
  759. // add xml record about track
  760. TiXmlElement *xml_node = new TiXmlElement("music");
  761. music_xml_root->LinkEndChild(xml_node);
  762. xml_node->SetAttribute("name", ogg_fn.stem().string() );
  763. xml_node->SetAttribute("file_name", ogg_fn.string() );
  764. xml_node->SetAttribute("loop", ch_final.attack_size);
  765. psf_decode(a_output_path / ogg_fn, a_output_path / raw_fn, a_dump_pcm,
  766. psf_data, psf_data_size, ch_final.attack_size, ch_final.loop_size, a_ogg_quality);
  767. psf_free(psf_data);
  768. }
  769. else
  770. {
  771. cout << "\ttrack contains only control opcodes, skipping" << endl;
  772. }
  773. delete [] file_data;
  774. }
  775. music_xml.SaveFile((a_output_path / a_music_xml_fn).string().c_str());
  776. delete [] psf_driver;*/
  777. }
  778. bool lzs_detect(const u8 *a_buffer, u32 a_size)
  779. {
  780. return *(u32 *)a_buffer == a_size - sizeof(u32);
  781. }
  782. u8 *lzs_extract(u32 &r_output_size, const u8 *a_input, u32 a_size)
  783. {
  784. const u8 *input_ptr = a_input + sizeof(u32);
  785. u32 input_size = *(u32 *)a_input;
  786. u32 buffer_size = MATH_ROUNDUP(a_size, 0xff);
  787. u8 *buffer = (u8 *)malloc(buffer_size);
  788. u32 input_offset = 0;
  789. r_output_size = 0;
  790. u8 control_byte = 0;
  791. u8 control_bit = 0;
  792. while(input_offset < input_size)
  793. {
  794. if(control_bit == 0)
  795. {
  796. control_byte = input_ptr[input_offset++];
  797. control_bit = 8;
  798. }
  799. if(control_byte & 1)
  800. {
  801. buffer[r_output_size++] = input_ptr[input_offset++];
  802. if(r_output_size == buffer_size)
  803. {
  804. buffer_size += 0xff;
  805. buffer = (u8*)realloc(buffer, buffer_size);
  806. }
  807. }
  808. else
  809. {
  810. u8 reference1 = input_ptr[input_offset++];
  811. u8 reference2 = input_ptr[input_offset++];
  812. u16 reference_offset = reference1 | ((reference2 & 0xF0) << 4);
  813. u8 reference_length = (reference2 & 0xF) + 3;
  814. int real_offset = r_output_size - ((r_output_size - 18 - reference_offset) & 0xFFF);
  815. for(u32 j = 0; j < reference_length; ++j)
  816. {
  817. buffer[r_output_size++] = real_offset < 0 ? 0 : buffer[real_offset];
  818. if(r_output_size == buffer_size)
  819. {
  820. buffer_size += 0xff;
  821. buffer = (u8*)realloc(buffer, buffer_size);
  822. }
  823. ++real_offset;
  824. }
  825. }
  826. control_byte >>= 1;
  827. --control_bit;
  828. }
  829. return buffer;
  830. }
  831. void psf_decode(path a_ogg_fn, path a_raw_fn, bool a_dump_pcm, char *a_psf_data, u32 a_psf_data_size,
  832. u32 a_attack_size, u32 a_loop_size, float a_ogg_quality)
  833. {
  834. /*
  835. PsfContext ctx;
  836. upse_set_audio_callback(upse_write_audio_cb, (void *)&ctx);
  837. g_psf_data_size = a_psf_data_size;
  838. g_psf_data_offset = 0;
  839. upse_psf_t *psf_ctx = upse_load(a_psf_data, &upse_iofuncs);
  840. if(psf_ctx != NULL)
  841. {
  842. ctx.samples_decoded = 0;
  843. ctx.samples_total = a_attack_size + a_loop_size;
  844. int result = vorbis_encoder_init(ctx.venc_ctx, a_ogg_fn, a_attack_size, a_ogg_quality);
  845. if(a_dump_pcm)
  846. ctx.of_pcm.open(a_raw_fn.string().c_str(), ios::binary);
  847. if(!result && (!a_dump_pcm || ctx.of_pcm.is_open()))
  848. {
  849. upse_execute();
  850. vorbis_encoder_free(ctx.venc_ctx);
  851. if(a_dump_pcm)
  852. ctx.of_pcm.close();
  853. }
  854. else
  855. {
  856. cout << "error: failed to initialize vorbis encoder" << endl;
  857. }
  858. upse_free_psf_metadata(psf_ctx);
  859. }
  860. else
  861. {
  862. cout << "error: failed to load psf data" << endl;
  863. }
  864. upse_set_audio_callback(NULL, NULL);*/
  865. }
  866. u32 psf_decode_time(char *a_psf_data, u32 a_psf_data_size)
  867. {
  868. u32 time = 0;
  869. /*
  870. upse_set_breakpoint_callback(upse_breakpoint_cb, (void *)&time, 0x80033894); //@[0x80049828 + 0xa0 * 4]
  871. g_psf_data_size = a_psf_data_size;
  872. g_psf_data_offset = 0;
  873. upse_psf_t *psf_ctx = upse_load(a_psf_data, &upse_iofuncs);
  874. if(psf_ctx != NULL)
  875. {
  876. upse_execute();
  877. upse_free_psf_metadata(psf_ctx);
  878. }
  879. else
  880. {
  881. cout << "error: failed to load psf data" << endl;
  882. }
  883. upse_set_breakpoint_callback(NULL, NULL, 0);
  884. */
  885. return time;
  886. }
  887. void psf_write(string a_out_fn, const u8 *a_buffer, u32 a_buffer_size)
  888. {
  889. // compress data
  890. uLong zlib_length = compressBound(a_buffer_size);
  891. u8 *psf_data = (u8 *)malloc(sizeof(PsfHeader) + zlib_length);
  892. Bytef *zlib_data = (Bytef *)(psf_data + sizeof(PsfHeader));
  893. if(compress2(zlib_data, &zlib_length, a_buffer, a_buffer_size, 9) == Z_OK)
  894. {
  895. // write psf
  896. PsfHeader &psf_header = *(PsfHeader *)psf_data;
  897. memcpy(psf_header.magic, "PSF", sizeof(psf_header.magic));
  898. psf_header.version = 1;
  899. psf_header.reserved_size = 0;
  900. psf_header.program_size = zlib_length;
  901. psf_header.program_crc = crc32(crc32(0, Z_NULL, 0), zlib_data, zlib_length);
  902. u32 psf_length = sizeof(psf_header) + zlib_length;
  903. ofstream oF(a_out_fn.c_str(), ios::binary);
  904. oF.write((char *)psf_data, psf_length);
  905. oF.close();
  906. }
  907. else
  908. {
  909. cout << "error: unable to compress psx executable" << endl;
  910. }
  911. free(psf_data);
  912. }
  913. char *psf_alloc(u32 &r_size, const u8 *a_buffer, u32 a_buffer_size)
  914. {
  915. // compress data
  916. uLong zlib_length = compressBound(a_buffer_size);
  917. char *psf_data = (char *)malloc(sizeof(PsfHeader) + zlib_length);
  918. Bytef *zlib_data = (Bytef *)(psf_data + sizeof(PsfHeader));
  919. if(compress2(zlib_data, &zlib_length, a_buffer, a_buffer_size, 9) == Z_OK)
  920. {
  921. // write psf
  922. PsfHeader &psf_header = *(PsfHeader *)psf_data;
  923. memcpy(psf_header.magic, "PSF", sizeof(psf_header.magic));
  924. psf_header.version = 1;
  925. psf_header.reserved_size = 0;
  926. psf_header.program_size = zlib_length;
  927. psf_header.program_crc = crc32(crc32(0, Z_NULL, 0), zlib_data, zlib_length);
  928. r_size = sizeof(psf_header) + zlib_length;
  929. }
  930. else
  931. {
  932. cout << "error: unable to compress psx executable" << endl;
  933. }
  934. return psf_data;
  935. }
  936. void psf_free(char *a_psf_data)
  937. {
  938. free(a_psf_data);
  939. }
  940. void upse_write_audio_cb(unsigned char *data, long bytes, void *user_data)
  941. {
  942. PsfContext &ctx = *(PsfContext *)user_data;
  943. u32 samples_to_write = min<u32>(bytes / (sizeof(s16) * g_PSF_CHANNELS_COUNT), ctx.samples_total - ctx.samples_decoded);
  944. ctx.samples_decoded += samples_to_write;
  945. if(ctx.of_pcm.is_open())
  946. ctx.of_pcm.write((char *)data, samples_to_write * sizeof(s16) * g_PSF_CHANNELS_COUNT);
  947. vorbis_encoder_update(ctx.venc_ctx, (s16 *)data, samples_to_write, g_PSF_CHANNELS_COUNT, ctx.samples_decoded >= ctx.samples_total);
  948. cout << "\r" << "\tdecoding " << samples_to_time(ctx.samples_decoded)
  949. << "/" << samples_to_time(ctx.samples_total) << "... " << flush;
  950. if(ctx.samples_decoded >= ctx.samples_total)
  951. {
  952. // upse_stop();
  953. cout << "done" << endl;
  954. }
  955. }
  956. void upse_breakpoint_cb(u32 samples_count, void *user_data)
  957. {
  958. *(u32 *)user_data = samples_count;
  959. //upse_stop();
  960. }
  961. void *upse_open_cb(char *path, char *mode)
  962. {
  963. return path;
  964. }
  965. size_t upse_read_cb(void *ptr, size_t sz, size_t nmemb, void *file)
  966. {
  967. char *data = (char *)file;
  968. size_t bytes_to_write = min((g_psf_data_size - g_psf_data_offset) / sz, nmemb) * sz;
  969. memcpy(ptr, &data[g_psf_data_offset], bytes_to_write);
  970. g_psf_data_offset += bytes_to_write;
  971. return bytes_to_write / sz;
  972. }
  973. int upse_seek_cb(void *ptr, long offset, int whence)
  974. {
  975. switch(whence)
  976. {
  977. case SEEK_SET:
  978. g_psf_data_offset = offset;
  979. break;
  980. case SEEK_CUR:
  981. g_psf_data_offset += offset;
  982. break;
  983. case SEEK_END:
  984. g_psf_data_offset = g_psf_data_offset + offset;
  985. break;
  986. default:
  987. return 1;
  988. }
  989. return 0;
  990. }
  991. int upse_close_cb(void *ptr)
  992. {
  993. return 0;
  994. }
  995. int vorbis_encoder_init(VorbisEncoderContext &ctx, path a_ogg_fn, u32 a_attack_size, float a_ogg_quality)
  996. {
  997. int result = 1;
  998. #ifdef QGears_SOUND
  999. ctx.ofs_file.open(a_ogg_fn.string().c_str(), ios::binary);
  1000. if(!ctx.ofs_file.is_open())
  1001. return result;
  1002. vorbis_info_init(&ctx.vi);
  1003. if((result = vorbis_encode_init_vbr(&ctx.vi, 2, 44100, a_ogg_quality)))
  1004. return result;
  1005. if((result = vorbis_analysis_init(&ctx.vds, &ctx.vi)))
  1006. return result;
  1007. vorbis_comment_init(&ctx.vc);
  1008. vorbis_comment_add_tag(&ctx.vc, "LOOP", to_string(a_attack_size).c_str());
  1009. if((result = vorbis_block_init(&ctx.vds, &ctx.vb)))
  1010. return result;
  1011. srand(time(NULL));
  1012. if((result = ogg_stream_init(&ctx.os, rand())))
  1013. return result;
  1014. ogg_packet headers[3];
  1015. if((result = vorbis_analysis_headerout(&ctx.vds, &ctx.vc, &headers[0], &headers[1], &headers[2])))
  1016. return result;
  1017. for(u32 i = 0; i < SIZEOF(headers); ++i)
  1018. if((result = ogg_stream_packetin(&ctx.os, &headers[i])))
  1019. return result;
  1020. // this ensures the actual audio data will start on a new page, as per spec
  1021. while(ogg_stream_flush(&ctx.os, &ctx.og))
  1022. {
  1023. ctx.ofs_file.write((char *)ctx.og.header, ctx.og.header_len);
  1024. ctx.ofs_file.write((char *)ctx.og.body, ctx.og.body_len);
  1025. }
  1026. result = 0;
  1027. #endif
  1028. return result;
  1029. }
  1030. void vorbis_encoder_free(VorbisEncoderContext &ctx)
  1031. {
  1032. #ifdef QGears_SOUND
  1033. ogg_stream_clear(&ctx.os);
  1034. vorbis_block_clear(&ctx.vb);
  1035. vorbis_comment_clear(&ctx.vc);
  1036. vorbis_dsp_clear(&ctx.vds);
  1037. vorbis_info_clear(&ctx.vi);
  1038. #endif
  1039. }
  1040. int vorbis_encoder_update(VorbisEncoderContext &ctx, s16 *a_samples, u32 a_samples_count, u32 a_channels_count, bool a_end)
  1041. {
  1042. int result = 0;
  1043. #ifdef QGears_SOUND
  1044. // 3rd argument done in tricky way because we can encode audio in chunks later
  1045. bool end = a_end;
  1046. for(u32 samples = a_samples_count; samples || end; samples = 0)
  1047. {
  1048. if(samples)
  1049. {
  1050. // uninterleave and submit samples
  1051. float **buffer = vorbis_analysis_buffer(&ctx.vds, samples);
  1052. for(u32 i = 0; i < samples * a_channels_count; ++i)
  1053. buffer[i % a_channels_count][i / a_channels_count] = a_samples[i] / 32768.f;
  1054. }
  1055. else
  1056. {
  1057. end = false;
  1058. }
  1059. if((result = vorbis_analysis_wrote(&ctx.vds, samples)))
  1060. return result;
  1061. // vorbis does some data preanalysis, then divvies up blocks for
  1062. // more involved (potentially parallel) processing. Get a single
  1063. // block for encoding now
  1064. while(vorbis_analysis_blockout(&ctx.vds, &ctx.vb) == 1)
  1065. {
  1066. // analysis, assume we want to use bitrate management
  1067. if((result = vorbis_analysis(&ctx.vb, NULL)))
  1068. return result;
  1069. if((result = vorbis_bitrate_addblock(&ctx.vb)))
  1070. return result;
  1071. while((result = vorbis_bitrate_flushpacket(&ctx.vds, &ctx.op)) == 1)
  1072. {
  1073. if((result = ogg_stream_packetin(&ctx.os, &ctx.op)))
  1074. return result;
  1075. while(ogg_stream_pageout(&ctx.os, &ctx.og))
  1076. {
  1077. ctx.ofs_file.write((char *)ctx.og.header, ctx.og.header_len);
  1078. ctx.ofs_file.write((char *)ctx.og.body, ctx.og.body_len);
  1079. if(ogg_page_eos(&ctx.og))
  1080. break;
  1081. }
  1082. }
  1083. if(result < 0)
  1084. return result;
  1085. }
  1086. }
  1087. result = 0;
  1088. #endif
  1089. return result;
  1090. }
  1091. string str_lowercase(string a_str)
  1092. {
  1093. string result;
  1094. result.resize(a_str.size());
  1095. transform(a_str.begin(), a_str.end(), result.begin(), ::tolower);
  1096. return result;
  1097. }
  1098. streampos file_get_size(ifstream &a_if)
  1099. {
  1100. streampos last_pos = a_if.tellg();
  1101. a_if.seekg(0, ios::end);
  1102. streampos result = a_if.tellg();
  1103. a_if.seekg(last_pos);
  1104. return result;
  1105. }
  1106. void file_read(u8 *r_data, string a_path)
  1107. {
  1108. ifstream iF(a_path.c_str(), ios::binary);
  1109. if(iF.is_open())
  1110. iF.read((char *)r_data, file_get_size(iF));
  1111. else
  1112. cout << "error: unable to open file " << a_path << endl;
  1113. }
  1114. void print_channel_stat(ChannelParam a_ch_param)
  1115. {
  1116. u32 total_size = a_ch_param.attack_size + a_ch_param.loop_size;
  1117. cout << samples_to_time(a_ch_param.attack_size) << "(" << a_ch_param.attack_size << ")/"
  1118. << samples_to_time(a_ch_param.loop_size) << "(" << a_ch_param.loop_size << ")/"
  1119. << samples_to_time(total_size) << "(" << total_size << ")";
  1120. }
  1121. string samples_to_time(u32 a_samples)
  1122. {
  1123. string result;
  1124. u32 time_seconds = a_samples / g_PSF_FREQUENCY;
  1125. u32 milli = (a_samples % g_PSF_FREQUENCY) / (g_PSF_FREQUENCY / 100);
  1126. u32 seconds = time_seconds % 60;
  1127. u32 minutes = time_seconds / 60;
  1128. stringstream sS;
  1129. sS << setfill('0');
  1130. sS << setw(2) << minutes << ':' << setw(2) << seconds << '.' << setw(2) << milli;
  1131. sS >> result;
  1132. return result;
  1133. }