1 /*
2 * gus_pat.c -- Midi Wavetable Processing library
3 *
4 * Copyright (C) WildMIDI Developers 2001-2015
5 *
6 * This file is part of WildMIDI.
7 *
8 * WildMIDI is free software: you can redistribute and/or modify the player
9 * under the terms of the GNU General Public License and you can redistribute
10 * and/or modify the library under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation, either version 3 of
12 * the licenses, or(at your option) any later version.
13 *
14 * WildMIDI is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License and
17 * the GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License and the
20 * GNU Lesser General Public License along with WildMIDI. If not, see
21 * <http://www.gnu.org/licenses/>.
22 */
23
24 #include <errno.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "gus_pat.h"
30 #include "common.h"
31 #include "wm_error.h"
32 #include "file_io.h"
33 #include "wildmidi_lib.h"
34
35 namespace WildMidi
36 {
37
38 /* Guspat Envelope Rate Timings */
39
40 float env_time_table[] = {
41 /* Row 1 = (4095.0 / (x * ( 1.0 / (1.6 * 14.0) ))) / 1000000.0 */
42 0.0f, 0.091728000f, 0.045864000f, 0.030576000f, 0.022932000f, 0.018345600f, 0.015288000f, 0.013104000f,
43 0.011466000f, 0.010192000f, 0.009172800f, 0.008338909f, 0.007644000f, 0.007056000f, 0.006552000f, 0.006115200f,
44 0.005733000f, 0.005395765f, 0.005096000f, 0.004827789f, 0.004586400f, 0.004368000f, 0.004169455f, 0.003988174f,
45 0.003822000f, 0.003669120f, 0.003528000f, 0.003397333f, 0.003276000f, 0.003163034f, 0.003057600f, 0.002958968f,
46 0.002866500f, 0.002779636f, 0.002697882f, 0.002620800f, 0.002548000f, 0.002479135f, 0.002413895f, 0.002352000f,
47 0.002293200f, 0.002237268f, 0.002184000f, 0.002133209f, 0.002084727f, 0.002038400f, 0.001994087f, 0.001951660f,
48 0.001911000f, 0.001872000f, 0.001834560f, 0.001798588f, 0.001764000f, 0.001730717f, 0.001698667f, 0.001667782f,
49 0.001638000f, 0.001609263f, 0.001581517f, 0.001554712f, 0.001528800f, 0.001503738f, 0.001479484f, 0.001456000f,
50
51 /* Row 2 = (4095.0 / (x * ((1.0 / (1.6 * 14.0)) / 8.0 ))) / 1000000.0 */
52 0.0f, 0.733824000f, 0.366912000f, 0.244608000f, 0.183456000f, 0.146764800f, 0.122304000f, 0.104832000f,
53 0.091728000f, 0.081536000f, 0.073382400f, 0.066711273f, 0.061152000f, 0.056448000f, 0.052416000f, 0.048921600f,
54 0.045864000f, 0.043166118f, 0.040768000f, 0.038622316f, 0.036691200f, 0.034944000f, 0.033355636f, 0.031905391f,
55 0.030576000f, 0.029352960f, 0.028224000f, 0.027178667f, 0.026208000f, 0.025304276f, 0.024460800f, 0.023671742f,
56 0.022932000f, 0.022237091f, 0.021583059f, 0.020966400f, 0.020384000f, 0.019833081f, 0.019311158f, 0.018816000f,
57 0.018345600f, 0.017898146f, 0.017472000f, 0.017065674f, 0.016677818f, 0.016307200f, 0.015952696f, 0.015613277f,
58 0.015288000f, 0.014976000f, 0.014676480f, 0.014388706f, 0.014112000f, 0.013845736f, 0.013589333f, 0.013342255f,
59 0.013104000f, 0.012874105f, 0.012652138f, 0.012437695f, 0.012230400f, 0.012029902f, 0.011835871f, 0.011648000f,
60
61 /* Row 3 = (4095.0 / (x * ((1.0 / (1.6 * 14.0)) / 64.0 ))) / 1000000.0 */
62 0.0f, 5.870592000f, 2.935296000f, 1.956864000f, 1.467648000f, 1.174118400f, 0.978432000f, 0.838656000f,
63 0.733824000f, 0.652288000f, 0.587059200f, 0.533690182f, 0.489216000f, 0.451584000f, 0.419328000f, 0.391372800f,
64 0.366912000f, 0.345328941f, 0.326144000f, 0.308978526f, 0.293529600f, 0.279552000f, 0.266845091f, 0.255243130f,
65 0.244608000f, 0.234823680f, 0.225792000f, 0.217429333f, 0.209664000f, 0.202434207f, 0.195686400f, 0.189373935f,
66 0.183456000f, 0.177896727f, 0.172664471f, 0.167731200f, 0.163072000f, 0.158664649f, 0.154489263f, 0.150528000f,
67 0.146764800f, 0.143185171f, 0.139776000f, 0.136525395f, 0.133422545f, 0.130457600f, 0.127621565f, 0.124906213f,
68 0.122304000f, 0.119808000f, 0.117411840f, 0.115109647f, 0.112896000f, 0.110765887f, 0.108714667f, 0.106738036f,
69 0.104832000f, 0.102992842f, 0.101217103f, 0.099501559f, 0.097843200f, 0.096239213f, 0.094686968f, 0.093184000f,
70
71 /* Row 4 = (4095.0 / (x * ((1.0 / (1.6 * 14.0)) / 512.0))) / 1000000.0 */
72 0.0f, 46.964736000f,23.482368000f,15.654912000f,11.741184000f, 9.392947200f, 7.827456000f, 6.709248000f,
73 5.870592000f, 5.218304000f, 4.696473600f, 4.269521455f, 3.913728000f, 3.612672000f, 3.354624000f, 3.130982400f,
74 2.935296000f, 2.762631529f, 2.609152000f, 2.471828211f, 2.348236800f, 2.236416000f, 2.134760727f, 2.041945043f,
75 1.956864000f, 1.878589440f, 1.806336000f, 1.739434667f, 1.677312000f, 1.619473655f, 1.565491200f, 1.514991484f,
76 1.467648000f, 1.423173818f, 1.381315765f, 1.341849600f, 1.304576000f, 1.269317189f, 1.235914105f, 1.204224000f,
77 1.174118400f, 1.145481366f, 1.118208000f, 1.092203163f, 1.067380364f, 1.043660800f, 1.020972522f, 0.999249702f,
78 0.978432000f, 0.958464000f, 0.939294720f, 0.920877176f, 0.903168000f, 0.886127094f, 0.869717333f, 0.853904291f,
79 0.838656000f, 0.823942737f, 0.809736828f, 0.796012475f, 0.782745600f, 0.769913705f, 0.757495742f, 0.745472000f
80 };
81 #ifdef DEBUG_GUSPAT
82 #define GUSPAT_FILENAME_DEBUG(dx) fprintf(stderr,"\r%s\n",dx)
83
84 #define GUSPAT_INT_DEBUG(dx,dy) fprintf(stderr,"\r%s: %i\n",dx,dy)
85 #define GUSPAT_FLOAT_DEBUG(dx,dy) fprintf(stderr,"\r%s: %f\n",dx,dy)
86 #define GUSPAT_START_DEBUG() fprintf(stderr,"\r")
87 #define GUSPAT_MODE_DEBUG(dx,dy,dz) if (dx & dy) fprintf(stderr,"%s",dz)
88 #define GUSPAT_END_DEBUG() fprintf(stderr,"\n")
89 #else
90 #define GUSPAT_FILENAME_DEBUG(dx)
91 #define GUSPAT_INT_DEBUG(dx,dy)
92 #define GUSPAT_FLOAT_DEBUG(dx,dy)
93 #define GUSPAT_START_DEBUG()
94 #define GUSPAT_MODE_DEBUG(dx,dy,dz)
95 #define GUSPAT_END_DEBUG()
96 #endif
97
98 #ifdef DEBUG_SAMPLES
99 #define SAMPLE_CONVERT_DEBUG(dx) printf("\r%s\n",dx)
100 #else
101 #define SAMPLE_CONVERT_DEBUG(dx)
102 #endif
103 /*
104 * sample data conversion functions
105 * convert data to signed shorts
106 */
107
108 /* 8bit signed */
convert_8s(unsigned char * data,struct _sample * gus_sample)109 static int convert_8s(unsigned char *data, struct _sample *gus_sample) {
110 unsigned char *read_data = data;
111 unsigned char *read_end = data + gus_sample->data_length;
112 signed short int *write_data = NULL;
113
114 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
115 gus_sample->data = (short*)calloc((gus_sample->data_length + 2),
116 sizeof(signed short int));
117 if (gus_sample->data != NULL) {
118 write_data = gus_sample->data;
119 do {
120 *write_data++ = (*read_data++) << 8;
121 } while (read_data != read_end);
122 return 0;
123 }
124
125 _WM_ERROR_NEW("Calloc failed (%s)\n", strerror(errno));
126 return -1;
127 }
128
129 /* 8bit signed ping pong */
convert_8sp(unsigned char * data,struct _sample * gus_sample)130 static int convert_8sp(unsigned char *data, struct _sample *gus_sample) {
131 unsigned long int loop_length = gus_sample->loop_end
132 - gus_sample->loop_start;
133 unsigned long int dloop_length = loop_length * 2;
134 unsigned long int new_length = gus_sample->data_length + dloop_length;
135 unsigned char *read_data = data;
136 unsigned char *read_end = data + gus_sample->loop_start;
137 signed short int *write_data = NULL;
138 signed short int *write_data_a = NULL;
139 signed short int *write_data_b = NULL;
140
141 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
142 gus_sample->data = (short*)calloc((new_length + 2), sizeof(signed short int));
143 if (gus_sample->data != NULL) {
144 write_data = gus_sample->data;
145 do {
146 *write_data++ = (*read_data++) << 8;
147 } while (read_data != read_end);
148
149 *write_data = (*read_data++ << 8);
150 write_data_a = write_data + dloop_length;
151 *write_data_a-- = *write_data;
152 write_data++;
153 write_data_b = write_data + dloop_length;
154 read_end = data + gus_sample->loop_end;
155 do {
156 *write_data = (*read_data++) << 8;
157 *write_data_a-- = *write_data;
158 *write_data_b++ = *write_data;
159 write_data++;
160 } while (read_data != read_end);
161
162 *write_data = (*read_data++ << 8);
163 *write_data_b++ = *write_data;
164 read_end = data + gus_sample->data_length;
165 if (read_data != read_end) {
166 do {
167 *write_data_b++ = (*read_data++) << 8;
168 } while (read_data != read_end);
169 }
170 gus_sample->loop_start += loop_length;
171 gus_sample->loop_end += dloop_length;
172 gus_sample->data_length = new_length;
173 gus_sample->modes ^= SAMPLE_PINGPONG;
174 return 0;
175 }
176
177 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
178 return -1;
179 }
180
181 /* 8bit signed reverse */
convert_8sr(unsigned char * data,struct _sample * gus_sample)182 static int convert_8sr(unsigned char *data, struct _sample *gus_sample) {
183 unsigned char *read_data = data;
184 unsigned char *read_end = data + gus_sample->data_length;
185 signed short int *write_data = NULL;
186 unsigned long int tmp_loop = 0;
187
188 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
189 gus_sample->data = (short*)calloc((gus_sample->data_length + 2),
190 sizeof(signed short int));
191 if (gus_sample->data != NULL) {
192 write_data = gus_sample->data + gus_sample->data_length - 1;
193 do {
194 *write_data-- = (*read_data++) << 8;
195 } while (read_data != read_end);
196 tmp_loop = gus_sample->loop_end;
197 gus_sample->loop_end = gus_sample->data_length - gus_sample->loop_start;
198 gus_sample->loop_start = gus_sample->data_length - tmp_loop;
199 gus_sample->loop_fraction = ((gus_sample->loop_fraction & 0x0f) << 4)
200 | ((gus_sample->loop_fraction & 0xf0) >> 4);
201 gus_sample->modes ^= SAMPLE_REVERSE;
202 return 0;
203 }
204 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
205 return -1;
206 }
207
208 /* 8bit signed reverse ping pong */
convert_8srp(unsigned char * data,struct _sample * gus_sample)209 static int convert_8srp(unsigned char *data, struct _sample *gus_sample) {
210 unsigned long int loop_length = gus_sample->loop_end
211 - gus_sample->loop_start;
212 unsigned long int dloop_length = loop_length * 2;
213 unsigned long int new_length = gus_sample->data_length + dloop_length;
214 unsigned char *read_data = data + gus_sample->data_length - 1;
215 unsigned char *read_end = data + gus_sample->loop_end;
216 signed short int *write_data = NULL;
217 signed short int *write_data_a = NULL;
218 signed short int *write_data_b = NULL;
219
220 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
221 gus_sample->data = (short*)calloc((new_length + 2), sizeof(signed short int));
222 if (gus_sample->data != NULL) {
223 write_data = gus_sample->data;
224 do {
225 *write_data++ = (*read_data--) << 8;
226 } while (read_data != read_end);
227
228 *write_data = (*read_data-- << 8);
229 write_data_a = write_data + dloop_length;
230 *write_data_a-- = *write_data;
231 write_data++;
232 write_data_b = write_data + dloop_length;
233 read_end = data + gus_sample->loop_start;
234 do {
235 *write_data = (*read_data--) << 8;
236 *write_data_a-- = *write_data;
237 *write_data_b++ = *write_data;
238 write_data++;
239 } while (read_data != read_end);
240
241 *write_data = (*read_data-- << 8);
242 *write_data_b++ = *write_data;
243 read_end = data - 1;
244 do {
245 *write_data_b++ = (*read_data--) << 8;
246 write_data_b++;
247 } while (read_data != read_end);
248 gus_sample->loop_start += loop_length;
249 gus_sample->loop_end += dloop_length;
250 gus_sample->data_length = new_length;
251 gus_sample->modes ^= SAMPLE_PINGPONG | SAMPLE_REVERSE;
252 return 0;
253 }
254
255 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
256 return -1;
257 }
258
259 /* 8bit unsigned */
convert_8u(unsigned char * data,struct _sample * gus_sample)260 static int convert_8u(unsigned char *data, struct _sample *gus_sample) {
261 unsigned char *read_data = data;
262 unsigned char *read_end = data + gus_sample->data_length;
263 signed short int *write_data = NULL;
264
265 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
266 gus_sample->data = (short*)calloc((gus_sample->data_length + 2),
267 sizeof(signed short int));
268 if (gus_sample->data != NULL) {
269 write_data = gus_sample->data;
270 do {
271 *write_data++ = ((*read_data++) ^ 0x80) << 8;
272 } while (read_data != read_end);
273 gus_sample->modes ^= SAMPLE_UNSIGNED;
274 return 0;
275 }
276 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
277 return -1;
278 }
279
280 /* 8bit unsigned ping pong */
convert_8up(unsigned char * data,struct _sample * gus_sample)281 static int convert_8up(unsigned char *data, struct _sample *gus_sample) {
282 unsigned long int loop_length = gus_sample->loop_end
283 - gus_sample->loop_start;
284 unsigned long int dloop_length = loop_length * 2;
285 unsigned long int new_length = gus_sample->data_length + dloop_length;
286 unsigned char *read_data = data;
287 unsigned char *read_end = data + gus_sample->loop_start;
288 signed short int *write_data = NULL;
289 signed short int *write_data_a = NULL;
290 signed short int *write_data_b = NULL;
291
292 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
293 gus_sample->data = (short*)calloc((new_length + 2), sizeof(signed short int));
294 if (gus_sample->data != NULL) {
295 write_data = gus_sample->data;
296 do {
297 *write_data++ = ((*read_data++) ^ 0x80) << 8;
298 } while (read_data != read_end);
299
300 *write_data = ((*read_data++) ^ 0x80) << 8;
301 write_data_a = write_data + dloop_length;
302 *write_data_a-- = *write_data;
303 write_data++;
304 write_data_b = write_data + dloop_length;
305 read_end = data + gus_sample->loop_end;
306 do {
307 *write_data = ((*read_data++) ^ 0x80) << 8;
308 *write_data_a-- = *write_data;
309 *write_data_b++ = *write_data;
310 write_data++;
311 } while (read_data != read_end);
312
313 *write_data = ((*read_data++) ^ 0x80) << 8;
314 *write_data_b++ = *write_data;
315 read_end = data + gus_sample->data_length;
316 if (read_data != read_end) {
317 do {
318 *write_data_b++ = ((*read_data++) ^ 0x80) << 8;
319 } while (read_data != read_end);
320 }
321 gus_sample->loop_start += loop_length;
322 gus_sample->loop_end += dloop_length;
323 gus_sample->data_length = new_length;
324 gus_sample->modes ^= SAMPLE_PINGPONG | SAMPLE_UNSIGNED;
325 return 0;
326 }
327
328 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
329 return -1;
330 }
331
332 /* 8bit unsigned reverse */
convert_8ur(unsigned char * data,struct _sample * gus_sample)333 static int convert_8ur(unsigned char *data, struct _sample *gus_sample) {
334 unsigned char *read_data = data;
335 unsigned char *read_end = data + gus_sample->data_length;
336 signed short int *write_data = NULL;
337 unsigned long int tmp_loop = 0;
338
339 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
340 gus_sample->data = (short*)calloc((gus_sample->data_length + 2),
341 sizeof(signed short int));
342 if (gus_sample->data != NULL) {
343 write_data = gus_sample->data + gus_sample->data_length - 1;
344 do {
345 *write_data-- = ((*read_data++) ^ 0x80) << 8;
346 } while (read_data != read_end);
347 tmp_loop = gus_sample->loop_end;
348 gus_sample->loop_end = gus_sample->data_length - gus_sample->loop_start;
349 gus_sample->loop_start = gus_sample->data_length - tmp_loop;
350 gus_sample->loop_fraction = ((gus_sample->loop_fraction & 0x0f) << 4)
351 | ((gus_sample->loop_fraction & 0xf0) >> 4);
352 gus_sample->modes ^= SAMPLE_REVERSE | SAMPLE_UNSIGNED;
353 return 0;
354 }
355 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
356 return -1;
357 }
358
359 /* 8bit unsigned reverse ping pong */
convert_8urp(unsigned char * data,struct _sample * gus_sample)360 static int convert_8urp(unsigned char *data, struct _sample *gus_sample) {
361 unsigned long int loop_length = gus_sample->loop_end
362 - gus_sample->loop_start;
363 unsigned long int dloop_length = loop_length * 2;
364 unsigned long int new_length = gus_sample->data_length + dloop_length;
365 unsigned char *read_data = data + gus_sample->data_length - 1;
366 unsigned char *read_end = data + gus_sample->loop_end;
367 signed short int *write_data = NULL;
368 signed short int *write_data_a = NULL;
369 signed short int *write_data_b = NULL;
370
371 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
372 gus_sample->data = (short*)calloc((new_length + 2), sizeof(signed short int));
373 if (gus_sample->data != NULL) {
374 write_data = gus_sample->data;
375 do {
376 *write_data++ = ((*read_data--) ^ 0x80) << 8;
377 } while (read_data != read_end);
378
379 *write_data = ((*read_data--) ^ 0x80) << 8;
380 write_data_a = write_data + dloop_length;
381 *write_data_a-- = *write_data;
382 write_data++;
383 write_data_b = write_data + dloop_length;
384 read_end = data + gus_sample->loop_start;
385 do {
386 *write_data = ((*read_data--) ^ 0x80) << 8;
387 *write_data_a-- = *write_data;
388 *write_data_b++ = *write_data;
389 write_data++;
390 } while (read_data != read_end);
391
392 *write_data = ((*read_data--) ^ 0x80) << 8;
393 *write_data_b++ = *write_data;
394 read_end = data - 1;
395 do {
396 *write_data_b++ = ((*read_data--) ^ 0x80) << 8;
397 } while (read_data != read_end);
398 gus_sample->loop_start += loop_length;
399 gus_sample->loop_end += dloop_length;
400 gus_sample->data_length = new_length;
401 gus_sample->modes ^= SAMPLE_PINGPONG | SAMPLE_REVERSE | SAMPLE_UNSIGNED;
402 return 0;
403 }
404
405 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
406 return -1;
407 }
408
409 /* 16bit signed */
convert_16s(unsigned char * data,struct _sample * gus_sample)410 static int convert_16s(unsigned char *data, struct _sample *gus_sample) {
411 unsigned char *read_data = data;
412 unsigned char *read_end = data + gus_sample->data_length;
413 signed short int *write_data = NULL;
414
415 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
416 gus_sample->data = (short*)calloc(((gus_sample->data_length >> 1) + 2),
417 sizeof(signed short int));
418 if (gus_sample->data != NULL) {
419 write_data = gus_sample->data;
420 do {
421 *write_data = *read_data++;
422 *write_data++ |= (*read_data++) << 8;
423 } while (read_data < read_end);
424
425 gus_sample->loop_start >>= 1;
426 gus_sample->loop_end >>= 1;
427 gus_sample->data_length >>= 1;
428 return 0;
429 }
430 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
431 return -1;
432 }
433
434 /* 16bit signed ping pong */
convert_16sp(unsigned char * data,struct _sample * gus_sample)435 static int convert_16sp(unsigned char *data, struct _sample *gus_sample) {
436 unsigned long int loop_length = gus_sample->loop_end
437 - gus_sample->loop_start;
438 unsigned long int dloop_length = loop_length * 2;
439 unsigned long int new_length = gus_sample->data_length + dloop_length;
440 unsigned char *read_data = data;
441 unsigned char *read_end = data + gus_sample->loop_start;
442 signed short int *write_data = NULL;
443 signed short int *write_data_a = NULL;
444 signed short int *write_data_b = NULL;
445
446 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
447 gus_sample->data = (short*)calloc(((new_length >> 1) + 2),
448 sizeof(signed short int));
449 if (gus_sample->data != NULL) {
450 write_data = gus_sample->data;
451 do {
452 *write_data = (*read_data++);
453 *write_data++ |= (*read_data++) << 8;
454 } while (read_data < read_end);
455
456 *write_data = (*read_data++);
457 *write_data |= (*read_data++) << 8;
458 write_data_a = write_data + (dloop_length >> 1);
459 *write_data_a-- = *write_data;
460 write_data++;
461 write_data_b = write_data + (dloop_length >> 1);
462 read_end = data + gus_sample->loop_end;
463 do {
464 *write_data = (*read_data++);
465 *write_data |= (*read_data++) << 8;
466 *write_data_a-- = *write_data;
467 *write_data_b++ = *write_data;
468 write_data++;
469 } while (read_data < read_end);
470
471 *write_data = *(read_data++);
472 *write_data |= (*read_data++) << 8;
473 *write_data_b++ = *write_data;
474 read_end = data + gus_sample->data_length;
475 if (read_data != read_end) {
476 do {
477 *write_data_b = *(read_data++);
478 *write_data_b++ |= (*read_data++) << 8;
479 } while (read_data < read_end);
480 }
481 gus_sample->loop_start += loop_length;
482 gus_sample->loop_end += dloop_length;
483 gus_sample->data_length = new_length;
484 gus_sample->modes ^= SAMPLE_PINGPONG;
485 gus_sample->loop_start >>= 1;
486 gus_sample->loop_end >>= 1;
487 gus_sample->data_length >>= 1;
488 return 0;
489 }
490
491 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
492 return -1;
493 }
494
495 /* 16bit signed reverse */
convert_16sr(unsigned char * data,struct _sample * gus_sample)496 static int convert_16sr(unsigned char *data, struct _sample *gus_sample) {
497 unsigned char *read_data = data;
498 unsigned char *read_end = data + gus_sample->data_length;
499 signed short int *write_data = NULL;
500 unsigned long int tmp_loop = 0;
501
502 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
503 gus_sample->data = (short*)calloc(((gus_sample->data_length >> 1) + 2),
504 sizeof(signed short int));
505 if (gus_sample->data != NULL) {
506 write_data = gus_sample->data + (gus_sample->data_length >> 1) - 1;
507 do {
508 *write_data = *read_data++;
509 *write_data-- |= (*read_data++) << 8;
510 } while (read_data < read_end);
511 tmp_loop = gus_sample->loop_end;
512 gus_sample->loop_end = gus_sample->data_length - gus_sample->loop_start;
513 gus_sample->loop_start = gus_sample->data_length - tmp_loop;
514 gus_sample->loop_fraction = ((gus_sample->loop_fraction & 0x0f) << 4)
515 | ((gus_sample->loop_fraction & 0xf0) >> 4);
516 gus_sample->loop_start >>= 1;
517 gus_sample->loop_end >>= 1;
518 gus_sample->data_length >>= 1;
519 gus_sample->modes ^= SAMPLE_REVERSE;
520 return 0;
521 }
522 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
523 return -1;
524 }
525
526 /* 16bit signed reverse ping pong */
convert_16srp(unsigned char * data,struct _sample * gus_sample)527 static int convert_16srp(unsigned char *data, struct _sample *gus_sample) {
528 unsigned long int loop_length = gus_sample->loop_end
529 - gus_sample->loop_start;
530 unsigned long int dloop_length = loop_length * 2;
531 unsigned long int new_length = gus_sample->data_length + dloop_length;
532 unsigned char *read_data = data + gus_sample->data_length - 1;
533 unsigned char *read_end = data + gus_sample->loop_end;
534 signed short int *write_data = NULL;
535 signed short int *write_data_a = NULL;
536 signed short int *write_data_b = NULL;
537
538 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
539 gus_sample->data = (short*)calloc(((new_length >> 1) + 2),
540 sizeof(signed short int));
541 if (gus_sample->data != NULL) {
542 write_data = gus_sample->data;
543 do {
544 *write_data = (*read_data--) << 8;
545 *write_data++ |= *read_data--;
546 } while (read_data < read_end);
547
548 *write_data = (*read_data-- << 8);
549 *write_data |= *read_data--;
550 write_data_a = write_data + (dloop_length >> 1);
551 *write_data_a-- = *write_data;
552 write_data++;
553 write_data_b = write_data + (dloop_length >> 1);
554 read_end = data + gus_sample->loop_start;
555 do {
556 *write_data = (*read_data--) << 8;
557 *write_data |= *read_data--;
558 *write_data_a-- = *write_data;
559 *write_data_b++ = *write_data;
560 write_data++;
561 } while (read_data < read_end);
562
563 *write_data = ((*read_data--) << 8);
564 *write_data |= *read_data--;
565 *write_data_b++ = *write_data;
566 read_end = data - 1;
567 do {
568 *write_data_b = (*read_data--) << 8;
569 *write_data_b++ |= *read_data--;
570 } while (read_data < read_end);
571 gus_sample->loop_start += loop_length;
572 gus_sample->loop_end += dloop_length;
573 gus_sample->data_length = new_length;
574 gus_sample->modes ^= SAMPLE_PINGPONG | SAMPLE_REVERSE;
575 return 0;
576 }
577
578 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
579 return -1;
580 }
581
582 /* 16bit unsigned */
convert_16u(unsigned char * data,struct _sample * gus_sample)583 static int convert_16u(unsigned char *data, struct _sample *gus_sample) {
584 unsigned char *read_data = data;
585 unsigned char *read_end = data + gus_sample->data_length;
586 signed short int *write_data = NULL;
587
588 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
589 gus_sample->data = (short*)calloc(((gus_sample->data_length >> 1) + 2),
590 sizeof(signed short int));
591 if (gus_sample->data != NULL) {
592 write_data = gus_sample->data;
593 do {
594 *write_data = *read_data++;
595 *write_data++ |= ((*read_data++) ^ 0x80) << 8;
596 } while (read_data < read_end);
597 gus_sample->loop_start >>= 1;
598 gus_sample->loop_end >>= 1;
599 gus_sample->data_length >>= 1;
600 gus_sample->modes ^= SAMPLE_UNSIGNED;
601 return 0;
602 }
603 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
604 return -1;
605 }
606
607 /* 16bit unsigned ping pong */
convert_16up(unsigned char * data,struct _sample * gus_sample)608 static int convert_16up(unsigned char *data, struct _sample *gus_sample) {
609 unsigned long int loop_length = gus_sample->loop_end
610 - gus_sample->loop_start;
611 unsigned long int dloop_length = loop_length * 2;
612 unsigned long int new_length = gus_sample->data_length + dloop_length;
613 unsigned char *read_data = data;
614 unsigned char *read_end = data + gus_sample->loop_start;
615 signed short int *write_data = NULL;
616 signed short int *write_data_a = NULL;
617 signed short int *write_data_b = NULL;
618
619 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
620 gus_sample->data = (short*)calloc(((new_length >> 1) + 2),
621 sizeof(signed short int));
622 if (gus_sample->data != NULL) {
623 write_data = gus_sample->data;
624 do {
625 *write_data = (*read_data++);
626 *write_data++ |= ((*read_data++) ^ 0x80) << 8;
627 } while (read_data < read_end);
628
629 *write_data = (*read_data++);
630 *write_data |= ((*read_data++) ^ 0x80) << 8;
631 write_data_a = write_data + (dloop_length >> 1);
632 *write_data_a-- = *write_data;
633 write_data++;
634 write_data_b = write_data + (dloop_length >> 1);
635 read_end = data + gus_sample->loop_end;
636 do {
637 *write_data = (*read_data++);
638 *write_data |= ((*read_data++) ^ 0x80) << 8;
639 *write_data_a-- = *write_data;
640 *write_data_b++ = *write_data;
641 write_data++;
642 } while (read_data < read_end);
643
644 *write_data = (*read_data++);
645 *write_data |= ((*read_data++) ^ 0x80) << 8;
646 *write_data_b++ = *write_data;
647 read_end = data + gus_sample->data_length;
648 if (read_data != read_end) {
649 do {
650 *write_data_b = (*read_data++);
651 *write_data_b++ |= ((*read_data++) ^ 0x80) << 8;
652 } while (read_data < read_end);
653 }
654 gus_sample->loop_start += loop_length;
655 gus_sample->loop_end += dloop_length;
656 gus_sample->data_length = new_length;
657 gus_sample->modes ^= SAMPLE_PINGPONG;
658 gus_sample->loop_start >>= 1;
659 gus_sample->loop_end >>= 1;
660 gus_sample->data_length >>= 1;
661 return 0;
662 }
663
664 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
665 return -1;
666 }
667
668 /* 16bit unsigned reverse */
convert_16ur(unsigned char * data,struct _sample * gus_sample)669 static int convert_16ur(unsigned char *data, struct _sample *gus_sample) {
670 unsigned char *read_data = data;
671 unsigned char *read_end = data + gus_sample->data_length;
672 signed short int *write_data = NULL;
673 unsigned long int tmp_loop = 0;
674
675 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
676 gus_sample->data = (short*)calloc(((gus_sample->data_length >> 1) + 2),
677 sizeof(signed short int));
678 if (gus_sample->data != NULL) {
679 write_data = gus_sample->data + (gus_sample->data_length >> 1) - 1;
680 do {
681 *write_data = *read_data++;
682 *write_data-- |= ((*read_data++) ^ 0x80) << 8;
683 } while (read_data < read_end);
684 tmp_loop = gus_sample->loop_end;
685 gus_sample->loop_end = gus_sample->data_length - gus_sample->loop_start;
686 gus_sample->loop_start = gus_sample->data_length - tmp_loop;
687 gus_sample->loop_fraction = ((gus_sample->loop_fraction & 0x0f) << 4)
688 | ((gus_sample->loop_fraction & 0xf0) >> 4);
689 gus_sample->loop_start >>= 1;
690 gus_sample->loop_end >>= 1;
691 gus_sample->data_length >>= 1;
692 gus_sample->modes ^= SAMPLE_REVERSE | SAMPLE_UNSIGNED;
693 return 0;
694 }
695 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
696 return -1;
697 }
698
699 /* 16bit unsigned reverse ping pong */
convert_16urp(unsigned char * data,struct _sample * gus_sample)700 static int convert_16urp(unsigned char *data, struct _sample *gus_sample) {
701 unsigned long int loop_length = gus_sample->loop_end
702 - gus_sample->loop_start;
703 unsigned long int dloop_length = loop_length * 2;
704 unsigned long int new_length = gus_sample->data_length + dloop_length;
705 unsigned char *read_data = data + gus_sample->data_length - 1;
706 unsigned char *read_end = data + gus_sample->loop_end;
707 signed short int *write_data = NULL;
708 signed short int *write_data_a = NULL;
709 signed short int *write_data_b = NULL;
710
711 SAMPLE_CONVERT_DEBUG(__FUNCTION__);
712 gus_sample->data = (short*)calloc(((new_length >> 1) + 2),
713 sizeof(signed short int));
714 if (gus_sample->data != NULL) {
715 write_data = gus_sample->data;
716 do {
717 *write_data = ((*read_data--) ^ 0x80) << 8;
718 *write_data++ |= *read_data--;
719 } while (read_data < read_end);
720
721 *write_data = ((*read_data--) ^ 0x80) << 8;
722 *write_data |= *read_data--;
723 write_data_a = write_data + (dloop_length >> 1);
724 *write_data_a-- = *write_data;
725 write_data++;
726 write_data_b = write_data + (dloop_length >> 1);
727 read_end = data + gus_sample->loop_start;
728 do {
729 *write_data = ((*read_data--) ^ 0x80) << 8;
730 *write_data |= *read_data--;
731 *write_data_a-- = *write_data;
732 *write_data_b++ = *write_data;
733 write_data++;
734 } while (read_data < read_end);
735
736 *write_data = ((*read_data--) ^ 0x80) << 8;
737 *write_data |= *read_data--;
738 *write_data_b++ = *write_data;
739 read_end = data - 1;
740 do {
741 *write_data_b = ((*read_data--) ^ 0x80) << 8;
742 *write_data_b++ |= *read_data--;
743 } while (read_data < read_end);
744 gus_sample->loop_start += loop_length;
745 gus_sample->loop_end += dloop_length;
746 gus_sample->data_length = new_length;
747 gus_sample->modes ^= SAMPLE_PINGPONG | SAMPLE_REVERSE | SAMPLE_UNSIGNED;
748 return 0;
749 }
750
751 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to parse sample", errno);
752 return -1;
753 }
754
755 /* sample loading */
756
load_gus_pat(const char * filename)757 struct _sample * Instruments::load_gus_pat(const char *filename)
758 {
759 unsigned char *gus_patch;
760 unsigned long int gus_size;
761 unsigned long int gus_ptr;
762 unsigned char no_of_samples;
763 struct _sample *gus_sample = NULL;
764 struct _sample *first_gus_sample = NULL;
765 unsigned long int i = 0;
766
767 int (*do_convert[])(unsigned char *data, struct _sample *gus_sample) = {
768 convert_8s,
769 convert_16s,
770 convert_8u,
771 convert_16u,
772 convert_8sp,
773 convert_16sp,
774 convert_8up,
775 convert_16up,
776 convert_8sr,
777 convert_16sr,
778 convert_8ur,
779 convert_16ur,
780 convert_8srp,
781 convert_16srp,
782 convert_8urp,
783 convert_16urp
784 };
785 unsigned long int tmp_loop;
786
787 SAMPLE_CONVERT_DEBUG(__FUNCTION__); SAMPLE_CONVERT_DEBUG(filename);
788
789 if ((gus_patch = _WM_BufferFile(sfreader, filename, &gus_size)) == NULL) {
790 return NULL;
791 }
792 if (gus_size < 239) {
793 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0);
794 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, 0);
795 free(gus_patch);
796 return NULL;
797 }
798 if (memcmp(gus_patch, "GF1PATCH110\0ID#000002", 22)
799 && memcmp(gus_patch, "GF1PATCH100\0ID#000002", 22)) {
800 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, "(unsupported format)",
801 0);
802 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, 0);
803 free(gus_patch);
804 return NULL;
805 }
806 if (gus_patch[82] > 1) {
807 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, "(unsupported format)",
808 0);
809 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, 0);
810 free(gus_patch);
811 return NULL;
812 }
813 if (gus_patch[151] > 1) {
814 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, "(unsupported format)",
815 0);
816 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, 0);
817 free(gus_patch);
818 return NULL;
819 }
820
821 GUSPAT_FILENAME_DEBUG(filename); GUSPAT_INT_DEBUG("voices",gus_patch[83]);
822
823 no_of_samples = gus_patch[198];
824 gus_ptr = 239;
825 while (no_of_samples) {
826 unsigned long int tmp_cnt;
827 if (first_gus_sample == NULL) {
828 first_gus_sample = (struct _sample*)malloc(sizeof(struct _sample));
829 gus_sample = first_gus_sample;
830 } else {
831 gus_sample->next = (struct _sample*)malloc(sizeof(struct _sample));
832 gus_sample = gus_sample->next;
833 }
834 if (gus_sample == NULL) {
835 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, NULL, 0);
836 _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, 0);
837 free(gus_patch);
838 return NULL;
839 }
840
841 gus_sample->next = NULL;
842 gus_sample->loop_fraction = gus_patch[gus_ptr + 7];
843 gus_sample->data_length = (gus_patch[gus_ptr + 11] << 24)
844 | (gus_patch[gus_ptr + 10] << 16)
845 | (gus_patch[gus_ptr + 9] << 8) | gus_patch[gus_ptr + 8];
846 gus_sample->loop_start = (gus_patch[gus_ptr + 15] << 24)
847 | (gus_patch[gus_ptr + 14] << 16)
848 | (gus_patch[gus_ptr + 13] << 8) | gus_patch[gus_ptr + 12];
849 gus_sample->loop_end = (gus_patch[gus_ptr + 19] << 24)
850 | (gus_patch[gus_ptr + 18] << 16)
851 | (gus_patch[gus_ptr + 17] << 8) | gus_patch[gus_ptr + 16];
852 gus_sample->rate = (gus_patch[gus_ptr + 21] << 8)
853 | gus_patch[gus_ptr + 20];
854 gus_sample->freq_low = ((gus_patch[gus_ptr + 25] << 24)
855 | (gus_patch[gus_ptr + 24] << 16)
856 | (gus_patch[gus_ptr + 23] << 8) | gus_patch[gus_ptr + 22]);
857 gus_sample->freq_high = ((gus_patch[gus_ptr + 29] << 24)
858 | (gus_patch[gus_ptr + 28] << 16)
859 | (gus_patch[gus_ptr + 27] << 8) | gus_patch[gus_ptr + 26]);
860 gus_sample->freq_root = ((gus_patch[gus_ptr + 33] << 24)
861 | (gus_patch[gus_ptr + 32] << 16)
862 | (gus_patch[gus_ptr + 31] << 8) | gus_patch[gus_ptr + 30]);
863
864 /* This is done this way instead of ((freq * 1024) / rate) to avoid 32bit overflow. */
865 /* Result is 0.001% inacurate */
866 gus_sample->inc_div = ((gus_sample->freq_root * 512) / gus_sample->rate) * 2;
867
868 #if 0
869 /* We dont use this info at this time, kept in here for info */
870 printf("\rTremolo Sweep: %i, Rate: %i, Depth %i\n",
871 gus_patch[gus_ptr+49], gus_patch[gus_ptr+50], gus_patch[gus_ptr+51]);
872 printf("\rVibrato Sweep: %i, Rate: %i, Depth %i\n",
873 gus_patch[gus_ptr+52], gus_patch[gus_ptr+53], gus_patch[gus_ptr+54]);
874 #endif
875 gus_sample->modes = gus_patch[gus_ptr + 55];
876 GUSPAT_START_DEBUG(); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_16BIT, "16bit "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_UNSIGNED, "Unsigned "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_LOOP, "Loop "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_PINGPONG, "PingPong "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_REVERSE, "Reverse "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_SUSTAIN, "Sustain "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_ENVELOPE, "Envelope "); GUSPAT_MODE_DEBUG(gus_patch[gus_ptr+55], SAMPLE_CLAMPED, "Clamped "); GUSPAT_END_DEBUG();
877
878 if (gus_sample->loop_start > gus_sample->loop_end) {
879 tmp_loop = gus_sample->loop_end;
880 gus_sample->loop_end = gus_sample->loop_start;
881 gus_sample->loop_start = tmp_loop;
882 gus_sample->loop_fraction =
883 ((gus_sample->loop_fraction & 0x0f) << 4)
884 | ((gus_sample->loop_fraction & 0xf0) >> 4);
885 }
886
887 /*
888 FIXME: Experimental Hacky Fix
889
890 This looks for "dodgy" release envelope settings that faulty editors
891 may have set and attempts to corrects it.
892 if (fix_release)
893 Lets make this automatic ...
894 */
895 {
896 /*
897 After studying faulty gus_pats this way may work better
898 Testing to determine if any further adjustments are required
899 */
900 if (env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 41]]) {
901 unsigned char tmp_hack_rate = 0;
902
903 if (env_time_table[gus_patch[gus_ptr + 41]] < env_time_table[gus_patch[gus_ptr + 42]]) {
904 // 1 2 3
905 tmp_hack_rate = gus_patch[gus_ptr + 40];
906 gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 42];
907 gus_patch[gus_ptr + 42] = tmp_hack_rate;
908 } else if (env_time_table[gus_patch[gus_ptr + 41]] == env_time_table[gus_patch[gus_ptr + 42]]) {
909 // 1 2 2
910 tmp_hack_rate = gus_patch[gus_ptr + 40];
911 gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 42];
912 gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 42];
913 gus_patch[gus_ptr + 42] = tmp_hack_rate;
914
915 } else {
916 if (env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 42]]) {
917 // 1 3 2
918 tmp_hack_rate = gus_patch[gus_ptr + 40];
919 gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 41];
920 gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 42];
921 gus_patch[gus_ptr + 42] = tmp_hack_rate;
922 } else {
923 // 2 3 1 or 1 2 1
924 tmp_hack_rate = gus_patch[gus_ptr + 40];
925 gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 41];
926 gus_patch[gus_ptr + 41] = tmp_hack_rate;
927 }
928 }
929 } else if (env_time_table[gus_patch[gus_ptr + 41]] < env_time_table[gus_patch[gus_ptr + 42]]) {
930 unsigned char tmp_hack_rate = 0;
931
932 if (env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 42]]) {
933 // 2 1 3
934 tmp_hack_rate = gus_patch[gus_ptr + 40];
935 gus_patch[gus_ptr + 40] = gus_patch[gus_ptr + 42];
936 gus_patch[gus_ptr + 42] = gus_patch[gus_ptr + 41];
937 gus_patch[gus_ptr + 41] = tmp_hack_rate;
938 } else {
939 // 3 1 2
940 tmp_hack_rate = gus_patch[gus_ptr + 41];
941 gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 42];
942 gus_patch[gus_ptr + 42] = tmp_hack_rate;
943 }
944 }
945
946 #if 0
947 if ((env_time_table[gus_patch[gus_ptr + 40]] < env_time_table[gus_patch[gus_ptr + 41]]) && (env_time_table[gus_patch[gus_ptr + 41]] == env_time_table[gus_patch[gus_ptr + 42]])) {
948 uint8_t tmp_hack_rate = 0;
949 tmp_hack_rate = gus_patch[gus_ptr + 41];
950 gus_patch[gus_ptr + 41] = gus_patch[gus_ptr + 40];
951 gus_patch[gus_ptr + 42] = gus_patch[gus_ptr + 40];
952 gus_patch[gus_ptr + 40] = tmp_hack_rate;
953 tmp_hack_rate = gus_patch[gus_ptr + 47];
954 gus_patch[gus_ptr + 47] = gus_patch[gus_ptr + 46];
955 gus_patch[gus_ptr + 48] = gus_patch[gus_ptr + 46];
956 gus_patch[gus_ptr + 46] = tmp_hack_rate;
957 }
958 #endif
959 }
960
961 for (i = 0; i < 6; i++) {
962 GUSPAT_INT_DEBUG("Envelope #",i);
963 if (gus_sample->modes & SAMPLE_ENVELOPE) {
964 unsigned char env_rate = gus_patch[gus_ptr + 37 + i];
965 gus_sample->env_target[i] = 16448 * gus_patch[gus_ptr + 43 + i];
966 GUSPAT_INT_DEBUG("Envelope Level",gus_patch[gus_ptr+43+i]); GUSPAT_FLOAT_DEBUG("Envelope Time",env_time_table[env_rate]);
967 gus_sample->env_rate[i] = (signed long int) (4194303.0
968 / ((float) _WM_SampleRate * env_time_table[env_rate]));
969 GUSPAT_INT_DEBUG("Envelope Rate",gus_sample->env_rate[i]); GUSPAT_INT_DEBUG("GUSPAT Rate",env_rate);
970 if (gus_sample->env_rate[i] == 0) {
971 _WM_ERROR_NEW("Warning: found invalid envelope(%lu) rate setting in %s. Using %f instead.\n",
972 i, filename, env_time_table[63]);
973 gus_sample->env_rate[i] = (signed long int) (4194303.0
974 / ((float) _WM_SampleRate * env_time_table[63]));
975 GUSPAT_FLOAT_DEBUG("Envelope Time",env_time_table[63]);
976 }
977 } else {
978 gus_sample->env_target[i] = 4194303;
979 gus_sample->env_rate[i] = (signed long int) (4194303.0
980 / ((float) _WM_SampleRate * env_time_table[63]));
981 GUSPAT_FLOAT_DEBUG("Envelope Time",env_time_table[63]);
982 }
983 }
984
985 gus_sample->env_target[6] = 0;
986 gus_sample->env_rate[6] = (signed long int) (4194303.0
987 / ((float) _WM_SampleRate * env_time_table[63]));
988
989 gus_ptr += 96;
990 tmp_cnt = gus_sample->data_length;
991
992 if (do_convert[(((gus_sample->modes & 0x18) >> 1)
993 | (gus_sample->modes & 0x03))](&gus_patch[gus_ptr], gus_sample)
994 == -1) {
995 free(gus_patch);
996 return NULL;
997 }
998
999 /*
1000 Test and set decay expected decay time after a note off
1001 NOTE: This sets samples for full range decay
1002 */
1003 if (gus_sample->modes & SAMPLE_ENVELOPE) {
1004 double samples_f = 0.0;
1005
1006 if (gus_sample->modes & SAMPLE_CLAMPED) {
1007 samples_f = (4194301.0 - (float)gus_sample->env_target[5]) / gus_sample->env_rate[5];
1008 } else {
1009 if (gus_sample->modes & SAMPLE_SUSTAIN) {
1010 samples_f = (4194301.0 - (float)gus_sample->env_target[3]) / gus_sample->env_rate[3];
1011 samples_f += (float)(gus_sample->env_target[3] - gus_sample->env_target[4]) / gus_sample->env_rate[4];
1012 } else {
1013 samples_f = (4194301.0 - (float)gus_sample->env_target[4]) / gus_sample->env_rate[4];
1014 }
1015 samples_f += (float)(gus_sample->env_target[4] - gus_sample->env_target[5]) / gus_sample->env_rate[5];
1016 }
1017 samples_f += (float)gus_sample->env_target[5] / gus_sample->env_rate[6];
1018 }
1019
1020 gus_ptr += tmp_cnt;
1021 gus_sample->loop_start = (gus_sample->loop_start << 10)
1022 | (((gus_sample->loop_fraction & 0x0f) << 10) / 16);
1023 gus_sample->loop_end = (gus_sample->loop_end << 10)
1024 | (((gus_sample->loop_fraction & 0xf0) << 6) / 16);
1025 gus_sample->loop_size = gus_sample->loop_end - gus_sample->loop_start;
1026 gus_sample->data_length = gus_sample->data_length << 10;
1027 no_of_samples--;
1028 }
1029 free(gus_patch);
1030 return first_gus_sample;
1031 }
1032
1033 }
1034