一 , 用 unity2018.4.9 vs2017 創建一個新的 Unity 項目 VoiceDemo,初始化項目:
1.導入 MRTK 包 (版本 HoloToolkit-Unity-2017.4.2.0)
2.應用項目設置爲 MR 項目 (一鍵設置成爲可以部署的環境)
3.使用 HoloLensCamera 替代默認相機
4.添加 CursorWithFeedback (識別並反饋手勢的光標控件)
5.添加 InputManager (作爲輸入源管理器,管理 gaze,gesture,speech等)
6.設置 InputManager 的 SimpleSinglePointerSelector 腳本的 Cursor 屬性爲添加的 CursorWithFeedback (添加手勢源到inputmanger)
7.添加一個 Cube
最終 Hierarchy 結構如下:
二,語音控制 SpeechInputSource.cs腳本 (效果:說出start rotate時,cube開始旋轉. 說出stop rotate時,cube停止旋轉)
(1),在 Hierarchy 創建一個空的 gameObject 並重命名爲 SpeechManager
,爲其添加 MRTK 的 SpeechInputSource.cs
腳本,爲其添加兩個關鍵字,分別是 start rotate 和 stop rotate。 //也許是作爲一個監聽的預設體,用來監聽聲音,無需附加給其他
屬性說明:
PersistentKeywords | Keyword 在所有場景中都是持久的,此語音輸入源實例在加載新場景時不會被銷燬 |
RecognizerStart | 是否在啓動時激活識別器 |
recognitionConfidenceLevel | Keyword 識別器的置信度 |
(2),新建一個腳本 CubRotate.cs
,並將其添加到 Cube 上。//用來使cube旋轉
這個腳本十分簡單,調用 StartRotate()
方法就能夠使 Cube 開始旋轉,調用 StopRotate()
方法使 Cube 停止旋轉。
using UnityEngine;
public class CubRotate : MonoBehaviour {
bool HasRotate = false;
void Update () {
if(HasRotate)
{
transform.Rotate(Vector3.up);
}
}
public void StartRotate()
{
HasRotate = true;
}
public void StopRotate()
{
HasRotate = false;
}
}
(3),爲 Cube 添加 MRTK 中的 SpeechInputHandler.cs
腳本, 該腳本用於處理語音輸入,利用上面的SpeechInputSource.cs腳本獲得的聲源進行處理。
在該腳本中,添加了兩個要處理的關鍵字,也就是在 SpeechInputSource.cs 中設置的 start rotate 和 stop rotate。在對應的 Response() 中調用了 Cube 的 CubeRotate.StartRotate() 和 CubeRotate.StopRotate() 方法。
//SpeechInputSource.cs捕獲到說出對應的關鍵字之後, SpeechInputHandler.cs來處理關鍵字(調用不同的方法),進而使cube做出動作
運行程序,因爲使用到了語音,所以必須使用真機運行,在運行前,不要忘記添加 Microphone 的權限。在 Edit/Project Settings/Player/Publishing Settings/Capabilities
中勾選 Microphone 。
二,實現用聲音操作 cube大小 (效果:首先會錄入外界的聲音,並實時播放. 當外界聲音大時,cube變大)
下面實現一個在耳機中播放麥克風錄入的聲音,並能夠根據聲音音量調整 Cube 的大小。
(1) 新建一個腳本 CubeMic.cs
,並將其添加到 Cube 上。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity.InputModule;
public class CubeMic : MonoBehaviour
{
//表示cube的原始大小
private Vector3 origScale;
//設置當前麥克風的“音量”,平均振幅
private float averageAmplitude;
void Start()
{
//保存原始大小
origScale = transform.localScale;
//設置麥克風的聲音
MicStream.MicSetGain(10);
//開啓麥克風
MicStream.MicStartStream(false, false);
}
//聲音過濾的方法
private void OnAudioFilterRead(float[] buffer, int numChannels)
{
//將麥克風輸入到聲音過濾的管線中,將麥克風的聲音從耳機中播放出來
MicStream.MicGetFrame(buffer, buffer.Length, numChannels);
//計算麥克風的聲音大小
float sumOfValues = 0;
for (int i = 0; i < buffer.Length; i++)
{
sumOfValues += Mathf.Abs(buffer[i]);
}
averageAmplitude = sumOfValues / buffer.Length;
}
void Update()
{
//根據“音量”調整cube的大小
transform.localScale = origScale * (1 + averageAmplitude * 10);
}
}
總結一下代碼:
- MicStream : HoloToolkit提供的麥克風操作類,詳細的用法可參考工具包中的MicStreamDemo類
- OnAudioFilterRead Unity引擎提供的聲音濾波函數,具體原理可參考官方文檔《OnAudioFilterRead》
- MicStream.MicGetFrame(…) : 這個方法可以獲取到麥克風的幀數據(float[]),可以在類似 OnAudioFilterRead 或者 Update 等高頻事件中調用並獲取。因爲獲取到的是麥克風最小數據單元,使用起來非常靈活。我們可以在 OnAudioFilterRead 中播放,也可以使用Socke實現遠程通話.
(2).爲 Cube 添加一個 Audio Souce
組件,用於播放聲音,它的屬性使用默認值即可。
在真機中運行程序,我們能夠聽見麥克風的聲音,並且 Cube 根據音量大小發生改變。
三, 有關語音中設置關鍵字的說明
- 不要使用單音節詞,避免被系統忽略。例如使用 Play Video 替代 Play。也要注意不要音節過多,增加用戶使用成本。
- 不要使用系統預置語音,防止歧義,例如 Select、Remove等。
- 避免押韻的語音,例如使用 Show Store 替代 Show More。
四, 語音的底層實現
官網語音底層代碼:https://docs.microsoft.com/zh-cn/windows/mixed-reality/holograms-101#chapter-4---voice
博客說明:https://blog.csdn.net/yuanlaijike/article/details/85202286