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.

455 lines
14KB

  1. /* _______ ____ __ ___ ___
  2. * \ _ \ \ / \ / \ \ / / ' ' '
  3. * | | \ \ | | || | \/ | . .
  4. * | | | | | | || ||\ /| |
  5. * | | | | | | || || \/ | | ' ' '
  6. * | | | | | | || || | | . .
  7. * | |_/ / \ \__// || | |
  8. * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
  9. * / \
  10. * / . \
  11. * read669.c - Code to read a 669 Composer module / / \ \
  12. * from an open file. | < / \_
  13. * | \/ /\ /
  14. * By Christopher Snowhill. \_ / > /
  15. * | \ / /
  16. * | ' /
  17. * \__/
  18. */
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "dumb.h"
  23. #include "internal/it.h"
  24. static int it_669_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, int tempo,
  25. int breakpoint, unsigned char *buffer,
  26. int *used_channels) {
  27. int pos;
  28. int channel;
  29. int row;
  30. IT_ENTRY *entry;
  31. pattern->n_rows = 64;
  32. if (dumbfile_getnc((char *)buffer, 64 * 3 * 8, f) < 64 * 3 * 8)
  33. return -1;
  34. /* compute number of entries */
  35. pattern->n_entries =
  36. 64 + 1; /* Account for the row end markers, speed command */
  37. if (breakpoint < 63)
  38. pattern->n_entries++; /* and break to row 0 */
  39. pos = 0;
  40. for (row = 0; row < 64; row++) {
  41. for (channel = 0; channel < 8; channel++) {
  42. if (buffer[pos + 0] != 0xFF || buffer[pos + 2] != 0xFF)
  43. pattern->n_entries++;
  44. pos += 3;
  45. }
  46. }
  47. pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
  48. if (!pattern->entry)
  49. return -1;
  50. if (breakpoint == 63)
  51. breakpoint++;
  52. entry = pattern->entry;
  53. entry->channel = 8;
  54. entry->mask = IT_ENTRY_EFFECT;
  55. entry->effect = IT_SET_SPEED;
  56. entry->effectvalue = tempo;
  57. entry++;
  58. pos = 0;
  59. for (row = 0; row < 64; row++) {
  60. if (row == breakpoint) {
  61. entry->channel = 8;
  62. entry->mask = IT_ENTRY_EFFECT;
  63. entry->effect = IT_BREAK_TO_ROW;
  64. entry->effectvalue = 0;
  65. entry++;
  66. }
  67. for (channel = 0; channel < 8; channel++) {
  68. if (buffer[pos + 0] != 0xFF || buffer[pos + 2] != 0xFF) {
  69. entry->channel = channel;
  70. entry->mask = 0;
  71. if (buffer[pos + 0] < 0xFE) {
  72. entry->mask |= IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT;
  73. entry->note = (buffer[pos + 0] >> 2) + 36;
  74. entry->instrument =
  75. (((buffer[pos + 0] << 4) | (buffer[pos + 1] >> 4)) &
  76. 0x3F) +
  77. 1;
  78. }
  79. if (buffer[pos + 0] <= 0xFE) {
  80. entry->mask |= IT_ENTRY_VOLPAN;
  81. entry->volpan = ((buffer[pos + 1] & 15) << 6) / 15;
  82. if (*used_channels < channel + 1)
  83. *used_channels = channel + 1;
  84. }
  85. if (buffer[pos + 2] != 0xFF) {
  86. entry->mask |= IT_ENTRY_EFFECT;
  87. entry->effectvalue = buffer[pos + 2] & 15;
  88. switch (buffer[pos + 2] >> 4) {
  89. case 0:
  90. entry->effect = IT_PORTAMENTO_UP;
  91. break;
  92. case 1:
  93. entry->effect = IT_PORTAMENTO_DOWN;
  94. break;
  95. case 2:
  96. entry->effect = IT_TONE_PORTAMENTO;
  97. break;
  98. case 3:
  99. entry->effect = IT_S;
  100. entry->effectvalue += IT_S_FINETUNE * 16 + 8;
  101. break;
  102. case 4:
  103. entry->effect = IT_VIBRATO;
  104. // XXX speed unknown
  105. entry->effectvalue |= 0x10;
  106. break;
  107. case 5:
  108. if (entry->effectvalue) {
  109. entry->effect = IT_SET_SPEED;
  110. } else {
  111. entry->mask &= ~IT_ENTRY_EFFECT;
  112. }
  113. break;
  114. #if 0
  115. /* dunno about this, really... */
  116. case 6:
  117. if (entry->effectvalue == 0) {
  118. entry->effect = IT_PANNING_SLIDE;
  119. entry->effectvalue = 0xFE;
  120. } else if (entry->effectvalue == 1) {
  121. entry->effect = IT_PANNING_SLIDE;
  122. entry->effectvalue = 0xEF;
  123. } else {
  124. entry->mask &= ~IT_ENTRY_EFFECT;
  125. }
  126. break;
  127. #endif
  128. default:
  129. entry->mask &= ~IT_ENTRY_EFFECT;
  130. break;
  131. }
  132. if (*used_channels < channel + 1)
  133. *used_channels = channel + 1;
  134. }
  135. entry++;
  136. }
  137. pos += 3;
  138. }
  139. IT_SET_END_ROW(entry);
  140. entry++;
  141. }
  142. return 0;
  143. }
  144. static int it_669_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f) {
  145. dumbfile_getnc((char *)sample->name, 13, f);
  146. sample->name[13] = 0;
  147. sample->filename[0] = 0;
  148. sample->length = dumbfile_igetl(f);
  149. sample->loop_start = dumbfile_igetl(f);
  150. sample->loop_end = dumbfile_igetl(f);
  151. if (dumbfile_error(f))
  152. return -1;
  153. if (sample->length <= 0) {
  154. sample->flags = 0;
  155. return 0;
  156. }
  157. sample->flags = IT_SAMPLE_EXISTS;
  158. sample->global_volume = 64;
  159. sample->default_volume = 64;
  160. sample->default_pan = 0;
  161. sample->C5_speed = 8363;
  162. // the above line might be wrong
  163. if ((sample->loop_end > sample->length) && !(sample->loop_start))
  164. sample->loop_end = 0;
  165. if (sample->loop_end > sample->length)
  166. sample->loop_end = sample->length;
  167. if (sample->loop_end - sample->loop_start > 2)
  168. sample->flags |= IT_SAMPLE_LOOP;
  169. sample->vibrato_speed = 0;
  170. sample->vibrato_depth = 0;
  171. sample->vibrato_rate = 0;
  172. sample->vibrato_waveform = 0; // do we have to set _all_ these?
  173. sample->finetune = 0;
  174. sample->max_resampling_quality = -1;
  175. return 0;
  176. }
  177. static int it_669_read_sample_data(IT_SAMPLE *sample, DUMBFILE *f) {
  178. long i;
  179. long truncated_size;
  180. /* let's get rid of the sample data coming after the end of the loop */
  181. if ((sample->flags & IT_SAMPLE_LOOP) && sample->loop_end < sample->length) {
  182. truncated_size = sample->length - sample->loop_end;
  183. sample->length = sample->loop_end;
  184. } else {
  185. truncated_size = 0;
  186. }
  187. sample->data = malloc(sample->length);
  188. if (!sample->data)
  189. return -1;
  190. if (sample->length) {
  191. i = dumbfile_getnc(sample->data, sample->length, f);
  192. if (i < sample->length) {
  193. // return -1;
  194. // ficking truncated files
  195. if (i <= 0) {
  196. sample->flags = 0;
  197. return 0;
  198. }
  199. sample->length = i;
  200. if (sample->loop_end > i)
  201. sample->loop_end = i;
  202. } else {
  203. /* skip truncated data */
  204. dumbfile_skip(f, truncated_size);
  205. // Should we be truncating it?
  206. if (dumbfile_error(f))
  207. return -1;
  208. }
  209. for (i = 0; i < sample->length; i++)
  210. ((signed char *)sample->data)[i] ^= 0x80;
  211. }
  212. return 0;
  213. }
  214. static DUMB_IT_SIGDATA *it_669_load_sigdata(DUMBFILE *f, int *ext) {
  215. DUMB_IT_SIGDATA *sigdata;
  216. int n_channels;
  217. int i;
  218. unsigned char tempolist[128];
  219. unsigned char breaklist[128];
  220. i = dumbfile_igetw(f);
  221. if (i != 0x6669 && i != 0x4E4A)
  222. return NULL;
  223. *ext = (i == 0x4E4A);
  224. sigdata = malloc(sizeof(*sigdata));
  225. if (!sigdata) {
  226. return NULL;
  227. }
  228. if (dumbfile_getnc((char *)sigdata->name, 36, f) < 36) {
  229. free(sigdata);
  230. return NULL;
  231. }
  232. sigdata->name[36] = 0;
  233. sigdata->order = NULL;
  234. sigdata->instrument = NULL;
  235. sigdata->pattern = NULL;
  236. sigdata->midi = NULL;
  237. sigdata->checkpoint = NULL;
  238. sigdata->sample = NULL;
  239. sigdata->n_instruments = 0;
  240. sigdata->song_message = malloc(72 + 2 + 1);
  241. if (!sigdata->song_message) {
  242. free(sigdata);
  243. return NULL;
  244. }
  245. if (dumbfile_getnc((char *)sigdata->song_message, 36, f) < 36) {
  246. _dumb_it_unload_sigdata(sigdata);
  247. return NULL;
  248. }
  249. sigdata->song_message[36] = 13;
  250. sigdata->song_message[36 + 1] = 10;
  251. if (dumbfile_getnc((char *)sigdata->song_message + 38, 36, f) < 36) {
  252. _dumb_it_unload_sigdata(sigdata);
  253. return NULL;
  254. }
  255. sigdata->song_message[38 + 36] = 0;
  256. sigdata->n_samples = dumbfile_getc(f);
  257. sigdata->n_patterns = dumbfile_getc(f);
  258. sigdata->restart_position = dumbfile_getc(f);
  259. if ((sigdata->n_samples) > 64 || (sigdata->n_patterns > 128)) {
  260. _dumb_it_unload_sigdata(sigdata);
  261. return NULL;
  262. }
  263. sigdata->order = malloc(128); /* We may need to scan the extra ones! */
  264. if (!sigdata->order) {
  265. _dumb_it_unload_sigdata(sigdata);
  266. return NULL;
  267. }
  268. if (dumbfile_getnc((char *)sigdata->order, 128, f) < 128) {
  269. _dumb_it_unload_sigdata(sigdata);
  270. return NULL;
  271. }
  272. for (i = 0; i < 128; i++) {
  273. if (sigdata->order[i] == 255)
  274. break;
  275. if (sigdata->order[i] >= sigdata->n_patterns) {
  276. _dumb_it_unload_sigdata(sigdata);
  277. return NULL;
  278. }
  279. }
  280. if (!i) {
  281. _dumb_it_unload_sigdata(sigdata);
  282. return NULL;
  283. }
  284. sigdata->n_orders = i;
  285. if (dumbfile_getnc((char *)tempolist, 128, f) < 128) {
  286. _dumb_it_unload_sigdata(sigdata);
  287. return NULL;
  288. }
  289. if (dumbfile_getnc((char *)breaklist, 128, f) < 128) {
  290. _dumb_it_unload_sigdata(sigdata);
  291. return NULL;
  292. }
  293. sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
  294. if (!sigdata->sample) {
  295. _dumb_it_unload_sigdata(sigdata);
  296. return NULL;
  297. }
  298. for (i = 0; i < sigdata->n_samples; i++)
  299. sigdata->sample[i].data = NULL;
  300. for (i = 0; i < sigdata->n_samples; i++) {
  301. if (it_669_read_sample_header(&sigdata->sample[i], f)) {
  302. _dumb_it_unload_sigdata(sigdata);
  303. return NULL;
  304. }
  305. }
  306. /* May as well try to save a tiny bit of memory. */
  307. if (sigdata->n_orders < 128) {
  308. unsigned char *order = realloc(sigdata->order, sigdata->n_orders);
  309. if (order)
  310. sigdata->order = order;
  311. }
  312. sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
  313. if (!sigdata->pattern) {
  314. _dumb_it_unload_sigdata(sigdata);
  315. return NULL;
  316. }
  317. for (i = 0; i < sigdata->n_patterns; i++)
  318. sigdata->pattern[i].entry = NULL;
  319. n_channels = 0;
  320. /* Read in the patterns */
  321. {
  322. unsigned char *buffer =
  323. malloc(64 * 3 * 8); /* 64 rows * 3 bytes * 8 channels */
  324. if (!buffer) {
  325. _dumb_it_unload_sigdata(sigdata);
  326. return NULL;
  327. }
  328. for (i = 0; i < sigdata->n_patterns; i++) {
  329. if (it_669_read_pattern(&sigdata->pattern[i], f, tempolist[i],
  330. breaklist[i], buffer, &n_channels) != 0) {
  331. free(buffer);
  332. _dumb_it_unload_sigdata(sigdata);
  333. return NULL;
  334. }
  335. }
  336. free(buffer);
  337. }
  338. sigdata->n_pchannels = n_channels;
  339. /* And finally, the sample data */
  340. for (i = 0; i < sigdata->n_samples; i++) {
  341. if (it_669_read_sample_data(&sigdata->sample[i], f)) {
  342. _dumb_it_unload_sigdata(sigdata);
  343. return NULL;
  344. }
  345. }
  346. /* Now let's initialise the remaining variables, and we're done! */
  347. sigdata->flags =
  348. IT_OLD_EFFECTS | IT_LINEAR_SLIDES | IT_STEREO | IT_WAS_A_669;
  349. sigdata->global_volume = 128;
  350. sigdata->mixing_volume = 48;
  351. sigdata->speed = 4;
  352. sigdata->tempo = 78;
  353. sigdata->pan_separation = 128;
  354. memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
  355. for (i = 0; i < DUMB_IT_N_CHANNELS; i += 2) {
  356. int sep = 32 * dumb_it_default_panning_separation / 100;
  357. sigdata->channel_pan[i + 0] = 32 + sep;
  358. sigdata->channel_pan[i + 1] = 32 - sep;
  359. }
  360. if (_dumb_it_fix_invalid_orders(sigdata) < 0) {
  361. _dumb_it_unload_sigdata(sigdata);
  362. return NULL;
  363. }
  364. return sigdata;
  365. }
  366. DUH *dumb_read_669_quick(DUMBFILE *f) {
  367. sigdata_t *sigdata;
  368. int ext;
  369. DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
  370. sigdata = it_669_load_sigdata(f, &ext);
  371. if (!sigdata)
  372. return NULL;
  373. {
  374. const char *tag[2][2];
  375. tag[0][0] = "TITLE";
  376. tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
  377. tag[1][0] = "FORMAT";
  378. tag[1][1] = ext ? "669 Extended" : "669";
  379. return make_duh(-1, 2, (const char *const(*)[2])tag, 1, &descptr,
  380. &sigdata);
  381. }
  382. }