'************************************************** '* Code for Namuda Study #32 * '* march 2013 * '* Springs * '************************************************** ' robots used in this piece: ' ' - not yet ' ' ' ' ' ' ' 10.03.2013: first rehearsal with Dominica Eyckmans ' to do: Harma: some more wind, evt. double with HarmO ' Temblo: softer and more variation on the low blocks ' Toypi: better dynamics required and more speed modulation. Maybe add more polyphony. ' 16.03.2013: HarmO added, unison with Harmo in Sprins_Ether task ' RoboDomi_To, changed for 3 voices. ' Temblo dymanics halved on the low blocks ' 17.03.2013: second rehearsal with Dominica Eyckmans ' ether task changed such as to end in a very high register on Harmo and Harma. ' Slider implemented. ' Duration is now about 9 minutes. 'TYPE UniSonsType DWORD ' note AS INTEGER ' common note for all tasks in unisons (not used here) ' normbody AS SINGLE ' normspeed AS SINGLE ' wind AS SINGLE ' highly integrated normbody, for wind ctrl. ' vol AS SINGLE ' faster normbody integration for volume ctrl. on monophonic wind instruments. 'END TYPE ' 'GLOBAL Uni AS UnisonsType ' we reuse this one here!, its declared global in Uni.inc %Spring_Meta = 32 '17 - robobomi uses tasks 17,18,19 %Spring_Temblo = 33 '18 %Spring_ether = 34 %Spring_Chords = 35 %Spring_Xy = 36 DECLARE SUB Init_Spring2013 () DECLARE SUB Spring_Temblo () ' on edgy-smooth DECLARE SUB Spring_Meta () DECLARE SUB Spring_ether () ' on Freeze DECLARE SUB Spring_Chords () ' on collision DECLARE SUB Spring_Xy () ' on theatrical collision ' RoboBomi on acceleration ' RoboBomi_To on fixspeed SUB Init_Spring2013 () ClearTasks Task(%Spring_meta).naam = "Spring" Task(%Spring_meta).freq = 12 Task(%Spring_meta).cptr = CODEPTR(Spring_Meta) Task(%Spring_meta).flags = %False TaskEX(%Spring_meta).StopCptr = CODEPTR(Spring_Meta_End) Task(%Spring_Temblo).naam = "Temblo" Task(%Spring_Temblo).freq = 8 ' ? Task(%Spring_Temblo).cptr = CODEPTR(Spring_Temblo) Task(%Spring_Temblo).flags = %False ' include procedures from RoboBomi: (Namuda Study #7) Task(%Robobomi).naam = "Bomi" 'for the serial music production Task(%Robobomi).cptr = CODEPTR(Robobomi) ' in robodomi.inc Task(%Robobomi).freq = 8 Task(%Robobomi).flags = %False Task(%Robobomi).Har.vel = NUL$(128) TaskEX(%Robobomi).startcptr = CODEPTR(MM_Bomi_On) TaskEX(%Robobomi).stopcptr = CODEPTR(MM_Bomi_Off) Task(%Robobomi_To).naam = "Toypi" 'for the serial music production Task(%Robobomi_To).cptr = CODEPTR(Robobomi_To) ' in robodomi.inc Task(%Robobomi_To).freq = 2 Task(%Robobomi_To).flags = %False Task(%Spring_ether).naam = "ether" Task(%Spring_ether).cptr = CODEPTR(Spring_ether) Task(%Spring_ether).freq = 4 Task(%Spring_ether).flags = %False Task(%Spring_ether).Har.vel = NUL$(128) TaskEX(%Spring_ether).startcptr = CODEPTR(MM_Vibi_On) ' TaskEX(%Robobomi_Ae).stopcptr = CODEPTR(MM_Aeio_Off) Task(%Spring_chords).naam = "chords" Task(%Spring_chords).cptr = CODEPTR(Spring_Chords) Task(%Spring_chords).freq = 50 '8 Task(%Spring_chords).flags = %False TaskEX(%Spring_chords).stopcptr = CODEPTR(MM_Piano_Off) Task(%Spring_Xy).naam = "XyTeacol" Task(%Spring_Xy).cptr = CODEPTR(Spring_Xy) Task(%Spring_Xy).freq = 256 Task(%Spring_Xy).flags = %False 'borrowed code fromothe rpieces for streaming Task(%Rob1).naam = "Rob-1" 'Robodies 1 gwr - dominica - edgy-smooth properties on Harmo and Piano Task(%Rob1).cptr = CODEPTR(Rob1) Task(%Rob1).freq = 8 Task(%Rob1).flags = %False TaskEX(%Rob1).stopCptr = CODEPTR(Rob1_Stop) 'CODEPTR(Domi_Edgy_Trig_Stop) Task(%wv_slw).naam="slowdown" Task(%wv_slw).freq = 12 Task(%wv_slw).cptr = CODEPTR(waves_slowdown) TaskEx(%wv_slw).StopCptr = CODEPTR(waves_slowdown_stop) MM_Bomi_On %MM_WHITE MM_Krum_Off MM_Qt_Off Controller Harmo.channel, 68, 127 IF ISFALSE Task(%Gesture_Analyser).tog THEN starttask %Gesture_Analyser MM_Temblo_On END SUB SUB Spring_Meta () STATIC cnt, dur, t AS DWORD 'STATIC wit, geel, groen, blauw, rood AS LONG IF ISFALSE Task(%Spring_Meta).tog THEN uni.note = 60 ' not used here. RESET cnt, dur t = TimeGetTime uni.vol = gesture.flue_val(3) logfile "Namuda #32 start at:" & TIME$ Task(%Spring_Meta).tog = %True END IF dur = (TimeGetTime - t)/ 1000 ' in seconds uni.normbody = gesture.flue_val(3) uni.normspeed = 1 + MAX( MIN (gesture.fixspeed_val(3) / 100, 2), 0) ' loopt tussen 1 en 3 uni.wind = ((uni.wind * 31) + gesture.flue_val(3))/ 32 ' normalized uni.vol = ((uni.vol * 3) + gesture.flue_val(3))/4 ' more responsive for the volume controllers HarmO.ctrl(7) = 20 MM_HarmO_On Controller HarmO.channel, 7, 30 HarmO.ctrl(7) = 30 MM_Harma_On ' plaats voor scoring hier... END SUB SUB Spring_Meta_End () IF Task(%Spring_Temblo).tog THEN Stoptask %Spring_Temblo IF Task(%RoboBomi).tog THEN Stoptask %RoboBomi IF Task(%RoboBomi_To).tog THEN Stoptask %RoboBomi_To IF Task(%Spring_ether).tog THEN Stoptask %Spring_ether IF Task(%Spring_Chords).tog THEN Stoptask %Spring_Chords IF Task(%Spring_Xy).tog THEN StopTask %Spring_Xy logfile "Namuda #32 stop at" & TIME$ END SUB SUB Spring_Temblo () ' edgy-smooth on temblo STATIC edgy, smooth, ratchet AS LONG LOCAL noot1,noot2,noot3 AS LONG IF ISFALSE Task(%Spring_Temblo).tog THEN MM_Temblo_On Task(%Spring_Temblo).tog = %True END IF ' modulation in function of edgy-smooth properties IF gesture.edgy_dur(3) THEN 'if edgy, we select the high blocks noot1 = MIN(72 + (gesture.edgy(0) *12), 77) ' logfile "noot"+ STR$(noot1) + STR$(@pDoppler.xa * 127)+ STR$(@pDoppler.ya * 127)+ STR$(@pDoppler.za * 127) noot2 = MIN(72 + (gesture.edgy(1) * 12), 77) noot3 = MIN(72 + (gesture.edgy(2) * 12), 77) addnote2har Temblo.har(1), noot1, (@pDoppler.xa * 120) addnote2har Temblo.har(1), noot2, (@pDoppler.ya * 120) addnote2har Temblo.har(1), noot3, (@pDoppler.za * 120) Instrumplay Temblo edgy = %True ELSE edgy = %False 'note off's not required on Temblo END IF IF gesture.smooth_dur(3) THEN ' if smooth we select the low blocks addnote2har Temblo.har(1), MIN(60 + (gesture.smooth(0) * 12), 65), MIN(127, @pDoppler.xa * 180) addnote2har Temblo.har(1), MIN(60 + (gesture.smooth(1) * 12), 65), MIN(127, @pDoppler.ya * 180) addnote2har Temblo.har(1), MIN(60 + (gesture.smooth(2) * 12), 65), MIN(127, @pDoppler.za * 180) instrumplay Temblo smooth = %True ELSE smooth = %False END IF IF ISFALSE edgy AND ISFALSE smooth THEN 'ratchet mPlay Temblo.channel, 69, MAX(@pDoppler.xa, @pDoppler.ya, @pDoppler.za) * 127 ratchet = %True ELSE IF ratchet THEN NoteOff Temblo.channel, 69 RESET ratchet END IF END IF Task(%Spring_Temblo).freq = 4 * uni.normspeed END SUB SUB Spring_ether () ' derived from Robobomi_Ae () in RoboBomi, originally for Aeio 'should play the inverted krebs of the series very slowly, on , and ' near the end of thwe piece, after the piano section, the octave slider should be brought up! LOCAL i, oct AS LONG STATIC sens AS SINGLE STATIC it, oldnote, trig , cnt, vnote, HarmoWind, HarmaWind, slnr AS LONG IF ISFALSE Task(%Spring_ether).tog THEN DIM TaskParamLabels(0 TO 1) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" TaskParamLabels(1) = "Octave" IF ISFALSE Task(%Spring_ether).hParam THEN RESET slnr MakeTaskParameterDialog %Spring_Ether,2,Slider(),0,UDctrl(),TaskParamLabels() END IF IF ISFALSE slnr THEN slnr = TaskEX(%Spring_Ether).SliderNumbers(0) Slider(slnr).value = Task(%Spring_Ether).freq ' 2 on init SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value 'SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, 2 Slider(slnr+1).value = 0 'SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 0 ' low octave on init oct = Slider(slnr+1).value \ 30 END IF progchange harmo.channel, 15 DIM ser_4(11) AS STATIC INTEGER '= Ser_InvKrebs 'zelfde als berekend in RoboBomi Ser_4(0) = 61 : Ser_4(1) = 63 : Ser_4(2) = 58 : Ser_4(3) = 55 Ser_4(4) = 64 : Ser_4(5) = 65 : Ser_4(6) = 59 : Ser_4(7) = 62 Ser_4(8) = 57 : Ser_4(9) = 56 : Ser_4(10) = 60 : Ser_4(11) = 66 'initialisatie 'MM_Harma_On 'MM_HarmO_On HarmOwind = 12 Controller Harmo.channel, 70, %False ' 2' HarmO.ctrl(70) = %False Controller Harmo.channel, 71, 127 ' 8' diapason - notes 29-52 HarmO.ctrl(71) = 127 Controller Harmo.channel, 72, %False HarmO.ctrl(72) = %False Controller Harmo.channel, 73, %False '127 ' 4' HarmO.ctrl(73) = %False FOR i = 74 TO 78 IF i <> 76 THEN ' Controller Harmo.channel, i, %False HarmO.ctrl(i) = %False ELSE Controller Harmo.channel, i, 127 ' 8' forte - notes 53-101 HarmO.ctrl(i) = 127 END IF NEXT i 'Controller Harmo.channel, 76, 127 ' 8' forte - notes 53-101 'HarmO.ctrl(76) = 127 FOR i = 0 TO 11 Ser_4(i) = Ser_4(i) - 19 'transpose series to range 36-47 NEXT i Controller Vibi.channel, 64, 127 'sustain on sens = 0.05 RESET cnt Task(%Spring_ether).tog = %True END IF Task(%Spring_ether).freq = MAX(2, Slider(slnr).value /4) ' 2 - 32 oct = Slider(slnr+1).value \ 30 'try playing on freeze property IF (gesture.freeze(0)) OR (gesture.freeze(1)) OR (gesture.freeze(2)) THEN IF ISFALSE Trig THEN mPlay Harma.channel, Ser_4(it) + (oct * 12), 127 mPlay HarmO.channel, Ser_4(it) + (oct * 12), 64 'with Vibi: mPlay Vibi.channel, 60 + ((ser_4(it)) MOD 12) + ((oct\2)*12), MIN(MAX(25, uni.vol * 2 * 127),127) vnote = 60 + ((ser_4(it)) MOD 12) + ((oct\2)*12) oldnote = Ser_4(it) + (oct * 12) ' for use in other procedures: Task(%Spring_ether).har.vel = NUL$(128) addNote2Har Task(%Spring_ether).Har, oldnote,64 addNote2Har Task(%Spring_ether).Har, vnote, MIN(MAX(25, uni.vol * 127),127) ' vibi INCR it it = it MOD 12 Trig = %True ELSE 'IF cnt > 2 THEN 'IF RND(1) > 0.5 THEN ' Controller Aeio.channel, 100 + (oldnote MOD 12), 2 'END IF 'END IF 'we modulate the tone here... Controller Vibi.channel, 22, 32 + (uni.normbody * 64) END IF ELSE IF oldnote THEN NoteOff Harma.channel, oldnote NoteOff HarmO.channel, oldnote NoteOff Vibi.channel, vnote RESET oldnote, vnote delNote2Har Task(%Spring_ether).Har, oldnote delNote2Har Task(%Spring_ether).Har, vnote END IF RESET Trig END IF ' luchtdruksturing harmoniums: HarmOwind = MIN(MAX((uni.wind * 127),30),80) ' with *40 the range was 10 to 19. HarmaWind = MIN(MAX((uni.wind * 200),40),100) ' was minimum 20 IF Harma.ctrl(7) <> HarmaWind THEN Controller Harma.channel, 7,Harmawind Harma.ctrl(7) = HarmaWind END IF IF INT(HarmO.ctrl(7)) <> INT(HarmoWind) THEN Controller HarmO.channel, 7, HarmOWind HarmO.ctrl(7) = HarmoWind logfile "Harmowind = " & STR$(Harmowind) END IF END SUB SUB Spring_Chords () ' we know the note context from other pitched procs. by reading ' Task(%Spring_ether).Har(1) and Task(%Robobomi).Har(1) STATIC xtrig, ytrig, ztrig, strig, lites AS LONG STATIC sens AS SINGLE IF ISFALSE Task(%Spring_Chords).tog THEN sens = 1.4 '14/10 MM_Piano_On Task(%Spring_Chords).tog = %True END IF ' Piano.Har(1).vel = SumHar$ (Task(%Spring_ether).Har, Task(%Robobomi).Har) ' InstrumPlay Piano ' on collision, do something... IF Gesture.collision(0) > sens THEN IF ISFALSE xtrig THEN 'mPlay Troms.channel, MIN(24 + ((Gesture.collision(0))*4),48), MIN(Gesture.impact(0) * 127,127) 'mPlay Snar.channel, 73 + RND(1), MIN(Gesture.impact(0) * 127, 127) ' should be alternating 73-74 Piano.Har(1).vel = SumHar$ (Task(%Spring_ether).Har, Task(%Robobomi).Har) Task(%Spring_Chords).Har = Piano.Har(1) ' save the chord played InstrumPlay Piano xtrig = %True END IF ELSE IF xtrig THEN InstrumPlay Piano RESET xtrig END IF END IF IF Gesture.collision(1) > sens THEN IF ISFALSE ytrig THEN Task(%Spring_Chords).har.vel = SumHar$ (Task(%Spring_ether).Har, Task(%Robobomi).Har) Piano.Har(1).vel = SolveHar$(Task(%Spring_Chords).har, -1, 0.9) Task(%Spring_Chords).Har = Piano.Har(1) ' save the chord played InstrumPlay Piano 'mPlay Vacca.channel, MIN(48 + ((Gesture.collision(1)) *8),88), MIN(Gesture.impact(1) * 127, 127) ytrig = %true END IF ELSE IF yTrig THEN Instrumplay Piano RESET ytrig END IF END IF IF Gesture.collision(2) > sens THEN IF ISFALSE ztrig THEN ' avoiding multiple triggers on the same collision Task(%Spring_Chords).har.vel = SumHar$ (Task(%Spring_Chords).Har, Task(%Robobomi).Har) Piano.Har(1).vel = SolveHar$(Task(%Spring_Chords).har, -1, 0.9) Task(%Spring_Chords).Har = Piano.Har(1) ' save the chord played InstrumPlay Piano 'mPlay Thunderwood.channel, MIN(1 + ((Gesture.collision(2))*4),14), MIN(Gesture.impact(2) * 150, 127) 'mPlay Psch.channel, MIN(72 + ((Gesture.collision(2))*3),83), MIN(Gesture.impact(2) * 160, 127) ztrig = %True END IF ELSE RESET ztrig END IF IF gesture.collision(3) THEN IF ISFALSE lites THEN 'licht MM_So_On %MM_White MM_Troms_On %MM_Lights MM_Heli_On %MM_Lights mPlay Thunderwood.channel, 0, 127 lites = %True END IF IF gesture.collision(3) > sens THEN 'added 13.05 IF ISFALSE strig THEN mPlay Troms.channel, 48,MIN(Gesture.impact(3) * 180, 127) 'cimbaal strig = %True END IF END IF ELSE IF lites THEN 'licht uit. MM_So_Off %MM_White MM_Troms_Off %MM_Lights MM_Heli_Off %MM_Lights mPlay Thunderwood.channel, 0, %False RESET lites END IF IF strig THEN IF gesture.collision(3) > sens THEN RESET strig END IF END IF END IF END SUB SUB Spring_Xy () ' based on: SUB Domi_Theacol_Trig () in Namuda.inc, originally for Puff. ' this is the inverse of the collision detection code ' here we look only into the acceleration data on order to detect theatrical collisions. ' these collisions have decelleration until standstill, followed by acceleration. ' we may want to make the timeframe adjustable (now 100) ' the task frequency is 256Hz STATIC slnr, lites AS DWORD STATIC xtrig, ytrig, ztrig AS LONG LOCAL i AS DWORD STATIC sens AS SINGLE IF ISFALSE Task(%Spring_Xy).tog THEN sens = 1 MM_Xy_On 'start gesture_analyser IF ISFALSE Task(%Gesture_analyser).tog THEN starttask %Gesture_Analyser Task(%Spring_Xy).tog = %True END IF ' on theatrical collision, do something... IF gesture.theacol(0) > sens THEN IF ISFALSE xtrig THEN mPlay Xy.channel, MIN(Xy.Lowtes + ((gesture.theacol(0))*8),Xy.Hightes), MIN(gesture.impact(0) * 120,120) xtrig = %True END IF ELSE RESET xtrig END IF IF gesture.theacol(1) > sens THEN IF ISFALSE ytrig THEN mPlay Xy.channel, MIN(Xy.lowtes + ((gesture.theacol(1))*8),Xy.Hightes), MIN(gesture.impact(1) * 120,120) ytrig = %true END IF ELSE RESET ytrig END IF IF gesture.theacol(2) > sens THEN IF ISFALSE ztrig THEN ' avoiding multiple triggers on the same collision mPlay Xy.channel, MIN(Xy.Lowtes + ((gesture.theacol(2))*8),Xy.Hightes), MIN(gesture.impact(2) * 120,120) ztrig = %True END IF ELSE RESET ztrig END IF IF gesture.theacol(3) THEN IF ISFALSE lites THEN MM_Xy_On %MM_Lights lites = %True END IF ELSE IF lites THEN MM_Xy_Off %MM_Lights RESET lites END IF END IF END SUB