Dr.Godfried-Willem RAES

Kursus Experimentele Muziek: Boekdeel1: Algoritmische Kompositie

Hogeschool Gent : Departement Muziek & Drama


<Terug naar inhoudstafel kursus>

   

 

1100: ALGORITMEN VOOR MUZIEK

1. Definitie

Een algoritme is een in formules uitdrukbaar regelsysteem waardoor logische en/of rekenkundige bewerkingen worden uitgevoerd.

Een algoritme heeft dan ook steeds een invoer (de gegevens waarop het algoritme bewerkingen zal uitvoeren) en een uitvoer (de resultaten van die bewerkingen). In deze kontekst worden eigenlijk uitsluitend de engelse termen INPUT en OUTPUT gebruikt.

In de komputerkontekst is het algoritme een deel van een programma. Het is een geprogrammeerde automaat.

2. Typologie

Algemeen beschouwd kunnen we enkele verschillende types algoritmen onderscheiden:

.1:Unaire konvertoren

Hierbij wordt een enkel INPUT gegeven omgezet in een enkele OUTPUT. Eenvoudige voorbeelden van dergelijke algoritmen zijn alle unaire wiskundige, logische en string-bewerkingen :

logische :

NOT (x)

deze bewerking, toegepast op getallen ,maakt van alle 1 in een binair getal 0 en van alle 0 weer 1.

rekenkundige :

- (x)

deze bewerking keert het teken van getal om. Positief wordt negatief en vice versa.

FIX (x)

deze bewerking laat van een getal alles wat na de komma staat weg.

INT (x)

deze bewerking rondt een getal af.

LOG (x)

berekent de logaritme van een getal

SQR (x)

vierkantswortel uit een getal

X= X+X , X=X*X , X=X^X

bewerkingen van een getal met zichzelf. Merk op dat X-X=0 en dat X/X=1

goniometrische:

SIN (x)

COS (x)

berekenen resp. de sinus en de cosinus van een getal.Voor de muziek zijn deze funkties interessant omdat ze repeterend zijn. We zullen er dan ook een les aan besteden.

stringbewerkingen:

ASC (x$)

geeft de ASCII code van een teken

CHR$(X)

geeft het ASCII teken van een getal

CVS(X)

zet een cijfer om in een string

De algemene vorm van een unair konversie algoritme in een konkreet basic- programma ziet eruit alsvolgt:

INVOER:

INPUT " Geef een getal ?", X

ALGORITME:

X=SQR(X)

X=LOG(X)

IF X THEN X=SIN(X) ELSE X=NOT(X)

UITVOER:

PRINT X

Zoals je ziet , kan het algoritme uit een hele reeks bewerkingen opgebouwd zijn. Ook kan de uitvoer natuurlijk meervoudig zijn.

.2:Relationele algoritmen

Hierbij is de OUTPUT het resultaat van een algoritme op meerdere INPUT's. Ook hier kan de OUTPUT eveneens veelvoudig zijn.

A. In het meest eenvoudige geval hebben we een variabele INPUT en een of meerdere konstanten, die ook in het algoritme zelf ingebouwd kunnen zijn.

Een voorbeeld :

DECLARE SUB Uit (byte%) :' dit is de midi-uitvoer procedure

DECLARE SUB Wacht(t!): ' dit is een wacht-tijd procedure

INVOER:

INPUT " Geef een getal ?", X

ALGORITME:

X=INT(X)

IF X >127 THEN X=X MOD 128

IF X <1 THEN X=-X

IF X >127 THEN X=X MOD 128

UITVOER:

Uit 144 : Uit X : Uit 64

Wacht 1000

Uit 144 : Uit X : Uit 0

END

De konstanten, die hier ingebouwd werden in het algoritme zijn de typische midi-begrenzingswaarden 0 en 127. Het algoritme garandeert dat welkdanig getal ook wordt opgegeven, er steeds een geoorloofde midi-code wordt voortgebracht.

B. De eigenlijke typische relationele algoritmen vertrekken van meerdere variabele INPUT's.

Voor de opbouw van de algoritmen kunnen ook hier alle logische , rekenkundige en stringbewerkingen worden gebruikt.

Logische : x AND y, Booleaanse EN funktie

x OR y, Booleaanse OF funktie

x IMP y, Booleaanse implikatie

x XOR y, Booleaanse exclusieve OF

Rekenkundige :

> , = , <

vergelijkingen

+ , - , * , ^ , / , \ , MOD

bewerkingen

Stringbewerkingen:

MID$(x,y),Z$

LEFT$(x),Z$

RIGHT$(x),Z$

Zowat het eenvoudigste voorbeeld hier zou volgend programma kunnen zijn, dat twee getallen vraagt aan de gebruiker, er allerlei bewerkingen op uitvoert en die dan op het scherm laat zien met de resultaten ervan :

INVOER :

INPUT " Geef eerste getal ? ", X

INPUT " Geef tweede getal ? ", Y

ALGORITME:

A=X+Y

B=X-Y

C=X*Y

D=X/Y

E=X^Y

UITVOER:

PRINT X;"+";Y;"=";A,X;"-";Y;"=";B

PRINT X;"*";Y;"=";C,X;"/";Y;"=";D

PRINT X;"^";Y;"=";E

Een iets meer gesofistikeerd voorbeeld , uit de muziek dan, zou hetvolgende kunnen zijn :

INVOER:

PRINT "Stop programma door beide noten 0 te maken"

INPUT "Geef een noot (midi-getal) ? ",N(1)

INPUT "Geef een tweede noot ?",N(2)

ALGORITME: IF N(1)=0 AND N(2)=0 THEN GOTO EINDE

IF N(1)=0 OR N(2)=0 THEN GOTO INVOER

N(1)=N(1) MOD 128

N(2)=N(2) MOD 128

IF N(1)>N(2) THEN SWAP N(1),N(2)

WHILE N(2)-N(1)>12

N(2)=N(2)-12

WEND

IF N(2)-N(1)=12 THEN N(3)=N(1)+7

IF N(2)-N(1)=7 THEN N(3)=N(1)+4

IF N(2)-N(1)=5 THEN N(3)=N(2)+4

IF N(2)-N(1)=4 THEN N(3)=N(1)+7

IF N(2)-N(1)=3 THEN N(3)=N(1)+7

IF N(2)-N(1)=6 THEN N(3)=N(1)+9

IF N(2)-N(1)=2 OR N(2)-N(1)=10 THEN N(3)=N(1)+5

IF N(2)-N(1)=1 OR N(2)-N(1)=11 THEN N(3)=N(1)-4

IF N(2)-N(1)=8 THEN N(3)=N(1)+3

IF N(2)-N(1)=9 THEN N(3)=N(1)+5

T=N(1)*N(2)*N(3)

UITVOER:

'noten aan

FOR I=1 to 3

Uit 144 : Uit N(I) : Uit 64

NEXT I

'aanhouden van de noten

Wacht T*100

'noten uit

FOR I=1 TO 3

Uit 144 : Uit N(I) : Uit 0

NEXT I

EINDE:

END

Bekijk goed wat dit programma doet! Wanneer je de kode voor de Uit procedure inleest, dan loopt dit direkt op een PV voorzien van een midi-interface. Het programma poogt op grond van de opgegeven noten, min of meer harmonische drieklanken op te bouwen. Bovenstaand programma is niet erg efficient geschreven (omwille van de leesbaarheid). Tracht het zelf eens eenvoudiger op te lossen.

C.:Relationele algoritmen met geheugenfunktie

Hierbij worden de gegevens uit de input in een geheugen opgeslagen, zodat het algoritme beroep kan doen op alle vroeger ingebrachte gegevens. Dit biedt uiteraard voor muzikale toepassingen veel boeiende perspektieven , omdat het hier toch om een in de tijd georganiseerde expressievorm gaat, waarbij immers geluiden alleen binnen hun temporele organisatie betekenis kunnen krijgen.

 Volgend meer uitgewerkt programmavoorbeeld moge een en ander verduidelijken:

DECLARE SUB Uit (byte%)

DECLARE SUN Wacht (t!)

GEHEUGEN:

DIM N1(500): DIM N2(500): DIM N3(500)

DIM TM(500)

J = 1

INVOER:

DO

PRINT " Stop wanneer beide noten=0 "

INPUT " Geef een noot 1 ?", N1(J)

INPUT " Geef een noot 2 ?", N2(J)

ALGORITME:

IF N1(J) = 0 AND N2(J) = 0 THEN EXIT DO

N1(J) = N1(J) MOD 128

N2(J) = N2(J) MOD 128

TM(J) = N1(J) * N2(J) + (TM(J - 1) MOD 1000)

N3(J) = N1(J) - N2(J) + (N1(J - 1) - N2(J - 1))

IF N3(J) < 0 THEN N3(J) = -N3(J)

N3(J) = N3(J) MOD 128

J = (J + 1) MOD 500

UITVOER:

Uit 144: Uit N1(J): Uit 64

Uit N2(J): Uit 64

Uit N3(J): Uit 64

Wacht TM(J) * 1000

Uit 144

Uit N1(J): Uit 0

Uit N2(J): Uit 0

Uit N3(J): Uit 0

LOOP

END

 

SUB Uit (byte%)

‘ zie elders voor deze midi-uit procedure (1063.html)

END SUB

SUB Wacht (t!)

tn!= TIMER + t!

DO

LOOP UNTIL TIMER > tn!

END SUB

 

.3: Algoritmen met feedback

Onder deze kategorie resorteren eigenlijk de interessantste vormen van algoritmen. Hierbij wordt immers een deel van de output terug als input aan het algoritme aangeboden . Ga zelf na hoe dit werd bereikt in het programma dat nu volgt :

INITIALIZE:

DEFINT A, Z

DEFINT N

DEFINT B

PRINT "Machine? ATARI 1040 (1) of PC (2) ?"

INPUT "Keuze ?", K

IF K < 1 OR K > 2 THEN CLS : GOTO INITIALIZE:

IF K = 2 THEN DP = &H378: CP = DP + 1: SP = DP + 2: SH = INP(SP)

GEHEUGEN:

DIM N(100, 6): DIM B(3)

J = 5

'het array bestaat uit 101 akkoorden van vijf

'noten - het laatste element van het array

'wordt gebruikt voor de tijdsduur

INVOER:

INPUT "Geef een startnoot ? ", N(5, 1)

INPUT "Geef een interval ? ", TD

INPUT "Geef een tempo ? ", TMP

IF TMP < 1 THEN PRINT " Illegal value ! ": GOTO INVOER

ALGORITME:

J = J + 1

N(J, 1) = N(J - 1, 1) + TD

N(J, 2) = N(J - 2, 1) - (J MOD 2)

N(J, 3) = N(J - 3, 1) - (J MOD 3)

N(J, 4) = N(J - 4, 1) - (J MOD 4)

N(J, 5) = N(J - 5, 1) - (J MOD TD)

FOR I = 1 TO 5

IF N(J, I) < 1 THEN N(J, I) = -N(J, I)

IF N(J, I) THEN N(J, I) = N(J, I) MOD 128

IF N(J, I) < 25 THEN N(J, I) = N(J, I) + 24

IF N(J, I) > 96 THEN N(J, I) = N(J, I) - 24

NEXT I

TT = 0

FOR Q = 1 TO 5: TT = TT + N(J, Q): NEXT Q

N(J, 6) = (TT \ TMP) * (J MOD 3): 'dit wordt de tijdsduur

 

GOSUB UITVOER:

K$ = INKEY$

IF K$ = "*" THEN GOTO EINDE

'beeindigingsalgoritme

IF (N(J, 4) - N(J, 5)) MOD 12 = 0 AND_

(N(J, 3) - N(J, 4)) MOD 12 = 0 OR TD = 0 THEN

N(J, 6) = 1000: ' lang slotakkoord

GOSUB UITVOER

GOTO EINDE

END IF

GOTO FEEDBACK:

 

UITVOER:

'Atari 1040-routine:

IF K = 1 THEN

FOR I = 1 TO 5

OUT 3, 144: OUT 3, N(J, I): OUT 3, 127

FOR T = 0 TO 12000 / TMP: NEXT T

NEXT I

FOR T = 0 TO N(J, 6): NEXT T

FOR I = 1 TO 5

OUT 3, 144: OUT 3, N(J, I): OUT 3, 0

NEXT I

ELSE

'Toshiba T1000-routine:

FOR I = 1 TO 5

B(1) = 144: B(2) = N(J, I): B(3) = 127

FOR Z = 1 TO 3: B = B(Z): GOSUB SND: NEXT Z

FOR T = 0 TO 6000 / TMP: NEXT T

NEXT I

FOR I = 1 TO 5

B(1) = 144: B(2) = N(J, I): B(3) = 0

FOR Z = 1 TO 3: B = B(Z): GOSUB SND: NEXT Z

NEXT I

END IF

RETURN

FEEDBACK:

IF J = 100 THEN

TD = TD + 1

FOR I = 1 TO 6

N(I - 1, I) = N(94 + I, I)

NEXT I

J = 5

END IF

TD = TD MOD 13

GOTO ALGORITME:

SND:

OUT DP, B: OUT SP, (SH OR 1): Z$ = "GWR": OUT SP, SH

CHKBUSY:

IF INP(CP) AND 128 THEN RETURN ELSE GOTO CHKBUSY

EINDE:

IF K = 2 THEN

FOR I = 0 TO 15

B = 176 + I: GOSUB SND

B = 123: GOSUB SND

B = 0: GOSUB SND

NEXT I

END IF

IF K = 1 THEN

FOR I = 0 TO 15

OUT 3, 176 + I: OUT 3, 123: OUT 3, 0

NEXT I

END IF

END

Bij analyse zul je gauw ontdekken dat dit programma genoeg heeft aan het inbrengen van twee initiele gegevens. Voor de rest genereert het trossen akkoorden (meestal vijfklanken) die vanuit deze initiele gegevens worden opgebouwd. Ook het uiteindelijke aantal gegenereerde akkoorden evenals hun duur, zijn van de input afhankelijk. Bovendien is er een , zij het primitief, temporeel verband tussen alle voortgebrachte noten.

3. Enkele muziekfilosofische beschouwingen.

Een dergelijk programma is niet alleen louter algoritmisch, maar bovendien ook een automaat. Nu is een dergelijke automaat in vele opzichten grondig verschillend van de muziekautomaten die we uit de instrumentenmusea kennen. Deze laatste immers zijn geen echte komponeermachines ( enkele bizarre pogingen , met name het Brusselse Componium dat niemand nog in gang weet te krijgen..., niet te na gesproken) maar loutere (af)speeldozen. Zij doen immers niets anders dan vooraf ingebrachte partituren ( in de vorm van rollen , platen , banden enz.) afspelen. Principieel bestaat er dan ook niet zoveel verschil tussen een platenspeler of een cassettedeck en een pneumatische orchestrion. Afgezien van de mogelijkheid live de metriek te bepalen, was ons programma uit les 9 , geschreven voor de uitvoering van 'Due Cose ...' van Luc Brewaeys , eigenlijk niet veel meer dan zo'n speeldoos in een modern komputerjasje. Ook alle in de handel verkrijgbare midi- sekwensers - softwarepaketten - zijn niet veel meer dan speeldozen, die alleen het uitvoeren van een op voorhand bedacht muziekstuk kunnen mogelijk maken en vergemakkelijken. Technisch gezien berusten , maar nu in komputerjargon , alle speeldozen op niets anders dan op het met behulp van de komputer invullen van een array met meerdere dimensies ( een dimensie voor het aantal metronomische tikken , een voor elke melodische stem, een voor een bij elke melodische stem toe te passen klankkleur , een voor de bij elke stem toe te passen dinamiek ... ). Het nut van dergelijke programmas (sequencers) lijkt mij niet direkt betwijfelbaar, maar de mogelijkheden die de komputer biedt, gaan onnoemelijk veel verder dat dit alles !

Het algoritmisch komponeren immers, zet de komputer in als een intelligente machine : een machine die niet alleen maar ingebrachte gegevens snel en perfekt weergeeft, maar een die die gegevens ook zelf berekent op grond van door de komponist ingebrachte wetmatigheden en verbanden. Ik leg nogal de nadruk op die komponist in dit verband , omdat er inderdaad vandaag wel programmas bestaan die de gebruiker toelaten een simpel thema in te spelen , en die er automatisch een vierstemmig en georkestreerd muziekstuk mee opbouwen, met uitgeprinte partituur erbij ! Dit is evenwel zowat diametraal het tegenovergestelde van wat ik onder kreatief werken - en dat zou komponeren dan toch horen te zijn - wil verstaan. Mijns inziens vallen de resultaten van de toepassing van dergelijke programmas onder het auteursschap van de software-ontwikkelaars, die echter geenszins als kreatieve komponisten mogen worden beschouwd , aangezien zij er zich toe beperken -aansluitend bij volmaakt traditionele esthetische opvattingen over muziek- bestaande harmonie- en kontrapuntregels als algoritmes in hun programma in te bouwen. Kortom, het zijn Muzak-makers.

Van intelligente algoritmische machines kunnen we hier eigenlijk pas spreken , wanneer die machine ( of beter, het programma dat we erop laten lopen) in het toepassen van die wetmatigheden mede rekening kan houden met kennis over de 'wereld' waarin die wetmatigheden van kracht worden geacht te zijn. Dit rekening houden, kan dan zo ver worden gedreven dat de machine bvb. de regels en samenhangen op eigen beslissingsgronden kan wijzigen, in funktie van een na te streven globale doelstelling. Een komputerprogramma waarin zoiets geimplementeerd werd, vertoont eigenschappen van wat met een 'expert-systeem' noemt. Voor de komponist is dit iets nogal interessants omdat de machine in staat is hem beter bewust te laten worden van de stilistische samenhangen waartoe hij in zijn werk neigt. Uiteraard kan hij dan daarop ingrijpen op een meer konstruktieve en direkte wijze dan dat ooit in de geschiedenis het geval is geweest.


Een doordenkertje :

Zoals men weet houdt Sabam (een op Belgisch grondgebied aktieve en door politici beschermde maffia) op komputer een Database bij van alle eerste 10 of 20 noten van elk door het auteursrecht beschermd (?) muziekstuk. Wat zou men daar beginnen indien een onnozele ziel er zich mee zou bezig houden om via een komputerprogramma , alle nog niet geschreven melodische lijnen uit te schrijven en door Sabam te laten beschermen... Hij zou dan elk nieuw ingebracht stukje als plagiaat kunnen laten vervolgen en multi-miljonair worden .


Filedate:911003

Terug naar inhoudstafel kursus: <Index Kursus>

Naar homepage dr.Godfried-Willem RAES

Naar volgend hoofdstuk