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