13 ef_TonePortamento = 3;
15 ef_TPortamVolSlide = 5;
16 ef_VibratoVolSlide = 6;
18 ef_FSlideDownFine = 8;
19 ef_SetModulatorVol = 9;
26 ef_TPortamVSlideFine = 16;
27 ef_VibratoVSlideFine = 17;
28 ef_SetCarrierVol = 18;
35 ef_ArpggVSlideFine = 25;
36 ef_MultiRetrigNote = 26;
37 ef_FSlideUpVSlide = 27;
38 ef_FSlideDownVSlide = 28;
39 ef_FSlUpFineVSlide = 29;
40 ef_FSlDownFineVSlide = 30;
43 ef_FSlUpFineVSlF = 33;
44 ef_FSlDownFineVSlF = 34;
47 ef_SetGlobalVolume = 37;
50 ef_ForceInsVolume = 40;
52 ef_ExtraFineArpeggio = 42;
53 ef_ExtraFineVibrato = 43;
54 ef_ExtraFineTremolo = 44;
55 ef_SetCustomSpeedTab = 45;
56 ef_GlobalFSlideUp = 46;
57 ef_GlobalFSlideDown = 47;
58 ef_ex_SetTremDepth = 0;
59 ef_ex_SetVibDepth = 1;
60 ef_ex_SetAttckRateM = 2;
61 ef_ex_SetDecayRateM = 3;
62 ef_ex_SetSustnLevelM = 4;
63 ef_ex_SetRelRateM = 5;
64 ef_ex_SetAttckRateC = 6;
65 ef_ex_SetDecayRateC = 7;
66 ef_ex_SetSustnLevelC = 8;
67 ef_ex_SetRelRateC = 9;
68 ef_ex_SetFeedback = 10;
69 ef_ex_SetPanningPos = 11;
70 ef_ex_PatternLoop = 12;
71 ef_ex_PatternLoopRec = 13;
72 ef_ex_MacroKOffLoop = 14;
73 ef_ex_ExtendedCmd = 15;
75 ef_ex_cmd_ResetVol = 1;
76 ef_ex_cmd_LockVol = 2;
77 ef_ex_cmd_UnlockVol = 3;
79 ef_ex_cmd_UnlockVP = 5;
80 ef_ex_cmd_VSlide_mod = 6;
81 ef_ex_cmd_VSlide_car = 7;
82 ef_ex_cmd_VSlide_def = 8;
83 ef_ex_cmd_LockPan = 9;
84 ef_ex_cmd_UnlockPan = 10;
85 ef_ex_cmd_VibrOff = 11;
86 ef_ex_cmd_TremOff = 12;
87 ef_ex_cmd_FVib_FGFS = 13;
88 ef_ex_cmd_FTrm_XFGFS = 14;
89 ef_ex_cmd_NoRestart = 15;
90 ef_ex2_PatDelayFrame = 0;
91 ef_ex2_PatDelayRow = 1;
94 ef_ex2_FineTuneUp = 4;
95 ef_ex2_FineTuneDown = 5;
96 ef_ex2_GlVolSlideUp = 6;
97 ef_ex2_GlVolSlideDn = 7;
98 ef_ex2_GlVolSlideUpF = 8;
99 ef_ex2_GlVolSlideDnF = 9;
100 ef_ex2_GlVolSldUpXF = 10;
101 ef_ex2_GlVolSldDnXF = 11;
102 ef_ex2_VolSlideUpXF = 12;
103 ef_ex2_VolSlideDnXF = 13;
104 ef_ex2_FreqSlideUpXF = 14;
105 ef_ex2_FreqSlideDnXF = 15;
106 ef_ex3_SetConnection = 0;
107 ef_ex3_SetMultipM = 1;
109 ef_ex3_SetTremoloM = 3;
110 ef_ex3_SetVibratoM = 4;
112 ef_ex3_SetSustainM = 6;
113 ef_ex3_SetMultipC = 7;
115 ef_ex3_SetTremoloC = 9;
116 ef_ex3_SetVibratoC = 10;
118 ef_ex3_SetSustainC = 12;
125 opl3port: Word = $388;
126 error_code: Integer = 0;
127 current_order: Byte = 0;
128 current_pattern: Byte = 0;
129 current_line: Byte = 0;
132 macro_speedup: Word = 1;
133 irq_mode: Boolean = FALSE;
134 max_patterns: Byte = 128;
135 fast_forward: Boolean = FALSE;
136 overall_volume: Byte = 63;
137 global_volume: Byte = 63;
140 song_timer: Word = 0;
141 song_timer_tenths: Word = 0;
144 timer_temp,timer_det: Word;
147 limit_exceeded: Boolean;
150 tFM_INST_DATA = Record
164 tADTRACK2_INS = Record
165 fm_data: tFM_INST_DATA;
171 tARPEGGIO_TABLE = Record
177 data: array[1..255] of Byte;
180 tVIBRATO_TABLE = Record
187 data: array[1..255] of Shortint;
190 tREGISTER_TABLE_DEF = Record
191 fm_data: tFM_INST_DATA;
192 freq_slide: Smallint;
197 tREGISTER_TABLE = Record
204 data: array[1..255] of tREGISTER_TABLE_DEF;
207 tMACRO_TABLE = Record
208 arpeggio: tARPEGGIO_TABLE;
209 vibrato: tVIBRATO_TABLE;
212 tFM_PARAMETER_TABLE = Record
220 multipM,kslM,tremM,vibrM,ksrM,sustM,
221 multipC,kslC,tremC,vibrC,ksrC,sustC: Byte;
224 tADTRACK2_EVENT = Record
234 tDIS_FMREG_COL = array[0..27] of Boolean;
237 tFIXED_SONGDATA = Record
238 songname: String[42];
239 composer: String[42];
240 instr_names: array[1..255] of String[42];
241 instr_data: array[1..255] of tADTRACK2_INS;
242 instr_macros: array[1..255] of tREGISTER_TABLE;
243 macro_table: array[1..255] of tMACRO_TABLE;
244 pattern_order: array[0..$7f] of Byte;
252 lock_flags: array[1..20] of Byte;
253 pattern_names: array[0..$7f] of String[42];
254 dis_fmreg_col: array[1..255] of tDIS_FMREG_COL;
257 tPLAY_STATUS = (isPlaying,isPaused,isStopped);
260 tVARIABLE_DATA = array[0..7] of
262 array[0..$0ff] of tADTRACK2_EVENT;
264 tPATTERN_DATA = array[0..15] of tVARIABLE_DATA;
267 tDUMMY_BUFF = array[0..PRED(655350)] of Byte;
270 tOLD_ADTRACK2_INS = Record
271 fm_data: tFM_INST_DATA;
276 pOLD_FIXED_SONGDATA = ^tOLD_FIXED_SONGDATA;
277 tOLD_FIXED_SONGDATA = Record
278 songname: String[42];
279 composer: String[42];
280 instr_names: array[1..250] of String[32];
281 instr_data: array[1..250] of tOLD_ADTRACK2_INS;
282 pattern_order: array[0..$7f] of Byte;
295 tCHUNK = tADTRACK2_EVENT;
298 tOLD_VARIABLE_DATA1 = array[0..$0f] of array[0..$3f] of
299 array[1..9] of tOLD_CHUNK;
301 tOLD_VARIABLE_DATA2 = array[0..7] of array[1..18] of
302 array[0..$3f] of tOLD_CHUNK;
304 tByteSet = Set of Byte;
307 INSTRUMENT_SIZE = SizeOf(tADTRACK2_INS);
308 CHUNK_SIZE = SizeOf(tCHUNK);
309 PATTERN_SIZE = 20*256*CHUNK_SIZE;
313 pattdata: ^tPATTERN_DATA;
314 songdata: tFIXED_SONGDATA;
315 old_songdata: tOLD_FIXED_SONGDATA;
316 old_hash_buffer: tOLD_VARIABLE_DATA1;
317 hash_buffer: tOLD_VARIABLE_DATA2;
318 buffer: array[0..PRED(SizeOf(tVARIABLE_DATA))] of Byte;
321 external_irq_hook: procedure = NIL;
322 _delay_counter: Longint = 0;
324 irq_initialized: Boolean = FALSE;
325 timer_fix: Boolean = TRUE;
326 pattern_break: Boolean = FALSE;
327 pattern_delay: Boolean = FALSE;
329 play_status: tPLAY_STATUS = isStopped;
330 replay_forbidden: Boolean = TRUE;
331 force_macro_keyon: Boolean = FALSE;
339 decay_bar: array[1..96] of tDECAY_BAR;
341 procedure start_playing;
342 procedure set_overall_volume(level: Byte);
343 procedure stop_playing;
344 procedure init_old_songdata;
345 procedure init_songdata;
348 procedure get_chunk(pattern,line,channel: Byte; var chunk: tADTRACK2_EVENT);
349 procedure put_chunk(pattern,line,channel: Byte; chunk: tADTRACK2_EVENT);
350 procedure count_order(var entries: Byte);
351 procedure timer_poll_proc;
352 procedure opl3exp(data: Word);
354 function calc_following_order(order: Byte): Integer;
355 function asciiz_string(str: String): String;
358 uses DOS,TimerInt,ParserIO;
361 _panning: array[0..2] of Byte = ($30,$10,$20);
364 _instr: array[0..11] of Byte = ($20, $20,
372 tTRACK_ADDR = array[1..20] of Word;
374 const { 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 }
375 _chmm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$006,$007,$008,$103,$100,$104,$101,$105,$102,$106,$107,$108,BYTE_NULL,BYTE_NULL);
376 _chmm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$010,$011,$012,$108,$100,$109,$101,$10a,$102,$110,$111,$112,BYTE_NULL,BYTE_NULL);
377 _chmm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$013,$014,$015,$10b,$103,$10c,$104,$10d,$105,$113,$114,$115,BYTE_NULL,BYTE_NULL);
379 _chpm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$106,$107,$108,$103,$100,$104,$101,$105,$102,$006,$007,$008,$008,$007);
380 _chpm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$110,$111,$112,$108,$100,$109,$101,$10a,$102,$010,$014,$012,$015,$011);
381 _chpm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$113,$114,$115,$10b,$103,$10c,$104,$10d,$105,$013,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL);
384 _chan_n: tTRACK_ADDR;
385 _chan_m: tTRACK_ADDR;
386 _chan_c: tTRACK_ADDR;
390 fixed_note_flag = $090;
391 pattern_loop_flag = $0e0;
392 pattern_break_flag = $0f0;
395 def_vibtrem_speed_factor: Byte = 1;
396 def_vibtrem_table_size: Byte = 32;
397 def_vibtrem_table: array[0..255] of Byte = (
398 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
399 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
400 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
401 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
402 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
403 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
404 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
405 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
406 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
407 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
408 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
409 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
410 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
411 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
412 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
413 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24);
416 vibtrem_speed_factor: Byte;
417 vibtrem_table_size: Byte;
418 vibtrem_table: array[0..255] of Byte;
421 fmpar_table: array[1..20] of tFM_PARAMETER_TABLE;
422 volume_lock: array[1..20] of Boolean;
423 volume_table: array[1..20] of Word;
424 vscale_table: array[1..20] of Word;
425 peak_lock: array[1..20] of Boolean;
426 pan_lock: array[1..20] of Boolean;
427 event_table: array[1..20] of tADTRACK2_EVENT;
428 voice_table: array[1..20] of Byte;
429 modulator_vol: array[1..20] of Byte;
430 carrier_vol: array[1..20] of Byte;
431 freq_table: array[1..20] of Word;
432 effect_table: array[1..20] of Word;
433 effect_table2: array[1..20] of Word;
434 fslide_table: array[1..20] of Byte;
435 fslide_table2: array[1..20] of Byte;
436 glfsld_table: array[1..20] of Word;
437 glfsld_table2: array[1..20] of Word;
438 porta_table: array[1..20] of Record freq: Word; speed: Byte; end;
439 porta_table2: array[1..20] of Record freq: Word; speed: Byte; end;
440 arpgg_table: array[1..20] of Record state,note,add1,add2: Byte; end;
441 arpgg_table2: array[1..20] of Record state,note,add1,add2: Byte; end;
442 vibr_table: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end;
443 vibr_table2: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end;
444 trem_table: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end;
445 trem_table2: array[1..20] of Record pos,speed,depth: Byte; fine: Boolean; end;
446 retrig_table: array[1..20] of Byte;
447 retrig_table2: array[1..20] of Byte;
448 tremor_table: array[1..20] of Record pos: Integer; volume: Word; end;
449 tremor_table2: array[1..20] of Record pos: Integer; volume: Word; end;
450 panning_table: array[1..20] of Byte;
451 last_effect: array[1..20] of Word;
452 last_effect2: array[1..20] of Word;
453 volslide_type: array[1..20] of Byte;
454 event_new: array[1..20] of Boolean;
455 notedel_table: array[1..20] of Byte;
456 notecut_table: array[1..20] of Byte;
457 ftune_table: array[1..20] of Shortint;
458 keyoff_loop: array[1..20] of Boolean;
459 macro_table: array[1..20] of Record
460 fmreg_pos,arpg_pos,vib_pos: Word;
461 fmreg_count,fmreg_duration,arpg_count,
462 vib_count,vib_delay: Byte;
464 fmreg_table,arpg_table,vib_table: Byte;
469 loopbck_table: array[1..20] of Byte;
470 loop_table: array[1..20,0..255] of Byte;
474 current_tremolo_depth: Byte = 0;
475 current_vibrato_depth: Byte = 0;
478 speed_update,lockvol,panlock,lockVP: Boolean;
479 tremolo_depth,vibrato_depth: Byte;
480 volume_scaling,percussion_mode: Boolean;
482 reset_chan: array[1..20] of Boolean;
484 procedure opl2out(reg,data: Word); assembler;
487 mov dx,word ptr [opl3port]
504 procedure opl3out(reg,data: Word); assembler;
507 mov dx,word ptr [opl3port]
521 procedure opl3exp(data: Word); assembler;
524 mov dx,word ptr [opl3port]
541 FreqRange = FreqEnd-FreqStart;
543 function nFreq(note: Byte): Word; assembler;
546 Fnum: array[0..11] of Word = (
547 $157,$16b,$181,$198,$1b0,$1ca,$1e5,$202,$220,$241,$263,$287);
568 add ax,word ptr [Fnum+ebx]
577 function calc_freq_shift_up(freq,shift: Word): Word; assembler;
585 and bx,0000001111111111b
587 and dx,0001110000000000b
589 and cx,1110000000000000b
597 @@1: sub bx,FreqRange
608 function calc_freq_shift_down(freq,shift: Word): Word; assembler;
616 and bx,0000001111111111b
618 and dx,0001110000000000b
620 and cx,1110000000000000b
628 @@1: add bx,FreqRange
639 function calc_vibtrem_shift(depth,position: Byte;
640 var direction: Byte): Word; assembler;
652 mov cl,vibtrem_table_size
655 lea edi,[vibtrem_table]
657 mov dl,byte ptr [edi]
665 mov dl,vibtrem_table_size
676 procedure change_freq(chan: Byte; freq: Word); assembler;
686 mov dx,word ptr [freq_table+ebx]
689 mov word ptr [freq_table+ebx],ax
691 mov dx,word ptr [_chan_n+ebx]
697 mov dx,word ptr [_chan_n+ebx]
709 function ins_parameter(ins,param: Byte): Byte; assembler;
714 lea esi,[songdata.instr_data]
717 mov eax,INSTRUMENT_SIZE
727 function min(value: Word; minimum: Word): Word; assembler;
736 function max(value: Word; maximum: Word): Word; assembler;
745 function asciiz_string(str: String): String;
747 If (Pos(#0,str) <> 0) then asciiz_string := Copy(str,1,Pos(#0,str)-1)
748 else asciiz_string := '';
751 function concw(lo,hi: Byte): Word;
753 concw := lo+(hi SHL 8);
756 procedure synchronize_song_timer;
758 song_timer := TRUNC(time_playing);
759 song_timer_tenths := TRUNC(time_playing*100) MOD 100;
760 timer_temp := song_timer_tenths;
763 procedure change_frequency(chan: Byte; freq: Word);
765 macro_table[chan].vib_paused := TRUE;
766 change_freq(chan,freq);
767 macro_table[chan].vib_count := 1;
768 macro_table[chan].vib_pos := 0;
769 macro_table[chan].vib_freq := freq;
770 macro_table[chan].vib_paused := FALSE;
773 function _macro_speedup: Word; assembler;
782 procedure update_timer(Hz: Longint);
784 _debug_str_ := 'A2PLAYER.PAS:update_timer';
785 If (Hz = 0) then begin TimerSetup(18); EXIT end
787 If (tempo = 18) and timer_fix then IRQ_freq := TRUNC((tempo+0.2)*20)
788 else IRQ_freq := 250;
789 While (IRQ_freq MOD (tempo*_macro_speedup) <> 0) do Inc(IRQ_freq);
790 If (IRQ_freq > MAX_IRQ_FREQ) then IRQ_freq := MAX_IRQ_FREQ;
791 TimerSetup(IRQ_freq);
794 procedure key_off(chan: Byte);
796 freq_table[chan] := LO(freq_table[chan])+
797 (HI(freq_table[chan]) AND NOT $20) SHL 8;
798 change_freq(chan,freq_table[chan]);
799 event_table[chan].note := event_table[chan].note OR keyoff_flag;
802 procedure release_sustaining_sound(chan: Byte);
804 opl3out(_instr[02]+_chan_m[chan],63);
805 opl3out(_instr[03]+_chan_c[chan],63);
807 FillChar(fmpar_table[chan].adsrw_car,
808 SizeOf(fmpar_table[chan].adsrw_car),0);
809 FillChar(fmpar_table[chan].adsrw_mod,
810 SizeOf(fmpar_table[chan].adsrw_mod),0);
812 opl3out($0b0+_chan_n[chan],0);
813 opl3out(_instr[04]+_chan_m[chan],BYTE_NULL);
814 opl3out(_instr[05]+_chan_c[chan],BYTE_NULL);
815 opl3out(_instr[06]+_chan_m[chan],BYTE_NULL);
816 opl3out(_instr[07]+_chan_c[chan],BYTE_NULL);
819 event_table[chan].instr_def := 0;
820 reset_chan[chan] := TRUE;
823 function scale_volume(volume,scale_factor: Byte): Byte;
825 scale_volume := 63-Round((63-volume)/63*
829 procedure set_ins_volume(modulator,carrier,chan: Byte);
836 // ** OPL3 emulation workaround **
837 // force muted instrument volume with missing ADSR instrument data
838 // when there is additionally no FM-reg macro defined for the instrument
839 If is_ins_adsr_data_empty(voice_table[chan]) and
840 NOT (songdata.instr_macros[voice_table[chan]].length <> 0) and
841 NOT replay_forbidden then
848 If (modulator <> BYTE_NULL) then
851 If volume_scaling then
852 If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
853 (percussion_mode and (chan in [17..20])) then
854 modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator);
855 If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
856 (percussion_mode and (chan in [17..20])) then
857 opl3out(_instr[02]+_chan_m[chan],
858 scale_volume(scale_volume(modulator,63-global_volume),63-overall_volume)+LO(vscale_table[chan]))
860 opl3out(_instr[02]+_chan_m[chan],
861 temp+LO(vscale_table[chan]));
862 volume_table[chan] := concw(temp,HI(volume_table[chan]));
863 If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
864 (percussion_mode and (chan in [17..20])) then
865 modulator_vol[chan] := 63-scale_volume(modulator,63-global_volume)
866 else modulator_vol[chan] := 63-modulator;
869 If (carrier <> BYTE_NULL) then
872 If volume_scaling then
873 carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier);
874 opl3out(_instr[03]+_chan_c[chan],
875 scale_volume(scale_volume(carrier,63-global_volume),63-overall_volume)+HI(vscale_table[chan]));
876 volume_table[chan] := concw(LO(volume_table[chan]),temp);
877 carrier_vol[chan] := 63-scale_volume(carrier,63-global_volume);
881 procedure reset_ins_volume(chan: Byte);
883 If NOT volume_scaling then
884 set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,
885 ins_parameter(voice_table[chan],3) AND $3f,chan)
886 else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
887 set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,0,chan)
888 else set_ins_volume(0,0,chan);
891 procedure set_global_volume;
897 For chan := 1 to songdata.nm_tracks do
898 If NOT ((carrier_vol[chan] = 0) and
899 (modulator_vol[chan] = 0)) then
900 If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
901 set_ins_volume(BYTE_NULL,HI(volume_table[chan]),chan)
902 else set_ins_volume(LO(volume_table[chan]),HI(volume_table[chan]),chan);
905 procedure set_overall_volume(level: Byte);
907 overall_volume := max(level,63);
911 procedure init_macro_table(chan,note,ins: Byte; freq: Word);
913 macro_table[chan].fmreg_count := 1;
914 macro_table[chan].fmreg_pos := 0;
915 macro_table[chan].fmreg_duration := 0;
916 macro_table[chan].fmreg_table := ins;
917 macro_table[chan].arpg_count := 1;
918 macro_table[chan].arpg_pos := 0;
919 macro_table[chan].arpg_table := songdata.instr_macros[ins].arpeggio_table;
920 macro_table[chan].arpg_note := note;
921 macro_table[chan].vib_count := 1;
922 macro_table[chan].vib_paused := FALSE;
923 macro_table[chan].vib_pos := 0;
924 macro_table[chan].vib_table := songdata.instr_macros[ins].vibrato_table;
925 macro_table[chan].vib_freq := freq;
926 macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
929 procedure set_ins_data(ins,chan: Byte);
935 If (ins <> event_table[chan].instr_def) or reset_chan[chan] then
937 opl3out(_instr[02]+_chan_m[chan],63);
938 opl3out(_instr[03]+_chan_c[chan],63);
940 If NOT pan_lock[chan] then
941 panning_table[chan] := ins_parameter(ins,11)
942 else panning_table[chan] := songdata.lock_flags[chan] AND 3;
944 opl3out(_instr[00]+_chan_m[chan],ins_parameter(ins,0));
945 opl3out(_instr[01]+_chan_c[chan],ins_parameter(ins,1));
946 opl3out(_instr[04]+_chan_m[chan],ins_parameter(ins,4));
947 opl3out(_instr[05]+_chan_c[chan],ins_parameter(ins,5));
948 opl3out(_instr[06]+_chan_m[chan],ins_parameter(ins,6));
949 opl3out(_instr[07]+_chan_c[chan],ins_parameter(ins,7));
950 opl3out(_instr[08]+_chan_m[chan],ins_parameter(ins,8));
951 opl3out(_instr[09]+_chan_c[chan],ins_parameter(ins,9));
952 opl3out(_instr[10]+_chan_n[chan],ins_parameter(ins,10) OR _panning[panning_table[chan]]);
954 fmpar_table[chan].connect := ins_parameter(ins,10) AND 1;
955 fmpar_table[chan].feedb := ins_parameter(ins,10) SHR 1 AND 7;
956 fmpar_table[chan].multipM := ins_parameter(ins,0) AND $0f;
957 fmpar_table[chan].kslM := ins_parameter(ins,2) SHR 6;
958 fmpar_table[chan].tremM := ins_parameter(ins,0) SHR 7;
959 fmpar_table[chan].vibrM := ins_parameter(ins,0) SHR 6 AND 1;
960 fmpar_table[chan].ksrM := ins_parameter(ins,0) SHR 4 AND 1;
961 fmpar_table[chan].sustM := ins_parameter(ins,0) SHR 5 AND 1;
962 fmpar_table[chan].multipC := ins_parameter(ins,1) AND $0f;
963 fmpar_table[chan].kslC := ins_parameter(ins,3) SHR 6;
964 fmpar_table[chan].tremC := ins_parameter(ins,1) SHR 7;
965 fmpar_table[chan].vibrC := ins_parameter(ins,1) SHR 6 AND 1;
966 fmpar_table[chan].ksrC := ins_parameter(ins,1) SHR 4 AND 1;
967 fmpar_table[chan].sustC := ins_parameter(ins,1) SHR 5 AND 1;
969 fmpar_table[chan].adsrw_car.attck := ins_parameter(ins,5) SHR 4;
970 fmpar_table[chan].adsrw_mod.attck := ins_parameter(ins,4) SHR 4;
971 fmpar_table[chan].adsrw_car.dec := ins_parameter(ins,5) AND $0f;
972 fmpar_table[chan].adsrw_mod.dec := ins_parameter(ins,4) AND $0f;
973 fmpar_table[chan].adsrw_car.sustn := ins_parameter(ins,7) SHR 4;
974 fmpar_table[chan].adsrw_mod.sustn := ins_parameter(ins,6) SHR 4;
975 fmpar_table[chan].adsrw_car.rel := ins_parameter(ins,7) AND $0f;
976 fmpar_table[chan].adsrw_mod.rel := ins_parameter(ins,6) AND $0f;
977 fmpar_table[chan].adsrw_car.wform := ins_parameter(ins,9) AND $07;
978 fmpar_table[chan].adsrw_mod.wform := ins_parameter(ins,8) AND $07;
980 If NOT reset_chan[chan] then
981 keyoff_loop[chan] := FALSE;
983 If reset_chan[chan] then
985 voice_table[chan] := ins;
986 reset_ins_volume(chan);
987 reset_chan[chan] := FALSE;
990 If (event_table[chan].note AND $7f in [1..12*8+1]) then
991 init_macro_table(chan,event_table[chan].note AND $7f,ins,freq_table[chan])
992 else init_macro_table(chan,0,ins,freq_table[chan]);
995 vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6,
996 fmpar_table[chan].kslC SHL 6);
997 voice_table[chan] := ins;
998 old_ins := event_table[chan].instr_def;
999 event_table[chan].instr_def := ins;
1001 If NOT volume_lock[chan] or
1002 (ins <> old_ins) then reset_ins_volume(chan);
1005 procedure update_modulator_adsrw(chan: Byte);
1007 opl3out(_instr[04]+_chan_m[chan],
1008 fmpar_table[chan].adsrw_mod.attck SHL 4+
1009 fmpar_table[chan].adsrw_mod.dec);
1010 opl3out(_instr[06]+_chan_m[chan],
1011 fmpar_table[chan].adsrw_mod.sustn SHL 4+
1012 fmpar_table[chan].adsrw_mod.rel);
1013 opl3out(_instr[08]+_chan_m[chan],
1014 fmpar_table[chan].adsrw_mod.wform);
1017 procedure update_carrier_adsrw(chan: Byte);
1019 opl3out(_instr[05]+_chan_c[chan],
1020 fmpar_table[chan].adsrw_car.attck SHL 4+
1021 fmpar_table[chan].adsrw_car.dec);
1022 opl3out(_instr[07]+_chan_c[chan],
1023 fmpar_table[chan].adsrw_car.sustn SHL 4+
1024 fmpar_table[chan].adsrw_car.rel);
1025 opl3out(_instr[09]+_chan_c[chan],
1026 fmpar_table[chan].adsrw_car.wform);
1029 procedure update_fmpar(chan: Byte);
1031 opl3out(_instr[00]+_chan_m[chan],fmpar_table[chan].multipM+
1032 fmpar_table[chan].ksrM SHL 4+
1033 fmpar_table[chan].sustM SHL 5+
1034 fmpar_table[chan].vibrM SHL 6+
1035 fmpar_table[chan].tremM SHL 7);
1036 opl3out(_instr[01]+_chan_c[chan],fmpar_table[chan].multipC+
1037 fmpar_table[chan].ksrC SHL 4+
1038 fmpar_table[chan].sustC SHL 5+
1039 fmpar_table[chan].vibrC SHL 6+
1040 fmpar_table[chan].tremC SHL 7);
1042 opl3out(_instr[10]+_chan_n[chan],(fmpar_table[chan].connect+
1043 fmpar_table[chan].feedb SHL 1) OR
1044 _panning[panning_table[chan]]);
1046 vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6,
1047 fmpar_table[chan].kslC SHL 6);
1048 set_ins_volume(LO(volume_table[chan]),
1049 HI(volume_table[chan]),chan);
1052 function is_4op_chan(chan: Byte): Boolean; assembler;
1054 mov al,byte ptr [songdata.flag_4op]
1108 procedure output_note(note,ins,chan: Byte; restart_macro: Boolean);
1115 If (note = 0) and (ftune_table[chan] = 0) then EXIT;
1116 If NOT (note in [1..12*8+1]) then freq := freq_table[chan]
1118 freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12));
1119 If NOT (is_4op_chan(chan) and (chan in [1,3,5,10,12,14])) then
1120 opl3out($0b0+_chan_n[chan],0);
1122 freq_table[chan] := concw(LO(freq_table[chan]),
1123 HI(freq_table[chan]) OR $20);
1125 pos := Round(25/(12*8+1)*note);
1126 If (decay_bar[pos].lvl <> 0) then
1128 (decay_bar[pos-1].dir <> 1) then
1130 else If (pos < 25) and
1131 (decay_bar[pos+1].lvl <> 1) then
1134 If is_4op_chan(chan) then
1135 If (chan in [2,4,6,11,13,15]) then
1137 decay_bar[pos].dir := 1;
1138 If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
1139 decay_bar[pos].max_lvl :=
1140 (carrier_vol[PRED(chan)]+carrier_vol[chan]) DIV 2
1141 else decay_bar[pos].max_lvl :=
1142 (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]+
1143 carrier_vol[chan]+modulator_vol[chan]) DIV 4;
1148 decay_bar[pos].dir := 1;
1149 If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
1150 decay_bar[pos].max_lvl :=
1152 else decay_bar[pos].max_lvl :=
1153 (carrier_vol[chan]+modulator_vol[chan]) DIV 2;
1157 If (ftune_table[chan] = -127) then ftune_table[chan] := 0;
1158 freq := freq+ftune_table[chan];
1160 If NOT (is_4op_chan(chan) and (chan in [1,3,5,10,12,14])) then
1161 change_frequency(chan,freq);
1165 event_table[chan].note := note;
1166 If restart_macro then
1167 With event_table[chan] do
1168 If NOT (((effect_def = ef_Extended) and
1169 (effect DIV 16 = ef_ex_ExtendedCmd) and
1170 (effect MOD 16 = ef_ex_cmd_NoRestart)) or
1171 ((effect_def2 = ef_Extended) and
1172 (effect2 DIV 16 = ef_ex_ExtendedCmd) and
1173 (effect2 MOD 16 = ef_ex_cmd_NoRestart))) then
1174 init_macro_table(chan,note,ins,freq)
1175 else macro_table[chan].arpg_note := note;
1179 procedure output_note_NR(note,ins,chan: Byte; restart_macro: Boolean);
1186 If (note = 0) and (ftune_table[chan] = 0) then EXIT;
1187 If NOT (note in [1..12*8+1]) then freq := freq_table[chan]
1189 freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12));
1190 freq_table[chan] := concw(LO(freq_table[chan]),
1191 HI(freq_table[chan]) OR $20);
1193 pos := Round(25/(12*8+1)*note);
1194 If (decay_bar[pos].lvl <> 0) then
1196 (decay_bar[pos-1].dir <> 1) then
1198 else If (pos < 25) and
1199 (decay_bar[pos+1].lvl <> 1) then
1202 If is_4op_chan(chan) then
1203 If (chan in [2,4,6,11,13,15]) then
1205 decay_bar[pos].dir := 1;
1206 If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
1207 decay_bar[pos].max_lvl :=
1208 (carrier_vol[PRED(chan)]+carrier_vol[chan]) DIV 2
1209 else decay_bar[pos].max_lvl :=
1210 (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]+
1211 carrier_vol[chan]+modulator_vol[chan]) DIV 4;
1216 decay_bar[pos].dir := 1;
1217 If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
1218 decay_bar[pos].max_lvl :=
1220 else decay_bar[pos].max_lvl :=
1221 (carrier_vol[chan]+modulator_vol[chan]) DIV 2;
1225 If (ftune_table[chan] = -127) then ftune_table[chan] := 0;
1226 freq := freq+ftune_table[chan];
1228 If NOT (is_4op_chan(chan) and (chan in [1,3,5,10,12,14])) then
1229 change_frequency(chan,freq);
1233 event_table[chan].note := note;
1234 If restart_macro then
1235 With event_table[chan] do
1236 If NOT (((effect_def = ef_Extended) and
1237 (effect DIV 16 = ef_ex_ExtendedCmd) and
1238 (effect MOD 16 = ef_ex_cmd_NoRestart)) or
1239 ((effect_def2 = ef_Extended) and
1240 (effect2 DIV 16 = ef_ex_ExtendedCmd) and
1241 (effect2 MOD 16 = ef_ex_cmd_NoRestart))) then
1242 init_macro_table(chan,note,ins,freq)
1243 else macro_table[chan].arpg_note := note;
1247 procedure generate_custom_vibrato(value: Byte);
1250 vibtab_size: array[0..15] of Byte = (
1251 16,16,16,16,32,32,32,32,64,64,64,64,128,128,128,128);
1258 function min0(value: Longint): Longint;
1260 If (value >= 0) then min0 := value
1266 // set default speed table
1268 vibtrem_table_size := def_vibtrem_table_size;
1269 Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table));
1272 // set custom speed table (fixed size = 32)
1275 vibtrem_table_size := def_vibtrem_table_size;
1277 For idx2 := 0 to 7 do
1279 vibtrem_table[idx2*32] := 0;
1280 For idx := 1 to 16 do
1281 vibtrem_table[idx2*32+idx] := ROUND(idx*mul_r);
1282 For idx := 17 to 31 do
1283 vibtrem_table[idx2*32+idx] := ROUND((32-idx)*mul_r);
1287 // set custom speed table (speed factor = 1-4)
1290 vibtrem_speed_factor := SUCC((value-240) MOD 4);
1291 vibtrem_table_size := 2*vibtab_size[value-240];
1292 mul_b := 256 DIV (vibtab_size[value-240]);
1293 For idx2 := 0 to PRED(128 DIV vibtab_size[value-240]) do
1295 vibtrem_table[2*vibtab_size[value-240]*idx2] := 0;
1296 For idx := 1 to vibtab_size[value-240] do
1297 vibtrem_table[2*vibtab_size[value-240]*idx2+idx] :=
1299 For idx := vibtab_size[value-240]+1 to
1300 2*vibtab_size[value-240]-1 do
1301 vibtrem_table[2*vibtab_size[value-240]*idx2+idx] :=
1302 min0((2*vibtab_size[value-240]-idx)*mul_b-1);
1308 procedure update_fine_effects(chan: Byte); forward;
1309 procedure play_line;
1313 event: array[1..20] of tCHUNK;
1314 eLo,eHi,eLo2,eHi2: array[1..20] of Byte;
1316 function no_loop(current_chan,current_line: Byte): Boolean;
1324 For chan := 1 to PRED(current_chan) do
1325 If (loop_table[chan][current_line] <> 0) and
1326 (loop_table[chan][current_line] <> BYTE_NULL) then
1334 function get_event(pattern,line,channel: Byte): tCHUNK;
1355 mov ebx,256*CHUNK_SIZE
1364 mov ebx,20*256*CHUNK_SIZE
1368 mov ebx,8*20*256*CHUNK_SIZE
1379 _debug_str_ := 'A2PLAYER.PAS:play_line';
1380 If (current_line = 0) and
1381 (current_order = calc_following_order(0)) then
1384 If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
1385 (current_order <> last_order) then
1387 FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
1388 FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
1389 last_order := current_order;
1392 For chan := 1 to songdata.nm_tracks do
1394 event[chan] := get_event(current_pattern,current_line,chan);
1395 If (effect_table[chan] <> 0) then last_effect[chan] := effect_table[chan];
1396 If (glfsld_table[chan] <> 0) then effect_table[chan] := glfsld_table[chan]
1397 else effect_table[chan] := effect_table[chan] AND $0ff00;
1398 If (effect_table2[chan] <> 0) then last_effect2[chan] := effect_table2[chan];
1399 If (glfsld_table2[chan] <> 0) then effect_table2[chan] := glfsld_table2[chan]
1400 else effect_table2[chan] := effect_table2[chan] AND $0ff00;
1401 ftune_table[chan] := 0;
1403 If (event[chan].note = BYTE_NULL) then
1404 event[chan].note := event_table[chan].note OR keyoff_flag
1405 else If (event[chan].note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then
1406 event[chan].note := event[chan].note-fixed_note_flag;
1408 If (event[chan].note <> 0) or
1409 (event[chan].effect_def <> 0) or
1410 (event[chan].effect_def2 <> 0) or
1411 ((event[chan].effect_def = 0) and (event[chan].effect <> 0)) or
1412 ((event[chan].effect_def2 = 0) and (event[chan].effect2 <> 0)) then
1413 event_new[chan] := TRUE
1414 else event_new[chan] := FALSE;
1416 If (event[chan].note <> 0) or
1417 (event[chan].instr_def <> 0) or
1418 (event[chan].effect_def+event[chan].effect <> 0) or
1419 (event[chan].effect_def2+event[chan].effect2 <> 0) then
1421 event_table[chan].effect_def := event[chan].effect_def;
1422 event_table[chan].effect := event[chan].effect;
1423 event_table[chan].effect_def2 := event[chan].effect_def2;
1424 event_table[chan].effect2 := event[chan].effect2;
1427 If (event[chan].instr_def <> 0) then
1428 If NOT Empty(songdata.instr_data[event[chan].instr_def],
1429 INSTRUMENT_SIZE) then
1430 set_ins_data(event[chan].instr_def,chan)
1432 release_sustaining_sound(chan);
1433 set_ins_data(event[chan].instr_def,chan);
1436 If NOT (event[chan].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,
1437 ef_VibratoVolSlide,ef_VibratoVSlideFine]) then
1438 FillChar(vibr_table[chan],SizeOf(vibr_table[chan]),0);
1440 If NOT (event[chan].effect_def2 in [ef_Vibrato,ef_ExtraFineVibrato,
1441 ef_VibratoVolSlide,ef_VibratoVSlideFine]) then
1442 FillChar(vibr_table2[chan],SizeOf(vibr_table2[chan]),0);
1444 If NOT (event[chan].effect_def in [ef_RetrigNote,ef_MultiRetrigNote]) then
1445 FillChar(retrig_table[chan],SizeOf(retrig_table[chan]),0);
1447 If NOT (event[chan].effect_def2 in [ef_RetrigNote,ef_MultiRetrigNote]) then
1448 FillChar(retrig_table2[chan],SizeOf(retrig_table2[chan]),0);
1450 If NOT (event[chan].effect_def in [ef_Tremolo,ef_ExtraFineTremolo]) then
1451 FillChar(trem_table[chan],SizeOf(trem_table[chan]),0);
1453 If NOT (event[chan].effect_def2 in [ef_Tremolo,ef_ExtraFineTremolo]) then
1454 FillChar(trem_table2[chan],SizeOf(trem_table2[chan]),0);
1456 If NOT (((event[chan].effect_def = ef_Arpeggio) and (event[chan].effect <> 0)) or
1457 (event[chan].effect_def = ef_ExtraFineArpeggio)) and
1463 (arpgg_table[chan].note <> 0) and (arpgg_table[chan].state <> 1) then
1465 arpgg_table[chan].state := 1;
1466 change_frequency(chan,nFreq(arpgg_table[chan].note-1)+
1467 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
1469 else If NOT (((event[chan].effect_def2 = ef_Arpeggio) and (event[chan].effect2 <> 0)) or
1470 (event[chan].effect_def2 = ef_ExtraFineArpeggio)) and
1471 (arpgg_table2[chan].note <> 0) and (arpgg_table2[chan].state <> 1) then
1473 arpgg_table2[chan].state := 1;
1474 change_frequency(chan,nFreq(arpgg_table2[chan].note-1)+
1475 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
1479 For chan := 1 to songdata.nm_tracks do
1481 If (tremor_table[chan].pos <> 0) and
1482 (event[chan].effect_def <> ef_Tremor) then
1484 tremor_table[chan].pos := 0;
1485 set_ins_volume(LO(tremor_table[chan].volume),
1486 HI(tremor_table[chan].volume),chan);
1489 If (tremor_table2[chan].pos <> 0) and
1490 (event[chan].effect_def2 <> ef_Tremor) then
1492 tremor_table2[chan].pos := 0;
1493 set_ins_volume(LO(tremor_table2[chan].volume),
1494 HI(tremor_table2[chan].volume),chan);
1497 eLo[chan] := LO(last_effect[chan]);
1498 eHi[chan] := HI(last_effect[chan]);
1499 eLo2[chan] := LO(last_effect2[chan]);
1500 eHi2[chan] := HI(last_effect2[chan]);
1503 For chan := 1 to songdata.nm_tracks do
1504 Case event[chan].effect_def of
1507 ef_ExtraFineArpeggio,
1510 If (event[chan].effect_def <> ef_Arpeggio) or
1511 (event[chan].effect <> 0) then
1513 Case event[chan].effect_def of
1515 effect_table[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect);
1517 ef_ExtraFineArpeggio:
1518 effect_table[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect);
1522 If (event[chan].effect <> 0) then
1523 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
1524 else If (eLo[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and
1525 (eHi[chan] <> 0) then
1526 effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
1527 else effect_table[chan] := effect_table[chan] AND $0ff00;
1530 If (event[chan].note AND $7f in [1..12*8+1]) then
1532 arpgg_table[chan].state := 0;
1533 arpgg_table[chan].note := event[chan].note AND $7f;
1534 If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
1536 arpgg_table[chan].add1 := event[chan].effect DIV 16;
1537 arpgg_table[chan].add2 := event[chan].effect MOD 16;
1540 else If (event[chan].note = 0) and
1541 (event_table[chan].note AND $7f in [1..12*8+1]) then
1543 If NOT (eLo[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio,
1544 ef_ArpggVSlide,ef_ArpggVSlideFine]) then
1545 arpgg_table[chan].state := 0;
1547 arpgg_table[chan].note := event_table[chan].note AND $7f;
1548 If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
1550 arpgg_table[chan].add1 := event[chan].effect DIV 16;
1551 arpgg_table[chan].add2 := event[chan].effect MOD 16;
1554 else effect_table[chan] := 0;
1562 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect);
1563 fslide_table[chan] := event[chan].effect;
1567 ef_GlobalFSlideDown:
1569 If (event[chan].effect_def = ef_GlobalFSlideUp) then
1571 If (event[chan].effect_def2 = ef_Extended) and
1572 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then
1573 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
1575 else If (event[chan].effect_def2 = ef_Extended) and
1576 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
1577 effect_table[chan] := concw(ef_FSlideUpFine,event[chan].effect)
1578 else effect_table[chan] := concw(ef_FSlideUp,event[chan].effect);
1582 If (event[chan].effect_def2 = ef_Extended) and
1583 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then
1584 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
1586 else If (event[chan].effect_def2 = ef_Extended) and
1587 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
1588 effect_table[chan] := concw(ef_FSlideDownFine,event[chan].effect)
1589 else effect_table[chan] := concw(ef_FSlideDown,event[chan].effect);
1591 For idx := chan to songdata.nm_tracks do
1593 fslide_table[idx] := event[chan].effect;
1594 glfsld_table[idx] := effect_table[chan];
1600 ef_FSlideDownVSlide,
1604 ef_FSlDownFineVSlide,
1606 If (event[chan].effect <> 0) then
1607 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
1608 else If (eLo[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide,
1609 ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF,
1610 ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and
1611 (eHi[chan] <> 0) then
1612 effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
1613 else effect_table[chan] := effect_table[chan] AND $0ff00;
1616 If (event[chan].note in [1..12*8+1]) then
1618 If (event[chan].effect <> 0) then
1619 effect_table[chan] := concw(ef_TonePortamento,event[chan].effect)
1620 else If (eLo[chan] = ef_TonePortamento) and
1621 (eHi[chan] <> 0) then
1622 effect_table[chan] := concw(ef_TonePortamento,eHi[chan])
1623 else effect_table[chan] := ef_TonePortamento;
1625 porta_table[chan].speed := HI(effect_table[chan]);
1626 porta_table[chan].freq := nFreq(event[chan].note-1)+
1627 SHORTINT(ins_parameter(event_table[chan].instr_def,12));
1629 else If (eLo[chan] = ef_TonePortamento) then
1631 If (event[chan].effect <> 0) then
1632 effect_table[chan] := concw(ef_TonePortamento,event[chan].effect)
1633 else If (eLo[chan] = ef_TonePortamento) and
1634 (eHi[chan] <> 0) then
1635 effect_table[chan] := concw(ef_TonePortamento,eHi[chan])
1636 else effect_table[chan] := ef_TonePortamento;
1637 porta_table[chan].speed := HI(effect_table[chan]);
1641 ef_TPortamVSlideFine:
1642 If (event[chan].effect <> 0) then
1643 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
1644 else If (eLo[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and
1645 (eHi[chan] <> 0) then
1646 effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
1647 else effect_table[chan] := effect_table[chan] AND $0ff00;
1650 ef_ExtraFineVibrato:
1652 If (event[chan].effect <> 0) then
1653 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
1654 else If (eLo[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and
1655 (eHi[chan] <> 0) then
1656 effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
1657 else effect_table[chan] := event[chan].effect_def;
1659 If (event[chan].effect_def2 = ef_Extended) and
1660 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
1661 vibr_table[chan].fine := TRUE;
1663 vibr_table[chan].speed := HI(effect_table[chan]) DIV 16;
1664 vibr_table[chan].depth := HI(effect_table[chan]) MOD 16;
1668 ef_ExtraFineTremolo:
1670 If (event[chan].effect <> 0) then
1671 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
1672 else If (eLo[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and
1673 (eHi[chan] <> 0) then
1674 effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
1675 else effect_table[chan] := event[chan].effect_def;
1677 If (event[chan].effect_def2 = ef_Extended) and
1678 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then
1679 trem_table[chan].fine := TRUE;
1681 trem_table[chan].speed := HI(effect_table[chan]) DIV 16;
1682 trem_table[chan].depth := HI(effect_table[chan]) MOD 16;
1686 ef_VibratoVSlideFine:
1688 If (event[chan].effect <> 0) then
1689 effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
1690 else If (eLo[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and
1691 (HI(effect_table[chan]) <> 0) then
1692 effect_table[chan] := concw(event[chan].effect_def,HI(effect_table[chan]))
1693 else effect_table[chan] := effect_table[chan] AND $0ff00;
1695 If (event[chan].effect_def2 = ef_Extended) and
1696 (event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
1697 vibr_table[chan].fine := TRUE;
1701 set_ins_volume(BYTE_NULL,63-event[chan].effect,chan);
1704 set_ins_volume(63-event[chan].effect,BYTE_NULL,chan);
1707 If percussion_mode and (chan in [17..20]) then
1708 set_ins_volume(63-event[chan].effect,BYTE_NULL,chan)
1709 else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
1710 set_ins_volume(BYTE_NULL,63-event[chan].effect,chan)
1711 else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan);
1714 If percussion_mode and (chan in [17..20]) then
1715 set_ins_volume(63-event[chan].effect,BYTE_NULL,chan)
1716 else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
1717 set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect),63-event[chan].effect,chan)
1718 else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan);
1721 If no_loop(chan,current_line) then
1723 pattern_break := TRUE;
1724 next_line := pattern_break_flag+chan;
1728 If no_loop(chan,current_line) then
1730 pattern_break := TRUE;
1731 next_line := max(event[chan].effect,PRED(songdata.patt_len));
1735 speed := event[chan].effect;
1738 update_timer(event[chan].effect);
1742 If (event[chan].effect DIV 16 in [0..7]) then
1744 fmpar_table[chan].adsrw_car.wform := event[chan].effect DIV 16;
1745 update_carrier_adsrw(chan);
1748 If (event[chan].effect MOD 16 in [0..7]) then
1750 fmpar_table[chan].adsrw_mod.wform := event[chan].effect MOD 16;
1751 update_modulator_adsrw(chan);
1756 effect_table[chan] := concw(ef_VolSlide,event[chan].effect);
1759 effect_table[chan] := concw(ef_VolSlideFine,event[chan].effect);
1762 If (event[chan].effect <> 0) then
1764 If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
1765 retrig_table[chan] := 1;
1766 effect_table[chan] := concw(ef_RetrigNote,event[chan].effect);
1771 global_volume := event[chan].effect;
1776 If (event[chan].effect DIV 16 <> 0) then
1778 If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
1779 retrig_table[chan] := 1;
1780 effect_table[chan] := concw(ef_MultiRetrigNote,event[chan].effect);
1784 If (event[chan].effect DIV 16 <> 0) and
1785 (event[chan].effect MOD 16 <> 0) then
1787 If (eLo[chan] <> ef_Tremor) then
1789 tremor_table[chan].pos := 0;
1790 tremor_table[chan].volume := volume_table[chan];
1792 effect_table[chan] := concw(ef_Tremor,event[chan].effect);
1796 Case (event[chan].effect DIV 16) of
1798 Case (event[chan].effect MOD 16) of
1800 opl3out(_instr[11],misc_register AND $07f);
1801 current_tremolo_depth := 0;
1805 opl3out(_instr[11],misc_register OR $080);
1806 current_tremolo_depth := 1;
1811 Case (event[chan].effect MOD 16) of
1813 opl3out(_instr[11],misc_register AND $0bf);
1814 current_vibrato_depth := 0;
1818 opl3out(_instr[11],misc_register OR $040);
1819 current_vibrato_depth := 1;
1823 ef_ex_SetAttckRateM:
1825 fmpar_table[chan].adsrw_mod.attck := event[chan].effect MOD 16;
1826 update_modulator_adsrw(chan);
1829 ef_ex_SetDecayRateM:
1831 fmpar_table[chan].adsrw_mod.dec := event[chan].effect MOD 16;
1832 update_modulator_adsrw(chan);
1835 ef_ex_SetSustnLevelM:
1837 fmpar_table[chan].adsrw_mod.sustn := event[chan].effect MOD 16;
1838 update_modulator_adsrw(chan);
1843 fmpar_table[chan].adsrw_mod.rel := event[chan].effect MOD 16;
1844 update_modulator_adsrw(chan);
1847 ef_ex_SetAttckRateC:
1849 fmpar_table[chan].adsrw_car.attck := event[chan].effect MOD 16;
1850 update_carrier_adsrw(chan);
1853 ef_ex_SetDecayRateC:
1855 fmpar_table[chan].adsrw_car.dec := event[chan].effect MOD 16;
1856 update_carrier_adsrw(chan);
1859 ef_ex_SetSustnLevelC:
1861 fmpar_table[chan].adsrw_car.sustn := event[chan].effect MOD 16;
1862 update_carrier_adsrw(chan);
1867 fmpar_table[chan].adsrw_car.rel := event[chan].effect MOD 16;
1868 update_carrier_adsrw(chan);
1873 fmpar_table[chan].feedb := event[chan].effect MOD 16;
1877 ef_ex_SetPanningPos:
1879 panning_table[chan] := event[chan].effect MOD 16;
1884 ef_ex_PatternLoopRec:
1885 If (event[chan].effect MOD 16 = 0) then
1886 loopbck_table[chan] := current_line
1887 else If (loopbck_table[chan] <> BYTE_NULL) then
1889 If (loop_table[chan][current_line] = BYTE_NULL) then
1890 loop_table[chan][current_line] := event[chan].effect MOD 16;
1891 If (loop_table[chan][current_line] <> 0) then
1893 pattern_break := TRUE;
1894 next_line := pattern_loop_flag+chan;
1896 else If (event[chan].effect DIV 16 = ef_ex_PatternLoopRec) then
1897 loop_table[chan][current_line] := BYTE_NULL;
1900 ef_ex_MacroKOffLoop:
1901 If (event[chan].effect MOD 16 <> 0) then
1902 keyoff_loop[chan] := TRUE
1903 else keyoff_loop[chan] := FALSE;
1906 Case (event[chan].effect MOD 16) of
1907 ef_ex_cmd_RSS: release_sustaining_sound(chan);
1908 ef_ex_cmd_ResetVol: reset_ins_volume(chan);
1909 ef_ex_cmd_LockVol: volume_lock [chan] := TRUE;
1910 ef_ex_cmd_UnlockVol: volume_lock [chan] := FALSE;
1911 ef_ex_cmd_LockVP: peak_lock [chan] := TRUE;
1912 ef_ex_cmd_UnlockVP: peak_lock [chan] := FALSE;
1913 ef_ex_cmd_VSlide_def: volslide_type[chan] := 0;
1914 ef_ex_cmd_LockPan: pan_lock [chan] := TRUE;
1915 ef_ex_cmd_UnlockPan: pan_lock [chan] := FALSE;
1916 ef_ex_cmd_VibrOff: change_frequency(chan,freq_table[chan]);
1917 ef_ex_cmd_TremOff: set_ins_volume(LO(volume_table[chan]),
1918 HI(volume_table[chan]),chan);
1919 ef_ex_cmd_VSlide_car:
1920 If (event[chan].effect_def2 = ef_Extended) and
1921 (event[chan].effect2 = ef_ex_ExtendedCmd*16+
1922 ef_ex_cmd_VSlide_mod) then
1923 volslide_type[chan] := 3
1924 else volslide_type[chan] := 1;
1926 ef_ex_cmd_VSlide_mod:
1927 If (event[chan].effect_def2 = ef_Extended) and
1928 (event[chan].effect2 = ef_ex_ExtendedCmd*16+
1929 ef_ex_cmd_VSlide_car) then
1930 volslide_type[chan] := 3
1931 else volslide_type[chan] := 2;
1936 Case (event[chan].effect DIV 16) of
1937 ef_ex2_PatDelayFrame,
1940 pattern_delay := TRUE;
1941 If (event[chan].effect DIV 16 = ef_ex2_PatDelayFrame) then
1942 tickD := (event[chan].effect MOD 16)
1943 else tickD := speed*(event[chan].effect MOD 16);
1948 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0);
1949 notedel_table[chan] := event[chan].effect MOD 16;
1954 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0);
1955 notecut_table[chan] := event[chan].effect MOD 16;
1959 Inc(ftune_table[chan],event[chan].effect MOD 16);
1961 ef_ex2_FineTuneDown:
1962 Dec(ftune_table[chan],event[chan].effect MOD 16);
1964 ef_ex2_GlVolSlideUp:
1965 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp,
1966 event[chan].effect MOD 16);
1967 ef_ex2_GlVolSlideDn:
1968 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn,
1969 event[chan].effect MOD 16);
1970 ef_ex2_GlVolSlideUpF:
1971 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF,
1972 event[chan].effect MOD 16);
1973 ef_ex2_GlVolSlideDnF:
1974 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF,
1975 event[chan].effect MOD 16);
1976 ef_ex2_GlVolSldUpXF:
1977 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF,
1978 event[chan].effect MOD 16);
1979 ef_ex2_GlVolSldDnXF:
1980 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF,
1981 event[chan].effect MOD 16);
1982 ef_ex2_VolSlideUpXF:
1983 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF,
1984 event[chan].effect MOD 16);
1985 ef_ex2_VolSlideDnXF:
1986 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF,
1987 event[chan].effect MOD 16);
1988 ef_ex2_FreqSlideUpXF:
1989 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
1990 event[chan].effect MOD 16);
1991 ef_ex2_FreqSlideDnXF:
1992 effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
1993 event[chan].effect MOD 16);
1997 Case (event[chan].effect DIV 16) of
1998 ef_ex3_SetConnection:
2000 fmpar_table[chan].connect := event[chan].effect MOD 16;
2006 fmpar_table[chan].multipM := event[chan].effect MOD 16;
2012 fmpar_table[chan].kslM := event[chan].effect MOD 16;
2018 fmpar_table[chan].tremM := event[chan].effect MOD 16;
2024 fmpar_table[chan].vibrM := event[chan].effect MOD 16;
2030 fmpar_table[chan].ksrM := event[chan].effect MOD 16;
2036 fmpar_table[chan].sustM := event[chan].effect MOD 16;
2042 fmpar_table[chan].multipC := event[chan].effect MOD 16;
2048 fmpar_table[chan].kslC := event[chan].effect MOD 16;
2054 fmpar_table[chan].tremC := event[chan].effect MOD 16;
2060 fmpar_table[chan].vibrC := event[chan].effect MOD 16;
2066 fmpar_table[chan].ksrC := event[chan].effect MOD 16;
2072 fmpar_table[chan].sustC := event[chan].effect MOD 16;
2078 For chan := 1 to songdata.nm_tracks do
2079 Case event[chan].effect_def2 of
2081 ef_ExtraFineArpeggio,
2084 If (event[chan].effect_def2 <> ef_Arpeggio) or
2085 (event[chan].effect2 <> 0) then
2087 Case event[chan].effect_def2 of
2089 effect_table2[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect2);
2091 ef_ExtraFineArpeggio:
2092 effect_table2[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect2);
2096 If (event[chan].effect2 <> 0) then
2097 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
2098 else If (eLo2[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and
2099 (eHi2[chan] <> 0) then
2100 effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
2101 else effect_table2[chan] := effect_table2[chan] AND $0ff00;
2104 If (event[chan].note AND $7f in [1..12*8+1]) then
2106 arpgg_table2[chan].state := 0;
2107 arpgg_table2[chan].note := event[chan].note AND $7f;
2108 If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
2110 arpgg_table2[chan].add1 := event[chan].effect2 DIV 16;
2111 arpgg_table2[chan].add2 := event[chan].effect2 MOD 16;
2114 else If (event[chan].note = 0) and
2115 (event_table[chan].note AND $7f in [1..12*8+1]) then
2117 If NOT (eLo2[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio,
2118 ef_ArpggVSlide,ef_ArpggVSlideFine]) then
2119 arpgg_table2[chan].state := 0;
2121 arpgg_table2[chan].note := event_table[chan].note AND $7f;
2122 If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
2124 arpgg_table2[chan].add1 := event[chan].effect2 DIV 16;
2125 arpgg_table2[chan].add2 := event[chan].effect2 MOD 16;
2128 else effect_table2[chan] := 0;
2136 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2);
2137 fslide_table2[chan] := event[chan].effect2;
2141 ef_GlobalFSlideDown:
2143 If (event[chan].effect_def2 = ef_GlobalFSlideUp) then
2145 If (event[chan].effect_def = ef_Extended) and
2146 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then
2147 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
2148 event[chan].effect2)
2149 else If (event[chan].effect_def = ef_Extended) and
2150 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
2151 effect_table2[chan] := concw(ef_FSlideUpFine,event[chan].effect2)
2152 else effect_table2[chan] := concw(ef_FSlideUp,event[chan].effect2);
2156 If (event[chan].effect_def = ef_Extended) and
2157 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then
2158 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
2159 event[chan].effect2)
2160 else If (event[chan].effect_def = ef_Extended) and
2161 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
2162 effect_table2[chan] := concw(ef_FSlideDownFine,event[chan].effect2)
2163 else effect_table2[chan] := concw(ef_FSlideDown,event[chan].effect2);
2165 For idx := chan to songdata.nm_tracks do
2167 fslide_table2[idx] := event[chan].effect2;
2168 glfsld_table2[idx] := effect_table2[chan];
2174 ef_FSlideDownVSlide,
2178 ef_FSlDownFineVSlide,
2180 If (event[chan].effect2 <> 0) then
2181 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
2182 else If (eLo2[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide,
2183 ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF,
2184 ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and
2185 (eHi2[chan] <> 0) then
2186 effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
2187 else effect_table2[chan] := effect_table2[chan] AND $0ff00;
2190 If (event[chan].note in [1..12*8+1]) then
2192 If (event[chan].effect2 <> 0) then
2193 effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2)
2194 else If (eLo2[chan] = ef_TonePortamento) and
2195 (eHi2[chan] <> 0) then
2196 effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan])
2197 else effect_table2[chan] := ef_TonePortamento;
2199 porta_table2[chan].speed := HI(effect_table2[chan]);
2200 porta_table2[chan].freq := nFreq(event[chan].note-1)+
2201 SHORTINT(ins_parameter(event_table[chan].instr_def,12));
2203 else If (eLo2[chan] = ef_TonePortamento) then
2205 If (event[chan].effect2 <> 0) then
2206 effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2)
2207 else If (eLo2[chan] = ef_TonePortamento) and
2208 (eHi2[chan] <> 0) then
2209 effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan])
2210 else effect_table2[chan] := ef_TonePortamento;
2211 porta_table2[chan].speed := HI(effect_table2[chan]);
2215 ef_TPortamVSlideFine:
2216 If (event[chan].effect2 <> 0) then
2217 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
2218 else If (eLo2[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and
2219 (eHi2[chan] <> 0) then
2220 effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
2221 else effect_table2[chan] := effect_table2[chan] AND $0ff00;
2224 ef_ExtraFineVibrato:
2226 If (event[chan].effect2 <> 0) then
2227 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
2228 else If (eLo2[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and
2229 (eHi2[chan] <> 0) then
2230 effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
2231 else effect_table2[chan] := event[chan].effect_def2;
2233 If (event[chan].effect_def = ef_Extended) and
2234 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
2235 vibr_table2[chan].fine := TRUE;
2237 vibr_table2[chan].speed := HI(effect_table2[chan]) DIV 16;
2238 vibr_table2[chan].depth := HI(effect_table2[chan]) MOD 16;
2242 ef_ExtraFineTremolo:
2244 If (event[chan].effect2 <> 0) then
2245 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
2246 else If (eLo2[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and
2247 (eHi2[chan] <> 0) then
2248 effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
2249 else effect_table2[chan] := event[chan].effect_def2;
2251 If (event[chan].effect_def = ef_Extended) and
2252 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FTrm_XFGFS) then
2253 trem_table2[chan].fine := TRUE;
2255 trem_table2[chan].speed := HI(effect_table2[chan]) DIV 16;
2256 trem_table2[chan].depth := HI(effect_table2[chan]) MOD 16;
2260 ef_VibratoVSlideFine:
2262 If (event[chan].effect2 <> 0) then
2263 effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
2264 else If (eLo2[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and
2265 (HI(effect_table2[chan]) <> 0) then
2266 effect_table2[chan] := concw(event[chan].effect_def2,HI(effect_table2[chan]))
2267 else effect_table2[chan] := effect_table2[chan] AND $0ff00;
2269 If (event[chan].effect_def = ef_Extended) and
2270 (event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_FVib_FGFS) then
2271 vibr_table2[chan].fine := TRUE;
2275 set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan);
2278 set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan);
2281 If percussion_mode and (chan in [17..20]) then
2282 set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan)
2283 else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
2284 set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan)
2285 else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan);
2288 If percussion_mode and (chan in [17..20]) then
2289 set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan)
2290 else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
2291 set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect2),63-event[chan].effect2,chan)
2292 else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan);
2295 If no_loop(chan,current_line) then
2297 pattern_break := TRUE;
2298 next_line := pattern_break_flag+chan;
2302 If no_loop(chan,current_line) then
2304 pattern_break := TRUE;
2305 next_line := max(event[chan].effect2,PRED(songdata.patt_len));
2309 speed := event[chan].effect2;
2312 update_timer(event[chan].effect2);
2316 If (event[chan].effect2 DIV 16 in [0..7]) then
2318 fmpar_table[chan].adsrw_car.wform := event[chan].effect2 DIV 16;
2319 update_carrier_adsrw(chan);
2322 If (event[chan].effect2 MOD 16 in [0..7]) then
2324 fmpar_table[chan].adsrw_mod.wform := event[chan].effect2 MOD 16;
2325 update_modulator_adsrw(chan);
2330 effect_table2[chan] := concw(ef_VolSlide,event[chan].effect2);
2333 effect_table2[chan] := concw(ef_VolSlideFine,event[chan].effect2);
2336 If (event[chan].effect2 <> 0) then
2338 If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
2339 retrig_table2[chan] := 1;
2340 effect_table2[chan] := concw(ef_RetrigNote,event[chan].effect2);
2345 global_volume := event[chan].effect2;
2350 If (event[chan].effect2 DIV 16 <> 0) then
2352 If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
2353 retrig_table2[chan] := 1;
2354 effect_table2[chan] := concw(ef_MultiRetrigNote,event[chan].effect2);
2358 If (event[chan].effect2 DIV 16 <> 0) and
2359 (event[chan].effect2 MOD 16 <> 0) then
2361 If (eLo2[chan] <> ef_Tremor) then
2363 tremor_table2[chan].pos := 0;
2364 tremor_table2[chan].volume := volume_table[chan];
2366 effect_table2[chan] := concw(ef_Tremor,event[chan].effect2);
2370 Case (event[chan].effect2 DIV 16) of
2372 Case (event[chan].effect2 MOD 16) of
2374 opl3out(_instr[11],misc_register AND $07f);
2375 current_tremolo_depth := 0;
2379 opl3out(_instr[11],misc_register OR $080);
2380 current_tremolo_depth := 1;
2385 Case (event[chan].effect2 MOD 16) of
2387 opl3out(_instr[11],misc_register AND $0bf);
2388 current_vibrato_depth := 0;
2392 opl3out(_instr[11],misc_register OR $040);
2393 current_vibrato_depth := 1;
2397 ef_ex_SetAttckRateM:
2399 fmpar_table[chan].adsrw_mod.attck := event[chan].effect2 MOD 16;
2400 update_modulator_adsrw(chan);
2403 ef_ex_SetDecayRateM:
2405 fmpar_table[chan].adsrw_mod.dec := event[chan].effect2 MOD 16;
2406 update_modulator_adsrw(chan);
2409 ef_ex_SetSustnLevelM:
2411 fmpar_table[chan].adsrw_mod.sustn := event[chan].effect2 MOD 16;
2412 update_modulator_adsrw(chan);
2417 fmpar_table[chan].adsrw_mod.rel := event[chan].effect2 MOD 16;
2418 update_modulator_adsrw(chan);
2421 ef_ex_SetAttckRateC:
2423 fmpar_table[chan].adsrw_car.attck := event[chan].effect2 MOD 16;
2424 update_carrier_adsrw(chan);
2427 ef_ex_SetDecayRateC:
2429 fmpar_table[chan].adsrw_car.dec := event[chan].effect2 MOD 16;
2430 update_carrier_adsrw(chan);
2433 ef_ex_SetSustnLevelC:
2435 fmpar_table[chan].adsrw_car.sustn := event[chan].effect2 MOD 16;
2436 update_carrier_adsrw(chan);
2441 fmpar_table[chan].adsrw_car.rel := event[chan].effect2 MOD 16;
2442 update_carrier_adsrw(chan);
2447 fmpar_table[chan].feedb := event[chan].effect2 MOD 16;
2451 ef_ex_SetPanningPos:
2453 panning_table[chan] := event[chan].effect2 MOD 16;
2458 ef_ex_PatternLoopRec:
2459 If (event[chan].effect2 MOD 16 = 0) then
2460 loopbck_table[chan] := current_line
2461 else If (loopbck_table[chan] <> BYTE_NULL) then
2463 If (loop_table[chan][current_line] = BYTE_NULL) then
2464 loop_table[chan][current_line] := event[chan].effect2 MOD 16;
2465 If (loop_table[chan][current_line] <> 0) then
2467 pattern_break := TRUE;
2468 next_line := pattern_loop_flag+chan;
2470 else If (event[chan].effect2 DIV 16 = ef_ex_PatternLoopRec) then
2471 loop_table[chan][current_line] := BYTE_NULL;
2474 ef_ex_MacroKOffLoop:
2475 If (event[chan].effect2 MOD 16 <> 0) then
2476 keyoff_loop[chan] := TRUE
2477 else keyoff_loop[chan] := FALSE;
2480 Case (event[chan].effect2 MOD 16) of
2481 ef_ex_cmd_RSS: release_sustaining_sound(chan);
2482 ef_ex_cmd_ResetVol: reset_ins_volume(chan);
2483 ef_ex_cmd_LockVol: volume_lock [chan] := TRUE;
2484 ef_ex_cmd_UnlockVol: volume_lock [chan] := FALSE;
2485 ef_ex_cmd_LockVP: peak_lock [chan] := TRUE;
2486 ef_ex_cmd_UnlockVP: peak_lock [chan] := FALSE;
2487 ef_ex_cmd_VSlide_def: volslide_type[chan] := 0;
2488 ef_ex_cmd_LockPan: pan_lock [chan] := TRUE;
2489 ef_ex_cmd_UnlockPan: pan_lock [chan] := FALSE;
2490 ef_ex_cmd_VibrOff: change_frequency(chan,freq_table[chan]);
2491 ef_ex_cmd_TremOff: set_ins_volume(LO(volume_table[chan]),
2492 HI(volume_table[chan]),chan);
2493 ef_ex_cmd_VSlide_car:
2494 If NOT ((event[chan].effect_def = ef_Extended) and
2495 (event[chan].effect = ef_ex_ExtendedCmd*16+
2496 ef_ex_cmd_VSlide_mod)) then
2497 volslide_type[chan] := 1;
2499 ef_ex_cmd_VSlide_mod:
2500 If NOT ((event[chan].effect_def = ef_Extended) and
2501 (event[chan].effect = ef_ex_ExtendedCmd*16+
2502 ef_ex_cmd_VSlide_car)) then
2503 volslide_type[chan] := 2;
2508 Case (event[chan].effect2 DIV 16) of
2509 ef_ex2_PatDelayFrame,
2512 pattern_delay := TRUE;
2513 If (event[chan].effect2 DIV 16 = ef_ex2_PatDelayFrame) then
2514 tickD := (event[chan].effect2 MOD 16)
2515 else tickD := speed*(event[chan].effect2 MOD 16);
2520 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0);
2521 notedel_table[chan] := event[chan].effect2 MOD 16;
2526 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0);
2527 notecut_table[chan] := event[chan].effect2 MOD 16;
2531 Inc(ftune_table[chan],event[chan].effect2 MOD 16);
2533 ef_ex2_FineTuneDown:
2534 Dec(ftune_table[chan],event[chan].effect2 MOD 16);
2536 ef_ex2_GlVolSlideUp:
2537 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp,
2538 event[chan].effect2 MOD 16);
2539 ef_ex2_GlVolSlideDn:
2540 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn,
2541 event[chan].effect2 MOD 16);
2542 ef_ex2_GlVolSlideUpF:
2543 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF,
2544 event[chan].effect2 MOD 16);
2545 ef_ex2_GlVolSlideDnF:
2546 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF,
2547 event[chan].effect2 MOD 16);
2548 ef_ex2_GlVolSldUpXF:
2549 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF,
2550 event[chan].effect2 MOD 16);
2551 ef_ex2_GlVolSldDnXF:
2552 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF,
2553 event[chan].effect2 MOD 16);
2554 ef_ex2_VolSlideUpXF:
2555 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF,
2556 event[chan].effect2 MOD 16);
2557 ef_ex2_VolSlideDnXF:
2558 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF,
2559 event[chan].effect2 MOD 16);
2560 ef_ex2_FreqSlideUpXF:
2561 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
2562 event[chan].effect2 MOD 16);
2563 ef_ex2_FreqSlideDnXF:
2564 effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
2565 event[chan].effect2 MOD 16);
2569 Case (event[chan].effect2 DIV 16) of
2570 ef_ex3_SetConnection:
2572 fmpar_table[chan].connect := event[chan].effect2 MOD 16;
2578 fmpar_table[chan].multipM := event[chan].effect2 MOD 16;
2584 fmpar_table[chan].kslM := event[chan].effect2 MOD 16;
2590 fmpar_table[chan].tremM := event[chan].effect2 MOD 16;
2596 fmpar_table[chan].vibrM := event[chan].effect2 MOD 16;
2602 fmpar_table[chan].ksrM := event[chan].effect2 MOD 16;
2608 fmpar_table[chan].sustM := event[chan].effect2 MOD 16;
2614 fmpar_table[chan].multipC := event[chan].effect2 MOD 16;
2620 fmpar_table[chan].kslC := event[chan].effect2 MOD 16;
2626 fmpar_table[chan].tremC := event[chan].effect2 MOD 16;
2632 fmpar_table[chan].vibrC := event[chan].effect2 MOD 16;
2638 fmpar_table[chan].ksrC := event[chan].effect2 MOD 16;
2644 fmpar_table[chan].sustC := event[chan].effect2 MOD 16;
2650 For chan := 1 to songdata.nm_tracks do
2652 If (event[chan].effect_def+event[chan].effect = 0) then
2653 If (glfsld_table[chan] = 0) then effect_table[chan] := 0
2655 event_table[chan].effect_def := event[chan].effect_def;
2656 event_table[chan].effect := event[chan].effect;
2659 If (event[chan].effect_def2+event[chan].effect2 = 0) then
2660 If (glfsld_table2[chan] = 0) then effect_table2[chan] := 0
2662 event_table[chan].effect_def2 := event[chan].effect_def2;
2663 event_table[chan].effect2 := event[chan].effect2;
2666 If (event[chan].note = event[chan].note OR keyoff_flag) then key_off(chan)
2667 else If NOT (LO(effect_table[chan]) in [ef_TonePortamento,
2669 ef_TPortamVSlideFine,
2670 ef_extended2+ef_fix2+ef_ex2_NoteDelay]) and
2671 NOT (LO(effect_table2[chan]) in [ef_TonePortamento,
2673 ef_TPortamVSlideFine,
2674 ef_extended2+ef_fix2+ef_ex2_NoteDelay]) then
2675 If NOT (((event[chan].effect_def2 = ef_SwapArpeggio) or
2676 (event[chan].effect_def2 = ef_SwapVibrato)) and
2677 (event[chan].effect_def = ef_Extended) and
2678 (event[chan].effect DIV 16 = ef_ex_ExtendedCmd) and
2679 (event[chan].effect MOD 16 = ef_ex_cmd_NoRestart)) and
2680 NOT (((event[chan].effect_def = ef_SwapArpeggio) or
2681 (event[chan].effect_def = ef_SwapVibrato)) and
2682 (event[chan].effect_def2 = ef_Extended) and
2683 (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd) and
2684 (event[chan].effect2 MOD 16 = ef_ex_cmd_NoRestart)) then
2685 output_note(event[chan].note,voice_table[chan],chan,TRUE)
2686 else output_note_NR(event[chan].note,voice_table[chan],chan,TRUE)
2687 else If (event[chan].note <> 0) and
2688 (event_table[chan].note = event_table[chan].note OR keyoff_flag) and
2689 ((event[chan].effect_def in [ef_TonePortamento,
2691 ef_TPortamVSlideFine]) or
2692 (event[chan].effect_def2 in [ef_TonePortamento,
2694 ef_TPortamVSlideFine])) then
2695 output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE)
2696 else If (event[chan].note <> 0) then
2697 event_table[chan].note := event[chan].note;
2699 Case event[chan].effect_def of
2702 If (event[chan].effect_def2 = ef_Extended) and
2703 (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd) and
2704 (event[chan].effect2 MOD 16 = ef_ex_cmd_NoRestart) then
2706 If (macro_table[chan].arpg_pos >
2707 songdata.macro_table[event[chan].effect].arpeggio.length) then
2708 macro_table[chan].arpg_pos :=
2709 songdata.macro_table[event[chan].effect].arpeggio.length;
2710 macro_table[chan].arpg_table := event[chan].effect;
2713 macro_table[chan].arpg_count := 1;
2714 macro_table[chan].arpg_pos := 0;
2715 macro_table[chan].arpg_table := event[chan].effect;
2716 macro_table[chan].arpg_note := event_table[chan].note;
2722 If (event[chan].effect_def2 = ef_Extended) and
2723 (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd) and
2724 (event[chan].effect2 MOD 16 = ef_ex_cmd_NoRestart) then
2726 If (macro_table[chan].vib_table >
2727 songdata.macro_table[event[chan].effect].vibrato.length) then
2728 macro_table[chan].vib_pos :=
2729 songdata.macro_table[event[chan].effect].vibrato.length;
2730 macro_table[chan].vib_table := event[chan].effect;
2733 macro_table[chan].vib_count := 1;
2734 macro_table[chan].vib_pos := 0;
2735 macro_table[chan].vib_table := event[chan].effect;
2736 macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
2740 ef_SetCustomSpeedTab:
2741 generate_custom_vibrato(event[chan].effect);
2744 Case event[chan].effect_def2 of
2747 If (event[chan].effect_def = ef_Extended) and
2748 (event[chan].effect DIV 16 = ef_ex_ExtendedCmd) and
2749 (event[chan].effect MOD 16 = ef_ex_cmd_NoRestart) then
2751 If (macro_table[chan].arpg_pos >
2752 songdata.macro_table[event[chan].effect2].arpeggio.length) then
2753 macro_table[chan].arpg_pos :=
2754 songdata.macro_table[event[chan].effect2].arpeggio.length;
2755 macro_table[chan].arpg_table := event[chan].effect2;
2758 macro_table[chan].arpg_count := 1;
2759 macro_table[chan].arpg_pos := 0;
2760 macro_table[chan].arpg_table := event[chan].effect2;
2761 macro_table[chan].arpg_note := event_table[chan].note;
2767 If (event[chan].effect_def = ef_Extended) and
2768 (event[chan].effect DIV 16 = ef_ex_ExtendedCmd) and
2769 (event[chan].effect MOD 16 = ef_ex_cmd_NoRestart) then
2771 If (macro_table[chan].vib_table >
2772 songdata.macro_table[event[chan].effect2].vibrato.length) then
2773 macro_table[chan].vib_pos :=
2774 songdata.macro_table[event[chan].effect2].vibrato.length;
2775 macro_table[chan].vib_table := event[chan].effect2;
2778 macro_table[chan].vib_count := 1;
2779 macro_table[chan].vib_pos := 0;
2780 macro_table[chan].vib_table := event[chan].effect2;
2781 macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
2785 ef_SetCustomSpeedTab:
2786 generate_custom_vibrato(event[chan].effect2);
2789 update_fine_effects(chan);
2792 If pattern_delay then
2794 time_playing := time_playing+1/tempo*tickD;
2795 If (time_playing > 3600-1) then time_playing := 0;
2798 time_playing := time_playing+1/tempo*speed;
2799 If (time_playing > 3600-1) then time_playing := 0;
2803 procedure portamento_up(chan: Byte; slide: Word; limit: Word);
2809 freq := calc_freq_shift_up(freq_table[chan] AND $1fff,slide);
2810 If (freq <= limit) then change_frequency(chan,freq)
2811 else change_frequency(chan,limit);
2814 procedure portamento_down(chan: Byte; slide: Word; limit: Word);
2820 freq := calc_freq_shift_down(freq_table[chan] AND $1fff,slide);
2821 If (freq >= limit) then change_frequency(chan,freq)
2822 else change_frequency(chan,limit);
2825 procedure macro_vibrato__porta_up(chan: Byte; depth: Byte);
2831 freq := calc_freq_shift_up(macro_table[chan].vib_freq AND $1fff,depth);
2832 If (freq <= nFreq(12*8+1)) then change_freq(chan,freq)
2833 else change_freq(chan,nFreq(12*8+1));
2836 procedure macro_vibrato__porta_down(chan: Byte; depth: Byte);
2842 freq := calc_freq_shift_down(macro_table[chan].vib_freq AND $1fff,depth);
2843 If (freq >= nFreq(0)) then change_freq(chan,freq)
2844 else change_freq(chan,nFreq(0));
2847 procedure tone_portamento(chan: Byte);
2849 If (freq_table[chan] AND $1fff > porta_table[chan].freq) then
2850 portamento_down(chan,porta_table[chan].speed,porta_table[chan].freq)
2851 else If (freq_table[chan] AND $1fff < porta_table[chan].freq) then
2852 portamento_up(chan,porta_table[chan].speed,porta_table[chan].freq);
2855 procedure tone_portamento2(chan: Byte);
2857 If (freq_table[chan] AND $1fff > porta_table2[chan].freq) then
2858 portamento_down(chan,porta_table2[chan].speed,porta_table2[chan].freq)
2859 else If (freq_table[chan] AND $1fff < porta_table2[chan].freq) then
2860 portamento_up(chan,porta_table2[chan].speed,porta_table2[chan].freq);
2863 procedure slide_volume_up(chan,slide: Byte);
2867 limit1,limit2,vLo,vHi: Byte;
2869 procedure slide_carrier_volume_up;
2873 If (vHi-slide >= limit1) then temp := concw(vLo,vHi-slide)
2874 else temp := concw(vLo,limit1);
2875 set_ins_volume(BYTE_NULL,HI(temp),chan);
2876 volume_table[chan] := temp;
2879 procedure slide_modulator_volume_up;
2883 If (vLo-slide >= limit2) then temp := concw(vLo-slide,vHi)
2884 else temp := concw(limit2,vHi);
2885 set_ins_volume(LO(temp),BYTE_NULL,chan);
2886 volume_table[chan] := temp;
2890 If NOT peak_lock[chan] then limit1 := 0
2891 else limit1 := ins_parameter(event_table[chan].instr_def,3) AND $3f;
2893 If NOT peak_lock[chan] then limit2 := 0
2894 else limit2 := ins_parameter(event_table[chan].instr_def,2) AND $3f;
2895 temp := volume_table[chan];
2897 Case volslide_type[chan] of
2899 slide_carrier_volume_up;
2900 If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
2901 (percussion_mode and (chan in [17..20])) then
2902 slide_modulator_volume_up;
2904 1: slide_carrier_volume_up;
2905 2: slide_modulator_volume_up;
2907 slide_carrier_volume_up;
2908 slide_modulator_volume_up;
2913 procedure slide_volume_down(chan,slide: Byte);
2919 procedure slide_carrier_volume_down;
2923 If (vHi+slide <= 63) then temp := concw(vLo,vHi+slide)
2924 else temp := concw(vLo,63);
2925 set_ins_volume(BYTE_NULL,HI(temp),chan);
2926 volume_table[chan] := temp;
2929 procedure slide_modulator_volume_down;
2933 If (vLo+slide <= 63) then temp := concw(vLo+slide,vHi)
2934 else temp := concw(63,vHi);
2935 set_ins_volume(LO(temp),BYTE_NULL,chan);
2936 volume_table[chan] := temp;
2940 temp := volume_table[chan];
2941 Case volslide_type[chan] of
2943 slide_carrier_volume_down;
2944 If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
2945 (percussion_mode and (chan in [17..20])) then
2946 slide_modulator_volume_down;
2948 1: slide_carrier_volume_down;
2949 2: slide_modulator_volume_down;
2951 slide_carrier_volume_down;
2952 slide_modulator_volume_down;
2957 procedure volume_slide(chan,up_speed,down_speed: Byte);
2959 If (up_speed <> 0) then slide_volume_up(chan,up_speed)
2960 else If (down_speed <> 0) then slide_volume_down(chan,down_speed);
2963 procedure global_volume_slide(up_speed,down_speed: Byte);
2965 If (up_speed <> BYTE_NULL) then
2966 global_volume := max(global_volume+up_speed,63);
2967 If (down_speed <> BYTE_NULL) then
2968 If (global_volume >= down_speed) then Dec(global_volume,down_speed)
2969 else global_volume := 0;
2973 procedure arpeggio(chan: Byte);
2976 arpgg_state: array[0..2] of Byte = (1,2,0);
2982 Case arpgg_table[chan].state of
2983 0: freq := nFreq(arpgg_table[chan].note-1);
2984 1: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add1);
2985 2: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add2);
2988 arpgg_table[chan].state := arpgg_state[arpgg_table[chan].state];
2989 change_frequency(chan,freq+
2990 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
2993 procedure arpeggio2(chan: Byte);
2996 arpgg_state: array[0..2] of Byte = (1,2,0);
3002 Case arpgg_table2[chan].state of
3003 0: freq := nFreq(arpgg_table2[chan].note-1);
3004 1: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add1);
3005 2: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add2);
3008 arpgg_table2[chan].state := arpgg_state[arpgg_table2[chan].state];
3009 change_frequency(chan,freq+
3010 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
3013 procedure vibrato(chan: Byte);
3016 freq,old_freq: Word;
3020 Inc(vibr_table[chan].pos,vibr_table[chan].speed*vibtrem_speed_factor);
3021 freq := calc_vibtrem_shift(vibr_table[chan].depth,
3022 vibr_table[chan].pos,direction);
3023 old_freq := freq_table[chan];
3024 If (direction = 0) then portamento_down(chan,freq,nFreq(0))
3025 else portamento_up(chan,freq,nFreq(12*8+1));
3026 freq_table[chan] := old_freq;
3029 procedure vibrato2(chan: Byte);
3032 freq,old_freq: Word;
3036 Inc(vibr_table2[chan].pos,vibr_table2[chan].speed*vibtrem_speed_factor);
3037 freq := calc_vibtrem_shift(vibr_table2[chan].depth,
3038 vibr_table2[chan].pos,direction);
3039 old_freq := freq_table[chan];
3040 If (direction = 0) then portamento_down(chan,freq,nFreq(0))
3041 else portamento_up(chan,freq,nFreq(12*8+1));
3042 freq_table[chan] := old_freq;
3045 procedure tremolo(chan: Byte);
3052 Inc(trem_table[chan].pos,trem_table[chan].speed*vibtrem_speed_factor);
3053 vol := calc_vibtrem_shift(trem_table[chan].depth,
3054 trem_table[chan].pos,direction);
3055 old_vol := volume_table[chan];
3056 If (direction = 0) then slide_volume_down(chan,vol)
3057 else slide_volume_up(chan,vol);
3058 volume_table[chan] := old_vol;
3061 procedure tremolo2(chan: Byte);
3068 Inc(trem_table2[chan].pos,trem_table2[chan].speed*vibtrem_speed_factor);
3069 vol := calc_vibtrem_shift(trem_table2[chan].depth,
3070 trem_table2[chan].pos,direction);
3071 old_vol := volume_table[chan];
3072 If (direction = 0) then slide_volume_down(chan,vol)
3073 else slide_volume_up(chan,vol);
3074 volume_table[chan] := old_vol;
3077 procedure update_effects;
3083 function chanvol(chan: Byte): Byte;
3085 If (ins_parameter(voice_table[chan],10) AND 1 = 0) then chanvol := 63-HI(volume_table[chan])
3086 else chanvol := 63-Round((LO(volume_table[chan])+HI(volume_table[chan]))/2);
3090 For chan := 1 to songdata.nm_tracks do
3092 eLo := LO(effect_table[chan]);
3093 eHi := HI(effect_table[chan]);
3094 eLo2 := LO(effect_table2[chan]);
3095 eHi2 := HI(effect_table2[chan]);
3098 ef_Arpeggio+ef_fix1:
3103 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3111 portamento_up(chan,eHi,nFreq(12*8+1));
3114 portamento_down(chan,eHi,nFreq(0));
3118 portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
3119 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3123 portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
3125 ef_FSlideDownVSlide:
3127 portamento_down(chan,fslide_table[chan],nFreq(0));
3128 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3132 portamento_down(chan,fslide_table[chan],nFreq(0));
3135 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3137 ef_FSlDownFineVSlide:
3138 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3141 tone_portamento(chan);
3145 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3146 tone_portamento(chan);
3149 ef_TPortamVSlideFine:
3150 tone_portamento(chan);
3153 If NOT vibr_table[chan].fine then
3157 If NOT trem_table[chan].fine then
3162 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3163 If NOT vibr_table[chan].fine then
3167 ef_VibratoVSlideFine:
3168 If NOT vibr_table[chan].fine then
3172 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3175 If (retrig_table[chan] >= eHi) then
3177 retrig_table[chan] := 0;
3178 output_note(event_table[chan].note,
3179 event_table[chan].instr_def,chan,TRUE);
3181 else Inc(retrig_table[chan]);
3184 If (retrig_table[chan] >= eHi DIV 16) then
3189 1: slide_volume_down(chan,1);
3190 2: slide_volume_down(chan,2);
3191 3: slide_volume_down(chan,4);
3192 4: slide_volume_down(chan,8);
3193 5: slide_volume_down(chan,16);
3195 9: slide_volume_up(chan,1);
3196 10: slide_volume_up(chan,2);
3197 11: slide_volume_up(chan,4);
3198 12: slide_volume_up(chan,8);
3199 13: slide_volume_up(chan,16);
3202 6: slide_volume_down(chan,chanvol(chan)-
3203 Round(chanvol(chan)*2/3));
3204 7: slide_volume_down(chan,chanvol(chan)-
3205 Round(chanvol(chan)*1/2));
3207 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)-
3209 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)-
3213 retrig_table[chan] := 0;
3214 output_note(event_table[chan].note,
3215 event_table[chan].instr_def,chan,TRUE);
3217 else Inc(retrig_table[chan]);
3220 If (tremor_table[chan].pos >= 0) then
3222 If (SUCC(tremor_table[chan].pos) <= eHi DIV 16) then
3223 Inc(tremor_table[chan].pos)
3225 slide_volume_down(chan,63);
3226 tremor_table[chan].pos := -1;
3229 else If (PRED(tremor_table[chan].pos) >= -(eHi MOD 16)) then
3230 Dec(tremor_table[chan].pos)
3232 set_ins_volume(LO(tremor_table[chan].volume),
3233 HI(tremor_table[chan].volume),chan);
3234 tremor_table[chan].pos := 1;
3237 ef_extended2+ef_fix2+ef_ex2_NoteDelay:
3238 If (notedel_table[chan] = 0) then
3240 notedel_table[chan] := BYTE_NULL;
3241 output_note(event_table[chan].note,
3242 event_table[chan].instr_def,chan,TRUE);
3244 else Dec(notedel_table[chan]);
3246 ef_extended2+ef_fix2+ef_ex2_NoteCut:
3247 If (notecut_table[chan] = 0) then
3249 notecut_table[chan] := BYTE_NULL;
3252 else Dec(notecut_table[chan]);
3254 ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp:
3255 global_volume_slide(eHi,BYTE_NULL);
3257 ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn:
3258 global_volume_slide(BYTE_NULL,eHi);
3262 ef_Arpeggio+ef_fix1:
3267 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3275 portamento_up(chan,eHi2,nFreq(12*8+1));
3278 portamento_down(chan,eHi2,nFreq(0));
3282 portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
3283 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3287 portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
3289 ef_FSlideDownVSlide:
3291 portamento_down(chan,fslide_table2[chan],nFreq(0));
3292 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3296 portamento_down(chan,fslide_table2[chan],nFreq(0));
3299 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3301 ef_FSlDownFineVSlide:
3302 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3305 tone_portamento2(chan);
3309 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3310 tone_portamento2(chan);
3313 ef_TPortamVSlideFine:
3314 tone_portamento2(chan);
3317 If NOT vibr_table2[chan].fine then
3321 If NOT trem_table2[chan].fine then
3326 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3327 If NOT vibr_table2[chan].fine then
3331 ef_VibratoVSlideFine:
3332 If NOT vibr_table2[chan].fine then
3336 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3339 If (retrig_table2[chan] >= eHi2) then
3341 retrig_table2[chan] := 0;
3342 output_note(event_table[chan].note,
3343 event_table[chan].instr_def,chan,TRUE);
3345 else Inc(retrig_table2[chan]);
3348 If (retrig_table2[chan] >= eHi2 DIV 16) then
3353 1: slide_volume_down(chan,1);
3354 2: slide_volume_down(chan,2);
3355 3: slide_volume_down(chan,4);
3356 4: slide_volume_down(chan,8);
3357 5: slide_volume_down(chan,16);
3359 9: slide_volume_up(chan,1);
3360 10: slide_volume_up(chan,2);
3361 11: slide_volume_up(chan,4);
3362 12: slide_volume_up(chan,8);
3363 13: slide_volume_up(chan,16);
3366 6: slide_volume_down(chan,chanvol(chan)-
3367 Round(chanvol(chan)*2/3));
3368 7: slide_volume_down(chan,chanvol(chan)-
3369 Round(chanvol(chan)*1/2));
3371 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)-
3373 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)-
3377 retrig_table2[chan] := 0;
3378 output_note(event_table[chan].note,
3379 event_table[chan].instr_def,chan,TRUE);
3381 else Inc(retrig_table2[chan]);
3384 If (tremor_table2[chan].pos >= 0) then
3386 If (SUCC(tremor_table2[chan].pos) <= eHi2 DIV 16) then
3387 Inc(tremor_table2[chan].pos)
3389 slide_volume_down(chan,63);
3390 tremor_table2[chan].pos := -1;
3393 else If (PRED(tremor_table2[chan].pos) >= -(eHi2 MOD 16)) then
3394 Dec(tremor_table2[chan].pos)
3396 set_ins_volume(LO(tremor_table2[chan].volume),
3397 HI(tremor_table2[chan].volume),chan);
3398 tremor_table2[chan].pos := 1;
3401 ef_extended2+ef_fix2+ef_ex2_NoteDelay:
3402 If (notedel_table[chan] = 0) then
3404 notedel_table[chan] := BYTE_NULL;
3405 output_note(event_table[chan].note,
3406 event_table[chan].instr_def,chan,TRUE);
3408 else Dec(notedel_table[chan]);
3410 ef_extended2+ef_fix2+ef_ex2_NoteCut:
3411 If (notecut_table[chan] = 0) then
3413 notecut_table[chan] := BYTE_NULL;
3416 else Dec(notecut_table[chan]);
3418 ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp:
3419 global_volume_slide(eHi2,BYTE_NULL);
3421 ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn:
3422 global_volume_slide(BYTE_NULL,eHi2);
3427 procedure update_fine_effects(chan: Byte);
3434 eLo := LO(effect_table[chan]);
3435 eHi := HI(effect_table[chan]);
3436 eLo2 := LO(effect_table2[chan]);
3437 eHi2 := HI(effect_table2[chan]);
3441 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3444 portamento_up(chan,eHi,nFreq(12*8+1));
3447 portamento_down(chan,eHi,nFreq(0));
3450 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3453 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3456 portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
3460 portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
3461 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3464 ef_FSlDownFineVSlide:
3465 portamento_down(chan,fslide_table[chan],nFreq(0));
3469 portamento_down(chan,fslide_table[chan],nFreq(0));
3470 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3473 ef_TPortamVSlideFine:
3474 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3477 If vibr_table[chan].fine then
3481 If trem_table[chan].fine then
3485 If vibr_table[chan].fine then
3488 ef_VibratoVSlideFine:
3490 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3491 If vibr_table[chan].fine then
3496 volume_slide(chan,eHi DIV 16,eHi MOD 16);
3498 ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF:
3499 global_volume_slide(eHi,BYTE_NULL);
3501 ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF:
3502 global_volume_slide(BYTE_NULL,eHi);
3507 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3510 portamento_up(chan,eHi2,nFreq(12*8+1));
3513 portamento_down(chan,eHi2,nFreq(0));
3516 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3519 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3522 portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
3526 portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
3527 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3530 ef_FSlDownFineVSlide:
3531 portamento_down(chan,fslide_table2[chan],nFreq(0));
3535 portamento_down(chan,fslide_table2[chan],nFreq(0));
3536 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3539 ef_TPortamVSlideFine:
3540 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3543 If vibr_table2[chan].fine then
3547 If trem_table2[chan].fine then
3551 If vibr_table2[chan].fine then
3554 ef_VibratoVSlideFine:
3556 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3557 If vibr_table2[chan].fine then
3562 volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
3564 ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF:
3565 global_volume_slide(eHi2,BYTE_NULL);
3567 ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF:
3568 global_volume_slide(BYTE_NULL,eHi2);
3572 procedure update_extra_fine_effects;
3579 For chan := 1 to songdata.nm_tracks do
3581 eLo := LO(effect_table[chan]);
3582 eHi := HI(effect_table[chan]);
3583 eLo2 := LO(effect_table2[chan]);
3584 eHi2 := HI(effect_table2[chan]);
3587 ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF:
3588 global_volume_slide(eHi,BYTE_NULL);
3590 ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF:
3591 global_volume_slide(BYTE_NULL,eHi);
3593 ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF:
3594 volume_slide(chan,eHi,0);
3596 ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF:
3597 volume_slide(chan,0,eHi);
3599 ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF:
3600 portamento_up(chan,eHi,nFreq(12*8+1));
3602 ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF:
3603 portamento_down(chan,eHi,nFreq(0));
3605 ef_ExtraFineArpeggio:
3608 ef_ExtraFineVibrato:
3609 If NOT vibr_table[chan].fine then
3612 ef_ExtraFineTremolo:
3613 If NOT trem_table[chan].fine then
3618 ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF:
3619 global_volume_slide(eHi2,BYTE_NULL);
3621 ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF:
3622 global_volume_slide(BYTE_NULL,eHi2);
3624 ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF:
3625 volume_slide(chan,eHi2,0);
3627 ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF:
3628 volume_slide(chan,0,eHi2);
3630 ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF:
3631 portamento_up(chan,eHi2,nFreq(12*8+1));
3633 ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF:
3634 portamento_down(chan,eHi2,nFreq(0));
3636 ef_ExtraFineArpeggio:
3639 ef_ExtraFineVibrato:
3640 If NOT vibr_table2[chan].fine then
3643 ef_ExtraFineTremolo:
3644 If NOT trem_table2[chan].fine then
3650 function calc_following_order(order: Byte): Integer;
3654 index,jump_count: Byte;
3657 _debug_str_ := 'A2PLAYER.PAS:calc_following_order';
3663 If (songdata.pattern_order[index] < $80) then result := index
3665 index := songdata.pattern_order[index]-$80;
3668 until (jump_count > $7f) or
3671 calc_following_order := result;
3674 function calc_order_jump: Integer;
3681 _debug_str_ := 'A2PLAYER.PAS:calc_order_jump';
3686 If (songdata.pattern_order[current_order] > $7f) then
3687 current_order := songdata.pattern_order[current_order]-$80;
3689 until (temp > $7f) or (songdata.pattern_order[current_order] < $80);
3691 If (temp > $7f) then begin stop_playing; result := -1; end;
3692 calc_order_jump := result;
3695 procedure update_song_position;
3701 _debug_str_ := 'A2PLAYER.PAS:update_song_position';
3702 If (current_line < PRED(songdata.patt_len)) and NOT pattern_break then Inc(current_line)
3704 If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
3705 (current_order < $7f) then
3707 FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
3708 FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
3712 If pattern_break and (next_line AND $0f0 = pattern_loop_flag) then
3714 temp := next_line-pattern_loop_flag;
3715 next_line := loopbck_table[temp];
3716 If (loop_table[temp][current_line] <> 0) then
3717 Dec(loop_table[temp][current_line]);
3719 else If pattern_break and (next_line AND $0f0 = pattern_break_flag) then
3721 current_order := event_table[next_line-pattern_break_flag].effect;
3722 pattern_break := FALSE;
3724 else If (current_order > $7f) then
3727 If (songdata.pattern_order[current_order] > $7f) then
3728 If (calc_order_jump = -1) then EXIT;
3730 current_pattern := songdata.pattern_order[current_order];
3731 If NOT pattern_break then current_line := 0
3733 pattern_break := FALSE;
3734 current_line := next_line;
3738 For temp := 1 to songdata.nm_tracks do
3740 glfsld_table[temp] := 0;
3741 glfsld_table2[temp] := 0;
3744 If (current_line = 0) and
3745 (current_order = calc_following_order(0)) and speed_update then
3747 tempo := songdata.tempo;
3748 speed := songdata.speed;
3749 update_timer(tempo);
3753 procedure poll_proc;
3759 _debug_str_bak_: String;
3762 _debug_str_bak_ := _debug_str_;
3763 _debug_str_ := 'A2PLAYER.PAS:_poll_proc';
3765 If (NOT pattern_delay and (ticks-tick0+1 >= speed)) or
3768 If (songdata.pattern_order[current_order] > $7f) then
3769 If (calc_order_jump = -1) then EXIT;
3771 current_pattern := songdata.pattern_order[current_order];
3773 If NOT fast_forward then update_effects
3774 else For temp := 1 to speed do
3777 If (temp MOD 4 = temp) then
3778 update_extra_fine_effects;
3782 If fast_forward or NOT pattern_delay then
3783 update_song_position;
3786 If fast_forward then
3787 If NOT pattern_delay then synchronize_song_timer;
3789 If fast_forward and pattern_delay then
3792 pattern_delay := FALSE;
3795 If fast_forward then fast_forward := FALSE;
3801 If pattern_delay and (tickD > 1) then Dec(tickD)
3803 If pattern_delay then
3806 update_song_position;
3808 pattern_delay := FALSE;
3813 If (tickXF MOD 4 = 0) then
3815 update_extra_fine_effects;
3818 _debug_str_ := _debug_str_bak_;
3821 procedure macro_poll_proc;
3829 finished_flag: Word;
3832 _debug_str_bak_: String;
3834 function _ins_adsr_data_empty(ins: Byte): Boolean;
3836 _ins_adsr_data_empty :=
3837 (ins_parameter(ins,5) SHR 4 = 0) and
3838 (ins_parameter(ins,4) SHR 4 = 0) and
3839 (ins_parameter(ins,5) AND $0f = 0) and
3840 (ins_parameter(ins,4) AND $0f = 0) and
3841 (ins_parameter(ins,7) SHR 4 = 0) and
3842 (ins_parameter(ins,6) SHR 4 = 0) and
3843 (ins_parameter(ins,7) AND $0f = 0) and
3844 (ins_parameter(ins,6) AND $0f = 0);
3848 _debug_str_bak_ := _debug_str_;
3849 _debug_str_ := 'ADT2UNIT.PAS:macro_poll_proc';
3850 For chan := 1 to songdata.nm_tracks do
3852 If NOT keyoff_loop[chan] then finished_flag := FINISHED
3853 else finished_flag := IDLE;
3855 With macro_table[chan] do
3857 With songdata.instr_macros[fmreg_table] do
3858 If (fmreg_table <> 0) and (speed <> 0) then
3859 If (fmreg_duration > 1) then Dec(fmreg_duration)
3862 If (fmreg_pos <= length) then
3863 If (loop_begin <> 0) and (loop_length <> 0) then
3864 If (fmreg_pos = loop_begin+PRED(loop_length)) then
3865 fmreg_pos := loop_begin
3866 else If (fmreg_pos < length) then Inc(fmreg_pos)
3867 else fmreg_pos := finished_flag
3868 else If (fmreg_pos < length) then Inc(fmreg_pos)
3869 else fmreg_pos := finished_flag
3870 else fmreg_pos := finished_flag;
3872 If (freq_table[chan] OR $2000 = freq_table[chan]) and
3873 (keyoff_pos <> 0) and
3874 (fmreg_pos >= keyoff_pos) then
3876 else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
3877 (fmreg_pos <> 0) and (keyoff_pos <> 0) and
3878 ((fmreg_pos < keyoff_pos) or (fmreg_pos = IDLE)) then
3879 fmreg_pos := keyoff_pos;
3881 If (fmreg_pos <> 0) and
3882 (fmreg_pos <> IDLE) and (fmreg_pos <> finished_flag) then
3884 fmreg_duration := data[fmreg_pos].duration;
3885 If (fmreg_duration <> 0) then
3886 With data[fmreg_pos] do
3888 // force KEY-ON with missing ADSR instrument data
3889 force_macro_keyon := FALSE;
3890 If (fmreg_pos = 1) then
3891 If _ins_adsr_data_empty(voice_table[chan]) and
3892 NOT (songdata.dis_fmreg_col[fmreg_table][0] and
3893 songdata.dis_fmreg_col[fmreg_table][1] and
3894 songdata.dis_fmreg_col[fmreg_table][2] and
3895 songdata.dis_fmreg_col[fmreg_table][3] and
3896 songdata.dis_fmreg_col[fmreg_table][12] and
3897 songdata.dis_fmreg_col[fmreg_table][13] and
3898 songdata.dis_fmreg_col[fmreg_table][14] and
3899 songdata.dis_fmreg_col[fmreg_table][15]) then
3900 force_macro_keyon := TRUE;
3902 If NOT songdata.dis_fmreg_col[fmreg_table][0] then
3903 fmpar_table[chan].adsrw_mod.attck := fm_data.ATTCK_DEC_modulator SHR 4;
3905 If NOT songdata.dis_fmreg_col[fmreg_table][1] then
3906 fmpar_table[chan].adsrw_mod.dec := fm_data.ATTCK_DEC_modulator AND $0f;
3908 If NOT songdata.dis_fmreg_col[fmreg_table][2] then
3909 fmpar_table[chan].adsrw_mod.sustn := fm_data.SUSTN_REL_modulator SHR 4;
3911 If NOT songdata.dis_fmreg_col[fmreg_table][3] then
3912 fmpar_table[chan].adsrw_mod.rel := fm_data.SUSTN_REL_modulator AND $0f;
3914 If NOT songdata.dis_fmreg_col[fmreg_table][4] then
3915 fmpar_table[chan].adsrw_mod.wform := fm_data.WAVEFORM_modulator AND $07;
3917 If NOT songdata.dis_fmreg_col[fmreg_table][6] then
3918 fmpar_table[chan].kslM := fm_data.KSL_VOLUM_modulator SHR 6;
3920 If NOT songdata.dis_fmreg_col[fmreg_table][7] then
3921 fmpar_table[chan].multipM := fm_data.AM_VIB_EG_modulator AND $0f;
3923 If NOT songdata.dis_fmreg_col[fmreg_table][8] then
3924 fmpar_table[chan].tremM := fm_data.AM_VIB_EG_modulator SHR 7;
3926 If NOT songdata.dis_fmreg_col[fmreg_table][9] then
3927 fmpar_table[chan].vibrM := fm_data.AM_VIB_EG_modulator SHR 6 AND 1;
3929 If NOT songdata.dis_fmreg_col[fmreg_table][10] then
3930 fmpar_table[chan].ksrM := fm_data.AM_VIB_EG_modulator SHR 4 AND 1;
3932 If NOT songdata.dis_fmreg_col[fmreg_table][11] then
3933 fmpar_table[chan].sustM := fm_data.AM_VIB_EG_modulator SHR 5 AND 1;
3935 If NOT songdata.dis_fmreg_col[fmreg_table][12] then
3936 fmpar_table[chan].adsrw_car.attck := fm_data.ATTCK_DEC_carrier SHR 4;
3938 If NOT songdata.dis_fmreg_col[fmreg_table][13] then
3939 fmpar_table[chan].adsrw_car.dec := fm_data.ATTCK_DEC_carrier AND $0f;
3941 If NOT songdata.dis_fmreg_col[fmreg_table][14] then
3942 fmpar_table[chan].adsrw_car.sustn := fm_data.SUSTN_REL_carrier SHR 4;
3944 If NOT songdata.dis_fmreg_col[fmreg_table][15] then
3945 fmpar_table[chan].adsrw_car.rel := fm_data.SUSTN_REL_carrier AND $0f;
3947 If NOT songdata.dis_fmreg_col[fmreg_table][16] then
3948 fmpar_table[chan].adsrw_car.wform := fm_data.WAVEFORM_carrier AND $07;
3950 If NOT songdata.dis_fmreg_col[fmreg_table][18] then
3951 fmpar_table[chan].kslC := fm_data.KSL_VOLUM_carrier SHR 6;
3953 If NOT songdata.dis_fmreg_col[fmreg_table][19] then
3954 fmpar_table[chan].multipC := fm_data.AM_VIB_EG_carrier AND $0f;
3956 If NOT songdata.dis_fmreg_col[fmreg_table][20] then
3957 fmpar_table[chan].tremC := fm_data.AM_VIB_EG_carrier SHR 7;
3959 If NOT songdata.dis_fmreg_col[fmreg_table][21] then
3960 fmpar_table[chan].vibrC := fm_data.AM_VIB_EG_carrier SHR 6 AND 1;
3962 If NOT songdata.dis_fmreg_col[fmreg_table][22] then
3963 fmpar_table[chan].ksrC := fm_data.AM_VIB_EG_carrier SHR 4 AND 1;
3965 If NOT songdata.dis_fmreg_col[fmreg_table][23] then
3966 fmpar_table[chan].sustC := fm_data.AM_VIB_EG_carrier SHR 5 AND 1;
3968 If NOT songdata.dis_fmreg_col[fmreg_table][24] then
3969 fmpar_table[chan].connect := fm_data.FEEDBACK_FM AND 1;
3971 If NOT songdata.dis_fmreg_col[fmreg_table][25] then
3972 fmpar_table[chan].feedb := fm_data.FEEDBACK_FM SHR 1 AND 7;
3974 If NOT songdata.dis_fmreg_col[fmreg_table][27] then
3975 If NOT pan_lock[chan] then
3976 panning_table[chan] := panning;
3978 If NOT songdata.dis_fmreg_col[fmreg_table][5] then
3979 set_ins_volume(63-fm_data.KSL_VOLUM_modulator AND $3f,
3982 If NOT songdata.dis_fmreg_col[fmreg_table][17] then
3983 set_ins_volume(BYTE_NULL,
3984 63-fm_data.KSL_VOLUM_carrier AND $3f,chan);
3986 update_modulator_adsrw(chan);
3987 update_carrier_adsrw(chan);
3990 If force_macro_keyon or
3991 NOT (fm_data.FEEDBACK_FM OR $80 <> fm_data.FEEDBACK_FM) then
3992 output_note(event_table[chan].note,
3993 event_table[chan].instr_def,chan,FALSE);
3995 If NOT songdata.dis_fmreg_col[fmreg_table][26] then
3996 If (freq_slide > 0) then
3997 portamento_up(chan,freq_slide,nFreq(12*8+1))
3998 else If (freq_slide < 0) then
3999 portamento_down(chan,Abs(freq_slide),nFreq(0));
4004 With songdata.macro_table[arpg_table].arpeggio do
4005 If (arpg_table <> 0) and (speed <> 0) then
4006 If (arpg_count = speed) then
4009 If (arpg_pos <= length) then
4010 If (loop_begin <> 0) and (loop_length <> 0) then
4011 If (arpg_pos = loop_begin+PRED(loop_length)) then
4012 arpg_pos := loop_begin
4013 else If (arpg_pos < length) then Inc(arpg_pos)
4014 else arpg_pos := finished_flag
4015 else If (arpg_pos < length) then Inc(arpg_pos)
4016 else arpg_pos := finished_flag
4017 else arpg_pos := finished_flag;
4019 If (freq_table[chan] OR $2000 = freq_table[chan]) and
4020 (keyoff_pos <> 0) and
4021 (arpg_pos >= keyoff_pos) then
4023 else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
4024 (keyoff_pos <> 0) and (keyoff_pos <> 0) and
4025 ((arpg_pos < keyoff_pos) or (arpg_pos = IDLE)) then
4026 arpg_pos := keyoff_pos;
4028 If (arpg_pos <> 0) and
4029 (arpg_pos <> IDLE) and (arpg_pos <> finished_flag) then
4030 Case data[arpg_pos] of
4031 0: change_frequency(chan,
4033 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
4036 change_frequency(chan,
4037 nFreq(max(arpg_note+data[arpg_pos],97)-1)+
4038 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
4041 change_frequency(chan,nFreq(data[arpg_pos]-$80-1)+
4042 SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
4045 else Inc(arpg_count);
4047 With songdata.macro_table[vib_table].vibrato do
4048 If NOT vib_paused and
4049 (vib_table <> 0) and (speed <> 0) then
4050 If (vib_count = speed) then
4051 If (vib_delay <> 0) then Dec(vib_delay)
4054 If (vib_pos <= length) then
4055 If (loop_begin <> 0) and (loop_length <> 0) then
4056 If (vib_pos = loop_begin+PRED(loop_length)) then
4057 vib_pos := loop_begin
4058 else If (vib_pos < length) then Inc(vib_pos)
4059 else vib_pos := finished_flag
4060 else If (vib_pos < length) then Inc(vib_pos)
4061 else vib_pos := finished_flag
4062 else vib_pos := finished_flag;
4064 If (freq_table[chan] OR $2000 = freq_table[chan]) and
4065 (keyoff_pos <> 0) and
4066 (vib_pos >= keyoff_pos) then
4068 else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
4069 (vib_pos <> 0) and (keyoff_pos <> 0) and
4070 ((vib_pos < keyoff_pos) or (vib_pos = IDLE)) then
4071 vib_pos := keyoff_pos;
4073 If (vib_pos <> 0) and
4074 (vib_pos <> IDLE) and (vib_pos <> finished_flag) then
4075 If (data[vib_pos] > 0) then
4076 macro_vibrato__porta_up(chan,data[vib_pos])
4077 else If (data[vib_pos] < 0) then
4078 macro_vibrato__porta_down(chan,Abs(data[vib_pos]))
4079 else change_freq(chan,vib_freq);
4081 else Inc(vib_count);
4084 _debug_str_ := _debug_str_bak_;
4089 macro_ticklooper: Longint;
4091 procedure timer_poll_proc;
4094 _debug_str_bak_: String;
4097 _debug_str_bak_ := _debug_str_;
4098 _debug_str_ := 'A2PLAYER.PAS:timer_poll_proc';
4100 If (timer_det < IRQ_freq DIV 200) then Inc(timer_det)
4103 Inc(_delay_counter);
4106 If (current_order = 0) and (current_line = 0) and
4107 (tick0 = ticks) then
4111 song_timer_tenths := 0;
4114 If (play_status = isPlaying) then
4116 song_timer_tenths := Trunc(100/IRQ_freq*timer_temp);
4117 If (song_timer_tenths = 100) then song_timer_tenths := 0;
4118 If (timer_temp < IRQ_freq) then Inc(timer_temp)
4125 If (song_timer > 3600-1) then
4129 song_timer_tenths := 0;
4132 If (ticklooper = 0) and NOT replay_forbidden then
4135 If (macro_ticklooper = 0) then
4139 If (ticklooper >= IRQ_freq DIV tempo) or fast_forward then
4142 Inc(macro_ticklooper);
4143 If (macro_ticklooper >= IRQ_freq DIV (tempo*_macro_speedup)) then
4144 macro_ticklooper := 0;
4146 _debug_str_ := _debug_str_bak_;
4151 _debug_str_ := 'A2PLAYER.PAS:newtimer';
4152 If irq_mode then timer_poll_proc;
4153 If (@external_irq_hook <> NIL) then external_irq_hook;
4158 _debug_str_ := 'A2PLAYER.PAS:init_irq';
4159 If irq_initialized then EXIT;
4160 irq_initialized := TRUE;
4161 TimerInstallHandler(@newtimer);
4167 _debug_str_ := 'A2PLAYER.PAS:done_irq';
4168 If NOT irq_initialized then EXIT;
4169 irq_initialized := FALSE;
4176 function calc_pattern_pos(pattern: Byte): Byte;
4180 jump_count,pattern_pos: Byte;
4183 _debug_str_ := 'A2PLAYER.PAS:calc_pattern_pos';
4184 pattern_pos := BYTE_NULL;
4186 index := calc_following_order(0);
4187 While (index <> -1) and (jump_count < $7f) do
4188 If (songdata.pattern_order[index] <> pattern) then
4189 If NOT (index < $7f) then BREAK
4192 index := calc_following_order(index);
4196 pattern_pos := index;
4199 calc_pattern_pos := pattern_pos;
4202 procedure init_buffers;
4208 _debug_str_ := 'A2PLAYER.PAS:init_buffers';
4209 FillChar(fmpar_table,SizeOf(fmpar_table),0);
4210 FillChar(pan_lock,SizeOf(pan_lock),BYTE(panlock));
4211 FillChar(volume_table,SizeOf(volume_table),0);
4212 FillChar(vscale_table,SizeOf(vscale_table),0);
4213 FillChar(modulator_vol,SizeOf(modulator_vol),0);
4214 FillChar(carrier_vol,SizeOf(carrier_vol),0);
4215 FillChar(event_table,SizeOf(event_table),0);
4216 FillChar(freq_table,SizeOf(freq_table),0);
4217 FillChar(effect_table,SizeOf(effect_table),0);
4218 FillChar(effect_table2,SizeOf(effect_table2),0);
4219 FillChar(fslide_table,SizeOf(fslide_table),0);
4220 FillChar(fslide_table2,SizeOf(fslide_table2),0);
4221 FillChar(glfsld_table,SizeOf(glfsld_table),0);
4222 FillChar(glfsld_table2,SizeOf(glfsld_table2),0);
4223 FillChar(porta_table,SizeOf(porta_table),0);
4224 FillChar(porta_table2,SizeOf(porta_table2),0);
4225 FillChar(arpgg_table,SizeOf(arpgg_table),0);
4226 FillChar(arpgg_table2,SizeOf(arpgg_table2),0);
4227 FillChar(vibr_table,SizeOf(vibr_table),0);
4228 FillChar(vibr_table2,SizeOf(vibr_table2),0);
4229 FillChar(trem_table,SizeOf(trem_table),0);
4230 FillChar(trem_table2,SizeOf(trem_table2),0);
4231 FillChar(retrig_table,SizeOf(retrig_table),0);
4232 FillChar(retrig_table2,SizeOf(retrig_table2),0);
4233 FillChar(tremor_table,SizeOf(tremor_table),0);
4234 FillChar(tremor_table2,SizeOf(tremor_table2),0);
4235 FillChar(panning_table,SizeOf(panning_table),0);
4236 FillChar(last_effect,SizeOf(last_effect),0);
4237 FillChar(last_effect2,SizeOf(last_effect2),0);
4238 FillChar(voice_table,SizeOf(voice_table),0);
4239 FillChar(event_new,SizeOf(event_new),0);
4240 FillChar(notedel_table,SizeOf(notedel_table),BYTE_NULL);
4241 FillChar(notecut_table,SizeOf(notecut_table),BYTE_NULL);
4242 FillChar(ftune_table,SizeOf(ftune_table),0);
4243 FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
4244 FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
4245 FillChar(reset_chan,SizeOf(reset_chan),BYTE(FALSE));
4246 FillChar(keyoff_loop,SizeOf(keyoff_loop),BYTE(FALSE));
4247 FillChar(macro_table,SizeOf(macro_table),0);
4249 If NOT lockvol then FillChar(volume_lock,SizeOf(volume_lock),0)
4250 else For temp := 1 to 20 do volume_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 4 AND 1);
4252 If NOT panlock then FillChar(panning_table,SizeOf(panning_table),0)
4253 else For temp := 1 to 20 do panning_table[temp] := songdata.lock_flags[temp] AND 3;
4255 If NOT lockVP then FillChar(peak_lock,SizeOf(peak_lock),0)
4256 else For temp := 1 to 20 do peak_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 5 AND 1);
4258 For temp := 1 to 20 do
4259 volslide_type[temp] := songdata.lock_flags[temp] SHR 2 AND 3;
4262 procedure init_player;
4268 _debug_str_ := 'A2PLAYER.PAS:init_player';
4271 For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0);
4272 For temp := $080 to $08d do opl2out(temp,BYTE_NULL);
4273 For temp := $090 to $095 do opl2out(temp,BYTE_NULL);
4275 speed_update := BOOLEAN(songdata.common_flag AND 1);
4276 lockvol := BOOLEAN(songdata.common_flag SHR 1 AND 1);
4277 lockVP := BOOLEAN(songdata.common_flag SHR 2 AND 1);
4278 tremolo_depth := songdata.common_flag SHR 3 AND 1;
4279 vibrato_depth := songdata.common_flag SHR 4 AND 1;
4280 panlock := BOOLEAN(songdata.common_flag SHR 5 AND 1);
4281 percussion_mode := BOOLEAN(songdata.common_flag SHR 6 AND 1);
4282 volume_scaling := BOOLEAN(songdata.common_flag SHR 7 AND 1);
4284 current_tremolo_depth := tremolo_depth;
4285 current_vibrato_depth := vibrato_depth;
4288 If NOT percussion_mode then
4301 misc_register := tremolo_depth SHL 7+
4302 vibrato_depth SHL 6+
4303 BYTE(percussion_mode) SHL 5;
4308 opl3exp($04+songdata.flag_4op SHL 8);
4312 opl2out(_instr[11],misc_register);
4314 current_tremolo_depth := tremolo_depth;
4315 current_vibrato_depth := vibrato_depth;
4316 global_volume := 63;
4317 vibtrem_speed_factor := def_vibtrem_speed_factor;
4318 vibtrem_table_size := def_vibtrem_table_size;
4319 Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table));
4321 For temp := 1 to 20 do
4323 arpgg_table[temp].state := 1;
4324 voice_table[temp] := temp;
4328 procedure stop_playing;
4334 _debug_str_ := 'A2PLAYER.PAS:stop_playing';
4336 play_status := isStopped;
4337 global_volume := 63;
4338 current_tremolo_depth := tremolo_depth;
4339 current_vibrato_depth := vibrato_depth;
4340 pattern_break := FALSE;
4342 current_pattern := 0;
4346 song_timer_tenths := 0;
4348 For temp := 1 to 20 do release_sustaining_sound(temp);
4349 opl2out(_instr[11],0);
4354 speed := songdata.speed;
4355 update_timer(songdata.tempo);
4358 procedure init_old_songdata;
4360 _debug_str_ := 'A2PLAYER.PAS:init_old_songdata';
4361 FillChar(old_songdata,SizeOf(old_songdata),0);
4362 FillChar(old_songdata.pattern_order,SizeOf(old_songdata.pattern_order),$080);
4363 FillChar(old_songdata.instr_data,SizeOf(old_songdata.instr_data),0);
4366 procedure init_songdata;
4368 _debug_str_ := 'A2PLAYER.PAS:init_songdata';
4369 If (play_status <> isStopped) then stop_playing
4372 FillChar(songdata,SizeOf(songdata),0);
4373 FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080);
4374 FillChar(pattdata^,PATTERN_SIZE*max_patterns,0);
4376 songdata.patt_len := 64;
4377 songdata.nm_tracks := 9;
4378 songdata.tempo := tempo;
4379 songdata.speed := speed;
4380 songdata.macro_speedup := 1;
4381 speed_update := FALSE;
4387 volume_scaling := FALSE;
4389 If (songdata.nm_tracks <= 18) then
4391 percussion_mode := FALSE;
4398 percussion_mode := TRUE;
4405 procedure start_playing;
4407 _debug_str_ := 'A2PLAYER.PAS:start_playing';
4409 If (error_code <> 0) then EXIT
4413 If (songdata.pattern_order[current_order] > $7f) then
4414 If (calc_order_jump = -1) then EXIT;
4416 current_pattern := songdata.pattern_order[current_order];
4418 pattern_break := FALSE;
4419 pattern_delay := FALSE;
4426 song_timer_tenths := 0;
4428 replay_forbidden := FALSE;
4429 play_status := isPlaying;
4432 macro_ticklooper := 0;
4433 speed := songdata.speed;
4434 macro_speedup := songdata.macro_speedup;
4435 update_timer(songdata.tempo);
4438 procedure get_chunk(pattern,line,channel: Byte;
4439 var chunk: tADTRACK2_EVENT); assembler;
4441 mov esi,dword ptr [pattdata]
4459 mov ebx,256*CHUNK_SIZE
4468 mov ebx,20*256*CHUNK_SIZE
4472 mov ebx,8*20*256*CHUNK_SIZE
4481 procedure put_chunk(pattern,line,channel: Byte;
4482 chunk: tADTRACK2_EVENT); assembler;
4485 mov edi,dword ptr [pattdata]
4490 mov limit_exceeded,TRUE
4500 mov ebx,256*CHUNK_SIZE
4509 mov ebx,20*256*CHUNK_SIZE
4513 mov ebx,8*20*256*CHUNK_SIZE
4522 procedure count_order(var entries: Byte);
4529 _debug_str_ := 'A2PLAYER.PAS:count_order';
4534 If (songdata.pattern_order[index] <> $80) then
4536 If (songdata.pattern_order[index] > $80) then
4537 If (songdata.pattern_order[index]-$80 <> index2) then
4539 index := songdata.pattern_order[index]-$80;
4545 If (index < $80) then Inc(index);
4546 until (index > $7f);
4552 old_exit_proc: Pointer;
4555 procedure new_exit_proc;
4557 _debug_str_ := 'A2PLAYER.PAS:new_exit_proc';
4560 FreeMem(pattdata,PATTERN_SIZE*max_patterns);
4564 old_exit_proc := ExitProc;
4565 ExitProc := @new_exit_proc;
4570 If (MemAvail > PATTERN_SIZE*temp) then
4572 max_patterns := temp;
4575 else If (temp-$10 >= $10) then Dec(temp,$10)
4582 If (error_code <> -2) then
4583 GetMem(pattdata,PATTERN_SIZE*max_patterns);
4585 FillChar(decay_bar,SizeOf(decay_bar),0);
4586 play_status := isStopped;