【Godot4】マイクからの音声入力を取得する

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Godot4】マイクからの音声入力を取得する

2023-4-12 | ,

Godot4でGDScriptを使ってマイクからの音声入力を取得してゴニョゴニョしたい!

概要

今回の記事では、Godot4でGDScriptを使ってマイクからの音声入力を取得する手順を掲載する。

この記事を執筆してる時点で参考になる資料が公式リファレンスくらいしかなく、この記事がベストプラクティスなのかは怪しい。

仕様書

環境

  • Gogot 4.0

手順書

「プロジェクト設定編」と「シーン設定編」と「スクリプト編」の3部構成です。

プロジェクト設定編

Godotでマイク入力を使うには、プロジェクトの設定を変更でマイク入力を許可する必要がある。下記の手順でマイク入力を許可できる。

  1. エディターの左上の「Project」->「Project Settings...」を左クリックする。
  2. タブ「General」の中の「Audio」に含まれる「Driver」を左クリックする。
  3. 右上の「Advanced Settings」を左クリックして有効にする。「Enable Input」の項目が表示されるので「On」を選択する。

シーン設定編

マイク入力を受け取る「Bus」と「Effect」と「ノード」の設定をする。

  1. エディターの中央下にあるタブ「Audio」を左クリックする。ミキサー的な画面が表示される。上の「Add Bus」を2回左クリックして「Bus(チャンネル的なもの)」を2つ追加する。
  2. 先程作った「Bus」に名前を付ける。中央を「Dummy」、右を「Record」とした。
  3. 「Record」の中の「Add Effect」を左クリックする。
  4. ポップアップで表示されるリストの中にある「Capture」を左クリックする。
  5. 「Capture」が追加されてチェックボックスにチェックが入ってることを確認する。この「Capture」を経由して音声の入力を取得することになる。
  6. 「Record」を出た後の音声の送り先を「Dummy」に設定する。「Record」の中の下の「Main」を「Dummy」に変更する。
  7. 「Scene」で「Node2D」の中に「AudioStreamPlayer」を追加する。
  8. 「Scene」で「AudioStreamPlayer」を選択して、「AudioStreamPlayer」の「Inspector」を表示する。「Stream」を左クリックして表示されるリストの中にある「New AudioStreamMicrophone」を選択する。
  9. 続いて「Inspector」の中にある「Playing」を「On」、「Autoplay」の「On」、「Bus」を「Record」に設定する。
  10. 前述の設定をすると、PCにマイクが接続されてれば「Record」のボリュームメーターに反応がある。Godotではマイクの選択はできないみたいでWindowsでいうところの「既定のマイク」が常に使われるようだ。マイクを接続してるのにも関わらずボリュームメーターに反応がない場合はGodotを再起動してみる。(私はこれに気付かず数時間頭を抱えることになった)

    スーピーカーからマイク入力の音声が出力されるが、必要ない場合は「Dummy」の中の「M(Mute)」を左クリックする。

スクリプト編

今回は先程設定した「AudioStreamPlayer」にスクリプトをアタッチしてマイク入力の音声を取得してみる。

  1. 「Scene」で「AudioStreamPlayer」を選択して、「AudioStreamPlayer」の「Inspector」を表示する。「Inspector」の下の方にある「Script」を左クリックして表示されるリストの中にある「New Script」を左クリックする。
  2. 下記はマイクから取得した音声をデバッグに出力するサンプル。データが多いので一部のデータしか出力されない。説明はコードの中にコメントで記載した。
    
    extends Node

var effect
var idx

func _ready():

Recordという名前のBusのインデックスを取得する。

idx = AudioServer.get_bus_index("Record")
# 指定したインデックスのBusの0番目のエフェクトを取得する。
effect = AudioServer.get_bus_effect(idx, 0)

func _process(delta):

get_bufferで取得できるデータのサイズを取得する。

var len:int = effect.get_frames_available()
# 指定したサイズを取得できるのか判定する。(できるはず)
if (effect.can_get_buffer(len)):
    # 指定したサイズのデータを取得してPackedVector2Array型に保存する。
    var array:PackedVector2Array = effect.get_buffer(len)
    for i in len:
        # 左右のデータを出力する。(おそらく-1~1の範囲のfloatの値が入ってる)
        # 実際にマイク音声で何かしらの処理をしたい場合はここに入力する。
        # 例:一定以上の音量の入力があったらUIになにかしらの反映するとか。
        print("L: " + array[i][0] + ", R: " + array[i][1])


## まとめ(感想文)

余談ですが、テスト時にあまりにも上手く行かず藁にもすがる思いでChatGPTに聞いてみたんだけども、嘘を付かれるという。嘘の内容は日記ブログの方に掲載したので興味がある方は見てみて下さい。

- [ChatGPTを使ってみた感想【日記】 | watermelonheadman.com](https://www.watermelonheadman.com/diary-20230411/)

## 引用・参考文献

- [AudioEffectCapture — Godot Engine (stable)の日本語のドキュメント](https://docs.godotengine.org/ja/stable/classes/class_audioeffectcapture.html)