Audio Graph AudioGraph 是 Windows.Media.Audio 命名空間下提供的音頻處理介面之一。 可以通過 AudioGraph 的靜態方法 CreateAsync 來實例化一個 AudioGraph 對象,實例化的時候需要傳入一個參數 AudioGraphSetting ...
Audio Graph
AudioGraph 是 Windows.Media.Audio 命名空間下提供的音頻處理介面之一。
可以通過 AudioGraph 的靜態方法 CreateAsync 來實例化一個 AudioGraph 對象,實例化的時候需要傳入一個參數 AudioGraphSettings 來配置 AudioGraph。 Windows把系統中的音頻分成了大概12種類型:
public enum AudioRenderCategory
{
Other = 0,
ForegroundOnlyMedia = 1,
BackgroundCapableMedia = 2,
Communications = 3,
Alerts = 4,
SoundEffects = 5,
GameEffects = 6,
GameMedia = 7,
GameChat = 8,
Speech = 9,
Movie = 10,
Media = 11
}
在構造 AudioGraph 的時候選擇一種類別,可以應用 Windows 的一些優化措施(具體不知道)
創建 AudioGraph 代碼如下:
private async Task InitAudioGraph()
{
AudioGraphSettings settings = new AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media);
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
if (result.Status == AudioGraphCreationStatus.Success)
{
audioGraph = result.Graph;
}
}
Audio Graph 如何工作
在 Audio Graph 中,可以包含各種音頻節點,包括:
- 音頻輸入節點(Input Node), DeviceInputNode, FileInputNode, MediaSourceInputNode,AudioFrameInputNode
- 音頻輸出節點(Output Node), AudioSubmixNode
- 中間節點(Submix Node), DeviceOutputNode, FileOutputNode, MediaSourceOutputNode,AudioFrameOutputNode
這三種類型的節點可以按照
輸入節點--->中間節點--->輸出節點
這種順序來組合,其中中間節點可以有多個,用來完成多級的音頻數據處理。
AudioGraph 中各個節點在處理音頻數據的時候,是分段處理的,把完整的音頻數據切分成一小段一小段來處理。
數字音樂存在採樣率的概念,比如48Khz,表示一秒採樣48000次,因此每一次採樣會有一個採樣得到採樣值Sample。
AudioGraph 在處理這些採樣值的時候,會將其分組,每一個分組為一個 Quantum,預設每一個Quantum 代表10ms, 因此針對48K採樣率的音頻,每一個Quantum會有480個Sample,也就是說每一次每個音頻節點只需要處理480個採樣值,針對這480個採樣值做各種處理,比如保存,比如變換效果等。
音頻輸入節點(Input Node)
音頻輸入節點是為了獲取音頻數據,可以通過麥克風錄音,也可以直接從文件讀取,也可以從一個網路流里獲取,甚至可以直接自己生成一個AudioFrame,自己往裡面填音頻數據
1.DeviceInputNode
設備輸入節點,實際上就是麥克風。
值得註意的是同一臺電腦上可能有多個音頻輸入設備,如果在創建輸入節點時不指定使用的輸入設備,將採用系統預設的。
Windows.Devices.Enumeration.DeviceInformation 下麵的介面可以幫助我們選擇音頻輸入設備
public IAsyncOperation<CreateAudioDeviceInputNodeResult> CreateDeviceInputNodeAsync(MediaCategory category,AudioEncodingProperties encodingProperties, DeviceInformation device);
2.FileInputNode
public IAsyncOperation<CreateAudioFileInputNodeResult> CreateFileInputNodeAsync(IStorageFile file);
支持的音頻格式有 MP3,wav,wma,m4a
在文件輸入節點裡面,可以控制播放音頻的速度,音量和播放進度
3.MediaSourceInputNode
IAsyncOperation<CreateMediaSourceAudioInputNodeResult> CreateMediaSourceAudioInputNodeAsync(MediaSource mediaSource);
MediaSource可以從多個途徑獲得,比如文件,比如網路流等,MediaSource類有許多的靜態方法可以創建MediaSource對象,比如文件,好處是播放穩定,網路流的話會受網路影響,可能中斷
4.AudioFrameInputNode
個人認為這個輸入節點非常實用,用於創建音頻資源和編輯音頻會特別方便,因為它允許我們自己填充需要播放的音頻數據,介面本身不難,難點是如何生成可以播放的音頻數據。
想要讀寫一個AudioFrame中數據,需要使用 COM 介面IMemoryBufferByteAccess
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
void GetBuffer(out byte* buffer, out uint capacity);
}
因為 UWP 本質上就是 各種COM介面組成,在這種場景下直接使用 COM 可能有效率方面的考慮
音頻輸出節點(Output Node)
與輸入節點對應,存在各自的輸入節點(MediaSourceInputNode除外)
- DeviceInputNode, 代表揚聲器
- FileInputNode, 代表文件,輸出音頻數據到文件
AudioFrameOutputNode, 這個應用場景我不是很明白,MSDN上這麼說:
“An example scenario for this is performing signal analysis on the audio output”
中間節點(混音節點 Submix Node)
所有的輸入節點,都有一個介面叫做:
public void AddOutgoingConnection(IAudioNode destination);
通過這個介面,可以把輸入節點和輸出節點連接起來,最簡單的,
fileInputNode.AddOutgoingConnection(deviceOutputNode);
這麼簡單一句,就實現了音樂播放,但是如果想做一些混音的話,就不是很方便了,所以需要 Submix Node.
fileInputNode.AddOutgoingConnection(submixNode);
deviceInputNode.AddOutgoingConnection(submixNode);
submixNode.AddOutgoingConnection(deviceOutputNode);
這三句代碼,可以實現把音樂文件和錄音直接混合輸出到揚聲器,當然也可以輸出到文件中。
使用場景
Audio Graph 對 UWP 處理音頻的能力是一次不錯的拓展,基於 Audio Graph,有很多好玩的使用場景,比如官方文檔裡面介紹到的空間音效 Spatial Audio.
目前我自己最簡單能想到到就是可以用這個做一個簡單的電臺主播助手APP,如圖:
參考
本文基本來自於微軟官方文檔:
Audio Graph
其中 Spatial Audio 部分的應用本文沒有介紹到,這部分需要一定的聲學知識才能玩得轉!