Dr.Godfried-Willem RAES
Kursus Experimentele Muziek: Boekdeel1: Algoritmische Kompositie
Hogeschool Gent : Departement Muziek & Drama
1110:
De sinus-funktie is zoals alle goniometrische funkties, een periodieke funktie. Dit houdt in dat voor toenemende waarden van x, de waarden van y op regelmatige wijze weerkeren. Dit is logisch aangezien het argument van een goniometrische funktie een hoek is.
In de dagdagelijkse wiskunde worden hoeken uitgedrukt in graden, waarbij 0 graden en 360 graden ons op het uitgangspunt terugbrengen. Komputers rekenen evenwel niet met dit op zich nogal merkwaardige, want op het zestigtallig stelsel gebaseerd, telsysteem. In de meeste komputertalen, zoals ook in de wetenschap, wordt gerekend met een andere hoekeenheid , namelijk de RADIAAL , afgekort tot Rad. Deze eenheid is gebaseerd op het irrationale getal Pi. 0 graden komt overeen met 0 Rad, en 360 graden met 2*Pi Rad. 180 graden is dus gewoonweg Pi zelf.
Om 'klassieke' hoeken om te rekenen naar hoeken uitgedrukt in radialen kunnen we volgend programma gebruiken :
INPUT "Hoek in graden ?",GR!
Pi = 3.1415926#
R# = (GR! * 2 * Pi) / 360
of vereenvoudigd :
R# = GR! * Pi / 180
PRINT "Dit is in Rad=";R#
Door haar periodiciteit leent de sinus-funktie toegepast in algoritmes zich uitstekend voor muziek waarbij faseverschuivingen tussen repetitieve patronen voor de formele struktuur gebruikt worden.
Vb: een eerste funktie stelt fa = Amplitude * (SIN(2*Pi*f *t+ pha))
Een tweede funktie stelt fb = Amplitude * (SIN(2*Pi*f *t+ phb))
Beide funkties genereren een sinus met gelijke frekwentie en amplitude, maar met verschillende faze, nml. pha en phb.
Wanneer pha en phb variabel worden gemaakt kunnen we beide sinussen vrij in onderlinge faze verschuiven.
We kunnen gebruik makend van de sinus of de complementaire cosinus funktie eveneens blokgolfsignalen scheppen waarvan we de faze kunnen moduleren. De fundamentele funktie voor een blokgolf ziet eruit als:
(De SGN funktie genereert -1 of +1 al naar gelang het teken van de uitdrukking die als argument wordt gegeven).
Het hiernavolgende programmadeel uit een van mijn oudere komposities, kan dit goed illustreren. Het gebruikte programma-algoritme genereert een driestemmig muzikaal fragment. De eerste en de tweede stem hebben een melodielijn die sinusvormig verloopt. Voor de derde partij kan een keuze gemaakt worden tussen twee verschillende funkties, die worden afgeleid van de eerste stem. De A keuze komt overeen met de wiskundige voorstelling van wat een ringmodulator doet. De patronen die gegenereert worden zijn vooral dan boeiend wanneer de frekwenties klein (0.01 - 0.1) worden gekozen, en ook het onderling verschil klein is. Probeer het uit met diverse waarden voor de sinus-frekwentie !
Merk ook op dat dit programma vol steekt van allerlei filters, waardoor het nauwelijks kan spaaklopen op verkeerde inputs vanwege de gebruiker.
[Toshiba T1000 (8088 XT) programma op disk onder de naam LES11P1.BAS
Vereenvoudigde versie voor Atari 1040ST op Atari-disks in het klasarchief.
Files verkrijgbaar via aanvraag per e-mail]
Onderzoek van de sinusfunktie als periodiek muzikaal algoritme
BEGIN:
'omwille van de verwerkingssnelheid nemen we alle variabelen waarvoor het kan , als gehele getallen (integers)
DEFINT R: DEFINT T: DEFINT N: DEFINT B: DEFINT K: DEFINT I: DEFINT J
DEFINT D: DEFINT C: DEFINT S
GOSUB INITIALIZE:
INVOER:
'eerst worden twee noten ingebracht waarrond het algoritme melodische patronen zal berekenen
INPUT "Referentienoot voor stem 1 ?", REFNOT1
INPUT "Referentienoot voor stem 2 ?", REFNOT2
REFNOT1 = INT(ABS(REFNOT1 MOD 128)): 'filter
REFNOT2 = INT(ABS(REFNOT2 MOD 128)): 'filter
'hier wordt de maximale tessituur-uitwijking van elke stem ingebracht
INPUT "Maximale intervalafwijking stem 1 ?", TOPNOT1
INPUT "Maximale intervalafwijking stem 2 ?", TOPNOT2
'hier volgt weer een filter
IF TOPNOT1 >= 74 THEN
T1MAX = 128 - REFNOT1
TOPNOT1 = TOPNOT1 MOD T1MAX
ELSE
T1MAX = REFNOT1
TOPNOT1 = TOPNOT1 MOD T1MAX
END IF
IF TOPNOT1 >= 74 THEN
T2MAX = 128 - REFNOT2
TOPNOT2 = TOPNOT2 MOD T2MAX
ELSE
T2MAX = REFNOT2
TOPNOT2 = TOPNOT2 MOD T2MAX
END IF
TOPNOT1 = INT(ABS(TOPNOT1)): TOPNOT2 = INT(ABS(TOPNOT2))
'nu worden de herhalingsfrekwenties van de sinussen voor beide stemmen
'opgegeven. Dit hoeven geen gehele getallen te zijn
INPUT "Stem 1 herhalingsfrekwentie ?", FX
INPUT "Stem 2 herhalingsfrekwentie ?", FY
'volgend filter elimineert negatieve waarden voor de frekwentie
FX = ABS(FX): FY = ABS(FY)
'hier wordt een afspeeltempo ingebracht, hoe groter het getal hoe sneller
'gespeeld wordt
INPUT "Afspeeltempo (Metronoomgetal) ? ", MM
'te grote waarden worden weggefilterd
MM = ABS(INT(MM MOD 10000))
MM = 10000 / MM
ALGO3KEUS:
'de gebruiker krijgt de keus tussen twee berekeningswijzen voor de door het algoritme
' toe te voegen derde stem de funktie weergegeven door A is het
'wiskundig model voor wat een ringmodulator precies doet
PRINT "Gewenste overdrachtfunktie voor stem 3 ? : "
PRINT " A= multiplier sinx.t * sin y.t"
PRINT " B= difference of squares "
INPUT " KEUZE ? ", K$
'volgend statement is weer een filter
IF NOT (K$ = "A" OR K$ = "B") THEN GOTO ALGO3KEUS:
'een array wordt gedimensioneerd om de noten op te slaan wat nuttig kan
'zijn voor een eventueel toe te voegen partituurschrijfroutine
DIM N(3, 5000)
'de teller wordt op nul geplaatst
T = 0
ALGORITME:
PI = 3.1415926#
'de opgegeven frekwenties worden omgerekend naar cirkelfrekwenties
'omega=2*Pi*f
HX = 2 * PI * FX: HY = 2 * PI * FY
'hier worden dan de hoeken in radialen berekend
HXR = (HX * PI) / 180: HYR = (HY * PI) / 180
'hoek A
A = SIN(HXR * T)
'omzetting naar een aanvaardbare MIDI-noot
N(1, T) = REFNOT1 + INT(A * TOPNOT1)
'hoek B
B = SIN(HYR * T)
N(2, T) = REFNOT2 + INT(B * TOPNOT2)
'in funktie van het gekozen algoritme voor stem 3 kiest het
'programma hier een bepaalde weg
IF K$ = "B" THEN GOTO BCASE ELSE GOTO ACASE
BCASE:
N(3, T) = INT(((A ^ 2) - (B ^ 2)) * ((TOPNOT1 + TOPNOT2) / 2)) + ((REFNOT1 + REFNOT2) / 2)
ACASE:
IF K$ = "A" THEN N(3, T) = INT((A * B * ((TOPNOT1 + TOPNOT2) / 2)) + ((REFNOT1 + REFNOT2) / 2))
'als alles berekend is, worden de noten ook gespeeld:
GOSUB UITVOER:
'onder hier bepaalde voorwaarde zal het stuk vanzelf besluiten
'Einde wanneer de sinus van beide hoeken gelijk is of wanneer stem 1 en 2 unisono spelen
IF A = B AND T > 1 THEN PRINT "Sinussen in vertrekpunt op T="; T: GOTO EIND:
IF N(1, T) = N(2, T) AND T > 500 THEN GOTO EIND:
'volgend statement laat toe het programma te onderbreken
S$ = INKEY$: IF S$ = "*" THEN GOTO EIND
'volgende routine vormt de eigenlijke hoekteller
WHILE T < 5001
IF T = 5000 THEN T = 0
T = T + 1: GOTO ALGORITME
WEND
'***************************************************************************
'slotsubroutine:
EIND:
FOR I = 0 TO MM * 1000: NEXT I
IF K = 1 THEN
FOR J = 127 TO 0 STEP -1: 'slotakkoord met decrescendo
FOR I = 1 TO 3 OUT 3, 144 + I: OUT 3, N(I, T): OUT 3, J
NEXT I
FOR M=0 TO MM : NEXT M
NEXT J
END IF
IF K = 2 THEN
FOR J = 127 TO 0 STEP -1
FOR I = 1 TO 3
B = 144 + I: GOSUB SND
B = N(I, T): GOSUB SND
B = J: GOSUB SND
NEXT I
FOR M=0 TO MM : NEXT M
NEXT J
END IF
PRINT " E I N D E "
END
'***************************************************************************
'initialisatie routine in funktie van de gebruikte machines
INITIALIZE:
PRINT "Machine ? ATARI 1040 (1) of TOSHIBA T1000 (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)
RETURN
'uitvoerroutine:
UITVOER:
IF K = 1 AND T = 0 THEN
FOR I = 1 TO 3
OUT 3, 144 + I: OUT 3, N(I, T): OUT 3, 100
NEXT I
END IF
IF K = 1 AND T > 0 THEN
FOR I = 1 TO 3
IF N(I, T) <> N(I, T - 1) THEN
OUT 3, 144 + I: OUT 3, N(I, T - 1): OUT 3, 0
OUT 3, 144 + I: OUT 3, N(I, T): OUT 3, 64
END IF
NEXT I
FOR I = 0 TO MM: NEXT I
END IF
IF K = 1 THEN RETURN
IF K = 2 AND T = 0 THEN
FOR I = 1 TO 3
B = 144 + I: GOSUB SND
B = N(I, T): GOSUB SND
B = 100: GOSUB SND
NEXT I
END IF
IF K = 2 AND T > 0 THEN
FOR I = 1 TO 3
IF N(I, T) <> N(I, T - 1) THEN
B = 144 + I: GOSUB SND
B = N(I, T - 1): GOSUB SND
B = 0: GOSUB SND
B = N(I, T): GOSUB SND
B = 64: GOSUB SND
END IF
NEXT I
FOR I = 0 TO MM: NEXT I
END IF
RETURN
'klassieke T1000 midisend routine
SND:
OUT DP, B: OUT SP, (SH OR 1): Z$ = "RAES": OUT SP, SH
CHKBUSY:
IF INP(CP) AND 128 THEN RETURN ELSE GOTO CHKBUSY
Het hoeft waarschijnlijk geen verder betoog, dat wat hier werd gedaan met de sinus-funktie ook kan met de andere goniometrische funkties zoals cosinus. Met tangens en cotangens moeten we echter wat voorzichtiger zijn, omdat beide funkties heel snel zeer grote numerieke waarden ( theoretisch van - tot + 'oneindig' ) aannemen, wat in komputerprogrammas steeds aanleiding geeft tot een of andere vorm van overflow. Wil je ze toch gebruiken , dan dient een filter geplaatst te worden vooraleer tangens of cotangens berekend worden ! Let er ook op dat alle standaard goniometrische funkties voor bepaalde hoeken door 0 gaan. Aangezien je nooit mag delen door nul moet je hier dus steeds speciaal alert voor zijn .
Het esthetische verschil tussen sinus/cosinus enerzijds en tangens/cotangens anderzijds schuilt hierin dat de eerste zeer snel door het nulpunt gaan ( de kurves hebben door het nulpunt de grootste helling) en de tweede net omgekeerd, precies rond het nulpunt de zwakste helling vertonen.
Tot besluit nog enkele basic-notaties van gebruikelijke en ook muzikaal bruikbare wiskundige periodieke overdrachtfunkties:
SIN(x)
COS(x)
TAN(x)
Afgeleide funkties zijn :
Cotangens(x)= -TAN((Pi/2)+x)
In radialen ! Pi/2 = 90 graden
Ook de cosinus kan uit de sinus worden afgeleid :
COS(x) = SIN((Pi/2)+x)
Voorts hebben we :
Secans(x) = 1/COS(x)
Cosecans(x) = 1/SIN(x)
Opmerkingen met betrekking tot het gebruik van goniometrische funkties in GFA-Basic voor Atari ST machines.
Het voor de Atari ST ontwikkelde GFA-basic beschikt over een aantal uitermate handige instrukties die het programmeren met goniometrische funkties aanzienlijk kunnen vereenvoudigen. Voor de omrekeningen tussen graden en radialen zijn zo volgende funkties ingebouwd:
RAD(x) en het komplement DEG(x)
RAD(x) zet een hoek x , uitgedrukt in graden , om naar radialen. DEG(x) zet een hoek x uitgedrukt in radialen om in graden. Uiteraard is de achterliggende ingebouwde funktie hier eveneens:
DEG(x) = (x * 180) / Pi
Wanneer aan de wiskundige nauwkeurigheid geen al te hoge eisen worden gesteld , kan ook gebruik gemaakt worden van de ingebouwde look-up tables (opzoekingstabellen in RAM) van dit Basic.
Daarvoor staan de speciale funkties:
SINQ(x) en COSQ(x) ter beschikking.
De waarden voor x dienen hierbij in 'gewone' graden te worden opgegeven. De look-up table bevat de resultaten van de funktie per graad. Voor fractionele waarden wordt lineair geinterpolleerd in stapjes van 1/16e graad. De vergelijkingen die intern aan deze funktie ten grondslag liggen zijn :
SINQ(gradenhoek) = SIN(RAD(gradenhoek))
COSQ(gradenhoek) = COS(RAD(gradenhoek))
Het immense voordeel van deze wiskundig inferieure benadering is dat de berekeningen op die manier minstens 10x sneller afgehandeld worden. Voor grafische toepassingen is er geen merkbaar verlies aan precisie, omdat de resolutie van het weergavescherm daartoe ontoereikend is.
Filedate: 850214
Terug naar inhoudstafel kursus: <Index Kursus> |
Naar homepage dr.Godfried-Willem RAES |