NuGetパッケージよりNAudioを使用しています。
音量が数値で返ってくるので、0.01以上だったら、しゃべっていると判断できると思われます。(精度を上げるなら0.001以上!?)
A.I.VOICEから配布されているAPIを使用せずに判断できます。(APIでbusyを判断した方が楽だと思われますが、なんらかの事情でAPIを使いたくないかた向けとなります。)
このコードを使えば、他のアプリの音量もチェックできるかもしれません。
プログラムの内容
やっていることは、NAudioを使い、A.I.VOICEのプロセスIDを取得。その後、音量を調べているだけです。
音量チェックは、タイマーを使い、0.2秒や0.3秒くらいで何度も行えば、常時喋っているか喋っていないかを判断できます。
サンプルコードの使用方法
1.VB.NETを起動し「新規プロジェクトの作成(N)」「Windowsフォームアプリ」を選択します。2.まっさらのForm1にLabel1とTimer1を設置します。
3.プロジェクトからNuGetパッケージ管理を選び、参照のタブの検索で「NAudio」を検索してインストールします。
4.コードエディタに、下記のコードをまるごと貼り付ければOKです。
5.A.I.VOICEを予め起動し、プログラムを実行する前に、何か1文字で良いので喋らせます。
6.プログラムを実行して、Form1が表示されたら、A.I.VOICEに長文の文章をしゃべらせてみましょう。
Label1.textにリアルタイムで音量が表示されます。
しゃべってない時でも、音量が0.00001等になることがあるので、0.01以上で喋っていると判断すると良さそうです。
ソースコード
Imports NAudio.CoreAudioApi
Public Class Form1
Private iDeviceEnumerator As MMDeviceEnumerator
Private iRender As MMDevice
Private iRenderAudioSessionManager As AudioSessionManager
Private iRenderSessions As SessionCollection
Private iAIVoice_ProcessID As String
Private Const cApp_Name As String = "AIVoiceEditor.exe"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call GetAIVoiece_ProcessID()
Timer1.Enabled = True
End Sub
'**********************************************************************************************
'A.I.VOICEのプロセスIDを取得するためだけのソース
'**********************************************************************************************
Private Sub GetAIVoiece_ProcessID()
Dim wLp As Integer
'==========================================================================================
'今Windows上で音が出てるアプリを取得する
'(A.I.Voice起動後、1文字でいいので、1回喋らせないと、この一覧から取得できない/0文字で再生ボタンを押すだけでもok)
'==========================================================================================
iDeviceEnumerator = New MMDeviceEnumerator()
Try
iRender = iDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia)
iRenderAudioSessionManager = iRender.AudioSessionManager
iRenderSessions = iRenderAudioSessionManager.Sessions
Catch
End Try
iDeviceEnumerator.Dispose() '解放する
'==========================================================================================
'音が出てるアプリ一覧からA.I.Voiceを探し、A.I.VOICEのプロセスIDを取得する
'もちろんA.I.VOICEが起動していなければ見つからないし、1文字以上予め何か喋らせないと見つからない
'==========================================================================================
iAIVoice_ProcessID = "" '初期化
If iRenderSessions IsNot Nothing Then
For wLp = 0 To iRenderSessions.Count - 1
If InStr(iRenderSessions(wLp).GetSessionInstanceIdentifier, cApp_Name) > 0 Then
'A.I.VOICEのプロセスIDを見つけたぜ!
iAIVoice_ProcessID = iRenderSessions(wLp).GetProcessID.ToString()
Exit For
End If
Next wLp
End If
If iAIVoice_ProcessID = "" Then
MessageBox.Show("A.I.VOICEが起動していないか、1文字もしゃべっていない為、プロセスIDを取得できませんでした。")
End If
End Sub
'***************************************************************************************
'タイマー等で、0.1秒や0.3秒ごとに実行すれば、常時ボリュームチェック可能
'***************************************************************************************
Private Function GetAIVoice_Volume(wAIVoice_ProcessID As String) As Single
Dim wVolume As Single
Dim wLp As Long
'音量初期値
wVolume = CSng(0)
'====================================================================================
'A.I.VOICEの音量を調べる
'しゃべり終わっても完全な0ではない時がある為、(0.000001等の事例がある)
'wVolumeが0.01以上だったら、しゃべっていると認識して良さそうだ
'====================================================================================
If iRenderSessions IsNot Nothing Then
For wLp = 0 To iRenderSessions.Count - 1
If iRenderSessions(wLp).GetProcessID.ToString() = wAIVoice_ProcessID Then
wVolume = iRenderSessions(wLp).AudioMeterInformation.MasterPeakValue
End If
Next
End If
Return wVolume
End Function
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'タイマーで常に音量を表示
Label1.Text = GetAIVoice_Volume(iAIVoice_ProcessID)
End Sub
End Class
注意点
ソースコードは、自由にコピー、改変してもらって問題ありません。ただし、問題があっても責任を負わないものとします。
また、コードはVB.NETであり、昔なつかしのVisualBasic6.0ではないのでご注意ください。
留意点
A.I.VOICEを予め起動し、なにか1回(1文字)でいいのでしゃべらせてからじゃないと、プロセスIDが取得できない。プロセスIDが取得できれば、動作に問題はありません。
使用言語・動作確認したバージョン
A.I.VOICE 1.4.5.0Microsoft Visual Studio Community 2022 (64 ビット)
NAudio 2.1.0 (NuGetパッケージよりインストール)
このソースの致命的な欠点
絵文字やスペース、句読点、読まない記号など、文字ではあるものの声に出して喋らない時に音量が0に近くなるので、A.I.VOICE上で再生しているか再生していないか(再生ボタンを押して今現在再生中かどうか)のチェックには使えない。あくまで、チェックにいった時に、音(声)が出ているか出ていないかのチェックとなる。
要するに、句読点などで、再生中ではあるものの声が出てない瞬間にチェックした時、再生中なのに0に近い値を返してしまうということです。(しゃべっていないのだから当然なのではあるのですが。)
関連記事
VB.NETでA.I.VOICEに喋らせる為の最短の設定とサンプルソースコードVB.NETで棒読みちゃんに文字を読ませるサンプルコード
VB.NETからOBSへキーを送信しホットキーを操作するサンプルコード