Dr.Godfried-Willem RAES

Kursus Experimentele Muziek: Boekdeel1: Algoritmische Kompositie

Hogeschool Gent : Departement Muziek & Drama


<Terug naar inhoudstafel kursus>

   

1110:

MUZIKALE EIGENSCHAPPEN VAN DE SINUS-FUNKTIE

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:

Fs = Amplitude * SGN(COS(2*Pi*f*t + pha))

(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)

 


Gfa-Basic

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