' ************************************************* ' * * ' * Version 2.0 - 15.08.2006 * ' ************************************************* '01.04.2002 Start coding '06.04.2002 Further work - hardware finished (electronics) ' belly type resides in g_n*h.dll. Here we use only the pointer to it! '11.04.2002 First test on Belly: Works! '12.04.2002 Mapping problems sorted out. '13.04.2002 Kloktype added. '21.04.2002 Two different but mutually exclusive listentasks implemented. One uses bellnumbers, the other tries ' to match to the requested pitch. '23.04.2002 Premiere of '01.06.2002 Belly on Zondernaamplein Gent (Tox @ W-XP - LPT) '04.06.2002 Klok 22 omgewisseld voor beter exemplaar. ' AW-USB port tested o.k. - works on Win XP. '06.12.2002 matching listentask removed. UDP listen now supported. ' controllers 4 (tollerance param) and &H44 (matching switch) implemented. '13.03.2003 strange behaviour in belly discovered with handling of controllers... '29.06.2004 Changes for the Millennium does no longer seem to run... '24.07.2004 Listentask improved with listenmask. '28.03.2005 bell changed in instrument: '09.08.2006 start rebuilding of Belly hardware... soon we will no longer need a laptop for Belly. '15.08.2006 old file renamed belly2002.inc. Now belly is a midi robot. ' all beat funnctions changed bu play functions. '17.08.2006 further adaptions to hardware changes - software shouldn't care about hardware mapping anymore! ' still to be checked when hardware's ready.. '24.08.2006: Both Pics programmed with version 1.0 software. '26.08.2006: Lites test task added. '27.08.2006: Hardware debug. '26.09.2006: checked. '22.02.2007: pitchmap test toegevoegd. %Pitchmap_test = 0 %Belly_ArpUp = 19 %Belly_ArpDown = 20 %Belly_Test = 48 %Belly_Lites = 49 ' new 2006 %Belly_Changes = 32 ' successive change ringing %Belly_Mil = 33 ' 2/3/5 changes, simultaneous %Belly_Cat = 34 %Bellies = 36 %Belly_sample = 37 'GLOBAL pBelly AS Bellytype PTR ' should not conflict with Belly declared as musician for midi-ctrl. ' we still need this one in the 2006 version. DECLARE FUNCTION Init_Belly () AS LONG 'DECLARE function InitKlokparams () as long 'to dll - still required for lookups!!! ' obsolete - gebruik GetBellyMapping in plaats voor lookups (analoog aan getvaccamapping etc ) DECLARE SUB Belly_Test () DECLARE SUB belly_ArpUp () DECLARE SUB belly_ArpDown () DECLARE SUB Bellies () DECLARE SUB Belly_Cat () DECLARE SUB Bell_Catalogue (Akk() AS INTEGER) DECLARE SUB Belly_Mil () DECLARE SUB Samplebells 'task - sample bells for DFT 'DECLARE SUB Belly_Power () ' button switch handler ctrl 66 DECLARE SUB Belly_Video () ' button switch handler ctrl 67 DECLARE SUB Belly_lites () ' light show test procedure DECLARE SUB Belly_Lites_Off () DECLARE SUB Belly_CreateHardwareMapping FUNCTION Init_Belly () AS LONG LOCAL m AS ASCIIZ * 40 LOCAL i AS DWORD LOCAL pmask AS QUAD PTR ' i = Belly_Init_Dll (gh,%False) ' to be changed ' IF ISFALSE i THEN EXIT FUNCTION ' pBelly = i ' @pBelly.pMessagehandler = CODEPTR(BellyMessageHandler) ' required in dll 'delete unecessary buttons ' ButnSW(2).tag0 = "Pow OFF" ' switches solenoid voltage on/off - now ctrl.66 'dubbel met knop in MM_Panicbuttonwindow ' ButnSW(2).tag1 = "Pow ON" ' ButnSW(2).cptr = CODEPTR(Belly_Power) ButnSW(3).tag0 = "Video OFF" ButnSW(3).tag1 = "Video ON" ButnSW(3).cptr = CODEPTR(Belly_Video) ButnSW(4).tag0 = "" ButnSW(5).tag0 = "" ButnSW(6).tag0 = "" ButnSW(7).tag0 = "" ButnSW(8).tag0 = "" ButnSW(9).tag0 = "" ButnSW(10).tag0 = "" ButnSW(11).tag0 = "" ButnOS(3).tag = "" ButnOS(4).tag = "" ButnOS(5).tag = "" ButnOS(6).tag = "" ButnOS(8).tag = "" ButnOS(9).tag = "" ' ButnOS(7).tag = "PANIC" ' m = UCASE$("Belly_AllOff") ' ButnOs(7).cptr = GetProcAddress(gh.gnh,m) Task(%Belly_test).naam = "Test" Task(%Belly_test).freq = 1 Task(%Belly_test).cptr = CODEPTR(belly_test) Task(%Belly_lites).naam = "Lites" Task(%Belly_Lites).cptr = CODEPTR(Belly_Lites) Task(%Belly_Lites).freq = 6 TaskEX(%Belly_Lites).stopcptr = CODEPTR(Belly_Lites_Off) Task(%Bellies).naam = "Bellies" Task(%Bellies).cptr = CODEPTR(bellies) Task(%Bellies).freq = 5 Task(%Belly_Changes).naam = "Changes" Task(%Belly_Changes).cptr = CODEPTR(belly_changes) Task(%Belly_Changes).freq = 2 Task(%Belly_mil).naam = "ChaMil" Task(%Belly_Mil).cptr = CODEPTR(Belly_Mil) Task(%Belly_mil).freq = 3 Task(%Belly_Cat).naam = "BelCat" Task(%Belly_Cat).cptr = CODEPTR(Belly_Cat) Task(%Belly_Cat).freq = 1 Task(%Belly_ArpUp).naam = "ArpUp" Task(%Belly_ArpUp).cptr = CODEPTR(Belly_ArpUp) Task(%Belly_ArpUp).freq = 1 Task(%Belly_ArpDown).naam = "ArpDown" Task(%Belly_ArpDown).cptr = CODEPTR(Belly_ArpDown) Task(%Belly_ArpDown).freq = 1 Task(%Belly_Sample).naam = "sample" Task(%Belly_Sample).cptr = CODEPTR(Samplebells) Task(%Belly_Sample).freq = .3 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) SetDlgItemText gh.Cockpit, %GMT_TITLE, "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR, $gwr Progchange Belly.channel, 122 warning "set Belly to patch 122" ' Belly_CreateHardwareMapping ' StartWaveInStream %true FUNCTION = %true END FUNCTION SUB Belly_Test () ' test procedure for debugging the hardware... ' used for determination of velocity range and tuning STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC udnr AS INTEGER LOCAL bel AS BYTE LOCAL velo AS BYTE IF ISFALSE Task(%Belly_test).tog THEN DIM TaskParamLabels(2) TaskParamLabels(0)="velo" ' aanslagtijd in ms - now we have 27.2 microsecond resolution TaskParamLabels(1)="speed" ' herhalingsfrekwentie TaskParamLabels(2)="klok" IF Task(%Belly_test).hParam = %Null THEN MakeTaskParameterDialog %Belly_test,2, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%Belly_test).SliderNumbers(0) udnr = TaskEX(%Belly_test).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Belly_UD_kloknummer) UDctrl(udnr).value = Belly.lowtes ' was 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 END IF 'controller belly.channel, &H44, 0 ' this makes only sense in the player context. 'warning "disabling belly pitch mapping!" ' belly itself does not listen to this conntroller. Task(%Belly_test).tog = %True EXIT SUB END IF bel = UDCtrl(udnr).value velo = slider(slnr).value IF velo THEN ' Play Belly.channel,@pBelly.Klok(bel).map, velo '!!now GMT is not aware of the hardware mapping anymore! ' just use the note Play Belly.channel, bel, velo 'Belly_Beat @pBelly.Klok(bel).map , velo END IF ' SetDlgItemText gh.Cockpit, %GMT_MSG1, "Klok(" & STR$(bel) & ") Hardware map= " & STR$(@pBelly.Klok(bel).map) & " f="& STR$(@pBelly.Klok(bel).pitch) SetDlgItemText gh.Cockpit, %GMT_MSG2, "Velocity = " & STR$(velo) & " - Speed = " & STR$(task(%Belly_test).freq) Task(%Belly_test).freq = Slider(slnr+1).value / 5 '10.0 IF Task(%Belly_test).freq < 0.2 THEN Task(%Belly_Test).freq = 0.2 IF velo THEN IF Task(%Belly_test).freq > 1000!/(velo + velo) THEN Task(%Belly_test).freq = 1000!/(velo+velo) END IF IF Task(%Belly_test).freq > 16 THEN Task(%Belly_Test).freq = 16 END SUB SUB Belly_UD_Kloknummer () ' for callback on kloknr. UpDown. LOCAL n AS BYTE n = UDCtrl(TaskEX(%belly_test).UpdownNumbers(0)).value IF n < Belly.lowtes THEN n = Belly.lowtes END IF IF n > Belly.hightes THEN n = Belly.hightes END IF 'n = n + Belly.LowTes UDCtrl(TaskEX(%belly_test).UpdownNumbers(0)).value = n SetDlgItemText Task(%belly_test).hparam, %GMT_TEXT0_ID + 16, "K=" & STR$(n) END SUB SUB Belly_Changes () LOCAL i AS DWORD LOCAL j AS DWORD LOCAL range AS BYTE LOCAL velo AS BYTE LOCAL flag AS BYTE STATIC tel AS DWORD STATIC slnr AS DWORD STATIC udnr AS DWORD IF ISFALSE Task(%belly_changes).tog THEN DIM root(3) AS STATIC INTEGER DIM cnt(3) AS STATIC DWORD DIM n(3) AS STATIC BYTE DIM TaskParamLabels(1) AS LOCAL ASCIIZ * 8 root(0) = 2 root(1) = 3 root(2) = 5 root(3) = 7 Task(%belly_changes).tog = %True TaskParamLabels(0)="velo" TaskParamLabels(1)="MM=" IF Task(%Belly_changes).hParam = %Null THEN MakeTaskParameterDialog %Belly_changes,1, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%Belly_changes).SliderNumbers(0) udnr = TaskEX(%Belly_changes).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Belly_Changes_UD) UDctrl(udnr).value = 30 Slider(slnr).value = 1 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Task(%Belly_Changes).freq = (30*4) / 60! END IF 'controller belly.channel, &H44, 0 'warning "disabling belly pitch mapping!" END IF tel = tel MOD 4 i = tel INCR cnt(i) cnt(i) = cnt(i) MOD root(i) IF ISFALSE cnt(i) THEN DO flag = %False n(i) = Belly.LowTes + RND(1) * 33! ' nrbells. FOR j = 0 TO 3 IF j <> i THEN IF n(i) = n(j) THEN flag = %True END IF NEXT j IF ISFALSE flag THEN EXIT LOOP LOOP ' nu hebben we een nieuwe klok in n(i) END IF ' Belly is a musician type now! ' range = @pBelly.Klok(n(tel)).maxvel - @pBelly.Klok(n(tel)).minvel Range = BellyNotes(n(tel)).maxvel - BellyNotes(n(tel)).minvel ' velo = @pBelly.Klok(n(tel)).minvel + (range * Slider(slnr).value / 127!) velo = BellyNotes(n(tel)).minvel + (range * Slider(slnr).value / 127) 'Belly_Beat ' Play Belly.channel, @pBelly.Klok(n(tel)).map, velo Play Belly.channel, n(tel), velo INCR tel END SUB SUB Belly_Changes_UD () ' for callback on Belly-Changes UpDown. LOCAL n AS BYTE n = UDCtrl(TaskEX(%belly_changes).UpdownNumbers(0)).value IF n < 1 THEN n = 1 END IF ' IF n > 240 THEN ' n = 240 ' END IF UDCtrl(TaskEX(%belly_changes).UpdownNumbers(0)).value = n SetDlgItemText Task(%belly_changes).hparam, %GMT_TEXT0_ID + 16, "MM=" & STR$(n*4) Task(%Belly_Changes).freq = (n*4) / 60! END SUB SUB Belly_Mil () ' changes for the millennium STATIC cnt AS DWORD STATIC slnr AS DWORD STATIC udnr AS DWORD LOCAL range AS WORD LOCAL crit AS SINGLE ' dissonance criterium LOCAL velo AS BYTE LOCAL d AS SINGLE LOCAL lusteller AS DWORD STATIC n() AS BYTE STATIC oldnote() AS BYTE 'STATIC Akk() AS INTEGER IF ISFALSE Task(%Belly_mil).tog THEN DIM n(2) AS STATIC BYTE DIM oldnote(2) AS STATIC BYTE DIM TaskParamLabels(1) AS LOCAL ASCIIZ * 8 cnt = 0 velo = 40 Task(%Belly_mil).Har.vel = STRING$(128,0) Task(%Belly_mil).tog = %True TaskParamLabels(0)="velo" TaskParamLabels(1)="MM=" IF Task(%Belly_Mil).hParam = %Null THEN MakeTaskParameterDialog %Belly_Mil,1, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%Belly_Mil).SliderNumbers(0) udnr = TaskEX(%Belly_Mil).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Belly_Mil_UD) UDctrl(udnr).value = 60 Slider(slnr).value = 6 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Task(%Belly_Mil).freq = 3 SetDlgItemText Task(%belly_mil).hparam, %GMT_TEXT0_ID + 16, "MM=" & STR$(180) END IF 'controller belly.channel, &H44, 0 'warning "disabling belly pitch mapping!" EXIT SUB END IF ' bepaal drie klokken N(0), n(1) en n(2)... velo = slider(slnr).value crit = ABS(SIN(cnt / 382)) ' so after 1200 cnt's, or at freq=3, 400", we will be round with a half sine. IF ISFALSE cnt MOD 30 THEN oldnote(0) = n(0) oldnote(1) = n(1) oldnote(2) = n(2) Task(%Belly_Mil).Har.vel = STRING$(128,0) lusteller = 0 DO DO n(0) = Belly.LowTes + 12 + (RND(1) * 20) n(1) = Belly.LowTes + 6 + (RND(1) * 18) n(2) = Belly.LowTes + RND(1) * 12 IF (n(0) <> n(1)) AND (n(1) <> n(2)) AND (n(0) <> n(2)) THEN IF (n(0) <> oldnote(0)) AND (n(0) <> oldnote(1)) AND (n(0) <> oldnote(2)) THEN IF (n(1) <> oldnote(0)) AND (n(1) <> oldnote(1)) AND (n(1) <> oldnote(2)) THEN IF (n(2) <> oldnote(0)) AND (n(2) <> oldnote(1)) AND (n(2) <> oldnote(2)) THEN EXIT DO END IF END IF END IF END IF LOOP ' Task(%Belly_Mil).har.vel = SumHar$ (@pBelly.klok(n(0)).Har, @pBelly.klok(n(1)).Har) Task(%Belly_Mil).har.vel = sumhar$(BellyNotes(n(0)).har, BellyNotes(N(1)).har) ' Task(%Belly_Mil).har.vel = SumHar$ (@pBelly.klok(n(2)).Har, Task(%Belly_Mil).har) Task(%Belly_Mil).Har.vel = SumHar$(BellyNotes(n(2)).Har, Task(%Belly_Mil).Har) ' the har-strings are the spectral data and so we can use the non spectral dissonance function ' in the new g_har.dll 'd = GetAkuDis (Task(%Belly_Mil).har) ' bug: since 2004, seems to always return 1 FillHarType Task(%Belly_Mil).Har, %use_velo ' new 20.01.2007 d = Task(%Belly_Mil).har.dis IF d =< crit THEN EXIT DO INCR lusteller IF lusteller > 1000 THEN crit = crit + 0.01 IF crit > 1 THEN crit = 1 IF crit = 1 THEN EXIT DO lusteller = %False END IF LOOP UNTIL d <= crit SetDlgItemText gh.Cockpit, %GMT_MSG1, "Klokken " & STR$(n(0)) & STR$(n(1)) & STR$(n(2)) SetDlgItemText gh.Cockpit, %GMT_MSG2, "dis = " & STR$(ROUND(d,2)) & " crit=" & STR$(ROUND(crit,2)) END IF IF n(0) < n(2) THEN SWAP n(0),n(2) IF n(0) < n(1) THEN SWAP n(0),n(1) IF n(1) < n(2) THEN SWAP n(1),n(2) IF ISFALSE cnt MOD 2 THEN ' range = @pBelly.Klok(n(0)).maxvel - @pBelly.Klok(n(0)).minvel range = BellyNotes(n(0)).maxvel - BellyNotes(n(0)).minvel ' velo = @pBelly.Klok(n(0)).minvel + (range * Slider(slnr).value / 127!) velo = BellyNotes(n(0)).minvel + (range * Slider(slnr).value / 127!) SELECT CASE (n(0) - Belly.Lowtes) CASE 4,9,12,24 ' velo = @pBelly.Klok(n(0)).minvel + (velo \16) velo = BellyNotes(n(0)).minvel + (Velo\16) END SELECT 'Belly_Beat ' Play Belly.channel, @pBelly.Klok(n(0)).map, velo Play Belly.channel, n(0), velo 'SumHar round(Klok(n(0)).nf,0),velo END IF IF ISFALSE cnt MOD 3 THEN ' range = @pBelly.Klok(n(1)).maxvel - @pBelly.Klok(n(1)).minvel range = BellyNotes(n(1)).maxvel - BellyNotes(n(1)).minvel ' velo = @pBelly.Klok(n(1)).minvel + (range * Slider(slnr).value / 127!) velo = BellyNotes(n(1)).minvel + (range * Slider(slnr).value / 127!) SELECT CASE (n(1) - Belly.LowTes) CASE 4,9,12,24 ' velo = @pBelly.Klok(n(1)).minvel + (velo \16) velo = BellyNotes(n(1)).minvel + (Velo\16) END SELECT 'Belly_Beat ' Play Belly.channel, @pBelly.Klok(n(1)).map, velo Play Belly.channel, n(1), velo END IF IF ISFALSE cnt MOD 5 THEN ' range = @pBelly.Klok(n(2)).maxvel - @pBelly.Klok(n(2)).minvel range = BellyNotes(n(2)).maxvel - BellyNotes(n(2)).minvel ' velo = @pBelly.Klok(n(2)).minvel + (range * Slider(slnr).value / 127!) velo = BellyNotes(n(2)).minvel + (range * Slider(slnr).value / 127!) SELECT CASE (n(2) - Belly.LowTes) CASE 4,9,12,24 ' velo = @pBelly.Klok(n(2)).minvel + (velo \16) velo = BellyNotes(n(2)).minvel + (Velo\16) END SELECT 'Belly_Beat ' Play Belly.channel, @pBelly.Klok(n(2)).map, velo Play Belly.channel, n(2), velo END IF INCR cnt IF cnt > 1200 THEN IF (cnt MOD 3) + (cnt MOD 5) + (cnt MOD 2) = %False THEN stoptask %Belly_Mil END IF END IF END SUB SUB Belly_Mil_UD () ' for callback on Belly-Mil UpDown. LOCAL n AS BYTE n = UDCtrl(TaskEX(%belly_mil).UpdownNumbers(0)).value IF n < 1 THEN n = 1 END IF UDCtrl(TaskEX(%belly_mil).UpdownNumbers(0)).value = n SetDlgItemText Task(%belly_mil).hparam, %GMT_TEXT0_ID + 16, "MM=" & STR$(n*3) Task(%Belly_mil).freq = (n*3) / 60! END SUB SUB Belly_Cat () LOCAL i AS LONG LOCAL j AS LONG LOCAL nr AS BYTE STATIC cnt AS LONG STATIC slnr AS DWORD STATIC udnr AS DWORD STATIC tog AS INTEGER LOCAL range AS WORD LOCAL velo AS BYTE STATIC trans AS BYTE STATIC Akk() AS INTEGER IF ISFALSE Task(%Belly_cat).tog THEN DIM TaskParamLabels(1) AS LOCAL ASCIIZ * 8 cnt = 0 velo = 40 tog = 1 trans = 0 Task(%Belly_cat).Har.vel = STRING$(128,0) Task(%Belly_cat).tog = %True TaskParamLabels(0)="velo" TaskParamLabels(1)="MM=" IF Task(%Belly_Cat).hParam = %Null THEN MakeTaskParameterDialog %Belly_Cat,1, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%Belly_Cat).SliderNumbers(0) udnr = TaskEX(%Belly_Cat).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Belly_Cat_UD) UDctrl(udnr).value = 12 Slider(slnr).value = 6 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Task(%Belly_Cat).freq = 0.2 SetDlgItemText Task(%belly_Cat).hparam, %GMT_TEXT0_ID + 16, "MM=" & STR$(12) END IF DIM Akk(0 TO &HFFF) AS STATIC INTEGER Bell_Catalogue Akk() 'controller belly.channel, &H44, 0 'warning "disabling belly pitch mapping!" EXIT SUB END IF Task(%Belly_cat).Har.vel = STRING$(128,0) ' play all those 19 triads on all possible bells... Akk(cnt) = TransChordNum (Akk(cnt), trans) trans = (trans + 5) MOD 12 AddCnr2Har Task(%Belly_Cat).Har , Akk(cnt), 68,110, Slider(slnr).value ' g_mus.dll IF tog = 1 THEN FOR j = 68 TO 108 IF IsNoteInHar (Task(%Belly_Cat).Har, j) THEN FOR i = 0 TO 33 ' IF ABS(@pBelly.Klok(i).nf - j) < 0.2 + (cnt/(UBOUND(Akk)*2)) THEN nr = i : EXIT FOR IF ABS(BellyNotes(i + Belly.LowTes).nf - j) < .2 + (cnt/(UBOUND(Akk)*2)) THEN nr = i : EXIT FOR NEXT i IF i < 34 THEN ' range = @pBelly.Klok(nr).maxvel - @pBelly.Klok(nr).minvel range = BellyNotes(nr + Belly.LowTes).maxvel - BellyNotes(nr + Belly.LowTes).minvel ' velo = @pBelly.Klok(nr).minvel + (range * Slider(slnr).value / 127!) velo = BellyNotes(nr + Belly.LowTes).minvel + (range * Slider(slnr).value / 127!) 'Belly_Beat ' Play Belly.channel @pBelly.Klok(nr).map , velo Play Belly.channel, nr + Belly.LowTes,velo END IF END IF NEXT j ELSE FOR j = 108 TO 68 STEP -1 IF IsNoteInHar (Task(%Belly_Cat).Har, j) THEN FOR i = 33 TO 0 STEP -1 ' IF ABS(@pBelly.Klok(i).nf - j) < 0.80 - (cnt/(UBOUND(Akk)*2)) THEN nr = i : EXIT FOR IF ABS(BellyNotes(i + Belly.LowTes).nf - j) < .8 - (cnt/(UBOUND(Akk)*2)) THEN nr = i : EXIT FOR NEXT i IF i > -1 THEN ' range = @pBelly.Klok(nr).maxvel - @pBelly.Klok(nr).minvel range = BellyNotes(nr + Belly.LowTes).maxvel - BellyNotes(nr + Belly.LowTes).minvel ' velo = @pBelly.Klok(nr).minvel + (range * Slider(slnr).value / 127!) velo = BellyNotes(nr + Belly.LowTes).minvel + (range * Slider(slnr).value / 127!) 'Belly_Beat ' Play Belly.channel @pBelly.Klok(nr).map , velo Play Belly.channel, nr + Belly.LowTes,velo END IF END IF NEXT j END IF SetDlgItemText gh.Cockpit, %GMT_MSG1, "Count= " & STR$(cnt) IF cnt <> %False THEN IF hMidiO(0) THEN 'DelShNo2Har Task(%Belly_Cat).Har, 0 ' bug FOR i = 87 TO 127 DelNote2Har Task(%Belly_Cat).Har, i NEXT i PlayHar Task(%Belly_Cat).Har,%Piperola_Channel END IF END IF IF tog = 1 THEN INCR cnt IF cnt > UBOUND(Akk) THEN cnt = UBOUND(Akk) : tog = -1 EXIT SUB 'elseif tog = -1 then ELSE DECR cnt IF cnt < 0 THEN cnt = 0 Task(%Belly_Cat).Har.vel = STRING$(128,0) PlayHar Task(%Belly_Cat).Har, %Piperola_Channel stoptask %Belly_cat END IF END IF END SUB SUB Belly_Cat_UD () ' for callback on Belly-Cat UpDown. LOCAL n AS BYTE n = UDCtrl(TaskEX(%belly_cat).UpdownNumbers(0)).value IF n < 1 THEN n = 1 END IF UDCtrl(TaskEX(%belly_cat).UpdownNumbers(0)).value = n SetDlgItemText Task(%belly_cat).hparam, %GMT_TEXT0_ID + 16, "MM=" & STR$(n) Task(%Belly_cat).freq = n / 60! END SUB SUB Belly_ArpUp () ' accelerando arpeggio upwards , crescendo ' duration = 20" STATIC bel AS LONG STATIC nrrepeats AS DWORD STATIC cnt AS DWORD LOCAL range AS WORD STATIC t AS DWORD IF ISFALSE Task(%belly_arpUp).tog THEN cnt = 0 bel = -1 Task(%belly_arpup).freq = 0.5 '17 nrrepeats = 1 Task(%belly_arpUp).tog = %true t = timeGetTime 'controller belly.channel, &H44, 0 'warning "disabling belly pitch mapping!" END IF IF ISFALSE cnt MOD nrrepeats THEN INCR bel nrrepeats = 1 + (bel * 2) ' 1 - 67 END IF ' range = @pBelly.Klok(bel).maxvel - @pBelly.Klok(bel).minvel range = BellyNotes(bel + Belly.LowTes).maxvel - BellyNotes(bel + Belly.LowTes).minvel range = range * ((bel+1) / 34) 'Belly_Beat ' Play Belly.channel, @pBelly.Klok(bel).map, @pBelly.Klok(bel).minvel + range Play Belly.channel, bel + Belly.Lowtes, BellyNotes(bel + Belly.LowTes).minvel + range INCR cnt Task(%belly_arpUp).freq = ((bel+1)/3) ' IF Task(%belly_arpUp).freq > @pBelly.Klok(bel).maxfreq THEN Task(%belly_arpUp).freq = @pBelly.Klok(bel).maxfreq IF Task(%belly_arpUp).freq > BellyNotes(bel + Belly.LowTes).maxfreq THEN Task(%belly_arpUp).freq = BellyNotes(bel + Belly.LowTes).maxfreq IF bel > 33 THEN stoptask %Belly_arpup SetDlgItemText gh.Cockpit, %GMT_MSG2, "Duration = " & STR$((timeGetTime - t)/1000) END IF END SUB SUB belly_ArpDown () ' ritardando arpeggio, decrescendo downwards ' as coded now, duration is 144" STATIC bel AS LONG STATIC nrrepeats AS DWORD STATIC cnt AS DWORD LOCAL range AS WORD STATIC t AS DWORD IF ISFALSE Task(%belly_arpDown).tog THEN cnt = 0 bel = 34 Task(%belly_arpdown).freq = 17 nrrepeats = 66 Task(%Belly_ArpDown).tog = %True t = timeGetTime 'controller belly.channel, &H44, 0 'warning "disabling belly pitch mapping!" END IF IF ISFALSE cnt MOD nrrepeats THEN DECR bel IF bel < 0 THEN stoptask %Belly_arpDown SetDlgItemText gh.Cockpit, %GMT_MSG2, "Duration = " & STR$((timeGetTime - t)/1000) EXIT SUB END IF nrrepeats = 1 + (bel * 2) ' 1 - 67 END IF ' range = @pBelly.Klok(bel).maxvel - @pBelly.Klok(bel).minvel range = BellyNotes(bel + Belly.LowTes).maxvel - BellyNotes(bel + Belly.Lowtes).minvel range = range * ((bel+1) / 34) 'Belly_Beat ' Play Belly.channel @pBelly.Klok(bel).map, @pBelly.Klok(bel).minvel + range Play Belly.channel, bel + Belly.LowTes, BellyNotes(bel + Belly.LowTes).minvel + range INCR cnt Task(%belly_arpDown).freq = ((bel+1)/3) ' IF Task(%belly_arpDown).freq > @pBelly.Klok(bel).maxfreq THEN Task(%Belly_arpDown).freq = @pBelly.Klok(bel).maxfreq IF Task(%belly_arpDown).freq > BellyNotes(Bel + Belly.LowTes).maxfreq THEN Task(%Belly_arpDown).freq = BellyNotes(Bel + Belly.LowTes).maxfreq END SUB SUB Bellies () ' random test with rescaling of velocities LOCAL bel AS BYTE LOCAL vel AS BYTE LOCAL range AS SINGLE bel = Belly.LowTes +(RND(1) * 45!) ' range = @pBelly.Klok(bel).maxvel - @pBelly.Klok(bel).minvel range = BellyNotes(bel).maxvel - BellyNotes(bel).minvel ' vel = @pBelly.Klok(bel).minvel + ((RND(1)^2) * range) vel = BellyNotes(bel).minvel + ((RND(1)^2) * range) ' IF vel > @pBelly.Klok(bel).minvel THEN IF vel > BellyNotes(bel).minvel THEN 'Belly_beat ' Play Belly.channel, @pBelly.$Klok(bel).map, vel Play Belly.channel, bel, vel END IF Task(%bellies).freq = 0.3 + (RND(1) *6) END SUB SUB Belly_Video () ' button switch handler for belly video power control: IF ISFALSE(ButnSW(3).Flag) THEN ButnSW(3).tag0 = "VidOff" ' on SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(3).tag0 Controller Belly.channel, 67, %True ELSE ButnSW(3).tag1 = "VideOn" ' off SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(3).tag1 Controller Belly.channel, 67, %False END IF END SUB SUB Bell_Catalogue (Akk() AS INTEGER) ' based on - the complete catalogue of different chords, each chord having a different interval ' constellation. Ordering is in increasing level of dissonance. ' Only chords that can be played by belly LOCAL i AS LONG LOCAL j AS LONG STATIC init AS BYTE STATIC Akk() AS INTEGER LOCAL n AS INTEGER LOCAL zandloper AS ASCIIZ PTR ' silly !!! (caused by declaration of WinApi) LOCAL hCursor AS LONG IF ISFALSE init THEN REDIM Akk(&HFFF) AS STATIC INTEGER hCursor = GetCursor () zandloper = %IDC_WAIT SetCursor LoadCursor (%Null, BYVAL(zandloper)) ' cfr. declaration PB WinApi SortChordsOnDissonance Akk(), &HF33C, 127 ' dll procedure ' parameters: %SortNoIsomorphs OR %SortPsyChord, only chords with 3-notes 'MSGBOX "Chords sorted. Ubound Akk = " & STR$(UBOUND(Akk)) ' 19 chords! ' now eliminate the chords belly cannot play: FOR i = 0 TO UBOUND(Akk) n = %False FOR j = 0 TO 33 ' IF IsNoteInChord(Akk(i),ROUND(@pBelly.Klok(j).nf,0)) THEN n = %True : EXIT FOR IF IsNoteInChord(Akk(i), ROUND(BellyNotes(j + Belly.LowTes).nf, 0)) THEN n = %True : EXIT FOR NEXT j IF ISFALSE n THEN Akk(i) = %False FOR j = i TO UBOUND(Akk) Akk(j) = Akk(j+1) NEXT j REDIM PRESERVE Akk(UBOUND(akk)-1) END IF NEXT i ' MSGBOX "Chords sorted. Ubound Akk = " & STR$(UBOUND(Akk)) ' still 19 chords! init = %True SetCursor hCursor EXIT SUB END IF END SUB SUB samplebells () LOCAL filenam AS STRING STATIC track AS LONG STATIC recording AS LONG STATIC nr AS LONG STATIC swtch AS LONG SELECT CASE swtch CASE 0 CONTROL SET TEXT gh.cockpit, %GMT_MSG1, "sampling bell" + STR$(nr) 'Belly_Beat ' Play Belly.channel, @pBelly.Klok(nr).map, (@pBelly.Klok(nr).maxvel + @pBelly.Klok(nr).minvel)\2 Play Belly.channel, nr + Belly.Lowtes, (BellyNotes(nr + Belly.LowTes).maxvel + BellyNotes(nr + Belly.LowTes).minvel) / 2 CASE 1 track = RecordAudioSample(2000) 'saves past 2 seconds.. IF track >= 0 THEN CONTROL SET TEXT gh.cockpit, %GMT_MSG2, "recording" + STR$(nr) + " - track:" + STR$(track) recording = %true ' INCR nr ELSE MSGBOX "failed recording",,FUNCNAME$ END IF CASE 2 IF recording THEN CHDIR "c:\b\pb\gmt\robots\belly\" SaveAudioTrack "klok" + TRIM$(STR$(nr)) + ".wav", track recording = %false CHDIR "c:\b\pb\gmt\" INCR nr IF nr > 34 THEN nr = 0 MSGBOX "done" StopTask %Belly_Sample END IF END IF END SELECT INCR swtch swtch = swtch MOD 3 END SUB SUB Belly_Lites STATIC slnr AS LONG STATIC cnt AS LONG IF ISFALSE Task(%Belly_Lites).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" IF ISFALSE Task(%Belly_Lites).hParam THEN MakeTaskParameterDialog %Belly_Lites,1,Slider(),0,UDctrl(),TaskParamLabels() END IF slnr = TaskEX(%Belly_Lites).SliderNumbers(0) cnt = -1 Task(%Belly_Lites).tog = %True END IF NoteOff Belly.channel, 120 + cnt INCR cnt IF cnt > 4 THEN cnt = 0 Play Belly.channel, 120 + cnt, 127 Task(%Belly_Lites).freq = MAX(slider(slnr).value / 5, 1) END SUB SUB Belly_Lites_Off () MM_Belly_Off %MM_Lights END SUB SUB Belly_CreateHardwareMapping '20060827 'pic cyclus: 27.2 microseconden '20060829: we created a sysex file from belly.dat, but needed to adapt the results from that manually ' now we base the basic hardware mapping from that sysex in stead!! LOCAL fin AS DWORD LOCAL fout AS DWORD LOCAL b$ LOCAL bel AS BYTE LOCAL vel AS WORD LOCAL i AS LONG LOCAL minv() AS SINGLE LOCAL maxv() AS SINGLE DIM minv(127) DIM maxv(127) fin = FREEFILE OPEN "c:\b\pb\gmt\robots\belly\belly_sysx.dat" FOR INPUT ACCESS READ LOCK WRITE AS fin fout = FREEFILE OPEN "c:\b\pb\gmt\robots\belly\belly_lookup.dat" FOR OUTPUT ACCESS WRITE LOCK WRITE AS fout DO UNTIL EOF(fin) LINE INPUT# fin, b$ IF TRIM$(b$) = "PROGRAM: 122" THEN EXIT LOOP LOOP DO UNTIL EOF(fin) LINE INPUT# fin, b$ IF TRIM$(b$) = "DATA:" THEN EXIT LOOP LOOP FOR bel = belly.lowtes TO belly.hightes LINE INPUT# fin, b$ ' msgbox b$,,funcname$ minv(bel) = VAL(PARSE$(b$, 5)) maxv(bel) = VAL(PARSE$(b$, 5)) + 127 * VAL(PARSE$(b$, 4)) ' msgbox str$(BellyNotes(bel - LBOUND(Bellynotes)).minvel) + str$(BellyNotes(bel - LBOUND(bellynotes)).maxvel) ' NEXT FOR bel = belly.lowtes TO belly.hightes PRINT# fout, "NOTE " + STR$(bel) PRINT# fout, "DATA 00000h"; FOR i = 1 TO 127 vel = minv(bel) + (i/127) * (maxv(Bel) - minv(bel)) IF ISFALSE(i MOD 8) THEN PRINT# fout, "DATA " + HEX$(vel, 5) + "h"; ELSEIF (i MOD 8) = 7 THEN PRINT# fout, "," + HEX$(vel, 5) + "h;" ELSE PRINT# fout, "," + HEX$(vel, 5) + "h"; END IF NEXT PRINT# fout, NEXT MSGBOX "belly_lookup.dat created!",,FUNCNAME$ END SUB 'EOF