@onjmin/dtm 1.0.7 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,6 +17,61 @@ npm i @onjmin/dtm
17
17
 
18
18
  ---
19
19
 
20
+ ## 2.0.0 への移行
21
+
22
+ 31 平均律への対応にあたり、**ノートのピッチの単位を変更**しました。1.x からの更新には修正が必要です。
23
+
24
+ ### ピッチの単位
25
+
26
+ `Note.pitch`(半音)が `Note.pitchUnits`(**1/372 オクターブの整数**)になりました。`NoteData` / `NoteRemove` / `PlayNoteEvent` / `MMLNotePlacement` / `ChordPlacement` も同様です。
27
+
28
+ ```
29
+ 12 平均律 1 半音 = 31 units 31 平均律 1 度 = 12 units
30
+ A4 (MIDI 69) = 2139 units 1 unit ≒ 3.2258 セント
31
+ ```
32
+
33
+ 372 = 12 × 31 で、12 と 31 は互いに素なので最小公倍数がこれになり、**両方の音律が誤差ゼロで同じ数直線に乗ります**。整数のままなので `pitchUnits` の同値判定(重複判定・当たり判定・協調編集の `(startStep, pitchUnits)` キー)がそのまま使えます。
34
+
35
+ 変換ヘルパを公開しています。
36
+
37
+ ```ts
38
+ import { pitchV1ToUnits, unitsToPitchV1, unitsToHz, unitsToMidiDetune } from "@onjmin/dtm";
39
+
40
+ pitchV1ToUnits(60); // 1860 … MIDI ノート番号 → units
41
+ unitsToPitchV1(1860); // 60 … units → MIDI ノート番号(12 平均律でのみ無損失)
42
+ unitsToHz(2139); // 440 … units → 周波数
43
+ unitsToMidiDetune(1968); // { midi: 63, detuneCents: 48.39 } … 31平均律の中立3度
44
+ ```
45
+
46
+ `unitsToMidiDetune` は SoundFont のように整数 MIDI ノートのゾーンしか持たない音源向けです。最寄りのゾーンを鳴らして残差を `detune`(セント)で補正します。
47
+
48
+ > **`PlayDrumEvent.pitch` と `DRUM_KEYS` は変更していません。** これらは GM 打楽器のキー番号であって
49
+ > 音高ではないため、units へ変換すると全ドラムが壊れます。
50
+
51
+ ### その他の破壊的変更
52
+
53
+ | 1.x | 2.0.0 |
54
+ |---|---|
55
+ | `init(target, w, h, config)` | `createRenderer(target, w, h, config)` が描画器インスタンスを返す |
56
+ | `new MMLCore(handlers, volume)` | 第 3 引数に `getConfig: () => RenderConfig` が必要 |
57
+ | `transposeNotes(cores, semitones)` | `transposeNotes(cores, steps)` — 単位は格子 1 ステップ |
58
+
59
+ `renderer` をインスタンス化したのは、モジュール全体がシングルトンで **1 ページに 2 つエディタをマウントすると後からマウントした側が Canvas を奪っていた**ためです(音律以前からのバグ)。曲ごとに音律が違うと格子まで食い違うため、31 平均律対応の前提でもあります。
60
+
61
+ `transposeNotes` の単位を変えたのは、31 平均律では「半音」がクロマチック半音(2 度)とダイアトニック半音(3 度)に分岐して一意に定まらないためです。12 平均律では 1 ステップ=1 半音なので、呼び出し側の値はそのままで動きます。
62
+
63
+ ### 協調編集
64
+
65
+ `onNotesPatch` / `applyPatch` で送受信する `pitchUnits` の意味が 1.x と異なるため、新旧クライアントが混ざると**黙って別の音になります**。dtm 自身は通信路を持たないので、バージョンの突き合わせは利用側アプリのハンドシェイクの責務です。
66
+
67
+ ```ts
68
+ import { PITCH_ENCODING_VERSION } from "@onjmin/dtm"; // 2 (1.x は 1 相当)
69
+ ```
70
+
71
+ v1 → v2 の変換は無損失ですが、**v2 → v1 は 12 平均律の曲でのみ**無損失です(31 平均律を半音へ丸めると最大 48.4 セント動きます)。
72
+
73
+ ---
74
+
20
75
  ## クイックスタート(全部入り `createDtmStudio`)
21
76
 
22
77
  楽器・ドラムの SoundFont、歌声合成、録音までを内包した一番簡単な入口です。SoundFont は実行時に CDN から動的 import し、歌声合成ワーカーは同梱の `dist/voice-worker.js` を使います。
@@ -384,6 +439,66 @@ const cp = mountChordPlayer(document.getElementById("chord-app"), "| C | G | Am
384
439
 
385
440
  ---
386
441
 
442
+ ## 音律(31 平均律)
443
+
444
+ `#edo=31` を宣言すると、その曲を 1 オクターブ 31 分割で扱います。省略時は 12 平均律なので、**既存の MML は 1 文字も解釈が変わりません**。
445
+
446
+ ```
447
+ #edo=31 @0 t120 o4 c c+ c# d- d_ d e_ e;
448
+ ```
449
+
450
+ 音律は**曲単位**です。トラックごと・小節ごとには変えられません。12 平均律と 31 平均律が一致するのはオクターブだけで、途中の音はすべてずれる(長 3 度で 12.9 セント、三全音で 19.4 セント)ため、同時に混ぜても音楽的に成立しないからです。
451
+
452
+ ### 臨時記号
453
+
454
+ 31 平均律では 4 記号を使い分けます。
455
+
456
+ | 記号 | 31 平均律 | 12 平均律 | 意味 |
457
+ |---|---|---|---|
458
+ | `#` | +2 度 | +1 半音 | クロマチック半音上げ(従来のシャープ) |
459
+ | `-` | −2 度 | −1 半音 | クロマチック半音下げ(従来のフラット) |
460
+ | `+` | +1 度 | +1 半音 | 格子 1 ステップ上げ(微分音) |
461
+ | `_` | −1 度 | −1 半音 | 格子 1 ステップ下げ(微分音) |
462
+
463
+ 12 平均律ではクロマチック半音=格子 1 ステップなので 4 記号すべてが従来の意味に潰れ、シャープ 2 つ・フラット 2 つの同義語になります。31 平均律でのみ `#`/`-` と `+`/`_` が分岐します。
464
+
465
+ 記号は累積するので `c##` は +4 度です(12 平均律では D)。幹音は五度連鎖で `c`=0 `d`=5 `e`=10 `f`=13 `g`=18 `a`=23 `b`=28 度。全 31 度の綴りは次の通りで、いずれも 2 文字以内・オクターブを跨ぎません。
466
+
467
+ ```
468
+ 0:c 1:c+ 2:c# 3:d- 4:d_ 5:d 6:d+ 7:d#
469
+ 8:e- 9:e_ 10:e 11:f- 12:e# 13:f 14:f+ 15:f#
470
+ 16:g- 17:g_ 18:g 19:g+ 20:g# 21:a- 22:a_ 23:a
471
+ 24:a+ 25:a# 26:b- 27:b_ 28:b 29:b+ 30:b#
472
+ ```
473
+
474
+ > 記号の選定: `^` は日本の MML 環境(サクラ・PMD・FMP・MUCOM88 等)でタイとして広く定着しており、
475
+ > ピッチ変更へ再定義すると過去の MML 資産が黙って別の音になるため使いません。`v` はベロシティ、
476
+ > `b` は音名 B で塞がっています。`+` を微分音へ転用できるのは `#` と冗長だからで、`-` は唯一の
477
+ > フラット記号なので転用せず、新記号 `_` に新しい概念(微分音)を割り当てています。
478
+ >
479
+ > 31 平均律はミーントーンなので五度連鎖だけで 31 音すべてに届き、ヴィチェンティーノ(1555)以来
480
+ > シャープ・フラット・重複臨時記号で記譜されてきました。`^`/`v` を使う ups-and-downs 記譜は
481
+ > 「五度連鎖が全音に届かない音律」向けの汎用記法で、31 平均律には必要ありません。
482
+
483
+ ### 何が変わるか
484
+
485
+ - **ピアノロール**: 1 オクターブが 31 段になります。音域(MIDI 0–127 相当)は音律に依らず固定なので、
486
+ 段数は自動的に 128 → 328 行へ変わります。鍵盤は幹音(白鍵相当)/微分音(短い中間鍵)/
487
+ クロマチック(黒鍵)の 3 階層で描かれます。縦の伸びは縦ズーム(50〜200%)で吸収できます。
488
+ - **和音**: コード進行入力は五度圏経由で 31 平均律の格子へ写されます。長 3 度が 10 度(純正 5:4 から
489
+ +0.79 セント)になるため、**同じコードが 12 平均律より綺麗に響きます**。増 4 度(15 度)と
490
+ 減 5 度(16 度)も区別されます。
491
+ - **歌声**: koe は Hz を直接受けるので、31 平均律の音もそのまま連続ピッチとして歌います。
492
+ - **MIDI 書き出し**: ピッチベンドの多チャンネル方式で書き出します(ドラム ch を除く 15 チャンネルへ
493
+ ベンド値の種類ぶんを割り当て、曲頭で RPN 0,0 により感度を ±2 半音へ固定)。dtm 同士なら無損失で
494
+ 往復しますが、1 トラック内のマルチチャンネルを潰す DAW では再現されません。
495
+ 15 種類を超えると頻度の低いものから最寄りの半音へ丸めます。
496
+ - **コード名の自動検出**: 12 平均律へ丸めてから判定するため、31 平均律では近似になります。
497
+ 通常のミーントーン和声(三和音・七の和音)は正しく復元されますが、中立 3 度やスーパーメジャーの
498
+ ような 31 平均律固有の音程は別のコードとして誤認されます。
499
+
500
+ ---
501
+
387
502
  ## 歌声合成(歌詞トラック `@@n`)
388
503
 
389
504
  演奏トラック `@n` とは別に歌詞専用行 `@@n` を書くと、そのトラックの Note On に合わせて 1 音節ずつ歌わせられます。