本書範例程式的下載方式 - 碁峰資訊epaper.gotop.com.tw/pdfsample/acl038800.pdf ·...
TRANSCRIPT
xiii
由於涉及到第三方原始碼授權與二進位函式庫授權,為了方便讀者
以最簡單的方式取得範例程式碼並編譯執行,本書實作範例原始碼皆公
開放置於 GitHub網站(https://github.com/)上。所有範例列表都可以在
https://github.com/SenWang之下找到。
次頁可以顯示所有專案(都以 kinectsample_開頭),如下圖
所示:
本書範例程式的下載方式
xiv
進入每一個專案後,直接點選 就可以下載特定範例的完整原
始碼。
如果讀者希望隨時與作者最新版程式碼保持同步,最簡單的方法就是
安裝 GitHub for Windows(http://windows.github.com/),點選網頁右上角
的 即可開始安裝步驟。
xvii
在專案上按下滑鼠右鍵選擇 open in explorer,可以開啟專案所在目錄:
專案預設都是放置在 C:\Users\<使用者 ID>\Documents\GitHub\目錄下。
除了 GitHub for Windows 外,任何符合 Git版本控制標準的用戶端
程式都可以用來同步範例原始碼。本書中每個實作範例都會附上專案位
址與同步位址方便讀者隨時擷取。也有單獨的範例專門解說如何用 Visual
Studio 2012 Update 2內建的 Git版本控制功能下載每個範例的原始碼。
Git是目前開放原始碼社群最熱門的原始碼版本控制工具。甚至微
軟開發工具(Visual Studio、Team Foundation Service)與雲端平台大力
(Azure)都大力支援這個版控與部署方式。雖然 Git進入門檻有點高,不
過學會之後妙用無窮,對 Git有興趣的朋友請參考。
中文版:版本控制使用 Git, 2/e /歐萊禮
英文版:Version Control with Git: Powerful tools and techniques for
collaborative software development, 2/e)
CHAPTER
5聲音處理
本章將介紹 Kinect的「耳朵」–麥克風陣列。四顆麥克風所構成
的陣列,收集所在環境中的各種聲音資訊,演算法分析蒐集到
的資訊後判定聲音之來源方位,提供給應用程式做高階應用。
此外,Kinect亦可拿來當作一般的麥克風進行聲音錄製。
5-2 Kinect體感程式設計入門與應用
5-1│ Kinect的聲音來源
麥克風
█麥克風陣列(圖片來源:官方教材 Using Kinect for Windows with XNA)
Kinect的聲音來自於底下由四個麥克風所構成的麥克風陣列。感應器
內含數位訊號處理器 Digital Signal Processing (DSP),可以用來過濾背
景雜音並強化聲音接收時的清晰度。
雖然有四個麥克風,不代表我們再進行聲音錄製的時候可以錄製四個
聲道(Channel)的聲音輸入,當我們使用官方函式庫時,只能接收來自底
層已經過初步處理的音源。
█分析聲音來源(圖片來源:官方教材 Using Kinect for Windows with XNA)
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-3
藉由四個麥克風分別對某個發音源所接收到的音量強弱,配合背景噪音
過濾功能,Kinect可以分析出聲音的來源,不過僅限水平方向,Kinect無法
辨識垂直方向的聲音位置,亦無法區分聲音來自 Kinect的前方還是後面。
消除 20分貝 (20dB) 環境雜音
Kinect麥克風陣列可以消除 20分貝(20dB)的環境雜音。根據麥克
風的擺放位置設計,來自 Kinect後方的聲音大致上會被額外壓低 6分貝
(6dB),這樣的設計可以讓來自 Kinect前方的聲音變得比較『重要』(相
對較大聲)。預設的情況下,Kinect會自動將麥克風陣列對準所在環境中
聲音最大的來源位置。
你好 正負50°(共100°)
█每 10°分割為一個鎖定區域
5-4 Kinect體感程式設計入門與應用
Kinect 所能辨識的水平聲音來源為以感應器為中心的正負 50°(共
100°)。預設只鎖定聲音最大來源位置的做法,在實務上並不恰當(現場很
多人的時候,講話最大聲的人不一定是正在使用 Kinect的用戶),因此開
發者可以透過 API,讓方向性麥克風(麥克風陣列)鎖定特定來源區域的聲
音,例如:根據用戶的骨架位置決定鎖定的區域。Kinect每次僅能鎖定區
間範圍為 10°的區域作為收音範圍,如此可以增強該使用者所發出的語音
命令之辨識精確度。
5-2│ Kinect的聲音 API
█聲音處理,Kinect視為功能較強的麥克風。倚靠底層作業系統元件運作
Kinect的聲音取樣(sampling)頻率為 16,000(16 KHz,每秒取樣一萬
六千次),解析度是 16 Bits(2 Bytes,也就是把取樣聲音區分成 2的 16次
方 =65536種等級)。
相較一般音樂 CD的取樣頻率為 44 KHz,Kinect麥克風不屬於高傳真
(High Fidelity)收音,但做為語音辨識或高品質語音通訊已經足夠。
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-5
麥克風陣列 鎖定角度
聲音來源
來源音量大小
取得
要操作 Kinect 的聲音功能,首先必須從 KinectSensor 物件中取出
AudioSource 物件。本章的實作範例,將利用取出的 AudioSource 物件
進行聲音來源的確認以及聲音的錄製等應用。從 KinectAudioSource 的
API 參 考 文 件 http://msdn.microsoft.com/en-us/library/microsoft.kinect.
kinectaudiosource_members.aspx可以發現,與聲音相關的方向,微軟提
供了 BeamAngle 和 SoundSourceAngle 兩種;而關於聲音的大小,則提
供 SoundSourceAngelConfidence屬性。這 3個屬性的數值,在我們使用
Kinect Explorer範例程式時已經見過。如下圖所示:
麥克風陣列鎖定角度
聲音來源
來源音量大小
█ Kinect Explorer關於聲音的資訊
Kinect Explorer顯示了兩個與方向有關以及一個與來源聲音大小的資訊。
5-6 Kinect體感程式設計入門與應用
其中,Sound Source Angle為經過數學演算法處理之後,系統終判
定聲音來源的角度,伴隨著一個介於 0到 1的 Confidence屬性值(通常用
來作為判定聲音強弱或聲音距離遠近的依據);Beam Angle則是方向性麥
克風(麥克風陣列)對準聲音來源之角度(Kinect Explorer範例程式中,系
統確定聲音來源後,如果發現聲音來源改變,會自動改變方向性麥克風對
準的方向)。因此,如果單純想得知聲音的來源方向,那麼 Sound Source
Angle的屬性值較為精確;Beam Angel的結果也可以當作聲音來源的判斷
依據,只是該屬性的正確用途是判讀麥克風陣列所對準用來收音的位置。
5-3│實作範例
範 例 1:偵測聲音來源方向
範例重點:
偵測聲音來源方向以及麥克風陣列之鎖定方向
範例說明:
初始化代表聲音處理器的 KinectAudioSource 物件。讀取 Sound
SourceAngle、SoundSourceAngleConfidence、以及 BeanAngle 等屬
性之數值。
範例網址- https://github.com/SenWang/kinectsample_soundsource
同步網址- https://github.com/SenWang/kinectsample_soundsource.git
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-7
操作步驟:
1 主程式架構
取得 KinectSensor物件後,接著取出 KinectAudioSource物件,任何
與聲音或語音辨識相關的系統功能都需要先針對 KinectAudioSource
物件作基礎設定,完成後才能進行聲音的追蹤。
請注意,為了避免與彩色 /深度攝影機一同使用時產生不必要的麻煩,
建議在 KinectSensor的 Start( )函式正確地啟動 Kinect之後,再開始
聲音相關的設定。本書範例遵循此作法。
2 基礎設定
設定 Kinect 聲音功能的步驟為第 28 行,叫用我們自己撰寫的
AudioSourceSetup()函式進行聲音參數設定。
設定完 Kinect聲音參數後,接著註冊事件處理函式如下:
5-8 Kinect體感程式設計入門與應用
這是告訴系統,一旦偵測到 SoundSourceAngle或 BeamAngle屬性值
改變(角度改變),請叫用這裡註冊的事件處理函式。
最後如第 33行,呼叫 Start()方法啟動 KinectAudioSource。
3 聲音參數設定
Kinect官方文件告訴我們,要讓 Kinect有效地判斷聲音方位,除了要
開啟抑制噪音( NoiseSuppression屬性)的功能,也要開啟自動增益
(AutomaticGainControlEnabled 屬性)功能,此外,如果要讓麥克
風陣列自動對準最大的音源方向,BeamAngleMode屬性必須設定為
Adaptive 或 Automatic 模式(預設為 Automatic 模式,但 Adaptive 模
式適合環境噪音較大之處,因此這裡改用 Adaptive模式)。
4 取得方向性麥克風(麥克風陣列)最新對準的方向
當 Kinect麥克風陣列鎖定的角度改變了,系統就會自動呼叫我們所註
冊的事件處理函式。藉由傳入的物件我們可以取得最新的系統對準角
度(Beam Angle)。這裡所傳回的數值是角度(degree,0到 360°)而
非徑度(radians,0到 2π)。MaxBeamAngle與 MinBeamAngle則是
Kinect所能判定的最大範圍。
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-9
如果我們面對 Kinect,左方為負,右方為正,MinBeamAngle就是左
邊最大可偵測的角度,MaxBeamAngle則是右邊最大可偵測的角度。
使用事件處理函式的最大缺點,在於我們都是被動地等待系統告知
我們最新的 Beam Angle。然而在高效能的程式中,事件處理函式
通常會耗用多餘的 CPU時間,我們可考慮改採主動詢問系統目前
的 Beam Angle 的方式,藉此取代被動的通知。開發人員可以透過
KinectAudiceSource物件的 BeamAngle屬性隨時查詢目前的角度,所
得到的數值和同一時間事件處理函式所傳入的完全相同。
不管用何種方法取得 BeamAngle屬性,所得到的值都是趨近 -50, -40,
-30, -20, -10, 0, +10, +20, +30, +40, +50的數字。
5 取得目前聲音來源方向
當系統發現 SoundSourceAngle的數值改變時,會叫用我們所註冊的
事件處理函式。藉由傳入的物件我們可以取得系統所偵測到的 Sound
Source Angle與 Confidence Level。
與 BeamAngle定義的方向相同,如果我們面對 Kinect,左方為負,
右方為正,MinSoundSourceAngle 就是左邊最大可偵測的角度,
MaxSoundSourceAngle則是右邊最大可偵測的角度。
如果要主動查詢系統目前的 Sound Source Angle 與 Confidence
Level, 請 透 過 KinectAudiceSource 物 件 的 SoundSourceAngle 與
SoundSourceAngleConfidence兩個屬性。
5-10 Kinect體感程式設計入門與應用
6 執行結果
執行後可以發現,如果一直在同一個位置講話,只會不斷觸發
SoundSourceAngleChanged事件;只有改變了發話位置,麥克風陣列
才會改變鎖定之位置進而觸發 BeamAngleChanged事件。
KinectAudioSource 物件的 ManualBeamAngle 用來設定麥克風陣列
的鎖定方位(Beam Angle),必須改變 BeamAngleMode為 Manual之
後才有效,根據 http://msdn.microsoft.com/en-us/library/microsoft.
kinect.kinectaudiosource.manualbeamangle.aspx ,雖然是 double型
態,但僅接受 -50, -40, -30, -20, -10, 0, +10, +20, +30, +40, +50這幾
個數字為合法參數值。BeamAngleMode 屬性有三種: Automatic、
Adaptive、Manual,預設為 Automatic模式。詳細說明請參考
http://msdn.microsoft.com/en-us/library/microsoft.kinect.
beamanglemode.aspx。
Automatic與 Adaptive都是要求系統自動鎖定聲音來源以進行收音,
只是 Adaptive比較適合噪音較多的環境。
範 例 2:使用 Kinect麥克風進行錄音
範例重點:
學習使用 KinectAudioSource物件與錄音相關程式設計技巧
範例說明:
.NET標準函式庫僅提供播放 .wav檔功能,本範例將倚靠 NAudio套件
處理 .wav檔的寫入。
範例網址- https://github.com/SenWang/kinectsample_record
同步網址- https://github.com/SenWang/kinectsample_record.git
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-11
操作步驟:
1 主程式架構
啟動 Kinect感應器之後,緊接著設定聲音(收音)相關參數。只要使用
者按下方向鍵的↑,就開始錄音程序;按下方向鍵的↓,則播放剛剛
所錄製的聲音檔。
2 聲音參數設定
三個與麥克風收音相關的參數,包括噪音抑制、自動增益、回音消除,
都可以透過對應的屬性修改。開發者可以自行修改並確認使用後的效
果,從而了解三個參數的意義與影響。
5-12 Kinect體感程式設計入門與應用
3 聲音錄製
第 36行的緩衝區大小決定錄音長度,也決定了存檔後的大小。第
38-40啟動麥克風讀取資料至緩衝區,讀取完畢後立刻關閉麥克風。
最後將記憶體中的聲音利用我們自行撰寫的 SaveToWaveFile()儲存至
檔案中。一旦叫用 KinectAudioSource的 Start()方法,就會立刻開啟
聲音串流(注意,Start()有一個能接受 TimeSpan物件的重載方法,用
來控制所錄製的聲音長度)。使用結束後,請別忘了呼叫 Stop()方法
會關閉聲音串流。
4 儲存聲音至檔案的輔助套件
要將緩衝區的資料存檔,必須加入檔案標頭(Header),一方面為了
儲存成標準檔案格式,二來容易播放(許多播放器只能讀取標準檔案
格式)。舉例來說,如果我們要存成 .wav檔(Wave file),就必須根據
規格寫入 .wav檔之標頭資訊,並夾帶從 Kinect所接收的資料(即緩
衝區之內容)。.wav檔之標頭格式請參考 https://ccrma.stanford.edu/
courses/422/projects/WaveFormat/。
由於本書並非一本專門討論聲音處理的著作,因此我們將借用名為
NAudio的套件協助我們將記憶體中的資料儲存為標準聲音檔。
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-13
請先在 Visual Studio 之中選擇工具 擴充功能和更新,確認您的
Visual Studio 已經加入名為 NuGet Package Manager 的擴充套件。
如果沒有,您可以利用右上方的搜尋功能於線上資料庫搜尋 NuGet
Package Manager並安裝之。如下圖所示:
接著請確認您已經安裝了 NAudio套件。在專案下的參考節點按下滑
鼠右鍵,選擇管理 NuGet套件。
5-14 Kinect體感程式設計入門與應用
如果已安裝的套件裡面沒有 NAudio,您可以使用右上方的搜尋功能,
在線上套件庫中搜尋 NAudio並安裝之。如下圖所示:
一旦安裝成功,我們就可以在參考節點底下看到 NAudio組件,如下
圖所示:
CH
AP
TER 5
聲音處理
CH
AP
TER 6
語音辨識與語音合成
CH
AP
TER 7
圖形介面K
inect
應用程式
CH
AP
TER 8
Kinect
互動
聲音處理 5-15
5 儲存聲音至檔案的程式碼
使用 Naudio套件前請加入底下命名空間:
using NAudio.Wave;
根據 Kinect 硬體規格的描述,Kinect 傳回的聲音的格式為 16,000
(16 KHz),解析度是 16 Bits(2 Bytes),單聲道。因此我們可以使
用程式碼:
var newFormat = new WaveFormat(16000, 16, 1);
設定存檔格式,接著直接將取自於 Kinect音源的緩衝區直接寫入檔案
即可。完整程式碼如下所示:
上述程式碼使用了 C#特有的 using(...)語法,又稱作 using陳述式
(using expression),如果讀者想了解為何這樣撰寫,請參考 C#程
式語言書籍。
6 播放存檔內容
這裡我們將借助 .NET內建的 SoundPlayer物件幫我們將 .wav檔讀出
並播放。使用 SoundPlayer時別忘了加入底下命名空間:
using System.Media;
直接呼叫 Play()方法即可開始進行播放。完整程式碼如下所示: