IT-WEB -- MCタイチ

menuicon

PCを音声でコントロールする①2025-12-31

ソフト音源の膨大なプリセットをチェックするときに、MIDIキーボードから手を放さずに音声で順送りしたいと思ったことはないでしょうか?私はあります。そこでAIの助けを借りてやったら、意外と簡単にできたので紹介します。勿論、ソフト音源以外のアプリ(メーラーや表計算など)でも使えます。

尚、本記事で解説するのはPCキーボードのUp(上矢印)/Down(下矢印)キーを音声で操作する方法です。これとは別に、音声でマウスを操作し、画面内の上下矢印キーを操作する方法については、別の記事で紹介します。

Pythonスクリプト

もし、Pythonを使ったことが無いという人は、ThonyというIDEを使うのがお勧めです。ここからダウンロードしてインストール(Pythonプロブラム本体も同時にインストールされる)。エディット画面に下のコードをコピペして実行するだけ。おっと、ライブラリのインストールを忘れてました。Thonyウインド上部のメニューのツール>パッケージを管理 で子画面を出して、コード内で”import ○○”と書かれているライブラリを検索して全てインストールしてください。

今やプログラミングには欠かせなくなったAI(ここではGemini)ですが、漠然と願いを伝えるだけだと、時々思わぬ迷宮に案内してくれるので、今回はPCベースのPythonスクリプトを指定しました。それでも最初は、クラウドベースの音声ライブラリーを勧められ、動いたものの案の定モッサリです。そこでもっと早い方法はないかと尋ねたところ、Voskというプリロードタイプのライブラリを勧められました。

もっとも僕としては、予め録音した自分の声と照合した方が早いと思っていたので、それを提案したところ「それはとても合理的な発想です」としながらも、やはり既存の音声ライブラリの方が早いとの事。理由は丁寧に説明してくれたものの納得出来ず暫く食い下がりましたが、ここで時間を食うよりもまずはAIのおすすめをやってみる事にしました。

で結論ですが、以下のコードで遅延も感じられず、ちゃんと動きました。「次(つぎ)」という音声に対してDownキー、「前(まえ)」という音声に対して、Upを押す設定です。

尚、当初のコードでは2段飛びが起きたので、少しチューニングしてあります。「まーえー」と音を伸ばしたりせず、短めに話した方がうまく行くと思います。もっとも、使う人の声や使用環境、マイクやマイキングによっては、”INTERVAL”や”last_action_time”の値を変更した方がうまく行くかもしれません。

Python
import json
import queue
import sounddevice as sd
from vosk import Model, KaldiRecognizer
import pyautogui
import time

# --- 設定 ---
# 1. Voskのモデルディレクトリを指定(既存の"model"フォルダを利用)
model = Model(r"C:\<path>\model") 

# 2. マイク設定
device_info = sd.query_devices(None, 'input')
samplerate = int(device_info['default_samplerate'])
q = queue.Queue()

def callback(indata, frames, time, status):
    q.put(bytes(indata))

# 3. 認識する言葉を最小限に絞って精度と速度を向上
words_limit = '["次", "前", "[unk]"]'
INTERVAL = 0.8  # 操作の間隔(0.5秒)
last_action_time = 0

# --- メイン処理 ---
with sd.RawInputStream(samplerate=samplerate, blocksize=8000, device=None,
                        dtype='int16', channels=1, callback=callback):
    
    rec = KaldiRecognizer(model, samplerate, words_limit)
    print(">>> 閲覧モード起動中(声でスクロール)")
    print(">>> 「次」で下へ、「前」で上へ移動します。")

    while True:
        data = q.get()
        current_time = time.time()

        if rec.AcceptWaveform(data):
            # 確定結果(今回は不使用)
            rec.Result() 
        else:
            # 認識途中の結果を取得(反応速度を優先)
            partial = json.loads(rec.PartialResult())
            p_text = partial.get("partial", "").replace(" ", "")
            
            if (current_time - last_action_time > INTERVAL):
                if "次" in p_text:
                    pyautogui.press('down')
                    print("Action: [下] キー送信")
                    last_action_time = current_time
                    rec.Reset() # 連続反応を防ぐためリセット

                elif "前" in p_text:
                    pyautogui.press('up')
                    print("Action: [上] キー送信")
                    last_action_time = current_time
                    rec.Reset()
Python

これに加えて、スペースキーを操作するコードが下記の通りです。命令文は「スペース」です。

Python
import json
import queue
import sounddevice as sd
from vosk import Model, KaldiRecognizer
import pyautogui
import time

# --- 設定 ---
model = Model(r"C:\<path>\model") 

device_info = sd.query_devices(None, 'input')
samplerate = int(device_info['default_samplerate'])
q = queue.Queue()

def callback(indata, frames, time, status):
    q.put(bytes(indata))

# 3. 認識対象に「スペース」を追加
words_limit = '["次", "前", "スペース", "[unk]"]'
INTERVAL = 0.8  
last_action_time = 0

with sd.RawInputStream(samplerate=samplerate, blocksize=8000, device=None,
                        dtype='int16', channels=1, callback=callback):
    
    rec = KaldiRecognizer(model, samplerate, words_limit)
    print(">>> 閲覧モード起動中")
    print(">>> 「次」:下 / 「前」:上 / 「スペース」:スペースキー")

    while True:
        data = q.get()
        current_time = time.time()

        if rec.AcceptWaveform(data):
            rec.Result() 
        else:
            partial = json.loads(rec.PartialResult())
            p_text = partial.get("partial", "").replace(" ", "")
            
            if (current_time - last_action_time > INTERVAL):
                if "次" in p_text:
                    pyautogui.press('down')
                    print("Action: [下] キー")
                    last_action_time = current_time
                    rec.Reset()

                elif "前" in p_text:
                    pyautogui.press('up')
                    print("Action: [上] キー")
                    last_action_time = current_time
                    rec.Reset()

                # --- 「スペース」という言葉に反応 ---
                elif "スペース" in p_text:
                    pyautogui.press('space')
                    print("Action: [スペース] キー")
                    last_action_time = current_time
                    rec.Reset()
Python

この「スペース」命令を追加したのは、寝そべった状態でYoutube動画を再生/停止したかったからです。しかし実際にやってみると、何も言ってないのに時々勝手に停止/再生します。これは多分、動画内の会話に反応してるのだろうと思ったので、取りあえず会話音が出るアプリでの使用はやめました。気が向いたらまたAIに相談して、対策するかもしれません。

↓↓ ♥ ♥ ♥ Share this post ♥ ♥ ♥ ↓↓
page top↑