' ****************************************** ' * * ' * hardware test and evaluation code * ' ****************************************** ' 19.06.2004: module added to GMT ' 23.06.2004: installed on Putty for tests ' 24.06.2004: debug session on Hurdy ' PIC bugs: inverted switches and PWM operation. ' 26.06.2004: more test and measurement code added ' 28.06.2004: adapted to improved PIC code. ' 29.06.2004: code added for individual string tests. ' 01.07.2004: controllers added ' 04.07.2004: the way the strings are tuned should be communicated to the software ' suggestion: hurdy.ctrl(20) = 33 ' tuning for the low string ' hurdy.ctrl(21) = 45 ' tuning for the high string. ' Hurdy demo piece - start coding ' 05.07.2004: Further work on Aux Arbres - demo piece for Hurdy ' 06.07.2004: kl. hurdy controller window made for playing individual notes (use button to toggle window) ' 11.07.2004: hard & soft test session - with radar ' 21.07.2004: controllers for prepulse duration added. ' 05.08.2004: improvements and debug by kristof lauwers ' 09.10.2004: tuning changed. (33/50 instead of 33/45) ' 10.10.2004: PIC problems met Hurdy: does not listen to all notes off! ' 11.10.2004: further development of Aux Arbres: now for Hurdy, Ake, Piperola, Bourdonola ' 13.10.2004: coding session on 'Aux Arbres' ' 14.10.2004: ... Aux Arbres ' 16.10.2004: simple sync mechanism added to Aux Arbres. Fermata on Harmonic rhythm to be done. ' 17.10.2004: further work on Aux Arbres before we move it to the Faust compilation. ' 18.10.2004: Aux Arbres moved to Faust compilation. ' 04.02.2007: Revision of hurdy with electromagnetic string drives. ' test code for electromagnetic drive to be written. ' 11.02.2007: Hardware definitive mounting on instrument. Waiting for PIC program. Test code ready. ' 04.04.2007: Hardware debug sessie. Bugs in pic4 mikrokode. ' 30.10.2007: Debug and evaluation session. ' new controllers added on the wishlist for the pic specs. ' 09.11.2007: PIC4, PIC1 and PIC3 reprogrammed. ' 11.11.2007: Religionszwang added. - solo piece for Hurdy. ' to be done: transpose for Hurdysound.milow and .mihigh (optional) ' sliders for max. bow pressure. ' 12.11.2007: opbouw religionszwang verbeterd. ' midi implementation on PIC level: - kanaal 9 ' note on (144+k) : 40-63 for low string , velocity byte = bow pressure low string (pwm) - 1 = no pressure (for e-drive) ' 64-88 for high string ' 0 light left ' 1 light right ' note off (128+k) : 40-63 and 64-88 releases bow pressure but does not move the tangents! ' key pressure (160+k): 40-63 and 64-88 bow pressure modulation during notes being played ' only notes 40 and 64 are required, since we have only 2 note polyphony. ' ctrl 1 : prepressure pulse width for low string pusher ' ctrl 2 : prepressure pulse width for high string pusher ' ctrl 3 : pwm value for low string e-drive ' ctrl 4 : pwm value for high string e-drive ' ctrl 5 : 0 = ctrl 3 used for e drive, 1 = velo used for e drive, 2 = velo used for e-drive and pushers [10.2007] ' ctrl 6 : same meaning, but for the high string [10.2007] ' ctrl 7 : motor speed 0-127 ' ctrl 20: tuning of lowest string [2007] - pic4 [ value = 40 means no transposition] ' ctrl 21: tuning of highest string [2007] - pic4 [ value = 64 means no transposition] ' ctrl 22: e-bow multiplier value low string (flageolets): 0=1, 2= x2, 3=x3 etc... limited to 22 ' ctrl 23: e-bow multiplier value high string ' ctrl 64: felt dampers active (0) or inactive (1) ' ctrl 66: bow motor ON/OFF switch ' ctrl 67: direction of bow motor rotation switch ' ctrl 68: error reset switch, motor controller bow ' ctrl 69: e-drive on off switch for the low string driver ' ctrl 70: e-drive on off switch for the high string driver ' ctrl 120, 121 : not implemented on PIC level, but used to store the on/off conditions for the lights. ' ctrl 123: all notes off ' reserved controllers for software applications: ' ctrl 20: tuning of lowest string so, transposition = Hurdy.ctrl(20) - Hurdy.lowtes ' ctrl 21: tuning of highest string so, transposition = Hurdy.ctrl(21) - Hurdy.lowtes ' sysexes: ' - fingering lookup tables ( n tables, each 24 bit integers for each note) ' - prog 120= 1 tangent per note (setting for e-mechanism) ' - prog 121= 1 or 2 tangents per note (damping other string side) ' - prog 0 = combinatory tangents for motor drive string ' - frequency lookup tables ( n tables, each 128 frequencies with 0.05% precision) (we can use mHz, for 32 bit integers) %Hurdy_Low = 21 %Hurdy_High = 22 %Hurdy_Test = 23 %Hurdy_Lights = 24 %Hurdy_Motor = 25 %Hurdy_e_low = 27 %Hurdy_e_high = 28 %Hurdy_tune_low = 30 ' can also be used for tuning %Hurdy_tune_high = 31 ' kode voor demo-stukjes gwr: ' religionszwang: %Relig = 50 ' scoring task. This one should be started for the piece 'Religionszwang' %HurL = 51 %HurH = 52 %HurM = 53 ' motor task %HurPL = 54 ' low bow task %HurPH = 55 ' high bow task 'een canon voor Hurdy %Hur = 57 ' not ready yet %HurMeta = 58 ' following type used for forced religion, Religionszwang ' after change in PICS with lookups for physical reality, this same code will ' perform the piece 'Scientia vincere tenebras'... TYPE HurdySounds DWORD lownote AS CUR ' werkelijk klinkende noot highnote AS CUR ' werkelijk klinkende noot lowfreq AS SINGLE ' werkelijke frekwentie highfreq AS SINGLE ' werkelijke frekwentie diftone AS SINGLE ' verschiltoon in Hz milow AS BYTE ' uitgestuurde midi noot, zonder transpositie, dus in bereik 40-63 mihigh AS BYTE ' uitgestuurde midi noot, zonder transpositie, dus in bereik 64-88 END TYPE GLOBAL HurdySound AS Hurdysounds DECLARE FUNCTION InitHurdy () AS LONG DECLARE SUB Hurdy_Test () ' tests all strings DECLARE SUB Hurdy_LoLim_UD1 () ' callback DECLARE SUB Hurdy_HiLim_UD2 () ' callback DECLARE SUB Hurdy_Dir_UD3 () ' callback DECLARE SUB Hurdy_LowPressSlider () ' callback for aftertouch DECLARE SUB Hurdy_HighPressSlider () ' id., high string DECLARE SUB Hurdy_Low () ' test low string DECLARE SUB Hurdy_Low_LoLim_UD1 () DECLARE SUB Hurdy_Low_HiLim_UD2 () DECLARE SUB Hurdy_Low_Prepress_UD3 () DECLARE SUB Hurdy_High () ' test high string DECLARE SUB Hurdy_High_LoLim_UD1 () DECLARE SUB Hurdy_High_HiLim_UD2 () DECLARE SUB Hurdy_High_Prepress_UD3 () DECLARE SUB hurdy_e_low () DECLARE SUB Hurdy_e_Low_LoLim_UD1 () DECLARE SUB Hurdy_e_Low_HiLim_UD2 () DECLARE SUB Hurdy_Sustain_UD3 () ' ctrl 64 DECLARE SUB hurdy_e_high () DECLARE SUB Hurdy_e_High_LoLim_UD1 () DECLARE SUB Hurdy_e_High_HiLim_UD2 () DECLARE SUB Hurdy_tune_low () DECLARE SUB Hurdy_tune_high () 'DECLARE SUB Hurdy_AllOff () - now MM_Hurdy_Off in g_mm.inc DECLARE SUB Hurdy_Lights () ' light test DECLARE SUB Hurdy_Motor () ' test motor PIC DECLARE SUB Hurdy_onoff_UD1 () ' motor task UD callback DECLARE SUB Hurdy_dir_UD2 () ' cw/cww DECLARE SUB Hurdy_Error_UD3 () ' error reset DECLARE SUB Hurdy_Motorslider_M () ' callback motor task, motor speed slider ' testkode voor control room: DECLARE SUB Hurdy_controlroom DECLARE CALLBACK FUNCTION CB_Hurdy_Controlroom GLOBAL hwCtrlHurdy AS LONG GLOBAL hMotorTrackBar AS LONG GLOBAL hLeftPressTrackBar AS LONG GLOBAL hLeftPrePressTrackBar AS LONG GLOBAL hRightPressTrackBar AS LONG GLOBAL hRightPrePressTrackBar AS LONG GLOBAL hEDriveLeft AS LONG GLOBAL hEdriveRight AS LONG '------------------------------ ' demo hurdy stukje gwr: DECLARE SUB HurCan () ' %Hur DECLARE SUB HurCanMeta () ' %Hurmeta ' "Religionszwang" 11.11.2007 DECLARE SUB Religionszwang () ' %Relig DECLARE SUB HurCanL () ' %HurL DECLARE SUB HurCanH () ' %HurH DECLARE SUB HurMot () ' %HurM DECLARE SUB HurPL () ' %HurPL DECLARE SUB HurPH () ' %HurPH DECLARE SUB Religionszwang_Stop () FUNCTION InitHurdy () AS LONG Task(%Hurdy_Low).naam = "" Task(%Hurdy_Low).cptr = CODEPTR(Hurdy_Low) Task(%Hurdy_Low).freq = 2 Task(%Hurdy_Low).flags = %False Task(%Hurdy_High).naam = "" Task(%Hurdy_High).cptr = CODEPTR(Hurdy_High) Task(%Hurdy_High).freq = 2 Task(%Hurdy_High).flags = %False Task(%Hurdy_Test).naam = "" Task(%Hurdy_Test).cptr = CODEPTR(Hurdy_Test) Task(%Hurdy_Test).freq = 2 Task(%Hurdy_Test).flags = %False Task(%Hurdy_Lights).naam = "HurLites" Task(%Hurdy_Lights).cptr = CODEPTR(Hurdy_Lights) Task(%Hurdy_Lights).freq = 2 Task(%Hurdy_Lights).flags = %False Task(%Hurdy_motor).naam = "HurMotor" Task(%Hurdy_motor).cptr = CODEPTR(Hurdy_Motor) Task(%Hurdy_motor).freq = 10 Task(%Hurdy_motor).flags = %False Task(%Hurdy_e_Low).naam = "" Task(%Hurdy_e_Low).cptr = CODEPTR(Hurdy_e_Low) Task(%Hurdy_e_Low).freq = 2 Task(%Hurdy_e_Low).flags = %False Task(%Hurdy_e_High).naam = "" Task(%Hurdy_e_High).cptr = CODEPTR(Hurdy_e_High) Task(%Hurdy_e_High).freq = 2 Task(%Hurdy_e_High).flags = %False Task(%Hurdy_tune_Low).naam = "" Task(%Hurdy_tune_Low).cptr = CODEPTR(Hurdy_tune_Low) Task(%Hurdy_tune_Low).freq = 2 Task(%Hurdy_tune_Low).flags = %False Task(%Hurdy_tune_High).naam = "" Task(%Hurdy_tune_High).cptr = CODEPTR(Hurdy_tune_High) Task(%Hurdy_tune_High).freq = 2 Task(%Hurdy_tune_High).flags = %False ' demo stukjes: ' demo hurdy stukje gwr: Task(%Hur).naam = "HurCan" Task(%Hur).cptr = CODEPTR(HurCan) Task(%Hur).freq = 20 Task(%Hur).flags = %False ' religionszwang: ----------------------------- Task(%Relig).naam = "Religie" Task(%Relig).freq = 1 Task(%Relig).cptr = CODEPTR(Religionszwang) Task(%Relig).flags = %False TaskEX(%Relig).stopcptr = CODEPTR(Religionszwang_stop) Task(%HurL).naam = "HurCanL" Task(%HurL).cptr = CODEPTR(HurCanL) Task(%HurL).freq = 10 Task(%HurL).flags = %False Task(%HurH).naam = "HurCanH" Task(%HurH).cptr = CODEPTR(HurCanH) Task(%HurH).freq = 10 Task(%HurH).flags = %False Task(%HurM).naam = "HurMot" Task(%HurM).cptr = CODEPTR(HurMot) Task(%HurM).freq = 2 Task(%HurM).flags = %False Task(%HurPL).naam = "BowLow" Task(%HurPL).cptr = CODEPTR(HurPL) Task(%HurPL).freq = 2 Task(%HurPL).flags = %False Task(%HurPH).naam = "BowHigh" Task(%HurPH).cptr = CODEPTR(HurPH) Task(%HurPH).freq = 2 Task(%HurPH).flags = %False '----------------------------------------------- Task(%Hurmeta).naam = "HurScr" Task(%Hurmeta).cptr = CODEPTR(HurCanMeta) Task(%Hurmeta).freq = 2 Task(%Hurmeta).flags = %False ' -------------------------------------------------------- ButnSW(10).tag0 = "HurdyCtrl tog" ButnSW(10).tag1 = "HurdyCtrl tog" ButnSW(10).cptr = CODEPTR(Hurdy_Controlroom) ' the tuning is read from inifile and sent to Hurdy in the Init_MM procedure. ' Hurdy.ctrl(20) = 33 ' low string transposes -7 (40 sounds 33) ' Hurdy.ctrl(21) = 50 ' high string transposes -14 (64 sounds 50) ' Controller Hurdy.channel, 20, 33 ' Controller Hurdy.channel, 21, 50 FUNCTION = %True END FUNCTION SUB Hurdy_Test () STATIC i AS DWORD STATIC slnr AS DWORD STATIC oldnote AS INTEGER STATIC lowpress AS BYTE STATIC highpress AS BYTE IF ISFALSE Task(%Hurdy_Test).tog THEN DIM TaskParamLabels(0 TO 5) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" ' slider TaskParamLabels(1) = "LoPres" ' slider - ctrl 1 TaskParamlabels(2) = "HiPres" ' slider - ctrl 2 TaskParamLabels(3) = "LowLim" ' UD TaskParamLabels(4) = "HiLim" ' uD TaskParamLabels(5) = "Dir" ' UD IF ISFALSE Task(%Hurdy_Test).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_Test,3,Slider(),3,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_Test).SliderNumbers(0) Slider(slnr+1).cptr = CODEPTR(Hurdy_LowPressSlider) Slider(slnr+2).cptr = CODEPTR(Hurdy_HighPressSlider) UDctrl(TaskEX(%Hurdy_Test).UpdownNumbers(0)).cptr = CODEPTR(Hurdy_LoLim_UD1) ' lowest note UDctrl(TaskEX(%Hurdy_Test).UpdownNumbers(1)).cptr = CODEPTR(Hurdy_HiLim_UD2) ' highest note UDctrl(TaskEX(%Hurdy_Test).UpdownNumbers(2)).cptr = CODEPTR(Hurdy_Dir_UD3) UDctrl(TaskEX(%Hurdy_Test).UpDownNumbers(0)).value = Hurdy.lowtes UDctrl(TaskEX(%Hurdy_Test).UpDownNumbers(1)).value = Hurdy.hightes i = UDctrl(TaskEX(%Hurdy_Test).UpDownNumbers(0)).value '40 Task(%Hurdy_Test).freq = 2 Slider(slnr).value = Task(%Hurdy_Test).freq Slider(slnr+1).value = %False Slider(slnr+2).value = %False SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 0 ' pressure off, on init. SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, 0 END IF i = Hurdy.lowtes Task(%Hurdy_Test).tog = %True END IF lowpress = Slider(slnr+1).value ' may send aftertouch to PWM pushers. highpress = Slider(slnr+2).value IF oldnote THEN Play Hurdy.channel, oldnote, 0 oldnote = %False END IF IF i < 64 THEN Play Hurdy.channel, i, lowpress ' old: if lowpress = 1, the e-bowing will be active ELSE Play Hurdy.channel, i, highpress END IF oldnote = i INCR i IF i > UDctrl(TaskEX(%Hurdy_Test).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Hurdy_Test).UpDownNumbers(0)).value Task(%Hurdy_Test).freq = 8 * (Slider(slnr).value) / 128! IF Task(%Hurdy_Test).freq < 0.1 THEN Task(%Hurdy_Test).freq = 0.1 END SUB SUB Hurdy_Low () STATIC i AS DWORD STATIC slnr AS DWORD STATIC oldnote AS INTEGER STATIC press AS BYTE STATIC cnt AS BYTE IF ISFALSE Task(%Hurdy_Low).tog THEN DIM TaskParamLabels(0 TO 5) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" ' slider MM tempo TaskParamLabels(1) = "Pres" ' slider TaskParamlabels(2) = "legato" ' slider - on / off proportie TaskParamLabels(3) = "LowLim" ' UD TaskParamLabels(4) = "HiLim" ' uD TaskParamLabels(5) = "PrePres" ' UD ctrl 1 IF ISFALSE Task(%Hurdy_low).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_Low,3,Slider(),3,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_Low).SliderNumbers(0) ' works via Hurdy.ctrl ' Slider(slnr+1).cptr = CODEPTR(Hurdy_LowPressSlider) ' sets Hurdy.ctrl(1) ' Slider(slnr+2).cptr = - no cptr, steers ON/OFF proportion UDctrl(TaskEX(%Hurdy_Low).UpdownNumbers(0)).cptr = CODEPTR(Hurdy_Low_LoLim_UD1) ' lowest note UDctrl(TaskEX(%Hurdy_Low).UpdownNumbers(1)).cptr = CODEPTR(Hurdy_Low_HiLim_UD2) ' highest note UDctrl(TaskEX(%Hurdy_Low).UpdownNumbers(2)).cptr = CODEPTR(Hurdy_Low_Prepress_UD3) UDctrl(TaskEX(%Hurdy_Low).UpDownNumbers(0)).value = Hurdy.lowtes i = UDctrl(TaskEX(%Hurdy_Low).UpDownNumbers(0)).value '40 Task(%Hurdy_Low).tempo = 60 Slider(slnr).value = Task(%Hurdy_low).tempo Slider(slnr+1).value = %False ' pressure Slider(slnr+2).value = %False ' legato / staccato SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 0 ' pressure off, on init. SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, 0 ' stacc. on init END IF i = Hurdy.lowtes Task(%Hurdy_low).tog = %True END IF press = Slider(slnr+1).value ' may send aftertouch to PWM pushers. IF oldnote THEN Play Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN Play Hurdy.channel, i, press oldnote = i INCR i IF i > UDctrl(TaskEX(%Hurdy_low).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Hurdy_low).UpDownNumbers(0)).value END IF BIT TOGGLE cnt, 0 Task(%Hurdy_low).tempo = MAX(Slider(slnr).value,1) ' ===> Period = 60/ tempo IF ISFALSE cnt THEN Task(%Hurdy_low).freq = 1 / ((1- (Slider(slnr+2).value / 128)) * (60 / Task(%Hurdy_low).tempo)) ' on freq. ELSE Task(%Hurdy_low).freq = 1 / ((Slider(slnr+2).value / 128) * (60 / Task(%Hurdy_low).tempo)) ' off freq. END IF END SUB SUB Hurdy_Low_LoLim_UD1 () ' controls the low limit of the note scale to be played on the low string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_low).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < Hurdy.lowtes THEN UDctrl(udnr).value = Hurdy.lowtes: noot = Hurdy.lowtes IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Hurdy_low).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Hurdy_Low_HiLim_UD2 () ' controls the high limit of the note scale to be played on the low string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_low).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 > 63 THEN UDctrl(udnr).value = 63 : noot = 63 SetDlgItemText Task(%Hurdy_low).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB Hurdy_Low_Prepress_UD3 () ' controls the duration of the preimpuls on the softshifts LOCAL value AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_low).UpDownNumbers(2) value = UDCtrl(udnr).value IF value < 1 THEN UDctrl(udnr).value = 0 : value = 0 IF value > 127 THEN UDctrl(udnr).value = 127 : value = 127 SetDlgItemText Task(%Hurdy_low).hparam, %GMT_TEXT0_ID + 18, "Pr=" & STR$(value) ModeMess Hurdy.channel, 1, value END SUB SUB Hurdy_High () STATIC i AS DWORD STATIC slnr AS DWORD STATIC oldnote AS INTEGER STATIC press AS BYTE STATIC cnt AS BYTE IF ISFALSE Task(%Hurdy_high).tog THEN DIM TaskParamLabels(0 TO 5) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" ' slider MM tempo TaskParamLabels(1) = "Pres" ' slider TaskParamlabels(2) = "legato" ' slider - on / off proportie TaskParamLabels(3) = "LowLim" ' UD1 TaskParamLabels(4) = "HiLim" ' uD2 TaskParamLabels(5) = "PrePress" ' ud3 IF ISFALSE Task(%Hurdy_high).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_high,3,Slider(),3,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_high).SliderNumbers(0) UDctrl(TaskEX(%Hurdy_high).UpdownNumbers(0)).cptr = CODEPTR(Hurdy_high_LoLim_UD1) ' lowest note UDctrl(TaskEX(%Hurdy_high).UpdownNumbers(1)).cptr = CODEPTR(Hurdy_high_HiLim_UD2) ' highest note UDctrl(TaskEX(%Hurdy_High).UpdownNumbers(2)).cptr = CODEPTR(Hurdy_high_Prepress_UD3 () UDctrl(TaskEX(%Hurdy_high).UpDownNumbers(0)).value = 64 i = UDctrl(TaskEX(%Hurdy_high).UpDownNumbers(0)).value Task(%Hurdy_high).tempo = 60 Slider(slnr).value = Task(%Hurdy_high).tempo Slider(slnr+1).value = %False ' pressure Slider(slnr+2).value = %False ' legato / staccato SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 0 ' pressure off, on init. SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, 0 ' staccato on init END IF i = Hurdy.lowtes + 24 Task(%Hurdy_high).tog = %True END IF press = Slider(slnr+1).value ' may send aftertouch to PWM pushers. IF oldnote THEN Play Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN Play Hurdy.channel, i, press oldnote = i INCR i IF i > UDctrl(TaskEX(%Hurdy_high).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Hurdy_high).UpDownNumbers(0)).value END IF BIT TOGGLE cnt, 0 Task(%Hurdy_high).tempo = MAX(Slider(slnr).value,1) ' ===> Period = 60/ tempo IF ISFALSE cnt THEN Task(%Hurdy_high).freq = 1 / ((1- (Slider(slnr+2).value / 128)) * (60 / Task(%Hurdy_high).tempo)) ' on freq. ELSE Task(%Hurdy_high).freq = 1 / ((Slider(slnr+2).value / 128) * (60 / Task(%Hurdy_high).tempo)) ' off freq. END IF END SUB SUB Hurdy_High_LoLim_UD1 () ' controls the low limit of the note scale to be played on the high string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_high).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < 64 THEN UDctrl(udnr).value = 64: noot = 64 IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Hurdy_high).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Hurdy_High_HiLim_UD2 () ' controls the high limit of the note scale to be played on the low string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_high).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 > Hurdy.hightes THEN UDctrl(udnr).value = Hurdy.hightes : noot = Hurdy.hightes SetDlgItemText Task(%Hurdy_high).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB Hurdy_High_Prepress_UD3 () ' controls the duration of the preimpuls on the softshifts LOCAL value AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_high).UpDownNumbers(2) value = UDCtrl(udnr).value IF value < 1 THEN UDctrl(udnr).value = 0 : value = 0 IF value > 127 THEN UDctrl(udnr).value = 127 : value = 127 SetDlgItemText Task(%Hurdy_high).hparam, %GMT_TEXT0_ID + 18, "Pr=" & STR$(value) ModeMess Hurdy.channel, 2, value END SUB SUB Hurdy_LoLim_UD1 () ' controls the low limit of the note scale to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_Test).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < Hurdy.lowtes THEN UDctrl(udnr).value = Hurdy.lowtes: noot = Hurdy.lowtes IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Hurdy_Test).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Hurdy_HiLim_UD2 () ' controls the high limit of the note scale to be played. LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_Test).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 > Hurdy.Hightes THEN UDctrl(udnr).value = Hurdy.hightes : noot = Hurdy.hightes SetDlgItemText Task(%Hurdy_Test).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB Hurdy_Dir_UD3 () LOCAL udnr AS DWORD LOCAL cwcww AS LONG udnr = TaskEX(%Hurdy_Test).UpdownNumbers(2) cwcww = UDCtrl(udnr).value IF cwcww < 1 THEN UDctrl(udnr).value = 0 : cwcww = UDctrl(udnr).value IF cwcww > 0 THEN UDctrl(udnr).value = 1 : cwcww = UDctrl(udnr).value IF Hurdy.ctrl(66) THEN ModeMess Hurdy.channel, 66, 0 ' motor OFF --- takes 5 seconds max. END IF ModeMess Hurdy.channel, 67, cwcww IF Hurdy.ctrl(66) THEN ModeMess Hurdy.channel, 66, 1 ' motor back ON END IF Hurdy.ctrl(67) = cwcww SetDlgItemText Task(%Hurdy_Test).hparam, %GMT_TEXT0_ID + 18, "cw=" & STR$(cwcww) END SUB SUB Hurdy_LowPressSlider () ' callback for aftertouch low string bow pressure LOCAL slnr AS DWORD slnr = TaskEX(%Hurdy_Test).SliderNumbers(2) KeyPress Hurdy.channel, 40, Slider(slnr).value ' 160+k, note, pressure 'Hurdy.ctrl(1) = Slider(slnr).value ' wrong - this is the prepulse controller! END SUB SUB Hurdy_HighPressSlider () ' callback for aftertouch high string bow pressure LOCAL slnr AS DWORD slnr = TaskEX(%Hurdy_Test).SliderNumbers(3) KeyPress Hurdy.channel, 64, Slider(slnr).value ' 160+k, note, pressure 'Hurdy.ctrl(2) = Slider(slnr).value ' wrong. This is prepulse controller END SUB SUB Hurdy_Lights () ' handled by PIC2 ' this seems to work as it should. 'STATIC light1 AS BYTE 'STATIC light2 AS BYTE STATIC cnt AS DWORD Task(%Hurdy_Lights).freq = 1 IF cnt MOD 5 THEN ' lang uit IF Hurdy.ctrl(120) THEN Play Hurdy.channel, 0, 0 ' linkerlamp, frontaal gezien. 'light1 = %False hurdy.ctrl(120) = %False END IF ELSE ' kort aan IF ISFALSE Hurdy.ctrl(120) THEN Play Hurdy.channel, 0, 127 'light1 = %True hurdy.ctrl(120) = %True END IF END IF IF cnt MOD 7 THEN IF Hurdy.ctrl(121) THEN Play Hurdy.channel, 1, 0 ' rechterlamp, frontaal gezien 'light2 = %False Hurdy.ctrl(121) = %False END IF ELSE IF ISFALSE Hurdy.ctrl(121) THEN Play Hurdy.channel, 1, 127 'light2 = %true Hurdy.ctrl(121) = %True END IF END IF INCR cnt END SUB SUB Hurdy_Motor () STATIC slnr AS DWORD ' this task does not send any midi. All action done via param. callbacks. ' test for operation of PIC2: ' this PIC receives Midi volume controllers, used to steer the motor frequency ' on reception of all notes OFF, the motor should stop. ' other controllers: 66 = motor ON/OFF switch ' 67 = direction of rotation ' 68 = error acknowledge switch IF ISFALSE Task(%Hurdy_Motor).tog THEN DIM TaskParamLabels(0 TO 3) AS ASCIIZ * 8 TaskParamLabels(0) = "Speed" TaskParamLabels(1) = "ON/OFF" TaskParamLabels(2) = "cwcww" ' 0/1 TaskParamLabels(3) = "Ack." ' 0/1 IF ISFALSE Task(%Hurdy_Motor).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_Motor,1,Slider(),3,UDctrl(),TaskParamLabels() ' change size of window manually! we have 1 slider and 3 UD's, which will not be visible... END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_Motor).SliderNumbers(0) Slider(slnr).cptr = CODEPTR(Hurdy_Motorslider_M) UDctrl(TaskEX(%Hurdy_Motor).UpdownNumbers(0)).cptr = CODEPTR(Hurdy_onoff_UD1) UDctrl(TaskEX(%Hurdy_Motor).UpdownNumbers(1)).cptr = CODEPTR(Hurdy_dir_UD2) UDctrl(TaskEX(%Hurdy_Motor).UpdownNumbers(2)).cptr = CODEPTR(Hurdy_error_UD3) UDctrl(TaskEX(%Hurdy_Motor).UpDownNumbers(0)).value = 0 UDctrl(TaskEX(%Hurdy_Motor).UpdownNumbers(1)).value = 0 ' cw - direction of rotation UDctrl(TaskEX(%Hurdy_Motor).UpdownNumbers(2)).value = 0 Task(%Hurdy_Motor).freq = 10 Slider(slnr).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value ' motor off, on init. ModeMess Hurdy.channel, 66, 0 END IF Task(%Hurdy_Motor).tog = %True END IF ' make sure motor does not run idle... Modemess Hurdy.channel, 7, Slider(slnr).value ' value stored in Hurdy.ctrl(7) END SUB SUB Hurdy_Motorslider_M () ' bow motor speed: steers motor frequency 3-phase current via Siemens Micromaster 410 LOCAL slnr AS DWORD slnr = TaskEX(%Hurdy_Motor).SliderNumbers(0) Modemess Hurdy.channel, 7, Slider(slnr).value Hurdy.ctrl(7) = Slider(slnr).value END SUB SUB Hurdy_onoff_UD1 () LOCAL onoff AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_Motor).UpDownNumbers(0) onoff = UDCtrl(udnr).value IF onoff < 1 THEN UDctrl(udnr).value = 0 : onoff = UDctrl(udnr).value IF onoff > 0 THEN UDctrl(udnr).value = 1 : onoff = UDctrl(udnr).value IF ISFALSE onoff THEN ' turn motor off Hurdy.ctrl(66) = 0 SetDlgItemText Task(%Hurdy_Motor).hparam, %GMT_TEXT0_ID + 16, "OFF" ModeMess Hurdy.channel, 66, 0 ELSE ' turns motor ON Hurdy.ctrl(66) = 1 SetDlgItemText Task(%Hurdy_Motor).hparam, %GMT_TEXT0_ID + 16, "ON" ModeMess Hurdy.channel, 66, 1 END IF END SUB SUB Hurdy_dir_UD2 () ' cw/cww ' controls the direction of rotation for the bow wheel motor ' probably also needs inversion, bit since it's a toggle and depending on the motor connection, ' we did not patch this one for the faulty PIC2 LOCAL cwcww AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_Motor).UpDownNumbers(1) cwcww = UDCtrl(udnr).value IF cwcww < 1 THEN UDctrl(udnr).value = 0 : cwcww = UDctrl(udnr).value IF cwcww > 0 THEN UDctrl(udnr).value = 1 : cwcww = UDctrl(udnr).value IF Hurdy.ctrl(66) THEN ModeMess Hurdy.channel, 66, 0 ' motor OFF --- takes 5 seconds max. END IF ModeMess Hurdy.channel, 67, cwcww IF Hurdy.ctrl(66) THEN ModeMess Hurdy.channel, 66, 1 ' motor back ON END IF Hurdy.ctrl(67) = cwcww SetDlgItemText Task(%Hurdy_Motor).hparam, %GMT_TEXT0_ID + 17, "cw=" & STR$(cwcww) END SUB SUB Hurdy_Error_UD3 () ' error reset - to be checked! (may only need a pulse) LOCAL ack AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_Motor).UpDownNumbers(2) ack = UDCtrl(udnr).value IF ack < 1 THEN UDctrl(udnr).value = 0 : ack = UDctrl(udnr).value IF ack > 0 THEN UDctrl(udnr).value = 1 : ack = UDctrl(udnr).value ' ModeMess Hurdy.channel, 123, ack ' this does all notes off... - temporary disabled. ModeMess Hurdy.channel, 68, ack Hurdy.ctrl(68) = ack SetDlgItemText Task(%Hurdy_Motor).hparam, %GMT_TEXT0_ID + 18, "er=" & STR$(ack) END SUB SUB Hurdy_controlroom 'cfr http://www.logosfoundation.org/instrum_gwr/hurdy/hurdyP4.txt LOCAL i AS LONG LOCAL x AS LONG LOCAL overt$() IF ISFALSE hwCtrlHurdy THEN DIALOG NEW 0, "Hurdy Control",1,240 ,510, 111, %WS_CAPTION OR %WS_POPUP OR %WS_SYSMENU TO hwCtrlHurdy x = 5 FOR i = Hurdy.lowtes TO ((Hurdy.LowTes + Hurdy.HighTes)/2) - 1 SELECT CASE (i MOD 12) CASE 0 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "C", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "C", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 1 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "C#", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "C#", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 2 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "D", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "D", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 3 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "D#", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "D#", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 4 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "E", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "E", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 5 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "F", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "F", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 6 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "F#", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "F#", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 7 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "G", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "G", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 8 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "G#", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "G#", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 9 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "A", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "A", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 10 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "Bb", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "Bb", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 11 CONTROL ADD CHECKBOX, hwCtrlHurdy, i, "B", x, 12, 18, 12, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, i + 24, "B", x, 26, 18, 12, %BS_PUSHLIKE x = x + 20 END SELECT NEXT CONTROL ADD LABEL, hwCtrlHurdy, 500, "Motor:", 5, 45, 30, 12 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy, 501, _ "Motor", 36, 45, 135, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hMotorTrackBar = GetDlgItem(hwCtrlHurdy,501) SendMEssage hMotorTrackbar, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hMotorTrackbar, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 503, "?", 174, 45, 15, 12 CONTROL ADD LABEL, hwCtrlHurdy, 560, "LPress:", 5, 58, 30, 12 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy, 561, _ "LPress", 36, 58, 135, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hLeftPressTrackBar = GetDlgItem(hwCtrlHurdy,561) SendMEssage hLeftPressTrackbar, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hLeftPressTrackbar, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 563, "?", 174, 58, 15, 12 CONTROL ADD LABEL, hwCtrlHurdy, 565, "LPrePress:", 192, 58, 40, 12 'new 20070404 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy, 566, _ "LPrePress", 233, 58, 135, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hLeftPrePressTrackbar = GetDlgItem(hwCtrlHurdy, 566) SendMessage hLeftPrePressTrackbar, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hLeftPrePressTrackbar, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 567, "?", 370, 58, 15, 12 CONTROL ADD LABEL, hwCtrlHurdy, 570, "RPress:", 5, 71, 30, 12 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy, 571, _ "RPress", 36, 71, 135, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hRightPressTrackBar = GetDlgItem(hwCtrlHurdy,571) SendMessage hRightPressTrackbar, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hRightPressTrackbar, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 573, "?", 174, 71, 15, 12 CONTROL ADD LABEL, hwCtrlHurdy, 575, "RPrePress:", 192, 71, 40, 12 'new 20070404 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy, 576, _ "RPrePress", 233, 71, 135, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hRightPrePressTrackbar = GetDlgItem(hwCtrlHurdy, 576) SendMessage hRightPrePressTrackbar, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hRightPrePressTrackbar, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 577, "?", 370, 71, 15, 12 'new 20070403 CONTROL ADD CHECKBOX, hwCtrlHurdy, 700, "E-drive L", 5, 84, 40, 12 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy,701, _ "E-drive L", 47, 84, 124, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hEDriveLeft = GetDlgItem(hwCtrlHurdy, 701) SendMEssage hEdriveLeft, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hEdriveLeft, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 702, "?", 174, 84, 15, 12 CONTROL ADD LABEL, hwCtrlHurdy, 703, "overtone:", 192, 84, 30, 12 DIM overt$(19) FOR i = 0 TO 19 overt$(i) = STR$(i + 1) NEXT CONTROL ADD COMBOBOX, hwCtrlHurdy, 704, overt$(), 230, 84, 30, 240, %CBS_DROPDOWNLIST COMBOBOX SELECT hwCtrlHurdy, 704, 1 CONTROL ADD CHECKBOX, hwCtrlHurdy, 710, "E-drive R", 5, 97, 40, 12 CONTROL ADD "msctls_trackbar32", hwCtrlHurdy,711, _ "E-drive R", 47, 97, 124, 12, %WS_CHILD OR %WS_VISIBLE OR %TBS_HORZ OR %TBS_BOTTOM hEDriveRight = GetDlgItem(hwCtrlHurdy, 711) SendMEssage hEdriveRight, %TBM_SETRANGE, %true, MAKLNG(0, 127) SendMEssage hEDriveRight, %TBM_SETPAGESIZE, 0, 4 'added on request by gwr CONTROL ADD LABEL, hwCtrlHurdy, 712, "?", 174, 97, 15, 12 CONTROL ADD LABEL, hwCtrlHurdy, 713, "overtone", 192, 97, 30, 12 CONTROL ADD COMBOBOX, hwCtrlHurdy, 714, overt$(), 230, 97, 30, 240, %CBS_DROPDOWNLIST '/new CONTROL ADD CHECKBOX, hwCtrlHurdy, 550, "On/Off", 192, 46, 40, 10, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, 551, "Clockwise", 234, 46, 55, 10, %BS_PUSHLIKE CONTROL ADD CHECKBOX, hwCtrlHurdy, 552, "Counterclockwise", 291, 46, 55, 10, %BS_PUSHLIKE COMBOBOX SELECT hwCtrlHurdy, 714, 1 CONTROL ADD BUTTON, hwCtrlHurdy, 600, "All Off", 365, 46, 30, 10 DIALOG SHOW MODELESS hwCtrlHurdy CALL CB_Hurdy_Controlroom ELSE DIALOG END hwCtrlHurdy hwCtrlHurdy = 0 END IF END SUB CALLBACK FUNCTION CB_Hurdy_Controlroom 'updated for new P4 specs by kl 20070403 'adapted gwr 10.11.2007 LOCAL motorspeed AS BYTE LOCAL press AS BYTE LOCAL i AS LONG LOCAL b$ LOCAL note AS BYTE STATIC lastlpress AS BYTE 'last pressure value to be used as note velo for next notes STATIC lastrpress AS BYTE STATIC lastlnote AS BYTE STATIC lastrnote AS BYTE STATIC lastleftpress AS BYTE 'if edrive mode is enabled, we set the pressure to 1 and keep the old value here to retore it when edrive is disabled again. not the same as lastlpress! STATIC lastleftprepress AS BYTE 'if edrive mode is enabled, we set the pressure to 1 and keep the old value here to retore it when edrive is disabled again. not the same as lastlpress! STATIC lastrightpress AS BYTE STATIC lastrightprepress AS BYTE SELECT CASE CBMSG CASE %WM_COMMAND SELECT CASE CBCTL CASE Hurdy.Lowtes TO Hurdy.hightes 'note checkboxes CONTROL GET CHECK CBHNDL, CBCTL TO i note = CBCTL IF note < (Hurdy.Lowtes + Hurdy.hightes) / 2 THEN IF (i>0) AND (lastlnote>0) AND (lastlnote <> note) THEN CONTROL SET CHECK CBHNDL, lastlnote, 0 lastlnote = note i = i * MAX(1, lastlpress) ELSE IF (i>0) AND (lastrnote>0) AND (lastrnote <> note) THEN CONTROL SET CHECK CBHNDL, lastrnote, 0 lastrnote = note i = i * MAX(1, lastrpress) END IF ' following corrected for edrive case!!! SELECT CASE note CASE < 64 ' low string IF Hurdy.ctrl(5) = 1 THEN Play Hurdy.channel, note, Hurdy.ctrl(3) ELSE Play Hurdy.channel, note, BYVAL i END IF CASE ELSE ' high string IF Hurdy.ctrl(6) = 1 THEN Play Hurdy.channel, note, Hurdy.ctrl(4) ELSE Play Hurdy.channel, note, BYVAL i END IF END SELECT CASE 550 'motor on/off CONTROL GET CHECK CBHNDL, CBCTL TO i controller Hurdy.channel, 66, i Hurdy.ctrl(66) = i CASE 551 CONTROL GET CHECK CBHNDL, CBCTL TO i IF Hurdy.ctrl(66) THEN Warning "Changing the motor direction while it is running does not make sense!" IF i THEN CONTROL SET CHECK CBHNDL, 552, 0 Hurdy.ctrl(67) = 0 Controller Hurdy.channel, 67, 0 END IF CASE 552 CONTROL GET CHECK CBHNDL, CBCTL TO i IF Hurdy.ctrl(66) THEN Warning "Changing the motor direction while it is running does not make sense!" IF i THEN CONTROL SET CHECK CBHNDL, 551, 0 Hurdy.ctrl(67) = 1 controller Hurdy.channel, 67, 1 END IF CASE 600 'all off FOR i = Hurdy.lowtes TO Hurdy.hightes CONTROL SET CHECK CBHNDL, i, 0 NEXT SendMessage hMotorTrackBar, %TBM_SETPOS, %true, 0 Modemess Hurdy.channel, 66, 0 ' = power off Controller Hurdy.channel, 123, %False Hurdy.ctrl(66) = 0 Hurdy.ctrl(7) = 0 ' Controller Hurdy.channel, 7, Hurdy.ctrl(7) ' Keypress Hurdy.channel, 40, 0: Keypress Hurdy.channel, 64, 0 ' Controller Hurdy.channel, 3, 0: Hurdy.ctrl(3) = 0 ' Controller Hurdy.channel, 4, 0: Hurdy.ctrl(4) = 0 CONTROL SET TEXT CBHNDL, 503, "0" CONTROL SET CHECK CBHNDL, 550, 0 CASE 700 'left e-drive (low string) CONTROL GET CHECK CBHNDL, CBCTL TO i Controller Hurdy.channel, 69, i IF i THEN 'e-drive on, stop pressure and prepressure lastleftpress = SendMessage(HLeftPressTrackBar, %TBM_GETPOS, 0, 0) lastleftprepress = SendMessage(HLeftprePressTrackBar, %TBM_GETPOS, 0, 0) SendMessage hLEftPressTrackBar, %TBM_SETPOS, %true, 1 SendMessage hLEftprePressTrackBar, %TBM_SETPOS, %true, 0 KeyPress Hurdy.channel, 40, 0 Hurdy.ctrl(1) = 0 Controller Hurdy.channel, 1, Hurdy.ctrl(1) lastlpress = 0 Controller Hurdy.channel, 69, 1 ' power e drive on Hurdy.ctrl(69) = 1 Controller Hurdy.channel, 5, 1 ' edrive exclusive Hurdy.ctrl(5) = 1 CONTROL SET TEXT CBHNDL, 563, " 1" CONTROL SET TEXT CBHNDL, 567, " 0" ELSE 'e-drive off - reset pressures if they haven't been changed in between press = SendMessage(HLeftPressTrackBar, %TBM_GETPOS, 0, 0) IF (press = 1) THEN SendMessage HLeftPressTrackBar, %TBM_SETPOS, %true, lastleftpress KeyPress Hurdy.channel, 40, lastleftpress lastlpress=lastleftpress CONTROL SET TEXT CBHNDL, 563, STR$(lastlpress) END IF press = SendMessage(hLeftPrePRessTrackbar, %TBM_GETPOS, 0, 0) IF press = 0 THEN SendMessage HLeftPrePressTrackBar, %TBM_SETPOS, %true, lastleftprepress Hurdy.ctrl(1) = lastleftprepress Controller Hurdy.channel, 1, Hurdy.ctrl(1) Controller Hurdy.channel, 5, 0 Hurdy.ctrl(5) = 0 CONTROL SET TEXT CBHNDL, 567, STR$(Hurdy.ctrl(1)) END IF END IF CASE 710 'right e-drive CONTROL GET CHECK CBHNDL, CBCTL TO i Controller Hurdy.channel, 70, i ' high string IF i THEN 'e-drive on, stop pressure and motor lastrightpress = SendMessage(HRightPressTrackBar, %TBM_GETPOS, 0, 0) lastrightprepress = SendMessage(HRightPressTrackBar, %TBM_GETPOS, 0, 0) SendMessage hRightPressTrackBar, %TBM_SETPOS, %true, 1 SendMessage hRightprePressTrackBar, %TBM_SETPOS, %true, 0 KeyPress Hurdy.channel, 64, 0 Hurdy.ctrl(2) = 0 Controller Hurdy.channel, 2, Hurdy.ctrl(2) lastrpress = 1 Controller Hurdy.channel, 70, 1 Hurdy.ctrl(70) = 1 Controller Hurdy.channel, 6, 1 ' e drive exclusive Hurdy.ctrl(6) = 1 CONTROL SET TEXT CBHNDL, 573, " 1" CONTROL SET TEXT CBHNDL, 577, " 0" ELSE press = SendMessage(HRightPressTrackBar, %TBM_GETPOS, 0, 0) IF (press=1) THEN SendMessage HRightPressTrackBar, %TBM_SETPOS, %true, lastrightpress KeyPress Hurdy.channel, 64, lastrightpress lastrpress = lastrightpress CONTROL SET TEXT CBHNDL, 573, STR$(lastrightpress) END IF press = SendMessage(hRightPrePRessTrackbar, %TBM_GETPOS, 0, 0) IF press = 0 THEN SendMessage HRightPrePressTrackBar, %TBM_SETPOS, %true, lastrightprepress Hurdy.ctrl(2) = lastrightprepress Controller Hurdy.channel, 2, Hurdy.ctrl(2) CONTROL SET TEXT CBHNDL, 567, STR$(Hurdy.ctrl(1)) END IF Controller Hurdy.channel, 6, %False Hurdy.ctrl(6) = %False END IF CASE 704 'l overtone sel - low string CONTROL GET TEXT CBHNDL, CBCTL TO b$ i = MAX(1, VAL(b$)) IF i <> Hurdy.ctrl(22) THEN Hurdy.ctrl(22) = i Controller Hurdy.channel, 22, Hurdy.ctrl(22) END IF CASE 714 'r overtone sel - high string CONTROL GET TEXT CBHNDL, CBCTL TO b$ i = MAX(1, VAL(b$)) IF i <> Hurdy.ctrl(23) THEN Hurdy.ctrl(23) = i Controller Hurdy.channel, 23, Hurdy.ctrl(23) END IF END SELECT CASE %WM_HSCROLL, %WM_VSCROLL 'note: id doesn't correspond with the one given at creation SELECT CASE CBLPARAM CASE hMotorTrackBar 'motor speed IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN motorspeed = HIWRD(CBWPARAM) ELSE motorspeed = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF CONTROL SET TEXT CBHNDL, 503, STR$(motorspeed) Hurdy.ctrl(7) = motorspeed Modemess Hurdy.channel, 7, Hurdy.ctrl(7) CASE hLeftPressTrackbar 'left trackbar pressure IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN press = HIWRD(CBWPARAM) ELSE press = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF IF press <> lastlpress THEN Keypress Hurdy.channel, 40, press lastlpress = press CONTROL SET TEXT CBHNDL, 563, STR$(press) END IF CASE hLeftPrepressTrackbar IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN press = HIWRD(CBWPARAM) ELSE press = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF IF press <> Hurdy.ctrl(1) THEN Hurdy.ctrl(1) = press controller Hurdy.channel, 1, Hurdy.ctrl(1) CONTROL SET TEXT CBHNDL, 567, STR$(press) END IF CASE hRightPressTrackbar 'right trackbar pressure IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN press = HIWRD(CBWPARAM) ELSE press = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF IF press <> lastrpress THEN Keypress Hurdy.channel, 64, press lastrpress = press CONTROL SET TEXT CBHNDL, 573, STR$(press) END IF CASE hRightPrepressTrackbar IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN press = HIWRD(CBWPARAM) ELSE press = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF IF press <> Hurdy.ctrl(2) THEN Hurdy.ctrl(2) = press controller Hurdy.channel, 2, Hurdy.ctrl(2) CONTROL SET TEXT CBHNDL, 577, STR$(press) END IF CASE hEdriveLeft IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN press = HIWRD(CBWPARAM) 'we misuse press for drive here ELSE press = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF IF press <> Hurdy.ctrl(3) THEN Hurdy.ctrl(3) = press controller Hurdy.channel, 3, Hurdy.ctrl(3) CONTROL SET TEXT CBHNDL, 702, STR$(Hurdy.ctrl(3)) END IF CASE hEdriveRight IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN press = HIWRD(CBWPARAM) 'we misuse press for drive here ELSE press = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) END IF IF press <> Hurdy.ctrl(4) THEN Hurdy.ctrl(4) = press controller Hurdy.channel, 4, Hurdy.ctrl(4) CONTROL SET TEXT CBHNDL, 712, STR$(Hurdy.ctrl(4)) END IF END SELECT CASE %WM_CLOSE, %WM_QUIT hwCtrlHurdy = 0 FOR i = Hurdy.lowtes TO Hurdy.hightes Play Hurdy.channel, i, 0 SLEEP 10 DIALOG DOEVENTS NEXT Controller Hurdy.channel, 123, %False Hurdy.ctrl(7) = %False END SELECT END FUNCTION SUB hurdy_e_low () ' test for e-bow mechanism on low string STATIC i AS DWORD STATIC slnr AS DWORD STATIC oldnote AS INTEGER STATIC press AS BYTE STATIC cnt AS BYTE IF ISFALSE Task(%Hurdy_e_Low).tog THEN DIM TaskParamLabels(0 TO 5) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" ' slider MM tempo TaskParamlabels(1) = "legato" ' slider - on / off proportie TaskParamlabels(2) = "volume" TaskParamLabels(3) = "LowLim" ' UD TaskParamLabels(4) = "HiLim" ' uD TaskParamlabels(5) = "Sustain" ' UD IF ISFALSE Task(%Hurdy_e_low).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_e_Low,3,Slider(),3,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_e_Low).SliderNumbers(0) UDctrl(TaskEX(%Hurdy_e_Low).UpdownNumbers(0)).cptr = CODEPTR(Hurdy_e_Low_LoLim_UD1) ' lowest note UDctrl(TaskEX(%Hurdy_e_Low).UpdownNumbers(1)).cptr = CODEPTR(Hurdy_e_Low_HiLim_UD2) ' highest note UDctrl(TaskEX(%Hurdy_e_Low).UpDownNumbers(0)).value = Hurdy.lowtes UDctrl(TaskEX(%Hurdy_e_low).UpdownNumbers(2)).cptr = CODEPTR(Hurdy_Sustain_UD3) i = UDctrl(TaskEX(%Hurdy_e_Low).UpDownNumbers(0)).value '40 Task(%Hurdy_e_Low).tempo = 60 Slider(slnr).value = Task(%Hurdy_e_low).tempo Slider(slnr+1).value = 120 ' legato / staccato Slider(slnr+2).value = 24 ' volume SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 120 ' legato. on init steers ON/OFF proportion SendMessage Slider(slnr+2).h, %TBM_SETPOS, %True, Slider(slnr+2).value END IF i = Hurdy.lowtes controller hurdy.channel, 1, %False ' no prepressure at all controller hurdy.channel, 66, %False ' stop motor controller hurdy.channel, 65, %False ' no motor on note on's controller hurdy.channel, 5, 1 ' ebow only Hurdy.ctrl(5) = 1 Task(%Hurdy_e_low).tog = %True END IF IF oldnote THEN Play Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN Play Hurdy.channel, i, Slider(slnr+2).value oldnote = i INCR i IF i > UDctrl(TaskEX(%Hurdy_e_low).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Hurdy_e_low).UpDownNumbers(0)).value END IF BIT TOGGLE cnt, 0 Task(%Hurdy_e_low).tempo = MAX(Slider(slnr).value,1) ' ===> Period = 60/ tempo IF ISFALSE cnt THEN Task(%Hurdy_e_low).freq = 1 / ((1- (Slider(slnr+1).value / 128)) * (60 / Task(%Hurdy_e_low).tempo)) ' on freq. ELSE Task(%Hurdy_e_low).freq = 1 / ((Slider(slnr+1).value / 128) * (60 / Task(%Hurdy_e_low).tempo)) ' off freq. END IF END SUB SUB Hurdy_e_Low_LoLim_UD1 () ' controls the low limit of the note scale to be played on the low string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_e_low).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < Hurdy.lowtes THEN UDctrl(udnr).value = Hurdy.lowtes: noot = Hurdy.lowtes IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Hurdy_e_low).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Hurdy_e_Low_HiLim_UD2 () ' controls the high limit of the note scale to be played on the low string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_e_low).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 > 63 THEN UDctrl(udnr).value = 63 : noot = 63 SetDlgItemText Task(%Hurdy_e_low).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB Hurdy_Sustain_UD3 () ' control for pedal sustain, ctrl 64 - felt dampers LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_e_low).UpDownNumbers(2) IF UDCtrl(udnr).value >= 1 THEN UDctrl(udnr).value = 1 Controller Hurdy.channel, 64, %True SetDlgItemText Task(%Hurdy_e_low).hparam, %GMT_TEXT0_ID + 18, "On" ELSE UDctrl(udnr).value = %False Controller Hurdy.channel, 64, %False SetDlgItemText Task(%Hurdy_e_low).hparam, %GMT_TEXT0_ID + 18, "Off" END IF END SUB SUB hurdy_e_high () ' e-drive high string test scale STATIC i AS DWORD STATIC slnr AS DWORD STATIC oldnote AS INTEGER STATIC press AS BYTE STATIC cnt AS BYTE IF ISFALSE Task(%Hurdy_e_high).tog THEN DIM TaskParamLabels(0 TO 4) AS ASCIIZ * 8 TaskParamLabels(0) = "Tempo" ' slider MM tempo TaskParamlabels(1) = "legato" ' slider - on / off proportie TaskParamLabels(2) = "volume" TaskParamLabels(3) = "LowLim" ' UD1 TaskParamLabels(4) = "HiLim" ' uD2 IF ISFALSE Task(%Hurdy_e_high).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_e_high,3,Slider(),2,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_E_high).SliderNumbers(0) UDctrl(TaskEX(%Hurdy_e_high).UpdownNumbers(0)).cptr = CODEPTR(Hurdy_e_high_LoLim_UD1) ' lowest note UDctrl(TaskEX(%Hurdy_e_high).UpdownNumbers(1)).cptr = CODEPTR(Hurdy_e_high_HiLim_UD2) ' highest note UDctrl(TaskEX(%Hurdy_e_high).UpDownNumbers(0)).value = 64 i = UDctrl(TaskEX(%Hurdy_e_high).UpDownNumbers(0)).value Task(%Hurdy_e_high).tempo = 60 Slider(slnr).value = Task(%Hurdy_e_high).tempo Slider(slnr+1).value = 120 ' legato / staccato Slider(slnr+2).value = 25 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, 120 ' legato on init Sendmessage Slider(slnr+2).h, %TBM_SETPOS,%True, Slider(slnr+2).value END IF i = Hurdy.lowtes + 24 controller hurdy.channel, 2, %False ' no prepressure at all controller hurdy.channel, 66, %False ' stop motor controller hurdy.channel, 65, %False ' no motor on note on's Task(%Hurdy_E_high).tog = %True END IF IF oldnote THEN Play Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN Play Hurdy.channel, i, Slider(slnr+2).value oldnote = i INCR i IF i > UDctrl(TaskEX(%Hurdy_e_high).UpDownNumbers(1)).value THEN i = UDctrl(TaskEX(%Hurdy_e_high).UpDownNumbers(0)).value END IF BIT TOGGLE cnt, 0 Task(%Hurdy_e_high).tempo = MAX(Slider(slnr).value,1) ' ===> Period = 60/ tempo IF ISFALSE cnt THEN Task(%Hurdy_e_high).freq = 1 / ((1- (Slider(slnr+1).value / 128)) * (60 / Task(%Hurdy_e_high).tempo)) ' on freq. ELSE Task(%Hurdy_e_high).freq = 1 / ((Slider(slnr+1).value / 128) * (60 / Task(%Hurdy_e_high).tempo)) ' off freq. END IF END SUB SUB Hurdy_e_High_LoLim_UD1 () ' controls the low limit of the note scale to be played on the high string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_e_high).UpDownNumbers(0) noot = UDCtrl(udnr).value IF noot < 64 THEN UDctrl(udnr).value = 64: noot = 64 IF noot > UDctrl(udnr+1).value THEN UDctrl(udnr).value = UDctrl(udnr+1).value : noot = UDctrl(udnr).value SetDlgItemText Task(%Hurdy_e_high).hparam, %GMT_TEXT0_ID + 16, "Lo=" & STR$(noot) END SUB SUB Hurdy_e_High_HiLim_UD2 () ' controls the high limit of the note scale to be played on the high string LOCAL noot AS BYTE LOCAL udnr AS DWORD udnr = TaskEX(%Hurdy_e_high).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 > Hurdy.hightes THEN UDctrl(udnr).value = Hurdy.hightes : noot = Hurdy.hightes IF noot > 127 THEN UDctrl(udnr).value = 127 : noot = 127 ' for tests only - 30.10.2007 SetDlgItemText Task(%Hurdy_e_high).hparam, %GMT_TEXT0_ID + 17, "Hi=" & STR$(noot) END SUB SUB hurdy_tune_low () STATIC slnr AS DWORD STATIC tuning AS DWORD IF ISFALSE Task(%Hurdy_tune_low).tog THEN DIM TaskParamLabels(1) AS ASCIIZ * 8 TaskParamLabels(1) = "Tuning" TaskParamlabels(2) = "Level" IF ISFALSE Task(%Hurdy_tune_low).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_tune_low,2,Slider(),0,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_tune_low).SliderNumbers(0) Slider(slnr).value = 33 ' 35 dit was de waarde met de PIC bug!!! - levert 33 op. SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF 'set controllers for e-drive Controller Hurdy.channel, 69, %TRue ' enable edrive low string Controller Hurdy.channel, 5, 1 ' make edrive exclusive and use velo byte for amplitude Controller Hurdy.channel, 64, %False ' sustain off Task(%Hurdy_tune_low).tog = %True END IF IF tuning <> slider(slnr).value THEN NoteOff Hurdy.channel, 40 tuning = MIN(MAX(slider(slnr).value, 24), 46) controller Hurdy.channel, 20, tuning SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, tuning END IF Play Hurdy.channel, 40, Slider(slnr+1).value END SUB SUB Hurdy_tune_high () STATIC slnr AS DWORD STATIC tuning AS DWORD IF ISFALSE Task(%Hurdy_tune_high).tog THEN DIM TaskParamLabels(1) AS ASCIIZ * 8 TaskParamLabels(0) = "Tuning" TaskParamLabels(1) = "Level" IF ISFALSE Task(%Hurdy_tune_high).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_tune_high,2,Slider(),0,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_tune_high).SliderNumbers(0) Slider(slnr).value = 50 ' 66 dit was de waarde met de PIC bug. De werkelijke stemming is dan 50 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF ' set controllers for e-drive: Controller Hurdy.channel, 70, 1 ' enable e-drive Controller Hurdy.channel, 6, 1 ' make e-drive exclusive and enable velo on drive amplitude Controller Hurdy.channel, 64, %False Task(%Hurdy_tune_high).tog = %True END IF IF tuning <> slider(slnr).value THEN NoteOff Hurdy.channel, 64 tuning = MIN(MAX(slider(slnr).value, 44), 78) controller Hurdy.channel, 21, tuning SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, tuning END IF Play Hurdy.channel,64, Slider(slnr+1).value END SUB '-------------------------------------------------------------------------- ' demo hurdy stukje gwr: SUB HurCan () ' %Hur STATIC cnt AS DWORD STATIC sl AS INTEGER STATIC sh AS INTEGER LOCAL flgH AS SINGLE LOCAL flgL AS SINGLE STATIC Hnote AS INTEGER STATIC Lnote AS INTEGER ' initialize all settings for Hurdy IF ISFALSE Task(%Hur).tog THEN Controller Hurdy.channel, 123, %False ' all off, except tuning ! Task(%Hur).freq = 1 '0.5 cnt = %False Controller Hurdy.channel, 69, 1 ' enable e-drive low string Controller Hurdy.channel, 70, 1 ' enable e-drive high string Controller Hurdy.channel, 5, 1 ' low string e-drive active Controller Hurdy.channel, 6, 1 ' high string e-drive active Controller Hurdy.channel, 64, 1 ' depress sustain pedal - no damping ProgChange Hurdy.channel, 120 ' not yet implemented. Should be single tangent lookup. ' now default Lnote = 40 Hnote = 64 sl = -1 sh = -1 Task(%Hur).tog = %True END IF ' intro: ' controller 22 = flageolets low string ' controller 23 = flageolets high string ' controller 3 = e -drive volume low string ' controller 4 = e -drive volume high string IF ISFALSE cnt MOD 21 THEN sl = -sl END IF IF ISFALSE cnt MOD 21 THEN sh = -sh END IF IF ISFALSE cnt MOD 2 THEN IF ISFALSE Hurdy.ctrl(121) THEN Play Hurdy.channel, 1, 127 ' linker lamp aan Hurdy.ctrl(121) = %True END IF ' Play Hurdy.channel, Hnote, 120 ' high string on, sound note 50(Re) ' flgH = ABS(SIN((cnt MOD 21) * 0.314159)) 'Controller Hurdy.channel, 23, flgH ' flageolets 'controller Hurdy.channel, 4, 15 + (flgH * 4) ' Play Hurdy.channel, Hnote, 15 + (flgH * 4) ' high string on, sound note 50(Re) ' Controller Hurdy.channel, 23, flgH ' flageolets flgh = cnt MOD 21 Play Hurdy.channel, HNote, 15 + (flgH *4) Controller Hurdy.channel, 23, flgH ELSE IF ISFALSE Hurdy.ctrl(120) THEN Play Hurdy.channel, 0, 127 ' rechter lamp aan Hurdy.ctrl(120) = %True END IF ' Play Hurdy.channel, LNote, 120 ' low string... note 33 (La) ' flgL = ABS(SIN((cnt MOD 21) * 0.314159)) 'controller Hurdy.channel, 3, 10 + (flgH * 3) ' Play Hurdy.channel, LNote, 10 + (flgL * 3) '120 ' low string... note 33 (La) ' Controller Hurdy.channel, 22, FlgL flgL = cnt MOD 21 Play Hurdy.channel, LNote, 10 + (flgL * 3) Controller Hurdy.channel, 22, FlgL END IF IF ISFALSE cnt MOD 13 THEN Hnote = Hnote + 5 IF Hnote > 88 THEN Hnote = 64 + (Hnote MOD 25) Hnote = 64 + (Hnote MOD 12) END IF END IF IF ISFALSE cnt MOD 17 THEN LNote = Lnote + 7 IF LNote > 63 THEN Lnote = 40 + (Lnote MOD 24) Lnote = 40 + (Lnote MOD 12) END IF END IF cnt = cnt + sL IF cnt < 0 THEN cnt = 0 END SUB SUB Religionszwang () ' intro en startup voor Religionszwang ' deze taak start zelf de volgende taken. Geen user interventie nodig. ' de stemming en afregeling van Hurdy moet wel perfekt zijn. STATIC cnt AS DWORD LOCAL speed AS INTEGER IF ISFALSE Task(%Relig).tog THEN cnt = %False Hurdy.ctrl(69) = %True Controller Hurdy.channel, 69, %True Hurdy.ctrl(5) = 1 Controller Hurdy.channel, 5, 1 Hurdy.ctrl(70) = %True Controller Hurdy.channel, 70, %True Hurdy.ctrl(6) = 1 Controller Hurdy.channel, 6, 1 ' motor off Hurdy.ctrl(66) = %False Controller Hurdy.channel, 66, %False Controller Hurdy.channel, 22, 1 ' reset harmonics! Controller Hurdy.channel, 23, 1 Hurdy.ctrl(22) = 1 Hurdy.ctrl(23) = 1 Task(%Relig).freq = 1 Task(%Relig).tog = %True END IF ' timing in sekonden. SELECT CASE cnt CASE < 10 Play Hurdy.channel, 45, MIN(127,cnt * 10) Hurdysound.lownote = Hurdy.ctrl(20) + (45 - Hurdy.lowtes) Hurdysound.lowfreq = N2F(Hurdysound.lownote) CASE < 20 Play Hurdy.channel, 64, MIN(127,(cnt - 10) * 10) Hurdysound.highnote = Hurdy.ctrl(21) + (64 - (Hurdy.lowtes+24)) Hurdysound.highfreq = N2F(Hurdysound.highnote) CASE < 30 IF ISFALSE Task(%HurL).swit THEN StartTask %HurL CASE < 40 IF ISFALSE Task(%HurH).swit THEN starttask %HurH CASE < 80 IF ISFALSE Hurdy.ctrl(120) THEN Play Hurdy.channel, 0, 127 Hurdy.ctrl(120) = %True END IF CASE < 140 IF ISFALSE Hurdy.ctrl(121) THEN Play Hurdy.channel, 1, 127 Hurdy.ctrl(121) = %True END IF CASE > 480 ' this be the end. - duration 7 minutes StopTask(%Relig) ' hier moet nog een decrescendo ingevoegd worden. CASE > 461 DECR Hurdy.ctrl(23) IF Hurdy.ctrl(23) < 1 THEN Hurdy.ctrl(23) = 1 ' high string Controller Hurdy.channel, 23, Hurdy.ctrl(23) Play Hurdy.channel, Hurdysound.mihigh, 120 ' check this CASE > 460 IF Task(%HurH).swit THEN StopTask %HurH CASE > 441 DECR Hurdy.ctrl(22) IF Hurdy.ctrl(22) < 1 THEN Hurdy.ctrl(22) = 1 Controller Hurdy.channel, 22, Hurdy.ctrl(22) Play Hurdy.channel, Hurdysound.milow,64 ' check this CASE > 440 IF Task(%HurL).swit THEN Stoptask %HurL CASE > 400 ' naar open snaar op de laagste snaar IF Hurdysound.milow <> 40 THEN Hurdysound.milow = 40 CASE > 360 IF Hurdysound.mihigh <> 71 THEN Hurdysound.mihigh = 71 ' transpose high string - now La (57 real) CASE > 340 ' voor de volgende nemen we nu het oktaaf: (La, een kwint boven de hoge snaar) IF Hurdysound.milow <> 52 THEN Hurdysound.milow = 52 ' transpose low string- now open La (33 real) CASE > 310 IF ISFALSE Task(%HurPL).swit THEN starttask %HurPL INCR Task(%HurM).pan END IF CASE > 270 ' high string pushers IF ISFALSE Task(%HurPH).swit THEN starttask %HurPH INCR Task(%HurM).pan END IF CASE > 220 ' start motor IF ISFALSE Task(%HurM).swit THEN starttask %HurM Task(%HurM).pan = %False END SELECT INCR cnt END SUB SUB HurCanL () ' %HurL ' forced religion ' Zwangmaesige religion oder religionszwang. STATIC h AS INTEGER STATIC cnt AS DWORD STATIC dir AS INTEGER LOCAL noot AS CUR LOCAL freq AS SINGLE LOCAL d AS SINGLE ' dissonantie LOCAL k AS SINGLE ' konsonantie ' low string melody IF ISFALSE Task(%HurL).tog THEN cnt = %False Hurdy.ctrl(69) = %True Controller Hurdy.channel, 69, %True Hurdy.ctrl(5) = 1 Controller Hurdy.channel, 5, 1 dir = -1 h = 0 Hurdysound.milow = 45 ' uitgestuurde midi noot- unisono Re met hoge snaar Task(%HurL).tog = %True END IF IF ISFALSE cnt MOD 21 THEN dir = -dir ' sign toggle END IF h = cnt MOD 21 IF Hurdy.ctrl(5) <> 1 THEN Controller Hurdy.channel, 5, 1 END IF Play Hurdy.channel, Hurdysound.milow, 27 + (h*5) ' 45 sounds Re=38 , 57 sounds Re=50, unison ' 27 + 100 = 127 Controller Hurdy.channel, 22, h IF hurdy.ctrl(5) <> 1 THEN Controller Hurdy.channel, 5, 2 END IF ' de werkelijk klinkende grondtoon is nu: noot = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) ' de klinkende toonhoogte is: HurdySound.lowfreq = N2F(noot) * MAX(h,1) ' platonische boventoon HurdySound.lownote = F2NF(HurdySound.lowfreq) HurdySound.diftone = ABS(Hurdysound.highfreq - Hurdysound.lowfreq) cnt = cnt + dir IF cnt < 0 THEN cnt = 0 ' tempo afhankelijk van het interval Task(%HurL).freq = 3 'SELECT CASE Hurdysound.diftone ' CASE < 12 ' Task(%HurL).freq = Task(%HurL).freq / 5 ' CASE < 24 ' ' dissonant ' Task(%HurL).freq = Task(%HurL).freq / 2.5 ' CASE < 100 ' Task(%HurL).freq = 3 ' CASE ELSE ' Task(%HurL).freq = Task(%HurL).freq * 2.5 'END SELECT ' tweede versie: tempo mede afhankelijk van de dissonantie-dipool - te evalueren 'd = GetDipoleDis (Hurdysound.lowfreq, 127, Hurdysound.highfreq, 127) ' 0-1 'SELECT CASE Hurdysound.diftone ' 'CASE < 2 ' ' ' CASE < 6 ' Task(%HurL).freq = Task(%HurL).freq / 7 ' CASE < 8 ' Task(%HurL).freq = Task(%HurL).freq / 5 ' CASE ELSE ' d = GetDipoleDis (Hurdysound.lowfreq, 127, Hurdysound.highfreq, 127) ' 0-1 ' Task(%HurL).freq = Task(%HurL).freq + (Task(%HurL).freq * d * 3) 'END SELECT ' derde versie: k = GetDipoleKon (Hurdysound.lowfreq,127, Hurdysound.highfreq,127) ' 0-1 IF k > 0.6 THEN Task(%HurL).freq = Task(%HurL).freq / (k * 10.0) ELSE d = GetDipoleDis (Hurdysound.lowfreq, 127, Hurdysound.highfreq, 127) ' 0-1 Task(%HurL).freq = Task(%HurL).freq + (Task(%HurL).freq * d * 3) END IF END SUB SUB HurCanH () ' %HurH ' high string melody STATIC h AS INTEGER STATIC cnt AS DWORD STATIC dir AS INTEGER LOCAL noot AS CUR LOCAL d AS SINGLE LOCAL k AS SINGLE IF ISFALSE Task(%HurH).tog THEN cnt = %False Hurdy.ctrl(70) = %True Controller Hurdy.channel, 70, %True Hurdy.ctrl(6) = 1 Controller Hurdy.channel, 6, 1 dir = -1 Task(%HurH).tog = %True Hurdysound.mihigh = 64 ' open string END IF IF ISFALSE cnt MOD 21 THEN dir = -dir ' sign toggle END IF h = cnt MOD 21 IF Hurdy.ctrl(6) <> 1 THEN Controller Hurdy.channel, 6, 1 END IF Play Hurdy.channel,Hurdysound.mihigh, 67 + (h*3) ' 67 + 60 = 127 Controller Hurdy.channel, 23, h IF Hurdy.ctrl(6) <> 1 THEN Controller Hurdy.channel, 6, 2 END IF ' de werkelijk klinkende grondtoon is nu: noot = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24)) ' de klinkende toonhoogte is: HurdySound.highfreq = N2F(noot) * MAX(h,1) HurdySound.highnote = F2NF(HurdySound.lowfreq) HurdySound.diftone = ABS(Hurdysound.highfreq - Hurdysound.lowfreq) cnt = cnt + dir ' telt op en af IF cnt < 0 THEN cnt = 0 ' tempo in funktie van interval Task(%HurH).freq = 3.2 ' derde versie: - o.k. k = GetDipoleKon (Hurdysound.lowfreq,127, Hurdysound.highfreq,127) ' 0-1 IF k > 0.6 THEN Task(%HurH).freq = Task(%HurH).freq / (k * 8.0) ELSE d = GetDipoleDis (Hurdysound.lowfreq, 127, Hurdysound.highfreq, 127) ' 0-1 Task(%HurH).freq = Task(%HurH).freq + (Task(%HurH).freq * d * 4) END IF END SUB SUB Hurmot () '%HurM - STATIC cnt AS DWORD STATIC speed AS INTEGER IF ISFALSE Task(%HurM).tog THEN cnt = 1 speed = 0 Task(%HurM).freq = 0.9 '1.81 Task(%HurM).tog = %True END IF IF ISFALSE Hurdy.ctrl(66) THEN Controller Hurdy.channel, 66, %True Hurdy.ctrl(66) = %True END IF SELECT CASE Task(%HurM).pan CASE %False ' slow speed-up speed = MIN(cnt, 64) CASE 1 ' set on start of first pusher task speed = MAX(0, speed - 1) CASE 2 ' set when both pushers are active speed = MAX(0, speed - 2) END SELECT IF speed <> Hurdy.ctrl(7) THEN Controller Hurdy.channel, 7, speed Hurdy.ctrl(7) = speed END IF IF speed = 0 THEN StopTask %HurM Controller Hurdy.channel, 66, %False ' motor off Hurdy.ctrl(66) = %False IF Task(%HurPL).swit THEN Stoptask %HurPL IF Task(%HurPH).swit THEN Stoptask %HurPH END IF INCR cnt END SUB SUB HurPL () '%HurPL STATIC cnt AS DWORD STATIC pres AS INTEGER STATIC sig AS INTEGER IF ISFALSE Task(%HurPL).tog THEN cnt = 0 pres = 1 sig = 1 Task(%HurPL).freq = 1.3 Task(%HurPL).tog = %True END IF ' use bow pushers - low string IF Hurdy.ctrl(5) <> 2 THEN Controller Hurdy.channel, 5, 2 Hurdy.ctrl(5) = 2 END IF IF ISFALSE cnt MOD 7 THEN pres = pres + (10 * sig) IF pres > 127 THEN sig = -sig pres = 127 END IF IF pres < 0 THEN Controller Hurdy.channel, 64, 64 ' sustain ON Hurdy.ctrl(64) = 64 Controller Hurdy.channel, 5, 1 ' reset ebow only Hurdy.ctrl(5) = 1 StopTask %HurPL EXIT SUB END IF Controller Hurdy.channel, 1, 120 ' prepuls softshift Hurdy.ctrl(1) = 120 KeyPress Hurdy.channel, 40, MIN(pres, 127) ELSE IF Hurdy.ctrl(1) THEN Controller Hurdy.channel, 1, %False Hurdy.ctrl(1) = %False KeyPress Hurdy.channel, 40, %False END IF END IF INCR cnt END SUB SUB HurPH () '%HurPH - bow pusher task for the high string STATIC cnt AS DWORD STATIC pres AS INTEGER STATIC sig AS INTEGER IF ISFALSE Task(%HurPH).tog THEN cnt = 0 pres = 1 sig = 1 Task(%HurPL).freq = 1.3 Task(%HurPH).tog = %True ' no dampers! Controller Hurdy.channel, 64, 1 Hurdy.ctrl(64) = 1 END IF IF Hurdy.ctrl(6) <> 2 THEN Controller Hurdy.channel, 6, 2 Hurdy.ctrl(6) = 2 END IF IF ISFALSE cnt MOD 5 THEN pres = pres + (6 * sig) IF pres > 127 THEN sig = -sig pres = 127 END IF IF pres < 0 THEN Controller Hurdy.channel, 64, 64 ' sustain ON Hurdy.ctrl(64) = 64 Controller Hurdy.channel, 6, 1 ' reset ebow only Hurdy.ctrl(6) = 1 Controller Hurdy.channel, 2, %False Hurdy.ctrl(2) = %False Keypress Hurdy.channel, 64, %False StopTask %HurPH EXIT SUB END IF Controller Hurdy.channel, 2, 120 ' prepuls softshift Hurdy.ctrl(2) = 120 KeyPress Hurdy.channel, 64, pres ELSE IF Hurdy.ctrl(2) THEN Controller Hurdy.channel, 2, %False Hurdy.ctrl(2) = %False KeyPress Hurdy.channel, 64, %False END IF END IF INCR cnt END SUB SUB Religionszwang_stop () ' stopprocedure for religionszwang Controller Hurdy.channel, 66, %False Hurdy.ctrl(66) = %False Controller Hurdy.channel, 7, %False Hurdy.ctrl(7) = %False Release Hurdy.channel, 40, 127 Release Hurdy.channel, 64, 127 ' lites off NoteOff Hurdy.channel, 0 NoteOff Hurdy.channel, 1 Hurdy.ctrl(120) = %False Hurdy.ctrl(121) = %False Task(%HurM).pan = %False ' make sure we reset this... MM_Hurdy_Off END SUB SUB HurCanMeta () ' %Hurmeta ' scoring task for hurdy canon END SUB '[EOF]