スポンサーリンク

AIでMIDIコントローラーを自分好みに改造!Claude CodeでIntech Studio「VSN1」をVUメーター化してみた

この記事は約13分で読めます。
この記事にはアフィリエイトなどPRが含まれています

Intech StudioVSN1という小型コントローラーをご存じでしょうか。小さなディスプレイとロータリーエンコーダー、8つのボタンを備えた個性的なデバイスですが、「面白そうだけど何に使えばいいのかよくわからない」と感じている方も多いかもしれません。そこで今回は、このVSN1をAIの力を借りてVUメーターに仕立てるという実験に挑戦してみました。

使ったのはClaude(AIチャット)とClaude Code。プログラムの知識は大昔の記憶程度で、その記憶もまったく使わず。PythonもClaude Codeも今回が初めてという状況でのチャレンジです。試行錯誤を重ねながらも、半日ほどで実用的なVUメーターを完成させることができました。今回はその一部始終を紹介していきます。

AIを活用し、Intech StudioのMIDIコントローラー、VSN1をVUメーターにしてみた


スポンサーリンク
スポンサーリンク

Intech StudioのGridシリーズとVSN1とは

Intech Studioは、高度にカスタマイズ可能なMIDIコントローラーを開発するメーカーです。同社が展開する「Gridシリーズ」は、専用ソフト「Grid Editor」を使ってボタンやノブなどの動作を自由に設定できるのが最大の特徴。自分の用途や好みに合わせてコントローラーを自由自在に作り上げられる、DIY精神あふれるプロダクトラインです。

以前に紹介した「磁石で自在に拡張する新世代MIDIコントローラー、Intech Studio「Grid」シリーズが日本上陸」という記事でGridシリーズの概要や関連製品について紹介しましたが、今回フォーカスするVSN1はその中でも特にユニークな存在です。本体には直径数センチほどの丸いディスプレイが搭載されており、カスタムグラフィックやアニメーションを表示することが可能。ロータリーエンコーダーと8つのボタンを組み合わせることで、さまざまなMIDIコントロール機能を実装できます。

Intech StudioのGridシリーズ。磁石つなげて自由に拡張できるUSBのMIDIコントローラー

ただ、このVSN1、その可能性の広さゆえに「具体的に何をさせればいいのか」というイメージが湧きにくいのも事実です。今回の実験は、そんなVSN1の活用法の一例として、VUメーターを実装するというものです。


まずClaudeに相談してみた

「VSN1をVUメーターにできないか」と思いついたものの、どうすれば実現できるのかまったく見当がつきません。そこでまずはClaudeに相談してみました。

Claudeからの答えはシンプルでした。「Windowsのオーディオ出力をリアルタイムで解析して、左右それぞれのレベルをMIDI CCに変換し、VSN1に送信する仕組みを作れば実現できます」というものです。

具体的な方針は次の2段構成。

PythonでWASAPIのLoopback機能を使ってオーディオ信号を取得し、レベルをMIDI CCに変換してVSN1に送信するプログラムを書く

Grid Editor(Luaスクリプト)で、受け取ったMIDI CCの値をディスプレイに針として描画するVUメーターUIを作るWindowsにはWASAPIというオーディオAPIが標準で搭載されており、そのLoopback機能を使えば再生中のすべての音をキャプチャできます。MacではBlackHoleなどの仮想オーディオデバイスが必要になりますが、Windowsなら追加ソフトなしで対応できる点が便利です。

こうしたシステム設計をすらすら提案してくれるのが、AIならではの強みです。「どうすればいいか」を相談するだけで、実装の道筋が見えてくる。これはプログラム知識がない人にとって非常に心強いものとなってくれるはずです。


Pythonでオーディオ→MIDI変換プログラムを作る

方針が決まったところで、さっそくPythonのプログラム作成に取り掛かりました。ここで初めてClaude Codeを使うことになります。

Claude Codeはターミナル(コマンドライン)上で動作するAIコーディングアシスタントです。「こういうプログラムを作りたい」と伝えるだけで、コードの生成、実行、エラーの修正まで自律的に進めてくれます。

Claude Codeを起動した画面

実は私自身、Pythonを使うのは今回が初めて。何度か勉強しなくちゃ…と思って入門書を買ったまま、何年も1ページも開かずにいた次第。そしてClaude Codeを使うのも今回の実験が初めてでした。Claude Codeは最近、いろいろなところで話題になっていたので、気になっていたものの、使ったことがなかったので、とっても楽しい経験にもなりました。

ターミナルを使うので、見た瞬間に敬遠してしまう人も多そうですが、「WASAPIのLoopbackでオーディオをキャプチャして、左右チャンネルのRMSレベルをMIDI CCとしてVSN1に送信するPythonスクリプトを作ってほしい」と伝えるだけで、Claude Codeがプログラムの雛形を生成してくれるので、まったくの初心者でも怖がる必要はなさそうです。

ChatGPTなどと同様、Claude Codeに直接、日本語で話しかけていく

プログラムの仕組みを簡単に説明すると、次のような流れになっています。

1. WASAPIのLoopback機能でシステムのオーディオ出力を取得
2. 左チャンネル(L)と右チャンネル(R)に分離
3. それぞれのRMS(二乗平均平方根)を計算してレベルを算出
4. dBFSに変換し、-40dB〜0dBの範囲をMIDI CC値(0〜127)にマッピング
5. スムージング処理を加えてVUメーター特有の「なめらかな動き」を再現
6. MIDI CCをVSN1に送信

もっともここでも試行錯誤の連続。「ライブラリが見つからない」「デバイスのインデックスが違う」といったエラーが次々と出てきましたが、そのたびにエラーメッセージをそのままClaudeやClaude Codeに貼り付けると、原因と対処法をすぐに教えてくれます。

最終的に完成したPythonのプログラムを参考用として掲載しておきます(環境によって一部設定変更が必要です)。もっとも、このプログラムを理解する必要はないですし、実際私自身、このプログラムはまったく見てないので、ただの大きな画像だと思って読み飛ばしてもらってOKです。もし、同じようなプログラムを組むことがあれば、その際、活用していただければ、と。

import numpy as np
import pyaudio
import mido
import time
import threading

# 設定
SAMPLE_RATE = 44100
CHUNK_SIZE = 1024
MIDI_CC_L = 1   # 左チャンネル用CC番号
MIDI_CC_R = 2   # 右チャンネルCC番号
MIDI_CHANNEL = 0
VU_SMOOTHING = 0.8  # スムージング係数(0〜1)

# WASAPIループバックデバイスのインデックス(環境に合わせて変更)
WASAPI_DEVICE_INDEX = None  # Noneで自動検出

def find_wasapi_loopback():
    """WASAPIループバックデバイスを探す"""
    p = pyaudio.PyAudio()
    for i in range(p.get_device_count()):
        info = p.get_device_info_by_index(i)
        if 'loopback' in info['name'].lower() or 'ループバック' in info['name'].lower():
            p.terminate()
            return i
    # ループバックが見つからない場合はデフォルト入力を使用
    default = p.get_default_input_device_info()
    p.terminate()
    return default['index']

def amplitude_to_vu(amplitude):
    """振幅値をVUメーター用のMIDI値(0〜127)に変換"""
    if amplitude <= 0:
        return 0
    # dBFSに変換
    db = 20 * np.log10(amplitude + 1e-9)
    # VUメーターの範囲: -40dB〜0dBを0〜127にマッピング
    db_min = -40.0
    db_max = 0.0
    normalized = (db - db_min) / (db_max - db_min)
    normalized = max(0.0, min(1.0, normalized))
    return int(normalized * 127)

class VUMeterBridge:
    def __init__(self):
        self.running = False
        self.level_l = 0.0
        self.level_r = 0.0
        
        # MIDIポートを開く(VSN1が接続されているポート名に合わせて変更)
        available_ports = mido.get_output_names()
        print("利用可能なMIDIポート:", available_ports)
        
        # VSN1のポートを自動検出
        vsn1_port = None
        for port in available_ports:
            if 'VSN' in port or 'Intech' in port or 'Grid' in port:
                vsn1_port = port
                break
        
        if vsn1_port is None and available_ports:
            vsn1_port = available_ports[0]
            print(f"VSN1が見つからないため、最初のポートを使用: {vsn1_port}")
        
        self.midi_out = mido.open_output(vsn1_port)
        print(f"MIDIポート接続: {vsn1_port}")
        
        # オーディオ
        self.p = pyaudio.PyAudio()
        device_index = find_wasapi_loopback()
        print(f"オーディオデバイス: {self.p.get_device_info_by_index(device_index)['name']}")
        
        self.stream = self.p.open(
            format=pyaudio.paFloat32,
            channels=2,
            rate=SAMPLE_RATE,
            input=True,
            input_device_index=device_index,
            frames_per_buffer=CHUNK_SIZE
        )
    
    def send_midi_cc(self, cc, value):
        msg = mido.Message('control_change', channel=MIDI_CHANNEL, control=cc, value=value)
        self.midi_out.send(msg)
    
    def process_audio(self):
        """オーディオを処理してMIDI CCを送信するメインループ"""
        while self.running:
            try:
                data = self.stream.read(CHUNK_SIZE, exception_on_overflow=False)
                samples = np.frombuffer(data, dtype=np.float32)
                
                # ステレオ分離
                left = samples[0::2]
                right = samples[1::2]
                
                # RMS計算
                rms_l = np.sqrt(np.mean(left ** 2))
                rms_r = np.sqrt(np.mean(right ** 2))
                
                # スムージング
                self.level_l = VU_SMOOTHING * self.level_l + (1 - VU_SMOOTHING) * rms_l
                self.level_r = VU_SMOOTHING * self.level_r + (1 - VU_SMOOTHING) * rms_r
                
                # MIDI CC送信
                cc_l = amplitude_to_vu(self.level_l)
                cc_r = amplitude_to_vu(self.level_r)
                self.send_midi_cc(MIDI_CC_L, cc_l)
                self.send_midi_cc(MIDI_CC_R, cc_r)
                
            except Exception as e:
                print(f"エラー: {e}")
                time.sleep(0.01)
    
    def start(self):
        self.running = True
        self.thread = threading.Thread(target=self.process_audio, daemon=True)
        self.thread.start()
        print("VUメーターブリッジ 起動中... Ctrl+Cで停止")
    
    def stop(self):
        self.running = False
        self.stream.stop_stream()
        self.stream.close()
        self.p.terminate()
        self.midi_out.close()
        print("停止しました")

if __name__ == '__main__':
    bridge = VUMeterBridge()
    bridge.start()
    try:
        while True:
            time.sleep(0.1)
    except KeyboardInterrupt:
        bridge.stop()

そのPythonのプログラムを起動して、音楽プレイヤーを鳴らした際の画面が以下のものです。この画面を見る意味はあまりないですが、画面下部にLとRのレベルがリアルタイムに変化していることが確認できます。

できあがったPythonのプログラムを実行すると、画面の一番下にLとRのレベルが数字でピラピラと表示されるようになった

また、この表示と同時に、MIDI CC #20にLchの値を、MIDI CC #21にRchの値を送信しているのです。


Grid EditorでVUメーターのUIを作る

Pythonプログラムによるオーディオ→MIDI CC変換が動くようになったら、次はGrid Editor側の作業です。

さらにClaude CodeにVSN1に書き込むLuaのスクリプト=プログラムを書いてもらった

Grid Editorは、Gridシリーズの各要素(ボタン、ノブ、ディスプレイなど)の動作を視覚的に設定できる専用ソフト。内部ではLuaというスクリプト言語を使って柔軟なカスタマイズが可能です。Luaは、組み込み系のシステムでよく利用されているほか、DTM関連でいうとReaperの機能拡張で利用されていたり、TouchOSCでのMIDIマッピングやUIカスタマイズなどで利用されるもの。ちょっと昔でいうとVOCALOID 3の時代にあったJob Pluginを書くのにも使われていた言語ですね。もっともこれも知識はまったく不要で、すべてClaudeにお任せです。Claudeが作成してくれたプロンプトをClaude Codeに投げてから5分程度待たされましたが、以下のようにLuaのスクリプトを作成してくれました。

Claude Codeが作ったLuaスクリプト

その後、このLuaスクリプトを、Grid Editorを起動し、ディスプレイのDrawのタブに書き込み。さらにSystemのUlitility部分にもMIDI CCが届いたらディスプレイへ送るこることを指示するLuaスクリプトを書き込みました。この辺も自分だけだとさっぱりわからなかったのですが、Claudeが手取り足取り教えてくれました。

できあがったLuaスクリプトをGrid Editorに貼り付けていく

最初に作ったVUメーターは、黒い背景に白い針が揺れるシンプルなもの。左右2チャンネルが横に並んで表示されるステレオ表示でした。

L/Rのステレオで表示されるVUメーターが完成!

これはこれでいいのですが、ちょっと小さすぎて見づらいというのが正直なところ。黒バックに緑の針も悪くないけど、もうちょっと見栄えをよくしたいな、と思ったのです。

そこで次の改良版では「バックライトのあるVUメーター風」にデザインを変更。メーターのセグメントが光るタイプのビジュアルにしてみました。それでもやはりステレオ2ch表示は小さすぎる、ということで、仕様を思い切って変更。

バックライトが光る感じのもっと大きいVUメータにしてみた

1チャンネルだけをフルサイズで表示し、8つのボタンのうち左右のボタンを押すとLch/Rchを切り替えられる仕様です。これが正解でした。大きな針が勢いよく振れるVUメーターになり、視認性が大幅にアップ。音楽を再生するたびに針が踊る様子はなかなか気持ちがいいものです。今回は右側にディスプレイがある仕様のVSN1-Rを使っていましたが、左側にディスプレイのあるVSN1-Lも持っていたら、それぞれをLとRに割り当てて使うのがよさそうですね。

左上のボタンを押すと、Lチャンネルが、右上のボタンを押すとRチャンネルが表示されるようにしてみた

DAWと組み合わせるにはどうすればいい?

単体のVUメーターとして動くようになり、Windowsで音楽を再生すればメーターが振れることを確認できました。しかし次の疑問が浮かびます。「せっかくなら、DAWと一緒に使いたい」。

ここでまたClaudeに相談してみました。

DAWでオーディオインターフェイスを使う場合、通常はASIOドライバーを経由します。ところがASIOはWASAPIとは別系統のため、今回作ったPythonプログラム(WASAPIのLoopbackを使用)ではDAWの出力音声を拾えないのです。

無料で入手できるVoicemeeter Bananaを活用してASIOをWASAPIにルーティング

解決策としてClaudeが提案したのが「Voicemeeter Bananaの活用」です。Voicemeeter Bananaはフリーウェアのバーチャルオーディオミキサーで、Windowsのオーディオルーティングを柔軟に変更できます。手順はこうです。

1. DAWの出力先をVoicemeeter BananaのVirtual Inputに設定
2. Voicemeeter Banana内でオーディオインターフェイスのWASAPIに信号を送るよう設定
3. WASAPIのLoopback経由でPythonプログラムがレベルをキャプチャ

ここではMOTUのM4を使って試してみましたが、拍子抜けするほどスムーズに動作しました。CubaseなどのDAWで再生した音がVSN1のVUメーターにリアルタイムで表示される様子は、なかなか感動的です。

DAWの出力をVoicemeeter BananaのASIOに送った後、MOTU M4のWASAPIドライバへ

なお、VSTプラグインとして実装すれば、こうした迂回路を使わずにASIOとも直接連携できます。ただしその場合はPythonではなくC/C++とJUCEフレームワークを使った開発が必要になるため、環境整備がかなり大変。今回は手軽に使えるVoicemeeter Bananaを選びました。


さらにCubaseコントローラーとしても活用

VUメーターとして動くようになったVSN1ですが、せっかく8つのボタンとロータリーエンコーダーが付いているのだから、DAWコントロールにも使いたいところです。

こちらはGrid Editorで追加設定するだけでOK。

ロータリーエンコーダー:Cubaseのマスターボリュームコントロール
Button 5(下段左から4番目):STOP
Button 6(下段左から5番目):Play

この設定を加えることで、VUメーターを見ながらボリューム調整や再生・停止操作ができる、コンパクトなDAWコントローラーに仕立てることができました。

DAW側の機能で大きいノブをマスターボリュームに割り当てた

VUメーターでレベルを確認しながら、ロータリーエンコーダーでさっとボリュームを調整。手元でPlayとStopを操作できる快適さは、一度味わったらやめられません。作業効率が目に見えて上がりました。


AIがあればプログラムスキルゼロでも自分だけの道具を作れる時代

今回の実験を振り返ると、改めてAIの力に驚かされます。

PythonもClaude Codeも初めて、プログラミングの知識はゼロ。それでも半日ほどでVSN1のVUメーターを完成させることができました。設計の相談はClaude(チャット)で、コーディングと実行はClaude Codeで、という役割分担が非常にうまく機能しました。

特に実感したのは、エラーが出ても怖くないということ。エラーメッセージをそのままClaude Codeに投げれば、原因を説明した上で修正してくれます。「なぜ動かないのか」を自分で調べる必要がないので、プログラミングに不慣れな人でも試行錯誤を続けられます。

Intech StudioのVSN1は、そのまま使うだけでも多機能なコントローラーですが、今回のようにAIを組み合わせることで「自分だけのカスタムデバイス」に生まれ変わります。VUメーターである必要はなく、クリップ検出ランプ、BPMインジケーター、コード検出表示など、アイデア次第でさまざまな用途が考えられます。

「面白そうだけど何に使えばいいかわからない」というVSN1に対する印象が、今回の実験でがらりと変わりました。AIという強力な相棒を得た今、こうしたハードウェアコントローラーの可能性は、プログラマーだけのものではなくなっています。ぜひ皆さんも、自分だけの使い道を探してみてください。

Intech Studio VSN1
ディスプレイ:円形LCDディスプレイ(カスタムグラフィック対応)
コントロール:ロータリーエンコーダー×1、ボタン×8
接続:USB
対応OS:Windows / macOS
設定ソフト:Grid Editor(無料)
価格:オープンプライス
販売:メトロ科学模型

【関連情報】
Intech Studio Gridシリーズ製品情報

【関連記事】
磁石で自在に拡張する新世代MIDIコントローラー、Intech Studio「Grid」シリーズが日本上陸
世界最小のUSB MIDIホスト、Intech Studio「KNOT」——GridやUSBコントローラーでMIDI機器を自在にコントロール

【価格チェック&購入】
◎Intech Studio ⇒ VSN1-L , VSN1-R
◎Amazon ⇒ VSN1-L , VSN1-R
◎サウンドハウス ⇒ VSN1-L , VSN1-R

この記事を書いた人

DTM、デジタルレコーディング、デジタルオーディオを中心に執筆するライター。インプレスのAV WatchでもDigital Audio Laboratoryを2001年より連載。「Cubase徹底操作ガイド」(リットーミュージック)、「ボーカロイド技術論」(ヤマハミュージックメディア)などの著書も多数ある。趣味は太陽光発電、2004年より自宅の電気を太陽光発電で賄うほか、現在3つの発電所を運用する発電所長でもある。

藤本 健をフォローする
MIDIテクノロジー

コメント

  1. Tosey より:

    マニアの極みのような記事で、ユニークで面白かったです。