1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 mod2midi.c
21
22 Mixer event -> MIDI event conversion
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif /* HAVE_CONFIG_H */
28 #ifndef NO_STRING_H
29 #include <string.h>
30 #else
31 #include <strings.h>
32 #endif
33
34 #include "timidity.h"
35 #include "common.h"
36 #include "instrum.h"
37 #include "playmidi.h"
38 #include "readmidi.h"
39 #include "tables.h"
40 #include "mod.h"
41 #include "output.h"
42 #include "controls.h"
43 #include "unimod.h"
44 #include "mod2midi.h"
45 #include "filter.h"
46 #include "math.h"
47 #include "freq.h"
48
49 /* Define this to show all the notes touched by a bending in the
50 * user interface's trace view. This is interesting but disabled
51 * because it needs tons of CPU power (tens of voices are activated
52 * but unaudible).
53 *
54 * EAW -- This is ancient code left over from an older method of handling
55 * pitch bends. This method spawned a separate note for every pitch the
56 * pitch bend covered, each with an initial keypressure of 1. As the pitch
57 * bend moved over a pitch covered by one of the spawned notes, the note
58 * covering the previous portion of the pitch bend was set back to a
59 * keypressure of 1, and the note covering the current portion of the pitch
60 * bend was set to 127. The original pitch bend was modified locally for
61 * each spawned note so as to bend each note for its portion of the pitch
62 * bend. This method had two major problems. First, spawning off that many
63 * notes, especially for multiple large pitch bends, resulted in a HUGE number
64 * of voices. This could sometimes max out the number of voices limit, and
65 * required a very large amount of CPU to process all the voices. The second
66 * problem was that it could sound very strange when the sample used for the
67 * pitch bend switched to a different sample due to a different note being
68 * used as the root of the pitch bend. When the new (current) pitch bend
69 * method was implemented, the older method was left as a define in order
70 * to visualize pitch bend ranges. It looked "interesting", and may have
71 * been useful early on for debugging some pitch bend related problems.
72 * However, it looks like noone ever tried redefining it again after changes
73 * were made elsewhere in the code, so it doesn't work quite right anymore,
74 * and pitch bends sound a bit strange when it is defined. I think that all
75 * of the ME_KEYPRESSURE related code in Voice_SetPeriod() may be left over
76 * from TRACE_SLIDE_NOTES support, so I have added some additional #ifdef's
77 * to get rid of code that looks like it might only be there for
78 * TRACE_SLIDE_NOTES support, and commented them as such. They do not appear
79 * to break the current pitch bend method.
80 */
81 /* #define TRACE_SLIDE_NOTES */
82
83 /* Define this to give a volume envelope to a MOD's notes. This
84 * could sound wrong with a few MODs, but gives richer sound most
85 * of the time. */
86 #define USE_ENVELOPE
87
88
89 #define SETMIDIEVENT(e, at, t, ch, pa, pb) \
90 { /* printf("%d %d " #t " %d %d\n", at, ch, pa, pb); */ \
91 (e).time = (at); (e).type = (t); \
92 (e).channel = (uint8)(ch); (e).a = (uint8)(pa); (e).b = (uint8)(pb); }
93
94 #define MIDIEVENT(at, t, ch, pa, pb) \
95 { MidiEvent event; SETMIDIEVENT(event, at, t, ch, pa, pb); \
96 readmidi_add_event(&event); }
97
98 /*
99 Clock
100 SampleRate := ----------
101 Period
102 */
103
104
105 #define NTSC_CLOCK 3579545.25
106 #define NTSC_RATE ((int32)(NTSC_CLOCK/428))
107
108 #define PAL_CLOCK 3546894.6
109 #define PAL_RATE ((int32)(PAL_CLOCK/428))
110
111 #define MOD_ROOT_NOTE 36
112
113 /* The internal bending register is 21-bits wide and it is made like this:
114 * _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
115 * | | | | | | | | | | | | | | | | | | | | | |
116 * | 8 bits | 8 bits | 5 bits |
117 * | note shift | fine tune |discarded|
118 * '---------------'---------------'---------'
119 *
120 * The note shift is an `offset' field: 128 = keep this note.
121 * To compute it, the values given to the pitch-wheel MIDI event are
122 * multiplied by the sensitivity. We want to be able to express a full
123 * 120 notes bending (8 bits for the note shift + 8 for the fine tune)
124 * with 14-bit pitch-wheel event, so we want a sensitivity value that
125 * forces the bottom 7 bits of the internal register to 0. This value
126 * is of course 128.
127 */
128
129 #define WHEEL_SENSITIVITY (1 << 7)
130 #define WHEEL_VALUE(bend) ((bend) / WHEEL_SENSITIVITY + 0x2000)
131
132
133 typedef struct _ModVoice
134 {
135 int sample; /* current sample ID */
136 int noteon; /* (-1 means OFF status) */
137 int time; /* time when note was activated */
138 int period; /* current frequency */
139 int wheel; /* current pitch wheel value */
140 int pan; /* current panning */
141 int vol; /* current volume */
142
143 int32 noteson[4]; /* bit map for notes 0-127 */
144 }
145 ModVoice;
146
147 static void mod_change_tempo (int32 at, int bpm);
148 static int period2note (int period, int *finetune);
149
150 static ModVoice ModV[MOD_NUM_VOICES];
151 static int at;
152
153 /******************** bitmap handling macros **********************************/
154
155 #define bitmapGet(map, n) ((map)[(n) >> 5] & (1 << ((n) & 31)))
156 #define bitmapSet(map, n) ((map)[(n) >> 5] |= (1 << ((n) & 31)))
157 #define bitmapClear(map) ((map)[0] = (map)[1] = (map)[2] = (map)[3] = 0)
158
159 static char significantDigitsLessOne[256] = {
160 -1, /* 1 */
161 0, /* 2 */
162 1, 1, /* 4 */
163 2, 2, 2, 2, /* 8 */
164 3, 3, 3, 3, 3, 3, 3, 3, /* 16 */
165 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 32 */
166
167 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* 64 */
168 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
169
170 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, /* 128 */
171 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
172 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
173 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
174
175 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* 256 */
176 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
177 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
178 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
179 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
180 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
181 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
182 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
183 };
184
185 /******************************************************************************/
186
187 void
mod_change_tempo(int32 at,int bpm)188 mod_change_tempo (int32 at, int bpm)
189 {
190 int32 tempo;
191 int c, a, b;
192
193 tempo = 60000000 / bpm;
194 c = (tempo & 0xff);
195 a = ((tempo >> 8) & 0xff);
196 b = ((tempo >> 16) & 0xff);
197 MIDIEVENT (at, ME_TEMPO, c, b, a);
198 }
199
200 int
period2note(int period,int * finetune)201 period2note (int period, int *finetune)
202 {
203 static int period_table[121] =
204 {
205 /* C C# D D# E F F# G G# A A# B */
206 13696,12928,12192,11520,10848,10240, 9664, 9120, 8608, 8096, 7680, 7248,
207 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4048, 3840, 3624,
208 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2024, 1920, 1812,
209 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906,
210 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
211 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
212 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
213 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
214 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28,
215 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14,
216
217 -100 /* just a guard */
218 };
219
220 int note;
221 int l, r, m;
222
223 if (period < 14 || period > 13696)
224 {
225 ctl->cmsg(CMSG_WARNING, VERB_NOISY, "BAD period %d", period);
226 *finetune = 0;
227 return -1;
228 }
229
230 /* bin search */
231 l = 0;
232 r = 120;
233 while (l < r)
234 {
235 m = (l + r) / 2;
236 if (period_table[m] >= period)
237 l = m + 1;
238 else
239 r = m;
240 }
241 note = l - 1;
242
243 /*
244 * 112 >= note >= 0
245 * period_table[note] >= period > period_table[note + 1]
246 */
247
248 if (period_table[note] == period)
249 *finetune = 0;
250 else {
251 /* Pick the closest note even if it is higher than this one.
252 * (e.g. 721 - 720 < 762 - 721 ----> pick 720) */
253 if (period - period_table[note + 1] < period_table[note] - period)
254 note++;
255
256 /* fine tune completion */
257 *finetune = ((period_table[note] - period) << 8) /
258 (period_table[note] - period_table[note + 1]);
259
260 *finetune <<= 5;
261 }
262 return note;
263 }
264
265 /********** Interface to mod.c */
266
267 void
Voice_SetVolume(UBYTE v,UWORD vol)268 Voice_SetVolume (UBYTE v, UWORD vol)
269 {
270 if (v >= MOD_NUM_VOICES)
271 return;
272
273 /* MOD volume --> MIDI volume */
274 vol >>= 1;
275 /* if (vol < 0) vol = 0; *//* UNSIGNED! */
276 if (vol > 127) vol = 127;
277
278 if (ModV[v].vol != vol) {
279 ModV[v].vol = vol;
280 MIDIEVENT (at, ME_EXPRESSION, v, vol, 0);
281 }
282 }
283
284 void
Voice_SetPeriod(UBYTE v,ULONG period)285 Voice_SetPeriod (UBYTE v, ULONG period)
286 {
287 int new_noteon, bend;
288
289 if (v >= MOD_NUM_VOICES)
290 return;
291
292 ModV[v].period = period;
293 if (ModV[v].noteon < 0)
294 return;
295
296 new_noteon = period2note (ModV[v].period, &bend);
297 if (new_noteon >= 0) {
298 #ifndef TRACE_SLIDE_NOTES
299 bend += (new_noteon - ModV[v].noteon) << 13;
300 new_noteon = ModV[v].noteon;
301 #endif
302 bend = WHEEL_VALUE(bend);
303 }
304
305 if (ModV[v].noteon != new_noteon)
306 {
307 /* EAW -- I think this is only here for TRACE_SLIDE_NOTES support? */
308 #ifdef TRACE_SLIDE_NOTES
309 MIDIEVENT(at, ME_KEYPRESSURE, v, ModV[v].noteon, 1);
310 #endif
311
312 if (new_noteon < 0)
313 {
314 ctl->cmsg(CMSG_WARNING, VERB_NOISY,
315 "Strange period %d",
316 ModV[v].period);
317 return;
318 }
319
320 /* EAW -- I think this is only here for TRACE_SLIDE_NOTES support? */
321 #ifdef TRACE_SLIDE_NOTES
322 else if (!bitmapGet(ModV[v].noteson, new_noteon))
323 {
324 MIDIEVENT(ModV[v].time, ME_NOTEON, v, new_noteon, 1);
325 bitmapSet(ModV[v].noteson, new_noteon);
326 }
327 #endif
328 }
329
330 if (ModV[v].wheel != bend)
331 {
332 ModV[v].wheel = bend;
333 MIDIEVENT (at, ME_PITCHWHEEL, v, bend & 0x7F, (bend >> 7) & 0x7F);
334 }
335
336 /* EAW -- I think this is only here for TRACE_SLIDE_NOTES support? */
337 #ifdef TRACE_SLIDE_NOTES
338 if (ModV[v].noteon != new_noteon)
339 {
340 MIDIEVENT(at, ME_KEYPRESSURE, v, new_noteon, 127);
341 ModV[v].noteon = new_noteon;
342 }
343 #endif
344 }
345
346 void
Voice_SetPanning(UBYTE v,ULONG pan)347 Voice_SetPanning (UBYTE v, ULONG pan)
348 {
349 if (v >= MOD_NUM_VOICES)
350 return;
351 if (pan == PAN_SURROUND)
352 pan = PAN_CENTER; /* :-( */
353
354 if (pan != ModV[v].pan) {
355 ModV[v].pan = pan;
356 MIDIEVENT(at, ME_PAN, v, pan * 127 / PAN_RIGHT, 0);
357 }
358 }
359
360 void
Voice_Play(UBYTE v,SAMPLE * s,ULONG start)361 Voice_Play (UBYTE v, SAMPLE * s, ULONG start)
362 {
363 int new_noteon, bend;
364 if (v >= MOD_NUM_VOICES)
365 return;
366
367 if (ModV[v].noteon != -1)
368 Voice_Stop (v);
369
370 new_noteon = period2note (ModV[v].period, &bend);
371 if (new_noteon < 0) {
372 ctl->cmsg(CMSG_WARNING, VERB_NOISY,
373 "Strange period %d",
374 ModV[v].period);
375 return;
376 }
377 bend = WHEEL_VALUE(bend);
378
379 ModV[v].noteon = new_noteon;
380 ModV[v].time = at;
381 bitmapSet(ModV[v].noteson, new_noteon);
382
383 if (ModV[v].sample != s->id)
384 {
385 ModV[v].sample = s->id;
386 MIDIEVENT(at, ME_SET_PATCH, v, ModV[v].sample, 0);
387 }
388
389 if (start > 0)
390 {
391 int a, b;
392 a = (start & 0xff);
393 b = ((start >> 8) & 0xff);
394 MIDIEVENT (at, ME_PATCH_OFFS, v, a, b);
395 }
396
397 if (ModV[v].wheel != bend)
398 {
399 ModV[v].wheel = bend;
400 MIDIEVENT (at, ME_PITCHWHEEL, v, bend & 0x7F, (bend >> 7) & 0x7F);
401 }
402
403 MIDIEVENT (at, ME_NOTEON, v, ModV[v].noteon, 127);
404 }
405
406 void
Voice_Stop(UBYTE v)407 Voice_Stop (UBYTE v)
408 {
409 int32 j;
410 int n;
411
412 if (v >= MOD_NUM_VOICES)
413 return;
414
415 if (ModV[v].noteon == -1)
416 return;
417
418 #define TURN_OFF_8(base, ofs) \
419 while (j & (0xFFL << (ofs))) { \
420 n = ofs + significantDigitsLessOne[(unsigned char) (j >> (ofs))]; \
421 MIDIEVENT (at, ME_NOTEOFF, v, (base) + n, 63); \
422 j ^= 1 << n; \
423 }
424
425 #define TURN_OFF_32(base) \
426 do { \
427 TURN_OFF_8((base), 24) \
428 TURN_OFF_8((base), 16) \
429 TURN_OFF_8((base), 8) \
430 TURN_OFF_8((base), 0) \
431 } while(0)
432
433 if ((j = ModV[v].noteson[0]) != 0) TURN_OFF_32(0);
434 if ((j = ModV[v].noteson[1]) != 0) TURN_OFF_32(32);
435 if ((j = ModV[v].noteson[2]) != 0) TURN_OFF_32(64);
436 if ((j = ModV[v].noteson[3]) != 0) TURN_OFF_32(96);
437 bitmapClear(ModV[v].noteson);
438 ModV[v].noteon = -1;
439 }
440
441 BOOL
Voice_Stopped(UBYTE v)442 Voice_Stopped (UBYTE v)
443 {
444 return (v >= MOD_NUM_VOICES) || (ModV[v].noteon == -1);
445 }
446
447 void
Voice_TickDone()448 Voice_TickDone ()
449 {
450 at++;
451 }
452
453 void
Voice_NewTempo(UWORD bpm,UWORD sngspd)454 Voice_NewTempo (UWORD bpm, UWORD sngspd)
455 {
456 mod_change_tempo(at, bpm);
457 }
458
459 void
Voice_EndPlaying()460 Voice_EndPlaying ()
461 {
462 int v;
463
464 at += 48 / (60.0/125.0); /* 1 second */
465 for(v = 0; v < MOD_NUM_VOICES; v++)
466 MIDIEVENT(at, ME_ALL_NOTES_OFF, v, 0, 0);
467 }
468
469 void
Voice_StartPlaying()470 Voice_StartPlaying ()
471 {
472 int v;
473
474 readmidi_set_track(0, 1);
475
476 current_file_info->divisions = 24;
477
478 for(v = 0; v < MOD_NUM_VOICES; v++)
479 {
480 ModV[v].sample = -1;
481 ModV[v].noteon = -1;
482 ModV[v].time = -1;
483 ModV[v].period = 0;
484 ModV[v].wheel = 0x2000;
485 ModV[v].vol = 127;
486 ModV[v].pan = (v & 1) ? 127 : 0;
487 bitmapClear(ModV[v].noteson);
488
489 MIDIEVENT(0, ME_PAN, v, ModV[v].pan, 0);
490 MIDIEVENT(0, ME_SET_PATCH, v, 1, 0);
491 MIDIEVENT(0, ME_MAINVOLUME, v, 127, 0);
492 MIDIEVENT(0, ME_EXPRESSION, v, 127, 0);
493 /* MIDIEVENT(0, ME_MONO, v, 0, 0); */
494 MIDIEVENT(0, ME_RPN_LSB, v, 0, 0);
495 MIDIEVENT(0, ME_RPN_MSB, v, 0, 0);
496 MIDIEVENT(0, ME_DATA_ENTRY_MSB, v, WHEEL_SENSITIVITY, 0);
497 MIDIEVENT(0, ME_DRUMPART, v, 0, 0);
498 }
499
500 at = 1;
501 }
502
503 /* convert from 8bit value to fractional offset (15.15) */
env_offset(int offset)504 static int32 env_offset(int offset)
505 {
506 return (int32)offset << (7+15);
507 }
508
509 /* calculate ramp rate in fractional unit;
510 * diff = 8bit, time = msec
511 */
env_rate(int diff,double msec)512 static int32 env_rate(int diff, double msec)
513 {
514 double rate;
515
516 if(msec < 6)
517 msec = 6;
518 if(diff == 0)
519 diff = 255;
520 diff <<= (7+15);
521 rate = ((double)diff / play_mode->rate) * control_ratio * 1000.0 / msec;
522 if(fast_decay)
523 rate *= 2;
524 return (int32)rate;
525 }
526
shrink_huge_sample(Sample * sp)527 void shrink_huge_sample (Sample *sp)
528 {
529 sample_t *orig_data;
530 sample_t *new_data;
531 unsigned int rate, new_rate;
532 uint32 data_length, new_data_length;
533 double loop_start, loop_end;
534 double scale, scale2;
535 double x, xfrac;
536 double y;
537 sample_t y1, y2, y3, y4;
538 uint32 i, xtrunc;
539
540 data_length = sp->data_length;
541 if (data_length < (1 << FRACTION_BITS) - 1)
542 return;
543 loop_start = sp->loop_start;
544 loop_end = sp->loop_end;
545 rate = sp->sample_rate;
546
547 scale = ((1 << (31 - FRACTION_BITS)) - 2.0) / data_length;
548 new_rate = rate * scale;
549 scale = new_rate / (float) rate;
550 scale2 = (float) rate / new_rate;
551
552 new_data_length = data_length * scale;
553 loop_start *= scale;
554 loop_end *= scale;
555
556 ctl->cmsg(CMSG_INFO, VERB_NORMAL,
557 "Sample too large (%ld): resampling down to %ld samples",
558 data_length, new_data_length);
559
560 orig_data = sp->data;
561 new_data = calloc(new_data_length + 1, sizeof(sample_t));
562
563 new_data[0] = orig_data[0];
564 for (i = 1; i < new_data_length; i++)
565 {
566 x = i * scale2;
567 xtrunc = (uint32) x;
568 xfrac = x - xtrunc;
569
570 if (xtrunc >= data_length - 1)
571 {
572 if (xtrunc == data_length)
573 new_data[i] = orig_data[data_length];
574 else /* linear interpolation */
575 {
576 y2 = orig_data[data_length - 1];
577 y3 = orig_data[data_length];
578 new_data[i] = ceil((y2 + (y3 - y2) * xfrac) - 0.5);
579 }
580 }
581 else /* cspline interpolation */
582 {
583 y1 = orig_data[xtrunc - 1];
584 y2 = orig_data[xtrunc];
585 y3 = orig_data[xtrunc + 1];
586 y4 = orig_data[xtrunc + 2];
587
588 y = (6*y3 + (5*y4 - 11*y3 + 7*y2 - y1) *
589 0.25 * (xfrac+1) * (xfrac-1)) * xfrac;
590 y = (((6*y2 + (5*y1 - 11*y2 + 7*y3 - y4) *
591 0.25 * xfrac * (xfrac-2)) * (1-xfrac)) + y) / 6.0;
592
593 if (y > 32767) y = 32767;
594 if (y < -32767) y = -32767;
595
596 new_data[i] = ceil(y - 0.5);
597 }
598 }
599
600 free(sp->data);
601 sp->data = new_data;
602 sp->sample_rate = new_rate;
603
604 sp->data_length = new_data_length << FRACTION_BITS;
605 sp->loop_start = loop_start * (1 << FRACTION_BITS);
606 sp->loop_end = loop_end * (1 << FRACTION_BITS);
607 }
608
load_module_samples(SAMPLE * s,int numsamples,int ntsc)609 void load_module_samples (SAMPLE * s, int numsamples, int ntsc)
610 {
611 int i;
612
613 for(i = 1; numsamples--; i++, s++)
614 {
615 Sample *sp;
616 char name[23];
617
618 if(!s->data)
619 continue;
620
621 ctl->cmsg(CMSG_INFO, VERB_DEBUG,
622 "MOD Sample %d (%.22s)", i, s->samplename);
623
624 special_patch[i] =
625 (SpecialPatch *)safe_malloc(sizeof(SpecialPatch));
626 special_patch[i]->type = INST_MOD;
627 special_patch[i]->samples = 1;
628 special_patch[i]->sample = sp =
629 (Sample *)safe_malloc(sizeof(Sample));
630 memset(sp, 0, sizeof(Sample));
631 memset(name, 0, 23 * sizeof(char));
632 if (s->samplename != NULL)
633 {
634 strncpy(name, s->samplename, 22);
635 name[22] = '\0';
636 code_convert(name, NULL, 23, NULL, "ASCII");
637 }
638 if(name[0] == '\0')
639 special_patch[i]->name = NULL;
640 else
641 special_patch[i]->name = safe_strdup(name);
642 special_patch[i]->sample_offset = 0;
643
644 sp->data = (sample_t *)s->data;
645 sp->data_alloced = 1;
646 sp->data_length = s->length;
647 sp->loop_start = s->loopstart;
648 sp->loop_end = s->loopend;
649
650 /* The sample must be padded out by 1 extra sample, so that
651 the interpolation routines won't cause a "pop" by reading
652 random data beyond data_length */
653 sp->data = (sample_t *) realloc(sp->data,
654 (sp->data_length + 1) *
655 sizeof(sample_t));
656 sp->data[sp->data_length] = 0;
657
658 /* Stereo instruments (SF_STEREO) are dithered by libunimod into mono */
659 sp->modes = MODES_UNSIGNED;
660 if (s->flags & SF_SIGNED) sp->modes ^= MODES_UNSIGNED;
661 if (s->flags & SF_LOOP) sp->modes ^= MODES_LOOPING;
662 if (s->flags & SF_BIDI) sp->modes ^= MODES_PINGPONG;
663 if (s->flags & SF_REVERSE) sp->modes ^= MODES_REVERSE;
664 if (s->flags & SF_16BITS) sp->modes ^= MODES_16BIT;
665
666 #ifdef USE_ENVELOPE
667 /* envelope (0,1:attack, 2:sustain, 3,4,5:release) */
668 sp->modes |= MODES_ENVELOPE;
669
670 /* attack */
671 sp->envelope_offset[0] = env_offset(255);
672 sp->envelope_rate[0] = env_rate(255, 0.0); /* fastest */
673 sp->envelope_offset[1] = sp->envelope_offset[0];
674 sp->envelope_rate[1] = 0; /* skip this stage */
675 /* sustain */
676 sp->envelope_offset[2] = sp->envelope_offset[1];
677 sp->envelope_rate[2] = 0;
678 /* release */
679 sp->envelope_offset[3] = env_offset(0);
680 sp->envelope_rate[3] = env_rate(255, 80.0); /* 80 msec */
681 sp->envelope_offset[4] = sp->envelope_offset[3];
682 sp->envelope_rate[4] = 0; /* skip this stage */
683 sp->envelope_offset[5] = sp->envelope_offset[4];
684 sp->envelope_rate[5] = 0; /* skip this stage, then the voice is
685 disappeared */
686 #endif
687 sp->sample_rate = PAL_RATE >> s->divfactor;
688 sp->low_freq = 0;
689 sp->high_freq = 0x7fffffff;
690 sp->root_freq = freq_table[MOD_ROOT_NOTE];
691 sp->volume = 1.0; /* I guess it should use globvol... */
692 sp->panning = s->panning == PAN_SURROUND ? 64 : s->panning * 128 / 255;
693 sp->note_to_use = 0;
694 sp->low_vel = 0;
695 sp->high_vel = 127;
696 sp->tremolo_sweep_increment =
697 sp->tremolo_phase_increment = sp->tremolo_depth =
698 sp->vibrato_sweep_increment = sp->vibrato_control_ratio = sp->vibrato_depth = 0;
699 sp->cutoff_freq = sp->resonance = sp->tremolo_to_pitch =
700 sp->tremolo_to_fc = sp->modenv_to_pitch = sp->modenv_to_fc =
701 sp->vel_to_fc = sp->key_to_fc = sp->vel_to_resonance = 0;
702 sp->envelope_velf_bpo = sp->modenv_velf_bpo =
703 sp->vel_to_fc_threshold = 64;
704 sp->key_to_fc_bpo = 60;
705 sp->scale_freq = 60;
706 sp->scale_factor = 1024;
707 memset(sp->envelope_velf, 0, sizeof(sp->envelope_velf));
708 memset(sp->envelope_keyf, 0, sizeof(sp->envelope_keyf));
709 memset(sp->modenv_velf, 0, sizeof(sp->modenv_velf));
710 memset(sp->modenv_keyf, 0, sizeof(sp->modenv_keyf));
711 memset(sp->modenv_rate, 0, sizeof(sp->modenv_rate));
712 memset(sp->modenv_offset, 0, sizeof(sp->modenv_offset));
713 sp->envelope_delay = sp->modenv_delay =
714 sp->tremolo_delay = sp->vibrato_delay = 0;
715 sp->sample_type = SF_SAMPLETYPE_MONO;
716 sp->sf_sample_link = -1;
717 sp->sf_sample_index = 0;
718
719 if (sp->data_length >= (1 << (31 - FRACTION_BITS)) - 1)
720 shrink_huge_sample(sp);
721 else
722 {
723 sp->data_length <<= FRACTION_BITS;
724 sp->loop_start <<= FRACTION_BITS;
725 sp->loop_end <<= FRACTION_BITS;
726 }
727
728 /* pitch detection for mod->midi file conversion and surround chorus */
729 if (play_mode->id_character == 'M' ||
730 opt_surround_chorus)
731 {
732 sp->chord = -1;
733 sp->root_freq_detected = freq_fourier(sp, &(sp->chord));
734 sp->transpose_detected =
735 assign_pitch_to_freq(sp->root_freq_detected) -
736 assign_pitch_to_freq(sp->root_freq / 1024.0);
737 }
738
739 /* If necessary do some anti-aliasing filtering */
740 if (antialiasing_allowed)
741 antialiasing((int16 *)sp->data, sp->data_length / 2,
742 sp->sample_rate, play_mode->rate);
743
744 s->data = NULL; /* Avoid free-ing */
745 s->id = i;
746 }
747 }
748