Added 'win32dist' Makefile target.
[ahxm.git] / ss_input.c
blob25ff6fb8d3f35eae4d1a4ec55f28d95bd0c8176c
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2008 Angel Ortega <angel@triptico.com>
6 ss_input.c - Code to load softsynth sounds in different formats
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include "config.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include "ahxm.h"
35 /** data **/
37 /* maximum page size */
38 int ss_page_size = 441000;
41 /** code **/
43 static int fget16(FILE * f)
44 /* Reads a 16 bit integer from a file in big endian byte ordering */
46 int c;
48 c = fgetc(f);
49 c += (fgetc(f) * 256);
51 return c;
55 static int fget32(FILE * f)
56 /* Reads a 32 bit integer from a file in big endian byte ordering */
58 int c;
60 c = fgetc(f);
61 c += (fgetc(f) * 256);
62 c += (fgetc(f) * 65536);
63 c += (fgetc(f) * 16777216);
65 return c;
69 static sample_t load_sample(FILE * f, int bits, int sign)
70 /* loads one sample from a file */
72 int s;
74 /* if on eof, return silence */
75 if (feof(f))
76 return 0;
78 if (bits == 8) {
79 s = fgetc(f) - 128;
80 s <<= 8;
82 else {
83 if (!sign)
84 s = fget16(f) - 32768;
85 else
86 s = (short int) fget16(f);
89 return ((sample_t) s) / 32768.0;
93 void load_pcm_wave(FILE * f, struct ss_wave *w)
94 /* loads an interleaved stream from a file */
96 int n, m;
98 /* fills the channels */
99 for (m = 0; m < w->p_size; m++) {
100 for (n = 0; n < w->n_channels; n++)
101 w->wave[n][m] = load_sample(f, w->bits, w->sign);
107 * ss_load_wav_file - Loads a file in .WAV format.
108 * @file: name of the file
109 * @base_freq: base frequency
110 * @min_freq: minimum frequency
111 * @max_freq: maximum frequency
112 * @loop_start: frame number of loop start (-1, no loop)
113 * @loop_end: frame number of loop end (-1, end of wave)
114 * @first_channel: first channel to start spreading
115 * @skip_channels: channels to skip when spreading
117 * Loads a file in .WAV format.
119 struct ss_wave *ss_load_wav_file(const char *file,
120 double base_freq, double min_freq,
121 double max_freq, double loop_start,
122 double loop_end, int first_channel,
123 int skip_channels)
125 FILE *f;
126 char dummydata[256];
127 int rlen, flen;
128 short int b_per_sec, n_channels;
129 char riffid[5], waveid[5], fmtid[5], dataid[5];
130 double size;
131 int s_rate, bits;
132 struct ss_wave *w;
133 int p;
135 if (*file == '|')
136 file = transconv_pipe(file + 1, ".wav", "ahxm");
137 else {
138 /* find the file in the library path */
139 if ((file = libpath_locate(file)) == NULL)
140 return NULL;
142 /* try converting */
143 if ((file = transconv(file, ".wav", "ahxm")) == NULL)
144 return NULL;
147 if ((f = fopen(file, "rb")) == NULL)
148 return NULL;
150 fread(riffid, 1, 4, f);
151 riffid[4] = 0;
152 fread(&rlen, 1, 4, f);
153 fread(waveid, 1, 4, f);
154 waveid[4] = 0;
156 if (strcmp(waveid, "WAVE")) {
157 fclose(f);
158 return NULL;
161 fread(fmtid, 1, 4, f);
162 fmtid[4] = 0;
163 flen = fget32(f);
165 if (flen > 240)
166 flen = 240;
168 if (fget16(f) != 1) {
169 /* wicked compressed format? fail */
170 fclose(f);
171 return NULL;
174 n_channels = fget16(f);
175 s_rate = fget32(f);
176 b_per_sec = fget32(f);
178 bits = fget16(f) / n_channels;
179 bits *= 8;
181 fread(dummydata, 1, (size_t) flen - 14, f);
182 fread(dataid, 1, 4, f);
183 dataid[4] = 0;
185 size = (double) fget32(f);
186 if (bits == 16)
187 size /= 2;
188 size /= (double) n_channels;
190 p = size > ss_page_size ? ss_page_size : size;
192 if ((w = ss_alloc_wave(size, n_channels, s_rate, p)) != NULL) {
193 w->base_freq = base_freq;
194 w->min_freq = min_freq;
195 w->max_freq = max_freq;
197 w->loop_start = loop_start;
199 if (loop_end < 0)
200 w->loop_end = size;
201 else
202 w->loop_end = loop_end;
204 w->first_channel = first_channel;
205 w->skip_channels = skip_channels;
207 /* fill the info needed for paging */
208 w->filename = strdup(file);
209 w->f_pos = ftell(f);
210 w->bits = bits;
211 w->sign = 1;
213 /* set the page offset further the end, to
214 force a page reading the first time it's used */
215 w->p_offset = (int) size;
218 fclose(f);
220 return w;
225 * ss_load_pat_file - Loads an instrument in .PAT format.
226 * @i: The instrument
227 * @filename: filename holding the instrument
229 * Loads data from a Gravis Ultrasound patch (.PAT) format and
230 * stores it as layers for an instrument.
232 * Returns -100 if the file could not be read, -101 or -102
233 * if the file is not recognized as a .PAT file, or 0 if
234 * everything went OK.
236 int ss_load_pat_file(struct ss_ins *i, const char *file)
238 FILE *f;
239 char buffer[512];
240 int m, n, o;
241 int n_layers;
242 int flags, bits, sign, loop, pingpong;
243 struct ss_wave *w;
245 if ((f = libpath_fopen(file, "rb")) == NULL)
246 return -100;
248 /* read signatures */
249 fread(buffer, 12, 1, f);
250 if (strcmp(buffer, "GF1PATCH110") != 0) {
251 fclose(f);
252 return -101;
255 fread(buffer, 10, 1, f);
256 if (strcmp(buffer, "ID#000002") != 0) {
257 fclose(f);
258 return -102;
261 /* skip description */
262 fread(buffer, 65, 1, f);
264 /* ignore volume */
265 fget16(f);
267 /* skip */
268 fread(buffer, 109, 1, f);
270 /* # of layers */
271 n_layers = fgetc(f);
273 /* skip */
274 fread(buffer, 40, 1, f);
276 for (n = 0; n < n_layers; n++) {
277 int size, s_rate;
278 double loop_start, loop_end;
279 double min_freq, max_freq, base_freq;
281 /* layer name */
282 fread(buffer, 8, 1, f);
284 size = (double) fget32(f);
285 loop_start = (double) fget32(f);
286 loop_end = (double) fget32(f);
287 s_rate = fget16(f);
289 min_freq = ((double) fget32(f)) / 1000.0;
290 max_freq = ((double) fget32(f)) / 1000.0;
291 base_freq = ((double) fget32(f)) / 1000.0;
293 if (base_freq < 0)
294 break;
296 /* ignore fine-tune */
297 fget16(f);
299 /* ignore pan position */
300 fgetc(f);
302 /* skip envelope rate, value, tremolo and vibrato */
303 fread(buffer, 18, 1, f);
305 flags = fgetc(f);
307 bits = flags & 0x01 ? 16 : 8;
308 sign = flags & 0x02 ? 0 : 1;
309 loop = flags & 0x04 ? 1 : 0;
310 pingpong = flags & 0x08 ? 1 : 0;
312 if (bits == 16) {
313 size /= 2;
314 loop_start /= 2;
315 loop_end /= 2;
318 /* skip frequency scale data */
319 fget16(f);
320 fget16(f);
322 /* skip reserved */
323 fread(buffer, 36, 1, f);
325 if ((w = ss_alloc_wave(size, 1, s_rate, -1)) == NULL)
326 break;
328 /* set the rest of values */
329 w->loop_start = loop_start;
330 w->loop_end = loop_end;
331 w->base_freq = base_freq;
332 w->min_freq = min_freq;
333 w->max_freq = max_freq;
334 w->bits = bits;
335 w->sign = sign;
337 /* load the wave */
338 ss_prepare_wave(w);
339 load_pcm_wave(f, w);
341 if (pingpong && loop) {
342 int loop_size;
343 sample_t *ptr;
345 /* if ping-pong, realloc space for a reverse
346 version of the loop */
347 loop_size = (int) (loop_end - loop_start);
349 ptr = (sample_t *) malloc((size + loop_size + 1)
350 * sizeof(sample_t));
352 /* transfer start and loop */
353 for (m = 0; m <= (int) loop_end; m++)
354 ptr[m] = w->wave[0][m];
356 /* transfer a reversed version of the loop */
357 for (o = m - 1; o >= loop_start; o--, m++)
358 ptr[m] = w->wave[0][o];
360 /* transfer the end */
361 for (o = loop_end + 1; o < size; o++, m++)
362 ptr[m] = w->wave[0][o];
364 w->loop_end += (double) loop_size;
365 w->size += (double) loop_size;
366 w->p_size += loop_size;
368 /* free and swap */
369 free(w->wave[0]);
370 w->wave[0] = ptr;
373 if (loop == 0)
374 w->loop_start = -1;
376 /* finally add layer to instrument */
377 ss_ins_add_layer(i, w);
380 fclose(f);
381 return 0;
385 /* Soundfont support */
387 #define CID(a,b,c,d) (((d)<<24)+((c)<<16)+((b)<<8)+((a)))
389 #define CID_RIFF CID('R','I','F','F')
390 #define CID_LIST CID('L','I','S','T')
391 #define CID_INFO CID('I','N','F','O')
392 #define CID_sdta CID('s','d','t','a')
393 #define CID_snam CID('s','n','a','m')
394 #define CID_smpl CID('s','m','p','l')
395 #define CID_pdta CID('p','d','t','a')
396 #define CID_phdr CID('p','h','d','r')
397 #define CID_pbag CID('p','b','a','g')
398 #define CID_pmod CID('p','m','o','d')
399 #define CID_pgen CID('p','g','e','n')
400 #define CID_inst CID('i','n','s','t')
401 #define CID_ibag CID('i','b','a','g')
402 #define CID_imod CID('i','m','o','d')
403 #define CID_igen CID('i','g','e','n')
404 #define CID_shdr CID('s','h','d','r')
405 #define CID_ifil CID('i','f','i','l')
406 #define CID_isng CID('i','s','n','g')
407 #define CID_irom CID('i','r','o','m')
408 #define CID_iver CID('i','v','e','r')
409 #define CID_INAM CID('I','N','A','M')
410 #define CID_IPRD CID('I','P','R','D')
411 #define CID_ICOP CID('I','C','O','P')
412 #define CID_sfbk CID('s','f','b','k')
413 #define CID_ICRD CID('I','C','R','D')
414 #define CID_IENG CID('I','E','N','G')
415 #define CID_ICMT CID('I','C','M','T')
416 #define CID_ISFT CID('I','S','F','T')
418 #define MAX_LAYERS 128
420 static int base_notes[MAX_LAYERS];
421 static int min_notes[MAX_LAYERS];
422 static int max_notes[MAX_LAYERS];
423 static int sampleids[MAX_LAYERS];
425 #define CALC_END(s,f) (ftell(f) + (s) + ((s) & 1))
428 int ss_load_sf2_file(struct ss_ins *i, const char *file, const char *iname)
430 FILE *f;
431 int n, num;
432 int cid, fsize, fend;
433 int sample_offset = 0;
434 int ibag_s = -1, ibag_e = -1;
435 int igen_s = -1, igen_e = -1;
436 char tmp[21];
437 int i_layers = 0;
439 if ((f = libpath_fopen(file, "rb")) == NULL)
440 return -100;
442 if ((cid = fget32(f)) != CID_RIFF)
443 return -101;
445 fsize = fget32(f);
446 fend = CALC_END(fsize, f);
448 if ((cid = fget32(f)) != CID_sfbk)
449 return -102;
451 while (ftell(f) < fend) {
452 int csize, cend;
454 cid = fget32(f);
455 csize = fget32(f);
456 cend = CALC_END(csize, f);
458 switch (cid) {
459 case CID_LIST:
461 cid = fget32(f);
463 while (ftell(f) < cend) {
464 int scid, ssize, send;
466 scid = fget32(f);
467 ssize = fget32(f);
468 send = CALC_END(ssize, f);
470 switch (cid) {
471 case CID_INFO:
473 switch (scid) {
474 case CID_ifil:
476 if (fget16(f) < 2)
477 return -103;
478 fget16(f);
479 break;
481 case CID_INAM:
482 case CID_irom:
483 case CID_ICRD:
484 case CID_IENG:
485 case CID_IPRD:
486 case CID_ICOP:
487 case CID_ISFT:
488 /* misc. data (ignored) */
489 break;
492 fseek(f, send, SEEK_SET);
493 break;
495 case CID_pdta:
497 switch (scid) {
498 case CID_phdr:
499 /* preset headers */
500 break;
502 case CID_pbag:
503 /* preset index list */
504 break;
506 case CID_pgen:
507 /* preset generator list */
508 break;
510 case CID_inst:
511 /* instrument names */
512 num = ssize / 22;
514 for (n = 0; n < num; n++) {
515 int i;
517 fread(tmp, 20, 1, f);
518 tmp[20] = '\0';
520 /* trim spaces */
521 for (i = 20; i && tmp[i] == '\0'; i--);
522 for (; i && tmp[i] == ' '; i--)
523 tmp[i] = '\0';
525 i = fget16(f);
527 /* if ibag_s is set and ibag_e isn't,
528 pick this as the end */
529 if (ibag_s != -1 && ibag_e == -1)
530 ibag_e = i;
532 if (iname != NULL) {
533 if (strcmp(iname, tmp) == 0)
534 ibag_s = i;
536 else {
537 printf("[%s]\n", tmp);
541 break;
543 case CID_ibag:
545 num = ssize / 4;
547 for (n = 0; n < num; n++) {
548 int igen = fget16(f);
549 fget16(f);
551 /* pick start of igen */
552 if (n == ibag_s)
553 igen_s = igen;
555 /* pick end of igen */
556 if (n == ibag_e)
557 igen_e = igen;
560 break;
562 case CID_igen:
564 num = ssize / 4;
566 /* init layers */
567 for (n = 0; n < MAX_LAYERS; n++) {
568 base_notes[n] = -1;
569 min_notes[n] = 0;
570 max_notes[n] = 127;
573 for (n = 0; n < num; n++) {
574 int op = fget16(f);
575 int am = fget16(f);
577 if (n >= igen_s && n < igen_e) {
579 if (op == 58) /* overridingRootKey */
580 base_notes[i_layers] = am;
582 if (op == 43) { /* keyRange */
583 min_notes[i_layers] = am & 0xff;
584 max_notes[i_layers] = am >> 8;
587 if (op == 53) { /* sampleID */
588 sampleids[i_layers++] = am;
593 break;
595 case CID_shdr:
596 /* sample headers */
597 num = ssize / 46;
599 for (n = 0; n < num; n++) {
600 int m;
601 int start, end;
602 int loop_start, loop_end;
603 int sample_rate, base_note;
604 int sample_type;
606 fread(tmp, 20, 1, f);
607 tmp[20] = '\0';
609 start = fget32(f);
610 end = fget32(f);
611 loop_start = fget32(f);
612 loop_end = fget32(f);
613 sample_rate = fget32(f);
614 base_note = fgetc(f);
615 fgetc(f); /* correction */
616 fget16(f); /* sample_link */
617 sample_type = fget16(f);
619 for (m = 0; m < i_layers; m++) {
620 struct ss_wave *w;
621 int t;
623 if (sampleids[m] != n)
624 continue;
626 /* create wave! */
627 if (base_notes[m] != -1)
628 base_note = base_notes[m];
630 if (verbose >= 2) {
631 printf("SF2 Sample:\t[%s]\n", tmp);
632 printf("start/end:\t%d/%d (%d)\n",
633 start, end, end - start);
634 printf("loop:\t\t%d/%d\n", loop_start,
635 loop_end);
636 printf("rate/stype:\t%d/%d\n",
637 sample_rate, sample_type);
638 printf("notes:\t\t%d/%d/%d\n",
639 min_notes[m], base_note,
640 max_notes[m]);
643 w = ss_alloc_wave(end - start, 1,
644 sample_rate, -1);
646 w->loop_start = loop_start - start;
647 w->loop_end = loop_end - start;
648 w->base_freq =
649 ss_note_frequency(base_note);
650 w->min_freq =
651 ss_note_frequency(min_notes[m]);
652 w->max_freq =
653 ss_note_frequency(max_notes[m]);
655 w->bits = 16;
656 w->sign = 1;
658 switch (sample_type) {
659 case 2: /* right */
660 w->first_channel = 1;
661 /* fallthrough */
662 case 4: /* left */
663 w->skip_channels = 1;
664 break;
667 t = ftell(f);
669 fseek(f, sample_offset + (start * 2),
670 SEEK_SET);
672 ss_prepare_wave(w);
673 load_pcm_wave(f, w);
675 fseek(f, t, SEEK_SET);
677 ss_ins_add_layer(i, w);
681 break;
684 fseek(f, send, SEEK_SET);
685 break;
687 case CID_sdta:
689 /* sample info starts here */
690 sample_offset = ftell(f);
692 fseek(f, send, SEEK_SET);
693 break;
695 default:
696 /* unknown chunk */
697 fseek(f, cend, SEEK_SET);
698 break;
702 break;
704 default:
705 fseek(f, cend, SEEK_SET);
706 break;
710 fclose(f);
712 if (iname != NULL && ibag_s == -1)
713 return -104;
715 return 0;