De Amerikaanse komponist Alvin LUCIER , een van de pioniers van de live- elektronische muziek, schreef in 1982-84 het stuk "CROSSINGS" voor klein orkest en 'slow-sweep pure wave oscillator'. Met 'pure-wave oscillator' wordt hier een sinus-generator bedoeld. Sinus-tonen hebben immers geen harmonisch spektrum en gelden daarom als 'pure' , nml. uitsluitend een grondtoon omvattend. De partituur werd gepubliceerd door het muziektijdschrift "SOUNDINGS", nummer 14/15 (1986), in Santa Fe, New Mexico USA.
De elektronische partij in dit stuk lijkt uiterst eenvoudig op het eerste gezicht. Het is immers niets meer dan een heel erg trage stijgende glissando van 25Hz tot ca.4500 Hz. Het voorgeschreven tempo is 2 minuten per oktaaf. De bezwaren tegen het manueel uitvoeren van dit soort brede glissandi met behulp van analoge oscillatoren zijn ook hier weer :
Opnieuw ligt het dus voor de hand een komputer in te zetten voor de uitvoering. Dit levert overigens ook een bijkomend voordeel op, immers de voorgeschreven frekwentiemeter in de partituur, die als dirigent voor de musici moet fungeren, kan hier samen met de video-installatie vervallen, omdat we de gespeelde frekwentie rechtstreeks door de komputer naar het scherm kunnen laten schrijven.
De requisietenlijst voor uitvoering van dit stuk komt er dan uit te zien alsvolgt:
Het programma dat hiervoor werd ontwikkeld ziet er dan zo uit:
'CROSSINGS - very slow rising sine wave: last update 06.05.89
'Eerst worden de te gebruiken subprogrammas aangegeven, samen met de
'erdoor over te dragen variabelen
DECLARE SUB INITFB01 (VOLUME%, BEND%, SH%, N$)
DECLARE SUB SCHERM (N$)
DECLARE SUB TIMTST (BEND%, SH%)
CLS : DEFINT A-Z: N$ = "CROSSINGS"
'&H378=dataport - &H379 is controllreadport -&H37A=strobe op T1000-prn
SH = INP(&H37A): '= high strobe situation .
'het schermopmaak-subprogramma wordt opgeroepen
CALL SCHERM(N$)
'het initialisatieprogramma voor de Yamaha FB01 wordt opgeroepen
CALL INITFB01(VOLUME%, BEND%, SH%, N$)
'volgend stukje programma laat de komputer zelf nagaan of de afspeelsnelheid
'der glissando's voldoet aan de voorwaarde van de partituur - 2 min per oktaaf
MEAS:
K$ = ""
LOCATE 10, 10
PRINT " Should I calculate the duration and adjust BEND-value accordingly ? "; WHILE K$ = "": K$ = INKEY$: WEND
IF K$ = "Y" OR K$ = "y" THEN
LOCATE 10, 10
PRINT " WAIT !!! Measuring time required to play one octave glissando ... ";
'het nu opgeroepen subprogramma test de snelheid en past BEND aan indien nodig
CALL TIMTST(BEND%, SH%)
LOCATE 10, 10
PRINT " Is this value O.K.? (push any key) - Faster? (+) - Slower? (-) ";
K$ = "": WHILE K$ = "": K$ = INKEY$: WEND
IF K$ = "-" THEN BEND = BEND - 1
IF K$ = "+" THEN BEND = BEND + 1
ELSE
LOCATE 10, 10
PRINT " ";
END IF
N$ = ""
'de aangepaste waarde van BEND gaat terug via het subprogramma naar de FB01
CALL INITFB01(VOLUME%, BEND%, SH%, N$)
START:
'ingave begin en eindnoot van de te spelen glissando
LOCATE 10, 10: PRINT " ";
LOCATE 10, 10: PRINT " Midi-Code start-note of glissando ? (20) "; : INPUT BEGINNOT
LOCATE 10, 10: PRINT " ";
LOCATE 10, 10: PRINT " Midi-Code last note of glissando ? (96)"; : INPUT EINDNOT
LOCATE 10, 10: PRINT " ";
'start van de eigenlijke uitvoering
LOCATE 10, 10: PRINT " Druk een toets om de glissando te doen starten ... ";
K$="" : WHILE K$="" : K$=INKEY$ : WEND
LOCATE 10, 10
PRINT " ";
LOCATE 10, 10
PRINT " Playing glissando from "; BEGINNOT; " to "; EINDNOT; " ";
LOCATE 12, 10
PRINT " Starttijd :"; TIME$;
STARTTIJD# = TIMER
LOCATE 15, 10: PRINT " Frekwentie = Herz ";
GOSUB GLISSANDO
END IF
EINDE:
STOPTIJD# = TIMER
DUUR% = STOPTIJD# - STARTTIJD#: DURMIN = DUUR% \ 60: DURSEC = DUUR% MOD 60
GOSUB ALLOFF
LOCATE 10, 10
PRINT " ";
LOCATE 12, 40
PRINT "Eindtijd:"; TIME$; " Duur:"; DURMIN; "'"; DURSEC; "s";
LOCATE 23, 10
PRINT " E I N D E "
END
'MIDI -stuurroutines - glissando wordt gespeeld via pitch-bend
GLISSANDO:
STP = 1
IF BEGINNOT < EINDNOT THEN
FOR NT = BEGINNOT TO EINDNOT STEP BEND
B = 144: GOSUB SD
B = NT: GOSUB SD
B = 127: GOSUB SD
FOR MSB = 64 TO 127
FOR LSB = 0 TO 127 STEP STP
GOSUB RTC
B = 224: GOSUB SD
B = LSB: GOSUB SD
B = MSB: GOSUB SD
NEXT LSB
'volgende formule zet de pitchbend-waarde om in CENTS
C% = ((127 + ((MSB - 64) * 128)) * BEND / 81.92)
'volgende formule zet de CENTS waarde en de MIDI-noot NT om in FREKWENTIE
F% = (16.352 * (2 ^ ((((NT - 12) * 100) + C%) / 1200))) * 10
LOCATE 15, 22
PRINT F / 10; " ";
NEXT MSB
NEXT NT
ELSE
SWAP EINDNOT, BEGINNOT: GOTO GLISSANDO
END IF
RETURN
ALLOFF:
'maakt decrescendo aan het einde en schakelt alles uit
FOR I = VOLUME TO 0 STEP -1: B = 176: GOSUB SD
B = &H7: GOSUB SD
B = I: GOSUB SD
SOUND 25000, 2: NEXT I
HOLDON:
B = 176: GOSUB SD
B = &H7B: GOSUB SD
B = 0: GOSUB SD
RETURN
RTC:
'deze subroutine laat toe manueel in real-time de afspeelsnelheid te
'vergroten of te verkleinen via de + en - toetsen.
'ook onderbreken kan via *
K$ = INKEY$: IF K$ = "" THEN RETURN
IF K$ = "+" THEN STP = STP + 1
IF K$ = "-" THEN STP = STP - 1
IF STP < 2 THEN STP = 1
IF STP > 127 THEN STP = 127
IF K$ = "*" THEN GOTO EINDE
IF K$ = " " THEN GOSUB HOLDON
IF K$ = " " THEN GOTO START
RETURN
'dit is de midi-stuurroutine voor de Toshiba en andere IBM-klonen
SD: OUT &H378, B: OUT &H37A, (SH OR 1): Z$ = "_": OUT &H37A, SH
WHILE INP(&H379) AND 128 = 0: WEND: RETURN
'hierna volgen nu de listings van de drie gebruikte subprogrammas:
SUB INITFB01 (VOLUME%, BEND%, SH%, N$) STATIC:
IF N$ <> "" THEN
LOCATE 10, 10
INPUT "Set output-level sine-wave (1-127) ?", VOLUME: GOSUB BLANK
VOLUME = VOLUME MOD 128
IF VOLUME < 1 THEN VOLUME = 64
BANK = 6: ' this bank contains sine-wave
VOICE = 47: ' this selects sine-wave
LOCATE 10, 10
INPUT "Set Configuration to nr.0-16 ?", CONFIG: GOSUB BLANK
CONFIG = CONFIG MOD 17
IF CONFIG < 1 THEN CONFIG = 0
PORTIME = 0
LOCATE 10, 10: INPUT "Set Pitch-bend range ( 2 !) ?", BEND: GOSUB BLANK
'sys-ex volgens configuration data-format &H00-&H9F - routine sysex3
PARAMETER = &H21: GEGEVENS = 0: GOSUB SYSEX3: ' memory protect OFF
PARAMETER = &H20: GEGEVENS = 0: GOSUB SYSEX3: ' set midi channel to 0
PARAMETER = &H22: GEGEVENS = CONFIG: GOSUB SYSEX3: ' configuration number
PARAMETER = &H24: GEGEVENS = VOLUME: GOSUB SYSEX3: ' volume master
'stuur titel kompositie naar display van de FB01
GOSUB CHRARRAY
FOR I = 0 TO 7: PARAMETER = I: GEGEVENS = C(I): GOSUB SYSEX3: NEXT I
ERASE C:
PARAMETER = 8: GEGEVENS = 1: GOSUB SYSEX3: 'combine mode=ON
PARAMETER = 9: GEGEVENS = 1: GOSUB SYSEX3: 'LFO-speed
PARAMETER = 10: GEGEVENS = 127: GOSUB SYSEX3: 'amd (1-127)
PARAMETER = 11: GEGEVENS = 127: GOSUB SYSEX3: 'pmd (1-127)
PARAMETER = 12: GEGEVENS = 0: GOSUB SYSEX3: 'LFO-waveform (0-3)
PARAMETER = 13: GEGEVENS = 0: GOSUB SYSEX3: 'KC#reception mode 0=all
'sys-ex volgens parameterchange by MIDI-channel - routine sysex
PARAMETER = 0: GEGEVENS = 1: GOSUB SYSEX: 'number of notes
PARAMETER = 1: GEGEVENS = 0: GOSUB SYSEX: 'midi-channel
PARAMETER = 2: GEGEVENS = 127: GOSUB SYSEX: 'set high note limit
PARAMETER = 3: GEGEVENS = 0: GOSUB SYSEX: 'set lowest note limit
PARAMETER = 4: GEGEVENS = BANK: GOSUB SYSEX: 'voice bank
PARAMETER = 5: GEGEVENS = VOICE: GOSUB SYSEX: 'instrument
PARAMETER = 6: GEGEVENS = 0: GOSUB SYSEX: 'detune value (0-127)
PARAMETER = 7: GEGEVENS = 2: GOSUB SYSEX: 'octave transpose 2=0
PARAMETER = 8: GEGEVENS = VOLUME: GOSUB SYSEX: 'set volume
PARAMETER = 9: GEGEVENS = 64: GOSUB SYSEX: 'panning =LR
PARAMETER = 10: GEGEVENS = 0: GOSUB SYSEX: 'LFO-disable
PARAMETER = 11: GEGEVENS = PORTIME: GOSUB SYSEX: 'portamento time
PARAMETER = 12: GEGEVENS = BEND: GOSUB SYSEX: 'set pitchbendrange
PARAMETER = 13: GEGEVENS = 0: GOSUB SYSEX: 'set to POLY-mode
PARAMETER = 14: GEGEVENS = 0: GOSUB SYSEX: 'do not assign pmd
END IF
IF N$ = "" THEN
PARAMETER = &H21: GEGEVENS = 0: GOSUB SYSEX3: 'protect=OFF
PARAMETER = 12: GEGEVENS = BEND: GOSUB SYSEX: 'set changed pitchbendrange
END IF
'set memory protect to ON again
PARAMETER = &H21: GEGEVENS = 1: GOSUB SYSEX3: 'protect= ON
GOTO SLT
SYSEX:
B = &HF0: GOSUB SND
B = &H43: GOSUB SND
B = 16: GOSUB SND
B = &H15: GOSUB SND
B = PARAMETER: GOSUB SND
B = GEGEVENS: GOSUB SND
B = &HF7: GOSUB SND
RETURN
SYSEX3:
B = &HF0: GOSUB SND
B = &H43: GOSUB SND
B = &H75: GOSUB SND
B = 0: GOSUB SND
B = &H10: GOSUB SND
B = PARAMETER: GOSUB SND
B = GEGEVENS: GOSUB SND
B = &HF7: GOSUB SND
RETURN
SND:
OUT &H378, B: OUT &H37A, (SH OR 1): Z$ = "_": OUT &H37A, SH
WHILE (INP(&H379) AND 128) = 0: WEND: RETURN
'routine die een string omzet in een array van ASCII-codes
'de string wordt automatisch beperkt tot 8 letter
CHRARRAY:
N$ = LEFT$((LTRIM$(N$)), 8): J = LEN(N$): IF J < 1 THEN GOTO CHRARRAY
FOR I = 1 TO J: N$ = RIGHT$(N$, J + 1 - I): C(I - 1) = ASC(N$): NEXT I
RETURN
BLANK:
LOCATE 10, 10: FOR J = 0 TO 69: PRINT " "; : NEXT J
RETURN
SLT:
END SUB
------------------------------------------------------------------------------
'subprogramma voor de schermopmaak:
SUB SCHERM (N$) STATIC
LOCATE 25, 1
PRINT " Godfried-Willem RAES - Experimental Music-Software - 1989"
LOCATE 1, 10: PRINT "Programma voor Toshiba T1000 & Logos Midi-poort op &H378"
LOCATE 2, 10: PRINT " To be used with Yamaha FB01 FM-synthesiser "
LOCATE 3, 10: PRINT N$
LOCATE 4, 10 :PRINT " composer : Alvin LUCIER"
LOCATE 5, 5: FOR I = 0 TO 74: PRINT CHR$(219); : NEXT I
LOCATE 6, 10: PRINT "Key-codes :";
LOCATE 7, 10: PRINT " + = faster - = slower * = stop ";
LOCATE 8, 1: FOR I = 0 TO 79: PRINT CHR$(205); : NEXT I
END SUB
------------------------------------------------------------------------------
'Subprogramma voor de automatisering van de instelling van BEND
SUB TIMTST (BEND%, SH%) STATIC
'this routine calculates the time per octave on the machines running
'this programm - it does change the input bend value such as to obtain
'a real-time glissando of about 2 minutes per octave as asked in the score.
BEGINNOT = 10
EINDNOT = BEGINNOT + BEND
MEETTIJD:
STARTTIM# = TIMER
'MIDI-Meet stuurroutine berekent tijd nodig voor een halve-toonsglissando
'het is een zgn. DUMMY van het hoofdprogramma en bevat evenveel instrukties
GLISTST:
STP = 1: BENT = 1
FOR NT = BEGINNOT TO BEGINNOT STEP BENT: ' dit is geen fout !
B = 144: GOSUB SN
B = NT: GOSUB SN
B = 0: GOSUB SN
FOR MSB = 64 TO 127
FOR LSB = 0 TO 127 STEP STP
GOSUB RN
B = 224: GOSUB SN
B = LSB: GOSUB SN
B = MSB: GOSUB SN
NEXT LSB
C% = ((127 + ((MSB - 64) * 128)) / 81.92) * BENT
F% = (16.352 * (2 ^ ((((NT - 12) * 100) + C%) / 1200))) * 10
LOCATE 15, 22: PRINT F / 10; " "; : NEXT MSB: NEXT NT
LOCATE 15, 22: PRINT " ";
STOPTIM# = TIMER
IF STOPTIM# < STARTTIM# THEN GOTO MEETTIJD
TIJD% = ((STOPTIM# - STARTTIM#) * 12) / BEND: ' tijd per oktaaf
BEND = INT(((TIJD% * BEND) / 120) + .5)
'adjusts bend close to 2 minutes/octave
LOCATE 18, 10
PRINT "Speed would be "; TIJD%; "s/octave - Bend adjusted to value "; BEND;
EXIT SUB
RN:
K$ = INKEY$: IF K$ = "" THEN RETURN
IF K$ = "+" THEN STP = STP + 1
IF K$ = "-" THEN STP = STP - 1
IF STP < 2 THEN STP = 1
IF STP > 127 THEN STP = 127
RETURN
SN: OUT &H378, B: OUT &H37A, (SH OR 1): Z$ = "_": OUT &H37A, SH
WHILE INP(&H379) AND 128 = 0: WEND: RETURN
EINDETIMTST:
END SUB
Het grote voordeel van dit gebruik van subprogramma's (programma MODULES noemt men dit meestal, is dat ze zonder meer in andere nieuwe programmas kunnen worden overgenomen. De variabelen dienen daarbij dan niet eens dezelfde namen te hebben! Namen van variabelen gelden slechts binnen een bepaalde module, en de waarden worden overgedragen op de variabelen opgegeven in de CALL en DECLARE instrukties.
[File written 06.05.1989]
Terug naar de inhoudstafel (kursus-index)
Homepage Dr.Godfried-Willem Raes