Dr.Godfried-Willem RAES
Kursus Experimentele Muziek: Boekdeel 1: Algoritmische Kompositie
Hogeschool Gent - Departement Muziek en Drama
<Terug naar inhoudstafel kursus>
Kontkont.bas demonstratieprogramma
Ranger.bas: een echolood als continuous controller
PulsePing.bas: een voorbeeld programma van Joachim Brackx
1122
Wie de midi-standaard goed heeft bestudeerd zal het al zijn opgevallen dat binnen deze standaard middels de byte sekwens
176+kanaal kontroller-nummer waarde-byte
heel wat parameters van daarvoor gevoelige midi-apparatuur kunnen worden bestuurd.
Omdat standaard midi-keyboards naast het toonwiel (dat overigens een andere -met name de pitch-bend 14-bit sekwens- kode opwekt) hooguit nog over een enkel 'modulation'-wheel beschikken, blijven deze mogelijkheden voor wie met standaard midi-apparatuur werkt veelal geheel onbenut.
Nochtans zijn het bij uitstek deze mogelijkheden die je muzikale rezultaten een persoonlijk karakter kunnen verlenen en, zijn uitgerekend in deze mogelijkheden werkelijke interaktiviteit vervat.
Om met kontinu-kontrollers te experimenteren, ontwikkelden we een klein testprogramma dat je toelaat via het komputerkeyboard allerlei real-time kontinu kontrole informatie uit te sturen. Mits kleine wijzigingen in het programma kan je eender welke reeks van 40 kontinue midi-kontrollers in real- time aansturen.
File: C:\bc7\kompos\KONTKONT.BAS
' *************************************************************************
' * Continuous Controller Test Utility *
' * KONTKONT.BAS *
' *************************************************************************
' This program needs and consists of following files:
' KONTKONT.BAS main module
' C:\bc7\bom\mpuuart.exe
' IPS33B.DOC - ascii documentation file
' TSR24.DOC - ascii documentation file
REM $INCLUDE: 'C:\bc7\kompos\IPS33B.DOC' :' dokumentatie ASCII-file
REM $INCLUDE: 'C:\bc7\kompos\TSR24.DOC'
REM $DYNAMIC
COMMON SHARED Noot%, mch%
COMMON SHARED kmap%()
COMMON SHARED amap%()
DECLARE SUB Uit (b%)
DECLARE SUB Progchanges ()
DECLARE SUB Noteonseq ()
DECLARE SUB Noteoffseq ()
DECLARE SUB keymap ()
CONST DP = &H330
'DP = &H320: ' voor logotronics interfaces
'DP = &H330: ' voor Roland MPU401 of MusicQuest in
UART-mode, or for Soundblaster interfaces
CLS
BEEP
IF DP = &H330 THEN SHELL "C:\bc7\bom\mpuuart.exe"
BEEP
DIM byte%(0 TO 127): ' continuous controller value
DIM oldbyte%(0 TO 127): ' previous CC-value
DIM controlmap%(0 TO 127): ' this program test maximum
40 controllers at the ' same time.
' The selected controllernumbers should be placed
' in this array
DIM SHARED kmap%(0 TO 80): ' index= controller-nummer
DIM SHARED amap%(0 TO 255): ' index= ascii-kode
keymap :' look-up table
Menu1:
CLS
LOCATE 5, 5: PRINT "Machine selection menu:";
LOCATE 7, 10: PRINT "1.- IPS33B - Digitech";
LOCATE 8, 10: PRINT "2.- TSR24 - Digitech";
LOCATE 9, 10: PRINT "3.- DHP55 - Digitech";
LOCATE 12, 10: PRINT "*.- QUIT";
DO
k$ = INKEY$
LOOP UNTIL k$ > ""
SELECT CASE k$
CASE "1"
machine$ = "IPS33B"
' set default start-up values:
FOR i% = 0 TO 126
controlmap%(i%) = i% + 1
' controllers 1 to 9 are used
NEXT i%
byte%(6) = 64: ' panning
byte%(7) = 127: ' master volume
'IPS33 basic midi channel:
mch% = 15
CASE "2"
machine$ = "TSR24"
FOR i% = 0 TO 127
controlmap%(i%) = i%
NEXT i%
mch% = 15
CASE "3"
machine$ = "DHP55"
FOR i% = 0 TO 127
controlmap%(i%) = i%
NEXT i%
mch% = 15
CASE "*"
END
CASE ELSE
GOTO Menu1
END SELECT
LOCATE 15, 10
PRINT "Controller numbers used will be:";
place% = 0
FOR i% = 0 TO 39
IF i% < 10 THEN
LOCATE 16 + (i% \ 10), 10 + place%:
PRINT controlmap%(i%)
place% = (place% + 5) MOD 50
ELSEIF i% < 20 THEN
LOCATE 16 + (i% \ 10), 10 + place% place% = (place% + 5) MOD 50
PRINT controlmap%(i%);
ELSEIF i% < 30 THEN
LOCATE 16 + (i% \ 10), 10 + place%
place% = (place% + 5) MOD 50
PRINT controlmap%(i%);
ELSEIF i% < 40 THEN
LOCATE 16 + (i% \ 10), 10 + place%
place% = (place% + 5) MOD 50
PRINT controlmap%(i%);
END IF
NEXT i%
LOCATE 21, 10
PRINT "The midi-channel used is"; mch%
SLEEP 10
' *************************************************************************
Explore:
CLS
LOCATE 25, 5
PRINT "LOGOSOFT - Dr.Godfried-Willem Raes -"; DATE$; "- Public
Domain";
LOCATE 24, 10
PRINT " |=program-change +=note-ON -=note-OFF <space>= QUIT ";
regel = 1
LOCATE regel, 10
PRINT "Midi Continuous Controller Real Time Exploration Utility";
regel = regel + 1
LOCATE regel, 10
PRINT "********************* "; machine$; " ************************";
regel = regel + 2
LOCATE regel, 10
PRINT "Controllers: (Upper-Case=UP ; Lower-case= DOWN) ";
regel = regel + 1
LOCATE regel, 1
PRINT "1/! 2/@ 3/# 4/$ 5/% 6/^ 7/& 8/* 9/( 0/)";
regel = regel + 1
IF machine$ = "IPS33B" THEN
LOCATE regel, 1: regel = regel + 1
PRINT "Expr1 Expr2 Expr3 Expr4 Expr5 Expr6 Expr7 midi cc midi cc";
LOCATE regel, 1: regel = regel + 1
PRINT "Pitch L Pitch R Delay L Delay R LRpan dry/wet volume regen regen
";
END IF
FOR i% = 0 TO 9
LOCATE regel, 1 + (i% * 8)
PRINT HEX$(176); controlmap%(i%);
NEXT i%
blok1 = regel + 1
regel = regel + 3
LOCATE regel, 1: regel = regel + 1
PRINT "Q/q W/w E/e R/r T/t Y/y U/u I/i O/o P/p";
FOR i% = 10 TO 19
LOCATE regel, 1 + ((i% - 10) * 8)
PRINT HEX$(176); controlmap%(i%);
NEXT i%
blok2 = regel + 1
regel = regel + 3
LOCATE regel, 1: regel = regel + 1
PRINT "A/a S/S D/d F/f G/g H/h J/j K/k L/l :/;";
FOR i% = 20 TO 29
LOCATE regel, 1 + ((i% - 20) * 8)
PRINT HEX$(176); controlmap%(i%);
NEXT i%
blok3 = regel + 1
regel = regel + 3
LOCATE regel, 1: regel = regel + 1
PRINT "Z/z X/x C/c V/v B/b N/n M/m </, >/. ?//";
FOR i% = 30 TO 39
LOCATE regel, 1 + ((i% - 30) * 8)
PRINT HEX$(176); controlmap%(i%);
NEXT i%
blok4 = regel + 1
'regel = regel + 3
' Flush keyboard-buffer:
DO: LOOP UNTIL INKEY$ = ""
' **********************************************************************
' interaktieve kontrole - display 40 real-time controller-values:
DO
FOR i% = 0 TO 9
LOCATE blok1, 1 + (i% * 8)
PRINT byte%(controlmap%(i%)); " ";
NEXT i%
FOR i% = 10 TO 19
LOCATE blok2, 1 + ((i% - 10) * 8)
PRINT byte%(controlmap%(i%)); " ";
NEXT i%
FOR i% = 20 TO 29
LOCATE blok3, 1 + ((i% - 20) * 8)
PRINT byte%(controlmap%(i%)); " ";
NEXT i%
FOR i% = 30 TO 39
LOCATE blok4, 1 + ((i% - 30) * 8)
PRINT byte%(controlmap%(i%)); " ";
NEXT i%
k$ = INKEY$
IF k$ <> "" THEN
toets% = ASC(k$): ' ascii-waarde van de ingedrukte toets
kode% = amap%(toets%): ' kodegetal 0-79 voor kontrollers
1-40
' 0= even - 1=oneven
IF kode% MOD 2 = 0 THEN value% = -1 ELSE value% = 1 abskont% = controlmap%(kode%
\ 2)
byte%(abskont%) = (byte%(abskont%) + value%)
' begrenzer:
IF byte%(abskont%) < 0 THEN byte%(abskont%) = 0
IF byte%(abskont%) > 127 THEN byte%(abskont%) = 127
IF machine$ = "IPS33B" THEN
IF abskont% = 8 OR abskont% = 9 THEN
' this limits the sum of both controllers to 100, as
needed
' when these controllers are assigned to the regenerate
Left
' and Right parameters.If not limited, overflow occurs
in the IPS33B
IF byte%(8) > 100 THEN byte%(8) = 100: byte%(9) = 0
IF byte%(9) > 100 THEN byte%(9) = 100: byte%(8) = 0
IF byte%(8) + byte%(9) > 100 THEN
IF byte%(8) >= byte%(9) THEN
DO
byte%(8) = byte%(8) - 1
LOOP UNTIL byte%(8) + byte%(9) <= 100
ELSE
DO
byte%(9) = byte%(9) - 1
LOOP UNTIL byte%(8) + byte%(9) <= 100
END IF
END IF
END IF
END IF
' Uitsturing wanneer bytes verschillend zijn van hun
vorige waarde:
IF machine$ = "IPS33B" THEN
' aangezien bij de IPS33B koppeling optreedt tussen de
diverse
' kontrollers dienen alle gewijzigde waarden te worden
opgespoord:
FOR i = 0 TO 120
IF byte%(controlmap%(i)) <> oldbyte%(controlmap%(i)) THEN
Uit (176 + mch%): Uit (i): Uit (byte%(controlmap%(i)))
oldbyte%(controlmap%(i)) = byte%(controlmap%(i))
END IF
NEXT i
ELSE
IF byte%(abskont%) <> oldbyte%(abskont%) THEN
Uit (176 + mch%): Uit (abskont%): Uit (byte%(abskont%))
oldbyte%(abskont%) = byte%(abskont%)
END IF
END IF
END IF
IF k$ = "|" THEN Progchanges
IF k$ = "+" THEN Noteonseq
IF k$ = "-" THEN Noteoffseq
IF k$ = " " THEN END
k$ = ""
LOOP
END
REM $STATIC
SUB keymap
' returns the filled array kmap%(0-79)
' look-up table for 40 keyboard-controller assignments
' in kommandovolgorde:
' eerste toetsenrij:
kmap%(0) = ASC("1"): ' dalend voor even
kmap%(1) = ASC("!"): ' stijgend voor oneven (shifted key)
kmap%(2) = ASC("2"): kmap%(3) = ASC("@")
kmap%(4) = ASC("3"): kmap%(5) = ASC("#")
kmap%(6) = ASC("4"): kmap%(7) = ASC("$")
kmap%(8) = ASC("5"): kmap%(9) = ASC("%")
kmap%(10) = ASC("6"): kmap%(11) = ASC("^")
kmap%(12) = ASC("7"): kmap%(13) = ASC("&")
kmap%(14) = ASC("8"): kmap%(15) = ASC("*")
kmap%(16) = ASC("9"): kmap%(17) = ASC("(")
kmap%(18) = ASC("0"): kmap%(19) = ASC(")")
' tweede toetsenrij:
kmap%(20) = ASC("q"): kmap%(21) = ASC("Q")
kmap%(22) = ASC("w"): kmap%(23) = ASC("W")
kmap%(24) = ASC("e"): kmap%(25) = ASC("E")
kmap%(26) = ASC("r"): kmap%(27) = ASC("R")
kmap%(28) = ASC("t"): kmap%(29) = ASC("T")
kmap%(30) = ASC("y"): kmap%(31) = ASC("Y")
kmap%(32) = ASC("u"): kmap%(33) = ASC("U")
kmap%(34) = ASC("i"): kmap%(35) = ASC("I")
kmap%(36) = ASC("o"): kmap%(37) = ASC("O")
kmap%(38) = ASC("p"): kmap%(39) = ASC("P")
' derde toetsenrij:
kmap%(40) = ASC("a"): kmap%(41) = ASC("A")
kmap%(42) = ASC("s"): kmap%(43) = ASC("S")
kmap%(44) = ASC("d"): kmap%(45) = ASC("D")
kmap%(46) = ASC("f"): kmap%(47) = ASC("F")
kmap%(48) = ASC("g"): kmap%(49) = ASC("G")
kmap%(50) = ASC("h"): kmap%(51) = ASC("H")
kmap%(52) = ASC("j"): kmap%(53) = ASC("J")
kmap%(54) = ASC("k"): kmap%(55) = ASC("K")
kmap%(56) = ASC("l"): kmap%(57) = ASC("L")
kmap%(58) = ASC(";"): kmap%(59) = ASC(":")
' vierde toetsenrij:
kmap%(60) = ASC("z"): kmap%(61) = ASC("Z")
kmap%(62) = ASC("x"): kmap%(63) = ASC("X")
kmap%(64) = ASC("c"): kmap%(65) = ASC("C")
kmap%(66) = ASC("v"): kmap%(67) = ASC("V")
kmap%(68) = ASC("b"): kmap%(69) = ASC("B")
kmap%(70) = ASC("n"): kmap%(71) = ASC("N")
kmap%(72) = ASC("m"): kmap%(73) = ASC("M")
kmap%(74) = ASC(","): kmap%(75) = ASC("<")
kmap%(76) = ASC("."): kmap%(77) = ASC(">")
kmap%(78) = ASC("/"): kmap%(79) = ASC("?")
' array in ascii-volgorde:
FOR i% = 0 TO 255
FOR j% = 0 TO 80
IF i% = kmap%(j%) THEN amap%(i%) = j%
NEXT j%
NEXT i%
END SUB
SUB Noteoffseq
Uit (144 + mch%): Uit (Noot%): Uit (0)
END SUB
SUB Noteonseq
Noot% = 24 + (RND(1) * 48)
Uit (144 + mch%): Uit (Noot%): Uit (127)
END SUB
SUB Progchanges
byte% = (RND(1) * 512) AND &H7F
Uit (192 + mch%): Uit (byte%)
END SUB
SUB Uit (b%)
IF DP = &H330 THEN
IF INP(&H331) AND 128 THEN
WAIT &H331, 64, 64: OUT DP, b%: EXIT SUB
ELSE
DO: dummy = INP(&H330): LOOP UNTIL INP(&H331) AND 128
WAIT &H331, 64, 64: OUT DP, b%: EXIT SUB
END IF
END IF
' Logotronics interfaces:
IF DP = &H2FA THEN
OUT &H2FA, b%: DO: LOOP UNTIL INP(&H2FB) AND 64: EXIT SUB
WHILE INP(&H2FB) < 64: WEND
END IF
IF DP = &H378 THEN
OUT &H378, b%: OUT &H37A, 0: ZZ# = ZZ# ^ ZZ#: OUT &H37A, 1
WHILE INP(&H379) AND 128: WEND
EXIT SUB
END IF
IF DP = &H320 THEN
' this is for Abulafia
OUT &H320, b%: OUT &H322, 0: ZZ# = TIMER + .00001
DO: LOOP UNTIL TIMER > ZZ#
OUT &H322, 1
WHILE INP(&H321) AND 128: WEND
EXIT SUB
ELSE
OUT DP, b%: OUT DP + 2, 0: T$ = "_": OUT DP + 2, 1
WHILE INP(DP + 1) AND 128: WEND
END IF
END SUB
Uitgaand van dit programma, is het niet erg moeilijk zelf een software- interface te schrijven dat zijn real-time input informatie nu eens niet betrekt uit manipulaties op het eerder beperkte komputerkeyboard, maar bvb. uit een reeks extern en via een ADC-kaart aan de komputer aangesloten sensoren.
Bijzonder geschikt daarvoor zijn o.m.:
- acceleratiemeters en transducers
- ultrasone bewegingsdetektoren
- mikrogolf-bewegingsdetektoren (radar) - piezoelektrische druktransducers
- potentiometers
- lichtgevoelige weerstanden
Meer informatie over de uitwerking van dergelijke projekten behoort echter tot het onderwerp van boekdeel 2, waar we ons uitvoerig met hardware en interaktiviteit gaan bezighouden.
Voor dit toepassingsvoorbeeld wordt uitgegaan van een als module op de markt verkrijgbare schakeling gepubliceerd in het amerikaanse elektronikatijdschrift Circuit Cellar. De bijhorende schemas en dokumentatie werden aan deze paragraaf toegevoegd. De praktische demonstratie van een en ander gebeurt in de les.
De software waarmee de schakeling als een midi-real-time controller kan worden gebruikt volgt hier:
' **************************************************************************
' * RANGER.BAS *
' * test-program for Ultrasonic Ranger *
' * to be used as a midi continuous controller *
' **************************************************************************
' Hardware conditions:
' - use Ciarcia's Circuit Cellar 50kHz Ultrasonic Ranging
System
' based on a Polaroid sensor device.
' - connect to parallel printer port. Only 3 bits are
used.
' - internal power supply: 5V dc - TTL compatible
' - meetbereik: 40cm - 10m Precizie: 2% (ca. 6-bits)
' - sampling rate: max. 12.5 s/s (recycle period= 80ms)
' - after switching on the Sonar-device, wait 5 milliseconds
' before sending the first INIT-command.
' - The pinning of the DIN-connector on SONAR-device
is:
' PIN 1 = + 5V (can be used to detect whether the device
is
' switched on
' PIN 2 = GROUND
' PIN 3 = NC
' PIN 4 = INIT (from computer to ranger)
' PIN 5 = ECHO (from ranger to computer)
' - The pinning on the DB25 printerconnector should be
as follows:
' PIN 1 = -Strobe: bit 0 &H37A WR not used
' PIN 2 = Data-bit 0 &H378 INIT (DIN-pin4)
' PIN 3 = Data-bit 1 &H378
' PIN 4 = Data-bit 2 &H378
' PIN 5 = Data-bit 3 &H378
' PIN 6 = Data-bit 4 &H378
' PIN 7 = Data-bit 5 &H378
' PIN 8 = Data-bit 6 &H378
' PIN 9 = Data-bit 7 &H378
' PIN 10= -Acknowledge: bit 6 &H379 RD
' PIN 11= Busy: bit 7 &H379 RD ECHO (DIN-pin5)
' PIN 12= Paper End: bit 5 &H379 RD
' PIN 13= Select: bit 4 &H379 RD +5V (DIN-pin1)
' Second Row:
' PIN 14=-Autofeed: bit 1 &H37A WR
' PIN 15=-Error bit 3 &H379 RD
' PIN 16=-Init Printer: bit 2 &H37A WR
' PIN 17=-Select Input: bit 3 &H37A WR
' PIN 18-25= GROUND GROUND (DIN-pin2)
' 07.08.1993: hardware build' 05.03.1995: first working
version
' hardware bugs removed. Cables checked.
' 06.03.1995: Timer - instructions removed
' They are not precize enough.
' Counter will be used instead.
' Time callibration routine should be written now
' 07.03.1995: Autocallibrating counter added
' Declaration of contants and variables:
CONST Wadr = &H378: ' use bit 0 as INIT-bit
CONST Radr = &H379: ' use bit 7 as echo databit
' use bit 4 to detect Sonar Device powered up.
' Omzettingskonstante:
' = geluidssnelheid/2 ( afstand= v.t/2 in sonar)
' 170 * 10 om uitkomst te hebben in decimeter
' 170 * 100 voor centimeter
' in teorie= 17000, maar deze waarde bleek onjuist
' een korrektiefaktor van 1.6 bleek nodig. Dus:
CONST Konst = 27200
CONST Inithigh = 1
CONST Initlow = 0
CONST Echo = 128
CONST Power = 16
CONST Channel = 0
CONST Cc = 176
COMMON SHARED Dist%, t#, timunit#, Delta%, Richting%
DECLARE SUB InitSonar ()
DECLARE SUB GetRange ()
DECLARE SUB Calibrate ()
DECLARE SUB Uit ()
' Initialisatie:
CP = INP(&H379)
DP = INP(&H378)
CLS
InitSonar
Calibrate
SHELL "C:\bc7\bom\MPUUART.EXE"
' Procedure:
LOCATE 14, 10
PRINT "Detected object is at a distance in centimeter of=";
LOCATE 15, 10
DO
GetRange
IF Dist% THEN
LOCATE 15, 10
PRINT Dist%; "cm", Delta%; "cm/s", Richting%;
byte% = (Dist% \ 2) AND &H7F
Uit (Cc + Channel): Uit (byte%)
END IF
SOUND 20000, 2
LOOP UNTIL INKEY$ <> ""
' Afsluiting:
LOCATE 18, 10PRINT " Reset printer-port on exit ? (Y/N)"
DO: k$ = INKEY$: LOOP UNTIL k$ <> ""
IF k$ = "Y" OR k$ = "y" THEN
' reset printerport to its original state:
LOCATE 19, 10
PRINT "Disconnect cable from ranging device now !";
SLEEP 20
OUT Wadr, DP
OUT Radr, CP
END IF
END
SUB Calibrate
ti# = TIMER
tt% = 0
DO: tt% = tt% + 1: LOOP UNTIL tt% = 32767
cnt# = TIMER - ti#
timunit# = (cnt# * Konst) / 32767#
END SUB
SUB GetRange
STATIC Olddist%
tt% = 0: ' reset time-counter
OUT Wadr, Inithigh: ' make INIT High. This enables the 420kHz
' oscillator and causes a transmit of 16
' cycles @ 300V - 49.4kHz
' The transducer holds a 150V dc bias, for receive.
' The osc. output steps to 93kHz and remains there as
' long as INIT stays high.
' DO : LOOP UNTIL (INP(Radr) AND Echo)
DO: tt% = tt% + 1: LOOP UNTIL (INP(Radr) XOR 255)
' Echo byte is inverted on printeradapter.
' Wait for echo. (When echo pulses high)
OUT Wadr, Initlow: ' make init low again.
Dist% = tt% * timunit#: ' read time-count value
' mits een konstante samplingfrekwentie (bv. 10 samples/s)
' kan ook de bewegingssnelheid in 1 dimensie worden afgeleid:
' Merk op dat de meetfout hier 2% * 2% = 4% beloopt,
en dat de snelheid ook
' een funktie is van de cosinus van de bewegingshoek
tegenover de rechte
' gevormd door de ultrasone golf!
IF Olddist% THEN
Delta% = Olddist% - Dist%
Richting% = SGN(Delta%)
Delta% = ABS(Delta%)
Olddist% = Dist%
ELSE
Olddist% = Dist%
END IF
END SUB
SUB InitSonar
OUT Wadr, Initlow
' check power-on:
IF INP(Radr) AND Power THEN SLEEP 1
ELSE
BEEP
LOCATE 10, 10:
PRINT "Sonar device unavailable or not powered on."
SLEEP 10
END
END IF
END SUB
SUB Uit
' hier komt de klassieke midi-uit procedure voor het
interface naar keuze
' Cfr. andere plaats in deze syllabus
END SUB
- Wanneer we de software note-on/note-off kommandos laten uitsturen verkrijgen we een goed bespeelbare, maar één-dimensionele, Theremin.
- Het opzet van de schakeling leent zich uitstekend voor toepassingen in het domein van het muziekteater. Hier kan bvb. het geluidsvolume of de panning automatisch in funktie worden gesteld van de plaats van een akteur of uitvoerder op de scene.
- Het voorbeeld zoals hier gegeven is in meer dan één opzicht eigenlijk een 'overkill'. Er wordt immers een enorme hoeveelheid komputerkracht verspild. Daarom zou het beter zijn in deze toepassing een klein dedicated system toe te passen, of zelfs, de counter in hardware uit te voeren. Zelf een eenvoudige 1-chip 'Basic-stamp' kan de hier gevergde taken makkelijk aan, wanneer althans geen direkte 31.5kBaud midi-output wordt verlangd. De Basic-stamp kan wel rechtstreeks een RS232 signaal afgeven aan 1200 of 2400 Baud, wat ruim volstaat.
Joachim Brackx schreef in 1995 een kleine algoritmische en interaktieve kompositie waarin van het hier beschreven echolood gebruik wordt gemaakt. De kode, waarin je veel procedures zult herkennen uit het vorige programma 'Ranger.bas', volgt hier:
< PULSE-PONG >
' 28.03.1995: Ranger routines used by Joachim Brackx
for composition program "Pulse-Pong"
' Declaration of contants and variables:
CONST Wadr = &H378: ' use bit 0 as INIT-bit
CONST Radr = &H379: ' use bit 7 as echo databit
CONST Konst = 27200
CONST Inithigh = 1
CONST Initlow = 0
CONST Echo = 128
CONST Power = 16
CONST Channel = 0
CONST Cc = 176
COMMON SHARED Dist%, t#, timunit#, Delta%, richting%COMMON SHARED Tc%
DECLARE SUB InitSonar ()
DECLARE SUB GetRange ()
DECLARE SUB Calibrate ()
DECLARE SUB Uit (Byte%)
DECLARE SUB AllOff (dd%)
DECLARE SUB InitProteus ()
DECLARE SUB VerGrond ()
DECLARE SUB mpuuart ()
' Initialisatie:
CP = INP(&H379): DP = INP(&H378) :CLS
InitSonar
Calibrate
mpuuart
InitProteus
SCREEN 12
' Procedure:
LOCATE 10, 8: PRINT "Dist% :"
LINE (0, 200)-(640, 200)
LINE (0, 250)-(640, 250)
FOR i = 1 TO 5
LINE (125 * i, 200)-(125 * i, 250)
NEXT i
OldPos = 100
Finish% = 0
AantInt% = 1
RANDOMIZE (TIMER)
Tc% = INT(RND(1) * 12) + 54
Flag% = 1
COLOR 9
LOCATE 5, 10: PRINT "Waiting..."
COLOR 15
DO
GetRange
SOUND 20000, 3
LOOP UNTIL Dist% < 200
COLOR 1
LOCATE 5, 10: PRINT "Playing..."
COLOR 15
DO
GetRange
IF Dist% > 260 THEN Dist% = 300
IF Dist% < 50 THEN Dist% = 50
IF Dist% <> 300 THEN
Detect% = 1
IF ODet% = 0 THEN DetFlag% = 1
ODet% = 1
X% = (Dist% - 50) * 2.56
LINE (OX%, 210)-(OX%, 240), 0
LINE (X%, 210)-(X%, 240): OX% = X%
ELSE
Detect% = 0
ODet% = 0
END IF
LOCATE 10, 15: PRINT Dist%; " "
LOCATE 20, 10: PRINT AantInt%
LOCATE 22, 10: PRINT Tc%
IF Detect% THEN
SELECT CASE Dist%
CASE 251 TO 280
Finish% = 1
CASE 201 TO 250
IF DetFlag% = 1 THEN VerGrond
DetFlag% = 0
State% = 4
CASE 151 TO 200
IF DetFlag% THEN
AantInt% = AantInt% + 1
IF AantInt% > 7 THEN AantInt% = 7
END IF
DetFlag% = 0
State% = 2
CASE 101 TO 150
'nothing
IF DetFlag% THEN
AantInt% = AantInt% - 1
IF AantInt% <= 0 THEN AantInt% = 1
END IF
DetFlag% = 0
State% = 2
CASE 50 TO 100
Par% = INT((Dist% - 50) * 2)
Uit (176): Uit (7): Uit (Par%)
Uit (178): Uit (7): Uit (100 - Par%)
State% = 1
END SELECT
END IF
IF OState% <> State% THEN PercFlag% = 1
OState% = State%
RANDOMIZE (TIMER)
qq# = .6 / AantInt%
zz# = RND(1) * qq#
tt# = TIMER
Note% = (Tc% + INT(RND(1) * AantInt%) * 7) MOD 12 + (INT(RND(1) * 5) + 3) *
12
Note2% = (Tc% MOD 12) + 36
Vel% = 127 - INT(zz# * 200)
Pan% = INT(RND(1) * 126) + 1
DO UNTIL TIMER >= tt# + zz#: LOOP
SOUND 20000, 2
Uit (128): Uit (ONote%): Uit (64)
Uit (130): Uit (ONote%): Uit (64)
Uit (176): Uit (10): Uit (Pan%)
Uit (178): Uit (10): Uit (127 - Pan%) Uit (144): Uit (Note%): Uit (Vel%): ONote%
= Note%
Uit (146): Uit (Note%): Uit (Vel%)
IF PercFlag% THEN
Uit (129): Uit (Onote2%): Uit (64)
Uit (145): Uit (Note2%): Uit (127): Onote2% = Note2%
PercFlag% = 0
END IF
LOOP UNTIL INKEY$ = CHR$(27) OR Finish% = 1
AantInt% = 7
COLOR 12
LOCATE 5, 10: PRINT "THE END..."
COLOR 15
DO
GetRange
LOCATE 10, 15: PRINT Dist%
IF Dist% <> 300 THEN
X% = (Dist% - 50) * 2.56
LINE (OX%, 210)-(OX%, 240), 0
LINE (X%, 210)-(X%, 240): OX% = X%
END IF
RANDOMIZE (TIMER)
qq# = .8 / AantInt%
zz# = RND(1) * qq#
tt# = TIMER
Note% = (Tc% + INT(RND(1) * AantInt%) * 7) MOD 12 + (INT(RND(1) * 5) + 3) *
12
Pan% = INT(RND(1) * 126) + 1
Vel% = AantInt% * 18
DO UNTIL TIMER >= tt# + zz#: LOOP
SOUND 20000, 2
Uit (128): Uit (ONote%): Uit (64)
Uit (130): Uit (ONote%): Uit (64)
Uit (176): Uit (10): Uit (Pan%)
Uit (178): Uit (10): Uit (127 - Pan%)
Uit (144): Uit (Note%): Uit (Vel%): ONote% = Note%
Uit (146): Uit (Note%): Uit (Vel%)
AantInt% = INT((Dist% - 50) / 35)
LOCATE 20, 10: PRINT AantInt%
LOOP UNTIL AantInt% = 0
AllOff (3)
CLS
' Afsluiting:
LOCATE 18, 10
PRINT " Reset printer-port on exit ? (Y/N)"
DO: k$ = INKEY$: LOOP UNTIL k$ <> ""
IF k$ = "Y" OR k$ = "y" THEN
' reset printerport to its original state:
LOCATE 19, 10
PRINT "Disconnect cable from ranging device now !";
SLEEP 20
OUT Wadr, DP
OUT Radr, CP
END IF
END
SUB AllOff (dd%)
FOR i = 1 TO dd%
FOR j = 1 TO 127
Uit (127 + i): Uit (j): Uit (64)
NEXT j
NEXT i
END SUB
SUB Calibrate
ti# = TIMER
tt% = 0
DO: tt% = tt% + 1: LOOP UNTIL tt% = 32767
cnt# = TIMER - ti#
timunit# = (cnt# * Konst) / 32767#
END SUB
SUB GetRange
STATIC Olddist%
tt% = 0: ' reset time-counter
OUT Wadr, Inithigh: ' make INIT High.
DO: tt% = tt% + 1: LOOP UNTIL (INP(Radr) XOR 255)
' Wait for echo. (When echo pulses high)
OUT Wadr, Initlow: ' make init low again.
Dist% = tt% * timunit#: ' read time-count value
IF Olddist% THEN
Delta% = Olddist% - Dist%
richting% = SGN(Delta%)
Delta% = ABS(Delta%)
Olddist% = Dist%
ELSE
Olddist% = Dist%
END IF
END SUB
SUB InitProteus
Uit (192): Uit (64)
Uit (193): Uit (51)
Uit (194): Uit (70)
Uit (176): Uit (7): Uit (100)
Uit (178): Uit (7): Uit (0)
END SUB
SUB InitSonar
OUT Wadr, Initlow
IF INP(Radr) AND Power THEN
SLEEP 1
ELSE
BEEP : LOCATE 10, 10:
PRINT "Sonar device unavailable or not powered on."
SLEEP 10 : END
END IF
END SUB
SUB mpuuart
' zie elders
END SUB
SUB VerGrond
RANDOMIZE (TIMER)
kans = INT(RND(1) * 5) + 1
SELECT CASE kans
CASE 1
RANDOMIZE (TIMER)
Tc% = INT(RND(1) * 12) + 54
CASE 2
Tc% = Tc% + 7
CASE 3
Tc% = Tc% - 7
CASE 4
Tc% = Tc% + 4
CASE 5
Tc% = Tc% - 4
END SELECT
END SUB
Terug naar de inhoudstafel: <
Index
Kursus>
Naar homepage
Dr.Godfried-Willem
RAES