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.

396 lines
11KB

  1. /* _______ ____ __ ___ ___
  2. * \ _ \ \ / \ / \ \ / / ' ' '
  3. * | | \ \ | | || | \/ | . .
  4. * | | | | | | || ||\ /| |
  5. * | | | | | | || || \/ | | ' ' '
  6. * | | | | | | || || | | . .
  7. * | |_/ / \ \__// || | |
  8. * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
  9. * / \
  10. * / . \
  11. * readam.c - Code to read a RIFF DSMF module / / \ \
  12. * from a parsed RIFF structure. | < / \_
  13. * | \/ /\ /
  14. * By Christopher Snowhill. \_ / > /
  15. * | \ / /
  16. * | ' /
  17. * \__/
  18. */
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "dumb.h"
  22. #include "internal/it.h"
  23. #include "internal/riff.h"
  24. static int it_riff_dsmf_process_sample(IT_SAMPLE *sample, DUMBFILE *f,
  25. int len) {
  26. int flags;
  27. dumbfile_getnc((char *)sample->filename, 13, f);
  28. sample->filename[14] = 0;
  29. flags = dumbfile_igetw(f);
  30. sample->default_volume = dumbfile_getc(f);
  31. sample->length = dumbfile_igetl(f);
  32. sample->loop_start = dumbfile_igetl(f);
  33. sample->loop_end = dumbfile_igetl(f);
  34. dumbfile_skip(f, 32 - 28);
  35. sample->C5_speed = dumbfile_igetw(f) * 2;
  36. dumbfile_skip(f, 36 - 34);
  37. dumbfile_getnc((char *)sample->name, 28, f);
  38. sample->name[28] = 0;
  39. /*if ( data[ 0x38 ] || data[ 0x39 ] || data[ 0x3A ] || data[ 0x3B ] )
  40. return -1;*/
  41. if (!sample->length) {
  42. sample->flags &= ~IT_SAMPLE_EXISTS;
  43. return 0;
  44. }
  45. /*if ( flags & ~( 2 | 1 ) )
  46. return -1;*/
  47. if (sample->length + 64 > len)
  48. return -1;
  49. sample->flags = IT_SAMPLE_EXISTS;
  50. sample->default_pan = 0;
  51. sample->global_volume = 64;
  52. sample->vibrato_speed = 0;
  53. sample->vibrato_depth = 0;
  54. sample->vibrato_rate = 0;
  55. sample->vibrato_waveform = IT_VIBRATO_SINE;
  56. sample->finetune = 0;
  57. sample->max_resampling_quality = -1;
  58. if (flags & 1) {
  59. if (((unsigned int)sample->loop_end <= (unsigned int)sample->length) &&
  60. ((unsigned int)sample->loop_start <
  61. (unsigned int)sample->loop_end)) {
  62. sample->length = sample->loop_end;
  63. sample->flags |= IT_SAMPLE_LOOP;
  64. if (flags & 0x10)
  65. sample->flags |= IT_SAMPLE_PINGPONG_LOOP;
  66. }
  67. }
  68. sample->data = malloc(sample->length);
  69. if (!sample->data)
  70. return -1;
  71. dumbfile_getnc(sample->data, sample->length, f);
  72. if (!(flags & 2)) {
  73. for (flags = 0; flags < sample->length; ++flags)
  74. ((signed char *)sample->data)[flags] ^= 0x80;
  75. }
  76. return 0;
  77. }
  78. static int it_riff_dsmf_process_pattern(IT_PATTERN *pattern, DUMBFILE *f,
  79. int len) {
  80. int length, row;
  81. unsigned flags;
  82. long start, end;
  83. int p, q, r;
  84. IT_ENTRY *entry;
  85. length = dumbfile_igetw(f);
  86. if (length > len)
  87. return -1;
  88. len = length - 2;
  89. pattern->n_rows = 64;
  90. pattern->n_entries = 64;
  91. row = 0;
  92. start = dumbfile_pos(f);
  93. end = start + len;
  94. while ((row < 64) && !dumbfile_error(f) && (dumbfile_pos(f) < end)) {
  95. p = dumbfile_getc(f);
  96. if (!p) {
  97. ++row;
  98. continue;
  99. }
  100. flags = p & 0xF0;
  101. if (flags) {
  102. ++pattern->n_entries;
  103. if (flags & 0x80)
  104. dumbfile_skip(f, 1);
  105. if (flags & 0x40)
  106. dumbfile_skip(f, 1);
  107. if (flags & 0x20)
  108. dumbfile_skip(f, 1);
  109. if (flags & 0x10)
  110. dumbfile_skip(f, 2);
  111. }
  112. }
  113. if (pattern->n_entries == 64)
  114. return 0;
  115. pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
  116. if (!pattern->entry)
  117. return -1;
  118. entry = pattern->entry;
  119. row = 0;
  120. if (dumbfile_seek(f, start, DFS_SEEK_SET))
  121. return -1;
  122. while ((row < 64) && !dumbfile_error(f) && (dumbfile_pos(f) < end)) {
  123. p = dumbfile_getc(f);
  124. if (!p) {
  125. IT_SET_END_ROW(entry);
  126. ++entry;
  127. ++row;
  128. continue;
  129. }
  130. flags = p;
  131. entry->channel = flags & 0x0F;
  132. entry->mask = 0;
  133. if (flags & 0xF0) {
  134. if (flags & 0x80) {
  135. q = dumbfile_getc(f);
  136. if (q) {
  137. entry->mask |= IT_ENTRY_NOTE;
  138. entry->note = q - 1;
  139. }
  140. }
  141. if (flags & 0x40) {
  142. q = dumbfile_getc(f);
  143. if (q) {
  144. entry->mask |= IT_ENTRY_INSTRUMENT;
  145. entry->instrument = q;
  146. }
  147. }
  148. if (flags & 0x20) {
  149. entry->mask |= IT_ENTRY_VOLPAN;
  150. entry->volpan = dumbfile_getc(f);
  151. }
  152. if (flags & 0x10) {
  153. q = dumbfile_getc(f);
  154. r = dumbfile_getc(f);
  155. _dumb_it_xm_convert_effect(q, r, entry, 0);
  156. }
  157. if (entry->mask)
  158. entry++;
  159. }
  160. }
  161. while (row < 64) {
  162. IT_SET_END_ROW(entry);
  163. ++entry;
  164. ++row;
  165. }
  166. pattern->n_entries = (int)((long)entry - (long)pattern->entry);
  167. if (!pattern->n_entries)
  168. return -1;
  169. return 0;
  170. }
  171. static DUMB_IT_SIGDATA *it_riff_dsmf_load_sigdata(DUMBFILE *f,
  172. struct riff *stream) {
  173. DUMB_IT_SIGDATA *sigdata;
  174. int n, o, found;
  175. if (!stream)
  176. goto error;
  177. if (stream->type != DUMB_ID('D', 'S', 'M', 'F'))
  178. goto error;
  179. sigdata = malloc(sizeof(*sigdata));
  180. if (!sigdata)
  181. goto error;
  182. sigdata->n_patterns = 0;
  183. sigdata->n_samples = 0;
  184. sigdata->name[0] = 0;
  185. found = 0;
  186. for (n = 0; (unsigned)n < stream->chunk_count; ++n) {
  187. struct riff_chunk *c = stream->chunks + n;
  188. switch (c->type) {
  189. case DUMB_ID('S', 'O', 'N', 'G'):
  190. /* initialization data */
  191. if ((found) || (c->size < 192))
  192. goto error_sd;
  193. found = 1;
  194. break;
  195. case DUMB_ID('P', 'A', 'T', 'T'):
  196. ++sigdata->n_patterns;
  197. break;
  198. case DUMB_ID('I', 'N', 'S', 'T'):
  199. ++sigdata->n_samples;
  200. break;
  201. }
  202. }
  203. if (!found || !sigdata->n_samples || !sigdata->n_patterns)
  204. goto error_sd;
  205. if (sigdata->n_samples > 255 || sigdata->n_patterns > 255)
  206. goto error_sd;
  207. sigdata->song_message = NULL;
  208. sigdata->order = NULL;
  209. sigdata->instrument = NULL;
  210. sigdata->sample = NULL;
  211. sigdata->pattern = NULL;
  212. sigdata->midi = NULL;
  213. sigdata->checkpoint = NULL;
  214. sigdata->mixing_volume = 48;
  215. sigdata->pan_separation = 128;
  216. sigdata->n_instruments = 0;
  217. sigdata->n_orders = 0;
  218. sigdata->restart_position = 0;
  219. memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
  220. for (n = 0; n < DUMB_IT_N_CHANNELS; n += 4) {
  221. int sep = 32 * dumb_it_default_panning_separation / 100;
  222. sigdata->channel_pan[n] = 32 - sep;
  223. sigdata->channel_pan[n + 1] = 32 + sep;
  224. sigdata->channel_pan[n + 2] = 32 + sep;
  225. sigdata->channel_pan[n + 3] = 32 - sep;
  226. }
  227. for (n = 0; (unsigned)n < stream->chunk_count; ++n) {
  228. struct riff_chunk *c = stream->chunks + n;
  229. switch (c->type) {
  230. case DUMB_ID('S', 'O', 'N', 'G'):
  231. if (dumbfile_seek(f, c->offset, DFS_SEEK_SET))
  232. goto error_usd;
  233. dumbfile_getnc((char *)sigdata->name, 28, f);
  234. sigdata->name[28] = 0;
  235. sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
  236. dumbfile_skip(f, 36 - 28);
  237. sigdata->n_orders = dumbfile_igetw(f);
  238. if (sigdata->n_orders > 1024) // Whoa, nelly.
  239. goto error_usd;
  240. // sigdata->n_samples = ptr[ 38 ] | ( ptr[ 39 ] << 8 ); // whatever
  241. // sigdata->n_patterns = ptr[ 40 ] | ( ptr[ 41 ] << 8 );
  242. dumbfile_skip(f, 42 - 38);
  243. sigdata->n_pchannels = dumbfile_igetw(f);
  244. sigdata->global_volume = dumbfile_getc(f);
  245. sigdata->mixing_volume = dumbfile_getc(f);
  246. sigdata->speed = dumbfile_getc(f);
  247. sigdata->tempo = dumbfile_getc(f);
  248. for (o = 0; o < 16; ++o) {
  249. sigdata->channel_pan[o] = dumbfile_getc(f) / 2;
  250. }
  251. sigdata->order = malloc(128);
  252. if (!sigdata->order)
  253. goto error_usd;
  254. dumbfile_getnc((char *)sigdata->order, 128, f);
  255. break;
  256. }
  257. }
  258. sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
  259. if (!sigdata->pattern)
  260. goto error_usd;
  261. for (n = 0; n < sigdata->n_patterns; ++n)
  262. sigdata->pattern[n].entry = NULL;
  263. sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
  264. if (!sigdata->sample)
  265. goto error_usd;
  266. for (n = 0; n < sigdata->n_samples; ++n) {
  267. IT_SAMPLE *sample = sigdata->sample + n;
  268. sample->data = NULL;
  269. }
  270. sigdata->n_samples = 0;
  271. sigdata->n_patterns = 0;
  272. for (n = 0; (unsigned)n < stream->chunk_count; ++n) {
  273. struct riff_chunk *c = stream->chunks + n;
  274. switch (c->type) {
  275. case DUMB_ID('P', 'A', 'T', 'T'):
  276. if (dumbfile_seek(f, c->offset, DFS_SEEK_SET))
  277. goto error_usd;
  278. if (it_riff_dsmf_process_pattern(
  279. sigdata->pattern + sigdata->n_patterns, f, c->size))
  280. goto error_usd;
  281. ++sigdata->n_patterns;
  282. break;
  283. case DUMB_ID('I', 'N', 'S', 'T'):
  284. if (dumbfile_seek(f, c->offset, DFS_SEEK_SET))
  285. goto error_usd;
  286. if (it_riff_dsmf_process_sample(
  287. sigdata->sample + sigdata->n_samples, f, c->size))
  288. goto error_usd;
  289. ++sigdata->n_samples;
  290. break;
  291. }
  292. }
  293. if (_dumb_it_fix_invalid_orders(sigdata) < 0) {
  294. _dumb_it_unload_sigdata(sigdata);
  295. return NULL;
  296. }
  297. return sigdata;
  298. error_usd:
  299. _dumb_it_unload_sigdata(sigdata);
  300. goto error;
  301. error_sd:
  302. free(sigdata);
  303. error:
  304. return NULL;
  305. }
  306. DUH *dumb_read_riff_dsmf(DUMBFILE *f, struct riff *stream) {
  307. sigdata_t *sigdata;
  308. DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
  309. sigdata = it_riff_dsmf_load_sigdata(f, stream);
  310. if (!sigdata)
  311. return NULL;
  312. {
  313. const char *tag[2][2];
  314. tag[0][0] = "TITLE";
  315. tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
  316. tag[1][0] = "FORMAT";
  317. tag[1][1] = "RIFF DSMF";
  318. return make_duh(-1, 2, (const char *const(*)[2])tag, 1, &descptr,
  319. &sigdata);
  320. }
  321. }