01.10.2014 Views

Download in .pdf-bestand - Hogeschool Gent

Download in .pdf-bestand - Hogeschool Gent

Download in .pdf-bestand - Hogeschool Gent

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

owered by TCPDF (www.tc<strong>pdf</strong>.org)<br />

Academiejaar 2012–2013<br />

Geassocieerde faculteit Toegepaste Ingenieurswetenschappen<br />

Valent<strong>in</strong> Vaerwyckweg 1 – 9000 <strong>Gent</strong><br />

Een webapplicatie voor<br />

geautomatiseerd contrapunt<br />

Masterproef voorgedragen tot het behalen van het diploma van<br />

Master <strong>in</strong> de <strong>in</strong>dustriële wetenschappen: <strong>in</strong>formatica<br />

Robbert MERLIER<br />

Promotoren: dr. Jan CNOPS<br />

dr. ir. Wijnand SCHEPENS (<strong>Hogeschool</strong> <strong>Gent</strong>)


owered by TCPDF (www.tc<strong>pdf</strong>.org)<br />

Academiejaar 2012–2013<br />

Geassocieerde faculteit Toegepaste Ingenieurswetenschappen<br />

Valent<strong>in</strong> Vaerwyckweg 1 – 9000 <strong>Gent</strong><br />

Een webapplicatie voor<br />

geautomatiseerd contrapunt<br />

Masterproef voorgedragen tot het behalen van het diploma van<br />

Master <strong>in</strong> de <strong>in</strong>dustriële wetenschappen: <strong>in</strong>formatica<br />

Robbert MERLIER<br />

Promotoren: dr. Jan CNOPS<br />

dr. ir. Wijnand SCHEPENS (<strong>Hogeschool</strong> <strong>Gent</strong>)


Voorwoord<br />

i<br />

Voorwoord<br />

Deze masterproef is het e<strong>in</strong>dresultaat van een vierjarige opleid<strong>in</strong>g toegepaste <strong>in</strong>genieurswetenschappen<br />

<strong>in</strong> de <strong>in</strong>formatica aan <strong>Hogeschool</strong> <strong>Gent</strong>. Het onderwerp is samen met dr. ir. Wijnand<br />

Schepens samengesteld uit een gemeenschappelijke <strong>in</strong>teresse voor muziek en muziekcompositie.<br />

Dit is dan ook de eerste persoon die ik zou willen bedanken. Voor de technische<br />

en morele steun <strong>in</strong> het project en voor de diepere <strong>in</strong>zichten <strong>in</strong> zowel de muziektheorie als<br />

<strong>in</strong>formaticasystemen die erbij gebruikt worden.<br />

Verder wil ik ook mijn <strong>in</strong>terne begeleider, dr. Jan Cnops, bedanken voor de verdere <strong>in</strong>zichten<br />

<strong>in</strong> het project en om mij op schema te houden.<br />

Verder ook nog een woord van dank een mijn vrienden aan Ho<strong>Gent</strong>: V<strong>in</strong>cent, Martijn en<br />

Ruben, die altijd klaar stonden om samen te werken aan onze respectievelijke thesis en om<br />

me gezelschap te houden <strong>in</strong> deze anders eenzame periode.<br />

Een academische opleid<strong>in</strong>g voltooien gaat natuurlijk ook moeilijk zonder de onvoorwaardelijke<br />

steun van mijn ouders. Voor het nalezen en advies van de scriptie maar ook om mij moed <strong>in</strong><br />

te spreken <strong>in</strong> moeilijkere tijden doorheen de jaren.<br />

- Robbert Merlier, 30/05/2013


Abstract<br />

ii<br />

Abstract<br />

Contrapunt is een oude techniek om klassieke muziek te schrijven. Het doel van dit project<br />

is om de beg<strong>in</strong>selen van het contrapunt te automatiseren zodat oefen<strong>in</strong>gen gecontroleerd en<br />

zelfs (deels) opgelost kunnen worden aan de hand van contrapuntregels die de gebruiker zelf<br />

oplegt. Die regels kunnen de klassieke regels zijn of regels die de gebruiker zelf heeft opgesteld.<br />

Dit alles wordt beschikbaar gemaakt via een website om de drempel naar de gebruiker toe te<br />

verlagen.<br />

Het uite<strong>in</strong>delijke resultaat (<strong>in</strong> testopstell<strong>in</strong>g) kan (bijna) ogenblikkelijk muziekstukken controleren<br />

en genereren. Het genereren gebeurt via het genetisch algoritme. De testopstell<strong>in</strong>g werkt<br />

met een (relatief) we<strong>in</strong>ig aantal regels waardoor het moeilijk is effectief te zien of het algoritme<br />

ook goed zal werken met grotere regelsets. De backtrack<strong>in</strong>gmethode ziet er veelbelovend uit<br />

als er veel regels zijn die de zoekruimte kunnen voorspellen <strong>in</strong> meerdere doorlopen.


Inhoudsopgave<br />

iii<br />

Inhoudsopgave<br />

Voorwoord<br />

Abstract<br />

Inhoudsopgave<br />

i<br />

ii<br />

iii<br />

1 Inleid<strong>in</strong>g 1<br />

1.1 Bestaande situatie en doelstell<strong>in</strong>g van het project . . . . . . . . . . . . . . . . 1<br />

1.2 Gebruikte technologieën . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />

2 Contrapunt 3<br />

2.1 Wat is contrapunt? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

2.2 Soorten contrapunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

2.2.1 Streng contrapunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

2.2.2 Vrij contrapunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

2.3 De klassieke regels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

2.3.1 Termen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

2.3.2 Algemene regels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.3.3 Regels voor het contrapunt van de eerste soort . . . . . . . . . . . . . 7<br />

2.4 Toepass<strong>in</strong>g <strong>in</strong> het project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

3 Architectuur 9<br />

3.1 Volledige architectuur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

3.2 Servertechnologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />

3.3 Webtechnologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

3.4 Communicatietechnologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

4 Server- en communicatieformaten 12<br />

4.1 Representatie van noten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

4.1.1 Lengte van een noot . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

4.1.2 Hoogte van een noot . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

4.2 Representatie van een muziekstuk . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

4.2.1 Representatie van een muziekstuk op de server . . . . . . . . . . . . . 16<br />

4.2.2 Communicatieformaten . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

4.2.3 Webrepresentaties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20


Inhoudsopgave<br />

iv<br />

5 Website 22<br />

5.1 Websitestructuur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

5.2 VexFlow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

6 Server side 29<br />

6.1 Representatie van regels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

6.1.1 Algemene <strong>in</strong>terface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

6.1.2 Voorspellende regels . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

6.2 Controleren van regels op een stuk . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

6.3 Genereren van noten aan de hand van regels . . . . . . . . . . . . . . . . . . . 32<br />

6.3.1 Random configuraties . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

6.3.2 Semi-random configuraties . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

6.3.3 Alles uitproberen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

6.3.4 Backtrack<strong>in</strong>g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

6.3.5 Optimalisatieprobleem . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

6.4 Aparte noten, <strong>in</strong> plaats van een volledige stem genereren . . . . . . . . . . . . 37<br />

7 Slot 38<br />

7.1 Serverkant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

7.2 Webapplicatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

7.3 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

Lijst van figuren 40<br />

Lijst van tabellen 41<br />

Bibliografie 42<br />

A Hewlett base40 systeem 43


Inleid<strong>in</strong>g 1<br />

Hoofdstuk 1<br />

Inleid<strong>in</strong>g<br />

1.1 Bestaande situatie en doelstell<strong>in</strong>g van het project<br />

Vandaag de dag wordt er <strong>in</strong> de compositietak van de klassieke muziektheorie nog veel met de<br />

hand gewerkt. Muziekstukken worden gecomponeerd via bepaalde regels (contrapunt, harmonie)<br />

en als die regels strikt gevolgd worden weet de componist zeker dat alles goed zal kl<strong>in</strong>ken.<br />

Soms wordt er ook (systematisch) afgeweken van bepaalde regels omdat men ondervonden<br />

heeft dat dit een speciale klank geeft die (sommige) mensen wel weten te appreciëren. Als<br />

men dan lang genoeg bezig is met het maken van muziek, hebben sommige mensen dan iets<br />

wat men beschrijft als een gevoel voor muziek. Men hoort de muziek al <strong>in</strong> het hoofd van voor<br />

het nog op papier (of op de computer) staat. De componist heeft zijn eigen stijl gemaakt door<br />

systematisch de vooropgestelde regels toe te passen, sommige regels systematisch te negeren<br />

en voor zichzelf regels (beter gezegd een gevoel) op te stellen.<br />

Uit het idee om dit systeem te automatiseren is dit project ontstaan. Het eerste doel <strong>in</strong> dit<br />

project is om, via de klassieke contrapuntregels, te controleren of een muziekstuk wel voldoet.<br />

Daarna zullen regels niet meer vast zijn. Dit wil zeggen dat de gebruiker bepaalde regels kan<br />

aan- of afzetten en zelfs zelf regels def<strong>in</strong>iëren. Verder zal gepoogd worden om bij een bestaande<br />

muziekstem een tweede te zoeken, die aan de regels, die de gebruiker heeft gekozen, voldoet.<br />

Dit alles gebeurt <strong>in</strong> de eerste contrapuntsoort met twee stemmen (zie hoofdstuk 2 op pag<strong>in</strong>a<br />

3). Verdere uitbreid<strong>in</strong>gen <strong>in</strong> het project zijn om het aantal stemmen uit te breiden en andere<br />

ritmes toe te laten (zie punt 2.2).<br />

1.2 Gebruikte technologieën<br />

De applicatie is ruwweg opgedeeld <strong>in</strong> twee stukken. De <strong>in</strong>terface met de gebruikers en de<br />

serverkant, waar het zware werk wordt verricht. We kiezen ervoor om de <strong>in</strong>terface naar de<br />

gebruikers toe ter beschikk<strong>in</strong>g te stellen via een website (HTML en JavaScript), de serverkant<br />

is opgebouwd uit gewone javaklassen, <strong>in</strong>terfaces, ... en om alles met elkaar te laten<br />

communiceren is er een RESTful webservice (met behulp van JAX-RS).<br />

Het meest uitdagende deel op de website is het weergeven (en afspelen) van muzieknoten.<br />

Hiervoor is er een JavaScript API, VexFlow genaamd, die dit kan ondersteunen. De rest van


1.2 Gebruikte technologieën 2<br />

de website is vooral HTML en veel JavaScript. Meer <strong>in</strong>formatie omtrent de technologieën van<br />

de site is te v<strong>in</strong>den <strong>in</strong> hoofdstuk 5.<br />

Verder, aan de serverkant, is het de bedoel<strong>in</strong>g dat alles zo voorgesteld wordt dat er zo we<strong>in</strong>ig<br />

mogelijk overhead geproduceerd wordt. Dit om de efficiëntie ten goede te komen. Een ook niet<br />

te onderschatten onderdeel is het systeem dat de regels bevat en de systemen om uite<strong>in</strong>delijk<br />

de regels toe te passen op het muziekstuk voor het te controleren of om zelfs muziek te<br />

genereren. Meer hierover <strong>in</strong> hoofdstuk 6.<br />

Het volledige samenwerkende systeem wordt kort doorgelicht <strong>in</strong> hoofdstuk 3.


Contrapunt 3<br />

Hoofdstuk 2<br />

Contrapunt<br />

2.1 Wat is contrapunt?<br />

Contrapunt is een muziektheoretische term, afgeleid van het Latijnse punctus contra punctum,<br />

wat zoveel betekent als noot tegen noot. Hierbij is het de kunst om, bij een gegeven stem,<br />

de cantus firmus (wat zoveel als “vaste zang” betekent, afgekort als c.f.), één of meerdere<br />

stemmen te creëren die erbij passen. Dit gebeurt uit een horizontaal standpunt (waar de<br />

klassieke harmonieleer uit een verticaal standpunt, dus akkoordprogressies, vertrekt). Het is<br />

dus de bedoel<strong>in</strong>g dat alle stemmen apart heel verschillend kl<strong>in</strong>ken en bewegen en dat ze samen<br />

toch goed kl<strong>in</strong>ken. Het contrapunt focust zicht op een wisselwerk<strong>in</strong>g tussen de stemmen,<br />

een wisselwerk<strong>in</strong>g tussen consonanten (samenkl<strong>in</strong>kend, muzikale ontspann<strong>in</strong>g) en dissonanten<br />

(niet welluidend, muzikale spann<strong>in</strong>g). Gerelateerde muziekgenres zijn onder andere het rondo,<br />

de canon en de fuga.<br />

2.2 Soorten contrapunt<br />

Contrapunt kan vooreerst <strong>in</strong> twee groepen onderverdeeld worden, namelijk het strenge en het<br />

vrije contrapunt. Het strenge contrapunt is onderworpen aan strenge ritmische regels terwijl<br />

<strong>in</strong> het vrije contrapunt de muziek een comb<strong>in</strong>atie van de strenge regels kan zijn of er zelfs van<br />

kan loskomen.<br />

2.2.1 Streng contrapunt<br />

In het strenge contrapunt zijn er vier klassieke soorten:<br />

1. Eén noot tegen één noot (figuur 2.1). Hierbij is er we<strong>in</strong>ig sprake van ritme. Er zijn<br />

evenveel noten <strong>in</strong> elke stem en die noten zijn allemaal evenlang.<br />

2. Twee noten tegen één (figuur 2.2). Hierbij worden er boven (onder) één noot van de<br />

ene stem twee gezet <strong>in</strong> de andere.<br />

3. Vier (of drie) noten tegen één (figuur 2.3). Naar analogie met de tweede soort zijn er<br />

<strong>in</strong> een stem vier (of drie) noten boven (of onder) de andere stem.<br />

4. Overgebonden halfbeweg<strong>in</strong>g (figuur 2.4). Hierbij worden er <strong>in</strong> een stem overal syncopen<br />

gebruikt tegenover het gewone ritme <strong>in</strong> de andere stem. De staart van de syncope kan<br />

op die manier dissonant worden om meer spann<strong>in</strong>g <strong>in</strong> het stuk te steken.


2.2 Soorten contrapunt 4<br />

Figuur 2.1: Streng contrapunt van de eerste soort<br />

Figuur 2.2: Streng contrapunt van de tweede soort<br />

Figuur 2.3: Streng contrapunt van de derde soort<br />

Figuur 2.4: Streng contrapunt: overgebonden halfbeweg<strong>in</strong>gen


2.3 De klassieke regels 5<br />

2.2.2 Vrij contrapunt<br />

In het vrije contrapunt (ook wel bloemrijk contrapunt) mag het ritme van de stem een comb<strong>in</strong>atie<br />

maken van de regels van het strenge contrapunt of zelfs loskomen van die regels. (figuur<br />

2.5)<br />

Figuur 2.5: Vrij contrapunt<br />

2.3 De klassieke regels<br />

2.3.1 Termen<br />

Alvorens de klassieke regels uit de doeken te doen zijn er eerst wat termen die verklaard<br />

moeten worden.<br />

Consonanten en dissonanten<br />

Onder consonanten verstaat men twee of meer noten die mooi samen kl<strong>in</strong>ken, <strong>in</strong> perfecte<br />

harmonie. Dissonanten daar<strong>in</strong>tegen kl<strong>in</strong>ken harmonisch niet samen maar worden soms toch<br />

gebruikt om een muzikale spann<strong>in</strong>g te creëren. Er zijn twee soorten consonanten: de perfecte<br />

en de imperfecte. In de literatuur worden perfecte consonanten als volledig bevredigend voor<br />

het oor en imperfecte als niet volledig bevredigend voor het oor beschreven. Dat dit een<br />

subjectieve omschrijv<strong>in</strong>g is, is wel duidelijk. Een meer wetenschappelijke verklar<strong>in</strong>g zit hem<br />

<strong>in</strong> het feit dat de <strong>in</strong>tervallen die als perfect consonant omschreven zijn dichter <strong>in</strong> de boventoonreeks<br />

zitten van de basisnoot dan de <strong>in</strong>tervallen die als imperfect omschreven worden, en<br />

dus fysisch gezien beter bij elkaar zullen kl<strong>in</strong>ken.<br />

De perfecte consonanten (zie figuur 2.6) zijn het unisono, het octaaf en de re<strong>in</strong>e kw<strong>in</strong>t. De<br />

Figuur 2.6: Perfecte consonanten, respectievelijk het unisono, het octaaf en de re<strong>in</strong>e kw<strong>in</strong>t<br />

imperfecte consonanten (zie figuur 2.7) zijn onder andere de grote en kle<strong>in</strong>e terts en grote en<br />

kle<strong>in</strong>e sext. De laatste groep, de dissonanten(zie figuur 2.8) zijn de grote en kle<strong>in</strong>e secunde,


2.3 De klassieke regels 6<br />

Figuur 2.7: Imperfecte consonanten, respectievelijk de grote terts, kle<strong>in</strong>e terts, grote sext en kle<strong>in</strong>e<br />

sext<br />

de kwart, de vermeerderde kwart en verm<strong>in</strong>derde kw<strong>in</strong>t en de grote en kle<strong>in</strong>e septiem. De<br />

Figuur 2.8: Dissonanten, respectievelijk de grote en kle<strong>in</strong>e secunde, kwart, vermeerderde kwart en<br />

verm<strong>in</strong>derde kw<strong>in</strong>t, grote en kle<strong>in</strong>e septiem<br />

vermeerderde kwart en de verm<strong>in</strong>derde kw<strong>in</strong>t zijn enharmonisch equivalent. Beide zijn <strong>in</strong>tervallen<br />

van zes halve tonen (drie volledige tonen), dit wordt ook wel een tritonus genoemd.<br />

Als men op een piano (na Bach’s wohltemperierte Klavier) de beide <strong>in</strong>tervallen zou spelen<br />

zou men tweemaal hetzelfde spelen. Er wordt <strong>in</strong> de muziektheorie wel een verschil gemaakt<br />

tussen de twee omdat ze een verschillende betekenis hebben <strong>in</strong> de toonaard van het stuk.<br />

Beweg<strong>in</strong>gen<br />

Als men twee muziekstemmen tegenover elkaar zet kan men een aantal soorten progressies<br />

hebben. Er is de parallelle beweg<strong>in</strong>g, de tegenbeweg<strong>in</strong>g of oblique beweg<strong>in</strong>g (geen beweg<strong>in</strong>g).<br />

Voorbeelden van deze <strong>in</strong> figuur 2.9.<br />

Figuur 2.9: Nootprogressies, respectievelijk de tegenbeweg<strong>in</strong>g, parallelle beweg<strong>in</strong>g en oblique beweg<strong>in</strong>g<br />

2.3.2 Algemene regels<br />

De algemene regels van contrapunt duiden op de relatie tussen de verschillende beweg<strong>in</strong>gen van<br />

en naar de verschillende consonanten (dissonanten worden niet toegelaten). Johann Joseph<br />

Fux beschrijft de volgende regels:


2.3 De klassieke regels 7<br />

1. om van een perfecte naar een perfecte consonant te gaan moet men <strong>in</strong> tegenbeweg<strong>in</strong>g<br />

of oblique beweg<strong>in</strong>g gaan,<br />

2. van een perfecte naar imperfecte consonant gaan mag via gelijk welke van de drie beweg<strong>in</strong>gen,<br />

3. naar een perfecte consonant vanaf een imperfecte gaan mag enkel <strong>in</strong> tegenbeweg<strong>in</strong>g of<br />

<strong>in</strong> oblique beweg<strong>in</strong>g,<br />

4. van een imperfecte naar een imperfecte consonant gaan mag via elke beweg<strong>in</strong>g.<br />

Als men de regels aandachtig bekijkt komt dit eigenlijk neer op de volgende regel:<br />

• Elke beweg<strong>in</strong>g is toegelaten behalve een parallelle beweg<strong>in</strong>g naar een perfecte consonant<br />

toe. Dit mag niet omdat, als men het <strong>in</strong>terval zou ontleden, men op een (weliswaar<br />

verborgen) parallelle kw<strong>in</strong>t of parallel octaaf zou uitkomen, wat een holle, onvolledige<br />

klank oplevert.<br />

2.3.3 Regels voor het contrapunt van de eerste soort<br />

Fux beschrijft twee soorten regels: de harde en de zachte. Harde regels mogen onder geen<br />

omstandigheden gebroken worden terwijl zachte wel mogen gebroken worden als dit kan vermijden<br />

dat een harde regel gebroken wordt. De basisregels worden aanzien als harde regels.<br />

Harde regels:<br />

1. Enkel consonanten worden toegelaten.<br />

2. Tegenover elke noot <strong>in</strong> de c.f. staat een noot <strong>in</strong> de contrapuntlijn.<br />

3. Er worden enkel noten die passen <strong>in</strong> de toonaard gebruikt. (Ook de tessituur van de<br />

zangstem moet gerespecteerd worden.)<br />

4. Het eerste en het laatste <strong>in</strong>terval moeten perfecte consonanten zijn. (In de literatuur<br />

v<strong>in</strong>dt men soms dat het laatste <strong>in</strong>terval een unisono of een octaaf moet zijn.)<br />

5. Het voorlaatste <strong>in</strong>terval is een kle<strong>in</strong>e sext (als de c.f. <strong>in</strong> de lage stem staat) of een<br />

kle<strong>in</strong>e terts (als de c.f. <strong>in</strong> de hoge stem staat). Dit kan ook opgevat worden als dat de<br />

laatste noot van het contrapunt moet vooraf gegaan worden door een kle<strong>in</strong>e secunde<br />

naar omhoog (de leidtoon dus).<br />

6. Sprongen groter dan de (kle<strong>in</strong>e) sext zijn verboden (behalve het octaaf) alsook sprongen<br />

naar vermeerderde en verm<strong>in</strong>derde <strong>in</strong>tervallen (dus ook de tritonus), en sprongen naar<br />

de septiem.<br />

Zachte regels:<br />

1. Een noot mag niet meer dan drie keer blijven liggen.<br />

2. Als er twee sprongen na elkaar komen (wat al zelden voorkomt), mogen die samen het<br />

octaaf niet overschrijden. Verder moeten de twee sprongen dan <strong>in</strong> dezelfde richt<strong>in</strong>g zijn.<br />

Ook moet de eerste sprong groter zijn dan de tweede als de sprongen allebei naar boven<br />

gaan. Indien de sprongen beide naar beneden gaan, komt de kle<strong>in</strong>ere voor de grotere<br />

sprong. Er mogen niet meer dan twee sprongen na elkaar komen.


2.4 Toepass<strong>in</strong>g <strong>in</strong> het project 8<br />

3. Een sprong moet gevolgd worden door een noot die <strong>in</strong> de andere richt<strong>in</strong>g beweegt.<br />

4. Hetzelfde harmonisch <strong>in</strong>terval mag niet meer dan drie keer na elkaar komen.<br />

2.4 Toepass<strong>in</strong>g <strong>in</strong> het project<br />

Bovenstaande regels (en de gebruikergedef<strong>in</strong>ieerde regels) worden gebruikt voor het controleren<br />

en genereren van muziek. Daarom is het noodzakelijk deze regels te omvatten <strong>in</strong> een<br />

bruikbaar softwaremodel. Als men er goed naar kijkt, zijn het allemaal regels die te maken<br />

hebben met <strong>in</strong>tervallen: bepaalde <strong>in</strong>tervallen (tussen twee stemmen) toelaten of afstraffen,<br />

het <strong>in</strong>terval tussen twee opeenvolgende noten beperken, een noot dat tussen een vooropgesteld<br />

<strong>in</strong>terval moet zitten, . . . Dit vereenvoudigt de zaak om regels te def<strong>in</strong>iëren <strong>in</strong> een softwaremodel.<br />

Een uitvoerige besprek<strong>in</strong>g van het softwaremodel (waar ook gebruikergedef<strong>in</strong>ieerde<br />

regels mogelijk zijn) gebeurt <strong>in</strong> punt 6.1 (pag<strong>in</strong>a 29).


Architectuur 9<br />

Hoofdstuk 3<br />

Architectuur<br />

In dit hoofdstuk worden de basisideeën en pr<strong>in</strong>cipes kort toegelicht. Deze worden <strong>in</strong> volgende<br />

hoofdstukken verder uitgewerkt.<br />

3.1 Volledige architectuur<br />

Het volledige samenwerkende model is te zien <strong>in</strong> figuur 3.1 en is opgebouwd uit drie grote<br />

delen: de serverkant, de kant van de webapplicatie en de communicatie tussen applicatie en<br />

server.<br />

WebApp (client)<br />

ArrayModel<br />

Object geörienteerd model<br />

1<br />

json<br />

Checker/<br />

Improver<br />

9<br />

6<br />

5<br />

4<br />

10<br />

json<br />

12<br />

2<br />

7 8<br />

Rules<br />

(hardcoded/<br />

userdef<strong>in</strong>ed)<br />

RESTful webservice<br />

11<br />

Controller<br />

3<br />

get rules<br />

create ruleset<br />

Figuur 3.1: Het samenwerkende model


3.2 Servertechnologie 10<br />

De samenwerk<strong>in</strong>g tussen de delen zit als volgt <strong>in</strong> elkaar:<br />

1. De client doet een aanvraag aan de webservice. De aanvraag wordt vergezeld van wat<br />

<strong>in</strong>formatie <strong>in</strong> json-formaat. Die <strong>in</strong>formatie is bijvoorbeeld het te controleren stuk bij<br />

een aanvraag om een stuk te controleren. Ook de de regels worden (met behulp van<br />

hun unieke identifier) meegegeven met de aanvraag. Hoe de <strong>in</strong>formatie er uit moet zien<br />

staat beschreven <strong>in</strong> enkele wrappers.<br />

2. De webservice die de aanvraag b<strong>in</strong>nenkrijgt vormt de json om naar een java-object, en<br />

haalt er de nodige <strong>in</strong>formatie uit. Indien nodig wordt de <strong>in</strong>formatie geconverteerd naar<br />

het juiste formaat. Daarna geeft de webservice de aanvraag door aan de controller.<br />

3. Het eerste wat de controller doet is een regelset creëren aan de hand van de meegegeven<br />

id’s. Hij haalt de regels op uit een repository die alle regels kent.<br />

4. Als alle <strong>in</strong>formatie <strong>in</strong> de juiste vorm staat en aangemaakt is maakt de controller een<br />

manipulator aan (een Checker of een Improver) afhankelijk van het soort contrapunt.<br />

Aan de manipulator wordt gevraagd de bereken<strong>in</strong>gen te maken op het muziekstuk aan<br />

de hand van de gegeven regelset.<br />

5. Om regels toe te passen heeft de manipulator gecodeerde noten nodig. Deze vraagt hij<br />

aan het muziekstuk.<br />

6. Afhankelijk of het muziekstuk ook een matrixmodel heeft of niet kunnen de gecodeerde<br />

noten direct of dynamisch berekend worden weergegeven.<br />

7. Het muziekstuk geeft de gecodeerde noten door aan de regel die de manipulator heeft<br />

opgelegd.<br />

8. De regel berekent een RuleRat<strong>in</strong>g en geeft die terug aan het muziekstuk.<br />

9. Het muziekstuk geeft het resultaat terug aan de manipulator. Na dat (eigenlijk tijdens)<br />

alle regels zijn gebruikt door de manipulator wordt een antwoord-muziekstuk opgesteld.<br />

Dit bevat aangepaste noten (door noten te veranderen, commentaar bij te schrijven, . . .<br />

afhankelijk wat de aanvraag was).<br />

10. De controller geeft alles terug door aan de webservice.<br />

11. En die zet alles terug om <strong>in</strong> een json-formaat dat leesbaar is door de client.<br />

12. Dit antwoord wordt dan terug doorgestuurd naar de <strong>in</strong>itiële aanvrager.<br />

In de volgende stukken van dit hoofdstuk bespreken we kort welke technologieën gebruikt<br />

worden voor de drie delen.<br />

3.2 Servertechnologie<br />

De server is volledig geschreven <strong>in</strong> java en de <strong>in</strong>terface naar buiten toe gebeurt via een RESTful<br />

webservice. Die webservice berust op de JAX-RS API. De serverkant wordt verder besproken<br />

<strong>in</strong> hoofdstuk 6.


3.3 Webtechnologie 11<br />

3.3 Webtechnologie<br />

Aangezien de server een RESTful webservice is, zijn er geen al te complexe technologieën<br />

nodig voor de webapplicatie. De user <strong>in</strong>terface en opmaak van de website zijn opgebouwd<br />

met behulp van standaard HTML5 en CSS. Om functionaliteit toe te voegen wordt gebruik<br />

gemaakt van JavaScript aangevuld met jQuery.<br />

Om muzieknoten weer te geven en af te spelen wordt gebruik gemaakt van een JavaScript<br />

API: VexFlow (Muthanna, 2013b). Meer hierover <strong>in</strong> hoofdstuk 5.<br />

3.4 Communicatietechnologie<br />

De communicatie tussen de webservice en de website steunt op Ajax calls. De gegevens worden<br />

uitgewisseld <strong>in</strong> een json-formaat.


Server- en communicatieformaten 12<br />

Hoofdstuk 4<br />

Server- en communicatieformaten<br />

Elk <strong>in</strong>dividueel onderdeel van het project werkt weliswaar met (ongeveer) dezelfde gegevens<br />

maar behandelt die anders. Daarom is het ook logisch voor elk deel een gepaste representatie<br />

van de gegevens te gebruiken. Er wordt eerst algemeen <strong>in</strong>gegaan <strong>in</strong> het representeren van<br />

muzieknoten. Iets dat, op het eerste zicht, niet zo moeilijk lijkt maar toch wat meer voeten<br />

<strong>in</strong> de aarde heeft. Daarna worden noten samengenomen <strong>in</strong> een muziekstukrepresentatie. Er<br />

zijn representaties voor de serverkant, voor de website en representaties die de communicatie<br />

vergemakkelijken. Verder zijn er ook manieren nodig om de regels (van het contrapunt) aan<br />

te duiden, voor te stellen en door te geven tussen website en webservice.<br />

4.1 Representatie van noten<br />

Een muzieknoot efficiënt representeren <strong>in</strong> een computersysteem heeft vele voeten <strong>in</strong> de aarde.<br />

Zo moet er een systeem bestaan om de lengte van de noten efficiënt weer te geven zodat er<br />

gemakkelijk bereken<strong>in</strong>gen op kunnen gebeuren, er is een systeem nodig om met verschillende<br />

toonhoogten (pitch) te kunnen rekenen omdat er <strong>in</strong> het systeem voor controle en generatie<br />

veel met <strong>in</strong>tervallen gewerkt wordt.<br />

4.1.1 Lengte van een noot<br />

Gebruikelijk wordt de lengte van een muzieknoot voorgesteld als een breuk. Zo heb je hele<br />

noten, halve noten, kwartnoten, . . . Die noten kunnen dan ook nog gepunt (hun waarde<br />

wordt met 50% vermeerderd), dubbel gepunt, tripel gepunt, . . . zijn. Ook kunnen triolen<br />

voorkomen. Dit wil zeggen als bijvoorbeeld drie kwartnoten worden samengenomen als triool,<br />

dat ze samen de waarde van twee kwartnoten hebben. (Dus: een triool heeft slechts 2/3 van<br />

zijn voorgestelde lengte).<br />

In de <strong>in</strong>formatica is het idee om zulk een systeem te gebruiken compleet uit den boze omdat<br />

het rekenen met lengtes van noten niet erg efficiënt is. Wat wel regelmatig gebruikt wordt<br />

<strong>in</strong> programma’s die met muziek werken is alle lengtes van noten vermenigvuldigen met 192.<br />

De kle<strong>in</strong>ste waarde die hiermee voorgesteld kan worden is een 1/128 trioolnoot (wat ruim<br />

voldoende is). De grootste waarde is theoretisch onbeperkt. Op die manier kan men een<br />

mapp<strong>in</strong>g opstellen zoals <strong>in</strong> tabel 4.1.<br />

Een ander voordeel aan dit systeem is dat men gemakkelijk triolen kan herkennen. Als de rest


4.1 Representatie van noten 13<br />

noot naam waarde gepunte waarde trioolwaarde<br />

hele noot 192 288 128<br />

halve noot 96 144 64<br />

kwartnoot 48 72 32<br />

achtste noot 24 36 16<br />

zestiende noot 12 18 8<br />

32 ste noot 6 9 4<br />

64 ste noot 3 - 2<br />

128 ste noot - - 1<br />

Tabel 4.1: Mapp<strong>in</strong>g van base192 op nootlengte


4.1 Representatie van noten 14<br />

na delen door drie nul is dan is de noot geen triool! Dit is handig omdat om triolen visueel<br />

weer te geven meestal een aantal extra acties vereist zijn.<br />

4.1.2 Hoogte van een noot<br />

De hoogte van een noot is bepaald door drie factoren: zijn rangklasse (do, re, mi, fa, sol,<br />

la of si), zijn register (het octaaf waar de noot <strong>in</strong> zit) en een modificator (wijzig<strong>in</strong>gsteken).<br />

Om dit <strong>in</strong> software te representeren zou men met een gewone klasse kunnen werken en daar<br />

de drie attributen <strong>in</strong> steken. Het berekenen van <strong>in</strong>tervallen zou dan neerkomen op een trage<br />

vergelijk<strong>in</strong>gsoperatie tussen twee noten.<br />

In een iets beter systeem wordt een noot voorgesteld door twee getallen: een getal voor zijn<br />

rang (met het octaaf <strong>in</strong>gerekend) en een getal voor zijn wijzig<strong>in</strong>gsteken. Dit is eigenlijk een<br />

systeem dat elke noot voorstelt als een <strong>in</strong>terval vanaf een bepaalde noot (meestal gebruikt men<br />

C 0 als basis). Dit betekent dat <strong>in</strong>tervallen via dit systeem ook kunnen voorgesteld worden<br />

door twee gehele getallen: men neemt de laagste noot als basis en bekijkt dan hoeveel hoger<br />

de hogere noot van de twee ligt. Er zijn wel nadelen aan dit systeem (buiten het feit dat<br />

het twee getallen zijn, die dus moeten <strong>in</strong>gekapseld worden <strong>in</strong> tenm<strong>in</strong>ste een struct). Eén<br />

van die nadelen is dat de naamgev<strong>in</strong>g <strong>in</strong> de klassieke muziek niet altijd overeenkomt met de<br />

voorstell<strong>in</strong>g, meer bepaald het getal dat toegekend wordt voor de wijzig<strong>in</strong>g van het <strong>in</strong>terval<br />

(grote, kle<strong>in</strong>e, verm<strong>in</strong>derde, . . . <strong>in</strong>tervallen). Dit staat geïllustreerd <strong>in</strong> tabel 4.2. Zoals daar<br />

te zien is is er een probleem bij de verm<strong>in</strong>derde <strong>in</strong>tervallen. De tonale <strong>in</strong>tervallen (unisono,<br />

kwart, kw<strong>in</strong>t, octaaf, ...) kunnen niet als groot of kle<strong>in</strong> aanzien worden. Aangezien bij de<br />

modale <strong>in</strong>tervallen (secunde, terts, sext, septiem,...) de modifier van het kle<strong>in</strong>e <strong>in</strong>terval −1<br />

is, komen de modifiers voor verm<strong>in</strong>derde <strong>in</strong>tervallen van tonale en modale <strong>in</strong>tervallen niet<br />

overeen. Een ander nadeel is terug dat het berekenen van <strong>in</strong>tervallen niet optimaal is.<br />

Een ander systeem om de hoogte van noten en grootte van <strong>in</strong>tervallen aan te duiden zou een<br />

modulo-12 (er zijn 12 halve tonen <strong>in</strong> een octaaf) systeem kunnen zijn. Elke noot van het<br />

octaaf stelt dan één getal voor en octaveren is gewoon de huidige nootwaarde plus 12 doen.<br />

Qua <strong>in</strong>tervallen is een terts dan 4, een re<strong>in</strong>e kw<strong>in</strong>t 7, . . . Het grote voordeel aan dit systeem<br />

is dat elke toonhoogte wordt voorgesteld door één enkel geheel getal en dus heel efficiënt<br />

kan opgeslagen en gemanipuleerd worden. Het nadeel van dit systeem is dat bijvoorbeeld<br />

een vermeerderde terts en een re<strong>in</strong>e kwart voorgesteld worden als hetzelfde nummer (5 <strong>in</strong><br />

dit geval) terwijl, als deze gebruikt worden <strong>in</strong> een muziekstuk, ze een verschillende functie<br />

hebben.<br />

Een beter systeem om dit te doen is al lang bekend, namelijk een systeem met basis 40,<br />

voorgesteld door Walter B. Hewlett <strong>in</strong> 1986.<br />

Het modulo-40 representatiesysteem voor toonhoogte maakt het mogelijk om <strong>in</strong>formatie<br />

over toonhoogte <strong>in</strong> te kapselen <strong>in</strong> een enkel nummer, waar het verschil<br />

tussen twee toonhoogtes het correcte <strong>in</strong>terval bepaalt tussen de twee toonhoogtes.<br />

(Hewlett, 1992)<br />

Het modulo-40 systeem zorgt er dus voor dat met toonhoogtes kan gerekend worden waarbij<br />

er reken<strong>in</strong>g gehouden wordt dat bijvoorbeeld een vermeerdere septiem niet hetzelfde is als<br />

een octaaf (al kl<strong>in</strong>ken ze wel hetzelfde). Het volledige systeem is weergegeven <strong>in</strong> bijlage A.


4.1 Representatie van noten 15<br />

Interval soort rang modifier<br />

unisono re<strong>in</strong> / perfect 0 0<br />

verm<strong>in</strong>derd 0 -1<br />

vergroot / overmatig 0 +1<br />

secunde kle<strong>in</strong> 1 -1<br />

groot 1 0<br />

verm<strong>in</strong>derd 1 -2<br />

vergroot / overmatig 1 +1<br />

terts kle<strong>in</strong> 2 -1<br />

groot 2 0<br />

verm<strong>in</strong>derd 2 -2<br />

vergroot / overmatig 2 +1<br />

kwart re<strong>in</strong> 3 0<br />

verm<strong>in</strong>derd 3 -1<br />

vergroot / overmatig 3 +1<br />

kw<strong>in</strong>t re<strong>in</strong> 4 0<br />

verm<strong>in</strong>derd 4 -1<br />

vergroot / overmatig 4 +1<br />

sext kle<strong>in</strong> 5 -1<br />

groot 5 0<br />

verm<strong>in</strong>derd 5 -2<br />

vergroot / overmatig 5 +1<br />

septiem kle<strong>in</strong> 6 -1<br />

groot 6 0<br />

verm<strong>in</strong>derd 6 -2<br />

vergroot / overmatig 6 +1<br />

octaaf re<strong>in</strong> 7 0<br />

verm<strong>in</strong>derd 7 -1<br />

vergroot / overmatig 7 +1<br />

Tabel 4.2: Muziektheoretische <strong>in</strong>tervallen met hun overeenkomstige nummers


4.2 Representatie van een muziekstuk 16<br />

Eigenlijk kan men dit systeem vergelijken met wiskundige punten en vectoren. De hoogte van<br />

een noot is dan het wiskundig punt, terwijl en <strong>in</strong>terval een vector is. Een <strong>in</strong>terval (vector)<br />

bij een noot (punt) optellen geeft dan een andere noot (punt), het verschil tussen twee noten<br />

(punten) is een <strong>in</strong>terval (vector), . . . Dit systeem heeft het voordeel van een enkel getal te<br />

zijn (zoals het modulo-12 systeem) maar toch reken<strong>in</strong>g te houden met de klassieke betekenis<br />

van verschillende noten (zoals het <strong>in</strong>terval-modificator systeem).<br />

Om (mogelijks) nog meer efficiëntie te krijgen kan men het concept modulo-40 systeem overbrengen<br />

naar een modulo-4096 pitch encod<strong>in</strong>g systeem. Het voordeel hiervan is dat het<br />

octaveren van noten (wat <strong>in</strong> dit project veel voorkomt bij het controleren van regels) neerkomt<br />

op het optellen of aftrekken van 4096 bij de nootwaarde. De aandachtige lezer zal al<br />

gemerkt hebben dat 4096 = 2 12 wat dus wil zeggen dat octaveren efficiënt kan gebeuren via<br />

bitoperaties. Ook modulo operaties (gebruikt bij <strong>in</strong>tervalbereken<strong>in</strong>gen) zijn veel efficiënter<br />

dan de modulo operaties bij het gelijkaardige systeem met basis 40. Het nadeel van dit systeem<br />

is dat er veel getallen niet gebruikt worden en dus de mapp<strong>in</strong>g een grote tabel zal nodig<br />

hebben waar bijna niks <strong>in</strong> staat. De getallen voor de pitch zijn ook veel groter (C 4 , een veel<br />

voorkomende noot, is bijvoorbeeld al 16384). Er is (nog) niet aangetoond of de voordelen<br />

opwegen tegen de nadelen.<br />

4.2 Representatie van een muziekstuk<br />

4.2.1 Representatie van een muziekstuk op de server<br />

Een muziekstuk bestaat simpelweg uit één of meerdere muziekstemmen, die op hun beurt<br />

uit een rij van noten, met elk hun lengte en toonhoogte, opgebouwd zijn. De gemakkelijkste<br />

manier om dit voor te stellen is natuurlijk een objectgeoriënteerd model, zoals te zien <strong>in</strong> figuur<br />

4.1.<br />

MusicScore<br />

1<br />

voices<br />

0..*<br />

MusicVoice<br />

1<br />

notes<br />

0..*<br />

MusicNote<br />

Figuur 4.1: Objectgeoriënteerd model<br />

Om de efficiëntie op te drijven maken we ook gebruik van een model gebaseerd op een matrix.<br />

Elke cel <strong>in</strong> de matrix stelt dan een noot voor. Dit wil zeggen dat alle noten even lang<br />

moeten zijn (wat zich perfect aansluit bij de eerste soort contrapunt). In de cel staat dan de


4.2 Representatie van een muziekstuk 17<br />

(gecodeerde) toonhoogte van de noot (zie punt 4.1.2). Om later gemakkelijk te zijn (bij het<br />

toepassen van de regels) zijn alle pitches <strong>in</strong> het matrixmodel relatief. Het model heeft een<br />

basisnoot (de grondnoot van de toonaard) waarop alle pitches gebaseerd zijn. De toonhoogtes<br />

worden dus voorgesteld als een <strong>in</strong>terval vanaf de basisnoot.<br />

Het nadeel van het matrixmodel is dat er bij een noot geen extra <strong>in</strong>formatie (zoals lengte van<br />

de noot, commentaar, type, . . . ) kan opgeslagen worden. Daarom wordt het matrixmodel<br />

gebruikt als aanvull<strong>in</strong>g op het objectgeoriënteerde model. Bij het aanmaken van het model<br />

wordt beslist of een matrixmodel al dan niet kan opgesteld worden Op die manier kan men<br />

alle <strong>in</strong>formatie van een noot opslaan en toch de efficiëntie van het matrixmodel gebruiken<br />

<strong>in</strong>dien nodig.<br />

Men zou kunnen vermoeden dat het matrixmodel enkel en alleen kan gebruikt worden bij de<br />

eerste soort contrapunt omdat er geen ritmes mogelijk zijn, maar door de koppel<strong>in</strong>g met het<br />

objectgeoriënteerde model en de <strong>in</strong>voer<strong>in</strong>g van het overgebonden noottype kan men toch <strong>in</strong><br />

zekere z<strong>in</strong> andere types contrapunt gebruiken. Men kan het tweede (twee tegen één), het derde<br />

(drie of vier tegen één) en het syncopentype voorstellen door langere noten voor te stellen als<br />

meerdere (gelijke) noten. Het type van de tweede, derde, . . . noot is dan overgebonden. Dit<br />

wil zeggen dat de <strong>in</strong>formatie van de noot dezelfde is als de voorgaande noot en de twee noten<br />

eigenlijk als één beschouwd moeten worden.<br />

Interface voor de muziekstukrepresentatie<br />

De algemene <strong>in</strong>terface voor een muziekstuk is de volgende:<br />

List<strong>in</strong>g 4.1: Score <strong>in</strong>terface<br />

public <strong>in</strong>terface Score {<br />

public Str<strong>in</strong>g getMeasureLength();<br />

public void setMeasureLength(Str<strong>in</strong>g measureLength);<br />

public Key getKey();<br />

public void setKey(Key key);<br />

public EnumMap getVoices();<br />

public void setVoices(EnumMap voices);<br />

public RuleRat<strong>in</strong>g checkRule(Rule rule, <strong>in</strong>t <strong>in</strong>dex, Voice voice) throws<br />

ScoreException;<br />

}<br />

Een muziekstuk heeft een aanduid<strong>in</strong>g voor de maatlengte (4/4 bvb.), een toonaard (Key) en<br />

een aantal stemmen. Ook is er een methode aanwezig om een regel op een bepaalde plaats <strong>in</strong><br />

het stuk te testen. De toonaard van het stuk bestaat uit de aanduid<strong>in</strong>g van de basisnoot en<br />

het terts<strong>in</strong>terval (dat de aanduid<strong>in</strong>g van grote of kle<strong>in</strong>e tertstoonladder aangeeft).<br />

Een stem ziet er als volgt uit:<br />

List<strong>in</strong>g 4.2: OOMusicVoice<br />

public class OOMusicVoice {<br />

private <strong>in</strong>t id;<br />

private Clef clef;<br />

private <strong>in</strong>t time;<br />

private Str<strong>in</strong>g comment;<br />

private NoteType type;


4.2 Representatie van een muziekstuk 18<br />

}<br />

private List notes;<br />

Een stem heeft op zich dan een unieke identifier, een sleutel (solsleutel, fasleutel, ...), een<br />

aanduid<strong>in</strong>g hoe lang een maat duurt (base 192 waarde <strong>in</strong> plaats van de str<strong>in</strong>gaanduid<strong>in</strong>g),<br />

mogelijks wat commentaar, een noottype en een lijst van noten. Op het eerste zicht lijkt het<br />

bizar dat een stem een noottype nodig heeft maar dit wordt gebruikt als aanduid<strong>in</strong>g of de<br />

stem aangepast mag worden. Men kan het zien als de standaardwaarde voor al zijn noten.<br />

Een noot heeft de volgende <strong>in</strong>formatie:<br />

List<strong>in</strong>g 4.3: OOMusicNote<br />

public class OOMusicNote {<br />

private Pitch pitch;<br />

private <strong>in</strong>t length;<br />

private NoteType type;<br />

private Str<strong>in</strong>g comment;<br />

}<br />

De pitch is een niet gecodeerde pitch zoals <strong>in</strong> punt 4.1.2 en de length een lengte zoals <strong>in</strong> punt<br />

4.1.1.<br />

Het matrixmodel ziet er als volgt uit:<br />

List<strong>in</strong>g 4.4: ArrayModel<br />

public <strong>in</strong>terface ArrayModel {<br />

public <strong>in</strong>t getBase();<br />

public void setBase(<strong>in</strong>t base);<br />

}<br />

public <strong>in</strong>t getCurrentNote(<strong>in</strong>t voice);<br />

public <strong>in</strong>t getCurrentNoteLength(<strong>in</strong>t voice);<br />

//methods for iterator access<br />

public <strong>in</strong>t getNumberOfNotes(<strong>in</strong>t voice);<br />

public boolean hasNextNote(<strong>in</strong>t voice);<br />

public void next(<strong>in</strong>t voice);<br />

public void previous(<strong>in</strong>t voice);<br />

public void first(<strong>in</strong>t voice);<br />

public void last(<strong>in</strong>t voice);<br />

//methods for random access<br />

public void gotoNote(<strong>in</strong>t voice, <strong>in</strong>t noteIndex);<br />

public void gotoParallelNote(<strong>in</strong>t source, <strong>in</strong>t noteIndex, <strong>in</strong>t target);<br />

//methods for construction<br />

public void fillvoice(<strong>in</strong>t voice, ArrayList notes);<br />

public void setScore(Integer[][] score);<br />

Het matrixmodel voorziet ondersteun<strong>in</strong>g voor random access en iteratie. De base stelt de<br />

grondnoot van het muziekstuk voor.<br />

Om nu beide modellen te comb<strong>in</strong>eren is er volgende <strong>in</strong>terface beschikbaar:


4.2 Representatie van een muziekstuk 19<br />

List<strong>in</strong>g 4.5: ScoreWithArrayModel label<br />

public abstract class ScoreWithArrayModel implements Score, ArrayModel{<br />

protected ArrayModel arrayModel;<br />

public abstract OOMusicNote getOONote(Voice v, <strong>in</strong>t <strong>in</strong>dex);<br />

public abstract RuleRat<strong>in</strong>g checkArray(Rule rule, <strong>in</strong>t <strong>in</strong>dex, <strong>in</strong>t voice,<br />

ArrayModel array) throws ScoreException;<br />

}<br />

Beide modellen worden gecomb<strong>in</strong>eerd en er wordt extra functionaliteit aangeboden. Om<br />

de gecodeerde toonhoogte op te halen kan men via de <strong>in</strong>terface van het ArrayModel gaan.<br />

Om extra <strong>in</strong>formatie op te halen is er een methode voorzien die objectgeoriënteerde noten<br />

via schijnbaar random acces kan ophalen. De extra methode wordt gebruikt om muziek te<br />

genereren (zie verder).<br />

4.2.2 Communicatieformaten<br />

Zoals al aangegeven <strong>in</strong> hoodstuk 3 is de uitgewisselde <strong>in</strong>formatie een json-formaat. Eigenlijk<br />

zijn er twee formaten: een b<strong>in</strong>nenkomend formaat voor de bestaande regels op de server en<br />

hun beschrijv<strong>in</strong>g en een formaat (<strong>in</strong>komend en uitgaand) die een aanvraag <strong>in</strong>kapselt.<br />

Regelaanvraagformaat<br />

Het formaat dat de regels en hun beschrijv<strong>in</strong>g representeert is eigenlijk gewoon de omzett<strong>in</strong>g<br />

(via Google gson) van een java HashMap die de unieke id’s van regels mapt op hun uitgebreide<br />

beschrijv<strong>in</strong>g, naar json. Een voorbeel is te zien <strong>in</strong> list<strong>in</strong>g 4.6<br />

List<strong>in</strong>g 4.6: Regelaanvraag antwoord<br />

{"ruleDescriptions":{<br />

...<br />

"21":{<br />

"id":21,<br />

"name":"ClassicVerticalRule",<br />

"description":"A rule to check if the <strong>in</strong>terval two notes of adjecent<br />

voices are allowed.",<br />

"parentId":20,<br />

"configurable":false,<br />

"predict<strong>in</strong>grate":"NOT_PREDICTABLE",<br />

"groups":["Classic"]},<br />

"20":{<br />

"id":20,<br />

"name":"VerticalRule",<br />

"description":"A rule to allow or dissalow <strong>in</strong>tervals betweet two adjecent<br />

voices.",<br />

"parentId":0,<br />

"configurable":true,<br />

"caseDescription":{<br />

"from":true,<br />

"to":false,<br />

"type":"INTERVAL"},<br />

"predict<strong>in</strong>grate":"NOT_PREDICTABLE",<br />

"groups":["configurable"]},<br />

...<br />

}}


4.2 Representatie van een muziekstuk 20<br />

Manipulatieaanvraag<br />

De aanvraag om een muziekstuk te manipuleren (controleren of noten genereren) heeft over het<br />

algemeen twee d<strong>in</strong>gen nodig: het muziekstuk dat de gebruiker heeft <strong>in</strong>gegeven en een set (al<br />

dan niet gebruikergeconfigureerde) regels. Ook wordt er aangegeven welke soort contrapunt<br />

gebruikt wordt. Algemeen, <strong>in</strong> java, ziet de wrapper er uit als <strong>in</strong> list<strong>in</strong>g 4.7<br />

List<strong>in</strong>g 4.7: ManipulateRequestWrapper<br />

public class ManipulateRequestWrapper {<br />

private HashMap rules;<br />

private WebModel score;<br />

private Species specie;<br />

}<br />

De regels zijn een verzamel<strong>in</strong>g van unieke identifiers samen met een optioneel argument. Als<br />

dit argument niet meegegeven is, wil dit zeggen dat de regel niet configureerbaar was en geen<br />

extra <strong>in</strong>fo nodig heeft. Verdere <strong>in</strong>formatie over het het configureren van regels en regels <strong>in</strong><br />

het algemeen is te v<strong>in</strong>den <strong>in</strong> punt 6.1 op pag<strong>in</strong>a 29. Het webmodel ziet er als volgt uit:<br />

List<strong>in</strong>g 4.8: WebModel<br />

public class WebModel {<br />

private HashMap voices;<br />

private Str<strong>in</strong>g key;<br />

private Str<strong>in</strong>g measureLength;<br />

}<br />

public class WebVoice{<br />

private Str<strong>in</strong>g clef;<br />

private Str<strong>in</strong>g[] notes;<br />

private Str<strong>in</strong>g comment;<br />

private char type;<br />

}<br />

Zoals hierboven te zien is, wordt een noot <strong>in</strong> het webmodel voorgesteld als één enkele karakterstr<strong>in</strong>g.<br />

Die str<strong>in</strong>g bevat, <strong>in</strong> de aanvraag van de client, de pitch van de noot, zijn type en<br />

eventueel zijn lengte. In het antwoord van de server bevat die str<strong>in</strong>g opnieuw de pitch van<br />

de noot en zijn eventuele lengte. Ook kan de noot commentaar bevatten (die kan aanduiden<br />

dat die noot de oorzaak is van een overtreden regel).<br />

4.2.3 Webrepresentaties<br />

Er zijn verschillende mogelijkheden om een muziekstuk te representeren <strong>in</strong> de webapplicatie.<br />

Eén van die mogelijkheden, die gemakkelijk gebruikt kan worden om het antwoord van de<br />

server weer te geven, is het b<strong>in</strong>nenkomende json-antwoord direct vertalen naar VexTab (zie<br />

hoofdstuk 5), aangevuld met een lijst van commenteren. Dit is niet erg bruikbaar als formaat<br />

voor <strong>in</strong>put omdat het moeilijk manipuleerbaar is (behalve als de gebruiker direct VexTab zou<br />

schrijven, wat niet van hem verwacht kan worden. . . ).


4.2 Representatie van een muziekstuk 21<br />

Inputformaat<br />

Om de gebruiker noten te laten <strong>in</strong>geven wordt via JavaScript en jQuery een <strong>in</strong>terface gegenereerd<br />

die gemakkelijk te begrijpen en te manipuleren is. Het is een dynamische tabel<br />

waar elke rij een stem voorstelt. In elke cel van een rij kan de gebruiker de gewenste noot<br />

<strong>in</strong>geven (via een formaat dat fel verwant is met ABC-notatie), alsook het type van de noot<br />

(vast, beweegbaar, . . . dit wordt gebruikt voor het genereren van muziek). Dit alles wordt<br />

gerenderd via VexFlow. Meer hierover <strong>in</strong> hoofdstuk 5.<br />

Om de regels <strong>in</strong> te geven moet de gebruiker gewoon de gewenste regels aanklikken en deze<br />

eventueel configureren via popups. De regels kunnen mooi geordend weergegeven worden op<br />

de website door de uitvoerige regelbeschrijv<strong>in</strong>g bij elke regel.<br />

Indien de gebruiker klaar is met het <strong>in</strong>geven van het gewenste muziekstuk en de gewenste<br />

regels wordt alles omgezet naar het communicatieformaat.


Website 22<br />

Hoofdstuk 5<br />

Website<br />

De website bestaat vooral uit HTML en JavaScript. Om de muzieknoten weer te geven en<br />

te laten afspelen wordt er gebruik gemaakt van VexFlow (zie 5.2). De communicatie naar de<br />

webservice toe gebeurt via json.<br />

Er worden, naast JavaScript, nog andere elementen gebruikt om de website op te bouwen.<br />

De grootste speler hier is jQuery (jQuery). Dit is een vrij JavaScript-framework die vele<br />

d<strong>in</strong>gen mogelijk en/of gemakkelijker maakt (DOM manipulaties, AJAX, . . . ). Ook wordt<br />

(<strong>in</strong> m<strong>in</strong>dere mate) gebruik gemaakt van underscore.js (Underscore). Deze bibliotheek wordt<br />

vooral gebruikt voor manipulaties op collecties (array, map,. . . ).<br />

5.1 Websitestructuur<br />

De volledige <strong>in</strong>houd van de website wordt bepaald door JavaScript. De enige HTML die er<br />

aan te pas komt is het <strong>in</strong>laden van de JavaScript-files en het plaatsen van drie div elementen<br />

(naast de knoppen om de serveracties te bepalen).<br />

List<strong>in</strong>g 5.1: Index van de webapplicatie label<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

...<br />

<br />

<br />

...<br />

<br />

<br />

<br />

<br />

<br />

<br />


5.1 Websitestructuur 23<br />

<br />

<br />

<br />

<br />

<br />

<br />

De eerste van de drie modules is de module voor het tonen, configureren, aanv<strong>in</strong>ken,. . . van<br />

regels. Deze is te zien <strong>in</strong> figuur 5.1. De tweede is deze die de gebruiker toelaat <strong>in</strong>put te geven<br />

(zie figuur 5.2). De laatste module dient om alle output (waaronder commentaren van de<br />

server) weer te geven. Uite<strong>in</strong>delijk is deze laatste niets meer dan een simpele textarea.<br />

Figuur 5.1: Weergeven en aanduiden van regels op de website<br />

Figuur 5.2: Inputmodule<br />

De pop-ups om details van regels te bekijken, of om regels te configureren (zie figuren 5.3 en<br />

5.4) zijn elementen van de jquery-ui.js bibliotheek.<br />

Aan elke module wordt een JavaScript module gekoppeld. De JavaScript modules zijn afgeschermd<br />

via het Reveal<strong>in</strong>g Module Pattern (Magaz<strong>in</strong>e, 2012). Dit komt erop neer dat elke


5.1 Websitestructuur 24<br />

Figuur 5.3: Details van een regel<br />

Figuur 5.4: Configuratie van een regel


5.2 VexFlow 25<br />

module een s<strong>in</strong>gleton is, met publieke en private delen. In het hoofdscript worden alle modules<br />

geïnitialiseerd (de respectievelijke div’s worden aan de module gekoppeld en de beg<strong>in</strong><strong>in</strong>houd<br />

wordt gegenereerd). De <strong>in</strong>putModule en ouptuModule zijn gelijkaardig als de ruleModule uit<br />

volgend codefragment.<br />

List<strong>in</strong>g 5.2: Initialisatie van de modules label<br />

$(document).ready(function() {<br />

<strong>in</strong>putModule.<strong>in</strong>it($("div#<strong>in</strong>putDiv"));<br />

outputModule.<strong>in</strong>it($("div#outputDiv"));<br />

ruleModule.<strong>in</strong>it($("div#rulesDiv"));<br />

});<br />

communication.getRules();<br />

$("<strong>in</strong>put#check").click(function() {<br />

communication.checkScore();<br />

});<br />

$("<strong>in</strong>put#improve").click(function() {<br />

communication.improveScore();<br />

});<br />

var ruleModule = function() {<br />

var $workiv;<br />

function <strong>in</strong>it($div) {<br />

$workdiv = $div;<br />

}<br />

function showRules(){ ... }<br />

function getSelectedRules(){ ... }<br />

}<br />

return{<br />

<strong>in</strong>it: <strong>in</strong>it,<br />

showRules: showRules,<br />

getSelectedRules: getSelectedRules<br />

};<br />

Verdere modules die gebruikt worden zijn een module voor syntaxcontrole, een module voor<br />

vertal<strong>in</strong>gen (om gegevens naar het juiste formaat om te zetten, een formaat die de server kan<br />

lezen) en een module die de communicatie met de server regelt.<br />

Het geheel (<strong>in</strong> dit geval, net na controle van een muziekstuk) ziet er uit als <strong>in</strong> figuur 5.5. Op<br />

die figuur ziet men dat een stuk net gecontroleerd is op een aantal klassieke regels. Er is<br />

een regel overtreden (geen parallelle octaven) en dit wordt aangegeven op de render<strong>in</strong>g van<br />

de noten (de noten die de overtred<strong>in</strong>g triggerden zijn omkaderd) en de commentaar <strong>in</strong> de<br />

ouputmodule is ook duidelijk.<br />

5.2 VexFlow<br />

De grootste uitdag<strong>in</strong>g aan de website is om muzieknoten mooi weer te geven en de gebruiker de<br />

mogelijkheid geven om deze ook te beluisteren. Dit alles kan gemakkelijk via een JavaScript


5.2 VexFlow 26<br />

Figuur 5.5: Volledige webapplicapplicatie<br />

Figuur 5.6: VexFlow voorbeeld


5.2 VexFlow 27<br />

API die VexFlow heet. In VexFlow kan men gemakkelijk muzieknotatie renderen via een<br />

HTML5 canvas of SVG. List<strong>in</strong>g 5.3 resulteert bijvoorbeeld <strong>in</strong> figuur 5.6.<br />

List<strong>in</strong>g 5.3: VexFlow voorbeeld<br />

<br />

<br />

var canvas = document.getElementById(‘‘draw’’);<br />

var renderer = new Vex.Flow.Renderer(<br />

canvas,Vex.Flow.Renderer.Backends.CANVAS);<br />

var ctx = renderer.getContext();<br />

var stave = new Vex.Flow.Stave(10, 0, 500);<br />

stave.addClef("treble").setContext(ctx).draw();<br />

var notes = [<br />

new Vex.Flow.StaveNote({ keys: ["c/4"], duration: "q" }),<br />

new Vex.Flow.StaveNote({ keys: ["d/4"], duration: "q" }),<br />

new Vex.Flow.StaveNote({ keys: ["b/4"], duration: "qr" }),<br />

new Vex.Flow.StaveNote({ keys: ["c/4", "e/4", "g/4"], duration: "q" })<br />

];<br />

var voice = new Vex.Flow.Voice({<br />

num_beats: 4,<br />

beat_value: 4,<br />

resolution: Vex.Flow.RESOLUTION<br />

});<br />

voice.addTickables(notes);<br />

var formatter = new Vex.Flow.Formatter()<br />

.jo<strong>in</strong>Voices([voice])<br />

.format([voice], 500);<br />

voice.draw(ctx, stave);<br />

<br />

Men maakt gewoon het object waarop getekend kan worden en dan kan je via de JavaScript<br />

API notenbalken, sleutels, muzieknoten (met of zonder wijzig<strong>in</strong>gstekens), . . . tekenen. Verder<br />

heeft Mohit Muthanna (de ontwerper van VexFlow) ook een product ontwikkeld (VexTab)<br />

dat gebruikt maakt van de VexFlow API. Met VexTab is het eenvoudig voor gebruikers om<br />

muziekstukken te maken en te embedden. Het voordeel om met VexTab te werken is dat<br />

er gemakkelijk een vertal<strong>in</strong>g kan zijn van het model op de server naar de VexTab-taal en<br />

omgekeerd. Een ander voordeel is dat er een mogelijkheid is toegevoegd om het muziekstuk<br />

te laten afspelen. List<strong>in</strong>g 5.4 zorgt ervoor dat figuur 5.7 wordt gerenderd.<br />

List<strong>in</strong>g 5.4: VexTab voorbeeld<br />

options player=true<br />

tabstave notation=true tablature=false<br />

notes :q C-D/4 ## (C/4.E/4.G/4)


5.2 VexFlow 28<br />

Figuur 5.7: VexTab voorbeeld


Server side 29<br />

Hoofdstuk 6<br />

Server side<br />

Aan de serverkant van de applicatie is het de bedoel<strong>in</strong>g dat alles zo efficiënt mogelijk wordt<br />

voorgesteld en uitgevoerd zodat de e<strong>in</strong>dgebruiker niet te lang moet wachten op zijn resultaat<br />

na een aanvraag op de site. Dit alles is niet vanzelfsprekend en wordt opgedeeld <strong>in</strong> meerdere<br />

delen:<br />

• representatie van regels (6.1),<br />

• controleren van regels op een muziekstuk (6.2),<br />

• genereren van muziek aan de hand van de regels (6.3).<br />

6.1 Representatie van regels<br />

Regels uit het klassieke contrapunt kunnen (grotendeels) voorgesteld worden als een <strong>in</strong>terval<br />

tussen twee noten dat al dan niet mag. Er zijn ook regels die op een enkele noot (<strong>in</strong> een<br />

bepaalde stem) gelden, zoals de tessituurregel (de noot moet z<strong>in</strong>gbaar zijn) en een regel die<br />

gebiedt dat de noot <strong>in</strong> de juiste toonaard zit. Andere regels gelden op meer dan twee noten<br />

(zoals de regel die zegt dat een noot best niet meer dan twee keer blijft liggen) en heel soms<br />

op een noot <strong>in</strong> een specifieke plaats van het stuk (de voorlaatste noot moet een leidtoon zijn).<br />

Aangezien één van de doelstell<strong>in</strong>gen van het project is om de gebruiker toe te laten zelf regels te<br />

def<strong>in</strong>iëren is een systeem uitgewerkt zodat de (meeste) soorten regels parameteriseerbaar zijn.<br />

De klassieke regels kan men zien als parameteriseerbare regels die al op voorhand <strong>in</strong>gevuld<br />

zijn met de standaardwaarden (voor efficiëntieredenen zijn deze hardgecodeerd <strong>in</strong> plaats van<br />

geparameteriseerd).<br />

Alles is ondergebracht <strong>in</strong> een systeem zoals <strong>in</strong> figuur 6.1.<br />

6.1.1 Algemene <strong>in</strong>terface<br />

Algemeen heeft een regel een w<strong>in</strong>dow. Dit duidt op het aantal noten dat de regel nodig heeft<br />

als <strong>in</strong>put (met rows de aanduid<strong>in</strong>g van verschillende stemmen en columns het aantal aaneenliggende<br />

noten per stem). De regel kan de <strong>in</strong>komende (gecodeerde) noten dan controleren.<br />

De parameters die verwacht worden bij het controleren van een regel zijn niet enkel de noten,<br />

maar ook een referentie naar het volledige stuk en een aanduid<strong>in</strong>g waar men zit <strong>in</strong> het stuk.


6.1 Representatie van regels 30<br />

W<strong>in</strong>dow<br />

BrowsI:I<strong>in</strong>t<br />

BcolumnsI:I<strong>in</strong>t<br />

RuleRat<strong>in</strong>g<br />

BokI:Iboolean<br />

Brat<strong>in</strong>gI:I<strong>in</strong>t<br />

BcommentI:IStr<strong>in</strong>g<br />

<br />

Rule<br />

_checkvNI:IRuleRat<strong>in</strong>g<br />

_getW<strong>in</strong>dowvNI:IW<strong>in</strong>dow<br />

_getDescriptionvN<br />

_<strong>in</strong>itvRuleArgumentIargumentN<br />

1<br />

1<br />

RuleDescription<br />

BidI:I<strong>in</strong>t<br />

BparentIdI:I<strong>in</strong>t<br />

BdescriptionI:IStr<strong>in</strong>g<br />

Bpredict<strong>in</strong>gRuleRateI:IPredict<strong>in</strong>gRuleRate<br />

BgroupsI:IArrayList<br />

BconfigurableI:Iboolean<br />

BnumberOfCasesI:IInteger<br />

BcaseDescriptionI:ICaseDescription<br />

<br />

Predict<strong>in</strong>gRule<br />

_predictvN<br />

_scratchListvN<br />

_updateListvN<br />

RuleArgument<br />

BvoicesI:IArrayList<br />

BstandardRat<strong>in</strong>gI:IInteger<br />

BcasesI:IArrayList<br />

1<br />

CaseDescription<br />

BfromI:Iboolean<br />

BtoI:Iboolean<br />

1<br />

1<br />

1<br />

RuleCase<br />

BfromI:IPitch<br />

BtoI:IPitch<br />

Brat<strong>in</strong>gI:IInteger<br />

<br />

Predict<strong>in</strong>gRuleRate<br />

IBNOT_PREDICTABLE<br />

IBONE_PASS<br />

IBMULTIPLE_PASS<br />

Figuur 6.1: Klassenschema regels<br />

Op die manier kan de regel aanvullende <strong>in</strong>formatie over het stuk, de stem en de noten ophalen.<br />

Dit is bijvoorbeeld nodig bij de klassieke regel die de toonaard controleert. De aanduid<strong>in</strong>g<br />

van de toonaard zit <strong>in</strong> het muziekstuk en niet <strong>in</strong> de gecodeerde noten. Op die manier weet de<br />

regel ook op welke plaats <strong>in</strong> het stuk de noten voorkomen. Na het controleren van de noten<br />

geeft de regel een RuleRat<strong>in</strong>g terug. Deze zegt of aan de regel al dan niet voldaan is, met<br />

welke score aan de regel voldaan is en mogelijks een commentaar bij de regel. Deze <strong>in</strong>formatie<br />

wordt gebruikt bij (uiteraard) het controleren van muziek, het genereren van muziek en om<br />

de gebruiker extra <strong>in</strong>formatie te geven na één van vorige acties.<br />

Elke regel heeft ook een description. Deze geeft enerzijds aan de e<strong>in</strong>dgebruiker meer <strong>in</strong>formatie<br />

over wat de regel precies doet, en anderzijds veel <strong>in</strong>formatie aan de webapplicatie over<br />

hoe de regel te <strong>in</strong>terpreteren. Zo kan de applicatie het identificatienummer van de regel achterhalen<br />

(via id), wat de algemene regels is (via de parentId), of de regel configureerbaar<br />

is(configurable) en hoe de configuratie van de regel er precies moet uit zien (numberOfCases<br />

en caseDescription).<br />

Een case van een configureerbare regel duidt een deel van de regel aan, en welke score er aan<br />

dat deel gegeven wordt. Bijvoorbeeld kan met een toonaardregel def<strong>in</strong>iëren. Men voegt voor<br />

elke toegelaten noot een case toe. Ook noten die wel mogen gebruikt worden, maar liever<br />

niet, kan men toevoegen en een negatieve rat<strong>in</strong>g geven. Noten die de gebruiker beter v<strong>in</strong>dt<br />

geeft men dan een hogere score.<br />

Om dan effectief een regel te configureren worden alle cases samengevoegd <strong>in</strong> een RuleArgu-


6.1 Representatie van regels 31<br />

ment. In het argument moet men ook aangeven op welke stemmen de regel van toepass<strong>in</strong>g<br />

is (een lege lijst duidt op alle stemmen) en eventueel wat de standaardrat<strong>in</strong>g is. Als men een<br />

standaardrat<strong>in</strong>g opgeeft wil dit zeggen dat alle mogelijke cases toegelaten worden met die rat<strong>in</strong>g.<br />

De toegevoegde cases zijn dan een uitzonder<strong>in</strong>g hierop (als de caserat<strong>in</strong>g niet <strong>in</strong>gevuld<br />

is) of een aanpass<strong>in</strong>g hierop (als de rat<strong>in</strong>g verschillend is van de standaard rat<strong>in</strong>g). Geen<br />

standaard rat<strong>in</strong>g opgeven wil zeggen dat alle gevallen die niet opgegeven zijn met behulp van<br />

cases niet toegelaten zijn.<br />

Als men een configureerbare regel wil gebruiken, moet die effectief ook geconfigureerd worden.<br />

Bij de <strong>in</strong>itialisatie op de serverkant wordt een RuleArgument verwacht om de regel op te<br />

bouwen.<br />

6.1.2 Voorspellende regels<br />

Een extra <strong>in</strong>terface, de Predict<strong>in</strong>gRule wordt gebruikt bij het genereren van muziek. Een regel<br />

kan ofwel niet voorspellend zijn (NOT PREDICTABLE), voorspellend <strong>in</strong> één enkele doorloop<br />

(ONE PASS) of voorspellend met meerdere doorlopen (MULTIPLE PASS).<br />

Voorspellers met enkele doorloop worden gebruikt om alvorens het genereren van muziek<br />

te beg<strong>in</strong>nen, de zoekruimte zoveel mogelijk <strong>in</strong> te perken. Voorbeelden van zulke regels zijn<br />

de tessituur regels (een stem moet b<strong>in</strong>nen bepaalde grenzen liggen), toonaardregels (niet<br />

elke noot kan voorkomen <strong>in</strong> een stuk) en zelfs de <strong>in</strong>tervalregels (bij de gegeven stem mogen<br />

bijvoorbeeld enkel consonanten staan, <strong>in</strong> het klassieke geval).<br />

Voorspellers met meerdere doorloop worden gebruikt tijdens het genereren. Deze verwachten<br />

dat al een deel van de te genereren stem af is. Voorbeelden van zulke regels zijn onder andere<br />

de algemene progressieregel (geen directe beweg<strong>in</strong>g naar perfecte consonanten toe).<br />

Het voorspellen zelf kan op verschillende manieren. De eerste manier (predict() ) verwacht<br />

een referentie naar het volledige muziekstuk en waar men <strong>in</strong> het stuk zit. De methode geeft<br />

alle mogelijkheden terug die de noot op die plaats kan hebben. Op het eerste zicht lijkt die<br />

methode voldoende maar <strong>in</strong> samenwerk<strong>in</strong>g met meerdere voorspellers is ze vrij <strong>in</strong>efficiënt.<br />

Daarom is de tweede methode aanwezig: scratchList(). Deze methode verwacht naast de<br />

zelfde argumenten van predict() ook nog een lijst met mogelijkheden. Uit deze lijst worden<br />

dan alle mogelijkheden geschrapt die niet voldoen aan de regel.<br />

Het laten schrappen <strong>in</strong> de lijst door de voorspellers is gemakkelijker en efficiënter dan de<br />

doorsnede van alle toelat<strong>in</strong>gslijsten van alle voorspellers te bepalen. Het vereist ook m<strong>in</strong>der<br />

plaats.<br />

De derde methode (updateList()) werkt analoog aan de vorige methode. Er worden geen<br />

mogelijkheden meer geschrapt maar een tell<strong>in</strong>g bij elke mogelijkheid bijgehouden. Deze is <strong>in</strong><br />

het leven geroepen voor het geval er een aantal regels zouden moeten samenwerken die ervoor<br />

zorgen dat er niks mogelijk is. Telkens een mogelijkheid voldoet aan een regel wordt een<br />

punt bijgeteld. Achteraf wordt enkel gewerkt met de mogelijkheden die het maximum aantal<br />

punten hebben (al overtreden deze systematisch één of meerdere regels). Het doel is immers<br />

een zo goed mogelijke oploss<strong>in</strong>g te geven aan de gebruiker, zelfs al moet deze regels overtreden.<br />

Als er regels overtreden worden zal dit uiteraard wel gemeld worden aan de gebruiker (aan<br />

de hand van commentaren bij stemmen en noten).


6.2 Controleren van regels op een stuk 32<br />

6.2 Controleren van regels op een stuk<br />

Om een muziekstuk te controleren volstaat het elke regel toe te passen op elke noot van het<br />

stuk. Het muziekstuk wordt stem per stem, noot per noot overlopen en telkens worden alle<br />

regels bekeken. De checker bekijkt voor elke regel of er genoeg noten beschikbaar zijn om de<br />

regel te voeden (aan de hand van het w<strong>in</strong>dow van de regel). Daarna wordt de regel meegegeven<br />

aan het muziekstuk samen met de plaatsaanduid<strong>in</strong>g van de huidige noot. Het muziekstuk<br />

zorgt ervoor dat de gecodeerde noten doorgegeven worden aan de regel (ofwel door <strong>in</strong> zijn<br />

matrixmodel te kijken ofwel door de noten dynamisch te coderen uit het objectgeoriënteerd<br />

model).<br />

De regel die de nodige noten b<strong>in</strong>nen krijgt controleert dan die noten. Er wordt vooral met<br />

<strong>in</strong>tervallen gewerkt <strong>in</strong> de regels: is het <strong>in</strong>terval tussen twee opeenvolgende noten wel toegestaan,<br />

is het <strong>in</strong>terval tussen twee noten op dezelfde tel wel toegestaan, . . . Regels die op<br />

een enkele noot werken hebben een lijst noten die toegestaan zijn of twee noten waartussen<br />

de noot moet zitten. Deze waarden zijn <strong>in</strong>itieel hardgecodeerd. Als men een uitbreidbare<br />

regel gebruikt kunnen deze waarden (de toegestane <strong>in</strong>tervallen, de toegestane noten, . . . )<br />

geparameteriseerd worden.<br />

Regels die enkel gelden <strong>in</strong> een specifieke plaats van het stuk zijn iets moeilijker. De regel<br />

wordt bij elke noot opgeroepen (<strong>in</strong>dien het venster dit toelaat) en <strong>in</strong> de regel zelf moet<br />

gekeken worden of de noot (of noten) nu wel op de juiste plaats staat om gecontroleerd te<br />

worden.<br />

6.3 Genereren van noten aan de hand van regels<br />

Het genereren van noten is een breed thema. Dit kan slaan op het genereren van een enkele<br />

noot tot een volledige stem. Een andere opvatt<strong>in</strong>g zou kunnen zijn dat na het controleren<br />

van de oploss<strong>in</strong>g een verbeter<strong>in</strong>g aangeboden wordt op basis van het orig<strong>in</strong>ele stuk waarbij zo<br />

we<strong>in</strong>ig mogelijk veranderd wordt. Er zijn verschillende methodes om dit aan te pakken. Deze<br />

methoden worden overlopen <strong>in</strong> volgende paragrafen. We gaan er hier van uit dat er maar twee<br />

stemmen meespelen: de gegeven stem (c.f.) en de te genereren stem (de contrapuntstem).<br />

6.3.1 Random configuraties<br />

Een eerste (zeer <strong>in</strong>efficiënte) methode om noten te genereren is pure randomgeneratie. Er<br />

worden een aantal configuraties (dit zijn tussenoploss<strong>in</strong>gen) compleet at random gegenereerd.<br />

Dit komt neer op een lijst gehele getallen genereren. Deze getallen zijn gecodeerde noothoogtes.<br />

Daarna wordt de configuratie samen met de c.f. gecontroleerd. De controle geeft weer<br />

hoeveel regels overtreden zijn en wat de totale score voor het stuk is. De beste configuratie<br />

wordt als oploss<strong>in</strong>g aangenomen. Dit systeem geeft slechte resultaten die lang op zich laten<br />

wachten (afhankelijk van het aantal iteraties).<br />

6.3.2 Semi-random configuraties<br />

Dit systeem is gelijkaardig aan het vorige met de aanpass<strong>in</strong>g dat de zoekruimte wordt verkle<strong>in</strong>d<br />

(zie figuur 6.2. Dit gebeurt met behulp van voorspellende regels die maar één enkele doorloop<br />

nodig hebben (zie verder). In plaats van volledig random getallen te genereren worden nu


6.3 Genereren van noten aan de hand van regels 33<br />

Figuur 6.2: Zoekruimtebeperk<strong>in</strong>g<br />

(gecodeerde) noten gegenereerd die bijvoorbeeld enkel <strong>in</strong> de juiste toonaard staan, waarbij<br />

enkel <strong>in</strong>tervallen <strong>in</strong>gezet worden die passen bij de c.f., . . . Dit systeem is nog altijd niet efficiënt<br />

maar geeft al veel betere resultaten.<br />

6.3.3 Alles uitproberen<br />

Hier worden alle mogelijke configuraties systematisch uitgeprobeerd (met terug een verm<strong>in</strong>derde<br />

zoekruimte). De beste configuratie, of een random configuratie uit het lijstje van beste<br />

configuraties, wordt dan naar voor geschoven als effectieve oploss<strong>in</strong>g.<br />

Dit systeem is bruikbaar voor kle<strong>in</strong>e stukken met een kle<strong>in</strong>e zoekruimte maar wordt al vlug<br />

traag. Het aantal mogelijke oploss<strong>in</strong>gen stijgt exponentieel met de lengte van de te zoeken<br />

configuraties, daarom is het m<strong>in</strong>der bruikbaar als de stukken langer worden. De mogelijkheid<br />

bestaat er wel <strong>in</strong> om langere stukken op te delen <strong>in</strong> kle<strong>in</strong>tjes en er voor te zorgen dat alles<br />

toch nog samen past, maar dat is niet optimaal.<br />

6.3.4 Backtrack<strong>in</strong>g<br />

Backtrack<strong>in</strong>g gaat zo ver mogelijk alle configuraties af, tot er gemerkt wordt dat, als men<br />

verder gaat, de configuratie toch niet beter zal zijn. Daarna keert het backtrack<strong>in</strong>galgoritme<br />

terug en probeert een andere mogelijkheid. Zo worden de beste mogelijkheden uit de immens<br />

grote zoekruimte gehaald zonder dat alles overlopen moet worden.<br />

Om dit zo efficiënt mogelijk te maken wordt de zoekruimte <strong>in</strong> eerste <strong>in</strong>stantie ook zo goed<br />

mogelijk verkle<strong>in</strong>d aan de hand van voorspellende regels met één doorloop. Voorspellende<br />

regels met één doorloop kunnen op voorhand op de gehele zoekruimte toegepast worden (dit


6.3 Genereren van noten aan de hand van regels 34<br />

zijn onder andere de tessituurregel, de toonaardregel, . . . ). Regels die meerdere doorlopen<br />

nodig hebben om te voorspellen zijn regels die, naast de algemene toonaard, c.f., . . . ook<br />

noten nodig hebben die gegenereerd zouden moeten zijn. Een voorbeeld daarvan is de regel<br />

die parallelle kw<strong>in</strong>ten en octaven verbiedt. Men kan pas weten dat er een parallel octaaf<br />

(kw<strong>in</strong>t) is <strong>in</strong>dien de voorlopen van de te voorspellen noot gekend is.<br />

Backtrack<strong>in</strong>g en voorspellende regels met meerdere doorlopen sluiten perfect op elkaar aan.<br />

Bij backtrack<strong>in</strong>g zullen, bij het kiezen van een volgende noot, de voorgaande noten als gekend<br />

beschouwd worden. Zo is de zoekruimte voor de noot veel kle<strong>in</strong>er. Dit kan men zien <strong>in</strong> figuur<br />

6.3. Daar worden de eerste twee noten als vast beschouwd. De mogelijkheden van de derde<br />

noot worden op die mannier dus beperkt tot drie mogelijke waarden. Twee van die waarden<br />

zijn de moeite niet om verder te onderzoeken omdat ze ervoor zorgen dat de vierde noot niet<br />

kan gekozen worden zonder een regel te overtreden. De andere mogelijkheid heeft wel een<br />

goede oploss<strong>in</strong>g.<br />

Figuur 6.3: Backtrack<strong>in</strong>g<br />

6.3.5 Optimalisatieprobleem<br />

Zelfs met de methode die hierboven beschreven staat kan het genereren soms toch nog te lang<br />

duren. Daarom kunnen we bij dit optimalisatieprobleem ook terugvallen op meta-heuristische<br />

methoden. We kiezen ervoor een evolutionair algoritme te gebruiken, namelijk een genetisch<br />

algoritme.<br />

Verloop van een genetisch algoritme<br />

Algemeen bestaat het algoritme uit volgende onderdelen:


6.3 Genereren van noten aan de hand van regels 35<br />

• Initialisatie. Er wordt een beg<strong>in</strong>populatie van configuraties gemaakt. Dit kan random<br />

of semi-random zijn.<br />

• Selectie. Uit de populatie worden de slechtste configuraties weggefilterd.<br />

• Genetisch opereren. De populatie wordt bewerkt met genetische operatoren. Meer<br />

hierover <strong>in</strong> een van de volgende paragrafen.<br />

• Term<strong>in</strong>atie. Aangezien de selectie en het genetisch opereren meerdere keren na elkaar<br />

gedaan worden, moet er een factor zijn die zegt wanneer de loop mag stoppen. Dit kan<br />

zijn na een bepaald aantal iteraties of wanneer elementen <strong>in</strong> de populatie een bepaalde<br />

threshold bereiken.<br />

• Fitnessfunctie. Dit is de functie die oploss<strong>in</strong>gen vergelijkt en vertelt welke beter of<br />

slechter zijn. In dit project komt dit neer op het controleren van de vaste stem(men)<br />

samen met de configuratie.<br />

Initialisatie<br />

Als <strong>in</strong>itiële populatie kunnen random of semi-random configuraties gebruikt worden. Omdat<br />

de overhead bij het produceren van randomconfiguraties met verm<strong>in</strong>derde zoekruimte m<strong>in</strong>iem<br />

is (en omdat we die zoekruimte toch nog moeten gebruiken), worden deze dan ook gebruikt.<br />

Genetisch opereren<br />

Er zijn <strong>in</strong> theorie twee genetische operatoren: crossover en mutation.<br />

Bij crossover (ook wel recomb<strong>in</strong>atie genoemd) wordt een nieuwe configuratie gemaakt uit twee<br />

(of meer) ouders. Hier kunnen we stellen dat een configuratie kan opgebouwd worden uit een<br />

deel van de (gecodeerde) noten van een eerste ouder en een deel van de noten van de tweede<br />

ouder. In het project wordt dit gerealiseerd door de ouders op een random plaats <strong>in</strong> de noten<br />

te splitsen en het eerste deel van de ene te comb<strong>in</strong>eren met het laatste deel van de tweede.<br />

Op die manier zou er een betere configuratie kunnen gemaakt worden.<br />

De tweede methode, mutatie, maakt een nieuwe configuratie uit één enkele ouder. Op één of<br />

meerdere random plaatsen worden (gecodeerde) noten vervangen door een andere. Om toch<br />

het voorgaande werk van de zoekruimtebeperk<strong>in</strong>g niet weg te smijten worden enkel noten uit<br />

de beperkte zoekruimte gebruikt (anders is de kans groot dat de mutatie sowieso slechter is<br />

dan de ouder).<br />

Om mutaties te verbeteren kan men ook gebruik maken van de voorspellende regels <strong>in</strong> meerdere<br />

doorloop. Niet enkel wordt naar de (verm<strong>in</strong>derde) zoekruimte gekeken maar ook naar de<br />

regels die een vaste omgev<strong>in</strong>g veronderstellen. Op die manier zijn verbeter<strong>in</strong>gen waarschijnlijker.<br />

Wel kan dit ervoor zorgen dat men vast raakt <strong>in</strong> een lokaal m<strong>in</strong>imum.<br />

Men kan ook de voorgaande methoden comb<strong>in</strong>eren: gemuteerde ouders comb<strong>in</strong>eren, een gecomb<strong>in</strong>eerde<br />

configuratie ook muteren, . . .


6.3 Genereren van noten aan de hand van regels 36<br />

Coder<strong>in</strong>g van configuraties<br />

In methoden die gebaseerd zijn op evolutie, zoals genetische algoritmen, spreekt men van<br />

genotypen en phenotypen. Hierbij zijn genotypen de effectieve configuraties (of delen ervan)<br />

die men zoekt terwijl phenotypes gecodeerde genotypen zijn. Dit wordt gebruikt om de configuraties<br />

gemakkelijker te manipuleren (comb<strong>in</strong>eren en muteren <strong>in</strong> het geval van genetische<br />

algoritmen).<br />

Zoals vroeger al aangehaald werd worden muzieknoten <strong>in</strong> dit project gecodeerd met behulp<br />

van het Hewlett base40 systeem (of het aangepaste base4096 systeem). Dit is perfect om te<br />

gebruiken <strong>in</strong> een genetisch algoritme. De reeksen gehele getallen kunnen zonder problemen<br />

gecomb<strong>in</strong>eerd worden, vervangen worden, . . .<br />

Term<strong>in</strong>atie<br />

Zoals eerder vermeld gebeurt term<strong>in</strong>atie meestal op basis van een aantal verlopen iteraties of<br />

op basis van een grenswaarde. Een grenswaarde v<strong>in</strong>den voor het genereren van een optimale<br />

stem kan moeilijk zijn omdat de regels, die de fitness- functie beïnvloedden, niet vast liggen.<br />

Als de gebruiker meer of m<strong>in</strong>der regels <strong>in</strong>geeft zou de threshold ook aangepast moeten worden.<br />

Wat men niet kan voorspellen bij die regels is of ze elkaar tegenspreken of niet. Dit bemoeilijkt<br />

de zaak sterk.<br />

Een andere manier is om de term<strong>in</strong>atie te laten afhangen van het aantal iteraties <strong>in</strong> het<br />

algoritme. Dit kan ook terug voor problemen zorgen bij meer of m<strong>in</strong>der regels. Hoe meer<br />

regels, hoe langer het controleren van elke configuratie (de fitness functie dus) duurt. Als men<br />

overdreven veel regels <strong>in</strong>geeft zal de tijd die het algoritme <strong>in</strong> beslag neemt toch onaanvaardbaar<br />

zijn als men het aantal iteraties sterk <strong>in</strong>perkt.<br />

Een andere mogelijkheid is om het algoritme te laten stoppen na een bepaalde tijd. Die<br />

tijd kan dan zelfs gedef<strong>in</strong>ieerd zijn door de gebruiker. Dit geeft de gebruiker een goed beeld<br />

hoelang hij zal moeten wachten, maar kan soms overkill zijn als de tijd te lang <strong>in</strong>gesteld is en<br />

de optimale oploss<strong>in</strong>g al vroeg gevonden wordt.<br />

Om nog meer gebruikersgemak te geven kan er de mogelijkheid <strong>in</strong>gebouwd worden het algoritme<br />

direct te laten stoppen na opdracht van de gebruiker. Daarna kan de tot dan beste<br />

configuratie naar voor geschoven worden als oploss<strong>in</strong>g.<br />

Een optimale afsluitstrategie is, net zoals metaheuristische methoden <strong>in</strong> het algemeen, niet<br />

strak genoeg gedef<strong>in</strong>ieerd. Daarom kan het goed zijn om verschillende methoden te comb<strong>in</strong>eren.<br />

Verdere uitbreid<strong>in</strong>gen<br />

Het voorgaande algoritme kan nog verder uitgebreid worden. Zo zou men een geheugen<br />

kunnen <strong>in</strong>bouwen om ervoor te zorgen dat vroeger verworpen configuraties sowieso niet meer<br />

aanvaard worden. Daarop kan men dan toch een uitzonder<strong>in</strong>gsmechanisme <strong>in</strong>bouwen om<br />

lokale m<strong>in</strong>ima te vermijden.


6.4 Aparte noten, <strong>in</strong> plaats van een volledige stem genereren 37<br />

6.4 Aparte noten, <strong>in</strong> plaats van een volledige stem genereren<br />

In vorige punten werd aangehaald op welke manieren men een volledige muziekstem kan<br />

genereren bij een gegeven stem. Een verdere uitbreid<strong>in</strong>g is niet om een volledige stem te<br />

genereren maar om enkele noten (die aangeduid zijn door de gebruiker) aan te passen of te<br />

genereren. Dit houdt uiteraard <strong>in</strong> dat het kan voorkomen dat er geen oploss<strong>in</strong>g is voor het<br />

gestelde probleem.<br />

De meest gemakkelijke manier om dit te bereiken is via het aanpassen van de zoekruimte.<br />

Men past voorgaande algoritmes gewoon toe op een zoekruimte waar de noten die vastgezet<br />

zijn slechts één mogelijkheid hebben: de <strong>in</strong>gegeven noot.<br />

Om te vermijden dat de zoekruimte van de <strong>in</strong> te vullen noot ledig wordt na een eerste doorloop<br />

kan gebruikt gemaakt worden van de derde methode voor zoekruimtebeperk<strong>in</strong>g (het tellen<br />

aan hoeveel regels een mogelijkheid voldoet <strong>in</strong> plaats van direct te schrappen). Men kan dan<br />

de beste mogelijkheden (lees: de mogelijkheden die de meeste regels respecteren) kiezen als<br />

zoekruimte.<br />

Verder, om dit systeem uit te werken, kan men ook niet gewoon meer een beroep doen op de<br />

berekende score van een configuratie. Er moet eerst gekeken worden welke configuraties de<br />

m<strong>in</strong>ste regels overtreden, en dan pas naar de score van die configuraties kijken. (Dit systeem<br />

wordt ook gebruikt bij het genereren van een volledige stem met gebruikergedef<strong>in</strong>ieerde regels:<br />

de gebruiker kan immers tegenstrijdige regels samen laten werken. . . )


Slot 38<br />

Hoofdstuk 7<br />

Slot<br />

Het doel van het project, namelijk het controleren en genereren van contrapunt, is <strong>in</strong> zekere<br />

mate volbracht. Het project werkte met een testopstell<strong>in</strong>g van een kle<strong>in</strong> aantal noten en een<br />

kle<strong>in</strong>e regelset maar kan zonder problemen verder uitgebreid worden. De applicatie werd voor<br />

gebruikersgemak aangeboden via een website die gebruik maakt van RESTful webservice.<br />

7.1 Serverkant<br />

De RESTful webservice biedt een dienst aan die bijna ogenblikkelijk muziekstukken kan controleren<br />

en genereren aan de hand van een bepaalde regelset. Die regelset wordt opgebouwd<br />

door de gebruiker en kan uit vaste regels (vooral klassiek geïnspireerde regels) en configureerbare<br />

regels (regels die de gebruiker, <strong>in</strong> beperkte mate, kan configureren) bestaan.<br />

Door de relatief kle<strong>in</strong>e regelset bij de testopstell<strong>in</strong>g van het project is het niet mogelijk perfect<br />

te weten hoe de generatiealgoritmes zullen reageren bij wat meer praktische regelsets. Wel is<br />

het duidelijk dat het algoritme dat random configuraties probeert slechter wordt naarmate het<br />

aantal regels toenemen. Zelfs al zijn het random configuraties uit de verm<strong>in</strong>derde zoekruimte.<br />

De voornaamste regels die bij de testopstell<strong>in</strong>g ontbreken zijn namelijk regels die niet <strong>in</strong> eerste<br />

doorloop de zoekruimte kunnen beperken.<br />

De methode die alle configuraties uitprobeert en daarna een beste configuratie selecteert uit<br />

een pool van beste is ook we<strong>in</strong>ig bruikbaar. Zelfs bij de testopstell<strong>in</strong>g (van een 7tal regels<br />

en 8 noten) duurt het ongeveer een halve m<strong>in</strong>uut om de oploss<strong>in</strong>g weer te geven. Bij het<br />

uitbreiden van de regelset zal de zoekruimte wel nog wat <strong>in</strong>geperkt worden maar door het<br />

stijgen van het aantal regels zal de tijd voor het controleren van een configuratie ook omhoog<br />

gaan. Aangezien er immens veel configuraties moeten gecontroleerd worden, zal de tijd van<br />

dit algoritme, bij uitbreid<strong>in</strong>g van de regelset, met grote waarschijnlijkheid ook stijgen.<br />

De beste methodes, namelijk backtrack<strong>in</strong>g en het genetische algoritme, kunnen elkaar afwisselen<br />

afhankelijk van de regelset. Momenteel lijkt het genetisch algoritme beter (lees: sneller)<br />

dan het backtrack<strong>in</strong>galgoritme, maar door de relatief kle<strong>in</strong>e testopstell<strong>in</strong>g is het genetisch<br />

algoritme naar alle waarschijnlijkheid niet goed afgesteld om met grotere regelsets overweg te<br />

kunnen. Verdere uitwerk<strong>in</strong>g hiervan kan dus aangewezen zijn.<br />

Het backtrack<strong>in</strong>galgoritme is het enige dat tijdens het zoeken van de optimale configuratie kan


7.2 Webapplicatie 39<br />

reken<strong>in</strong>g houden met voorspellende regels van meerdere doorloop (zonder de gehele configuratie<br />

te moeten controleren). Dus als de regelset uitgebreid wordt zal het backtrack<strong>in</strong>galgoritme<br />

waarschijnlijk efficiënter te werk gaan.<br />

7.2 Webapplicatie<br />

De webapplicatie is momenteel perfect afgesteld op de webservice maar is nog niet zo gebruiksvriendelijk.<br />

Van de gebruiker wordt verwacht dat hij bijna geen fouten maakt <strong>in</strong> de <strong>in</strong>voer.<br />

Dit kan verbeterd worden door, <strong>in</strong> plaats van tekst<strong>in</strong>put, gebruik te maken van dropdown<br />

menu’s en dergelijke.<br />

Het renderen van noten lijkt op het eerste zicht voldoende maar kan ook nog wat beter. Zo<br />

zou er beter duidelijker aangegeven worden waar een fout zit bij na het controleren van een<br />

stuk. De noten <strong>in</strong> meerdere stemmen staan ook niet altijd perfect boven elkaar omdat de<br />

stemmen onafhankelijk van elkaar gerenderd worden op een verschillende notenbalk. Ook<br />

zouden maatstrepen het geheel duidelijker maken. Een aanvull<strong>in</strong>g bij het afspelen van de<br />

noten zou kunnen zijn dat de noten die op dat moment kl<strong>in</strong>ken, aangeduid worden.<br />

7.3 Conclusie<br />

Het is duidelijk dat de <strong>in</strong>tenties <strong>in</strong> het beg<strong>in</strong> van het project volbracht zijn. Wel zou het, voor<br />

het effectief gebruikt zou kunnen worden <strong>in</strong> de echte wereld, wat afgewerkt moeten worden<br />

qua gebruikersgemak en mogelijkheden van regels.


LIJST VAN FIGUREN 40<br />

Lijst van figuren<br />

2.1 Streng contrapunt van de eerste soort . . . . . . . . . . . . . . . . . . . . . . 4<br />

2.2 Streng contrapunt van de tweede soort . . . . . . . . . . . . . . . . . . . . . . 4<br />

2.3 Streng contrapunt van de derde soort . . . . . . . . . . . . . . . . . . . . . . . 4<br />

2.4 Streng contrapunt: overgebonden halfbeweg<strong>in</strong>gen . . . . . . . . . . . . . . . . 4<br />

2.5 Vrij contrapunt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

2.6 Perfecte consonanten, respectievelijk het unisono, het octaaf en de re<strong>in</strong>e kw<strong>in</strong>t 5<br />

2.7 Imperfecte consonanten, respectievelijk de grote terts, kle<strong>in</strong>e terts, grote sext<br />

en kle<strong>in</strong>e sext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.8 Dissonanten, respectievelijk de grote en kle<strong>in</strong>e secunde, kwart, vermeerderde<br />

kwart en verm<strong>in</strong>derde kw<strong>in</strong>t, grote en kle<strong>in</strong>e septiem . . . . . . . . . . . . . . 6<br />

2.9 Nootprogressies, respectievelijk de tegenbeweg<strong>in</strong>g, parallelle beweg<strong>in</strong>g en oblique<br />

beweg<strong>in</strong>g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

3.1 Het samenwerkende model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

4.1 Objectgeoriënteerd model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

5.1 Weergeven en aanduiden van regels op de website . . . . . . . . . . . . . . . . 23<br />

5.2 Inputmodule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

5.3 Details van een regel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

5.4 Configuratie van een regel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

5.5 Volledige webapplicapplicatie . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

5.6 VexFlow voorbeeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

5.7 VexTab voorbeeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />

6.1 Klassenschema regels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

6.2 Zoekruimtebeperk<strong>in</strong>g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

6.3 Backtrack<strong>in</strong>g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

A.1 Modulo-40 mapp<strong>in</strong>g 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43


LIJST VAN TABELLEN 41<br />

Lijst van tabellen<br />

4.1 Mapp<strong>in</strong>g van base192 op nootlengte . . . . . . . . . . . . . . . . . . . . . . . 13<br />

4.2 Muziektheoretische <strong>in</strong>tervallen met hun overeenkomstige nummers . . . . . . 15


BIBLIOGRAFIE 42<br />

Bibliografie<br />

C. Blum & A. Roli (2003). Metaheuristics <strong>in</strong> comb<strong>in</strong>atorial optimization: Overview and<br />

conceptual comparison. ACM Comput<strong>in</strong>g Surveys (CSUR), 35(3):268–308.<br />

J. J. Fux & A. Mann (1965). The study of counterpo<strong>in</strong>t from Johann Joseph Fux’s Gradus<br />

ad Parnassum, volume 277. WW Norton & Company.<br />

N. Gallon & M. Bitsch (1964). Traité de contrepo<strong>in</strong>t. Durand.<br />

W. B. Hewlett (1992). A base-40 number l<strong>in</strong>e representation of musical pitch notation.<br />

Musikometrika, 50:1–14.<br />

jQuery (2013). jquery. URL http://jquery.com/.<br />

S. Magaz<strong>in</strong>e (2012). JavaScript Essentials. Smash<strong>in</strong>g Magaz<strong>in</strong>e.<br />

M. Muthanna (2013a). Vexflow - music engrav<strong>in</strong>g <strong>in</strong> javascript and html5. URL http:<br />

//www.vexflow.com.<br />

M. Muthanna (2013b). Vextab - a simple text-based language for music notation. URL<br />

http://vexflow.com/vextab.<br />

Underscore (2013). Underscore.js. URL http://underscorejs.org/.<br />

Wikipedia (2011b). Music theory/counterpo<strong>in</strong>t/species counterpo<strong>in</strong>t/<strong>in</strong> two voices.<br />

URL http://en.wikibooks.org/wiki/Music_Theory/Counterpo<strong>in</strong>t/<br />

Species_Counterpo<strong>in</strong>t/In_Two_Voices.<br />

Wikipedia (2013a). Genetic algorithm. URL http://en.wikipedia.org/wiki/<br />

Genetic_algorithm.


Hewlett base40 systeem 43<br />

Bijlage A<br />

Hewlett base40 systeem<br />

Figuur A.1: Modulo-40 mapp<strong>in</strong>g 1<br />

1 http://www.ccarh.org/publications/repr<strong>in</strong>ts/base40/

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!