Added an abstract to mp_doccer documents.
[ahxm.git] / ss_input.c
blob1b9c7c445ac189b76f305e95e0060b9024d04588
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"
34 /*******************
35 Data
36 ********************/
38 /* maximum page size */
39 int ss_page_size = 441000;
41 /*******************
42 Code
43 ********************/
45 static int fget16(FILE * f)
46 /* Reads a 16 bit integer from a file in big endian byte ordering */
48 int c;
50 c = fgetc(f);
51 c += (fgetc(f) * 256);
53 return c;
57 static int fget32(FILE * f)
58 /* Reads a 32 bit integer from a file in big endian byte ordering */
60 int c;
62 c = fgetc(f);
63 c += (fgetc(f) * 256);
64 c += (fgetc(f) * 65536);
65 c += (fgetc(f) * 16777216);
67 return c;
71 static sample_t load_sample(FILE * f, int bits, int sign)
72 /* loads one sample from a file */
74 int s;
76 /* if on eof, return silence */
77 if (feof(f))
78 return 0;
80 if (bits == 8) {
81 s = fgetc(f) - 128;
82 s <<= 8;
84 else {
85 if (!sign)
86 s = fget16(f) - 32768;
87 else
88 s = (short int) fget16(f);
91 return ((sample_t) s) / 32768.0;
95 void load_pcm_wave(FILE * f, struct ss_wave *w)
96 /* loads an interleaved stream from a file */
98 int n, m;
100 /* fills the channels */
101 for (m = 0; m < w->p_size; m++) {
102 for (n = 0; n < w->n_channels; n++)
103 w->wave[n][m] = load_sample(f, w->bits, w->sign);
109 * ss_load_wav_file - Loads a file in .WAV format.
110 * @file: name of the file
111 * @base_freq: base frequency
112 * @min_freq: minimum frequency
113 * @max_freq: maximum frequency
114 * @loop_start: frame number of loop start (-1, no loop)
115 * @loop_end: frame number of loop end (-1, end of wave)
116 * @first_channel: first channel to start spreading
117 * @skip_channels: channels to skip when spreading
119 * Loads a file in .WAV format.
121 struct ss_wave *ss_load_wav_file(const char *file,
122 double base_freq, double min_freq, double max_freq,
123 double loop_start, double loop_end,
124 int first_channel, int skip_channels)
126 FILE *f;
127 char dummydata[256];
128 int rlen, flen;
129 short int b_per_sec, n_channels;
130 char riffid[5], waveid[5], fmtid[5], dataid[5];
131 double size;
132 int s_rate, bits;
133 struct ss_wave *w;
134 int p;
136 if (*file == '|')
137 file = transconv_pipe(file + 1, ".wav", "ahxm");
138 else {
139 /* find the file in the library path */
140 if ((file = libpath_locate(file)) == NULL)
141 return NULL;
143 /* try converting */
144 if ((file = transconv(file, ".wav", "ahxm")) == NULL)
145 return NULL;
148 if ((f = fopen(file, "r")) == NULL)
149 return NULL;
151 fread(riffid, 1, 4, f);
152 riffid[4] = 0;
153 fread(&rlen, 1, 4, f);
154 fread(waveid, 1, 4, f);
155 waveid[4] = 0;
157 if (strcmp(waveid, "WAVE")) {
158 fclose(f);
159 return NULL;
162 fread(fmtid, 1, 4, f);
163 fmtid[4] = 0;
164 flen = fget32(f);
166 if (flen > 240)
167 flen = 240;
169 if (fget16(f) != 1) {
170 /* wicked compressed format? fail */
171 fclose(f);
172 return NULL;
175 n_channels = fget16(f);
176 s_rate = fget32(f);
177 b_per_sec = fget32(f);
179 bits = fget16(f) / n_channels;
180 bits *= 8;
182 fread(dummydata, 1, (size_t) flen - 14, f);
183 fread(dataid, 1, 4, f);
184 dataid[4] = 0;
186 size = (double) fget32(f);
187 if (bits == 16)
188 size /= 2;
189 size /= (double) n_channels;
191 p = size > ss_page_size ? ss_page_size : size;
193 if ((w = ss_alloc_wave(size, n_channels, s_rate, p)) != NULL) {
194 w->base_freq = base_freq;
195 w->min_freq = min_freq;
196 w->max_freq = max_freq;
198 w->loop_start = loop_start;
200 if (loop_end < 0)
201 w->loop_end = size;
202 else
203 w->loop_end = loop_end;
205 w->first_channel = first_channel;
206 w->skip_channels = skip_channels;
208 /* fill the info needed for paging */
209 w->filename = strdup(file);
210 w->f_pos = ftell(f);
211 w->bits = bits;
212 w->sign = 1;
214 /* set the page offset further the end, to
215 force a page reading the first time it's used */
216 w->p_offset = (int) size;
219 fclose(f);
221 return w;
226 * ss_load_pat_file - Loads an instrument in .PAT format.
227 * @i: The instrument
228 * @filename: filename holding the instrument
230 * Loads data from a Gravis Ultrasound patch (.PAT) format and
231 * stores it as layers for an instrument.
233 * Returns -100 if the file could not be read, -101 or -102
234 * if the file is not recognized as a .PAT file, or 0 if
235 * everything went OK.
237 int ss_load_pat_file(struct ss_ins *i, const char *file)
239 FILE *f;
240 char buffer[512];
241 int m, n, o;
242 int n_layers;
243 int flags, bits, sign, loop, pingpong;
244 struct ss_wave *w;
246 if ((f = libpath_fopen(file, "r")) == NULL)
247 return -100;
249 /* read signatures */
250 fread(buffer, 12, 1, f);
251 if (strcmp(buffer, "GF1PATCH110") != 0) {
252 fclose(f);
253 return -101;
256 fread(buffer, 10, 1, f);
257 if (strcmp(buffer, "ID#000002") != 0) {
258 fclose(f);
259 return -102;
262 /* skip description */
263 fread(buffer, 65, 1, f);
265 /* ignore volume */
266 fget16(f);
268 /* skip */
269 fread(buffer, 109, 1, f);
271 /* # of layers */
272 n_layers = fgetc(f);
274 /* skip */
275 fread(buffer, 40, 1, f);
277 for (n = 0; n < n_layers; n++) {
278 int size, s_rate;
279 double loop_start, loop_end;
280 double min_freq, max_freq, base_freq;
282 /* layer name */
283 fread(buffer, 8, 1, f);
285 size = (double) fget32(f);
286 loop_start = (double) fget32(f);
287 loop_end = (double) fget32(f);
288 s_rate = fget16(f);
290 min_freq = ((double) fget32(f)) / 1000.0;
291 max_freq = ((double) fget32(f)) / 1000.0;
292 base_freq = ((double) fget32(f)) / 1000.0;
294 if (base_freq < 0)
295 break;
297 /* ignore fine-tune */
298 fget16(f);
300 /* ignore pan position */
301 fgetc(f);
303 /* skip envelope rate, value, tremolo and vibrato */
304 fread(buffer, 18, 1, f);
306 flags = fgetc(f);
308 bits = flags & 0x01 ? 16 : 8;
309 sign = flags & 0x02 ? 0 : 1;
310 loop = flags & 0x04 ? 1 : 0;
311 pingpong = flags & 0x08 ? 1 : 0;
313 if (bits == 16) {
314 size /= 2;
315 loop_start /= 2;
316 loop_end /= 2;
319 /* skip frequency scale data */
320 fget16(f);
321 fget16(f);
323 /* skip reserved */
324 fread(buffer, 36, 1, f);
326 if ((w = ss_alloc_wave(size, 1, s_rate, -1)) == NULL)
327 break;
329 /* set the rest of values */
330 w->loop_start = loop_start;
331 w->loop_end = loop_end;
332 w->base_freq = base_freq;
333 w->min_freq = min_freq;
334 w->max_freq = max_freq;
335 w->bits = bits;
336 w->sign = sign;
338 /* load the wave */
339 ss_prepare_wave(w);
340 load_pcm_wave(f, w);
342 if (pingpong && loop) {
343 int loop_size;
344 sample_t *ptr;
346 /* if ping-pong, realloc space for a reverse
347 version of the loop */
348 loop_size = (int) (loop_end - loop_start);
350 ptr = (sample_t *) malloc((size + loop_size + 1)
351 * sizeof(sample_t));
353 /* transfer start and loop */
354 for (m = 0; m <= (int) loop_end; m++)
355 ptr[m] = w->wave[0][m];
357 /* transfer a reversed version of the loop */
358 for (o = m - 1; o >= loop_start; o--, m++)
359 ptr[m] = w->wave[0][o];
361 /* transfer the end */
362 for (o = loop_end + 1; o < size; o++, m++)
363 ptr[m] = w->wave[0][o];
365 w->loop_end += (double) loop_size;
366 w->size += (double) loop_size;
367 w->p_size += loop_size;
369 /* free and swap */
370 free(w->wave[0]);
371 w->wave[0] = ptr;
374 if (loop == 0)
375 w->loop_start = -1;
377 /* finally add layer to instrument */
378 ss_ins_add_layer(i, w);
381 fclose(f);
382 return 0;
386 /* Soundfont support */
388 #define CID(a,b,c,d) (((d)<<24)+((c)<<16)+((b)<<8)+((a)))
390 #define CID_RIFF CID('R','I','F','F')
391 #define CID_LIST CID('L','I','S','T')
392 #define CID_INFO CID('I','N','F','O')
393 #define CID_sdta CID('s','d','t','a')
394 #define CID_snam CID('s','n','a','m')
395 #define CID_smpl CID('s','m','p','l')
396 #define CID_pdta CID('p','d','t','a')
397 #define CID_phdr CID('p','h','d','r')
398 #define CID_pbag CID('p','b','a','g')
399 #define CID_pmod CID('p','m','o','d')
400 #define CID_pgen CID('p','g','e','n')
401 #define CID_inst CID('i','n','s','t')
402 #define CID_ibag CID('i','b','a','g')
403 #define CID_imod CID('i','m','o','d')
404 #define CID_igen CID('i','g','e','n')
405 #define CID_shdr CID('s','h','d','r')
406 #define CID_ifil CID('i','f','i','l')
407 #define CID_isng CID('i','s','n','g')
408 #define CID_irom CID('i','r','o','m')
409 #define CID_iver CID('i','v','e','r')
410 #define CID_INAM CID('I','N','A','M')
411 #define CID_IPRD CID('I','P','R','D')
412 #define CID_ICOP CID('I','C','O','P')
413 #define CID_sfbk CID('s','f','b','k')
414 #define CID_ICRD CID('I','C','R','D')
415 #define CID_IENG CID('I','E','N','G')
416 #define CID_ICMT CID('I','C','M','T')
417 #define CID_ISFT CID('I','S','F','T')
419 #define MAX_LAYERS 128
421 static int base_notes[MAX_LAYERS];
422 static int min_notes[MAX_LAYERS];
423 static int max_notes[MAX_LAYERS];
424 static int sampleids[MAX_LAYERS];
426 #define CALC_END(s,f) (ftell(f) + (s) + ((s) & 1))
429 int ss_load_sf2_file(struct ss_ins *i, const char *file, const char *iname)
431 FILE *f;
432 int n, num;
433 int cid, fsize, fend;
434 int sample_offset = 0;
435 int ibag_s = -1, ibag_e = -1;
436 int igen_s = -1, igen_e = -1;
437 char tmp[21];
438 int i_layers = 0;
440 if ((f = libpath_fopen(file, "r")) == NULL)
441 return -100;
443 if ((cid = fget32(f)) != CID_RIFF)
444 return -101;
446 fsize = fget32(f);
447 fend = CALC_END(fsize, f);
449 if ((cid = fget32(f)) != CID_sfbk)
450 return -102;
452 while (ftell(f) < fend) {
453 int csize, cend;
455 cid = fget32(f);
456 csize = fget32(f);
457 cend = CALC_END(csize, f);
459 switch (cid) {
460 case CID_LIST:
462 cid = fget32(f);
464 while (ftell(f) < cend) {
465 int scid, ssize, send;
467 scid = fget32(f);
468 ssize = fget32(f);
469 send = CALC_END(ssize, f);
471 switch (cid) {
472 case CID_INFO:
474 switch (scid) {
475 case CID_ifil:
477 if (fget16(f) < 2)
478 return -103;
479 fget16(f);
480 break;
482 case CID_INAM:
483 case CID_irom:
484 case CID_ICRD:
485 case CID_IENG:
486 case CID_IPRD:
487 case CID_ICOP:
488 case CID_ISFT:
489 /* misc. data (ignored) */
490 break;
493 fseek(f, send, SEEK_SET);
494 break;
496 case CID_pdta:
498 switch (scid) {
499 case CID_phdr:
500 /* preset headers */
501 break;
503 case CID_pbag:
504 /* preset index list */
505 break;
507 case CID_pgen:
508 /* preset generator list */
509 break;
511 case CID_inst:
512 /* instrument names */
513 num = ssize / 22;
515 for (n = 0; n < num; n++) {
516 int i;
518 fread(tmp, 20, 1, f);
519 tmp[20] = '\0';
521 /* trim spaces */
522 for (i = 20; i && tmp[i] == '\0'; i--);
523 for (; i && tmp[i] == ' '; i--)
524 tmp[i] = '\0';
526 i = fget16(f);
528 /* if ibag_s is set and ibag_e isn't,
529 pick this as the end */
530 if (ibag_s != -1 && ibag_e == -1)
531 ibag_e = i;
533 if (iname != NULL) {
534 if (strcmp(iname, tmp) == 0)
535 ibag_s = i;
537 else {
538 printf("[%s]\n", tmp);
542 break;
544 case CID_ibag:
546 num = ssize / 4;
548 for (n = 0; n < num; n++) {
549 int igen = fget16(f);
550 fget16(f);
552 /* pick start of igen */
553 if (n == ibag_s)
554 igen_s = igen;
556 /* pick end of igen */
557 if (n == ibag_e)
558 igen_e = igen;
561 break;
563 case CID_igen:
565 num = ssize / 4;
567 /* init layers */
568 for (n = 0; n < MAX_LAYERS; n++) {
569 base_notes[n] = -1;
570 min_notes[n] = 0;
571 max_notes[n] = 127;
574 for (n = 0; n < num; n++) {
575 int op = fget16(f);
576 int am = fget16(f);
578 if (n >= igen_s && n < igen_e) {
580 if (op == 58) /* overridingRootKey */
581 base_notes[i_layers] = am;
583 if (op == 43) { /* keyRange */
584 min_notes[i_layers] = am & 0xff;
585 max_notes[i_layers] = am >> 8;
588 if (op == 53) { /* sampleID */
589 sampleids[i_layers++] = am;
594 break;
596 case CID_shdr:
597 /* sample headers */
598 num = ssize / 46;
600 for (n = 0; n < num; n++) {
601 int m;
602 int start, end;
603 int loop_start, loop_end;
604 int sample_rate, base_note;
605 int sample_type;
607 fread(tmp, 20, 1, f);
608 tmp[20] = '\0';
610 start = fget32(f);
611 end = fget32(f);
612 loop_start = fget32(f);
613 loop_end = fget32(f);
614 sample_rate = fget32(f);
615 base_note = fgetc(f);
616 fgetc(f); /* correction */
617 fget16(f); /* sample_link */
618 sample_type = fget16(f);
620 for (m = 0; m < i_layers; m++) {
621 struct ss_wave *w;
622 int t;
624 if (sampleids[m] != n)
625 continue;
627 /* create wave! */
628 if (base_notes[m] != -1)
629 base_note = base_notes[m];
631 if (verbose >= 2) {
632 printf("SF2 Sample:\t[%s]\n", tmp);
633 printf("start/end:\t%d/%d (%d)\n", start, end, end - start);
634 printf("loop:\t\t%d/%d\n", loop_start, loop_end);
635 printf("rate/stype:\t%d/%d\n", sample_rate, sample_type);
636 printf("notes:\t\t%d/%d/%d\n",
637 min_notes[m], base_note, max_notes[m]);
640 w = ss_alloc_wave(
641 end - start, 1,
642 sample_rate, -1
645 w->loop_start = loop_start - start;
646 w->loop_end = loop_end - start;
647 w->base_freq = ss_note_frequency(base_note);
648 w->min_freq = ss_note_frequency(min_notes[m]);
649 w->max_freq = ss_note_frequency(max_notes[m]);
651 w->bits = 16;
652 w->sign = 1;
654 switch (sample_type) {
655 case 2: /* right */
656 w->first_channel = 1;
657 /* fallthrough */
658 case 4: /* left */
659 w->skip_channels = 1;
660 break;
663 t = ftell(f);
665 fseek(f, sample_offset + (start * 2), SEEK_SET);
667 ss_prepare_wave(w);
668 load_pcm_wave(f, w);
670 fseek(f, t, SEEK_SET);
672 ss_ins_add_layer(i, w);
676 break;
679 fseek(f, send, SEEK_SET);
680 break;
682 case CID_sdta:
684 /* sample info starts here */
685 sample_offset = ftell(f);
687 fseek(f, send, SEEK_SET);
688 break;
690 default:
691 /* unknown chunk */
692 fseek(f, cend, SEEK_SET);
693 break;
697 break;
699 default:
700 fseek(f, cend, SEEK_SET);
701 break;
705 fclose(f);
707 if (iname != NULL && ibag_s == -1)
708 return -104;
710 return 0;