' ************************************** ' * * ' * an automated saxophone by * ' * Godfried-Willem Raes * ' * 1991 - 2006 * ' * version 3 * ' ************************************** '02.1991 Version1 , coded in BC7. '06.05.2002 Start coding version 2 '02.05.2006 Start coding version 3 '04.05.2006 kl adaptions to play along on internal midi card (marked [TEMP]) ' note off's vergeten... '11.05.2006: adapted to test hardware on the lowest level. '12.05.2006: debug on Vaio '23.05.2006: moved again to yes. '29.05.2006: pd connnection: translate sliders to note, amp, dc messages - also tagged [TEMP][/TEMP] '01.11.2006: dsPIC board prototype klaar. '09.11.2006: tasks added for evaluation of ds-pic board. '10.11.2006: debugged and tested gwr. %Autosax_test = 48 %AutoSax_scales = 49 %AutoSax_lyrics = 50 %Autosax_patch = 52 ' R&D %autosax_solo = 56 'kl piece ' added gwr 09.11.2006 - can also be used for development. ' we can keep the same tasknrs. for the so cockpit. %Autosax_dspic = 32 %DS_Attack = 35 %DS_Hold = 36 %DS_DECAY = 37 %DS_sustain = 38 %DS_release = 39 %DS_LFO1 = 40 %DS_LFO2 = 41 %DS_Pitchbend = 42 %DS_Portamento = 43 %DS_Midichannel = 45 %Autosaxsynthchan = &H0700 'for development only.. [using PC internal soundcard] DECLARE FUNCTION Init_AutoSax () AS LONG DECLARE SUB AutoSax_Test () DECLARE SUB Autosax_Scales () DECLARE SUB AutoSax_Lyrics () DECLARE SUB AutoSax_UD_Nootnummer () DECLARE SUB Autosax_Windslider () DECLARE SUB Autosax_Ampslider () DECLARE SUB Autosax_DCslider () DECLARE SUB Autosax_PWMslider () DECLARE SUB Autosax_Power () ' adapted. DECLARE SUB Autosax65 () DECLARE SUB Autosax66 () DECLARE SUB Autosax67 () DECLARE SUB Autosax_patch ()'for r&d DECLARE SUB Autosax_DSPic () ' r&d DECLARE SUB Autosax_DS_UD_Note () DECLARE SUB DS_Attack () DECLARE SUB DS_hold () DECLARE SUB DS_decay () DECLARE SUB DS_sustain () DECLARE SUB DS_release () DECLARE SUB DS_LFO2 () DECLARE SUB DS_LFO1 () DECLARE SUB DS_MidiChannel () DECLARE SUB DS_Pitchbend () DECLARE SUB DS_Portamento () DECLARE SUB DS_UD_Port () '[TEMP] GLOBAL fudp AS DWORD GLOBAL ip AS LONG '[/TEMP] GLOBAL ds_channel AS WORD GLOBAL ds_offset AS INTEGER 'DECLARE SUB AutoSax_Solo 'kl piece ' memo: ' controller 1 = windddruk motor PIC2 - pwm ' controller 2 = kegelventiel (vooorlopig) PIC2 -pwm ' controller 65 PIC1 - hoogspannning on/off (relais) ' controller 66 PIC2 - motor on/off ' controller 67 PIC2 - motor error reset ' channel pressure = kegelventiel ' velo-byte = kegelventiel ' note byte = klepkombinaties ' controller 7 = volume rietsignaal PIC3 ' note byte = frekwentie rietsignaal PIC3 ' pitch bend PIC3 ' controller 10 dc offset/duty cycle PIC3 (normally panning, so default is at 64) ' controller 11 reed opening PIC3 (optional PWM signal 0-127) ' program change: 100-127 = kleppen lookup tables ' sysex , keyword sax1 = kleppen lookuptables PIC1 FUNCTION Init_AutoSax () AS LONG 'delete unnecessary buttons ButnSW(2).tag0 = "Pow Off" ' switches solenoid voltage on/off ButnSW(2).tag1 = "Pow ON " ButnSW(2).cptr = CODEPTR(Autosax_POwer) ' redirected to MM_Autosax_ON / OFF functions ButnSW(3).tag0 = "" ' implemented for hardware debug and research ButnSW(4).tag0 = "65on" ButnSW(4).tag1 = "65off" ButnSW(4).cptr = CODEPTR(Autosax65) ' high voltage relay ButnSW(5).tag0 = "66on" ButnSW(5).tag1 = "66off" ButnSW(5).cptr = CODEPTR(Autosax66) ' motor on off ButnSW(6).tag0 = "67on" ButnSW(6).tag1 = "67off" ButnSW(6).cptr = CODEPTR(Autosax67) ' error motor reset ButnSW(7).tag0 = "" ButnSW(8).tag0 = "" ButnSW(9).tag0 = "" ButnSW(10).tag0 = "" ButnSW(11).tag0 = "" ' ButnOS(3).tag = "SavMixer" ' ButnOs(3).cptr = CODEPTR(MixerDump) ' ButnOS(4).tag = "SavNote" ' ButnOs(4).cptr = CODEPTR(fdbckDump) ButnOS(5).tag = "" ButnOS(6).tag = "" ButnOS(8).tag = "" ButnOS(9).tag = "" Task(%Autosax_test).naam = "Test" Task(%Autosax_test).freq = 1 Task(%Autosax_test).cptr = CODEPTR(autosax_test) Task(%Autosax_scales).naam = "Scale" Task(%Autosax_scales).freq = 1 Task(%Autosax_scales).cptr = CODEPTR(Autosax_scales) Task(%AutoSax_Lyrics).naam = "Lyrics" Task(%AutoSax_Lyrics).freq = 4 Task(%Autosax_Lyrics).cptr = CODEPTR(autosax_lyrics) ' Task(%TG100_Test).naam = "TG100Vol" ' Task(%TG100_Test).freq = 10 ' Task(%TG100_Test).cptr = CODEPTR(TG100_SendVolume) Task(%Autosax_patch).naam = "Mpatch" Task(%Autosax_patch).freq = 10 Task(%Autosax_Patch).cptr = CODEPTR(autosax_patch) Task(%AutosaX_pATCH).flags = %Midi_Task Task(%Autosax_dspic).naam = "ds-Pic" Task(%Autosax_dspic).freq = 4 Task(%Autosax_dspic).cptr = CODEPTR(autosax_dspic) Task(%ds_attack).naam = "attack" Task(%ds_attack).freq = 8 Task(%ds_attack).cptr = CODEPTR(ds_attack) Task(%ds_hold).naam = "hold" Task(%ds_hold).freq = 8 Task(%ds_hold).cptr = CODEPTR(ds_hold) Task(%ds_decay).naam = "decay" Task(%ds_decay).freq = 8 Task(%ds_decay).cptr = CODEPTR(ds_decay) Task(%ds_sustain).naam = "sustain" Task(%ds_sustain).freq = 8 Task(%ds_sustain).cptr = CODEPTR(ds_sustain) Task(%ds_release).naam = "release" Task(%ds_release).freq = 8 Task(%ds_release).cptr = CODEPTR(ds_release) Task(%ds_lfo1).naam = "LFO1" Task(%ds_lfo1).freq = 8 Task(%ds_lfo1).cptr = CODEPTR(ds_lfo1) Task(%ds_lfo2).naam = "LFO2" Task(%ds_lfo2).freq = 8 Task(%ds_lfo2).cptr = CODEPTR(ds_lfo2) Task(%ds_Midichannel).naam = "Channel" Task(%ds_midichannel).freq = 1 Task(%ds_midichannel).cptr = CODEPTR(ds_midichannel) Task(%DS_Pitchbend).naam = "Bend" Task(%ds_Pitchbend).freq = 20 Task(%ds_Pitchbend).cptr = CODEPTR(DS_PitchBend) Task(%DS_Portamento).naam = "Porta" Task(%DS_Portamento).freq = 6 Task(%DS_Portamento).cptr = CODEPTR(DS_Portamento) SetDlgItemText gh.Cockpit, %GMT_TITLE, "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR, $gwr 'autosax on MM_AutoSax_On '[TEMP] ' in afwachting van een intern DS-PIC board in autosax. ' Warning "Autosax currently expects the internal midi card to be selected on port 1, channel 0!" ' IF ISFALSE hMidiO(1) THEN ' MSGBOX "hMidiO(1) should be internal soundcard!",,FUNCNAME$ ' EXIT FUNCTION ' END IF ' AutoSax.patch = 73 ' ProgChange Autosax.channel, AutoSax.patch ' Progchange %Autosaxsynthchan, 66 'altsax 'open connection to PD ' HOST ADDR "localhost" TO ip ' fudp = FREEFILE ' warning HEX$(ip) ' UDP OPEN AS fudp TIMEOUT 1000 '[/TEMP] ' to be checked for temporary patch: ' IF hMidiO(0) THEN ' ' init soundcard midi: ' ProgChange Autosax.channel, AutoSax.patch ' ELSE ' MSGBOX "Midi internal card must be selected!",,FUNCNAME$ ' END IF ds_channel = 0 'autosax.channel ds_offset = 6 'transposition for ds-pic synth FUNCTION = %true END FUNCTION SUB AutoSax_Test () ' test procedure for debugging the hardware... STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC udnr AS INTEGER STATIC noot AS BYTE STATIC velo AS BYTE STATIC oldnoot AS BYTE LOCAL period AS SINGLE LOCAL onoff AS SINGLE STATIC mnote AS BYTE STATIC mvelo AS BYTE STATIC j AS INTEGER IF ISFALSE Task(%AutoSax_test).tog THEN DIM TaskParamLabels(9) TaskParamLabels(0)="wvvel" 'note velocity - kegelventiel TaskParamLabels(1)="speed" 'task freq TaskParamLabels(2)="wind" 'ctrl 1 - motor pwm TaskParamLAbels(3)="amp" 'ctrl 7 - DS-Pic volume TaskPAramLabels(4)="DC" 'ctrl 10 - DS_pic dc-offset - to be chANGED TaskParamLabels(5)="opening" 'Ctrl 11 - reed opening 'kl question: wat is het verschil met amp? pwm? TaskParamLabels(6)="velo" ' velo injectr signal midi TaskParamlabels(7)="on/off" ' stacc-legato slider ' ud TaskParamLabels(8)="noot" ' klepkombinatie TaskParamLabels(9)="mnote" ' rietfrekwentie - noot IF Task(%AutoSax_test).hParam = %Null THEN MakeTaskParameterDialog %AutoSax_test,8, Slider(),2,UdCtrl(), TaskParamLabels() slnr = TaskEX(%AutoSax_test).SliderNumbers(0) udnr = TaskEX(%AutoSax_test).UpDownNumbers(0) Slider(slnr+2).cptr = CODEPTR(AutoSax_WindSlider) ' so we can also used it in other tasks Slider(slnr + 3).cptr = CODEPTR(AutoSax_AmpSlider) Slider(slnr + 4).cptr = CODEPTR(AutoSax_DCSlider) Slider(slnr + 5).cptr = CODEPTR(AutoSax_PWMSlider) UDctrl(udnr).cptr = CODEPTR(AutoSax_UD_nootnummer) UDctrl(udnr).value = 48 UDctrl(udnr+1).cptr = CODEPTR(Autosax_UD_midinoot) UDctrl(udnr+1).value = 48 mnote = 48 noot = 48 Slider(slnr).value = 0 ' volume - velo windklep SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Slider(slnr+1).value = 10 ' tempo SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value Slider(slnr + 2).value = 64 ' wind - motor speed SendMessage Slider(Slnr+2).h, %TBM_SETPOS,%True, Slider(Slnr+2).value END IF Task(%AutoSax_test).tog = %True EXIT SUB END IF ' ModeMess &H0100, 123, %False ' Play &H0100, noot-12, velo ' the reed takes twice the frequency of excitation!!! ' oldnoot = noot '[/TEMP] SetDlgItemText gh.Cockpit, %GMT_MSG1, "Note = "& STR$(noot) & " Inject= " & STR$(Mnote) SetDlgItemText gh.Cockpit, %GMT_MSG2, "Velocity = " & STR$(velo) & " Mvelo=" & STR$(mvelo) Task(%AutoSax_test).freq = Slider(slnr+1).value / 16.0 IF Task(%AutoSax_test).freq < 0.1 THEN Task(%AutoSax_Test).freq = 0.1 IF Task(%AutoSax_test).freq > 20 THEN Task(%AutoSax_Test).freq = 20 ' following now handled in the slider callback. This will also work when the task is not running. 'IF Slider(slnr + 2).value <> AutoSax.ctrl(1) THEN 'motor PWM ' AutoSax.ctrl(1) = Slider(slnr + 2).value ' Controller AutoSax.channel, 1, AutoSax.ctrl(1) ' works ok 'END IF ' IF Slider(slnr + 3).value <> AutoSax.ctrl(7) THEN 'DS-Pic volume ' AutoSax.ctrl(7) = Slider(slnr + 3).value ' Controller AutoSax.channel, 7, AutoSax.ctrl(7) ' Controller &H0100, 7, Autosax.ctrl(7) ' for internal soundcard ' END IF ' not yet implemented: ' IF Slider(slnr + 4).value <> AutoSax.ctrl(10) THEN 'DS-Pic dc-offset ' AutoSax.ctrl(10) = Slider(slnr + 4).value ' Controller AutoSax.channel, 10, AutoSax.ctrl(10) ' END IF ' IF Slider(slnr + 5).value <> AutoSax.ctrl(11) THEN 'DS-Pic reed opening ' AutoSax.ctrl(11) = Slider(slnr + 5).value ' Controller AutoSax.channel, 11, AutoSax.ctrl(11) ' END IF OnOff = Slider(slnr+7).value / 128 ' 0- 0.99218 IF OnOff < 0.0078 THEN OnOff = 0.0078125 period = 1! / (32! * ((Slider(slnr+1).value+1) / 128!)) ' tempo - duur in sekonden. IF ISFALSE j THEN '[temp] ' UDP SEND fudp, AT ip, 4001, "noteon" + STR$(Mnote) + CHR$(10) '[/temp] Play Autosax.channel, noot, velo 'Play %Autosaxsynthchan, mnote, mvelo Play ds_channel, noot - ds_offset, mvelo period = period * OnOff ELSE '[temp] 'UDP SEND fudp, AT ip, 4001, "noteoff" + STR$(Mnote) + CHR$(10) '[/temp] Play Autosax.channel, noot , %False 'Play %Autosaxsynthchan, mnote, 0 NoteOff ds_channel, noot-ds_offset 'i = UDctrl(TaskEX(%pprep).UpDownNumbers(0)).value noot = UDCtrl(udnr).value 'klepnoot mnote = UDCtrl(udnr+1).value 'inject note velo = slider(slnr).value 'windklep velo mvelo = slider(slnr+6 ).value ' midi note velocity ' Controller autosax.channel, 2, velo ' test pic2 period = period * (1! - OnOff) END IF Task(%Autosax_test).freq = MAX(MIN(1! / period, 1000),1) INCR j j = j MOD 2 END SUB SUB Autosax_Windslider () ' slider callback LOCAL n AS LONG n = Slider(TaskEX(%autosax_test).SliderNumbers(2)).value Controller AutoSax.channel, 1, n Autosax.ctrl(1) = n END SUB SUB AutoSax_AmpSlider LOCAL n AS LONG n = Slider(TaskEX(%autosax_test).SliderNumbers(3)).value Controller ds_channel, 7, n '[TEMP] 'UDP SEND fudp, AT ip, 4001, "amp" + STR$(n) + CHR$(10) '[/TEMP] END SUB SUB AutoSax_DCSlider LOCAL n AS LONG n = Slider(TaskEX(%autosax_test).SliderNumbers(4)).value '[TEMP] 'UDP SEND fudp, AT ip, 4001, "dc " + STR$((n-64)/64) + CHR$(10) '[/TEMP] END SUB SUB AutoSax_PWMSlider LOCAL n AS LONG n = Slider(TaskEX(%autosax_test).SliderNumbers(5)).value '[TEMP] 'UDP SEND fudp, AT ip, 4001, "pwm " + STR$((n-64)/64) + CHR$(10) '[/TEMP] END SUB SUB AutoSax_UD_Nootnummer () ' for callback on noot UpDown. LOCAL n AS BYTE n = UDCtrl(TaskEX(%autosax_test).UpdownNumbers(0)).value IF n < 0 THEN n = 0 END IF IF n > 127 THEN n = 127 END IF UDCtrl(TaskEX(%AutoSax_test).UpdownNumbers(0)).value = n SetDlgItemText Task(%AutoSax_test).hparam, %GMT_TEXT0_ID + 16, "K=" & STR$(n) END SUB SUB AutoSax_UD_MidiNoot() ' for callback on noot UpDown. (synth noot) LOCAL n AS BYTE n = UDCtrl(TaskEX(%autosax_test).UpdownNumbers(1)).value IF n < 0 THEN n = 0 END IF IF n > 127 THEN n = 127 END IF UDCtrl(TaskEX(%AutoSax_test).UpdownNumbers(1)).value = n SetDlgItemText Task(%AutoSax_test).hparam, %GMT_TEXT0_ID + 17, "N=" & STR$(n) END SUB SUB Autosax_Scales () STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC noot AS DWORD IF ISFALSE Task(%AutoSax_scales).tog THEN DIM TaskParamLabels(4) TaskParamLabels(0)="volu" TaskParamLabels(1)="speed" 'TaskParamLabels(2)="wind" 'ctrl 1 - motor pwm - use the slider in the test task. TaskParamLAbels(2)="amp" 'ctrl 7 - DS-Pic volume TaskPAramLabels(3)="DC" 'ctrl 10 - DS_pic dc-offset TaskParamLabels(4)="opening" 'Ctrl 11 - reed opening IF Task(%AutoSax_scales).hParam = %Null THEN MakeTaskParameterDialog %AutoSax_scales,4, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%AutoSax_scales).SliderNumbers(0) Slider(slnr).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Slider(slnr+1).value = 10 SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value Slider(slnr + 3).value = 64 SendMessage Slider(Slnr+3).h, %TBM_SETPOS,%True, Slider(Slnr+3).value END IF Task(%AutoSax_scales).tog = %True noot = 47 'EXIT SUB END IF '[TEMP] 'UDP SEND fudp, AT ip, 4001, "noteoff" + (STR$(noot)) + CHR$(10) 'Play %Autosaxsynthchan, noot, 0 Play ds_channel, noot - ds_offset, %False INCR noot 'UDP SEND fudp, AT ip, 4001, "noteon" + (STR$(noot)) + CHR$(10) 'Play %Autosaxsynthchan, noot, Slider(slnr).value Play ds_channel, noot - ds_offset, Slider(slnr).value '[/TEMP] Play Autosax.channel, noot, Slider(slnr).value IF noot > Autosax.hightes THEN noot = 47 '48 Task(%AutoSax_Scales).freq = Slider(slnr+1).value / 10! IF Task(%Autosax_Scales).freq < 0.2 THEN Task(%Autosax_Scales).freq = 0.2 ' IF Slider(slnr + 2).value <> AutoSax.ctrl(1) THEN 'motor PWM ' AutoSax.ctrl(1) = Slider(slnr + 2).value ' Controller AutoSax.channel, 1, AutoSax.ctrl(1) ' END IF 'VOLGENDE IS OM UITEINDLIJK TERUG TE ZETTEN - geremd om wind bug te checken.. IF Slider(slnr + 3).value <> AutoSax.ctrl(7) THEN 'DS-Pic volume AutoSax.ctrl(7) = Slider(slnr + 3).value Controller ds_channel, 7, AutoSax.ctrl(7) END IF ' IF Slider(slnr + 4).value <> AutoSax.ctrl(10) THEN 'DS-Pic dc-offset ' AutoSax.ctrl(10) = Slider(slnr + 4).value ' Controller AutoSax.channel, 10, AutoSax.ctrl(10) ' END IF ' IF Slider(slnr + 5).value <> AutoSax.ctrl(11) THEN 'DS-Pic dc-offset ' AutoSax.ctrl(11) = Slider(slnr + 5).value ' Controller AutoSax.channel, 11, AutoSax.ctrl(11) ' END IF END SUB SUB AutoSax_Lyrics () ' demotje gwr LOCAL d AS SINGLE LOCAL i AS DWORD STATIC mel() AS INTEGER STATIC cnt AS LONG STATIC length AS LONG STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC crit AS SINGLE STATIC rest AS LONG STATIC oldnoot AS BYTE IF ISFALSE Task(%Autosax_Lyrics).tog THEN DIM TaskParamLabels(4) TaskParamLabels(0)="volu" TaskParamLabels(1)="speed" 'TaskParamLabels(2)="wind" 'ctrl 1 - motor pwm - use slider in test task TaskParamLAbels(2)="amp" 'ctrl 7 - DS-Pic volume TaskPAramLabels(3)="DC" 'ctrl 10 - DS_pic dc-offset TaskParamLabels(4)="opening" 'Ctrl 11 - reed opening IF Task(%AutoSax_lyrics).hParam = %Null THEN MakeTaskParameterDialog %AutoSax_lyrics,4, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%AutoSax_lyrics).SliderNumbers(0) Slider(slnr).value = 127 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value Slider(slnr+1).value = 48 SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value END IF REDIM mel(32) cnt = %False Task(%Autosax_Lyrics).tog = %True d = Dismel (60,64) EXIT SUB END IF IF rest THEN NoteOff Autosax.channel, oldnoot 'NoteOff %Autosaxsynthchan, oldnoot NoteOff ds_channel, oldnoot - ds_offset Task(%AutoSax_Lyrics).freq = (0.1 + (RND(1) * 0.9)) * (Slider(slnr+1).value/ 32) rest = %False EXIT SUB END IF SELECT CASE cnt CASE 0 IF mel(length) THEN NoteOff Autosax.channel, mel(length) 'AutoSax_Play mel(length), %False mel(0) = 48 + (RND(1) * 40.0) length = 3 + (RND(1) * 28) REDIM mel(length) crit = 0.8 Task(%AutoSax_Lyrics).freq = (1 + (RND(1) * 4)) * (Slider(slnr+1).value/ 32) CASE ELSE DO i = 0 DO mel(cnt) = 48 + (RND(1) * 40.0) ' ' d = Flue (mel(cnt-2),mel(cnt-1),mel(cnt)) d = MelFrameQual (mel(),cnt+1) IF d >= crit THEN EXIT LOOP INCR i IF i > 200 THEN EXIT LOOP LOOP IF d >= crit THEN EXIT LOOP IF i > 200 THEN crit = crit - 0.1 ' i = 0 IF crit < 0 THEN crit = 0 END IF LOOP 'AutoSax_Play mel(cnt),(127 - (cnt * 2)) * (Slider(slnr).value /128) Play Autosax.channel,mel(cnt),(127 - (cnt * 2)) * (Slider(slnr).value /128) '[TEMP] 'Play %Autosaxsynthchan, oldnoot, 0 Play ds_channel, oldnoot - ds_offset, %False 'Play %Autosaxsynthchan, mel(cnt), 127 '(127 - (cnt * 2)) * (Slider(slnr).value /128) Play ds_channel, mel(cnt)-ds_offset, 127 '(127 - (cnt * 2)) * (Slider(slnr).value /128) oldnoot = mel(cnt) '[/TEMP] Task(%AutoSax_Lyrics).freq = (0.1 + (RND(1) * 0.9)) * (Slider(slnr+1).value/ 32) END SELECT ' IF Slider(slnr + 2).value <> AutoSax.ctrl(1) THEN 'motor PWM ' AutoSax.ctrl(1) = Slider(slnr + 2).value ' Controller AutoSax.channel, 1, AutoSax.ctrl(1) ' END IF IF Slider(slnr + 2).value <> AutoSax.ctrl(7) THEN 'DS-Pic volume AutoSax.ctrl(7) = Slider(slnr + 2).value Controller ds_channel, 7, Autosax.ctrl(7) 'Controller AutoSax.channel, 7, AutoSax.ctrl(7) END IF IF Slider(slnr + 3).value <> AutoSax.ctrl(12) THEN 'DS-Pic dc-offset AutoSax.ctrl(12) = Slider(slnr + 3).value Controller AutoSax.channel, 12, AutoSax.ctrl(12) END IF IF Slider(slnr + 4).value <> AutoSax.ctrl(13) THEN 'DS-Pic AutoSax.ctrl(13) = Slider(slnr + 5).value Controller AutoSax.channel, 13, AutoSax.ctrl(13) END IF INCR cnt IF cnt > length THEN cnt = %False rest = %True END IF END SUB SUB AutoSax_Power () ' button switch handler for autosax power control: IF ISFALSE(ButnSW(2).Flag) THEN ButnSW(2).tag0 = "PowOff" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(2).tag0 MM_Autosax_ON ELSE ButnSW(2).tag1 = "PowOn" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(2).tag1 MM_Autosax_Off '[temp] Modemess %Autosaxsynthchan, 123, %False '[/temp] END IF END SUB SUB AutoSax65 () ' button switch handler for autosax controller 65 - high voltage relay IF ISFALSE(ButnSW(4).Flag) THEN ButnSW(4).tag0 = "65Off" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(4).tag0 Controller Autosax.channel, 65, 127 Autosax.ctrl(65) = 127 ELSE ButnSW(4).tag1 = "65On" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(4).tag1 Controller Autosax.channel, 65, %False Autosax.ctrl(65) = %False END IF END SUB SUB AutoSax66 () ' button switch handler for autosax controller 66 - motor on/off IF ISFALSE(ButnSW(5).Flag) THEN ButnSW(5).tag0 = "66Off" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(5).tag0 Controller Autosax.channel, 66, 127 Autosax.ctrl(66) = 127 ELSE ButnSW(5).tag1 = "66On" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(5).tag1 Controller Autosax.channel, 66, %False Autosax.ctrl(66) = %False END IF END SUB SUB AutoSax67 () ' button switch handler for autosax controller 67 - motor error reset IF ISFALSE(ButnSW(6).Flag) THEN ButnSW(6).tag0 = "67Off" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(6).tag0 Controller Autosax.channel, 67, 127 Autosax.ctrl(67) = 127 ELSE ButnSW(6).tag1 = "67On" SetDlgItemText gh.Cockpit, App.butnSWparam, ButnSW(6).tag1 Controller Autosax.channel, 67, %False Autosax.ctrl(67) = %False END IF END SUB SUB autosax_Patch () ' 1 UD controller to change the midi patch ' 1 slider for the volume controller via midi sound STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC udnr AS INTEGER STATIC level AS INTEGER IF ISFALSE Task(%AutoSax_patch).tog THEN DIM TaskParamLabels(1) TaskParamLabels(0)="level" 'ctrl 7 TaskParamLabels(1)="patch" 'prog change IF Task(%AutoSax_patch).hParam = %Null THEN MakeTaskParameterDialog %AutoSax_patch,1, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%AutoSax_patch).SliderNumbers(0) udnr = TaskEX(%AutoSax_patch).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(AutoSax_UD_patch) UDctrl(udnr).value = Autosax.patch Slider(slnr).value = 64 ' volume SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%AutoSax_patch).tog = %True EXIT SUB END IF IF level <> slider(slnr).value THEN level = slider(slnr).value Controller &H100, 7, level END IF END SUB SUB AutoSax_UD_Patch () ' for callback on program changes LOCAL n AS BYTE n = UDCtrl(TaskEX(%autosax_patch).UpdownNumbers(0)).value IF n < 0 THEN n = 0 END IF IF n > 127 THEN n = 127 END IF Modemess &H100, 123, %False ProgChange &H100, n UDCtrl(TaskEX(%AutoSax_patch).UpdownNumbers(0)).value = n SetDlgItemText Task(%AutoSax_patch).hparam, %GMT_TEXT0_ID + 16, "P=" & STR$(n) END SUB SUB Autosax_dspic () ' for evaluation purposes. STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC udnr AS INTEGER STATIC level AS INTEGER STATIC oldnote AS INTEGER IF ISFALSE Task(%AutoSax_dspic).tog THEN DIM TaskParamLabels(2) TaskParamLabels(0)="speed" ' tempo TaskParamLabels(1)="velo" ' note velo TaskParamLabels(2)="note" 'UD IF Task(%AutoSax_dspic).hParam = %Null THEN MakeTaskParameterDialog %AutoSax_dspic,2, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%AutoSax_dspic).SliderNumbers(0) udnr = TaskEX(%AutoSax_dspic).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(Autosax_DS_UD_Note) UDctrl(udnr).value = 48 ' noot Slider(slnr).value = 12 ' speed SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%AutoSax_dspic).tog = %True EXIT SUB END IF IF oldnote THEN NoteOff ds_channel, oldnote oldnote = %False ELSE Play ds_channel, UDctrl(udnr).value - ds_offset, Slider(slnr+1).value oldnote = UDCtrl(UDnr).value - ds_offset END IF Task(%AutoSax_dspic).freq = Slider(slnr).value / 6.0 IF Task(%Autosax_dspic).freq < 0.1 THEN Task(%Autosax_dspic).freq = 0.1 END SUB SUB Autosax_DS_UD_Note () ' for callback on notes LOCAL n AS BYTE n = UDCtrl(TaskEX(%autosax_dspic).UpdownNumbers(0)).value IF n < 0 THEN n = 0 END IF IF n > 127 THEN n = 127 END IF UDCtrl(TaskEX(%AutoSax_dspic).UpdownNumbers(0)).value = n SetDlgItemText Task(%AutoSax_dspic).hparam, %GMT_TEXT0_ID + 16, "N=" & STR$(n + ds_offset) ' note 51 plays 57 END SUB SUB DS_Attack () STATIC slnr AS LONG IF ISFALSE Task(%ds_attack).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 10 TaskParamLabels(0)="attack" 'ctrl 16 IF Task(%ds_attack).hParam = %Null THEN MakeTaskParameterDialog %ds_attack,1, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_attack).SliderNumbers(0) Slider(slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%ds_attack).tog = %True EXIT SUB END IF IF autosax.ctrl(16) <> slider(slnr).value THEN controller ds_channel, 16, slider(slnr).value autosax.ctrl(16) = slider(slnr).value END IF END SUB SUB DS_hold () STATIC slnr AS LONG IF ISFALSE Task(%ds_hold).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 10 TaskParamLabels(0)="hold" 'ctrl 17 IF Task(%ds_hold).hParam = %Null THEN MakeTaskParameterDialog %ds_hold,1, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_hold).SliderNumbers(0) Slider(slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%ds_hold).tog = %True EXIT SUB END IF IF autosax.ctrl(17) <> slider(slnr).value THEN controller ds_channel, 17, slider(slnr).value autosax.ctrl(17) = slider(slnr).value END IF END SUB SUB DS_decay () STATIC slnr AS LONG IF ISFALSE Task(%ds_decay).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 10 TaskParamLabels(0)="decay" 'ctrl 18 IF Task(%ds_decay).hParam = %Null THEN MakeTaskParameterDialog %ds_decay,1, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_decay).SliderNumbers(0) Slider(slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%ds_decay).tog = %True EXIT SUB END IF IF autosax.ctrl(18) <> slider(slnr).value THEN controller ds_channel, 18, slider(slnr).value autosax.ctrl(18) = slider(slnr).value END IF END SUB SUB DS_sustain () STATIC slnr AS LONG IF ISFALSE Task(%ds_sustain).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 10 TaskParamLabels(0)="sustain" 'ctrl 19 IF Task(%ds_sustain).hParam = %Null THEN MakeTaskParameterDialog %ds_sustain,1, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_sustain).SliderNumbers(0) Slider(slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%ds_sustain).tog = %True EXIT SUB END IF IF autosax.ctrl(19) <> slider(slnr).value THEN controller ds_channel, 19, slider(slnr).value autosax.ctrl(19) = slider(slnr).value END IF END SUB SUB DS_release () STATIC slnr AS LONG IF ISFALSE Task(%ds_release).tog THEN DIM TaskParamLabels(0) AS ASCIIZ * 10 TaskParamLabels(0)="release" 'ctrl 80 (&H50) IF Task(%ds_release).hParam = %Null THEN MakeTaskParameterDialog %ds_release,1, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_release).SliderNumbers(0) Slider(slnr).value = 64 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%ds_release).tog = %True EXIT SUB END IF IF autosax.ctrl(80) <> slider(slnr).value THEN controller ds_channel, 80, slider(slnr).value autosax.ctrl(80) = slider(slnr).value END IF END SUB SUB DS_LFO2 () STATIC slnr AS LONG IF ISFALSE Task(%ds_lfo2).tog THEN DIM TaskParamLabels(1) AS ASCIIZ * 10 TaskParamLabels(0)="freq" 'ctrl 93 TaskParamLabels(1)="depth" 'ctrl 1 IF Task(%ds_lfo2).hParam = %Null THEN MakeTaskParameterDialog %ds_lfo2,2, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_lfo2).SliderNumbers(0) Slider(slnr).value = 0 Slider(slnr+1).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value END IF Task(%ds_lfo2).tog = %True EXIT SUB END IF IF autosax.ctrl(93) <> slider(slnr).value THEN controller ds_channel, 93, slider(slnr).value autosax.ctrl(93) = slider(slnr).value END IF ' other ctrl added - incompatible with wind controller !!! IF autosax.ctrl(1) <> slider(slnr+1).value THEN controller ds_channel, 1, slider(slnr+1).value autosax.ctrl(1) = slider(slnr+1).value END IF END SUB SUB DS_LFO1 () STATIC slnr AS LONG IF ISFALSE Task(%ds_lfo1).tog THEN DIM TaskParamLabels(1) AS ASCIIZ * 10 TaskParamLabels(0)="freq" 'ctrl 92 - &H5C TaskParamLabels(1)="depth" ' ctrl 91 - &H5B IF Task(%ds_lfo1).hParam = %Null THEN MakeTaskParameterDialog %ds_lfo1,2, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_lfo1).SliderNumbers(0) Slider(slnr).value = 0 Slider(slnr+1).value = 0 SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value SendMessage Slider(Slnr+1).h, %TBM_SETPOS,%True, Slider(Slnr+1).value END IF Task(%ds_lfo1).tog = %True EXIT SUB END IF IF autosax.ctrl(92) <> slider(slnr).value THEN controller ds_channel, 92, slider(slnr).value autosax.ctrl(92) = slider(slnr).value END IF IF autosax.ctrl(91) <> slider(slnr+1).value THEN controller ds_channel, 91, slider(slnr+1).value autosax.ctrl(91) = slider(slnr+1).value END IF END SUB SUB DS_PitchBend () STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS LONG STATIC pb AS WORD STATIC opb AS WORD IF ISFALSE Task(%ds_pitchbend).tog THEN DIM TaskParamLabels(1) TaskParamLabels(0)="msb" TaskParamLabels(1)="lsb" IF Task(%ds_pitchbend).hParam = %Null THEN MakeTaskParameterDialog %ds_pitchbend,2, Slider(),0,UdCtrl(), TaskParamLabels() slnr = TaskEX(%ds_pitchbend).SliderNumbers(0) END IF Task(%ds_pitchbend).tog = %True EXIT SUB END IF pb = Slider(slnr).value SHIFT LEFT pb, 7 pb = pb OR Slider(slnr+1).value IF pb <> opb THEN Bend ds_channel, Slider(slnr+1).value, Slider(slnr).value opb = pb END IF END SUB SUB DS_MidiChannel () 'only added to check out the midichannel used. - gwr. 09.11.2006 'channel is 0 STATIC TaskParamLabels() AS ASCIIZ*8 STATIC udnr AS INTEGER IF ISFALSE Task(%ds_midichannel).tog THEN DIM TaskParamLabels(0) TaskParamLabels(0)="chan" IF Task(%ds_midichannel).hParam = %Null THEN MakeTaskParameterDialog %ds_midichannel,0, Slider(),1,UdCtrl(), TaskParamLabels() udnr = TaskEX(%ds_midichannel).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(DS_MidiChannel) ' selfreferencing to task! UDctrl(udnr).value = 0 END IF Task(%ds_midichannel).tog = %True EXIT SUB END IF IF udctrl(udnr).value > 15 THEN UDctrl(udnr).value = 15 END IF IF UDctrl(udnr).value < 0 THEN UDctrl(udnr).value = 0 END IF ds_channel = UDctrl(udnr).value SetDlgItemText Task(%ds_midichannel).hparam, %GMT_TEXT0_ID + 16, "K=" & STR$(ds_channel) END SUB SUB DS_Portamento () 'implemented ctrls's: 'portamento 0= off, 1=on overlapping notes only, 2= always on 'portamento time STATIC TaskParamLabels() AS ASCIIZ*8 STATIC slnr AS INTEGER STATIC udnr AS INTEGER IF ISFALSE Task(%DS_Portamento).tog THEN DIM TaskParamLabels(1) TaskParamLabels(0)="porta" 'ctrl 5 - portamento time TaskParamLabels(1)="port" 'UD portamento switch 0,1,2, IF Task(%DS_Portamento).hParam = %Null THEN MakeTaskParameterDialog %DS_Portamento,1, Slider(),1,UdCtrl(), TaskParamLabels() slnr = TaskEX(%DS_Portamento).SliderNumbers(0) udnr = TaskEX(%DS_Portamento).UpDownNumbers(0) UDctrl(udnr).cptr = CODEPTR(DS_UD_port) UDctrl(udnr).value = 0 Slider(slnr).value = 0 ' time SendMessage Slider(Slnr).h, %TBM_SETPOS,%True, Slider(Slnr).value END IF Task(%DS_Portamento).tog = %True EXIT SUB END IF IF udctrl(udnr).value THEN ' portamento time IF autosax.ctrl(5) <> slider(slnr).value THEN autosax.ctrl(5) = slider(slnr).value Controller ds_channel, 5, autosax.ctrl(5) END IF END IF END SUB SUB DS_UD_Port () ' for callback on portamento settings : 0, 1, 2 - controller 65 - must change: also used for power ON !!! LOCAL n AS BYTE n = UDCtrl(TaskEX(%DS_portamento).UpdownNumbers(0)).value IF n < 0 THEN n = 0 END IF IF n > 2 THEN n = 2 END IF Controller ds_channel, 65, n Autosax.ctrl(65) = n UDCtrl(TaskEX(%DS_Portamento).UpdownNumbers(0)).value = n SetDlgItemText Task(%DS_Portamento).hparam, %GMT_TEXT0_ID + 16, "P=" & STR$(n) END SUB 'EOF