cp_loader_it_samples.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*************************************************************************/
  2. /* cp_loader_it_samples.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "cp_loader_it.h"
  31. #include "cp_sample.h"
  32. struct AuxSampleData {
  33. uint32_t fileofs;
  34. uint32_t c5spd;
  35. uint32_t length;
  36. uint32_t loop_begin;
  37. uint32_t loop_end;
  38. bool loop_enabled;
  39. bool pingpong_enabled;
  40. bool is16bit;
  41. bool stereo;
  42. bool exists;
  43. bool compressed;
  44. };
  45. enum IT_Sample_Flags {
  46. IT_SAMPLE_EXISTS = 1,
  47. IT_SAMPLE_16BITS = 2,
  48. IT_SAMPLE_STEREO = 4,
  49. IT_SAMPLE_COMPRESSED = 8,
  50. IT_SAMPLE_LOOPED = 16,
  51. IT_SAMPLE_SUSTAIN_LOOPED = 32,
  52. IT_SAMPLE_LOOP_IS_PINGPONG = 64,
  53. IT_SAMPLE_SUSTAIN_LOOP_IS_PINGPONG = 128
  54. };
  55. CPLoader::Error CPLoader_IT::load_sample(CPSample *p_sample) {
  56. AuxSampleData aux_sample_data;
  57. char aux_header[4];
  58. file->get_byte_array((uint8_t *)aux_header, 4);
  59. if (aux_header[0] != 'I' ||
  60. aux_header[1] != 'M' ||
  61. aux_header[2] != 'P' ||
  62. aux_header[3] != 'S') {
  63. //CP_PRINTERR("IT CPLoader CPSample: Failed Identifier");
  64. return FILE_UNRECOGNIZED;
  65. }
  66. // Ignore deprecated 8.3 filename
  67. for (int i = 0; i < 12; i++)
  68. file->get_byte();
  69. file->get_byte(); //ignore zerobyte
  70. p_sample->set_global_volume(file->get_byte());
  71. /* SAMPLE FLAGS */
  72. uint8_t flags = file->get_byte();
  73. aux_sample_data.loop_enabled = flags & IT_SAMPLE_LOOPED;
  74. aux_sample_data.pingpong_enabled = flags & IT_SAMPLE_LOOP_IS_PINGPONG;
  75. aux_sample_data.is16bit = flags & IT_SAMPLE_16BITS;
  76. aux_sample_data.exists = flags & IT_SAMPLE_EXISTS;
  77. aux_sample_data.stereo = flags & IT_SAMPLE_STEREO;
  78. aux_sample_data.compressed = flags & IT_SAMPLE_COMPRESSED;
  79. p_sample->set_default_volume(file->get_byte());
  80. /* SAMPLE NAME */
  81. char aux_name[26];
  82. file->get_byte_array((uint8_t *)aux_name, 26);
  83. p_sample->set_name(aux_name);
  84. // ??
  85. uint8_t convert_flag = file->get_byte();
  86. // PAN
  87. uint8_t pan = file->get_byte();
  88. p_sample->set_pan(pan & 0x7F);
  89. p_sample->set_pan_enabled(pan & 0x80);
  90. aux_sample_data.length = file->get_dword();
  91. aux_sample_data.loop_begin = file->get_dword();
  92. aux_sample_data.loop_end = file->get_dword();
  93. aux_sample_data.c5spd = file->get_dword();
  94. /*p_sample->data.set_sustain_loop_begin=*/file->get_dword();
  95. /*p_sample->data.sustain_loop_end=*/file->get_dword();
  96. aux_sample_data.fileofs = file->get_dword();
  97. p_sample->set_vibrato_speed(file->get_byte());
  98. p_sample->set_vibrato_depth(file->get_byte());
  99. p_sample->set_vibrato_rate(file->get_byte());
  100. switch (file->get_byte()) {
  101. /* Vibrato Wave: 0=sine, 1=rampdown, 2=square, 3=random */
  102. case 0: p_sample->set_vibrato_type(CPSample::VIBRATO_SINE); break;
  103. case 1: p_sample->set_vibrato_type(CPSample::VIBRATO_SAW); break;
  104. case 2: p_sample->set_vibrato_type(CPSample::VIBRATO_SQUARE); break;
  105. case 3: p_sample->set_vibrato_type(CPSample::VIBRATO_RANDOM); break;
  106. default: p_sample->set_vibrato_type(CPSample::VIBRATO_SINE); break;
  107. }
  108. //printf("Name %s - Flags: fileofs :%i - c5spd %i - len %i 16b %i - data?: %i\n",p_sample->get_name(),aux_sample_data.fileofs,aux_sample_data.c5spd, aux_sample_data.length, aux_sample_data.is16bit,aux_sample_data.exists);
  109. CPSample_ID samp_id;
  110. if (aux_sample_data.exists) {
  111. samp_id = load_sample_data(aux_sample_data);
  112. CPSampleManager::get_singleton()->set_c5_freq(samp_id, aux_sample_data.c5spd);
  113. CPSampleManager::get_singleton()->set_loop_begin(samp_id, aux_sample_data.loop_begin);
  114. CPSampleManager::get_singleton()->set_loop_end(samp_id, aux_sample_data.loop_end);
  115. CPSample_Loop_Type loop_type = aux_sample_data.loop_enabled ? (aux_sample_data.pingpong_enabled ? CP_LOOP_BIDI : CP_LOOP_FORWARD) : CP_LOOP_NONE;
  116. CPSampleManager::get_singleton()->set_loop_end(samp_id, aux_sample_data.loop_end);
  117. CPSampleManager::get_singleton()->set_loop_type(samp_id, loop_type);
  118. }
  119. //printf("Loaded id is null?: %i\n",samp_id.is_null());
  120. p_sample->set_sample_data(samp_id);
  121. if (!samp_id.is_null()) {
  122. // printf("Loaded ID: stereo: %i len %i 16bit %i\n",CPSampleManager::get_singleton()->is_stereo(samp_id), CPSampleManager::get_singleton()->get_size( samp_id), CPSampleManager::get_singleton()->is_16bits( samp_id) );
  123. }
  124. CP_ERR_COND_V(file->eof_reached(), FILE_CORRUPTED);
  125. CP_ERR_COND_V(file->get_error(), FILE_CORRUPTED);
  126. return FILE_OK;
  127. }
  128. CPSample_ID CPLoader_IT::load_sample_data(AuxSampleData &p_sample_data) {
  129. int aux_sample_properties = (p_sample_data.is16bit ? IT_SAMPLE_16BITS : 0) | (p_sample_data.compressed ? IT_SAMPLE_COMPRESSED : 0) | (p_sample_data.stereo ? IT_SAMPLE_STEREO : 0);
  130. file->seek(p_sample_data.fileofs);
  131. CPSampleManager *sm = CPSampleManager::get_singleton();
  132. CPSample_ID id;
  133. switch (aux_sample_properties) {
  134. case (0): // 8 bits, mono
  135. case (IT_SAMPLE_16BITS): // 16 bits mono
  136. case (IT_SAMPLE_STEREO): // 8 bits stereo
  137. case (IT_SAMPLE_16BITS | IT_SAMPLE_STEREO): { // 16 bits mono
  138. id = sm->create(p_sample_data.is16bit, p_sample_data.stereo, p_sample_data.length);
  139. if (id.is_null())
  140. break;
  141. sm->lock_data(id);
  142. int16_t *ptr16 = (int16_t *)sm->get_data(id);
  143. int8_t *ptr8 = (int8_t *)ptr16;
  144. int chans = p_sample_data.stereo ? 2 : 1;
  145. if (p_sample_data.is16bit) {
  146. for (int c = 0; c < chans; c++) {
  147. for (int i = 0; i < p_sample_data.length; i++) {
  148. ptr16[i * chans + c] = file->get_word();
  149. }
  150. }
  151. } else {
  152. for (int c = 0; c < chans; c++) {
  153. for (int i = 0; i < p_sample_data.length; i++) {
  154. ptr8[i * chans + c] = file->get_byte();
  155. }
  156. }
  157. }
  158. sm->unlock_data(id);
  159. } break;
  160. case (IT_SAMPLE_COMPRESSED): { // 8 bits compressed
  161. id = sm->create(false, false, p_sample_data.length);
  162. if (id.is_null())
  163. break;
  164. sm->lock_data(id);
  165. if (load_sample_8bits_IT_compressed((void *)sm->get_data(id), p_sample_data.length)) {
  166. sm->unlock_data(id);
  167. sm->destroy(id);
  168. break;
  169. }
  170. sm->unlock_data(id);
  171. } break;
  172. case (IT_SAMPLE_16BITS | IT_SAMPLE_COMPRESSED): { // 16 bits compressed
  173. id = sm->create(true, false, p_sample_data.length);
  174. if (id.is_null())
  175. break;
  176. sm->lock_data(id);
  177. if (load_sample_16bits_IT_compressed((void *)sm->get_data(id), p_sample_data.length)) {
  178. sm->unlock_data(id);
  179. sm->destroy(id);
  180. break;
  181. }
  182. sm->unlock_data(id);
  183. } break;
  184. default: {
  185. // I dont know how to handle stereo compressed, does that exist?
  186. } break;
  187. }
  188. return id;
  189. }
  190. CPLoader::Error CPLoader_IT::load_samples() {
  191. for (int i = 0; i < header.smpnum; i++) {
  192. //seek to sample
  193. file->seek(0xC0 + header.ordnum + header.insnum * 4 + i * 4);
  194. uint32_t final_location = file->get_dword();
  195. file->seek(final_location);
  196. Error err = load_sample(song->get_sample(i));
  197. CP_ERR_COND_V(err, err);
  198. }
  199. if (file->eof_reached() || file->get_error())
  200. return FILE_CORRUPTED;
  201. return FILE_OK;
  202. }
  203. /* * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE
  204. -The following sample decompression code is based on xmp's code.(http://xmp.helllabs.org) which is based in openCP code.
  205. * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE */
  206. uint32_t CPLoader_IT::read_n_bits_from_IT_compressed_block(uint8_t p_bits_to_read) {
  207. uint32_t aux_return_value;
  208. uint32_t val;
  209. uint8_t *buffer = (uint8_t *)source_position;
  210. if (p_bits_to_read <= source_remaining_bits) {
  211. val = buffer[3];
  212. val <<= 8;
  213. val |= buffer[2];
  214. val <<= 8;
  215. val |= buffer[1];
  216. val <<= 8;
  217. val |= buffer[0];
  218. aux_return_value = val & ((1 << p_bits_to_read) - 1);
  219. val >>= p_bits_to_read;
  220. source_remaining_bits -= p_bits_to_read;
  221. buffer[3] = val >> 24;
  222. buffer[2] = (val >> 16) & 0xFF;
  223. buffer[1] = (val >> 8) & 0xFF;
  224. buffer[0] = (val)&0xFF;
  225. } else {
  226. aux_return_value = buffer[3];
  227. aux_return_value <<= 8;
  228. aux_return_value |= buffer[2];
  229. aux_return_value <<= 8;
  230. aux_return_value |= buffer[1];
  231. aux_return_value <<= 8;
  232. aux_return_value |= buffer[0];
  233. uint32_t nbits = p_bits_to_read - source_remaining_bits;
  234. source_position++;
  235. buffer += 4;
  236. val = buffer[3];
  237. val <<= 8;
  238. val |= buffer[2];
  239. val <<= 8;
  240. val |= buffer[1];
  241. val <<= 8;
  242. val |= buffer[0];
  243. aux_return_value |= ((val & ((1 << nbits) - 1)) << source_remaining_bits);
  244. val >>= nbits;
  245. source_remaining_bits = 32 - nbits;
  246. buffer[3] = val >> 24;
  247. buffer[2] = (val >> 16) & 0xFF;
  248. buffer[1] = (val >> 8) & 0xFF;
  249. buffer[0] = (val)&0xFF;
  250. }
  251. return aux_return_value;
  252. }
  253. bool CPLoader_IT::read_IT_compressed_block(bool p_16bits) {
  254. uint16_t size;
  255. size = file->get_word();
  256. if (file->eof_reached() || file->get_error()) return true;
  257. pat_data = (uint8_t *)CP_ALLOC(4 * ((size >> 2) + 2));
  258. if (!pat_data)
  259. return true;
  260. source_buffer = (uint32_t *)pat_data;
  261. file->get_byte_array((uint8_t *)source_buffer, size);
  262. if (file->eof_reached() || file->get_error()) {
  263. free_IT_compressed_block();
  264. return true;
  265. }
  266. source_position = source_buffer;
  267. source_remaining_bits = 32;
  268. return false;
  269. }
  270. void CPLoader_IT::free_IT_compressed_block() {
  271. if (pat_data) {
  272. CP_FREE(pat_data);
  273. pat_data = NULL;
  274. }
  275. }
  276. bool CPLoader_IT::load_sample_8bits_IT_compressed(void *p_dest_buffer, int p_buffsize) {
  277. int8_t *dest_buffer; /* destination buffer which will be returned */
  278. uint16_t block_length; /* length of compressed data block in samples */
  279. uint16_t block_position; /* position in block */
  280. uint8_t bit_width; /* actual "bit width" */
  281. uint16_t aux_value; /* value read from file to be processed */
  282. int8_t d1, d2; /* integrator buffers (d2 for it2.15) */
  283. int8_t *dest_position; /* position in output buffer */
  284. int8_t v; /* sample value */
  285. bool it215; // is this an it215 module?
  286. dest_buffer = (int8_t *)p_dest_buffer;
  287. if (dest_buffer == NULL)
  288. return true;
  289. for (int i = 0; i < p_buffsize; i++)
  290. dest_buffer[i] = 0;
  291. dest_position = dest_buffer;
  292. it215 = (header.cmwt == 0x215);
  293. /* now unpack data till the dest buffer is full */
  294. while (p_buffsize) {
  295. /* read a new block of compressed data and reset variables */
  296. if (read_IT_compressed_block(false)) {
  297. CP_PRINTERR("Out of memory decompressing IT CPSample");
  298. return true;
  299. }
  300. block_length = (p_buffsize < 0x8000) ? p_buffsize : 0x8000;
  301. block_position = 0;
  302. bit_width = 9; /* start with width of 9 bits */
  303. d1 = d2 = 0; /* reset integrator buffers */
  304. /* now uncompress the data block */
  305. while (block_position < block_length) {
  306. aux_value = read_n_bits_from_IT_compressed_block(bit_width); /* read bits */
  307. if (bit_width < 7) { /* method 1 (1-6 bits) */
  308. if (aux_value == (1 << (bit_width - 1))) { /* check for "100..." */
  309. aux_value = read_n_bits_from_IT_compressed_block(3) + 1; /* yes -> read new width; */
  310. bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
  311. /* and expand it */
  312. continue; /* ... next value */
  313. }
  314. } else if (bit_width < 9) { /* method 2 (7-8 bits) */
  315. uint8_t border = (0xFF >> (9 - bit_width)) - 4;
  316. /* lower border for width chg */
  317. if (aux_value > border && aux_value <= (border + 8)) {
  318. aux_value -= border; /* convert width to 1-8 */
  319. bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
  320. /* and expand it */
  321. continue; /* ... next value */
  322. }
  323. } else if (bit_width == 9) { /* method 3 (9 bits) */
  324. if (aux_value & 0x100) { /* bit 8 set? */
  325. bit_width = (aux_value + 1) & 0xff; /* new width... */
  326. continue; /* ... and next value */
  327. }
  328. } else { /* illegal width, abort */
  329. free_IT_compressed_block();
  330. CP_PRINTERR("CPSample has illegal BitWidth ");
  331. return true;
  332. }
  333. /* now expand value to signed byte */
  334. if (bit_width < 8) {
  335. uint8_t tmp_shift = 8 - bit_width;
  336. v = (aux_value << tmp_shift);
  337. v >>= tmp_shift;
  338. } else
  339. v = (int8_t)aux_value;
  340. /* integrate upon the sample values */
  341. d1 += v;
  342. d2 += d1;
  343. /* ... and store it into the buffer */
  344. *(dest_position++) = it215 ? d2 : d1;
  345. block_position++;
  346. }
  347. /* now subtract block lenght from total length and go on */
  348. free_IT_compressed_block();
  349. p_buffsize -= block_length;
  350. }
  351. return false;
  352. }
  353. bool CPLoader_IT::load_sample_16bits_IT_compressed(void *p_dest_buffer, int p_buffsize) {
  354. int16_t *dest_buffer; /* destination buffer which will be returned */
  355. uint16_t block_length; /* length of compressed data block in samples */
  356. uint16_t block_position; /* position in block */
  357. uint8_t bit_width; /* actual "bit width" */
  358. uint32_t aux_value; /* value read from file to be processed */
  359. int16_t d1, d2; /* integrator buffers (d2 for it2.15) */
  360. int16_t *dest_position; /* position in output buffer */
  361. int16_t v; /* sample value */
  362. bool it215; // is this an it215 module?
  363. dest_buffer = (int16_t *)p_dest_buffer;
  364. if (dest_buffer == NULL)
  365. return true;
  366. for (int i = 0; i < p_buffsize; i++)
  367. dest_buffer[i] = 0;
  368. dest_position = dest_buffer;
  369. it215 = (header.cmwt == 0x215);
  370. while (p_buffsize) {
  371. /* read a new block of compressed data and reset variables */
  372. if (read_IT_compressed_block(true)) {
  373. return true;
  374. }
  375. block_length = (p_buffsize < 0x4000) ? p_buffsize : 0x4000;
  376. block_position = 0;
  377. bit_width = 17; /* start with width of 9 bits */
  378. d1 = d2 = 0; /* reset integrator buffers */
  379. while (block_position < block_length) {
  380. aux_value = read_n_bits_from_IT_compressed_block(bit_width); /* read bits */
  381. if (bit_width < 7) { /* method 1 (1-6 bits) */
  382. if ((signed)aux_value == (1 << (bit_width - 1))) { /* check for "100..." */
  383. aux_value = read_n_bits_from_IT_compressed_block(4) + 1; /* yes -> read new width; */
  384. bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
  385. /* and expand it */
  386. continue; /* ... next value */
  387. }
  388. } else if (bit_width < 17) {
  389. uint16_t border = (0xFFFF >> (17 - bit_width)) - 8;
  390. if ((int)aux_value > (int)border && (int)aux_value <= ((int)border + 16)) {
  391. aux_value -= border; /* convert width to 1-8 */
  392. bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
  393. /* and expand it */
  394. continue; /* ... next value */
  395. }
  396. } else if (bit_width == 17) {
  397. if (aux_value & 0x10000) { /* bit 8 set? */
  398. bit_width = (aux_value + 1) & 0xff; /* new width... */
  399. continue; /* ... and next value */
  400. }
  401. } else { /* illegal width, abort */
  402. CP_PRINTERR("CPSample has illegal BitWidth ");
  403. free_IT_compressed_block();
  404. return true;
  405. }
  406. /* now expand value to signed byte */
  407. if (bit_width < 16) {
  408. uint8_t tmp_shift = 16 - bit_width;
  409. v = (aux_value << tmp_shift);
  410. v >>= tmp_shift;
  411. } else
  412. v = (int16_t)aux_value;
  413. /* integrate upon the sample values */
  414. d1 += v;
  415. d2 += d1;
  416. /* ... and store it into the buffer */
  417. *(dest_position++) = it215 ? d2 : d1;
  418. block_position++;
  419. }
  420. /* now subtract block lenght from total length and go on */
  421. free_IT_compressed_block();
  422. p_buffsize -= block_length;
  423. }
  424. return false;
  425. }