'**************************************************************************** ' simulator code module * '**************************************************************************** ' 07.08.2001: separated from machine control module. #IF %DEF(%Klungsim) SUB ThunderSimSkin () STATIC stat AS LONG IF ISFALSE stat THEN CALL ThSetDefaultTekst stat = 1 StopTask 1 END IF END SUB SUB ThSetDefaultTekst () STATIC init AS LONG LOCAL tekst AS STRING tekst = CHR$(13) +CHR$(13) +"Click one of the buttons to select a piece." + CHR$(13)+CHR$(13)+CHR$(13) tekst = tekst + " 1. by Godfried-Willem Raes" + CHR$(13)+CHR$(13) tekst = tekst + " 2. by Kristof Lauwers"+ CHR$(13) + CHR$(13) tekst = tekst + REPEAT$(5, CHR$(13)) tekst = tekst + "If you have played one or more pieces, please submit your contribution by clicking the Submit button. If you're not connected to the internet you will be prompted to make a connection. This will also end " IF ISFALSE init THEN init = %true CONTROL ADD LABEL, gh.cockpit,%GMT_BUTNUSER_ID,tekst,4,2,206,270',%SS_SUNKEN ' CONTROL ADD LABEL, gh.cockpit,%GMT_BUTNUSER_ID,tekst,10,7,185,260 ELSE CONTROL SET TEXT gh.cockpit,%GMT_BUTNUSER_ID,tekst END IF END SUB SUB StartWoody () STATIC stat AS LONG LOCAL i AS LONG LOCAL tekst AS STRING IF ISFALSE stat THEN stat = 1 tekst = CHR$(13) + "Playing ," + CHR$(13)+ CHR$(13) + "a piece by Godfried-Willem Raes" 'two blank lines at top causes a crash here!! no idea why... tekst = tekst + REPEAT$(3, CHR$(13)) tekst = tekst + "Push the button again to stop" tekst = tekst + REPEAT$(3, CHR$(13)) tekst = tekst + "This piece presents all elements of thunderwood one by one."+CHR$(13) tekst = tekst + REPEAT$(13, CHR$(13)) tekst = tekst + "You can control the following parameters using the sliders:" + CHR$(13) + CHR$(13) tekst = tekst + "Maximum velocity:" + CHR$(13)+ CHR$(13) tekst = tekst + "Speed:" CONTROL SET TEXT gh.cockpit, %GMT_BUTNUSER_ID, tekst CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID + 1 ' CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID + 2 ' CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID + 3 StartTask %klungels ELSEIF stat = 1 THEN stat = 0 StopTask %woody ' #IF %DEF(%klungSim) StoreUserAction "[END WOODY]" ' #ENDIF FOR i = 0 TO 19 StopTask %klt + i NEXT CONTROL ENABLE gh.cockpit, %GMT_BUTNOS_ID + 1 'was disable CONTROL ENABLE gh.cockpit, %GMT_BUTNOS_ID + 10 ThSetDefaultTekst END IF END SUB SUB ThunderInitSim LOCAL i AS LONG ' ThunderWood.simulator = %True ' reorient pointers to simulation procedures... ' should also set tasks... Task(ThunderWood.thundertask).cPtr = CODEPTR(TW_Thunder_Task_sim) Task(Thunderwood.chimestask).cPtr = CODEPTR(TW_Chimes_Task_sim) Task(Thunderwood.raintask).cPtr = CODEPTR(TW_Rain_Task_sim) Task(Thunderwood.beattask(1)).cPtr = CODEPTR(PeckerLow_sim) Task(Thunderwood.beattask(2)).cPtr = CODEPTR(PeckerTenor_sim) Task(Thunderwood.beattask(3)).cPtr = CODEPTR(PeckerAlto_sim) Task(Thunderwood.beattask(4)).cPtr = CODEPTR(PeckerHigh_sim) Task(Thunderwood.windtask).cPtr = CODEPTR(WindSimu) Task(Thunderwood.ratchettask).cptr = CODEPTR(TW_Ratch_sim) Task(%woody).cptr = CODEPTR(Sim_Woody) Task(%woody + 1).cptr = CODEPTR(Sim_WoodStoch) IF KlungSimulatorMode = %klungSimWav THEN IF InitThunderWaves < 0 THEN MSGBOX "Sorry," + CHR$(13) + "The wave simulation has failed." + CHR$(13) + "We will use midi instead."+CHR$(13)+"Please select a midi out device from the ouput devices menu." KlungSimulatorMode = %klungSimMid ELSE StartWaveOutStream %AudioStreamCallBack END IF END IF Task(%woody).freq = 16 '32 '8 'keep 16 for sim 'we have a task for wind simulation. real wind doesn't need a task 'when simulation used, the speed param should be put in task.starttime 'we have to do this in the code of the piece the user can interact with (cfr windtest2 code), 'as TW_Wind is in the dll now, and doesn't support the simulations Task(ThunderWood.windtask ).naam = "windSimu" Task(ThunderWood.windtask ).level = 60 Task(ThunderWood.windtask ).channel = 6 Task(ThunderWood.windtask ).patch = 122 'seashore Task(ThunderWood.windtask ).duur = 20 ' = speed of motor > pitch 'Task(ThunderWood.windtask ).freq = 1 Task(ThunderWood.windtask ).cptr = CODEPTR(WindSimu) 'when the midisimuratchet is used, it uses this task to take care of sending the note off cmd Task(ThunderWood.Ratchettask ).naam = "simRatOff" Task(ThunderWood.Ratchettask ).channel = 9 Task(ThunderWood.Ratchettask ).patch = 72 Task(ThunderWood.Ratchettask ).freq = 4 Task(ThunderWood.Ratchettask ).cptr = CODEPTR(MidiRatchetOff) ' Task(%tht+9).naam = "debugger" ' task(%tht+9).freq = 1 ' Task(%tht+9).cptr = CODEPTR(TW_DEBUG) SELECT CASE KlungSimulatorMode CASE %klungSimMid FOR i = 3 TO 6 '= peckertasks ' Task(ThunderWood.thundertask+i).flags = Task(ThunderWood.thundertask+i).flags OR %MIDI_TASK ?? forgot it for the other tasks and it worked... Task(ThunderWood.thundertask+i).patch = 115 task(ThunderWood.thundertask+i).channel = 5 ProgChange task(ThunderWood.thundertask+i).channel, Task(ThunderWood.thundertask+i).patch'116 Task(ThunderWood.thundertask+i).pan = 127 - (127/(i-2)) NEXT ProgChange task(ThunderWood.thundertask).channel, task(ThunderWood.thundertask).patch ProgChange task(ThunderWood.chimestask).channel, task(ThunderWood.chimestask).patch Task(ThunderWood.windtask ).freq = 10 ProgChange task(ThunderWood.windtask ).channel, task(ThunderWood.windtask ).patch 'windsimu ProgChange task(ThunderWood.Ratchettask ).channel, task(ThunderWood.Ratchettask ).patch 'for ratchet CASE %klungSimWav Task(ThunderWood.windtask ).freq = 3.2 'windsimu END SELECT 'make a cockpit with only the possibility to choos a piece for people @ home... FOR i = 0 TO UBOUND(ButnOs) ButnOs(i).tag = "" NEXT FOR i = 0 TO UBOUND(ButnSw) ButnSw(i).tag0 = "" NEXT ButnOs(0).tag = "Woody" ButnOs(1).tag = "WoodStoch" ' ButnOs(2).tag = "Tango" ' ButnOs(3).tag = "???" ButnOs(10).tag = "Submit" ButnOs(0).cptr = CODEPTR(StartWoody) ButnOs(1).cptr = CODEPTR(StartWoodStoch) ' ButnOs(2).cptr = CODEPTR(StartTango) ' ButNos(3).cptr = CODEPTR(StartThomasPiece) ButnOs(10).cptr = CODEPTR(WSBSubmit) CONTROL DISABLE gh.Cockpit, %GMT_BUTNOS_ID + 10 FOR i = 0 TO %woody+1'%stochl CONTROL KILL gh.cockpit, %GMT_TASK0_ID + i NEXT task(1).cptr=CODEPTR(ThunderSimSkin) task(1).naam = "ThInSim" task(1).swit =%false' %true task(1).freq = 10 StartTask 1 END SUB FUNCTION InitThunderWaves () AS LONG 'prepare samples here in memory. needs some source samples... 'pointers to the static wavehdr structures are global LOCAL i AS DWORD LOCAL track AS LONG STATIC WindHdr AS WaveHdr STATIC RainHdr AS WaveHdr STATIC ThunderHdr AS WaveHdr STATIC ChimesHdr AS WaveHdr STATIC RatChetHdr AS WaveHdr STATIC Peckerhdr AS WaveHdr LOCAL SSize AS DWORD LOCAL peak AS DWORD 'wind Ssize = %CD_SR * 2 ' 1 second DIM wind(0 TO SSize) AS STATIC INTEGER WindHdr.dwBufferLength = (SSize + 1) * 2 WindHdr.lpData = VARPTR(wind(0)) pWindHdr = VARPTR(WindHdr) FOR i = LBOUND(wind) TO UBOUND(wind) IF UBOUND(wind) - i < 40000 THEN wind(i) = (RND(1) * (UBOUND(wind) - i)) / 4 ELSE IF peak < 40000 THEN peak = peak + 1 wind(i) = RND(1) * peak/4 END IF IF RND(1) >= 0.5 THEN wind(i) = - wind(i) NEXT ResizeAudioTrack track, %false ' MSGBOX "thsheet" ' 'thunder IF ISFALSE(ExistFile("ThSheet.wav")) THEN 'if sample not in main dir, copy from .\klung FILECOPY ".\thunde~1\ThSheet.wav", "ThSheet.wav" track = ReadWaveData("ThSheet.wav") KILL "ThSheet.wav" ELSE track = ReadWaveData("ThSheet.wav") END IF IF track < 0 THEN FUNCTION = -1 EXIT FUNCTION END IF SSize = (trackDuration(track) * 2*%CD_SR/1000) - 1 '(WavHdr(track).dwBufferlength \ 4)-1 DIM ThSheet(0 TO SSize) AS STATIC INTEGER ThunderHdr.dwBufferLength = WavHdr(track).dwBufferLength ThunderHdr.lpData = VARPTR(ThSheet(0)) pThunderHdr = VARPTR(ThunderHdr) POKE$ ThunderHdr.lpData, PEEK$(WavHdr(track).lpData, WavHdr(track).dwBufferLength) ResizeAudioTrack track, %false ' MSGBOX "rain" 'rain IF ISFALSE(ExistFile("raindrop.wav")) THEN 'if sample not in main dir, copy from .\klung FILECOPY ".\thunde~1\raindrop.wav", "raindrop.wav" track = ReadWaveData("raindrop.wav") KILL "raindrop.wav" ELSE track = ReadWaveData("raindrop.wav") END IF ' track = ReadWaveData("raindrop.wav") IF track < 0 THEN FUNCTION = -1 EXIT FUNCTION END IF SSize = (trackDuration(track) * 2*%CD_SR/1000) - 1 '(WavHdr(track).dwBufferlength \ 4)-1 DIM raindrop(0 TO SSize) AS STATIC INTEGER RainHdr.dwBufferLength = WavHdr(track).dwBufferLength RainHdr.lpData = VARPTR(raindrop(0)) pRainHdr = VARPTR(RainHdr) POKE$ RainHdr.lpData, PEEK$(WavHdr(track).lpData, WavHdr(track).dwBufferLength) ResizeAudioTrack track, %false ' MSGBOX "chimes" 'chimes IF ISFALSE(ExistFile("Chime.wav")) THEN 'if sample not in main dir, copy from .\klung FILECOPY ".\thunde~1\Chime.wav", "Chime.wav" track = ReadWaveData("chime.wav") KILL "chime.wav" ELSE track = ReadWaveData("chime.wav") END IF ' track = ReadWaveData("Chime.wav") IF track < 0 THEN FUNCTION = -1 EXIT FUNCTION END IF SSize = (trackDuration(track) * 2*%CD_SR/1000) - 1 '(WavHdr(track).dwBufferlength \ 4)-1 DIM chime(0 TO SSize) AS STATIC INTEGER ChimesHdr.dwBufferLength = WavHdr(track).dwBufferLength ChimesHdr.lpData = VARPTR(chime(0)) pChimesHdr = VARPTR(ChimesHdr) POKE$ ChimesHdr.lpData, PEEK$(WavHdr(track).lpData, WavHdr(track).dwBufferLength) ResizeAudioTrack track, %false ' MSGBOX "ratchet" 'ratchet IF ISFALSE(ExistFile("ratchet.wav")) THEN 'if sample not in main dir, copy from .\klung FILECOPY ".\thunde~1\ratchet.wav", "ratchet.wav" track = ReadWaveData("ratchet.wav") KILL "ratchet.wav" ELSE track = ReadWaveData("ratchet.wav") END IF IF track < 0 THEN FUNCTION = -1 EXIT FUNCTION END IF SSize = (trackDuration(track) * 2*%CD_SR/1000) - 1 '(WavHdr(track).dwBufferlength \ 4)-1 DIM ratchet(0 TO SSize) AS STATIC INTEGER RatchetHdr.dwBufferLength = WavHdr(track).dwBufferLength RatchetHdr.lpData = VARPTR(ratchet(0)) pRatchetHdr = VARPTR(RatchetHdr) POKE$ RatchetHdr.lpData, PEEK$(WavHdr(track).lpData, WavHdr(track).dwBufferLength) ResizeAudioTrack track, %false ' MSGBOX "pecker" 'pecker IF ISFALSE(ExistFile("peck.wav")) THEN 'if sample not in main dir, copy from .\klung FILECOPY ".\thunde~1\peck.wav", "peck.wav" track = ReadWaveData("peck.wav") KILL "peck.wav" ELSE track = ReadWaveData("peck.wav") END IF ' track = ReadWaveData("peck.wav") IF track < 0 THEN FUNCTION = -1 EXIT FUNCTION END IF SSize = (trackDuration(track) * 2*%CD_SR/1000) - 1 '(WavHdr(track).dwBufferlength \ 4)-1 DIM peck(0 TO SSize) AS STATIC INTEGER PeckerHdr.dwBufferLength = WavHdr(track).dwBufferLength PeckerHdr.lpData = VARPTR(peck(0)) pPeckerHdr = VARPTR(PeckerHdr) POKE$ PeckerHdr.lpData, PEEK$(WavHdr(track).lpData, WavHdr(track).dwBufferLength) ResizeAudioTrack track, %false FUNCTION = 1 END FUNCTION SUB MidiRatchetOff () STATIC tog AS LONG SELECT CASE tog CASE 0 INCR tog CASE 1 NoteOff Task(ThunderWood.Ratchettask).channel,74 tog = %false StopTask ThunderWood.Ratchettask END SELECT END SUB SUB WindSimu () 'task.duur for pitch 'use this task for simulation of wind sounds. this is the only simu that not works automaticly when the simu flag is set LOCAL track AS LONG LOCAL track2 AS LONG LOCAL fakt AS SINGLE STATIC tog AS DWORD STATIC oldnote1 AS LONG STATIC oldnote2 AS LONG IF task(ThunderWood.windtask ).level > 70 THEN task(ThunderWood.windtask).level = 70 ' ThunderLog STR$(task(ThunderWood.windtask ).level) IF KlungSimulatorMode = %KlungSimMid THEN IF task(ThunderWood.windtask).duur = %false THEN task(ThunderWood.windtask).tog = %false NoteOff Task(ThunderWood.windtask).channel, oldnote1 NoteOff Task(ThunderWood.windtask).channel, oldnote2 StopTask ThunderWood.windtask END IF 'we always have 2 overlapping notes for continuity SELECT CASE tog CASE 0 oldnote1 = Task(ThunderWood.windtask ).duur Play Task(ThunderWood.windtask ).channel, oldnote1, Task(ThunderWood.windtask ).level tog = 1 CASE 1 oldnote2 = Task(ThunderWood.windtask ).duur + 1 Play Task(ThunderWood.windtask ).channel,oldnote2 ,Task(ThunderWood.windtask ).level tog = 2 CASE 2 NoteOff Task(ThunderWood.windtask ).channel, oldnote1 oldnote1 = Task(ThunderWood.windtask ).duur Play Task(ThunderWood.windtask ).channel, oldnote1, Task(ThunderWood.windtask ).level tog = 3 CASE 3 NoteOff Task(ThunderWood.windtask ).channel, oldnote2 oldnote2 = Task(ThunderWood.windtask ).duur +1 Play Task(ThunderWood.windtask ).channel, oldnote2, Task(ThunderWood.windtask ).level tog = 2 END SELECT ELSEIF KlungSimulatorMode = %klungSimWav THEN fakt = 128/7 - task(ThunderWood.windtask ).duur / 7 IF fakt < .1 THEN fakt = .1 track = LPF(@pWindHdr, fakt ) IF track < 0 THEN EXIT SUB NormalizeWave WavHdr(track), 20 + task(ThunderWood.thundertask).level\6 PlayAudioTrack track, %MODULATE_VOLUME END IF END SUB SUB PeckerLow_sim () 'task that plays rolls on low woodblock 'all peckers limit their own frequency .1 > 25 'velo(task.level) values 1 - 127 remapped in TW_Woodpecker (dll) STATIC count AS LONG 'hammer counter LOCAL track AS LONG IF task(ThunderWood.beattask(1)).freq > 25 THEN task(ThunderWood.beattask(1)).freq = 25 IF task(ThunderWood.beattask(1)).freq < .1 THEN task(ThunderWood.beattask(1)).freq = .1 SELECT CASE KlungSimulatorMode CASE %klungSimMid NoteOff Task(ThunderWood.beattask(1)).channel, 55 Play Task(ThunderWood.beattask(1)).channel, 55, task(ThunderWood.beattask(1)).level CASE %klungSimWav track = GetFreeAudiotrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, WaveDuration(@pPeckerHdr) * 1.2 ' POKE$ WavHdr(track).lpData, PEEK$(@pPeckerHdr.lpData, WavHdr(track).dwBufferLength) VariSpeed @pPeckerHdr, WavHdr(track) StereoNormaliseWave WavHdr(track), 35 + task(ThunderWood.beattask(1)).level/2, 10 + task(ThunderWood.beattask(1)).level/2 ' NorMalizeWave WavHdr(track), 20 + task(ThunderWood.beattask(1)).level/3 PlayaudioTrack track, %MODULATE_VOLUME END SELECT END SUB SUB PeckerTenor_sim () STATIC count AS LONG 'hammer counter LOCAL i AS LONG LOCAL track AS LONG IF ISFALSE count THEN count = 6 IF task(ThunderWood.beattask(2)).freq > 25 THEN task(ThunderWood.beattask(2)).freq = 25 IF task(ThunderWood.beattask(2)).freq < .1 THEN task(ThunderWood.beattask(2)).freq = .1 SELECT CASE KlungSimulatorMode CASE %klungSimMid NoteOff Task(ThunderWood.beattask(2)).channel, 59 Play Task(ThunderWood.beattask(2)).channel, 59, task(ThunderWood.beattask(2)).level CASE %klungSimWav track = GetFreeAudiotrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, WaveDuration(@pPeckerHdr) * 1 ' POKE$ WavHdr(track).lpData, PEEK$(@pPeckerHdr.lpData, WavHdr(track).dwBufferLength) VariSpeed @pPeckerHdr, WavHdr(track) StereoNormaliseWave WavHdr(track), 25 + task(ThunderWood.beattask(2)).level/2, 10 + task(ThunderWood.beattask(2)).level/2 ' NorMalizeWave WavHdr(track), 20 + task(ThunderWood.beattask(2)).level/3 PlayaudioTrack track, %MODULATE_VOLUME END SELECT END SUB SUB PeckerAlto_sim () STATIC count AS LONG 'hammer counter LOCAL track AS LONG IF ISFALSE count THEN count = 10 IF task(ThunderWood.beattask(3)).freq > 25 THEN task(ThunderWood.beattask(3)).freq = 25 IF task(ThunderWood.beattask(3)).freq < .1 THEN task(ThunderWood.beattask(3)).freq = .1 SELECT CASE KlungSimulatorMode CASE %klungSimMid NoteOff Task(ThunderWood.beattask(3)).channel, 63 Play Task(ThunderWood.beattask(3)).channel, 63, task(ThunderWood.beattask(3)).level CASE %klungSimWav track = GetFreeAudiotrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, WaveDuration(@pPeckerHdr) * .78 ' POKE$ WavHdr(track).lpData, PEEK$(@pPeckerHdr.lpData, WavHdr(track).dwBufferLength) VariSpeed @pPeckerHdr, WavHdr(track) StereoNormaliseWave WavHdr(track), 15 + task(ThunderWood.beattask(3)).level/2, 20 + task(ThunderWood.beattask(3)).level/2 ' NorMalizeWave WavHdr(track), 20 + task(ThunderWood.beattask(3)).level/3 PlayaudioTrack track, %MODULATE_VOLUME END SELECT END SUB SUB PeckerHigh_sim () STATIC count AS LONG 'hammer counter LOCAL track AS LONG IF ISFALSE count THEN count = 13 IF task(ThunderWood.beattask(4)).freq > 25 THEN task(ThunderWood.beattask(4)).freq = 25 IF task(ThunderWood.beattask(4)).freq < .1 THEN task(ThunderWood.beattask(4)).freq = .1 SELECT CASE KlungSimulatorMode CASE %klungSimMid NoteOff Task(ThunderWood.beattask(4)).channel, 70 Play Task(ThunderWood.beattask(4)).channel, 70, task(ThunderWood.beattask(4)).level CASE %klungSimWav track = GetFreeAudiotrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, WaveDuration(@pPeckerHdr) * .7 ' POKE$ WavHdr(track).lpData, PEEK$(@pPeckerHdr.lpData, WavHdr(track).dwBufferLength) VariSpeed @pPeckerHdr, WavHdr(track) StereoNormaliseWave WavHdr(track), 5 + task(ThunderWood.beattask(4)).level/2, 30 + task(ThunderWood.beattask(4)).level/2 ' NorMalizeWave WavHdr(track), 20 + task(ThunderWood.beattask(4)).level/3 PlayaudioTrack track, %MODULATE_VOLUME END SELECT END SUB SUB TW_Ratch_sim (BYVAL velo AS DWORD) ' 1 - any , lbound trimmed to 25 LOCAL track AS LONG 'now one shot ratchet, for long rolls give large velo values ' this uses note on / note off !!! ' connected via 24V relais to midi note 15 output in the Thunderwood board ' The velo parameter just switches ON/OFF (0 switches the ratchet off, any other value switches it ON) ' cfr. ppHold code in DLL, with different port adress, since the ratchet is connected to the velo ports!!! ' This allows us to use only a single driver board for Thunderwood! ' kristof, wat doe je voor note-off hier ??? 'task ThunderWood.Ratchettask (= 'midiratchetoff) switches the midi ratchet off 'it has a tog to prevent it switching the note off @ starttask, 'so the note length is determined by its taskfreq. it switches itself of and resets its tog. ' MSGBOX "simumode" 'IF ISFALSE(velo) THEN EXIT SUB 'IF velo > 0 AND velo < 25 THEN velo = 25 'as a shorter ratch then 25 ms makes no sense SELECT CASE KlungSimulatorMode CASE %klungSimMid Play task(ThunderWood.Ratchettask ).channel,74, 100 IF velo > 0 THEN task(ThunderWood.Ratchettask ).freq = 1000/velo startTask ThunderWood.Ratchettask END IF CASE %klungSimWav track = GetFreeAudiotrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, WaveDuration(@pRatchetHdr) POKE$ WavHdr(track).lpData, PEEK$(@pRatchetHdr.lpData, WavHdr(track).dwBufferLength) IF velo < 25 THEN velo = 25 ResizeAudioTrack track, TrackDuration(track)*velo/127 PlayaudioTrack track, %MODULATE_VOLUME END SELECT END SUB SUB TW_Thunder_Task_sim () ' should use shaker task as in 'task.level (for velocity = pulse duration) should be ranged from 1 - 127 & is recomputed 'here to pulse... 'limits its own max frequency, ranging 0.1 - 20 ' since we map velo directly on the pulse duration in ms, the maximum velocity for single notes ' should be limited to 1000/freq ' LOCAL Mynote AS DWORD ' LOCAL pulse AS DWORD LOCAL track AS LONG STATIC midioldnote AS DWORD STATIC tog AS DWORD ' Mynote = 19 ' uses notes 19 and 20 IF KlungSimulatorMode = %klungSimWav THEN IF Task(ThunderWood.thundertask).freq > 5 THEN Task(ThunderWood.thundertask).freq = 5 '=max 2.5 beats/s ELSE IF Task(ThunderWood.thundertask).freq > 20 THEN Task(ThunderWood.thundertask).freq = 20 END IF IF Task(ThunderWood.thundertask).freq < .2 THEN task(ThunderWood.thundertask).freq = .2 'freq 0 = land of no return IF ISFALSE Task(ThunderWood.thundertask).level THEN EXIT SUB IF ISFALSE tog THEN SELECT CASE KlungSimulatorMode CASE %klungSimMid Noteoff task(ThunderWood.thundertask).channel, 14 'midioldnote ' midioldnote = INT(18 + RND * 4) Play task(ThunderWood.thundertask).channel, 14, task(ThunderWood.thundertask).level CASE %klungSimWav 'play only half as much in wavesimu END SELECT BIT SET tog,0 ELSE SELECT CASE KlungSimulatorMode CASE %klungSimMid 'we play only half as much notes in the midisimulation! CASE %klungSimWav track = GetFreeAudiotrack IF track < 0 THEN EXIT SUB ResizeAudiotrack track, WaveDuration(@pThunderHdr) POKE$ Wavhdr(track).lpData, PEEK$(@pThunderHdr.lpData, @pThunderHdr.dwBufferLength) NormalizeWave WavHdr(track), 50 + task(ThunderWood.thundertask).level/3 PlayAudioTrack track, %MODULATE_VOLUME END SELECT BIT RESET tog, 0 END IF END SUB SUB TW_Chimes_Task_sim () 'uses shaker tasks as in 'velocity values should be passed with values 1 - 127 'recomputed internally to pulse 'limits its own frequency, ranging 2 - 5.4 ' since we map velo directly on the pulse duration in ms, the maximum velocity for single notes ' should be limited to 1000/freq ' LOCAL Mynote AS DWORD LOCAL pulse AS DWORD LOCAL track AS LONG STATIC tog AS DWORD ' Mynote = 17 ' uses notes 17 and 18 IF Task(ThunderWood.chimestask).freq < .2 THEN task(ThunderWood.chimestask).freq = .2 IF Task(ThunderWood.chimestask).freq > 6 THEN task(ThunderWood.chimestask).freq = 6 IF ISFALSE Task(ThunderWood.chimestask).level THEN EXIT SUB IF ISFALSE tog THEN SELECT CASE KlungSimulatorMode CASE %klungSimMid Play task(ThunderWood.chimestask).channel, 58, Task(ThunderWood.chimestask).level CASE %klungSimWav track = GetFreeAudioTrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, WaveDuration(@pChimesHdr) POKE$ WavHdr(track).lpData, PEEK$(@pChimesHdr.lpData, WavHdr(track).dwBufferLength) 'keep it on half freq too NorMalizeWave WavHdr(track), 50 + Task(ThunderWood.chimestask).level/3 PlayAudioTrack track, %MODULATE_VOLUME END SELECT BIT SET tog,0 ELSE SELECT CASE KlungSimulatorMode CASE %klungSimMid NoteOff task(ThunderWood.chimestask).channel, 58 CASE %klungSimWav END SELECT BIT RESET tog, 0 END IF END SUB SUB TW_Rain_Task_sim () 'task duur = min task frequency 1-127, remapped here 'task.tempo = lbound of random frequencyamount 1-127 '?should we have frequency limits here ? 'task.level = max velo, values between 1 and level, range 1 - 127, scaled to pulse 'so we have values between starttime and (starttime + stoptime) LOCAL Mynote AS DWORD LOCAL midivelo AS DWORD LOCAL pulse AS DWORD LOCAL track AS LONG STATIC oldmidinote AS DWORD ' MyNote = 16 'reschedule random frequencie for evey call ' this requires random pulses with parametric density for a good rain sound. ' could use task if we reschedule continuously with different frequencies. ' here we do not need toggling between two notes ! ' The rain machine has two parameters: velo (reflecting volume) and density (reflecting spectrum) ' Power supply: 45Volts !!! (all notes 16 to 23) IF ISFALSE Task(ThunderWood.raintask).level THEN EXIT SUB END IF pulse = Task(ThunderWood.raintask).level / 5 '000830 we had a double remapping here !! see TW_rain in g_hard ' IF pulse > 25 THEN pulse = 25 Task(ThunderWood.raintask).freq = (task(ThunderWood.raintask).duur/10) + (4*RND(1) * task(ThunderWood.raintask).tempo) IF pulse > 900/task(ThunderWood.raintask).freq THEN pulse = 900/task(ThunderWood.raintask).freq '900: was 1000 for ms, for security ' Task(ThunderWood.raintask).freq = task(ThunderWood.raintask).duur '1'30 SELECT CASE KlungSimulatorMode CASE %klungSimMid IF oldmidinote THEN NoteOff task(ThunderWood.raintask).channel, oldmidinote oldmidinote = 83 + INT(RND * 15) midivelo = 25 + INT(RND * pulse * 4) 'INT(RND * task(ThunderWood.raintask).level * 5) 'IF midivelo > 127 THEN midivelo = 127 Play Task(ThunderWood.raintask).channel,oldmidinote, midivelo CASE %klungSimWav 'we still could use a better sample here... track = GetFreeAudioTrack IF track < 0 THEN EXIT SUB ResizeAudioTrack track, INT(WaveDuration(@pRainHdr) * (.5 + RND(1)/2)) variSpeed @pRainHdr, WavHdr(track) NormalizeWave WavHdr(track), 50 + pulse + INT(RND(1) * 25) PlayAudioTrack track, %MODULATE_VOLUME ' to do... END SELECT END SUB SUB Sim_Woody () 'piece for woodpecker STATIC low AS DWORD STATIC tenor AS DWORD STATIC alto AS DWORD STATIC high AS DWORD STATIC progr AS DWORD STATIC gCount AS DWORD 'general counter STATIC wind AS LONG 'switches: STATIC thunder AS LONG STATIC rain AS LONG STATIC chimes AS LONG STATIC sl0 AS LONG STATIC sl1 AS LONG IF ISFALSE task(%woody).tog THEN INCR task(%woody).tog gcount = %false wind = %false thunder = %false rain = %false chimes = %false progr = %false 'slider 0 for velo 'slider 1 for speed Slider(0).minval = 1 Slider(0).maxval = 127 Slider(0).stap = 1 Slider(0).value = 60'maxNr Slider(1).minval = 1 Slider(1).maxval = 127 Slider(1).stap = 1 Slider(1).value = 6.35*(task(%woody).freq - 5) '60 SendMessage Slider(0).h, %TBM_SETRANGE,%True, MakeLong(Slider(0).minval, Slider(0).maxval) SendMessage Slider(0).h, %TBM_SETPAGESIZE,0,Slider(0).stap SendMessage Slider(0).h, %TBM_SETPOS,%True, Slider(0).value SendMessage Slider(1).h, %TBM_SETRANGE,%True, MakeLong(Slider(1).minval, Slider(1).maxval) SendMessage Slider(1).h, %TBM_SETPOS,%True, Slider(1).value SetDlgItemText gh.Cockpit, %GMT_TITLE , "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR , $gwr IF KlungSimulatorMode = %klungSimMid THEN task(ThunderWood.beattask(1)).level = 90 task(ThunderWood.beattask(2)).level = 90 task(ThunderWood.beattask(3)).level = 90 task(ThunderWood.beattask(4)).level = 90 END IF sl0 = slider(0).value sl1 = slider(1).value StoreUserAction "[THUNDERWOOD]" StoreUserAction "[WOODY]" END IF IF sl0\10 <> Slider(0).value\10 THEN sl0 = slider(0).value StoreUserAction "VELO "+TRIM$(STR$(sl0)) END IF IF sl1\10<> Slider(1).value\10 THEN sl1 = Slider(1).value StoreUserAction "SPEED "+TRIM$(STR$(sl1)) END IF task(%woody).freq = 5 + Slider(1).value /6.35 ' remvd FOR dbg INCR gCount IF ISFALSE low THEN task(ThunderWood.beattask(1)).level = 100 * SIN(Pi*gcount/115)^2 '115 = 23 * 5> one cycle = 23 beats task(ThunderWood.beattask(1)).level = INT(task(ThunderWood.beattask(1)).level * Slider(0).value/127) IF task(ThunderWood.beattask(1)).level < 20 THEN task(ThunderWood.beattask(1)).level = 20 CALL DWORD task(Thunderwood.beattask(1)).cptr END IF IF ISFALSE tenor THEN task(ThunderWood.beattask(2)).level = 100 * SIN(Pi*gcount/203 )^2 ' 29 * 7> one cycle = 29 beats task(ThunderWood.beattask(2)).level = INT(task(ThunderWood.beattask(2)).level * Slider(0).value/127) IF task(ThunderWood.beattask(2)).level < 20 THEN task(ThunderWood.beattask(2)).level = 20 CALL DWORD task(Thunderwood.beattask(2)).cptr END IF IF ISFALSE alto THEN task(ThunderWood.beattask(3)).level = 100 * SIN(Pi*gcount/333)^2 ' 37 * 9> one cycle = 29 beats task(ThunderWood.beattask(3)).level = INT(task(ThunderWood.beattask(3)).level * Slider(0).value/127) IF task(ThunderWood.beattask(3)).level < 20 THEN task(ThunderWood.beattask(3)).level = 20 CALL DWORD task(Thunderwood.beattask(3)).cptr END IF IF ISFALSE high THEN task(ThunderWood.beattask(4)).level = 100 * SIN(Pi*gcount/451 )^2 ' 41 * 11> one cycle = 37 beats task(ThunderWood.beattask(4)).level = INT(task(ThunderWood.beattask(4)).level * Slider(0).value/127) IF task(ThunderWood.beattask(4)).level < 20 THEN task(ThunderWood.beattask(4)).level = 20 CALL DWORD task(Thunderwood.beattask(4)).cptr END IF IF (tenor + alto + high) = 0 THEN ' oldprogr = progr INCR progr SELECT CASE progr CASE 2 IF wind THEN EXIT SELECT 'start wind Wind = %true task(ThunderWood.windtask ).level = 60 task(ThunderWood.windtask ).duur = 5 StartTask ThunderWood.windtask CASE 3 'start thunder IF thunder THEN EXIT SELECT task(ThunderWood.thundertask).freq = 2 task(ThunderWood.thundertask).level = 100 StartTask ThunderWood.thundertask thunder = %true CASE 4 'start rain IF rain THEN EXIT SELECT task(ThunderWood.raintask).duur = 5 task(ThunderWood.raintask).tempo = 127 task(ThunderWood.raintask).level = 30 Rain = %true StartTask ThunderWood.raintask CASE 5 'chimes IF chimes THEN EXIT SELECT task(ThunderWood.chimestask).freq = 2 task(ThunderWood.chimestask).level = 1 chimes=%true StartTask ThunderWood.chimestask CASE 6 StopTask ThunderWood.thundertask StopTask ThunderWood.chimestask StopTask ThunderWood.raintask StopTask ThunderWood.beattask(1) StopTask ThunderWood.beattask(2) StopTask ThunderWood.beattask(3) StopTask ThunderWood.beattask(4) StopTask ThunderWood.windtask ' StopTask %woody StartWoody 'else continue current state... 'stop END SELECT END IF INCR low: INCR tenor: INCR alto: INCR high 'every x steps reset, on next step we play the note ' with gwr's original values, one cycle takes 468901 steps!... 'now we try w. smaller vals > now we still have 3465 steps IF low = 5 THEN low = %false 'was 19 '!! if we change those values we als have to adapt IF tenor = 7 THEN tenor = %false 'was 23 '!! the values who determin the volume cycles IF alto = 9 THEN alto = %false 'was 29 '! (c.s.) IF high = 11 THEN high = %false 'was 37 IF (low + tenor + alto = 0) OR (low + tenor + high = 0) OR _ (low + alto + high = 0) OR (tenor + alto + high = 0) THEN TW_Ratch task(ThunderWood.beattask(1)).level+task(ThunderWood.beattask(2)).level+task(ThunderWood.beattask(3)).level+task(ThunderWood.beattask(4)).level END IF 'experiment: IF gcount MOD INT(task(%woody).freq/3) THEN EXIT SUB 'we don't need to do the following that often... IF wind THEN ' put value in .duur field of windsimu task ( = note) task(ThunderWood.windtask ).duur = 127 * SIN(gcount/560 * Pi)^6 task(ThunderWood.windtask ).level = task(ThunderWood.windtask ).duur * Sl0\127 IF ISFALSE BIT(task(ThunderWood.windtask ).swit, %TASK_ONOFF) THEN StartTask ThunderWood.windtask ' ELSEIF BIT(task(ThunderWood.windtask ).swit, %TASK_ONOFF) THEN ' StopTask ThunderWood.windtask END IF END IF IF thunder THEN '3 min cycles task(ThunderWood.thundertask ).level = 100 * ABS(SIN(Pi*gcount/270*Pi )^2 * SIN(Pi*gcount/83)^2) ' 41 * 11> one cycle = 37 beats task(ThunderWood.thundertask).level = task(ThunderWood.thundertask).level*slider(0).value/127 task(ThunderWood.thundertask).freq = 1+ 5 * ABS(SIN(Pi*gcount/370 )^2 * SIN(Pi*gcount/83)^ 4) IF KlungSimulatorMode = %klungSimWav THEN task(ThunderWood.thundertask).freq = task(ThunderWood.thundertask).freq /2 END IF IF task(ThunderWood.thundertask).freq < 2 THEN IF BIT(task(ThunderWood.thundertask).swit, %TASK_ONOFF) THEN task(ThunderWood.thundertask).freq = 2 stoptask ThunderWood.thundertask END IF ELSE IF (ISFALSE BIT(task(ThunderWood.thundertask).swit, %TASK_ONOFF)) AND (task(ThunderWood.thundertask).level >=40) THEN StartTask ThunderWood.thundertask END IF ' EXIT SUB END IF IF rain THEN '5 min cycles task(ThunderWood.raintask).level = 100 * SIN(gcount/540 * Pi)^2 * SIN(Pi*gcount/197)^6 task(ThunderWood.raintask).level = INT(task(ThunderWood.raintask).level * Slider(0).value/127) IF task(ThunderWood.raintask).level < 20 THEN task(ThunderWood.raintask).level = 20 ' EXIT SUB END IF IF chimes THEN task(ThunderWood.chimestask).level =127 * SIN(gcount/68 *Pi)^2 * COS(Pi*gcount/221)^2 task(ThunderWood.chimestask).level = INT(task(ThunderWood.chimestask).level * Slider(0).value/127) task(ThunderWood.chimestask).freq = 2 + 2 * SIN(gcount/127)^2 * SIN(Pi*gcount/71)^2 ' EXIT SUB END IF END SUB FUNCTION WoodStochEnd() AS LONG task(%woody+1).pan = 1 'signal for the task to perform its end CONTROL DISABLE gh.cockpit,%GMT_TASK0_ID + 1 END FUNCTION SUB StartWoodStoch () STATIC stat AS LONG LOCAL i AS LONG LOCAL tekst AS STRING IF ISFALSE stat THEN stat = 1 tekst = CHR$(13) +CHR$(13) + "Playing ," + CHR$(13)+"a piece by Kristof Lauwers." tekst = tekst + REPEAT$(3, CHR$(13)) tekst = tekst + "Click the button again to stop" tekst = tekst + REPEAT$(3, CHR$(13)) tekst = tekst + "This is an organic algorythm that keeps itself going forever (or until you stop it). " tekst = tekst + "Every thunderwood element is assigned an energy level wich determines its speed and loudness. " tekst = tekst + "All elements are continuously exchanging energy. " tekst = tekst + "At the beginning there's not enough energy to make anything play. " tekst = tekst + "You have to boost the energy level of an element (see window on the right) to start the piece. " +CHR$(13) + CHR$(13) tekst = tekst + "If this sounds way too complicated, just click some buttons on the left to try it out." tekst = tekst + REPEAT$(6, CHR$(13)) tekst = tekst + "You can control the following parameters using the sliders:" + CHR$(13) + CHR$(13) tekst = tekst + "Average note velocity:" + CHR$(13)+ CHR$(13) tekst = tekst + "Average note Speed: " CONTROL SET TEXT gh.cockpit, %GMT_BUTNUSER_ID, tekst CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID CONTROL SET TEXT gh.cockpit, %GMT_BUTNUSER_ID, tekst CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID ' CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID + 2 ' CONTROL DISABLE gh.cockpit, %GMT_BUTNOS_ID + 3 #IF %DEF(%klungsim) StoreUserAction "[THUNDERWOOD]" StoreUserAction "[WOODSTOCH]" #ENDIF StartTask %woody+1 ELSEIF stat = 1 THEN stat = 2 'we should offer the posibility to resume the piece here... WoodStochEnd tekst = CHR$(13) + CHR$(13)+"Ending ..."+CHR$(13) CONTROL SET TEXT gh.cockpit, %GMT_BUTNUSER_ID, tekst ELSEIF stat = 2 THEN stat = 0 StopTask %Woody+1 #IF %DEF(%klungsim) StoreUserAction "[END WOODSTOCH]" #ENDIF StopTask %woody+1 FOR i = 0 TO 8 StopTask ThunderWood.thundertask+i NEXT CONTROL ENABLE gh.cockpit, %GMT_BUTNOS_ID 'was disable ' CONTROL ENABLE gh.cockpit, %GMT_BUTNOS_ID + 1 'CONTROL ENABLE gh.cockpit, %GMT_BUTNOS_ID + 3 CONTROL ENABLE gh.cockpit, %GMT_BUTNOS_ID + 10 CALL ThSetDefaultTekst END IF END SUB SUB Sim_WoodStoch () STATIC i AS LONG STATIC sl0 AS LONG STATIC sl1 AS LONG LOCAL j AS LONG LOCAL dummy AS SINGLE LOCAL tekst AS STRING STATIC InfLevel AS SINGLE 'level = infLevel * AME STATIC infFreq AS SINGLE STATIC infNeighb AS SINGLE 'influence to 'neighbour notes', defined as fourth u/d STATIC hoekLevel AS DOUBLE STATIC hoekFreq AS DOUBLE STATIC OnCount AS DWORD STATIC hDlgWS AS LONG STATIC density AS LONG LOCAL harm AS harmtype 'piece for thwood by kl 'each has an amount of energy wich influences the levl and tremolo speed 'if the AME is high enough, it is slowly passed to the notes one fifth higher / lower 'note: vvery low Meta_AME can have unexpected reults! IF ISFALSE task(%woody+1).tog THEN 'this tog is resetted when task is stopped by the user... task(%woody +1).pan = 0 ' pan = 1 for end of piece, tasknr of beatertask when the according button is clicked to raise energy level task(%woody+1).tog = %true FOR i = 0 TO 8 task(ThunderWood.thundertask+i).level = 0 task(ThunderWood.thundertask+i).freq = .1 NEXT density = 64 hoekLevel = 1 hoekFreq = 1.3' 2 infNeighb = .2 '1 ' .3 DIM AME(0 TO 8) AS STATIC DOUBLE 'amount of energy DIM HighCount(0 TO 8) AS STATIC DOUBLE IF Meta_AME_thunder =0 THEN Meta_AME_Thunder = 1 'set values that remain constant... task(ThunderWood.raintask).duur=64 task(ThunderWood.raintask).tempo=64 DIALOG NEW %HWND_DESKTOP,"WoodStoch parameter window",1,1,300,280 TO hDlgWS tekst ="This buttons represent the different elements of ."+CHR$(13) tekst=tekst+"Every element is assigned a different energy level, wich determines its speed and loudness. " tekst=tekst+"The energy levels are displayed on the buttons ." tekst = tekst + "If an elements energy level is too low to make the note sound, you can boost it by clicking its button. " tekst = tekst + "You can also randomize all energylevels. " CONTROL ADD LABEL, hDlgWS,-1,tekst, 10,10,280,50,%SS_SUNKEN'%SS_ETCHEDHORZ OR %SS_LEFT tekst = "thundersheet:" CONTROL ADD LABEL, hDlgWs,-1,tekst,10,70,60,16 CONTROL ADD BUTTON, hDlgWS, %GMT_BUTNUSER_ID+0,"0" ,80,70,19,16,%BS_NOTIFY CALL SBC3 tekst="chimes:" CONTROL ADD LABEL, hDlgWs,-1,tekst,10,90,60,16 CONTROL ADD BUTTON, hDlgWS, %GMT_BUTNUSER_ID+1, "0",80,90,19,16,%BS_NOTIFY CALL SBC3 tekst="rain:" CONTROL ADD LABEL, hDlgWs,-1,tekst,10,110,60,16 CONTROL ADD BUTTON, hDlgWs,%GMT_BUTNUSER_ID+2,"0",80,110,19,16, %BS_NOTIFY CALL SBC3 tekst="peckers:" CONTROL ADD LABEL, hDlgWs,-1, tekst,10,130,60,16 CONTROL ADD BUTTON, hDlgWs,%GMT_BUTNUSER_ID+3,"0",80,130,19,16, %BS_NOTIFY CALL SBC3 CONTROL ADD BUTTON, hDlgWs,%GMT_BUTNUSER_ID+4,"0",102,130,19,16, %BS_NOTIFY CALL SBC3 CONTROL ADD BUTTON, hDlgWs,%GMT_BUTNUSER_ID+5,"0",124,130,19,16, %BS_NOTIFY CALL SBC3 CONTROL ADD BUTTON, hDlgWs,%GMT_BUTNUSER_ID+6,"0",146, 130,19,16, %BS_NOTIFY CALL SBC3 tekst="wind:" CONTROL ADD LABEL, hDlgWs,-1,tekst,10,150,19,16 CONTROL ADD BUTTON, hDlgWs,%GMT_BUTNUSER_ID+7,"0",80,150,19,16, %BS_NOTIFY CALL SBC3 tekst="ratchet" CONTROL ADD LABEL, hDlgWs,-1, tekst,10,170,60,16 CONTROL ADD BUTTON,hDlgWs,%GMT_BUTNUSER_ID+8,"0",80,170,19,16, %BS_NOTIFY CALL SBC3 tekst = "Decrease energy levels" CONTROL ADD BUTTON, hDlgWs, %GMT_BUTNUSER_ID + 25, tekst, 10, 235,107,16, %BS_NOTIFY CALL SBC3 tekst = "Randomize energy levels" CONTROL ADD BUTTON, hDlgWS, %GMT_BUTNUSER_ID+26, tekst, 10, 255, 107,16,%BS_NOTIFY CALL SBC3 DIALOG SHOW MODELESS hDlgWS Slider(0).minval = 1 Slider(0).maxval = 100 Slider(0).stap = 1 Slider(0).value = 80'0.3 * 100 '127 * SIN(hoeklevel)^2'maxNr Slider(1).minval = 1 Slider(1).maxval = 100 Slider(1).value = 80'0.6 * 100'127 * SIN(HoekFreq)^2 'increment*10000 SendMessage Slider(0).h, %TBM_SETRANGE,%True, MakeLong(Slider(0).minval, Slider(0).maxval) SendMessage Slider(0).h, %TBM_SETPAGESIZE,0,Slider(0).stap SendMessage Slider(0).h, %TBM_SETPOS,%True, Slider(0).value SendMessage Slider(1).h, %TBM_SETRANGE,%True, MakeLong(Slider(1).minval, Slider(1).maxval) SendMessage Slider(1).h, %TBM_SETPOS,%True, Slider(1).value SetDlgItemText gh.Cockpit, %GMT_TITLE , "" SetDlgItemText gh.Cockpit, %GMT_AUTHOR , $krl END IF IF sl0<>Slider(0).value THEN sl0 = Slider(0).value StoreUserAction "VELO "+TRIM$(STR$(Slider(0).value)) END IF IF sl1<>Slider(1).value THEN sl1=Slider(1).value StoreUserAction "SPEED "+TRIM$(STR$(Slider(1).value)) END IF InfLevel = Meta_AME_Thunder * Slider(0).value / 100 InfFreq = Meta_AME_Thunder * Slider(1).value / 100 SELECT CASE task(%woody+1).pan 'holds value of button communication CASE ThunderWood.thundertask TO ThunderWood.thundertask+8 AME(task(%woody+1).pan - ThunderWood.thundertask) = .85 ' tekst = "50" CONTROL DISABLE hDlgWS, %GMT_BUTNUSER_ID + task(%woody+1).pan - ThunderWood.thundertask task(task(%woody+1).pan).duur = %false task(%woody+1).pan = %false IF Density < 127 THEN INCR density StoreUserAction "DENSITY "+TRIM$(STR$(density)) CASE %tht + 24 'increase overal energy level task(%woody+1).pan = %false FOR j = 0 TO 8 AME(j) = AME(j) + .1 IF AME(j) > 1 THEN AME(j) = 1 NEXT IF Density < 117 THEN Density = Density + 10 StoreUserAction "DENSITY "+TRIM$(STR$(density)) CASE %tht + 25 'decrease overal energy level ' MSGBOX "decr" task(%woody+1).pan = %false FOR j = 0 TO 8 AME(j) = AME(j) - .1 IF AME(j) < 0 THEN AME(j) = 0 NEXT IF Density > 10 THEN Density = Density - 10 StoreUserAction "DENSITY "+TRIM$(STR$(density)) CASE %tht + 26 'randomize energy levels task(%woody+1).pan = %false FOR j = 0 TO 8 AME(j) = RND(1) ^6 IF AME(j) < 0 THEN AME(j) = 0 '??! NEXT CASE 1 'end of piece FOR j = 0 TO 8 AME(j) = AME(j) * .9 NEXT ARRAY SCAN AME(), >.1, TO j IF ISFALSE j THEN 'end stochrung DIALOG SHOW STATE hDlgWS, %SW_HIDE DIALOG END hDlgWS FOR j = 0 TO 7 'sic StopTask ThunderWood.thundertask+j NEXT StartWoodStoch END IF CASE ELSE task(%woody+1).pan = %false END SELECT FOR j = 0 TO 8 tekst = TRIM$(STR$(INT(AME(j)*100))) CONTROL SET TEXT hDlgWS, %GMT_BUTNUSER_ID + j,tekst IF (127 * AME(j) * infLevel < 5) AND (ISFALSE task(ThunderWood.thundertask+j).duur) THEN 'was AME(i)<.2 and task(ThunderWood.thundertask+j).duur = 1 CONTROL ENABLE hDlgWS, %GMT_BUTNUSER_ID + j ELSEIF (127 * AME(j) * infLevel>5) AND task(ThunderWood.thundertask+j).duur THEN task(ThunderWood.thundertask+j).duur = 0 CONTROL DISABLE hDlgWS, %GMT_BUTNUSER_ID + j END IF NEXT INCR i IF i >8 THEN i = 0 '-1 END IF IF i=8 THEN IF AME(i) > Meta_AME_thunder * .1 THEN TW_RATCH INT(AME(i)*127*inflevel) ELSE task(ThunderWood.thundertask+i).level = INT( (2 * task(ThunderWood.thundertask+i).level + (127 * AME(i) * infLevel)) / 3) IF i<> 2 THEN task(ThunderWood.thundertask+i).freq = (4 * task(ThunderWood.thundertask+i).freq + (.1 + 6 * AME(i) * infFreq)) / 5 IF i = 0 THEN task(ThunderWood.thundertask).freq=task(ThunderWood.thundertask).freq/3 'for thundersheet IF i=2 THEN task(ThunderWood.thundertask+i).duur = (INT(127*AME(i)*infFreq)) 'for rain IF (task(ThunderWood.thundertask+i).level > 3) THEN IF ISFALSE BIT (task(ThunderWood.thundertask+i).swit,%TASK_ONOFF) THEN StartTask ThunderWood.thundertask+i : EXIT SUB ELSEIF BIT(task(ThunderWood.thundertask+i).swit, %TASK_ONOFF) THEN StopTask ThunderWood.thundertask+i END IF END IF j = i - 1 DO WHILE j < 0: j = j + 7: LOOP AME(j) = AME(j) + AME(i) * (infNeighb / (2*task(%woody+1).freq)) j = i + 1 DO WHILE j > 8: j = j - 7: LOOP AME(j) = AME(j) + AME(i) * (infNeighb / (2*task(%woody+1).freq)) AME(i) = AME(i) - AME(i) * (infNeighb / task(%woody+1).freq) IF AME(i) < .3 THEN AME(j) = AME(j) + AME(i) 'last bit passed at once.. AME(i) = 0 StopTask ThunderWood.thundertask+i END IF FOR j = 0 TO 8 IF AME(j) > Meta_AME_Thunder THEN AME(j) = 0 'too much energy is deadly... the energy is spread over all klungs, and a little bit is lost END IF NEXT 'high energy's grow automaticly IF AME(i)>.5 THEN AME(i) = AME(i)* 1.09 OnCount = %false FOR j = 0 TO 8 IF AME(j)> .25 THEN INCR Oncount NEXT IF OnCount > 3 THEN ' if too much are playing the highest ae killed FOR j = 0 TO 8 IF AME(j)>.4 THEN AME(j) = %false ELSEIF AME(j)<.2 THEN AME(j)=.8 END IF NEXT END IF IF AME(i) > Meta_AME_Thunder/3 THEN 'if energy is high for a long time, we're getting tired... INCR HighCount(i) IF HighCount(i) > 4 THEN AME(i) = AME(i) - .05 END IF IF AME(i) > Meta_AME_Thunder THEN AME(i) = Meta_AME_Thunder ELSE IF AME(i) < 0 THEN AME(i) = 0 IF HighCount(i) THEN DECR highCount(i) END IF END SUB CALLBACK FUNCTION SBC3 AS LONG IF CBCTLMSG <> %BN_CLICKED THEN EXIT FUNCTION IF ISFALSE task(%Woody+1).pan THEN task(%woody+1).pan = ThunderWood.thundertask + CBCTL - 600 END FUNCTION #ENDIF