If 'interactive' mode is selected, an error message is printed,
[ahxm.git] / ss_input.c
blob439d37aad3c228c04684682bf93ee314f53839c8
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>
31 #include <unistd.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
35 #include "annhell.h"
37 /*******************
38 Data
39 ********************/
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 float load_sample(FILE * f, int bits, int sign)
72 /* loads one sample from a file */
74 int s;
76 /* Caution: no error condition is checked */
78 if(bits == 8)
80 s=fgetc(f) - 128;
81 s <<= 8;
83 else
85 if(!sign)
86 s=fget16(f) - 32768;
87 else
88 s=(short int)fget16(f);
91 return((float) s);
95 static void load_pcm_wave(FILE * f, int bits, int sign, struct ss_wave * w)
96 /* loads an interleaved stream from a file */
98 int n, i;
99 double m;
101 /* fills the channels */
102 for(m=0;m < w->size;m++)
104 i=(int) m;
106 for(n=0;n < w->n_channels;n++)
107 w->wave[n][i]=load_sample(f, bits, sign);
113 * ss_load_wav_file - Loads a file in .WAV format.
114 * @file: name of the file
115 * @base_freq: base frequency
116 * @min_freq: minimum frequency
117 * @max_freq: maximum frequency
118 * @loop_start: frame number of loop start (-1, no loop)
119 * @loop_end: frame number of loop end (-1, end of wave)
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)
127 FILE * f;
128 char dummydata[256];
129 int rlen, flen;
130 short int b_per_sec, n_channels;
131 char riffid[5], waveid[5], fmtid[5], dataid[5];
132 double size;
133 int s_rate, bits;
134 struct ss_wave * w;
136 if((f=path_fopen(file, "r")) == NULL)
137 return(NULL);
139 fread(riffid, 1, 4, f);
140 riffid[4] = 0;
141 fread(&rlen, 1, 4, f);
142 fread(waveid, 1, 4, f);
143 waveid[4] = 0;
145 if(strcmp(waveid,"WAVE"))
147 fclose(f);
148 return(NULL);
151 fread(fmtid, 1, 4, f);
152 fmtid[4] = 0;
153 flen=fget32(f);
155 if(flen > 240)
156 flen=240;
158 if(fget16(f) != 1)
160 /* wicked compressed format? fail */
161 fclose(f);
162 return(NULL);
165 n_channels=fget16(f);
166 s_rate=fget32(f);
167 b_per_sec=fget32(f);
169 bits=fget16(f) / n_channels;
170 bits *= 8;
172 fread(dummydata, 1, (size_t)flen - 14, f);
173 fread(dataid, 1, 4, f);
174 dataid[4] = 0;
176 size=(double) fget32(f);
177 if(bits == 16) size /= 2;
178 size /= (double) n_channels;
180 if((w=ss_alloc_wave(size, n_channels, s_rate)) != NULL)
182 w->base_freq=base_freq;
183 w->min_freq=min_freq;
184 w->max_freq=max_freq;
186 w->loop_start=loop_start;
188 if(loop_end < 0)
189 w->loop_end=size;
190 else
191 w->loop_end=loop_end;
193 load_pcm_wave(f, bits, 1, w);
196 fclose(f);
198 return(w);
202 static char * wave_file_preprocess(char * file)
203 /* preprocess the file, converting with external tools if necessary */
205 char * ext;
206 char * ptr;
207 char tmp[2048];
208 char home[1024];
209 static char c_file[1024];
210 int n;
212 /* gets the file extension */
213 if((ext=strrchr(file, '.')) == NULL)
214 return(NULL);
216 /* if it's a .wav file, return as is; no
217 further processing is needed */
218 if(strcmp(ext, ".wav") == 0 || strcmp(ext, ".WAV") == 0)
219 return(file);
221 /* resolve the file name */
222 if((file=locate_file(file)) == NULL)
223 return(NULL);
225 /* build the directory cache name */
226 if((ptr=getenv("HOME")) == NULL)
227 ptr="/tmp";
229 snprintf(home, sizeof(home), "%s/.annhellcache", ptr);
230 home[sizeof(home) - 1]='\0';
232 /* create a suitable cached file name */
233 strncpy(tmp, file, sizeof(tmp));
234 tmp[sizeof(tmp) - 1]='\0';
236 for(n=0;tmp[n] != '\0';n++)
237 if(tmp[n] == '/') tmp[n]='_';
239 snprintf(c_file, sizeof(c_file), "%s/%s.wav", home, tmp);
240 c_file[sizeof(c_file) - 1]='\0';
242 /* does the file already exist? */
243 if(access(c_file, R_OK) == 0)
244 return(c_file);
246 /* create the cache directory */
247 mkdir(home, 0755);
249 /* try known conversions; this is an ugly hack */
251 if(strcmp(ext, ".flac") == 0 || strcmp(ext, ".FLAC") == 0)
253 /* flac file */
254 snprintf(tmp, sizeof(tmp), "flac -d -s -o '%s' '%s'",
255 c_file, file);
256 tmp[sizeof(tmp) - 1]='\0';
258 system(tmp);
260 else
261 if(strcmp(ext, ".mp3") == 0 || strcmp(ext, ".MP3") == 0)
263 /* mp3 file */
264 snprintf(tmp, sizeof(tmp), "mpg321 -q -w '%s' '%s'",
265 c_file, file);
266 tmp[sizeof(tmp) - 1]='\0';
268 system(tmp);
271 return(c_file);
276 * ss_load_wave_file - Loads a wave file.
277 * @file: name of the file
278 * @base_freq: base frequency
279 * @min_freq: minimum frequency
280 * @max_freq: maximum frequency
281 * @loop_start: frame number of loop start (-1, no loop)
282 * @loop_end: frame number of loop end (-1, end of wave)
284 * Loads a wave file.
286 struct ss_wave * ss_load_wave_file(char * file,
287 double base_freq, double min_freq, double max_freq,
288 double loop_start, double loop_end)
290 /* preprocess the file, given its extension */
291 if((file=wave_file_preprocess(file)) == NULL)
292 return(NULL);
294 return(ss_load_wav_file(file, base_freq, min_freq,
295 max_freq, loop_start, loop_end));
300 * ss_load_pat_file - Loads an instrument in .PAT format.
301 * @i: The instrument
302 * @filename: filename holding the instrument
304 * Loads data from a Gravis Ultrasound patch (.PAT) format and
305 * stores it as layers for an instrument.
307 * Returns -100 if the file could not be read, -101 or -102
308 * if the file is not recognized as a .PAT file, or 0 if
309 * everything went OK.
311 int ss_load_pat_file(struct ss_ins * i, char * file)
313 FILE * f;
314 char buffer[512];
315 int m, n, o;
316 int n_layers;
317 int flags, bits, sign, loop, pingpong;
318 struct ss_wave * w;
320 if((f=path_fopen(file, "r")) == NULL)
321 return(-100);
323 /* read signatures */
324 fread(buffer, 12, 1, f);
325 if(strcmp(buffer, "GF1PATCH110") != 0)
327 fclose(f);
328 return(-101);
331 fread(buffer, 10, 1, f);
332 if(strcmp(buffer, "ID#000002") != 0)
334 fclose(f);
335 return(-102);
338 /* skip description */
339 fread(buffer, 65, 1, f);
341 /* ignore volume */
342 fget16(f);
344 /* skip */
345 fread(buffer, 109, 1, f);
347 /* # of layers */
348 n_layers=fgetc(f);
350 /* skip */
351 fread(buffer, 40, 1, f);
353 for(n=0;n < n_layers;n++)
355 int size, s_rate;
356 double loop_start, loop_end;
357 double min_freq, max_freq, base_freq;
359 /* layer name */
360 fread(buffer, 8, 1, f);
362 size=(double)fget32(f);
363 loop_start=(double)fget32(f);
364 loop_end=(double)fget32(f);
365 s_rate=fget16(f);
367 min_freq=((double)fget32(f)) / 1000.0;
368 max_freq=((double)fget32(f)) / 1000.0;
369 base_freq=((double)fget32(f)) / 1000.0;
371 if(base_freq < 0)
372 break;
374 /* ignore fine-tune */
375 fget16(f);
377 /* ignore pan position */
378 fgetc(f);
380 /* skip envelope rate, value, tremolo and vibrato */
381 fread(buffer, 18, 1, f);
383 flags=fgetc(f);
385 bits=flags & 0x01 ? 16 : 8;
386 sign=flags & 0x02 ? 0 : 1;
387 loop=flags & 0x04 ? 1 : 0;
388 pingpong=flags & 0x08 ? 1 : 0;
390 if(bits == 16)
392 size /= 2;
393 loop_start /= 2;
394 loop_end /= 2;
397 /* skip frequency scale data */
398 fget16(f); fget16(f);
400 /* skip reserved */
401 fread(buffer, 36, 1, f);
403 if((w=ss_alloc_wave(size, 1, s_rate)) == NULL)
404 break;
406 /* set the rest of values */
407 w->loop_start=loop_start;
408 w->loop_end=loop_end;
409 w->base_freq=base_freq;
410 w->min_freq=min_freq;
411 w->max_freq=max_freq;
413 /* load the wave */
414 load_pcm_wave(f, bits, sign, w);
416 if(pingpong && loop)
418 int loop_size;
419 float * ptr;
421 /* if ping-pong, realloc space for a reverse
422 version of the loop */
423 loop_size=(int)(loop_end - loop_start);
425 ptr=(float *) malloc((size + loop_size + 1)
426 * sizeof(float));
428 /* transfer start and loop */
429 for(m=0;m <= (int)loop_end;m++)
430 ptr[m]=w->wave[0][m];
432 /* transfer a reversed version of the loop */
433 for(o=m - 1;o >= loop_start;o--,m++)
434 ptr[m]=w->wave[0][o];
436 /* transfer the end */
437 for(o=loop_end + 1;o < size;o++,m++)
438 ptr[m]=w->wave[0][o];
440 w->loop_end += (double) loop_size;
441 w->size += (double) loop_size;
443 /* free and swap */
444 free(w->wave[0]);
445 w->wave[0]=ptr;
448 if(loop == 0) w->loop_start=-1;
450 /* finally add layer to instrument */
451 ss_ins_add_layer(i, w);
454 fclose(f);
455 return(0);