' ************************************************* ' * * ' * for clarinet and interactive robot(s) * ' * 2010 * ' * Godfried-Willem RAES * ' * A composition commissioned by * ' * Daniel Pastene * ' ************************************************* ' 05.06.2001 started off from Lickstick code framework. ' 29.07.2001 cannot be compiled without LickStick ! ' 13.06.2002 adapted to version 5.82 ' 11.10.2003 adepted to version 7.20 ' 27.03.2005 adapted to PBWIN8.0 ' 03.10.2006: adapted to new paths for audiofiles ' 26.01.2010: Based on the original code, Woodstock_Jazz is written for Daniel Pastene ' for the Jazz&Sounds Festival, march 2010. ' Output is on the M&M robots. ' 25.02.2010: Further modification of code in order to use it for Jazz&Sounds ' 5.03.2010: listen task now working.. but without proper initialisation, CQT produces nonsense! ' 15.03.2010 xof found well hidden reason why registers closed: if the %MIDI_TASK task flag is set, Stoptask sends an alloff controller, which ckoses the registers on harmO ' %MIDI_TASK flags removed for now.. %WoodstockJazz_Score_Task = 17 %ws_wind = 18 %ws_trem = 19 %ws_valve = 20 %WoodstockJazz_V1_Task = 25 ' Voice 1 / Stimme 1 %WoodstockJazz_V2_Task = 26 ' Voice 2 / Stimme 2 #IF NOT %DEF(%Pattern1_Task) %Pattern1_Task = 28 ' Formula 1 %Pattern2_Task = 29 ' Formula 2 %Pattern3_Task = 30 ' Formula 3 #ENDIF '%ClarDetune_Task = 32 ' delay line 1 ' as in cellopi, lickstick and Woodstock %ws_imi = 32 %InvFast_Task = 33 ' midi delay line players %BackInv_Task = 34 %BackSlow_Task = 35 %Gerade_Task = 36 ' straight delay line %ws_Vox1 = 37 %ws_Vox2 = 38 %ws_Vox3 = 39 %ws_Vox4 = 40 %ws_dens = 41 %ws_ddens = 42 %ws_loop = 43 %ws_randloop = 44 ' '%LS_RingModulator_Task = %AudioRingModulator_Task ' =53 specific for LickStick/WoodStock '%LS_PitchShift_Task = %AudioVarspeed_Task ' =56 split off from %AudioProcess Task 07.03.2000 GLOBAL Clarinet AS MUSICIAN GLOBAL hwCtrlharmO AS LONG GLOBAL hwRegharmO AS LONG GLOBAL lastnotein AS LONG DECLARE FUNCTION InitWoodStockJazz () AS LONG 'DECLARE SUB WoodstockJazzInitSynth () DECLARE SUB ButnSW_WoodstockJazzStartStop () DECLARE SUB WoodstockJazzScore() DECLARE SUB WoodstockJazzListen () ' midi input listening task DECLARE SUB WoodstockJazzPatternAlgo (pattern AS BYTE) ' input score calculation DECLARE SUB SetJazzContext (noot?, velo?) ' as in cellopi DECLARE SUB WoodstockJazzDoEvent () ' interactive score ' following is borrowed from Lickstick module... 'DECLARE SUB GetLastNote(noot?, velo?, Instrument AS musician) ' generalized version to replace former individual procedures ' in Cellopi, Cohiba, Obotek, Toverfluit... DECLARE SUB WoodstockJazzPattern1 () ' Formel 1 DECLARE SUB WoodstockJazzPattern2 () ' Formel 2 DECLARE SUB WoodstockJazzPattern3 () ' Formel 3 ' borrowed from Lickstick: DECLARE SUB Woodstockjazz_Stock1 () ' stimme1 / voice1 / stick1 DECLARE SUB Woodstockjazz_Stock2 () ' audio tasks 'DECLARE SUB WoodstockJazzPitchShift () ' speeds up/down recorded sample 'DECLARE SUB WoodstockJazzPlaySample () ' plays prerecorded samples from disk - WoodstockJazzSpecific 'DECLARE SUB WoodstockJazzRingModulator () ' midi delaylines: 'DECLARE SUB ClarDetune() ' uses midi pitchshift DECLARE SUB WoodstockJazzDelayInvertFast () DECLARE SUB WoodstockJazzDelayBackInvert () DECLARE SUB WoodstockJazzDelayBackSlow () DECLARE SUB WoodstockJazzDelayPlayerNormal () ' generalizable: ' borrowed from lickstick module: DECLARE FUNCTION Woodstockjazz_GetDifferentPatternNote (PatternSeq() AS PatternSequenceType, pattern AS BYTE) AS INTEGER '------------------------------------------------------------------- FUNCTION InitWoodstockJazz () AS LONG LOCAL tasknr AS INTEGER LOCAL nr AS LONG LOCAL CockpitLayo AS CockpitLabels LOCAL i AS LONG FUNCTION = %False IF ISFALSE hMidiI(0) THEN ErrorMidiIn : EXIT FUNCTION IF ISFALSE hMidiO(0) THEN ErrorMidiOut : EXIT FUNCTION ' SelectMidiEquipment $WOODSTOCKINI, Meq() ' Update_MidiEquipment Meq() ReadPatternRecognitionDataFile $WOODSTOCKINI ' ReadSynthConfigFile $WOODSTOCKINI ,Meq() ' should know the Meq() selected!!! ReadCockpitLabelsFromFile $WOODSTOCKINI, CockpitLayo Recording_Available = %False ' false on init. - global variable GetInstrumentParams Clarinet, %ID_Clarinet Clarinet.channel = 0 ' midi input listening channel Clarinet.patch = %ID_Clarinet ' gm patch is 71 Recog.Cptr = CODEPTR(WoodstockJazzDoEvent) ' input recognition callback Init_MM MM_Panicbuttonwindow MM_Harmo_On MM_Harmo_On %MM_Regs ProgChange Harmo.channel, 122 ButnSW(1).tag0 = "START" ' start/stop toggle ButnSW(1).tag1 = "STOP" ButnSW(1).cptr = CODEPTR(ButnSW_WoodstockJazzStartStop) ' change the default routing !!! ButnSW(2).tag0 = "" ' "STAFF" ' creates/kills a music monitoring window ButnSW(3).tag0 = "" ' "USER" ' creates/kills a user feedback window ButnSW(7).tag0 = "harmOCtrl tog" ButnSW(7).tag1 = "harmOCtrl tog" ButnSW(7).cptr = CODEPTR(harmO_Controlroom) ButnSW(8).tag0 = "RegisterCtrl tog" ButnSW(8).tag1 = "RegisterCtrl tog" ButnSW(8).cptr = CODEPTR(harmO_Registers) '%False ButnSW(9).tag0 = "" ButnSW(10).tag0 = "" ButnSW(11).tag0 = "" ' ONE SHOT FUNCTIONS: ButnOS(1).tag = "" ButnOS(2).tag = "" ButnOS(3).tag = "" ButnOS(4).tag = "" ButnOS(5).tag = "" ButnOS(6).tag = "" ButnOS(8).tag = "Clear" ' clears delay lines ButnOS(7).tag = "" ButnOS(9).tag = "" ButnOS(10).tag = "" ' declaration of specific tasks: Task(%Listen_Task).naam = "Listen" Task(%Listen_Task).freq = 30 Task(%Listen_Task).channel = 0 ' &H0400 'Clarinet.channel Task(%Listen_Task).cptr = CODEPTR(WoodstockJazzListen) Task(%Listen_Task).starttime = 0 Task(%Listen_Task).stoptime = 1000 Task(%Listen_Task).Rit.minduur = Clarinet.minduur/1000 ' in ms in type Task(%Listen_Task).Rit.maxduur = Clarinet.maxduur/1000 Task(%Listen_Task).flags = Task(%Listen_Task).flags OR %HARM_TASK OR %SCORE_TASK 'OR %MIDI_TASK SetMidiListenChannel Task(%Listen_Task).channel, 1 warning "patch for jazz and sounds: Gi-10 on port 0 (input & output) InitP2M "GI10", 0 '&H400 'Task(%Listen_Task).channel ' Task(%WoodstockJazz_Score_Task).naam = "Scoring" ' for automatic playing - scheduler ' Task(%WoodstockJazz_Score_Task).freq = 1 ' Task(%WoodstockJazz_Score_Task).tempo = 60 ' Task(%WoodstockJazz_Score_Task).cptr = CODEPTR(WoodstockJazzScore) Task(%ws_wind).naam = "wind" Task(%ws_wind).freq = 8 Task(%ws_wind).cptr = CODEPTR(ws_Wind) Task(%ws_trem).naam = "tremulant" Task(%ws_trem).freq = 8 Task(%ws_trem).cptr = CODEPTR(ws_trem) TaskEx(%ws_trem).stopcptr = CODEPTR(ws_trem_off) Task(%ws_valve).naam = "valve" Task(%ws_valve).freq = 5 Task(%ws_valve).cptr = CODEPTR(ws_valve) ' Task(%WoodstockJazz_V1_Task).naam = "wStock 1" ' vertical harmony stimme 1 ' Task(%WoodstockJazz_V1_Task).cptr = CODEPTR(Woodstockjazz_Stock1) ' Task(%WoodstockJazz_V1_Task).freq = 1 ' Task(%WoodstockJazz_V1_Task).tempo = 20 ' Task(%WoodstockJazz_V1_Task).flags = Task(%WoodstockJazz_V1_Task).flags OR %SCORE_TASK '' OR %MIDI_TASK ' Task(%WoodstockJazz_V2_Task).naam = "wStock 2" ' vertical harmony stimme 2 ' Task(%WoodstockJazz_V2_Task).cptr = CODEPTR(Woodstockjazz_Stock2) ' Task(%WoodstockJazz_V2_Task).freq = 1 ' Task(%WoodstockJazz_V2_Task).tempo = 20 ' Task(%WoodstockJazz_V2_Task).flags = Task(%WoodstockJazz_V2_Task).flags OR %SCORE_TASK ''OR %MIDI_TASK Task(%Pattern1_Task).naam = "Formula1" Task(%Pattern1_Task).freq = 20 Task(%Pattern1_Task).tempo = 60 Task(%Pattern1_Task).cptr = CODEPTR(WoodstockJazzPattern1) Task(%Pattern1_Task).starttime = -1 Task(%Pattern1_Task).stoptime = 1000 Task(%Pattern1_Task).Rit.minduur = .035 Task(%Pattern1_Task).Rit.maxduur = 4 ' in s ' Task(%Pattern1_Task).flags = Task(%Pattern1_Task).flags' OR %MIDI_TASK Task(%Pattern2_Task).naam = "Formula2" Task(%Pattern2_Task).freq = 30 Task(%Pattern2_Task).tempo = 61 Task(%Pattern2_Task).cptr = CODEPTR(WoodstockJazzPattern2) Task(%Pattern2_Task).starttime = -1 Task(%Pattern2_Task).stoptime = 1000 Task(%Pattern2_Task).Rit.minduur = .025 Task(%Pattern2_Task).Rit.maxduur = 4 ' in s ' Task(%Pattern2_Task).flags = Task(%Pattern2_Task).flags 'OR %MIDI_TASK Task(%Pattern3_Task).naam = "Formula3" Task(%Pattern3_Task).freq = 16 Task(%Pattern3_Task).tempo = 62 Task(%Pattern3_Task).cptr = CODEPTR(WoodstockJazzPattern3) Task(%Pattern3_Task).starttime = -1 Task(%Pattern3_Task).stoptime = 1000 Task(%Pattern3_Task).Rit.minduur = .045 Task(%Pattern3_Task).Rit.maxduur = 4 ' in s ' Task(%Pattern3_Task).flags = Task(%Pattern3_Task).flags 'OR %MIDI_TASK ' Task(%ClarDetune_Task).naam = "Detune" ' Task(%ClarDetune_Task).freq = 24 ' Task(%ClarDetune_Task).cptr = CODEPTR(ClarDetune) ' Task(%ClarDetune_Task).Rit.minduur = 0.035 ' in s ' Task(%ClarDetune_Task).Rit.maxduur = 5.000 ' in s ' Task(%ClarDetune_Task).flags = Task(%ClarDetune_Task).flags OR %MIDI_TASK Task(%InvFast_Task).naam = "FastInv" Task(%InvFast_Task).freq = 60 Task(%InvFast_Task).cptr = CODEPTR(WoodstockJazzDelayInvertFast) Task(%InvFast_Task).Rit.minduur = 0.050 ' in s Task(%InvFast_Task).Rit.maxduur = 5.000 ' in s Task(%InvFast_Task).flags = Task(%InvFast_Task).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%BackInv_Task).naam = "InvCanc" Task(%BackInv_Task).freq = 58 Task(%BackInv_Task).cptr = CODEPTR(WoodstockJazzDelayBackInvert) Task(%BackInv_Task).Rit.minduur = 0.050 ' in s Task(%BackInv_Task).Rit.maxduur = 5.000 ' in s Task(%BackInv_Task).flags = Task(%BackInv_Task).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%BackSlow_Task).naam = "SloCanc" Task(%BackSlow_Task).freq = 31 Task(%BackSlow_Task).cptr = CODEPTR(WoodstockJazzDelayBackSlow) Task(%BackSlow_Task).Rit.minduur = 0.10 ' in s Task(%BackSlow_Task).Rit.maxduur = 10.000 ' in s Task(%BackSlow_Task).flags = Task(%BackSlow_Task).flags OR %HARM_TASK ''OR %MIDI_TASK Task(%Gerade_Task).naam = "Straight" Task(%Gerade_Task).freq = 35 Task(%Gerade_Task).cptr = CODEPTR(WoodstockJazzDelayPlayerNormal) Task(%Gerade_Task).Rit.minduur = 0.10 ' in s Task(%Gerade_Task).Rit.maxduur = 10.000 ' in s Task(%Gerade_Task).flags = Task(%Gerade_Task).flags OR %HARM_TASK ''OR %MIDI_TASK Task(%ws_imi).naam = "Imitate" Task(%ws_imi).freq = 20 Task(%ws_imi).cptr = CODEPTR(WS_Imi) Task(%ws_imi).flags = Task(%ws_imi).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%ws_dens).naam = "dens" Task(%ws_dens).freq = 20 Task(%ws_dens).cptr = CODEPTR(DensTes) Task(%ws_dens).flags = Task(%ws_dens).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%ws_ddens).naam = "Ddens" Task(%ws_ddens).freq = 20 Task(%ws_ddens).cptr = CODEPTR(DDensTes) Task(%ws_ddens).flags = Task(%ws_ddens).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%ws_loop).naam = "loop" Task(%ws_loop).freq = 20 Task(%ws_loop).cptr = CODEPTR(WS_loop) Task(%ws_loop).flags = Task(%ws_loop).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%ws_randloop).naam = "rndloop" Task(%ws_randloop).freq = 20 Task(%ws_randloop).cptr = CODEPTR(WS_randloop) Task(%ws_randloop).flags = Task(%ws_randloop).flags OR %HARM_TASK '' OR %MIDI_TASK Task(%ws_vox1).naam = "Vox1" Task(%ws_Vox1).freq = 0.1666 ' 1.8 Task(%ws_Vox1).tempo = 6 ' 54 Task(%ws_Vox1).cptr = CODEPTR(Ws_Vox1) Task(%ws_Vox1).flags = Task(%Baklava_Vox4).flags OR %HARM_TASK Task(%ws_Vox1).starttime = -1 Task(%ws_Vox1).stoptime = 1000 Task(%ws_Vox1).Rit.minduur = 0.125 ' 050 ' in s Task(%ws_Vox1).Rit.maxduur = 1.000 ' in s Task(%ws_vox2).naam = "Vox2" Task(%ws_Vox2).freq = 0.1666 ' 1.8 Task(%ws_Vox2).tempo = 6 ' 54 Task(%ws_Vox2).cptr = CODEPTR(Ws_Vox2) Task(%ws_Vox2).flags = Task(%Baklava_Vox4).flags OR %HARM_TASK Task(%ws_Vox2).starttime = -1 Task(%ws_Vox2).stoptime = 1000 Task(%ws_Vox2).Rit.minduur = 0.125 ' 050 ' in s Task(%ws_Vox2).Rit.maxduur = 1.000 ' in s Task(%ws_vox3).naam = "Vox3" Task(%ws_Vox3).freq = 0.1666 ' 1.8 Task(%ws_Vox3).tempo = 6 ' 54 Task(%ws_Vox3).cptr = CODEPTR(Ws_Vox3) Task(%ws_Vox3).flags = Task(%Baklava_Vox4).flags OR %HARM_TASK Task(%ws_Vox3).starttime = -1 Task(%ws_Vox3).stoptime = 1000 Task(%ws_Vox3).Rit.minduur = 0.125 ' 050 ' in s Task(%ws_Vox3).Rit.maxduur = 1.000 ' in s Task(%ws_vox4).naam = "Vox4" Task(%ws_Vox4).freq = 0.1666 ' 1.8 Task(%ws_Vox4).tempo = 6 ' 54 Task(%ws_Vox4).cptr = CODEPTR(Ws_Vox4) Task(%ws_Vox4).flags = Task(%Baklava_Vox4).flags OR %HARM_TASK Task(%ws_Vox4).starttime = -1 Task(%ws_Vox4).stoptime = 1000 Task(%ws_Vox4).Rit.minduur = 0.125 ' 050 ' in s Task(%ws_Vox4).Rit.maxduur = 1.000 ' in s ' realtime audio tasks:----------------------------------------------- 'Task(%AudioDelay_Task).naam = "Delay" ' = 48 ' Task(%AudioDelay_Task).cPtr = CODEPTR(gwrAudioDelay) ' in gmt_gwr.bas ' Task(%AudioDelay_Task).freq = 20 ' Task(%AudioDelay_Task).duur = 8000 'Task(%AudioSample_Task).naam = "Record" ' =49 ' Task(%AudioSample_Task).cPtr = CODEPTR(gwrRecordSample) ' in gmt_gwr.bas ' Task(%AudioSample_Task).freq = 20 ' Task(%AudioSample_Task).duur = 4000 ' was 3000 on 28.02.2000 ' this time is increased during the piece. ' (cfr. do-event code) 'Task(%AudioPlayReversed_Task).naam = "Reverse" '50 ' Task(%AudioPlayReversed_Task).cPtr = CODEPTR(gwrPlayReversed) ' backwards ' Task(%AudioPlayReversed_Task).freq = 20 ' Task(%AudioPlaySample_Task).naam = "PlaySamp" ' = 51 - playback of prerecorded samples ' Task(%AudioPlaySample_Task).cPtr = CODEPTR(WoodstockJazzPlaySample) ' - specific code for WoodstockJazz ' Task(%AudioPlaySample_Task).freq = 20 ' ' Task(%AudioPlayRecordedSample_Task).naam = "PlayBack" '[ = 52] ' Task(%AudioPlayRecordedSample_Task).cPtr = CODEPTR(gwrPlayRecordedSample) ' in gmt_gwr.bas ' Task(%AudioPlayRecordedSample_Task).freq = 22 ' Task(%LS_RingModulator_Task).naam = "RingMod" ' 53 ' Task(%LS_RingModulator_Task).cPtr = CODEPTR(WoodstockJazzRingModulator) ' Task(%Ls_RingModulator_Task).freq = 7 ' Task(%AudioCrossModulator_Task).naam = "CrossMod" ' 54 ' Task(%AudioCrossModulator_Task).cPtr = CODEPTR(gwrCrossModulator) ' in gmt_gwr.bas ' Task(%AudioCrossModulator_Task).freq = 6 ' Task(%AudioCrossTimeModulator_Task).naam = "CrossTim" ' 55 ' in gmt_gwr.bas ' Task(%AudioCrossTimeModulator_Task).cPtr = CODEPTR(gwrCrossTimeModulator) ' Task(%AudioCrossTimeModulator_Task).freq = 6 ' Task(%LS_PitchShift_Task).naam = "VarSpeed" ' split of from audioprocess 07.03.2000 ' Task(%LS_PitchShift_Task).cPtr = CODEPTR(WoodstockJazzPitchShift) ' Task(%LS_PitchShift_Task).freq = 8 ' nr = ReadAudioDataFromFile ($WoodStockINI, AudioFader()) ' dll call ' for now, lets delete audiofader tasks... ' Task(0).naam = "" ' Task(0).cPtr = %False ' Task(AudioFader(0).TaskNr).naam = "" ' Task(AudioFader(0).TaskNr).cPtr = %False ' Task(AudioFader(1).TaskNr).naam = "" ' Task(AudioFader(1).TaskNr).cPtr = %False ' WoodstockJazzInitSynth ' FOR i = %WoodstockJazz_V1_Task TO %gerade_task ''causes stoptask to close registers.. ' Task(i).channel = Harmo.channel ' NEXT LastNotePlayed = 50 'Bb Clarinet. '' ' create the melody window automatically on startup: - not used here and it sometimes stays hanging after we closed Gmt.. '' LOCAL msg AS tagMSG '' msg.hWnd = gh.Cockpit '' msg.message = %WM_COMMAND '' msg.wParam = %GMT_BUTNSW_ID + 5 ' creates score display window. '' msg.lParam = %Null '' DispatchMessage msg '' DrawAllPatterns gh.MelPat ' display the score... (this only prepares the window size!) ' write caption bars: LOCAL m AS ASCIIZ * 40 m = "GMT: " Sendmessage gh.Cockpit, %WM_SETTEXT,0, VARPTR(m) m = " Score" SendMessage gh.MelPat, %WM_SETTEXT,0, VARPTR(m) FUNCTION = %True END FUNCTION SUB WoodstockJazzDoEvent () ' ' recognition wave playing waits for device available, so that the sample always plays, even if too late... ' ' however, in the present version, there is no cueing up of files/ tracks to be played... ' STATIC delaytimecounter AS BYTE ' LOCAL chk AS BYTE ' ' IF ISFALSE Task(%AudioPlaySample_Task).swit THEN StartTask %AudioPlaySample_Task ' ' specific version for WoodstockJazz. ' DrawAllPatterns gh.MelPat ' SELECT CASE Recog.nr ' CASE 1 ' ' samples: detunes ' IF Task(%ClarDetune_Task).swit THEN ' 'StartTask %ClarDetune_Task ' starts/stops velo-dependent detuning on recognition of La ' IF BIT(Task(%BackInv_Task).swit,%TASK_ONOFF) THEN ' StopTask %BackInv_Task ' ReadDelayLine% %BackInv_Task, 0, 0 ' force a reset ' END IF ' ELSE ' 'StopTask %ClarDetune_Task ' 'ReadDelayLine% %ClarDetune_Task, 0,0 ' force reset ' IF ISFALSE Task(%BackInv_Task).swit THEN ' StartTask %BackInv_Task ' ELSE ' StopTask %BackInv_Task ' ReadDelayLine% %BackInv_Task, 0, 0 ' force a reset ' END IF ' END IF ' WoodstockJazzPatternAlgo Recog.nr - 1 ' recalculate new pattern ' CASE 2 ' ' samples: ademklasse ' chk = %False ' '' IF ISFALSE Task(%AudioSample_Task).swit THEN ' ''IF ISFALSE Task(%AudioDelay_Task).swit THEN ' '' Task(%AudioSample_Task).duur = Task(%AudioSample_Task).duur * 1.5 ' recording duration ' ' was set to 5000 ms before 29.02.2000. ' '' StartTask %AudioSample_Task ' autostops. ' '' chk = %True ' IF BIT(Task(%Gerade_Task).swit,%TASK_ONOFF) THEN ' StopTask %Gerade_Task ' ReadDelayLine% %Gerade_Task, 0, 0 ' force a reset ' END IF ' '' END IF ' '' END IF ' IF ISFALSE chk THEN ' IF ISFALSE Task(%Gerade_Task).swit THEN ' StartTask %Gerade_Task ' ELSE ' StopTask %Gerade_Task ' ReadDelayLine% %Gerade_Task, 0, 0 ' force a reset ' END IF ' END IF ' WoodstockJazzPatternAlgo Recog.nr -1 ' CASE 3 ' ' samples: multiphonics ' ' mPlay RT recorded sample. only if a recorded sample is available... ' '' IF Recording_Available THEN ' ' flag to signal availibility of a recorded sample. ' '' IF ISFALSE Task(%AudioPlayRecordedSample_Task).swit THEN ' '' StartTask %AudioPlayRecordedSample_Task ' autostops ' '' IF BIT(Task(%BackSlow_Task).swit,%TASK_ONOFF) THEN ' '' StopTask %BackSlow_Task ' '' ReadDelayLine% %BackSlow_Task, 0, 0 ' force a reset ' '' END IF ' '' ELSE ' '' IF BIT(Task(%BackSlow_Task).swit,%TASK_ONOFF) THEN ' '' StopTask %BackSlow_Task ' '' ReadDelayLine% %Backslow_Task, 0,0 ' reset ' '' END IF ' '' END IF ' '' ELSE ' IF ISFALSE Task(%BackSlow_Task).swit THEN ' StartTask %BackSlow_Task 'WoodstockJazzDelayBackSlow ' ELSE ' StopTask %BackSlow_Task ' ReadDelayLine% %BackSlow_Task, 0, 0 ' force a reset ' END IF ' ''END IF ' WoodstockJazzPatternAlgo Recog.nr -1 ' CASE 4 ' ' samples: Pitched clicks ' ' start audio delay line... ' ' we pass the delay time in Task().duur , expressed in milliseconds ' ' the duration of the delay event in Task().stoptime, expressed in seconds ' ''IF ISFALSE Task(%AudioDelay_Task).swit THEN ' '' INCR delaytimecounter ' '' Task(%AudioDelay_Task).duur = 2000 - (delaytimecounter * 100) ' in ms. ' '' IF Task(%AudioDelay_Task).duur < 255 THEN Task(%AudioDelay_Task).duur = 255 ' '' Task(%AudioDelay_Task).stoptime = 30 - (delaytimecounter) ' in seconds ' '' IF Task(%AudioDelay_Task).stoptime < 1 THEN Task(%AudioDelay_Task).stoptime = 1 ' '' StartTask %AudioDelay_Task ' '' ' SetDlgItemText hCockpit, %GMT_MSG1, "Audio-delay " & STR$(Task(%AudioDelay_Task).duur) & "ms " & STR$(Task(%AudioDelay_Task).stoptime) & " s " ' ''ELSE ' ' start a midi-delay... ' IF ISFALSE Task(%InvFast_Task).swit THEN ' StartTask %InvFast_Task ' autostops ' ELSE ' StopTask %InvFast_Task ' ReadDelayLine% %InvFast_Task, 0, 0 ' force a reset ' END IF ' ''END IF ' WoodstockJazzPatternAlgo Recog.nr -1 ' CASE 5 ' ' samples: artikulaties ' IF ISFALSE Task(%Pattern1_Task).swit THEN ' StartTask %Pattern1_Task ' pattern 1 ' chk = %True ' ELSE ' StopTask %Pattern1_Task ' ''IF Recording_Available THEN ' '' IF ISFALSE Task(%AudioPlayReversed_Task).swit THEN ' '' StartTask %AudioPlayReversed_Task ' reverse playback audio ' '' chk = %True ' '' IF BIT(Task(%InvFast_Task).swit,%TASK_ONOFF) THEN ' '' StopTask %InvFast_Task ' '' ReadDelayLine% %InvFast_Task, 0, 0 ' force a reset ' '' END IF ' '' ELSE ' '' chk = %False ' '' END IF ' ''ELSE ' '' chk = %False ' ''END IF ' END IF ' ''IF ISFALSE chk THEN ' IF ISFALSE Task(%InvFast_Task).swit THEN ' StartTask %InvFast_Task ' ELSE ' StopTask %InvFast_Task ' ReadDelayLine% %InvFast_Task, 0, 0 ' force a reset ' END IF ' ''END IF ' WoodstockJazzPatternAlgo Recog.nr -1 ' CASE 6 ' ' samples: noiseclicks ' IF ISFALSE Task(%Pattern2_Task).swit THEN ' StartTask %Pattern2_Task ' ELSE ' StopTask %Pattern2_Task ' '' IF Recording_Available THEN ' '' IF ISFALSE Task(%AudioCrossTimeModulator_Task).swit THEN ' '' StartTask %AudioCrossTimeModulator_Task ' '' END IF ' '' END IF ' END IF ' WoodstockJazzPatternAlgo Recog.nr -1 ' CASE 7 ' ' samples: flatterzunge ' IF ISFALSE Task(%Pattern3_Task).swit THEN ' StartTask %Pattern3_Task ' pattern 3 ' ''IF Recording_Available THEN ' ' added 07.03.2000 ' '' IF ISFALSE Task(%LS_PitchShift_Task).swit THEN ' '' StartTask %LS_PitchShift_Task ' '' END IF ' ''END IF ' ELSE ' StopTask %Pattern3_Task ' ''IF Recording_Available THEN ' '' IF ISFALSE Task(%AudioCrossModulator_Task).swit THEN ' '' StartTask %AudioCrossModulator_Task ' '' END IF ' ''END IF ' END IF ' CASE 8 ' ' samples: Noise ' ''IF Recording_Available THEN ' '' IF ISFALSE Task(%LS_RingModulator_Task).swit THEN ' '' StartTask %LS_RingModulator_Task ' '' IF BIT(Task(%InvFast_Task).swit,%TASK_ONOFF) THEN ' '' StopTask %InvFast_Task ' '' ReadDelayLine% %InvFast_Task, 0, 0 ' force a reset ' '' END IF ' '' END IF ' ''ELSE ' IF ISFALSE Task(%InvFast_Task).swit THEN ' StartTask %InvFast_Task ' ELSE ' StopTask %InvFast_Task ' ReadDelayLine% %InvFast_Task, 0, 0 ' force a reset ' END IF ' ''END IF ' END SELECT END SUB SUB WoodstockJazzListen () EXPORT LOCAL nv% LOCAL noot? LOCAL velo? LOCAL Xlatv AS WORD STATIC oldnote% IF ISFALSE Task(%Listen_Task).tog THEN IF (Task(%Listen_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB oldnote% = %False Task(%Listen_Task).tog = %True END IF nv% = GetMidiNote% (Task(%Listen_Task).channel, %Remove OR %Oldest) IF nv% = %NotFalse THEN EXIT SUB ' no new note in buffer velo? = LOBYT (nv%) noot? = HIBYT (nv%) ' if note within range... SetDlgItemText gh.Cockpit, %GMT_AUTHOR, STR$(noot) + STR$(velo) IF (noot? >= Clarinet.lowtes) AND (noot? <= Clarinet.hightes) THEN ' if note-on.... IF velo? > %False THEN IF oldnote% THEN DelNote2Har Task(%Listen_Task).Har, oldnote% ' remove oldnote ... This implies monophonic instrument. WriteDelayLine oldnote%, 0 GetLastNote LOBYT(oldnote%), 0 , Clarinet ' sets/updates the global var LastNotePlayed END IF AddNote2Har Task(%Listen_Task).Har, (noot?), (velo?) WriteDelayLine noot?, velo? GetLastNote noot?, velo?, Clarinet Lastnotein = noot oldnote% = noot? ELSE ' if note off... WriteDelayLine noot?, 0 GetLastNote noot?, 0, Clarinet DelNote2Har Task(%Listen_Task).Har, (noot?) ' we delete the note after calling GetLastNote and its ' implied MatchPattern call, since we need the velo value of the ' note just switched of there! lastnotein = -noot oldnote% = %False END IF SetJazzContext noot?, velo? ' following should become part of a monitoring task... SetDlgItemText gh.Cockpit, %GMT_TEXT_TES, STR$(INT(WoodstockJazz.tes)) SetDlgItemText gh.Cockpit, %GMT_MSG1, "V=" & STR$(WoodstockJazz.vol) & " d=" & FORMAT$(WoodstockJazz.dens,"##.#") END IF END SUB 'SUB WoodstockJazzScore() EXPORT ' STATIC msduration AS DWORD ' ' scoring task. ' IF ISFALSE Task(%WoodstockJazz_Score_Task).tog THEN ' IF (Task(%WoodstockJazz_Score_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB ' Task(%WoodstockJazz_Score_Task).tog = %True ' msduration = App.komposduur * 1000 ' convert to milliseconds ' Task(%WoodstockJazz_Score_Task).freq = 1 ' END IF ' IF Getpromil% < 0 THEN EXIT SUB ' 'Normprop = (tnow - tstart)/ msduration ' WoodstockJazz.Angle = ((timeGetTime - App.tstart) * Pi2)/ msduration ' 0 to Pi2 (radians) ' IF WoodstockJazz.Angle > Pi2 THEN WoodstockJazz.Angle = WoodstockJazz.Angle - Pi2 ' circles ' ' here we should add all code for linear scoring (if any...) ' ' If Getpromil% < 10 'END SUB SUB ButnSW_WoodstockJazzStartStop () LOCAL ButtonNr AS LONG LOCAL i AS DWORD ButtonNr = App.butnSWparam - %GMT_BUTNSW_ID IF ButnSW(Buttonnr).flag THEN App.MTstart = %True App.tstart = timeGetTime ' start the chronometerfunction SetDlgItemText gh.Cockpit, %GMT_BUTNSW_ID + ButtonNr, "STOP" ClearMiBuf 0 ' start with a blank midi input buffer BlockSysExReception hMidiI(0) 'SxThread ' dll proc ' StartTask App.PromilTasknr Promil %True ' StartTask App.RunTimeTaskNr runtime %True StartTask %Listen_Task ' StartTask %WoodstockJazz_Score_Task StartTask App.GlobalHarmonyTaskNr StartTask %ws_wind ' DrawAllPatterns gh.MelPat ' does not work here!, only on a second push on the button... win7: actually does work and draws the patterns on the desktop if the window doesn't exist.. ELSE App.MTstart = %False SetDlgItemText gh.Cockpit, %GMT_BUTNSW_ID + ButtonNr, "CONT" END IF App.butnSWparam = %False END SUB SUB SetJazzContext (noot?, velo?) EXPORT STATIC tog AS BYTE STATIC Cnt() AS BYTE STATIC oldwijzer AS DWORD LOCAL wijzer AS DWORD LOCAL nrevents AS LONG logfile FUNCNAME$ + STR$(noot?) + STR$(velo?) IF ISFALSE tog THEN WoodstockJazz.vol = 24 ' midi level WoodstockJazz.tes = 440 ' in Hz WoodstockJazz.dens = 0.5 ' in events/sec (Hz) tog = %True DIM Cnt(0 TO 255) ' 1 byte for every cs. - so we integrate over 2,56 seconds END IF ' bereken de gemiddelde geluidsterkte van de input (integration) IF velo? THEN WoodstockJazz.Vol = WoodstockJazz.Vol + WoodstockJazz.Vol + WoodstockJazz.Vol + velo? SHIFT RIGHT WoodstockJazz.Vol, 2 END IF ' ' bereken de gemiddelde tessituurligging van de input IF noot? THEN WoodstockJazz.tes = ((WoodstockJazz.tes * 3) + N2F(noot?)) / 4 logfile "new tes"+ STR$(WoodstockJazz.tes) END IF ' calculate the density of the input over a timeframe of 255cs. ' The result is returned in WoodstockJazz.dens wijzer = (timeGetTime / 10) 'MOD 256 wijzer = wijzer AND 255 IF wijzer <> oldwijzer THEN DO INCR oldwijzer oldwijzer = oldwijzer AND 255 Cnt(oldwijzer) = %False LOOP UNTIL oldwijzer = wijzer END IF Cnt(wijzer) = %True ' now count the number of events in the buffer: FOR wijzer = 0 TO 255 IF Cnt(wijzer) THEN INCR nrevents NEXT wijzer WoodstockJazz.dens = nrevents / 2.56! ' express result in events/second ' max.value = 100 ' note that these values should be halved for approximate tempo ' derivation, since here we count both note-ons and note-offs. END SUB SUB DensTes STATIC LastNote AS LONG STATIC tlastnote AS LONG STATIC sw AS LONG INCR sw CONTROL SET TEXT gh.cockpit, %GMT_TITLE, STR$(f2n(WoodstockJazz.tes)) IF BIT(sw, 0) THEN IF INT(f2n(WoodstockJazz.tes))<> LastNote THEN mPlay Harmo.channel, LastNote, 0 LastNote = INT(f2n(WoodstockJazz.tes)) mPlay Harmo.channel, LastNote, 20 CONTROL SET TEXT gh.cockpit, %GMT_AUTHOR, STR$(LastNote) '' tlastnote = timegettime END IF ELSE mPlay Harmo.channel, LAstNote, 0 END IF Task(%ws_dens).freq = MAX(1, WoodsTockJazz.dens ) END SUB SUB DDensTes STATIC ltes AS SINGLE STATIC LastNote AS LONG STATIC tlastnote AS LONG STATIC sw AS LONG INCR sw IF ISFALSE ltes THEN ltes = 60 ltes = (4 * ltes + f2n(WoodstockJazz.tes)) / 5 IF BIT(sw, 0) THEN IF INT(ltes)<> LastNote THEN mPlay Harmo.channel, LastNote, 0 LastNote = INT(ltes) mPlay Harmo.channel, LastNote, 20 ' tlastnote = timegettime END IF ELSE mPlay Harmo.channel, LastNote, 0 END IF Task(%ws_dens).freq = MAX(1, WoodsTockJazz.dens * 1.3 ) END SUB SUB WS_loop STATIC note$ STATIC p AS LONG STATIC sw AS LONG STATIC lastnote AS BYTE IF lastnotein > 0 THEN IF lastnotein <> ASC(note$) THEN note$ = CHR$(lastnotein) + note$ note$ = LEFT$(note$, 8) warning "pattern: "+ note$ + "'" END IF ' ELSEIF ASC(note$) > 0 THEN ' note$ = CHR$(0) + note$ END IF INCR sw IF BIT(Sw, 0) THEN IF ASC(note$, p) THEN lastnote = ASC(note$, p) mPlay Harmo.channel, LAstNote, 20 END IF ELSE IF lastnote THEN mPlay Harmo.channel, LastNote, 0 END IF INCR p IF p > LEN(note$) THEN p = 1 Task(%ws_loop).freq = (3 * Task(%ws_loop).freq + WoodstockJazz.dens/3)/4 END SUB SUB WS_RandLoop STATIC note$ STATIC p AS LONG STATIC sw AS LONG STATIC lastnote AS BYTE IF lastnotein > 0 THEN IF lastnotein <> ASC(note$) THEN note$ = CHR$(lastnotein) + note$ note$ = LEFT$(note$, 8) END IF ' ELSEIF ASC(note$) > 0 THEN ' note$ = CHR$(0) + note$ END IF INCR sw IF BIT(Sw, 0) THEN p = 1 + INT(RND * LEN(note$)) IF ASC(note$, p) THEN lastnote = ASC(note$, p) mPlay Harmo.channel, LAstNote, 20 END IF ELSE IF lastnote THEN mPlay Harmo.channel, LastNote, 0 END IF ' INCR p ' IF p > LEN(note$) THEN p = 1 Task(%ws_loop).freq = (3 * Task(%ws_loop).freq + WoodstockJazz.dens/3)/4 END SUB SUB Woodstockjazz_Stock1 () EXPORT STATIC Ritmeteller% STATIC HarV1 AS HarmType STATIC starttempo AS SINGLE LOCAL tiks! IF ISFALSE Task(%WoodstockJazz_V1_Task).tog THEN Task(%WoodstockJazz_V1_Task).tog = %True HarV1.vel = STRING$(128,0) starttempo = Task(%WoodstockJazz_V1_Task).tempo ' should become dependent on input tempo! END IF ' This procedure is polyphonic. IF Task(%WoodstockJazz_V1_Task).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 ' get new parameters: Task(%WoodstockJazz_V1_Task).tempo = WoodstockJazz.dens / 8 IF Task(%WoodstockJazz_V1_Task).tempo < 5 THEN Task(%WoodstockJazz_V1_Task).tempo = 5 ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, %WoodstockJazz_V1_Task, 3 END IF tiks! = RitmSigma!(Task(%WoodstockJazz_V1_Task).Rit) IF tiks! <= 0 THEN EXIT SUB ' het tempo voor een gehele maat is frq = task(tasknr%).tempo / 60 ' zo'n gehele maat beslaat een aantal eenheden gegeven in tiks! Task(%WoodstockJazz_V1_Task).freq = (tiks! * Task(%WoodstockJazz_V1_Task).tempo ) / (60 * ABS(Task(%WoodstockJazz_V1_Task).Rit.pattern(Ritmeteller%))) IF Task(%WoodstockJazz_V1_Task).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(%WoodstockJazz_V1_Task).Har.vel = STRING$(128,0) ELSE ' now we have to find a new chord to mPlay for our task... IF Task(App.GlobalHarmonyTasknr).Har.vel <> STRING$(128, 0) THEN SELECT CASE Ritmeteller% MOD 3 CASE %False Task(%WoodstockJazz_V1_Task).Har.vel = SolveHar$ (Task(App.GlobalHarmonyTasknr).Har, BYCOPY LastNotePlayed, 0.05) CASE %True Task(%WoodstockJazz_V1_Task).Har.vel = InBetweenHar$(HarV1, Task(App.GlobalHarmonyTaskNr).Har) CASE 2 Task(%WoodstockJazz_V1_Task).Har.vel = DiminuteHar$(HarV1,LastNotePlayed MOD 12,11,1) ' aug END SELECT ELSE Task(%WoodstockJazz_V1_Task).Har.vel = STRING$(128,0) END IF END IF INCR Ritmeteller% IF Task(%WoodstockJazz_V1_Task).Har.vel <> HarV1.vel THEN IF Task(%WoodstockJazz_V1_Task).Har.vel <> Task(App.GlobalHarmonyTasknr).Har.vel THEN PlayHar Task(%WoodstockJazz_V1_Task).Har, Harmo.channel ' playhar keeps track of oldnotes internally... IF Task(%WoodstockJazz_V1_Task).Har.vel <> STRING$(128,0) THEN HarV1.vel = Task(%WoodstockJazz_V1_Task).Har.vel ' remember previous output. END IF END IF END IF END SUB SUB Woodstockjazz_Stock2 () EXPORT STATIC Ritmeteller% STATIC HarV2 AS HarmType STATIC starttempo AS SINGLE LOCAL tiks! IF ISFALSE Task(%WoodstockJazz_V2_Task).tog THEN IF (Task(%WoodstockJazz_V2_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB Task(%WoodstockJazz_V2_Task).tog = %True HarV2.vel = STRING$(128,0) starttempo = Task(%WoodstockJazz_V2_Task).tempo ' should be dependent on input tempo! END IF ' modelled after VoicePrototype in GMT.BAS / Cohiba.bas ' This procedure is polyphonic. IF Task(%WoodstockJazz_V2_Task).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 ' get new parameters: Task(%WoodstockJazz_V2_Task).tempo = WoodstockJazz.dens / 8 IF Task(%WoodstockJazz_V2_Task).tempo < 4 THEN Task(%WoodstockJazz_V2_Task).tempo = 4 ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, %WoodstockJazz_V2_Task, 2 END IF tiks! = RitmSigma!(Task(%WoodstockJazz_V2_Task).Rit) IF tiks! <= 0 THEN EXIT SUB ' het tempo voor een gehele maat is frq = task(tasknr%).tempo / 60 ' zo'n gehele maat beslaat een aantal eenheden gegeven in tiks! Task(%WoodstockJazz_V2_Task).freq = (tiks! * Task(%WoodstockJazz_V2_Task).tempo ) / (60 * ABS(Task(%WoodstockJazz_V2_Task).Rit.pattern(Ritmeteller%))) IF Task(%WoodstockJazz_V2_Task).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(%WoodstockJazz_V2_Task).Har.vel = STRING$(128,0) ELSE ' now we have to find a new chord to mPlay for our task... IF Task(App.GlobalHarmonyTasknr).Har.vel <> STRING$(128, 0) THEN SELECT CASE Ritmeteller% MOD 4 CASE %False Task(%WoodstockJazz_V2_Task).Har.vel = SolveHar$ (Task(App.GlobalHarmonyTasknr).Har, BYCOPY LastNotePlayed, 0.05) CASE %True Task(%WoodstockJazz_V2_Task).Har.vel = InBetweenHar$(HarV2, Task(App.GlobalHarmonyTaskNr).Har) CASE 2 Task(%WoodstockJazz_V2_Task).Har.vel = DiminuteHar$(HarV2,LastNotePlayed MOD 12,11,1) ' aug CASE 3 Task(%WoodstockJazz_V2_Task).Har.vel = SymDimHar$(HarV2,LastNotePlayed MOD 12,-1) ' dim END SELECT ELSE Task(%WoodstockJazz_V2_Task).Har.vel = STRING$(128,0) END IF END IF INCR Ritmeteller% IF Task(%WoodstockJazz_V2_Task).Har.vel <> HarV2.vel THEN IF Task(%WoodstockJazz_V2_Task).Har.vel <> Task(App.GlobalHarmonyTasknr).Har.vel THEN PlayHar Task(%WoodstockJazz_V2_Task).Har, Harmo.channel ' playhar keeps track of oldnotes internally... IF Task(%WoodstockJazz_V2_Task).Har.vel <> STRING$(128,0) THEN HarV2.vel = Task(%WoodstockJazz_V2_Task).Har.vel ' remember previous output. END IF END IF END IF END SUB SUB WoodstockJazzPattern1 () EXPORT STATIC i% STATIC toets% STATIC Initpattern AS BYTE STATIC Melody() AS INTEGER STATIC stoptijd AS DWORD LOCAL j% IF ISFALSE Task(%Pattern1_Task).tog THEN i% = %False toets% = %True IF ISFALSE Initpattern THEN DIM Melody (0 TO 12) ' 13 notes (14 in lickstick) FOR i = 0 TO UBOUND(Melody) Melody(i) = 52 '60 NEXT i Initpattern = %True END IF Task(%Pattern1_Task).tog = %True stoptijd = timeGetTime + 20000 ' 20 sec. max. END IF IF toets% THEN mPlay Harmo.channel, Melody(i%),WoodstockJazz.vol OR 1 ' midi level depends on input level toets% = %False AddNote2Har Task(%Pattern1_Task).Har,Melody(i%), 20 'WoodstockJazz.vol OR 1 ELSE NoteOff Harmo.channel, Melody(i%) toets% = %True Task(%Pattern1_Task).Har.vel = STRING$(128, 0) INCR i% IF i% > UBOUND(Melody) THEN i% = 0 j% = RND(1) * UBOUND(Melody) IF LastNotePlayed <> Melody(j%) THEN Melody(j%)= LastNotePlayed END IF IF timeGetTime > stoptijd THEN Task(%Pattern1_Task).tog = %False StopTask %Pattern1_Task END IF END IF ' tempo also depends on input density!: Task(%Pattern1_Task).freq = MAX(1, MIN(10,WoodstockJazz.dens)) ' in events/sec (Hz) END SUB SUB WoodstockJazzPattern2 () EXPORT STATIC i%, toets% STATIC Melody() AS INTEGER STATIC Initpattern AS BYTE STATIC stoptijd AS DWORD LOCAL j% IF ISFALSE Task(%Pattern2_Task).tog THEN i% = 0 toets% = %NotFalse IF ISFALSE Initpattern THEN DIM Melody (0 TO 6) '7, 11 notes in lickstick FOR i = 0 TO UBOUND(Melody) Melody(i) = 65 '61 NEXT i InitPattern = %True END IF Task(%Pattern2_Task).tog = %True stoptijd = timeGettime + 16000 END IF IF toets% THEN mPlay Harmo.channel, Melody(i%), WoodstockJazz.vol OR 1 toets% = %False AddNote2Har Task(%Pattern2_Task).Har,Melody(i%), 20 'WoodstockJazz.Vol OR 1 ELSE mPlay Harmo.channel, Melody(i%), %False toets% = %NotFalse Task(%Pattern2_Task).Har.vel = STRING$(128, 0) INCR i% IF i% > UBOUND(Melody) THEN i% = 0 j% = RND(1) * UBOUND(Melody) IF LastNotePlayed <> Melody(j%) THEN Melody(j%)= LastNotePlayed ELSE Melody(j%) = LastNotePlayed - 12 IF Melody(j%) < 24 THEN Melody(j%) = 24 ' your never know... END IF END IF IF timeGetTime > stoptijd THEN Task(%Pattern2_Task).tog = %False StopTask %Pattern2_Task END IF END IF ' tempo also depends on input density!: Task(%Pattern2_Task).freq =MAX(1, MIN(10, (WoodstockJazz.dens * 3 / 2))) ' in events/sec (Hz) END SUB SUB WoodstockJazzPattern3 () EXPORT STATIC i%, toets% STATIC Melody() AS INTEGER STATIC Initpattern AS BYTE STATIC stoptijd AS DWORD LOCAL j% IF ISFALSE Task(%Pattern3_Task).tog THEN i% = 0 toets% = %NotFalse IF ISFALSE Initpattern THEN DIM Melody (0 TO 10) ' 11, in lickstick 7 notes FOR i = 0 TO UBOUND(Melody) Melody(i) = 78 '62 NEXT i Initpattern = %True END IF Task(%Pattern3_Task).tog = %True stoptijd = timeGetTime + 18000 ' 18 sec. END IF IF toets% THEN mPlay Harmo.channel, Melody(i%), WoodstockJazz.vol OR 1 toets% = %False AddNote2Har Task(%Pattern3_Task).Har,Melody(i%), 20 ' WoodstockJazz.vol OR 1 ELSE mPlay Harmo.channel, Melody(i%), %False toets% = %NotFalse Task(%Pattern3_Task).Har.vel = STRING$(128, 0) INCR i% IF i% > UBOUND(Melody) THEN i% = 0 j% = RND(1) * UBOUND(Melody) IF LastNotePlayed <> Melody(j%) THEN Melody(j%)= LastNotePlayed END IF IF timeGetTime > stoptijd THEN Task(%Pattern3_Task).tog = %False StopTask %Pattern3_Task END IF END IF ' tempo also depends on input density!: Task(%Pattern3_Task).freq = MAX(1, MIN(10, (WoodstockJazz.dens * 2 / 3))) ' in events/sec (Hz) END SUB SUB WoodstockJazzPatternAlgo (pattern AS BYTE) ' in this piece we recalculate patterns dynamically ' every time a pattern is recognized, it is extended with a single note value. ' pattern = Recog.nr + 1 ' recog.nr starts at 1 , whilst LBOUND(PatternSeq) = 0 LOCAL i AS LONG LOCAL noot AS INTEGER STATIC patduur4 AS SINGLE STATIC tog AS BYTE IF ISFALSE tog THEN patduur4 = PatternSeq(4).duur(0) + PatternSeq(4).duur(1) tog = %True END IF SELECT CASE pattern CASE 0 FOR i = 0 TO PatternSeq(pattern).lengte IF i > 0 THEN PatternSeq(pattern).noot(i)= PatternSeq(pattern).noot(i-1) + i PatternSeq(pattern).velo(i)= PatternSeq(pattern).velo(i-1) PatternSeq(pattern).duur(i)= PatternSeq(pattern).duur(i-1) END IF NEXT i IF PatternSeq(pattern).noot(PatternSeq(pattern).lengte) > Clarinet.Hightes THEN EXIT SUB ' end reached. IF PatternSeq(pattern).lengte < 14 THEN INCR PatternSeq(pattern).lengte END IF CASE 1 FOR i = 0 TO PatternSeq(pattern).lengte IF i > 0 THEN PatternSeq(pattern).noot(i)= PatternSeq(pattern).noot(i-1) - i PatternSeq(pattern).velo(i)= PatternSeq(pattern).velo(i-1) PatternSeq(pattern).duur(i)= PatternSeq(pattern).duur(i-1) END IF NEXT i IF PatternSeq(pattern).noot(PatternSeq(pattern).lengte) < Clarinet.LowTes THEN EXIT SUB ' end reached IF PatternSeq(pattern).lengte < 14 THEN INCR PatternSeq(pattern).lengte END IF CASE 2 FOR i = 0 TO PatternSeq(pattern).lengte IF i > 0 THEN IF BIT(i,0) THEN PatternSeq(pattern).noot(i)= PatternSeq(pattern).noot(i-1) - i ELSE PatternSeq(pattern).noot(i)= PatternSeq(pattern).noot(i-1) + i END IF PatternSeq(pattern).velo(i)= PatternSeq(pattern).velo(i-1) PatternSeq(pattern).duur(i)= PatternSeq(pattern).duur(i-1) END IF NEXT i IF PatternSeq(pattern).noot(PatternSeq(pattern).lengte) < Clarinet.LowTes THEN EXIT SUB ' end reached IF PatternSeq(pattern).noot(PatternSeq(pattern).lengte) > Clarinet.HighTes THEN EXIT SUB IF PatternSeq(pattern).lengte < 14 THEN INCR PatternSeq(pattern).lengte END IF CASE 3 FOR i = 0 TO PatternSeq(pattern).lengte IF i > 0 THEN IF BIT(i,0) THEN PatternSeq(pattern).noot(i)= PatternSeq(pattern).noot(i-1) + i ELSE PatternSeq(pattern).noot(i)= PatternSeq(pattern).noot(i-1) - i END IF PatternSeq(pattern).velo(i)= PatternSeq(pattern).velo(i-1) PatternSeq(pattern).duur(i)= PatternSeq(pattern).duur(i-1) END IF NEXT i IF PatternSeq(pattern).noot(PatternSeq(pattern).lengte) < Clarinet.LowTes THEN EXIT SUB ' end reached IF PatternSeq(pattern).noot(PatternSeq(pattern).lengte) > Clarinet.HighTes THEN EXIT SUB IF PatternSeq(pattern).lengte < 14 THEN INCR PatternSeq(pattern).lengte END IF CASE 4 ' mi - sol at start ' we add 1 whole tone up on each recognition - and shorten the durations ' first calculate the total duration now: ' patduur = 0 ' FOR i = 0 TO PatternSeq(4).lengte -1 ' patduur = patduur + PatternSeq(4).duur(i) ' bereken huidige totale tijdsduur ' NEXT i ' patduur = 2 'PatternSeq(4).duur(0) * PatternSeq(4).lengte -1 FOR i = 0 TO PatternSeq(4).lengte ' 27.02.2000 PatternSeq(4).duur(i) = patduur4 / PatternSeq(4).lengte NEXT i noot = GetDifferentPatternNote(PatternSeq(),4) IF noot >= Clarinet.LowTes THEN PatternSeq(4).noot(PatternSeq(4).lengte) = noot PatternSeq(4).velo(PatternSeq(4).lengte)= PatternSeq(4).velo(PatternSeq(4).lengte -1) ELSE PatternSeq(4).noot(PatternSeq(4).lengte)= PatternSeq(4).noot(PatternSeq(4).lengte -1) + 2 PatternSeq(4).velo(PatternSeq(4).lengte)= PatternSeq(4).velo(PatternSeq(4).lengte -1) END IF IF PatternSeq(4).noot(PatternSeq(4).lengte) < Clarinet.LowTes THEN EXIT SUB ' end reached IF PatternSeq(4).noot(PatternSeq(4).lengte) > Clarinet.HighTes THEN EXIT SUB IF PatternSeq(4).lengte < 14 THEN INCR PatternSeq(4).lengte ' so the last element is zero. END IF CASE 5 ' la at start - changes dynamically noot = GetDifferentPatternNote(PatternSeq(),5) IF noot >= Clarinet.LowTes THEN PatternSeq(5).noot(0) = noot END IF ' CASE 6 ' no change ' CASE 7 ' no change END SELECT DrawAllPatterns gh.MelPat END SUB FUNCTION Woodstockjazz_GetDifferentPatternNote (PatternSeq() AS PatternSequenceType, pattern AS BYTE) AS INTEGER ' we pass the pointer to the type such that -at a later moment- we may place ' this procedure in our dll. ' the pattern number passed is the destination pattern for the note, such that the proc. takes ' melodiousness into consideration. LOCAL H AS Harmtype LOCAL H2 AS HarmType LOCAL PatCnt AS LONG LOCAL i AS LONG H.vel = STRING$(128,0) H2.vel = STRING$(128,0) ' this function returns a note missing in the patterns as they are on the moment of the call. FOR patCnt = 0 TO UBOUND(PatternSeq) FOR i = 0 TO PatternSeq(patCnt).lengte IF PatternSeq(patCnt).velo(i) > 0 THEN AddNote2Har H, PatternSeq(patCnt).noot(i), PatternSeq(patCnt).velo(i) END IF NEXT i NEXT patCnt H2.vel = ComplementHar$ (H,Clarinet.lowtes, Clarinet.hightes) ' returns the notes not present in ' the Har$ passed. FUNCTION = StealNoteFromHar(H2, PatternSeq(pattern).noot(PatternSeq(pattern).lengte-1), Clarinet.lowtes, Clarinet.hightes) END FUNCTION 'SUB WoodstockJazzPlaySample () ' ' this task plays the prerecorded wave files on disk. ' ' This task has very specific WoodstockJazz code, since we use a large set of changing sample-files. ' STATIC Jumpval AS BYTE ' STATIC CatIdx1 AS BYTE ' STATIC CatIdx2 AS BYTE ' STATIC CatIdx3 AS BYTE ' STATIC CatIdx4 AS BYTE ' STATIC CatIdx5 AS BYTE ' STATIC CatIdx6 AS BYTE ' STATIC CatIdx7 AS BYTE ' STATIC CatIdx8 AS BYTE ' LOCAL Filnam AS ASCIIZ * 40 ' LOCAL retval AS LONG ' STATIC tracknr AS LONG ' STATIC duur AS DWORD ' ' IF ISFALSE Task(%AudioPlaySample_Task).tog THEN ' IF (Task(%AudioPlaySample_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB ' IF ISFALSE Audio.hWo THEN ' Stoptask %AudioPlaySample_Task ' EXIT SUB ' END IF ' Task(%AudioPlaySample_Task).tog = %True ' Jumpval = %False ' ' calculate the filename for the sample to be played...: ' SELECT CASE Recog.nr ' CASE 1 ' ' detunes ' Filnam = "WS0" & TRIM$(STR$(CatIdx1)) & ".WAV" ' 'INCR CatIdx1 ' 'IF CatIdx1 > 2 THEN CatIdx1 = 0 ' CASE 2 ' Filnam = "WS1" & TRIM$(STR$(CatIdx2)) & ".WAV" ' 'INCR CatIdx2 ' 'IF CatIdx2 > 10 THEN CatIdx2 = 0 ' CASE 3 ' Filnam = "WS2" & TRIM$(STR$(CatIdx3)) & ".WAV" ' 'INCR CatIdx3 ' 'IF CatIdx3 > 7 THEN CatIdx3 = 0 ' CASE 4 ' Filnam = "WS3" & TRIM$(STR$(CatIdx4)) & ".WAV" ' 'INCR CatIdx4 ' 'IF CatIdx4 > 17 THEN CatIdx4 = 0 ' CASE 5 ' Filnam = "WS4" & TRIM$(STR$(CatIdx5)) & ".WAV" ' 'INCR CatIdx5 ' 'IF CatIdx5 > 4 THEN CatIdx5 = 0 ' CASE 6 ' Filnam = "WS5" & TRIM$(STR$(CatIdx6)) & ".WAV" ' 'INCR CatIdx6 ' 'IF CatIdx6 > 3 THEN CatIdx6 = 0 ' CASE 7 ' Filnam = "WS6" & TRIM$(STR$(CatIdx7)) & ".WAV" ' 'INCR CatIdx7 ' 'IF CatIdx7 > 4 THEN CatIdx7 = 0 ' CASE 8 ' Filnam = "WS7" & TRIM$(STR$(CatIdx8)) & ".WAV" ' 'INCR CatIdx8 ' 'IF CatIdx8 > 15 THEN CatIdx8 = 0 ' END SELECT ' Filnam = ".\WoodSt~1\" + TRIM$(LCASE$(Filnam)) + CHR$(0) ' ' here we check for the existence of these files... ' IF ISFALSE Existfile(UCASE$(Filnam)) THEN ' StopTask %AudioPlaySample_Task ' EXIT SUB ' END IF ' ' sofar we know that the file exists... ' ' so, lets try loading it into a free track: ' END IF ' ' SELECT CASE Jumpval ' CASE %False ' retval = PlayWaveFile (Filnam, %MODULATE_VOLUME OR %MODULATE_PANNING) ' SELECT CASE retval ' CASE > 15 ' ' means we played the file without using the waveouthandle. ' StopTask %AudioPlaySample_Task ' EXIT SUB ' CASE 0 TO 15 ' ' bereken de duur van het te spelen sample... ' tracknr = retval ' duur = TrackDuration(Tracknr) ' in milliseconds ' Jumpval = %True ' Task(%AudioPlaySample_Task).freq = 1000 / duur ' EXIT SUB ' CASE -2 ' ' no need to try again... ' StopTask %AudioPlaySample_Task ' EXIT SUB ' CASE -1 ' ' wait until device becomes available... ' Jumpval = %False ' Task(%AudioPlaySample_Task).freq = 5 ' EXIT SUB ' END SELECT ' CASE %True ' IF TrackStatus.playing(tracknr) THEN ' Task(%AudioPlaySample_Task).freq = 36 ' EXIT SUB ' END IF ' ' now we can stop the task and free its resources: ' Task(%AudioPlaySample_Task).tog = %False ' Task(%AudioPlaySample_Task).freq = 20 ' StopTask %AudioPlaySample_Task ' END SELECT 'END SUB SUB WoodstockJazzDelayInvertFast () ' This delay plays at always increasing speed. ' All intervals are inverted. ' The mirror note for the inversion depends on ' the momentaneous note played by the Clarinet. LOCAL nv% LOCAL noot? LOCAL velo? STATIC delaytime AS DWORD STATIC SPEED AS SINGLE STATIC tout AS DWORD IF ISFALSE Task(%InvFast_Task).tog THEN nv% = GetPromil% IF nv% <= %False THEN StopTask %InvFast_Task EXIT SUB END IF Task(%InvFast_Task).tog = %True delaytime = nv% * App.Komposduur SPEED = 1.3! * (1! + (SPEED/10!)) ' 1.5 = double speed - this goes accellerando! ' the value changes for each new call to the task. END IF IF timegettime < tout THEN EXIT SUB nv% = ReadDelayLine%(%InvFast_Task, delaytime, SPEED) SELECT CASE nv% CASE %False, %NotFalse EXIT SUB ' if no note came in, exit the task CASE -2 ' read past present. Task(%InvFast_Task).Har.vel = STRING$(128,0) PlayHar Task(%InvFast_Task).Har, Harmo.channel nv% = ReadDelayLine%(%InvFast_Task, 0, 0) ' force a reset Task(%InvFast_Task).tog = %False ' force calculation of a new delay time StopTask %InvFast_Task ' stop the task. EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) noot? = LastNotePlayed + LastNotePlayed - noot? IF noot? > 127 THEN EXIT SUB IF noot? <=0 THEN EXIT SUB Task(%InvFast_Task).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(%InvFast_Task).Har, (noot?),20 '(velo?) PlayHar Task(%InvFast_Task).Har , Harmo.channel tout = timegettime + 100 END SUB SUB WoodstockJazzDelayBackInvert () ' plays backwards with inverted intervals LOCAL nv% LOCAL noot? LOCAL velo? STATIC delaytime AS DWORD STATIC SPEED AS SINGLE STATIC tout AS DWORD IF ISFALSE Task(%BackInv_Task).tog THEN IF (Task(%BackInv_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB nv% = GetPromil% ' nv just used to save another variable... IF nv% <= %False THEN StopTask %BackInv_Task EXIT SUB END IF Task(%BackInv_Task).tog = %True delaytime = nv% * App.Komposduur SPEED = 1.3! * (1! + (ABS(SPEED)/10!)) ' 1.5 = double speed - this goes accellerando! ' the value changes for each new call to the task. SPEED = - SPEED END IF IF timegettime < tout THEN EXIT SUB 'avoid notes that are too fast to sound.. nv% = ReadDelayLine%(%BackInv_Task, delaytime, SPEED) ' speed is negative, so we mPlay backwards SELECT CASE nv% CASE %False, %NotFalse, -2 EXIT SUB ' if no note came in, exit the task CASE -3 ' read past delay in backwardsmode: force reset, stop task. Task(%BackInv_Task).Har.vel = STRING$(128,0) PlayHar Task(%BackInv_Task).Har, Harmo.channel ' notes off nv% = ReadDelayLine%(%BackInv_Task, 0, 0) ' force a reset Task(%BackInv_Task).tog = %False ' force calculation of a new delay time StopTask %BackInv_Task ' stop the task. EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) noot? = LastNotePlayed + LastNotePlayed - noot? ' we mirror/invert the intervals IF noot? > 127 THEN EXIT SUB IF noot? <=0 THEN EXIT SUB Task(%BackInv_Task).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(%BackInv_Task).Har, (noot?), 20 '(velo?) PlayHar Task(%BackInv_Task).Har , Harmo.channel tout = timegettime + 100 END SUB SUB WoodstockJazzDelayBackSlow () ' plays backwards at decreasing lower speed ' This task does not always stop before the end of the piece, if not stopped by an interactive event. LOCAL nv% LOCAL noot? LOCAL velo? STATIC delaytime AS DWORD ' in ms STATIC COUNT AS DWORD STATIC SPEED AS SINGLE STATIC tout AS DWORD IF ISFALSE Task(%BackSlow_Task).tog THEN IF (Task(%BackSlow_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB nv% = GetPromil% ' nv just used to save another variable... IF nv% <= %False THEN StopTask %BackSlow_Task EXIT SUB END IF Task(%BackSlow_Task).tog = %True delaytime = 500 'keep it constant to 500ms instead of doing delaytime = nv% * App.Komposduur INCR COUNT SPEED = -(1 -COUNT/Pi) 'slower & negative ' TO BE CHECKED!!!!!!!!!!!!!!!!! ' -0.68169 , -0.3633, -0.045 IF SPEED < -0.045 THEN SPEED = -0.045 ' the value changes for each new call to the task. END IF IF timegettime < tout THEN EXIT SUB nv% = ReadDelayLine%(%BackSlow_Task, delaytime, SPEED) ' speed is negative, so we mPlay backwards SELECT CASE nv% CASE %False, %NotFalse, -2 EXIT SUB ' if no note came in, exit the task CASE -3 ' read past delay in backwardsmode: force reset, stop task. cannot happen... Task(%BackSlow_Task).Har.vel = STRING$(128,0) PlayHar Task(%BackSlow_Task).Har, Harmo.channel ' notes off nv% = ReadDelayLine%(%BackSlow_Task, 0, 0) ' force a reset Task(%BackSlow_Task).tog = %False ' force calculation of a new delay time StopTask %BackSlow_Task ' stop the task. EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) - 12 ' octave down ' no inversion of intervals. IF noot? > 127 THEN EXIT SUB IF noot? <= 0 THEN EXIT SUB Task(%BackSlow_Task).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(%BackSlow_Task).Har, (noot?), 20 '(velo?) PlayHar Task(%BackSlow_Task).Har , Harmo.channel tout = timegettime + 100 END SUB SUB ws_imi STATIC noot AS LONG STATIC rf AS SINGLE IF lastnotein = noot THEN EXIT SUB noot = lastnotein rf =MAX(2, (3 * rf + WoodstockJazz.dens/4)/4) IF lastnotein > 0 THEN AddNote2Har Task(%ws_imi).har, noot, 20 Task(%ws_imi).freq = rf ELSE RESET Task(%ws_imi).har.vel Task(%ws_imi).freq = 20 END IF PlayHar Task(%ws_imi).har, Harmo.channel END SUB SUB WoodstockJazzDelayPlayerNormal () ' this taskprocedure demonstrates how to build a delay-line for ' midi input. This one outputs at normal speed. LOCAL nv% LOCAL noot? LOCAL velo? STATIC tout AS DWORD IF ISFALSE Task(%Gerade_Task).tog THEN IF (Task(%Gerade_Task).swit AND %TASK_BUSY) = %d1 THEN EXIT SUB Task(%Gerade_Task).tog = %True END IF IF timegettime < tout THEN EXIT SUB nv% = ReadDelayLine%(%Gerade_Task, 5000, 1!) ' 5 second delay ' > 1 speed-up ' < 1 slow down SELECT CASE nv% CASE %False EXIT SUB CASE %NotFalse EXIT SUB ' if no note came in, exit the task CASE -2 ' read past present. ' This can only happen if speed! > 1! nv% = ReadDelayLine%(%Gerade_Task, 0, 0) ' force a reset StopTask %Gerade_Task ' switch task off on error. EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) '- 24 IF noot? <= %False THEN velo? = %False : Noot? = %False ' lets implement full polyphonic playing: IF velo? = %False THEN DelNote2Har Task(%Gerade_Task).Har, (noot?) PlayHar Task(%Gerade_Task).Har, Harmo.channel ELSE DelNote2Har Task(%Gerade_Task).Har, (noot) PlayHar Task(%Gerade_Task).Har, Harmo.channel AddNote2Har Task(%Gerade_Task).Har, (noot?), (velo?) PlayHar Task(%Gerade_Task).Har , Harmo.channel END IF tout = timegettime + 100 END SUB SUB ws_wind STATIC wind AS SINGLE wind = MIN(100, MAX(20, (10 * wind + woodstockjazz.vol) / 11)) Harmo.ctrl(7) = INT(wind) Controller Harmo.channel, 7, Harmo.ctrl(7) END SUB SUB ws_trem STATIC trem AS SINGLE trem = (10 * trem + woodstockjazz.vol) / 11 Harmo.ctrl(82) = INT(trem) Controller Harmo.channel, 82, Harmo.ctrl(82) END SUB SUB ws_trem_off Harmo.ctrl(82) = 0 Controller Harmo.channel, 82, 0 END SUB SUB ws_valve 'slow task STATIC cc AS DWORD STATIC v AS SINGLE v = MAX (64, (12 * v + Woodstockjazz.vol) / 13) INCR cc IF ISFALSE cc MOD 10 THEN Harmo.ctrl(1) = v Controller Harmo.channel, 1, v END IF END SUB SUB Ws_Vox1 () EXPORT ' uses Harmo & Harmo STATIC Ritmeteller%, HarV1 AS HarmType , starttempo AS SINGLE LOCAL tiks! IF ISFALSE Task(%ws_Vox1).tog THEN Task(%ws_Vox1).tog = %True HarV1.vel = STRING$(128,0) starttempo = Task(%ws_Vox1).tempo END IF ' modelled after VoicePrototype in Cohiba / CelloPi ' This procedure is polyphonic. IF ISFALSE Task(%ws_Vox1).Rit.pattern(Ritmeteller%) THEN Ritmeteller% = %False ' get new parameters: Task(%ws_Vox1).tempo = starttempo * (1 + Tprop!(%ws_Vox1)) ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, %ws_Vox1, 2 END IF tiks! = RitmSigma!(Task(%ws_Vox1).Rit) IF tiks! <= 0 THEN EXIT SUB Task(%ws_Vox1).freq = (tiks! * Task(%ws_Vox1).tempo ) / (60 * ABS(Task(%ws_Vox1).Rit.pattern(Ritmeteller%))) IF Task(%ws_Vox1).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(%ws_Vox1).Har.vel = STRING$(128,0) ELSE ' now we have to find a new chord to mPlay for our task... IF Task(App.GlobalHarmonyTasknr).Har.vel <> STRING$(128, 0) THEN Task(%ws_Vox1).Har.vel = SolveHar$ (Task(App.GlobalHarmonyTasknr).Har, LastNotePlayed, 0.05) ELSE Task(%ws_Vox1).Har.vel = STRING$(128,0) END IF END IF INCR Ritmeteller% IF Task(%ws_Vox1).Har.vel <> HarV1.vel THEN IF Task(%ws_Vox1).Har.vel <> Task(App.GlobalHarmonyTasknr).Har.vel THEN PlayHar Task(%ws_vox1).har, Harmo.channel IF Task(%ws_Vox1).Har.vel <> STRING$(128,0) THEN HarV1.vel = Task(%ws_Vox1).Har.vel END IF END IF END IF END SUB SUB Ws_Vox2 () EXPORT ' mapped on STATIC Ritmeteller%, HarV2 AS HarmType , starttempo AS SINGLE LOCAL tiks! IF ISFALSE Task(%ws_Vox2).tog THEN Task(%ws_Vox2).tog = %True HarV2.vel = STRING$(128,0) starttempo = Task(%ws_Vox2).tempo END IF ' This procedure is polyphonic. IF Task(%ws_Vox2).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 ' get new parameters: Task(%ws_Vox2).tempo = starttempo * (1 + Tprop!(%ws_Vox2)) ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, %ws_Vox2, 3 HarV2.vel = Task(App.GlobalHarmonyTasknr).Har.vel END IF tiks! = RitmSigma!(Task(%ws_Vox2).Rit) IF tiks! < 1 THEN EXIT SUB ' het tempo voor een gehele maat is frq = task(tasknr%).tempo / 60 ' zo'n gehele maat beslaat een aantal eenheden gegeven in tiks! Task(%ws_Vox2).freq = (tiks! * Task(%ws_Vox2).tempo ) / (60 * ABS(Task(%ws_Vox2).Rit.pattern(Ritmeteller%))) IF Task(%ws_Vox2).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(%ws_Vox2).Har.vel = STRING$(128,0) ELSE ' now we have to find a new chord to mPlay for our task... Task(%ws_Vox2).Har.vel = SymDimHar$(HarV2,(LastNotePlayed),+1) ' augment END IF INCR Ritmeteller% IF Task(%ws_Vox2).Har.vel <> HarV2.vel THEN PlayHar Task(%ws_vox2).har, Harmo.channel IF Task(%ws_Vox2).Har.vel <> STRING$(128,0) THEN HarV2.vel = Task(%ws_Vox2).Har.vel END IF END IF END SUB SUB Ws_Vox3 () EXPORT ' plays on klung STATIC Ritmeteller%, HarV3 AS HarmType , starttempo AS SINGLE STATIC cnt?, V3level?, V3pan? LOCAL tiks! IF ISFALSE Task(%ws_Vox3).tog THEN Task(%ws_Vox3).tog = %True HarV3.vel = STRING$(128,0) starttempo = Task(%ws_Vox3).tempo END IF ' This procedure is polyphonic. IF Task(%ws_Vox3).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 INCR cnt? cnt? = cnt? AND 3 ' 0,1,2,3 Task(%ws_Vox3).tempo = starttempo * (1.5 + COS(Tang!(%ws_Vox3))) IF ISFALSE cnt? MOD 2 THEN ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, %ws_Vox3, 3 ' must be byref!!! ELSE ShepChord2Rit Task(App.GlobalHarmonyTaskNr).Har, %ws_Vox3, 3, 57 END IF HarV3.vel = Task(App.GlobalHarmonyTasknr).Har.vel END IF tiks! = RitmSigma!(Task(%ws_Vox3).Rit) IF tiks! < 1 THEN EXIT SUB ' het tempo voor een gehele maat is frq = task(tasknr%).tempo / 60 ' zo'n gehele maat beslaat een aantal eenheden gegeven in tiks! Task(%ws_Vox3).freq = (tiks! * Task(%ws_Vox3).tempo ) / (60 * ABS(Task(%ws_Vox3).Rit.pattern(Ritmeteller%))) IF Task(%ws_Vox3).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(%ws_Vox3).Har.vel = STRING$(128,0) ELSE ' now we have to find a new chord to mPlay for our task... Task(%ws_Vox3).Har.vel = SymDimHar$(HarV3,(LastNotePlayed),-1) ' dim END IF INCR Ritmeteller% IF Task(%ws_Vox3).Har.vel <> HarV3.vel THEN PlayHar Task(%ws_vox1).har, Harmo.channel IF Task(%ws_Vox3).Har.vel <> STRING$(128,0) THEN HarV3.vel = Task(%ws_Vox3).Har.vel END IF END IF END SUB SUB Ws_Vox4 () EXPORT ' STATIC Ritmeteller% STATIC HarV4 AS harmtype STATIC Starttempo AS SINGLE STATIC V4level AS BYTE STATIC V4pan AS BYTE LOCAL tiks! IF ISFALSE Task(%ws_Vox4).tog THEN Task(%ws_Vox4).tog = %True HarV4.vel = STRING$(128,0) StartTempo = Task(%ws_Vox4).tempo END IF IF Task(%ws_Vox4).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 Task(%ws_Vox4).tempo = starttempo * (1.5 + COS(Tang!(%ws_Vox4))) ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, %ws_Vox4, 2 ' must be byref!!! HarV4.vel = Task(App.GlobalHarmonyTasknr).Har.vel V4level = Task(%ws_Vox4).level V4pan = Task(%ws_Vox4).pan END IF tiks! = RitmSigma!(Task(%ws_Vox4).Rit) IF tiks! < 1 THEN EXIT SUB ' het tempo voor een gehele maat is frq = task(tasknr%).tempo / 60 ' zo'n gehele maat beslaat een aantal eenheden gegeven in tiks! Task(%ws_Vox4).freq = (tiks! * Task(%ws_Vox4).tempo ) / (60 * ABS(Task(%ws_Vox4).Rit.pattern(Ritmeteller%))) IF Task(%ws_Vox4).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(%ws_Vox4).Har.vel = STRING$(128,0) ELSE ' now we have to find a new chord to mPlay for our task... Task(%ws_Vox3).Har.vel = DiminuteHar$(HarV4,LastNotePlayed MOD 12,11,1) ' aug END IF INCR Ritmeteller% V4pan = (V4pan + 7) MOD 128 IF Task(%ws_Vox4).Har.vel <> HarV4.vel THEN Harmo.Har(1).vel = Task(%ws_Vox4).Har.vel Instrumplay Harmo IF Task(%ws_Vox4).Har.vel <> STRING$(128,0) THEN HarV4.vel = Task(%ws_Vox4).Har.vel END IF END IF END SUB SUB HarmO_controlroom () ' to be adapted to wide range of harmO LOCAL i AS LONG LOCAL x AS LONG LOCAL b$ IF ISFALSE hwCtrlharmO THEN DIALOG NEW 0, "harmO Control",1,150 ,450, 104, %WS_CAPTION OR %WS_POPUP OR %WS_SYSMENU TO hwCtrlharmO x = 5 FOR i = harmO.lowtes TO harmO.LowTes + (harmO.HighTes - harmO.LowTes)/2 '((harmO.LowTes + harmO.HighTes)/2) - 1 SELECT CASE (i MOD 12) CASE 0 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "C", x, 55, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 1 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "C#", x, 43, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 2 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "D", x, 55, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 3 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "D#", x, 43, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 4 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "E", x, 55, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 5 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "F", x, 55, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 6 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "F#", x, 43, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 7 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "G", x, 55, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 8 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "G#", x, 43, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 9 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "A", x, 55, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 10 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "Bb", x, 43, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 11 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "B", x, 55, 18, 12, %BS_PUSHLIKE x = x + 20 END SELECT NEXT x = 5 FOR i = harmO.LowTes + (harmO.HighTes - harmO.LowTes)/2 TO harmO.Hightes SELECT CASE (i MOD 12) CASE 0 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "C", x, 24, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 1 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "C#", x, 12, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 2 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "D", x, 24, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 3 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "D#", x, 12, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 4 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "E", x, 24, 18, 12, %BS_PUSHLIKE x = x + 20 CASE 5 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "F", x, 24, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 6 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "F#", x, 12, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 7 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "G", x, 24, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 8 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "G#", x, 12, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 9 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "A", x, 24, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 10 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "Bb", x, 12, 18, 12, %BS_PUSHLIKE x = x + 10 CASE 11 CONTROL ADD CHECKBOX, hwCtrlharmO, i, "B", x, 24, 18, 12, %BS_PUSHLIKE x = x + 20 END SELECT NEXT ' CONTROL ADD LABEL, hwCtrlharmO, 500, "WindPress:", 5, 76, 30, 12 'separate task ' CONTROL ADD "msctls_trackbar32", hwCtrlharmO, 501, _ ' "WindPress", 36, 76, 135, 12, %WS_CHILD OR %WS_VISIBLE OR _ ' %TBS_HORZ OR %TBS_BOTTOM ' CONTROL ADD LABEL, hwCtrlharmO, 503, "?", 174, 76, 30, 12 ' hharmOWindTrackBar = GetDlgItem(hwCtrlharmO,501) CONTROL ADD BUTTON, hwCtrlharmO, 600, "All Off", 247, 76, 30, 12 DIALOG SHOW MODELESS hwCtrlharmO CALL CB_harmO_Controlroom ELSE DIALOG END hwCtrlharmO hwCtrlharmO = 0 END IF END SUB CALLBACK FUNCTION CB_harmO_Controlroom () LOCAL wind AS BYTE LOCAL valve AS SINGLE LOCAL i AS LONG, j AS LONG LOCAL note AS BYTE SELECT CASE CBMSG CASE %WM_COMMAND SELECT CASE CBCTL CASE harmO.Lowtes TO harmO.hightes 'note checkboxes CONTROL GET CHECK CBHNDL, CBCTL TO i note = CBCTL mPlay harmO.channel, note, BYVAL i CASE 600 'all off ' Controller harmO.channel, 123, %False FOR i = harmO.lowtes TO harmO.hightes 'mPlay harmO.channel, i, 0 CONTROL GET CHECK CBHNDL, CBCTL TO j IF j THEN mPlay Harmo.channel, note, 0 CONTROL SET CHECK CBHNDL, i, 0 SLEEP 10 DIALOG DOEVENTS NEXT harmO.ctrl(7) = %False Controller harmO.channel, 7, harmO.ctrl(7) CONTROL SET TEXT CBHNDL, 503, "0"' END SELECT ' CASE %WM_HSCROLL, %WM_VSCROLL 'note: id doesn't correspond at all with the one given at creation ' SELECT CASE CBLPARAM ' CASE hharmOWindTrackBar 'wind pressure ' IF (LOWRD(CBWPARAM) = %TB_THUMBPOSITION) OR (LOWRD(CBWPARAM) = %TB_THUMBTRACK) THEN ' wind = HIWRD(CBWPARAM) ' ELSE ' wind = SendMessage (CBLPARAM, %TBM_GETPOS,%Null, %Null) ' END IF ' wind = wind * 1.27 ' CONTROL SET TEXT CBHNDL, 503, STR$(wind) ' harmO.ctrl(7) = wind ' Controller harmO.channel, 7, harmO.ctrl(7) ' END SELECT CASE %WM_CLOSE, %WM_QUIT hwCtrlharmO = 0 ' Controller harmO.channel, 123, %False ' harmO.ctrl(7) = %False ' Controller harmO.channel, 7, harmO.ctrl(7) END SELECT END FUNCTION SUB HarmO_registers () ' rev. gwr 16.07.2005 - harma ' adapted to harmO by KL. 20.11.2009 LOCAL i AS LONG LOCAL x AS LONG LOCAL label$() LOCAL b$ IF ISFALSE hwRegharmO THEN DIM label$(8) ARRAY ASSIGN label$() = "cor2'", "dia8'", "bour16'", "prin4'","sub32'","vl 4'", "forte8'", "clar16'", "oboe8'" DIALOG NEW 0, "HarmO Registers",1,150 ,400, 20, %WS_CAPTION OR %WS_POPUP OR %WS_SYSMENU TO hwRegharmO FOR i = 0 TO 8 CONTROL ADD CHECKBOX, hwRegHarmo, i+1, label$(i), 1 + 42 * i, 1, 40, 12, %BS_PUSHLIKE NEXT DIALOG SHOW MODELESS hwRegharmO CALL CB_harmOReg ELSE DIALOG END hwCtrlharmO hwCtrlharmO = 0 END IF END SUB CALLBACK FUNCTION CB_HarmoReg LOCAL i AS LONG SELECT CASE CBMSG CASE %WM_COMMAND SELECT CASE CBCTL CASE 1 TO 9 CONTROL GET CHECK CBHNDL, CBCTL TO i controller HarmO.channel, 69 + CBCTL, i END SELECT END SELECT END FUNCTION '[EOF] _ _