3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2006 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
38 /* maximum page size */
39 int ss_page_size
= 441000;
45 static int fget16(FILE * f
)
46 /* Reads a 16 bit integer from a file in big endian byte ordering */
51 c
+= (fgetc(f
) * 256);
57 static int fget32(FILE * f
)
58 /* Reads a 32 bit integer from a file in big endian byte ordering */
63 c
+= (fgetc(f
) * 256);
64 c
+= (fgetc(f
) * 65536);
65 c
+= (fgetc(f
) * 16777216);
71 static sample_t
load_sample(FILE * f
, int bits
, int sign
)
72 /* loads one sample from a file */
76 /* if on eof, return silence */
77 if(feof(f
)) return(0);
87 s
= fget16(f
) - 32768;
89 s
= (short int)fget16(f
);
92 return(((sample_t
) s
) / 32768.0);
96 void load_pcm_wave(FILE * f
, struct ss_wave
* w
)
97 /* loads an interleaved stream from a file */
101 /* fills the channels */
102 for(m
= 0;m
< w
->p_size
;m
++)
104 for(n
= 0;n
< w
->n_channels
;n
++)
105 w
->wave
[n
][m
] = load_sample(f
, w
->bits
, w
->sign
);
111 * ss_load_wav_file - Loads a file in .WAV format.
112 * @file: name of the file
113 * @base_freq: base frequency
114 * @min_freq: minimum frequency
115 * @max_freq: maximum frequency
116 * @loop_start: frame number of loop start (-1, no loop)
117 * @loop_end: frame number of loop end (-1, end of wave)
118 * @first_channel: first channel to start spreading
119 * @skip_channels: channels to skip when spreading
121 * Loads a file in .WAV format.
123 struct ss_wave
* ss_load_wav_file(char * file
,
124 double base_freq
, double min_freq
, double max_freq
,
125 double loop_start
, double loop_end
,
126 int first_channel
, int skip_channels
)
131 short int b_per_sec
, n_channels
;
132 char riffid
[5], waveid
[5], fmtid
[5], dataid
[5];
138 /* find the file in the library path */
139 if((file
= libpath_locate(file
)) == NULL
)
143 if((file
= transconv(file
, ".wav", "ahxm")) == NULL
)
146 if((f
= fopen(file
, "r")) == NULL
)
149 fread(riffid
, 1, 4, f
);
151 fread(&rlen
, 1, 4, f
);
152 fread(waveid
, 1, 4, f
);
155 if(strcmp(waveid
,"WAVE"))
161 fread(fmtid
, 1, 4, f
);
170 /* wicked compressed format? fail */
175 n_channels
= fget16(f
);
177 b_per_sec
= fget32(f
);
179 bits
= fget16(f
) / n_channels
;
182 fread(dummydata
, 1, (size_t)flen
- 14, f
);
183 fread(dataid
, 1, 4, f
);
186 size
= (double) fget32(f
);
187 if(bits
== 16) 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
)
194 w
->base_freq
= base_freq
;
195 w
->min_freq
= min_freq
;
196 w
->max_freq
= max_freq
;
198 w
->loop_start
= loop_start
;
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
);
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
;
226 * ss_load_pat_file - Loads an instrument in .PAT format.
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
, char * file
)
243 int flags
, bits
, sign
, loop
, pingpong
;
246 if((f
= libpath_fopen(file
, "r")) == NULL
)
249 /* read signatures */
250 fread(buffer
, 12, 1, f
);
251 if(strcmp(buffer
, "GF1PATCH110") != 0)
257 fread(buffer
, 10, 1, f
);
258 if(strcmp(buffer
, "ID#000002") != 0)
264 /* skip description */
265 fread(buffer
, 65, 1, f
);
271 fread(buffer
, 109, 1, f
);
277 fread(buffer
, 40, 1, f
);
279 for(n
= 0;n
< n_layers
;n
++)
282 double loop_start
, loop_end
;
283 double min_freq
, max_freq
, base_freq
;
286 fread(buffer
, 8, 1, f
);
288 size
= (double)fget32(f
);
289 loop_start
= (double)fget32(f
);
290 loop_end
= (double)fget32(f
);
293 min_freq
= ((double)fget32(f
)) / 1000.0;
294 max_freq
= ((double)fget32(f
)) / 1000.0;
295 base_freq
= ((double)fget32(f
)) / 1000.0;
300 /* ignore fine-tune */
303 /* ignore pan position */
306 /* skip envelope rate, value, tremolo and vibrato */
307 fread(buffer
, 18, 1, f
);
311 bits
= flags
& 0x01 ? 16 : 8;
312 sign
= flags
& 0x02 ? 0 : 1;
313 loop
= flags
& 0x04 ? 1 : 0;
314 pingpong
= flags
& 0x08 ? 1 : 0;
323 /* skip frequency scale data */
324 fget16(f
); fget16(f
);
327 fread(buffer
, 36, 1, f
);
329 if((w
= ss_alloc_wave(size
, 1, s_rate
, -1)) == NULL
)
332 /* set the rest of values */
333 w
->loop_start
= loop_start
;
334 w
->loop_end
= loop_end
;
335 w
->base_freq
= base_freq
;
336 w
->min_freq
= min_freq
;
337 w
->max_freq
= max_freq
;
350 /* if ping-pong, realloc space for a reverse
351 version of the loop */
352 loop_size
= (int)(loop_end
- loop_start
);
354 ptr
= (sample_t
*) malloc((size
+ loop_size
+ 1)
357 /* transfer start and loop */
358 for(m
= 0;m
<= (int)loop_end
;m
++)
359 ptr
[m
] = w
->wave
[0][m
];
361 /* transfer a reversed version of the loop */
362 for(o
= m
- 1;o
>= loop_start
;o
--, m
++)
363 ptr
[m
] = w
->wave
[0][o
];
365 /* transfer the end */
366 for(o
= loop_end
+ 1;o
< size
;o
++, m
++)
367 ptr
[m
] = w
->wave
[0][o
];
369 w
->loop_end
+= (double) loop_size
;
370 w
->size
+= (double) loop_size
;
371 w
->p_size
+= loop_size
;
378 if(loop
== 0) w
->loop_start
= -1;
380 /* finally add layer to instrument */
381 ss_ins_add_layer(i
, w
);