Download in .pdf-bestand - Hogeschool Gent
Download in .pdf-bestand - Hogeschool Gent
Download in .pdf-bestand - Hogeschool Gent
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/