日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows下Core_Audio_APIs的使用简介

發布時間:2025/3/8 windows 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows下Core_Audio_APIs的使用简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windows Vista?之后系統,音頻系統相比之前的系統有很大的變化,產生了一套新的底層?API?即?Core Audio APIs?。該低層?API?為高層?API(?如?Media Foundation(?將要取代DirectShow?等高層?API)?等?)?提供服務。該系統API具有低延遲、高可靠性、安全性等特點。

本文主要從實時音視頻場景中,簡單介紹該API的使用。

Core Audio APIs?的組成:MMDeviceEndpointVolumeWASAPI等。對于實時音視頻系統,主要用到的是MMDeviceEndpointVolume這兩套API。其在系統中的位置如下圖:

?

我對實時音視頻中音頻設備的使用簡單的分為:

1、設備列表管理

2、設備初始化

3、設備功能管理

4、數據交互

5、音量管理

6、設備終端監聽

接下來為大家介紹相關功能的實現:

?

1、設備列表管理

音頻設備的管理,由MMDevice API來實現。

首先我們要創建一個IMMDeviceEnumerator對象來開始相關功能的調用。

IMMDeviceEnumerator* ptrEnumerator;

CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,??????????????????? __uuidof(IMMDeviceEnumerator),??????????????????? reinterpret_cast<void**>(&ptrEnumerator));

并通過IMMDeviceEnumerator可以實現:獲取系統默認設備GetDefaultAudioEndpoint、獲取設備集合IMMDeviceCollection、獲取指定設備GetDevice、注冊設備監聽IMMNotificationClient(監聽設備插拔及狀態變更)。

通過這些方法,我們能得到系統默認設備、遍歷設備列表、打開指定設備并監聽設備變更。這樣就實現了實時音視頻中的設備管理相關的功能。

?

2、設備初始化

音頻設備的啟動是整個音頻模塊的可靠性的重要節點。根據設備類型和設備數據捕獲方式,我們可分為3類設備:麥克風采集、揚聲器播放、揚聲器采集。

首先我們需要一個IMMDevice對象,可以在設備管理的相關功能中獲取。

IMMDevice* pDevice;

//GetDefault

ptrEnumerator->GetDefaultAudioEndpoint((EDataFlow)dir,????????????????????????????????????????????? (ERole)role/* eCommunications */,????????????????????????????????????????????? &pDevice);

//Get by path

ptrEnumerator->GetDevice(device_path, &pDevice);

//GetIndex

pCollection->Item(index, &pDevice);

再通過IMMDevice得到IAudioClient,設備的格式設置及初始化通過IAudioClient對象實現。一般都以共享模式打開,其中麥克風采集及揚聲器播使用事件驅動方式處理數據,而揚聲器采集以回環的方式驅動處理數據。簡單示例如下:

//mic capturer

ptrClient->Initialize(

AUDCLNT_SHAREMODE_SHARED,

AUDCLNT_STREAMFLAGS_EVENTCALLBACK |?

AUDCLNT_STREAMFLAGS_NOPERSIST,

0,

0,?

?(WAVEFORMATEX*)&Wfx,

NULL);

//playout render

ptrClient->Initialize(

AUDCLNT_SHAREMODE_SHARED,

AUDCLNT_STREAMFLAGS_EVENTCALLBACK,

0,

0,?

?(WAVEFORMATEX*)&Wfx,

NULL);

//playout capturer

ptrClient->Initialize(

AUDCLNT_SHAREMODE_SHARED,

AUDCLNT_STREAMFLAGS_LOOPBACK,

0,

0,?

?(WAVEFORMATEX*)&Wfx,

NULL);

其中Wfx是設備格式參數,一般為了保證設備的可用性,使用默認格式(通過IAudioClient::GetMixFormat獲取),如果需要使用自定義格式,可以通過IAudioClient::IsFormatSupported方法去遍歷嘗試設備支持格式。

?

3、設備功能管理

針對麥克風設備,我們通常需要對其進行數據處理。部分硬件設備和系統支持自帶的降噪、增益、消回音等功能。但是一般windows系統下設備比較繁雜不可控,大都使用軟件算法處理。如果我們需要檢測設備是否使用了自帶的處理功能及相關參數,需要使用Topology模塊的功能。

IDeviceTopology* pTopo;

pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_INPROC_SERVER, 0,&pTopo);

通過IDeviceTopology,我們能夠遍歷IConnector對象,獲得IAudioAutoGainControlIAudioVolumeLevel等能力對象,并處理相關能力。

注意:IConnector可能是循環嵌套,在遍歷IConnectorIPart時需要判別成員對象IPart的類型。

?

4、數據交互

在設備初始化的時候,我們就根據不同的設備選擇了不同的模式進行了啟動。不同的設備在各自的模式下,數據驅動也各有不同:

麥克風采集:

揚聲器播放:

揚聲器采集:

在和設備進行數據交互時,我們需要根據數據獲取模式,獲取對應的服務對象來獲取設備數據。其中采集部分使用IAudioCaptureClient服務用于獲取設備數據,播放使用IAudioRenderClient服務獲取設備數據傳入指針。示例如下:

//capturer

IAudioCaptureClient* ptrCaptureClient;//audioin or audioout

ptrClient->GetService(__uuidof(IAudioCaptureClient), (void**)&ptrCaptureClient);

{//work thread

?? ? //Wait Event

ptrCaptureClient->GetBuffer(

&pData,??????????? // packet which is ready to be read by used

&framesAvailable,? // #frames in the captured packet (can be zero)

&flags,?? ?????????// support flags (check)

&recPos,??? // device position of first audio frame in data packet

&recTime);? // value of performance counter at the time of recording

//pData processing

ptrCaptureClient->ReleaseBuffer(framesAvailable);

}

//render

IAudioRenderClient* ptrRenderClient;//audioout

ptrClient->GetService(__uuidof(IAudioRenderClient), (void**)&ptrRenderClient);

{//work thread

??????? ?????? BYTE* pData;//form buffer?

??????? ?????? UINT32 bufferLength = 0;

??????? ?????? ptrClient->GetBufferSize(&bufferLength);

??????? ?????? UINT32 playBlockSize = nSamplesPerSec / 100;

??????? ?????? //Wait Event

??????? ?????? UINT32 padding = 0;

??????? ?????? ptrClient->GetCurrentPadding(&padding);

??????? ?????? if (bufferLength - padding > playBlockSize)

??????? ?????? {

??????????? ????????????? ptrRenderClient->GetBuffer(playBlockSize, &pData);

//request and getdata

ptrCaptureClient->ReleaseBuffer(playBlockSize, 0);

}

}

在實際的數據交互中,需要另開單獨線程處理GetBufferReleaseBuffer。其中麥克風采集及揚聲器播放時,都是通過設備事件驅動,可以在設備初始化完成后設置響應的事件句柄(IAudioClient::SetEventHandle)。

在整個音視頻系統中,設備數據線程還需要統計數據處理時長、采集播放緩存大小等,用戶監聽檢查設備狀態及aec延遲計算。

?

5、音量管理

一般音量管理只在設備選定后處理當前設備的音量,所以一般使用IAudioEndpointVolume,該對象通過設備對象IMMDevice獲取:

IAudioEndpointVolume* pVolume;

pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL,?????????????????????????? reinterpret_cast<void**>(&pVolume));

得到IAudioEndpointVolume對象后,我們能處理當前設備的音量控制:

pVolume->GetMasterVolumeLevelScalar(&fLevel);

pVolume->SetMasterVolumeLevelScalar(fLevel, NULL);

靜音控制:

BOOL mute;

pVolume->GetMute(&mute);

pVolume->SetMute(mute, NULL);

以及注冊IAudioEndpointVolumeCallback監聽音量狀態:

IAudioEndpointVolumeCallback* cbSessionVolume;//need to do

pVolume->RegisterControlChangeNotify(cbSessionVolume);

6、設備終端監聽

在運行過程中除了設備的插拔等操作,還可能有一些屬性變更等,一般用IAudioSessionEvents監聽:

IAudioSessionControl* ptrSessionControl;

ptrClient->GetService(__uuidof(IAudioSessionControl), (void**)&ptrSessionControl);

IAudioSessionEvents* notify;

ptrSessionControl->RegisterAudioSessionNotification(notify);

該回調監聽,能監聽該設備的連接工作狀態,名稱變更等。

?

一些注意事項:

1、線程優先級

在實際的工程開發過程中,我們需要對音頻線程的工作線程進行處理。通常通過調用系統模塊Avrt.dll,動態調用其下的函數,將調用線程與指定任務(Pro Audio)相關聯。上代碼:

函數綁定:

avrt_module_ = LoadLibrary(TEXT("Avrt.dll"));

if (avrt_module_)

{

_PAvRevertMmThreadCharacteristics = (PAvRevertMmThreadCharacteristics)GetProcAddress(avrt_module_, "AvRevertMmThreadCharacteristics");

_PAvSetMmThreadCharacteristicsA = (PAvSetMmThreadCharacteristicsA)GetProcAddress(avrt_module_, "AvSetMmThreadCharacteristicsA");

_PAvSetMmThreadPriority = (PAvSetMmThreadPriority)GetProcAddress(avrt_module_, "AvSetMmThreadPriority");

}

在實際的數據處理線程關聯:

hMmTask_ = _PAvSetMmThreadCharacteristicsA("Pro Audio", &taskIndex);

if (hMmTask_)

{

_PAvSetMmThreadPriority(hMmTask_, AVRT_PRIORITY_CRITICAL);

}

通過任務綁定,能有效的提升音頻數據處理線程的可靠性。

2、工作線程

設備的相關初始化和釋放操作,需要在統一的線程處理,部分系統com對象在釋放時需要在創建線程釋放,不然可能導致釋放崩潰。而一些音量選擇、監聽等的處理可以在用戶線程處理,但需要做好多線程安全。

3、設備格式選擇

在設備的采樣率、聲道等格式選擇時,如果需要使用自定義的格式,可能出現格式匹配失敗或者選擇匹配的格式后設備初始化失敗的場景。通常此類場景下直接使用默認格式啟動。

4、數據處理異常

在數據處理線程處理音頻數據時,通常會出現事件響應超時、設備對象異常等情況。通常的處理方法是,先退出數據線程并結束設備,然后檢查當前設備是否正常功能,然后重新啟動當前設備或選用默認設備。

?

了解網易云信音視頻通話>>>

了解網易云信,來自網易核心架構的通信與視頻云服務>>

更多技術干貨,歡迎關注vx公眾號“網易智慧企業技術+”。系列課程提前看,精品禮物免費得,還可直接對話CTO。

聽網易CTO講述前沿觀察,看最有價值技術干貨,學網易最新實踐經驗。網易智慧企業技術+,陪你從思考者成長為技術專家。

總結

以上是生活随笔為你收集整理的Windows下Core_Audio_APIs的使用简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 波多野结衣黄色网址 | 无遮挡的裸体按摩的视频 | 国产一级久久久 | 欧美先锋影音 | 亚洲熟妇色自偷自拍另类 | 免费黄色成人 | 西比尔在线观看完整视频高清 | 免费观看一级视频 | 亚洲国产精品视频 | www.操.com| www久久久久久 | 国产成人精品三级麻豆 | 亚洲av色香蕉一区二区三区 | 欧美性猛交xxxx乱大交 | 午夜嘿嘿 | 伊人论坛 | 国产精品电影在线观看 | 色网导航站 | 色悠悠网 | 污视频大全| 免费观看已满十八岁 | 丰满少妇被猛烈进入一区二区 | 欧美不在线 | 国产a∨精品一区二区三区仙踪林 | 古装做爰无遮挡三级视频 | 韩国女主播av | 亚洲成人精品网 | 成人免费毛片网 | 午夜影院体验区 | 成人影视免费观看 | 亚洲第一大综合区 | 国产在线观看成人 | 精品视频在线免费看 | 暴力调教一区二区三区 | 福利电影一区 | 最近中文字幕在线中文视频 | 久久黄色视 | 国产熟女一区二区三区五月婷 | 亚洲青青草 | 五月婷婷中文字幕 | 极品色影视 | 林雅儿欧洲留学恋爱日记在线 | 国产一页 | 小镇姑娘高清播放视频 | 日韩区欧美区 | 欧美成人三级在线视频 | 亚洲一区二区不卡在线观看 | 日韩五码在线 | 一本加勒比波多野结衣 | 少妇与公做了夜伦理 | 欧美一区二区三区影院 | 999久久久精品视频 亚洲视频精品在线 | wwwav视频在线观看 | 国产一级淫片a | 少妇又紧又色又爽又刺激视频 | 波多野结衣一区二区三区免费视频 | 污免费在线观看 | 国产免费一区二区三区四区五区 | 好吊一区二区三区视频 | 久久久77 | 欧美精品黑人猛交高潮 | 一区二区三区少妇 | 日韩精品一区二区av | 欧美中文视频 | 亚洲精品在线视频免费观看 | 女女调教被c哭捆绑喷水百合 | 成人h视频 | 亚洲欧美中日韩 | 亚洲av毛片成人精品 | 老妇裸体性激交老太视频 | 淫久久| 美女福利在线 | 久久久欧美精品sm网站 | 一区二区三区四区久久 | 污黄视频在线观看 | 午夜动态图 | 免费三片在线播放 | 国产一二三区精品 | 中文字幕69页 | 成人精品免费视频 | 富二代成人短视频 | 在线看国产 | 91黄色在线观看 | av收藏小四郎最新地址 | 欧美另类视频在线 | 成人久久免费 | 欧美成人免费 | 人人舔人人爽 | 久久精品国产99国产精品 | 无码人妻精品一区二区三区99不卡 | 欧美黄在线观看 | 日日操av | 艳妇乳肉豪妇荡乳xxx | 欧洲日韩一区二区三区 | 免费成人毛片 | 国产一区二区三区久久 | 亚洲五十路| 国产视频一区二区三区四区五区 | 大陆av在线播放 |