1 /************************************************************************
2    patchload.c  --  loads patches for playmidi package
3    Some of this code was adapted from code written by Hannu Solovainen
4 
5    Copyright (C) 1994-1996 Nathan I. Laredo
6 
7    This program is modifiable/redistributable under the terms
8    of the GNU General Public Licence.
9 
10    You should have received a copy of the GNU General Public License
11    along with this program; if not, write to the Free Software
12    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
13    Send your comments and all your spare pocket change to
14    laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
15    Kelly Drive, Lackland AFB, TX 78236-5128, USA.
16  *************************************************************************/
17 
18 #include "playmidi.h"
19 #ifdef linux
20 #include <linux/ultrasound.h>
21 #else
22 #endif
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include "gmvoices.h"
27 
28 SEQ_USE_EXTBUF();
29 extern int play_gus, play_sb, play_ext, playing, verbose, force8bit;
30 extern int reverb, fmloaded[256], patchloaded[256];
31 extern int gus_dev, sb_dev, ext_dev, seqfd, wantopl3;
32 extern struct synth_info card_info[MAX_CARDS];
33 extern void close_show(int);
34 
35 static int use8bit = 0;
36 
37 struct pat_header {
38     char magic[12];
39     char version[10];
40     char description[60];
41     unsigned char instruments;
42     char voices;
43     char channels;
44     unsigned short nr_waveforms;
45     unsigned short master_volume;
46     unsigned int data_size;
47 };
48 
49 struct sample_header {
50     char name[7];
51     unsigned char fractions;
52     int len;
53     int loop_start;
54     int loop_end;
55     unsigned short base_freq;
56     int low_note;
57     int high_note;
58     int base_note;
59     short detune;
60     unsigned char panning;
61 
62     unsigned char envelope_rate[6];
63     unsigned char envelope_offset[6];
64 
65     unsigned char tremolo_sweep;
66     unsigned char tremolo_rate;
67     unsigned char tremolo_depth;
68 
69     unsigned char vibrato_sweep;
70     unsigned char vibrato_rate;
71     unsigned char vibrato_depth;
72 
73     char modes;
74 
75     short scale_frequency;
76     unsigned short scale_factor;
77 };
78 
79 struct patch_info *patch;
80 int spaceleft, totalspace;
81 
82 void gus_reload_8_bit();
83 
gus_load(pgm)84 void gus_load(pgm)
85 int pgm;
86 {
87     int i, j, patfd, offset;
88     struct pat_header header;
89     struct sample_header sample;
90     char buf[256], name[256];
91     struct stat info;
92 
93     if (pgm < 0) {
94 	use8bit = force8bit;
95 	SEQ_DUMPBUF();
96 	for (i = 0; i < 256; i++)
97 	    patchloaded[i] = 0;
98 	if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1)
99 	    close_show(-1);
100 	spaceleft = gus_dev;
101 	ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
102 	totalspace = spaceleft;
103     }
104 
105     if (patchloaded[pgm] < 0)
106 	return;
107 
108     if (patchloaded[pgm] == 1)
109 	return;
110 
111     if (gmvoice[pgm] == NULL) {
112 	patchloaded[pgm] = -1;
113 	return;
114     }
115     sprintf(name, PATCH_PATH1 "/%s.pat", gmvoice[pgm]);
116 
117     if (stat(name, &info) == -1) {
118 	sprintf(name, PATCH_PATH2 "/%s.pat", gmvoice[pgm]);
119 	if (stat(name, &info) == -1)
120 	    return;
121     }
122     if ((patfd = open(name, O_RDONLY, 0)) == -1)
123 	return;
124     if (spaceleft < info.st_size) {
125 	if (!use8bit)
126 	    gus_reload_8_bit();
127 	if (use8bit)
128 	    if (spaceleft < info.st_size / 2) {
129 		close(patfd);
130 		patchloaded[pgm] = -1;	/* no space for patch */
131 		return;
132 	    }
133     }
134     if (read(patfd, buf, 0xef) != 0xef) {
135 	close(patfd);
136 	return;
137     }
138     memcpy((char *) &header, buf, sizeof(header));
139 
140     if (strncmp(header.magic, "GF1PATCH110", 12)) {
141 	close(patfd);
142 	return;
143     }
144     if (strncmp(header.version, "ID#000002", 10)) {
145 	close(patfd);
146 	return;
147     }
148     header.nr_waveforms = *(unsigned short *) &buf[85];
149     header.master_volume = *(unsigned short *) &buf[87];
150 
151     offset = 0xef;
152 
153     for (i = 0; i < header.nr_waveforms; i++) {
154 
155 	if (lseek(patfd, offset, 0) == -1) {
156 	    close(patfd);
157 	    return;
158 	}
159 	if (read(patfd, &buf, sizeof(sample)) != sizeof(sample)) {
160 	    close(patfd);
161 	    return;
162 	}
163 	memcpy((char *) &sample, buf, sizeof(sample));
164 
165 	/*
166 	 * Since some fields of the patch record are not 32bit aligned, we must
167 	 * handle them specially.
168 	 */
169 	sample.low_note = *(int *) &buf[22];
170 	sample.high_note = *(int *) &buf[26];
171 	sample.base_note = *(int *) &buf[30];
172 	sample.detune = *(short *) &buf[34];
173 	sample.panning = (unsigned char) buf[36];
174 
175 	memcpy(sample.envelope_rate, &buf[37], 6);
176 	memcpy(sample.envelope_offset, &buf[43], 6);
177 
178 	sample.tremolo_sweep = (unsigned char) buf[49];
179 	sample.tremolo_rate = (unsigned char) buf[50];
180 	sample.tremolo_depth = (unsigned char) buf[51];
181 
182 	sample.vibrato_sweep = (unsigned char) buf[52];
183 	sample.vibrato_rate = (unsigned char) buf[53];
184 	sample.vibrato_depth = (unsigned char) buf[54];
185 	sample.modes = (unsigned char) buf[55];
186 	sample.scale_frequency = *(short *) &buf[56];
187 	sample.scale_factor = *(unsigned short *) &buf[58];
188 
189 	offset = offset + 96;
190 	patch = (struct patch_info *) malloc(sizeof(*patch) + sample.len);
191 
192 	if (patch == NULL) {
193 	    close(patfd);
194 	    return;
195 	}
196 	patch->key = GUS_PATCH;
197 	patch->device_no = gus_dev;
198 	patch->instr_no = pgm;
199 	patch->mode = sample.modes | WAVE_TREMOLO |
200 	    WAVE_VIBRATO | WAVE_SCALE;
201 	patch->len = (use8bit ? sample.len / 2 : sample.len);
202 	patch->loop_start =
203 	    (use8bit ? sample.loop_start / 2 : sample.loop_start);
204 	patch->loop_end = (use8bit ? sample.loop_end / 2 : sample.loop_end);
205 	patch->base_note = sample.base_note;
206 	patch->high_note = sample.high_note;
207 	patch->low_note = sample.low_note;
208 	patch->base_freq = sample.base_freq;
209 	patch->detuning = sample.detune;
210 	patch->panning = (sample.panning - 7) * 16;
211 
212 	memcpy(patch->env_rate, sample.envelope_rate, 6);
213 	for (j = 0; j < 6; j++)	/* tone things down slightly */
214 	    patch->env_offset[j] =
215 		(736 * sample.envelope_offset[j] + 384) / 768;
216 
217 	if (reverb)
218 	    if (pgm < 120)
219 		patch->env_rate[3] = (2 << 6) | (12 - (reverb >> 4));
220 	    else if (pgm > 127)
221 		patch->env_rate[1] = (3 << 6) | (63 - (reverb >> 1));
222 
223 	patch->tremolo_sweep = sample.tremolo_sweep;
224 	patch->tremolo_rate = sample.tremolo_rate;
225 	patch->tremolo_depth = sample.tremolo_depth;
226 
227 	patch->vibrato_sweep = sample.vibrato_sweep;
228 	patch->vibrato_rate = sample.vibrato_rate;
229 	patch->vibrato_depth = sample.vibrato_depth;
230 
231 	patch->scale_frequency = sample.scale_frequency;
232 	patch->scale_factor = sample.scale_factor;
233 
234 	patch->volume = header.master_volume;
235 
236 	if (lseek(patfd, offset, 0) == -1) {
237 	    close(patfd);
238 	    return;
239 	}
240 	if (read(patfd, patch->data, sample.len) != sample.len) {
241 	    close(patfd);
242 	    return;
243 	}
244 	if (patch->mode & WAVE_16_BITS && use8bit) {
245 	    patch->mode &= ~WAVE_16_BITS;
246 	    /* cut out every other byte to make 8-bit data from 16-bit */
247 	    for (j = 0; j < patch->len; j++)
248 		patch->data[j] = patch->data[1 + j * 2];
249 	}
250 	SEQ_WRPATCH(patch, sizeof(*patch) + patch->len);
251 	free(patch);
252 	offset = offset + sample.len;
253     }
254     close(patfd);
255     spaceleft = gus_dev;
256     ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
257     patchloaded[pgm] = 1;
258     return;
259 }
260 
gus_reload_8_bit()261 void gus_reload_8_bit()
262 {
263     int i;
264 
265     if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1) {
266 	close_show(-1);
267     }
268     spaceleft = gus_dev;
269     ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
270     totalspace = spaceleft;
271     use8bit = 1;
272     for (i = 0; i < 256; i++)
273 	if (patchloaded[i] > 0) {
274 	    patchloaded[i] = 0;
275 	    gus_load(i);
276 	}
277 }
278 
adjustfm(buf,key)279 void adjustfm(buf, key)
280 char *buf;
281 int key;
282 {
283     unsigned char pan = ((rand() % 3) + 1) << 4;
284 
285     if (key == FM_PATCH) {
286 	buf[39] &= 0xc0;
287 	if (buf[46] & 1)
288 	    buf[38] &= 0xc0;
289 	buf[46] = (buf[46] & 0xcf) | pan;
290 	if (reverb) {
291 	    unsigned val;
292 	    val = buf[43] & 0x0f;
293 	    if (val > 0)
294 		val--;
295 	    buf[43] = (buf[43] & 0xf0) | val;
296 	}
297     } else {
298 	int mode;
299 	if (buf[46] & 1)
300 	    mode = 2;
301 	else
302 	    mode = 0;
303 	if (buf[57] & 1)
304 	    mode++;
305 	buf[50] &= 0xc0;
306 	if (mode == 3)
307 	    buf[49] &= 0xc0;
308 	if (mode == 1)
309 	    buf[39] &= 0xc0;
310 	if (mode == 2 || mode == 3)
311 	    buf[38] &= 0xc0;
312 	buf[46] = (buf[46] & 0xcf) | pan;
313 	buf[57] = (buf[57] & 0xcf) | pan;
314 	if (mode == 1 && reverb) {
315 	    unsigned val;
316 	    val = buf[43] & 0x0f;
317 	    if (val > 0)
318 		val--;
319 	    buf[43] = (buf[43] & 0xf0) | val;
320 	    val = buf[54] & 0x0f;
321 	    if (val > 0)
322 		val--;
323 	    buf[54] = (buf[54] & 0xf0) | val;
324 	}
325     }
326 }
327 
loadfm()328 void loadfm()
329 {
330     int sbfd, i, n, voice_size, data_size;
331     char buf[60];
332     struct sbi_instrument instr;
333 
334     for (i = 0; i < 256; i++)
335 	fmloaded[i] = 0;
336     srand(getpid());
337     if (wantopl3) {
338 	voice_size = 60;
339 	sbfd = open(O3MELODIC, O_RDONLY, 0);
340     } else {
341 	voice_size = 52;
342 	sbfd = open(SBMELODIC, O_RDONLY, 0);
343     }
344     if (sbfd == -1)
345 	close_show(-1);
346     instr.device = sb_dev;
347 
348     for (i = 0; i < 128; i++) {
349 	if (read(sbfd, buf, voice_size) != voice_size)
350 	    close_show(-1);
351 	instr.channel = i;
352 
353 	if (strncmp(buf, "4OP", 3) == 0) {
354 	    instr.key = OPL3_PATCH;
355 	    data_size = 22;
356 	} else {
357 	    instr.key = FM_PATCH;
358 	    data_size = 11;
359 	}
360 
361 	fmloaded[i] = instr.key;
362 
363 	adjustfm(buf, instr.key);
364 	for (n = 0; n < 32; n++)
365 	    instr.operators[n] = (n < data_size) ? buf[36 + n] : 0;
366 
367 	SEQ_WRPATCH(&instr, sizeof(instr));
368     }
369     close(sbfd);
370 
371     if (wantopl3)
372 	sbfd = open(O3DRUMS, O_RDONLY, 0);
373     else
374 	sbfd = open(SBDRUMS, O_RDONLY, 0);
375 
376     for (i = 128; i < 175; i++) {
377 	if (read(sbfd, buf, voice_size) != voice_size)
378 	    close_show(-1);
379 	instr.channel = i;
380 
381 	if (strncmp(buf, "4OP", 3) == 0) {
382 	    instr.key = OPL3_PATCH;
383 	    data_size = 22;
384 	} else {
385 	    instr.key = FM_PATCH;
386 	    data_size = 11;
387 	}
388 	fmloaded[i] = instr.key;
389 
390 	adjustfm(buf, instr.key);
391 	for (n = 0; n < 32; n++)
392 	    instr.operators[n] = (n < data_size) ? buf[n + 36] : 0;
393 
394 	SEQ_WRPATCH(&instr, sizeof(instr));
395     }
396     close(sbfd);
397 }
398