' ********************************************* ' * * ' * & * ' * * ' * for flute and electronics * ' *CopyLeft 1998/2002 by Godfried-Willem RAES * ' * dedicated to Karin De Fleyt * ' ********************************************* ' This code module should be compiled and linked with ' last update: 11.06.2002 ' 13.01.2001 : recheck code for recognition. ' we should make a panatella version... ' Follow. structure removed, Patternrecognition changed. ' 02.09.2001: Panatella version code added. ' 27.03.2005: recompiled under PB8.0 ' 03.10.2006: audiofiles moved and software adapted accordingly GLOBAL Flute AS Musician '----- procedure declarations for --------- DECLARE FUNCTION CohibaInit () AS LONG DECLARE SUB CohibaInitSynth () ' proteus 2 initialisation procedure DECLARE SUB CohibaGetLastNote (noot?, velo?) DECLARE SUB CohibaDoEvent () ' interactive score - called from melodyrecognize ' by its codepointer in recog.cPtr. DECLARE SUB CohibaListen () ' task 16 reads midi in and writes to the delay lines DECLARE SUB CohibaVoice1 () ' task 17 DECLARE SUB CohibaVoice2 () ' task 18 DECLARE SUB CohibaVoice3 () ' task 19 DECLARE SUB CohibaVoice4 () ' task 20 DECLARE SUB CohibaPlayGlob () ' task 21 DECLARE SUB CohibaDelayInvertN () ' task 22 DECLARE SUB CohibaDelayInvertSlow () ' task 23 DECLARE SUB CohibaDelayInvertFast () ' task 24 DECLARE SUB CohibaDelayInvertBackwards () ' task 25 DECLARE SUB CohibaDelayN () ' task 26 DECLARE SUB CohibaDelayS () ' task 27 DECLARE SUB CohibaDelayF () ' task 28 DECLARE SUB CohibaDelayBackN () ' task 29 DECLARE SUB CohibaDetune () ' task 30 DECLARE SUB CohibaScore () ' task 31 DECLARE SUB CohibaRitme (tasknr%) ' coupled to voice procedures. A single proc. serves all voices. DECLARE SUB CohibaPattern1 () ' task 32 DECLARE SUB CohibaPattern2 () ' task 33 DECLARE SUB CohibaStereo () ' pseudotask 62 DECLARE SUB CohibaMultiChannel () ' pseudotask 63 DECLARE SUB ButnSW_CohibaStartStop () ' specific code for the panatella version. DECLARE FUNCTION Init_Panatella () AS LONG ' new 09.2001 DECLARE SUB PanatellaDoEvent () DECLARE SUB Flute_Listen () DECLARE SUB SetFluteContext (noot AS BYTE, velo AS BYTE) DECLARE SUB ButnSW_PanatellaStartStop () DECLARE SUB PanatellaPattern1 () ' task 32 DECLARE SUB PanatellaPattern2 () ' task 33 #IF %DEF(%Nidaq) %nomoveref_task = 35 DECLARE SUB GetNoMoveRef () DECLARE SUB PanatellaPanning () #ENDIF '********************************************************************** ' cohiba.bas ---- Procedure code for * '********************************************************************** FUNCTION CohibaInit () AS LONG LOCAL Tasknr AS INTEGER LOCAL CockpitLayo AS CockpitLabels IF ISFALSE hMidiI(0) THEN ErrorMidiIn : EXIT FUNCTION IF ISFALSE hMidiO(0) THEN ErrorMidiOut: EXIT FUNCTION SelectMidiEquipment $COHIBAINI, Meq() Update_MidiEquipment Meq() ReadPatternRecognitionDataFile $Cohibaini ReadSynthConfigFile $Cohibaini, Meq() ' ReadFaderParams $Cohibaini , Audiofader() ReadCockpitLabelsFromFile $Cohibaini, CockpitLayo GetInstrumentParams Flute, %ID_FLUTE Recog.cPtr = CODEPTR(CohibaDoEvent) ' new !!![01.08.1999] Recog.nr = -1 ' this procedure defines all the tasks that are required for the piece ' it is called from InitTasks in GMT_GWR only when the metaconstant %Cohiba is defined. Task(%Listen_Task).naam = "Listen " ' for flute player input - reads midi-input and writes delayline buffers Task(%Listen_Task).freq = 35 ' 21 Hz should be very responsive... Task(%Listen_Task).channel = 0 'Flute.channel ' input channel - normally set to 0 Task(%Listen_Task).level = 127 Task(%Listen_Task).pan = 0 Task(%Listen_Task).cptr = CODEPTR(CohibaListen) Task(%Listen_Task).starttime = 0 Task(%Listen_Task).stoptime = 1000 Task(%Listen_Task).Rit.minduur = Flute.minduur/1000 ' Flute.minduur is in ms Task(%Listen_Task).Rit.maxduur = Flute.maxduur/1000 Task(17).naam = "Voice1" Task(17).freq = 0.1 ' recalculated internally Task(17).tempo = 5.6 :' 60 '30 Task(17).cptr = CODEPTR(CohibaVoice1) Task(17).starttime = -1 Task(17).stoptime = 1000 Task(17).Rit.minduur = .333 ' 125 ' 050 ' in s Task(17).Rit.maxduur = 4 ' in s Task(18).naam = "Voice2" Task(18).freq = 0.136 Task(18).tempo = 8.2 ' 36 Task(18).cptr = CODEPTR(CohibaVoice2) Task(18).starttime = -1 Task(18).stoptime = 1000 Task(18).Rit.minduur = 0.125 ' 050 ' in s Task(18).Rit.maxduur = 1.000 ' in s Task(19).naam = "Voice3" Task(19).freq = 0.113 ' 1.5 Task(19).tempo = 6.8 ' 45 Task(19).cptr = CODEPTR(CohibaVoice3) Task(19).starttime = -1 Task(19).stoptime = 1000 Task(19).Rit.minduur = 0.125' 050 ' in s Task(19).Rit.maxduur = 1.000 ' in s Task(20).naam = "Voice4" Task(20).freq = 0.1666 ' 1.8 Task(20).tempo = 10 ' 54 Task(20).cptr = CODEPTR(CohibaVoice4) Task(20).starttime = -1 Task(20).stoptime = 1000 Task(20).Rit.minduur = 0.125 ' 050 ' in s Task(20).Rit.maxduur = 1.000 ' in s Task(21).naam = "PlayGlob" Task(21).freq = 0.68 Task(21).tempo = 40.8 Task(21).cptr = CODEPTR(CohibaPlayGlob) Task(21).Rit.minduur = 0.150 ' in s Task(21).Rit.maxduur = 3.000 ' in s Task(22).naam = "Dly-Inv " ' inverted delay line , original timing. Task(22).freq = 32 Task(22).cptr = CODEPTR(CohibaDelayInvertN) Task(22).Rit.minduur = 0.150 ' in s Task(22).Rit.maxduur = 3.000 ' in s Task(23).naam = "Dly-S " Task(23).freq = 16 Task(23).cptr = CODEPTR(CohibaDelayInvertSlow) Task(23).Rit.minduur = 0.200 ' in s Task(23).Rit.maxduur = 3.000 ' in s Task(24).naam = "Dly-F " Task(24).freq = 60 Task(24).cptr = CODEPTR(CohibaDelayInvertFast) Task(24).Rit.minduur = 0.050 ' in s Task(24).Rit.maxduur = 2.000 ' in s Task(25).naam = "Dly-Back" Task(25).freq = 32 Task(25).cptr = CODEPTR(CohibaDelayInvertBackwards) Task(25).Rit.minduur = 0.100 ' in s Task(25).Rit.maxduur = 1.000 ' in s Task(26).naam = "Dly-Norm" ' normal delay lines Task(26).freq = 32 Task(26).cptr = CODEPTR(CohibaDelayN) Task(26).Rit.minduur = 0.100 ' in s Task(26).Rit.maxduur = 2.200 ' in s Task(27).naam = "Dly-Slow" Task(27).freq = 15 Task(27).cptr = CODEPTR(CohibaDelayS) Task(27).Rit.minduur = 0.200 ' in s Task(27).Rit.maxduur = 3.300 ' in s Task(28).naam = "Dly-Fast" Task(28).freq = 50 Task(28).cptr = CODEPTR(CohibaDelayF) Task(28).Rit.minduur = 0.50 ' in s Task(28).Rit.maxduur = 2.700 ' in s Task(29).naam = "DlyNBack" Task(29).freq = 30 Task(29).cptr = CODEPTR(CohibaDelayBackN) Task(29).Rit.minduur = 0.100 ' in s Task(29).Rit.maxduur = 1.800 ' in s Task(30).naam = "Detune" Task(30).freq = 20 Task(30).cptr = CODEPTR(CohibaDetune) Task(30).Rit.minduur = 0.065 ' in s Task(30).Rit.maxduur = 5.000 ' in s Task(30).Starttime = 910 Task(30).Stoptime = 1000 Task(31).naam = "Score" ' for automatic playing - scheduler Task(31).freq = 1 Task(31).tempo = 60 Task(31).cptr = CODEPTR(CohibaScore) Task(32).naam = "Pattern1" Task(32).freq = 19 Task(32).tempo = 60 Task(32).cptr = CODEPTR(CohibaPattern1) Task(32).starttime = -1 Task(32).stoptime = 1000 Task(32).Rit.minduur = .065 Task(32).Rit.maxduur = 4 ' in s Task(33).naam = "Pattern2" Task(33).freq = 19.3 Task(33).tempo = 61 Task(33).cptr = CODEPTR(CohibaPattern2) Task(33).starttime = -1 Task(33).stoptime = 1000 Task(33).Rit.minduur = .065 Task(33).Rit.maxduur = 4 ' in s Task(62).naam = "Stereo" Task(62).freq = 10 Task(62).cptr = CODEPTR(CohibaStereo) Task(63).naam = "Ambio " Task(63).freq = 10 Task(63).cptr = CODEPTR(CohibaMultichannel) CohibaInitSynth ' send settings to synthesizer Task(App.GlobalHarmonyTaskNr).swit = %True ' we stick to the default number in *.ini Task(App.ReadSeqScoreTaskNr).cPtr = %False ' remove from cockpit. LOCAL nr AS LONG ' nr = ReadAudioDataFromFile ($COHIBAINI, AudioFader()) removed 11.06.2002 LastNotePlayed = 61 ' initialize the global variable. ' delete buttons that are not required or functional and set our own handler ButnSW(1).cptr = CODEPTR(ButnSW_CobibaStartStop) ButnSW(2).tag0 = "" ButnSW(3).tag0 = "" ButnSW(7).tag0 = "" ButnSW(8).tag0 = "" ButnSW(9).tag0 = "" ButnSW(10).tag0 = "" ButnSW(11).tag0 = "" ' one shot buttons: ButnOS(1).tag = "" ButnOS(2).tag = "" ButnOS(3).tag = "" ButnOS(4).tag = "" ButnOS(5).tag = "" ButnOS(6).tag = "" ButnOS(7).tag = "" ButnOS(9).tag = "" ButnOS(10).tag = "" ButnOS(11).tag = "" ' create the melody window automatically on startup: [we fake pressing a button...] LOCAL msg AS tagMSG msg.hWnd = gh.Cockpit msg.message = %WM_COMMAND msg.wParam = %GMT_BUTNSW_ID + 5 msg.lParam = %Null DispatchMessage msg ' write caption bars: LOCAL m AS ASCIIZ * 40 m = "GMT Cockpit for " Sendmessage gh.Cockpit, %WM_SETTEXT,0, VARPTR(m) m = " - Score" SendMessage gh.MelPat, %WM_SETTEXT,0, VARPTR(m) ' InvalidateRect gh.MelPat, BYVAL 0, BYVAL 1 FUNCTION = %True END FUNCTION FUNCTION Init_Panatella () AS LONG LOCAL Tasknr AS INTEGER LOCAL i AS LONG LOCAL CockpitLayo AS CockpitLabels FUNCTION = %False IF ISFALSE hMidiI(0) THEN ErrorMidiIn : EXIT FUNCTION IF ISFALSE hMidiO(0) THEN ErrorMidiOut: EXIT FUNCTION SelectMidiEquipment $Panatellaini, Meq() ReadPatternRecognitionDataFile $Panatellaini ReadSynthConfigFile $Panatellaini, Meq() ' ReadFaderParams $Panatellaini , AudioFader() ReadCockpitLabelsFromFile $Panatellaini, CockpitLayo GetInstrumentParams Flute, %ID_FLUTE Recog.cPtr = CODEPTR(PanatellaDoEvent) Recog.nr = -1 Task(%Listen_Task).naam = "Listen " ' for flute player input - reads midi-input and writes delayline buffers Task(%Listen_Task).freq = 30 ' 21 Hz should be very responsive... Task(%Listen_Task).channel = 0 'Flute.channel ' input channel - normally set to 0 Task(%Listen_Task).level = 127 Task(%Listen_Task).pan = 0 Task(%Listen_Task).cptr = CODEPTR(Flute_Listen) Task(%Listen_Task).starttime = 0 Task(%Listen_Task).stoptime = 1000 Task(%Listen_Task).Rit.minduur = Flute.minduur/1000 ' Flute.minduur is in ms Task(%Listen_Task).Rit.maxduur = Flute.maxduur/1000 Task(17).naam = "Voice1" Task(17).freq = 0.1 ' recalculated internally Task(17).tempo = 5.6 :' 60 '30 Task(17).cptr = CODEPTR(CohibaVoice1) Task(17).starttime = -1 Task(17).stoptime = 1000 Task(17).Rit.minduur = .333 ' 125 ' 050 ' in s Task(17).Rit.maxduur = 4 ' in s Task(18).naam = "Voice2" Task(18).freq = 0.136 Task(18).tempo = 8.2 ' 36 Task(18).cptr = CODEPTR(CohibaVoice2) Task(18).starttime = -1 Task(18).stoptime = 1000 Task(18).Rit.minduur = 0.125 ' 050 ' in s Task(18).Rit.maxduur = 1.000 ' in s Task(19).naam = "Voice3" Task(19).freq = 0.113 ' 1.5 Task(19).tempo = 6.8 ' 45 Task(19).cptr = CODEPTR(CohibaVoice3) Task(19).starttime = -1 Task(19).stoptime = 1000 Task(19).Rit.minduur = 0.125' 050 ' in s Task(19).Rit.maxduur = 1.000 ' in s Task(20).naam = "Voice4" Task(20).freq = 0.1666 ' 1.8 Task(20).tempo = 10 ' 54 Task(20).cptr = CODEPTR(CohibaVoice4) Task(20).starttime = -1 Task(20).stoptime = 1000 Task(20).Rit.minduur = 0.125 ' 050 ' in s Task(20).Rit.maxduur = 1.000 ' in s Task(21).naam = "PlayGlob" Task(21).freq = 0.68 Task(21).tempo = 40.8 Task(21).cptr = CODEPTR(CohibaPlayGlob) Task(21).Rit.minduur = 0.150 ' in s Task(21).Rit.maxduur = 3.000 ' in s Task(22).naam = "Dly-Inv " ' inverted delay line , original timing. Task(22).freq = 32 Task(22).cptr = CODEPTR(CohibaDelayInvertN) Task(22).Rit.minduur = 0.150 ' in s Task(22).Rit.maxduur = 3.000 ' in s Task(23).naam = "Dly-S " Task(23).freq = 16 Task(23).cptr = CODEPTR(CohibaDelayInvertSlow) Task(23).Rit.minduur = 0.200 ' in s Task(23).Rit.maxduur = 3.000 ' in s Task(24).naam = "Dly-F " Task(24).freq = 60 Task(24).cptr = CODEPTR(CohibaDelayInvertFast) Task(24).Rit.minduur = 0.050 ' in s Task(24).Rit.maxduur = 2.000 ' in s Task(25).naam = "Dly-Back" Task(25).freq = 32 Task(25).cptr = CODEPTR(CohibaDelayInvertBackwards) Task(25).Rit.minduur = 0.100 ' in s Task(25).Rit.maxduur = 1.000 ' in s Task(26).naam = "Dly-Norm" ' normal delay lines Task(26).freq = 32 Task(26).cptr = CODEPTR(CohibaDelayN) Task(26).Rit.minduur = 0.100 ' in s Task(26).Rit.maxduur = 2.200 ' in s Task(27).naam = "Dly-Slow" Task(27).freq = 15 Task(27).cptr = CODEPTR(CohibaDelayS) Task(27).Rit.minduur = 0.200 ' in s Task(27).Rit.maxduur = 3.300 ' in s Task(28).naam = "Dly-Fast" Task(28).freq = 50 Task(28).cptr = CODEPTR(CohibaDelayF) Task(28).Rit.minduur = 0.50 ' in s Task(28).Rit.maxduur = 2.700 ' in s Task(29).naam = "DlyNBack" Task(29).freq = 30 Task(29).cptr = CODEPTR(CohibaDelayBackN) Task(29).Rit.minduur = 0.100 ' in s Task(29).Rit.maxduur = 1.800 ' in s Task(30).naam = "Detune" Task(30).freq = 20 Task(30).cptr = CODEPTR(CohibaDetune) Task(30).Rit.minduur = 0.065 ' in s Task(30).Rit.maxduur = 5.000 ' in s Task(30).Starttime = 910 Task(30).Stoptime = 1000 ' Task(31).naam = "Score" ' for automatic playing - scheduler ' Task(31).freq = 1 ' Task(31).tempo = 60 ' Task(31).cptr = CODEPTR(CohibaScore) Task(32).naam = "Pattern1" Task(32).freq = 19 Task(32).tempo = 60 Task(32).cptr = CODEPTR(PanatellaPattern1) Task(32).starttime = -1 Task(32).stoptime = 1000 Task(32).Rit.minduur = .065 Task(32).Rit.maxduur = 4 ' in s Task(33).naam = "Pattern2" Task(33).freq = 19.3 Task(33).tempo = 61 Task(33).cptr = CODEPTR(PanatellaPattern2) Task(33).starttime = -1 Task(33).stoptime = 1000 Task(33).Rit.minduur = .065 Task(33).Rit.maxduur = 4 ' in s Task(62).naam = "Stereo" Task(62).freq = 10 Task(62).cptr = CODEPTR(CohibaStereo) Task(63).naam = "Ambio " Task(63).freq = 10 Task(63).cptr = CODEPTR(CohibaMultichannel) CohibaInitSynth ' send settings to synthesizer Task(App.GlobalHarmonyTaskNr).swit = %True ' we stick to the default number in *.ini Task(App.ReadSeqScoreTaskNr).cPtr = %False ' remove from cockpit. LOCAL nr AS LONG ' nr = ReadAudioDataFromFile ($PanatellaINI, AudioFader()) - removed 11.06.2002 LastNotePlayed = 61 ' initialize the global variable. ' delete buttons that are not required or functional and set our own handler ButnSW(1).cptr = CODEPTR(ButnSW_PanatellaStartStop) ButnSW(2).tag0 = "" ButnSW(3).tag0 = "" ButnSW(7).tag0 = "" ButnSW(8).tag0 = "" ButnSW(9).tag0 = "" ButnSW(10).tag0 = "" ButnSW(11).tag0 = "" ' one shot buttons: ButnOS(1).tag = "" ButnOS(2).tag = "" ButnOS(3).tag = "" ButnOS(4).tag = "" ButnOS(5).tag = "" ButnOS(6).tag = "" ButnOS(7).tag = "" ButnOS(9).tag = "" ButnOS(10).tag = "" ButnOS(11).tag = "" ' create the melody window automatically on startup: [we fake pressing a button...] LOCAL msg AS tagMSG msg.hWnd = gh.Cockpit msg.message = %WM_COMMAND msg.wParam = %GMT_BUTNSW_ID + 5 msg.lParam = %Null DispatchMessage msg DrawAllPatterns gh.MelPat ' write caption bars: LOCAL m AS ASCIIZ * 40 m = " " Sendmessage gh.Cockpit, %WM_SETTEXT,0, VARPTR(m) m = " Score" SendMessage gh.MelPat, %WM_SETTEXT,0, VARPTR(m) ' InvalidateRect gh.MelPat, BYVAL 0, BYVAL 1 ' MSGBOX STR$(task(32).channel) + STR$(task(32).channel) #IF %DEF(%Nidaq) REDIM DataBuf0(0 TO 0) AS INTEGER Task(%DAQ_TASK).naam = "DAQ-Buf" '12 ' alternative for double buffer DAQ mode. Task(%DAQ_TASK).cPtr = CODEPTR(DAQ_Task) ' the procedure is in gmt_ii.bas Task(%DAQ_TASK).freq = DAQparams.scanfreq ' default - sets the sampling rate. Task(%DAQ_TASK).channel = %DAQ_S07 ' flags = sets the number of channels ' Task(%NoMoveRef_Task).naam = "Calib" ' Task(%NoMoveREf_Task).cPtr = CODEPTR(GetNoMoveRef) ' Task(%NoMoveRef_Task).freq = 16 i = Prepare_DAQ_Hardware ($KarinIni) ' in g_NiDAQ.dll IF ISFALSE i THEN MSGBOX "Daq hardware preparation failed!",,"Warning" Task(36).naam = "Pan" Task(36).cptr = CODEPTR(Panatellapanning) Task(36).freq = 8 #ENDIF FUNCTION = %True END FUNCTION SUB ButnSW_CobibaStartStop () LOCAL buttonnr AS DWORD ' added 21.04.2000 ' changed 04.05.2000 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 + 1, "STOP" IF hMidiI(0) THEN ClearMiBuf 0 ' start with a blank midi input buffer BlockSysExReception hMidiI(0) ' dll procedure END IF ' IF App.MTSpeedTasknr > -1 THEN StartTask App.MTSpeedTaskNr 'IF App.PromilTasknr > -1 THEN StartTask App.PromilTaskNr 'IF App.RunTimeTaskNr > -1 THEN StartTask App.RunTimeTaskNr Promil %True Runtime %True IF App.GlobalHarmonyTasknr > -1 THEN StartTask App.GlobalHarmonyTasknr StartTask %Listen_Task '16 ' listen StartTask 31 ' score ELSE App.MTstart = %False SetDlgItemText gh.Cockpit, %GMT_BUTNSW_ID + 1, "CONT" 'IF App.PromilTasknr > -1 THEN StopTask App.PromilTaskNr Promil %False IF App.GlobalHarmonyTaskNr > -1 THEN StopTask App.GlobalHarmonyTasknr StopTask %Listen_Task '16 END IF App.ButnSWparam = %False END SUB SUB CohibaInitSynth LOCAL i AS DWORD LOCAL j AS WORD ' this procedure sends all midi settings to the midi gear needed for this piece. ' if the tasks are already initialized: ' It is not indispensable to do this, since starting a task that uses midi, will automatically send the ' correct patch to the port/channel. FOR i = LBOUND(Task) TO UBOUND(Task) IF (Task(i).flags AND %MIDI_TASK) = %MIDI_TASK THEN SELECT CASE UCASE$(TRIM$(Meq(0).naam)) 'App.SynthName CASE "PROTEUS2", "PROTEUS2XR" ProteusPatch Meq(0), Task(i).channel, Task(i).patch ' for cohiba CASE ELSE ProgChange Task(i).channel, Task(i).patch ' for panatella END SELECT ModeMess Task(i).channel, &H79, 0 ' reset all controllers ModeMess Task(i).channel, 7 , Task(i).level ModeMess Task(i).channel, 10, Task(i).pan END IF NEXT i SetPitchBendRange Meq(0),0,1 ' set global pitchbendrange to +/- 1 semitone END SUB SUB CohibaListen () EXPORT LOCAL nv%, noot?, velo? STATIC oldnote AS BYTE IF ISFALSE Task(%Listen_Task).tog THEN oldnote = %False Task(%Listen_Task).tog = %True END IF nv% = GetMidiNote% (Task(%Listen_Task).channel, %Remove OR %Oldest) IF nv% = %NotFalse THEN EXIT SUB velo? = LOBYT (nv%) noot? = HIBYT (nv%) IF (noot? >= Flute.lowtes) AND (noot? <= Flute.hightes) THEN IF velo? > 0 THEN IF oldnote THEN DelNote2Har Task(%Listen_Task).Har, oldnote WriteDelayLine oldnote, %False CohibaGetLastNote oldnote, %False ' this starts the patternrecognizer END IF AddNote2Har Task(%Listen_Task).Har, noot?, velo? WriteDelayLine noot?, velo? CohibaGetLastNote noot?, velo? oldnote = noot? ELSE WriteDelayLine noot?, %False CohibaGetLastNote noot?, %False DelNote2Har Task(%Listen_Task).Har, noot? oldnote = %False END IF END IF END SUB SUB CohibaGetLastNote (noot?, velo?) EXPORT ' changed 13.01.2001 - patternrecognition is now called from here! STATIC tog? IF tog? = %False THEN DIM Pregnancy(Flute.lowtes TO Flute.hightes) AS STATIC LONG tog? = %True END IF IF (noot? < Flute.lowtes) OR (noot? > Flute.hightes) THEN EXIT SUB ' keeps durations of notes played. (polyphonic!) ' this proc. should be called after reception of a note off command. ' we demand a minimum value for velo? as well of course... IF velo? > Flute.minvel THEN Pregnancy(noot?)= - timeGetTime ' set time value negative ELSE IF ISFALSE velo? THEN IF Pregnancy(noot?) < 0 THEN Pregnancy(noot?) = timeGetTime + Pregnancy(noot?) ' result will always be positive now. IF Pregnancy(noot?) >= Flute.minduur THEN LastNotePlayed = noot? MelodyPatternRecognize noot?, ASC(MID$(Task(%Listen_Task).Har.Vel,noot?+1,1)), Pregnancy(noot?) ' new 13.01.2001 END IF Pregnancy(noot?) = %False END IF ELSE ' very soft note on Pregnancy(noot?)= %False END IF END IF END SUB SUB CohibaDoEvent () EXPORT ' reacts on changes in the recognized sequence counter. ' called by its codepointer in Recog.cPtr. SELECT CASE Recog.nr CASE < %False EXIT SUB CASE 0 StartTask 22 ' normal inverted delay PlayWavefile SampleList(Recog.nr), 0 CASE 1 StartTask 23 ' slow inverted delay PlayWavefile SampleList(Recog.nr), 0 CASE 2 StartTask 24 ' fast inverted delay PlayWavefile SampleList(Recog.nr), 0 CASE 3 StartTask 25 ' normal inverted backwards delay StartTask 32 ' pattern 1 StartTask 33 ' pattern 2 PlayWavefile SampleList(Recog.nr), 0 CASE 4 StopTask 23 ' slow inverted delay OFF PlayWavefile SampleList(Recog.nr), 0 StopTask 33 ' stop pattern 2 CASE 5 StopTask 22 ' normal inverted delay OFF PlayWavefile SampleList(Recog.nr), 0 StopTask 32 ' stop pattern 1 CASE 6 StartTask 26 ' normal delay PlayWavefile SampleList(Recog.nr), 0 CASE 7 StopTask 26 ' normal delay OFF StartTask 27 ' slow delay PlayWavefile SampleList(Recog.nr), 0 CASE 8 StartTask 28 ' fast delay PlayWavefile SampleList(Recog.nr), 0 CASE 9 StartTask 29 ' backwards normal delay PlayWavefile SampleList(Recog.nr), 0 CASE 10 StartTask 23 ' slow inverted delay ON StartTask 30 ' detune PlayWavefile SampleList(Recog.nr), 0 StopTask 24 ' fast inverted delay off StopTask 28 ' fast delay off StopTask 20 ' voice 4 off END SELECT END SUB SUB CohibaVoice1 () ' This procedure is polyphonic. STATIC Ritmeteller%, tasknr% , HarV1 AS HarmType , starttempo AS SINGLE IF tasknr% = %False THEN tasknr% = 17 HarV1.vel = STRING$(128,0) starttempo = Task(tasknr%).tempo END IF LOCAL tiks! IF Task(tasknr%).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 ' get new parameters: Task(tasknr%).tempo = starttempo * (1 + Tprop!(tasknr%)) ' return a new pattern for the rhythm as soon as the actual one has been completed. (new bar): Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, tasknr%, 2 ' must be byref!!! END IF tiks! = RitmSigma!(Task(tasknr%).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(tasknr%).freq = (tiks! * Task(tasknr%).tempo ) / (60 * ABS(Task(tasknr%).Rit.pattern(Ritmeteller%))) IF Task(tasknr%).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(tasknr%).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(tasknr%).Har.vel = SolveHar$ (Task(App.GlobalHarmonyTasknr).Har, (LastNotePlayed), 0.05) ELSE Task(tasknr%).Har.vel = STRING$(128,0) END IF END IF INCR Ritmeteller% IF Task(tasknr%).Har.vel <> HarV1.vel THEN IF Task(tasknr%).Har.vel <> Task(App.GlobalHarmonyTasknr).Har.vel THEN PlayHar Task(tasknr%).Har, Task(tasknr%).channel ' playhar keeps track of oldnotes internally... IF Task(tasknr%).Har.vel <> STRING$(128,0) THEN HarV1.vel = Task(tasknr%).Har.vel END IF END IF END IF END SUB SUB CohibaVoice2 ' modelled after Voice1. This procedure is polyphonic. STATIC Ritmeteller%, tasknr%, HarV2 AS HarmType , Starttempo AS SINGLE IF tasknr% = %False THEN tasknr% = 18 HarV2.vel = STRING$(128,0) Starttempo = Task(tasknr%).tempo END IF LOCAL tiks!, bn% IF Task(tasknr%).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 Task(tasknr%).tempo = Starttempo * (1 + Tprop!(tasknr%)) Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, Tasknr%, 3 HarV2.vel = Task(App.GlobalHarmonyTaskNr).Har.vel ' remember globhar now END IF tiks! = RitmSigma!(Task(tasknr%).Rit) IF tiks! < 1 THEN EXIT SUB Task(tasknr%).freq = (tiks! * Task(tasknr%).tempo ) / (60 * ABS(Task(tasknr%).Rit.pattern(Ritmeteller%))) IF Task(tasknr%).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(tasknr%).Har.vel = STRING$(128,0) ELSE ' now we have to figure out a new chord to mPlay for our task... Task(tasknr%).Har.vel = SymDimHar$ (HarV2, LastNotePlayed, +1) ' augment END IF INCR Ritmeteller% IF Task(tasknr%).Har.vel <> HarV2.vel THEN PlayHar Task(tasknr%).Har, Task(tasknr%).channel ' playhar keeps track of oldnotes internally... IF Task(tasknr%).Har.vel <> STRING$(128,0) THEN HarV2.vel = Task(tasknr%).Har.vel END IF END IF END SUB SUB CohibaVoice3 ' modelled after Voice1. This procedure is polyphonic. STATIC Ritmeteller%, tasknr%, HarV3 AS HarmType , StartTempo AS SINGLE, cnt? , V3level? , V3pan? IF tasknr% = %False THEN tasknr% = 19 HarV3.vel = STRING$(128,0) StartTempo = Task(tasknr%).tempo cnt? = 0 END IF LOCAL tiks!, bn% IF Task(tasknr%).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 INCR cnt? cnt? = cnt? AND 3 ' counts 0, 1, 2 , 3 Task(tasknr%).tempo = StartTempo * (1.5 + COS(Tang!(tasknr%))) IF cnt? MOD 2 = 0 THEN ' was : Iprop2Rit App.GlobalHarmonyTasknr, tasknr% , 3 Iprop2Rit Task(App.GlobalHarmonyTasknr).Har, Tasknr%, 3 ELSE ' was: ShepChord2Rit App.GlobalHarmonyTasknr, tasknr% , 3, 65 ShepChord2Rit Task(App.GlobalHarmonyTasknr).Har, Tasknr%, 3, 65 END IF HarV3.vel = Task(App.GlobalHarmonyTaskNr).Har.vel ' remember globhar now V3level? = Task(tasknr%).level ' reset volume for each bar. V3pan? = Task(tasknr%).pan END IF tiks! = RitmSigma!(Task(tasknr%).Rit) IF tiks! < 1 THEN EXIT SUB Task(tasknr%).freq = (tiks! * Task(tasknr%).tempo ) / (60 * ABS(Task(tasknr%).Rit.pattern(Ritmeteller%))) IF Task(tasknr%).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(tasknr%).Har.vel = STRING$(128,0) ELSE ' now we have to figure out a new chord to mPlay for our task... Task(tasknr%).Har.vel = SymDimHar$ (HarV3, LastNotePlayed, -1) ' dim END IF INCR Ritmeteller% V3pan? = (V3pan? + 8) MOD 128 IF Task(tasknr%).Har.vel <> HarV3.vel THEN ModeMess Task(tasknr%).channel, 7 , V3level? ModeMess Task(tasknr%).channel, 10, V3pan? IF V3level? >= 3 THEN V3level? = V3level? - 3 ELSE V3level? = 0 END IF PlayHar Task(tasknr%).Har, Task(tasknr%).channel ' playhar keeps track of oldnotes internally... IF Task(tasknr%).Har.vel <> STRING$(128,0) THEN HarV3.vel = Task(tasknr%).Har.vel END IF END IF END SUB SUB CohibaVoice4 STATIC Ritmeteller%, tasknr%, HarV4 AS HarmType , StartTempo AS SINGLE, V4level AS BYTE, V4pan AS BYTE IF tasknr% = %False THEN tasknr% =20 HarV4.vel = STRING$(128,0) StartTempo = Task(tasknr%).tempo END IF LOCAL tiks!, bn% IF Task(tasknr%).Rit.pattern(Ritmeteller%) = 0 THEN Ritmeteller% = 0 Task(tasknr%).tempo = StartTempo * (1.5 + COS(Tang!(tasknr%))) Iprop2Rit Task(App.GlobalharmonyTasknr).Har, Tasknr%, 2 HarV4.vel = Task(App.GlobalHarmonyTaskNr).Har.vel :' remember globhar now V4level = Task(tasknr%).level V4pan = Task(tasknr%).pan END IF tiks! = RitmSigma!(Task(tasknr%).Rit) IF tiks! < 1 THEN EXIT SUB Task(tasknr%).freq = (tiks! * Task(tasknr%).tempo ) / (60 * ABS(Task(tasknr%).Rit.pattern(Ritmeteller%))) IF Task(tasknr%).Rit.pattern(Ritmeteller%) < 0 THEN ' this means we have to mPlay a rest... Task(tasknr%).Har.vel = STRING$(128,0) ELSE ' now we have to figure out a new chord to mPlay for our task... Task(tasknr%).Har.vel = DiminuteHar$ (HarV4, LastNotePlayed MOD 12,11, 1) ' aug END IF INCR Ritmeteller% V4pan = (V4pan + 7) MOD 128 IF Task(tasknr%).Har.vel <> HarV4.vel THEN PlayHar Task(tasknr%).Har, Task(tasknr%).channel ' playhar keeps track of oldnotes internally... ModeMess Task(tasknr%).channel, 10, V4pan IF Task(tasknr%).Har.vel <> STRING$(128,0) THEN HarV4.vel = Task(tasknr%).Har.vel END IF END IF END SUB SUB CohibaRitme (tasknr%) LOCAL Shape!(), nrtiks%, ScratchHar AS HarmType REDIM Shape!(0 TO %d7 - 1) ' receives result from library function ShiftDownStrongest Task(App.GlobalHarmonyTasknr).Har, ScratchHar ' but shift it down Har2Shape ScratchHar, Shape!() ' inverse transform HanningWindow Shape!() ' apply window function ' result depends on Task().Rit.minduur and Task().tempo nrtiks% = GetNrTicks (Tasknr%) IF nrtiks% <= 1 THEN Task(tasknr%).Rit.pattern(0)= -1 ' rust Task(tasknr%).Rit.pattern(1)= 0 ' einde patroon EXIT SUB END IF Wave2Ritm Shape!(), Task(tasknr%).Rit, nrtiks% ' ofwel nog: PositRitm Task(tasknr%).Rit, NrTiks% ' verwijder nullen uit het array... ShiftLeftOnZero Task(tasknr%).Rit, 1! / nrtiks% ERASE Shape! END SUB ' -------------------------------------------------------------------------- SUB CohibaDelayInvertN () ' This delay line outputs at normal speed but inverts the intervals LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD, mirrornote? IF ISFALSE tasknr% THEN nv% = GetPromil% IF nv% <=0 THEN EXIT SUB delaytime = nv% * App.komposduur tasknr% = 22 mirrornote? = 66 END IF nv% = ReadDelayLine(tasknr%, delaytime, 1!) ' delaytime= time from start up to recognition of pattern 1 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(tasknr%, 0, 0) ' force a reset StopTask tasknr% EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) noot? = mirrornote? + mirrornote? - noot? IF noot? > 127 THEN EXIT SUB IF noot? <=0 THEN EXIT SUB Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDelayInvertSlow () ' this taskprocedure builds a delay-line for ' midi input. This code plays back at half speed, so it never ends. LOCAL nv%, noot?, velo? STATIC tasknr%, mirrornote? IF ISFALSE tasknr% THEN tasknr%= 23 mirrornote? = 60 END IF nv% = ReadDelayLine(tasknr%, 200, 0.5!) ' 0.20 second delay, < 1 slow down IF nv% <= %False THEN EXIT SUB velo? = LOBYT (nv%) noot? = HIBYT (nv%) noot? = mirrornote? + mirrornote? - noot? IF noot? > 127 THEN EXIT SUB IF noot? <=0 THEN EXIT SUB Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?,velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDelayInvertFast () ' This delay plays at always increasing speed. LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD, COUNT AS DWORD , SPEED AS SINGLE, mirrornote? IF ISFALSE tasknr% THEN nv% = GetPromil% IF nv% <=0 THEN EXIT SUB delaytime = nv% * App.Komposduur tasknr% = 24 INCR COUNT ' not used SPEED = 1.3! * (1! + (SPEED/10!)) ' 1.5 = double speed - this goes accellerando! mirrornote? = 68 END IF nv% = ReadDelayLine(tasknr%, delaytime, SPEED) ' 15 second delay, > 1 speed-up SELECT CASE nv% CASE %False, %NotFalse: EXIT SUB ' if no note came in, exit the task CASE -2 ' read past present. Task(tasknr%).Har.vel = STRING$(128,0) PlayHar Task(tasknr%).Har, Task(tasknr%).channel nv% = ReadDelayLine(tasknr%, 0, 0) ' force a reset tasknr% = %Null ' force calculation of a new delay time EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) noot? = mirrornote? + mirrornote? -noot? IF noot? > 127 THEN EXIT SUB IF noot? <=0 THEN EXIT SUB Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDelayInvertBackwards ' This code plays back backwards. LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD, SPEED AS SINGLE IF ISFALSE tasknr% THEN nv% = GetPromil%() IF nv% =< 0 THEN EXIT SUB delaytime = nv% * App.komposduur SPEED = -1! ' - ( nv%/(1000-nv%)) ' = abs. value > 1, thus we mPlay faster tasknr%= 25 END IF nv% = ReadDelayLine(tasknr%, delaytime, SPEED) ' was: 5000 milliseconds, negative = backwards playing SELECT CASE nv% CASE %False,%NotFalse, -2 EXIT SUB CASE -3 ' read past delay in backwardsmode ' we can force a reset: nv% = ReadDelayLine(tasknr%,0,0) Task(tasknr%).Har.vel= STRING$(128,0) PlayHar Task(tasknr%).Har, Task(tasknr%).channel tasknr% = %Null ' we could of course also switch the task off... END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) noot? = 128 - noot? ' invert intervals IF noot? > 127 THEN EXIT SUB Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaPlayGlob STATIC Tasknr% IF ISFALSE Tasknr% THEN Tasknr%= 21 PlayHar Task(App.GlobalHarmonyTaskNr).Har, Task(Tasknr%).channel ' do not add the contents of this harmony in Globhar, since that would cause a harmonic feedback situation. END SUB SUB CohibaDelayF ' This delay task plays at twice original speed. LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD IF ISFALSE tasknr% THEN nv% = GetPromil%() delaytime = (nv% - 727) * App.komposduur ' the time it took for recognizing pattern 9 IF delaytime < 50 THEN EXIT SUB tasknr% = 28 END IF nv% = ReadDelayLine(tasknr%, delaytime, 1.5!) ' 10 second delay = 10000 milliseconds ' > 1 speed-up SELECT CASE nv% CASE %False, %NotFalse: EXIT SUB ' if no note came in, exit the task CASE -2 ' read past present. ' This can only happen if speed! > 1! Task(tasknr%).Har.vel = STRING$(128,0) PlayHar Task(tasknr%).Har, Task(tasknr%).channel nv% = ReadDelayLine(tasknr%, 0, 0) :' force a reset 'StopTask tasknr% :' this if we want auto switch off 'tasknr% = %Null EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDelayN ' This one outputs at normal speed. LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD IF ISFALSE tasknr% THEN nv% = GetPromil%() delaytime = (nv% - 545) * App.komposduur IF delaytime < 50 THEN EXIT SUB tasknr% = 26 END IF nv% = ReadDelayLine(tasknr%, delaytime, 1!) ' was 3' SELECT CASE nv% CASE %False: EXIT SUB CASE %NotFalse : EXIT SUB ' if no note came in, exit the task CASE -2 nv% = ReadDelayLine(tasknr%, 0, 0) :' force a reset tasknr%= %Null EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDelayS ' This code plays back at half speed, so it never ends. LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD IF ISFALSE tasknr% THEN nv% = GetPromil%() delaytime = (nv% - 636) * App.komposduur IF delaytime < 10 THEN EXIT SUB tasknr%= 27 END IF nv% = ReadDelayLine(tasknr%, delaytime , 0.5!) ' was 0.25 second delay, ' < 1 slow down IF nv% <= %False THEN EXIT SUB velo? = LOBYT (nv%) noot? = HIBYT (nv%) Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDelayBackN ' This code plays back backwards. LOCAL nv%, noot?, velo? STATIC tasknr%, delaytime AS DWORD IF ISFALSE tasknr% THEN nv% = Getpromil%() delaytime = (nv% - 818)* App.komposduur IF delaytime < 100 THEN EXIT SUB tasknr%= 29 END IF nv% = ReadDelayLine(tasknr%, delaytime, -1!) ' negative = backwards playing SELECT CASE nv% CASE %False,%NotFalse, -2 EXIT SUB CASE -3 ' read past delay in backwardsmode ' we force a reset: nv% = ReadDelayLine(tasknr%,0,0) Task(tasknr%).Har.vel= STRING$(128,0) PlayHar Task(tasknr%).Har, Task(tasknr%).channel ' but unconditionally stop the task: StopTask tasknr% tasknr% = %Null EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) Task(tasknr%).Har.vel = STRING$(128,0) ' monophonic IF velo? THEN AddNote2Har Task(tasknr%).Har, noot?, velo? PlayHar Task(tasknr%).Har , Task(tasknr%).channel END SUB SUB CohibaDetune () EXPORT LOCAL nv%, noot?, velo? , detunednote! STATIC tasknr% IF ISFALSE tasknr% THEN tasknr% =30 END IF nv% = ReadDelayLine%(tasknr%, 50, 1!) '50 millisecond delay SELECT CASE nv% CASE %False: EXIT SUB CASE %NotFalse : EXIT SUB ' if no note came in, exit the task CASE -2 ' This can only happen if speed! > 1! nv% = ReadDelayLine%(tasknr%, 0, 0) :' force a reset AllNotesOff Task(tasknr%).channel StopTask Tasknr% tasknr% = %False EXIT SUB END SELECT velo? = LOBYT (nv%) noot? = HIBYT (nv%) IF velo? THEN AllNotesOff Task(tasknr%).channel detunednote! = noot? + SIN(Tang!(Tasknr%)) NoteCentOn Task(tasknr%).channel, detunednote!, velo? ELSE AllNotesOff Task(tasknr%).channel END IF END SUB SUB CohibaScore () EXPORT STATIC tasknr% STATIC wijzer AS BYTE IF ISFALSE tasknr% THEN LOCAL i AS BYTE tasknr% = 31 DIM Marker(0 TO UBOUND(PatternSeq) + 1) AS STATIC WORD ' should match nr. of sequences to recognize! wijzer = %Null FOR i = 0 TO UBOUND(Marker) Marker(i) = (i* 1000) / UBOUND(Marker) NEXT i END IF IF Getpromil > Marker(wijzer) THEN SELECT CASE wijzer CASE 0 IF ISFALSE Task(%Listen_Task).swit THEN StartTask %Listen_Task CASE 1 '91 IF ISFALSE Task(17).swit THEN StartTask 17 CASE 2 '182 CASE 3 '273 IF ISFALSE Task(18).swit THEN StartTask 18 CASE 4 '364 CASE 5 '454 IF ISFALSE Task(19).swit THEN StartTask 19 ' in case recognition of pattern 2 failed: IF Task(23).swit = %True THEN StopTask 23 ' in case recognition of pattern 5 failed: IF Task(33).swit = %True THEN StopTask 33 CASE 6 '545 IF Task(17).swit = %True THEN StopTask 17 ' stop voice 1 'in case the recognition of pattern 1 failed: IF Task(22).swit = %True THEN StopTask 22 ' in case recognition of pattern 6 failed: IF Task(32).swit = %True THEN StopTask 32 CASE 7 '636 IF ISFALSE Task(20).swit THEN StartTask 20 CASE 8 '727 IF Task(18).swit= %True THEN StopTask 18 ' voice 2 off ' in case recognition of pattern 8 failed: IF Task(26).swit = %True THEN StopTask 26 CASE 9 '818 IF Task(25).swit = %True THEN StopTask 25 CASE 10 '909 'IF Task(30).swit = %False THEN StartTask 30 ' detune IF Task(19).swit = %True THEN StopTask 19 ' voice 3 OFF 'IF Task(20).swit = %True THEN StopTask 20 ' voice 4 OFF CASE 11 '1000 - quit composition IF Task(17).swit = %True THEN StopTask 17 IF Task(18).swit = %True THEN StopTask 18 IF Task(19).swit = %True THEN StopTask 19 IF Task(20).swit = %True THEN StopTask 20 IF Task(23).swit = %True THEN StopTask 23 'IF Task(%Listen_Task).swit = %True THEN StopTask %Listen_Task IF Task(30).swit = %True THEN StopTask 30 IF Task(27).swit = %True THEN StopTask 27 IF Task(29).swit = %True THEN StopTask 29 StopTask tasknr% tasknr% = %False ' reset EXIT SUB END SELECT ' IF ISFALSE Follow.lParam THEN ' ' this happens when the sequence to be recognized was effectively recognized within the timeslot. ' Follow.dwParam = %Null ' the parameter is switched off everytime ' ' a pattern was recognized. ' ' Follow.lParam being %NotFalse (-1), enables recognition of a next sequence. ' ELSE ' ' in this case, the player did not succeed in making the engine recognize his pattern... ' Follow.dwParam = wijzer ' ' so we pass the number of the next sequence to be recognized back to the recognition ' ' procedure (MelodyRecognize in GMT). This also resets the notecounter. ' END IF ' Follow.lParam = %NotFalse ' required to enable recognition IF gh.MelPat THEN DrawMelody gh.MelPat, wijzer,%Null INCR wijzer ELSE ClearMiBuf 0 ' 22.01.1999 added. END IF Task(tasknr%).freq = 2 + (1000 / App.komposduur) END SUB SUB CohibaPattern1 STATIC i%, tasknr% , toets% STATIC Melody() AS INTEGER LOCAL j% IF ISFALSE tasknr% THEN i% = 0 tasknr% = 32 toets% = %NotFalse DIM Melody (0 TO 23) Melody(0)= 65 : Melody(1)= 66: Melody(2)= 68: Melody(3)=71 Melody(4)= 72 : Melody(5)= 74: Melody(6)= 76: Melody(7)=66 Melody(8)= 65 : Melody(9)= 71: Melody(10)= 67: Melody(11)=74 Melody(12)=72 : Melody(13)=66: Melody(14)=76: Melody(15)=71 Melody(16)=65 : Melody(17) =74 : Melody(18)=67 : Melody(19)=66 Melody(20)= 72: Melody(21)=71: Melody(22)=76: Melody(23)=74 END IF IF ISTRUE toets% THEN mPlay Task(tasknr%).channel, Melody(i%), Task(tasknr%).level toets% = %False AddNote2Har Task(tasknr%).Har,Melody(i%), 127 ELSE mPlay Task(tasknr%).channel, Melody(i%), %False toets% = %NotFalse Task(tasknr%).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 END IF END SUB SUB CohibaPattern2 STATIC i%, tasknr% , toets% STATIC Melody() AS INTEGER LOCAL j% IF ISFALSE tasknr% THEN i% = 0 tasknr%= 33 toets% = %NotFalse DIM Melody (0 TO 23) Melody(0)= 65 : Melody(1)= 66: Melody(2)= 68: Melody(3)=71 Melody(4)= 72 : Melody(5)= 74: Melody(6)= 76: Melody(7)=66 Melody(8)= 65 : Melody(9)= 71: Melody(10)= 67: Melody(11)=74 Melody(12)=72 : Melody(13)=66: Melody(14)=76: Melody(15)=71 Melody(16)=65 : Melody(17) =74 : Melody(18)=67 : Melody(19)=66 Melody(20)= 72: Melody(21)=71: Melody(22)=76: Melody(23)=74 END IF IF ISTRUE toets% THEN mPlay Task(tasknr%).channel, Melody(i%), Task(tasknr%).level toets% = %False AddNote2Har Task(tasknr%).Har,Melody(i%), 127 ELSE mPlay Task(tasknr%).channel, Melody(i%), %False toets% = %NotFalse Task(tasknr%).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 END IF END SUB SUB CohibaStereo () LOCAL value AS WORD LOCAL param AS WORD ' sets proteus to stereo (all channels patched to main out) IF ISFALSE Task(62).tog THEN Task(62).tog = %True END IF value = %False FOR param = 416 TO 431 SysEx hMidiO(0), CHR$(&HF0,&H18,4,Meq(0).id,3,param MOD 128, param \ 128, value MOD 128, value\128, &HF7) NEXT param StopTask 62 END SUB SUB CohibaMultiChannel () LOCAL value AS WORD LOCAL param AS WORD ' sets proteus to 6-outputs: main, sub1 and sub2 such that we can use multiple loudspeakerconfigurations ' for cohiba. IF ISFALSE Task(63).tog THEN Task(63).tog = %True END IF ' settings for multichannel - 6 speakers: SELECT CASE TRIM$(UCASE$(Meq(0).naam)) CASE "PROTEUS2","PROTEUS2XR" value = %False FOR param = 416 TO 431 SysEx hMidiO(0), CHR$(&HF0,&H18,4,Meq(0).id,3,param MOD 128, param \ 128, value MOD 128, value\128, &HF7) INCR value value = value AND 3 IF value = 3 THEN value = %False NEXT param CASE "PROTEUS2000" value = %False FOR param = 0 TO 15 ' channels ' select channel: SysEx hMidiO(0), CHR$(&HF0,&H18,&H0F,Meq(0).id,&H55,129 MOD 128,129 \ 128,LOBYT(param),0, &HF7) ' multimode-mix output: SysEx hMidiO(0), CHR$(&HF0,&H18,&H0F,Meq(0).id,&H55, 133 MOD 128, 133 \ 128,LOBYT(value),0,&HF7) INCR value value = value AND 3 NEXT param CASE "PROCUSSION" value = %True FOR param = 0 TO 15 SysEx hMidiO(0), CHR$(&HF0,&H18,&H06,Meq(0).id,9,32+param,&B1100000 OR LOBYT(param),0, LOBYT(value), 0, &HF7) INCR value IF value > 8 THEN value = %True ' 0= OFF !!!, so we use 1-8 NEXT param END SELECT StopTask 63 END SUB SUB Flute_Listen () EXPORT LOCAL nv%, noot?, velo? STATIC oldnote AS BYTE IF ISFALSE Task(%Listen_Task).tog THEN oldnote = %False Task(%Listen_Task).tog = %True END IF nv% = GetMidiNote% (Task(%Listen_Task).channel, %Remove OR %Oldest) IF nv% = %NotFalse THEN EXIT SUB velo? = LOBYT (nv%) noot? = HIBYT (nv%) IF (noot? >= Flute.lowtes) AND (noot? <= Flute.hightes) THEN IF velo? > 0 THEN IF oldnote THEN DelNote2Har Task(%Listen_Task).Har, oldnote WriteDelayLine oldnote, %False GetLastNote oldnote, %False, Flute ' cfr. Lickstick, Woodstock END IF AddNote2Har Task(%Listen_Task).Har, noot?, velo? WriteDelayLine noot?, velo? GetLastNote noot?, velo?, Flute oldnote = noot? ELSE WriteDelayLine noot?, %False GetLastNote noot?, %False, Flute DelNote2Har Task(%Listen_Task).Har, noot? oldnote = %False END IF SetFluteContext noot?, velo? SetDlgItemText gh.Cockpit, %GMT_TEXT_TES,STR$(INT(Panatella.tes)) SetDlgItemText gh.Cockpit, %GMT_MSG1, "V=" & STR$(Panatella.vol) & " d=" & FORMAT$(Panatella.dens,"##.#") END IF END SUB SUB SetFluteContext (noot AS BYTE, velo AS BYTE) STATIC tog AS BYTE STATIC Cnt() AS BYTE STATIC oldwijzer AS DWORD LOCAL wijzer AS DWORD LOCAL nrevents AS LONG IF ISFALSE tog THEN Panatella.vol = 24 ' midi level Panatella.tes = 440 ' in Hz Panatella.dens = 0.5 ' in events/sec (Hz) Cohiba.vol = 24 Cohiba.tes = 440 Cohiba.dens = 0.5 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 Panatella.Vol = Panatella.Vol + Panatella.Vol + Panatella.Vol + velo SHIFT RIGHT Panatella.Vol, 2 Cohiba.vol = Panatella.Vol END IF ' ' bereken de gemiddelde tessituurligging van de input IF noot? THEN Panatella.tes = ((Panatella.tes * 3) + N2F(noot)) / 4 Cohiba.tes = Panatella.tes END IF ' calculate the density of the input over a timeframe of 255cs. ' The result is returned in WoodStock.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 Panatella.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. Cohiba.dens = Panatella.dens END SUB SUB PanatellaDoEvent () EXPORT STATIC tog AS LONG ' voorlopig zelfde invulling als voor cohiba. ' reacts on changes in the recognized sequence counter. ' called by its codepointer in Recog.cPtr. STATIC rcnt() AS DWORD IF ISFALSE tog THEN DIM rcnt(0 TO UBOUND(PatternSeq)) AS STATIC DWORD tog = %True END IF IF Recog.nr >=0 THEN INCR rcnt(Recog.nr) SELECT CASE Recog.nr CASE < %False EXIT SUB CASE 0 SELECT CASE rcnt(0) MOD 2 CASE 1 StartTask 22 ' normal inverted delay CASE 0 StopTask 22 END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 1 SELECT CASE rcnt(1) MOD 2 CASE 1 StartTask 23 ' slow inverted delay CASE 0 StopTask 23 END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 2 SELECT CASE rcnt(2) MOD 2 CASE 1 StartTask 24 ' fast inverted delay CASE 0 StopTask 24 END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 3 SELECT CASE rcnt(3) MOD 2 CASE 1 StartTask 25 ' normal inverted backwards delay StartTask 32 ' pattern 1 StartTask 33 ' pattern 2 CASE 0 StopTask 25 StopTask 32 StopTask 33 END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 4 SELECT CASE rcnt(4) MOD 2 CASE 1 StopTask 23 ' slow inverted delay OFF StopTask 33 ' stop pattern 2 CASE 0 StopTask 33 StartTask 29 ' backwards normal delay - panatella only END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 5 SELECT CASE rcnt(5) MOD 2 CASE 1 StopTask 22 ' normal inverted delay OFF StopTask 32 ' stop pattern 1 CASE 0 Stoptask 32 StartTask 23 ' slow inverted delay ON END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 6 SELECT CASE rcnt(6) MOD 2 CASE 1 StartTask 26 ' normal delay CASE 0 StopTask 26 END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 7 SELECT CASE rcnt(7) MOD 2 CASE 1 StopTask 26 ' normal delay OFF StartTask 27 ' slow delay CASE 0 StopTask 23 END SELECT PlayWavefile SampleList(Recog.nr), 0 CASE 8 SELECT CASE rcnt(8) MOD 3 CASE 1 StartTask 28 ' fast delay CASE 2 StartTask 30 CASE 0 StopTask 24 StopTask 28 StopTask 20 END SELECT PlayWavefile SampleList(Recog.nr), 0 ' following cases do not occur in panatella CASE 9 StartTask 29 ' backwards normal delay - used in case 4 PlayWavefile SampleList(Recog.nr), 0 CASE 10 StartTask 23 ' slow inverted delay ON - used in case 5 StartTask 30 ' detune - case 8 PlayWavefile SampleList(Recog.nr), 0 StopTask 24 ' fast inverted delay off StopTask 28 ' fast delay off StopTask 20 ' voice 4 off END SELECT END SUB SUB ButnSW_PanatellaStartStop () LOCAL buttonnr 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" IF hMidiI(0) THEN ClearMiBuf 0 ' start with a blank midi input buffer BlockSysExReception hMidiI(0) ' dll procedure END IF 'IF App.MTSpeedTasknr > -1 THEN StartTask App.MTSpeedTaskNr 'IF App.PromilTasknr > -1 THEN StartTask App.PromilTaskNr Promil %True 'IF App.RunTimeTaskNr > -1 THEN StartTask App.RunTimeTaskNr runtime %True IF App.GlobalHarmonyTasknr > -1 THEN StartTask App.GlobalHarmonyTasknr StartTask %Listen_Task '16 ' listen DrawAllPatterns gh.MelPat ELSE ' LOCAL buf$ LOCAL i AS LONG buf$= "!!!" + CHR$(13) FOR i = 16 TO 64 'All are 0 !!!!! buf$ = buf$ + STR$(i) + STR$(task(i).channel) + CHR$(13) NEXT MSGBOX buf$ ' App.MTstart = %False SetDlgItemText gh.Cockpit, %GMT_BUTNSW_ID + buttonnr, "CONT" 'IF App.PromilTasknr > -1 THEN StopTask App.PromilTaskNr Promil %False IF App.GlobalHarmonyTaskNr > -1 THEN StopTask App.GlobalHarmonyTasknr StopTask %Listen_Task '16 END IF App.ButnSWparam = %False END SUB SUB PanatellaPattern1 () STATIC i%, toets% STATIC tasknr AS INTEGER STATIC Melody() AS INTEGER STATIC stoptijd AS DWORD 'STATIC Initpattern AS BYTE LOCAL j% IF ISFALSE tasknr THEN i% = 0 tasknr = 32 toets% = %True DIM Melody (0 TO 12) FOR i% = 0 TO UBOUND(Melody) Melody(i%) = 65 NEXT i% END IF IF ISFALSE Task(tasknr).tog THEN toets% = %True Task(tasknr).tog = %True stoptijd = timeGetTime + 15000 ' 15 sec. max. END IF IF toets% THEN mPlay Task(tasknr).channel, Melody(i%), Panatella.vol OR 1 'Task(tasknr).level toets% = %False AddNote2Har Task(tasknr).Har,Melody(i%), Panatella.vol OR 1 ELSE NoteOff Task(tasknr).channel, Melody(i%) toets% = %True Task(tasknr).Har.vel = STRING$(128, 0) INCR i% IF i% > UBOUND(Melody) THEN i%= %False j% = RND(1) * UBOUND(Melody) IF LastNotePlayed <> Melody(j%) THEN Melody(j%)= LastNotePlayed IF TimeGetTime > stoptijd THEN Task(tasknr).tog = %False StopTask tasknr END IF END IF Task(tasknr).freq = Panatella.dens END SUB SUB PanatellaPattern2 () STATIC i%, toets% STATIC tasknr AS INTEGER STATIC Melody() AS INTEGER STATIC stoptijd AS DWORD LOCAL j% IF ISFALSE tasknr THEN tasknr%= 33 DIM Melody (0 TO 10) FOR i% = 0 TO UBOUND(Melody) Melody(i%)= 66 NEXT i% i% = %False END IF IF ISFALSE Task(tasknr).tog THEN toets% = %True Task(tasknr).tog = %True stoptijd = timeGetTime + 15000 ' 15 sec. max. END IF IF ISTRUE toets% THEN mPlay Task(tasknr).channel, Melody(i%), Panatella.vol OR 1 'Task(tasknr%).level toets% = %False AddNote2Har Task(tasknr).Har,Melody(i%), Panatella.vol OR 1 '127 ELSE NoteOff Task(tasknr).channel, Melody(i%) toets% = %True Task(tasknr).Har.vel = STRING$(128, 0) INCR i% j% = RND(1) * UBOUND(Melody) IF LastNotePlayed <> Melody(j%) THEN Melody(j%)= LastNotePlayed IF i% > UBOUND(Melody) THEN i% = %False IF timeGetTime > stoptijd THEN Task(tasknr).tog = %False StopTask tasknr END IF END IF Task(tasknr).freq = Panatella.dens END SUB #IF %DEF(%NiDaq) SUB Panatellapanning 'task - modulates panning of patterns, dependent on movement STATIC buf AS LONG STATIC oldbuf AS LONG STATIC tog AS LONG STATIC hdlg AS LONG STATIC verschil AS LONG LOCAL pan AS BYTE IF ISFALSE tog THEN buf = Databuf0(UBOUND(DataBuf0)) oldbuf = buf tog = %true END IF oldbuf =buf buf = Databuf0(UBOUND(DataBuf0)) verschil = (6 * verschil + ABS(buf - oldbuf)) / 7 ' pan = (verschil / 50) * 63 pan = verschil *.75 '/2 'check right scaling w/ flute ' MSGBOX STR$(pan) IF pan > 63 THEN pan = 63 CONTROL SET TEXT gh.cockpit, %GMT_MSG2, STR$(pan) task(32).pan = 64 - pan 'panatellapattern1 task(33).pan = 64 + pan ' 2 ModeMess Task(32).channel, 10, Task(32).pan ModeMess Task(33).channel, 10, Task(33).pan END SUB #ENDIF ' --- [EOF] ---