' *************************************************************************** ' * * ' * 2000 - 2011 ' * compile with gmt.bas and _slagwerk.inc * ' * Procedure declarations are in thunder.bi * ' *************************************************************************** ' 18.07.2000 : Hardware debug o.k. ' 17-18.07.2000 : coding by Kristof Lauwers ' 19-21.07 : put limitations and scalings of velo, freq, ... in lowlevel tasks ' 21.07 : bug detected in GetController > we should debug all midi in routines...! '12.08.2000 : debugged by gwr - hardware code moved to DLL '21.09.2000 :listens to metacommands. ignores unknown pieces! so new pieces have to be added in messagehandler also '12.10.2000 : run through GWR '16.10.2000 : last update before try out '07.08.2001 : rewritten for operation with NiDAQ DIO interfaces under NT ' thun_sim split of from this module. ' thunder.bi must be included!!! '!! IMPORTANT remember that the windmachine simulation resides in a separate sub windsimu!! '25.04.2002 : Code added for powerup, hardware modified. Check ports in the dll after hardware debug. '27.04.2002 : Strobo light added. '29.04.2002 : code sections moved to dll. '01.08.2002 : stormwind added to dll and this proc. '08.08.2002 : Bird added to dll and this proc. - tested o.k. ' To be done: simulator code for storm and bird. '22.04.2004 : Thunderwood repaired (IRF540 on windmachine did burn out). '24.07.2004 : listentask changed with masks. '05.09.2006 : ThunderWood - version 2: now a midi robot !!! '07.09.2006 : tests for peckers, ratchet, strobo, bird updated for midirobot but not tested yet - other tests may crash! ' remember #if %def(teobeupdated).. '07.09.2006 : Giant cricket added to thunderwood. Mapped on note 26 ' Orange light mapped on controller 70. '12.09.2006 : PIC code version 1 uploaded. ' Thunder.inc is the old code module. '16.11.2008 : for some reason, thunderwood seems to loose its hold for controller 66. ' may be related to mains glitches and the use of electronic relais. '01.07.2010 : Thunderwood failure after transport to Alden Biesen. Repair required. '28.09.2010 : Start adding squeek sounds and fire lights. '29.05.2011 : Squeak PIC firmware upgraded. Test code extended. '22.05.2017: Stormwind module redesigned, using a 16-bit motor controller PIC. FUNCTION Init_Thunderwood () AS LONG LOCAL m AS ASCIIZ * 40 LOCAL i AS LONG Task(%twtst).naam = "PeckTest" Task(%twtst).freq = 3 Task(%twtst).swit= %false Task(%twtst).cptr = CODEPTR(PeckerTest) Task(%twtst + 1).naam = "WindXtof" ' no good as simple test proc. Task(%twtst + 1).freq = 5 Task(%twtst + 1).swit = %false Task(%twtst + 1).cptr = CODEPTR(WindTest) Task(%twtst + 2).naam = "RatchTst" Task(%twtst + 2).freq = 0.4 Task(%twtst + 2).cptr = CODEPTR(RatchetTest) TaskEX(%twtst +2).stopcptr = CODEPTR(RatchetTest_Off) Task(%twtst + 3).naam = "ThundTst" Task(%twtst + 3).freq = 10 Task(%twtst + 3).cptr = CODEPTR(ThunderTest) Task(%twtst + 4).naam = "ChimeTst" Task(%twtst + 4).freq = 10 Task(%twtst + 4).cptr = CODEPTR(ChimesTest) Task(%twtst + 5).naam="RainTest" Task(%twtst + 5).freq = 60 Task(%twtst + 5).cptr = CODEPTR(RainTest) Task(%twtst + 6).naam = "Wind" ' better as test proc. for wind. Task(%twtst + 6).freq = 10 Task(%twtst + 6).cptr = CODEPTR(WindTest2) Task(%twtst + 7).naam = "Strobo" Task(%twtst + 7).freq = 1 Task(%twtst + 7).cptr = CODEPTR(Strobotest) Task(%twtst + 8).naam = "Storm" Task(%twtst + 8).freq = 0.98 Task(%twtst + 8).cptr = CODEPTR(TW_Storm_Test) TaskEX(%twtst+8).stopcptr = CODEPTR(TW_Storm_stop) Task(%twtst + 9).naam = "Bird" Task(%twtst + 9).freq = 2 Task(%twtst + 9).cptr = CODEPTR(TW_Bird_Test) Task(%twtst + 10).naam = "Cricket" Task(%twtst + 10).freq = 5 Task(%twtst + 10).cptr = CODEPTR(TW_Cricket_Test) Task(%twtst + 11).naam = "Light" Task(%twtst + 11).freq = 8 Task(%twtst + 11).cptr = CODEPTR(TW_Light_Test) Task(%twtst + 12).naam = "Squeek1" Task(%twtst + 12).freq = 1 Task(%twtst + 12).cptr = CODEPTR(TW_Squeek1_Test) Task(%twtst + 13).naam = "Squeek2" Task(%twtst + 13).freq = 1 Task(%twtst + 13).cptr = CODEPTR(TW_Squeek2_Test) Task(48).naam = "Green" '120 underside Task(48).freq = 16 Task(48).cptr = CODEPTR(TW_Green) Task(49).naam = "Red" '121 red spot steered by storm-motor board, one 1W LED in squaeker board Task(49).freq = 16 Task(49).cptr = CODEPTR(TW_Red) Task(50).naam = "Yellow" '122 Task(50).freq = 16 Task(50).cptr = CODEPTR(TW_Yellow) Task(51).naam = "Amber" '123 Task(51).freq = 16 Task(51).cptr = CODEPTR(TW_Amber) Task(52).naam = "NC124" '124 Task(52).freq = 16 Task(52).cptr = CODEPTR(TW_NC) Task(53).naam = "Blue" '125 Task(53).freq = 16 Task(53).cptr = CODEPTR(TW_Blue) Task(54).naam = "G-Strip" '126 Task(54).freq = 16 Task(54).cptr = CODEPTR(TW_Green_Strip) Task(55).naam = "White" '127 Task(55).freq = 16 Task(55).cptr = CODEPTR(TW_White) Task(%MM_SysxTask).naam = "SendSysx" Task(%MM_SysxTask).freq = .33 Task(%MM_SysxTask).cptr = CODEPTR(MM_Sysx) 'in m_robots.inc ProgChange Thunderwood.channel, 122 warning "Using mapping 122 on Thunderwood" #IF %DEF(%ToBeUpdated) Task(%woody).naam = "Woody" 'piece for thunderwood Task(%woody).freq = 12'16 '32 '8 Task(%woody).cptr = CODEPTR(Woody) TaskEX(%Woody).StopCptr = CODEPTR(MM_Thunderwood_Off) Task(%woody + 1).naam="WDStoch" Task(%woody + 1).cptr=CODEPTR(WoodStoch) Task(%woody + 1).freq=4 'was 3,2 001004 TaskEX(%Woody + 1).StopCptr = CODEPTR(MM_Thunderwood_Off) #ENDIF 'delete unecessary buttons - watch out with this if you combine it with ' other instruments that might use some of these buttons!! ButnSW(2).tag0 = "" ButnSW(3).tag0 = "" ButnSW(4).tag0 = "" ButnSW(5).tag0 = "" ButnSW(6).tag0 = "" ButnSW(7).tag0 = "" ButnSW(8).tag0 = "" ButnSW(9).tag0 = "" ButnSW(11).tag0 = "" ButnOS(3).tag = "" ButnOS(4).tag = "" ButnOS(5).tag = "" ButnOS(6).tag = "" ButnOS(8).tag = "" ButnOS(9).tag = "" FUNCTION = %True END FUNCTION SUB Peckertest () 'test code for pecker 'sliders are for pecker speed & velo 'rev. gwr 09.09.06 '13.09.2006: second low pecker not working, due to a PIC code error. STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC udnr AS INTEGER IF ISFALSE Task(%twtst).tog THEN DIM TaskParamLabels(2) TaskParamLabels(0)="Speed" TaskParamLabels(1)="velo" TaskParamLabels(2)="Note" MakeTaskParameterDialog %twtst,2, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%twtst).SliderNumbers(0) 'get slidernumber given in GMT-code Slider(Slnr).value = 5 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Slider(Slnr+1).value = 1 SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value udnr = TaskEX(%twtst).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Pecker_Test_UD) UDctrl(udnr).value = 1 Task(%twtst).tog = %True 'EXIT SUB END IF Task(%twtst).freq = MAX(.2, Slider(slnr).value / 5) mPlay Thunderwood.channel, UdCtrl(udnr).value, Slider(slnr+1).value END SUB SUB Pecker_test_ud () LOCAL udnr AS DWORD udnr = TaskEX(%TwTst).UpdownNumbers(0) IF UdCtrl(udnr).value > 14 THEN UdCtrl(udnr).value = 14 IF UdCtrl(udnr).value < 1 THEN UdCtrl(udnr).value = 1 SetDlgItemText Task(%twtst).hparam, %GMT_TEXT0_ID + 16, STR$(UDCtrl(udnr).value) END SUB SUB RatchetTest () ' note: the ratched has no velo sensitivity and requires a note off!!! ' rev. gwr 09.09.06 STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC cnt AS LONG IF ISFALSE task(%twtst + 2).tog THEN DIM TaskParamLabels(1) TaskParamLabels(0)="Speed" MakeTaskParameterDialog %twtst+2,2, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%twtst+2).SliderNumbers(0) 'get slidernumber given in GMT-code Slider(Slnr).value = 5 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value cnt = %False Task(%twtst+2).tog = %True END IF IF ISFALSE cnt THEN mPlay Thunderwood.channel, 15, 127 ELSE NoteOff ThunderWood.channel, 15 END IF INCR cnt IF cnt > 1 THEN cnt = %False Task(%twtst+2).freq = MAX(.2, Slider(slnr).value / 10) END SUB SUB RatchetTest_Off () NoteOff ThunderWood.channel, 15 END SUB SUB StroboTest () ' no velo here. ' do not switch this one fast on and off. The stroboscope works automatic and is switched through ' an electromechanic relay. STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC OldVal AS LONG IF ISFALSE Task(%twtst+7).tog THEN DIM TaskParamLabels(0) TaskParamLabels(0) = "Speed" IF ISFALSE Task(%twtst + 7).hParam THEN MakeTaskParameterDialog %twtst+7,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(%twtst + 7).SliderNumbers(0) Slider(Slnr).value = 10 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Task(%twtst+7).tog = %True END IF IF Oldval = %True THEN mPlay Thunderwood.channel, 0, 0 OldVal =%False ELSE mPlay Thunderwood.channel, 0, 64 OldVal = %True END IF Task(%twtst+7).freq = MAX(.1, Slider(Slnr).value / 32) END SUB SUB TW_Bird_Test () ' testmodule for bird sound ' for a realistic bird sound, one should modulate the task frequency ' put random slider to 0 for testing purposes ' 1 to make it work the way it used to work STATIC TaskParamlabels() AS ASCIIZ*8 STATIC slnr AS INTEGER IF ISFALSE Task(%twtst+9).tog THEN DIM TaskParamLabels(2) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Force" TaskParamLabels(2) = "random" IF Task(%twtst+9).hParam = %Null THEN MakeTaskParameterDialog %twtst+9,3, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(%twtst+9).SliderNumbers(0) Slider(Slnr).value = 20 Slider(Slnr+1).value = 0 Slider(slnr+2).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, Slider(Slnr+2).value Task(%twtst+9).tog = %True END IF ' TW_Bird INT(.5 * Slider(slnr+1).value * SQR(RND)) ' bytes mPlay Thunderwood.channel, 22, ((127 - Slider(slnr + 2).value)/127) * Slider(slnr + 1 ).value + (Slider(slnr + 2).value/127) * INT(2 * Slider(slnr+1).value * SQR(RND)) Task(%twtst+9).freq = Slider(slnr).value / 10 ' 12Hz max. IF Slider(slnr+1).value THEN ' limit duty cycle to 50% IF Task(%twtst+9).freq > 1000 / Slider(slnr+1).value THEN Task(%twtst+9).freq = 1000/ Slider(slnr+1).value END IF Task(%twtst + 9).freq = ((127 - Slider(slnr + 2).value)/127) * Task(%twtst + 9).freq + (Slider(slnr + 2).value/127) * SQR(RND) * 2 * Task(%twtst + 9).freq IF Task(%twtst+9).freq < 0.25 THEN Task(%twtst+9).freq = 0.25 END SUB SUB TW_Cricket_Test () ' testmodule for giant cricket sound ' for a realistic cricket sound, one should modulate the task frequency ' put random slider to 0 for testing purposes ' 1 to make it work the way it used to work STATIC TaskParamlabels() AS ASCIIZ*8 STATIC slnr AS INTEGER IF ISFALSE Task(%twtst+10).tog THEN DIM TaskParamLabels(2) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Force" TaskParamLabels(2) = "random" IF Task(%twtst+10).hParam = %Null THEN MakeTaskParameterDialog %twtst+10,3, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(%twtst+10).SliderNumbers(0) Slider(Slnr).value = 20 Slider(Slnr+1).value = 0 Slider(slnr+2).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, Slider(Slnr+2).value Task(%twtst+10).tog = %True END IF mPlay Thunderwood.channel, 26, ((127 - Slider(slnr + 2).value)/127) * Slider(slnr + 1 ).value + (Slider(slnr + 2).value/127) * INT(2 * Slider(slnr+1).value * SQR(RND)) Task(%twtst+10).freq = Slider(slnr).value / 8 IF Slider(slnr+1).value THEN ' limit duty cycle to 50% IF Task(%twtst+10).freq > 1000 / Slider(slnr+1).value THEN Task(%twtst+10).freq = 1000/ Slider(slnr+1).value END IF Task(%twtst + 10).freq = ((127 - Slider(slnr + 2).value)/127) * Task(%twtst + 10).freq + (Slider(slnr + 2).value/127) * SQR(RND) * 2 * Task(%twtst + 10).freq IF Task(%twtst+10).freq < 0.25 THEN Task(%twtst+10).freq = 0.25 END SUB SUB TW_Light_Test () ' orange rotating light STATIC TaskParamlabels() AS ASCIIZ*8 STATIC slnr AS INTEGER IF ISFALSE Task(%twtst+11).tog THEN DIM TaskParamLabels(0) TaskParamLabels(0) = "Speed" IF Task(%twtst+11).hParam = %Null THEN MakeTaskParameterDialog %twtst+11,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(%twtst+11).SliderNumbers(0) Slider(Slnr).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Task(%twtst+11).tog = %True END IF IF Thunderwood.ctrl(70) <> Slider(slnr).value THEN ThunderWood.ctrl(70) = Slider(slnr).value Controller ThunderWood.channel, 70, ThunderWood.ctrl(70) END IF Task(%twtst+11).freq = 8 END SUB SUB WindTest () 'testmodule for windmachine STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr() AS INTEGER LOCAL i AS INTEGER LOCAL OutVal AS SINGLE 'output value to windmachine, must be single for computations done on it!!! STATIC hoek AS SINGLE STATIC eksp AS DWORD 'exponent v/d sinuskurve STATIC OldVal AS LONG STATIC SPEED AS BYTE IF ISFALSE Task(%twtst+1).tog THEN DIM Slnr(2) DIM TaskParamLabels(2) TaskParamLabels(0) = "Speed" 'with wich an exponential sine functon proceeds through time TaskParamLabels(1) = "curve" 'exponent TaskParamLabels(2) = "MaxVal" 'maximum speed value for windmachine IF Task(%twtst+1).hParam = %Null THEN MakeTaskParameterDialog %twtst+1,3, Slider(),0,UdCtrl(), TaskParamLabels() END IF FOR i = 0 TO 2 slnr(i) = TaskEX(%twtst+1).SliderNumbers(i) 'get slidermumber given in GMT-code Slider(Slnr(i)).value = 20 SendMessage Slider(Slnr(i)).h, %TBM_SETPOS,%True, Slider(Slnr(i)).value NEXT Task(%twtst+1).tog = %True END IF hoek = hoek + Slider(slnr(0)).value / ( 1000 * Pi) 'tussen .001 en .127 halve sinussen / sec bij taskfreq 5 IF hoek >= Pi THEN hoek = %false eksp = INT(Slider(slnr(1)).value/20) IF eksp < 1 THEN eksp = 1 '1 to 6 OutVal = ABS(SIN(hoek ))^eksp OutVal = INT(OutVal * Slider(slnr(2)).value) + 4 IF OutVal < 0 THEN OutVal = 0 IF OutVal <> OldVal THEN SPEED = INT(OutVal) mPlay Thunderwood.channel, 24, SPEED ' should also work with ctrl 1 SetDlgItemText gh.CockPit, %GMT_msg1, " hoek " + STR$(hoek) + " curve " + STR$(eksp) + " MaxVal " + STR$(Slider(slnr(2)).value * 2) SetDlgItemText BYVAL gh.Cockpit, (%GMT_msg2),"Output Value: "+ STR$(OutVal) OldVal = OutVal END IF END SUB SUB WindTest2 () ' elementary test for the hardware pwm ' should also be controlled by controller 1 STATIC TaskParamLabels() AS ASCIIZ * 8 STATIC slnr AS LONG STATIC outVal AS LONG IF ISFALSE slnr THEN DIM TaskParamLabels (0) TaskParamLabels(0) = "PWM" MakeTaskParameterDialog %twtst+6,1, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%twtst + 6).SliderNumbers(0) 'get slidermumber given in GMT-code END IF outval = Slider(slnr).value ' range 0-127 IF Thunderwood.ctrl(1) <> outval THEN mPlay Thunderwood.channel, 24, outval ' = Controller Thunderwood.channel, 1, outval Thunderwood.ctrl(1) = outval END IF Task(%twtst+6).freq = 5 END SUB SUB Windtest2_Off () NoteOff Thunderwood.channel, 24 ThunderWood.ctrl(1) = %False END SUB SUB ThunderTest () ' donderblik - autotoggles as in klung STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr() AS INTEGER LOCAL i AS INTEGER IF ISFALSE Task(%twtst+3).tog THEN DIM Slnr(1) DIM TaskParamLabels(1) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Velo " IF Task(%twtst+3).hParam = %Null THEN MakeTaskParameterDialog %twtst+3,2, Slider(),0,UdCtrl(), TaskParamLabels() END IF FOR i = 0 TO 1 slnr(i) = TaskEX(%twtst+3).SliderNumbers(i) 'get slidermumber given in GMT-code Slider(Slnr(i)).value = 10 SendMessage Slider(Slnr(i)).h, %TBM_SETPOS,%True, Slider(Slnr(i)).value NEXT Task(%twtst+3).tog = %TRue END IF Task(%twtst+3).freq = MAX(Slider(slnr(0)).value/6, 1) mPlay ThunderWood.channel, 19, Slider(slnr(1)).value ' autotoggles END SUB SUB ChimesTest () 'bamboo windchimes ' autotoggles now (as in klung) STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr() AS INTEGER LOCAL i AS INTEGER IF ISFALSE Task(%twtst+4).tog THEN DIM Slnr(1) DIM TaskParamLabels(1) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Velo " IF Task(%twtst+4).hParam = %Null THEN MakeTaskParameterDialog %twtst+4,2, Slider(),0,UdCtrl(), TaskParamLabels() END IF FOR i = 0 TO 1 slnr(i) = TaskEX(%twtst+4).SliderNumbers(i) 'get slidermumber given in GMT-code Slider(Slnr(i)).value = 10 SendMessage Slider(Slnr(i)).h, %TBM_SETPOS,%True, Slider(Slnr(i)).value NEXT Task(%twtst+4).tog = %True END IF Task(%twtst+4).freq = MAX(Slider(slnr(0)).value/6, 1) mPlay ThunderWood.channel, 17, Slider(slnr(1)).value ' autotoggles END SUB SUB RainTest () ' in afwachting van pic implementatie van de ruisgenerator. gwr STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr() AS INTEGER LOCAL i AS INTEGER IF ISFALSE Task(%twtst+5).tog THEN DIM Slnr(3) DIM TaskParamLabels(3) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "MinSp" TaskParamLabels(2) = "Velo " IF Task(%twtst+5).hParam = %Null THEN MakeTaskParameterDialog %twtst+5,3, Slider(),0,UdCtrl(), TaskParamLabels() END IF FOR i = 0 TO 3 slnr(i) = TaskEX(%twtst+5).SliderNumbers(i) 'get slidernumber given in GMT-code Slider(Slnr(i)).value = 20 SendMessage Slider(Slnr(i)).h, %TBM_SETPOS,%True, Slider(Slnr(i)).value NEXT Task(%twtst+5).tog = %True END IF Task(%twtst+5).freq = Slider(slnr(1)).value + MAX(Slider(slnr(0)).value * RND(1),1) mPlay Thunderwood.channel, 16, RND(1) * Slider(slnr(2)).value END SUB SUB TW_Storm_Test () ' module changed 22.05.2017 ' requires ctrl.66 to be on! ' noteoff + release implemented for braking. STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr, udnr AS LONG STATIC velo, cnt AS INTEGER LOCAL i AS INTEGER IF ISFALSE Task(%twtst+8).tog THEN DIM TaskParamLabels(3) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Rate" TaskParamLabels(2) = "Brake" TaskParamLabels(3) = "#66" IF ISFALSE Task(%twtst+8).hParam THEN MakeTaskParameterDialog %twtst+8,3, Slider(),1,UdCtrl(), TaskParamLabels() slnr= TaskEX(%twtst+8).SliderNumbers(0) Slider(Slnr).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Slider(Slnr+1).value = 10 SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value Slider(Slnr+2).value = 0 SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, Slider(Slnr+2).value udnr = TaskEX(%twtst+8).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Storm_CC66_UD) UDctrl(udnr).value = 0 END IF Task(%twtst+8).tog = %True END IF Task(%twtst+8).freq = (Slider(slnr+1).value + 1) / 32 IF ISFALSE cnt THEN velo = slider(slnr).value ' IF velo > 0 THEN mPlay Thunderwood.channel, 25, velo ' ELSE ' IF slider(slnr+2).value = 0 THEN ' NoteOff Thunderwood.channel, 25 ' ELSE ' Release Thunderwood.channel, 25, slider(slnr+2).value ' END IF ' END IF ELSE ' with the rate slider to 0, the note will stay ON: IF Slider(slnr+1).value > 0 THEN IF slider(slnr+2).value = 0 THEN NoteOff Thunderwood.channel, 25 ELSE Release Thunderwood.channel, 25, Slider(slnr+2).value END IF END IF END IF INCR cnt IF cnt > 1 THEN cnt = %False END SUB SUB Storm_CC66_ud () 'power on/off switch test LOCAL udnr AS DWORD udnr = TaskEX(%TwTst+8).UpdownNumbers(0) IF UdCtrl(udnr).value > 1 THEN UdCtrl(udnr).value = 1 IF UdCtrl(udnr).value < 1 THEN UdCtrl(udnr).value = 0 SetDlgItemText Task(%twtst).hparam, %GMT_TEXT0_ID + 16, STR$(UDCtrl(udnr).value) Controller Thunderwood.channel, 66, UDCtrl(udnr).value Thunderwood.ctrl(66) = UDCtrl(udnr).value END SUB SUB TW_Storm_Stop () NoteOff Thunderwood.channel, 25 END SUB #IF %DEF (%ToBeAdapted) SUB Woody () 'piece for woodpecker - by gwr STATIC low AS DWORD STATIC tenor AS DWORD STATIC alto AS DWORD STATIC high AS DWORD STATIC progr AS DWORD STATIC gCount AS DWORD 'general counter STATIC wind AS LONG 'switches: STATIC thunder AS LONG STATIC rain AS LONG STATIC chimes AS LONG STATIC sl0 AS LONG STATIC sl1 AS LONG IF ISFALSE task(%woody).tog THEN INCR task(%woody).tog gcount = %false wind = %false thunder = %false rain = %false chimes = %false progr = %false 'slider 0 for velo 'slider 1 for speed Slider(0).minval = 1 Slider(0).maxval = 127 Slider(0).stap = 1 Slider(0).value = 60'maxNr Slider(1).minval = 1 Slider(1).maxval = 127 Slider(1).stap = 1 Slider(1).value = 6.35*(task(%woody).freq - 5) '60 SendMessage Slider(0).h, %TBM_SETRANGE,%True, MakeLong(Slider(0).minval, Slider(0).maxval) SendMessage Slider(0).h, %TBM_SETPAGESIZE,0,Slider(0).stap SendMessage Slider(0).h, %TBM_SETPOS,%True, Slider(0).value SendMessage Slider(1).h, %TBM_SETRANGE,%True, MakeLong(Slider(1).minval, Slider(1).maxval) SendMessage Slider(1).h, %TBM_SETPOS,%True, Slider(1).value SetDlgItemText gh.Cockpit, %GMT_TITLE , "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR , $gwr task(%twtst + 11)).level = 5 task(%twtst + 12)).level = 5 task(%twtst + 13)).level = 5 task(%twtst + 14)).level = 5 END IF task(%woody).freq = 5 + Slider(1).value /6.35 INCR gCount IF ISFALSE low THEN task(%twtst + 11)).level = 100 * SIN(Pi*gcount/115)^2 '115 = 23 * 5> one cycle = 23 beats task(%twtst + 11)).level = INT(task(%twtst + 11)).level * Slider(0).value/127) PeckerLow END IF IF ISFALSE tenor THEN task(%twtst + 12)).level = 100 * SIN(Pi*gcount/203 )^2 ' 29 * 7> one cycle = 29 beats task(%twtst + 12)).level = INT(task(%twtst + 12)).level * Slider(0).value/127) PeckerTenor END IF IF ISFALSE alto THEN task(%twtst + 13)).level = 100 * SIN(Pi*gcount/333)^2 ' 37 * 9> one cycle = 29 beats task(%twtst + 13)).level = INT(task(%twtst + 13)).level * Slider(0).value/127) PeckerAlto END IF IF ISFALSE high THEN task(%twtst + 14)).level = 100 * SIN(Pi*gcount/451 )^2 ' 41 * 11> one cycle = 37 beats task(%twtst + 14)).level = INT(task(%twtst + 14)).level * Slider(0).value/127) PeckerHigh END IF IF (low + tenor + alto + high) = 0 THEN INCR progr SELECT CASE progr CASE 2 IF wind THEN EXIT SELECT 'start wind Wind = %true TW_Wind 5 CASE 3 'start thunder IF thunder THEN EXIT SELECT task(%twtst + 10).freq = 2 task(%twtst + 10).level = 100 StartTask %twtst + 10 thunder = %true CASE 4 'start rain IF rain THEN EXIT SELECT task(%twtst + 16).duur = 5 task(%twtst + 16).tempo = 127 task(%twtst + 16).level = 30 Rain = %true StartTask %twtst + 16 CASE 5 'chimes IF chimes THEN EXIT SELECT task(%twtst + 15).freq = 2 task(%twtst + 15).level = 1 chimes=%true StartTask %twtst + 15 CASE 6 ' ThunderLog "the end" END SELECT END IF INCR low: INCR tenor: INCR alto: INCR high 'every x steps reset, on next step we Play the note ' with gwr's original values, one cycle takes 468901 steps!... 'now we try with smaller vals > now we still have 3465 steps IF low = 5 THEN low = %false 'was 19 '!! if we change those values we also have to adapt IF tenor = 7 THEN tenor = %false 'was 23 '!! the values determining the volume cycles IF alto = 9 THEN alto = %false 'was 29 '! (c.s.) IF high = 11 THEN high = %false 'was 37 IF (low + tenor + alto = 0) OR (low + tenor + high = 0) OR _ (low + alto + high = 0) OR (tenor + alto + high = 0) THEN TW_Ratch task(%twtst + 11)).level+task(%twtst + 12)).level+task(%twtst + 13)).level+task(%twtst + 14)).level END IF 'experiment: IF gcount MOD INT(task(%woody).freq/3) THEN EXIT SUB 'we don't need to do the following that often... IF wind THEN TW_Wind 255 * SIN(gcount/257 * Pi)^2 * SIN(gcount/76)^2 END IF IF thunder THEN '3 min cycles task(%twtst + 10 ).level = 27 + 100 * ABS(SIN(Pi*gcount/1050*Pi )^2 * SIN(Pi*gcount/415)^2) ' 41 * 11> one cycle = 37 beats task(%twtst + 10).freq = 1.5+ 5 * ABS(SIN(Pi*gcount/1150 )^2 * SIN(Pi*gcount/715)^ 2) IF task(%twtst + 10).level < 40 THEN 'if level is low we stop tasks > avoid having all tasks on simultan. for a long time... Stoptask %twtst + 10 ELSEIF (ISFALSE BIT(task(%twtst + 10).swit, %TASK_ONOFF)) AND (task(%twtst + 10).freq >2.2) AND (task(%twtst + 10).level >50) THEN StartTask %twtst + 10 END IF IF task(%twtst + 10).freq < 2 THEN IF BIT(task(%twtst + 10).swit, %TASK_ONOFF) THEN task(%twtst + 10).freq = 2 stoptask %twtst + 10 END IF ELSE IF (ISFALSE BIT(task(%twtst + 10).swit, %TASK_ONOFF)) AND (task(%twtst + 10).level >=40) THEN StartTask %twtst + 10 END IF ' EXIT SUB END IF IF rain THEN '5 min cycles task(%twtst + 16).tempo = 47 + 200 * ABS(SIN(gcount/540 * Pi) * SIN(Pi*gcount/197)) IF task(%twtst + 16).tempo < 90 THEN Stoptask %twtst + 16 ELSEIF (ISFALSE BIT(task(%twtst + 16).swit, %TASK_ONOFF)) AND (task(%twtst + 16).tempo >100) THEN StartTask %twtst + 16 END IF END IF IF chimes THEN task(%twtst + 15).level =27 + 80 * SIN(gcount/68 *Pi)^2 * COS(Pi*gcount/221)^2 ThunderLog STR$(task(%twtst + 15).level) IF task(%twtst + 15).level < 50 THEN 'if level is low we stop tasks > avoid having all tasks on simultan. for a long time... Stoptask %twtst + 15 ELSEIF ISFALSE BIT(task(%twtst + 15).swit, %TASK_ONOFF) THEN StartTask %twtst + 15 END IF 'ThunderLog "chimes" task(%twtst + 15).freq = 2 + 2 * SIN(gcount/127)^2 * SIN(Pi*gcount/71)^2 ' EXIT SUB END IF END SUB SUB WoodStoch () ' a piece by Kristof Lauwers STATIC i AS LONG STATIC sl0 AS LONG STATIC sl1 AS LONG LOCAL j AS LONG LOCAL dummy AS SINGLE LOCAL tekst AS STRING STATIC InfLevel AS SINGLE 'level = infLevel * AME STATIC infFreq AS SINGLE STATIC infNeighb AS SINGLE 'influence to 'neighbour notes', defined as fourth u/d STATIC hoekLevel AS DOUBLE STATIC hoekFreq AS DOUBLE STATIC OnCount AS DWORD STATIC hDlgWS AS LONG STATIC density AS LONG LOCAL harm AS harmtype 'piece for thwood by kl 'each has an amount of energy wich influences the levl and tremolo speed 'if the AME is high enough, it is slowly passed to the notes one fifth higher / lower 'note: very low Meta_AME can have unexpected reults! IF ISFALSE task(%woody+1).tog THEN 'this tog is resetted when task is stopped by the user... task(%woody +1).pan = 0 ' pan = 1 for end of piece, tasknr of beatertask when the according button is clicked to raise energy level task(%woody+1).tog = %true FOR i = 0 TO 8 task(%twtst + 10+i).level = 0 task(%twtst + 10+i).freq = .1 NEXT density = 64 hoekLevel = 1 hoekFreq = 1.3' 2 infNeighb = .4 DIM AME(0 TO 8) AS STATIC DOUBLE 'amount of energy DIM HighCount(0 TO 8) AS STATIC DOUBLE IF Meta_AME_thunder =0 THEN Meta_AME_Thunder = 1 'set values that remain constant... task(%twtst + 16).duur=64 task(%twtst + 16).tempo=64 AME(INT(RND(1)*6)) = .9 DIALOG SHOW MODELESS hDlgWS Slider(0).minval = 1 Slider(0).maxval = 100 Slider(0).stap = 1 Slider(0).value = 80'0.3 * 100 '127 * SIN(hoeklevel)^2'maxNr Slider(1).minval = 1 Slider(1).maxval = 100 Slider(1).value = 80'0.6 * 100'127 * SIN(HoekFreq)^2 'increment*10000 SendMessage Slider(0).h, %TBM_SETRANGE,%True, MakeLong(Slider(0).minval, Slider(0).maxval) SendMessage Slider(0).h, %TBM_SETPAGESIZE,0,Slider(0).stap SendMessage Slider(0).h, %TBM_SETPOS,%True, Slider(0).value SendMessage Slider(1).h, %TBM_SETRANGE,%True, MakeLong(Slider(1).minval, Slider(1).maxval) SendMessage Slider(1).h, %TBM_SETPOS,%True, Slider(1).value SetDlgItemText gh.Cockpit, %GMT_TITLE , "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR , $krl END IF InfLevel = Meta_AME_Thunder * Slider(0).value / 100 InfFreq = Meta_AME_Thunder * Slider(1).value / 100 hoekLevel = hoekLevel + Pi/(95 * task(%Stochl).freq) ' 1.5 min voor 1 cyclus IF hoekLevel = Pi THEN hoekLevel = 0 hoekFreq = hoekfreq + Pi/(160 * task(%Stochl).freq) ' 2.333 min / cyclus IF hoekFreq > Pi THEN hoekFreq = 0 InfLevel = InfLevel*ABS(SIN(hoekLevel))^2 InfFreq = InfFreq *ABS(SIN(hoekFreq)) '^4 IF InfFreq >.9 THEN InfFreq=.9 IF InfLevel <(.1 + slider(0).value / 200) THEN InfLevel=(.1 + Slider(0).value / 200) IF inflevel >.72 THEN infLevel = .72 IF infFreq <.01 THEN infFreq = .01 INCR i FOR dummy = 0 TO 8 tekst = tekst + TRIM$(STR$(INT(AME(dummy)*1000))) + " " NEXT tekst = tekst + " - "+STR$(Meta_AME_Thunder) ThunderLog tekst IF i >8 THEN i = 0 '-1 END IF IF i=8 THEN IF AME(i) > Meta_AME_thunder * .1 THEN TW_RATCH INT(AME(i)*127*inflevel) ELSEIF i = 7 THEN 'wind IF Meta_AME_thunder > .75 THEN 'min. 1 ! TW_WIND INT(AME(i)*225*SIN(30*hoekfreq)*inflevel) ELSE TW_WIND 0 END IF ELSE task(%twtst + 10+i).level = INT( (2 * task(%twtst + 10+i).level + (127 * AME(i) * infLevel)) / 3) SELECT CASE i CASE 0, 1 IF task(%twtst + 10+i).level < 30 THEN task(%twtst + 10+i).level = 30 CASE ELSE IF task(%twtst + 10+i).level < 10 THEN task(%twtst + 10+i).level = 10 END SELECT IF i<> 2 THEN task(%twtst + 10+i).freq = (4 * task(%twtst + 10+i).freq + (.1 + 6 * AME(i) * infFreq)) / 5 IF i=2 THEN task(%twtst + 10+i).duur = (INT(127*AME(i)*infFreq)) 'for rain IF (task(%twtst + 10+i).level > 3) THEN ' IF i > 6 THEN EXIT SUB 'DBG IF ISFALSE BIT (task(%twtst + 10+i).swit,%TASK_ONOFF) THEN StartTask %twtst + 10+i : EXIT SUB ELSEIF BIT(task(%twtst + 10+i).swit, %TASK_ONOFF) THEN StopTask %twtst + 10+i END IF END IF ' ThunderLog "b" j = i - 1 DO WHILE j < 0: j = j + 7: LOOP AME(j) = AME(j) + AME(i) * (infNeighb / (2*task(%woody+1).freq)) j = i + 1 DO WHILE j > 8: j = j - 7: LOOP AME(j) = AME(j) + AME(i) * (infNeighb / (2*task(%woody+1).freq)) AME(i) = AME(i) - AME(i) * (infNeighb / task(%woody+1).freq) #IF %DEF(%klungSim) IF AME(i) < .3 THEN AME(j) = AME(j) + AME(i) 'last bit passed at once.. AME(i) = 0 StopTask %twtst + 10+i END IF #ENDIF ' ThunderLog "c" FOR j = 0 TO 8 IF AME(j) > Meta_AME_Thunder THEN AME(j) = 0 'too much energy is deadly... the energy is spread over all klungs, and a little bit is lost #IF NOT %DEF(%klungSim) 'FOR dummy = 0 TO 8 ' AME(INT(dummy)) = AME(INT(dummy)) + 0.05 'NEXT grow: dummy = RND * 8 IF dummy <4 OR dummy > 7 THEN AME(RND(1)*8)=AME(RND(0)*8)+.6 ELSE AME(RND(1)*8)=AME(RND(0)*8)+.2 GOTO grow END IF #ENDIF END IF NEXT dummy = %false FOR j = 0 TO 8 IF AME(j) < Meta_AME_Thunder/5 THEN INCR dummy NEXT IF dummy >= 7 THEN dummy = RND * 8 IF dummy <4 OR dummy > 7 THEN AME(dummy)=AME(dummy)+.6 END IF END IF 'high energy's grow automaticaly IF AME(i) > Meta_AME_Thunder/2 THEN AME(i) = AME(i) *1.09 OnCount = %false FOR j = 0 TO 8 IF AME(j)> .25 THEN INCR Oncount NEXT IF OnCount > 3 THEN ' if too much are playing the highest ae killed FOR j = 0 TO 8 IF AME(j)>.4 THEN AME(j) = %false ELSEIF AME(j)<.2 THEN AME(j)=.8 END IF NEXT END IF IF AME(i) > Meta_AME_Thunder/3 THEN 'if energy is high for a long time, we're getting tired... INCR HighCount(i) IF HighCount(i) > 4 THEN AME(i) = AME(i) - .05 END IF IF AME(i) > Meta_AME_Thunder THEN AME(i) = Meta_AME_Thunder ELSE IF AME(i) < 0 THEN AME(i) = 0 IF HighCount(i) THEN DECR highCount(i) END IF END SUB #ENDIF SUB TW_Squeek1_Test () ' brass resonator squeaker ' note-pressure is also implemented on the PIC STATIC TaskParamlabels() AS ASCIIZ*8 STATIC slnr, cnt AS INTEGER IF ISFALSE Task(%twtst+12).tog THEN DIM TaskParamLabels(1) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Force" IF Task(%twtst+12).hParam = %Null THEN MakeTaskParameterDialog %twtst+12,2, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(%twtst+12).SliderNumbers(0) Slider(Slnr).value = 20 Slider(Slnr+1).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value cnt = %False Task(%twtst+12).tog = %True END IF IF ISFALSE cnt MOD 2 THEN mPlay Thunderwood.channel, 21, Slider(slnr + 1).value ELSE NoteOff Thunderwood.channel, 21 END IF INCR cnt Task(%twtst+12).freq = MAX(Slider(slnr).value / 10, 1) ' 12Hz max. END SUB SUB TW_Squeek2_Test () 'wood resonator squeaker STATIC TaskParamlabels() AS ASCIIZ*8 STATIC slnr, cnt AS INTEGER IF ISFALSE Task(%twtst+13).tog THEN DIM TaskParamLabels(1) TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "Force" IF Task(%twtst+13).hParam = %Null THEN MakeTaskParameterDialog %twtst+13,2, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(%twtst+13).SliderNumbers(0) Slider(Slnr).value = 20 Slider(Slnr+1).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value cnt = %False Task(%twtst+13).tog = %True END IF IF ISFALSE cnt MOD 2 THEN mPlay Thunderwood.channel, 23, Slider(slnr + 1).value ELSE NoteOff Thunderwood.channel, 23 END IF INCR cnt Task(%twtst+13).freq = MAX(Slider(slnr).value / 10, 1) ' 12Hz max. END SUB SUB TW_Green () ' velocity byte steers the flashing speed ' controlled by Squeaker board - 3W green LED STATIC oldvel AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(48).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(48).hParam = %Null THEN MakeTaskParameterDialog 48,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(48).SliderNumbers(0) Slider(Slnr).value = 64 oldvel = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 120, oldvel Task(48).tog = %True END IF IF slider(slnr).value <> oldvel THEN mPlay Thunderwood.channel, 120, Slider(slnr).value oldvel = slider(slnr).value END IF END SUB SUB TW_Red () ' velocity byte steers the flashing speed STATIC oldvel AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(49).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(49).hParam = %Null THEN MakeTaskParameterDialog 49,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(49).SliderNumbers(0) Slider(Slnr).value = 64 oldvel = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 121, oldvel Task(49).tog = %True END IF IF slider(slnr).value <> oldvel THEN mPlay Thunderwood.channel, 121, Slider(slnr).value oldvel = slider(slnr).value END IF END SUB SUB TW_Yellow () ' velocity byte steers the flashing speed STATIC oldvel AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(50).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(50).hParam = %Null THEN MakeTaskParameterDialog 50,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(50).SliderNumbers(0) Slider(Slnr).value = 64 oldvel = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 122, oldvel Task(50).tog = %True END IF IF slider(slnr).value <> oldvel THEN mPlay Thunderwood.channel, 122, Slider(slnr).value oldvel = slider(slnr).value END IF END SUB SUB TW_Amber () ' velocity byte steers the flashing speed STATIC oldvel AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(51).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(51).hParam = %Null THEN MakeTaskParameterDialog 51,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(51).SliderNumbers(0) Slider(Slnr).value = 64 oldvel = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 123, oldvel Task(51).tog = %True END IF IF slider(slnr).value <> oldvel THEN mPlay Thunderwood.channel, 123, Slider(slnr).value oldvel = slider(slnr).value END IF END SUB SUB TW_NC () ' velocity byte steers the flashing speed STATIC oldvel AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(52).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(52).hParam = %Null THEN MakeTaskParameterDialog 52,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(52).SliderNumbers(0) Slider(Slnr).value = 64 oldvel = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 124, oldvel Task(52).tog = %True END IF IF slider(slnr).value <> oldvel THEN mPlay Thunderwood.channel, 124, Slider(slnr).value oldvel = slider(slnr).value END IF END SUB SUB TW_Blue () ' velocity byte steers the flashing speed STATIC oldvel AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(53).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(53).hParam = %Null THEN MakeTaskParameterDialog 53,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(53).SliderNumbers(0) Slider(Slnr).value = 64 oldvel = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 125, oldvel Task(53).tog = %True END IF IF slider(slnr).value <> oldvel THEN mPlay Thunderwood.channel, 125, Slider(slnr).value oldvel = slider(slnr).value END IF END SUB SUB TW_Green_Strip () ' tested o.k. 03.06.2017 STATIC cnt AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(54).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(54).hParam = %Null THEN MakeTaskParameterDialog 54,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(54).SliderNumbers(0) Slider(Slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 126, 127 Task(54).tog = %True END IF IF cnt THEN mPlay Thunderwood.channel, 126, 127 ELSE NoteOff Thunderwood.channel, 126 END IF INCR cnt cnt = cnt MOD 2 Task(54).freq = slider(slnr).value / 16 END SUB SUB TW_White () ' white LED's on the upper-backside ' tested o.k. gwr 04.06.2017 STATIC cnt AS BYTE STATIC slnr AS DWORD IF ISFALSE Task(55).tog THEN DIM TaskParamLabels(0) AS ASCIIZ*8 TaskParamLabels(0) = "Speed" IF Task(55).hParam = %Null THEN MakeTaskParameterDialog 55,1, Slider(),0,UdCtrl(), TaskParamLabels() END IF slnr = TaskEX(55).SliderNumbers(0) Slider(Slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value mPlay Thunderwood.channel, 127, 127 Task(55).tog = %True END IF IF cnt THEN mPlay Thunderwood.channel, 127, 127 ELSE NoteOff Thunderwood.channel, 127 END IF INCR cnt cnt = cnt MOD 2 Task(55).freq = slider(slnr).value / 16 END SUB 'SUB ThunderOff () ' LOCAL i AS LONG ' FOR i = %twtst + 10 TO %twtst + 14 ' StopTask i ' NEXT 'END SUB '[EOF] _ _ _