AquesTone のピッチベンドセンシティビティですが、なんか10倍の値を指定しないとまともに動作しない感じ

するんですがどうなってますですか?

いや先日の

をちょっと改造して Python から AquesTone*1 を弄るプログラム作ってたんですが。

'''AquesTone Test.

要 MIDI Yoke & VSTHost.

マウス左ボタンでスタッカート、
右ボタンでレガート(スペースでノートオフ)。
鍵盤を押す場所の上下でベロシティ調整。
発音中にマウスホイール回転にてピッチベンド。
'''
import sys
import pygame
import pygame.midi
from pygame.locals import *

MIDIDEVICE = b'Out To MIDI Yoke:  1'
INSTRUMENT = 80  # 楽器の種類 (0-127)
                 #   0:Piano, 19:Organ, 56:Trumpet, 91:Voice 等
KEY_WIDTH = 20  # 鍵盤の幅
WIDTH, HEIGHT = 800, 128  # 画面の大きさ

PITCH_BEND_SENSITIVITY = 12  # ピッチベンドの最大(半音単位)
PITCH_BEND_SCALE = 1/10  # 1カウントでのピッチベンドの量(半音単位)

FPS = 60
NOTE_CENTER = 60  # 中央の音。C(ド)の音を指定
COLOR = 0, 255, 200  # 色
WHITE_COLOR = 255, 255, 255  # 白鍵の色
BLACK_COLOR = 0, 0, 50  # 黒鍵の色
BG_COLOR = 100, 0, 50  # 背景色

KEY_COLOR = 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0  # 0=白鍵, 1=黒鍵
NOTE_NAME = ('C', 'C#', 'D', 'D#', 'E',
             'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')


def set_pitchbend(midiout, value):
    p = int(value * 8192 / PITCH_BEND_SENSITIVITY)
    p = max(-8192, min(+8191, p))
    print(value, p)
    p += 8192
    midiout.write_short(0xe0, p % 128, p // 128)  # ピッチベンド

def set_pitchbend_sensitivity(midiout, value, channel=0):
    print('pitch:', value)
    s = 0xb0 + channel
    midiout.write([
        [[s, 101, 0], 0],
        [[s, 100, 0], 0],
        [[s, 6, value * 10], 0],  # なぜか 10倍 の値を指定しないと
                                  # Pitchbend Level が正しく設定されない
        [[s, 38, 0], 0]])

def main():
    pygame.init()
    pygame.midi.init()
    fsenc = sys.getfilesystemencoding()
    midiid = None
    for i in range(pygame.midi.get_count()):
        interf, name, inp, outp, opened = pygame.midi.get_device_info(i)
        if name == MIDIDEVICE:
            midiid = i
            break
##    midiid = pygame.midi.get_default_output_id()  ## 標準の音源でテスト
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    midiout = pygame.midi.Output(midiid)
##    midiout.set_instrument(INSTRUMENT)  ## 標準の音源でテストする時はこれも生かす
    clock = pygame.time.Clock()
    clock.tick(FPS)
    keys = WIDTH // KEY_WIDTH + 1
    keylist = [False] * (keys + 7)
    note_start = NOTE_CENTER - keys // 2
    note_no = None
    vel = 0
    set_pitchbend_sensitivity(midiout, PITCH_BEND_SENSITIVITY)
    pitchbend = 0
    set_pitchbend(midiout, pitchbend)
    caption = 'AquesTone test'
    while True:
        for e in pygame.event.get():
            if e.type is QUIT:
                midiout.write_short(0xb0, 123)  # オールノートオフ
                return
            elif e.type is KEYDOWN and e.key is K_ESCAPE:
                return
            elif e.type is KEYDOWN and e.key is K_SPACE:
                note_no = None
                for key, b in enumerate(keylist):
                    if b:
                        midiout.note_off(note_start + key, 0)
                        keylist[key] = False
            elif e.type is MOUSEBUTTONDOWN and (
                e.button == 1 or e.button == 3):
                x, y = e.pos
                pitchbend = 0
                set_pitchbend(midiout, pitchbend)
                vel = 128 * y // HEIGHT
                key = x // KEY_WIDTH
                keylist[key] = True
                note = note_start + key
                midiout.note_on(note, vel)
                caption = '{0}{1}, Velocity:{2}'.format(
                    NOTE_NAME[note % 12], note // 12 - 2, vel)
                if note_no != note and note_no is not None:
                    midiout.note_off(note_no, 0)
                    keylist[note_no - note_start] = False
                note_no = note
            elif e.type is MOUSEBUTTONDOWN and e.button == 2:
                pitchbend = 0
                set_pitchbend(midiout, pitchbend)
            elif e.type is MOUSEBUTTONDOWN and e.button == 4:
                pitchbend += PITCH_BEND_SCALE
                pitchbend = min(PITCH_BEND_SENSITIVITY, pitchbend)
                set_pitchbend(midiout, pitchbend)
            elif e.type is MOUSEBUTTONDOWN and e.button == 5:
                pitchbend -= PITCH_BEND_SCALE
                pitchbend = max(-PITCH_BEND_SENSITIVITY, pitchbend)
                set_pitchbend(midiout, pitchbend)
            elif e.type is MOUSEBUTTONUP and e.button == 1:
                note_no = None
                for key, b in enumerate(keylist):
                    if b:
                        midiout.note_off(note_start + key, 0)
                        keylist[key] = False
        screen.fill(BG_COLOR)
        for key in range(keys):
            x = key * KEY_WIDTH
            screen.fill((WHITE_COLOR, BLACK_COLOR)[
                KEY_COLOR[(note_start + key) % 12]],
                        (x + 1 , 0, KEY_WIDTH - 2, HEIGHT))
            if keylist[key]:
                pygame.draw.rect(
                    screen, COLOR, (x, 0, KEY_WIDTH, HEIGHT), 3)
        clock.tick(FPS)
        pygame.display.flip()
        notes = []
        for key, b in enumerate(keylist):
            if b:
                nn = note_start + key
                notes.append('{0}:{1}'.format(NOTE_NAME[nn % 12], nn))
        pygame.display.set_caption(caption)
        

if  __name__ == '__main__':
    try:
        main()
    finally:
        pygame.quit()

# Public Domain. 好きに流用してください。

Python 3.1 & Pygame 1.9 & Windows 用。

あと必要なのは

あたり。

設定方法

これは MIDI YokeOut To MIDI Yoke: 1 に出力するプログラム。なので、まずは VSTHostAquesTone を使えるようにして、その VSTHost

Devices > MIDI > MIDI Input Devices

In From MIDI Yoke: 1 を指定。そして VSTHost 上の AquesToneMIDI Input Devices も同様に In From MIDI Yoke: 1 を指定。以上で行けるはず。

いやこの半端スクリプトの使い方はともかく

こんなふうに Python からコントロールするのでなくて普通の MIDI シーケンサー使っていても同様にピッチベンドセンシティビティ(Pitchbend Level)おかしいんじゃないかと思うのですが……まあ打ち込みの時には直接 VSTi のパネルの GUI 使って調整するから MIDI のそれは使わない、ということなのかな?

そもそも打ち込みよりリアルタイム演奏を重視している音源*2な感じだし、その場合だとこれでも不都合は表れないから気にする人も居なかったのでしょうか……。

*1:Ver. 0.7.5.2

*2:歌詞の指定も MIDI からじゃできないし