たま日記

たまに書く

WT11が発声するボイスについて調べた


ウィンドシンセ用音源 Yamaha WT11はTX81Zと互換性がある。ただしWT11はTX81Zでいうパフォーマンスモードで動作する。音色の選択は96個あるパフォーマンスから1つを選択することで行う。1つのパフォーマンスは1つ以上のボイスから構成される。つまりMIDIのnote onを1つ受け取ると、複数のボイスを同時発声する。ボイスはTX81Zでいうシングルモードの音色に相当する。

A01~C32のパフォーマンスそれぞれが発生するボイスを以下に示す。ボイス番号(A01~D32)に続く「_数字」は、このボイスを割り当てたYM2414のチャンネル数を表す(1~8)。たとえば「A01 Oboe 1」なら、ch1~ch4にA01のボイスが、ch5~ch8にA02のボイスがセットされており、note onを受け取るたびにch1+ch5→ch2+ch6→ch3+ch7→ch4+ch8→ch1+ch5→...のように発声する。

Performance   : Voices
A01 Oboe 1    : A01_4 A02_4 
A02 Oboe 2    : A03_4 A02_4 
A03 Bassoon   : A04_8 
A04 Clarinet  : A05_4 A26_4 
A05 Piccolo   : A08_8 
A06 Flute     : A06_4 A07_4 
A07 PanFlute  : A14_4 A14_4 
A08 PuffPanFlt: A15_4 A16_1 A32_3 
A09 SopranoSax: A12_3 A25_3 A27_2 
A10 TenorSax 1: A10_2 A11_3 A26_3 
A11 TenorSax 2: A10_2 A25_3 A26_3 
A12 BaritonSax: A10_4 A09_4 
A13 Recorder  : A13_8 
A14 Ocarina   : A19_8 
A15 Shakuhachi: A17_4 A18_4 
A16 ClearWinds: A20_4 A20_4 
A17 WoodWinds : A02_4 A04_4 
A18 Picc/Clar : A05_4 A06_4 
A19 PowerWood : A21_4 A21_4 
A20 HolloWood : A22_8 
A21 HardWood  : A24_8 
A22 ReedWinds : A03_4 A05_4 
A23 SilverWind: A08_4 A13_4 
A24 FatReed 1 : A23_4 A30_4 
A25 FatReed 2 : A26_4 A30_4 
A26 FluteEns. : A29_3 A29_3 A07_2 
A27 Flute 5ths: A06_4 A06_4 
A28 SaxSect.1 : A26_2 A25_2 
A29 SaxSect.2 : A12_3 A26_3 A09_2 
A30 Chime/Oboe: A02_4 A31_4 
A31 BassoonDuo: A04_4 A04_4 
A32 Mammoth ! : A04_3 A26_3 A31_1 A31_1 
B01 Trumpet 1 : B26_4 B13_4 
B02 Trumpet 2 : B02_4 B12_4 
B03 MutedTrp. : B03_3 B03_2 B04_2 B01_1 
B04 Flugel 1  : B18_4 B12_4 
B05 Flugel 2  : B04_4 B04_4 
B06 Trombone  : B05_8 
B07 FrenchHorn: B06_4 B06_4 
B08 Tuba      : B07_8 
B09 BrassEns. : B05_3 B07_3 B05_2 
B10 FusionBrs : B02_3 B05_3 B02_2 
B11 HardPopBrs: B31_2 B05_2 B31_2 B13_2 
B12 HvyPopBrs : B32_3 B05_3 B13_2 
B13 ClassicBrs: B13_3 B04_3 B05_2 
B14 ClassicHrn: B04_4 B06_4 
B15 OrchHorns : B06_3 B06_3 B04_2 
B16 MuteBrass : B05_3 B03_3 B03_2 
B17 TuttiBrass: B13_1 B13_1 B05_1 B05_1 B13_1 B13_1 B07_1 B07_1 
B18 HarmoSynth: B10_4 B10_4 
B19 SmoothBrs : B11_4 B11_4 
B20 DualSynth : B14_4 B14_4 
B21 LyriSynth : B15_4 B15_4 
B22 MelloSynth: B16_4 B16_4 
B23 BuzzySynth: B17_4 B17_4 
B24 SharpSynth: B20_4 B20_4 
B25 SolidSynth: B21_4 B21_4 
B26 SwampSynth: B09_4 B09_4 
B27 SandyBrass: B25_4 B25_4 
B28 AttackSyn.: B27_4 B08_4 
B29 SynthBrs 1: B28_4 B10_4 
B30 SynthBrs 2: B29_4 B28_4 
B31 SynthBrs 3: B08_4 B08_4 
B32 SynthOrch : B23_3 B24_3 B15_2 
C01 Harmonica1: C01_8 
C02 Harmonica2: C02_8 
C03 Concertina: C03_4 C03_4 
C04 Bandonion : C04_4 C04_4 
C05 Accordion : C05_4 C05_4 
C06 Violin    : C19_4 C20_4 
C07 Cello     : D03_4 D04_4 
C08 Strings   : D06_3 D06_3 D06_2 
C09 DualString: D06_3 D06_3 D06_2 
C10 DistGuitar: C06_4 C07_4 
C11 A.Guitar  : C16_4 C17_4 
C12 Fretless  : C13_4 C13_4 
C13 UpriteBass: C14_4 C15_4 
C14 PipeOrgan : C29_4 C29_4 
C15 Choir     : D01_4 D01_4 
C16 Whistle   : C22_3 C22_3 C22_2 
C17 Bells     : C31_3 C31_3 C31_2 
C18 GuitarSyn : C08_4 C08_4 
C19 PortaLead : C18_4 C18_4 
C20 Clavidion1: C09_4 C09_4 
C21 Clavidion2: C10_4 C10_4 
C22 SynthLead : C28_3 C28_3 C28_2 
C23 FuzzySax  : C11_4 C12_4 
C24 Fuzz 5ths : C24_4 C24_4 
C25 BreathHit : C25_4 C26_1 C26_1 C26_1 C26_1 
C26 Breath 5th: C25_4 C25_1 C25_1 C25_1 C25_1 
C27 TalkingBox: C30_3 C30_3 C30_2 
C28 HarmoWhist: D07_3 D08_3 D08_2 
C29 SpaceDust : D02_3 D05_3 D02_2 
C30 Str/Flute : D16_2 D16_2 D16_2 D09_2 
C31 Str/Oboe  : D16_2 D16_2 D16_2 D15_2 
C32 FreeJazz  : D11_4 D12_4

これとは逆に、A01~D32の各ボイスはどのパフォーマンスから利用されているかについても調べてみた。全てのボイスが使われているわけではないことが分かる。

Voice [Performances]
A01   [A01_Oboe 1    ]
A02   [A01_Oboe 1    , A02_Oboe 2    , A17_WoodWinds , A30_Chime/Oboe]
A03   [A02_Oboe 2    , A22_ReedWinds ]
A04   [A03_Bassoon   , A17_WoodWinds , A31_BassoonDuo, A31_BassoonDuo, A32_Mammoth ! ]
A05   [A04_Clarinet  , A18_Picc/Clar , A22_ReedWinds ]
A06   [A06_Flute     , A18_Picc/Clar , A27_Flute 5ths, A27_Flute 5ths]
A07  m[A06_Flute     , A26_FluteEns. ]
A08   [A05_Piccolo   , A23_SilverWind]
A09   [A12_BaritonSax, A29_SaxSect.2 ]
A10 0m[A10_TenorSax 1, A11_TenorSax 2, A12_BaritonSax]
A11   [A10_TenorSax 1]
A12   [A09_SopranoSax, A29_SaxSect.2 ]
A13   [A13_Recorder  , A23_SilverWind]
A14   [A07_PanFlute  , A07_PanFlute  ]
A15   [A08_PuffPanFlt]
A16  m[A08_PuffPanFlt]
A17   [A15_Shakuhachi]
A18   [A15_Shakuhachi]
A19   [A14_Ocarina   ]
A20   [A16_ClearWinds, A16_ClearWinds]
A21   [A19_PowerWood , A19_PowerWood ]
A22   [A20_HolloWood ]
A23   [A24_FatReed 1 ]
A24   [A21_HardWood  ]
A25   [A09_SopranoSax, A11_TenorSax 2, A28_SaxSect.1 ]
A26   [A04_Clarinet  , A10_TenorSax 1, A11_TenorSax 2, A25_FatReed 2 , A28_SaxSect.1 , A29_SaxSect.2 , A32_Mammoth ! ]
A27  m[A09_SopranoSax]
A28   []
A29   [A26_FluteEns. , A26_FluteEns. ]
A30   [A24_FatReed 1 , A25_FatReed 2 ]
A31  m[A30_Chime/Oboe, A32_Mammoth ! , A32_Mammoth ! ]
A32   [A08_PuffPanFlt]
B01  m[B03_MutedTrp. ]
B02   [B02_Trumpet 2 , B10_FusionBrs , B10_FusionBrs ]
B03   [B03_MutedTrp. , B03_MutedTrp. , B16_MuteBrass , B16_MuteBrass ]
B04   [B03_MutedTrp. , B05_Flugel 2  , B05_Flugel 2  , B13_ClassicBrs, B14_ClassicHrn, B15_OrchHorns ]
B05   [B06_Trombone  , B09_BrassEns. , B09_BrassEns. , B10_FusionBrs , B11_HardPopBrs, B12_HvyPopBrs , B13_ClassicBrs, B16_MuteBrass , B17_TuttiBrass, B17_TuttiBrass]
B06   [B07_FrenchHorn, B07_FrenchHorn, B14_ClassicHrn, B15_OrchHorns , B15_OrchHorns ]
B07   [B08_Tuba      , B09_BrassEns. , B17_TuttiBrass, B17_TuttiBrass]
B08   [B28_AttackSyn., B31_SynthBrs 3, B31_SynthBrs 3]
B09  m[B26_SwampSynth, B26_SwampSynth]
B10   [B18_HarmoSynth, B18_HarmoSynth, B29_SynthBrs 1]
B11   [B19_SmoothBrs , B19_SmoothBrs ]
B12  m[B02_Trumpet 2 , B04_Flugel 1  ]
B13   [B01_Trumpet 1 , B11_HardPopBrs, B12_HvyPopBrs , B13_ClassicBrs, B17_TuttiBrass, B17_TuttiBrass, B17_TuttiBrass, B17_TuttiBrass]
B14   [B20_DualSynth , B20_DualSynth ]
B15   [B21_LyriSynth , B21_LyriSynth , B32_SynthOrch ]
B16   [B22_MelloSynth, B22_MelloSynth]
B17   [B23_BuzzySynth, B23_BuzzySynth]
B18   [B04_Flugel 1  ]
B19   []
B20   [B24_SharpSynth, B24_SharpSynth]
B21   [B25_SolidSynth, B25_SolidSynth]
B22   []
B23   [B32_SynthOrch ]
B24   [B32_SynthOrch ]
B25   [B27_SandyBrass, B27_SandyBrass]
B26  m[B01_Trumpet 1 ]
B27  m[B28_AttackSyn.]
B28   [B29_SynthBrs 1, B30_SynthBrs 2]
B29   [B30_SynthBrs 2]
B30   []
B31   [B11_HardPopBrs, B11_HardPopBrs]
B32   [B12_HvyPopBrs ]
C01   [C01_Harmonica1]
C02   [C02_Harmonica2]
C03   [C03_Concertina, C03_Concertina]
C04   [C04_Bandonion , C04_Bandonion ]
C05   [C05_Accordion , C05_Accordion ]
C06   [C10_DistGuitar]
C07   [C10_DistGuitar]
C08   [C18_GuitarSyn , C18_GuitarSyn ]
C09   [C20_Clavidion1, C20_Clavidion1]
C10   [C21_Clavidion2, C21_Clavidion2]
C11   [C23_FuzzySax  ]
C12   [C23_FuzzySax  ]
C13   [C12_Fretless  , C12_Fretless  ]
C14 0m[C13_UpriteBass]
C15 0 [C13_UpriteBass]
C16 0m[C11_A.Guitar  ]
C17 0 [C11_A.Guitar  ]
C18  m[C19_PortaLead , C19_PortaLead ]
C19   [C06_Violin    ]
C20   [C06_Violin    ]
C21   []
C22   [C16_Whistle   , C16_Whistle   , C16_Whistle   ]
C23 0m[]
C24   [C24_Fuzz 5ths , C24_Fuzz 5ths ]
C25   [C25_BreathHit , C26_Breath 5th, C26_Breath 5th, C26_Breath 5th, C26_Breath 5th, C26_Breath 5th]
C26  m[C25_BreathHit , C25_BreathHit , C25_BreathHit , C25_BreathHit ]
C27   []
C28   [C22_SynthLead , C22_SynthLead , C22_SynthLead ]
C29   [C14_PipeOrgan , C14_PipeOrgan ]
C30   [C27_TalkingBox, C27_TalkingBox, C27_TalkingBox]
C31   [C17_Bells     , C17_Bells     , C17_Bells     ]
C32 0 []
D01   [C15_Choir     , C15_Choir     ]
D02   [C29_SpaceDust , C29_SpaceDust ]
D03   [C07_Cello     ]
D04   [C07_Cello     ]
D05   [C29_SpaceDust ]
D06   [C08_Strings   , C08_Strings   , C08_Strings   , C09_DualString, C09_DualString, C09_DualString]
D07   [C28_HarmoWhist]
D08   [C28_HarmoWhist, C28_HarmoWhist]
D09   [C30_Str/Flute ]
D10 0 []
D11   [C32_FreeJazz  ]
D12   [C32_FreeJazz  ]
D13   []
D14   []
D15   [C31_Str/Oboe  ]
D16   [C30_Str/Flute , C30_Str/Flute , C30_Str/Flute , C31_Str/Oboe  , C31_Str/Oboe  , C31_Str/Oboe  ]
D17 0 []
D18 0 []
D19 0 []
D20 0 []
D21 0 []
D22 0 []
D23 0 []
D24 0 []
D25 0 []
D26 0 []
D27 0 []
D28 0 []
D29 0 []
D30 0 []
D31 0 []
D32 0 []

  • [ ]の前に m が付いているボイスはMonoモード(Polyモードではない=エンベロープをリトリガしない)
  • [ ]の前に 0 が付いているボイスはBCEG bias=0(他は全て99)「プァン」という音の出だしの表現?

他に気づいたこと:

  • Portament time > 0 なのはボイスC18のみ
  • OP1~4のKVS(Key Velocity Sensitivity、note onで与えられるvelocity値の感度)が0以外のものもある。
  • OP1~4のEBS(EG Bias Sensitivity、ブレスが音量に与える影響の感度)が7以外のものもある。

TX81Zを解析した(パフォーマンスモード編 追記)

TX81ZのPCEDの設定項目「Volume」について調査し忘れていた。パフォーマンスモードで設定できる8つの楽器ごとに音量を設定するためのパラメータである。

VCEDのVolumeと同様に0~99の値を指定する。YM2414のTLレジスタにセットされる値に影響することも同様。4つのオペレータのうち、キャリアとなるオペレータのみに影響することも同様。

次の値がTLレジスタに書き込まれる値に加算される。TLレジスタは値が0の時に音量最大となり、値が127の時に音量最小となる。

vol	加算値
0	127
1	127
2	96
3	86
4	77
5	72
6	67
7	62
8	60
9	56
10	54
11	51
12	50
13	48
14	45
15	44
16	42
17	41
18	40
19	39
20	37
21	36
22	35
23	34
24	33
25	32
26	31
27	30
28	29
29	28
30	28
31	27
32	26
33	25
34	25
35	24
36	23
37	23
38	22
39	21
40	21
41	20
42	20
43	19
44	19
45	18
46	18
47	17
48	17
49	16
50	16
51	15
52	15
53	14
54	14
55	13
56	13
57	13
58	12
59	12
60	11
61	11
62	11
63	10
64	10
65	9
66	9
67	9
68	8
69	8
70	8
71	7
72	7
73	7
74	7
75	6
76	6
77	6
78	5
79	5
80	5
81	4
82	4
83	4
84	3
85	3
86	3
87	3
88	2
89	2
90	2
91	2
92	1
93	1
94	1
95	1
96	0
97	0
98	0
99	0

TX81Zを解析した(パフォーマンスモード編)

TX81Zに搭載されているOPZは(OPMと同様に)異なる8音を同時に発声する能力を持つ。1つのNote on信号を受信するとシングルモードでは1音を発声するのに対し、パフォーマンスモードでは2つ以上の音を同時に発声することができる。どのように組み合わせるかはPCED(Performance Edit Parameters)で指定する。

以下、Instrument Detuneというパラメータの働きを述べる。音の高さを微妙にずらすためのもので、音の厚み?を増やすのに使うようだ。-7~+7の値をとる。OPZのKF(Key Fraction:半音の1/64)に素直に加算されるかと思っていたが、その加算量は音の高さによって異なることが解析の結果判明した。


まず音の高さから。発声される音の高さは次のように決まる:

  1. MIDIのNote on信号で0~127が指定される
  2. この値にVCEDのTransposeパラメータで-24~+24が加算される
  3. さらにPCEDのNoteShiftパラメータで-24~+24が加算される
  4. 12以下の場合、13以上になるまで12を足す
  5. 109以上の場合、108以下になるまで12を引く
  6. この結果、音の高さ t は13(C#-1)~108(C7)となる。真ん中のドは60(C3)。

この音の高さとInstrument Detuneパラメータの値でKF=0からずらす量が決まる。

横軸: Instrument Detune (-7~7)
縦軸: (音の高さ - 13) / 4

      -7  -6  -5  -4  -3  -2  -1  0  1  2  3  4   5   6   7
   +-------------------------------------------------------
 0 | -17 -15 -12 -10  -8  -5  -3  0  2  4  7  9  12  14  17
 1 | -17 -15 -12 -10  -7  -5  -3  0  2  4  7  9  11  14  16
 2 | -16 -14 -12 -10  -7  -5  -3  0  2  4  6  9  11  13  16
 3 | -16 -14 -12  -9  -7  -5  -3  0  2  4  6  9  11  13  15
 4 | -16 -13 -11  -9  -7  -5  -2  0  2  4  6  8  10  13  15
 5 | -15 -13 -11  -9  -7  -5  -2  0  2  4  6  8  10  12  14
 6 | -15 -13 -11  -9  -6  -4  -2  0  2  4  6  8  10  12  14
 7 | -14 -12 -10  -8  -6  -4  -2  0  2  4  6  8  10  12  14
 8 | -14 -12 -10  -8  -6  -4  -2  0  1  3  5  7   9  11  13
 9 | -13 -12 -10  -8  -6  -4  -2  0  1  3  5  7   9  11  13
10 | -13 -11  -9  -8  -6  -4  -2  0  1  3  5  7   9  10  12
11 | -13 -11  -9  -7  -6  -4  -2  0  1  3  5  7   8  10  12
12 | -12 -10  -9  -7  -5  -4  -2  0  1  3  5  6   8  10  11
13 | -12 -10  -8  -7  -5  -4  -2  0  1  3  4  6   8   9  11
14 | -11 -10  -8  -7  -5  -3  -2  0  1  3  4  6   7   9  10
15 | -11  -9  -8  -6  -5  -3  -2  0  1  3  4  6   7   9  10
16 | -10  -9  -7  -6  -5  -3  -2  0  1  2  4  5   7   8  10
17 | -10  -9  -7  -6  -4  -3  -2  0  1  2  4  5   6   8   9
18 |  -9  -8  -7  -6  -4  -3  -2  0  1  2  3  5   6   7   9
19 |  -9  -8  -7  -5  -4  -3  -2  0  1  2  3  5   6   7   8
20 |  -9  -7  -6  -5  -4  -3  -1  0  1  2  3  4   5   7   8
21 |  -8  -7  -6  -5  -4  -3  -1  0  1  2  3  4   5   6   7
22 |  -8  -7  -6  -5  -3  -2  -1  0  1  2  3  4   5   6   7
23 |  -7  -6  -5  -4  -3  -2  -1  0  1  2  3  4   5   6   7

あとは実装。しばらくプログラムから離れていたので思い出すところから。エミュレーションしたいのはWT11なので、TX81Zの解析結果がそのまま適用できるか微妙…。

WT11固有のパラメータ


WT11のエディットバッファ内のボイスデータ・パフォーマンスデータをTX81Z Programmerで取得する、という記事を前回書いた。その後マニュアルを眺めていたらTX81Zにはない固有のパラメータが存在するのに気が付いた。

ボイスデータについては、TX81ZのVCED・ACEDに加えWT11にはACED2というデータがある。アフタータッチの感度などを設定できる。

パフォーマンスデータについては、TX81ZのPCEDに加えWT11にはPCED2というデータがある。DSPエフェクタの設定項目のように見える。

ACED2・PCED2はTX81Z Programmerでは取得できなそうなので、吸出しプログラムを作ってみた。WT11はsecret modeで起動した後に本体のキーでボイスやパフォーマンスを変更するとsysexをMIDIに出力するようなので、それを拾って表示することにした。

ボイスデータを変更すると、こんなsysexデータが出力される。各行の先頭の数字はsysexのサイズ。マニュアルのTOTAL BULK SIZEにあるように、VCED=101、ACED=41、ACED2=28bytesとなる。

  101:f0 43 00 03 00 5d 14 12 00 07 0f 0a 01 04 00 00 46 0a 03 1f 1f 00 07 0f 0f 01 03 00 00 44 04 03 15 14 00 05 0f 09 01 02 00 00 2f 08 03 12 1f 00 0b 0f 1f 01 05 00 00 63 0a 03 03 00 1f 0a 00 00 00 02 05 00 18 00 02 00 00 28 01 00 00 0f 00 0f 00 32 63 57 54 31 31 20 20 41 30 31 20 63 63 63 32 32 32 56 f7
   41:f0 43 00 7e 00 21 4c 4d 20 20 38 39 37 36 41 45 00 00 00 02 00 00 00 00 01 00 00 00 00 03 00 00 00 00 03 00 00 00 00 3a f7
   28:f0 43 00 7e 00 14 4c 4d 20 20 38 30 32 33 41 45 00 00 32 00 00 00 00 00 00 00 22 f7

一方パフォーマンスデータのsysexデータはこんな感じ。PCED=128、PCED2=51bytesとなる。

  128:f0 43 00 7e 00 78 4c 4d 20 20 38 39 37 36 50 45 04 00 20 00 00 3b 07 18 47 03 01 00 04 00 21 00 00 7f 07 18 63 03 01 00 00 00 20 00 00 7f 07 18 63 03 00 00 00 00 20 00 00 7f 07 18 63 03 00 00 00 00 20 00 00 7f 07 18 63 03 00 00 00 00 20 00 00 7f 07 18 63 03 00 00 00 00 20 00 00 7f 07 18 63 03 00 00 00 00 20 00 00 7f 07 18 63 03 00 00 00 00 00 00 4f 62 6f 65 20 31 20 20 20 20 13 f7
   51:f0 43 00 7e 00 2b 4c 4d 20 20 38 30 37 33 50 45 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 01 25 64 00 14 00 00 00 00 00 00 00 00 00 00 00 00 1a f7

ポチポチとキーを押下するごとに表示されるので、これをファイルに保存すればOK。

プログラムはJavaで作った。Javaは意外とMIDI関連ライブラリが充実している。

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Receiver;
import javax.sound.midi.SysexMessage;
import javax.sound.midi.Transmitter;

/**
 * WT11をsecret modeで起動すると,
 * 本体のキーでボイス/パフォーマンスを切り替えるときにMIDIにダンプデータが出てくる
 * これを拾って表示する
 */
public class WT11sysex {
    Receiver receiver;
    Transmitter transmitter;
    MidiDevice deviceIn, deviceOut;

    WT11sysex() {
        String AUDIOIF = "UR22mkII"; // オーディオインタフェース名
        try {
            MidiDevice.Info info[] = MidiSystem.getMidiDeviceInfo();
            for (MidiDevice.Info i: info) {
                MidiDevice device = MidiSystem.getMidiDevice(i);
                String name = i.getName();
                String desc = i.getDescription();
                System.out.printf("%s ## %s\n", name, desc);
                if (name.contains(AUDIOIF) && device.getMaxReceivers() != 0)
                    deviceOut = device;
                if (name.contains(AUDIOIF) && device.getMaxTransmitters() != 0)
                    deviceIn = device;
            }
            deviceOut.open();
            receiver = deviceOut.getReceiver();
            deviceIn.open();
            transmitter = deviceIn.getTransmitter();
            transmitter.setReceiver(new MyReceiver());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void shutdown() {
        receiver.close();
        transmitter.close();
        deviceOut.close();
        deviceIn.close();
    }

    /** 拾ったsysexデータを表示する */
    class MyReceiver implements Receiver {

        @Override
        public void send(MidiMessage message, long timeStamp) {
            int len = message.getLength();
            byte b[] = message.getMessage();
            System.out.printf("%5d:", len);
            for (int i=0; i<len; i++) System.out.printf("%02x ", b[i]);
            System.out.println();
        }

        @Override
        public void close() {
        }
    }

    /** SYSEXを送る予定だったが不要だった */
    void sendSysex() {
        try {
            int seq[] = { 0xf0,0x43,0x20,0x7e,'L','M',' ',' ','8','0','2','3','A','E',0xf7 }; // (3)ACED2 + ACED + VCED
            byte b[] = new byte[seq.length];
            for (int i=0; i<seq.length; i++) b[i] = (byte)(seq[i] & 0xff);
            SysexMessage message = new SysexMessage(b, b.length);
            receiver.send(message,  -1);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /** 60秒のうちにキーで切り替える */
    public static void main(String args[]) throws Exception {
        WT11sysex wt11 = new WT11sysex();
        //wt11.sendSysex();
        Thread.sleep(60000);
        wt11.shutdown();
    }
}

WT11をゲットした

TX81Zを検索していると、ちょいちょいWT11のページも引っかかる。面白そうなので中古品を買ってみた。
f:id:androuet:20210507180346j:plain

WT11YAMAHAから発売された音源モジュール。プリセットのほとんどが木管/金管楽器でWX11などのブレス入力MIDIコントローラーとつないで使う。Wikipediaによると30年以上前の設計のようだ。

  • 1986年:TX81Z発売(FMシンセサイザ)
  • 1987年:WX7発売(MIDIコントローラー)
  • 1988年:WX11発売(  〃  )
  • 1988年:WT11発売(FMシンセサイザ)
  • 1998年:WX5発売(MIDIコントローラー 10年経ってからの発売)

WT11の中身はTX81Zとほぼ同じでエフェクタ付き、という仕様なのが分かった。TX81Zとも互換性?があるようだ。シークレットモードへの移行方法も説明されている。
ameblo.jp


というわけで、次の目標は「WT11のプリセットを自作ウィンドシンセで鳴らす」ということにする。まずはプリセットデータの取り出しから行った。

WT11はTX81Zで言うパフォーマンスモードで動いている。取り出すべきデータは次の2つ:

  1. PCED (Performance Edit Parameters):96個
  2. VCED+ACED (Voice Edit Parameters + Additional Parameters):112個

取説の40ページによると、これらをパフォーマンスエディットバッファ・ボイスエディットバッファに入れればMIDI経由で読み取れるように見える。TX81Z Programmerで取り出しを行った。

PCEDデータの取り出しは通常モードでできる。「A01 Oboe 1」~「C32 FreeJazz」という名前のデータ96個を得ることができた。

VCED+ACEDデータの取り出しはシークレットモードへの移行が必要(通常モードだとバッファにセットする方法がなさそうなので)。ちょっと変則的な名前がついていて、

  • 「WT11 A01 」~「WT11 A32 」
  • 「WT11 B01 」~「WT11 B32 」
  • 「WT11 C01 」~「WT11 C32 」
  • 「WT11-D01」~「WT11-D16」

という名前のデータ112個を得ることができた。パフォーマンスモードの実装はこれから。

話は変わるがちょっと前にティンホイッスルを買った。強く息を吹くとオクターブが高くなるという不思議な楽器だ。楽譜も買った。アイリッシュ音楽は祝祭感があってよいと思う(無印ぽい気もするが)。
celtnofue.com

リバーブつけた

今までのなんちゃってリバーブをFreeverbに変更した。ソースコードは以下のページからリンクされているページで入手できる。
prettoguitar.blogspot.com

リンク先はFreeverb3というVSTの作者のページ。Freeverbより音質がよいらしい。ESP32で動くかどうかは分からない。
freeverb3vst.osdn.jp

freeverbsource.zipをダウンロードし、

  • allpass.cpp, allpass.hpp
  • comb.cpp, comb.hpp
  • denormals.h
  • revmodel.cpp, revmodel.hpp
  • tuning.h

をESP32ソースファイルの置き場所にコピーし、

revmodel *freeverb;
  :
freeverb = new revmodel();

でリバーブモデル?を生成しておく。入出力バッファを

float revInput1[64], revInput2[64];
float revOutput1[64], revOutput2[64];

で64サンプル×2ch分確保しておく。ym2151.cのym2151_update_one()で得られる64サンプル2ch分をrevInput1/2[]に格納して

freeverb->processreplace(revInput1, revInput2, revOutput1, revOutput2, 64, 1);

を呼び出すとrevOutput1/2[]に出力される。これをi2s_write()に渡すとリバーブされた音が出る。思っていた以上にきれいな音だった。耳の肥えていない自分にはこれで十分かな。パラメータはroomsize, damp, wet, dry, widthの5つ。tuning.hに初期値が設定してある。dryが0だったので0.67に変更した。

ESP32で処理するときの負荷だが、44100サンプル作るのに

だった。結構ぎりぎり! 今はcore0で実行している。BLE MIDIと一緒に使うのは無理かもしれない。

音色エディタを作った

ウィンドシンセの音色をPCから変更するための音色エディタを作った。

f:id:androuet:20210409173335p:plain
音色エディタ

よくありそうなFM音源音色エディタだけど、16進数を編集していたのに比べれば楽になった。ウィンドシンセとの通信はシリアル経由。そのうちBLE MIDIでやりとりしたい。PCでも同じエンジンが動いているので、ウィンドシンセを繋がなくても音は確認できる。

上半分はTX81Zのパラメータの設定と波形の表示。小さくまとめたかったのでcontrolP5で。Swingの中にProcessingコードを埋め込む方法はここを参考にした。音色作成には波形よりも周波数スペクトルを見たほうがよいのかも。今後の課題。

下半分はプリセットの選択。こちらはSwingで。赤文字はこのサイトで聴くことのできる音。実機が無かった頃は、この音と比較しながらエミュレータを作っていた。

ウィンドシンセの音源としてFM音源を使う方法については以下のサイトが参考になった。

いま気が付いたのだが「ウインドシンセ」「ウィンドシンセ」どちらが一般的なのだろう?