summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Design.md56
-rw-r--r--doc/MML_BNF.md102
2 files changed, 99 insertions, 59 deletions
diff --git a/doc/Design.md b/doc/Design.md
index f345d82..7c3d076 100644
--- a/doc/Design.md
+++ b/doc/Design.md
@@ -292,10 +292,10 @@ MML文字列
| 相対音量 | `v+` / `v-` (ppmck) | 0〜15へクランプして合成 |
| スイープ | `s`+数値,符号付き数値 (ppmck) | 2A03 Pulse sweepへ反映 |
| タイ | `^` (ppmck), `&` (両モード) | `^`はタイ、`&`はスラー |
-| リピート | `[`, `]` + 数値 | ppmckはASTへ保持してwarning、Pyxelは展開 |
+| リピート | `[`, `]` + 数値, `\|` | 両モードで構造検証。ppmckのリピート内`\|`は終端分岐 |
| エンベロープ/LFO | `@v`/`@@`/`@MP`/`@EP`/`@EN` (ppmck), `@ENV`/`@VIB`/`@GLI` (pyxel) | IR v2定義表を参照して合成 |
| 小節線 | `\|` | 視覚用、再生に影響しない |
-| トラック識別 | ppmck: `A`/`B`/`T`/`N`/`L`, pyxel: `数字:` | |
+| トラック識別 | ppmck: `A`/`B`/`T`/`N`/`L`, pyxel: `0:`〜`3:` | |
| ヘッダー | `#` で始まる行 (ppmck) | |
| コメント | `;` 以降行末 (ppmck) | |
| 拡張コマンド | `@ENV`/`@VIB`/`@GLI` (pyxel) | 空白区切りの数値引数をIR v2へ保持して合成 |
@@ -303,14 +303,16 @@ MML文字列
### 5.3 Parser(モード別)
-Parserの責務は**トークン列からASTを生成するのみ**。値範囲チェックやチャンネル適合性の判断は行わない。
+Parserの責務は**トークン列から構造的に妥当なASTを生成すること**である。必須token、トップレベル順序、リピート対応、空定義を検証する。値範囲チェックやチャンネル適合性の判断は行わない。構文errorが1件でもあればSemanticAnalyzerへ進まない。
#### ppmckパーサ
- トラックヘッダー `A`/`B`/`T`/`N`/`L` を認識
- `#` ヘッダーを認識
- 各コマンドをASTノードに変換
-- リピートの開始・終了をAST文として保持し、未対応warningを返す
+- トップレベル順序を`headers → global definitions → tracks`として検証
+- `L`を専用文法で解析し、`l`、休符、リピート、小節線以外を拒否
+- リピートの開始・終端分岐・終了を`RepeatStartStmt`/`RepeatBreakStmt`/`RepeatEndStmt`として保持し、対応、分岐重複、ネストを検証
- タイ `^` / スラー `&` の結合対象をASTで保持
- `@v`/`@@`/`@MP`/`@EP`/`@EN` エンベロープ定義 `{...|...}` と使用をASTで保持
@@ -318,7 +320,7 @@ Parserの責務は**トークン列からASTを生成するのみ**。値範囲ã
- トラックヘッダー `0:`〜`3:` を認識
- `@ENV`/`@VIB`/`@GLI` のパラメータをASTノードに保持
-- リピート `[...]N` の開始・終了をAST文として保持し、SemanticAnalyzerでネストを展開
+- リピート `[...]N` の対応とネストを検証し、開始・終了をAST文として保持
### 5.4 SemanticAnalyzer(モード別)
@@ -330,7 +332,7 @@ SemanticAnalyzerの責務は**ASTを検証・解釈してNoteSequence IRを生æˆ
- MIDI音番号変換
- tick計算
- タイ処理
-- リピート展開(pyxel)
+- ppmck/pyxel共通のトランザクション型リピート展開(各トラック最大100,000イベント)
- 値範囲チェック
- 音域チェック
@@ -338,11 +340,11 @@ SemanticAnalyzerの責務は**ASTを検証・解釈してNoteSequence IRを生æˆ
- Triangle音量無視
- Noise音高無視
-- 全体ループ `L` の処理
+- `L`の時間軸から全チャンネル共通`loop_start`を算出し、4音声チャンネルへ`RepeatEvent(repeat_count=0)`を追加
- `@` = デューティ比、`q` = クオンタイズ(gate_time = value / 8)として解釈
- `^` タイを前の音符の音長延長として解釈
-- `D`/`s`/`v+`/`v-`、各種エンベロープ/LFOをIRへ保持し `SEMANTIC_UNSUPPORTED_FEATURE` warningを返す
-- リピートなど合成未対応のASTに対するwarning
+- `D`/`s`/`v+`/`v-`、各種エンベロープ/LFOを値域・チャンネル検証後にIRへ保持
+- mckc型の`[前半|後半]N`を展開。回数省略時だけ2周期プレビューwarningを返す
#### pyxel固有
@@ -350,7 +352,7 @@ SemanticAnalyzerの責務は**ASTを検証・解釈してNoteSequence IRを生æˆ
- ゲートタイム `Q0-Q100` → `0.0-1.0`
- `@` コマンドのチャンネル適合性チェック
- `@ENV`/`@VIB`/`@GLI` のIR v2定義、選択、解除、合成
-- 無限リピートの2回打ち切りwarning
+- 無限リピートの2周期プレビューwarning
- `&` スラーを前の音符の音長延長として解釈
---
@@ -361,7 +363,7 @@ SemanticAnalyzerの責務は**ASTを検証・解釈してNoteSequence IRを生æˆ
- **モード共通**: ppmck/pyxel両方を1つのASTノード型セットで表現
- **位置情報**: 全ノードに `line`, `column` を保持
-- **構造保持**: リピート開始・終了とタイの結合対象を、意味解析可能な文列として保持
+- **構造保持**: リピート開始・終端分岐・終了とタイの結合対象を、意味解析可能な文列として保持
### 6.2 主要ASTノード
@@ -515,6 +517,10 @@ class RepeatStartStmt(ASTNode):
pass
@dataclass
+class RepeatBreakStmt(ASTNode):
+ pass # ppmckの現在のリピート階層に属する終端分岐
+
+@dataclass
class RepeatEndStmt(ASTNode):
count: int | None # None=無限
@@ -595,9 +601,10 @@ class ErrorPhase(Enum):
### 8.2 ppmckモード
```bnf
-<ppmck_mml> ::= <ppmck_header>* <ppmck_track>*
-<ppmck_track> ::= <track_header> <ppmck_statement>*
-<track_header>::= "A" | "B" | "T" | "N" | "L"
+<ppmck_mml> ::= <ppmck_header>* <global_definition>* <ppmck_track>*
+<ppmck_track> ::= <audio_track> | <loop_track>
+<audio_track> ::= ("A" | "B" | "T" | "N") <ppmck_statement>*
+<loop_track> ::= "L" (<length_cmd> | <rest> | <loop_repeat> | <bar>)*
<ppmck_statement>
::= <note> | <rest> | <octave_cmd> | <length_cmd>
| <volume_cmd> | <relative_volume_cmd> | <duty_cmd>
@@ -608,7 +615,10 @@ class ErrorPhase(Enum):
| <lfo_def> | <lfo_use> | <lfo_off>
| <pitch_env_def> | <pitch_env_use> | <pitch_env_off>
| <note_env_def> | <note_env_use> | <note_env_off>
- | <repeat_start> | <repeat_end> | <bar>
+ | <ppmck_repeat> | <bar>
+<ppmck_repeat>::= "[" <ppmck_statement>* ("|" <ppmck_statement>*)? "]" <number>?
+<loop_repeat> ::= "[" (<length_cmd> | <rest> | <loop_repeat>)*
+ ("|" (<length_cmd> | <rest> | <loop_repeat>)*)? "]" <number>?
```
### 8.3 pyxelモード
@@ -617,12 +627,13 @@ class ErrorPhase(Enum):
<pyxel_mml> ::= <pyxel_track>*
<pyxel_track> ::= <pyxel_track_header> <pyxel_statement>*
<pyxel_track_header>
- ::= <number> ":"
+ ::= "0:" | "1:" | "2:" | "3:"
<pyxel_statement>
::= <note> | <rest> | <octave_cmd> | <length_cmd>
| <volume_cmd> | <gate_cmd> | <tone_cmd> | <tempo_cmd>
| <transpose_cmd> | <detune_cmd> | <tie_cmd>
- | <repeat_start> | <repeat_end> | <bar> | <ext_cmd>
+ | <pyxel_repeat> | <bar> | <ext_cmd>
+<pyxel_repeat>::= "[" <pyxel_statement>* "]" <number>?
```
---
@@ -651,7 +662,7 @@ NoteSequence IRを入力としてPulse1、Pulse2、Triangle、Noiseを合成しã
|---|---|---|
| **大文字/小文字** | 小文字 `c d e`(`D` ディチューンは大文字のみ) | 大文字 `C D E` |
| **コマンド** | `o` `l` `v` `v+`/`v-` `t` `@` `q` `^` `&` `D` `s` | `O` `L` `V` `T` `Q` `@` `K` `Y` `&` |
-| **チャンネル指定** | `A` `B` `T` `N`(文字) | `0:`〜`3:`(番号) |
+| **チャンネル指定** | `A` `B` `T` `N`、制御用`L` | `0:`〜`3:`(番号) |
| **Parser** | `parser_ppmck.py` | `parser_pyxel.py` |
| **SemanticAnalyzer** | `semantic_ppmck.py` | `semantic_pyxel.py` |
| **音量範囲** | 0-15(クラシックAPU準拠) | 0-127 |
@@ -660,7 +671,7 @@ NoteSequence IRを入力としてPulse1、Pulse2、Triangle、Noiseを合成しã
| **タイ/スラー** | `^` = タイ、`&` = スラー | `&` = スラー(タイなし) |
| **ディチューン** | `D-127`〜`D126`(セント) | `Y-127`〜`Y127`(セント) |
| **エンベロープ/LFO** | `@v`/`@@`/`@MP`/`@EP`/`@EN`(合成対応) | `@ENV`/`@VIB`/`@GLI`(合成対応) |
-| **リピート** | `L`(構文上のループトラック)、`[...]`(AST保持・warning、合成未反映) | `[...]`(回数指定、省略時は2回で打ち切り、ネスト対応) |
+| **リピート** | `L`からloop_startを算出。`[...]N`と`[前半\|後半]N`をネスト展開 | `[...]N`をネスト展開 |
---
@@ -675,6 +686,7 @@ NoteSequence IRを入力としてPulse1、Pulse2、Triangle、Noiseを合成しã
| 5 | pyxel `@` とトラック番号の矛盾 | トラック番号優先。`@` はPulse系のみデューティ比として有効 |
| 6 | Noise note_number → period マッピング | ppmck: `period=8, mode=0` 固定。pyxel: マッピング式適用 |
| 7 | 出力構成 | `YYYYMMDD_HHMMSS_mmm/output.wav`, `YYYYMMDD_HHMMSS_mmm/output.mml` |
+| 8 | リピート安全上限 | 各トラックの展開後イベント数は100,000件以下。超過時は展開前に意味error |
---
@@ -684,12 +696,12 @@ NoteSequence IRを入力としてPulse1、Pulse2、Triangle、Noiseを合成しã
|---|---|
| MCPツール | `compose_mml`(compose/validate/template) |
| Lexer | ppmck/pyxel 両モード対応、共通トークン定義、INVALIDトークン。ppmck向けに `@v`/`@@`/`@MP`/`@EP`/`@EN`/`^`/`D`/`s`/`v+`/`v-` トークンを追加 |
-| Parser | ppmck/pyxel 別Parser、AST生成。ppmckでエンベロープ定義 `{...\|...}` と各種IR保持コマンドをパース |
-| SemanticAnalyzer | ppmck/pyxel 別Analyzer、AST→IR変換。ppmckで `@`=duty、`q`=quantize、`^`=tie を解釈し、未対応コマンドをIR保持+warning |
+| Parser | ppmck/pyxel 別Parser。必須token、トップレベル順序、case、リピート対応を検証し、ppmckの`RepeatBreakStmt`と専用L文法を構築 |
+| SemanticAnalyzer | ppmck/pyxel別Analyzer、AST→IR変換。共通反復展開、事前イベント上限、値域→チャンネル→状態→IR順の検証、Lのloop_start算出を実装 |
| IR | NoteSequence、各種Event(Quantize/Detune/Sweep/RelativeVolume/VolumeEnvelope/DutyEnvelope/Lfo/PitchEnv/NoteEnv 等)、ErrorDetail(phase付き) |
| Synthesizer | Pulse/Triangle/Noise 4ch合成、線形ミキシング、WAV出力 |
| Templates | basic/melody/chord/drum/empty の5種 × 2モード。ppmckテンプレートは `@` でデューティ比を指定 |
-| テスト | pytestの固定・統合テスト、Hypothesisの生成テスト、ruffによるリント/フォーマット。全200テスト通過 |
+| テスト | pytestの固定・統合テスト、Hypothesisの生成テスト、ruffによるリント/フォーマット |
---
diff --git a/doc/MML_BNF.md b/doc/MML_BNF.md
index 0c3f3b0..6093911 100644
--- a/doc/MML_BNF.md
+++ b/doc/MML_BNF.md
@@ -12,8 +12,9 @@
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<number> ::= <digit>+
-/* 音符名(Lexer で正規化: ppmck は小文字、pyxel は大文字 → 内部は小文字) */
-<note_name> ::= "c" | "d" | "e" | "f" | "g" | "a" | "b"
+/* 音符名(case-sensitive。受理後のASTでは小文字へ正規化) */
+<ppmck_note_name> ::= "c" | "d" | "e" | "f" | "g" | "a" | "b"
+<pyxel_note_name> ::= "C" | "D" | "E" | "F" | "G" | "A" | "B"
/* 変化記号 */
<sharp> ::= "+" | "#"
@@ -43,6 +44,8 @@
<whitespace> ::= " " | "\t" | "\r" | "\n"
```
+`<whitespace>`は字句間の区切りであり、statementやASTノードではない。`#`はppmckの行頭ヘッダー開始、または両モードで音符名の直後に置くsharpとしてのみ有効である。
+
---
## 2. ppmck モード
@@ -50,7 +53,7 @@
### 2.1 全体構造
```bnf
-<ppmck_mml> ::= <ppmck_header>* <ppmck_track>*
+<ppmck_mml> ::= <ppmck_header>* <ppmck_global_definition>* <ppmck_track>*
<ppmck_header> ::= "#" <header_key> <header_value>?
<header_key> ::= "TITLE" | "COMPOSER" | "PROGRAMER" | "OCTAVE-REV"
@@ -58,15 +61,30 @@
| "EFFECT-INCLUDE"
<header_value> ::= "\"" <string> "\""
-<ppmck_track> ::= <track_header> <ppmck_statement>*
-<track_header> ::= "A" | "B" | "T" | "N" | "L"
+<ppmck_global_definition>
+ ::= <vol_envelope_def> | <duty_envelope_def> | <lfo_def>
+ | <pitch_env_def> | <note_env_def>
+
+<ppmck_track> ::= <audio_track> | <loop_track>
+<audio_track> ::= <audio_track_header> <ppmck_statement>*
+<audio_track_header>
+ ::= "A" | "B" | "T" | "N"
+<loop_track> ::= "L" <loop_statement>*
+<loop_statement> ::= <length_cmd> | <ppmck_rest> | <loop_repeat> | <bar>
+<loop_repeat_item>::= <length_cmd> | <ppmck_rest> | <loop_repeat>
+<loop_repeat> ::= "[" <loop_repeat_item>* ("|" <loop_repeat_item>*)? "]" <number>?
```
+グローバル定義は全トラック共通である。既存入力との互換性のため、同じ定義を音声トラック内の`<ppmck_ext_cmd>`として置くこともできる。`L`は音声を生成しない制御トラックで、0回または1回だけ記述できる。
+
### 2.2 ステートメント
```bnf
-<ppmck_statement> ::= <note>
- | <rest>
+<ppmck_statement> ::= <ppmck_simple_statement> | <ppmck_repeat> | <bar>
+
+<ppmck_simple_statement>
+ ::= <ppmck_note>
+ | <ppmck_rest>
| <octave_cmd>
| <length_cmd>
| <volume_cmd>
@@ -76,14 +94,10 @@
| <tie_cmd>
| <slur_cmd>
| <ppmck_ext_cmd>
- | <repeat_start>
- | <repeat_end>
- | <bar>
| <comment>
- | <newline>
-<note> ::= <note_name> <accidental>? <length>
-<rest> ::= "r" <length>
+<ppmck_note> ::= <ppmck_note_name> <accidental>? <length>
+<ppmck_rest> ::= "r" <length>
<octave_cmd> ::= "o" <number> /* o0 〜 o7 */
| <octave_up>
@@ -96,12 +110,18 @@
<quantize_cmd> ::= "q" <number> /* q1 〜 q8 */
<tempo_cmd> ::= "t" <number> /* t1 〜 */
-<tie_cmd> ::= "^" (<note> | <number>)
-<slur_cmd> ::= "&" (<note> | <rest> | <number>)
+<tie_cmd> ::= "^" (<ppmck_note> | <number>)
+<slur_cmd> ::= "&" (<ppmck_note> | <ppmck_rest> | <number>)
<comment> ::= ";" <string_to_eol>
+
+<ppmck_repeat_item>
+ ::= <ppmck_simple_statement> | <ppmck_repeat>
+<ppmck_repeat> ::= "[" <ppmck_repeat_item>* ("|" <ppmck_repeat_item>*)? "]" <number>?
```
+`[本体]N`は本体をN回再生する。`[前半|後半]N`は`前半+後半`をN−1回、最後に前半だけを再生する。`N=1`では前半だけとなる。`|`は現在のリピート階層で高々1個で、ネストした`|`は内側に所属する。リピート外の`|`は小節線である。回数省略は無限を表し、IRプレビューでは`前半+後半`を2回展開して`repeat_count=0`を保持する。
+
### 2.3 合成拡張コマンド
```bnf
@@ -123,27 +143,27 @@
| <note_env_off>
<relative_volume_cmd>
- ::= "v+" <number>? /* 1 〜 15 */
- | "v-" <number>? /* 1 〜 15 */
+ ::= "v+" <number>? /* 省略時1、1 〜 15 */
+ | "v-" <number>? /* 省略時1、1 〜 15 */
<detune_cmd> ::= "D" <signed_number> /* -127 〜 126 */
<sweep_cmd> ::= "s" <number> "," <signed_number>
-<vol_envelope_def>::= "@v" <number> "=" "{" <number_list> "|" <number_list>? "}"
+<vol_envelope_def>::= "@v" <number> "=" "{" <number_list> ("|" <number_list>?)? "}"
<vol_envelope_use>::= "@v" <number>
-<duty_envelope_def>::= "@" <number> "=" "{" <number_list> "|" <number_list>? "}"
+<duty_envelope_def>::= "@" <number> "=" "{" <number_list> ("|" <number_list>?)? "}"
<duty_envelope_use>::= "@@" <number>
<lfo_def> ::= "@MP" <number> "=" "{" <number> "," <number> "," <number> "," <number> "}"
<lfo_use> ::= "MP" <number>
<lfo_off> ::= "MPOF"
-<pitch_env_def> ::= "@EP" <number> "=" "{" <signed_number_list> "|" <signed_number_list>? "}"
+<pitch_env_def> ::= "@EP" <number> "=" "{" <signed_number_list> ("|" <signed_number_list>?)? "}"
<pitch_env_use> ::= "EP" <number>
<pitch_env_off> ::= "EPOF"
-<note_env_def> ::= "@EN" <number> "=" "{" <signed_number_list> "|" <signed_number_list>? "}"
+<note_env_def> ::= "@EN" <number> "=" "{" <signed_number_list> ("|" <signed_number_list>?)? "}"
<note_env_use> ::= "EN" <number>
<note_env_off> ::= "ENOF"
@@ -158,13 +178,10 @@
```bnf
<ppmck_stage2> ::= <count_length>
- | <section_repeat>
| <transpose_cmd>
| <noise_mode_cmd>
-<count_length> ::= <note_name> <accidental>? "%" <number>
-
-<section_repeat> ::= "[" <ppmck_statement>+ "]" <number>?
+<count_length> ::= <ppmck_note_name> <accidental>? "%" <number>
<transpose_cmd> ::= "K" <number>
<noise_mode_cmd> ::= "m" <number>
@@ -182,14 +199,14 @@
<pyxel_track> ::= <pyxel_track_header> <pyxel_statement>*
<pyxel_track_header>
- ::= <number> ":" /* 0: 1: 2: 3: */
+ ::= "0:" | "1:" | "2:" | "3:"
```
### 3.2 ステートメント
```bnf
-<pyxel_statement> ::= <note>
- | <rest>
+<pyxel_statement> ::= <pyxel_note>
+ | <pyxel_rest>
| <octave_cmd>
| <length_cmd>
| <volume_cmd>
@@ -199,14 +216,12 @@
| <transpose_cmd>
| <detune_cmd>
| <tie_cmd>
- | <repeat_start>
- | <repeat_end>
+ | <pyxel_repeat>
| <bar>
| <ext_cmd>
- | <newline>
-<note> ::= <note_name> <accidental>? <length>
-<rest> ::= "R" <length>
+<pyxel_note> ::= <pyxel_note_name> <accidental>? <length>
+<pyxel_rest> ::= "R" <length>
<octave_cmd> ::= "O" <number> /* O0 〜 O7 */
| <octave_up>
@@ -221,24 +236,29 @@
<transpose_cmd> ::= "K" <signed_number> /* 半音単位 */
<detune_cmd> ::= "Y" <signed_number> /* セント単位 */
-<tie_cmd> ::= <tie> (<note> | <rest> | <number>)
+<tie_cmd> ::= <tie> (<pyxel_note> | <pyxel_rest> | <number>)
+<pyxel_repeat> ::= "[" <pyxel_statement>* "]" <number>?
```
+Pyxelリピートはネストできる。指定回数は1以上で、回数省略は無限を表す。IRプレビューでは本体を2回展開し、`repeat_count=0`を保持する。Pyxelの`|`は常に小節線であり、終端分岐ではない。
+
### 3.3 合成拡張コマンド
```bnf
<ext_cmd> ::= <env_cmd> | <vib_cmd> | <gli_cmd>
<env_cmd> ::= "@ENV" <number> <env_def>?
-<env_def> ::= <number>+
+<env_def> ::= <number> <number> (<number> <number>)*
<vib_cmd> ::= "@VIB" <number> <vib_def>?
-<vib_def> ::= <number>+
+<vib_def> ::= <number> <number> <number>
<gli_cmd> ::= "@GLI" <number> <gli_def>?
-<gli_def> ::= <number>+
+<gli_def> ::= <number> <number>
```
+slot 0は解除専用で、パラメータを指定できない。slot 1以上ではパラメータ付きの初出を定義、パラメータなしを既定義slotの選択として扱う。Pyxel公式の波括弧、カンマ、負数、`*`を使う拡張形式は本受理文法に含めない。
+
---
## 4. トラック・チャンネル対応
@@ -259,6 +279,8 @@
|---|---|---|---|---|
| `o` / `O` | 両方 | 0 〜 7 | 4 | |
| `l` / `L` | 両方 | 1 〜 192 | 4 | |
+| 音符・休符の明示音長 | 両方 | 1 〜 192 | 現在の`l`/`L` | |
+| タイ対象の音長 | 両方 | 1 〜 192 | — | |
| `v` | ppmck | 0 〜 15 | 15 | |
| `V` | pyxel | 0 〜 127 | 100 | |
| `v+` / `v-` | ppmck | 1 〜 15 | 1 | 相対音量(0〜15へクランプ) |
@@ -274,8 +296,14 @@
| `@MP` / `MP` / `MPOF` | ppmck | 0 〜 255 | — | 三角LFO |
| `@EP` / `EP` / `EPOF` | ppmck | 0 〜 255 | — | cent単位ピッチエンベロープ |
| `@EN` / `EN` / `ENOF` | ppmck | 0 〜 255 | — | 絶対半音オフセット列 |
+| ppmck envelope slot | ppmck | 0 〜 255 | — | 全定義・参照共通 |
+| volume envelope要素 | ppmck | 0 〜 15 | — | |
+| duty envelope要素 | ppmck | 0 〜 3 | — | |
+| pitch/note envelope要素 | ppmck | -127 〜 126 | — | |
+| `@MP`要素 | ppmck | delay 0〜255, period 1〜255, depth 0〜255, 第4値0 | — | |
| `K` | pyxel | -127 〜 127 | 0 | トランスポーズ(半音) |
| `Y` | pyxel | -127 〜 127 | 0 | ディチューン(セント) |
+| リピート回数 | 両方 | 1以上、または省略(無限) | 省略 | 展開後は各トラック100,000イベント以下 |
---