Skip to content

Commit

Permalink
keyがflatのあるタイプであれば、出力MMLはflatを使うようにした
Browse files Browse the repository at this point in the history
  • Loading branch information
cat2151 committed Jan 5, 2024
1 parent a799023 commit e007310
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 136 deletions.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A library transpiles Chord notation into Music Macro Language.
https://cat2151.github.io/dist/chord2mml/

# 状況
- まだTDD開始直後です。majとmaj7のclosed voicingのみ、四分音符固定、音域固定、等の状態です
- まだTDD開始直後です。majやmaj7などは鳴ります。一方でchord qualityの大部分は後回しにしています
## 近いゴール
- [MML-chord-generator](https://github.com/cat2151/MML-chord-generator)のサブセットのような最低限の機能を実現すること
## 遠いゴール
Expand All @@ -18,4 +18,24 @@ https://cat2151.github.io/dist/chord2mml/
- は、[easychord2mml](https://github.com/cat2151/easychord2mml/)で担当します。

# このprojectが優先すること
- 関数に`Chord notation文字列`を与えて、`MML文字列`を取得できること。
- 関数に`Chord notation文字列`を与えて、`MML文字列`を取得できること。

# 目指すこと
- 概念実証
- 丁寧で完璧な動作を細部まで完璧に作り込むことよりも、
- 大きな用途のある機能の目処を立てることを優先する
- シンプル
- ルールはシンプルであることを優先します。
- できるだけ入力データそのままを扱います。
- 例えばオクターブは手動制御とします。
- 「octave-up」などをユーザーが明示的に書きます。
- なぜなら「octave上がよい」「octave下がよい」かは、入力データからは断定できないためです。
- また「スタンダードなほうを自動で選び、そこから外れた場合にユーザーが制御とする」こともしません。
- なぜなら、スタンダードの境界線がグラデーションであることや、どこまでがスタンダードかのルールが複雑となり、仕様が複雑となるためです。

# 目指さないこと
- レアケース調査。あらゆるレアケースの表記を、全ての書籍とインターネットの隅々まで調べ上げる
- まだ発生していない可能性への先行対応。「こんな可能性もありそう」というものをすべて洗い出して検討する
- 完璧なフォーマット。全てに対応できる表記フォーマットを完成させる
- 全組み合わせテスト。全てに対応できるようテストケースを全組み合わせについて完成させる
- 完璧な全自動。あらゆる曖昧な入力に対してすべてを全自動でいい感じにしてくれるシステムを構築する
2 changes: 1 addition & 1 deletion dist/chord2mml.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build:peggy-commonjs": "peggy ./peggyjs/chord2mml_chord2ast.pegjs --output ./src/chord2mml_chord2ast.cjs",
"watch": "run-p watch:**",
"watch:web": "webpack-dev-server --open",
"watch:peggy": "chokidar \"**/*.pegjs\" -c \"npm run build:peggy-commonjs && npm run build:peggy-es\"",
"watch:peggy": "chokidar \"**/*.pegjs\" -c \"npm run build:peggy-commonjs && npm run build:web\"",
"test": "jest --silent=false --verbose false"
},
"dependencies": {
Expand Down
37 changes: 22 additions & 15 deletions peggyjs/chord2mml_chord2ast.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,22 @@
}
default: throw new Error(`ERROR : getOffsetByScale`);
}
} // function

function getRootCdefgabOffset(root, sharp, flat) {
let offset;
switch (root) {
case 'C': offset = 0; break;
case 'D': offset = 2; break;
case 'E': offset = 4; break;
case 'F': offset = 5; break;
case 'G': offset = 7; break;
case 'A': offset = 9; break;
case 'B': offset = 11; break;
default: throw new Error(`ERROR : getRootCdefgabOffset`);
}
offset += sharp.length - flat.length;
return offset;
}
}}
{
Expand Down Expand Up @@ -135,7 +151,11 @@ BASS_PLAY_MODE_ROOT=_ ("bass is root"i / "bass plays root"i / "bass play root"i)
TEMPO=_ ("BPM"i / "TEMPO"i) _ bpm:[0-9]+ [\,\.]? _ { return { event: "inline mml", mml: "t" + bpm.join("") }; }
BAR=_ "|" _ { return { event: "bar" }; }
BAR_SLASH=" / " _ { return { event: "bar slash" }; }
KEY=_ "key"i [ \=]? k:ROOT_CDEFGAB [\,\.]? _ { key = k; return { event: "" }; }
KEY=_ "key"i [ \=]? k:KEY_EVENT [\,\.]? _ { return k; }
KEY_EVENT=root:[A-G] sharp:SHARP* flat:FLAT* {
key = getRootCdefgabOffset(root, sharp, flat);
return { event: "key", root, sharpLength: sharp.length, flatLength: flat.length }; }

SCALE=_ s:("ionian"i / "dorian"i / "phrygian"i / "lydian"i / "mixolydian"i / "aeolian"i / "locrian"i) [\,\.]? _ { scale = s.toLowerCase(); return { event: "" }; }

OCTAVE_UP=_ ("octave"i [ \-] "up"i) [\,\.]? _ { return { event: "octave up" }; }
Expand All @@ -149,20 +169,7 @@ OCTAVE_DOWN_LOWER=_ "/" ("octave"i [ \-] "down"i) [\,\.]? _ { return { event: "o
ROOT=ROOT_CDEFGAB
/ROOT_DEGREE

ROOT_CDEFGAB=root:[A-G] sharp:SHARP* flat:FLAT* {
let offset;
switch (root) {
case 'C': offset = 0; break;
case 'D': offset = 2; break;
case 'E': offset = 4; break;
case 'F': offset = 5; break;
case 'G': offset = 7; break;
case 'A': offset = 9; break;
case 'B': offset = 11; break;
default: throw new Error(`ERROR : ROOT_CDEFGAB`);
}
offset += sharp.length - flat.length;
return offset; }
ROOT_CDEFGAB=root:[A-G] sharp:SHARP* flat:FLAT* { return getRootCdefgabOffset(root, sharp, flat); }

ROOT_DEGREE=sharp:SHARP* flat:FLAT* root:("VII" / "III" / "VI"/ "IV" / "II" / "V" / "I") { // 文字数の多い順に並べるのは、そうしないとVIをV Iと認識するので防止用
// 課題。getOffsetByScale() が大規模。当ライブラリの方針的に、AST生成側の分担としては大規模すぎる感触。
Expand Down
Loading

0 comments on commit e007310

Please sign in to comment.