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