Dr.Godfried-Willem RAES

Kursus Experimentele Muziek: Boekdeel 1: Algoritmische Kompositie

Hogeschool Gent

Departement Muziek en Drama


Naar kursus index

  1062:

NUTTIGE PROGRAMMA-PROCEDURES

1.Kompatibiliteit...

Niets in ook maar enige programmeertaal geeft de schrijver van een programma ook maar enige garantie dat zijn programma en vooral de gegevens die het produceert of nodig heeft, door werk van anderen kan gebruikt worden. Het hoeft allicht geen betoog dat dit een zware handikap kan zijn. Omdat een grote mate van uitwisselbaarheid van kode en bestanden m.b.t. muzikale kompositie tussen de studenten in dit vak onderling van zeer groot belang is, meen ik dat het aangewezen is enkele algemene afspraken te maken waardoor stukken van programmas evenals alle gegevens, een zeker universeel gebruik en inzicht mogelijk zou maken.

Voor het in het geheugen aanmaken van muzikale komposities, stel ik daarom voor een van de hiernavolgende opslagformaten te gebruiken.

 

 

Eerst en vooral gaan we hier de eerste twee formaten behandelen, omdat voor het algoritmisch komponeren zonder twijfel het eenvoudigst te hanteren zijn. De andere twee komen verder in de kursus uitvoerig aan de orde. Het laatste formaat werd door onszelf ontwikkeld voor gebruik in de kontekst van onze GMT programmeertaal.

1. P%(0 TO i&,0 TO j%)

waarbij:

i& de teller is voor de tijdseenheden. (dit is de kleinste in het stuk voorziene metrische eenheid, bvb. de tweeendertigste noot). Merk op dat bij de dimensionering I& bepaald wordt als een 'long integer'. Doen we dit niet dan kunnen onze arrays nooit meer geheugen toegewezen krijgen dan 64kByte, wat voor een iets ambitieuzer stuk muziek niet voldoende blijkt te zijn.

j% de teller is voor de verschillende stemmen, en wel alsvolgt: Op de oneven plaatsen van J staan de noten. Op de even plaatsen staat de dynamiek. Merk op dan de 0-plaats niet wordt gebruikt. Wanneer nuttig of toepasselijk kan hier het tonaal centrum van het stuk in worden geplaatst (Tc% MOD 12). Voor j% is een gewoon geheel getal (integer) meer dan voldoende. In het standaard formaat gebruiken we immers per array niet meer dan 7 stemmen ( j%= 1 TO 13 STEP 2).

Merk ook op dat het array nooit iets anders dan gehele getallen kan bevatten (P%). Gehele getallen vragen weliswaar 2 bytes aan opslagruimte, maar Basic laat ons helaas niet toe enkelvoudige bytes als dusdanig te deklareren. (Het is alleen mogelijk via de omweg van het string*1-formaat)

Muzikaal gezien stellen we ons hierbij de i&-teller best voor als een horizontale tijdsas, terwijl de j%-teller de verschillende stemmen bepaalt.

Dus P%(0,1) is de eerste noot in de eerste stem, want i& = 0 en j% = 1. Een akkoord sekwens do-mi-sol-do sol-si-re-fa in vierde noten, met als kleinste metrische waarde de zestiende noot, ziet er dan (decimaal genoteerd als midi-getallen) uit als:

i&: 0 1 2 3 4 5 6 8 9 ...

j%

0 0 0 0 0 0 0 0 0 0 0 ...

1 60 0 0 0 65 0 0 0 65 0 ...noten stem 1

2 127 0 0 0 127 0 0 0 0 0 ...dynamiek

3 55 0 0 0 62 0 0 0 62 0 ... noten stem 2

4 127 0 0 0 127 0 0 0 0 0 ...dynamiek

5 52 0 0 0 59 0 0 0 59 0 ...noten stem 3

6 127 0 0 0 127 0 0 0 0 0 ...dynamiek

7 48 0 0 0 55 0 0 0 55 0 ...noten stem 4

8 127 0 0 0 127 0 0 0 0 0 ...dynamiek

enz...

Alles wat in deze struktuur vertikaal staat gebeurt dus gelijktijdig. Naar struktuur is er dan ook een grote overeenkomst met de principiele opvatting van een partituur.

Zo'n array - gelezen door het DOS-programma DEBUG als een binaire file ziet er evenwel uit alsvolgt (getallen worden hier steeds getoond in hexadecimaal stelsel, het interne formaat van elke komputer):

J 0 1 2 3 4 5 6 7 8 9 A B C D E F

I

0 00 30 40 00 00 37 40 00 - 00 3C 40 00 00 00 00 00

1 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

2 00 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

3 00 00 00 00 00 37 00 00 - 00 00 00 00 00 00 00 00

4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

5 00 31 40 00 00 36 40 42 - 40 3F 40 00 00 00 00 00

6 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

7 00 31 00 00 00 36 00 42 - 00 3F 40 00 00 00 00 00

enz...

Dit opslagformaat staat dan ook erg dicht bij de interne struktuur van de machine.

Wil je een bestaande binaire file, bvb. <fuga1.bin> bekijken met het dos programma 'debug', dan geef je volgend kommando:

DEBUG C:\ + path + fuga1.bin

waarna je door de opdracht 'd' (dan Dump) de file te lezen krijgt in het hier getoonde formaat. In de linkerkolom verschijnen segment en offset van de geheugenplaats waarin debug de file in het geheugen heeft ingeladen. Elke herhaling van het dump kommando d, laat een nieuw blok van het geheugen in hexadecimaal formaat op het scherm zien.

Voor meer informatie over debug, zie DOS-users manual.

 

Merk op dat de richting waarin i& en j% worden weergeven hier is omgekeerd. Dit is het data-formaat dat de komputer zal gebruiken voor de opslag op disks van onze muziekbestanden. Als gebruikers en programmeurs, zullen we echter -zolang alles goed gaat- alleen bezig zijn met arrays in de vorm P%(i&,j%).

Let op: P%(i&,0) wordt hier niet voor opslag van noten gebruikt. Op die plek kunnen 'pointers' worden opgeslagen (bvb. transpositie gegevens of andere gekodeerde aanduidingen).

 

 

Beperkingen:

Dit arrayformaat mag slechts tot en met 7 stemmige stukken gebruikt worden. Wanneer een stuk uit meer dan 7 stemmen moet bestaan, moet je verschillende identieke arrays gebruiken, bvb P1%(i&,j%), P2%(i&,j%), P3%(i&,j%) ....

Noten en dynamiek moeten zich strikt houden aan de standaarden vervat in de midi-specifikaties: alleen positieve gehele getallen tussen 0 en 127 kunnen aanvaard worden voor noten en dynamieken! Wil je mikrotonaal werken dan kan je ofwel gebruik maken van een omzettingsprogramma bij de weergave van de files, ofwel van een parallel-lopend array met de cents-informatie per noot. Hiervoor heeft het weinig zin standaarden vast te leggen, omdat ze noch door de hardware, noch door de muzieknotatie zelf zijn gestandaardiseerd.

De arrays moeten als binaire random-access files op disk worden opgeslagen en als dusdanig ook opnieuw ingelezen. Daartoe stel ik een koppel universele lees- en schrijf procedures ter beschikking van de studenten, die via de merge instruktie, of door je programma te schrijven uitgaande van een van de in de klas voorhanden zijnde programmaskeletten, aan elk nieuw programma kunnen worden toegevoegd.

Wie van mijn Midi-interface ontwerp gebruik wil maken, dient zich uiteraard ook te houden aan de daarvoor geldende standaarden die voortspruiten uit de eigenschappen van de gebruikte hardware. Midi-drivers voor dit interface evenals voor de kommercieel gangbare interfaces van Roland (MPU401), MusicQuest en Soundblaster stel ik eveneens ter beschikking.

 

2. Universele procedure voor het wegschrijven van P%(i&,j%) arrays

 

Vanuit het hoofdprogramma over te dragen variabelen (SHARED):

P%(i&,j%)

Het array zelf.

Het geheugen dient te worden vrijgemaakt voor de allokatie van dynamische arrays via een metakommando:

REM $DYNAMIC

De dimensionering dient te gebeuren in het hoofdprogramma, bij voorkeur via het koppel instrukties:

COMMON SHARED P%()

DIM SHARED P%(0 TO Einde&, 0 TO 15)

Einde& is hier de grootste waarde van de i& pointer, of de laatste tijdseenheid van het muziekstuk. Merk op dat beide niet noodzakelijk samenvallen. De grootte van het array kan via een interne funktie van Basic worden achterhaald: UBOUND (P%,1), de grootte van het muziekstuk (die kleiner of gelijk moet zijn aan de door deze funktie opgeleverde waarde) echter niet.

Q$

de naam waaronder het te maken bestand naar disk dient te worden weggeschreven,

 

NVOICES%

het aantal gebruikte en weg te schrijven muzikale stemmen in het array.

(kan ook afgeleid worden uit UBOUND(P%,2))

CODE :

 

SUB WRFIL STATIC

' dit subprogramma schrijft een in het geheugen aanwezig array van de vorm P(I,J) naar een binaire file op disk

' de naam van deze file moet opgeslagen zijn in de variabele Q$.Deze variabele mag ook diskdrive en pad mee 'omvatten. bvb. Q$="C:\bc7\kompos\sonate1.bin"

' Q$ dient als gemeenschappelijke string-variabele gedeklareerd te worden in het hoofdprogramma.

' Het array zelf P(I,J) dient uiteraard eerder in het programma gedimensioneerd te zijn!

' De lengte van het array (het aantal kolommen I) is opgeslagen in de variabele EINDE

 

NUL%=0

K&=1 ' tellervariabelen

' K telt het aantal bytes in de file

' dit zijn lokale variabelen

OPEN Q$ FOR BINARY AS #1

' kreeert de gevraagde file op disk

FOR i&= 0 TO EINDE&

FOR j%=0 TO 15

IF j% < ((NVOICES% * 2 ) + 1) THEN

' (NVOICES% * 2) + 1 =

' 7 voor 3-stemmig stuk

' 9 voor 4-stemmig stuk

' 11 voor 5-stemmig

' 13 voor 6 -stemmig

' 15 voor 7-stemmig (maximum)

PUT #1, K, P%(i&,j%)

K& = K& + 1

ELSE

PUT #1, K&, NUL%

K& = K& + 1

ENDIF

NEXT j%

NEXT i&

 

CLOSE #1

END SUB

 

3. Universele procedure voor het inlezen van files ...

Vanuit het hoofdprogramma over te dragen variabelen:

C$ DOS-naam van het te lezen bestand

Door het subprogramma aan het hoofdprogramma mee te delen variabelen:

P%() het array zelf

EINDE& grootste waarde van I

 

CODE:

SUB RDFIL STATIC

' deze procedure leest een op disk opgeslagen binaire-file (een muziek-array op disk) in een array

' de stringvariabele C$ bevat de naam van de binaire file evenals het eventuele pad om de file te vinden

' C$ is dus iets zoals "C:\bc7\kompos\fuga33.bin"

' Y& is gedefinieerd als een Long-Integer en daarvoor worden

' door BC7 en Quick-basic 8 bytes in het geheugen gereserveerd.

' Verder in het programma gaan we de file inlezen via deze variabele in groepjes van 4 words.

I& = 0

J% = 0 ' lokale teller-variabelen

OPEN C$ FOR BINARY AS #1 : ' opent de binaire file

ENDCOUNT&= LOF(1): ' bepaalt de grootte van het array op grond van de lengte van de file

REDIM P%(ENDCOUNT&\16,15) ' dimensioneer het nodige array in het geheugen

CLS ' wis het scherm

LOCATE 10,10

PRINT " Reading "; C$;" ... w a i t !!! ";

 

K& = 1 ' stel de teller op 1

WHILE NOT EOF(1) ' zolang de file niet teneinde is ...

GET #1, K&, Y& ' lees vanuit file 1, het getal op de K&-de plaats en ken het toe aan Y&

IF Y& <> 0 THEN ' hierna wordt het getal Y& ontbonden in vier afzonderlijke bytes...

P%(I&,J%) = Y& MOD &H100

Y& = (Y& - P%(I&,J%)) \ 256 ' opgelet: integer -division !

P%(I&,J%+1) = Y& MOD &H100

Y& = (Y& - P%(I&,J% + 1)) \ 256

P%(I&,J%+2) = Y& MOD &H100

Y& = (Y& - P%(I&,J% + 2)) \ 256

P%(I&,J%+3) = Y& MOD &H100

ELSE ' als Y =0 dan zijn alle bytes 0

P%(I&, J%) = 0

P%(I&, J% + 1) = 0

P%(I&, J% + 2) = 0

P%(I&, J% + 3) = 0

ENDIF

K& = K& + 4 ' de teller wordt 4 eenheden opgeschoven (=8 bytes)

J% = J% + 4

IF J% = 16 THEN I& = I& + 1

J% = J% MOD 16 ' J% telt rij per rij telkens van 0 tot 15

WEND

EINDE& = I& + 1 ' stel de teller een eenheid voorbij de laatste kolom

CLOSE #1

ENDSUB

 

Vorige programma-module doet weliswaar perfekt wat ze hoort te doen, maar, de uitvoering ervan neemt op oudere komputers nogal wat tijd in beslag. Dit komt doordat QB4.5 de I/O-routines nodig voor het inlezen van de gegevens op een ongebufferde wijze uitvoert. Wie over een snelle harddisk of over een grote in hardware uitgevoerde RAM-buffer beschikt zal zich daar wellicht niet zo erg aan storen, maar wanneer je de module op een laptop-XT met floppys gaat gebruiken (de Toshiba T1000 bvb.), dan duurt het opladen van een partituur van zo'n 10 a 15 minuten speelduur gemakkelijk zo'n 4 a 5 minuten... Voor real-time koncertsituaties kunnen musici zich zoiets uiteraard niet veroorloven. Daarom heb ik ook een wat I/O betreft iets sneller alternatief bedacht, waarin via een truukje, een soort I/O-buffer gemaakt wordt. Hiervoor wordt de file in grote mootjes als STRING ingelezen en pas daarna omgezet naar een binair array. Dit alternatief vergt echter beduidend meer processortijd!

 

SUB RDFIL

'procedure om binaire partituurfiles sneller te lezen. I/O tijd is sterk beknot, maar processortijd is

'nu groter dan bij gebruik van de RDFIL_0 module

' over te dragen variabelen zijn : P() AS INTEGER

' ENDCOUNT

' C$ = path + file-name binary file

'ze moeten in een COMMON SHARED statement opgenomen worden in het hoofdprogramma.

DEFLNG X ' dit mag ook in het hoofdprogramma

OPEN C$ FOR INPUT AS #1

X = LOF(1)

DIM P(X \ 16, 15) AS INTEGER: ' (X \ 16) = endcount

' LOF(1) is steeds = ((X\16)*16)+1. Het extra byte is de E.O.F.-marker !

NRBLOK = (X \ (2 ^ 14)): ' aantal volledige blokken van 16kByte in de file

' het maximale maat voor strings in QB is eigenlijk 2^5, maar dan dreigen we een

' out off string space foutmelding te krijgen!

REST = X MOD (2 ^ 14): ' overschot... nu moet X= (NRBLOK * (2^14) ) + REST

I = 0: K = 0: J = 0 ' reset alle tellers naar 0 - pro disciplina

'nu gebeurt het inlezen van de file C$

'eerst wordt het aantal volledige 16kByte blokken ingelezen

DO UNTIL I >= NRBLOK

S$ = INPUT$((2 ^ 14), #1): GOSUB CONVERT: I = I + 1

LOOP

' inlezen resterend aantal bytes in de file...

IF REST > 0 THEN S$ = INPUT$((REST), #1): GOSUB CONVERT

CLOSE #1

ENDCOUNT = (X \ 16)

EXIT SUB

'conversiealgoritme string naar binair

CONVERT:

NRB = LEN(S$): ' aantal bytes in elke string

FOR Y = 1 TO NRB: ' byte-teller

P(K, J) = ASC(MID$(S$, Y, 1)): J = J + 1

IF J = 16 THEN K = K + 1: J = J MOD 16

NEXT Y

S$ = "" ' geheugen opruimen ...

RETURN

END SUB

4. Voordelen van deze programma afspraken...

Wie van hierboven beschreven afspraken gebruik maakt, kan daardoor direkt beschikken over een aantal utilities die uiterst nuttig kunnen zijn :

- DARMS / TOLK

Een programma dat binaire files omzet in DARMS-kode, die direkt in Noteprocessor evenals in heel wat muziekanalyse software gebruikt in de muzikologie, ingebracht kan worden. Dit gebeurt stem per stem. Voor elke stem wordt een afzonderlijke .DOC file gemaakt.

Door dit programma kunnen algoritmisch gemaakte muziekstukken dus direkt in traditionele muzieknotatie worden omgezet. Dit programma werd in 1993 opgenomen als procedure binnen het nog veel algemener bruikbaar vertaalprogramma <TOLK>. Noteprocessor mag vandaag evenwel gelden als eerder verouderd, ondanks het uiterst overzichtelijke kodeformaat (DARMS).

- LINDEC:

Een programma dat toelaat ook DARMS-files aan te maken die geschikt zijn voor notatie in lineaire dekompositie (polyfonie op een enkele notenbalk).

- TRANSPOZE:

een programma dat de stemmen van een muziekstuk korrekt transponeert en daarbij tevens rekening kan houden met de tessituurbegrenzingen van de diverse muziekinstrumenten.

- PLAYER:

Een programma gemaakt om in real-time binaire arrays te kunnen weergeven en waarbij heel wat interpretatie-mogelijkheden bestaan:accelerando, rit., crescendo, dim., orkestratie veranderingen, tutti-ripieno ...

Het programma bevat tot nu toe midi-sturingen voor de Yamaha synthesisers FB01, DX21, TX81Z evenals voor de effekt-apparatuur (pitch- shifters) Yamaha REX50 en Roland SE50 en de synthe-modules van Emu (Proteus-reeks).

- KORAAL:

Een reeks programmas die harmonie schrijven onder of boven een willekeurige stem uit een array. Elk programma uit deze reeks heeft een eigen set regels waarvolgend harmonie wordt geschreven: drieklankenharmonie, vierklanken, spektraalharmonie, symmetrische harmoniesystemen...

-MIDIFILE:

Een programma dat binaire files omzet in gestandaardiseerde midi-files zoals die door sequencers worden gebruikt en gegenereerd. Dit maakt het mogelijk algoritmische stukken met bestaande kommerciele software te kombineren. Het vormt ook een unieke link tussen IBM en Atari machines. Deze konversie verliep vroeger in het programma TOLK hoewel het daar via de omweg van het door CakePro gebruikte ASC en WRK formaat verliep. Sedert 1996 staat de studenten echter ook een rechtstreeks vertaalprogramma naar midi-fileformaat ter beschikking. Het is nu dan ook zonder meer mogelijk geworden je files rechtstreeks in een programma zoals finale te verwerken, waardoor het maken van een professionele partituur een fluitje van een cent kan worden.

Verder in voorbereiding zijn nog volgende programmas:

-KONTRAPUNT:

Een programma dat gegeven een enkele stem, alle andere op kontrapuntische wijze toevoegt.

-VOICING:

Een stemvoerings programma. Voor instrumentatie. (Joachim Brackx & G.-W.Raes)

- Jullie eigen programmas en utilities...

 

2. Extended P-formaat voor partituurarrays

 

Het hiervoor beschreven P%(i&,j%)-koncept dat intussen toch reeds zo'n 15 jaar oud is, heeft uiteraard ook zijn beperkingen. De zwaarst wegende beperking is wellicht de moeilijke uitbreidbaarheid van het formaat buiten de in 1 array bevatbare 7-stemmen. Door de j% pointer vanaf 0 te laten tellen zouden we natuurlijk wel een extra stem krijgen, en uiteraard kunnen we zoveel P(i,j) arrays definieren als we groepen van 8 stemmen nodig hebben, maar het blijft voor zo'n gevallen toch behelpen, o.m. omdat het de kompositiekode onnodig veel langer en komplexer maakt. (Programmeertalen beschikken meestal niet over meta-statements waarmee bvb de naam van een variabele zelf een variabele kan zijn, waardoor we bij het komponeren met een reeks P() arrays geen globalizerende procedures kunnen toepassen.).

Het mooie -en voor de programmeur is dit een droom- is de eenvoud van de tijds-benadering (in vaste inkrementen), waardoor we overal naar believen noten kunnen invoegen zonder telkens het hele array te moeten herberekenen of sorteren zoals dat het geval is wanneer delta-time kodering wordt toegepast. Het 'extended' P-formaat vertrekt in zijn struktuur van dezelfde tijdsbenadering als het P%(i&,j%) formaat, maar is in feite opgebouwd als een verzameling individuele stemmen of tracks: voor elke stem dus een afzonderlijk array. Voor de programmering wordt gebruik gemaakt van een user-defined type variabele. Het prototype of model ervan wordt vooraan in het programma gedeklareerd:

'$ DYNAMIC

CONST MaxSize = 1000

CONST NrTracks = 16

' Hier wordt het prototype voor de user-variabele ExtPij gedeklareerd:

TYPE ExtPij

note(0 TO MaxSize) AS INTEGER

velo(0 TO MaxSize) AS INTEGER

END TYPE

 

Na de deklaraties van alle procedures kan nu het prototype toegepast worden op de partituur die we willen opbouwen. Er wordt in dit geval een array van het type zoals gedefinieerd in ExtPij gedimensioneerd:

DIM SHARED P(1 TO NrTracks) AS ExtPij

De verschillende geheugenlokaties van de partituur worden geschreven zoals in volgend (muzikaal absurde) voorbeeld:

FOR i% = 0 TO MaxSize -1

FOR j% = 1 TO NrTracks

P(j%).note(i%) = 64 + ((j% + i%) MOD 12)

P(j%).velo(i%) = 1 + (i% MOD 84)

NEXT j%

NEXT i%

FOR j%= 1 TO NrTracks

P(j%).note(MaxSize)= P(j%).note(i%-1) :' voorlaatste noot

P(j%).velo(MaxSize) = 0 :' note-off

NEXT j%

Om het voorbeeld volledig te maken, geven we ook een voorbeeld van hoe de uitlezing van de partituur-array in zijn werk gaat:

Het omzetten van 'klassieke' P%(i&,j%) formaat files naar dit 'extended' formaat is heel eenvoudig. Gegeven een P%(i&,j%) array -gemaakt binnen een programma ofwel ingelezen als bestand, dan gebeurt de omzetting alsvolgt:

'$ DYNAMIC

CONST MaxSize = 1000 :' neem UBOUND(P%,1) als waarde

CONST NrTracks = 7 :' neem slechts zoveel als er stemmen in P(i,j) staan.

TYPE ExtPij

note(0 TO MaxSize) AS INTEGER

velo(0 TO MaxSize) AS INTEGER

END TYPE

DIM SHARED P(1 TO NrTracks) AS ExtPij

FOR i% = 0 TO MaxSize

FOR k% = 1 TO NrTracks

j%=((k%-1)*2)+1

P(j%).note(i%) = P%(i%,j%)

P(j%).velo(i%) = P%(i%,j%+1)

NEXT k%

NEXT i%

Na deze operatie kunnen we het geheugen in beslag genomen door het oorspronkelijke P%(i%,j%) array opnieuw vrijmaken met volgende instruktie:

ERASE P%().

Het nieuwe formaat laat ons toe nog heel wat verder te gaan. Zo kunnen we bvb. naast noot-informatie ook pitchbend en real-time controller informatie opslaan:

TYPE ExtPij

note(0 TO MaxSize) AS INTEGER

velo(0 TO MaxSize) AS INTEGER

bend(0 TO MaxSize) AS INTEGER :' 14 bits, msb-lsb

cc1(0 TO MaxSize) AS INTEGER

pan(0 TO MaxSize) AS INTEGER

END TYPE

Maar, we kunnen het ook uitbreiden naar polifonie per stem toe, door de arrays binnen het prototype zelf meerdimensioneel te maken:

TYPE ExtPij

note(0 TO NrVoices,0 TO MaxSize) AS INTEGER

velo(0 TO NrVoices, 0 TO MaxSize) AS INTEGER

pan(0 TO MaxSize) AS INTEGER

END TYPE

Het grote probleem is echter, dat we wanneer we zoveel vrijheid nemen met het array-formaat, we in problemen dreigen te komen bij de opslag op disk van de informatie. In plaats van zelf ook hiervoor een systeem uit te dokteren, hebben we er in dit geval de voorkeur aan gegeven voor de opslag gebruik te maken van het algemeen gebruikelijke en gestandaardizeerde midi-file formaat. De daarvoor noodzakelijke procedures worden verder in deze hoofdstukken uitvoerig behandeld. Je hoeft ze ook niet telkens opnieuw zelf te gaan programmeren: utilities voor de vertaling van P%(i,j) files naar midi-files en procedure kode voor het aanpakken van de omzetting van extented P-arrays naar midifiles hebben we ten behoeve van de studenten uitgewerkt.

Te zijner tijd willen daar ook nog utilities aan toevoegen voor de omgekeerde weg: de omzetting van midi-files naar extended-P. Dit zal echter niet kunnen zonder enig inzicht en inbreng van de gebruiker.

 

Nota 03.02.2009:

omwille van de kompatibiliteit met vroeger gemaakte partituurbestanden is in het vandaag gangbare real-time kompositieprogramma <GMT> een funktie voorzien waarmee die oude bestanden kunnen worden ingelezen. Ze is opgenomen in g_file.bas, gekompileerd in f_file.dll. De export naam van de funktie is ReadPijFile ().


Filedate: [931204 ]

Naar kursus index

Naar homepage dr.Godfried-Willem RAES

Naar P() to Midi-file konversiesoftware