Využití Riemannovy teorie pro automatizovanou sazbu not

Transkript

Využití Riemannovy teorie pro automatizovanou sazbu not
Konzervatoř P. J. Vejvanovského Kroměřı́ž
Materiály pro výuku IKT v hudbě (2015/2016)
Využitı́ Riemannovy teorie
k automatizaci hudebnı́ sazby v systému
Lilypond
Adam Šiška
1
Úvod do implementace
V tomto textu nastı́nı́me možnosti aplikace počı́tačového programovánı́ a sazby
notových zápisů v Riemannově1 teorii hudebnı́ harmonie. Zůstaneme poplatni
základnı́m omezenı́m této teorie jako je ignorovánı́ oktávového členěnı́ tónů,
stejně jako jejich enharmonické chápánı́ s tı́m, že tyto nedostatky mohou sloužit
jako náměty pro samostatnou studentskou činnost. Pokusı́me se o implementaci základnı́ch operacı́ teorie v jazyce Haskell2 . Sazbu notových zápisů zajistı́ systém Lilypond3 . Podrobnějšı́ informace ohledně technických detailů práce
s představenými systémy nalezne čtenář v poslednı́ kapitole textu.
2
Zavedenı́ jmen tónů
V Riemanově teorii ztotožňujeme jména tónů s dvanácti čı́sly od nuly do jedenácti. Prvnı́m samozřejmým problémem je tedy nemožnost (enharmonického)
rozlišenı́ mezi křı́žky a béčky. V programovém kódy budeme tedy vytvářet obě
dvě varianty výpisu čı́selných (tónových) řad. Je zřejmé, že dı́ky tomuto faktu,
nelze očekávat sto procentnı́ korektnost z hlediska klasické hudebnı́ teorie.
1 https://en.wikipedia.org/wiki/Neo-Riemannian
theory (cit. 24.4.2016)
2 https://www.haskell.org/hugs/pages/downloading.htm
3 http://lilypond.org/download.html,
http://frescobaldi.org/download
1
Nebudeme hned rozebı́rat všechny aspekty jazyka Haskell. Dı́ky jeho funkcionálnı́mu zápisu budou implementace definic teorie velmi přı́močaré. Vždy
když to jen trochu půjde využijeme triků pro odstraněnı́ technikcýh problémů.
V prvnı́ definici funkce ton stanovı́me všem čı́slům přı́slušná jména tónů s křı́žky.
Následujı́cı́ řádky (a dalšı́ definice) je třeba uložit do počı́tačového souboru
se správnou přı́ponou, např. tonnetz.hs.
ton
ton
ton
ton
ton
ton
ton
ton
ton
ton
ton
ton
ton
0 = " c"
1 = " cis"
2 = " d"
3 = " dis"
4 = " e"
5 = " f"
6 = " fis"
7 = " g"
8 = " gis"
9 = " a"
10 = " ais"
11 = " b"
x = ton (x ‘mod‘ 12)
Funkce ton převede jedno čı́slo na jméno tónu, které čı́slo zastupuje. V jazyce
Haskell můžeme jednoduše pracovat s celými řadami čı́sel (a tedy tónů). Řadu
čı́sel zadáme pomocı́ hranatých závorek např. takto: [0,4,7,4,4,2,4]. Pro
převedenı́ celé takové řady na jména tónů v systému Lilypond definujeme funkci
tony.
tony s = concat (map ton s)
Zbývá doplnit paralelnı́ funkce tonB a tonyB, které budou překládat čı́sla na názvy tónů s béčky. Stačı́ doplnit následujı́cı́ řádky kódu.
tonB 1 = " des"
tonB 3 = " es"
tonB 6 = " ges"
tonB 8 = " as"
tonB 10 = " bes"
tonB x = ton x
tonyB s = concat (map tonB s)
Transpozice a inverze
Užitı́ představených funkcı́ nabývá na efektivitě při použitı́ dvou základnı́ch
operacı́ Riemannovy teorie transpozice a inverze. Obě operace lze opět přı́močaře
implementovat, každou operaci následuje rozšı́řenı́ na řadu čı́sel.
2
t n x
trans
i n x
inv n
=
n
=
s
(x + n) ‘mod‘ 12
s = map (t n) s
(-x + n) ‘mod‘ 12
= map (i n) s
Stupnice
Nynı́ můžeme představit prvnı́ možnosti automatizace hudebnı́ sazby na přı́kladu stupnic. Stupnice je tónová řada vzniklá historicky, tudı́ž je třeba definovat
základnı́ stupnice jako konstanty.
cdur = [0,2,4,5,7,9,11,0]
amoll = [9,11,0,2,4,5,7,9]
Dalšı́ stupnice ale lze zı́skat automaticky. Je nutné zdůraznit, že představený
systém v obou přı́padech křı́žků i béček rozeznává pouze pět prvnı́ch těchto
předznamenánı́. Stupnice vzdálené již nejsou vypsány korektně z hlediska hudebnı́ harmonie, z hlediska enharmonické záměny tónů (a tedy např. výstupu
MIDI) jsou všechny stupnice v pořádku.
Pokud definice tonnetz.hs otevřeme4 pomocı́ programu Hugs (WinHugs), dostaneme možnost využı́vat definované funkce. Přı́klady povelů pro systém Hugs
budou vždy uvozeny výzvou Main> a bude je následovat výsledek interpretace
povelu na novem řádku.
Pro začátek zkusı́me funkčnost zadaných funkcı́5 . Následujı́cı́ řádky ukazujı́
žádanou interakci se systémem Hugs.
Main> ton 6
" fis"
Main> tonB 10
" bes"
Main> tony [2,6,9]
" d fis a"
Main> tonyB [3,7,10]
" es g bes"
V generovánı́ stupnic začneme (informaticky) od nuly. Následujı́cı́ povel vypı́še
stupnici cdur, kterou máme zadanou jako konstantu.
Main> tony (trans 0 cdur)
" c d e f g a b c"
4 Pokud po otevřenı́ vidı́te výzvu Main> proběhlo vše v pořádku. Pokud vidı́te chybový
výpis a výzvu Hugs>, je ve vašem souboru nějaký překlep.
5 Definované funkce lze vypsat povelem Main>:b
3
Dalšı́ stupnice s jednı́m křı́žkem (G dur) začı́ná o sedm půltónů (tj. kvintu) výš
než C dur. S každým dalšı́m posunem o sedm (kvintovým) vzniká dalšı́ stupnice.
Main>
" g a
Main>
" d e
Main>
" a b
tony (trans 7 cdur)
b c d e fis g"
tony (trans 14 cdur)
fis g a b cis d"
tony (trans 21 cdur)
cis d e fis gis a"
Stupnice s béčky vznikajı́ při kvartových posunech, tj. posunech o pět půltónů.
Main> tonyB (trans 5 cdur)
" f g a bes c d e f"
Main> tonyB (trans 10 cdur)
" bes c d es f g a bes"
Main> tonyB (trans 15 cdur)
" es f g as bes c d es"
Přı́klady sazby
Představené funkce lze použı́t při tvorbě nejrůznějšı́ch (chromatických) cvičenı́.
Rozklady kvintakordů lze v postupu po kvartách definovat třeba takto (připomı́náme že výsledek je vhodnějšı́ použı́t spı́še sluchově“ v MIDI, protože
”
z hlediska hudebnı́ teorie nejsou všechna jména tónů korektnı́):
Main> concat [ tonyB (trans i [0,4,7]) | i<-[0,5,10,15,20,25,30] ]
" c e g f a c bes d f es g bes as c es des f as ges bes des"
Inverze měnı́ tónorod melodie a umožňuje zı́skat zajı́mavé náměty z již existujı́cı́ nápěvků. Pokud vezmeme napřı́klad tóny lidové pı́sně Ovčáci, čtveráci“,
”
zı́skáme postup v f moll:
Main> tonyB (inv 0 [0,4,7,4,4,2,4,5,2,4,2,0])
" c as f as as bes as g bes as bes c"
4
3
Generovánı́ a sazba akordů
Kvintakord je trojice tónů znějı́cı́ch zároveň. V systému Lilypond takové souzvuky uzavı́ráme do lomených závorek <>. Jak lze vidět v poslednı́m přı́kladu,
inverze tvořı́ z durového kvintakordu [0,4,7] trojici tónů [0,8,5] což je pozpátku jmenovaný mollový kvintakord. Tónorod tedy musı́me v implementaci
rozeznat, takže definujeme predikáty dur a moll.
dur [x,y,z] = ((x+4) ‘mod‘ 12 == y) && ((x+7) ‘mod‘ 12 == z)
dur _ = False
moll [x,y,z] = ((x+8) ‘mod‘ 12 == y) && ((x+5) ‘mod‘ 12 == z)
moll _ = False
Následujı́ definice funkcı́ akord a akordB, které trojici tónů přeložı́ na zápis
jejich souzvuku v systému Lilypond. Pořadı́ tónů mollového kvintakordu musı́
být opačná.
akord s = if moll s then " <" ++ tony (reverse s) ++ ">"
else " <" ++ tony s ++ ">"
akordB s = if moll s then " <" ++ tonyB (reverse s) ++ ">"
else " <" ++ tonyB s ++ ">"
Stejně jako v přı́padě jednotlivých tónů, které tvořı́ řady, budou nás zajı́mat
řady akordů. Poslednı́ dvě funkce vypisujı́ libovolný počet akordů najednou,
napřı́klad v tónině C dur zadáme TSD jako [[0,4,7],[5,9,0],[7,11,2]].
akordy s = concat (map akord s)
akordyB s = concat (map akordB s)
Poznamenejme, že v tomto přı́padě nedává výpis s křı́žky nebo s béčky stejný
smysl jako při práci s řadou tónů. Akord sám běžně zadává tóninu, jejı́ž předznamenánı́ je určeno. Napsat adekvátnı́ funkci akordyT může čtenář zkusit jako
cvičenı́. Na závěr uvedeme přı́klad povelu vypisujı́cı́ho TSD v tónině Es dur.
Main> akordyB (map (trans 3) [[0,4,7],[5,9,0],[7,11,2]])
" < es g bes> < as c es> < bes d f>"
4
PLR-systém
Riemannova teorie dává různé akordy do různých harmonicko-matematických
vztahů označených velkými pı́smeny P, L, R6 . Tyto vztahy následně vytvářejı́ sı́t’
6 Pı́smena vycházejı́ z anglického pojmenovánı́ vztahu tónin, tj. Parallel – tónina stejnojmenná, Relativ – tónina paralelnı́ a Lead tone exchange – tónina hornı́ tercie.
5
akordů Tonnetz uspořádaných do tvaru toru (torus je objekt připomı́najı́cı́ americkou koblihu s dı́rou uprostřed, topologicky shodný třeba i s šálkem na kávu).
p [x,y,z] = inv (x+z) [x,y,z]
r [x,y,z] = inv (x+z) [x,y,z]
l [x,y,z] = inv (x+z) [x,y,z]
Jednoduchá aplikace nových funkcı́ je snadná. Při současné aplikaci vı́ce operacı́ na akord uplatnı́me standardnı́ notaci pro skládánı́ funkcı́7 , např. operaci
l(r(l(r [0,4,7]))), zapı́šeme (l.r.l.r) [0,4,7]. Následuje přı́klad operacı́
P, L, R pro akord a moll, dostáváme postupně A dur, C dur a F dur.
Main>
" < a
Main>
" < c
Main>
" < f
akord (p [4,0,9])
cis e>"
akord (l [4,0,9])
e g>"
akord (r [4,0,9])
a c>"
Při úvahách o postupech akordů musı́me pracovat s posloupnostmi, ve kterých
následujı́cı́ člen závisı́ na předchozı́m. Z tohoto pohledu definujeme elementárnı́
funkci iter, jež jako parametr dostane funkci následnı́ka f a prvnı́ hodnotu x,
a generuje (nekonečnou) posloupnost [x, f x, f (f x), f (f (f x), ...].
iter f x = x : iter f (f x)
Napřı́klad jsme viděli, že kvartové posuny generujı́ nové tóniny s béčky:
Main> akordyB (take 6 (iter (trans 5) [0,4,7]))
" < c e g> < f a c> < bes d f> < es g bes> < as c es> < des f as>"
V analýze postupu akordů nás zajı́majı́ vztahy (vazby) po sobě jdoucı́ch akordů.
A tyto vztahy jsou pochopitelně různé. Potřebujeme tedy zavést funkci podobnou funkci iter, která ale dostane celou řadu funkcı́ a bude je postupně
uplatňovat na zadaný akord.
postup [] a = [a]
postup (f:s) a = a : postup s (f a)
Pokud funkci použijeme pro tři povely, napřı́klad postup [f,g,h] x, zı́skáme
ve výsledku čtyři prvky [x, f x, g (f x), h (g (f x))].
7 Platı́ (.) f g x = f (g x). Pro přı́padně zájemce o problematiku je nutné podotknout, že
funkce (.) je jednou z několika málo vstupnı́ch bran k pochopenı́ funkcionálnı́ho programovánı́.
6
Následujı́cı́ přı́klady jsou z úvodnı́ho textu o Riemannově teorii, jedná se o postup I-vi-IV-V 50. léta“, postup Pachelbel“ a postup Devátá“:
”
”
”
Main> akordy (postup [r,l, r.l.r.l, l.r] [0,4,7])
" < c e g> < a c e> < f a c> < g b d> < c e g>"
Main> akordy (postup [r.l, r.l.r, l.r, l] [2,6,9])
" < d fis a> < a cis e> < b d fis> < fis a cis> < d fis a>"
Main> akordy (postup (concat [[r, l]|i<-[1..12]]) [0,4,7])
" < c e g> < a c e> < f a c> < d f a> < ais d f> < g ais d> ...
Rozšı́řenı́ NSH
Základnı́ operace P, L, R lze rozšı́řit o různé zkratky. Napřı́klad pro durové
kvintakordy platı́, že složená operace R · L vede na subdominantu, a operace
L · R vede na dominantnu zadaného akordu.
V tzv. neo-Riemannovské teorii se užı́vajı́ tři dalšı́ operace N, S, H jako zkratky
za složené operace P · L · R, R · P · L a L · P · L.
n = p.l.r
s = r.p.l
h = l.p.l
V následujı́cı́ch přı́kladech jsou vypsáni NSH následnı́cı́ akordu C dur, tj. f moll,
cis moll a as moll (všimněme si enharmonicky vyjádřeného tónu b = ces).
Main> akord (n [0,4,7])
" < f as c>"
Main> akord (s [0,4,7])
" < cis e gis>"
Main> akord (h [0,4,7])
" < as b es>"
Přı́buznost kvintakordů a jejich spoje
Pozorný čtenář si jistě všiml, že akordy ve vztazı́ch P, L, R ale i N, S nebo L.R,
R.L obsahujı́ vždy nějaké společné tóny. Společné tóny jsou v hudebnı́ teorii
důsledkem definice přı́buznosti na různých skupinách kvintakordů (vždy v jedné
diatonické stupnici). V tomto textu zavedeme pojem přı́buznosti obecněji v opačném směru8 , právě jako výskyt stejných tónů v obou akordech (dodejme, že
u navzájem různých akordů mohou nastat pouze tři situace, žádný, jeden, nebo
dva společné tóny).
8 V hudebnı́ teorii napřı́klad akordy C dur a c moll nejsou přı́buzné, ačkoliv majı́ dva
společné tóny. Nevyskytujı́ se společně v jedné diatonické stupnici.
7
Harmonické zákonitosti vyžadujı́, aby akordy se společnými tóny byly napojeny tzv. přı́sně. To znamená, že společné tóny akordů majı́ být tzv. zadrženy
v jednom hlase a ostatnı́ tóny majı́ být vedeny nejkratšı́ cestou. V tomto textu
nám jde o ukázky algoritmického myšlenı́ aplikovaného v hudebnı́ teorii (a ne
o úplnou faktickou správnost z jejı́ho hlediska), zkusme tedy i definici přı́sného
spoje poněkud zobecnit.
Základnı́ myšlenkou spojovánı́ akordů je plynulost. Zajı́má nás vzdálenost jednotlivých tónů mezi dva akordy a tuto vzdálenost se snažı́me minimalizovat.
Zavedeme jednoduchou definici minimálnı́ vzdálenosti tónů a na ni založenou
vzdálenost dvou akordů:
v n m = min ((n-m) ‘mod‘12) ((m-n) ‘mod‘ 12)
vzd [a,b,c] [x,y,z] = v a x + v b y + v c z
Při posuzovánı́ vzdálenostı́ jednotlivých tónů v akordech, musı́me pochopitelně
vyzkoušet všechny možnosti prohozenı́ třı́ tónů druhého akordu. Naprogramovat
obecnou funkci permutace libovolných prvků je problém nad rámec tohoto textu.
Zde využijeme faktu, že permutace provádı́me vždy pouze na trojicı́ch tónů.
Možnostı́, jak různě uspořádat tři tóny je šest. Přı́mo je tedy vyjmenujeme:
perm [x,y,z] = [[x,y,z],[x,z,y],[y,x,z],[y,z,x],[z,x,y],[z,y,x]]
Nynı́ stačı́ definované funkce vhodně zkombinovat. Určı́me vzdálenost prvnı́ho
zadaného akordu [a,b,c] ke všem šesti variantám druhého akordu [x,y,z]
a vybereme tu jeho variantu, která vykazuje vzdálenost celkově nejmenšı́. Pro
ilustraci úvahy provedeme přı́kazy pro spoj akordů C dur a e moll:
Main> perm [11,7,4]
[[11,7,4],[11,4,7],[7,11,4],[7,4,11],[4,11,7],[4,7,11]]
Main> [ vzd [0,4,7] x | x<-perm [11,7,4]]
[7,1,13,9,9,11]
Z výsledku druhého přı́kazu vidı́me, že nejmenšı́ vzdálenost se zadaným akordem C dur vykazuje druhá varianta akordu e moll tvaru [11,4,7].
Zbývá tedy doplnit funkci, která bude pro dva zadané akordy vracet konkrétnı́
obrat druhého z nich. Definice už nenı́ úplně triviálnı́, potřebuje pomocné funkce
nejmensi a pos, které určı́ pozici nejmenšı́ hodnoty v seznamu vzdálenostı́.
Na stejném mı́stě v seznamu permutacı́ akordu totiž najdeme výsledný obrat.
spoj a b = (perm b) !! nejmensi [vzd a x| x<-perm b]
nejmensi x = pos 0 x (minimum x)
pos i (x:s) y = if x==y then i else pos (i+1) s y
8
Jako ukázku použitı́ těchto definic vytvořı́me funkci zpracovávajı́cı́ výstup funkce
postup (tj. řadu akordů) z úvodu této kapitoly. Každý spoj vždy závisı́ na aktuálnı́m akordu a vybraný obrat v následném kroku ovlivňuje dalšı́ akordy.
spoje (a:b:s) = a:spoje (spoj a b:s)
spoje s = s
Na závěr textu uvedeme přı́klady generovánı́ spojených postupů akordů podle
vzoru 50. léta“ a Pachelbel“ i s grafickými výstupy:
”
”
Main> akordy (spoje (postup [r,l, r.l.r.l, l.r] [0,4,7]))
" < c e g> < c e a> < c f a> < b d g> < c e g>"
Main> akordy (spoje (postup [r.l, r.l.r, l.r, l] [2,6,9]))
" < d fis a> < cis e a> < d fis b> < cis fis a> < d fis a>"
5
Technické okénko
Poslednı́ kapitola tohoto textu popisuje zprovozněnı́ aplikacı́ a představenı́ způsobu práce s nimi na počı́tači se systémem Windows.
Nejprve nainstalujeme software zmı́něný v úvodu textu. Začneme programem
WinHugs. Po jeho instalaci a spuštěnı́ vidı́me prostředı́ s výzvou Hugs>. Mı́rně
problematické se může jevit vytvořenı́ zdrojového souboru jazyka Haskell. Zdrojový soubor je čistě textový soubor, který v prostředı́ Windows vytvořı́me pomocı́ aplikace Poznámkový blok. Při ukládánı́ je nutné uvést celé jméno souboru
i s přı́ponou .hs a ve volbě typu souboru vybrat Všechny soubory (*.*) mı́sto
volby Textové dokumenty (*.txt). Pokud soubor správně uložı́te, měl by zı́skat
ikonu listu papı́ru se zahnutým rohem a se symbolem lambda (λ). Tento soubor
můžete otevřı́t v prostředı́ WinHugs dvojklikem“ a pokud soubor neobsahuje
”
syntaktické chyby, mı́sto standardnı́ výzvy programu uvidı́te výzvu Main>. Nynı́
můžete vyhodnocovat zadané hodnoty a funkce napsánı́m jejich jména (přı́padně
parametrů) a potvrzenı́m klávesou Enter. V programu funguje historie přı́kazů
ovládaná šipkami nahoru a dolů. Při změně zdrojového souboru stačı́ v prostředı́
WinHugs vstupnı́ definice obnovit povelem :r, vypsánı́ načtených funkcı́ provede povel :b.
9
Druhým krokem je instalace systému Lilypond pro sazbu not. Systém Lilypond nainstalujeme snadno, jeho použitı́ (jedná se o překladač) ale nemusı́
být pro běžné uživatele GUI systémů pohodlné. Nainstalujeme proto také tzv.
frontend s názvem Frescobaldi, který nám umožnı́ s překladačem Lilypond
pracovat na úrovni WYSIWYG9 ve vı́ce oddělených částech hlavnı́ho okna,
z nichž jedno bude obsahovat zdrojový text v jazyce Lilypond a druhé bude
zobrazovat výsledný PDF soubor s notami. Mezi nástroji tohoto programu je
i průvodce vytvořenı́m složitějšı́ch partitur, panel pro rychlé vkládánı́ přı́kazů,
nebo přehrávánı́ výsledných MIDI souborů.
Zbývá popsat jak pracovat s představeným programovým kódem. Zadaný soubor tonnetz.hs doporučujeme otevřı́t jak v Poznámkovém bloku pro úpravy,
tak v prostředı́ WinHugs pro vyvolávánı́ funkcı́ už od samého začátku vytvářenı́
souboru a postupně přidávat definice z tohoto textu. Po každé změně stačı́
v Poznámkovém bloku soubor uložit (Ctrl+S) a v prostředı́ WinHugs zadat
:r. Podle následujı́cı́ výzvy hned vidı́me, zda nemáme v souboru chybu. Pokud
ano, je zobrazen řádek jejı́ho výskytu. Textové výstupy jednotlivých přı́kazů
obsahujı́cı́ch noty lze okamžitě využı́t při sazbě not. Stačı́ výsledek funkce (bez
okrajových uvozovek) vybrat a zkopı́rovat. Vloženı́ do programu Frescobaldi
musı́ předcházet bud’ vytvořenı́ nové partitury s průvodcem (ve zdrojovém textu
je následně komentářem % Hudba následuje zde. vyznačeno, kam je třeba text
vložit), nebo je nutné vytvořit alespoň elementárnı́ přı́klad pro relativnı́ vkládánı́
not:
\relative c’ {
% Hudba následuje zde.
c4 e g c | c,1
}
Pro překlad kódu na notový výstup stačı́ kliknout na ikonu leknı́nu (Vyrýt).
9 What
You See Is What You Get – co vidı́š, to dostaneš
10