All MIDI data is stored in a buffer instead of directly written from
[ahxm.git] / ss_input.c
blob09494ae964ec8e3c237b191cd4593ec24bba9411
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2005 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 "annhell.h"
34 /*******************
35 Data
36 ********************/
38 /*******************
39 Code
40 ********************/
42 static int fget16(FILE * f)
43 /* Reads a 16 bit integer from a file in big endian byte ordering */
45 int c;
47 c=fgetc(f);
48 c += (fgetc(f) * 256);
50 return(c);
54 static int fget32(FILE * f)
55 /* Reads a 32 bit integer from a file in big endian byte ordering */
57 int c;
59 c=fgetc(f);
60 c += (fgetc(f) * 256);
61 c += (fgetc(f) * 65536);
62 c += (fgetc(f) * 16777216);
64 return(c);
68 static float load_sample(FILE * f, int bits, int sign)
69 /* loads one sample from a file */
71 int s;
73 /* Caution: no error condition is checked */
75 if(bits == 8)
77 s=fgetc(f) - 128;
78 s <<= 8;
80 else
82 if(!sign)
83 s=fget16(f) - 32768;
84 else
85 s=(short int)fget16(f);
88 return((float) s);
92 static void load_pcm_wave(FILE * f, int bits, int sign, struct ss_wave * w)
93 /* loads an interleaved stream from a file */
95 int n, i;
96 double m;
98 /* fills the channels */
99 for(m=0;m < w->size;m++)
101 i=(int) m;
103 for(n=0;n < w->n_channels;n++)
104 w->wave[n][i]=load_sample(f, bits, sign);
110 * ss_load_wav_file - Loads a file in .WAV format.
111 * @file: name of the file
112 * @base_freq: base frequency
113 * @min_freq: minimum frequency
114 * @max_freq: maximum frequency
115 * @loop_start: frame number of loop start (-1, no loop)
116 * @loop_end: frame number of loop end (-1, end of wave)
118 * Loads a file in .WAV format.
120 struct ss_wave * ss_load_wav_file(char * file,
121 double base_freq, double min_freq, double max_freq,
122 double loop_start, double loop_end)
124 FILE * f;
125 char dummydata[256];
126 int rlen, flen;
127 short int b_per_sec, n_channels;
128 char riffid[5], waveid[5], fmtid[5], dataid[5];
129 double size;
130 int s_rate, bits;
131 struct ss_wave * w;
133 if((f=path_fopen(file, "r")) == NULL)
134 return(NULL);
136 fread(riffid, 1, 4, f);
137 riffid[4] = 0;
138 fread(&rlen, 1, 4, f);
139 fread(waveid, 1, 4, f);
140 waveid[4] = 0;
142 if(strcmp(waveid,"WAVE"))
144 fclose(f);
145 return(NULL);
148 fread(fmtid, 1, 4, f);
149 fmtid[4] = 0;
150 flen=fget32(f);
152 if(flen > 240)
153 flen=240;
155 if(fget16(f) != 1)
157 /* wicked compressed format? fail */
158 fclose(f);
159 return(NULL);
162 n_channels=fget16(f);
163 s_rate=fget32(f);
164 b_per_sec=fget32(f);
166 bits=fget16(f) / n_channels;
167 bits *= 8;
169 fread(dummydata, 1, (size_t)flen - 14, f);
170 fread(dataid, 1, 4, f);
171 dataid[4] = 0;
173 size=(double) fget32(f);
174 if(bits == 16) size /= 2;
175 size /= (double) n_channels;
177 if((w=ss_alloc_wave(size, n_channels, s_rate)) != NULL)
179 w->base_freq=base_freq;
180 w->min_freq=min_freq;
181 w->max_freq=max_freq;
183 w->loop_start=loop_start;
185 if(loop_end < 0)
186 w->loop_end=size;
187 else
188 w->loop_end=loop_end;
190 load_pcm_wave(f, bits, 1, w);
193 fclose(f);
195 return(w);
200 * ss_load_pat_file - Loads an instrument in .PAT format.
201 * @i: The instrument
202 * @filename: filename holding the instrument
204 * Loads data from a Gravis Ultrasound patch (.PAT) format and
205 * stores it as layers for an instrument.
207 * Returns -100 if the file could not be read, -101 or -102
208 * if the file is not recognized as a .PAT file, or 0 if
209 * everything went OK.
211 int ss_load_pat_file(struct ss_ins * i, char * file)
213 FILE * f;
214 char buffer[512];
215 int m, n, o;
216 int n_layers;
217 int flags, bits, sign, loop, pingpong;
218 struct ss_wave * w;
220 if((f=path_fopen(file, "r")) == NULL)
221 return(-100);
223 /* read signatures */
224 fread(buffer, 12, 1, f);
225 if(strcmp(buffer, "GF1PATCH110") != 0)
227 fclose(f);
228 return(-101);
231 fread(buffer, 10, 1, f);
232 if(strcmp(buffer, "ID#000002") != 0)
234 fclose(f);
235 return(-102);
238 /* skip description */
239 fread(buffer, 65, 1, f);
241 /* ignore volume */
242 fget16(f);
244 /* skip */
245 fread(buffer, 109, 1, f);
247 /* # of layers */
248 n_layers=fgetc(f);
250 /* skip */
251 fread(buffer, 40, 1, f);
253 for(n=0;n < n_layers;n++)
255 int size, s_rate;
256 double loop_start, loop_end;
257 double min_freq, max_freq, base_freq;
259 /* layer name */
260 fread(buffer, 8, 1, f);
262 size=(double)fget32(f);
263 loop_start=(double)fget32(f);
264 loop_end=(double)fget32(f);
265 s_rate=fget16(f);
267 min_freq=((double)fget32(f)) / 1000.0;
268 max_freq=((double)fget32(f)) / 1000.0;
269 base_freq=((double)fget32(f)) / 1000.0;
271 if(base_freq < 0)
272 break;
274 /* ignore fine-tune */
275 fget16(f);
277 /* ignore pan position */
278 fgetc(f);
280 /* skip envelope rate, value, tremolo and vibrato */
281 fread(buffer, 18, 1, f);
283 flags=fgetc(f);
285 bits=flags & 0x01 ? 16 : 8;
286 sign=flags & 0x02 ? 0 : 1;
287 loop=flags & 0x04 ? 1 : 0;
288 pingpong=flags & 0x08 ? 1 : 0;
290 if(bits == 16)
292 size /= 2;
293 loop_start /= 2;
294 loop_end /= 2;
297 /* skip frequency scale data */
298 fget16(f); fget16(f);
300 /* skip reserved */
301 fread(buffer, 36, 1, f);
303 if((w=ss_alloc_wave(size, 1, s_rate)) == NULL)
304 break;
306 /* set the rest of values */
307 w->loop_start=loop_start;
308 w->loop_end=loop_end;
309 w->base_freq=base_freq;
310 w->min_freq=min_freq;
311 w->max_freq=max_freq;
313 /* load the wave */
314 load_pcm_wave(f, bits, sign, w);
316 if(pingpong && loop)
318 int loop_size;
319 float * ptr;
321 /* if ping-pong, realloc space for a reverse
322 version of the loop */
323 loop_size=(int)(loop_end - loop_start);
325 ptr=(float *) malloc((size + loop_size + 1)
326 * sizeof(float));
328 /* transfer start and loop */
329 for(m=0;m <= (int)loop_end;m++)
330 ptr[m]=w->wave[0][m];
332 /* transfer a reversed version of the loop */
333 for(o=m - 1;o >= loop_start;o--,m++)
334 ptr[m]=w->wave[0][o];
336 /* transfer the end */
337 for(o=loop_end + 1;o < size;o++,m++)
338 ptr[m]=w->wave[0][o];
340 w->loop_end += (double) loop_size;
341 w->size += (double) loop_size;
343 /* free and swap */
344 free(w->wave[0]);
345 w->wave[0]=ptr;
348 if(loop == 0) w->loop_start=-1;
350 /* finally add layer to instrument */
351 ss_ins_add_layer(i, w);
354 fclose(f);
355 return(0);