' ****************************************** ' * * ' * hardware test and evaluation code * ' * also contains demo pieces * ' * "ReligionsZwang" * ' * "Scientia Vincere Tenebras" * ' ****************************************** ' 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, with Emilie De Vlam ' 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, for performance with Emilie de Vlam ' 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. Fine tuning of parameters. ' 22.11.2007: Eerste try out uitvoering religionszwang. Gray patterns added in harmonic series ' 25.02.2008: Start coding for Scientia Vincere Tenebras. ' 28.02.2008: Further work on scientia. (math!) ' 29.02.2008: debug session. First sounding result pretty deceiving... ' 01.03.2008: Version 1.0 of Scientia recorded. Has some bugs. ' 02.03.2008: Further improvements. Note that whenever we change the strings, the parameters for ' Scientia will and have to change. ' 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 24: cent correction low string (0-100) ' ctrl 25: cent correction high string (0-100) ' 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_LeftLite = 18 ' kant lage snaar %Hurdy_RightLite = 19 ' kant hoge snaar %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 %Hurdy_bend_low = 32 ' cent korrektie ctrl 24 %Hurdy_bend_high = 33 ' ctrl 25 ' 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 ' scientia vincere tenebras: %Scientia = 49 ' first attempt '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 grayflaglow AS BYTE ' flag for application of gray coded melodies grayflaghigh AS BYTE scientia AS BYTE ' flag for the scientia vincere tenebras version using pitch bends ' milowbend AS DWORD ' only for scientia ' mihighbend AS DWORD ' only for scientia END TYPE GLOBAL HurdySound AS Hurdysounds TYPE Hurdy_lut ' look up tables for inharmonicity in hurdy strings freq (1 TO 32) AS SINGLE ' exact frequency of the partial. Index 1 is always the fundamental note (1 TO 32) AS CUR ' fractional midi note mul (1 TO 32) AS INTEGER ' integer multiplier required for ctrl 22 and 23 cent (1 TO 32) AS BYTE ' pitch deviation required for ctrl 24 and 25 END TYPE GLOBAL H_Low() AS Hurdy_Lut GLOBAL H_High() AS Hurdy_Lut DECLARE FUNCTION InitHurdy () AS LONG DECLARE FUNCTION Get_B_Param (BYVAL sg AS SINGLE, BYVAL em AS SINGLE, BYVAL c AS SINGLE, BYVAL L AS SINGLE, BYVAL d AS SINGLE) AS SINGLE ' this one belongs in g_indep. 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_bend_low () ' added 29.02.2008 DECLARE SUB Hurdy_bend_high () 'DECLARE SUB Hurdy_AllOff () - now MM_Hurdy_Off in g_mm.inc DECLARE SUB Hurdy_Lights () ' light test DECLARE SUB Hurdy_LeftLite () DECLARE SUB Hurdy_RightLite () DECLARE SUB Hurdy_LitesOff () 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 Scientia_VincereTenebras () ' %Scientia - 28.02.2008 DECLARE SUB HurCanL () ' %HurL DECLARE SUB HurCanH () ' %HurH DECLARE SUB HurMot () ' %HurM DECLARE SUB HurPL () ' %HurPL DECLARE SUB HurPH () ' %HurPH DECLARE SUB Religionszwang_Stop () DECLARE SUB Hurdy_Lookup () ' required for Scientia vincere tenebras. (28.02.2008) FUNCTION InitHurdy () AS LONG Task(%Hurdy_LeftLite).naam = "Lite 0" Task(%Hurdy_LeftLite).cptr = CODEPTR(Hurdy_LeftLite) Task(%Hurdy_LeftLite).freq = 2 Task(%Hurdy_LeftLite).flags = %False TaskEX(%Hurdy_LeftLite).stopcptr = CODEPTR(Hurdy_LitesOff) Task(%Hurdy_RightLite).naam = "Lite 1" Task(%Hurdy_RightLite).cptr = CODEPTR(Hurdy_RightLite) Task(%Hurdy_RightLite).freq = 2 Task(%Hurdy_RightLite).flags = %False TaskEX(%Hurdy_RightLite).stopcptr = CODEPTR(Hurdy_LitesOff) 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 TaskEX(%Hurdy_Lights).stopCptr = CODEPTR(Hurdy_LitesOff) 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 = "TuneLow" 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 = "TunHigh" Task(%Hurdy_tune_High).cptr = CODEPTR(Hurdy_tune_High) Task(%Hurdy_tune_High).freq = 2 Task(%Hurdy_tune_High).flags = %False Task(%Hurdy_bend_Low).naam = "CentLow" Task(%Hurdy_bend_Low).cptr = CODEPTR(Hurdy_bend_Low) Task(%Hurdy_bend_Low).freq = 10 Task(%Hurdy_bend_Low).flags = %False Task(%Hurdy_bend_High).naam = "CentHigh" Task(%Hurdy_bend_High).cptr = CODEPTR(Hurdy_bend_High) Task(%Hurdy_bend_High).freq = 10 Task(%Hurdy_bend_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 ' scientia: Task(%scientia).naam = "Scientia" Task(%scientia).freq = 1 Task(%scientia).cptr = CODEPTR(Scientia_Vincere_Tenebras) Task(%scientia).flags = %False TaskEX(%scientia).stopcptr = CODEPTR(Religionszwang_stop) ' not a bug! ' 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 Hurdy_Lookup ' initialize the lookups for inharmonicity FUNCTION = %True END FUNCTION SUB Hurdy_LeftLite () mPlay Hurdy.channel, 0, 127 END SUB SUB Hurdy_RightLite () mPlay Hurdy.channel, 1, 127 END SUB SUB Hurdy_LitesOff () MM_Hurdy_Off %MM_White END SUB 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 mPlay Hurdy.channel, oldnote, 0 oldnote = %False END IF IF i < 64 THEN mPlay Hurdy.channel, i, lowpress ' old: if lowpress = 1, the e-bowing will be active ELSE mPlay 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 mPlay Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN mPlay 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 mPlay Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN mPlay 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 cnt AS DWORD Task(%Hurdy_Lights).freq = 1 IF cnt MOD 5 THEN ' lang uit IF Hurdy.ctrl(120) THEN mPlay Hurdy.channel, 0, 0 ' linkerlamp, frontaal gezien. (hoge snaar) hurdy.ctrl(120) = %False END IF ELSE ' kort aan IF ISFALSE Hurdy.ctrl(120) THEN mPlay Hurdy.channel, 0, 127 hurdy.ctrl(120) = %True END IF END IF IF cnt MOD 7 THEN IF Hurdy.ctrl(121) THEN mPlay Hurdy.channel, 1, 0 ' rechterlamp, frontaal gezien. (lage snaar) Hurdy.ctrl(121) = %False END IF ELSE IF ISFALSE Hurdy.ctrl(121) THEN mPlay Hurdy.channel, 1, 127 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 restore 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 restore 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 mPlay Hurdy.channel, note, Hurdy.ctrl(3) ELSE mPlay Hurdy.channel, note, BYVAL i END IF CASE ELSE ' high string IF Hurdy.ctrl(6) = 1 THEN mPlay Hurdy.channel, note, Hurdy.ctrl(4) ELSE mPlay 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 logfile FUNCNAME$ + " - scroll" 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 logfile FUNCNAME$ + " - quit" hwCtrlHurdy = 0 FOR i = Hurdy.lowtes TO Hurdy.hightes mPlay 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 mPlay Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN mPlay 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 mPlay Hurdy.channel, oldnote, 0 oldnote = %False END IF IF ISFALSE cnt THEN mPlay 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(0) = "Tuning" TaskParamlabels(1) = "Level" 'was 2 - probably this caused the crashes we had before 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 mPlay 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 mPlay 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 mPlay Hurdy.channel, 1, 127 ' linker lamp aan Hurdy.ctrl(121) = %True END IF ' mPlay 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) ' mPlay Hurdy.channel, Hnote, 15 + (flgH * 4) ' high string on, sound note 50(Re) ' Controller Hurdy.channel, 23, flgH ' flageolets flgh = cnt MOD 21 mPlay Hurdy.channel, HNote, 15 + (flgH *4) Controller Hurdy.channel, 23, flgH ELSE IF ISFALSE Hurdy.ctrl(120) THEN mPlay Hurdy.channel, 0, 127 ' rechter lamp aan Hurdy.ctrl(120) = %True END IF ' mPlay Hurdy.channel, LNote, 120 ' low string... note 33 (La) ' flgL = ABS(SIN((cnt MOD 21) * 0.314159)) 'controller Hurdy.channel, 3, 10 + (flgH * 3) ' mPlay Hurdy.channel, LNote, 10 + (flgL * 3) '120 ' low string... note 33 (La) ' Controller Hurdy.channel, 22, FlgL flgL = cnt MOD 21 mPlay 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 ' This is a piece in absolute platonic just intonation. ' deze taak start zelf de volgende taken. Geen user interventie nodig. ' de stemming en afregeling van Hurdy moet wel perfekt zijn. ' De kompositorische opbouw van het stukje wordt hier bepaald. STATIC cnt AS DWORD LOCAL SPEED AS INTEGER IF ISFALSE Task(%Relig).tog THEN cnt = %False ProgChange Hurdy.channel, 0 ' nog niet geimplementeerd... 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, 2 ' reset harmonics! Controller Hurdy.channel, 23, 1 Hurdy.ctrl(22) = 1 Hurdy.ctrl(23) = 1 Hurdysound.mihigh = 64 ' midi noot uit te sturen bij begin voor de hoge snaar (open snaar) Hurdysound.milow = 45 ' midi noot uit te sturen bij begin voor de lage snaar (Re, met transp.) Hurdysound.grayflaglow = %False Hurdysound.grayflaghigh = %False Hurdysound.scientia = %False SetDlgItemText gh.Cockpit, %GMT_MSG1, "ReligionsZwang" Task(%Relig).freq = 1 Task(%Relig).tog = %True END IF ' timing in sekonden. SELECT CASE cnt CASE < 10 mPlay Hurdy.channel, Hurdysound.milow, MIN(127,cnt * 10) ' = 45 Hurdysound.lownote = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) ' ctr20 = tuning = 33 Hurdysound.lowfreq = N2F(Hurdysound.lownote) ' werkelijke toonhoogte = re CASE < 20 mPlay Hurdy.channel, Hurdysound.mihigh, MIN(127,(cnt - 10) * 10) ' 64 Hurdysound.highnote = Hurdy.ctrl(21) + (Hurdysound.mihigh - (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 ' licht aan mPlay Hurdy.channel, 0, 127 Hurdy.ctrl(120) = %True END IF CASE < 110 IF ISFALSE Hurdy.ctrl(121) THEN ' licht aan mPlay Hurdy.channel, 1, 127 Hurdy.ctrl(121) = %True END IF CASE < 120 IF ISFALSE Hurdysound.grayflaglow THEN Hurdysound.grayflaglow = %True CASE < 150 IF ISFALSE Hurdysound.grayflaghigh THEN Hurdysound.grayflaghigh = %True CASE > 480 ' this be the end. - duration 8 minutes StopTask(%Relig) ' hier moet nog een decrescendo ingevoegd worden. ' lichten gaan uit in de stop-procedure CASE > 461 DECR Hurdy.ctrl(23) ' flageolet nr. IF Hurdy.ctrl(23) < 1 THEN Hurdy.ctrl(23) = 1 ' high string Controller Hurdy.channel, 23, Hurdy.ctrl(23) IF Hurdy.ctrl(6) <> 1 THEN Controller Hurdy.channel, 6, 1 ' bow mode Hurdy.ctrl(6) = 1 END IF mPlay Hurdy.channel, Hurdysound.mihigh, 127 ' check this CASE > 460 IF Task(%HurH).swit THEN StopTask %HurH Hurdy.ctrl(23) = 20 CASE > 441 DECR Hurdy.ctrl(22) ' flageolet nr. IF Hurdy.ctrl(22) < 1 THEN Hurdy.ctrl(22) = 1 ' low string Controller Hurdy.channel, 22, Hurdy.ctrl(22) IF Hurdy.ctrl(5) <> 1 THEN Controller Hurdy.channel, 5, 1 Hurdy.ctrl(5) = 1 END IF mPlay Hurdy.channel, Hurdysound.milow,64 - ((20 - Hurdy.ctrl(22))*2) ' check this - niet kletteren! CASE > 440 IF Task(%HurL).swit THEN Stoptask %HurL Hurdy.ctrl(22) = 20 CASE > 420 IF Hurdysound.grayflaghigh THEN Hurdysound.grayflaghigh = %False CASE > 410 IF Hurdysound.grayflaglow THEN Hurdysound.grayflaglow = %False CASE > 400 ' naar open snaar op de laagste snaar IF Hurdysound.milow <> 40 THEN Hurdysound.milow = 40 IF Task(%HurPL).swit THEN stoptask %HurPL 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 > 270 '280 ' 290 ' 300 ' 310 IF ISFALSE Task(%HurPL).swit THEN starttask %HurPL INCR Task(%HurM).pan END IF CASE > 240 '250 '260 '270 ' high string pushers IF ISFALSE Task(%HurPH).swit THEN starttask %HurPH INCR Task(%HurM).pan END IF CASE > 200 '220 ' start motor IF ISFALSE Task(%HurM).swit THEN starttask %HurM Task(%HurM).pan = %False END SELECT INCR cnt END SUB SUB Scientia_Vincere_Tenebras () ' intro en startup voor Scientia Vincere Tenebras ' Hierin gebruiken we de reeele partials van de snaar volgens de bevindingen van de moderne fysika. ' deze taak start zelf de volgende taken. Geen user interventie nodig. ' de stemming en afregeling van Hurdy moet wel perfekt zijn. ' De kompositorische opbouw van het stukje wordt hier bepaald. STATIC cnt AS DWORD LOCAL SPEED AS INTEGER LOCAL fundamental AS INTEGER IF ISFALSE Task(%Scientia).tog THEN cnt = %False ProgChange Hurdy.channel, 0 ' nog niet geimplementeerd. 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 ' was 2 ' reset multipliers Controller Hurdy.channel, 23, 1 Hurdy.ctrl(22) = 1 Hurdy.ctrl(23) = 1 Hurdysound.mihigh = 64 ' midi noot uit te sturen bij begin voor de hoge snaar (open snaar) Hurdysound.milow = 45 ' midi noot uit te sturen bij begin voor de lage snaar (Re, met transp.) Hurdysound.grayflaglow = %False Hurdysound.grayflaghigh = %False Hurdysound.scientia = %True ' this is the only difference with religionszwang. SetDlgItemText gh.Cockpit, %GMT_MSG1, "Scientia vincere tenebras" Task(%Scientia).freq = 1 Task(%Scientia).tog = %True END IF ' timing in sekonden. SELECT CASE cnt CASE < 10 mPlay Hurdy.channel, Hurdysound.milow, MIN(127,cnt * 10) ' = 45 Hurdysound.lownote = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) ' ctr20 = tuning = 33 ' so this is 38 at start up. Hurdysound.lowfreq = N2F(Hurdysound.lownote) ' werkelijke toonhoogte = re CASE < 20 mPlay Hurdy.channel, Hurdysound.mihigh, MIN(127,(cnt - 10) * 10) ' 64 Hurdysound.highnote = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24)) Hurdysound.highfreq = N2F(Hurdysound.highnote) ' until here there is no pitch correction involved. We only play the fundamental. CASE < 30 IF ISFALSE Task(%HurL).swit THEN StartTask %HurL ' start partials low string CASE < 40 IF ISFALSE Task(%HurH).swit THEN starttask %HurH ' start partials high string CASE < 80 IF ISFALSE Hurdy.ctrl(120) THEN ' licht aan mPlay Hurdy.channel, 0, 127 Hurdy.ctrl(120) = %True END IF CASE < 110 IF ISFALSE Hurdy.ctrl(121) THEN ' licht aan mPlay Hurdy.channel, 1, 127 Hurdy.ctrl(121) = %True END IF CASE < 120 IF ISFALSE Hurdysound.grayflaglow THEN Hurdysound.grayflaglow = %True CASE < 150 IF ISFALSE Hurdysound.grayflaghigh THEN Hurdysound.grayflaghigh = %True CASE > 480 ' this be the end. - duration 8 minutes StopTask(%Scientia) ' hier moet nog een decrescendo ingevoegd worden. ' lichten gaan uit in de stop-procedure CASE > 461 ' note that the partial number is not the same here as the multiplier in ctrl 23 DECR Hurdy.ctrl(23) ' flageolet nr. on high string IF Hurdy.ctrl(23) < 1 THEN Hurdy.ctrl(23) = 1 ' high string ' real sound pitch is now H_High(fundamental).freq(Hurdy.ctrl(23)) IF Hurdy.ctrl(6) <> 1 THEN Controller Hurdy.channel, 6, 1 ' bow mode Hurdy.ctrl(6) = 1 END IF mPlay Hurdy.channel, Hurdysound.mihigh, 127 ' max. volume fundamental = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24)) Controller Hurdy.channel, 23, H_High(fundamental).mul(Hurdy.ctrl(23)) ' partial number 02.03 ' met pitch bend korrektie: Hurdy.ctrl(25) = H_High(fundamental).cent(Hurdy.ctrl(23)) Controller Hurdy.channel, 25, Hurdy.ctrl(25) CASE > 460 IF Task(%HurH).swit THEN StopTask %HurH Hurdy.ctrl(23) = 20 CASE > 441 DECR Hurdy.ctrl(22) ' flageolet nr. IF Hurdy.ctrl(22) < 1 THEN Hurdy.ctrl(22) = 1 ' low string IF Hurdy.ctrl(5) <> 1 THEN Controller Hurdy.channel, 5, 1 Hurdy.ctrl(5) = 1 END IF mPlay Hurdy.channel, Hurdysound.milow,64 - ((20 - Hurdy.ctrl(22))*2) ' check this - niet kletteren! fundamental = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) Controller Hurdy.channel, 22, H_Low(fundamental).mul(Hurdy.ctrl(22)) ' partial number 02.03 ' met pitch bend korrektie!!! Hurdy.ctrl(24) = H_Low(fundamental).cent(Hurdy.ctrl(22)) Controller Hurdy.channel, 24, Hurdy.ctrl(24) CASE > 440 IF Task(%HurL).swit THEN Stoptask %HurL Hurdy.ctrl(22) = 20 CASE > 420 IF Hurdysound.grayflaghigh THEN Hurdysound.grayflaghigh = %False CASE > 410 IF Hurdysound.grayflaglow THEN Hurdysound.grayflaglow = %False CASE > 400 ' naar open snaar op de laagste snaar IF Hurdysound.milow <> 40 THEN Hurdysound.milow = 40 ' following may be wrong 'Hurdysound.lownote = Hurdy.ctrl(20) + (Hurdysound.milow - (Hurdy.lowtes))'= 33 IF Task(%HurPL).swit THEN stoptask %HurPL CASE > 360 IF Hurdysound.mihigh <> 71 THEN Hurdysound.mihigh = 71 ' transpose high string - now La (57 real) Hurdysound.highnote = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24)) '=57 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) ' following may be wrong Hurdysound.lownote = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) ' = 45 CASE > 270 '280 ' 290 ' 300 ' 310 IF ISFALSE Task(%HurPL).swit THEN starttask %HurPL INCR Task(%HurM).pan END IF CASE > 240 '250 '260 '270 ' high string pushers IF ISFALSE Task(%HurPH).swit THEN starttask %HurPH INCR Task(%HurM).pan END IF CASE > 200 '220 ' start motor IF ISFALSE Task(%HurM).swit THEN starttask %HurM Task(%HurM).pan = %False END SELECT SetDlgItemText gh.Cockpit, %GMT_MSG2, "cn: " & STR$(cnt) INCR cnt END SUB SUB HurCanL () ' %HurL ' forced religion ' Zwangmaesige religion oder religionszwang. ' also used in Scientia vincere tenebras 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 LOCAL fundamental AS INTEGER ' 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 Hurdysound.lownote = Hurdysound.lownote = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) ' = 38 fundamental = Hurdysound.lownote Task(%HurL).tog = %True END IF IF ISFALSE cnt MOD 21 THEN dir = -dir ' sign toggle END IF h = cnt MOD 21 ' harmonieken teller IF HurdySound.grayflaglow THEN IF h <= 15 THEN h = gray(h) ' use gray pattern for melody ELSEIF h < 20 THEN h = gray(h+12) ' no overrun ELSE h = 20 END IF END IF IF Hurdy.ctrl(5) <> 1 THEN Controller Hurdy.channel, 5, 1 END IF mPlay Hurdy.channel, Hurdysound.milow, 27 + (h*5) ' 45 sounds Re=38 , 57 sounds Re=50, unison ' 27 + 100 = 127 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) ' transpositie - grondtoon met tangenten IF ISFALSE Hurdysound.scientia THEN Controller Hurdy.channel, 22, h ' flageolet nr ' de klinkende toonhoogte is: (in religionszwang) HurdySound.lowfreq = N2F(noot) * MAX(h,1) ' platonische boventoon HurdySound.lownote = F2NF(HurdySound.lowfreq) ELSE ' if scientia vincere tenebras flag then ' fundamental = Hurdy.ctrl(20) + (Hurdysound.milow - Hurdy.lowtes) Controller Hurdy.channel, 22, H_Low(noot).mul(MAX(h,1)) ' flageolet nr -multiplier Hurdysound.lowfreq = H_Low(noot).freq(MAX(h,1)) ' echte boventoon volgens lookup Hurdysound.lownote = H_Low(noot).note(MAX(h,1)) ' klinkende fraktionele midi noot Hurdy.ctrl(24) = H_low(fundamental).cent(MAX(h,1)) Controller Hurdy.channel, 24, Hurdy.ctrl(24) ' korrigeer via pich bend! END IF 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 () ' high string melody - task %HurH STATIC h AS INTEGER STATIC cnt AS DWORD STATIC dir AS INTEGER LOCAL noot AS CUR LOCAL d AS SINGLE LOCAL k AS SINGLE LOCAL fundamental AS INTEGER 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 Hurdysound.highnote = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24))'= 50 fundamental = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24))'= 50 END IF IF ISFALSE cnt MOD 21 THEN dir = -dir ' sign toggle END IF h = cnt MOD 21 IF HurdySound.grayflaghigh THEN IF h <= 15 THEN h = gray(h) ' use gray pattern for melody ELSEIF h < 20 THEN h = gray(h+12) ' no overrun ELSE h = 20 END IF END IF IF Hurdy.ctrl(6) <> 1 THEN Controller Hurdy.channel, 6, 1 END IF IF Hurdy.ctrl(6) <> 1 THEN Controller Hurdy.channel, 6, 2 END IF ' de werkelijke grondtoon is nu: noot = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24)) IF ISFALSE Hurdysound.scientia THEN mPlay Hurdy.channel,Hurdysound.mihigh, 67 + (h*3) ' 67 + 60 = 127 Controller Hurdy.channel, 23, h ' flageolet number ' de klinkende toonhoogte is: (in ReligionsZwang) HurdySound.highfreq = N2F(noot) * MAX(h,1) ' frekwentie van de boventoon HurdySound.highnote = F2NF(HurdySound.highfreq) ' fraktionele midi noot ELSE ' scientia vincere tenebras: 'fundamental = Hurdy.ctrl(21) + (Hurdysound.mihigh - (Hurdy.lowtes+24)) Hurdysound.highfreq =H_High(noot).freq(MAX(h,1)) ' echte boventoon volgens lookup Hurdysound.highnote =H_High(noot).note(MAX(h,1)) 'F2NF(Hurdysound.highfreq) ' send multiplier for flageolet: Controller Hurdy.channel, 23, H_High(noot).mul(MAX(h,1)) ' realnote = H_High(fundamental).note(h) Hurdy.ctrl(25) = H_High(fundamental).cent(MAX(h,1)) ' bend Controller Hurdy.channel, 25, Hurdy.ctrl(25) ' korrigeer via pich bend! END IF 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 - Motor control task STATIC cnt AS DWORD STATIC SPEED AS CUR IF ISFALSE Task(%HurM).tog THEN cnt = 1 SPEED = 0 Task(%HurM).freq = 0.75 '1.81 Controller Hurdy.channel, 66, %True Hurdy.ctrl(66) = %True Task(%HurM).tog = %True END IF SELECT CASE Task(%HurM).pan CASE %False ' slow speed-up SPEED = MIN(cnt*2, 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 - 0.5) END SELECT IF SPEED <> Hurdy.ctrl(7) THEN Controller Hurdy.channel, 7, SPEED Hurdy.ctrl(7) = SPEED END IF IF SPEED = 0 THEN Controller Hurdy.channel, 66, %False ' motor off Hurdy.ctrl(66) = %False ' stop pusher tasks: IF Task(%HurPL).swit THEN Stoptask %HurPL IF Task(%HurPH).swit THEN Stoptask %HurPH StopTask %HurM 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 ' enable both e-drive and bowing 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) ' if we want shorter pulses here, we have to make the task.freq higher! Task(%HurPL).freq = 2 ELSE IF Hurdy.ctrl(1) THEN Controller Hurdy.channel, 1, %False Hurdy.ctrl(1) = %False KeyPress Hurdy.channel, 40, %False END IF Task(%HurPL).freq = 1.3 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 ' in fact only required for scientia: Hurdy.ctrl(24) = 0 ' bend off Hurdy.ctrl(25) = 0 Controller Hurdy.channel, 24, 0 Controller Hurdy.channel, 25, 0 ' ----------------------------------- Hurdy.ctrl(120) = %False Hurdy.ctrl(121) = %False Task(%HurM).pan = %False ' make sure we reset this... SetDlgItemText gh.Cockpit, %GMT_MSG1, " " MM_Hurdy_Off END SUB SUB HurCanMeta () ' %Hurmeta ' scoring task for hurdy canon END SUB SUB Hurdy_lookup () ' two dimensional lookup for note/bend ' so we have a separate lookup for every single note on each string. 'TYPE Hurdy_lut ' look up tables for inharmonicity in hurdy strings ' note ( 1 TO 32) AS CUR ' index is partial number ' cent ( 1 TO 32) AS BYTE ' freq ( 1 to 32) as single ' mul ( 1 to 32) as integer 'END TYPE LOCAL i AS LONG LOCAL p AS LONG LOCAL sg AS SINGLE LOCAL em AS SINGLE LOCAL d AS SINGLE LOCAL L AS SINGLE ' volle snaarlengte LOCAL Ln AS SINGLE ' ingekorte snaarlengte met tangenten LOCAL dens AS SINGLE LOCAL T AS SINGLE LOCAL c AS SINGLE LOCAL b AS SINGLE LOCAL n AS LONG LOCAL nf AS CUR LOCAL fmn AS CUR LOCAL f AS SINGLE STATIC tog AS LONG IF ISFALSE tog THEN ' we berekenen de lookup eenmalig. DIM H_Low(33 TO 57) AS GLOBAL Hurdy_Lut DIM H_High(50 TO 74) AS GLOBAL Hurdy_Lut ' low string sg = 7.3 ' kg/l em = 2E11 ' Pa Youngs modulus d = 1.5 '1.4 ' mm L = 1.215 ' m dens = 0.0129 ' 0.01123747692 ' kg/m T = (55^2) * dens * 4 * (L^2) ' snaarspanning in newton c = SQR(T/ dens) ' prop.snelheid in m/s b = Get_B_Param (sg,em,c,L,d) n = 0 FOR i = 33 TO 57 Ln = L/ 2^(n/12) INCR n b = Get_B_Param (sg,em,c,Ln,d) H_Low(i).note(1) = i ' fundamental H_Low(i).freq(1) = N2F(i) H_Low(i).cent(1) = %False H_Low(i).mul(1) = 1 FOR p = 2 TO 32 ' calculate the inharmonic partials H_Low(i).freq(p) = N2F(i) * p * SQR(1+ (b * (p^2))) nf = F2NF(H_low(i).freq(p)) IF nf > 127 THEN EXIT FOR H_Low(i).note(p) = nf ' cur now FIX(nf) ' this was wrong: H_Low(i).cent(p) = (FRAC(nf) * 100) ' korrektie 02.03.2008: H_Low(i).mul(p) = H_low(i).freq(p) \ H_Low(i).freq(1) ' integer divide - this is the value we need for ctrl 22 ' this frequency would be f = H_Low(i).freq(1) * H_Low(i).mul(p) ' this is too low ' converted to fractional midi: fmn = F2NF(f) ' thus the cent correction to be applied partial should become: H_Low(i).cent(p) = (nf - fmn) * 100 NEXT p NEXT i ' high string: sg = 7.3 ' kg/l em = 2E11 ' Pa d = 0.6 '0.7 ' mm L = 1.220 ' m dens = 0.002064 ' '0.003848451 ' kg/m T = (146.83^2) * dens * 4 * (L^2) ' snaarspanning in newton c = SQR(T/ dens) ' prop.snelheid in m/s b = Get_B_Param (sg,em,c,L,d) n = 0 FOR i = 50 TO 74 Ln = L/ 2^(n/12) INCR n b = Get_B_Param (sg,em,c,Ln,d) H_High(i).note(1) = i H_High(i).freq(1) = N2F(i) H_High(i).cent(1) = %False H_High(i).mul(1) = 1 FOR p = 2 TO 32 H_High(i).freq(p) = N2F(i) * p * SQR(1+ (b * (p^2))) nf = F2NF(H_High(i).freq(p)) IF nf > 127 THEN EXIT FOR H_High(i).note(p) = nf 'FIX(nf) ' wrong: H_High(i).cent(p) = (FRAC(nf) * 100) H_High(i).mul(p) = H_High(i).freq(p) \ H_Low(i).freq(1) f = H_High(i).freq(1) * H_High(i).mul(p) fmn = F2NF(f) H_High(i).cent(p) = (nf - fmn) * 100 NEXT p NEXT i tog = %True END IF END SUB SUB Hurdy_bend_low () ' ctrl 24 - e-bow must be ON !!! STATIC slnr AS DWORD IF ISFALSE Task(%Hurdy_bend_low).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 8 TaskParamLabels(0) = "Cents" IF ISFALSE Task(%Hurdy_bend_low).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_bend_low,1,Slider(),0,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_bend_low).SliderNumbers(0) Slider(slnr).value = 0 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_bend_low).tog = %True END IF IF hurdy.ctrl(24) <> slider(slnr).value THEN hurdy.ctrl(24) = slider(slnr).value controller Hurdy.channel, 24, hurdy.ctrl(24) SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Hurdy.ctrl(24) END IF END SUB SUB Hurdy_bend_high () ' ctrl 25 - e-bow must be ON !!! STATIC slnr AS DWORD IF ISFALSE Task(%Hurdy_bend_high).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 8 TaskParamLabels(0) = "Cents" IF ISFALSE Task(%Hurdy_bend_high).hParam THEN slnr = %False MakeTaskParameterDialog %Hurdy_bend_high,1,Slider(),0,UDctrl(),TaskParamLabels() END IF IF slnr = %False THEN slnr = TaskEX(%Hurdy_bend_high).SliderNumbers(0) Slider(slnr).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF 'set controllers for e-drive Controller Hurdy.channel, 70, %True ' enable edrive high string Controller Hurdy.channel, 6, 1 ' make edrive exclusive and use velo byte for amplitude Controller Hurdy.channel, 64, %False ' sustain off Task(%Hurdy_bend_high).tog = %True END IF IF Hurdy.ctrl(25) <> slider(slnr).value THEN Hurdy.ctrl(25) = slider(slnr).value controller Hurdy.channel, 25, Hurdy.ctrl(25) SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Hurdy.ctrl(25) END IF END SUB FUNCTION Get_B_Param (BYVAL sg AS SINGLE, BYVAL em AS SINGLE, BYVAL c AS SINGLE, BYVAL L AS SINGLE, BYVAL d AS SINGLE) AS SINGLE ' this one belongs in g_indep. ' for doc. and info see: hurdy_inhar.bas, gwr 02.2008 LOCAL r AS SINGLE LOCAL k AS SINGLE LOCAL lambda AS SINGLE r = (d/2) / 1000 k = ((r^2)*em)/ (4 *sg) lambda = k / (c^2) FUNCTION = (lambda * (Pi^2) / (L^2)) / 1000 END FUNCTION '[EOF]