リムナンテスは愉快な気分

徒然なるままに、言語、数学、音楽、プログラミング、時々人生についての記事を書きます

イスクイル 4 (v.0.19) で地理的固有名詞を表す(2)

この記事はイスクイル 4 (2021)を扱っています。対応するバージョンは

です。


limnanthaceae.hatenablog.com

これの続きです。


都市・国家について。

都市名

語幹 -PHW- を用います。hluséi-phwära または phwära hle'i または phwära hi に固有名詞を後置させると表現できます。意味は「〜という固有名で表される街」。

とてもかんたん。

日本語 イスクイル
東京 hluséi-phwära tokyo
デリー hluséi-phwära dilli
上海 hluséi-phwära zaňhe
サンパウロ hluséi-phwära saupaulu
メキシコシティ hluséi-phwära méxiko
カイロ hluséi-phwära alkáhira
ムンバイ hluséi-phwära mumbëi
北京 hluséi-phwära peičiň
ダッカ hluséi-phwära dhaka
大阪 hluséi-phwära osaka
ニューヨーク hluséi-phwära nuyórk

「シティ」は音写しないほうがよいと思います。

国名

くそめんどい。

基本は wusuḑca 「〜という地/国」を使います。文脈から国だとわかる場合は単に wusa でも可。

日本語 イスクイル
日本 wusuḑca nihón *1
カナダ wusuḑca kánada
フランス wusuḑca fřans
ドイツ wusuḑca doič
イタリア wusuḑca italya
ロシア wusuḑca rasiya


国名に政治体制が含まれる場合(ドミニカ共和国など)や、方角が含まれる場合(北マケドニア南アフリカなど)、その政治体制や方角の部分をイスクイルの語彙を使って表現します。

…というよりは政治体制込みでないと、国家が特定されない場合だと思いますが。

共和国

共和国は語根 -ḐT- を使います。

日本語 イスクイル
中央アフリカ共和国 hlusëudnéi-eḑtëila áfrika
ドミニカ共和国 hlusëudnéi-eḑtëila domínika
コンゴ民主共和国 hlaḑtáu-eḑtëila hi kongo


ちなみにドミニカ国wusuḑca domínikaコンゴ共和国wusuḑca kongo

方角・地理的特徴入り

日本語 イスクイル
北マケドニア wusaidna makedóniya
南アフリカ wusuidna áfrika
南スーダン wusuidna sudán
赤道ギニア hlantňú-wusa giné

首長国連邦・連合王国・合衆国

日本語 イスクイル
アラブ首長国連邦 hlellú-ellkina hi arab
グレートブリテン及び北アイルランド連合王国 hlellú-allkila (hi britanya hiu wusadnuň eryë)
アメリカ合衆国 hluséi-eksmaça amérika

*1:母語話者感覚

イスクイル 4 (v.0.19) で地理的固有名詞を表す(1)

この記事はイスクイル 4 (2021)を扱っています。対応するバージョンは

です。


大州・大洋・山・海・湖・川・砂漠といった、自然のものに対する固有名詞がイスクイル 4でどのように表されるか?



固有名詞はイスクイルの音韻に適合するように発音が置き換えられ、借用語として扱われます。

固有名詞はイスクイル単語としてそのまま使えず、必ず媒介語幹(carrier stem)-S- から作られる単語に後置されます。(具体的な形態論構成は各具体例の下で説明するので、そちらを参照してください。)
ショートカット hle'ihi を使うこともありますが。

大州

大州=大陸と考えても多分差し支えない。

ここで、大州とはアジア州ヨーロッパ州アフリカ州オセアニア州北アメリカ州南アメリカ州、南極州からなる七大州を指すこととします。
アジアとヨーロッパはユーラシア大陸じゃないのかとか思いますが、大州・大陸の数え方は諸説あるようですので、とりあえず一番細かい分類である七大州のイスクイル的表現を考えます。

これら大州を表すときは usarça を用います。この単語の大まかな意味(直訳)は「(後続する名詞は)地理的な場所を表す固有名称または借用語で、3つ以上の互いに異なる各要素が連合して相補的に一つの機能を持っている」です。

なおイスクイルには「北方」を表す接辞 -aidn- 、「南方」を表す接辞 -uidn- があります。これらの接辞は usarç- と -a の間に挿入されます。したがって、北アメリカ州には usarçaidna南アメリカ州には usarçuidna が使われます。なので、それぞれイスクイル的には「アメリカ州の北部」、「アメリカ州の南部」といったような表現になると思われます。

日本語 イスクイル
アフリカ州 usarça áfrika
南極州 usarça antárktika
アジア州 usarça asya
ヨーロッパ州 usarça europa
オセアニア州 usarça oseanya
北アメリカ州 usarçaidna amérika
南アメリカ州 usarçuidna amérika


usarça は形態論的に u-s-a-rç-a と分解されます。
(Slot Xの音価 [n] は「後ろからn番目の音節にアクセント」を意味します。)

Slot 音価 グロス
II u S3/PRC
III s [the "carrier" root]
IV a STA/BSC/EXS
VI COA/MDF/DEL/M/NRM
IX a THM
X [2] UNFRAMED


usarçaidna

Slot 音価 グロス
II u S3/PRC
III s [the "carrier" root]
IV a STA/BSC/EXS
VI COA/MDF/DEL/M/NRM
VII aidn OGC_2/1
IX a THM
X [2] UNFRAMED


usarçuidna

Slot 音価 グロス
II u S3/PRC
III s [the "carrier" root]
IV a STA/BSC/EXS
VI COA/MDF/DEL/M/NRM
VII uidn OGC_2/1
IX a THM
X [2] UNFRAMED

大洋

ここでいう大洋は太平洋、大西洋、インド洋、北極海南極海の五大洋を指すこととします。

大洋を表すには hluséi-bwala もしくは bwala hi を使います。
bwala が「海」を表しています。hluséi-の部分が「固有名」といったような意味合いを持っています。「〜という固有名の海」を表すには、「固有名」で「海」を修飾する、つまり「固有名の」のような形容詞を作ればよいです。イスクイルでは、修飾語(「固有名」)の語形を変えてハイフンで被修飾語(「海」)に繋げることで実現します。この修飾語のことを concatenated formative (連結形成素;修飾形成素*1)、被修飾語のことを parent formative (親形成素;被修飾形成素)と呼びます。

もう一つの方法の bwala hi ですが、この hi は register adjunct (記銘付属詞)と呼ばれるもののうちの SPECIFICATIVE です。hi の後ろの単語は、hi に先行する形成詞の固有名詞を表します。

日本語 イスクイル
太平洋 hluséi-bwala pasífika / bwala hi pasífika
大西洋 hluséi-bwala atlantis / bwala hi atlantis
インド洋 hluséi-bwala indus / bwala hi indus
北極海*2 hluséi-bwala arktos / bwala hi arktos / bwalaidna
南極海 bwaluidna


hluséi-bwala
Type-1は形容詞が修飾する、Type-2は合成語を生成する、といったイメージでよいと思います、
hluséi の slot IX はアクセントが乗っていますが Illocution+Expectation+Validation ではなく Format(=Case?)を表します。多分、格と同じと考えてよいと思います。多分。というわけで、hluséi は様格「〜として」を取っています。

Slot 音価 グロス
I hl [Type-1 Concatenation]/[Default]
II u S3/PRC
III s [the "carrier" root]
IX ei ESS
X [1] UNFRAMED
-
II (a) S1/PRC
III bw 'body of salt water'
IV a STA/BSC/EXS
VI l CSL/UPX/DEL/M/NRM
IX a THM
X [2] UNFRAMED


bwala hi

II (a) S3/PRC
III bw [the "carrier" root]
IV a STA/BSC/EXS
VI l COA/MDF/DEL/M/NRM
IX a THM
X [2] UNFRAMED
hi SPF

その他海・内海

地中海、黒海東シナ海、大洋でない内海など。

内海だと思うなら hluséi-bwaleuxa を使います。hluséi-bwala に「小さいもの」を意味する接中辞 -eux- が挟まった形です。全体で「〜という名の固有名で表される小さい海」のような意味になります(これを使った例が公式ドキュメントに存在しないのですが)。

他のでかい海の一部分だと思う場合は hluséi-bwala に -ft (部分)の type-2 接辞を適用します。

階梯 -ft_2 POR 部分
1 -aift- 最小部分
2 -auft- 非常に小さい部分
3 -eift- 小さい部分
4 -euft- いくらか小さい部分
5 -ëuft- 部分
6 -ouft- かなりを占める部分
7 -oift- (ほぼ)半分
8 -iuft- 大部分
9 -uift- ほとんど全部

例えば階梯6なら hluséi-bwaloufta になりますし、階梯3なら hluséi-bwaleifta になります。どれを使うかは主観。ですが、比較対象が太平洋、大西洋、インド洋レベルなので、ほぼほぼ階梯6以下になるとは思います。ええ。

日本語 イスクイル
地中海 hluséi-bwaloufta mediterra / bwaloufta hi mediterra
黒海 hraxmé-bwaleufta
アゾフ海 hluséi-bwaleifta azof / bwaleifta hi azof
北海 bwalaidneufta
バルト海 hluséi-bwalëufta balt / bwalëufta hi balt
カリブ海 hluséi-bwalëufta karíb / bwalëufta hi karíb
ベーリング海 hluséi-bwalëufta bering / bwalëufta hi bering
アラビア海 hluséi-bwalëufta arab / bwalëufta hi arab

バルト海まあまあ小さいんで hluséi-bwaleifta balt とかの方がよさそうですけどね…そのあたりはお好みで。
地中海、黒海アゾフ海のように回りを陸地で囲まれているような海は hluséi-bwaleuxa を使ってもよいです。
なお黒海、北海は借用語を使わずにそれぞれ「黒い海」、「北の海」という合成語で表しています。

塩水なら -BW- 、淡水なら -LZ-

日本語 イスクイル
カスピ海 hluséi-wubwiuxa kaspi / wubwiuxa hi kaspi
アラル海 hluséi-wubwoixäkta aral / wubwoixäkta hi aral
バイカル湖 hluséi-wubwoixa baikál / wubwoixa hi baikál
ジュネーヴ hluséi-wubwoixa ženév / wubwoixa hi ženév
エリー湖 hluséi-walziuxa érìe / walziuxa hi érìe
ガリラヤ湖 hluséi-wulza kínneret / wulza hi kínneret

内海と同じく。
実はめんどくさい湾の区別。
イスクイルでは湾の湾曲度合いによって微妙に語彙が変わります。

日本語 イスクイル
ビスケー湾 hluséi-bwaleufta biskaya
ベニン湾 hluséi-bwalaufta benín
メキシコ湾 hluséi-bwaleufta méxiko
サンフランシスコ湾 hluséi-bwalaifta sanfransisko
ハドソン湾 hluséi-bwaleufta hëdsën
ジェームズ湾 hluséi-bwaleifta jeimz

砂漠・山・高原・峡谷・ツンドラ・滝・三角州

日本語 イスクイル
ゴビ砂漠 hluséi-wazha gob
アンデス山脈 hluséi-ejlamska andes
ヒマラヤ山脈 hluséi-ejlamska himálaya
チベット高原 hluséi-wujliuxa phö
グランドキャニオン wevňiuxa
ナイアガラの滝 hluséi-urţraňska nayagra
アマゾン川デルタ hluséi-welzwa amazonas

河川

hluséi-welza を使います。由来は語根 -LZ- のstem 2。

なお同じ河川でも呼び名が複数ある場合があり、イスクイルにおいて河川名は

  1. 最も支配的な民族における名称
  2. 複数の呼び名を複合した名称
  3. 古語または祖語での発音による名称

のような形式で表されています。

日本語 イスクイル
ナイル川 hluséi-welza nil
アマゾン川 hluséi-welza amazonas
長江 hluséi-welza caňčyaň*3
ミシシッピ川 hluséi-welza misisipi
ミズーリ川 hluséi-welza misuri
イェニセイ川 hluséi-welza yeniséi
黄河 hluséi-welza hwaňhë *4


hluséi-welza

Slot 音価 グロス
I hl [Type-1 Concatenation]/[Default]
II u S3/PRC
III s [the "carrier" root]
IX ei ESS
X [1] UNFRAMED
-
I w [No concatenation present]/[Default]
II e S2/PRC
III lz 'body of fresh water'
IX a THM
X [2] UNFRAMED

*1:もう少しいい訳語があれば誰か提案してほしい

*2:公式ドキュメントには"bwalaidna"の語は無いのですが、あくまでもガイドラインでしかないという解釈のもと、南極海との対比で"bwalaidna"を入れました。個人的には"arktos"を借用する方が文化依存的なので気にくわないのですが。

*3:中古漢語?

*4:公式では”黄”のみ音写しているが、語源を考えると"河"まで音写すべき

イスクイル 4 (v.0.19) で日付・時刻を表す

この記事はイスクイル 4 (2021)を扱っています。対応するバージョンは

です。


イスクイル 3に比べてかなり扱いやすくなりました。

イスクイルでは日時を表す時に「ある期間における何番目」という表現をします。

例えば「午前8時」なら「1日のうちの8番目の時刻」ですし、「水曜日」なら「3番目の日」、「5月20日」なら「5月20番目の日」です。


イスクイルにおいてはこの「ある期間」を接辞で、「何番目」を語根(というか語幹と接辞)で表現します。

SPT (-rw / -ry)

まず期間の方から。期間を表す接辞は -rw / -ry*1です。イスクイルにおける接辞は通称VxCs接辞(実質的に接中辞)と呼ばれるもので、イスクイルでは接辞を使って語彙を爆発的に増やしています。

単語をやらずに接中辞からやるのも変な話ですが、こちらの方が説明が少ないので接辞からいきます。

期間を表す接辞 -rw / -ry は「n番目」とすると以下のように9段階*2に変化します。

階梯 -rw / -ry*3 SPT 暦上定点
1 -arw- / -ary- 1分に対する(n秒)
2 -ärw- / -äry- 1時間に対する(n分)
3 -erw- / -ery- 1日に対する(n時)
4 -irw- / -iry- 1週間に対する(第n曜日)
5 -ëirw- / -ëiry- 1ヶ月に対する(第n日)
6 -örw- / -öry- 1ヶ月に対する(第n週)
7 -orw- / -ory- 1年に対する(第n月)
8 -ürw- / -üry- (n年)
9 -urw- / -ury- (n世紀)

ちなみに接辞はタイプ1からタイプ3まであって上表はタイプ1なのですが、「SPTタイプ1の第3階梯」のことを「SPT_1/3」と表記したりします。

例えば「21世紀」は上の表の階梯9を使って"wullärsurya"と表されます。"wullärs"が21番目(後述)で、"ury"が〜世紀にあたります。最後の"a"は格です。格はだいたい接辞の後に置かれます。"a"は辞書形くらいのイメージでとりあえずは大丈夫だと思います。

もう一つ例を。「曜日に」は上の表の階梯4を使って"wucpirwa'o"と表されます。"wucp"が6番目、つまり月曜日から数えて6番目の曜日は土曜日ということになります。"irw"が「週のうちの〜」なので全体で「週のうちの6番目の日」=「土曜日」。

数体系

続いて「n番目」の部分について。イスクイルの数体系は(多分)10進化100進法を採用しています。

次の表は日時を表すのに使われる0〜10までの数詞*4*5です。

n 語根 n番目 (短縮系)
0 VR uvral- wuvr-
1 LL ullal- wull-
2 KS uksal- wuks-
3 Z uzal- wuz-
4 upšal- wupš-
5 ST ustal- wust-
6 CP ucpal- wucp-
7 NS unsal- wuns-
8 ČK učkal- wučk-
9 LẒ ulẓal- wulẓ-
10 J ujal- wuj-


「n番目」の列が基本形です。その時の意味合いによって母音を変化させる場合があります。ある特定の場合は一番右の列のような短縮系を使うことができます。音節数が減るので、使えるときは短縮系を使うことが多いと思います。例えば「第3」なら"wuzörwa"と表されます。(日曜日が0番目なのか7番目なのかは謎)


11以上99以下の2桁の数字を作るには以下の接辞 -rs を使います。

階梯 -rs TNX 10の倍数
1 -ars- n+10
2 -ärs- n+20
3 -ers- n+30
4 -irs- n+40
5 -ëirs- n+50
6 -örs- n+60
7 -ors- n+70
8 -ürs- n+80
9 -urs- n+90

ドイツ語のように「一の位-十の位」の語順になるので、11はwullars-、12はwuksars-、13はwuzars-、と続きます。なお(イスクイル 3とは違い?)20, 30, 40, ... はそれぞれ 0+20, 0+30, 0+40, ... と解釈されるので、20はwuvrärs-、30はwuvrers-、40はwuvrirs-、となります。

期間の話の時の例で言えば「21世紀」は"wullärsurya"でしたが、21を表す wullärs- は wull(1)-ärs(+20)- のように分解されます。

日時の表現の例

その前に便利な格について。イスクイル 4には格が68個ありますが、日時の表現に頻出の格をピックアップします。

1 a themaic 主題格(デフォルトの格)
41 ë'i*6 comitative 随伴格「〜に沿って」
61 a'o concursive 時間格「〜の時点で」
68 o'a prolimitive 到達格「〜までに」


以下は日時の表現例です。

34秒までに:wupšersaryo'a
wupš(4)- ers(+30)- ary(秒\subset分)- o'a(までに)


日付に関しては少し便利な表現の仕方があります。

5月22日:wuksärsëirwiasta *7
wuks(2) - ärs(+20) - ëirw(日\subset月) - iast(5) - a

wuksärsëirw- までは今まで通り「22日」と解釈されます。で、5月であることを表す時に「5月」という単語を追加するのではなく、5を表す接辞 -iast- を付加することで、全体で「5月22日」を表現することができます。

1〜12までの接辞を次の表にまとめます。

n グロス 語形*8
1 XX1 -iazc-
2 XX2 -iaks-
3 XX3 -iaz-
4 XX4 -iapš-
5 XX5 -iast-
6 XX6 -iacp-
7 XX7 -ians-
8 XX8 -iačk-
9 XX9 -ialẓ-
10 X10 -iaj-
11 X11 -iacg-
12 X12 -iajd-


1969年3月15日:wustarsëirwiaza walẓarsa'o walẓörsürwë'i
wust(5) - ars(+10) - ëirw(日\subset月) - iaz(3) - a(デフォルト) walẓ(9) - ars(+10) - a'o(の) walẓ(9) - örs(+60) - ürw(年) - ë'i(に沿って)

全体で「1969年の3月15日」という解釈です。
wustarsëirwiaza で3月15日、walẓarsa'o walẓörsürwë'i で1969年です。1969年のうち walẓars- が上二桁の「19」、walẓörs- が下二桁の「69」に対応します。
walẓars- の方が -a'o で wustarsëirwiaza 「3月15日」を修飾し、walẓörs- は -ë'i で walẓarsa'o を修飾しています。


また、SPT_1/3を使った時刻表現については特殊な用法があります

午前8時52分:wučkerwa waksëirs *9
wučk(8) - erw(時-分\subset日) - a(デフォルト) waks(2) - ëirs(+50) - oň(と*10

-erw- は「〜時」を表す接辞なので wučkerwa で「8時」を意味します。
ただ、この -erw- を使う場合、後続要素に「〜分」を接続することが可能です。waksëirs- に -oň をつけた waksëirsoň*11を後置すると「52分」を表すことができます。


午後8時52分33秒:wuvrärserwa waksëirs wazersarwë'i
wuvr(0) - ärs(+20) - erw(時-分\subset日) - a(デフォルト) waks(2) - ëirs(50) - oň(と) waz(3) - ers(+30) - arw(秒\subset分) - ë'i(に沿って)

午後8時は20時なので wuvrärs-(20) を使って表現します。こちらも先の例文同様に waksëirsoň が後続し、頭の2単語で「20時52分」=「午後8時52分」を表しています。
秒は別単語として wazersarw-ë'i が続きます。解釈に迷いますが wazersarwë'i は wuvrärserwa を修飾しているとみて良いと思います。


(書いてて思ったんですけど、イスクイル 4って格の表示が完全に後置詞ですね。)

*1:wとyは前後の音環境で交替することがある。

*2:本当は10段階3タイプあるので全30段階だがひとまず使わないのでここでは触れません

*3:表はSPT_1/1からSPT_1/9まで。

*4:数詞という品詞はイスクイルには存在しないのですが、便宜上数詞という言葉を使います。

*5:以降基本形としてS3/PRC-STA/BSC/EXS-CSL/UPX/DEL/M/NRMを想定。

*6:原型は ëi' だが、イスクイルの音韻論では語末にglottal stopが来ないという規則があるのでしばしば ë'i の形になる

*7:文法書6.0章には ksialärsëirwiasta って書いてありましたけど別に普通に5月22日って言いたければ wuks-で いいんですよね…?と思ったので wuks- で紹介しています。

*8:全てdegree 4 type 3

*9:waks- と ksal- < (a)ksal は同じ意味だと思っているので、いちいち説明するのもめんどくさいため waks- 表記しています。

*10:COO_1/7

*11:品詞がわからない。文法書で何か見落としてるかもしれない。

【Tone.js】絶対和音感を鍛えるアプリで四和音を出題する

前々回と前回はこちら。

limnanthaceae.hatenablog.com
limnanthaceae.hatenablog.com


今回の完成形はこんな感じ。

f:id:frecafloros:20210430231052p:plain

チェックリストの作成

出題する和音の種類を選択できるようにします。
の前に和音のピッチクラスを再整理します。

// chord の pitch class
const chordTypes = [
	// triad
	{'chordName': '', 'chordKeys': [0,4,7]},
	{'chordName': 'm', 'chordKeys': [0,3,7]},
	{'chordName': 'dim', 'chordKeys': [0,3,6]},
	{'chordName': 'aug', 'chordKeys': [0,4,8]},
	{'chordName': 'sus4', 'chordKeys': [0,5,7]},
	{'chordName': 'sus2', 'chordKeys': [0,2,7]},
	// tetrad
	{'chordName': '7', 'chordKeys': [0,4,7,10]},
	{'chordName': 'm7', 'chordKeys': [0,3,7,10]},
	{'chordName': 'M7', 'chordKeys': [0,4,7,11]},
	{'chordName': 'mM7', 'chordKeys': [0,3,7,11]},
	{'chordName': 'm7b5', 'chordKeys': [0,3,6,10]},
	{'chordName': 'dim7', 'chordKeys': [0,3,6,9]},
	{'chordName': 'aug7', 'chordKeys': [0,4,8,10]},
	{'chordName': 'augM7', 'chordKeys': [0,4,8,11]},
	{'chordName': '6', 'chordKeys': [0,4,7,9]},
	{'chordName': 'm6', 'chordKeys': [0,3,7,9]},
	{'chordName': 'add9', 'chordKeys': [0,2,4,7]},
	//pentad
	{'chordName': '9', 'chordKeys': [0,2,4,7,10]},
	{'chordName': 'm9', 'chordKeys': [0,2,3,7,10]},
	{'chordName': '7(b9)', 'chordKeys': [0,1,4,7,10]},
	{'chordName': 'm7(b9)', 'chordKeys': [0,1,3,7,10]},
	{'chordName': '7(#9)', 'chordKeys': [0,3,4,7,10]},
	{'chordName': 'm7(11)', 'chordKeys': [0,3,5,7,10]},
	{'chordName': '7(#11)', 'chordKeys': [0,4,6,7,10]},
	{'chordName': '7(13)', 'chordKeys': [0,4,7,9,10]},
	{'chordName': 'm7(13)', 'chordKeys': [0,3,7,9,10]},
]

思いつく限りを放り込みました。triad=三和音、tetrad=四和音、pentad=五和音です(古典音楽理論でtetradとかpentadとか言わないと思いますがtriadと揃えて造語しました)。本当は11とか13とか六和音とかありますが、ちょっと面倒なので今後機会があれば実装することにします。

htmlのチェックボックスの方では、上のリストに対応する値を設定します。

<div class="config">
	<dl>
		<dt><label><input type="checkbox" id="checkTriad">三和音:</label></dt>
		<dd>
			<label><input type="checkbox" name="chordval" value=0>(M)</label>
			<label><input type="checkbox" name="chordval" value=1>m</label>
			<label><input type="checkbox" name="chordval" value=2>dim</label>
			<label><input type="checkbox" name="chordval" value=3>aug</label>
			<label><input type="checkbox" name="chordval" value=4>sus4</label>
			<label><input type="checkbox" name="chordval" value=5>sus2</label>
		</dd>
	</dl>
	<dl>
		<dt><label><input type="checkbox" id="checkTetrad">四和音:</label></dt>
		<dd>
			<label><input type="checkbox" name="chordval" value=6>7</label>
			<label><input type="checkbox" name="chordval" value=7>m7</label>
			<label><input type="checkbox" name="chordval" value=8>M7</label>
			<label><input type="checkbox" name="chordval" value=9>mM7</label>
			<label><input type="checkbox" name="chordval" value=10>m7b5</label>
			<label><input type="checkbox" name="chordval" value=11>dim7</label>
			<label><input type="checkbox" name="chordval" value=12>aug7</label>
			<label><input type="checkbox" name="chordval" value=13>augM7</label>
			<label><input type="checkbox" name="chordval" value=14>6</label>
			<label><input type="checkbox" name="chordval" value=15>m6</label>
			<label><input type="checkbox" name="chordval" value=16>add9</label>
		</dd>
	</dl>
	<dl>
		<dt><label><input type="checkbox" id="checkPentad">五和音:</label></dt>
		<dd>
			<label><input type="checkbox" name="chordval" value=17>9</label>
			<label><input type="checkbox" name="chordval" value=18>m9</label>
			<label><input type="checkbox" name="chordval" value=19>7(b9)</label>
			<label><input type="checkbox" name="chordval" value=20>m7(b9)</label>
			<label><input type="checkbox" name="chordval" value=21>7(#9)</label>
			<label><input type="checkbox" name="chordval" value=22>m7(11)</label>
			<label><input type="checkbox" name="chordval" value=23>7(#11)</label>
			<label><input type="checkbox" name="chordval" value=24>7(13)</label>
			<label><input type="checkbox" name="chordval" value=25>m7(13)</label>
		</dd>
	</dl>
</div>

全選択できるように、「三和音」・「四和音」・「五和音」の横にもチェックボックスをつけておきます。例えば「三和音」をクリックすると三和音の全てにチェックが入るような仕様にする予定。

リスト型で作ってますが、cssの設定はdl、dt、ddに対して

dl{
	display: flex;
	margin: 0;
}

dt{
	font-weight: bold;
	width: 30%;
}

dd{
	margin: 0;
	display: inline-block;
	width: 70%;
}

です。dt(三和音・四和音・五和音)とdd(m、m7、etc.)の描画エリアの比が3:7になるようにしています。



See the Pen
chordtrainer-08
by frecafloros (@frecafloros)
on CodePen.


今はただの飾りですが。

単にチェックボックスをつけるだけなら<input type="checkbox"...>だけで十分なのですが、これだとチェックボックスからテキストが分離して改行されてしまう場合があります。これを回避するために<label>タグを使っています。<label>タグを使う利点は主に2つで、テキスト回り込みを回避することに加えて、テキストをクリックすることでもチェックが入れられることです。

<label>タグ自体のcss

label{
	white-space: nowrap;
}

で指定します。これでテキストが改行されなくなります。

選んだ種類の和音をランダムに選ぶ

どの和音がチェックされているかを取得→値をリストにスタック→乱数出す→スタックしたリストの値を使ってコード参照

の手順でやっていこうかなと思います。

その前に、三四五和音のチェックボックスの処理から行います。チェックされていたら該当の和音全部チェック入れる、チェックが外れたら全部消す、という処理をまず始めます。

三和音のところの要素はgetElementByIdで、(M)やmなどの具体的な和音はnameでグループ化しているのでgetElementsByNameで探すことができます。addEventListenerを使うとチェックボックスがon/offになるタイミングを感知することができるのでこいつを使います。チェックボックスはonがtrueでoffがfalseになっているので、下のようにfor文を回して処理していきます。

const checkTriad = document.getElementById("checkTriad");
const chordval = document.getElementsByName("chordval");

checkTriad.addEventListener("click", ()=>{
	if(checkTriad.checked){
		for(let i=0;i<=5;i++){
			chordval[i].checked = true;
		}
	}else{
		for(let i=0;i<=5;i++){
			chordval[i].checked = false;
		}
	}
});

四和音、五和音も同様に。(全選択した後にどこか一つの和音のチェックボックスを切っても、三・四・五和音のチェックボックスがonのままになってしまいますがいつか直します。)(よく考えたらonchangeでいいような…?)


続いて、「次の問題」ボタンが押されたら、onになっているチェックボックスを検知して値(value)をリストにぶっ込みます。値を取得してcheckChordTypes配列にひたすらプッシュ。

// checkbox 検知
checkChordTypes = [];
for(let i=0;i<chordval.length;i++){
	if(chordval[i].checked == true){
		checkChordTypes.push(chordval[i].value);
	}
}

そうするとチェックされたところの値だけをぶっこんだcheckChordTypes = [0,2,3,5,7]のような配列ができるので、この配列のindexを乱数回して指定します。例えば乱数で3が出たらcheckChordTypes[3]つまり5が選ばれた和音の種類、という算段。(一つも選択されてないときのエラー判定書いてないのでこの時多分バグる。あとで抽選しないように直す。)

chordNum = checkChordTypes[randomInt(0,checkChordTypes.length)];



See the Pen
chordtrainer-09
by frecafloros (@frecafloros)
on CodePen.


ひとまず実装したい機能は全部積めたので、ここらで終了にしたいと思います。
気が向いた時にバグ取り、ビジュアル面の強化、24平均律の和音などに手を出していこうかなと考えています。

【p5.js】絶対和音感アプリの見た目をどうにかする(左半分)

limnanthaceae.hatenablog.com


これの続きです。


どうにかします。
毎回CSSを勉強しては忘れるを繰り返しているのでちゃんと記録しようと思います。
(あと最初にCSS勉強した時のfloatとかtableとかで頑張ってた時代の先入観が抜けない)


この記事での完成形はこんな感じです。

f:id:frecafloros:20210429002941p:plain

右半分に設定(次回作る、と思う)と問題送りや答えの表示などの制御ボタン、左半分にコードと構成音の表示をするという形にします。

領域の整理

htmlを整形します。

<div class="container">
	<div class="obj-left">
		<div class="figure">figure</div>
		<div class="obj-chord">chord: <span id="chordname-txt"></span></div>
	</div>
	<div class="obj-right">
		<div class="config">config</div>
		<div class="c">
			<button class="btn-sound" onclick="buttonSound();">和音再生</button>
		</div>
		<div class="c">
			<button class="btn-answer" onclick="buttonAnswer();">答えの表示</button>
		</div>
		<div class="c">
			<button class="btn-next" onclick="buttonNext();">次の問題</button>
	</div>
</div>


中央寄せ、flexbox
flexbox使いながらmargin: auto;しても中央に行かないので注意

.container{
	display: flex;
	justify-content: center;
}

さて、ビジュアル面を作るためにp5.jsというライブラリを使っていきます。

function setup(){
  createCanvas(300,300).parent('chord-constellation');
  background('skyblue');
}

createCanvas()で描画領域を作成します。これだけでも動きますが、parent()でidを指定すると特定のdiv要素に作ったり複数作ったりすることができます。

下のデモでは分かりやすくするため背景色をbackground('skyblue')(水色)で塗ってあります。


See the Pen
chordtrainer-05
by frecafloros (@frecafloros)
on CodePen.


音の分布

chord constellation(日本語訳がわからない)を描画します。

f:id:frecafloros:20210429003813p:plain

これです。

前節で作ったsetup()にわちゃわちゃ追加していきましょう。
まず、音名を円状に等間隔で並べます。

translate(canvasWidth/2, canvasHeight/2);
const r = 80;
for(let i=0;i<12;i++){
  text(pitch2keyname[i], r*sin(i*TAU/12), -1*r*cos(i*TAU/12));

関数を扱いやすくするために、translate()で座標原点を移動させます。デフォルトは描画領域の左上角が座標原点になりますが、translate(canvasWidth/2, canvasHeight/2)とすると座標原点が描画領域の中央に移動します。

後ろのfor文で0番目のキー=Cから時計回りに音名を並べます。text()を使うと文字を突っ込むことができるのですが、第1引数がテキスト内容、第2引数が横の座標、第3引数が縦の座標だと思います。多分。

円状に並べるので三角関数を使います。sin()とかcos()にはデフォルトでrad(ラジアン)を突っ込むようになっているはずです。p5.jsでTAU=\tau=2\piが使えるので大変便利。


続いて、テキストの細かい設定をします。

textAlign(CENTER,CENTER);
textSize(16);
textFont('Optima');

textAlign()は基準点とテキスト配置の位置関係を表します。textAlign(CENTER,CENTER)なら、基準点はテキストボックスの中央になります。

textSize()で文字の大きさ(px)を指定します。px以外にも指定できるかもしれないけど調べてない。今回は16 pxで作成します。

textFont()で文字のフォントを指定します。デザイン性重視でOptimaを使用。多分webフォントというやつで、特にPCに入ってなくても表示される…と思う。


解答ボタンを押すと和音分布を表す棒が表示されるようにします。

// constellation の棒描画
const l = 50;
let tmpPitch = rootPc;

strokeWeight(2);
stroke(0);
line(0, 0, l*sin(tmpPitch*TAU/12), -1*l*cos(tmpPitch*TAU/12));

strokeWeight(1);
stroke(127);
for(let i=1;i<chord.length;i++){
  tmpPitch = rootPc + chordTypes[chordNum]['chordKeys'][i];
  line(0, 0, l*sin(tmpPitch*TAU/12), -1*l*cos(tmpPitch*TAU/12));
}

line()に直線の起終点の座標を与えると線が引けます。今回は根音だけ線を太く濃くしたいので、そこだけ他とは別に描画しました。


あと流石に300x300はでかすぎたので描画領域を200x200にリサイズ。


See the Pen
chordtrainer-06
by frecafloros (@frecafloros)
on CodePen.


コード名の表示

javascriptでhtmlを操作します。

<div class="obj-left">
	<div id="chord-constellation" class="figure"></div>
	<div class="obj-chord">
		<div id="chordname-txt">
			<span class="chord-name" id="chordname-1"></span><br>
			<span class="chord-element" id="chordname-2"></span>
		</div>
	</div>
</div>


解答ボタンを押したらコードネームを表示するようにします。
javascriptの側で、htmlの要素(ここではspan)にcssのclassを動的に追加します。このclassを予めcssの側で設定しておくことで、cssの適用をon / offで切り替えすることができます。

// chord name表示
targetName = document.getElementById("chordname-txt");
targetName.classList.add("chord-icon");
targetName.classList.add("orange");



See the Pen
chordtrainer-07
by frecafloros (@frecafloros)
on CodePen.


続き。

limnanthaceae.hatenablog.com

【Tone.js】絶対和音感を鍛えるアプリを作る

コード進行を耳コピしたいのに音がわからない…ということはありませんか?
というわけで和音を聞き取る特訓ができるアプリを作ります。tone.jsというライブラリを使うとブラウザ上で音を出すことができるようですので、これを使います。

基本設計

  1. スタートボタンを押すと和音が流れる
  2. 答え合わせボタンを押すと和音のコード名が表示される


というシンプルな構成にしようと思います。あんまり理想が高すぎると完成しないので。

1つ目の「スタートボタンを押すと和音が流れる」は、あらかじめ用意しておいた和音リストからランダムに選択し、和音を流す。2つ目の「答え合わせボタンを押すと和音のコード名が表示される」は、'Cm'や'Eaugadd9'といったようなコード名が最低限、将来的にはピッチクラス、構成音名、半音圏上の図示ができるようになればいいなぁ、くらいの気持ちです。

単音を鳴らす

Tone.jsはWeb Audio APIというやつを簡単に操作できるように作成されたJSのライブラリらしいです。

早速Tone.jsをインポートします。htmlのヘッダーに以下の記述を入れるとTone.jsが使えるようになります。

<script>https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.15/Tone.js</script>

手始めに単音を鳴らします。練習として、ボタンを押すと「ラ」の音(220Hz)が八分音符の長さだけ流れるようにします。

let buttonStart = () => {
	const synth = new Tone.Synth().toDestination();
	synth.triggerAttackRelease("A3", "8n");	
};

デフォルトは多分120BPM(=1分間に四分音符が120拍の速さ)だと思います。

new Tone.Synth().toDestination()シンセサイザーを生成します。以降このシンセ(=オブジェクト)に対して操作をするような感じ。
triggerAttackRelease()は音を鳴らし(Attack)て止める(Release)までの一連の動作をやってくれます。第一引数はA3やC4などの音高を指定、第二引数は音の長さを指定します。音の長さは四分音符なら4n、八分音符なら8n、といった勝手です。

スタートボタンを押すとA3(220Hz)の音が流れるはずです。(スマホ等の場合はResultを押してから)


See the Pen
chordtrainer-01
by frecafloros (@frecafloros)
on CodePen.


和音を鳴らす

和音を鳴らします。ただのSynth()はmonosynthっぽいので代わりにPolySynth()を使います。PolySynth()以外で和音出せるのかは謎。

原理的には、前段の"A3"の代わりに["A3", "C4", "E4"]のようなコード構成音の配列を入れることで和音を鳴らします。

let buttonStart = () => {
	const synth = new Tone.PolySynth().toDestination();
	synth.triggerAttackRelease(["A3", "C4", "E4"], "8n");	
};

これでAmの和音が鳴る。

ついでに、今後の拡張性を考えて、根音(のピッチクラス)とコードの種類からコード構成音を自動生成できるようにします。

// scale
const scale = [
	'C3', 'C#3', 'D3', 'D#3', 'E3', 'F3', 'F#3', 'G3', 'G#3', 'A3', 'A#3', 'B3',
	'C4', 'C#4', 'D4', 'D#4', 'E4', 'F4', 'F#4', 'G4', 'G#4', 'A4', 'A#4', 'B4',
	'C5', 'C#5', 'D5', 'D#5', 'E5', 'F5', 'F#5', 'G5', 'G#5', 'A5', 'A#5', 'B5'
];

// chord の pitch class
const chordTypes = [
	{'chordName':'M', 'chordKeys': [0,4,7]},
	{'chordName':'m', 'chordKeys': [0,3,7]},
	{'chordName':'dim', 'chordKeys': [0,3,6]},
	{'chordName':'aug', 'chordKeys': [0,4,8]}
];

まずスケールですが、転回形を今後加えることを考えて一応3オクターブ分用意します。根音はC3からB3までのどれかを選択する感じで。コードのタイプはとりあえず三和音のメジャー、マイナー、dim、augを用意します。もろもろの都合により、辞書のリストになってます。そのうち増やす。

和音の配列を生成するために、ルート音とコード音からスケールの音を拾ってきてスタックしていきます。

// 和音生成
chord = [];
for (let j=0;j<chordTypes[2]['chordKeys'].length; j++){
	let pitch = scale[6+chordTypes[2]['chordKeys'][j]];
	chord.push(pitch);
}

上の例では、スケールの6番目(F#3)から+0番目、+4番目、+6番目(dimの配列)を拾ってきて音のリストを作っています。したがって完成したリストは["F#3", "A3", "C4"]となるはず。

下のデモでスタートボタンを押すとF#dimが鳴るはずです。


See the Pen
chordtrainer-02
by frecafloros (@frecafloros)
on CodePen.

ランダムに和音を鳴らす

絶対和音感を鍛えたいので、ランダムに和音が出題されてほしいです。なのでボタンをクリックしたときにどの和音を鳴らすかを乱数で決めます。

JavaScriptの乱数生成は[0, 1)を生成する関数しかない?ようなので、ランダムに整数値を吐き出す関数を作ります。

// 乱数生成器
let randomInt = (min, max) => {
	// 返値はmin以上max未満の整数
	min = Math.ceil(min);
	max = Math.floor(max);
	return Math.floor(Math.random() * (max - min) + min);
};

この関数はmin以上max未満の整数値をランダムで返します。
根音は12種類のうちから、コードは4種類のうちから1つずつ選びます。

スタートボタンを押すと和音がランダムに鳴るようになっていると思います。


See the Pen
chordtrainer-03
by frecafloros (@frecafloros)
on CodePen.


コードネームを表示する

「答えを表示」で今鳴っている和音のコードネームを表示させます。といっても前段で生成した乱数を元にテキスト化するだけです。

テキストをhtmlに流し込むにはgetElementById()を使って場所の指定をします。また、流し込むテキストの内容はinnerHTMLに代入する形で実現できます。

// chord name表示
targetName = document.getElementById("chordname-txt");
targetName.innerHTML = pitch2keyname[rootPc] + chordTypes[chordNum]['chordName'];

rootPcは根音のピッチクラス(0から11までの整数値)、chordNumは和音の構成を選択する値です。例えばchordNum=0はメジャーコードに対応しています。

下のデモでは、「次の問題」でまた別の和音をランダムに選択し鳴らします。「答えを表示」を押すと、CmF#dimといったような形で和音のコードネームが表示されるはずです。選ばれた和音は「和音再生」で何度も聞くことができます。


See the Pen
chordtrainer-04
by frecafloros (@frecafloros)
on CodePen.


とりあえず素体は出来たので、(細かいところが少し気にはなりますが)四和音などに拡張する前にUIをどうにかしたいですね。



続き

limnanthaceae.hatenablog.com

12平均律に飽きてしまった前衛的なみなさんに送るn平均律動画集(重いです)

12平均律はオワコン!時代はn平均律

1-11平均律

特に1-4平均律の曲はこの動画以外でみたことがない。
www.youtube.com

1平均律

と思っていたらあった。
Edolian - Cohesion (1EDO) - YouTube