1 /***************************************************************************
2 ****************************************************************************
3 ****************************************************************************
4 *
5 * FunktrackerGOLD - By Jason Nunn
6 * Copyright (C) 1996,1998 Jason Nunn
7 *
8 * FunktrackerGOLD now comes under the GNU General Public License. Please
9 * read the COPYING notice in this distribution.
10 *
11 * ================================================================
12 * playback routines
13 *
14 ****************************************************************************
15 ****************************************************************************
16 ***************************************************************************/
17 #include "funktracker_defs.h"
18 #include "dsp_mixxer.h"
19
20 /*funk ptrs*/
21 tfunk_info funk_info;
22 tfunk_hr *funk_hr_ptr; /*header pointer*/
23 tslot *funk_pat_ptr;
24 void *funk_sam_ptrs[64]; /*sample pointers ptr*/
25 tfunk_chan funk_chan[MAXIMUM_CHANNELS];
26 void (*CARD_freq_convert)(int,long) = DSPi_freq_convert;
27 void (*CARD_volume_convert)(int,int,int) = DSPi_volume_convert;
28
29 /*******************************************
30 * private vars
31 *******************************************/
32 int note_table[64] =
33 {
34 13696,12928,12192,11520,10848,10240, 9664, 9120, 8608, 8128, 7680, 7248,
35 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624,
36 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1808,
37 1712, 1616, 1520, 1440, 1360, 1280, 1208, 1144, 1080, 1016, 960, 904,
38 856, 808, 760, 720, 680, 640, 600, 568, 536, 504, 480, 448,
39 0, 0, 0, 0
40 };
41
42 int com_volume_inc[16] =
43 {
44 1, 2, 3, 4, 5, 6, 7, 8,
45 10, 12, 16, 20, 24, 32, 48, 64
46 };
47
48 int com_sine_table[64] =
49 {
50 -6, -19, -31, -43, -55, -66, -76, -86,
51 -95,-103,-110,-116,-120,-124,-127,-128,
52 -128,-127,-124,-121,-116,-110,-103, -95,
53 -86, -77, -66, -55, -44, -32, -19, -7,
54 6, 18, 30, 42, 54, 65, 76, 85,
55 94, 102, 109, 115, 120, 124, 126, 127,
56 127, 126, 124, 121, 116, 110, 104, 96,
57 87, 77, 67, 56, 44, 32, 20, 8
58 };
59
60 int com_triangle_table[64] =
61 {
62 -4, -12, -20, -28, -36, -44, -52, -60,
63 -68, -76, -84, -92,-100,-108,-116,-124,
64 -124,-116,-108,-100, -92, -84, -76, -68,
65 -60, -52, -44, -36, -28, -20, -12, -4,
66 4, 12, 20, 28, 36, 44, 52, 60,
67 68, 76, 84, 92, 100, 108, 116, 124,
68 123, 115, 107, 99, 91, 83, 75, 67,
69 59, 51, 43, 35, 27, 19, 11, 3
70 };
71
72 int com_square_table[64] =
73 {
74 -64,-128,-128,-127,-127,-128,-128,-127,
75 -127,-128,-128,-127,-127,-128,-128,-127,
76 -127,-128,-128,-127,-127,-128,-128,-127,
77 -127,-128,-128,-127,-127,-128,-128, -64,
78 95, 127, 127, 126, 126, 127, 127, 126,
79 126, 127, 127, 126, 126, 127, 127, 126,
80 126, 127, 127, 126, 126, 127, 127, 126,
81 126, 127, 127, 126, 126, 127, 127, 95
82 };
83
84 int com_sawtooth_table[64] =
85 {
86 -1, -5, -9, -13, -17, -21, -25, -29,
87 -33, -37, -41, -45, -49, -53, -57, -61,
88 -65, -69, -73, -77, -81, -85, -89, -93,
89 -97,-101,-105,-109,-113,-117,-121,-125,
90 127, 123, 119, 115, 111, 107, 103, 99,
91 95, 91, 87, 83, 79, 75, 71, 67,
92 63, 59, 55, 51, 47, 43, 39, 35,
93 31, 27, 23, 19, 15, 11, 7, 3
94 };
95
96 int com_random_table[64] =
97 {
98 168, 167, 167, 165, 201, 201, 202, 201,
99 244, 244, 244, 244, 85, 82, 85, 85,
100 44, 44, 44, 44, 114, 114, 114, 114,
101 77, 77, 73, 77, 116, 116, 116, 116,
102 87, 87, 87, 87, 31, 31, 31, 31,
103 198, 198, 198, 198, 105, 104, 105, 105,
104 103, 105, 103, 103, 166, 166, 165, 166,
105 171, 172, 171, 171, 217, 217, 217, 217
106 };
107
108 int c_channel;
109 tslot *pattern_ptr; /*ptr to extract data from pattern*/
110
111 /**************************************************************************
112 ***************************************************************************
113 ***************************************************************************
114 ***************************************************************************
115 ***************************************************************************
116 *
117 * Tracker Code
118 *
119 ***************************************************************************
120 ***************************************************************************
121 ***************************************************************************
122 ***************************************************************************
123 **************************************************************************/
124
125 /**************************************************************************
126 *
127 **************************************************************************/
128
129 /***********************************
130 *
131 * ebx = ifreq, returns = eax
132 *
133 ***********************************/
ifreq_to_rfreq(long ifreq)134 long ifreq_to_rfreq(long ifreq)
135 {
136 if(ifreq > 0)
137 return (0x1b4f4d0 / ifreq);
138 else
139 return 0;
140 }
141
ifreq_to_rfreq_vib(long ifreq)142 long ifreq_to_rfreq_vib(long ifreq)
143 {
144 ifreq += funk_chan[c_channel].ifreq_vibrato;
145 if(ifreq <= 0) ifreq = 1;
146 return ifreq_to_rfreq(ifreq);
147 }
148
149 /***********************************
150 *
151 ***********************************/
volume_convert(void)152 void volume_convert(void)
153 {
154 if(funk_chan[c_channel].channel_kill == STOP)
155 CARD_volume_convert(c_channel,0,0);
156 else
157 CARD_volume_convert(
158 c_channel,
159 funk_chan[c_channel].rvolume,
160 funk_chan[c_channel].balance);
161 }
162
vol_to_realvol(void)163 void vol_to_realvol(void)
164 {
165 funk_chan[c_channel].rvolume = funk_chan[c_channel].volume;
166 }
167
vol_to_realvol_vib(void)168 void vol_to_realvol_vib(void)
169 {
170 funk_chan[c_channel].rvolume =
171 funk_chan[c_channel].volume + funk_chan[c_channel].volume_vibrato;
172 if(funk_chan[c_channel].rvolume < 0) funk_chan[c_channel].rvolume = 0;
173 if(funk_chan[c_channel].rvolume > 255) funk_chan[c_channel].rvolume = 255;
174 }
175
176 /***********************************
177 * bl = note, returns ebx = ifreq
178 ***********************************/
179 #define note_2_ifreq(note) note_table[note]
180
181 /***********************************
182 *
183 * misc. vibrato function used by
184 * frequency and volume functions
185 *
186 * al = waveform
187 * ah = amplitude
188 * cl = speed
189 * ebx = ptr to vibrato table
190 * returns al = value, ebx = ptr
191 *
192 ***********************************/
com_vib_func(int waveform,int amplitude,int speed,int * vib_table_ptr)193 int com_vib_func(int waveform,
194 int amplitude,
195 int speed,
196 int *vib_table_ptr)
197 {
198 register int tmp;
199
200 amplitude++;
201 switch(waveform)
202 {
203 case 1: /*triangle*/
204 tmp = com_triangle_table[*vib_table_ptr];
205 break;
206 case 2: /*square*/
207 tmp = com_square_table[*vib_table_ptr];
208 break;
209 case 3: /*sawtooth*/
210 tmp = com_sawtooth_table[*vib_table_ptr];
211 break;
212 case 4: /*random*/
213 tmp = com_random_table[*vib_table_ptr];
214 break;
215 default: /*sine*/
216 tmp = com_sine_table[*vib_table_ptr];
217 break;
218 }
219 *vib_table_ptr += (~speed & 0xf) + 1;
220 *vib_table_ptr &= 0x3f;
221 return (tmp * amplitude) >> 4;
222 }
223
224 /***********************************
225 *
226 * Decode values form slot patterns
227 *
228 ***********************************/
decode_sample_no(void)229 int decode_sample_no(void)
230 {
231 funk_chan[c_channel].sample =
232 ((pattern_ptr->not_sam & 0x3) << 4) + (pattern_ptr->sam_com >> 4);
233 return funk_chan[c_channel].sample;
234 }
235
decode_note_no(void)236 int decode_note_no(void)
237 {
238 return pattern_ptr->not_sam >> 2;
239 }
240
241 /***********************************
242 *
243 * for NOTE 3D: reload samples attrs
244 *
245 * returns sample volume
246 *
247 ***********************************/
reload_sample2(int sam_no)248 int reload_sample2(int sam_no)
249 {
250 register int tmp1;
251
252 funk_chan[c_channel].balance = funk_hr_ptr->funk_sb[sam_no].balance;
253
254 tmp1 = funk_hr_ptr->funk_sb[sam_no].pt_and_sop;
255 funk_chan[c_channel].port_type = tmp1 >> 4;
256 funk_chan[c_channel].sample_ofs_parm = tmp1 & 0xf;
257
258 tmp1 = funk_hr_ptr->funk_sb[sam_no].vv_waveform;
259 funk_chan[c_channel].vib_waveform = tmp1 >> 4;
260 funk_chan[c_channel].vol_vib_waveform = tmp1 & 0xf;
261
262 tmp1 = funk_hr_ptr->funk_sb[sam_no].rl_and_as;
263 funk_chan[c_channel].retrig_limit = tmp1 >> 4;
264 funk_chan[c_channel].arp_speed = tmp1 & 0xf;
265
266 return funk_hr_ptr->funk_sb[sam_no].volume;
267 }
268
reload_sample_attr(void)269 int reload_sample_attr(void)
270 {
271 return reload_sample2(decode_sample_no());
272 }
273
274 /***********************************
275 *
276 * returns sample volume
277 *
278 ***********************************/
do_retrig_sample(int sam_no)279 int do_retrig_sample(int sam_no)
280 {
281 if(funk_hr_ptr->funk_sb[sam_no].length > 0)
282 {
283 if(funk_hr_ptr->funk_sb[sam_no].start == 0xffffffff)
284 chmix[c_channel].funkctrl = 0x2; /*set funkctrl*/
285 else
286 chmix[c_channel].funkctrl = 0x3;
287 chmix[c_channel].sample_addr = funk_sam_ptrs[sam_no];
288 chmix[c_channel].start = funk_hr_ptr->funk_sb[sam_no].start;
289
290 if(chmix[c_channel].start > funk_hr_ptr->funk_sb[sam_no].length)
291 chmix[c_channel].start = funk_hr_ptr->funk_sb[sam_no].length;
292
293 chmix[c_channel].length = funk_hr_ptr->funk_sb[sam_no].length;
294 chmix[c_channel].sample_ptr = 0;
295 }
296 return reload_sample2(sam_no);
297 }
298
decode_sample(void)299 int decode_sample(void)
300 {
301 return do_retrig_sample(decode_sample_no());
302 }
303
304 /***********************************
305 *
306 ***********************************/
do_full_note(int note,int volume)307 void do_full_note(int note,int volume)
308 {
309 funk_chan[c_channel].note = note;
310 funk_chan[c_channel].volume = volume;
311 funk_chan[c_channel].ifreq = note_2_ifreq(note);
312 funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
313 vol_to_realvol();
314 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
315 volume_convert();
316 }
317
load_attr_active(int volume)318 void load_attr_active(int volume)
319 {
320 funk_chan[c_channel].volume = volume;
321 vol_to_realvol();
322 volume_convert();
323 }
324
325 /***********************************
326 *
327 ***********************************/
normal_decode_system(void)328 void normal_decode_system(void)
329 {
330 register int note,volume;
331
332 note = decode_note_no();
333 if(note == 0x3d) /*if ReLOad samples then ...*/
334 load_attr_active(reload_sample_attr());
335 else
336 {
337 volume = decode_sample();
338 if(note != 0x3e) /*if SAMPLE ONLY slot,then dont change note*/
339 {
340 funk_chan[c_channel].note_command = 0xf;
341 funk_chan[c_channel].volume_command = 0xf;
342 do_full_note(note,volume);
343 }
344 }
345 }
346
normal_decode_note(void)347 void normal_decode_note(void)
348 {
349 register int note,volume;
350
351 note = decode_note_no();
352 if(note == 0x3d) /*if ReLOad samples then ...*/
353 load_attr_active(reload_sample_attr());
354 else
355 {
356 volume = decode_sample();
357 if(note != 0x3e) /*if SAMPLE ONLY slot,then dont change note*/
358 {
359 funk_chan[c_channel].volume_command = 0xf;
360 do_full_note(note,volume);
361 }
362 }
363 }
364
normal_decode_volume(void)365 void normal_decode_volume(void)
366 {
367 register int note,volume;
368
369 note = decode_note_no();
370 if(note == 0x3d) /*if ReLOad samples then ...*/
371 load_attr_active(reload_sample_attr());
372 else
373 {
374 volume = decode_sample();
375 if(note != 0x3e) /*if SAMPLE ONLY slot,then dont change note*/
376 {
377 funk_chan[c_channel].note_command = 0xf;
378 do_full_note(note,volume);
379 }
380 }
381 }
382
383 /***********************************
384 *
385 ***********************************/
comc_decode(void)386 void comc_decode(void)
387 {
388 register int note,volume;
389
390 note = decode_note_no();
391 if(note == 0x3d) /*if ReLOad samples then ...*/
392 load_attr_active(reload_sample_attr());
393 else
394 {
395 volume = decode_sample();
396 if(note != 0x3e) /*if SAMPLE ONLY slot,then dont change note*/
397 {
398 funk_chan[c_channel].volume_command = 0xf;
399 funk_chan[c_channel].volume = volume;
400 funk_chan[c_channel].note = note;
401 funk_chan[c_channel].ifreq_portdest = note_2_ifreq(note);
402 funk_chan[c_channel].rfreq_portdest = ifreq_to_rfreq(funk_chan[c_channel].ifreq_portdest);
403 vol_to_realvol();
404 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
405 volume_convert();
406 }
407 }
408 }
409
410 /***********************************
411 *
412 ***********************************/
comi_decode(void)413 void comi_decode(void)
414 {
415 register int note,volume;
416
417 note = decode_note_no();
418 if(note == 0x3d) /*if ReLOad samples then ...*/
419 funk_chan[c_channel].volume_portdest = reload_sample_attr();
420 else
421 {
422 volume = decode_sample();
423 if(note != 0x3e) /*if SAMPLE ONLY slot,then dont change note*/
424 {
425 funk_chan[c_channel].note_command = 0xf;
426 funk_chan[c_channel].volume_portdest = volume;
427 funk_chan[c_channel].note = note;
428 funk_chan[c_channel].ifreq = note_2_ifreq(note);
429 funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
430 vol_to_realvol();
431 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
432 volume_convert();
433 }
434 else
435 {
436 funk_chan[c_channel].volume_portdest = volume;
437 }
438 }
439 }
440
441 /***************************************************************************
442 *
443 ***************************************************************************/
444 #define IPORT_TOP_LIM 448
445 #define RPORT_TOP_LIM (0x1b4f4d0 / 448)
446
447 #define IPORT_BOT_LIM 13696
448 #define RPORT_BOT_LIM (0x1b4f4d0 / 13696)
449
450 /***********************************
451 *0Com A: port up (modified as from R2)
452 *
453 * com_val : 00000000
454 * \ rate /
455 *
456 ***********************************/
com_port_up_log(int note_com_val)457 void com_port_up_log(int note_com_val)
458 {
459 funk_chan[c_channel].ifreq -= (note_com_val + 1) << 2;
460 if(funk_chan[c_channel].ifreq <= IPORT_TOP_LIM)
461 {
462 funk_chan[c_channel].note_command = 0xf;
463 funk_chan[c_channel].ifreq = IPORT_TOP_LIM;
464 }
465 funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
466 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
467 }
468
com_port_up_lin(int note_com_val)469 void com_port_up_lin(int note_com_val)
470 {
471 funk_chan[c_channel].rfreq += (note_com_val + 1) << 3;
472 if(funk_chan[c_channel].rfreq >= RPORT_TOP_LIM)
473 {
474 funk_chan[c_channel].note_command = 0xf;
475 funk_chan[c_channel].rfreq = RPORT_TOP_LIM;
476 }
477 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
478 }
479
480 /***********************************
481 *1Com B: port down (modified as of R2)
482 *
483 * com_val : 00000000
484 * \ rate /
485 *
486 ***********************************/
com_port_dn_log(int note_com_val)487 void com_port_dn_log(int note_com_val)
488 {
489 funk_chan[c_channel].ifreq += (note_com_val + 1) << 2;
490 if(funk_chan[c_channel].ifreq >= IPORT_BOT_LIM)
491 {
492 funk_chan[c_channel].note_command = 0xf;
493 funk_chan[c_channel].ifreq = IPORT_BOT_LIM;
494 }
495 funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
496 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
497 }
498
com_port_dn_lin(int note_com_val)499 void com_port_dn_lin(int note_com_val)
500 {
501 funk_chan[c_channel].rfreq -= (note_com_val + 1) << 3;
502 if(funk_chan[c_channel].rfreq <= RPORT_BOT_LIM)
503 {
504 funk_chan[c_channel].note_command = 0xf;
505 funk_chan[c_channel].rfreq = RPORT_BOT_LIM;
506 }
507 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
508 }
509
510 /***********************************
511 *2Com C: port to note (modified as of R2)
512 *
513 ***********************************/
com_porta_log_subm1(void)514 void com_porta_log_subm1(void)
515 {
516 funk_chan[c_channel].note_command = 0xf;
517 funk_chan[c_channel].ifreq = funk_chan[c_channel].ifreq_portdest;
518 funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
519 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
520 }
521
com_porta_log(void)522 void com_porta_log(void)
523 {
524 if(funk_chan[c_channel].ifreq == funk_chan[c_channel].ifreq_portdest)
525 funk_chan[c_channel].note_command = 0xf;
526 else
527 if(funk_chan[c_channel].ifreq > funk_chan[c_channel].ifreq_portdest)
528 {
529 com_port_up_log(funk_chan[c_channel].note_com_val);
530 if(funk_chan[c_channel].ifreq <= funk_chan[c_channel].ifreq_portdest)
531 com_porta_log_subm1();
532 }
533 else
534 {
535 com_port_dn_log(funk_chan[c_channel].note_com_val);
536 if(funk_chan[c_channel].ifreq >= funk_chan[c_channel].ifreq_portdest)
537 com_porta_log_subm1();
538 }
539 }
540
com_porta_lin_subm1(void)541 void com_porta_lin_subm1(void)
542 {
543 funk_chan[c_channel].note_command = 0xf;
544 funk_chan[c_channel].rfreq = funk_chan[c_channel].rfreq_portdest;
545 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
546 }
547
com_porta_lin(void)548 void com_porta_lin(void)
549 {
550 if(funk_chan[c_channel].rfreq == funk_chan[c_channel].rfreq_portdest)
551 funk_chan[c_channel].note_command = 0xf;
552 else
553 if(funk_chan[c_channel].rfreq < funk_chan[c_channel].rfreq_portdest)
554 {
555 com_port_up_lin(funk_chan[c_channel].note_com_val);
556 if(funk_chan[c_channel].rfreq >= funk_chan[c_channel].rfreq_portdest)
557 com_porta_lin_subm1();
558 }
559 else
560 {
561 com_port_dn_lin(funk_chan[c_channel].note_com_val);
562 if(funk_chan[c_channel].rfreq <= funk_chan[c_channel].rfreq_portdest)
563 com_porta_lin_subm1();
564 }
565 }
566
567 /***********************************
568 *3Com D: vibrato
569 *
570 * com_val : 0000 0000
571 * \speed/ \amplitude/
572 *
573 *vib_waveform = 0 : sine
574 * 1 : triangle
575 * 2 : square
576 * 3 : sawtooth
577 * 4 : random
578 *
579 ***********************************/
580 #define VIBAMP 1
581
com_vibrato(void)582 void com_vibrato(void)
583 {
584 funk_chan[c_channel].ifreq_vibrato = com_vib_func(
585 funk_chan[c_channel].vib_waveform,
586 funk_chan[c_channel].note_com_val & 0xf, /*amp*/
587 funk_chan[c_channel].note_com_val >> 4, /*speed*/
588 &funk_chan[c_channel].vib_ptr) << VIBAMP;
589 funk_chan[c_channel].rfreq = ifreq_to_rfreq_vib(funk_chan[c_channel].ifreq);
590 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
591 }
592
593 /***********************************
594 *4Com E: vibrato Fanin
595 *
596 * com_val : 0000 0000
597 * \speed/ \fanin value/
598 *
599 *vib_waveform = 0 : sine
600 * 1 : triangle
601 * 2 : square
602 * 3 : sawtooth
603 * 4 : random
604 *
605 ***********************************/
com_vib_fanin(void)606 void com_vib_fanin(void)
607 {
608 register int fanin,speed;
609
610 fanin = funk_chan[c_channel].note_com_val & 0xf;
611 speed = (funk_chan[c_channel].note_com_val & 0xf0) >> 2;
612
613 if(funk_chan[c_channel].note_beat_count < 0xf)
614 if(funk_chan[c_channel].note_comspd_count < speed)
615 funk_chan[c_channel].note_comspd_count++;
616 else
617 {
618 funk_chan[c_channel].note_comspd_count = 0;
619 funk_chan[c_channel].note_beat_count++;
620 }
621 funk_chan[c_channel].ifreq_vibrato = com_vib_func(
622 funk_chan[c_channel].vib_waveform,
623 fanin, /*amp*/
624 funk_chan[c_channel].note_beat_count, /*speed*/
625 &funk_chan[c_channel].vib_ptr) << VIBAMP;
626 funk_chan[c_channel].rfreq = ifreq_to_rfreq_vib(funk_chan[c_channel].ifreq);
627 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
628 }
629
630 /***********************************
631 *5Com F: vibrato Fanout
632 *
633 * com_val : 0000 0000
634 * \speed/ \fanin value/
635 *
636 *vib_waveform = 0 : sine
637 * 1 : triangle
638 * 2 : square
639 * 3 : sawtooth
640 * 4 : random
641 *
642 ***********************************/
com_vib_fanout(void)643 void com_vib_fanout(void)
644 {
645 register int fanin,speed;
646
647 fanin = funk_chan[c_channel].note_com_val & 0xf;
648 speed = (funk_chan[c_channel].note_com_val & 0xf0) >> 2;
649
650 if(funk_chan[c_channel].note_beat_count > 0)
651 if(funk_chan[c_channel].note_comspd_count < speed)
652 funk_chan[c_channel].note_comspd_count++;
653 else
654 {
655 funk_chan[c_channel].note_comspd_count = 0;
656 funk_chan[c_channel].note_beat_count--;
657 }
658 funk_chan[c_channel].ifreq_vibrato = com_vib_func(
659 funk_chan[c_channel].vib_waveform,
660 fanin, /*amp*/
661 funk_chan[c_channel].note_beat_count, /*speed*/
662 &funk_chan[c_channel].vib_ptr) << VIBAMP;
663 funk_chan[c_channel].rfreq = ifreq_to_rfreq_vib(funk_chan[c_channel].ifreq);
664 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
665 }
666
667 /***********************************
668 *6Com G: volume sld up
669 *
670 * com_val : 0000 0000
671 * \rate/
672 *
673 ***********************************/
com_vol_up(void)674 void com_vol_up(void)
675 {
676 funk_chan[c_channel].volume +=
677 com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf];
678
679 if(funk_chan[c_channel].volume > 255)
680 {
681 funk_chan[c_channel].volume_command = 0xf;
682 funk_chan[c_channel].volume = 255;
683 }
684 vol_to_realvol();
685 volume_convert();
686 }
687
688 /***********************************
689 *7Com H: volume slide down
690 *
691 * com_val : 0000 0000
692 * \rate/
693 *
694 ***********************************/
com_vol_dn(void)695 void com_vol_dn(void)
696 {
697 funk_chan[c_channel].volume -=
698 com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf];
699 if(funk_chan[c_channel].volume < 0)
700 {
701 funk_chan[c_channel].volume_command = 0xf;
702 funk_chan[c_channel].volume = 0;
703 }
704 vol_to_realvol();
705 volume_convert();
706 }
707
708 /***********************************
709 *8Com I: volume porta (Rapid ctrl)
710 *
711 ***********************************/
com_vol_porta_subm1(void)712 void com_vol_porta_subm1(void)
713 {
714 funk_chan[c_channel].volume_command = 0xf;
715 funk_chan[c_channel].volume = funk_chan[c_channel].volume_portdest;
716 vol_to_realvol();
717 volume_convert();
718 }
719
com_vol_porta(void)720 void com_vol_porta(void)
721 {
722 if(funk_chan[c_channel].volume == funk_chan[c_channel].volume_portdest)
723 funk_chan[c_channel].volume_command = 0xf;
724 else
725 {
726 if(funk_chan[c_channel].volume >= funk_chan[c_channel].volume_portdest)
727 {
728 com_vol_dn();
729 if(funk_chan[c_channel].volume <= funk_chan[c_channel].volume_portdest)
730 com_vol_porta_subm1();
731 }
732 else
733 {
734 com_vol_up();
735 if(funk_chan[c_channel].volume >= funk_chan[c_channel].volume_portdest)
736 com_vol_porta_subm1();
737 }
738 }
739 }
740
741 /*********************************
742 *
743 *********************************/
vol_sys_rapid_p1(void)744 void vol_sys_rapid_p1(void)
745 {
746 if((funk_chan[c_channel].volume_command >= 6) &&
747 (funk_chan[c_channel].volume_command <= 8))
748 if(funk_chan[c_channel].volume_comspd_count <
749 (funk_chan[c_channel].volume_com_val >> 4))
750 {
751 funk_chan[c_channel].volume_comspd_count++;
752 }
753 else
754 {
755 funk_chan[c_channel].volume_comspd_count = 0;
756 switch(funk_chan[c_channel].volume_command)
757 {
758 case 0x6:
759 com_vol_up();
760 break;
761 case 0x7:
762 com_vol_dn();
763 break;
764 case 0x8:
765 com_vol_porta();
766 break;
767 }
768 }
769 }
770
771 /***********************************
772 *9Com J: Volume Reverb
773 *
774 * A simulated echo effect
775 *
776 * com_val : 0000 0000
777 *
778 *
779 ***********************************/
com_reverb(void)780 void com_reverb(void)
781 {
782 register int incre = (funk_chan[c_channel].volume_com_val & 0xf);
783 register int speed = (funk_chan[c_channel].volume_com_val & 0xf0) >> 2;
784 if(funk_chan[c_channel].volume_comspd_count < speed)
785 {
786 funk_chan[c_channel].volume_comspd_count++;
787 if(funk_chan[c_channel].volume > 0)
788 {
789 funk_chan[c_channel].volume -= com_volume_inc[incre];
790 if(funk_chan[c_channel].volume < 0)
791 funk_chan[c_channel].volume = 0;
792 }
793 }
794 else /*echo*/
795 {
796 funk_chan[c_channel].volume_comspd_count = 0;
797 funk_chan[c_channel].volume_beat_count -=
798 (-funk_chan[c_channel].volume_com_val & 0xf0) >> 4;
799 if(funk_chan[c_channel].volume_beat_count > 0)
800 {
801 funk_chan[c_channel].volume = funk_chan[c_channel].volume_beat_count;
802 }
803 else
804 {
805 funk_chan[c_channel].volume_command = 0xf;
806 funk_chan[c_channel].volume = 0;
807 }
808 }
809 vol_to_realvol();
810 volume_convert();
811 }
812
813 /***********************************
814 *ACom K: tremola
815 *
816 * com_val : 0000 0000
817 * \rate/
818 *
819 ***********************************/
com_tremola(void)820 void com_tremola(void)
821 {
822 funk_chan[c_channel].volume_vibrato = com_vib_func(
823 funk_chan[c_channel].vol_vib_waveform,
824 funk_chan[c_channel].volume_com_val & 0xf, /*amp*/
825 funk_chan[c_channel].volume_com_val >> 4, /*speed*/
826 &funk_chan[c_channel].vol_vib_ptr);
827 vol_to_realvol_vib();
828 volume_convert();
829 }
830
831 /***********************************
832 *BCom L: arpeggio
833 *
834 * com_val : 0000 0000
835 * \N1/ \N2/
836 *
837 ***********************************/
com_arpeggio(void)838 void com_arpeggio(void)
839 {
840 register int arp_note;
841
842 if(funk_chan[c_channel].note_comspd_count < funk_chan[c_channel].arp_speed)
843 funk_chan[c_channel].note_comspd_count++;
844 else
845 {
846 funk_chan[c_channel].note_comspd_count = 0;
847 arp_note = funk_chan[c_channel].note;
848 switch(funk_chan[c_channel].note_beat_count)
849 {
850 case 1:
851 arp_note += (funk_chan[c_channel].note_com_val >> 4);
852 break;
853 case 2:
854 arp_note += (funk_chan[c_channel].note_com_val & 0xf);
855 break;
856 }
857 if(arp_note > 59)
858 arp_note = funk_chan[c_channel].note;
859 funk_chan[c_channel].ifreq = note_2_ifreq(arp_note);
860 funk_chan[c_channel].rfreq = ifreq_to_rfreq(funk_chan[c_channel].ifreq);
861 CARD_freq_convert(c_channel,funk_chan[c_channel].rfreq);
862 if(funk_chan[c_channel].note_beat_count == 2)
863 funk_chan[c_channel].note_beat_count = 0;
864 else
865 funk_chan[c_channel].note_beat_count++;
866 }
867 }
868
869 /***********************************
870 *CCom M: sample offset
871 *
872 * This is a all present sample
873 * offset that is effective all the
874 * time for a given channel
875 *
876 *
877 ***********************************/
com_sample_offset(void)878 void com_sample_offset(void)
879 {
880 register long offs = funk_chan[c_channel].com_val <<
881 funk_chan[c_channel].sample_ofs_parm;
882 if(offs > funk_hr_ptr->funk_sb[funk_chan[c_channel].sample].length)
883 offs = funk_hr_ptr->funk_sb[funk_chan[c_channel].sample].length;
884 chmix[c_channel].sample_ptr += offs;
885 }
886
887 /***********************************
888 *DCom N: volume
889 *
890 ***********************************/
com_volume(void)891 void com_volume(void)
892 {
893 funk_chan[c_channel].volume = funk_chan[c_channel].volume_com_val;
894 vol_to_realvol();
895 volume_convert();
896 }
897
898 /***********************************
899 *ECom O0: misc control (cmd revised since R1)
900 *
901 *value control set
902 *------------------
903 *0 vibrato sine
904 *1 vibrato triangle
905 *2 vibrato square
906 *3 vibrato sawtooth
907 *4 vibrato random
908 *5 tremola sine
909 *6 tremola triangle
910 *7 tremola square
911 *8 tremola sawtooth
912 *9 tremola random
913 *a halt note system
914 *b halt volume system
915 *c halt all systems
916 *d invert funkcrtl
917 *e fine balance pann left
918 *f fine balance pann right
919 *
920 ***********************************/
com_misccrtl(void)921 void com_misccrtl(void)
922 {
923 switch(funk_chan[c_channel].com_val & 0xf)
924 {
925 case 0x0:
926 funk_chan[c_channel].vib_waveform = 0;
927 break;
928 case 0x1:
929 funk_chan[c_channel].vib_waveform = 1;
930 break;
931 case 0x2:
932 funk_chan[c_channel].vib_waveform = 2;
933 break;
934 case 0x3:
935 funk_chan[c_channel].vib_waveform = 3;
936 break;
937 case 0x4:
938 funk_chan[c_channel].vib_waveform = 4;
939 break;
940 case 0x5:
941 funk_chan[c_channel].vol_vib_waveform = 0;
942 break;
943 case 0x6:
944 funk_chan[c_channel].vol_vib_waveform = 1;
945 break;
946 case 0x7:
947 funk_chan[c_channel].vol_vib_waveform = 2;
948 break;
949 case 0x8:
950 funk_chan[c_channel].vol_vib_waveform = 3;
951 break;
952 case 0x9:
953 funk_chan[c_channel].vol_vib_waveform = 4;
954 break;
955 case 0xa:
956 funk_chan[c_channel].note_command = 0xf;
957 break;
958 case 0xb:
959 funk_chan[c_channel].volume_command = 0xf;
960 break;
961 case 0xc:
962 funk_chan[c_channel].note_command = 0xf;
963 funk_chan[c_channel].volume_command = 0xf;
964 break;
965 case 0xd:
966 /* NOT USED*/
967 break;
968 case 0xe:
969 case 0xf:
970 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
971 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
972 break;
973 }
974 }
975
com_pan_left(void)976 void com_pan_left(void)
977 {
978 funk_chan[c_channel].balance--;
979 if(funk_chan[c_channel].balance < 0)
980 {
981 funk_chan[c_channel].volume_command = 0xf;
982 funk_chan[c_channel].balance = 0;
983 }
984 volume_convert();
985 }
986
com_pan_right(void)987 void com_pan_right(void)
988 {
989 funk_chan[c_channel].balance++;
990 if(funk_chan[c_channel].balance > 0xff)
991 {
992 funk_chan[c_channel].volume_command = 0xf;
993 funk_chan[c_channel].balance = 0xff;
994 }
995 volume_convert();
996 }
997
998 /***********************************
999 * Com O1: volume cut *
1000 * *
1001 ***********************************/
com_volume_cut(void)1002 void com_volume_cut(void)
1003 {
1004 if(funk_chan[c_channel].volume_comspd_count <
1005 (funk_chan[c_channel].volume_com_val & 0xf))
1006 {
1007 funk_chan[c_channel].volume_comspd_count++;
1008 }
1009 else
1010 {
1011 funk_chan[c_channel].volume_command = 0xf;
1012 funk_chan[c_channel].volume = 0;
1013 vol_to_realvol();
1014 volume_convert();
1015 }
1016 }
1017
1018 /***********************************
1019 * Com O2: Note Delay
1020 *
1021 *NB/ will only work within a slot time period.
1022 *when the next slot is loaded, the command and value are
1023 *purged (just like retrig)
1024 ***********************************/
com_note_delay(void)1025 void com_note_delay(void)
1026 {
1027 if(funk_chan[c_channel].comspd_count <
1028 (funk_chan[c_channel].com_val & 0xf))
1029 {
1030 funk_chan[c_channel].comspd_count++;
1031 }
1032 else
1033 {
1034 funk_chan[c_channel].command = 0xf;
1035 pattern_ptr = funk_chan[c_channel].delay_pattern_ptr;
1036 normal_decode_system();
1037 }
1038 }
1039
1040 /***********************************
1041 * Com O3: set arpeggio speed
1042 *
1043 ***********************************/
com_arp_speed_set(void)1044 void com_arp_speed_set(void)
1045 {
1046 funk_chan[c_channel].arp_speed = funk_chan[c_channel].com_val & 0xf;
1047 }
1048
1049 /***********************************
1050 * Com O4: fine port_up
1051 *
1052 * com_val : 0000
1053 * \ rate /
1054 *
1055 ***********************************/
com_fine_port_up(void)1056 void com_fine_port_up(void)
1057 {
1058 register int x = funk_chan[c_channel].note_com_val & 0xf;
1059 if(funk_chan[c_channel].port_type)
1060 com_port_up_lin(x);
1061 else
1062 com_port_up_log(x);
1063 }
1064
1065 /***********************************
1066 * Com O5: fine port_dn
1067 *
1068 * com_val : 0000
1069 * \ rate /
1070 *
1071 ***********************************/
com_fine_port_dn(void)1072 void com_fine_port_dn(void)
1073 {
1074 register int x = funk_chan[c_channel].note_com_val & 0xf;
1075 if(funk_chan[c_channel].port_type)
1076 com_port_dn_lin(x);
1077 else
1078 com_port_dn_log(x);
1079 }
1080
1081 /***********************************
1082 * Com O6: fine vol sld up
1083 *
1084 * com_val : 0000
1085 * \rate/
1086 *
1087 ***********************************/
1088
1089 /*refer to com_vol_up(void)*/
1090
1091 /***********************************
1092 * Com O7: fine vol sld dn
1093 *
1094 * com_val : 0000
1095 * \rate/
1096 *
1097 ***********************************/
1098
1099 /*refer to com_vol_dn(void)*/
1100
1101 /***********************************
1102 * Com O8: volume crest
1103 *
1104 * com_val : 0000
1105 * \speed/ (prehand)
1106 *
1107 * volume slides up then down,
1108 * starting at current frequency
1109 *
1110 ***********************************/
com_vol_crest(void)1111 void com_vol_crest(void)
1112 {
1113 switch(funk_chan[c_channel].volume_beat_count)
1114 {
1115 case 1: /*@@wait_a_bit*/
1116 if(funk_chan[c_channel].volume_comspd_count <
1117 (-((funk_chan[c_channel].volume_com_val & 0xf) + 1) & 0xf))
1118 {
1119 funk_chan[c_channel].volume_comspd_count++;
1120 }
1121 else
1122 {
1123 funk_chan[c_channel].volume_comspd_count = 0;
1124 funk_chan[c_channel].volume_beat_count++;
1125 }
1126 break;
1127 case 2: /*@@slide_down*/
1128 funk_chan[c_channel].volume -=
1129 (com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf] >> 2) + 1;
1130 if(funk_chan[c_channel].volume <= funk_chan[c_channel].volume_portdest)
1131 {
1132 funk_chan[c_channel].volume_command = 0xf;
1133 funk_chan[c_channel].volume = funk_chan[c_channel].volume_portdest;
1134 }
1135 vol_to_realvol();
1136 volume_convert();
1137 break;
1138 default:
1139 funk_chan[c_channel].volume +=
1140 com_volume_inc[funk_chan[c_channel].volume_com_val & 0xf];
1141 if(funk_chan[c_channel].volume > 0xff)
1142 {
1143 funk_chan[c_channel].volume_comspd_count = 0;
1144 funk_chan[c_channel].volume_beat_count++;
1145 funk_chan[c_channel].volume = 0xff;
1146 }
1147 vol_to_realvol();
1148 volume_convert();
1149 break;
1150 }
1151 }
1152
1153 /***********************************
1154 * Com O9: Echo Feedback Gain (was volume though in R1)
1155 *
1156 ***********************************/
com_echo_feedback(void)1157 void com_echo_feedback(void)
1158 {
1159 chmix[c_channel].echo_feedback = funk_chan[c_channel].com_val & 0xf;
1160 }
1161
1162 /***********************************
1163 * Com OA: master volume set (cmd revised since R1)
1164 *
1165 * master effects all volumes.
1166 *
1167 * format: 4 3 2 1
1168 * \| \---/
1169 * dir increment
1170 * 1 = up
1171 * 0 = down
1172 ***********************************/
com_master_set(void)1173 void com_master_set(void)
1174 {
1175 register int tmp = c_channel;
1176 register int dec_val = (funk_chan[c_channel].com_val & 0x7) << 2;
1177
1178 if(funk_chan[c_channel].com_val & 0x8)
1179 {
1180 funk_info.master_volume += dec_val;
1181 if(funk_info.master_volume > 0xff)
1182 funk_info.master_volume = 0xff;
1183 }
1184 else
1185 {
1186 funk_info.master_volume -= dec_val;
1187 if(funk_info.master_volume < 0)
1188 funk_info.master_volume = 0;
1189 }
1190 for(c_channel = 0;c_channel < funk_info.no_active_channels;c_channel++)
1191 volume_convert();
1192 c_channel = tmp;
1193 }
1194
1195 /***********************************
1196 * Com OB: Echo Delay
1197 *
1198 * In the Funktracker Revision 1 (DOS32 Funktracker), this command
1199 * was "Expand Loop". As the command wasn't used very often (and
1200 * wasn't very useful anyway, it has been replaced by this extremely
1201 * useful command.
1202 ***********************************/
com_echo_delay(void)1203 void com_echo_delay(void)
1204 {
1205 chmix[c_channel].echo_delay = funk_chan[c_channel].com_val & 0xf;
1206 }
1207
1208 /***********************************
1209 * Com OC: Echo Decay
1210 *
1211 * Refer to the above comment in Com OB. This command used to be
1212 * "Colapse Loop". I don't think i've ever used these old commands
1213 * actually.
1214 ***********************************/
com_echo_decay(void)1215 void com_echo_decay(void)
1216 {
1217 chmix[c_channel].echo_decay = funk_chan[c_channel].com_val & 0xf;
1218 }
1219
1220 /***********************************
1221 * Com OD: note retrig
1222 *
1223 * com_val : ???? 0000
1224 * \speed/ (prehand)
1225 *
1226 * command only handled on full
1227 * or sample only slots
1228 *
1229 ***********************************/
com_note_retrig(void)1230 void com_note_retrig(void)
1231 {
1232 if(funk_chan[c_channel].retrig_spd_count <
1233 (funk_chan[c_channel].com_val & 0xf))
1234 {
1235 funk_chan[c_channel].retrig_spd_count++;
1236 }
1237 else
1238 {
1239 funk_chan[c_channel].retrig_spd_count = 0;
1240 if(funk_chan[c_channel].retrig_count < funk_chan[c_channel].retrig_limit)
1241 {
1242 funk_chan[c_channel].retrig_count++;
1243 do_retrig_sample(funk_chan[c_channel].sample);
1244 }
1245 else
1246 funk_chan[c_channel].command = 0xf;
1247 }
1248 }
1249
1250 /***********************************
1251 * Com OE: set channel balance
1252 *
1253 ***********************************/
com_balance(void)1254 void com_balance(void)
1255 {
1256 funk_chan[c_channel].balance = (funk_chan[c_channel].com_val & 0xf) << 4;
1257 volume_convert();
1258 }
1259
1260 /***********************************
1261 * Com OF: tempo
1262 *
1263 ***********************************/
com_tempo(void)1264 void com_tempo(void)
1265 {
1266 funk_info.tempo = funk_chan[c_channel].com_val & 0xf;
1267 }
1268
1269 /***************************************************************************
1270 *
1271 * Command control for null slots only
1272 *
1273 ***************************************************************************/
cnc_vs_basic(void)1274 void cnc_vs_basic(void)
1275 {
1276 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1277 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1278 funk_chan[c_channel].volume_comspd_count = 0;
1279 }
1280
com_null_ctrl(void)1281 void com_null_ctrl(void)
1282 {
1283 switch(funk_chan[c_channel].command)
1284 {
1285 case 0x0: /*com a*/
1286 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1287 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1288 break;
1289 case 0x1: /*com b*/
1290 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1291 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1292 break;
1293 case 0x2: /*com c*/
1294 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1295 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1296 break;
1297 case 0x3: /*com d*/
1298 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1299 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1300 funk_chan[c_channel].note_comspd_count = 0;
1301 break;
1302 case 0x4: /*com e*/
1303 funk_chan[c_channel].note_beat_count = 0;
1304 goto set_vib_fan;
1305 case 0x5: /*com f*/
1306 funk_chan[c_channel].note_beat_count = 0xf;
1307 set_vib_fan:
1308 if(funk_chan[c_channel].note_command == 0x3)/*if vibrato command*/
1309 funk_chan[c_channel].note_beat_count =
1310 funk_chan[c_channel].note_com_val >> 4;
1311 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1312 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1313 funk_chan[c_channel].note_comspd_count = 0;
1314 break;
1315 case 0x6: /*com g*/
1316 cnc_vs_basic();
1317 break;
1318 case 0x7: /*com h*/
1319 cnc_vs_basic();
1320 break;
1321 case 0x8: /*com i*/
1322 cnc_vs_basic();
1323 break;
1324 case 0x9: /*com j*/
1325 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1326 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1327 funk_chan[c_channel].volume_comspd_count = 0;
1328 funk_chan[c_channel].volume_beat_count = funk_chan[c_channel].volume;
1329 break;
1330 case 0xa: /*com k*/
1331 cnc_vs_basic();
1332 break;
1333 case 0xb: /*com l*/
1334 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1335 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1336 funk_chan[c_channel].note_comspd_count = 0;
1337 funk_chan[c_channel].note_beat_count = 1;
1338 break;
1339 case 0xd: /*com n*/
1340 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1341 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1342 com_volume();
1343 break;
1344 case 0xe: /*O commands*/
1345 switch(funk_chan[c_channel].com_val & 0xf0)
1346 {
1347 case 0x00: /*com o0*/
1348 com_misccrtl();
1349 break;
1350 case 0x10: /*com o1*/
1351 cnc_vs_basic();
1352 break;
1353 case 0x30: /*com o3*/
1354 com_arp_speed_set();
1355 break;
1356 case 0x40: /*com o4*/
1357 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1358 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1359 com_fine_port_up();
1360 break;
1361 case 0x50: /*com o5*/
1362 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1363 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1364 com_fine_port_dn();
1365 break;
1366 case 0x60: /*com o6*/
1367 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1368 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1369 com_vol_up();
1370 break;
1371 case 0x70: /*com o7*/
1372 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1373 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1374 com_vol_dn();
1375 break;
1376 case 0x80: /*com o8*/
1377 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1378 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1379 funk_chan[c_channel].volume_comspd_count = 0;
1380 funk_chan[c_channel].volume_beat_count = 0;
1381 funk_chan[c_channel].volume_portdest = funk_chan[c_channel].volume;
1382 break;
1383 case 0x90: /*com o9*/
1384 com_echo_feedback();
1385 break;
1386 case 0xa0: /*com oa*/
1387 com_master_set();
1388 break;
1389 case 0xb0: /*com ob*/
1390 com_echo_delay();
1391 break;
1392 case 0xc0: /*com oc*/
1393 com_echo_decay();
1394 break;
1395 case 0xe0: /*com oe*/
1396 com_balance();
1397 break;
1398 case 0xf0: /*com of*/
1399 com_tempo();
1400 break;
1401 }
1402 break;
1403 }
1404 }
1405
1406 /***************************************************************************
1407 *
1408 * Command control for full slots
1409 *
1410 ***************************************************************************/
cfc_vs_basic(void)1411 void cfc_vs_basic(void)
1412 {
1413 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1414 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1415 funk_chan[c_channel].volume_comspd_count = 0;
1416 normal_decode_volume();
1417 }
1418
com_full_ctrl(void)1419 void com_full_ctrl(void)
1420 {
1421 switch(funk_chan[c_channel].command)
1422 {
1423 case 0x0: /*com a*/
1424 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1425 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1426 normal_decode_note();
1427 break;
1428 case 0x1: /*com b*/
1429 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1430 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1431 normal_decode_note();
1432 break;
1433 case 0x2: /*com c*/
1434 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1435 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1436 comc_decode();
1437 break;
1438 case 0x3: /*com d*/
1439 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1440 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1441 funk_chan[c_channel].note_comspd_count = 0;
1442 normal_decode_note();
1443 break;
1444 case 0x4: /*com e*/
1445 funk_chan[c_channel].note_beat_count = 0;
1446 goto set_vib_fan;
1447 case 0x5: /*com f*/
1448 funk_chan[c_channel].note_beat_count = 0xf;
1449 set_vib_fan:
1450 if(funk_chan[c_channel].note_command == 0x3) /*if vibrato command*/
1451 funk_chan[c_channel].note_beat_count =
1452 funk_chan[c_channel].note_com_val >> 4;
1453 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1454 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1455 funk_chan[c_channel].note_comspd_count = 0;
1456 normal_decode_note();
1457 break;
1458 case 0x6: /*com g*/
1459 cfc_vs_basic();
1460 break;
1461 case 0x7: /*com h*/
1462 cfc_vs_basic();
1463 break;
1464 case 0x8: /*com i*/
1465 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1466 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1467 funk_chan[c_channel].volume_comspd_count = 0;
1468 comi_decode();
1469 break;
1470 case 0x9: /*com j*/
1471 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1472 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1473 funk_chan[c_channel].volume_comspd_count = 0;
1474 normal_decode_volume();
1475 funk_chan[c_channel].volume_beat_count = funk_chan[c_channel].volume;
1476 break;
1477 case 0xa: /*com k*/
1478 cfc_vs_basic();
1479 break;
1480 case 0xb: /*com l*/
1481 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1482 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1483 funk_chan[c_channel].note_comspd_count = 0;
1484 funk_chan[c_channel].note_beat_count = 1;
1485 normal_decode_note();
1486 break;
1487 case 0xc: /*com m*/
1488 normal_decode_system();
1489 com_sample_offset();
1490 break;
1491 case 0xd: /*com n*/
1492 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1493 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1494 normal_decode_volume();
1495 com_volume();
1496 break;
1497 case 0xe: /*O commands*/
1498 switch(funk_chan[c_channel].com_val & 0xf0)
1499 {
1500 case 0x00: /*com o0*/
1501 normal_decode_system();
1502 com_misccrtl();
1503 break;
1504 case 0x10: /*com o1*/
1505 cfc_vs_basic();
1506 break;
1507 case 0x20: /*com o2*/
1508 funk_chan[c_channel].comspd_count = 0;
1509 funk_chan[c_channel].delay_pattern_ptr = pattern_ptr;
1510 break;
1511 case 0x30: /*com o3*/
1512 normal_decode_system();
1513 com_arp_speed_set();
1514 break;
1515 case 0x40: /*com o4*/
1516 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1517 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1518 normal_decode_note();
1519 com_fine_port_up();
1520 break;
1521 case 0x50: /*com o5*/
1522 funk_chan[c_channel].note_command = funk_chan[c_channel].command;
1523 funk_chan[c_channel].note_com_val = funk_chan[c_channel].com_val;
1524 normal_decode_note();
1525 com_fine_port_dn();
1526 break;
1527 case 0x60: /*com o6*/
1528 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1529 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1530 normal_decode_volume();
1531 com_vol_up();
1532 break;
1533 case 0x70: /*com o7*/
1534 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1535 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1536 normal_decode_volume();
1537 com_vol_dn();
1538 break;
1539 case 0x80: /*com o8*/
1540 funk_chan[c_channel].volume_command = funk_chan[c_channel].command;
1541 funk_chan[c_channel].volume_com_val = funk_chan[c_channel].com_val;
1542 funk_chan[c_channel].volume_comspd_count = 0;
1543 funk_chan[c_channel].volume_beat_count = 0;
1544 normal_decode_volume();
1545 funk_chan[c_channel].volume_portdest = funk_chan[c_channel].volume;
1546 break;
1547 case 0x90: /*com o9*/
1548 normal_decode_system();
1549 com_echo_feedback();
1550 break;
1551 case 0xa0: /*com oa*/
1552 com_master_set();
1553 normal_decode_system();
1554 break;
1555 case 0xb0: /*com ob*/
1556 normal_decode_system();
1557 com_echo_delay();
1558 break;
1559 case 0xc0: /*com oc*/
1560 normal_decode_system();
1561 com_echo_decay();
1562 break;
1563 case 0xd0: /*com od*/
1564 funk_chan[c_channel].retrig_count = 1;
1565 funk_chan[c_channel].retrig_spd_count = 0;
1566 normal_decode_system();
1567 break;
1568 case 0xe0: /*com oe*/
1569 normal_decode_system();
1570 com_balance();
1571 break;
1572 case 0xf0: /*com of*/
1573 normal_decode_system();
1574 com_tempo();
1575 break;
1576 }
1577 break;
1578 case 0xf:
1579 normal_decode_system();
1580 break;
1581 }
1582 }
1583
1584 /***************************************************************************
1585 *
1586 * Command control for rapid "on the fly"
1587 * Rapid commands that have a speed parameter
1588 *
1589 ***************************************************************************/
com_rapid_ctrl(void)1590 void com_rapid_ctrl(void)
1591 {
1592 for(c_channel = 0;c_channel < funk_info.no_active_channels;c_channel++)
1593 {
1594 vol_sys_rapid_p1();
1595 switch(funk_chan[c_channel].note_command)
1596 {
1597 case 0x0:
1598 if(funk_chan[c_channel].port_type)
1599 com_port_up_lin(funk_chan[c_channel].note_com_val);
1600 else
1601 com_port_up_log(funk_chan[c_channel].note_com_val);
1602 break;
1603 case 0x1:
1604 if(funk_chan[c_channel].port_type)
1605 com_port_dn_lin(funk_chan[c_channel].note_com_val);
1606 else
1607 com_port_dn_log(funk_chan[c_channel].note_com_val);
1608 break;
1609 case 0x2:
1610 if(funk_chan[c_channel].port_type)
1611 com_porta_lin();
1612 else
1613 com_porta_log();
1614 break;
1615 case 0x3: /*command d*/
1616 com_vibrato();
1617 break;
1618 case 0x4: /*command e*/
1619 com_vib_fanin();
1620 break;
1621 case 0x5: /*command f*/
1622 com_vib_fanout();
1623 break;
1624 case 0xb: /*command l*/
1625 com_arpeggio();
1626 break;
1627 }
1628 switch(funk_chan[c_channel].volume_command)
1629 {
1630 case 0x9: /*command j*/
1631 com_reverb();
1632 break;
1633 case 0xa: /*command k*/
1634 com_tremola();
1635 break;
1636 case 0xe:
1637 switch(funk_chan[c_channel].volume_com_val)
1638 {
1639 case 0x0e:
1640 com_pan_left();
1641 break;
1642 case 0x0f:
1643 com_pan_right();
1644 break;
1645 }
1646 switch(funk_chan[c_channel].volume_com_val & 0xf0)
1647 {
1648 case 0x10: /*command o1*/
1649 com_volume_cut();
1650 break;
1651 case 0x80: /*command o8*/
1652 com_vol_crest();
1653 break;
1654 }
1655 break;
1656 }
1657 if(funk_chan[c_channel].command == 0xe)
1658 switch(funk_chan[c_channel].com_val & 0xf0)
1659 {
1660 case 0x20: /*command o2*/
1661 com_note_delay();
1662 break;
1663 case 0xd0: /*command od*/
1664 com_note_retrig();
1665 break;
1666 }
1667 }
1668 }
1669
1670 /***************************************************************************
1671 *
1672 * ESI = current pattern
1673 *
1674 * format:
1675 *
1676 * 00000000 11111111 22222222
1677 * \ /\ /\ / \ /
1678 * note sample com command value
1679 *
1680 * - if note: = 3D, then reload sample attrs
1681 * = 3F, then it's a null slot
1682 * = 3E, then sample only slot
1683 *
1684 ***************************************************************************/
trekk_slot(int pattern_no)1685 void trekk_slot(int pattern_no)
1686 {
1687 register tslot *pattern_addr =
1688 funk_pat_ptr + (pattern_no * 64 * funk_info.no_active_channels) +
1689 (funk_info.pattern_ofs * funk_info.no_active_channels);
1690 for(c_channel = 0;c_channel < funk_info.no_active_channels;c_channel++)
1691 {
1692 pattern_ptr = pattern_addr + c_channel;
1693 funk_chan[c_channel].command = pattern_ptr->sam_com & 0xf;
1694 funk_chan[c_channel].com_val = pattern_ptr->com_val;
1695 if((pattern_ptr->not_sam >> 2) == 0x3f)
1696 com_null_ctrl();
1697 else
1698 com_full_ctrl(); /*IF FULL SLOT or SAMPLE ONLY SLOT*/
1699 }
1700 }
1701
1702 /***************************************************************************
1703 ****************************************************************************
1704 ****************************************************************************
1705 ****************************************************************************
1706 *
1707 * The actual tracker thingy :) ....0.02 second tick (or roughly)
1708 *
1709 ****************************************************************************
1710 ****************************************************************************
1711 ****************************************************************************
1712 ***************************************************************************/
funk_tracker(void)1713 void funk_tracker(void)
1714 {
1715 if(funk_info.trek_status == PLAY)
1716 {
1717 com_rapid_ctrl();
1718 if(funk_info.tempo_count < funk_info.tempo)
1719 funk_info.tempo_count++;
1720 else
1721 {
1722 funk_info.tempo_count = 0;
1723 funk_info.pattern_ofs_display = funk_info.pattern_ofs;
1724 funk_info.sequence_ofs_display = funk_info.sequence_ofs;
1725 trekk_slot(funk_hr_ptr->order_list[funk_info.sequence_ofs]);
1726 if(funk_info.pattern_ofs ==
1727 funk_hr_ptr->break_list[funk_hr_ptr->order_list[funk_info.sequence_ofs]])
1728 {
1729 if(funk_info.sequence_ofs < funk_info.no_of_sequences)
1730 {
1731 funk_info.sequence_ofs++;
1732 funk_info.pattern_ofs = 0;
1733 }
1734 else
1735 if(funk_hr_ptr->loop_order == 0xFF)
1736 funk_info.trek_status = STOP;
1737 else
1738 if(funk_hr_ptr->loop_order > funk_info.no_of_sequences)
1739 funk_info.trek_status = STOP;
1740 else
1741 {
1742 funk_info.sequence_ofs = funk_hr_ptr->loop_order;
1743 funk_info.pattern_ofs = 0;
1744 }
1745 }
1746 else
1747 funk_info.pattern_ofs++;
1748 }
1749 }
1750 }
1751