' ****************************************** ' * & * ' * test and evaluation code * ' ****************************************** ' 18.04.2005: first coding. ' 01.06.2005: Vacca technically ready. Test code written. ' 02.06.2005: debug session ' 11.06.2005: measurements ' 12.06.2005: data file updated with new measurements for PIC version 1.0 ' 12.06.2005: new PIC's programmed with firmware version 2.0. .DAT file adapted. ' measurements to be taken up again. Minima too large now. ' 10.07.2005: new PIC's programmed with firmware version 3.0 ' 11.07.2005: prog.change implemented for different velo scalings. ' 16.07.2005: sysex. to be implemented in g_mm.inc ' 17.07.2005: function PlayVacca added to g_mm.inc ' 25.01.2006: sysx support added - program 122 should now be default for new vacca pieces! ' 15.04.2006: Support for added. ' 23.04.2006: 'Koetjes en Kalfjes' demo stukje voor Vacca en Vitello ' 17.12.2006: Lampjes tests toegevoegd voor Vitello ' 22.02.2007: Pitchmap test toegevoegd. ' 13.12.2007: some minor bugs cleaned up. ' 27.12.2008: debug session on vitello lites. Procs added. ' 29.10.2013: Ctrl.66 implemented on Vacca, as well as lights. ' g_mm.inc updated as well with functions for Vacca. %Pitchmap_Test = 1 'was 0, which overwrote the syssex task!! %Vacca_Rep = 32 ' repetition test with rescaling %Vacca_Scale = 33 ' rescaled %Vacca_Remap = 34 ' with pitch mapping function %Vacca_Changes = 48 ' rescaled %Vacca_Object = 49 ' re-added gwr 06.09.2005 %RM_CHILL = 51 'musique d'ameublement voor vacca, tubi, ake en harma %KoeKalf = 53 ' was 59 ' demo stukje vacca en vitello %Vitello_Yellow = 59 %Vitello_Red = 60 %Vitello_Lites = 61 %Vitello_Test = 62 ' hardware test %Vacca_Test = 63 ' hardware test - no rescaling: for firmware evaluation purposes %Vitello_12 = 16 %Vitello_13 = 17 %Vitello_14 = 18 %Vitello_15 = 19 %Vitello_16 = 20 %Vitello_17 = 21 %Vitello_18 = 22 ' new 29.10.2013: test code for Vacca Lights. %Vacca_LedStrip = 24 ' note 24 %Vacca_LR = 25 ' notes 25,26 %Vacca_Front = 26 ' note 27 %Vacca_Back = 27 ' note 28 %Vacca_PW1 = 28 ' note 29 green %Vacca_PW2 = 29 ' note 30 green %Vacca_Green = 30 #INCLUDE "demos\clapping.inc" TYPE KompositieObjekt DWORD duur AS DWORD ' in ms END TYPE DECLARE FUNCTION Init_Vacca () AS LONG DECLARE SUB Vacca_Rep () DECLARE SUB Vacca_Note_UD1 () DECLARE SUB Vacca_Test () ' test for hardware velo scaling and repetition rate DECLARE SUB Vitello_Test () DECLARE SUB Vitello_Lites () DECLARE SUB Vitello_Red () DECLARE SUB Vitello_Yellow () DECLARE SUB VacVit () DECLARE SUB Vacca_HWNote_UD1 () DECLARE SUB Vacca_Scale () ' scale test DECLARE SUB Vacca_LoLim_UD1 () DECLARE SUB Vacca_LoLim_UD1 () DECLARE SUB Vacca_Changes () DECLARE SUB Vacca_Poly_UD1 () DECLARE SUB Vacca_Object () ' 14.06.2005 - gwr DECLARE SUB Vacca_Remap () ' test for the PlayVacca function DECLARE SUB Vacca_LoLimRM_UD1 () DECLARE SUB Vacca_HiLimRM_UD2 () DECLARE SUB Vacca_CentsRM_UD3 () DECLARE SUB Vacca_dbg () 'TEMP! DECLARE SUB Vitello_12 () DECLARE SUB Vitello_13 () DECLARE SUB Vitello_14 () DECLARE SUB Vitello_15 () DECLARE SUB Vitello_16 () DECLARE SUB Vitello_17 () DECLARE SUB Vitello_18 () DECLARE SUB Vacca_LedStrip () ' 29.11.2013 gwr DECLARE SUB Vacca_LR () DECLARE SUB Vacca_Front () DECLARE SUB Vacca_Back () DECLARE SUB Vacca_PW1 () ' green DECLARE SUB Vacca_PW2 () ' green FUNCTION Init_Vacca () AS LONG LOCAL retval AS LONG LOCAL m AS ASCIIZ * 20 Progchange Vacca.channel, 122 warning "set Vacca to patch 122" 'MM_Vitello_On ' remapped tests: Task(%Vacca_Rep).naam = "Vacca" Task(%Vacca_Rep).cptr = CODEPTR(Vacca_Rep) Task(%Vacca_Rep).freq = 2 Task(%Vacca_Rep).flags = %False Task(%Vacca_Scale).naam = "Scales" Task(%Vacca_Scale).cptr = CODEPTR(Vacca_Scale) Task(%Vacca_Scale).freq = 2 Task(%Vacca_Scale).flags = %False Task(%Vacca_Remap).naam = "RM-scale" Task(%Vacca_Remap).cptr = CODEPTR(Vacca_Remap) Task(%Vacca_Remap).freq = 2 Task(%Vacca_Remap).flags = %False Task(%Vacca_Changes).naam = "Changes" Task(%Vacca_Changes).cptr = CODEPTR(Vacca_Changes) Task(%Vacca_Changes).freq = 8 Task(%Vacca_Changes).flags = %False Task(%RM_Chill).naam = "ruemling" Task(%RM_Chill).freq = 1 Task(%RM_Chill).cptr = CODEPTR(RM_Chill) Task(%RM_Chill).flags = 0 TaskEx(%RM_Chill).stopcptr = CODEPTR(MM_Ake_Off) ' Vacca-0bject - GWR kompos module - 14.06.2005 Task(%Vacca_Object).naam = "VaccaObj" Task(%Vacca_Object).cptr = CODEPTR(Vacca_Object) Task(%Vacca_Object).freq = 8 Task(%Vacca_Object).flags = %False TaskEX(%Vacca_Object).Startcptr = CODEPTR(MM_Vacca_On) ' hardware tests: Task(%Vacca_Test).naam = "Vacc_Tst" Task(%Vacca_test).cptr = CODEPTR(Vacca_Test) Task(%Vacca_Test).freq = 2 Task(%Vacca_Test).flags = %False Task(%Vitello_Test).naam = "Vite_Tst" Task(%Vitello_test).cptr = CODEPTR(Vitello_Test) Task(%Vitello_Test).freq = 2 Task(%Vitello_Test).flags = %False TaskEX(%Vitello_Test).startCptr = CODEPTR(MM_Vitello_On) TaskEX(%Vitello_Test).stopCptr = CODEPTR(MM_Vitello_Off) Task(%Vitello_Lites).naam = "ViteLite" Task(%Vitello_Lites).cptr = CODEPTR(Vitello_Lites) Task(%Vitello_Lites).freq = 2 Task(%Vitello_Lites).flags = %False Task(%Vitello_Red).naam = "ViteRed" Task(%Vitello_Red).cptr = CODEPTR(Vitello_Red) Task(%Vitello_Red).freq = 3 Task(%Vitello_Red).flags = %False Task(%Vitello_Yellow).naam = "ViteYel" Task(%Vitello_Yellow).cptr = CODEPTR(Vitello_Yellow) Task(%Vitello_Yellow).freq = 4 Task(%Vitello_Yellow).flags = %False Task(%KoeKalf).naam = "KoeKalf" Task(%Koekalf).cptr = CODEPTR(VacVit) Task(%Koekalf).freq = 4 Task(%Koekalf).flags = %False TaskEX(%Koekalf).startCptr = CODEPTR(MM_Vitello_On) TaskEX(%Koekalf).stopCptr = CODEPTR(MM_Vitello_Off) Task(%MM_SysxTask).naam = "SendSysx" Task(%MM_SysxTask).freq = .33 Task(%MM_SysxTask).cptr = CODEPTR(MM_Sysx) 'in m_robots.inc Task(%Pitchmap_test).naam = "PitMap" ' in pitchmap.inc Task(%Pitchmap_test).freq = 10 Task(%Pitchmap_test).cptr = CODEPTR(Pitchmap_test) Task(%Vitello_12).naam = "Vit12" Task(%Vitello_12).cptr =CODEPTR(Vitello_12) Task(%Vitello_12).freq = 2 Task(%Vitello_13).naam = "Vit13" Task(%Vitello_13).cptr =CODEPTR(Vitello_13) Task(%Vitello_13).freq = 2.1 Task(%Vitello_14).naam = "Vit14" Task(%Vitello_14).cptr =CODEPTR(Vitello_14) Task(%Vitello_14).freq = 2.2 Task(%Vitello_15).naam = "Vit15" Task(%Vitello_15).cptr =CODEPTR(Vitello_15) Task(%Vitello_15).freq = 2.3 Task(%Vitello_16).naam = "Vit16" Task(%Vitello_16).cptr =CODEPTR(Vitello_16) Task(%Vitello_16).freq = 2.4 Task(%Vitello_17).naam = "Vit17" Task(%Vitello_17).cptr =CODEPTR(Vitello_17) Task(%Vitello_17).freq = 2.5 Task(%Vitello_18).naam = "Vit18" Task(%Vitello_18).cptr =CODEPTR(Vitello_18) Task(%Vitello_18).freq = 2.6 Task(%Vacca_LedStrip).naam = "Vac24" Task(%Vacca_LedStrip).cptr =CODEPTR(Vacca_LedStrip) Task(%Vacca_LedStrip).freq = 1 Task(%Vacca_LR).naam = "Vac2526" Task(%Vacca_LR).cptr =CODEPTR(Vacca_LR) Task(%Vacca_LR).freq = 1 Task(%Vacca_Front).naam = "Vac27" Task(%Vacca_Front).cptr =CODEPTR(Vacca_Front) Task(%Vacca_Front).freq = 1 Task(%Vacca_Back).naam = "Vac28" Task(%Vacca_Back).cptr =CODEPTR(Vacca_Back) Task(%Vacca_Back).freq = 1 Task(%Vacca_PW1).naam = "Vac29" Task(%Vacca_PW1).cptr =CODEPTR(Vacca_PW1) Task(%Vacca_PW1).freq = 1 Task(%Vacca_PW2).naam = "Vac30" Task(%Vacca_PW2).cptr =CODEPTR(Vacca_PW2) Task(%Vacca_PW2).freq = 1 Task(%Vacca_Green).naam = "Green" Task(%Vacca_Green).cptr =CODEPTR(Vacca_Green) Task(%Vacca_Green).freq = 10 TaskEX(%Vacca_Green).StopCptr = CODEPTR(Vacca_Green_Off) MM_Vacca_On Clapping_Music_Init m = "& testkode" Sendmessage gh.Cockpit, %WM_SETTEXT,0, VARPTR(m) FUNCTION = %True END FUNCTION SUB Vacca_Rep () ' test note repeats with rescaled velo's STATIC note AS INTEGER LOCAL velo AS INTEGER LOCAL v AS SINGLE STATIC slnr AS DWORD STATIC udnr AS DWORD IF ISFALSE Task(%Vacca_Rep).tog THEN DIM TaskParamLabels(0 TO 2) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" TaskParamLabels(2) = "Note" IF ISFALSE Task(%Vacca_rep).hParam THEN slnr = %False MakeTaskParameterDialog %Vacca_Rep,2,Slider(),1,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Vacca_Rep).SliderNumbers(0) UDctrl(TaskEX(%Vacca_rep).UpdownNumbers(0)).cptr = CODEPTR(Vacca_Note_UD1) ' note UDctrl(TaskEX(%Vacca_rep).UpDownNumbers(0)).value = Vacca.lowtes Task(%Vacca_rep).freq = 2 Slider(slnr).value = Task(%Vacca_rep).freq SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 4 ' low level on init. udnr = TaskEX(%Vacca_rep).UpDownNumbers(0) END IF Task(%Vacca_rep).tog = %True END IF note = UDctrl(udnr).value v = Slider(slnr+1).value / 128.0 ' normalized 0-1 ' rescaling: IF v THEN velo = VaccaNotes(note).minvel + ((VaccaNotes(note).maxvel - VaccaNotes(note).minvel) * v) mPlay Vacca.channel, note, velo END IF SetDlgItemText gh.Cockpit,%GMT_MSG1, "Pitch=" & STR$(VaccaNotes(note).nf) Task(%Vacca_Rep).freq = (Slider(slnr).value) / 4! END SUB SUB Vacca_Note_UD1 () ' controls the repetition note to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Rep).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < Vacca.lowtes THEN UDctrl(udnr).value = Vacca.lowtes : noot = Vacca.lowtes IF noot > Vacca.hightes THEN UDctrl(udnr).value = Vacca.hightes : noot = Vacca.hightes SetDlgItemText Task(%Vacca_Rep).hparam, %GMT_TEXT0_ID + 16, "N=" & STR$(noot) END SUB SUB Vacca_Scale () ' test tone-scale in order of hardware STATIC slnr AS DWORD STATIC i AS INTEGER LOCAL velo AS INTEGER LOCAL v AS SINGLE IF ISFALSE Task(%Vacca_Scale).tog THEN DIM TaskParamLabels(0 TO 3) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" TaskParamLabels(2) = "LowLim" TaskParamLabels(3) = "HiLim" IF ISFALSE Task(%Vacca_Scale).hParam THEN slnr = %False MakeTaskParameterDialog %Vacca_Scale,2,Slider(),2,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Vacca_Scale).SliderNumbers(0) UDctrl(TaskEX(%Vacca_Scale).UpdownNumbers(0)).cptr = CODEPTR(Vacca_LoLim_UD1) ' lowest note UDctrl(TaskEX(%Vacca_Scale).UpdownNumbers(1)).cptr = CODEPTR(Vacca_HiLim_UD2) ' highest note UDctrl(TaskEX(%Vacca_Scale).UpDownNumbers(0)).value = Vacca.lowtes UDctrl(TaskEX(%Vacca_Scale).UpDownNumbers(1)).value = Vacca.hightes i = Vacca.lowtes ' =UDctrl(TaskEX(%Vacca_Scale).UpDownNumbers(0)).value Task(%Vacca_Scale).freq = 2 Slider(slnr).value = Task(%Vacca_Scale).freq SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 4 ' low level on init. END IF Task(%Vacca_Scale).tog = %True END IF v = slider(slnr+1).value / 128! IF v THEN velo = VaccaNotes(i).minvel + ((VaccaNotes(i).maxvel - VaccaNotes(i).minvel) * v) mPlay Vacca.channel, i, velo END IF INCR i IF i > UDctrl(TaskEX(%Vacca_Scale).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Vacca_Scale).UpDownNumbers(0)).value Task(%Vacca_Scale).freq = MAX(0.125, (Slider(slnr).value) / 4) END SUB SUB Vacca_LoLim_UD1 () ' controls the low limit of the note scale to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Scale).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < Vacca.lowtes THEN UDctrl(udnr).value = Vacca.lowtes : noot = Vacca.lowtes IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Vacca_Scale).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Vacca_HiLim_UD2 () ' controls the high limit of the note scale to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Scale).UpDownNumbers(1) noot = UDCtrl(udnr).value IF noot < UDctrl(udnr-1).value THEN UDctrl(udnr).value = UDctrl(udnr-1).value : noot = UDctrl(udnr).value IF noot > Vacca.hightes THEN UDctrl(udnr).value = Vacca.hightes : noot = Vacca.hightes SetDlgItemText Task(%Vacca_Scale).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB Vacca_Changes () STATIC cnt AS DWORD LOCAL n1 AS INTEGER LOCAL n2 AS INTEGER LOCAL n3 AS INTEGER LOCAL n4 AS INTEGER LOCAL velo AS INTEGER LOCAL v AS SINGLE STATIC slnr AS DWORD STATIC udnr AS DWORD IF ISFALSE Task(%Vacca_Changes).tog THEN DIM TaskParamLabels(0 TO 2) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" TaskParamLabels(2) = "Poly" IF ISFALSE Task(%Vacca_Changes).hParam THEN slnr = %False MakeTaskParameterDialog %Vacca_Changes,2,Slider(),1,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Vacca_Changes).SliderNumbers(0) UDctrl(TaskEX(%Vacca_Changes).UpdownNumbers(0)).cptr = CODEPTR(Vacca_Poly_UD1) UDctrl(TaskEX(%Vacca_Changes).UpDownNumbers(0)).value = 1 ' start monophonic Task(%Vacca_Changes).freq = 4 Slider(slnr).value = Task(%Vacca_Changes).freq * 4 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Slider(slnr+1).value = 4 SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 4 ' low level on init. udnr = TaskEX(%Vacca_Changes).UpDownNumbers(0) END IF Task(%Vacca_Changes).tog = %True cnt = 0 END IF v = Slider(slnr+1).value / 128! IF UDctrl(udnr).value > 0 THEN IF ISFALSE cnt MOD 2 THEN n1 = Vacca.lowtes + (RND(1) * 48) velo = VaccaNotes(n1).minvel + ((VaccaNotes(n1).maxvel - VaccaNotes(n1).minvel) * v) mPlay Vacca.channel, n1, velo END IF END IF IF UDctrl(udnr).value > 1 THEN IF ISFALSE cnt MOD 3 THEN n2 = Vacca.lowtes + (RND(1) * 48) IF n2 <> n1 THEN velo = VaccaNotes(n2).minvel + ((VaccaNotes(n2).maxvel - VaccaNotes(n2).minvel) * v) mPlay Vacca.channel, n2, velo END IF END IF END IF IF UDctrl(udnr).value > 2 THEN IF ISFALSE cnt MOD 5 THEN n3 = Vacca.lowtes + (RND(1) * 48) IF n3 <> n2 THEN IF n3 <> n1 THEN velo = VaccaNotes(n3).minvel + ((VaccaNotes(n3).maxvel - VaccaNotes(n3).minvel) * v) mPlay Vacca.channel, n3, velo END IF END IF END IF END IF IF UDctrl(udnr).value > 3 THEN IF ISFALSE cnt MOD 7 THEN n4 = Vacca.lowtes + (RND(1) * 48) IF n4 <> n2 THEN IF n4 <> n3 THEN IF n3 <> n1 THEN velo = VaccaNotes(n4).minvel + ((VaccaNotes(n4).maxvel - VaccaNotes(n4).minvel) * v) mPlay Vacca.channel, n4, velo END IF END IF END IF END IF END IF INCR cnt Task(%Vacca_Changes).freq = MAX(1, Slider(slnr).value / 4) END SUB SUB Vacca_Poly_UD1 () ' controls the number of meters and thus polyphony to be played. LOCAL poly AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Changes).UpDownNumbers(0) poly = UDCtrl(udnr).value IF poly < 1 THEN UDctrl(udnr).value = 1 : poly = 1 IF poly > 4 THEN UDctrl(udnr).value = 4 : poly = 4 SetDlgItemText Task(%Vacca_Changes).hparam, %GMT_TEXT0_ID + 16, "P=" & STR$(poly) END SUB SUB Vacca_Test () ' test note repeats - without rescaling STATIC note AS INTEGER LOCAL velo AS INTEGER STATIC slnr AS DWORD STATIC udnr AS DWORD IF ISFALSE Task(%Vacca_Test).tog THEN DIM TaskParamLabels(0 TO 2) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" TaskParamLabels(2) = "Note" IF ISFALSE Task(%Vacca_Test).hParam THEN slnr = %False MakeTaskParameterDialog %Vacca_Test,2,Slider(),1,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Vacca_Test).SliderNumbers(0) UDctrl(TaskEX(%Vacca_Test).UpdownNumbers(0)).cptr = CODEPTR(Vacca_HWNote_UD1) ' note UDctrl(TaskEX(%Vacca_Test).UpDownNumbers(0)).value = Vacca.lowtes Task(%Vacca_Test).freq = 2 Slider(slnr).value = Task(%Vacca_Test).freq SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 4 ' low level on init. udnr = TaskEX(%Vacca_Test).UpDownNumbers(0) END IF Task(%Vacca_Test).tog = %True END IF note = UDctrl(udnr).value velo = Slider(slnr+1).value ' for PIC test, so no rescaling here. mPlay Vacca.channel, note, velo Task(%Vacca_Test).freq = (Slider(slnr).value) / 4! END SUB SUB Vacca_HWNote_UD1 () ' controls the note to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Test).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < Vacca.lowtes THEN UDctrl(udnr).value = Vacca.lowtes : noot = Vacca.lowtes IF noot > Vacca.hightes THEN UDctrl(udnr).value = Vacca.hightes : noot = Vacca.hightes SetDlgItemText Task(%Vacca_Test).hparam, %GMT_TEXT0_ID + 16, "N=" & STR$(noot) END SUB SUB Vitello_Test () ' test note repeats - without rescaling STATIC note AS INTEGER LOCAL velo AS INTEGER STATIC slnr AS DWORD STATIC udnr AS DWORD IF ISFALSE Task(%Vitello_Test).tog THEN DIM TaskParamLabels(0 TO 2) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" TaskParamLabels(2) = "Note" IF ISFALSE Task(%Vitello_Test).hParam THEN slnr = %False MakeTaskParameterDialog %Vitello_Test,2,Slider(),1,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Vitello_Test).SliderNumbers(0) UDctrl(TaskEX(%Vitello_Test).UpdownNumbers(0)).cptr = CODEPTR(Vitello_HWNote_UD1) ' note UDctrl(TaskEX(%Vitello_Test).UpDownNumbers(0)).value = Vitello.lowtes Task(%Vitello_Test).freq = 2 Slider(slnr).value = Task(%Vitello_Test).freq SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 4 ' low level on init. udnr = TaskEX(%Vitello_Test).UpDownNumbers(0) END IF 'Controller Vitello.channel, 66, 127 - done using task startcptr to MM_Vitello_On Task(%Vitello_Test).tog = %True END IF note = UDctrl(udnr).value velo = Slider(slnr+1).value ' for PIC test, so no rescaling here. mPlay Vitello.channel, note, velo Task(%Vitello_Test).freq = (Slider(slnr).value) / 4! END SUB SUB Vitello_HWNote_UD1 () ' controls the note to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vitello_Test).UpDownNumbers(0) noot = UDCtrl(udnr).value IF (noot < Vitello.lowtes) AND (noot > 48) THEN UDctrl(udnr).value = 47: noot = 47 ELSEIF noot = 48 THEN UDctrl(udnr).value = vitello.lowtes: noot = vitello.lowtes ELSEIF (noot < 44) THEN UDctrl(udnr).value = 44: noot = 44 END IF IF noot > Vitello.hightes THEN UDctrl(udnr).value = Vitello.hightes : noot = Vitello.hightes SetDlgItemText Task(%Vitello_Test).hparam, %GMT_TEXT0_ID + 16, "N=" & STR$(noot) END SUB SUB Vitello_Lites () STATIC cnt AS LONG IF ISFALSE Task(%Vitello_Lites).tog THEN cnt = 12 Task(%Vitello_Lites).freq = 2 Task(%Vitello_Lites).tog = %True END IF MM_Vitello_Off %MM_Lights SELECT CASE cnt CASE 12 mPlay Vitello.channel, 12, 127 CASE 13 mPlay Vitello.channel, 13, 127 CASE 14 mPlay Vitello.channel, 14, 127 CASE 15 mPlay Vitello.channel, 15, 127 CASE 16 mPlay Vitello.channel, 16, 127 CASE 17 mPlay Vitello.channel, 17, 127 CASE 18 mPlay Vitello.channel, 18, 127 END SELECT INCR cnt IF cnt > 18 THEN cnt = 12 END SUB SUB Vitello_Red () STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN MM_Vitello_On %MM_Red ' mPlay Vitello.channel, 12, 127 ' mPlay Vitello.channel, 13, 127 ' mPlay Vitello.channel, 14, 127 ELSE MM_Vitello_Off %MM_Red ' NoteOff Vitello.channel, 12 ' NoteOff Vitello.channel, 13 ' NoteOff Vitello.channel, 14 END IF INCR cnt END SUB SUB Vitello_Yellow () STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN MM_Vitello_On %MM_Yellow 'mPlay Vitello.channel, 15, 127 'mPlay Vitello.channel, 16, 127 'mPlay Vitello.channel, 17, 127 'mPlay Vitello.channel, 18, 127 ELSE MM_Vitello_Off %MM_Yellow 'NoteOff Vitello.channel, 15 'NoteOff Vitello.channel, 16 'NoteOff Vitello.channel, 17 'NoteOff Vitello.channel, 18 END IF INCR cnt END SUB SUB Vacca_Object () ' algoritmic composition code module without user interaction. ' "An object for Vacca" ' duration now is 3'26" STATIC cnt AS DWORD ' tick counter STATIC t0 AS DWORD ' starttime STATIC poly AS DWORD ' metric polyphony STATIC dimcnt AS DWORD ' diminuendo divider at ending LOCAL v AS SINGLE ' normalized velocity 0-1 LOCAL velo AS INTEGER ' bell dependent velocity after rescaling STATIC n1 AS INTEGER STATIC n2 AS INTEGER STATIC n3 AS INTEGER STATIC n4 AS INTEGER STATIC n5 AS INTEGER STATIC endtog AS DWORD IF ISFALSE Task(%Vacca_Object).tog THEN poly = 1 t0 = timegettime cnt = 1 '0 Task(%Vacca_Object).level = 10 Task(%Vacca_Object).freq = 4 mPlay Vacca.channel, Vacca.lowtes,64 n1 = Vacca.hightes n2 = Vacca.hightes - 6 n3 = n2 - 6 n4 = n3 - 6 n5 = n4 - 6 dimcnt = 2 endtog = %False ' test boundaries of lookup: IF UBOUND(VaccaNotes) < Vacca.hightes THEN stoptask %Vacca_Object Warning "VaccaNotes array dimension problem",5000 EXIT SUB ELSE Task(%Vacca_Object).tog = %True END IF END IF SELECT CASE poly CASE 1 IF Task(%Vacca_Object).level < 30 THEN INCR Task(%Vacca_Object).level END IF CASE 2 IF task(%Vacca_Object).level < 40 THEN INCR Task(%Vacca_Object).level END IF CASE 3 IF Task(%Vacca_Object).level < 50 THEN INCR Task(%Vacca_Object).level END IF CASE 4 IF Task(%Vacca_Object).level < 60 THEN INCR Task(%Vacca_Object).level END IF CASE 5 IF Task(%Vacca_Object).level < 100 THEN INCR Task(%Vacca_Object).level END IF CASE ELSE ' do not change - once it becomes 6, amplitude ctrl is under algo control END SELECT v = Task(%Vacca_Object).level / 128! IF poly > 0 THEN IF ISFALSE cnt MOD 2 THEN SELECT CASE poly CASE 1 n1 = Vacca.lowtes + (RND(1) * 47) CASE 2 n1 = Vacca.lowtes + 8 + (RND(1) * 39) CASE 3 n1 = Vacca.lowtes + 16 + (RND(1) *31) CASE 4 n1 = Vacca.lowtes + 24 + (RND(1) * 23) CASE ELSE n1 = Vacca.lowtes + 31 + (RND(1) * 16) END SELECT ' n1 = Vacca.lowtes + poly + (RND(1) * (48-poly)) '((poly-1) * 4)+ (RND(1) * (48 - ((poly-1)*4))) IF n1 > Vacca.hightes THEN n1 = Vacca.hightes velo = VaccaNotes(n1).minvel + ((VaccaNotes(n1).maxvel - VaccaNotes(n1).minvel) * v) ' IF n1 < Vacca.lowtes THEN Warning "n1=" & STR$(n1),5000 mPlay Vacca.channel, n1, velo END IF END IF IF poly > 1 THEN IF ISFALSE cnt MOD 3 THEN DO n2 = Vacca.lowtes + poly + (RND(1) * (47!-poly)) '((poly-1) * 3) + (RND(1) * 48) '(RND(1) * (48 -((poly-1)*3) )) LOOP UNTIL (n2 < n1) AND ((n1-n2) =< 12) 'IF n1-n2 > 12 THEN n2 = n2 + 12 IF n2 < Vacca.lowtes OR n2 > Vacca.hightes THEN Warning "n2=" & STR$(n2),5000 velo = VaccaNotes(n2).minvel + ((VaccaNotes(n2).maxvel - VaccaNotes(n2).minvel) * v) mPlay Vacca.channel, n2, velo END IF END IF IF poly > 2 THEN IF ISFALSE cnt MOD 5 THEN DO n3 = Vacca.lowtes + (RND(1) *47)' ((poly-1) * 2) + (RND(1) * (48-((poly-1)*2))) LOOP UNTIL (n3 < n2) AND (n2-n3 <=12) 'IF n2-n3 > 12 THEN n3 = n3-12 IF n3 < Vacca.lowtes THEN warning "n3=" & STR$(n3),5000 'IF n3 <> n2 THEN ' IF n3 <> n1 THEN velo = VaccaNotes(n3).minvel + ((VaccaNotes(n3).maxvel - VaccaNotes(n3).minvel) * v) mPlay Vacca.channel, n3, velo ' END IF 'END IF END IF END IF IF poly > 3 THEN IF ISFALSE cnt MOD 7 THEN DO n4 = Vacca.lowtes + (RND(1) *36!) '(RND(1) * (48-((poly-1)*1))) 'IF n4 = Vacca.lowtes THEN EXIT LOOP LOOP UNTIL (n4 < n3) AND (n3-n4 <=12) ' n4 <> n1 AND n4 <> n2 'AND n4 < n3 IF n4 >= Vacca.lowtes AND n4 <= Vacca.hightes THEN velo = VaccaNotes(n4).minvel + ((VaccaNotes(n4).maxvel - VaccaNotes(n4).minvel) * v) mPlay Vacca.channel, n4, velo ELSE Warning "n4 out of range", 5000 END IF END IF END IF IF poly > 4 THEN IF ISFALSE cnt MOD 8 THEN DO IF n4 > Vacca.lowtes THEN n5 = Vacca.lowtes + (RND(1) * 12!) ' low bells ELSE n5 = Vacca.lowtes + 1 EXIT LOOP END IF LOOP UNTIL n5 < n4 '(n5 <> n1) AND (n5 <> n2) 'AND (n5 <> n3) AND (n5 <> n4) velo = VaccaNotes(n5).minvel + ((VaccaNotes(n5).maxvel - VaccaNotes(n5).minvel) * v) mPlay Vacca.channel, n5, velo END IF END IF IF ISFALSE cnt MOD 210 THEN ' = 2 * 3 * 5 * 7 IF n5 <> Vacca.lowtes THEN mPlay Vacca.channel, Vacca.lowtes , VaccaNotes(Vacca.lowtes).maxvel END IF IF poly < 5 THEN Task(%Vacca_Object).Freq = 0.5 ' fermata END IF ELSE IF poly < 5 THEN Task(%Vacca_Object).freq = 4 END IF END IF IF ISFALSE cnt MOD 32 THEN IF poly < 6 THEN INCR poly ' no tempo change! ELSE ' on entry freq will be = 4 'IF Task(%Vacca_Object).freq > 39 THEN IF endtog THEN 'decrease dynamics IF ISFALSE cnt MOD dimcnt THEN DECR Task(%Vacca_Object).level SELECT CASE Task(%Vacca_Object).level 'CASE 40 ' INCR dimcnt CASE 25 INCR dimcnt CASE 20 INCR dimcnt CASE 10 INCR dimcnt CASE 5 INCR dimcnt CASE 3 INCR dimcnt CASE 0 mPlay Vacca.channel, Vacca.lowtes, VaccaNotes(Vacca.lowtes).minvel + 6 StopTask %Vacca_Object END SELECT END IF ' small ritardando: Task(%Vacca_Object).freq = Task(%Vacca_Object).freq * 0.97 IF Task(%Vacca_Object).freq < 38 THEN Task(%Vacca_Object).freq = 38 ELSE ' accellerando: (vanzodra poly >= 6) Task(%Vacca_Object).freq = Task(%Vacca_Object).freq * 1.15 IF Task(%Vacca_Object).level > 70 THEN DECR Task(%Vacca_Object).level END IF IF Task(%Vacca_Object).freq > 45 THEN endtog = %True END IF END IF END IF INCR cnt END SUB SUB RM_Chill STATIC init AS LONG STATIC ins$ STATIC note AS BYTE STATIC klungshake AS LONG LOCAL b$ IF ISFALSE init THEN Controller Ake.channel, 1, 70 'redelijk stil Controller Ake.channel, 7, 0 Task(%RM_Chill).freq = .1 + RND END IF IF klungshake > 0 THEN CONTROL SET TEXT gh.cockpit, %GMT_MSg2, "shake" DECR klungshake AddNote2Har klung.har(1), note, 20 + RND * 100 InstrumTransposeToRange Klung InstrumPlay Klung IF ISFALSE KlungShake THEN task(%RM_CHILL).freq = .1 + RND CONTROL SET TEXT gh.cockpit, %GMT_MSG1, "freq:" + STR$(task(%RM_CHILL).freq) CONTROL SET TEXT gh.cockpit, %GMT_MSg2, "?" END IF EXIT SUB END IF IF ISFALSE LEN(ins$) THEN ins$ = "vatk" note = Ake.LowTes + RND * (Ake.HighTes - Ake.LowTes) END IF b$ = MID$(ins$, INT(1 + RND * LEN(ins$)), 1) ins$=REMOVE$(ins$, b$) CONTROL SET TEXT gh.cockpit, %GMT_MSg2, b$ SELECT CASE b$ CASE "v" IF ISFALSE PlayVacca (note, RND * 20, 100) THEN 'if we can't mPlay the right note, we mPlay the direct mapping warning "playvacca refused " + STR$(note) AddNote2Har Vacca.Har(1), note, 20 + RND * 100 InstrumTransposeToRange Vacca END IF InstrumPlay Vacca InstrumPlay Ake CASE "a" AddNote2Har Ake.har(1), note, 64 InstrumPlay Ake CASE "t" IF RND < .5 THEN AddNote2Har Tubi.har(1), note + 12, 20 + RND * 100 ELSE AddNote2Har Tubi.har(1), note-36, 20 + RND * 100 END IF InstrumTransposeToRange Tubi InstrumPlay Tubi InstrumPlay Ake CASE "k" IF ISFALSE klungshake THEN klungshake = 2 task(%RM_CHILL).freq = 10 + RND * 10 END IF AddNote2Har Klung.har(1), note, 20 + RND * 100 InstrumTransposeToRange Klung InstrumPlay Klung InstrumPlay Ake CASE ELSE warning "error in " + FUNCNAME$ + "b$=" + b$ + " ins$=" + ins$ + " mid=" + STR$(1 + RND(0) * LEN(ins$)) END SELECT IF ISFALSE klungshake THEN task(%RM_CHILL).freq = .1 + RND CONTROL SET TEXT gh.cockpit, %GMT_MSG1, "freq:" + STR$(task(%RM_CHILL).freq) END SUB SUB Vacca_Object_Start () Task(%Vacca_Object).duur = 210 ' in s Task(%Vacca_Object).tempo = 120 ' MM END SUB SUB Vacca_Remap () ' test tone-scale with remapping of pitches. STATIC slnr AS DWORD STATIC i AS INTEGER LOCAL velo AS INTEGER LOCAL mn AS DWORD IF ISFALSE Task(%Vacca_Remap).tog THEN DIM TaskParamLabels(0 TO 4) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" TaskParamLabels(2) = "LowLim" TaskParamLabels(3) = "HiLim" TaskParamLabels(4) = "tol" ' tollerance in cents. IF ISFALSE Task(%Vacca_Remap).hParam THEN slnr = %False MakeTaskParameterDialog %Vacca_Remap,2,Slider(),3,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Vacca_Remap).SliderNumbers(0) UDctrl(TaskEX(%Vacca_Remap).UpdownNumbers(0)).cptr = CODEPTR(Vacca_LoLimRM_UD1) ' lowest note UDctrl(TaskEX(%Vacca_Remap).UpdownNumbers(1)).cptr = CODEPTR(Vacca_HiLimRM_UD2) ' highest note UDctrl(TaskEX(%Vacca_Remap).UpdownNumbers(2)).cptr = CODEPTR(Vacca_CentsRM_UD3) UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(0)).value = 45 UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(1)).value = 88 UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(2)).value = 20 i = 45 ' =UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(0)).value Task(%Vacca_Remap).freq = 2 Slider(slnr).value = Task(%Vacca_Remap).freq SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 4 ' low level on init. END IF Task(%Vacca_Remap).tog = %True END IF IF slider(slnr+1).value THEN velo = slider(slnr+1).value mn = PlayVacca (i, velo, UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(2)).value) CONTROL SET TEXT gh.cockpit, %GMT_MSG1, STR$(i) + STR$(mn) ' if ms = false, no bell was found. END IF INCR i IF i > UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Vacca_Remap).UpDownNumbers(0)).value Task(%Vacca_Remap).freq = (Slider(slnr).value) / 4 END SUB SUB Vacca_LoLimRM_UD1 () ' controls the low limit of the note scale to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Remap).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < 45 THEN UDctrl(udnr).value = 45 : noot = 45 IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Vacca_Remap).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Vacca_HiLimRM_UD2 () ' controls the high limit of the note scale to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Remap).UpDownNumbers(1) noot = UDCtrl(udnr).value IF noot < UDctrl(udnr-1).value THEN UDctrl(udnr).value = UDctrl(udnr-1).value : noot = UDctrl(udnr).value IF noot > 88 THEN UDctrl(udnr).value = 88 : noot = 88 SetDlgItemText Task(%Vacca_Remap).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB Vacca_CentsRM_UD3 () ' controls the allowable cent deviation for the scale requested. LOCAL cent AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Vacca_Remap).UpDownNumbers(2) cent = UDCtrl(udnr).value IF cent < 0 THEN UDctrl(udnr).value = 0 : cent = 0 IF cent > 100 THEN UDctrl(udnr).value = 100 : cent = 100 SetDlgItemText Task(%Vacca_Remap).hparam, %GMT_TEXT0_ID + 18, "tol" & STR$(cent) END SUB SUB VacVit () ' 'Koetjes en Kalfjes' een demo stukje voor en - gwr ' harmonische samenhang nog uit te werken! ' %KoeKalf STATIC cnt AS LONG STATIC t0 AS DWORD STATIC slnr AS DWORD LOCAL v1,v2,v3 AS BYTE LOCAL n1,n2,n3 AS BYTE IF ISFALSE Task(%Koekalf).tog THEN DIM TaskParamLabels(0 TO 1) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" MM_Vacca_On IF ISFALSE Task(%Koekalf).hParam THEN slnr = %False MakeTaskParameterDialog %Koekalf,2,Slider(),0,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Koekalf).SliderNumbers(0) Task(%Koekalf).freq = 4 Slider(slnr).value = Task(%Koekalf).freq * 8 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Task(%Koekalf).level = 10 Slider(slnr+1).value = 10 SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Task(%Koekalf).level ' low level on init. END IF t0 = timegettime cnt = 1 '0 mPlay Vacca.channel, Vacca.lowtes,64 mPlay Vitello.channel, Vitello.lowtes, 64 ' n1 = Vacca.hightes ' n2 = Vacca.hightes - 6 ' n3 = n2 - 6 ' n4 = n3 - 6 ' n5 = n4 - 6 'dimcnt = 2 'endtog = %False ' test boundaries of lookup: IF UBOUND(VaccaNotes) < Vacca.hightes THEN stoptask %Koekalf Warning "VaccaNotes array dimension problem",5000 EXIT SUB ELSE Task(%Koekalf).tog = %True END IF END IF Task(%Koekalf).level = Slider(slnr+1).value IF ISFALSE cnt MOD 2 THEN n1= Vacca.lowtes + (RND(1) * Vacca.hightes) mPlay Vacca.channel,n1 , Task(%Koekalf).level END IF IF ISFALSE cnt MOD 3 THEN v1 = Vitello.lowtes + (RND(1) * Vitello.hightes) mPlay Vitello.channel,v1 , Task(%Koekalf).level END IF IF ISFALSE cnt MOD 4 THEN DO n2 = Vacca.lowtes + (RND(1) * 16) LOOP UNTIL n2 <> n1 mPlay Vacca.channel, n2, Task(%Koekalf).level END IF IF ISFALSE cnt MOD 6 THEN DO v2 = Vitello.lowtes + (RND(1) * 16) LOOP UNTIL v2 <> v1 mPlay Vitello.channel,v2, Task(%Koekalf).level END IF IF ISFALSE cnt MOD 8 THEN DO n3 = Vacca.lowtes + (RND(1) * 8) LOOP UNTIL (n3 <> n1) AND (n3 <> n2) mPlay Vacca.channel, n3, Task(%Koekalf).level END IF IF ISFALSE cnt MOD 9 THEN DO v3 = Vitello.lowtes + (RND(1) * 8) LOOP UNTIL (v3 <> v1) AND (v3 <> v2) mPlay Vitello.channel,v3 , Task(%Koekalf).level END IF 'lites IF ISFALSE cnt MOD 12 THEN mPlay Vitello.channel, 12 + (RND(1)* 8), 127 END IF IF ISFALSE cnt MOD 32 THEN MM_Vitello_Off %MM_Lights END IF INCR cnt Task(%Koekalf).freq = MAX(Slider(slnr).value,1) / 8.0 END SUB SUB Vitello_12 () ' rood frontaal 12V led spotje STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 12, 127 ELSE Noteoff Vitello.channel, 12 END IF INCR cnt END SUB SUB Vitello_13 () ' rood licht lampjes zijkanten vooraan STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 13, 127 ELSE Noteoff Vitello.channel, 13 END IF INCR cnt END SUB SUB Vitello_14 () ' rood licht lampjes zijkanten achteraan STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 14, 127 ELSE Noteoff Vitello.channel, 14 END IF INCR cnt END SUB SUB Vitello_15 () ' centraal onderaan gele LED spot naar achter gericht STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 15, 127 ELSE Noteoff Vitello.channel, 15 END IF INCR cnt END SUB SUB Vitello_16 () ' centraal onderaan gele LED spot naar voor gericht STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 16, 127 ELSE Noteoff Vitello.channel, 16 END IF INCR cnt END SUB SUB Vitello_17 () STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 17, 127 ELSE Noteoff Vitello.channel, 17 END IF INCR cnt END SUB SUB Vitello_18 () STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vitello.channel, 18, 127 ELSE Noteoff Vitello.channel, 18 END IF INCR cnt END SUB SUB Vacca_LedStrip () STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vacca.channel, 24, RND(120,127) '124 '7 ELSE Noteoff Vacca.channel, 24 END IF INCR cnt END SUB SUB Vacca_LR () STATIC cnt AS DWORD SELECT CASE cnt MOD 2 CASE 0 mPlay Vacca.channel, 25, RND(120,127) '125 ' 127 NoteOff Vacca.channel, 26 CASE 1 mPlay Vacca.channel, 26, RND(120,127) '125 ' 127 NoteOff Vacca.channel,25 END SELECT INCR cnt END SUB SUB Vacca_Front () STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vacca.channel, 27, RND(120,127) ELSE Noteoff Vacca.channel, 27 END IF INCR cnt END SUB SUB Vacca_Back () ' tungsten 12V/3W STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vacca.channel, 28, RND(120,127) '124 '7 ELSE Noteoff Vacca.channel, 28 END IF INCR cnt END SUB SUB Vacca_PW1 () 'green STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vacca.channel, 29, RND(1,127) ELSE Noteoff Vacca.channel, 29 END IF INCR cnt END SUB SUB Vacca_PW2 () 'green STATIC cnt AS DWORD IF ISFALSE cnt MOD 2 THEN mPlay Vacca.channel, 30, RND(1,127) ELSE Noteoff Vacca.channel, 30 END IF INCR cnt END SUB SUB Vacca_Green () IF ISFALSE Task(%Vacca_Green).tog THEN MM_Vacca_On %MM_Green Task(%Vacca_Green).tog = %True END IF END SUB SUB Vacca_Green_Off () MM_Vacca_Off %MM_Green END SUB