'********************************************************** '* TechnoFaustus * '* Tango * '* 2000 - 2014 * '********************************************************** ' may use doppler radar at 1024 S/s ' contains test code for this ' 09.07.2009: unexplicable crashes on \\Xi, not on \\No ' derived from beat/dance demo code: ' to do here: improve orchestration for M&M ' interactivity on gesture ' playdur debug ' 01.06.2014: Code revisited. ' clean up required: we can ommit all doppler and DFT coding ' if we include the gesture recognition code from Namuda. ' 07.06.2014: Gesture recognition engine added. ' 08.06.2014: ending for dance coding. ' 09.06.2014: Rehearsal session with Dominica Eyckmans ' 10.06.2014: Required robots for Dance: ' Piano, Autosax, Asa, Fa, Klar, Horny, Bono, So, Heli, Simba, Psch, Troms,Korn, Ob 'Task-constants: %Faust_Tango = 48 ' test %Faust_Tango_Har = 49 %Faust_Tango_Mel = 50 %Faust_Dance = 32 %Faust_Dance_End = 33 %Faust_Fight = 34 ' in older versions this was %Butohfight %Faust_Dop = 40 ' doppler test ii_2000 NiDAQmx %Faust_FFT = 41 ' %Faust_Dop+1 %Faust_Test_DFTmap = 42 '%Faust_FFT + 1 %FxV = 43 '%Faust_FFT + 2 %FyV = 44 '%Faust_FFT + 3 %FzV = 45 '%Faust_FFt + 4 %DopplerDisplay = 46 '%Faust_FFT + 5 ' %ButohFight = 47 '%Faust_FFT + 6 'TYPE Faust_Dance_Type DWORD ' moved to Technofautus.bi ' tc AS BYTE ' tonal center - grondtoon akkoorden ' nextnote AS BYTE ' chordtype AS STRING * 20 ' ritpat (0 TO 30) AS STRING * 255 ' nrpats AS DWORD ' tiks_per_beat AS DWORD ' tiks_per_bar AS DWORD ' nrbeats AS DWORD ' maat AS DWORD ' maatteller ' beat AS DWORD ' beat teller ' tik AS DWORD ' tikteller ' velfak AS SINGLE ' scaling factor for velocities (normalized) 'END TYPE DECLARE FUNCTION Faust_Init_Tango () AS DWORD DECLARE SUB Faust_Tango () DECLARE SUB Faust_Tango_Har () DECLARE SUB Faust_Tango_Mel () DECLARE SUB Faust_Dance () DECLARE SUB Faust_Dance_Stop () DECLARE SUB Faust_Dance_End () DECLARE SUB Faust_DanceChordPlay (Velocities() AS BYTE) DECLARE SUB Faust_Dancebeat(ritmAr() AS BYTE, velocities() AS BYTE) DECLARE SUB Faust_DanceMelo (velocities() AS BYTE) DECLARE SUB Faust_DanceVelogen(Velocities() AS BYTE) 'DECLARE SUB Faust_Dancefile(Fd AS Faust_Dance_Type, tempo&) ' research procs. DECLARE SUB Faust_Doppler_Test () DECLARE SUB Faust_FFT_Test () DECLARE SUB Faust_Test_DFTmap () ' following together are the composition code for 'Ascent' DECLARE SUB F_X_Vekt () DECLARE SUB F_X_Vekt_Stop () DECLARE SUB F_Y_Vekt () DECLARE SUB F_Y_Vekt_Stop () DECLARE SUB F_Z_Vekt () DECLARE SUB F_Z_Vekt_Stop () ' following is for the butoh fight scene DECLARE SUB Butoh_Fight () DECLARE SUB Butoh_Fight_Stop () FUNCTION Faust_Init_Tango () AS DWORD LOCAL i AS DWORD LOCAL m AS ASCIIZ * 30 App.Komposduur = Read_Duration_From_File ($faustini, "FaustTango") 'function in g_file.dll 15.10.2003 App.id = %ID_FAUSTTANGO ' interactive tango Task(%Faust_Tango).naam = "Tango" Task(%Faust_Tango).cptr = CODEPTR(Faust_Tango) Task(%Faust_Tango).freq = 100 Task(%Faust_Tango).tempo = 120 Task(%Faust_Tango).flags = %False '%Harm_Task Task(%Faust_Tango_Har).naam = "TangHar" Task(%Faust_Tango_Har).cptr = CODEPTR(Faust_Tango_Har) Task(%Faust_Tango_Har).freq = 16 Task(%Faust_Tango_Har).flags = %False '%Harm_Task Task(%Faust_Tango_Mel).naam = "TangMel" Task(%Faust_Tango_Mel).cptr = CODEPTR(Faust_Tango_Mel) Task(%Faust_Tango_Mel).freq = 100 Task(%Faust_Tango_Mel).flags = %False ' interactive hiphop dance Task(%Faust_Dance).naam = "Dance" Task(%Faust_Dance).cptr = CODEPTR(Faust_Dance) Task(%Faust_Dance).freq = 20 Task(%Faust_Dance).tempo = 20 Task(%Faust_Dance).flags = %False '%MIDI_TASK 'OR %Harm_Task TaskEx(%Faust_Dance).stopCptr = CODEPTR(Faust_Dance_Stop) Task(%Faust_Dance_End).naam = "ending" ' 08.06.2014 task(%Faust_Dance_End).cptr = CODEPTR(Faust_Dance_End) Task(%Faust_Dance_End).freq = 20 Task(%Faust_Dance_End).tempo = 120 Task(%Faust_Dance_End).flags = %False '%MIDI_TASK 'OR %Harm_Task 'TaskEx(%Faust_Dance_End).stopCptr = CODEPTR(MM_AllOff) Task(%Faust_Fight).naam = "Fight" ' interactive ending for dances Task(%Faust_Fight).cptr = CODEPTR(Butoh_Fight) Task(%Faust_Fight).freq = 200 ' more than 256 makes no sense, because that would be larger than the Sampling rate Task(%Faust_Fight).flags = %False TaskEX(%Faust_Fight).stopcptr = CODEPTR(Butoh_Fight_Stop) ' ------------------------------------------------------------------------ ' test code for development. [maybe removed] Task(%Faust_Dop).naam = "Dop_tst" Task(%Faust_Dop).cptr = CODEPTR(Faust_Doppler_Test) Task(%Faust_Dop).freq = 20 'Task(%Faust_Dop).level = 127 'Task(%Faust_Dop).tempo = 20 Task(%Faust_Dop).flags = %False Task(%Faust_FFT).naam = "FFT_tst" Task(%Faust_FFT).cptr = CODEPTR(Faust_FFT_Test) Task(%Faust_FFT).freq = 20 'Task(%Faust_Dop).level = 127 'Task(%Faust_Dop).tempo = 20 Task(%Faust_FFT).flags = %False Task(%Faust_Test_DFTmap).naam = "FFTmap" Task(%Faust_Test_DFTmap).cptr = CODEPTR(Faust_Test_DFTmap) Task(%Faust_Test_DFTmap).freq = 20 'Task(%Faust_Test_DFTmap).level = 127 'Task(%Faust_Test_DFTmap).tempo = 20 Task(%Faust_Test_DFTmap).flags = %False Task(%FxV).naam = "FXV" Task(%FxV).cptr = CODEPTR(F_X_Vekt) Task(%FxV).freq = 20 Task(%FxV).flags = %False TaskEX(%fxv).stopcptr = CODEPTR(F_X_Vekt_Stop) Task(%FyV).naam = "FYV" Task(%FyV).cptr = CODEPTR(F_Y_Vekt) Task(%FyV).freq = 20 Task(%FyV).flags = %False TaskEX(%FyV).stopcptr = CODEPTR(F_Y_Vekt_Stop) Task(%FzV).naam = "FZV" Task(%FzV).cptr = CODEPTR(F_Z_Vekt) Task(%FzV).freq = 20 Task(%FzV).flags = %False TaskEX(%FzV).stopcptr = CODEPTR(F_Z_Vekt_Stop) IF ISFALSE Task(%Gesture_Analyser).tog THEN starttask %Gesture_Analyser ' requires doppler hardware! FaustPatches "tango" ' also sets the robotports m = "" SendMessage gh.Cockpit, %WM_SETTEXT,0, VARPTR(m) SetDlgItemText gh.Cockpit, %GMT_TITLE, "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR, $gwr SetDlgItemText gh.Cockpit, %GMT_MSG1, "Faust and Mefisto" SetDlgItemText gh.Cockpit, %GMT_MSG2, "ii-2000 doppler" FUNCTION = %True END FUNCTION SUB Faust_Tango () LOCAL note, oldnote AS INTEGER STATIC tiks! STATIC ritmeteller AS INTEGER STATIC prevnote, otc AS BYTE ' note before the silence ' to be written. ' requires globalharmony task to be active. ' 09.06.2014: Now uses Faust_Tango_Har task as harmony source. ' 10.06.2014: further coding. We need a harmonic development scheme and a melody generator. IF ISFALSE Task(%Faust_Tango).tog THEN 'App.tempo = 60 '120 Task(%Faust_Tango).Rit.pattern(0) = %False IF ISFALSE Task(%Faust_Tango_Har).tog THEN starttask %Faust_Tango_Har IF ISFALSE Task(%Faust_Tango_Mel).tog THEN starttask %Faust_Tango_Mel RESET Fd.maat 'reset Fd.beat Task(%Faust_Tango).tog = %True END IF Task(%Faust_Tango).tempo = (Slider(1).value / 4) * gesture.velocity(3) ' we could also try gesture.fixspeed_val, but that's not normalized. ' het tempo voor een gehele maat is frq = task(tasknr%).tempo / 60 ' zo'n gehele maat beslaat een aantal eenheden gegeven in tiks! SELECT CASE Task(%Faust_Tango).Rit.pattern(Ritmeteller) CASE %False RESET Ritmeteller, prevnote tiks! = GetRitme (Task(%Faust_Tango).Rit, %Tango, slider(0).value / 128!) ' staccato-legato slider logfile "Ticks=" & " " & STR$(tiks!) ' = 16 on first run INCR Fd.maat Faust_Tango ' reiterate immediately - if ever the pattern would start with 0, we have an infinite loop. CASE > 0 Piano.Har(1).vel = Task(%Faust_Tango_Har).Har.vel InstrumPlay Piano CASE < 0 Piano.Har(1).vel = NUL$(128) InstrumPlay Piano END SELECT 'calculate the global parameters for coordination between the tasks: IF Fd.maat \ 12 <> otc THEN Fd.tc = (Fd.tc + 7 MOD 12) otc = Fd.maat \ 12 END IF Task(%Faust_Tango).freq = (tiks! * Task(%Faust_Tango).tempo ) / (60! * ABS(Task(%Faust_Tango).Rit.pattern(Ritmeteller))) INCR Ritmeteller END SUB SUB Faust_Tango_Har () STATIC cnt AS DWORD IF ISFALSE Task(%Faust_Tango_Har).tog THEN RESET cnt Task(%Faust_Tango_Har).tog = %True END IF SELECT CASE cnt MOD 2 CASE %False ' here we build chords based on gesture properties: LOCAL note, velo AS BYTE Task(%Faust_Tango_Har).Har.vel = NUL$(128) note = 36 + Fd.tc + (gesture.velocity(0) * 64) velo = gesture.flue_val(0) * 127 Addnote2Har Task(%Faust_Tango_Har).Har, note, velo note = 36 + Fd.tc + (gesture.velocity(1) * 64) velo = gesture.flue_val(1) * 127 Addnote2Har Task(%Faust_Tango_Har).Har, note, velo note = 36 + Fd.tc + (gesture.velocity(2) * 64) velo = gesture.flue_val(2) * 127 Addnote2Har Task(%Faust_Tango_Har).Har, note, velo CASE 1 ' here we 'solve' the chord Task(%Faust_Tango_Har).Har.vel = SolveHar$ (Task(%Faust_Tango_Har).Har, Fd.tc, 0.9) END SELECT INCR cnt ' debug: ' logfile str$(note) & " " & STR$(velo) 'Task(%Faust_Tango_Har).Har.vel ' o.k. END SUB SUB Faust_Tango_Mel () ' 10.06.2014 ' melody generator for Faust-Tango ' should be in sync with Faust Tango ' we take Fd.tc into account and have a bar counter. STATIC tik, oldbar, Ritmeteller AS DWORD STATIC noot, cnt AS INTEGER STATIC tiks! IF ISFALSE Task(%Faust_Tango_Mel).tog THEN RESET cnt, ritmeteller, oldbar Task(%Faust_Tango_Mel).tog = %True END IF IF Fd.maat <> oldbar THEN ' Fd.maat incremented in the Faust_Tango task. RESET tik oldbar = Fd.maat INCR cnt END IF Task(%Faust_Tango_Mel).tempo = Task(%Faust_Tango).tempo '= (Slider(1).value / 4) * gesture.velocity(3) SELECT CASE Task(%Faust_Tango_Mel).Rit.pattern(Ritmeteller) CASE %False RESET Ritmeteller tiks! = GetRitme (Task(%Faust_Tango_Mel).Rit, %Tango, 1) ' legato ' we could also get another rhythm than %Tango here, ' provided the ticksum is also 16. Faust_Tango_Mel ' reiterate immediately - if ever the pattern would start with 0, we have an infinite loop. CASE > 0 Asa.Har(1) = Task(%Faust_Tango_Har).Har noot = GetStrongest (Asa.Har(1), 1) ' is mod 12 noot = 64 + noot IF noot MOD 12 = Fd.tc MOD 12 THEN noot = noot + 10 mPlay Asa.channel, noot,gesture.flue_val(3) * 127 CASE < 0 NoteOff Asa.channel,noot END SELECT INCR tik ' so counts 1-16 Fd.beat = (tik \ 4)+ 1 ' counts 1,2,3,4 Task(%Faust_Tango_Mel).freq = (tiks! * Task(%Faust_Tango_Mel).tempo ) / (60! * ABS(Task(%Faust_Tango_Mel).Rit.pattern(Ritmeteller))) INCR Ritmeteller END SUB SUB Faust_Dance () ' Note that this is derived from earlier code we had in Robogo.inc (Namuda Study #5) ' tempo made interactive 05.06.2014 ' 07.06.2014 velocities made interactive. (via Fd.velfak) ' 09.06.2014: Rehearsed with Dominica Eyckmans STATIC toets% STATIC slnr, tel AS BYTE STATIC tf AS SINGLE LOCAL j, k AS LONG STATIC breaks, toon AS BYTE STATIC Ritmar() AS BYTE ' mapping STATIC Velocities() AS BYTE IF ISFALSE Task(%Faust_Dance).tog THEN toets% = %NotFalse IF ISFALSE Task(%Faust_Dance).hParam THEN DIM TaskParamLabels(0 TO 1) AS STATIC ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Level" 'TaskParamLabels(2) = "Beat" not used MakeTaskParameterDialog %Faust_Dance,2,Slider(),0,UDctrl(),TaskParamLabels() ' was 2 sliders! END IF RANDOMIZE TIMER tel = 0 Fd.tik = 0 Fd.maat = 0 Fd.nextnote = RND(36, 48) Fd.chordtype = "mineur" ' Faust_DanceFile (Fd, tempo) ' moet in een data bestandje kunnen komen. ' voorlopig hard gekodeerd: Fd.ritpat(0)= "1*******2*******3*******4*******" ' 32 tekens = 4 x 8 Fd.ritpat(1)= "b t b t " Fd.ritpat(2)= "b t b t " Fd.ritpat(3)= "b t b t " Fd.ritpat(4)= "b t b b t " Fd.ritpat(5)= "b b t b t b " Fd.ritpat(6)= "b b t b t " Fd.ritpat(7)= "b b t b t " Fd.ritpat(8)= "b b t b b t " Fd.nrpats = 9 Fd.tiks_per_bar = LEN(TRIM$((Fd.ritpat(0)))) ' 32 Fd.tiks_per_beat = 8 Fd.nrbeats = Fd.tiks_per_bar /Fd.tiks_per_beat ' 4 'logfile "Aantal patronen: " & STR$(Fd.nrpats - 1) 'logfile "Aantal tellen : " & STR$(Fd.nrbeats) 'logfile "Tiks per tel " & STR$(Fd.tiks_per_beat) 'logfile "Aantal tiks: " & STR$(Fd.tiks_per_bar) REDIM Velocities(Fd.tiks_per_bar - 1) AS STATIC BYTE Faust_DanceVelogen Velocities() 'genereert array van velocities per maat 'werkt enkel binair, ternair nog doen!!! REDIM RitmAr((Fd.nrpats-2), (Fd.tiks_per_bar -1)) AS STATIC BYTE 'array v midi-nootnummers in de percussie-bank '36 basdrum 38 snaredrum FOR j = 0 TO Fd.nrpats - 2 FOR k = 0 TO Fd.tiks_per_bar - 1 SELECT CASE ASC(Fd.ritpat(j+1), (k+1)) CASE 98 'b bas drum RitmAr (j, k) = 24 'voor troms, op soundcard in GM note 36 CASE 116 't snare RitmAr (j, k) = 72 ' voor snar, op soundcard in GM note 38 CASE ELSE RitmAr (j,k) = 0 END SELECT NEXT k NEXT j IF slnr = %False THEN slnr = TaskEX(%Faust_Dance).SliderNumbers(1) ' level slider END IF ' MM_Piano_On Progchange Piano.channel, 122 MM_Autosax_On MM_Ob_On ' MM_Troms_On MM_Simba_On MM_Psch_On MM_Heli_On MM_So_On ProgChange mDisp_A.channel, 4 ' starts stopwatch on display in MM:SS (autoincrementing) Task(%Faust_Dance).tog = %True END IF 'einde initialisatie taak IF ISTRUE toets% THEN 'Fd.velfak = Slider(slnr).value / 128! ' normalized level - can become gesture interactive. '07.06.2014: ' attempt to gesture interactive coding: Fd.velfak = MAX(Slider(slnr).value/ 128!, gesture.flue_val(3)) ' surface function ' so this way the slider sets the minimum value. ' with slider on max, there is no interactivity anymore. toets% = %False toon = Fd.nextnote breaks = RND (0,5) ' 0 1 2 3 4 5 ' HH 1 2 3 4 ' mod 2 = 0 : 0 2 4 = 1/2 ' kans 1/2 1/3 1/2 1/3 ' mod 3 = 0 : 0 3 = 1/3 ' to do: insert call to sub die de velocities aanpast naar prioriteit IF ISFALSE Fd.tik THEN Fd.beat= RND(0,Fd.nrpats-2) 'vb max 4 Fd.beat = 4 INCR Fd.maat IF Fd.maat MOD 4 = 1 THEN toon = toon -4 ' om de vier maten een kwart lager (boring) 'play 9,53,60 * Fd.velfak 'crash - moet Simba worden. 'play 9,49,80 * Fd.velfak 'crash mPlay Psch.channel,76, 60 * Fd.velfak mPlay Psch.channel,81, 80 * Fd.velfak ELSE IF (breaks MOD 2) = 1 THEN mPlay Troms.channel, 42, 120 * Fd.velfak ' high bongo END IF END IF END IF Faust_Dancebeat ritmAr(), velocities() ' tel 1 2 3 0 ' Fd.tik mod 8 =0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 SELECT CASE (Fd.tik MOD Fd.tiks_per_beat) ' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 CASE 0 tel = (tel + 1) MOD 4 '?? mod Fd.tiks_per_beat ?? ' RANDOMIZE SELECT CASE RND(0,20) CASE < 8 ' or Fd.chordtype = "dominant" THEN 'RitmAr (Fd.beat, Fd.tik) >< 0 AND Fd.nextnote = ((toon +7) MOD 24) + 36 'harmonie centr toonhoogte wijzigen !! hier enkel bij akk op de tel Fd.chordtype = "mineur" Fd.tc = toon Faust_DanceChordPlay velocities() ', velocity ' kans moet 2/3 zijn CASE 15 IF TRIM$(Fd.chordtype) = "mineur" THEN toon = (Fd.nextnote - 5) Fd.chordtype="dominant" Fd.tc = toon Faust_DanceChordPlay velocities() ', velocity) ' kans moet 2/3 zijn END IF END SELECT IF breaks MOD 2 = 0 THEN ' mPlay 9,42, Velocities(Fd.tik) * Fd.velfak 'HH mPlay Simba.channel, 68, Velocities(Fd.tik) * Fd.velfak ' simba notes 65-70 hihat END IF ' RANDOMIZE IF breaks MOD 3 = 0 THEN 'playDur 2, (toon MOD 12) + 36, Velocities(Fd.tik) * Fd.velfak, RND (1,4)*100 PlayDur Heli.channel, (toon MOD 12) + 36, Velocities(Fd.tik)* 127, RND(1,4)* 127 PlayDur So.channel, 24 + (toon MOD 12), Velocities(Fd.tik)* 127, RND(2,4) * 127 'RND(2,4)*50 ' speelt extra basnoot (kans 1/3) op de tel END IF CASE 2 IF breaks MOD 3 = 0 THEN 'playDur 9,42, Velocities(Fd.tik) * Fd.velfak, RND (2,10) 'HH PlayDur Simba.channel, 71, Velocities(Fd.tik) * Fd.velfak, RND (2,20) ' hi hat close on simba END IF CASE 4 IF RND(0,5)=5 OR (TRIM$(Fd.chordtype) = "dominant") THEN 'RitmAr (Fd.beat, Fd.tik) >< 0 AND Fd.nextnote = ((toon +7) MOD 24) + 36 'harmonie centr toonhoogte wijzigen !! hier enkel bij akk op de tel Fd.chordtype = "mineur" END IF IF RitmAr (Fd.beat, Fd.tik) >< 0 AND (RND(3,5)=4) THEN Faust_DanceChordPlay velocities() ', velocity ' kans moet 1/3 en niet na 1e tel END IF IF breaks MOD 2 = 0 THEN 'play 9,42, Velocities(Fd.tik) * Fd.velfak 'HH mPlay Simba.channel, 65, Velocities(Fd.tik) * Fd.velfak ' in RoboGo we have this on tambourine, note 77 END IF CASE 6 IF breaks MOD 3 = 0 THEN 'playDur 9,42, Velocities(Fd.tik) * Fd.velfak, RND(2,10) 'HH Playdur Simba.channel, 71, Velocities(Fd.tik) * Fd.velfak, RND(2,10) END IF END SELECT ' add melodyline: Faust_DanceMelo velocities() ' here we need more differentiation in instruments. Fd.tik = (Fd.tik + 1) MOD Fd.tiks_per_bar ELSE toets% = %NotFalse END IF ' fixed coding: 'Task(%Faust_Dance).freq = 64! * (Slider(slnr-1).value / 128!) ' volgende moet interaktief worden: tempo (werkt alleen in doppler mode) 'tf = (@pDoppler.xf + @pDoppler.yf + @pDoppler.zf) / 540 ' zou moeten 0-1 worden nu ' with integration: 'tf = ((tf * 3) + ((@pDoppler.xf + @pDoppler.yf + @pDoppler.zf) / 540)) / 4 ' this appeared to be too shaky 'Task(%Faust_Dance).freq = 64! * tf '* (Slider(slnr-1).value / 128!) ' 05.06.2014 ' 07.06.2014: so now we try this: tf = gesture.velocity(3) ' we could also try gesture.fixspeed_val, but that's not normalized. Task(%Faust_Dance).freq = Slider(slnr-1).value * tf IF Task(%Faust_Dance).freq < 0.5 THEN Task(%Faust_Dance).freq = 0.5 ' we can use the display to show time or count... (done on init: stopwatch mode) END SUB SUB Faust_Dance_Stop () ProgChange mDisp_A.channel, 1 ' stop chrono, switch to ascii mode mPlay mDisp_A.channel, 1, 16 ' blank mPlay mDisp_A.channel, 2, ASC("E") mPlay mDisp_A.channel, 3, ASC("N") mPlay mDisp_A.channel, 4, ASC("D") StartTask %Faust_Dance_End END SUB SUB Faust_Dance_End () '08.06.2014: final chord decrescendo and ending for Dance STATIC t AS DWORD IF ISFALSE Task(%Faust_Dance_End).tog THEN fd.velfak = 1 t = timegettime mPlay So.channel, 24 + (fd.tc MOD 12), 120 mPlay Bono.channel, 36 + (fd.tc MOD 12), 120 mPlay Fa.channel, 48 + (fd.tc MOD 12), 127 mPlay Autosax.channel, 48 + 4 + (fd.tc MOD 12), 127 mPlay Klar.channel, 60 + 10 + (fd.tc MOD 12), 126 mPlay Ob.channel, 60 + 7 + (fd.tc MOD 12), 127 mPlay Korn.channel, 72 + 3 + (fd.tc MOD 12), 127 Task(%Faust_Dance_End).freq = 4 Task(%Faust_Dance_End).tog = %True END IF fd.velfak = MAX(0, fd.velfak - 0.01) Controller So.channel, 7, 127 * fd.velfak Controller Bono.channel, 7, 127 * fd.velfak Controller Fa.channel, 7, 127 * fd.velfak Controller Autosax.channel, 7, 127 * fd.velfak Controller Klar.channel, 7, 127 * fd.velfak Controller Ob.channel, 17, 127 * fd.velfak Controller Korn.channel, 17, 127 * fd.velfak ' add percussion, interactive: IF ISFALSE Task(%Faust_Fight).tog THEN starttask %Faust_Fight IF fd.velfak <= 0.01 THEN MM_So_Off 'MM_Qt_Off 'MM_Krum_Off MM_Autosax_Off MM_Klar_Off MM_Ob_Off MM_Korn_Off MM_Bono_Off MM_Fa_Off stoptask %Faust_Dance_End ' butohfight will stay ON!!! END IF END SUB SUB Faust_DanceChordPlay (Velocities() AS BYTE) LOCAL b AS BYTE b= RND (50,126) ' duurtijd van de noten SELECT CASE TRIM$(Fd.chordtype) CASE "mineur" Playdur Piano.channel, Fd.tc ,velocities(Fd.tik) * Fd.velfak,b 'basnoot '90 Playdur Piano.channel, Fd.tc + 24,(velocities(Fd.tik) * Fd.velfak)-5 ,b 'oktaaf Playdur Piano.channel, Fd.tc + 36 + 3, (velocities(Fd.tik) * Fd.velfak) -5,b 'terts Playdur Piano.channel, Fd.tc + 24 + 7, (velocities(Fd.tik) * Fd.velfak)-5,b 'kwint Playdur Piano.channel, Fd.tc + 36 + 10, (velocities(Fd.tik) * Fd.velfak)-5,b 'sept CASE "dominant" Playdur Piano.channel, Fd.tc ,velocities(Fd.tik) * Fd.velfak,b 'basnoot Playdur Piano.channel, Fd.tc + 24, (velocities(Fd.tik) * Fd.velfak)-5,b 'oktaaf Playdur Piano.channel, Fd.tc + 36 + 4, (velocities(Fd.tik) * Fd.velfak)-5,b 'terts Playdur Piano.channel, Fd.tc + 24 + 7, (velocities(Fd.tik) * Fd.velfak)-5,b 'kwint Playdur Piano.channel, Fd.tc + 36 + 10, (velocities(Fd.tik) * Fd.velfak)-5,b 'sept END SELECT END SUB SUB Faust_DanceVelogen(Veloc() AS BYTE) LOCAL l,m,n,i AS BYTE FOR i = 0 TO Fd.tiks_per_bar - 1 Veloc(i) = 0 NEXT Veloc(0)= 100 l = Fd.tiks_per_bar \2 m = 90 DO WHILE (l MOD 2) >< 1 'IF l > 2 then Veloc (l)= m 'l-1 ' PRINt "Velo" l-1 " : " m 'end if n= l * 2 DO WHILE n < Fd.tiks_per_bar IF Veloc(n) = 0 THEN 'n-1 Veloc(n) = m 'n-1 END IF n = n + l LOOP m = m - 10 l = l\2 LOOP FOR i = 0 TO Fd.tiks_per_bar -1 IF Veloc(i) = 0 THEN Veloc(i) = m NEXT 'uitschrijven van het velocity-array ter kontrole ' FOR i = 0 TO Fd.tiks_per_bar ?-1 ' logfile "Velo" i " : " Velo(i) ' NEXT END SUB SUB Faust_DanceMelo (velocities() AS BYTE) ' was ooit lesdemo voor algoritmische kompositie. ' melody generator ' blue note ' 08.06.2014: Fd as Faust_Dance_Type made global. ' 10.06.2014: Needs changes of instrumentation. Now only using autosax. ' Instrumentation changes implemented. LOCAL rand, rand2 AS BYTE LOCAL melotoon? STATIC oldtc, cnt AS INTEGER STATIC robot AS musician ' to allow instrument changes melotoon? = Fd.tc MOD 24 ' om binnen 2 oktaven te blijven ' C D Eb F F# G Ab Bb C ' 0 2 3 5 6 7 8 10 0 7 of 8 noten RND (0,7) rand = RND(0,5) rand2 = RND (0,7) 'Playdur Piano.channel, melotoon?+ 84, 100, 100 ' 10.06.2014: new section to implement instrument changes IF melotoon? <> oldtc THEN oldtc = melotoon? INCR cnt cnt = cnt MOD 6 ' if we want the changes to happen less often we can do mod 12 and ' change instrumentation only on even counts. SELECT CASE cnt CASE 0 MM_Autosax_On Robot = Autosax CASE 1 MM_Klar_On Robot = Klar CASE 2 MM_Horny_On Robot = Horny CASE 3 MM_Fa_On Robot = Fa CASE 4 MM_Asa_On ' needs to be louder Controller Asa.channel, 7, 120 Robot = Asa CASE 5 MM_Bono_On Robot = Bono END SELECT END IF '---------------------------------------------------------- 'add xylophone on edgy property: [ copied from RoboGo!] IF gesture.edgy_dur(3) THEN mPlay Xy.channel, melotoon? +72, MIN(@pDoppler.xa * 127, 127) END IF '!!! case voor ternair bijmaken en t volgende case binair maken SELECT CASE Fd.nrbeats '(Fd.tiks_per_bar\Fd.tiks_per_beat) 'aantal tellen = aantal tiks / onderverdeling CASE 4 SELECT CASE Fd.tik MOD Fd.tiks_per_beat ' 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 CASE 0 'op de tel: grondnoot of kwint SELECT CASE rand MOD 4 CASE 0 'grondnoot (kans: 2 op 6) ' 1 & 2 & 3 & 4 & PlayDur Robot.channel, melotoon?+48, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 CASE 1 'kwint (kans: 2 op 6) PlayDur Robot.channel, melotoon?+48+7, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 CASE 2 'terts (kans: 1 op 6) SELECT CASE TRIM$(Fd.chordtype) CASE "mineur" playDur Robot.channel, melotoon?+48+3, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 CASE "dominant" playDur Robot.channel, melotoon?+48+4, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 END SELECT CASE 3 'septiem (kans: 1 op 6 !!!moet minder kans zijn) playDur Robot.channel, melotoon?+48+10, velocities(Fd.tik) * Fd.velfak,(rand+1)*50 END SELECT 'case 2 ' CASE Fd.tiks_per_beat\2 '4 'doorgangsnoten (? hoe aanpakken vorige/volgende noot weten) ' SELECT CASE rand MOD 5 CASE 1 ' secunde (kans: 1 op 6) playDur Robot.channel, melotoon?+48+2, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 CASE 2 ' kwart (kans: 1 op 6) playDur Robot.channel, melotoon?+48+5, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 END SELECT CASE Fd.tiks_per_beat\2\2 '4 'doorgangsnoten SELECT CASE rand MOD 5 CASE 4 ' secunde (kans: 1 op 6) playDur Robot.channel, melotoon?+48+2, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 CASE 5 ' kwart (kans: 1 op 6) playDur Robot.channel, melotoon?+48+5, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 END SELECT CASE Fd.tiks_per_beat\2\2\2 '4 'doorgangsnoten (? hoe aanpakken vorige/volgende noot weten) SELECT CASE rand MOD 5 CASE 4 ' secunde (kans: 1 op 6) playDur Robot.channel, melotoon?+48+2, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 CASE 5 ' kwart (kans: 1 op 6) playDur Robot.channel, melotoon?+48+5, velocities(Fd.tik) * Fd.velfak,(rand2+1)*50 END SELECT ' of noten 60 + 8 (sixt), 60+5/6 (kwart), 60+1 (#), 60+11 (!leidtoon) END SELECT END SELECT END SUB SUB Faust_Dancebeat(ritmAr() AS BYTE, velocities() AS BYTE) ' moet op een robot zonder note-off requirement! IF ritmAr(Fd.beat, Fd.tik) > %False THEN mPlay Troms.channel, ritmAr(Fd.beat, Fd.tik), velocities(Fd.tik) * Fd.velfak END IF END SUB '--------------------------------------------------------------------------------------------------------------- SUB Faust_Doppler_Test () ' testkode voor de verdere ontwikkeling van doppler US onder NiDaqmx. ' dit moet in g_nxh.dll terechtkomen wanneer het goed werkt. ' 07.06.2014: Dit mag verwijderd worden. STATIC binsize, xamax, yamax, zamax AS SINGLE DIM arr(0 TO 255) AS STATIC SINGLE DIM han(0 TO 255) AS STATIC SINGLE DIM xfast(0 TO 255) AS STATIC SINGLE DIM yfast(0 TO 255) AS STATIC SINGLE DIM zfast(0 TO 255) AS STATIC SINGLE DIM xmed(0 TO 255) AS STATIC SINGLE DIM ymed(0 TO 255) AS STATIC SINGLE DIM zmed(0 TO 255) AS STATIC SINGLE DIM xslow(0 TO 255) AS STATIC SINGLE DIM yslow(0 TO 255) AS STATIC SINGLE DIM zslow(0 TO 255) AS STATIC SINGLE LOCAL i AS LONG STATIC slnr AS LONG #IF %DEF(%g_NiDAQmx) IF ISFALSE Task(%Faust_Dop).tog THEN IF ISFALSE Task(%Faust_Dop).hParam THEN DIM TaskParamLabels(0 TO 1) AS STATIC ASCIIZ * 8 TaskParamLabels(0) = "xyz" ' slider links=x-vektor, midden = y vektor, rechts = z vektor TaskParamLabels(1) = "fms" ' slider links= fast data, midden = medium, rechts = slow (4") MakeTaskParameterDialog %Faust_Dop,2,Slider(),0,UDctrl(),TaskParamLabels() ' 2 sliders! END IF IF ISFALSE slnr THEN slnr = TaskEX(%Faust_Dop).SliderNumbers(0) END IF xamax = %False yamax = %False zamax = %False 'get the pointer to the doppler structure in g_nxh" ' cptr = GetProcAddress(gh.gnh, "GETDOPPLERPOINTER") ' CALL DWORD cptr USING GetDopplerPointer TO p ' if returns p = 0, then it crashes... ' pDoppler = p - now global ' fast buffers: 1024S/s - 250ms timeframe DIM xbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pxfast DIM ybuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pyfast DIM zbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pzfast ' medium time buffers: 256 S/s - 1 s timeframe DIM xmbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pxm DIM ymbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pym DIM zmbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pzm ' slow time buffers: 64 S/s - 4 s timeframe DIM xsbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pxslow DIM ysbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pyslow DIM zsbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pzslow ' @pDoppler.dta = 4 ' amplitude integration depth ' prepare a hanning window data array of 256 elements: MAT han()= CON(1) ' set all elements to 1 'if han(10) <> 1! then warning "Hanning error" - ok HanningWindow Han() ' now apply the window to obtain a normalised array 'warning "Han's=" & str$(Han(40)) & STR$(Han(128)) & str$(Han(200)) 'ok Task(%Faust_Dop).tog = %True END IF ' display the wave data in the melody window ' first reduce all data to single (to improve this, we need a display function taking doubles) FOR i = 0 TO 255 xfast(i) = xbuf(i) ' fast data yfast(i) = ybuf(i) zfast(i) = zbuf(i) xmed(i) = xmbuf(i) ' medium data - convert to singles ymed(i) = ymbuf(i) zmed(i) = zmbuf(i) xslow(i) = xsbuf(i) ' slow data yslow(i) = ysbuf(i) zslow(i) = zsbuf(i) NEXT i IF gh.melpat THEN SELECT CASE slider(slnr).value CASE < 42 ' display x-buffer SELECT CASE slider(slnr+1).value CASE < 42 ' fast data MAT arr()= (0.5) * xfast() ShowNormArray gh.melpat,arr() binsize = 4 ' 4Hz tot 512 Hz CASE > 84 ' slow data buffer MAT arr()= (0.5) * xslow() ShowNormArray gh.melpat,arr() binsize = 0.25 CASE ELSE ' medium data buffer (1 sec.) MAT arr()= (0.5) * xmed() ShowNormArray gh.melpat,arr() binsize = 1 END SELECT CASE > 84 ' display z-buffer SELECT CASE slider(slnr+1).value CASE < 42 ' fast data MAT arr()= (0.5) * zfast() ShowNormArray gh.melpat,arr() binsize = 4 CASE > 84 ' slow data buffer MAT arr()= (0.5) * zslow() ShowNormArray gh.melpat,arr() binsize = 0.25 CASE ELSE ' medium data buffer (1 sec.) MAT arr()= (0.5) * zmed() ShowNormArray gh.melpat,arr() binsize = 1 END SELECT CASE ELSE ' display y buffer SELECT CASE slider(slnr+1).value CASE < 42 ' fast data MAT arr()= (0.5) * yfast() ShowNormArray gh.melpat,arr() binsize = 4 CASE > 84 ' slow data buffer MAT arr()= (0.5) * yslow() ShowNormArray gh.melpat,arr() binsize = 0.25 CASE ELSE ' medium data buffer (1 sec.) MAT arr()= (0.5) * ymed() ShowNormArray gh.melpat,arr() binsize = 1 END SELECT END SELECT END IF ' check accelleration range: IF @pDoppler.xac > xamax THEN xamax = @pDoppler.xac IF @pDoppler.yac > yamax THEN yamax = @pDoppler.yac IF @pDoppler.zac > zamax THEN zamax = @pDoppler.zac SetDlgItemText gh.Cockpit, %GMT_MSG1, "Aac= " & FORMAT$(xamax,"0.000") & " " & FORMAT$(yamax,"0.000") & " " & FORMAT$(zamax,"0.000") ' check amplitude range: ' if @pDoppler.xa > xamax then xamax = @pDoppler.xa ' if @pDoppler.ya > yamax then yamax = @pDoppler.ya ' if @pDoppler.za > zamax then zamax = @pDoppler.za ' SetDlgItemText gh.Cockpit, %GMT_MSG1, "SMax= " & FORMAT$(xamax,"0.000") & " " & FORMAT$(yamax,"0.000") & " " & FORMAT$(zamax,"0.000") ' show calculated amplitudes: ' SetDlgItemText gh.Cockpit, %GMT_MSG1, "Amps= " & FORMAT$(@pDoppler.xa,"0.000") & " " & FORMAT$(@pDoppler.ya,"0.000") & " " & FORMAT$(@pDoppler.za,"0.000") ' show calculated frequency: SetDlgItemText gh.Cockpit, %GMT_MSG2, "Freqs= " & STR$(@pDoppler.xf) & " " & STR$(@pDoppler.yf) & " " & STR$(@pDoppler.zf) '------------------------------------------------------- 'alternative approach: do the FFT on 256 samples: DIM spx(0 TO 127)AS STATIC SINGLE ' 0-127 should be enough MAT arr() = (2) * arr() ' = arr() + arr() ' renormalize Hanningwindow arr() ' - instead of calling this everytime, it's much faster to do: ' MAT arr() = arr() * Han() '- but this seems not working... ' probably because of the same array in left and right part of the equation DFT arr(), spx() ' using the fast buffer data, this is 0.25 seconds ==> each band is 4 Hz wide (4 - 512 Hz) ' using the medium buffer data, this is 1 seconds ==> each band is 1 Hz wide (1-128 Hz) ' using the slow buffer data, this is 4 seconds ==> each band is 0.25Hz wide (0.25 - 32Hz) ' this slow buffer gives tempo indications: MM15 to MM1920 ' the tempo bands are: MM15, MM30, MM45, MM60, MM75, MM90, MM105, MM120, MM135... IF gh.harvel THEN ShowNormArray gh.harvel, spx() ' gh.spec 'spx has 128 frequency bins END IF ' find the fundamental speed of movement ' second attempt, using our sorting procedure in g_indep. STATIC SrtSpec AS Spectrum128SingleType LOCAL maxfreq AS SINGLE maxfreq = SortDFT (spx(), binsize, SrtSpec) '(dftarr() AS SINGLE, binsize AS SINGLE,sp AS Spectrum128SingleType IF maxfreq THEN Task(%Faust_Test_DFTmap).freq = ((Task(%Faust_Test_DFTmap).freq * 3) + maxfreq) / 4 IF ISFALSE Task(%Faust_Test_DFTmap).swit THEN starttask %Faust_Test_DFTmap END IF ELSE IF Task(%Faust_Test_DFTmap).swit THEN stoptask %Faust_Test_DFTmap END IF END IF Task(%Faust_Test_DFTmap).level = SrtSpec.pow(0) * 127 #ENDIF END SUB SUB Faust_FFT_Test ' integrated in above proc. ' test DFT task STATIC cnt AS DWORD IF ISFALSE Task(%Faust_FFT).tog THEN ' medium time buffers: 256 S/s - 1 s timeframe DIM xmbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pxm DIM ymbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pym DIM zmbuf(0 TO 255) AS STATIC DOUBLE AT @pDoppler.pzm cnt = 0 ' prepare a hanning window data array of 256 elements: DIM han(255) AS STATIC DOUBLE MAT han()= CON(1) ' set all elements to 1 HanningWindow_Dbl Han() ' now apply the window to obtain a normalised array DIM arr(255) AS STATIC DOUBLE DIM spx(128) AS STATIC DOUBLE DIM spy(128) AS STATIC DOUBLE DIM spz(128) AS STATIC DOUBLE Task(%Faust_FFT).freq = 100 ' als dit niet crasht... Task(%Faust_FFT).tog = %True END IF SELECT CASE cnt MOD 3 CASE 0 MAT arr() = xmbuf() * Han() DFT_Dbl arr(), spx() CASE 1 MAT arr() = ymbuf() * Han() DFT_Dbl arr(), spy() CASE 2 MAT arr() = zmbuf() * Han() DFT_Dbl arr(), spz() END SELECT INCR cnt END SUB SUB Faust_Test_DFTmap () ' mag weg 2014 'Task(%Faust_Test_DFTmap).freq = mapped on DFT STATIC cnt AS LONG mPlay Snar.channel, 60 + cnt, MIN(Task(%Faust_Test_DFTmap).level* 5, 127) INCR cnt IF cnt > 12 THEN cnt = %False END SUB SUB F_X_Vekt () ' %FxV STATIC note AS INTEGER STATIC oldnote AS INTEGER STATIC oldhelinote AS INTEGER STATIC cnt AS INTEGER IF ISFALSE Task(%Fxv).tog THEN IF ISFALSE note THEN note = 58 MM_Ob_On MM_Heli_On cnt = %False Task(%Fxv).tog = %True END IF 'test @pDoppler.xa, @pDoppler.xf, @pDoppler.xac IF INT(@pDoppler.xa * 127) THEN 'note = note + 1 + (@pDoppler.xac) note = note + (SQR(RND(1)) + @pDoppler.xac) IF note > 93 THEN note = 58 IF note < 58 THEN note = 58 mPlay Ob.channel, note, MIN(@pDoppler.xa * 256,127) oldnote = note IF ISFALSE cnt MOD 3 THEN mPlay Heli.channel, note - 24, MIN(@pDoppler.xa * 150, 127) oldhelinote = note - 24 ELSE IF oldhelinote THEN noteoff heli.channel, oldhelinote oldhelinote = %False END IF END IF Task(%Fxv).freq = MAX(@pDoppler.xf / 4, 1.5) '0.25) ' scaling op xf uitzoeken. ? SQR INCR cnt ELSE IF oldnote THEN NoteOff Ob.channel, oldnote oldnote = %False END IF IF oldhelinote THEN NoteOff Heli.channel, oldhelinote oldhelinote = %False END IF Task(%Fxv).freq = 100 ' make it very responsive END IF END SUB SUB F_y_Vekt () '%FyV STATIC note AS INTEGER STATIC oldnote AS INTEGER STATIC oldbrdnote AS INTEGER STATIC cnt AS DWORD IF ISFALSE Task(%Fyv).tog THEN IF ISFALSE note THEN note = 24 MM_Autosax_On MM_Bourdonola_On cnt = %False Controller Autosax.channel, 7, 120 Controller Autosax.channel, 17,120 Task(%Fyv).tog = %True EXIT SUB END IF IF INT(@pDoppler.ya * 127) THEN 'note = note + 1 + (@pDoppler.yac) note = note + (SQR(RND(1)) + @pDoppler.yac) IF note > 86 THEN note = 24 IF note < 24 THEN note = 24 mPlay Autosax.channel, note, MIN(@pDoppler.ya * 256,127) oldnote = note IF (note > 35) AND (note < 62) THEN IF ISFALSE cnt MOD 3 THEN IF oldbrdnote THEN NoteOff Bourdonola.channel, oldbrdnote oldbrdnote = %False END IF mPlay Bourdonola.channel, note, 64 oldbrdnote = note END IF END IF Task(%Fyv).freq = MAX(@pDoppler.yf / 4,1.5) '0.25) INCR cnt ELSE IF oldnote THEN Noteoff Autosax.channel, oldnote oldnote = %False END IF IF oldbrdnote THEN Noteoff Bourdonola.channel, oldbrdnote oldbrdnote = %False END IF Task(%Fyv).freq = 101 END IF END SUB SUB F_Z_Vekt () ' %FzV STATIC note AS INTEGER STATIC oldnote AS INTEGER STATIC oldsonote AS INTEGER STATIC cnt AS DWORD IF ISFALSE task(%Fzv).tog THEN IF ISFALSE note THEN note = 58 MM_Korn_On MM_So_On mPlay So.channel, 49,127 mPlay So.channel, 50,127 mPlay So.channel, 51, 127 cnt = %False Controller So.channel, 1, 25 Controller So.channel, 7, 100 Controller Korn.channel, 17, 127 Task(%Fzv).tog = %True EXIT SUB END IF IF INT(@pDoppler.za * 127) THEN 'note = note + 1 + (@pDoppler.zac) note = note + (SQR(RND(1)) + (@pDoppler.zac)) ' to be tested: is it still rising? IF note > 90 THEN note = 58 IF note < 58 THEN note = 55 mPlay Korn.channel, note, MIN(@pDoppler.za * 255,127) oldnote = note IF ISFALSE cnt MOD 3 THEN IF note < 47 + 36 THEN mPlay So.channel, note - 36, MIN(@pDoppler.za * 150, 127) oldsonote = note - 36 ELSE IF oldsonote THEN NoteOff So.channel, oldsonote oldsonote = %False END IF END IF END IF Task(%Fzv).freq = MAX(@pDoppler.zf / 4, 1.5) '0.25) INCR cnt ELSE IF oldnote THEN NoteOff Korn.channel, oldnote oldnote = %False END IF IF oldsonote THEN NoteOff So.channel, oldnote oldsonote = %False END IF Task(%Fzv).freq = 99 END IF END SUB SUB F_X_Vekt_Stop () MM_Ob_Off MM_Heli_Off END SUB SUB F_Y_Vekt_Stop () MM_Autosax_Off () MM_Bourdonola_Off END SUB SUB F_Z_Vekt_Stop () MM_So_Off MM_Korn_Off END SUB SUB Butoh_Fight () ' test for accelleration data mapping ' collision detection code: virtual drumming ' gwr. 10.07.2009 ' to avoid double triggering, we have to implement a death-time of ca. 20ms. after each trigger ' hence the tx,ty,tx timing variables. ' This coding dates from before we has the gesture type up and working. ' it could be rewritten accordingly. ' 08.06.2014: Called from Dance_end as a quick-and-dirty ending... ' 09.06.2014: Rehearsed with Dominica Eyckmans. DIM xp(0 TO 3) AS STATIC SINGLE DIM yp(0 TO 3) AS STATIC SINGLE DIM zp(0 TO 3) AS STATIC SINGLE STATIC slnr AS DWORD STATIC tx AS DWORD ' death time in milliseconds STATIC ty AS DWORD STATIC tz AS DWORD IF ISFALSE Task(%Faust_Fight).tog THEN IF ISFALSE Task(%Faust_Fight).hParam THEN DIM TaskParamLabels(0 TO 2) AS STATIC ASCIIZ * 8 TaskParamLabels(0) = "f-min" ' minimum required speed of movement - set to 70 TaskParamLabels(1) = "a-min" ' minimum required amplitude - set to 20 TaskParamLabels(2) = "t-death" ' dode tijd na trigger in ms MakeTaskParameterDialog %Faust_Fight,3,Slider(),0,UDctrl(),TaskParamLabels() ' 2 sliders! END IF IF ISFALSE slnr THEN slnr = TaskEX(%Faust_Fight).SliderNumbers(0) END IF MM_Simba_On MM_Troms_On MM_Psch_On MM_Thunderwood_On Task(%Faust_Fight).freq = 64 Task(%Faust_Fight).tog = %True Noteoff simba.channel, 0 NoteOff simba.channel, 1 tx = timegettime -20 ty = timegettime -20 tz = timegettime -20 EXIT SUB END IF ARRAY DELETE xp(), @pDoppler.xac ARRAY DELETE yp(), @pDoppler.yac ARRAY DELETE zp(), @pDoppler.zac IF timegettime > tx THEN ' dode tijd moet verstreken zijn IF @pDoppler.xa * 1000 > slider(slnr+1).value THEN ' er moet een mimimale bewegingshoeveelheid zijn IF @pDoppler.xf > slider(slnr).value THEN ' er moet een minimale snelheid zijn ' acceleratiepiekdetektor: ' we kijken naar een maximum voor vertraging, botsing dus. ' we bekijken telkens 4 samples IF SGN(xp(2)) < 0 THEN ' vertraging! ' strenger zou zijn te eisen dat alle waarden, behalve de laatste, negatief zijn. IF (xp(0) >= xp(1)) AND (xp(1) > xp(2)) AND (xp(2) < xp(3)) THEN ' er moet een tekenwisseling zijn SELECT CASE ABS(xp(2)) CASE < 1 mPlay Troms.channel, 44,MIN(@pDoppler.xa * 256, 127) mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) CASE < 2 mPlay Troms.channel, 41,MIN(@pDoppler.xa * 256, 127) mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) CASE < 3 mPlay Troms.channel, 38,MIN(@pDoppler.xa * 256, 127) mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) CASE < 4 mPlay Troms.channel, 34,MIN(@pDoppler.xa * 256, 127) mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) CASE < 5 mPlay Troms.channel, 30,MIN(@pDoppler.xa * 256, 127) mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) CASE < 6 mPlay Troms.channel, 24,MIN(@pDoppler.xa * 256, 127) mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) CASE ELSE mPlay Troms.channel, 48, MIN(@pDoppler.xa * 256, 127) ' cymbal mPlay Snar.channel, 60 + ABS(xp(2)), MIN(@pDoppler.xa * 256, 127) END SELECT tx = timegettime + 20 END IF END IF END IF END IF END IF IF timegettime > ty THEN IF @pDoppler.ya * 1000 > slider(slnr+1).value THEN IF @pDoppler.yf > slider(slnr).value THEN IF SGN(yp(2)) < 0 THEN IF (yp(0) >= yp(1)) AND (yp(1) > yp(2)) AND (yp(2) < yp(3)) THEN SELECT CASE ABS(yp(2)) CASE < 1 mPlay Simba.channel, 60 , MIN(@pDoppler.ya * 256, 127) CASE < 2 mPlay Simba.channel, 61 , MIN(@pDoppler.ya * 256, 127) CASE < 3 mPlay Simba.channel, 62 , MIN(@pDoppler.ya * 256, 127) CASE < 4 mPlay Simba.channel, 63 , MIN(@pDoppler.ya * 256, 127) CASE < 5 mPlay Simba.channel, 72 , MIN(@pDoppler.ya * 256, 127) CASE < 6 mPlay Simba.channel, 73, MIN(@pDoppler.ya * 256, 127) CASE < 7 mPlay Simba.channel, 74 , MIN(@pDoppler.ya * 256, 127) CASE < 8 mPlay Simba.channel, 80 , MIN(@pDoppler.ya * 256, 127) ' icebell CASE < 9 mPlay Simba.channel, 78 , MIN(@pDoppler.ya * 256, 127) ' casta1 CASE < 10 mPlay Simba.channel, 79 , MIN(@pDoppler.ya * 256, 127) ' casta 2 CASE ELSE mPlay Simba.channel, 77 , MIN(@pDoppler.ya * 256, 127) ' tambourine END SELECT ty = timegettime + 20 END IF END IF END IF END IF END IF IF timegettime > tz THEN IF @pDoppler.za * 1000 > slider(slnr+1).value THEN IF @pDoppler.zf > slider(slnr).value THEN IF SGN(zp(2)) < 0 THEN IF (zp(0) >= zp(1)) AND (zp(1) > zp(2)) AND (zp(2) < zp(3)) THEN SELECT CASE ABS(zp(2)) CASE < 1 mPlay Psch.channel, 72 , MIN(@pDoppler.za * 256, 127) CASE < 2 mPlay Psch.channel, 74 , MIN(@pDoppler.za * 256, 127) CASE < 3 mPlay Psch.channel, 76 , MIN(@pDoppler.za * 256, 127) mPlay Thunderwood.channel, 13, MIN(@pDoppler.za * 256, 127) CASE < 4 mPlay Psch.channel, 78, MIN(@pDoppler.za * 256, 127) mPlay Thunderwood.channel, 8, MIN(@pDoppler.za * 256, 127) CASE < 5 mPlay Psch.channel, 80, MIN(@pDoppler.za * 256, 127) mPlay Thunderwood.channel, 5, MIN(@pDoppler.za * 256, 127) CASE < 6 mPlay Psch.channel, 82 , MIN(@pDoppler.za * 256, 127) mPlay Thunderwood.channel, 2, MIN(@pDoppler.za * 256, 127) CASE < 7 mPlay Thunderwood.channel, 1, 127 CASE < 8 mPlay Springers.channel,72, 127 CASE < 9 mPlay Springers.channel, 73, 127 CASE < 10 mPlay Springers.channel, 79, 120 CASE < 11 mPlay Springers.channel, 80, 120 ' case < 12 'Play Springers.channel,36, 127 CASE ELSE mPlay Springers.channel, 36, 127 ' shaker 1: 72/73 ' shaker 2: 79/80 END SELECT tz = timegettime + 20 END IF END IF END IF END IF END IF END SUB SUB Butoh_Fight_Stop () MM_So_Off MM_Troms_Off MM_Simba_Off MM_Thunderwood_Off MM_Springers_Off END SUB